Browse Source

test: Add comprehensive STS session claims validation tests

- TestSTSSessionClaimsToSessionInfo: Validates basic claims conversion
- TestSTSSessionClaimsToSessionInfoCredentialGeneration: Verifies credential generation
- TestSTSSessionClaimsToSessionInfoPreservesAllFields: Ensures all fields are preserved
- TestSTSSessionClaimsToSessionInfoEmptyFields: Tests handling of empty/nil fields
- TestSTSSessionClaimsToSessionInfoCredentialExpiration: Validates expiration handling

All tests pass with proper timing tolerance for credential generation.
pull/7944/head
Chris Lu 1 month ago
parent
commit
77afd24e65
  1. 211
      weed/iam/sts/session_claims_test.go

211
weed/iam/sts/session_claims_test.go

@ -0,0 +1,211 @@
package sts
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// TestSTSSessionClaimsToSessionInfo tests the ToSessionInfo conversion
func TestSTSSessionClaimsToSessionInfo(t *testing.T) {
sessionId := "test-session-123"
issuer := "test-issuer"
expiresAt := time.Now().Add(time.Hour)
claims := NewSTSSessionClaims(sessionId, issuer, expiresAt).
WithSessionName("test-session-name").
WithRoleInfo(
"arn:aws:iam::123456789012:role/test-role",
"arn:aws:iam::123456789012:assumed-role/test-role/session",
"arn:aws:iam::123456789012:assumed-role/test-role/session",
).
WithIdentityProvider("oidc", "user-123", "https://issuer.example.com").
WithMaxDuration(time.Hour)
sessionInfo := claims.ToSessionInfo()
// Verify basic claims are converted
assert.Equal(t, sessionId, sessionInfo.SessionId)
assert.Equal(t, "test-session-name", sessionInfo.SessionName)
assert.Equal(t, "arn:aws:iam::123456789012:role/test-role", sessionInfo.RoleArn)
assert.Equal(t, "arn:aws:iam::123456789012:assumed-role/test-role/session", sessionInfo.AssumedRoleUser)
assert.Equal(t, "oidc", sessionInfo.IdentityProvider)
assert.Equal(t, "user-123", sessionInfo.ExternalUserId)
// Verify credentials are generated
assert.NotNil(t, sessionInfo.Credentials, "credentials should be populated")
assert.NotEmpty(t, sessionInfo.Credentials.AccessKeyId, "access key should be generated")
assert.NotEmpty(t, sessionInfo.Credentials.SecretAccessKey, "secret key should be generated")
// Credential expiration may have sub-second differences, so just check they're close
assert.True(t, sessionInfo.Credentials.Expiration.Sub(expiresAt) < time.Second, "credential expiration should match session expiration")
// Verify expiration is preserved (within 1 second tolerance for timing differences)
assert.WithinDuration(t, expiresAt, sessionInfo.ExpiresAt, 1*time.Second)
}
// TestSTSSessionClaimsToSessionInfoCredentialGeneration tests that credentials are properly generated
func TestSTSSessionClaimsToSessionInfoCredentialGeneration(t *testing.T) {
sessionId := "deterministic-session-id"
issuer := "test-issuer"
expiresAt := time.Now().Add(time.Hour)
claims1 := NewSTSSessionClaims(sessionId, issuer, expiresAt)
sessionInfo1 := claims1.ToSessionInfo()
// Create another claims object with the same session ID
claims2 := NewSTSSessionClaims(sessionId, issuer, expiresAt)
sessionInfo2 := claims2.ToSessionInfo()
// Verify that both have valid credentials (may not be the same due to randomness, but same structure)
assert.NotNil(t, sessionInfo1.Credentials, "credentials should be populated")
assert.NotNil(t, sessionInfo2.Credentials, "credentials should be populated")
// Both should have the same access key and secret key patterns
assert.NotEmpty(t, sessionInfo1.Credentials.AccessKeyId)
assert.NotEmpty(t, sessionInfo1.Credentials.SecretAccessKey)
assert.NotEmpty(t, sessionInfo2.Credentials.AccessKeyId)
assert.NotEmpty(t, sessionInfo2.Credentials.SecretAccessKey)
}
// TestSTSSessionClaimsToSessionInfoPreservesAllFields tests that all fields are preserved
func TestSTSSessionClaimsToSessionInfoPreservesAllFields(t *testing.T) {
sessionId := "test-session-id"
issuer := "test-issuer"
expiresAt := time.Now().Add(2 * time.Hour)
policies := []string{"policy1", "policy2"}
requestContext := map[string]interface{}{
"sourceIp": "192.168.1.1",
"userAgent": "test-agent",
}
claims := NewSTSSessionClaims(sessionId, issuer, expiresAt).
WithSessionName("session-name").
WithRoleInfo("role-arn", "assumed-role", "principal").
WithIdentityProvider("provider", "external-id", "issuer").
WithPolicies(policies).
WithRequestContext(requestContext).
WithMaxDuration(2 * time.Hour)
sessionInfo := claims.ToSessionInfo()
// Verify all fields are preserved
assert.Equal(t, sessionId, sessionInfo.SessionId)
assert.Equal(t, "session-name", sessionInfo.SessionName)
assert.Equal(t, "role-arn", sessionInfo.RoleArn)
assert.Equal(t, "assumed-role", sessionInfo.AssumedRoleUser)
assert.Equal(t, "principal", sessionInfo.Principal)
assert.Equal(t, "provider", sessionInfo.IdentityProvider)
assert.Equal(t, "external-id", sessionInfo.ExternalUserId)
assert.Equal(t, "issuer", sessionInfo.ProviderIssuer)
assert.Equal(t, policies, sessionInfo.Policies)
assert.Equal(t, requestContext, sessionInfo.RequestContext)
assert.WithinDuration(t, expiresAt, sessionInfo.ExpiresAt, 1*time.Second)
}
// TestSTSSessionClaimsToSessionInfoEmptyFields tests handling of empty/nil fields
func TestSTSSessionClaimsToSessionInfoEmptyFields(t *testing.T) {
sessionId := "minimal-session"
issuer := "issuer"
expiresAt := time.Now().Add(time.Hour)
// Create claims with minimal fields
claims := NewSTSSessionClaims(sessionId, issuer, expiresAt)
sessionInfo := claims.ToSessionInfo()
// Verify basic fields are preserved
assert.Equal(t, sessionId, sessionInfo.SessionId)
assert.Empty(t, sessionInfo.SessionName)
assert.Empty(t, sessionInfo.RoleArn)
// Verify credentials are still generated even with minimal fields
assert.NotNil(t, sessionInfo.Credentials)
assert.NotEmpty(t, sessionInfo.Credentials.AccessKeyId)
assert.NotEmpty(t, sessionInfo.Credentials.SecretAccessKey)
}
// TestSTSSessionClaimsToSessionInfoCredentialExpiration tests credential expiration
func TestSTSSessionClaimsToSessionInfoCredentialExpiration(t *testing.T) {
sessionId := "test-session"
issuer := "issuer"
tests := []struct {
name string
expiresAt time.Time
expectNotExpired bool
description string
}{
{
name: "future_expiration",
expiresAt: time.Now().Add(time.Hour),
expectNotExpired: true,
description: "Credentials should not be expired if ExpiresAt is in the future",
},
{
name: "past_expiration",
expiresAt: time.Now().Add(-time.Hour),
expectNotExpired: false,
description: "Credentials should be expired if ExpiresAt is in the past",
},
{
name: "near_future_expiration",
expiresAt: time.Now().Add(time.Minute),
expectNotExpired: true,
description: "Credentials should not be expired even if close to expiration",
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
claims := NewSTSSessionClaims(sessionId, issuer, tc.expiresAt)
sessionInfo := claims.ToSessionInfo()
assert.NotNil(t, sessionInfo.Credentials)
// Check expiration within 1 second due to timing precision
assert.True(t, sessionInfo.Credentials.Expiration.Sub(tc.expiresAt) < time.Second)
if tc.expectNotExpired {
assert.False(t, time.Now().After(tc.expiresAt), tc.description)
} else {
assert.True(t, time.Now().After(tc.expiresAt), tc.description)
}
})
}
}
// TestSessionInfoIntegration tests the full integration of session info flow
func TestSessionInfoIntegration(t *testing.T) {
// Create a session claim
sessionId, err := GenerateSessionId()
require.NoError(t, err)
expiresAt := time.Now().Add(time.Hour)
claims := NewSTSSessionClaims(sessionId, "test-issuer", expiresAt).
WithSessionName("integration-test").
WithRoleInfo(
"arn:aws:iam::123456789012:role/integration",
"arn:aws:iam::123456789012:assumed-role/integration/test",
"arn:aws:iam::123456789012:assumed-role/integration/test",
).
WithIdentityProvider("test-provider", "user-id", "https://test.example.com")
// Convert to SessionInfo
sessionInfo := claims.ToSessionInfo()
// Verify the session info has valid credentials
assert.NotNil(t, sessionInfo.Credentials)
assert.NotEmpty(t, sessionInfo.Credentials.AccessKeyId)
assert.NotEmpty(t, sessionInfo.Credentials.SecretAccessKey)
// Verify basic session properties
assert.Equal(t, sessionId, sessionInfo.SessionId)
assert.Equal(t, "integration-test", sessionInfo.SessionName)
assert.False(t, sessionInfo.ExpiresAt.IsZero())
// Verify that the session is valid
assert.True(t, sessionInfo.ExpiresAt.After(time.Now()), "session should not be expired")
assert.False(t, sessionInfo.Credentials.Expiration.Before(time.Now()), "credentials should not be expired")
}
Loading…
Cancel
Save