1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
# frozen_string_literal: true
class NamespaceSetting < ApplicationRecord
include CascadingNamespaceSettingAttribute
include Sanitizable
include ChronicDurationAttribute
cascading_attr :delayed_project_removal
cascading_attr :toggle_security_policy_custom_ci
belongs_to :namespace, inverse_of: :namespace_settings
enum jobs_to_be_done: { basics: 0, move_repository: 1, code_storage: 2, exploring: 3, ci: 4, other: 5 }, _suffix: true
enum enabled_git_access_protocol: { all: 0, ssh: 1, http: 2, ssh_certificates: 3 }, _suffix: true
attribute :default_branch_protection_defaults, default: -> { {} }
validates :enabled_git_access_protocol, inclusion: { in: enabled_git_access_protocols.keys }
validates :code_suggestions, allow_nil: false, inclusion: { in: [true, false] }
validates :default_branch_protection_defaults, json_schema: { filename: 'default_branch_protection_defaults' }
validates :default_branch_protection_defaults, bytesize: { maximum: -> { DEFAULT_BRANCH_PROTECTIONS_DEFAULT_MAX_SIZE } }
validate :allow_mfa_for_group
validate :allow_resource_access_token_creation_for_group
sanitizes! :default_branch_name
before_validation :normalize_default_branch_name
after_create :set_code_suggestions_default
chronic_duration_attr :runner_token_expiration_interval_human_readable, :runner_token_expiration_interval
chronic_duration_attr :subgroup_runner_token_expiration_interval_human_readable, :subgroup_runner_token_expiration_interval
chronic_duration_attr :project_runner_token_expiration_interval_human_readable, :project_runner_token_expiration_interval
NAMESPACE_SETTINGS_PARAMS = %i[
default_branch_name
delayed_project_removal
lock_delayed_project_removal
resource_access_token_creation_allowed
prevent_sharing_groups_outside_hierarchy
new_user_signups_cap
setup_for_company
jobs_to_be_done
runner_token_expiration_interval
enabled_git_access_protocol
subgroup_runner_token_expiration_interval
project_runner_token_expiration_interval
default_branch_protection_defaults
].freeze
# matches the size set in the database constraint
DEFAULT_BRANCH_PROTECTIONS_DEFAULT_MAX_SIZE = 1.kilobyte
self.primary_key = :namespace_id
def self.allowed_namespace_settings_params
NAMESPACE_SETTINGS_PARAMS
end
def prevent_sharing_groups_outside_hierarchy
return super if namespace.root?
namespace.root_ancestor.prevent_sharing_groups_outside_hierarchy
end
def emails_enabled?
return emails_enabled unless namespace.has_parent?
all_ancestors_have_emails_enabled?
end
def show_diff_preview_in_email?
return show_diff_preview_in_email unless namespace.has_parent?
all_ancestors_allow_diff_preview_in_email?
end
def runner_registration_enabled?
runner_registration_enabled && all_ancestors_have_runner_registration_enabled?
end
def all_ancestors_have_runner_registration_enabled?
return false unless Gitlab::CurrentSettings.valid_runner_registrars.include?('group')
return true unless namespace.has_parent?
!self.class.where(namespace_id: namespace.ancestors, runner_registration_enabled: false).exists?
end
def allow_runner_registration_token?
settings = Gitlab::CurrentSettings.current_application_settings
settings.allow_runner_registration_token && namespace.root_ancestor.allow_runner_registration_token
end
private
def all_ancestors_have_emails_enabled?
self.class.where(namespace_id: namespace.self_and_ancestors, emails_enabled: false).none?
end
def all_ancestors_allow_diff_preview_in_email?
!self.class.where(namespace_id: namespace.self_and_ancestors, show_diff_preview_in_email: false).exists?
end
def normalize_default_branch_name
self.default_branch_name = default_branch_name.presence
end
def set_code_suggestions_default
# users should have code suggestions disabled by default
return if namespace&.user_namespace?
# groups should have code suggestions enabled by default
update_column(:code_suggestions, true)
end
def allow_mfa_for_group
if namespace&.subgroup? && allow_mfa_for_subgroups == false
errors.add(:allow_mfa_for_subgroups, _('is not allowed since the group is not top-level group.'))
end
end
def allow_resource_access_token_creation_for_group
if namespace&.subgroup? && !resource_access_token_creation_allowed
errors.add(:resource_access_token_creation_allowed, _('is not allowed since the group is not top-level group.'))
end
end
end
NamespaceSetting.prepend_mod_with('NamespaceSetting')
|