138 lines
3.9 KiB
Go
138 lines
3.9 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
|
|
"go.infratographer.com/x/events"
|
|
"go.infratographer.com/x/gidx"
|
|
)
|
|
|
|
func (s *service) processRelationships(ctx context.Context, subjectType string, relationships []Relationship) {
|
|
var err error
|
|
|
|
for _, rel := range relationships {
|
|
err = s.publisher.PublishChange(ctx, subjectType, events.ChangeMessage{
|
|
SubjectID: rel.Resource.PrefixedID(),
|
|
EventType: string(events.CreateChangeType),
|
|
AdditionalSubjectIDs: []gidx.PrefixedID{
|
|
rel.RelatedResource.PrefixedID(),
|
|
},
|
|
})
|
|
|
|
if err != nil {
|
|
s.logger.Errorw("error publishing change",
|
|
"subject_type", subjectType,
|
|
"resource.id", rel.Resource.PrefixedID(),
|
|
"related_resource.id", rel.RelatedResource.PrefixedID(),
|
|
"error", err,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (s *service) processMemberships(ctx context.Context, memberships []ResourceMemberships) {
|
|
resourceRoleID := make(map[gidx.PrefixedID]map[string]gidx.PrefixedID)
|
|
resourceRoleMembers := make(map[gidx.PrefixedID]map[string]map[gidx.PrefixedID]bool)
|
|
roleActions := make(map[string][]string)
|
|
|
|
for _, membership := range memberships {
|
|
resourceID := membership.Resource.PrefixedID()
|
|
role := membership.Role
|
|
memberID := membership.Member.PrefixedID()
|
|
|
|
if _, ok := resourceRoleMembers[resourceID]; !ok {
|
|
resourceRoleID[resourceID] = make(map[string]gidx.PrefixedID)
|
|
resourceRoleMembers[resourceID] = make(map[string]map[gidx.PrefixedID]bool)
|
|
}
|
|
|
|
if _, ok := resourceRoleMembers[resourceID][role]; !ok {
|
|
resourceRoleMembers[resourceID][role] = make(map[gidx.PrefixedID]bool)
|
|
roleActions[role] = s.roles[role]
|
|
}
|
|
|
|
resourceRoleMembers[resourceID][role][memberID] = true
|
|
}
|
|
|
|
resourceRoleAssignments := make(map[gidx.PrefixedID]map[gidx.PrefixedID]map[gidx.PrefixedID]bool)
|
|
|
|
for resourceID, roles := range resourceRoleID {
|
|
resourceRoleAssignments[resourceID] = make(map[gidx.PrefixedID]map[gidx.PrefixedID]bool)
|
|
|
|
for role := range roles {
|
|
actions := roleActions[role]
|
|
|
|
resourceRole, err := s.perms.FindResourceRoleByActions(ctx, resourceID, actions)
|
|
if err != nil {
|
|
s.logger.Warnw("failed to find role by actions for resource", "resource.id", resourceID, "role", role, "actions", actions, "error", err)
|
|
|
|
continue
|
|
}
|
|
|
|
resourceRoleID[resourceID][role] = resourceRole.ID
|
|
resourceRoleAssignments[resourceID][resourceRole.ID] = make(map[gidx.PrefixedID]bool)
|
|
|
|
assignments, err := s.perms.ListRoleAssignments(ctx, resourceRole.ID)
|
|
if err != nil {
|
|
s.logger.Warnw("failed to get role assignments for resource", "resource.id", resourceID, "role", role, "error", err)
|
|
|
|
continue
|
|
}
|
|
|
|
for _, assignment := range assignments {
|
|
resourceRoleAssignments[resourceID][resourceRole.ID][assignment] = true
|
|
}
|
|
}
|
|
}
|
|
|
|
for resourceID, roles := range resourceRoleMembers {
|
|
for role, members := range roles {
|
|
roleID := resourceRoleID[resourceID][role]
|
|
actions := roleActions[role]
|
|
|
|
logger := s.logger.With("resource.id", resourceID, "role.name", role, "actions", actions)
|
|
|
|
var createdRole bool
|
|
|
|
if roleID == gidx.NullPrefixedID {
|
|
logger.Infow("creating role for resource")
|
|
|
|
resourceRoleID, err := s.perms.CreateRole(ctx, resourceID, actions)
|
|
if err != nil {
|
|
logger.Errorw("failed to create role for resource", "error", err)
|
|
|
|
continue
|
|
}
|
|
|
|
createdRole = true
|
|
roleID = resourceRoleID
|
|
}
|
|
|
|
logger = logger.With("role.id", roleID)
|
|
|
|
assignments := make(map[gidx.PrefixedID]bool)
|
|
|
|
if !createdRole {
|
|
assignments = resourceRoleAssignments[resourceID][roleID]
|
|
}
|
|
|
|
for memberID := range members {
|
|
mlogger := logger.With("member.id", memberID)
|
|
|
|
if _, ok := assignments[memberID]; ok {
|
|
mlogger.Infow("skipping already assigned member")
|
|
|
|
continue
|
|
}
|
|
|
|
if err := s.perms.AssignRole(ctx, roleID, memberID); err != nil {
|
|
mlogger.Errorw("failed to assign member to role", "error", err)
|
|
|
|
continue
|
|
}
|
|
|
|
mlogger.Infow("role assigned to member")
|
|
}
|
|
}
|
|
}
|
|
}
|