Files
bridge/internal/service/users.go
2023-07-13 23:38:02 +00:00

131 lines
2.8 KiB
Go

package service
import (
"context"
"go.infratographer.com/x/gidx"
)
func (s *service) IsUser(id gidx.PrefixedID) bool {
if idType, ok := s.idPrefixMap[id.Prefix()]; ok {
return idType == TypeUser
}
return false
}
func (s *service) IsAssignableResource(id gidx.PrefixedID) bool {
if idType, ok := s.idPrefixMap[id.Prefix()]; ok {
switch idType {
case TypeOrganization, TypeProject:
return true
default:
return false
}
}
return false
}
func (s *service) AssignUser(ctx context.Context, userID gidx.PrefixedID, resourceIDs ...gidx.PrefixedID) error {
var memberships []ResourceMemberships
for _, resourceID := range resourceIDs {
role, err := s.getUserResourceRole(ctx, userID, resourceID)
if err != nil {
s.logger.Warnw("failed to determine role for user resource", "error", err)
continue
}
if role == "" {
continue
}
memberships = append(memberships, ResourceMemberships{
Resource: prefixedID{resourceID},
Role: role,
Member: prefixedID{userID},
})
}
s.syncMemberships(ctx, memberships)
s.logger.Infow("assignment sync complete", "memberships", len(memberships))
return nil
}
func (s *service) UnassignUser(ctx context.Context, userID gidx.PrefixedID, resourceIDs ...gidx.PrefixedID) error {
for _, resourceID := range resourceIDs {
rlogger := s.logger.With("user.id", userID, "resource.id", resourceID)
role, err := s.getUserResourceRole(ctx, userID, resourceID)
if err != nil {
rlogger.Warnw("failed to determine role for user resource", "error", err)
continue
}
if role == "" {
continue
}
actions := s.roles[role]
rlogger = rlogger.With("role.name", role, "role.actions", actions)
resourceRole, err := s.perms.FindResourceRoleByActions(ctx, resourceID, actions)
if err != nil {
rlogger.Warnw("failed to find role by actions for resource", "error", err)
continue
}
rlogger = rlogger.With("role.id", resourceRole.ID)
assigned, err := s.perms.RoleHasAssignment(ctx, resourceRole.ID, userID)
if err != nil {
rlogger.Warnw("failed to check role assignment", "error", err)
continue
}
if !assigned {
rlogger.Warnw("unable to unassign member which is not assigned")
continue
}
if err = s.perms.UnassignRole(ctx, resourceRole.ID, userID); err != nil {
rlogger.Errorw("failed to unassign member from role", "error", err)
continue
}
}
return nil
}
func (s *service) getUserResourceRole(ctx context.Context, userID, resourceID gidx.PrefixedID) (string, error) {
var (
role string
err error
)
if idType, ok := s.idPrefixMap[resourceID.Prefix()]; ok {
switch idType {
case TypeOrganization:
role, err = s.metal.GetUserOrganizationRole(ctx, userID, resourceID)
case TypeProject:
role, err = s.metal.GetUserProjectRole(ctx, userID, resourceID)
}
}
if err != nil {
return "", err
}
return role, nil
}