package sparrow import ( "context" "crypto/rand" "crypto/rsa" "crypto/sha256" "fmt" "io" "net/http" "net/http/httptest" "os" "strings" "testing" "github.com/golang-jwt/jwt" "github.com/google/uuid" "gotest.tools/v3/assert" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" "edge-infra.dev/pkg/edge/edgeencrypt" "edge-infra.dev/pkg/lib/fog" ) var ( data = []byte("my-data") cfg = &Config{Namespace: edgeencrypt.EncryptionName, JWTSecret: edgeencrypt.EncryptionJWTSecret} server *Server cl client.Client ) func TestMain(m *testing.M) { cl = fake.NewFakeClient() server = NewEncryptionServer(cfg, cl, fog.New()) os.Exit(m.Run()) } func TestHealth(t *testing.T) { w := httptest.NewRecorder() req, err := http.NewRequest("GET", "/health", nil) assert.NilError(t, err) server.router.ServeHTTP(w, req) assert.Equal(t, 200, w.Code) assert.Equal(t, "ok", w.Body.String()) } func TestEncryptUnAuthorize(t *testing.T) { w := httptest.NewRecorder() req, err := http.NewRequest("POST", "/v1/encrypt", strings.NewReader(string(data))) assert.NilError(t, err) server.router.ServeHTTP(w, req) // no bearer token assert.Equal(t, 401, w.Code) } func TestEncryptionSuccess(t *testing.T) { w := httptest.NewRecorder() req, err := http.NewRequest("POST", "/v1/encrypt", strings.NewReader(string(data))) assert.NilError(t, err) privateKey := createPublicPrivateKey(t) channelID := uuid.NewString() channelName := "my-channel" token, err := edgeencrypt.CreateToken(jwt.SigningMethodRS256, privateKey, edgeencrypt.DefaultDuration, channelID, channelName, edgeencrypt.Encryption, "my-banner") assert.NilError(t, err) req.Header.Set("Authorization", "Bearer "+token) server.router.ServeHTTP(w, req) assert.Equal(t, 200, w.Code) body, err := io.ReadAll(w.Body) assert.NilError(t, err) e := &edgeencrypt.EncryptedData{} err = e.FromDecryptionRequest(body) assert.NilError(t, err) assert.Equal(t, channelName, e.Channel) assert.Equal(t, "1", e.KeyVersion) ec := &edgeencrypt.EncryptionClaims{ ChannelID: e.ChannelID, Channel: channelName, Role: edgeencrypt.Decryption, } assert.NilError(t, e.Valid()) decryptedData, err := edgeencrypt.DecryptData(context.Background(), e, ec, func(_ context.Context, _, _, _ string, aesKey []byte) ([]byte, error) { return rsa.DecryptOAEP(sha256.New(), rand.Reader, privateKey, aesKey, nil) }) assert.NilError(t, err) assert.Equal(t, string(data), string(decryptedData)) } func createPublicPrivateKey(t *testing.T) *rsa.PrivateKey { privateKey, err := rsa.GenerateKey(rand.Reader, edgeencrypt.RSA2048) assert.NilError(t, err) publicKey := &privateKey.PublicKey pem, err := edgeencrypt.ConvertRSAPublicKeyToPEM(publicKey) assert.NilError(t, err) ee := &edgeencrypt.PublicKey{Version: "1", PEM: pem} // public key to validate bearer token err = ee.Save(context.Background(), cl, edgeencrypt.EncryptionName, edgeencrypt.EncryptionJWTSecret) assert.NilError(t, err) // public key to encrypt data channelEncryptionSecret := fmt.Sprintf(edgeencrypt.EncryptionSecret, "my-channel") err = ee.Save(context.Background(), cl, edgeencrypt.EncryptionName, channelEncryptionSecret) assert.NilError(t, err) return privateKey }