fixed authorization (now checks the role inside of the project)

This commit is contained in:
2026-03-02 13:46:14 +08:00
parent e32a4a2779
commit 8ca995d490
6 changed files with 253 additions and 16 deletions
+45 -5
View File
@@ -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
}
+24
View File
@@ -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)
}
}