Skip to content

Owner can manage project owners via UI

charlie ablett requested to merge 21432-cablett-grant-project-owner-role into master

What does this MR do and why?

Allow users that are existing OWNERs:

  • to upgrade an existing member to OWNER in the project
  • to downgrade an existing OWNER to any other access level in the project
  • to remove an existing OWNER from the project

In other MRs:

  • to select OWNER when inviting a new member to the project 👉 !89209 (merged)
  • to invite a group to the project with OWNER access level 👉 !89209 (merged)
  • to create a project access token with OWNER access level 👉 !89114 (merged)
  • ensure both maintainers and owners receive access request notifications 👉 !90018 (merged)
  • update the project team owners method to include direct project owners 👉 !92871 (closed)
  • update owned_by? method to make its usage clear 👉 !90365 (closed)

Any other users with a different access level other than OWNER in the project, should not be able to perform these actions, ie, a MAINTAINER in a project:

  • cannot select OWNER access level when inviting a new member to the project. The maximum access level shown in the access level dropdown should be MAINTAINER
  • cannot upgrade an existing member to OWNER in the project. Upgrade should be allowed only till MAINTAINER access level.
  • cannot downgrade an existing OWNER to any other access level in the project. Edits should be disabled in the UI.
  • cannot remove an existing OWNER from the project. Remove member button should not appear.
  • cannot invite a group to the project with OWNER access level. The maximum access level shown in the access level dropdown should be MAINTAINER
  • cannot create a project access token with OWNER access level. The maximum access level shown in the access level dropdown should be MAINTAINER

Also covered in #368349 (closed)

Testing locally - status on master (before change):

  1. Invite new member (only up to Maintainer)

image

  1. View memberships (only up to Maintainer)

image

Testing locally - status on this branch (after change):

Part 1: make someone else an Owner of a group project

  1. View members page under Project Information under any project under either a group OR a personal project. For the example below we'll use a group project.

  2. View an existing user, and notice the dropdown now includes Owner

image

  1. Add an existing user with Owner status using the form via username (via email presumably works too, I didn't try it)

image

image

  1. See new member has Owner status, and original owner also is owner!

image

  1. Notes also include the badge annotation

image

Part 2: Verify Owner permissions

  1. Create some issue under the project.

  2. As an Admin, visit the user's profile in the Admin view

Owner access shown next to the project 👍

image

  1. Impersonate them.

image

  1. See the Delete button, only available to Owners!

image

  1. In console, you can verify that your User can now do things:
> p = Project.find <ID of the project>
> u = User.find <ID of the new Owner user>
> i = Project.issues.last
> Ability.allowed?(u, :delete_issue, i)
#=> true
policy debugger output
[4] pry(main)> ip = IssuePolicy.new(u, i)
=> #<IssuePolicy (@tomasa.hegmann : Issue/498)>
[5] pry(main)> ip.debug(:destroy_issue)
- [0] prevent when all?(anonymous, ~public_project) ((@tomasa.hegmann : Project/35))
- [14] prevent when all?(archived, ~pending_delete) ((@tomasa.hegmann : Project/35))
- [21] prevent when all?(confidential, ~can_read_confidential) ((@tomasa.hegmann : Issue/498))
  ProjectFeature Load (11.5ms)  SELECT "project_features".* FROM "project_features" WHERE "project_features"."project_id" = 35 LIMIT 1 /*application:console,db_config_name:main,line:/home/charlie/.rbenv/gems/2.7.0/gems/marginalia-1.10.0/lib/marginalia/comment.rb:25:in `block in construct_comment'*/
- [28] prevent when issues_disabled ((@tomasa.hegmann : Project/35))
- [28] prevent when all?(~public_project, ~internal_access, ~project_allowed_for_job_token) ((@tomasa.hegmann : Project/35))
+ [58] enable when can?(:owner_access) ((@tomasa.hegmann : Project/35))
=> #<DeclarativePolicy::Runner::State:0x0000558f005d1260
 @called_conditions=
  #<Set: {"/dp/condition/DeclarativePolicy::Base/anonymous/User:9",
   "/dp/condition/ProjectPolicy/archived/Project:35",
   "/dp/condition/IssuePolicy/confidential/Issue:498",
   "/dp/condition/ProjectPolicy/issues_disabled/User:9,Project:35",
   "/dp/condition/ProjectPolicy/public_project/Project:35",
   "/dp/condition/BasePolicy/admin/User:9",
   "/dp/condition/BasePolicy/auditor/User:9",
   "/dp/condition/ProjectPolicy/needs_new_sso_session/User:9,Project:35",
   "/dp/condition/ProjectPolicy/owner/User:9,Project:35",
   "/dp/condition/BasePolicy/visual_review_bot/User:9",
   "/dp/condition/BasePolicy/security_bot/User:9",
   "/dp/condition/BasePolicy/alert_bot/User:9",
   "/dp/condition/BasePolicy/support_bot/User:9",
   "/dp/condition/BasePolicy/external_authorization_enabled",
   "/dp/condition/DeclarativePolicy::Base/default"}>,
 @enabled=true,
 @prevented=false>

Part 3: Do something now permissable

  1. Delete an issue impersonating that person, which is possible as an Owner but not a Maintainer in a group project

image

  1. success! issue gone! 🚀

image

Part 4: Misc

  1. External users can be owners and have a badge

image

  1. Adding another owner to a personal project does NOT give them the ability to remove the namespace's user as a member via the UI nor the REST API

image

(on my local @tomasa.hegmann has user id 9, and their personal project id is 18, of which @user1 is also an owner)

$ curl --request DELETE --header "PRIVATE-TOKEN: glpat-user1-token" "https://gdk.test:3443/api/v4/projects/18/members/9"
{"message":"403 Forbidden"}
  1. Deleting the project! Can they do that?

  2. As a MAINTAINER there is no Remove button beside the OWNER direct users, nor is the dropdown to edit their role enabled.

image

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #21432 (closed)

Edited by charlie ablett

Merge request reports