Class: Member
- Inherits:
-
ApplicationRecord
show all
- Extended by:
- Gitlab::Utils::Override
- Includes:
- AfterCommitQueue, Ci::PipelineScheduleOwnershipValidator, CreatedAtFilterable, EachBatch, Expirable, FromUnion, Gitlab::Access, Gitlab::Experiment::Dsl, Gitlab::Utils::StrongMemoize, Importable, Presentable, RestrictedSignup, Sortable, UpdateHighestRole
- Defined in:
- app/models/member.rb
Constant Summary
collapse
- AVATAR_SIZE =
40
- ACCESS_REQUEST_APPROVERS_TO_BE_NOTIFIED_LIMIT =
10
- STATE_ACTIVE =
0
- STATE_AWAITING =
1
UpdateHighestRole::HIGHEST_ROLE_JOB_DELAY, UpdateHighestRole::HIGHEST_ROLE_LEASE_TIMEOUT
Gitlab::Access::ADMIN, Gitlab::Access::ADMINISTRATOR_PROJECT_ACCESS, Gitlab::Access::AccessDeniedError, Gitlab::Access::DEVELOPER, Gitlab::Access::DEVELOPER_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_PROJECT_ACCESS, Gitlab::Access::OWNER_SUBGROUP_ACCESS, Gitlab::Access::PLANNER, Gitlab::Access::PROTECTION_DEV_CAN_INITIAL_PUSH, Gitlab::Access::PROTECTION_DEV_CAN_MERGE, Gitlab::Access::PROTECTION_DEV_CAN_PUSH, Gitlab::Access::PROTECTION_FULL, Gitlab::Access::PROTECTION_NONE, Gitlab::Access::REPORTER, Gitlab::Access::SECURITY_MANAGER
Constants included
from Expirable
Expirable::DAYS_TO_EXPIRE
ApplicationRecord::MAX_PLUCK
HasCheckConstraints::NOT_NULL_CHECK_PATTERN
ResetOnColumnErrors::MAX_RESET_PERIOD
Instance Attribute Summary collapse
Attributes included from Importable
#importing, #user_contributions
Class Method Summary
collapse
Instance Method Summary
collapse
extended, extensions, included, method_added, override, prepended, queue_verification, verify!
#notify_and_disable_all_pipeline_schedules_for_user
#present
all_keys, all_values, global_protection_levels, #human_access, human_access, #human_access_labeled, human_access_with_none, #human_access_with_none, level_encompasses?, option_descriptions, 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, #role_description, role_description, subgroup_creation_options, subgroup_creation_string_options, subgroup_creation_string_values, subgroup_creation_values, sym_options, sym_options_with_admin, sym_options_with_owner
Methods included from Expirable
#expired?, #expires?, #expires_soon?
#run_after_commit, #run_after_commit_or_now
===, cached_column_list, #create_or_load_association, current_transaction, declarative_enum, default_select_columns, delete_all_returning, #deleted_from_database?, id_in, id_not_in, iid_in, nullable_column?, primary_key_in, #readable_by?, safe_ensure_unique, safe_find_or_create_by, safe_find_or_create_by!, #to_ability_name, underscore, where_exists, where_not_exists, with_fast_read_statement_timeout, without_order
#sharding_organization
#reset_on_union_error, #reset_on_unknown_attribute_error
#serializable_hash
Instance Attribute Details
#raw_invite_token ⇒ Object
Returns the value of attribute raw_invite_token.
28
29
30
|
# File 'app/models/member.rb', line 28
def raw_invite_token
@raw_invite_token
end
|
Class Method Details
.access_for_user_ids(user_ids) ⇒ Object
455
456
457
|
# File 'app/models/member.rb', line 455
def access_for_user_ids(user_ids)
with_user(user_ids).has_access.pluck(:user_id, :access_level).to_h
end
|
.coerce_to_no_access ⇒ Object
472
473
474
|
# File 'app/models/member.rb', line 472
def coerce_to_no_access
select(member_columns_with_no_access)
end
|
.filter_by_2fa(value) ⇒ Object
416
417
418
419
420
421
422
423
424
425
|
# File 'app/models/member.rb', line 416
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
|
.filter_by_user_type(value) ⇒ Object
427
428
429
430
431
|
# File 'app/models/member.rb', line 427
def filter_by_user_type(value)
return unless ::User.user_types.key?(value)
left_join_users.merge(::User.where(user_type: value))
end
|
.find_by_invite_token(raw_invite_token) ⇒ Object
459
460
461
462
|
# File 'app/models/member.rb', line 459
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
450
451
452
453
|
# File 'app/models/member.rb', line 450
def left_join_users
left_outer_joins(:user)
.allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/417456")
end
|
.null_member_role_id_sql ⇒ Object
484
485
486
|
# File 'app/models/member.rb', line 484
def null_member_role_id_sql
Arel::Nodes::As.new(Arel::Nodes::SqlLiteral.new('NULL'), Arel::Nodes::SqlLiteral.new('member_role_id'))
end
|
.pluck_user_ids ⇒ Object
468
469
470
|
# File 'app/models/member.rb', line 468
def pluck_user_ids
pluck(:user_id)
end
|
.search(query) ⇒ Object
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
|
# File 'app/models/member.rb', line 390
def search(query)
scope = joins(:user)
.merge(User.search(query, use_minimum_char_limit: false))
.allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/417456")
return scope unless Gitlab::Pagination::Keyset::Order.keyset_aware?(scope)
order = Gitlab::Pagination::Keyset::Order.(scope)
order.apply_cursor_conditions(scope).reorder(order)
end
|
.search_invite_email(query) ⇒ Object
412
413
414
|
# File 'app/models/member.rb', line 412
def search_invite_email(query)
invite.where(['invite_email ILIKE ?', "%#{query}%"])
end
|
.seat_assignable?(user:, namespace: nil) ⇒ Boolean
89
90
91
|
# File 'app/models/member.rb', line 89
def self.seat_assignable?(user:, namespace: nil)
seat_assignable(users: user, namespace: namespace).exists?
end
|
.seat_assignable_highest_access_level(user:, namespace: nil) ⇒ Object
93
94
95
|
# File 'app/models/member.rb', line 93
def self.seat_assignable_highest_access_level(user:, namespace: nil)
seat_assignable(users: user, namespace: namespace).maximum(:access_level)
end
|
.seat_assignable_highest_access_levels(users:, namespace: nil) ⇒ Object
97
98
99
|
# File 'app/models/member.rb', line 97
def self.seat_assignable_highest_access_levels(users:, namespace: nil)
seat_assignable(users: users, namespace: namespace).group(:user_id).maximum(:access_level)
end
|
.shared_members(group) ⇒ Object
476
477
478
479
480
481
482
|
# File 'app/models/member.rb', line 476
def shared_members(group)
columns = member_columns_for_shared_members(group)
joins("JOIN group_group_links ON members.source_id = group_group_links.shared_with_group_id")
.select(columns)
.where(group_group_links: { shared_group_id: group.self_and_ancestors })
end
|
.sort_by_attribute(method) ⇒ Object
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
|
# File 'app/models/member.rb', line 433
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 'recent_created_user' then order_recent_created_user
when 'oldest_created_user' then order_oldest_created_user
when 'recent_last_activity' then order_recent_last_activity
when 'oldest_last_activity' then order_oldest_last_activity
when 'last_joined' then order_created_desc
when 'oldest_joined' then order_created_asc
else
order_by(method)
end
end
|
.valid_email?(email) ⇒ Boolean
464
465
466
|
# File 'app/models/member.rb', line 464
def valid_email?(email)
Devise.email_regexp.match?(email)
end
|
Instance Method Details
#accept_invite!(new_user) ⇒ Object
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
|
# File 'app/models/member.rb', line 559
def accept_invite!(new_user)
return false unless invite?
return false unless new_user
self.user = new_user
return false unless self.user.save
self.invite_token = nil
self.invite_accepted_at = Time.current.utc
saved = self.save
after_accept_invite if saved
saved
end
|
#accept_request(current_user) ⇒ Object
550
551
552
553
554
555
556
557
|
# File 'app/models/member.rb', line 550
def accept_request(current_user)
return false unless request?
updated = self.update(requested_at: nil, created_by: current_user, request_accepted_at: Time.current.utc)
after_accept_request if updated
updated
end
|
#access_field ⇒ Object
528
529
530
|
# File 'app/models/member.rb', line 528
def access_field
access_level
end
|
#create_notification_setting ⇒ Object
614
615
616
|
# File 'app/models/member.rb', line 614
def create_notification_setting
user.notification_settings.find_or_create_for(source)
end
|
#created_by_name ⇒ Object
651
652
653
|
# File 'app/models/member.rb', line 651
def created_by_name
created_by&.name
end
|
#decline_invite! ⇒ Object
576
577
578
579
580
581
582
583
584
|
# File 'app/models/member.rb', line 576
def decline_invite!
return false unless invite?
destroyed = self.destroy
after_decline_invite if destroyed
destroyed
end
|
#destroy_notification_setting ⇒ Object
618
619
620
|
# File 'app/models/member.rb', line 618
def destroy_notification_setting
notification_setting&.destroy
end
|
#generate_invite_token ⇒ Object
586
587
588
589
590
|
# File 'app/models/member.rb', line 586
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
592
593
594
|
# File 'app/models/member.rb', line 592
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
636
637
638
639
640
641
642
643
644
645
|
# File 'app/models/member.rb', line 636
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)
.non_request
.order(:access_level).last
end
end
|
#hook_prerequisites_met? ⇒ Boolean
544
545
546
547
548
|
# File 'app/models/member.rb', line 544
def hook_prerequisites_met?
user.present?
end
|
#invite? ⇒ Boolean
532
533
534
|
# File 'app/models/member.rb', line 532
def invite?
self.invite_token.present?
end
|
#invite_to_unknown_user? ⇒ Boolean
647
648
649
|
# File 'app/models/member.rb', line 647
def invite_to_unknown_user?
invite? && user_id.nil?
end
|
#notifiable?(type, opts = {}) ⇒ Boolean
rubocop: disable CodeReuse/ServiceClass
#notification_setting ⇒ Object
622
623
624
|
# File 'app/models/member.rb', line 622
def notification_setting
@notification_setting ||= user&.notification_settings_for(source)
end
|
#pending? ⇒ Boolean
540
541
542
|
# File 'app/models/member.rb', line 540
def pending?
invite? || request?
end
|
#prevent_role_assignement?(current_user, params) ⇒ Boolean
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
|
# File 'app/models/member.rb', line 666
def prevent_role_assignement?(current_user, params)
return false if current_user.can_admin_all_resources?
assigning_access_level = params[:access_level] || access_level
current_access_level = params[:current_access_level]
return false if Gitlab::Access.level_encompasses?(
current_access_level: current_access_level,
level_to_assign: assigning_access_level
)
!source.can_assign_role?(current_user, assigning_access_level)
end
|
#real_source_type ⇒ Object
524
525
526
|
# File 'app/models/member.rb', line 524
def real_source_type
source_type
end
|
#request? ⇒ Boolean
536
537
538
|
# File 'app/models/member.rb', line 536
def request?
requested_at.present?
end
|
#resend_invite ⇒ Object
596
597
598
599
600
601
602
|
# File 'app/models/member.rb', line 596
def resend_invite
return unless invite?
generate_invite_token! unless @raw_invite_token
send_invite
end
|
#send_invitation_reminder(reminder_index) ⇒ Object
604
605
606
607
608
609
610
611
612
|
# File 'app/models/member.rb', line 604
def send_invitation_reminder(reminder_index)
return unless invite?
generate_invite_token! unless @raw_invite_token
run_after_commit_or_now do
Members::InviteReminderMailer.email(self, @raw_invite_token, reminder_index).deliver_later
end
end
|
#update_two_factor_requirement ⇒ Object