Class: Member
- Inherits:
-
ApplicationRecord
show all
- Includes:
- AfterCommitQueue, CreatedAtFilterable, EachBatch, Expirable, FromUnion, Gitlab::Access, Gitlab::Utils::StrongMemoize, Importable, Presentable, Sortable, UpdateHighestRole
- Defined in:
- app/models/member.rb
Constant Summary
UpdateHighestRole::HIGHEST_ROLE_JOB_DELAY, UpdateHighestRole::HIGHEST_ROLE_LEASE_TIMEOUT
Gitlab::Access::AccessDeniedError, Gitlab::Access::DEVELOPER, Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS, Gitlab::Access::GUEST, Gitlab::Access::MAINTAINER, Gitlab::Access::MAINTAINER_PROJECT_ACCESS, Gitlab::Access::MAINTAINER_SUBGROUP_ACCESS, Gitlab::Access::MINIMAL_ACCESS, Gitlab::Access::NO_ACCESS, Gitlab::Access::NO_ONE_PROJECT_ACCESS, Gitlab::Access::OWNER, Gitlab::Access::OWNER_SUBGROUP_ACCESS, Gitlab::Access::PROTECTION_DEV_CAN_MERGE, Gitlab::Access::PROTECTION_DEV_CAN_PUSH, Gitlab::Access::PROTECTION_FULL, Gitlab::Access::PROTECTION_NONE, Gitlab::Access::REPORTER
Constants included
from Expirable
Expirable::DAYS_TO_EXPIRE
Instance Attribute Summary collapse
Attributes included from Importable
#imported, #importing
Class Method Summary
collapse
-
.access_for_user_ids(user_ids) ⇒ Object
-
.access_levels ⇒ Object
-
.add_user(source, user, access_level, existing_members: nil, current_user: nil, expires_at: nil, ldap: false) ⇒ Object
-
.add_users(source, users, access_level, current_user: nil, expires_at: nil) ⇒ Object
-
.filter_by_2fa(value) ⇒ Object
-
.find_by_invite_token(raw_invite_token) ⇒ Object
-
.left_join_users ⇒ Object
-
.search(query) ⇒ Object
-
.search_invite_email(query) ⇒ Object
-
.set_member_attributes(member, access_level, current_user: nil, expires_at: nil, ldap: false) ⇒ Object
Populates the attributes of a member.
-
.sort_by_attribute(method) ⇒ Object
Instance Method Summary
collapse
#clear_memoization, #strong_memoize, #strong_memoized?
#present
all_values, human_access, #human_access, #human_access_with_none, human_access_with_none, options, options_with_none, options_with_owner, #owner?, project_creation_level_name, project_creation_options, project_creation_string_options, project_creation_string_values, project_creation_values, protection_options, protection_values, subgroup_creation_options, subgroup_creation_string_options, subgroup_creation_string_values, subgroup_creation_values, sym_options, sym_options_with_owner
Methods included from Expirable
#expired?, #expires?, #expires_soon?
#run_after_commit, #run_after_commit_or_now
at_most, id_in, id_not_in, iid_in, pluck_primary_key, primary_key_in, safe_ensure_unique, safe_find_or_create_by, safe_find_or_create_by!, underscore, where_exists, with_fast_statement_timeout, without_order
Instance Attribute Details
#raw_invite_token ⇒ Object
Returns the value of attribute raw_invite_token
16
17
18
|
# File 'app/models/member.rb', line 16
def raw_invite_token
@raw_invite_token
end
|
Class Method Details
.access_for_user_ids(user_ids) ⇒ Object
170
171
172
|
# File 'app/models/member.rb', line 170
def access_for_user_ids(user_ids)
where(user_id: user_ids).has_access.pluck(:user_id, :access_level).to_h
end
|
.add_user(source, user, access_level, existing_members: nil, current_user: nil, expires_at: nil, ldap: false) ⇒ Object
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
|
# File 'app/models/member.rb', line 179
def add_user(source, user, access_level, existing_members: nil, current_user: nil, expires_at: nil, ldap: false)
member = retrieve_member(source, user, existing_members)
access_level = retrieve_access_level(access_level)
return member unless can_update_member?(current_user, member)
set_member_attributes(
member,
access_level,
current_user: current_user,
expires_at: expires_at,
ldap: ldap
)
if member.request?
::Members::ApproveAccessRequestService.new(
current_user,
access_level: access_level
).execute(
member,
skip_authorization: ldap,
skip_log_audit_event: ldap
)
else
member.save
end
member
end
|
.add_users(source, users, access_level, current_user: nil, expires_at: nil) ⇒ Object
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
|
# File 'app/models/member.rb', line 224
def add_users(source, users, access_level, current_user: nil, expires_at: nil)
return [] unless users.present?
emails, users, existing_members = parse_users_list(source, users)
self.transaction do
(emails + users).map! do |user|
add_user(
source,
user,
access_level,
existing_members: existing_members,
current_user: current_user,
expires_at: expires_at
)
end
end
end
|
.filter_by_2fa(value) ⇒ Object
135
136
137
138
139
140
141
142
143
144
|
# File 'app/models/member.rb', line 135
def filter_by_2fa(value)
case value
when 'enabled'
left_join_users.merge(User.with_two_factor)
when 'disabled'
left_join_users.merge(User.without_two_factor)
else
all
end
end
|
.find_by_invite_token(raw_invite_token) ⇒ Object
174
175
176
177
|
# File 'app/models/member.rb', line 174
def find_by_invite_token(raw_invite_token)
invite_token = Devise.token_generator.digest(self, :invite_token, raw_invite_token)
find_by(invite_token: invite_token)
end
|
.left_join_users ⇒ Object
159
160
161
162
163
164
165
166
167
168
|
# File 'app/models/member.rb', line 159
def left_join_users
users = User.arel_table
members = Member.arel_table
member_users = members.join(users, Arel::Nodes::OuterJoin)
.on(members[:user_id].eq(users[:id]))
.join_sources
joins(member_users)
end
|
.search(query) ⇒ Object
127
128
129
|
# File 'app/models/member.rb', line 127
def search(query)
joins(:user).merge(User.search(query))
end
|
.search_invite_email(query) ⇒ Object
131
132
133
|
# File 'app/models/member.rb', line 131
def search_invite_email(query)
invite.where(['invite_email ILIKE ?', "%#{query}%"])
end
|
.set_member_attributes(member, access_level, current_user: nil, expires_at: nil, ldap: false) ⇒ Object
Populates the attributes of a member.
This logic resides in a separate method so that EE can extend this logic, without having to patch the `add_user` method directly.
216
217
218
219
220
221
222
|
# File 'app/models/member.rb', line 216
def set_member_attributes(member, access_level, current_user: nil, expires_at: nil, ldap: false)
member.attributes = {
created_by: member.created_by || current_user,
access_level: access_level,
expires_at: expires_at
}
end
|
.sort_by_attribute(method) ⇒ Object
146
147
148
149
150
151
152
153
154
155
156
157
|
# File 'app/models/member.rb', line 146
def sort_by_attribute(method)
case method.to_s
when 'access_level_asc' then reorder(access_level: :asc)
when 'access_level_desc' then reorder(access_level: :desc)
when 'recent_sign_in' then order_recent_sign_in
when 'oldest_sign_in' then order_oldest_sign_in
when 'last_joined' then order_created_desc
when 'oldest_joined' then order_created_asc
else
order_by(method)
end
end
|
Instance Method Details
#accept_invite!(new_user) ⇒ Object
337
338
339
340
341
342
343
344
345
346
347
348
349
350
|
# File 'app/models/member.rb', line 337
def accept_invite!(new_user)
return false unless invite?
self.invite_token = nil
self.invite_accepted_at = Time.current.utc
self.user = new_user
saved = self.save
after_accept_invite if saved
saved
end
|
#accept_request ⇒ Object
328
329
330
331
332
333
334
335
|
# File 'app/models/member.rb', line 328
def accept_request
return false unless request?
updated = self.update(requested_at: nil)
after_accept_request if updated
updated
end
|
#access_field ⇒ Object
312
313
314
|
# File 'app/models/member.rb', line 312
def access_field
access_level
end
|
#create_notification_setting ⇒ Object
388
389
390
|
# File 'app/models/member.rb', line 388
def create_notification_setting
user.notification_settings.find_or_create_for(source)
end
|
#created_by_name ⇒ Object
422
423
424
|
# File 'app/models/member.rb', line 422
def created_by_name
created_by&.name
end
|
#decline_invite! ⇒ Object
352
353
354
355
356
357
358
359
360
|
# File 'app/models/member.rb', line 352
def decline_invite!
return false unless invite?
destroyed = self.destroy
after_decline_invite if destroyed
destroyed
end
|
#destroy_notification_setting ⇒ Object
392
393
394
|
# File 'app/models/member.rb', line 392
def destroy_notification_setting
notification_setting&.destroy
end
|
#generate_invite_token ⇒ Object
362
363
364
365
366
|
# File 'app/models/member.rb', line 362
def generate_invite_token
raw, enc = Devise.token_generator.generate(self.class, :invite_token)
@raw_invite_token = raw
self.invite_token = enc
end
|
#generate_invite_token! ⇒ Object
368
369
370
|
# File 'app/models/member.rb', line 368
def generate_invite_token!
generate_invite_token && save(validate: false)
end
|
#highest_group_member ⇒ Object
Find the user's group member with a highest access level
410
411
412
413
414
415
416
|
# File 'app/models/member.rb', line 410
def highest_group_member
strong_memoize(:highest_group_member) do
next unless user_id && source&.ancestors&.any?
GroupMember.where(source: source.ancestors, user_id: user_id).order(:access_level).last
end
end
|
#invite? ⇒ Boolean
316
317
318
|
# File 'app/models/member.rb', line 316
def invite?
self.invite_token.present?
end
|
#invite_to_unknown_user? ⇒ Boolean
418
419
420
|
# File 'app/models/member.rb', line 418
def invite_to_unknown_user?
invite? && user_id.nil?
end
|
#notifiable?(type, opts = {}) ⇒ Boolean
rubocop: disable CodeReuse/ServiceClass
#notification_setting ⇒ Object
396
397
398
|
# File 'app/models/member.rb', line 396
def notification_setting
@notification_setting ||= user&.notification_settings_for(source)
end
|
#pending? ⇒ Boolean
324
325
326
|
# File 'app/models/member.rb', line 324
def pending?
invite? || request?
end
|
#real_source_type ⇒ Object
308
309
310
|
# File 'app/models/member.rb', line 308
def real_source_type
source_type
end
|
#request? ⇒ Boolean
320
321
322
|
# File 'app/models/member.rb', line 320
def request?
requested_at.present?
end
|
#resend_invite ⇒ Object
372
373
374
375
376
377
378
|
# File 'app/models/member.rb', line 372
def resend_invite
return unless invite?
generate_invite_token! unless @raw_invite_token
send_invite
end
|
#send_invitation_reminder(reminder_index) ⇒ Object
380
381
382
383
384
385
386
|
# File 'app/models/member.rb', line 380
def send_invitation_reminder(reminder_index)
return unless invite?
generate_invite_token! unless @raw_invite_token
run_after_commit_or_now { notification_service.invite_member_reminder(self, @raw_invite_token, reminder_index) }
end
|