fixed authorization (now checks the role inside of the project)
This commit is contained in:
+45
-5
@@ -87,15 +87,24 @@ func AuthorizeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
claimRoles := collectClaimRoles(claims)
|
||||
projectRoleCount := 0
|
||||
for _, project := range claims.Projects {
|
||||
projectRoleCount += len(project.RoleID)
|
||||
log.Printf("[Handler] Project role claim - project_id=%d, alias=%s, roles=%v", project.ProjectID, project.Alias, project.RoleID)
|
||||
}
|
||||
log.Printf("[Handler] Claim roles parsed - base=%v, additional=%v, projects=%d, projectRoleEntries=%d, combined=%v",
|
||||
claims.RoleID,
|
||||
claims.AdditionalRoleID,
|
||||
len(claims.Projects),
|
||||
projectRoleCount,
|
||||
claimRoles,
|
||||
)
|
||||
if len(claimRoles) == 0 {
|
||||
log.Printf("ERROR: No roles found in JWT claims for user=%s", claims.UsersID)
|
||||
}
|
||||
requestedRoles := collectRequestedRoles(&ctx)
|
||||
if len(requestedRoles) == 0 {
|
||||
requestedRoles = claimRoles
|
||||
}
|
||||
|
||||
validRoles := intersectRoles(requestedRoles, claimRoles)
|
||||
validRoles := buildRoleCandidates(requestedRoles, claimRoles)
|
||||
log.Printf("[Handler] Role candidate resolution - requested=%v, finalCandidates=%v", requestedRoles, validRoles)
|
||||
if len(validRoles) == 0 {
|
||||
log.Printf("ERROR: Role mismatch for user=%s - requestedRoles=%v, claimRoles=%v", ctx.UsersID, requestedRoles, claimRoles)
|
||||
helper.RespondWithError(w, http.StatusForbidden, "Role ID mismatch")
|
||||
@@ -197,3 +206,34 @@ func intersectRoles(requested, available []int) []int {
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func buildRoleCandidates(requested, claimRoles []int) []int {
|
||||
if len(claimRoles) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(requested) == 0 {
|
||||
return append([]int(nil), claimRoles...)
|
||||
}
|
||||
|
||||
primary := intersectRoles(requested, claimRoles)
|
||||
if len(primary) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
seen := make(map[int]struct{}, len(primary))
|
||||
for _, role := range primary {
|
||||
seen[role] = struct{}{}
|
||||
}
|
||||
|
||||
result := append([]int(nil), primary...)
|
||||
for _, role := range claimRoles {
|
||||
if _, exists := seen[role]; exists {
|
||||
continue
|
||||
}
|
||||
seen[role] = struct{}{}
|
||||
result = append(result, role)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -440,3 +440,27 @@ func TestCollectClaimRolesIncludesAdditionalRoles(t *testing.T) {
|
||||
t.Fatalf("unexpected role order/content: %v", roles)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildRoleCandidates_PrioritizesRequestedThenFallsBackToClaims(t *testing.T) {
|
||||
requested := []int{30}
|
||||
claimRoles := []int{30, 44, 52}
|
||||
|
||||
result := buildRoleCandidates(requested, claimRoles)
|
||||
if len(result) != 3 {
|
||||
t.Fatalf("expected 3 candidate roles, got %d (%v)", len(result), result)
|
||||
}
|
||||
|
||||
if result[0] != 30 || result[1] != 44 || result[2] != 52 {
|
||||
t.Fatalf("unexpected candidate role order/content: %v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildRoleCandidates_ReturnsNilWhenRequestedNotInClaims(t *testing.T) {
|
||||
requested := []int{999}
|
||||
claimRoles := []int{30, 44}
|
||||
|
||||
result := buildRoleCandidates(requested, claimRoles)
|
||||
if len(result) != 0 {
|
||||
t.Fatalf("expected no candidates for mismatched requested role, got %v", result)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user