gitlab 4.12.0 → 4.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +24 -16
- data/lib/gitlab/api.rb +2 -0
- data/lib/gitlab/cli.rb +6 -5
- data/lib/gitlab/cli_helpers.rb +10 -16
- data/lib/gitlab/client/build_variables.rb +17 -12
- data/lib/gitlab/client/commits.rb +42 -5
- data/lib/gitlab/client/container_registry.rb +1 -1
- data/lib/gitlab/client/epic_issues.rb +23 -0
- data/lib/gitlab/client/epics.rb +73 -0
- data/lib/gitlab/client/group_badges.rb +88 -0
- data/lib/gitlab/client/group_labels.rb +1 -1
- data/lib/gitlab/client/groups.rb +247 -2
- data/lib/gitlab/client/issue_links.rb +48 -0
- data/lib/gitlab/client/issues.rb +12 -1
- data/lib/gitlab/client/jobs.rb +91 -8
- data/lib/gitlab/client/keys.rb +11 -0
- data/lib/gitlab/client/labels.rb +1 -1
- data/lib/gitlab/client/merge_request_approvals.rb +155 -2
- data/lib/gitlab/client/merge_requests.rb +76 -4
- data/lib/gitlab/client/merge_trains.rb +55 -0
- data/lib/gitlab/client/notes.rb +27 -0
- data/lib/gitlab/client/packages.rb +95 -0
- data/lib/gitlab/client/pipeline_schedules.rb +16 -4
- data/lib/gitlab/client/pipelines.rb +37 -0
- data/lib/gitlab/client/project_exports.rb +54 -0
- data/lib/gitlab/client/project_releases.rb +11 -0
- data/lib/gitlab/client/projects.rb +119 -7
- data/lib/gitlab/client/remote_mirrors.rb +51 -0
- data/lib/gitlab/client/repositories.rb +56 -1
- data/lib/gitlab/client/repository_files.rb +16 -0
- data/lib/gitlab/client/resource_state_events.rb +57 -0
- data/lib/gitlab/client/runners.rb +126 -21
- data/lib/gitlab/client/search.rb +5 -1
- data/lib/gitlab/client/user_snippets.rb +114 -0
- data/lib/gitlab/client/users.rb +267 -12
- data/lib/gitlab/client.rb +16 -2
- data/lib/gitlab/configuration.rb +1 -1
- data/lib/gitlab/error.rb +36 -1
- data/lib/gitlab/headers/page_links.rb +37 -0
- data/lib/gitlab/headers/total.rb +29 -0
- data/lib/gitlab/help.rb +8 -8
- data/lib/gitlab/objectified_hash.rb +23 -7
- data/lib/gitlab/paginated_response.rb +29 -40
- data/lib/gitlab/request.rb +35 -21
- data/lib/gitlab/shell_history.rb +2 -2
- data/lib/gitlab/version.rb +1 -1
- data/lib/gitlab.rb +17 -6
- metadata +24 -48
- data/lib/gitlab/page_links.rb +0 -35
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Gitlab::Client
|
|
4
|
+
# Defines methods related to user snippets.
|
|
5
|
+
# @see https://docs.gitlab.com/ce/api/snippets.html
|
|
6
|
+
module UserSnippets
|
|
7
|
+
# Get a list of the snippets of the current user.
|
|
8
|
+
#
|
|
9
|
+
# @example
|
|
10
|
+
# Gitlab.user_snippets
|
|
11
|
+
#
|
|
12
|
+
# @return [Array<Gitlab::ObjectifiedHash>] List of snippets of current user
|
|
13
|
+
def user_snippets
|
|
14
|
+
get('/snippets')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Get a single snippet.
|
|
18
|
+
#
|
|
19
|
+
# @example
|
|
20
|
+
# Gitlab.user_snippet(1)
|
|
21
|
+
#
|
|
22
|
+
# @param [Integer] id ID of snippet to retrieve.
|
|
23
|
+
# @return [Gitlab::ObjectifiedHash] Information about the user snippet
|
|
24
|
+
def user_snippet(id)
|
|
25
|
+
get("/snippets/#{id}")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Get raw contents of a single snippet.
|
|
29
|
+
#
|
|
30
|
+
# @example
|
|
31
|
+
# Gitlab.user_snippet_raw(1)
|
|
32
|
+
#
|
|
33
|
+
# @param [Integer] id ID of snippet to retrieve.
|
|
34
|
+
# @return [String] User snippet text
|
|
35
|
+
def user_snippet_raw(id)
|
|
36
|
+
get("/snippets/#{id}/raw",
|
|
37
|
+
format: nil,
|
|
38
|
+
headers: { Accept: 'text/plain' },
|
|
39
|
+
parser: ::Gitlab::Request::Parser)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Create a new snippet.
|
|
43
|
+
#
|
|
44
|
+
# @example
|
|
45
|
+
# Gitlab.create_user_snippet({ title: 'REST', file_name: 'api.rb', content: 'some code', description: 'Hello World snippet', visibility: 'public'})
|
|
46
|
+
#
|
|
47
|
+
# @param [Hash] options A customizable set of options.
|
|
48
|
+
# @option options [String] :title (required) Title of a snippet.
|
|
49
|
+
# @option options [String] :file_name (required) Name of a snippet file.
|
|
50
|
+
# @option options [String] :content (required) Content of a snippet.
|
|
51
|
+
# @option options [String] :description (optional) Description of a snippet.
|
|
52
|
+
# @option options [String] :visibility (optional) visibility of a snippet.
|
|
53
|
+
# @return [Gitlab::ObjectifiedHash] Information about created snippet.
|
|
54
|
+
def create_user_snippet(options = {})
|
|
55
|
+
post('/snippets', body: options)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Update an existing snippet.
|
|
59
|
+
#
|
|
60
|
+
# @example
|
|
61
|
+
# Gitlab.edit_user_snippet(34, { file_name: 'README.txt' })
|
|
62
|
+
# Gitlab.edit_user_snippet(34, { file_name: 'README.txt', title: 'New title' })
|
|
63
|
+
#
|
|
64
|
+
# @param [Integer] id ID of snippet to update.
|
|
65
|
+
# @param [Hash] options A customizable set of options.
|
|
66
|
+
# @option options [String] :title (optional) Title of a snippet.
|
|
67
|
+
# @option options [String] :file_name (optional) Name of a snippet file.
|
|
68
|
+
# @option options [String] :content (optional) Content of a snippet.
|
|
69
|
+
# @option options [String] :description (optional) Description of a snippet.
|
|
70
|
+
# @option options [String] :visibility (optional) visibility of a snippet.
|
|
71
|
+
# @return [Gitlab::ObjectifiedHash] Information about updated snippet.
|
|
72
|
+
def edit_user_snippet(id, options = {})
|
|
73
|
+
put("/snippets/#{id}", body: options)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Delete an existing snippet.
|
|
77
|
+
#
|
|
78
|
+
# @example
|
|
79
|
+
# Gitlab.delete_user_snippet(14)
|
|
80
|
+
#
|
|
81
|
+
# @param [Integer] id ID of snippet to delete.
|
|
82
|
+
# @return [void] This API call returns an empty response body.
|
|
83
|
+
def delete_user_snippet(id)
|
|
84
|
+
delete("/snippets/#{id}")
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# List all public snippets.
|
|
88
|
+
#
|
|
89
|
+
# @example
|
|
90
|
+
# Gitlab.public_snippets
|
|
91
|
+
# Gitlab.public_snippets(per_page: 2, page: 1)
|
|
92
|
+
#
|
|
93
|
+
# @param [Hash] options A customizable set of options.
|
|
94
|
+
# @option options [String] :per_page (optional) Number of snippets to return per page.
|
|
95
|
+
# @option options [String] :page (optional) Page to retrieve.
|
|
96
|
+
#
|
|
97
|
+
# @return [Array<Gitlab::ObjectifiedHash>] List of all public snippets
|
|
98
|
+
def public_snippets(options = {})
|
|
99
|
+
get('/snippets/public', query: options)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Get user agent details for a snippet.
|
|
103
|
+
#
|
|
104
|
+
# @example
|
|
105
|
+
# Gitlab.snippet_user_agent_details(1)
|
|
106
|
+
#
|
|
107
|
+
# @param [Integer] id ID of snippet to delete.
|
|
108
|
+
#
|
|
109
|
+
# @return [Array<Gitlab::ObjectifiedHash>] Details of the user agent
|
|
110
|
+
def snippet_user_agent_details(id)
|
|
111
|
+
get("/snippets/#{id}/user_agent_detail")
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
data/lib/gitlab/client/users.rb
CHANGED
|
@@ -37,11 +37,11 @@ class Gitlab::Client
|
|
|
37
37
|
# @example
|
|
38
38
|
# Gitlab.create_user('joe@foo.org', 'secret', 'joe', { name: 'Joe Smith' })
|
|
39
39
|
# or
|
|
40
|
-
# Gitlab.create_user('joe@foo.org', 'secret')
|
|
40
|
+
# Gitlab.create_user('joe@foo.org', 'secret', 'joe')
|
|
41
41
|
#
|
|
42
|
-
# @param [String] email The email of a user.
|
|
43
|
-
# @param [String] password The password of a user.
|
|
44
|
-
# @param [String] username The username of a user.
|
|
42
|
+
# @param [String] email(required) The email of a user.
|
|
43
|
+
# @param [String] password(required) The password of a user.
|
|
44
|
+
# @param [String] username(required) The username of a user.
|
|
45
45
|
# @param [Hash] options A customizable set of options.
|
|
46
46
|
# @option options [String] :name The name of a user. Defaults to email.
|
|
47
47
|
# @option options [String] :skype The skype of a user.
|
|
@@ -51,15 +51,29 @@ class Gitlab::Client
|
|
|
51
51
|
# @return [Gitlab::ObjectifiedHash] Information about created user.
|
|
52
52
|
def create_user(*args)
|
|
53
53
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
{ email: args[0], password: args[1], name: args[0] }
|
|
58
|
-
end
|
|
54
|
+
raise ArgumentError, 'Missing required parameters' unless args[2]
|
|
55
|
+
|
|
56
|
+
body = { email: args[0], password: args[1], username: args[2], name: args[0] }
|
|
59
57
|
body.merge!(options)
|
|
60
58
|
post('/users', body: body)
|
|
61
59
|
end
|
|
62
60
|
|
|
61
|
+
# Creates a service account.
|
|
62
|
+
# Requires authentication from an admin account.
|
|
63
|
+
#
|
|
64
|
+
# @example
|
|
65
|
+
# Gitlab.create_service_account('service_account_6018816a18e515214e0c34c2b33523fc', 'Service account user')
|
|
66
|
+
#
|
|
67
|
+
# @param [String] name (required) The email of the service account.
|
|
68
|
+
# @param [String] username (required) The username of the service account.
|
|
69
|
+
# @return [Gitlab::ObjectifiedHash] Information about created service account.
|
|
70
|
+
def create_service_account(*args)
|
|
71
|
+
raise ArgumentError, 'Missing required parameters' unless args[1]
|
|
72
|
+
|
|
73
|
+
body = { name: args[0], username: args[1] }
|
|
74
|
+
post('/service_accounts', body: body)
|
|
75
|
+
end
|
|
76
|
+
|
|
63
77
|
# Updates a user.
|
|
64
78
|
#
|
|
65
79
|
# @example
|
|
@@ -112,6 +126,39 @@ class Gitlab::Client
|
|
|
112
126
|
post("/users/#{user_id}/unblock")
|
|
113
127
|
end
|
|
114
128
|
|
|
129
|
+
# Deactivates the specified user. Available only for admin.
|
|
130
|
+
#
|
|
131
|
+
# @example
|
|
132
|
+
# Gitlab.deactivate_user(15)
|
|
133
|
+
#
|
|
134
|
+
# @param [Integer] user_id The Id of user
|
|
135
|
+
# @return [Boolean] success or not
|
|
136
|
+
def deactivate_user(user_id)
|
|
137
|
+
post("/users/#{user_id}/deactivate")
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Activate the specified user. Available only for admin.
|
|
141
|
+
#
|
|
142
|
+
# @example
|
|
143
|
+
# Gitlab.activate_user(15)
|
|
144
|
+
#
|
|
145
|
+
# @param [Integer] user_id The Id of user
|
|
146
|
+
# @return [Boolean] success or not
|
|
147
|
+
def activate_user(user_id)
|
|
148
|
+
post("/users/#{user_id}/activate")
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# Approves the specified user. Available only for admin.
|
|
152
|
+
#
|
|
153
|
+
# @example
|
|
154
|
+
# Gitlab.approve_user(15)
|
|
155
|
+
#
|
|
156
|
+
# @param [Integer] user_id The Id of user
|
|
157
|
+
# @return [Boolean] success or not
|
|
158
|
+
def approve_user(user_id)
|
|
159
|
+
post("/users/#{user_id}/approve")
|
|
160
|
+
end
|
|
161
|
+
|
|
115
162
|
# Creates a new user session.
|
|
116
163
|
#
|
|
117
164
|
# @example
|
|
@@ -125,6 +172,20 @@ class Gitlab::Client
|
|
|
125
172
|
post('/session', body: { email: email, password: password }, unauthenticated: true)
|
|
126
173
|
end
|
|
127
174
|
|
|
175
|
+
# Gets a list of user activities (for admin access only).
|
|
176
|
+
#
|
|
177
|
+
# @example
|
|
178
|
+
# Gitlab.activities
|
|
179
|
+
#
|
|
180
|
+
# @param [Hash] options A customizable set of options.
|
|
181
|
+
# @option options [Integer] :page The page number.
|
|
182
|
+
# @option options [Integer] :per_page The number of results per page.
|
|
183
|
+
# @option options [String] :from The start date for paginated results.
|
|
184
|
+
# @return [Array<Gitlab::ObjectifiedHash>]
|
|
185
|
+
def activities(options = {})
|
|
186
|
+
get('/user/activities', query: options)
|
|
187
|
+
end
|
|
188
|
+
|
|
128
189
|
# Gets a list of user's SSH keys.
|
|
129
190
|
#
|
|
130
191
|
# @example
|
|
@@ -227,10 +288,15 @@ class Gitlab::Client
|
|
|
227
288
|
#
|
|
228
289
|
# @param [String] email Email address
|
|
229
290
|
# @param [Integer] user_id The ID of a user.
|
|
291
|
+
# @param [Boolean] skip_confirmation Skip confirmation and assume e-mail is verified
|
|
230
292
|
# @return [Gitlab::ObjectifiedHash]
|
|
231
|
-
def add_email(email, user_id = nil)
|
|
293
|
+
def add_email(email, user_id = nil, skip_confirmation = nil)
|
|
232
294
|
url = user_id.to_i.zero? ? '/user/emails' : "/users/#{user_id}/emails"
|
|
233
|
-
|
|
295
|
+
if skip_confirmation.nil?
|
|
296
|
+
post(url, body: { email: email })
|
|
297
|
+
else
|
|
298
|
+
post(url, body: { email: email, skip_confirmation: skip_confirmation })
|
|
299
|
+
end
|
|
234
300
|
end
|
|
235
301
|
|
|
236
302
|
# Delete email
|
|
@@ -248,7 +314,7 @@ class Gitlab::Client
|
|
|
248
314
|
delete(url)
|
|
249
315
|
end
|
|
250
316
|
|
|
251
|
-
# Search for
|
|
317
|
+
# Search for users by name
|
|
252
318
|
#
|
|
253
319
|
# @example
|
|
254
320
|
# Gitlab.user_search('gitlab')
|
|
@@ -262,5 +328,194 @@ class Gitlab::Client
|
|
|
262
328
|
options[:search] = search
|
|
263
329
|
get('/users', query: options)
|
|
264
330
|
end
|
|
331
|
+
|
|
332
|
+
# Get user by username
|
|
333
|
+
#
|
|
334
|
+
# @example
|
|
335
|
+
# Gitlab.user_by_username('gitlab')
|
|
336
|
+
#
|
|
337
|
+
# @param [String] username A username to get.
|
|
338
|
+
# @param [Hash] options A customizable set of options.
|
|
339
|
+
# @return [Array<Gitlab::ObjectifiedHash>]
|
|
340
|
+
def user_by_username(username, options = {})
|
|
341
|
+
options[:username] = username
|
|
342
|
+
get('/users', query: options)
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
# Gets user custom_attributes.
|
|
346
|
+
#
|
|
347
|
+
# @example
|
|
348
|
+
# Gitlab.user_custom_attributes(2)
|
|
349
|
+
#
|
|
350
|
+
# @param [Integer] user_id The ID of a user.
|
|
351
|
+
# @return [Gitlab::ObjectifiedHash]
|
|
352
|
+
def user_custom_attributes(user_id)
|
|
353
|
+
get("/users/#{user_id}/custom_attributes")
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
# Gets single user custom_attribute.
|
|
357
|
+
#
|
|
358
|
+
# @example
|
|
359
|
+
# Gitlab.user_custom_attribute(key, 2)
|
|
360
|
+
#
|
|
361
|
+
# @param [String] key The custom_attributes key
|
|
362
|
+
# @param [Integer] user_id The ID of a user.
|
|
363
|
+
# @return [Gitlab::ObjectifiedHash]
|
|
364
|
+
def user_custom_attribute(key, user_id)
|
|
365
|
+
get("/users/#{user_id}/custom_attributes/#{key}")
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
# Creates a new custom_attribute
|
|
369
|
+
#
|
|
370
|
+
# @example
|
|
371
|
+
# Gitlab.add_custom_attribute('some_new_key', 'some_new_value', 2)
|
|
372
|
+
#
|
|
373
|
+
# @param [String] key The custom_attributes key
|
|
374
|
+
# @param [String] value The custom_attributes value
|
|
375
|
+
# @param [Integer] user_id The ID of a user.
|
|
376
|
+
# @return [Gitlab::ObjectifiedHash]
|
|
377
|
+
def add_user_custom_attribute(key, value, user_id)
|
|
378
|
+
url = "/users/#{user_id}/custom_attributes/#{key}"
|
|
379
|
+
put(url, body: { value: value })
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
# Delete custom_attribute
|
|
383
|
+
# Will delete a custom_attribute
|
|
384
|
+
#
|
|
385
|
+
# @example
|
|
386
|
+
# Gitlab.delete_user_custom_attribute('somekey', 2)
|
|
387
|
+
#
|
|
388
|
+
# @param [String] key The custom_attribute key to delete
|
|
389
|
+
# @param [Integer] user_id The ID of a user.
|
|
390
|
+
# @return [Boolean]
|
|
391
|
+
def delete_user_custom_attribute(key, user_id)
|
|
392
|
+
delete("/users/#{user_id}/custom_attributes/#{key}")
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
# Get all impersonation tokens for a user
|
|
396
|
+
#
|
|
397
|
+
# @example
|
|
398
|
+
# Gitlab.user_impersonation_tokens(1)
|
|
399
|
+
#
|
|
400
|
+
# @param [Integer] user_id The ID of the user.
|
|
401
|
+
# @param [String] state Filter impersonation tokens by state {}
|
|
402
|
+
# @return [Array<Gitlab::ObjectifiedHash>]
|
|
403
|
+
def user_impersonation_tokens(user_id)
|
|
404
|
+
get("/users/#{user_id}/impersonation_tokens")
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
# Get impersonation token information
|
|
408
|
+
#
|
|
409
|
+
# @example
|
|
410
|
+
# Gitlab.user_impersonation_token(1, 1)
|
|
411
|
+
#
|
|
412
|
+
# @param [Integer] user_id The ID of the user.
|
|
413
|
+
# @param [Integer] impersonation_token_id ID of the impersonation token.
|
|
414
|
+
# @return [Gitlab::ObjectifiedHash]
|
|
415
|
+
def user_impersonation_token(user_id, impersonation_token_id)
|
|
416
|
+
get("/users/#{user_id}/impersonation_tokens/#{impersonation_token_id}")
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
# Create impersonation token
|
|
420
|
+
#
|
|
421
|
+
# @example
|
|
422
|
+
# Gitlab.create_user_impersonation_token(2, "token", ["api", "read_user"])
|
|
423
|
+
# Gitlab.create_user_impersonation_token(2, "token", ["api", "read_user"], "1970-01-01")
|
|
424
|
+
#
|
|
425
|
+
# @param [Integer] user_id The ID of the user.
|
|
426
|
+
# @param [String] name Name for impersonation token.
|
|
427
|
+
# @param [Array<String>] scopes Array of scopes for the impersonation token
|
|
428
|
+
# @param [String] expires_at Date for impersonation token expiration in ISO format.
|
|
429
|
+
# @return [Gitlab::ObjectifiedHash]
|
|
430
|
+
def create_user_impersonation_token(user_id, name, scopes, expires_at = nil)
|
|
431
|
+
body = { name: name, scopes: scopes }
|
|
432
|
+
body[:expires_at] = expires_at if expires_at
|
|
433
|
+
post("/users/#{user_id}/impersonation_tokens", body: body)
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
# Get all personal access tokens for a user
|
|
437
|
+
#
|
|
438
|
+
# @example
|
|
439
|
+
# Gitlab.user_personal_access_tokens(1)
|
|
440
|
+
#
|
|
441
|
+
# @param [Integer] user_id The ID of the user.
|
|
442
|
+
# @return [Array<Gitlab::ObjectifiedHash>]
|
|
443
|
+
def user_personal_access_tokens(user_id)
|
|
444
|
+
get("/personal_access_tokens?user_id=#{user_id}")
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
# Create personal access token
|
|
448
|
+
#
|
|
449
|
+
# @example
|
|
450
|
+
# Gitlab.create_personal_access_token(2, "token", ["api", "read_user"])
|
|
451
|
+
# Gitlab.create_personal_access_token(2, "token", ["api", "read_user"], "1970-01-01")
|
|
452
|
+
#
|
|
453
|
+
# @param [Integer] user_id The ID of the user.
|
|
454
|
+
# @param [String] name Name of the personal access token.
|
|
455
|
+
# @param [Array<String>] scopes Array of scopes for the impersonation token
|
|
456
|
+
# @param [String] expires_at Date for impersonation token expiration in ISO format.
|
|
457
|
+
# @return [Gitlab::ObjectifiedHash]
|
|
458
|
+
def create_personal_access_token(user_id, name, scopes, expires_at = nil)
|
|
459
|
+
body = { name: name, scopes: scopes }
|
|
460
|
+
body[:expires_at] = expires_at if expires_at
|
|
461
|
+
post("/users/#{user_id}/personal_access_tokens", body: body)
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
# Rotate a personal access token
|
|
465
|
+
#
|
|
466
|
+
# @example
|
|
467
|
+
# Gitlab.rotate_personal_access_token(1)
|
|
468
|
+
#
|
|
469
|
+
# @param [Integer] personal_access_token_id ID of the personal access token.
|
|
470
|
+
# @return [Gitlab::ObjectifiedHash]
|
|
471
|
+
def rotate_personal_access_token(personal_access_token_id, expires_at = nil)
|
|
472
|
+
body = {}
|
|
473
|
+
body[:expires_at] = expires_at if expires_at
|
|
474
|
+
post("/personal_access_tokens/#{personal_access_token_id}/rotate", body: body)
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
# Revoke an impersonation token
|
|
478
|
+
#
|
|
479
|
+
# @example
|
|
480
|
+
# Gitlab.revoke_user_impersonation_token(1, 1)
|
|
481
|
+
#
|
|
482
|
+
# @param [Integer] user_id The ID of the user.
|
|
483
|
+
# @param [Integer] impersonation_token_id ID of the impersonation token.
|
|
484
|
+
# @return [Gitlab::ObjectifiedHash]
|
|
485
|
+
def revoke_user_impersonation_token(user_id, impersonation_token_id)
|
|
486
|
+
delete("/users/#{user_id}/impersonation_tokens/#{impersonation_token_id}")
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
# Lists all projects and groups a user is a member of
|
|
490
|
+
#
|
|
491
|
+
# @example
|
|
492
|
+
# Gitlab.memberships(2)
|
|
493
|
+
#
|
|
494
|
+
# @param [Integer] user_id The ID of the user.
|
|
495
|
+
def memberships(user_id)
|
|
496
|
+
get("/users/#{user_id}/memberships")
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
# Revoke a personal access token
|
|
500
|
+
#
|
|
501
|
+
# @example
|
|
502
|
+
# Gitlab.revoke_personal_access_token(1)
|
|
503
|
+
#
|
|
504
|
+
# @param [Integer] personal_access_token_id ID of the personal access token.
|
|
505
|
+
# @return [Gitlab::ObjectifiedHash]
|
|
506
|
+
def revoke_personal_access_token(personal_access_token_id)
|
|
507
|
+
delete("/personal_access_tokens/#{personal_access_token_id}")
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
# Disables two factor authentication (2FA) for the specified user.
|
|
511
|
+
#
|
|
512
|
+
# @example
|
|
513
|
+
# Gitlab.disable_two_factor(1)
|
|
514
|
+
#
|
|
515
|
+
# @param [Integer] id The ID of a user.
|
|
516
|
+
# @return [Gitlab::ObjectifiedHash]
|
|
517
|
+
def disable_two_factor(user_id)
|
|
518
|
+
patch("/users/#{user_id}/disable_two_factor")
|
|
519
|
+
end
|
|
265
520
|
end
|
|
266
521
|
end
|
data/lib/gitlab/client.rb
CHANGED
|
@@ -19,12 +19,16 @@ module Gitlab
|
|
|
19
19
|
include ContainerRegistry
|
|
20
20
|
include Deployments
|
|
21
21
|
include Environments
|
|
22
|
+
include EpicIssues
|
|
23
|
+
include Epics
|
|
22
24
|
include Events
|
|
23
25
|
include Features
|
|
26
|
+
include GroupBadges
|
|
24
27
|
include GroupBoards
|
|
25
28
|
include GroupLabels
|
|
26
29
|
include GroupMilestones
|
|
27
30
|
include Groups
|
|
31
|
+
include IssueLinks
|
|
28
32
|
include Issues
|
|
29
33
|
include Jobs
|
|
30
34
|
include Keys
|
|
@@ -33,22 +37,27 @@ module Gitlab
|
|
|
33
37
|
include Markdown
|
|
34
38
|
include MergeRequestApprovals
|
|
35
39
|
include MergeRequests
|
|
40
|
+
include MergeTrains
|
|
36
41
|
include Milestones
|
|
37
42
|
include Namespaces
|
|
38
43
|
include Notes
|
|
44
|
+
include Packages
|
|
39
45
|
include PipelineSchedules
|
|
40
46
|
include PipelineTriggers
|
|
41
47
|
include Pipelines
|
|
42
48
|
include ProjectBadges
|
|
43
49
|
include ProjectClusters
|
|
50
|
+
include ProjectExports
|
|
44
51
|
include ProjectReleaseLinks
|
|
45
52
|
include ProjectReleases
|
|
46
53
|
include Projects
|
|
47
54
|
include ProtectedTags
|
|
55
|
+
include RemoteMirrors
|
|
48
56
|
include Repositories
|
|
49
57
|
include RepositoryFiles
|
|
50
58
|
include RepositorySubmodules
|
|
51
59
|
include ResourceLabelEvents
|
|
60
|
+
include ResourceStateEvents
|
|
52
61
|
include Runners
|
|
53
62
|
include Search
|
|
54
63
|
include Services
|
|
@@ -59,6 +68,7 @@ module Gitlab
|
|
|
59
68
|
include Templates
|
|
60
69
|
include Todos
|
|
61
70
|
include Users
|
|
71
|
+
include UserSnippets
|
|
62
72
|
include Versions
|
|
63
73
|
include Wikis
|
|
64
74
|
|
|
@@ -71,14 +81,18 @@ module Gitlab
|
|
|
71
81
|
inspected
|
|
72
82
|
end
|
|
73
83
|
|
|
84
|
+
# Utility method for URL encoding of a string.
|
|
85
|
+
# Copied from https://ruby-doc.org/stdlib-2.7.0/libdoc/erb/rdoc/ERB/Util.html
|
|
86
|
+
#
|
|
87
|
+
# @return [String]
|
|
74
88
|
def url_encode(url)
|
|
75
|
-
|
|
89
|
+
url.to_s.b.gsub(/[^a-zA-Z0-9_\-.~]/n) { |m| sprintf('%%%02X', m.unpack1('C')) } # rubocop:disable Style/FormatString
|
|
76
90
|
end
|
|
77
91
|
|
|
78
92
|
private
|
|
79
93
|
|
|
80
94
|
def only_show_last_four_chars(token)
|
|
81
|
-
"#{'*' * (token.size - 4)}#{token[-4
|
|
95
|
+
"#{'*' * (token.size - 4)}#{token[-4..]}"
|
|
82
96
|
end
|
|
83
97
|
end
|
|
84
98
|
end
|
data/lib/gitlab/configuration.rb
CHANGED
|
@@ -35,7 +35,7 @@ module Gitlab
|
|
|
35
35
|
|
|
36
36
|
# Resets all configuration options to the defaults.
|
|
37
37
|
def reset
|
|
38
|
-
self.endpoint = ENV['GITLAB_API_ENDPOINT']
|
|
38
|
+
self.endpoint = ENV['GITLAB_API_ENDPOINT'] || ENV['CI_API_V4_URL']
|
|
39
39
|
self.private_token = ENV['GITLAB_API_PRIVATE_TOKEN'] || ENV['GITLAB_API_AUTH_TOKEN']
|
|
40
40
|
self.httparty = get_httparty_config(ENV['GITLAB_API_HTTPARTY_OPTIONS'])
|
|
41
41
|
self.sudo = nil
|
data/lib/gitlab/error.rb
CHANGED
|
@@ -34,6 +34,17 @@ module Gitlab
|
|
|
34
34
|
@response.parsed_response.message
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
# Additional error context returned by some API endpoints
|
|
38
|
+
#
|
|
39
|
+
# @return [String]
|
|
40
|
+
def error_code
|
|
41
|
+
if @response.respond_to?(:error_code)
|
|
42
|
+
@response.error_code
|
|
43
|
+
else
|
|
44
|
+
''
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
37
48
|
private
|
|
38
49
|
|
|
39
50
|
# Human friendly message.
|
|
@@ -63,6 +74,14 @@ module Gitlab
|
|
|
63
74
|
else
|
|
64
75
|
@response.parsed_response
|
|
65
76
|
end
|
|
77
|
+
rescue Gitlab::Error::Parsing
|
|
78
|
+
# Return stringified response when receiving a
|
|
79
|
+
# parsing error to avoid obfuscation of the
|
|
80
|
+
# api error.
|
|
81
|
+
#
|
|
82
|
+
# note: The Gitlab API does not always return valid
|
|
83
|
+
# JSON when there are errors.
|
|
84
|
+
@response.to_s
|
|
66
85
|
end
|
|
67
86
|
|
|
68
87
|
# Handle error response message in case of nested hashes
|
|
@@ -116,6 +135,9 @@ module Gitlab
|
|
|
116
135
|
# Raised when API endpoint returns the HTTP status code 503.
|
|
117
136
|
class ServiceUnavailable < ResponseError; end
|
|
118
137
|
|
|
138
|
+
# Raised when API endpoint returns the HTTP status code 522.
|
|
139
|
+
class ConnectionTimedOut < ResponseError; end
|
|
140
|
+
|
|
119
141
|
# HTTP status codes mapped to error classes.
|
|
120
142
|
STATUS_MAPPINGS = {
|
|
121
143
|
400 => BadRequest,
|
|
@@ -129,7 +151,20 @@ module Gitlab
|
|
|
129
151
|
429 => TooManyRequests,
|
|
130
152
|
500 => InternalServerError,
|
|
131
153
|
502 => BadGateway,
|
|
132
|
-
503 => ServiceUnavailable
|
|
154
|
+
503 => ServiceUnavailable,
|
|
155
|
+
522 => ConnectionTimedOut
|
|
133
156
|
}.freeze
|
|
157
|
+
|
|
158
|
+
# Returns error class that should be raised for this response. Returns nil
|
|
159
|
+
# if the response status code is not 4xx or 5xx.
|
|
160
|
+
#
|
|
161
|
+
# @param [HTTParty::Response] response The response object.
|
|
162
|
+
# @return [Class<Error::ResponseError>, nil]
|
|
163
|
+
def self.klass(response)
|
|
164
|
+
error_klass = STATUS_MAPPINGS[response.code]
|
|
165
|
+
return error_klass if error_klass
|
|
166
|
+
|
|
167
|
+
ResponseError if response.server_error? || response.client_error?
|
|
168
|
+
end
|
|
134
169
|
end
|
|
135
170
|
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Gitlab
|
|
4
|
+
module Headers
|
|
5
|
+
# Parses link header.
|
|
6
|
+
#
|
|
7
|
+
# @private
|
|
8
|
+
class PageLinks
|
|
9
|
+
HEADER_LINK = 'Link'
|
|
10
|
+
DELIM_LINKS = ','
|
|
11
|
+
LINK_REGEX = /<([^>]+)>; rel="([^"]+)"/.freeze
|
|
12
|
+
METAS = %w[last next first prev].freeze
|
|
13
|
+
|
|
14
|
+
attr_accessor(*METAS)
|
|
15
|
+
|
|
16
|
+
def initialize(headers)
|
|
17
|
+
link_header = headers[HEADER_LINK]
|
|
18
|
+
|
|
19
|
+
extract_links(link_header) if link_header && link_header =~ /(next|first|last|prev)/
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def extract_links(header)
|
|
25
|
+
header.split(DELIM_LINKS).each do |link|
|
|
26
|
+
LINK_REGEX.match(link.strip) do |match|
|
|
27
|
+
url = match[1]
|
|
28
|
+
meta = match[2]
|
|
29
|
+
next if !url || !meta || METAS.index(meta).nil?
|
|
30
|
+
|
|
31
|
+
send("#{meta}=", url)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Gitlab
|
|
4
|
+
module Headers
|
|
5
|
+
# Parses total header.
|
|
6
|
+
#
|
|
7
|
+
# @private
|
|
8
|
+
class Total
|
|
9
|
+
HEADER_TOTAL = 'x-total'
|
|
10
|
+
TOTAL_REGEX = /^\d+$/.freeze
|
|
11
|
+
|
|
12
|
+
attr_accessor :total
|
|
13
|
+
|
|
14
|
+
def initialize(headers)
|
|
15
|
+
header_total = headers[HEADER_TOTAL]
|
|
16
|
+
|
|
17
|
+
extract_total(header_total) if header_total
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def extract_total(header_total)
|
|
23
|
+
TOTAL_REGEX.match(header_total.strip) do |match|
|
|
24
|
+
@total = match[0]
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|