Ctrl K
ComunidadGuías…

tests/vault_test.go

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package main

import (
	"context"
	"net/http"
	"testing"

	"github.com/shellhub-io/shellhub/tests/environment"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

type vault struct {
	Data    string `json:"data"`
	Version int64  `json:"version"`
}

// TestEnterpriseVault covers the vault the server keeps for a user in a namespace. Each write of
// its data carries the version the writer last read, and the server refuses one based on a version
// another write has already replaced, so a session holding a stale copy cannot overwrite the keys
// another session saved.
func TestEnterpriseVault(t *testing.T) {
	t.Parallel()

	ctx := context.Background()

	compose := newEnterpriseEnvironment(t, ctx, environment.New(t, run))

	t.Run("a write based on a stale version is refused with 409 and the first write is kept", func(t *testing.T) {
		first := compose.AuthUser(t, ShellHubUsername, ShellHubPassword).Token
		second := compose.AuthUser(t, ShellHubUsername, ShellHubPassword).Token

		resp, err := asBearer(t, compose, first).
			SetBody(map[string]string{"meta": `{"salt":"c2FsdA=="}`}).
			Put("/api/vault/meta")
		require.NoError(t, err)
		require.Equal(t, http.StatusOK, resp.StatusCode(), resp.String())

		read := readVault(t, compose, first).Version
		require.Equal(t, read, readVault(t, compose, second).Version, "the two sessions read different versions")

		firstData := `{"iv":"Zmlyc3Q=","ciphertext":"Zmlyc3Q="}`
		resp, err = asBearer(t, compose, first).
			SetBody(map[string]any{"data": firstData, "version": read}).
			Put("/api/vault/data")
		require.NoError(t, err)
		require.Equal(t, http.StatusOK, resp.StatusCode(), resp.String())

		resp, err = asBearer(t, compose, second).
			SetBody(map[string]any{"data": `{"iv":"c2Vjb25k","ciphertext":"c2Vjb25k"}`, "version": read}).
			Put("/api/vault/data")
		require.NoError(t, err)
		assert.Equal(t, http.StatusConflict, resp.StatusCode(), resp.String())

		stored := readVault(t, compose, second)
		assert.Equal(t, firstData, stored.Data, "the stale write replaced the first writer's data")
		assert.Equal(t, read+1, stored.Version, "the stale write bumped the version")
	})
}

func readVault(t *testing.T, compose *environment.DockerCompose, token string) vault {
	t.Helper()

	stored := vault{}
	resp, err := asBearer(t, compose, token).SetResult(&stored).Get("/api/vault")
	require.NoError(t, err)
	require.Equal(t, http.StatusOK, resp.StatusCode(), resp.String())

	return stored
}