mirror of
https://github.com/ultravioletrs/cocos.git
synced 2026-06-23 04:10:25 +00:00
8eb1fac9ad
* Refactor and update dependencies in the project - Updated go.sum to replace `github.com/absmach/magistrala` with `github.com/absmach/supermq` across various modules. - Removed VSock configuration from environment variables and QEMU arguments. - Updated QEMU configuration and related tests to remove references to guest CID and VSock. - Added new HTTP transport layer for API endpoints in the manager. - Introduced Prometheus monitoring configuration with alert rules and Alertmanager setup. - Updated service and VM interfaces to remove unused methods and references. - Refactored tests to align with the new structure and dependencies. Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add MaxVMs configuration and enforce limit on VM creation Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add comprehensive tests for HTTP transport handlers and endpoints Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Add test case for exceeding maximum number of VMs in TestRun Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Improve error handling in TestHandlerWithCustomRouter to ensure response writing is checked Signed-off-by: Sammy Oina <sammyoina@gmail.com> * Update dependencies to latest versions - Upgrade cel.dev/expr from v0.23.0 to v0.24.0 - Upgrade github.com/absmach/supermq from v0.16.0 to v0.17.0 - Upgrade github.com/cenkalti/backoff from v4.3.0 to v5.0.2 - Upgrade github.com/cncf/xds/go to v0.0.0-20250501225837-2ac532fd4443 - Upgrade github.com/go-chi/chi/v5 from v5.2.1 to v5.2.2 - Upgrade github.com/go-jose/go-jose/v3 from v3.0.3 to v3.0.4 - Upgrade github.com/gofrs/uuid/v5 from v5.3.0 to v5.3.2 - Upgrade github.com/prometheus/client_golang from v1.22.0 to v1.23.0 - Upgrade github.com/prometheus/client_model from v0.6.1 to v0.6.2 - Upgrade github.com/prometheus/common from v0.62.0 to v0.65.0 - Upgrade github.com/prometheus/procfs from v0.15.1 to v0.16.1 - Upgrade go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp from v0.60.0 to v0.62.0 - Upgrade go.opentelemetry.io/otel/exporters/otlp/otlptrace from v1.36.0 to v1.37.0 - Upgrade golang.org/x/crypto from v0.39.0 to v0.40.0 - Upgrade golang.org/x/sys from v0.33.0 to v0.34.0 - Upgrade golang.org/x/text from v0.26.0 to v0.27.0 - Upgrade golang.org/x/time from v0.11.0 to v0.12.0 - Upgrade google.golang.org/grpc from v1.73.0 to v1.74.2 Signed-off-by: Sammy Oina <sammyoina@gmail.com> --------- Signed-off-by: Sammy Oina <sammyoina@gmail.com>
159 lines
4.0 KiB
Go
159 lines
4.0 KiB
Go
// Copyright (c) Ultraviolet
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
package auth
|
|
|
|
import (
|
|
"context"
|
|
"crypto"
|
|
"crypto/ecdsa"
|
|
"crypto/ed25519"
|
|
"crypto/elliptic"
|
|
"crypto/rand"
|
|
"crypto/rsa"
|
|
"crypto/sha256"
|
|
"crypto/x509"
|
|
"encoding/base64"
|
|
"testing"
|
|
|
|
"github.com/absmach/supermq/pkg/errors"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/ultravioletrs/cocos/agent"
|
|
"google.golang.org/grpc/metadata"
|
|
)
|
|
|
|
func TestAuthenticateUser(t *testing.T) {
|
|
resultConsumerKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
require.NoError(t, err)
|
|
|
|
dataProviderKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
|
require.NoError(t, err)
|
|
|
|
pubEd25519Key, algorithmProviderKey, err := ed25519.GenerateKey(rand.Reader)
|
|
require.NoError(t, err)
|
|
|
|
resultConsumerPubKey, err := x509.MarshalPKIXPublicKey(&resultConsumerKey.PublicKey)
|
|
require.NoError(t, err)
|
|
|
|
dataProviderPubKey, err := x509.MarshalPKIXPublicKey(&dataProviderKey.PublicKey)
|
|
require.NoError(t, err)
|
|
|
|
algorithmProviderPubKey, err := x509.MarshalPKIXPublicKey(pubEd25519Key)
|
|
require.NoError(t, err)
|
|
|
|
manifest := agent.Computation{
|
|
ResultConsumers: []agent.ResultConsumer{{UserKey: resultConsumerPubKey}},
|
|
Datasets: []agent.Dataset{{UserKey: dataProviderPubKey}},
|
|
Algorithm: agent.Algorithm{UserKey: algorithmProviderPubKey},
|
|
}
|
|
|
|
auth, err := New(manifest)
|
|
if err != nil {
|
|
t.Fatalf("failed to create authenticator: %v", err)
|
|
}
|
|
|
|
testCases := []struct {
|
|
name string
|
|
role UserRole
|
|
key any
|
|
expectedErr error
|
|
}{
|
|
{
|
|
name: "valid result consumer",
|
|
role: ConsumerRole,
|
|
key: resultConsumerKey,
|
|
expectedErr: nil,
|
|
},
|
|
{
|
|
name: "valid data provider",
|
|
role: DataProviderRole,
|
|
key: dataProviderKey,
|
|
expectedErr: nil,
|
|
},
|
|
{
|
|
name: "valid algorithm provider",
|
|
role: AlgorithmProviderRole,
|
|
key: algorithmProviderKey,
|
|
expectedErr: nil,
|
|
},
|
|
{
|
|
name: "invalid role",
|
|
role: "invalid-role",
|
|
key: resultConsumerKey,
|
|
expectedErr: ErrSignatureVerificationFailed,
|
|
},
|
|
{
|
|
name: "invalid key",
|
|
role: ConsumerRole,
|
|
key: dataProviderKey,
|
|
expectedErr: ErrSignatureVerificationFailed,
|
|
},
|
|
{
|
|
name: "missing signature",
|
|
role: ConsumerRole,
|
|
key: resultConsumerKey,
|
|
expectedErr: ErrInvalidMetadata,
|
|
},
|
|
{
|
|
name: "missing metadata",
|
|
role: ConsumerRole,
|
|
key: resultConsumerKey,
|
|
expectedErr: ErrMissingMetadata,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
signature, err := signRole(tc.role, tc.key)
|
|
if err != nil {
|
|
t.Fatalf("failed to sign role: %v", err)
|
|
}
|
|
|
|
ctx := context.Background()
|
|
|
|
switch tc.name {
|
|
case "missing signature":
|
|
ctx = metadata.NewIncomingContext(ctx, metadata.Pairs())
|
|
case "missing metadata":
|
|
default:
|
|
ctx = metadata.NewIncomingContext(ctx, metadata.Pairs(SignatureMetadataKey, signature))
|
|
}
|
|
|
|
ctx, err = auth.AuthenticateUser(ctx, tc.role)
|
|
assert.True(t, errors.Contains(err, tc.expectedErr), "expected error %v, got %v", tc.expectedErr, err)
|
|
|
|
if err == nil {
|
|
switch id, ok := agent.IndexFromContext(ctx); {
|
|
case tc.role == ConsumerRole:
|
|
assert.True(t, ok, "expected index in context")
|
|
assert.Equal(t, 0, id, "expected index 0 in context")
|
|
default:
|
|
assert.False(t, ok, "expected no index in context")
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func signRole(role UserRole, key crypto.PrivateKey) (string, error) {
|
|
var signature []byte
|
|
var err error
|
|
|
|
switch k := key.(type) {
|
|
case ed25519.PrivateKey:
|
|
signature, err = k.Sign(rand.Reader, []byte(role), crypto.Hash(0))
|
|
case *rsa.PrivateKey, *ecdsa.PrivateKey:
|
|
hash := sha256.Sum256([]byte(role))
|
|
signer := key.(crypto.Signer)
|
|
signature, err = signer.Sign(rand.Reader, hash[:], crypto.SHA256)
|
|
default:
|
|
return "", errors.New("unsupported key type")
|
|
}
|
|
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return base64.StdEncoding.EncodeToString(signature), nil
|
|
}
|