customRoleCheck will validate a custom role for inserting or updating. If the role is not valid, an error will be returned. - Check custom roles are valid for their resource types + actions - Check the actor can create the custom role - Check the custom role does not grant perms the actor does not h
(ctx context.Context, role database.CustomRole, action policy.Action)
| 1431 | // - Prevent negative perms for non-system roles |
| 1432 | // - Prevent roles that have both organization scoped and non-organization scoped permissions |
| 1433 | func (q *querier) customRoleCheck(ctx context.Context, role database.CustomRole, action policy.Action) error { |
| 1434 | act, ok := ActorFromContext(ctx) |
| 1435 | if !ok { |
| 1436 | return ErrNoActor |
| 1437 | } |
| 1438 | |
| 1439 | // Org and org member permissions require an org role. |
| 1440 | if role.OrganizationID.UUID == uuid.Nil && (len(role.OrgPermissions) > 0 || len(role.MemberPermissions) > 0) { |
| 1441 | return xerrors.Errorf("organization and member permissions require specifying an organization id") |
| 1442 | } |
| 1443 | |
| 1444 | // Org roles can only specify org permissions; system roles can also specify orgMember ones. |
| 1445 | if role.OrganizationID.UUID != uuid.Nil && (len(role.SitePermissions) > 0 || len(role.UserPermissions) > 0) { |
| 1446 | return xerrors.Errorf("organization roles specify site or user permissions") |
| 1447 | } |
| 1448 | |
| 1449 | // For now only system roles can specify orgMember permissions. |
| 1450 | if !role.IsSystem && len(role.MemberPermissions) > 0 { |
| 1451 | return xerrors.Errorf("non-system roles specify member permissions") |
| 1452 | } |
| 1453 | |
| 1454 | // The rbac.Role has a 'Valid()' function on it that will do a lot |
| 1455 | // of checks. |
| 1456 | rbacRole, err := rolestore.ConvertDBRole(database.CustomRole{ |
| 1457 | Name: role.Name, |
| 1458 | DisplayName: role.DisplayName, |
| 1459 | SitePermissions: role.SitePermissions, |
| 1460 | OrgPermissions: role.OrgPermissions, |
| 1461 | UserPermissions: role.UserPermissions, |
| 1462 | MemberPermissions: role.MemberPermissions, |
| 1463 | OrganizationID: role.OrganizationID, |
| 1464 | }) |
| 1465 | if err != nil { |
| 1466 | return xerrors.Errorf("invalid args: %w", err) |
| 1467 | } |
| 1468 | |
| 1469 | err = rbacRole.Valid() |
| 1470 | if err != nil { |
| 1471 | return xerrors.Errorf("invalid role: %w", err) |
| 1472 | } |
| 1473 | |
| 1474 | if len(rbacRole.ByOrgID) > 0 && (len(rbacRole.Site) > 0 || len(rbacRole.User) > 0) { |
| 1475 | // This is a choice to keep roles simple. If we allow mixing site and org |
| 1476 | // scoped perms, then knowing who can do what gets more complicated. Roles |
| 1477 | // should either be entirely org-scoped or entirely unrelated to |
| 1478 | // organizations. |
| 1479 | return xerrors.Errorf("invalid custom role, cannot assign both org-scoped and site/user permissions at the same time") |
| 1480 | } |
| 1481 | |
| 1482 | if len(rbacRole.ByOrgID) > 1 { |
| 1483 | // Again to avoid more complexity in our roles. Roles are limited to one |
| 1484 | // organization. |
| 1485 | return xerrors.Errorf("invalid custom role, cannot assign permissions to more than 1 org at a time") |
| 1486 | } |
| 1487 | |
| 1488 | // System roles are managed internally and may include permissions |
| 1489 | // (including negative ones) that user-facing custom role APIs |
| 1490 | // should reject. Still validate that the role shape and perms |
no test coverage detected