Skip to content

Commit

Permalink
fix: handle project default groups with multiple project members
Browse files Browse the repository at this point in the history
Only the project with a name matching the project default group will
have a role created.
  • Loading branch information
smlx committed Jan 17, 2025
1 parent 1bafcf9 commit 66187bf
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 12 deletions.
28 changes: 19 additions & 9 deletions internal/sync/roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,31 +73,40 @@ func isLagoonGroup(
// ID of the group's project.
func projectGroupRoleName(
group keycloak.Group,
projectNames map[int]string,
groupProjectsMap map[string][]int,
) (string, error) {
projectIDs, ok := groupProjectsMap[group.ID]
if !ok {
return "", fmt.Errorf("missing project group ID %s in groupProjectsMap",
group.ID)
}
if len(projectIDs) != 1 {
return "", fmt.Errorf("too many projects in group ID %s: %d", group.ID,
len(projectIDs))
if len(projectIDs) == 0 {
return "", fmt.Errorf("missing project IDs in project group ID %s", group.ID)
}
if projectIDs[0] < 0 {
return "", fmt.Errorf("invalid project ID in group ID %s: %d", group.ID,
projectIDs[0])
for _, pid := range projectIDs {
if pid < 0 {
return "", fmt.Errorf("invalid project ID in group ID %s: %d", group.ID, pid)
}
if strings.TrimPrefix(group.Name, "project-") == projectNames[pid] {
return fmt.Sprintf("p%d", pid), nil
}
}
return fmt.Sprintf("p%d", projectIDs[0]), nil
return "", fmt.Errorf(
"couldn't match project group ID %s to any member project IDs: %v",
group.ID,
projectIDs,
)
}

// generateProjectGroupRole constructs an opensearch.Role from the given
// keycloak group corresponding to a Lagoon project group.
func generateProjectGroupRole(
group keycloak.Group,
projectNames map[int]string,
groupProjectsMap map[string][]int,
) (string, *opensearch.Role, error) {
name, err := projectGroupRoleName(group, groupProjectsMap)
name, err := projectGroupRoleName(group, projectNames, groupProjectsMap)
if err != nil {
return "", nil,
fmt.Errorf("couldn't generate project group role name: %v", err)
Expand Down Expand Up @@ -200,7 +209,8 @@ func generateRoles(
var err error
for _, group := range groups {
if isProjectGroup(log, group) {
name, role, err = generateProjectGroupRole(group, groupProjectsMap)
name, role, err =
generateProjectGroupRole(group, projectNames, groupProjectsMap)
if err != nil {
log.Warn("couldn't generate role for project group",
zap.String("group name", group.Name), zap.Error(err))
Expand Down
6 changes: 4 additions & 2 deletions internal/sync/rolesmapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,14 @@ func calculateRoleMappingDiff(
func generateRolesMapping(
log *zap.Logger,
groups []keycloak.Group,
projectNames map[int]string,
groupProjectsMap map[string][]int,
) map[string]opensearch.RoleMapping {
rolesmapping := map[string]opensearch.RoleMapping{}
for _, group := range groups {
// figure out if this is a regular group or project group
if isProjectGroup(log, group) {
name, err := projectGroupRoleName(group, groupProjectsMap)
name, err := projectGroupRoleName(group, projectNames, groupProjectsMap)
if err != nil {
log.Warn("couldn't generate project group role name", zap.Error(err),
zap.String("group name", group.Name))
Expand Down Expand Up @@ -123,6 +124,7 @@ func syncRolesMapping(
ctx context.Context,
log *zap.Logger,
groups []keycloak.Group,
projectNames map[int]string,
roles map[string]opensearch.Role,
groupProjectsMap map[string][]int,
o OpensearchService,
Expand All @@ -137,7 +139,7 @@ func syncRolesMapping(
// ignore non-lagoon rolesmapping
existing = filterRolesMapping(existing, roles)
// generate the rolesmapping required by Lagoon
required := generateRolesMapping(log, groups, groupProjectsMap)
required := generateRolesMapping(log, groups, projectNames, groupProjectsMap)
// calculate rolesmapping to add/remove
toCreate, toDelete := calculateRoleMappingDiff(existing, required)
for _, name := range toDelete {
Expand Down
2 changes: 1 addition & 1 deletion internal/sync/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func Sync(ctx context.Context, log *zap.Logger, l LagoonDBService,
case "roles":
syncRoles(ctx, log, groups, projectNames, roles, groupProjectsMap, o, dryRun)
case "rolesmapping":
syncRolesMapping(ctx, log, groups, roles, groupProjectsMap, o, dryRun)
syncRolesMapping(ctx, log, groups, projectNames, roles, groupProjectsMap, o, dryRun)
case "indexpatterns":
syncIndexPatterns(ctx, log, groupsSansGlobal, projectNames, groupProjectsMap,
o, d, dryRun, legacyIndexPatternDelimiter)
Expand Down

0 comments on commit 66187bf

Please sign in to comment.