canAssignRoles handles assigning built in and custom roles.
(ctx context.Context, orgID uuid.UUID, added, removed []rbac.RoleIdentifier)
| 1217 | |
| 1218 | // canAssignRoles handles assigning built in and custom roles. |
| 1219 | func (q *querier) canAssignRoles(ctx context.Context, orgID uuid.UUID, added, removed []rbac.RoleIdentifier) error { |
| 1220 | actor, ok := ActorFromContext(ctx) |
| 1221 | if !ok { |
| 1222 | return ErrNoActor |
| 1223 | } |
| 1224 | |
| 1225 | roleAssign := rbac.ResourceAssignRole |
| 1226 | shouldBeOrgRoles := false |
| 1227 | if orgID != uuid.Nil { |
| 1228 | roleAssign = rbac.ResourceAssignOrgRole.InOrg(orgID) |
| 1229 | shouldBeOrgRoles = true |
| 1230 | } |
| 1231 | |
| 1232 | grantedRoles := make([]rbac.RoleIdentifier, 0, len(added)+len(removed)) |
| 1233 | grantedRoles = append(grantedRoles, added...) |
| 1234 | grantedRoles = append(grantedRoles, removed...) |
| 1235 | customRoles := make([]rbac.RoleIdentifier, 0) |
| 1236 | // Validate that the roles being assigned are valid. |
| 1237 | for _, r := range grantedRoles { |
| 1238 | isOrgRole := r.OrganizationID != uuid.Nil |
| 1239 | if shouldBeOrgRoles && !isOrgRole { |
| 1240 | return xerrors.Errorf("Must only update org roles") |
| 1241 | } |
| 1242 | |
| 1243 | if !shouldBeOrgRoles && isOrgRole { |
| 1244 | return xerrors.Errorf("Must only update site wide roles") |
| 1245 | } |
| 1246 | |
| 1247 | if shouldBeOrgRoles { |
| 1248 | if orgID == uuid.Nil { |
| 1249 | return xerrors.Errorf("should never happen, orgID is nil, but trying to assign an organization role") |
| 1250 | } |
| 1251 | |
| 1252 | if r.OrganizationID != orgID { |
| 1253 | return xerrors.Errorf("attempted to assign role from a different org, role %q to %q", r, orgID.String()) |
| 1254 | } |
| 1255 | } |
| 1256 | |
| 1257 | // All roles should be valid roles |
| 1258 | if _, err := rbac.RoleByName(r); err != nil { |
| 1259 | customRoles = append(customRoles, r) |
| 1260 | } |
| 1261 | } |
| 1262 | |
| 1263 | customRolesMap := make(map[rbac.RoleIdentifier]struct{}, len(customRoles)) |
| 1264 | for _, r := range customRoles { |
| 1265 | customRolesMap[r] = struct{}{} |
| 1266 | } |
| 1267 | |
| 1268 | if len(customRoles) > 0 { |
| 1269 | // Leverage any custom role cache that might exist. |
| 1270 | expandedCustomRoles, err := rolestore.Expand(ctx, q.db, customRoles) |
| 1271 | if err != nil { |
| 1272 | return xerrors.Errorf("fetching custom roles: %w", err) |
| 1273 | } |
| 1274 | |
| 1275 | // If the lists are not identical, then have a problem, as some roles |
| 1276 | // provided do no exist. |
no test coverage detected