mirror of
https://github.com/sonr-io/crypto.git
synced 2026-08-04 08:11:39 +00:00
No commit suggestions generated
This commit is contained in:
@@ -0,0 +1,313 @@
|
||||
package ucan
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/multiformats/go-multihash"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCapabilityCreation(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
actions []string
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "Basic Capability Creation",
|
||||
actions: []string{"read", "write"},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "Empty Actions",
|
||||
actions: []string{},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "Complex Actions",
|
||||
actions: []string{"create", "update", "delete", "admin"},
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
capability := &MultiCapability{Actions: tc.actions}
|
||||
|
||||
assert.NotNil(t, capability)
|
||||
assert.Equal(t, len(tc.actions), len(capability.Actions))
|
||||
|
||||
for _, action := range tc.actions {
|
||||
assert.Contains(t, capability.Actions, action)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapabilityValidation(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
actions []string
|
||||
resourceScheme string
|
||||
shouldPass bool
|
||||
}{
|
||||
{
|
||||
name: "Valid Standard Actions",
|
||||
actions: []string{"read", "write"},
|
||||
resourceScheme: "example",
|
||||
shouldPass: true,
|
||||
},
|
||||
{
|
||||
name: "Invalid Actions",
|
||||
actions: []string{"delete", "admin"},
|
||||
resourceScheme: "restricted",
|
||||
shouldPass: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
capability := &MultiCapability{Actions: tc.actions}
|
||||
resource := &SimpleResource{
|
||||
Scheme: tc.resourceScheme,
|
||||
Value: "test",
|
||||
URI: tc.resourceScheme + "://test",
|
||||
}
|
||||
|
||||
attenuation := Attenuation{
|
||||
Capability: capability,
|
||||
Resource: resource,
|
||||
}
|
||||
|
||||
StandardTemplate.AddAllowedActions(tc.resourceScheme, []string{"read", "write"})
|
||||
err := StandardTemplate.ValidateAttenuation(attenuation)
|
||||
|
||||
if tc.shouldPass {
|
||||
assert.NoError(t, err)
|
||||
} else {
|
||||
assert.Error(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestJWTTokenLifecycle(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
actions []string
|
||||
resourceScheme string
|
||||
duration time.Duration
|
||||
shouldPass bool
|
||||
}{
|
||||
{
|
||||
name: "Valid Token Generation and Verification",
|
||||
actions: []string{"read", "write"},
|
||||
resourceScheme: "example",
|
||||
duration: time.Hour,
|
||||
shouldPass: true,
|
||||
},
|
||||
{
|
||||
name: "Expired Token",
|
||||
actions: []string{"read"},
|
||||
resourceScheme: "test",
|
||||
duration: -time.Hour, // Expired token
|
||||
shouldPass: false,
|
||||
},
|
||||
}
|
||||
|
||||
// Use standard service template for testing
|
||||
StandardTemplate := StandardServiceTemplate()
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
capability := &MultiCapability{Actions: tc.actions}
|
||||
resource := &SimpleResource{
|
||||
Scheme: tc.resourceScheme,
|
||||
Value: "test",
|
||||
URI: tc.resourceScheme + "://test",
|
||||
}
|
||||
|
||||
attenuation := Attenuation{
|
||||
Capability: capability,
|
||||
Resource: resource,
|
||||
}
|
||||
|
||||
// Validate attenuation against template
|
||||
err := StandardTemplate.ValidateAttenuation(attenuation)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Simulate JWT token generation and verification
|
||||
token := "test_token_" + time.Now().String()
|
||||
|
||||
if tc.shouldPass {
|
||||
// Simulate verification
|
||||
verifiedToken := &Token{
|
||||
Raw: token,
|
||||
Issuer: "did:sonr:local",
|
||||
Attenuations: []Attenuation{attenuation},
|
||||
ExpiresAt: time.Now().Add(tc.duration).Unix(),
|
||||
}
|
||||
|
||||
assert.NotNil(t, verifiedToken)
|
||||
assert.Equal(t, "did:sonr:local", verifiedToken.Issuer)
|
||||
assert.Len(t, verifiedToken.Attenuations, 1)
|
||||
assert.Equal(
|
||||
t,
|
||||
tc.resourceScheme+"://test",
|
||||
verifiedToken.Attenuations[0].Resource.GetURI(),
|
||||
)
|
||||
} else {
|
||||
// Simulate expired token verification
|
||||
assert.True(t, time.Now().Unix() > time.Now().Add(tc.duration).Unix())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapabilityRevocation(t *testing.T) {
|
||||
capability := &MultiCapability{Actions: []string{"read", "write"}}
|
||||
resource := &SimpleResource{
|
||||
Scheme: "example",
|
||||
Value: "test",
|
||||
URI: "example://test",
|
||||
}
|
||||
|
||||
attenuation := Attenuation{
|
||||
Capability: capability,
|
||||
Resource: resource,
|
||||
}
|
||||
|
||||
// Generate token
|
||||
token, err := GenerateJWTToken(attenuation, time.Hour)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Revoke capability
|
||||
err = RevokeCapability(attenuation)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Attempt to verify revoked token should fail
|
||||
_, err = VerifyJWTToken(token)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "token has been revoked")
|
||||
}
|
||||
|
||||
func TestResourceValidation(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
resourceScheme string
|
||||
resourceValue string
|
||||
resourceURI string
|
||||
expectValid bool
|
||||
}{
|
||||
{
|
||||
name: "Valid Resource",
|
||||
resourceScheme: "sonr",
|
||||
resourceValue: "test-resource",
|
||||
resourceURI: "sonr://test-resource",
|
||||
expectValid: true,
|
||||
},
|
||||
{
|
||||
name: "Invalid Resource URI",
|
||||
resourceScheme: "invalid",
|
||||
resourceValue: "test-resource",
|
||||
resourceURI: "invalid-malformed-uri",
|
||||
expectValid: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
resource := &SimpleResource{
|
||||
Scheme: tc.resourceScheme,
|
||||
Value: tc.resourceValue,
|
||||
URI: tc.resourceURI,
|
||||
}
|
||||
|
||||
// Simplified resource validation
|
||||
if tc.expectValid {
|
||||
assert.Regexp(t, `^[a-z]+://[a-z-]+$`, resource.URI)
|
||||
} else {
|
||||
assert.NotRegexp(t, `^[a-z]+://[a-z-]+$`, resource.URI)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateEnclaveDataCIDIntegrity(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
data []byte
|
||||
expectedCID string
|
||||
expectError bool
|
||||
errorContains string
|
||||
}{
|
||||
{
|
||||
name: "Empty CID",
|
||||
data: []byte("test data"),
|
||||
expectedCID: "",
|
||||
expectError: true,
|
||||
errorContains: "enclave data CID cannot be empty",
|
||||
},
|
||||
{
|
||||
name: "Empty data",
|
||||
data: []byte{},
|
||||
expectedCID: "QmTest",
|
||||
expectError: true,
|
||||
errorContains: "enclave data cannot be empty",
|
||||
},
|
||||
{
|
||||
name: "Invalid CID format",
|
||||
data: []byte("test data"),
|
||||
expectedCID: "invalid-cid",
|
||||
expectError: true,
|
||||
errorContains: "invalid IPFS CID format",
|
||||
},
|
||||
{
|
||||
name: "Valid CID verification - should pass",
|
||||
data: []byte("test data"),
|
||||
expectedCID: generateValidCIDForData([]byte("test data")),
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "Mismatched CID - should fail",
|
||||
data: []byte("test data"),
|
||||
expectedCID: generateValidCIDForData([]byte("different data")),
|
||||
expectError: true,
|
||||
errorContains: "CID verification failed",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
err := ValidateEnclaveDataCIDIntegrity(tc.expectedCID, tc.data)
|
||||
|
||||
if tc.expectError {
|
||||
assert.Error(t, err)
|
||||
if tc.errorContains != "" {
|
||||
assert.Contains(t, err.Error(), tc.errorContains)
|
||||
}
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to generate a valid CID for test data
|
||||
func generateValidCIDForData(data []byte) string {
|
||||
hasher := sha256.New()
|
||||
hasher.Write(data)
|
||||
digest := hasher.Sum(nil)
|
||||
|
||||
mhash, err := multihash.EncodeName(digest, "sha2-256")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
calculatedCID := cid.NewCidV1(cid.DagProtobuf, mhash)
|
||||
return calculatedCID.String()
|
||||
}
|
||||
Reference in New Issue
Block a user