(ctx context.Context, req *adminv1.SetOrganizationMemberUserRoleRequest)
| 595 | } |
| 596 | |
| 597 | func (s *Server) SetOrganizationMemberUserRole(ctx context.Context, req *adminv1.SetOrganizationMemberUserRoleRequest) (*adminv1.SetOrganizationMemberUserRoleResponse, error) { |
| 598 | observability.AddRequestAttributes(ctx, |
| 599 | attribute.String("args.org", req.Org), |
| 600 | attribute.String("args.email", req.Email), |
| 601 | attribute.String("args.role", req.Role), |
| 602 | ) |
| 603 | |
| 604 | org, err := s.admin.DB.FindOrganizationByName(ctx, req.Org) |
| 605 | if err != nil { |
| 606 | return nil, err |
| 607 | } |
| 608 | |
| 609 | claims := auth.GetClaims(ctx) |
| 610 | forceAccess := claims.Superuser(ctx) && req.SuperuserForceAccess |
| 611 | if !claims.OrganizationPermissions(ctx, org.ID).ManageOrgMembers && !forceAccess { |
| 612 | return nil, status.Error(codes.PermissionDenied, "not allowed to set org members role") |
| 613 | } |
| 614 | |
| 615 | role, err := s.admin.DB.FindOrganizationRole(ctx, req.Role) |
| 616 | if err != nil { |
| 617 | return nil, err |
| 618 | } |
| 619 | if role.Admin && !claims.OrganizationPermissions(ctx, org.ID).ManageOrgAdmins && !forceAccess { |
| 620 | return nil, status.Error(codes.PermissionDenied, "as a non-admin you are not allowed to assign an admin role") |
| 621 | } |
| 622 | |
| 623 | user, err := s.admin.DB.FindUserByEmail(ctx, req.Email) |
| 624 | if err != nil { |
| 625 | if !errors.Is(err, database.ErrNotFound) { |
| 626 | return nil, err |
| 627 | } |
| 628 | // Check if there is a pending invite for this user |
| 629 | invite, err := s.admin.DB.FindOrganizationInvite(ctx, org.ID, req.Email) |
| 630 | if err != nil { |
| 631 | return nil, err |
| 632 | } |
| 633 | err = s.admin.DB.UpdateOrganizationInviteRole(ctx, invite.ID, role.ID) |
| 634 | if err != nil { |
| 635 | return nil, err |
| 636 | } |
| 637 | return &adminv1.SetOrganizationMemberUserRoleResponse{}, nil |
| 638 | } |
| 639 | |
| 640 | // Check admin status edge cases |
| 641 | isAdmin, isLastAdmin, err := s.admin.DB.FindOrganizationMemberUserAdminStatus(ctx, org.ID, user.ID) |
| 642 | if err != nil { |
| 643 | return nil, err |
| 644 | } |
| 645 | if isAdmin && !claims.OrganizationPermissions(ctx, org.ID).ManageOrgAdmins && !forceAccess { |
| 646 | return nil, status.Error(codes.PermissionDenied, "as a non-admin you are not allowed to remove an admin member") |
| 647 | } |
| 648 | if isLastAdmin { |
| 649 | return nil, status.Error(codes.FailedPrecondition, "cannot remove the last admin member") |
| 650 | } |
| 651 | |
| 652 | err = s.admin.UpdateOrganizationMemberUserRole(ctx, org.ID, user.ID, role.ID) |
| 653 | if err != nil { |
| 654 | return nil, err |
nothing calls this directly
no test coverage detected