blob: 94ae29af3d0f2635866ddd3cd102d595b33b5d17 (
plain)
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
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
166
167
168
169
170
171
172
173
174
175
176
177
178
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
|
# frozen_string_literal: true
module Gitlab
module RackAttack
module Request
FILES_PATH_REGEX = %r{^/api/v\d+/projects/[^/]+/repository/files/.+}.freeze
GROUP_PATH_REGEX = %r{^/api/v\d+/groups/[^/]+/?$}.freeze
def unauthenticated?
!(authenticated_user_id([:api, :rss, :ics]) || authenticated_runner_id)
end
def throttled_user_id(request_formats)
user_id = authenticated_user_id(request_formats)
if Gitlab::RackAttack.user_allowlist.include?(user_id)
Gitlab::Instrumentation::Throttle.safelist = 'throttle_user_allowlist'
return
end
user_id
end
def authenticated_runner_id
request_authenticator.runner&.id
end
def api_request?
path.start_with?('/api')
end
def api_internal_request?
path =~ %r{^/api/v\d+/internal/}
end
def health_check_request?
path =~ %r{^/-/(health|liveness|readiness|metrics)}
end
def container_registry_event?
path =~ %r{^/api/v\d+/container_registry_event/}
end
def product_analytics_collector_request?
path.start_with?('/-/collector/i')
end
def should_be_skipped?
api_internal_request? || health_check_request? || container_registry_event?
end
def web_request?
!api_request? && !health_check_request?
end
def protected_path?
!protected_path_regex.nil?
end
def protected_path_regex
path =~ protected_paths_regex
end
def throttle?(throttle, authenticated:)
fragment = Gitlab::Throttle.throttle_fragment!(throttle, authenticated: authenticated)
__send__("#{fragment}?") # rubocop:disable GitlabSecurity/PublicSend
end
def throttle_unauthenticated_api?
api_request? &&
!should_be_skipped? &&
!throttle_unauthenticated_packages_api? &&
!throttle_unauthenticated_files_api? &&
!throttle_unauthenticated_deprecated_api? &&
Gitlab::Throttle.settings.throttle_unauthenticated_api_enabled &&
unauthenticated?
end
def throttle_unauthenticated_web?
web_request? &&
!should_be_skipped? &&
# TODO: Column will be renamed in https://gitlab.com/gitlab-org/gitlab/-/issues/340031
Gitlab::Throttle.settings.throttle_unauthenticated_enabled &&
unauthenticated?
end
def throttle_authenticated_api?
api_request? &&
!throttle_authenticated_packages_api? &&
!throttle_authenticated_files_api? &&
!throttle_authenticated_deprecated_api? &&
Gitlab::Throttle.settings.throttle_authenticated_api_enabled
end
def throttle_authenticated_web?
web_request? &&
!throttle_authenticated_git_lfs? &&
Gitlab::Throttle.settings.throttle_authenticated_web_enabled
end
def throttle_unauthenticated_protected_paths?
post? &&
!should_be_skipped? &&
protected_path? &&
Gitlab::Throttle.protected_paths_enabled? &&
unauthenticated?
end
def throttle_authenticated_protected_paths_api?
post? &&
api_request? &&
protected_path? &&
Gitlab::Throttle.protected_paths_enabled?
end
def throttle_authenticated_protected_paths_web?
post? &&
web_request? &&
protected_path? &&
Gitlab::Throttle.protected_paths_enabled?
end
def throttle_unauthenticated_packages_api?
packages_api_path? &&
Gitlab::Throttle.settings.throttle_unauthenticated_packages_api_enabled &&
unauthenticated?
end
def throttle_authenticated_packages_api?
packages_api_path? &&
Gitlab::Throttle.settings.throttle_authenticated_packages_api_enabled
end
def throttle_authenticated_git_lfs?
git_lfs_path? &&
Gitlab::Throttle.settings.throttle_authenticated_git_lfs_enabled
end
def throttle_unauthenticated_files_api?
files_api_path? &&
Gitlab::Throttle.settings.throttle_unauthenticated_files_api_enabled &&
unauthenticated?
end
def throttle_authenticated_files_api?
files_api_path? &&
Gitlab::Throttle.settings.throttle_authenticated_files_api_enabled
end
def throttle_unauthenticated_deprecated_api?
deprecated_api_request? &&
Gitlab::Throttle.settings.throttle_unauthenticated_deprecated_api_enabled &&
unauthenticated?
end
def throttle_authenticated_deprecated_api?
deprecated_api_request? &&
Gitlab::Throttle.settings.throttle_authenticated_deprecated_api_enabled
end
private
def authenticated_user_id(request_formats)
request_authenticator.user(request_formats)&.id
end
def request_authenticator
@request_authenticator ||= Gitlab::Auth::RequestAuthenticator.new(self)
end
def protected_paths
Gitlab::CurrentSettings.current_application_settings.protected_paths
end
def protected_paths_regex
Regexp.union(protected_paths.map { |path| /\A#{Regexp.escape(path)}/ })
end
def packages_api_path?
path =~ ::Gitlab::Regex::Packages::API_PATH_REGEX
end
def git_lfs_path?
path =~ Gitlab::PathRegex.repository_git_lfs_route_regex
end
def files_api_path?
path =~ FILES_PATH_REGEX
end
def deprecated_api_request?
# The projects member of the groups endpoint is deprecated. If left
# unspecified, with_projects defaults to true
with_projects = params['with_projects']
with_projects = true if with_projects.blank?
path =~ GROUP_PATH_REGEX && Gitlab::Utils.to_boolean(with_projects)
end
end
end
end
::Gitlab::RackAttack::Request.prepend_mod_with('Gitlab::RackAttack::Request')
|