Commit 413d723b authored by Sanad Liaquat's avatar Sanad Liaquat

Merge branch 'shl-267553-remove-pat-creation-api-feature-flag' into 'master'

Remove pat_creation_api_for_admin feature flag

See merge request gitlab-org/gitlab!49222
parents fc3f3e72 461ac958
---
title: Add ability for admins to create PAT for other users via API
merge_request: 49222
author:
type: added
---
name: pat_creation_api_for_admin
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/45152
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/267553
type: development
group: group::access
default_enabled: false
...@@ -96,4 +96,4 @@ curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://git ...@@ -96,4 +96,4 @@ curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://git
## Create a personal access token (admin only) ## Create a personal access token (admin only)
See the [Users API documentation](users.md#create-a-personal-access-token-admin-only) for information on creating a personal access token. See the [Users API documentation](users.md#create-a-personal-access-token) for information on creating a personal access token.
...@@ -1480,19 +1480,13 @@ Parameters: ...@@ -1480,19 +1480,13 @@ Parameters:
| `user_id` | integer | yes | The ID of the user | | `user_id` | integer | yes | The ID of the user |
| `impersonation_token_id` | integer | yes | The ID of the impersonation token | | `impersonation_token_id` | integer | yes | The ID of the impersonation token |
## Create a personal access token (admin only) ## Create a personal access token **(CORE ONLY)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/17176) in GitLab 13.6. > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/17176) in GitLab 13.6.
> - It's [deployed behind a feature flag](../user/feature_flags.md), disabled by default. > - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/267553) in GitLab 13.8.
> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-an-administrators-ability-to-use-the-api-to-create-personal-access-tokens). **(CORE)**
WARNING: Use this API to create a new personal access token. Token values are returned once.
This feature might not be available to you. Check the **version history** note above for details. Make sure you save it as you can't access it again.
> Requires admin permissions.
> Token values are returned once. Make sure you save it - you can't access it again.
It creates a new personal access token.
```plaintext ```plaintext
POST /users/:user_id/personal_access_tokens POST /users/:user_id/personal_access_tokens
...@@ -1632,22 +1626,3 @@ Example response: ...@@ -1632,22 +1626,3 @@ Example response:
}, },
] ]
``` ```
## Enable or disable an administrator's ability to use the API to create personal access tokens **(CORE)**
An administrator's ability to create personal access tokens through the API is
deployed behind a feature flag that is **disabled by default**.
[GitLab administrators with access to the GitLab Rails console](../administration/feature_flags.md)
can enable it.
To enable it:
```ruby
Feature.enable(:pat_creation_api_for_admin)
```
To disable it:
```ruby
Feature.disable(:pat_creation_api_for_admin)
```
...@@ -745,8 +745,6 @@ module API ...@@ -745,8 +745,6 @@ module API
optional :expires_at, type: Date, desc: 'The expiration date in the format YEAR-MONTH-DAY of the personal access token' optional :expires_at, type: Date, desc: 'The expiration date in the format YEAR-MONTH-DAY of the personal access token'
end end
post feature_category: :authentication_and_authorization do post feature_category: :authentication_and_authorization do
not_found! unless Feature.enabled?(:pat_creation_api_for_admin)
response = ::PersonalAccessTokens::CreateService.new( response = ::PersonalAccessTokens::CreateService.new(
current_user: current_user, target_user: target_user, params: declared_params(include_missing: false) current_user: current_user, target_user: target_user, params: declared_params(include_missing: false)
).execute ).execute
......
...@@ -2853,115 +2853,91 @@ RSpec.describe API::Users do ...@@ -2853,115 +2853,91 @@ RSpec.describe API::Users do
let(:expires_at) { 3.days.from_now.to_date.to_s } let(:expires_at) { 3.days.from_now.to_date.to_s }
let(:scopes) { %w(api read_user) } let(:scopes) { %w(api read_user) }
context 'when feature flag is enabled' do it 'returns error if required attributes are missing' do
before do post api("/users/#{user.id}/personal_access_tokens", admin)
stub_feature_flags(pat_creation_api_for_admin: true)
end
it 'returns error if required attributes are missing' do
post api("/users/#{user.id}/personal_access_tokens", admin)
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to eq('name is missing, scopes is missing, scopes does not have a valid value')
end
it 'returns a 404 error if user not found' do
post api("/users/#{non_existing_record_id}/personal_access_tokens", admin),
params: {
name: name,
scopes: scopes,
expires_at: expires_at
}
expect(response).to have_gitlab_http_status(:not_found) expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']).to eq('404 User Not Found') expect(json_response['error']).to eq('name is missing, scopes is missing, scopes does not have a valid value')
end end
it 'returns a 401 error when not authenticated' do it 'returns a 404 error if user not found' do
post api("/users/#{user.id}/personal_access_tokens"), post api("/users/#{non_existing_record_id}/personal_access_tokens", admin),
params: { params: {
name: name, name: name,
scopes: scopes, scopes: scopes,
expires_at: expires_at expires_at: expires_at
} }
expect(response).to have_gitlab_http_status(:unauthorized) expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to eq('401 Unauthorized') expect(json_response['message']).to eq('404 User Not Found')
end end
it 'returns a 403 error when authenticated as normal user' do it 'returns a 401 error when not authenticated' do
post api("/users/#{user.id}/personal_access_tokens", user), post api("/users/#{user.id}/personal_access_tokens"),
params: { params: {
name: name, name: name,
scopes: scopes, scopes: scopes,
expires_at: expires_at expires_at: expires_at
} }
expect(response).to have_gitlab_http_status(:forbidden) expect(response).to have_gitlab_http_status(:unauthorized)
expect(json_response['message']).to eq('403 Forbidden') expect(json_response['message']).to eq('401 Unauthorized')
end end
it 'creates a personal access token when authenticated as admin' do it 'returns a 403 error when authenticated as normal user' do
post api("/users/#{user.id}/personal_access_tokens", admin), post api("/users/#{user.id}/personal_access_tokens", user),
params: { params: {
name: name, name: name,
expires_at: expires_at, scopes: scopes,
scopes: scopes expires_at: expires_at
} }
expect(response).to have_gitlab_http_status(:created) expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response['name']).to eq(name) expect(json_response['message']).to eq('403 Forbidden')
expect(json_response['scopes']).to eq(scopes) end
expect(json_response['expires_at']).to eq(expires_at)
expect(json_response['id']).to be_present
expect(json_response['created_at']).to be_present
expect(json_response['active']).to be_truthy
expect(json_response['revoked']).to be_falsey
expect(json_response['token']).to be_present
end
context 'when an error is thrown by the model' do it 'creates a personal access token when authenticated as admin' do
let!(:admin_personal_access_token) { create(:personal_access_token, user: admin) } post api("/users/#{user.id}/personal_access_tokens", admin),
let(:error_message) { 'error message' } params: {
name: name,
expires_at: expires_at,
scopes: scopes
}
before do expect(response).to have_gitlab_http_status(:created)
allow_next_instance_of(PersonalAccessToken) do |personal_access_token| expect(json_response['name']).to eq(name)
allow(personal_access_token).to receive_message_chain(:errors, :full_messages) expect(json_response['scopes']).to eq(scopes)
.and_return([error_message]) expect(json_response['expires_at']).to eq(expires_at)
expect(json_response['id']).to be_present
expect(json_response['created_at']).to be_present
expect(json_response['active']).to be_truthy
expect(json_response['revoked']).to be_falsey
expect(json_response['token']).to be_present
end
allow(personal_access_token).to receive(:save).and_return(false) context 'when an error is thrown by the model' do
end let!(:admin_personal_access_token) { create(:personal_access_token, user: admin) }
end let(:error_message) { 'error message' }
it 'returns the error' do before do
post api("/users/#{user.id}/personal_access_tokens", personal_access_token: admin_personal_access_token), allow_next_instance_of(PersonalAccessToken) do |personal_access_token|
params: { allow(personal_access_token).to receive_message_chain(:errors, :full_messages)
name: name, .and_return([error_message])
expires_at: expires_at,
scopes: scopes
}
expect(response).to have_gitlab_http_status(:unprocessable_entity) allow(personal_access_token).to receive(:save).and_return(false)
expect(json_response['message']).to eq(error_message)
end end
end end
end
context 'when feature flag is disabled' do it 'returns the error' do
before do post api("/users/#{user.id}/personal_access_tokens", personal_access_token: admin_personal_access_token),
stub_feature_flags(pat_creation_api_for_admin: false)
end
it 'returns a 404' do
post api("/users/#{user.id}/personal_access_tokens", admin),
params: { params: {
name: name, name: name,
expires_at: expires_at, expires_at: expires_at,
scopes: scopes scopes: scopes
} }
expect(response).to have_gitlab_http_status(:not_found) expect(response).to have_gitlab_http_status(:unprocessable_entity)
expect(json_response['message']).to eq('404 Not Found') expect(json_response['message']).to eq(error_message)
end end
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment