From dcc0c5003f21bfbac6908dd4cc6a461cbc196627 Mon Sep 17 00:00:00 2001 From: Balasankar 'Balu' C Date: Fri, 13 Sep 2024 09:04:04 +0530 Subject: [PATCH 1/2] Add Project Access Token related endpoints Signed-off-by: Balasankar 'Balu' C --- lib/gitlab/client/projects.rb | 69 ++++++++++++++ .../fixtures/project_access_token_create.json | 16 ++++ spec/fixtures/project_access_token_get.json | 15 +++ .../project_access_tokens_get_all.json | 33 +++++++ spec/gitlab/client/projects_spec.rb | 92 +++++++++++++++++++ 5 files changed, 225 insertions(+) create mode 100644 spec/fixtures/project_access_token_create.json create mode 100644 spec/fixtures/project_access_token_get.json create mode 100644 spec/fixtures/project_access_tokens_get_all.json diff --git a/lib/gitlab/client/projects.rb b/lib/gitlab/client/projects.rb index 493c925be..962f3fe18 100644 --- a/lib/gitlab/client/projects.rb +++ b/lib/gitlab/client/projects.rb @@ -715,5 +715,74 @@ def project_deploy_tokens(project, options = {}) def project_languages(project) get("/projects/#{url_encode project}/languages") end + + # List all project access tokens. + # + # @example + # Gitlab.project_access_tokens(42) + # + # @param [Integer, String] project The ID or path of a project. + # @option options [String] :state Limit by active/inactive state. Optional. + # + # @return [Array] + def project_access_tokens(project, options = {}) + get("/projects/#{url_encode project}/access_tokens", query: options) + end + + # Get a specific project access token. + # + # @example + # Gitlab.project_access_token(42, 1234) + # + # @param [Integer, String] project The ID or path of a project. + # @param [Integer] token_id The ID of the project access token. + # + # @return [Gitlab::ObjectifiedHash] Information about the specified project access token. + def project_access_token(project, token_id, options = {}) + get("/projects/#{url_encode project}/access_tokens/#{token_id}", query: options) + end + + # Creates a new project access token. + # + # @example + # Gitlab.create_project_access_token(42, 'My Token', ['api'], '2024-12-12', access_level: 40) + # + # @param [Integer, String] project The ID or path of a project. + # @param [String] name The name of the project access token. + # @param [Array] scopes List of scopes of the project access token. + # @param [String] expires_at A date string in the format YYYY-MM-DD. + # @option options [Integer] :access_level Access level. Optional. Defaults to 40. + # + # @return [Gitlab::ObjectifiedHash] Information about the created project access token. + def create_project_access_token(project, name, scopes, expires_at, options = {}) + post("/projects/#{url_encode project}/access_tokens", body: { name: name, scopes: scopes, expires_at: expires_at }.merge(options)) + end + + # Rotate a project access token. + # + # @example + # Gitlab.rotate_project_access_token(42, 1234) + # + # @param [Integer, String] project The ID or path of a project. + # @param [Integer] token_id The ID of the project access token. + # @option options [String] :expires_at A date string in the format YEAR-MONTH-DAY. + # + # @return [Gitlab::ObjectifiedHash] Information about the specified project access token. + def rotate_project_access_token(project, token_id, options = {}) + post("/projects/#{url_encode project}/access_tokens/#{token_id}/rotate", query: options) + end + + # Revoke a project access token. + # + # @example + # Gitlab.revoke_project_access_token(42, 1234) + # + # @param [Integer, String] project The ID or path of a project. + # @param [Integer] token_id The ID of the project access token. + # + # @return [Gitlab::ObjectifiedHash] + def revoke_project_access_token(project, token_id) + delete("/projects/#{url_encode project}/access_tokens/#{token_id}") + end end end diff --git a/spec/fixtures/project_access_token_create.json b/spec/fixtures/project_access_token_create.json new file mode 100644 index 000000000..5aafe45ac --- /dev/null +++ b/spec/fixtures/project_access_token_create.json @@ -0,0 +1,16 @@ +{ + "id": 2, + "name": "Reporter Token", + "revoked": false, + "created_at": "2024-09-13T03:05:43.075Z", + "scopes": [ + "api" + ], + "user_id": 2, + "last_used_at": null, + "last_used_at": "2024-09-13T04:10:23.075Z", + "active": true, + "expires_at": "2024-09-20", + "access_level": 20, + "token": "glpat-aRandomStringAsToken" +} diff --git a/spec/fixtures/project_access_token_get.json b/spec/fixtures/project_access_token_get.json new file mode 100644 index 000000000..b973a916e --- /dev/null +++ b/spec/fixtures/project_access_token_get.json @@ -0,0 +1,15 @@ +{ + "id": 2, + "name": "Reporter Token", + "revoked": false, + "created_at": "2024-09-13T03:05:43.075Z", + "scopes": [ + "api" + ], + "user_id": 2, + "last_used_at": null, + "last_used_at": "2024-09-13T04:10:23.075Z", + "active": true, + "expires_at": "2024-09-20", + "access_level": 20 +} diff --git a/spec/fixtures/project_access_tokens_get_all.json b/spec/fixtures/project_access_tokens_get_all.json new file mode 100644 index 000000000..2a13f7ce2 --- /dev/null +++ b/spec/fixtures/project_access_tokens_get_all.json @@ -0,0 +1,33 @@ +[ + { + "id": 2, + "name": "Reporter Token", + "revoked": false, + "created_at": "2024-09-13T03:05:43.075Z", + "scopes": [ + "api" + ], + "user_id": 2, + "last_used_at": null, + "last_used_at": "2024-09-13T04:10:23.075Z", + "active": true, + "expires_at": "2024-09-20", + "access_level": 20 + }, + { + "id": 3, + "name": "Developer Token", + "revoked": false, + "created_at": "2024-09-13T03:06:20.075Z", + "scopes": [ + "read_api", + "read_repository" + ], + "user_id": 2, + "last_used_at": null, + "last_used_at": "2024-09-13T06:15:23.075Z", + "active": true, + "expires_at": "2024-09-25", + "access_level": 40 + } +] diff --git a/spec/gitlab/client/projects_spec.rb b/spec/gitlab/client/projects_spec.rb index db831a7f1..fd9874b33 100644 --- a/spec/gitlab/client/projects_spec.rb +++ b/spec/gitlab/client/projects_spec.rb @@ -937,4 +937,96 @@ expect(@project_languages.to_hash.keys).to contain_exactly('Ruby', 'Shell') end end + + describe '.project_access_tokens' do + before do + stub_get('/projects/2/access_tokens', 'project_access_tokens_get_all') + @tokens = Gitlab.project_access_tokens(2) + end + + it 'gets the correct resource' do + expect(a_get('/projects/2/access_tokens')).to have_been_made + end + + it 'gets an array of project access tokens' do + expect(@tokens.first.id).to eq(2) + expect(@tokens.last.id).to eq(3) + end + end + + describe '.project_access_token' do + before do + stub_get('/projects/2/access_tokens/2', 'project_access_token_get') + @token = Gitlab.project_access_token(2, 2) + end + + it 'gets the correct resource' do + expect(a_get('/projects/2/access_tokens/2')).to have_been_made + end + + it 'gets a project access token' do + expect(@token.user_id).to eq(2) + expect(@token.id).to eq(2) + expect(@token.access_level).to eq(20) + expect(@token.scopes).to eq(['api']) + expect(@token.name).to eq('Reporter Token') + end + end + + describe '.create_project_access_token' do + before do + stub_post('/projects/2/access_tokens', 'project_access_token_create') + @token = Gitlab.create_project_access_token(2, 'Reporter Token', ['api'], '2024-09-20') + end + + it 'posts the correct resource' do + expect(a_post('/projects/2/access_tokens').with(body: 'name=Reporter%20Token&scopes%5B%5D=api&expires_at=2024-09-20')).to have_been_made + end + + it 'returns a valid project access token' do + expect(@token.user_id).to eq(2) + expect(@token.id).to eq(2) + expect(@token.access_level).to eq(20) + expect(@token.scopes).to eq(['api']) + expect(@token.name).to eq('Reporter Token') + expect(@token.token).to eq('glpat-aRandomStringAsToken') + end + end + + describe '.rotate_project_access_token' do + before do + stub_post('/projects/2/access_tokens/2/rotate', 'project_access_token_create') + @token = Gitlab.rotate_project_access_token(2, 2) + end + + it 'posts the correct resource' do + expect(a_post('/projects/2/access_tokens/2/rotate')).to have_been_made + end + + it 'returns a valid project access token' do + expect(@token.user_id).to eq(2) + expect(@token.id).to eq(2) + expect(@token.access_level).to eq(20) + expect(@token.scopes).to eq(['api']) + expect(@token.name).to eq('Reporter Token') + expect(@token.token).to eq('glpat-aRandomStringAsToken') + end + end + + describe '.revoke_project_access_token' do + before do + stub_request(:delete, "#{Gitlab.endpoint}/projects/2/access_tokens/2") + .with(headers: { 'PRIVATE-TOKEN' => Gitlab.private_token }) + .to_return(status: 204) + @token = Gitlab.revoke_project_access_token(2, 2) + end + + it 'deletes the correct resource' do + expect(a_delete('/projects/2/access_tokens/2')).to have_been_made + end + + it 'removes a token' do + expect(@token.to_h).to be_empty + end + end end From ebcf3e72bf1c94f72286b016ae5376047cfe5490 Mon Sep 17 00:00:00 2001 From: Balasankar 'Balu' C Date: Fri, 13 Sep 2024 23:26:23 +0530 Subject: [PATCH 2/2] Add Project CI/CD variable related endpoints Signed-off-by: Balasankar 'Balu' C --- lib/gitlab/client/projects.rb | 80 ++++++++++++++++++++ spec/fixtures/project_variable_create.json | 11 +++ spec/fixtures/project_variable_get.json | 11 +++ spec/fixtures/project_variables_get_all.json | 24 ++++++ spec/gitlab/client/projects_spec.rb | 65 ++++++++++++++++ 5 files changed, 191 insertions(+) create mode 100644 spec/fixtures/project_variable_create.json create mode 100644 spec/fixtures/project_variable_get.json create mode 100644 spec/fixtures/project_variables_get_all.json diff --git a/lib/gitlab/client/projects.rb b/lib/gitlab/client/projects.rb index 962f3fe18..a5909e7da 100644 --- a/lib/gitlab/client/projects.rb +++ b/lib/gitlab/client/projects.rb @@ -784,5 +784,85 @@ def rotate_project_access_token(project, token_id, options = {}) def revoke_project_access_token(project, token_id) delete("/projects/#{url_encode project}/access_tokens/#{token_id}") end + + # List all project variables. + # + # @example + # Gitlab.project_variables(42) + # + # @param [Integer, String] project The ID or path of a project. + # + # @return [Array] + def project_variables(project, options = {}) + get("/projects/#{url_encode project}/variables", query: options) + end + + # Get a specific project variable. + # + # @example + # Gitlab.project_variable(42, 'MY_VAR') + # + # @param [Integer, String] project The ID or path of a project. + # @param [Integer] key The key of the variable. + # + # @return [Gitlab::ObjectifiedHash] Information about the specified project variable. + def project_variable(project, key, options = {}) + get("/projects/#{url_encode project}/variables/#{key}", query: options) + end + + # Creates a new project variable. + # + # @example + # Gitlab.create_project_variable(42, 'MY_VAR', 'Value of the variable') + # + # @param [Integer, String] project The ID or path of a project. + # @param [String] key The key of the project variable. + # @param [String] value The value of the project variable. + # @option options [String] :description Description for the project variable. + # @option options [String] :environment_scope The environment scope for the project variable. + # @option options [Boolean] :masked Whether the variable is masked. + # @option options [Boolean] :protected Whether the variable is protected. + # @option options [Boolean] :raw Whether the variable is raw. + # @option options [String] :variable_type The type of the project variable. + # + # @return [Gitlab::ObjectifiedHash] Information about the created project variable. + def create_project_variable(project, key, value, options = {}) + post("/projects/#{url_encode project}/variables", body: { key: key, value: value }.merge(options)) + end + + # Updates an existing project variable. + # + # @example + # Gitlab.update_project_variable(42, 'MY_VAR', 'Value of the variable') + # + # @param [Integer, String] project The ID or path of a project. + # @param [String] key The key of the project variable. + # @param [String] value The value of the project variable. + # @option options [String] :description Description for the project variable. + # @option options [String] :environment_scope The environment scope for the project variable. + # @option options [Boolean] :masked Whether the variable is masked. + # @option options [Boolean] :protected Whether the variable is protected. + # @option options [Boolean] :raw Whether the variable is raw. + # @option options [String] :variable_type The type of the project variable. + # @option options [Hash] :filter Filter the project variables considered. + # + # @return [Gitlab::ObjectifiedHash] Information about the updated project variable. + def update_project_variable(project, key, value, options = {}) + put("/projects/#{url_encode project}/variables", body: { key: key, value: value }.merge(options)) + end + + # Delete a project variable. + # + # @example + # Gitlab.delete_project_variable(42, 'MY_VAR') + # + # @param [Integer, String] project The ID or path of a project. + # @param [Integer] key The key of the project variable. + # @option options [Hash] :filter Filter the project variables considered. + # + # @return [Gitlab::ObjectifiedHash] + def delete_project_variable(project, key, options = {}) + delete("/projects/#{url_encode project}/variables/#{key}", query: options) + end end end diff --git a/spec/fixtures/project_variable_create.json b/spec/fixtures/project_variable_create.json new file mode 100644 index 000000000..e100b49c3 --- /dev/null +++ b/spec/fixtures/project_variable_create.json @@ -0,0 +1,11 @@ +{ + "variable_type": "env_var", + "key": "MY_VAR", + "value": "Custom Value", + "hidden": false, + "protected": false, + "masked": false, + "raw": true, + "environment_scope": "*", + "description": "A sample variable" +} diff --git a/spec/fixtures/project_variable_get.json b/spec/fixtures/project_variable_get.json new file mode 100644 index 000000000..e100b49c3 --- /dev/null +++ b/spec/fixtures/project_variable_get.json @@ -0,0 +1,11 @@ +{ + "variable_type": "env_var", + "key": "MY_VAR", + "value": "Custom Value", + "hidden": false, + "protected": false, + "masked": false, + "raw": true, + "environment_scope": "*", + "description": "A sample variable" +} diff --git a/spec/fixtures/project_variables_get_all.json b/spec/fixtures/project_variables_get_all.json new file mode 100644 index 000000000..de2968a20 --- /dev/null +++ b/spec/fixtures/project_variables_get_all.json @@ -0,0 +1,24 @@ +[ + { + "variable_type": "env_var", + "key": "MY_VAR", + "value": "Custom Value", + "hidden": false, + "protected": false, + "masked": false, + "raw": true, + "environment_scope": "*", + "description": "A sample variable" + }, + { + "variable_type": "env_var", + "key": "MY_VAR_2", + "value": "Another Value", + "hidden": false, + "protected": false, + "masked": false, + "raw": true, + "environment_scope": "*", + "description": "Another sample variable" + } +] diff --git a/spec/gitlab/client/projects_spec.rb b/spec/gitlab/client/projects_spec.rb index fd9874b33..1000185c4 100644 --- a/spec/gitlab/client/projects_spec.rb +++ b/spec/gitlab/client/projects_spec.rb @@ -1029,4 +1029,69 @@ expect(@token.to_h).to be_empty end end + + describe '.project_variables' do + before do + stub_get('/projects/2/variables', 'project_variables_get_all') + @variables = Gitlab.project_variables(2) + end + + it 'gets the correct resource' do + expect(a_get('/projects/2/variables')).to have_been_made + end + + it 'gets an array of project variables' do + expect(@variables.first.key).to eq('MY_VAR') + expect(@variables.last.key).to eq('MY_VAR_2') + end + end + + describe '.project_variable' do + before do + stub_get('/projects/2/variables/MY_VAR', 'project_variable_get') + @variable = Gitlab.project_variable(2, 'MY_VAR') + end + + it 'gets the correct resource' do + expect(a_get('/projects/2/variables/MY_VAR')).to have_been_made + end + + it 'gets a project variable' do + expect(@variable.key).to eq('MY_VAR') + expect(@variable.value).to eq('Custom Value') + end + end + + describe '.create_project_variable' do + before do + stub_post('/projects/2/variables', 'project_variable_create') + @variable = Gitlab.create_project_variable(2, 'MY_VAR', 'Custom Value') + end + + it 'gets the correct resource' do + expect(a_post('/projects/2/variables').with(body: 'key=MY_VAR&value=Custom%20Value')).to have_been_made + end + + it 'creates a project variable' do + expect(@variable.key).to eq('MY_VAR') + expect(@variable.value).to eq('Custom Value') + end + end + + describe '.delete_project_variable' do + before do + stub_request(:delete, "#{Gitlab.endpoint}/projects/2/variables/MY_VAR") + .with(headers: { 'PRIVATE-TOKEN' => Gitlab.private_token }) + .to_return(status: 204) + @variable = Gitlab.delete_project_variable(2, 'MY_VAR') + end + + it 'deletes the correct resource' do + expect(a_delete('/projects/2/variables/MY_VAR')).to have_been_made + end + + it 'removes a token' do + expect(@variable.to_h).to be_empty + end + end end