Class: Group
- Inherits:
-
Namespace
show all
- Extended by:
- Gitlab::Utils::Override
- Includes:
- AccessRequestable, AfterCommitQueue, Avatarable, BulkMemberAccessLoad, BulkUsersByEmailLoad, ChronicDurationAttribute, EachBatch, Gitlab::ConfigHelper, Gitlab::Utils::StrongMemoize, GroupAPICompatibility, GroupDescendant, IdInOrdered, Importable, LoadedInGroupList, Members::Enumerable, RunnerTokenExpirationInterval, SelectForProjectAuthorization, TokenAuthenticatable, WithUploads
- Defined in:
- app/models/group.rb
Defined Under Namespace
Classes: CrmSettings
Constant Summary
collapse
- README_PROJECT_PATH =
'gitlab-profile'
Constants included
from WithUploads
WithUploads::FILE_UPLOADERS
Constants included
from Avatarable
Avatarable::ALLOWED_IMAGE_SCALER_WIDTHS, Avatarable::COMBINED_AVATAR_SIZES, Avatarable::COMBINED_AVATAR_SIZES_RETINA, Avatarable::GROUP_AVATAR_SIZES, Avatarable::MAXIMUM_FILE_SIZE, Avatarable::PROJECT_AVATAR_SIZES, Avatarable::USER_AVATAR_SIZES
Constants inherited
from Namespace
Namespace::NUMBER_OF_ANCESTORS_ALLOWED, Namespace::SHARED_RUNNERS_SETTINGS, Namespace::SR_DISABLED_AND_OVERRIDABLE, Namespace::SR_DISABLED_AND_UNOVERRIDABLE, Namespace::SR_ENABLED, Namespace::STATISTICS_COLUMNS, Namespace::URL_MAX_LENGTH
BlocksUnsafeSerialization::UnsafeSerializationError
Namespaces::Traversal::Linear::UnboundedSearch
Gitlab::SQL::Pattern::MIN_CHARS_FOR_PARTIAL_MATCHING, Gitlab::SQL::Pattern::REGEX_QUOTED_TERM
Gitlab::VisibilityLevel::INTERNAL, Gitlab::VisibilityLevel::PRIVATE, Gitlab::VisibilityLevel::PUBLIC
CacheMarkdownField::INVALIDATED_BY
ApplicationRecord::MAX_PLUCK
HasCheckConstraints::NOT_NULL_CHECK_PATTERN
ResetOnColumnErrors::MAX_RESET_PERIOD
Instance Attribute Summary
Attributes included from Importable
#importing, #user_contributions
Attributes inherited from Namespace
#emails_enabled_memoized, #root_ancestor
#skip_markdown_cache_validation
Class Method Summary
collapse
Instance Method Summary
collapse
-
#access_level_roles ⇒ Object
-
#access_level_values ⇒ Object
-
#access_request_approvers_to_be_notified ⇒ Object
-
#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) ⇒ Object
-
#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
-
#adjourned_deletion? ⇒ Boolean
-
#authorizable_members_with_parents ⇒ Object
-
#blocked_owners ⇒ Object
-
#bots ⇒ Object
-
#create_group_level_work_items_feature_flag_enabled? ⇒ Boolean
-
#crm_enabled? ⇒ Boolean
-
#crm_group ⇒ Object
-
#crm_group? ⇒ Boolean
-
#default_branch_name ⇒ Object
-
#delete_contacts ⇒ Object
-
#delete_organizations ⇒ Object
-
#dependency_proxy_feature_available? ⇒ Boolean
-
#dependency_proxy_for_containers_policy_subject ⇒ Object
-
#dependency_proxy_image_prefix ⇒ Object
-
#dependency_proxy_image_ttl_policy ⇒ Object
-
#dependency_proxy_setting ⇒ Object
-
#descendant_project_members_with_inactive ⇒ Object
-
#direct_members ⇒ Object
-
#enforced_runner_token_expiration_interval ⇒ Object
-
#execute_hooks(data, hooks_scope) ⇒ Object
-
#execute_integrations(data, hooks_scope) ⇒ Object
-
#export_archive_exists?(user) ⇒ Boolean
-
#export_file(user) ⇒ Object
-
#export_file_exists?(user) ⇒ Boolean
-
#feature_available?(feature, user = nil) ⇒ Boolean
-
#first_owner ⇒ Object
-
#gitlab_deploy_token ⇒ Object
-
#glql_integration_feature_flag_enabled? ⇒ Boolean
-
#group_feature ⇒ Object
-
#group_readme ⇒ Object
-
#has_container_repository_including_subgroups? ⇒ Boolean
-
#has_issues_with_contacts? ⇒ Boolean
-
#has_maintainer?(user) ⇒ Boolean
-
#has_owner?(user) ⇒ Boolean
-
#has_project_with_service_desk_enabled? ⇒ Boolean
-
#has_user?(user) ⇒ Boolean
Only for direct and not requested members with higher access level than MIMIMAL_ACCESS It returns true for non-active users.
-
#hashed_storage?(_feature) ⇒ Boolean
-
#hierarchy_members ⇒ Object
Returns all members that are part of the group, it’s subgroups, and ancestor groups.
-
#hierarchy_members_with_inactive ⇒ Object
-
#highest_group_member(user) ⇒ Object
-
#hook_attrs ⇒ Object
-
#human_name ⇒ Object
-
#import_export_upload_by_user(user) ⇒ Object
-
#last_owner?(user) ⇒ Boolean
Check if user is a last owner of the group.
-
#ldap_synced? ⇒ Boolean
-
#lfs_enabled? ⇒ Boolean
-
#mattermost_team_params ⇒ Object
-
#max_member_access_for_user(user, only_concrete_membership: false) ⇒ Object
Return the highest access level for a user.
-
#member(user) ⇒ Object
-
#member?(user, min_access_level = Gitlab::Access::GUEST) ⇒ Boolean
-
#member_owners_excluding_project_bots ⇒ Object
Excludes non-direct owners for top-level group Excludes project_bots.
-
#members_from_self_and_ancestors_with_effective_access_level ⇒ Object
-
#members_with_descendants ⇒ Object
-
#members_with_parents(only_active_users: true) ⇒ Object
-
#membership_locked? ⇒ Boolean
-
#namespace_work_items_enabled? ⇒ Boolean
Note: this method is overridden in EE to check the work_item_epics feature flag which also enables this feature.
-
#notification_email_for(user) ⇒ Object
-
#notification_group ⇒ Object
-
#notification_settings(hierarchy_order: nil) ⇒ Object
Overrides notification_settings has_many association This allows to apply notification settings from parent groups to child groups and projects.
-
#notification_settings_for(user, hierarchy_order: nil) ⇒ Object
-
#open_issues_count(current_user = nil) ⇒ Object
rubocop: disable CodeReuse/ServiceClass.
-
#open_merge_requests_count(current_user = nil) ⇒ Object
rubocop: disable CodeReuse/ServiceClass.
-
#owned_by?(user) ⇒ Boolean
-
#packages_feature_enabled? ⇒ Boolean
-
#packages_policy_subject ⇒ Object
-
#parent_allows_two_factor_authentication? ⇒ Boolean
-
#post_create_hook ⇒ Object
-
#post_destroy_hook ⇒ Object
-
#preload_shared_group_links ⇒ Object
-
#project_creation_level ⇒ Object
-
#readme_project ⇒ Object
-
#refresh_members_authorized_projects(priority: UserProjectAccessChangedService::HIGH_PRIORITY, direct_members_only: false) ⇒ Object
rubocop: disable CodeReuse/ServiceClass.
-
#refresh_project_authorizations ⇒ Object
-
#related_group_ids ⇒ Object
-
#runners_token ⇒ Object
each existing group needs to have a ‘runners_token`.
-
#self_and_ancestors_ids ⇒ Object
-
#self_and_descendants_ids ⇒ Object
-
#self_and_hierarchy_intersecting_with_user_groups(user) ⇒ Object
-
#shared_with_group_links_visible_to_user(user) ⇒ Object
-
#subgroup_creation_level ⇒ Object
-
#supports_events? ⇒ Boolean
-
#supports_lock_on_merge? ⇒ Boolean
-
#supports_saved_replies? ⇒ Boolean
-
#system_hook_service ⇒ Object
rubocop: disable CodeReuse/ServiceClass.
-
#timelogs ⇒ Object
rubocop: enable CodeReuse/ServiceClass.
-
#update_two_factor_requirement_for_members ⇒ Object
-
#usage_quotas_enabled? ⇒ Boolean
-
#user_ids_for_project_authorizations ⇒ Object
-
#users_count ⇒ Object
-
#users_ids_of_direct_members ⇒ Object
rubocop: enable CodeReuse/ServiceClass.
-
#users_with_descendants ⇒ Object
-
#visibility_level_allowed?(level = self.visibility_level) ⇒ Boolean
-
#visibility_level_allowed_by_parent?(level = self.visibility_level) ⇒ Boolean
-
#visibility_level_allowed_by_projects?(level = self.visibility_level) ⇒ Boolean
-
#visibility_level_allowed_by_sub_groups?(level = self.visibility_level) ⇒ Boolean
-
#wiki_comments_feature_flag_enabled? ⇒ Boolean
-
#work_items_alpha_feature_flag_enabled? ⇒ Boolean
-
#work_items_beta_feature_flag_enabled? ⇒ Boolean
-
#work_items_feature_flag_enabled? ⇒ Boolean
extended, extensions, included, method_added, override, prepended, queue_verification, verify!
#effective_runner_token_expiration_interval, #effective_runner_token_expiration_interval_human_readable, #enforced_runner_token_expiration_interval_human_readable
#chronic_duration_attributes, #output_chronic_duration_attribute
#project_creation_level_str, #project_creation_level_str=, #subgroup_creation_level_str, #subgroup_creation_level_str=
#retrieve_upload
#perform_fast_destroy
#run_after_commit, #run_after_commit_or_now
build_hierarchy, #hierarchy
#children_count, #guest_count, #member_count, #project_count, #subgroup_count
Methods included from Avatarable
#avatar_path, #avatar_type, #uncached_avatar_path, #upload_paths
#request_access
#gitlab_config, #gitlab_config_features
Methods inherited from Namespace
#actual_limits, #actual_plan, #actual_plan_name, #aggregation_scheduled?, #all_ancestors_have_runner_registration_enabled?, #all_catalog_resources, #all_container_repositories, #all_project_ids_except, #all_projects, #all_projects_except_soft_deleted, #all_projects_with_pages, #allow_runner_registration_token?, #any_project_has_container_registry_tags?, #any_project_with_pages_deployed?, #any_project_with_shared_runners_enabled?, #auto_devops_enabled?, #bot_user_namespace?, by_path, #certificate_based_clusters_enabled?, #changing_allow_descendants_override_disabled_shared_runners_is_allowed, #changing_shared_runners_enabled_is_allowed, clean_name, clean_path, #closest_setting, #container_repositories_size, #container_repositories_size_cache_key, #default_branch_protected?, #default_branch_protection, #default_branch_protection_settings, #deleted?, #emails_disabled?, #emails_enabled?, #enabled_git_access_protocol, find_by_path_or_name, #find_fork_of, find_top_level, #first_auto_devops_config, #first_project_with_container_registry_tags, #full_path_before_last_save, gfm_autocomplete_search, #group_namespace?, #has_parent?, #issue_repositioning_disabled?, #kind, #licensed_feature_available?, #linked_to_subscription?, #multiple_issue_boards_available?, #owner_required?, #package_settings, #paid?, #project_namespace?, #recent?, reference_pattern, reference_prefix, #root?, search, #send_update_instructions, #service_desk_alias_address, #shared_runners, #shared_runners_setting, #shared_runners_setting_higher_than?, sti_class_for, #subgroup?, sum_project_statistics_column, #to_param, #to_reference, #to_reference_base, #user_namespace?, username_reserved?, #visibility_level_field, #web_url
Methods included from Referable
#referable_inspect, #reference_link_text, #to_reference, #to_reference_base
#allow_stale_runner_pruning=, #allow_stale_runner_pruning?
#serializable_hash
#all_project_ids, #self_and_descendant_ids
#all_project_ids, #ancestor_ids, #ancestors, #ancestors_upto, #descendants, #parent=, #parent_id=, #root_ancestor, #self_and_ancestor_ids, #self_and_ancestors, #self_and_descendant_ids, #self_and_descendants, #self_and_hierarchy, #traversal_ids, #traversal_ids=, #traversal_path, #use_traversal_ids?
#all_project_ids, #ancestor_ids, #ancestors, #ancestors_upto, #descendants, #object_hierarchy, #root_ancestor, #self_and_ancestor_ids, #self_and_ancestors, #self_and_descendant_ids, #self_and_descendants, #self_and_hierarchy
#flipper_id
split_query_to_search_terms
Methods included from Routable
#build_full_path, find_by_full_path, #full_name, #full_path, #full_path_components, #parent_loaded?, #route_loaded?
allowed_for?, allowed_level?, allowed_levels, allowed_levels_for_user, closest_allowed_level, #internal?, level_name, level_value, levels_for_user, non_restricted_level?, options, #private?, #public?, public_visibility_restricted?, restricted_level?, string_level, string_options, string_values, valid_level?, #visibility, #visibility=, #visibility_attribute_present?, #visibility_attribute_value, #visibility_level_attributes, #visibility_level_previous_changes, #visibility_level_value
#attribute_invalidated?, #banzai_render_context, #cached_html_for, #cached_html_up_to_date?, #can_cache_field?, #invalidated_markdown_cache?, #latest_cached_markdown_version, #mentionable_attributes_changed?, #mentioned_filtered_user_ids_for, #parent_user, #refresh_markdown_cache, #refresh_markdown_cache!, #rendered_field_content, #skip_project_check?, #store_mentions!, #updated_cached_html_for
===, cached_column_list, #create_or_load_association, declarative_enum, default_select_columns, id_in, id_not_in, iid_in, nullable_column?, pluck_primary_key, 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
#reset_on_union_error, #reset_on_unknown_attribute_error
#serializable_hash
Class Method Details
.descendant_groups_counts ⇒ Object
386
387
388
|
# File 'app/models/group.rb', line 386
def descendant_groups_counts
left_joins(:children).group(:id).count(:children_namespaces)
end
|
.get_ids_by_ids_or_paths(ids, paths) ⇒ Object
382
383
384
|
# File 'app/models/group.rb', line 382
def get_ids_by_ids_or_paths(ids, paths)
by_ids_or_paths(ids, paths).pluck(:id)
end
|
.group_members_counts ⇒ Object
394
395
396
|
# File 'app/models/group.rb', line 394
def group_members_counts
left_joins(:group_members).group(:id).count(:members)
end
|
.groups_user_can(groups, user, action, same_root: false) ⇒ Object
347
348
349
350
351
|
# File 'app/models/group.rb', line 347
def groups_user_can(groups, user, action, same_root: false)
DeclarativePolicy.user_scope do
groups.select { |group| Ability.allowed?(user, action, group) }
end
end
|
.ids_with_disabled_email(groups) ⇒ Object
Returns the ids of the passed group models where the ‘emails_enabled` column is set to false anywhere in the ancestor hierarchy.
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
|
# File 'app/models/group.rb', line 364
def ids_with_disabled_email(groups)
inner_groups = Group.where('id = namespaces_with_emails_disabled.id')
inner_query = inner_groups
.self_and_ancestors
.joins(:namespace_settings)
.where(namespace_settings: { emails_enabled: false })
.select('1')
.limit(1)
group_ids = Namespace
.from('(SELECT * FROM namespaces) as namespaces_with_emails_disabled')
.where(namespaces_with_emails_disabled: { id: groups })
.where('EXISTS (?)', inner_query)
.pluck(:id)
Set.new(group_ids)
end
|
.preset_root_ancestor_for(groups) ⇒ Object
This method can be used only if all groups have the same top-level group
355
356
357
358
359
360
|
# File 'app/models/group.rb', line 355
def preset_root_ancestor_for(groups)
return groups if groups.size < 2
root = groups.first.root_ancestor
groups.drop(1).each { |group| group.root_ancestor = root }
end
|
.prevent_project_creation?(user, project_creation_setting) ⇒ Boolean
.project_creation_levels_for_user(user) ⇒ Object
Handle project creation permissions based on application setting and group setting. The ‘default_project_creation` application setting is the default value and can be overridden by the `project_creation_level` group setting. `nil` value of namespaces.project_creation_level` means that allowed creation level has not been explicitly set by the group owner and is a placeholder value for inheriting the value from the ApplicationSetting.
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
|
# File 'app/models/group.rb', line 406
def project_creation_levels_for_user(user)
project_creation_allowed_on_levels = [
::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS,
::Gitlab::Access::MAINTAINER_PROJECT_ACCESS,
nil
]
if user.can_admin_all_resources?
project_creation_allowed_on_levels << ::Gitlab::Access::ADMINISTRATOR_PROJECT_ACCESS
end
default_project_creation = ::Gitlab::CurrentSettings.default_project_creation
prevent_project_creation_by_default = prevent_project_creation?(user, default_project_creation)
project_creation_allowed_on_levels.delete(nil) if prevent_project_creation_by_default
project_creation_allowed_on_levels
end
|
.projects_counts ⇒ Object
390
391
392
|
# File 'app/models/group.rb', line 390
def projects_counts
left_joins(:non_archived_projects).group(:id).count(:projects)
end
|
.public_or_visible_to_user(user) ⇒ Object
WARNING: This method should never be used on its own please do make sure the number of rows you are filtering is small enough for this query
318
319
320
321
322
323
324
325
326
|
# File 'app/models/group.rb', line 318
def public_or_visible_to_user(user)
return public_to_user unless user
public_for_user = public_to_user_arel(user)
visible_for_user = visible_to_user_arel(user)
public_or_visible = public_for_user.or(visible_for_user)
where(public_or_visible)
end
|
.select_for_project_authorization ⇒ Object
328
329
330
331
332
333
334
335
336
|
# File 'app/models/group.rb', line 328
def select_for_project_authorization
if current_scope.joins_values.include?(:shared_projects)
joins('INNER JOIN namespaces project_namespace ON project_namespace.id = projects.namespace_id')
.where(project_namespace: { share_with_group_lock: false })
.select("projects.id AS project_id", "LEAST(project_group_links.group_access, members.access_level) AS access_level")
else
super
end
end
|
.sort_by_attribute(method) ⇒ Object
300
301
302
303
304
305
306
307
308
309
310
311
312
313
|
# File 'app/models/group.rb', line 300
def sort_by_attribute(method)
case method.to_s
when 'storage_size_desc'
reorder('storage_size DESC, namespaces.id DESC')
when 'path_asc'
order_path_asc
when 'path_desc'
order_path_desc
else
order_by(method)
end
end
|
.sti_name ⇒ Object
32
33
34
|
# File 'app/models/group.rb', line 32
def self.sti_name
'Group'
end
|
.supported_keyset_orderings ⇒ Object
36
37
38
|
# File 'app/models/group.rb', line 36
def self.supported_keyset_orderings
{ name: [:asc] }
end
|
.with_api_scopes ⇒ Object
398
399
400
|
# File 'app/models/group.rb', line 398
def with_api_scopes
preload(:namespace_settings, :group_feature, :parent)
end
|
.without_integration(integration) ⇒ Object
338
339
340
341
342
343
344
345
|
# File 'app/models/group.rb', line 338
def without_integration(integration)
integrations = Integration
.select('1')
.where("#{Integration.table_name}.group_id = namespaces.id")
.where(type: integration.type)
where('NOT EXISTS (?)', integrations)
end
|
Instance Method Details
#access_level_roles ⇒ Object
#access_level_values ⇒ Object
905
906
907
|
# File 'app/models/group.rb', line 905
def access_level_values
access_level_roles.values
end
|
#access_request_approvers_to_be_notified ⇒ Object
#add_developer(user, current_user = nil) ⇒ Object
561
562
563
|
# File 'app/models/group.rb', line 561
def add_developer(user, current_user = nil)
add_member(user, :developer, current_user: current_user)
end
|
#add_guest(user, current_user = nil) ⇒ Object
549
550
551
|
# File 'app/models/group.rb', line 549
def add_guest(user, current_user = nil)
add_member(user, :guest, current_user: current_user)
end
|
#add_maintainer(user, current_user = nil) ⇒ Object
565
566
567
|
# File 'app/models/group.rb', line 565
def add_maintainer(user, current_user = nil)
add_member(user, :maintainer, current_user: current_user)
end
|
#add_member(user, access_level) ⇒ Object
#add_members(users, access_level, current_user: nil, expires_at: nil) ⇒ Object
535
536
537
538
539
540
541
542
543
|
# File 'app/models/group.rb', line 535
def add_members(users, access_level, current_user: nil, expires_at: nil)
Members::Groups::CreatorService.add_members( self,
users,
access_level,
current_user: current_user,
expires_at: expires_at
)
end
|
#add_owner(user, current_user = nil) ⇒ Object
569
570
571
|
# File 'app/models/group.rb', line 569
def add_owner(user, current_user = nil)
add_member(user, :owner, current_user: current_user)
end
|
#add_planner(user, current_user = nil) ⇒ Object
553
554
555
|
# File 'app/models/group.rb', line 553
def add_planner(user, current_user = nil)
add_member(user, :planner, current_user: current_user)
end
|
#add_reporter(user, current_user = nil) ⇒ Object
557
558
559
|
# File 'app/models/group.rb', line 557
def add_reporter(user, current_user = nil)
add_member(user, :reporter, current_user: current_user)
end
|
#adjourned_deletion? ⇒ Boolean
869
870
871
|
# File 'app/models/group.rb', line 869
def adjourned_deletion?
false
end
|
#authorizable_members_with_parents ⇒ Object
#blocked_owners ⇒ Object
585
586
587
|
# File 'app/models/group.rb', line 585
def blocked_owners
members.blocked.where(access_level: Gitlab::Access::OWNER)
end
|
#bots ⇒ Object
806
807
808
|
# File 'app/models/group.rb', line 806
def bots
users.project_bot
end
|
#create_group_level_work_items_feature_flag_enabled? ⇒ Boolean
993
994
995
|
# File 'app/models/group.rb', line 993
def create_group_level_work_items_feature_flag_enabled?
::Feature.enabled?(:create_group_level_work_items, self, type: :wip)
end
|
#crm_enabled? ⇒ Boolean
949
950
951
|
# File 'app/models/group.rb', line 949
def crm_enabled?
crm_settings.nil? || crm_settings.enabled?
end
|
#crm_group ⇒ Object
1064
1065
1066
1067
1068
1069
|
# File 'app/models/group.rb', line 1064
def crm_group
Group.id_in_ordered(traversal_ids.reverse)
.joins(:crm_settings)
.where.not(crm_settings: { source_group_id: nil })
.first&.crm_settings&.source_group || root_ancestor
end
|
#crm_group? ⇒ Boolean
1072
1073
1074
1075
1076
|
# File 'app/models/group.rb', line 1072
def crm_group?
return true if root? && crm_settings&.source_group_id.nil?
crm_targets.present?
end
|
#default_branch_name ⇒ Object
897
898
899
|
# File 'app/models/group.rb', line 897
def default_branch_name
namespace_settings&.default_branch_name
end
|
1083
1084
1085
|
# File 'app/models/group.rb', line 1083
def delete_contacts
CustomerRelations::Contact.where(group_id: id).delete_all
end
|
#delete_organizations ⇒ Object
1087
1088
1089
|
# File 'app/models/group.rb', line 1087
def delete_organizations
CustomerRelations::Organization.where(group_id: id).delete_all
end
|
#dependency_proxy_feature_available? ⇒ Boolean
479
480
481
|
# File 'app/models/group.rb', line 479
def dependency_proxy_feature_available?
::Gitlab.config.dependency_proxy.enabled
end
|
#dependency_proxy_for_containers_policy_subject ⇒ Object
#dependency_proxy_image_prefix ⇒ Object
#dependency_proxy_image_ttl_policy ⇒ Object
937
938
939
|
# File 'app/models/group.rb', line 937
def dependency_proxy_image_ttl_policy
super || build_dependency_proxy_image_ttl_policy
end
|
#dependency_proxy_setting ⇒ Object
941
942
943
|
# File 'app/models/group.rb', line 941
def dependency_proxy_setting
super || build_dependency_proxy_setting
end
|
#descendant_project_members_with_inactive ⇒ Object
744
745
746
747
748
749
|
# File 'app/models/group.rb', line 744
def descendant_project_members_with_inactive
ProjectMember
.with_source_id(all_projects)
.non_request
.non_invite
end
|
#direct_members ⇒ Object
703
704
705
706
707
|
# File 'app/models/group.rb', line 703
def direct_members
GroupMember.active_without_invites_and_requests
.non_minimal_access
.where(source_id: id)
end
|
#enforced_runner_token_expiration_interval ⇒ Object
957
958
959
960
961
962
963
964
965
966
|
# File 'app/models/group.rb', line 957
def enforced_runner_token_expiration_interval
all_parent_groups = Gitlab::ObjectHierarchy.new(Group.where(id: id)).ancestors
all_group_settings = NamespaceSetting.where(namespace_id: all_parent_groups)
group_interval = all_group_settings.where.not(subgroup_runner_token_expiration_interval: nil).minimum(:subgroup_runner_token_expiration_interval)&.seconds
[
Gitlab::CurrentSettings.group_runner_token_expiration_interval&.seconds,
group_interval
].compact.min
end
|
#execute_hooks(data, hooks_scope) ⇒ Object
873
874
875
876
|
# File 'app/models/group.rb', line 873
def execute_hooks(data, hooks_scope)
end
|
#execute_integrations(data, hooks_scope) ⇒ Object
878
879
880
881
882
|
# File 'app/models/group.rb', line 878
def execute_integrations(data, hooks_scope)
integrations.public_send(hooks_scope).each do |integration| integration.async_execute(data)
end
end
|
#export_archive_exists?(user) ⇒ Boolean
865
866
867
|
# File 'app/models/group.rb', line 865
def export_archive_exists?(user)
import_export_upload_by_user(user)&.export_archive_exists?
end
|
#export_file(user) ⇒ Object
861
862
863
|
# File 'app/models/group.rb', line 861
def export_file(user)
import_export_upload_by_user(user)&.export_file
end
|
#export_file_exists?(user) ⇒ Boolean
857
858
859
|
# File 'app/models/group.rb', line 857
def export_file_exists?(user)
import_export_upload_by_user(user)&.export_file_exists?
end
|
#feature_available?(feature, user = nil) ⇒ Boolean
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
|
# File 'app/models/group.rb', line 1012
def feature_available?(feature, user = nil)
feature = feature == :issues ? :epics : feature
if ::Groups::FeatureSetting.available_features.include?(feature)
group_feature.feature_available?(feature, user) else
super
end
end
|
#first_owner ⇒ Object
891
892
893
894
895
|
# File 'app/models/group.rb', line 891
def first_owner
first_owner_member = all_group_members.all_owners.order(:user_id).first
first_owner_member&.user || parent&.first_owner || owner
end
|
#gitlab_deploy_token ⇒ Object
1023
1024
1025
1026
1027
|
# File 'app/models/group.rb', line 1023
def gitlab_deploy_token
strong_memoize(:gitlab_deploy_token) do
deploy_tokens.gitlab_deploy_token
end
end
|
#glql_integration_feature_flag_enabled? ⇒ Boolean
980
981
982
|
# File 'app/models/group.rb', line 980
def glql_integration_feature_flag_enabled?
feature_flag_enabled_for_self_or_ancestor?(:glql_integration)
end
|
#group_feature ⇒ Object
945
946
947
|
# File 'app/models/group.rb', line 945
def group_feature
super || build_group_feature
end
|
#group_readme ⇒ Object
1050
1051
1052
|
# File 'app/models/group.rb', line 1050
def group_readme
readme_project&.repository&.readme
end
|
#has_container_repository_including_subgroups? ⇒ Boolean
595
596
597
|
# File 'app/models/group.rb', line 595
def has_container_repository_including_subgroups?
::ContainerRepository.for_group_and_its_subgroups(self).exists?
end
|
1079
1080
1081
|
# File 'app/models/group.rb', line 1079
def has_issues_with_contacts?
CustomerRelations::IssueContact.joins(:issue).where(issue: { project_id: Project.where(namespace_id: self_and_descendant_ids) }).exists?
end
|
#has_maintainer?(user) ⇒ Boolean
589
590
591
592
593
|
# File 'app/models/group.rb', line 589
def has_maintainer?(user)
return false unless user
members_with_parents.maintainers.exists?(user_id: user)
end
|
#has_owner?(user) ⇒ Boolean
579
580
581
582
583
|
# File 'app/models/group.rb', line 579
def has_owner?(user)
return false unless user
members_with_parents.all_owners.exists?(user_id: user)
end
|
#has_project_with_service_desk_enabled? ⇒ Boolean
916
917
918
|
# File 'app/models/group.rb', line 916
def has_project_with_service_desk_enabled?
Gitlab::ServiceDesk.supported? && all_projects.service_desk_enabled.exists?
end
|
#has_user?(user) ⇒ Boolean
Only for direct and not requested members with higher access level than MIMIMAL_ACCESS It returns true for non-active users
697
698
699
700
701
|
# File 'app/models/group.rb', line 697
def has_user?(user)
return false unless user
group_members.non_invite.exists?(user: user)
end
|
#hashed_storage?(_feature) ⇒ Boolean
816
817
818
|
# File 'app/models/group.rb', line 816
def hashed_storage?(_feature)
false
end
|
#hierarchy_members ⇒ Object
Returns all members that are part of the group, it’s subgroups, and ancestor groups
731
732
733
734
735
|
# File 'app/models/group.rb', line 731
def hierarchy_members
GroupMember
.active_without_invites_and_requests
.where(source_id: self_and_hierarchy.reorder(nil).select(:id))
end
|
#hierarchy_members_with_inactive ⇒ Object
737
738
739
740
741
742
|
# File 'app/models/group.rb', line 737
def hierarchy_members_with_inactive
GroupMember
.non_request
.non_invite
.where(source_id: self_and_hierarchy.reorder(nil).select(:id))
end
|
#highest_group_member(user) ⇒ Object
798
799
800
801
802
803
804
|
# File 'app/models/group.rb', line 798
def highest_group_member(user)
GroupMember
.where(source_id: self_and_ancestors_ids, user_id: user.id)
.non_request
.order(:access_level)
.last
end
|
#hook_attrs ⇒ Object
1055
1056
1057
1058
1059
1060
1061
1062
|
# File 'app/models/group.rb', line 1055
def hook_attrs
{
group_name: name,
group_path: path,
group_id: id,
full_path: full_path
}
end
|
#human_name ⇒ Object
498
499
500
|
# File 'app/models/group.rb', line 498
def human_name
full_name
end
|
#import_export_upload_by_user(user) ⇒ Object
853
854
855
|
# File 'app/models/group.rb', line 853
def import_export_upload_by_user(user)
import_export_uploads.find_by(user_id: user.id)
end
|
#last_owner?(user) ⇒ Boolean
Check if user is a last owner of the group. Excludes non-direct owners for top-level group Excludes project_bots
602
603
604
605
606
607
608
|
# File 'app/models/group.rb', line 602
def last_owner?(user)
return false unless user
all_owners = member_owners_excluding_project_bots
all_owners.size == 1 && all_owners.first.user_id == user.id
end
|
#ldap_synced? ⇒ Boolean
630
631
632
|
# File 'app/models/group.rb', line 630
def ldap_synced?
false
end
|
#lfs_enabled? ⇒ Boolean
522
523
524
525
526
527
|
# File 'app/models/group.rb', line 522
def lfs_enabled?
return false unless Gitlab.config.lfs.enabled
return Gitlab.config.lfs.enabled if self[:lfs_enabled].nil?
self[:lfs_enabled]
end
|
#mattermost_team_params ⇒ Object
780
781
782
783
784
785
786
787
788
|
# File 'app/models/group.rb', line 780
def mattermost_team_params
max_length = 59
{
name: path[0..max_length],
display_name: name[0..max_length],
type: public? ? 'O' : 'I' }
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 group unless specifically added to it
769
770
771
772
773
774
775
776
777
778
|
# File 'app/models/group.rb', line 769
def max_member_access_for_user(user, only_concrete_membership: false)
return GroupMember::NO_ACCESS unless user
unless only_concrete_membership
return GroupMember::OWNER if user.can_admin_all_resources?
return GroupMember::OWNER if user.can_admin_organization?(organization)
end
max_member_access(user)
end
|
#member(user) ⇒ Object
790
791
792
793
794
795
796
|
# File 'app/models/group.rb', line 790
def member(user)
if group_members.loaded?
group_members.find { |gm| gm.user_id == user.id }
else
group_members.find_by(user_id: user)
end
end
|
#member?(user, min_access_level = Gitlab::Access::GUEST) ⇒ Boolean
573
574
575
576
577
|
# File 'app/models/group.rb', line 573
def member?(user, min_access_level = Gitlab::Access::GUEST)
return false unless user
max_member_access_for_user(user) >= min_access_level
end
|
#member_owners_excluding_project_bots ⇒ Object
Excludes non-direct owners for top-level group Excludes project_bots
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
|
# File 'app/models/group.rb', line 612
def member_owners_excluding_project_bots
members_from_hiearchy = if root?
members.non_minimal_access.without_invites_and_requests
else
members_with_parents(only_active_users: false)
end
owners = []
members_from_hiearchy.all_owners.non_invite.each_batch do |relation|
owners += relation.preload(:user, :source).load.reject do |member|
member.user.nil? || member.user.project_bot?
end
end
owners
end
|
#members_from_self_and_ancestors_with_effective_access_level ⇒ Object
719
720
721
722
|
# File 'app/models/group.rb', line 719
def members_from_self_and_ancestors_with_effective_access_level
members_with_parents.select([:user_id, 'MAX(access_level) AS access_level'])
.group(:user_id)
end
|
#members_with_descendants ⇒ Object
724
725
726
727
728
|
# File 'app/models/group.rb', line 724
def members_with_descendants
GroupMember
.active_without_invites_and_requests
.where(source_id: self_and_descendants.reorder(nil).select(:id))
end
|
#members_with_parents(only_active_users: true) ⇒ Object
713
714
715
716
717
|
# File 'app/models/group.rb', line 713
def members_with_parents(only_active_users: true)
Members::MembersWithParents
.new(self)
.members(active_users: only_active_users)
end
|
#membership_locked? ⇒ Boolean
845
846
847
|
# File 'app/models/group.rb', line 845
def membership_locked?
false end
|
#namespace_work_items_enabled? ⇒ Boolean
Note: this method is overridden in EE to check the work_item_epics feature flag which also enables this feature
989
990
991
|
# File 'app/models/group.rb', line 989
def namespace_work_items_enabled?
::Feature.enabled?(:namespace_level_work_items, self, type: :development)
end
|
#notification_email_for(user) ⇒ Object
483
484
485
486
487
|
# File 'app/models/group.rb', line 483
def notification_email_for(user)
notification_settings = notification_settings_for(user, hierarchy_order: :asc)
notification_settings.find { |n| n.notification_email.present? }&.notification_email
end
|
#notification_group ⇒ Object
1046
1047
1048
|
# File 'app/models/group.rb', line 1046
def notification_group
self
end
|
#notification_settings(hierarchy_order: nil) ⇒ Object
Overrides notification_settings has_many association This allows to apply notification settings from parent groups to child groups and projects.
459
460
461
462
463
464
465
466
467
468
469
|
# File 'app/models/group.rb', line 459
def notification_settings(hierarchy_order: nil)
source_type = self.class.base_class.name
settings = NotificationSetting.where(source_type: source_type, source_id: self_and_ancestors_ids)
return settings unless hierarchy_order && self_and_ancestors_ids.length > 1
settings
.joins("LEFT JOIN (#{self_and_ancestors(hierarchy_order: hierarchy_order).to_sql}) AS ordered_groups ON notification_settings.source_id = ordered_groups.id")
.select('notification_settings.*, ordered_groups.depth AS depth')
.order("ordered_groups.depth #{hierarchy_order}")
end
|
#notification_settings_for(user, hierarchy_order: nil) ⇒ Object
471
472
473
|
# File 'app/models/group.rb', line 471
def notification_settings_for(user, hierarchy_order: nil)
notification_settings(hierarchy_order: hierarchy_order).where(user: user)
end
|
#open_issues_count(current_user = nil) ⇒ Object
rubocop: disable CodeReuse/ServiceClass
#open_merge_requests_count(current_user = nil) ⇒ Object
rubocop: disable CodeReuse/ServiceClass
#owned_by?(user) ⇒ Boolean
529
530
531
532
533
|
# File 'app/models/group.rb', line 529
def owned_by?(user)
return false unless user
non_invite_owner_members.exists?(user: user)
end
|
#packages_feature_enabled? ⇒ Boolean
475
476
477
|
# File 'app/models/group.rb', line 475
def packages_feature_enabled?
::Gitlab.config.packages.enabled
end
|
#packages_policy_subject ⇒ Object
1029
1030
1031
|
# File 'app/models/group.rb', line 1029
def packages_policy_subject
::Packages::Policies::Group.new(self)
end
|
#parent_allows_two_factor_authentication? ⇒ Boolean
909
910
911
912
913
914
|
# File 'app/models/group.rb', line 909
def parent_allows_two_factor_authentication?
return true unless has_parent?
ancestor_settings = ancestors.find_top_level.namespace_settings
ancestor_settings.allow_mfa_for_subgroups
end
|
#post_create_hook ⇒ Object
634
635
636
637
638
|
# File 'app/models/group.rb', line 634
def post_create_hook
Gitlab::AppLogger.info("Group \"#{name}\" was created")
system_hook_service.execute_hooks_for(self, :create)
end
|
#post_destroy_hook ⇒ Object
640
641
642
643
644
|
# File 'app/models/group.rb', line 640
def post_destroy_hook
Gitlab::AppLogger.info("Group \"#{name}\" was removed")
system_hook_service.execute_hooks_for(self, :destroy)
end
|
#preload_shared_group_links ⇒ Object
884
885
886
887
888
889
|
# File 'app/models/group.rb', line 884
def preload_shared_group_links
ActiveRecord::Associations::Preloader.new(
records: [self],
associations: { shared_with_group_links: [shared_with_group: :route] }
).call
end
|
#project_creation_level ⇒ Object
833
834
835
|
# File 'app/models/group.rb', line 833
def project_creation_level
super || ::Gitlab::CurrentSettings.default_project_creation
end
|
#readme_project ⇒ Object
1041
1042
1043
|
# File 'app/models/group.rb', line 1041
def readme_project
projects.find_by(path: README_PROJECT_PATH)
end
|
#refresh_members_authorized_projects(priority: UserProjectAccessChangedService::HIGH_PRIORITY, direct_members_only: false) ⇒ Object
rubocop: disable CodeReuse/ServiceClass
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
|
# File 'app/models/group.rb', line 653
def refresh_members_authorized_projects(
priority: UserProjectAccessChangedService::HIGH_PRIORITY,
direct_members_only: false
)
user_ids = if direct_members_only
users_ids_of_direct_members
else
user_ids_for_project_authorizations
end
UserProjectAccessChangedService
.new(user_ids)
.execute(priority: priority)
end
|
#refresh_project_authorizations ⇒ Object
820
821
822
|
# File 'app/models/group.rb', line 820
def refresh_project_authorizations
refresh_members_authorized_projects
end
|
810
811
812
813
814
|
# File 'app/models/group.rb', line 810
def related_group_ids
[id,
*ancestors.pluck(:id),
*shared_with_group_links.pluck(:shared_with_group_id)]
end
|
#runners_token ⇒ Object
each existing group needs to have a ‘runners_token`. we do this on read since migrating all existing groups is not a feasible solution.
827
828
829
830
831
|
# File 'app/models/group.rb', line 827
def runners_token
return unless allow_runner_registration_token?
ensure_runners_token!
end
|
#self_and_ancestors_ids ⇒ Object
683
684
685
686
687
|
# File 'app/models/group.rb', line 683
def self_and_ancestors_ids
strong_memoize(:self_and_ancestors_ids) do
self_and_ancestors.pluck(:id)
end
end
|
#self_and_descendants_ids ⇒ Object
689
690
691
692
693
|
# File 'app/models/group.rb', line 689
def self_and_descendants_ids
strong_memoize(:self_and_descendants_ids) do
self_and_descendants.pluck(:id)
end
end
|
#self_and_hierarchy_intersecting_with_user_groups(user) ⇒ Object
678
679
680
681
|
# File 'app/models/group.rb', line 678
def self_and_hierarchy_intersecting_with_user_groups(user)
user_groups = GroupsFinder.new(user).execute.unscope(:order)
self_and_hierarchy.unscope(:order).where(id: user_groups)
end
|
#shared_with_group_links_visible_to_user(user) ⇒ Object
953
954
955
|
# File 'app/models/group.rb', line 953
def shared_with_group_links_visible_to_user(user)
shared_with_group_links.preload_shared_with_groups.filter { |link| Ability.allowed?(user, :read_group, link.shared_with_group) }
end
|
#subgroup_creation_level ⇒ Object
#supports_events? ⇒ Boolean
849
850
851
|
# File 'app/models/group.rb', line 849
def supports_events?
false
end
|
#supports_lock_on_merge? ⇒ Boolean
997
998
999
|
# File 'app/models/group.rb', line 997
def supports_lock_on_merge?
feature_flag_enabled_for_self_or_ancestor?(:enforce_locked_labels_on_merge, type: :ops)
end
|
#supports_saved_replies? ⇒ Boolean
1005
1006
1007
|
# File 'app/models/group.rb', line 1005
def supports_saved_replies?
false
end
|
#system_hook_service ⇒ Object
rubocop: disable CodeReuse/ServiceClass
647
648
649
|
# File 'app/models/group.rb', line 647
def system_hook_service
SystemHooksService.new
end
|
#timelogs ⇒ Object
rubocop: enable CodeReuse/ServiceClass
933
934
935
|
# File 'app/models/group.rb', line 933
def timelogs
Timelog.in_group(self)
end
|
#update_two_factor_requirement_for_members ⇒ Object
1037
1038
1039
|
# File 'app/models/group.rb', line 1037
def update_two_factor_requirement_for_members
hierarchy_members.find_each(&:update_two_factor_requirement)
end
|
#usage_quotas_enabled? ⇒ Boolean
1001
1002
1003
|
# File 'app/models/group.rb', line 1001
def usage_quotas_enabled?
root?
end
|
#user_ids_for_project_authorizations ⇒ Object
674
675
676
|
# File 'app/models/group.rb', line 674
def user_ids_for_project_authorizations
members_with_parents.pluck(Arel.sql('DISTINCT members.user_id'))
end
|
#users_count ⇒ Object
757
758
759
|
# File 'app/models/group.rb', line 757
def users_count
members.count
end
|
#users_ids_of_direct_members ⇒ Object
rubocop: enable CodeReuse/ServiceClass
670
671
672
|
# File 'app/models/group.rb', line 670
def users_ids_of_direct_members
direct_members.pluck_user_ids
end
|
#users_with_descendants ⇒ Object
751
752
753
754
755
|
# File 'app/models/group.rb', line 751
def users_with_descendants
User
.where(id: members_with_descendants.select(:user_id))
.reorder(nil)
end
|
#visibility_level_allowed?(level = self.visibility_level) ⇒ Boolean
516
517
518
519
520
|
# File 'app/models/group.rb', line 516
def visibility_level_allowed?(level = self.visibility_level)
visibility_level_allowed_by_parent?(level) &&
visibility_level_allowed_by_projects?(level) &&
visibility_level_allowed_by_sub_groups?(level)
end
|
#visibility_level_allowed_by_parent?(level = self.visibility_level) ⇒ Boolean
502
503
504
505
506
|
# File 'app/models/group.rb', line 502
def visibility_level_allowed_by_parent?(level = self.visibility_level)
return true unless parent_id && parent_id.nonzero?
level <= parent.visibility_level
end
|
#visibility_level_allowed_by_projects?(level = self.visibility_level) ⇒ Boolean
508
509
510
|
# File 'app/models/group.rb', line 508
def visibility_level_allowed_by_projects?(level = self.visibility_level)
!projects.not_aimed_for_deletion.where('visibility_level > ?', level).exists?
end
|
#visibility_level_allowed_by_sub_groups?(level = self.visibility_level) ⇒ Boolean
512
513
514
|
# File 'app/models/group.rb', line 512
def visibility_level_allowed_by_sub_groups?(level = self.visibility_level)
!children.where('visibility_level > ?', level).exists?
end
|
984
985
986
|
# File 'app/models/group.rb', line 984
def
feature_flag_enabled_for_self_or_ancestor?(:wiki_comments, type: :wip)
end
|
#work_items_alpha_feature_flag_enabled? ⇒ Boolean
976
977
978
|
# File 'app/models/group.rb', line 976
def work_items_alpha_feature_flag_enabled?
feature_flag_enabled_for_self_or_ancestor?(:work_items_alpha)
end
|
#work_items_beta_feature_flag_enabled? ⇒ Boolean
972
973
974
|
# File 'app/models/group.rb', line 972
def work_items_beta_feature_flag_enabled?
feature_flag_enabled_for_self_or_ancestor?(:work_items_beta, type: :beta)
end
|
#work_items_feature_flag_enabled? ⇒ Boolean
968
969
970
|
# File 'app/models/group.rb', line 968
def work_items_feature_flag_enabled?
feature_flag_enabled_for_self_or_ancestor?(:work_items)
end
|