Class: ProjectTeam
- Inherits:
-
Object
- Object
- ProjectTeam
- Defined in:
- app/models/project_team.rb
Instance Attribute Summary collapse
-
#project ⇒ Object
Returns the value of attribute project.
Instance Method Summary collapse
- #add_developer(user, current_user: nil) ⇒ Object
- #add_guest(user, current_user: nil) ⇒ Object
- #add_maintainer(user, current_user: nil) ⇒ Object
-
#add_member(user, access_level, current_user: nil, expires_at: nil, immediately_sync_authorizations: false) ⇒ Object
NOTE:
immediately_sync_authorizationscan be expensive to run in the foreground. - #add_members(users, access_level, current_user: nil, expires_at: nil) ⇒ Object
- #add_owner(user, current_user: nil) ⇒ Object
- #add_planner(user, current_user: nil) ⇒ Object
- #add_reporter(user, current_user: nil) ⇒ Object
- #add_role(user, role, current_user: nil) ⇒ Object
- #add_security_manager(user, current_user: nil) ⇒ Object
- #contribution_check_for_user_ids(user_ids) ⇒ Object
- #contributor?(user_id) ⇒ Boolean
- #developer?(user) ⇒ Boolean
- #developers ⇒ Object
- #find_member(user_id) ⇒ Object
- #guest?(user) ⇒ Boolean
- #guests ⇒ Object
-
#has_user?(user) ⇒ Boolean
Only for direct and not invited members.
- #human_max_access(user_id) ⇒ Object
- #import(source_project, current_user) ⇒ Object
-
#initialize(project) ⇒ ProjectTeam
constructor
A new instance of ProjectTeam.
- #maintainer?(user) ⇒ Boolean
- #maintainers ⇒ Object
- #max_member_access(user_id) ⇒ Object
-
#max_member_access_for_user(user, only_concrete_membership: false) ⇒ Object
Return the highest access level for a user.
-
#max_member_access_for_user_ids(user_ids) ⇒ Object
Determine the maximum access level for a group of users in bulk.
-
#member?(user, min_access_level = Gitlab::Access::GUEST) ⇒ Boolean
Checks if
useris authorized for this project, with at least themin_access_level(if given). - #members ⇒ Object (also: #users)
- #owner?(user) ⇒ Boolean
- #owners ⇒ Object
- #planner?(user) ⇒ Boolean
- #planners ⇒ Object
- #purge_member_access_cache_for_user_id(user_id) ⇒ Object
- #reporter?(user) ⇒ Boolean
- #reporters ⇒ Object
-
#truncate ⇒ Object
Remove all users from project team.
- #write_member_access_for_user_id(user_id, project_access_level) ⇒ Object
Constructor Details
#initialize(project) ⇒ ProjectTeam
Returns a new instance of ProjectTeam.
6 7 8 |
# File 'app/models/project_team.rb', line 6 def initialize(project) @project = project end |
Instance Attribute Details
#project ⇒ Object
Returns the value of attribute project.
4 5 6 |
# File 'app/models/project_team.rb', line 4 def project @project end |
Instance Method Details
#add_developer(user, current_user: nil) ⇒ Object
28 29 30 |
# File 'app/models/project_team.rb', line 28 def add_developer(user, current_user: nil) add_member(user, :developer, current_user: current_user) end |
#add_guest(user, current_user: nil) ⇒ Object
10 11 12 |
# File 'app/models/project_team.rb', line 10 def add_guest(user, current_user: nil) add_member(user, :guest, current_user: current_user) end |
#add_maintainer(user, current_user: nil) ⇒ Object
32 33 34 |
# File 'app/models/project_team.rb', line 32 def add_maintainer(user, current_user: nil) add_member(user, :maintainer, current_user: current_user) end |
#add_member(user, access_level, current_user: nil, expires_at: nil, immediately_sync_authorizations: false) ⇒ Object
NOTE: immediately_sync_authorizations can be expensive to run in the foreground. This should only be used in rare cases where asynchronous authorization does not work (e.g. user is created and used immediately in the same request).
69 70 71 72 73 74 75 76 77 78 |
# File 'app/models/project_team.rb', line 69 def add_member(user, access_level, current_user: nil, expires_at: nil, immediately_sync_authorizations: false) Members::Projects::CreatorService.add_member( # rubocop:disable CodeReuse/ServiceClass project, user, access_level, current_user: current_user, expires_at: expires_at, immediately_sync_authorizations: ) end |
#add_members(users, access_level, current_user: nil, expires_at: nil) ⇒ Object
56 57 58 59 60 61 62 63 64 |
# File 'app/models/project_team.rb', line 56 def add_members(users, access_level, current_user: nil, expires_at: nil) Members::Projects::CreatorService.add_members( # rubocop:disable CodeReuse/ServiceClass project, users, access_level, current_user: current_user, expires_at: expires_at ) end |
#add_owner(user, current_user: nil) ⇒ Object
36 37 38 |
# File 'app/models/project_team.rb', line 36 def add_owner(user, current_user: nil) add_member(user, :owner, current_user: current_user) end |
#add_planner(user, current_user: nil) ⇒ Object
14 15 16 |
# File 'app/models/project_team.rb', line 14 def add_planner(user, current_user: nil) add_member(user, :planner, current_user: current_user) end |
#add_reporter(user, current_user: nil) ⇒ Object
18 19 20 |
# File 'app/models/project_team.rb', line 18 def add_reporter(user, current_user: nil) add_member(user, :reporter, current_user: current_user) end |
#add_role(user, role, current_user: nil) ⇒ Object
40 41 42 |
# File 'app/models/project_team.rb', line 40 def add_role(user, role, current_user: nil) public_send(:"add_#{role}", user, current_user: current_user) # rubocop:disable GitlabSecurity/PublicSend end |
#add_security_manager(user, current_user: nil) ⇒ Object
22 23 24 25 26 |
# File 'app/models/project_team.rb', line 22 def add_security_manager(user, current_user: nil) return unless Gitlab::Security::SecurityManagerConfig.enabled? add_member(user, :security_manager, current_user: current_user) end |
#contribution_check_for_user_ids(user_ids) ⇒ Object
254 255 256 257 258 259 260 261 262 263 264 265 266 |
# File 'app/models/project_team.rb', line 254 def contribution_check_for_user_ids(user_ids) Gitlab::SafeRequestLoader.execute( resource_key: "contribution_check_for_users:#{project.id}", resource_ids: user_ids, default_value: false ) do |user_ids| project.merge_requests .merged .where(author_id: user_ids, target_branch: project.default_branch.to_s) .pluck(:author_id) .product([true]).to_h end end |
#contributor?(user_id) ⇒ Boolean
268 269 270 271 272 |
# File 'app/models/project_team.rb', line 268 def contributor?(user_id) return false if max_member_access(user_id) >= Gitlab::Access::GUEST contribution_check_for_user_ids([user_id])[user_id] end |
#developer?(user) ⇒ Boolean
179 180 181 |
# File 'app/models/project_team.rb', line 179 def developer?(user) max_member_access(user.id) == Gitlab::Access::DEVELOPER end |
#developers ⇒ Object
102 103 104 |
# File 'app/models/project_team.rb', line 102 def developers @developers ||= fetch_members(Gitlab::Access::DEVELOPER) end |
#find_member(user_id) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 |
# File 'app/models/project_team.rb', line 44 def find_member(user_id) member = project.members.find_by(user_id: user_id) # If user is not in project members # we should check for group membership if group && !member member = group.members.find_by(user_id: user_id) end member end |
#guest?(user) ⇒ Boolean
167 168 169 |
# File 'app/models/project_team.rb', line 167 def guest?(user) max_member_access(user.id) == Gitlab::Access::GUEST end |
#guests ⇒ Object
90 91 92 |
# File 'app/models/project_team.rb', line 90 def guests @guests ||= fetch_members(Gitlab::Access::GUEST) end |
#has_user?(user) ⇒ Boolean
Only for direct and not invited members
196 197 198 199 200 |
# File 'app/models/project_team.rb', line 196 def has_user?(user) return false unless user project.project_members.non_invite.exists?(user: user) end |
#human_max_access(user_id) ⇒ Object
202 203 204 |
# File 'app/models/project_team.rb', line 202 def human_max_access(user_id) Gitlab::Access.human_access(max_member_access(user_id)) end |
#import(source_project, current_user) ⇒ Object
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'app/models/project_team.rb', line 125 def import(source_project, current_user) target_project = project source_members = source_members_for_import(source_project) target_user_ids = target_project.project_members.pluck_user_ids importer_access_level = max_member_access(current_user.id) source_members.reject! do |member| # Skip if user already present in team !member.invite? && target_user_ids.include?(member.user_id) end new_members = source_members.map do |member| new_member = member.dup new_member.id = nil new_member.source = target_project # So that a maintainer cannot import a member with owner access new_member.access_level = [new_member.access_level, importer_access_level].min new_member.created_by = current_user params = { access_level: new_member.access_level, member_role_id: member.member_role_id } if new_member.prevent_role_assignement?(current_user, params) new_member.errors.add(:base, _("Insufficient permissions to assign this member")) end new_member end ProjectMember.transaction do new_members.each do |member| next if member.errors.any? member.save end end new_members rescue StandardError false end |
#maintainer?(user) ⇒ Boolean
183 184 185 |
# File 'app/models/project_team.rb', line 183 def maintainer?(user) max_member_access(user.id) == Gitlab::Access::MAINTAINER end |
#maintainers ⇒ Object
106 107 108 |
# File 'app/models/project_team.rb', line 106 def maintainers @maintainers ||= fetch_members(Gitlab::Access::MAINTAINER) end |
#max_member_access(user_id) ⇒ Object
230 231 232 |
# File 'app/models/project_team.rb', line 230 def max_member_access(user_id) max_member_access_for_user_ids([user_id])[user_id] end |
#max_member_access_for_user(user, only_concrete_membership: false) ⇒ Object
Return the highest access level for a user
A special case is handled here when the user is a GitLab admin which implies it has “OWNER” access everywhere, but should not officially appear as a member of a project unless specifically added to it
242 243 244 245 246 247 248 249 250 251 252 |
# File 'app/models/project_team.rb', line 242 def max_member_access_for_user(user, only_concrete_membership: false) return ProjectMember::NO_ACCESS unless user return ProjectMember::OWNER if project.owner == user unless only_concrete_membership return ProjectMember::OWNER if user.can_admin_all_resources? return ProjectMember::OWNER if user.can_admin_organization?(project.organization) end max_member_access(user.id) end |
#max_member_access_for_user_ids(user_ids) ⇒ Object
Determine the maximum access level for a group of users in bulk.
Returns a Hash mapping user ID -> maximum access level.
209 210 211 212 213 214 215 216 217 218 219 220 |
# File 'app/models/project_team.rb', line 209 def max_member_access_for_user_ids(user_ids) Gitlab::SafeRequestLoader.execute( resource_key: project.max_member_access_for_resource_key(User), resource_ids: user_ids, default_value: Gitlab::Access::NO_ACCESS ) do |user_ids| project. .where(user: user_ids) .group(:user_id) .maximum(:access_level) end end |
#member?(user, min_access_level = Gitlab::Access::GUEST) ⇒ Boolean
Checks if user is authorized for this project, with at least the min_access_level (if given).
189 190 191 192 193 |
# File 'app/models/project_team.rb', line 189 def member?(user, min_access_level = Gitlab::Access::GUEST) return false unless user max_member_access(user.id) >= min_access_level end |
#members ⇒ Object Also known as: users
85 86 87 |
# File 'app/models/project_team.rb', line 85 def members @members ||= fetch_members end |
#owner?(user) ⇒ Boolean
121 122 123 |
# File 'app/models/project_team.rb', line 121 def owner?(user) owners.include?(user) end |
#owners ⇒ Object
110 111 112 113 114 115 116 117 118 119 |
# File 'app/models/project_team.rb', line 110 def owners @owners ||= if group group.owners.allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/432606") else # workaround until we migrate Project#owners to have membership with # OWNER access level Array.wrap(fetch_members(Gitlab::Access::OWNER)) | Array.wrap(project.owner) end end |
#planner?(user) ⇒ Boolean
171 172 173 |
# File 'app/models/project_team.rb', line 171 def planner?(user) max_member_access(user.id) == Gitlab::Access::PLANNER end |
#planners ⇒ Object
94 95 96 |
# File 'app/models/project_team.rb', line 94 def planners @planners ||= fetch_members(Gitlab::Access::PLANNER) end |
#purge_member_access_cache_for_user_id(user_id) ⇒ Object
226 227 228 |
# File 'app/models/project_team.rb', line 226 def purge_member_access_cache_for_user_id(user_id) project.purge_resource_id_from_request_store(User, user_id) end |
#reporter?(user) ⇒ Boolean
175 176 177 |
# File 'app/models/project_team.rb', line 175 def reporter?(user) max_member_access(user.id) == Gitlab::Access::REPORTER end |
#reporters ⇒ Object
98 99 100 |
# File 'app/models/project_team.rb', line 98 def reporters @reporters ||= fetch_members(Gitlab::Access::REPORTER) end |
#truncate ⇒ Object
Remove all users from project team
81 82 83 |
# File 'app/models/project_team.rb', line 81 def truncate ProjectMember.truncate_team(project) end |
#write_member_access_for_user_id(user_id, project_access_level) ⇒ Object
222 223 224 |
# File 'app/models/project_team.rb', line 222 def write_member_access_for_user_id(user_id, project_access_level) project.merge_value_to_request_store(User, user_id, project_access_level) end |