package auth import ( "testing" ) func TestHashAPIKey(t *testing.T) { tests := []struct { name string key string expected string }{ { name: "known hash", key: "password", expected: "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8", }, { name: "another known hash", key: "test", expected: "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := HashAPIKey(tt.key) if got != tt.expected { t.Errorf("HashAPIKey() = %v, want %v", got, tt.expected) } }) } } func TestHashAPIKeyConsistency(t *testing.T) { key := "my-secret-key" hash1 := HashAPIKey(key) hash2 := HashAPIKey(key) if hash1 != hash2 { t.Errorf("HashAPIKey() not consistent: %v != %v", hash1, hash2) } if len(hash1) != 64 { t.Errorf("HashAPIKey() wrong length: got %d, want 64", len(hash1)) } } func TestGenerateAPIKey(t *testing.T) { // Test that it generates keys key1 := GenerateAPIKey() if len(key1) != 64 { t.Errorf("GenerateAPIKey() length = %d, want 64", len(key1)) } // Test uniqueness (timing-based, should be different) key2 := GenerateAPIKey() if key1 == key2 { t.Errorf("GenerateAPIKey() not unique: both generated %s", key1) } } func TestUserHasPermission(t *testing.T) { tests := []struct { name string user *User permission string want bool }{ { name: "wildcard grants all", user: &User{ Permissions: map[string]bool{"*": true}, }, permission: "anything", want: true, }, { name: "direct permission", user: &User{ Permissions: map[string]bool{"jobs:create": true}, }, permission: "jobs:create", want: true, }, { name: "hierarchical permission match", user: &User{ Permissions: map[string]bool{"jobs": true}, }, permission: "jobs:create", want: true, }, { name: "no permission", user: &User{ Permissions: map[string]bool{"jobs:read": true}, }, permission: "jobs:create", want: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := tt.user.HasPermission(tt.permission) if got != tt.want { t.Errorf("HasPermission() = %v, want %v", got, tt.want) } }) } } func TestUserHasRole(t *testing.T) { tests := []struct { name string user *User role string want bool }{ { name: "has role", user: &User{ Roles: []string{"admin", "user"}, }, role: "admin", want: true, }, { name: "does not have role", user: &User{ Roles: []string{"user"}, }, role: "admin", want: false, }, { name: "empty roles", user: &User{ Roles: []string{}, }, role: "admin", want: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := tt.user.HasRole(tt.role) if got != tt.want { t.Errorf("HasRole() = %v, want %v", got, tt.want) } }) } } func TestAuthConfigValidateAPIKey(t *testing.T) { config := &AuthConfig{ Enabled: true, APIKeys: map[Username]APIKeyEntry{ "testuser": { Hash: APIKeyHash(HashAPIKey("test-key")), Admin: false, Roles: []string{"user"}, Permissions: map[string]bool{ "jobs:read": true, }, }, "admin": { Hash: APIKeyHash(HashAPIKey("admin-key")), Admin: true, }, }, } tests := []struct { name string key string wantErr bool wantAdmin bool }{ { name: "valid user key", key: "test-key", wantErr: false, wantAdmin: false, }, { name: "valid admin key", key: "admin-key", wantErr: false, wantAdmin: true, }, { name: "invalid key", key: "wrong-key", wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { user, err := config.ValidateAPIKey(tt.key) if (err != nil) != tt.wantErr { t.Errorf("ValidateAPIKey() error = %v, wantErr %v", err, tt.wantErr) return } if !tt.wantErr && user.Admin != tt.wantAdmin { t.Errorf("ValidateAPIKey() admin = %v, want %v", user.Admin, tt.wantAdmin) } }) } } func TestAuthConfigDisabled(t *testing.T) { config := &AuthConfig{ Enabled: false, } user, err := config.ValidateAPIKey("any-key") if err != nil { t.Errorf("ValidateAPIKey() with auth disabled should not error: %v", err) } if !user.Admin { t.Error("ValidateAPIKey() with auth disabled should return admin user") } }