Skip to content

Commit 1d16530

Browse files
committed
Merge branch 'if-53347_fix_impersonation_tokens' into 'master'
Display impersonation token value only after creation See merge request gitlab-org/gitlab-ce!22916
2 parents 97e3d5c + f3cd24a commit 1d16530

File tree

14 files changed

+54
-26
lines changed

14 files changed

+54
-26
lines changed

app/controllers/admin/impersonation_tokens_controller.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ def create
1111
@impersonation_token = finder.build(impersonation_token_params)
1212

1313
if @impersonation_token.save
14+
PersonalAccessToken.redis_store!(current_user.id, @impersonation_token.token)
1415
redirect_to admin_user_impersonation_tokens_path, notice: "A new impersonation token has been created."
1516
else
1617
set_index_vars
@@ -53,6 +54,8 @@ def set_index_vars
5354
@impersonation_token ||= finder.build
5455
@inactive_impersonation_tokens = finder(state: 'inactive').execute
5556
@active_impersonation_tokens = finder(state: 'active').execute.order(:expires_at)
57+
58+
@new_impersonation_token = PersonalAccessToken.redis_getdel(current_user.id)
5659
end
5760
# rubocop: enable CodeReuse/ActiveRecord
5861
end

app/views/admin/impersonation_tokens/index.html.haml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55

66
.row.prepend-top-default
77
.col-lg-12
8+
- if @new_impersonation_token
9+
= render "shared/personal_access_tokens_created_container", new_token_value: @new_impersonation_token,
10+
container_title: 'Your New Impersonation Token',
11+
clipboard_button_title: 'Copy impersonation token to clipboard'
12+
813
= render "shared/personal_access_tokens_form", path: admin_user_impersonation_tokens_path, impersonation: true, token: @impersonation_token, scopes: @scopes
914

1015
= render "shared/personal_access_tokens_table", impersonation: true, active_tokens: @active_impersonation_tokens, inactive_tokens: @inactive_impersonation_tokens

app/views/profiles/personal_access_tokens/index.html.haml

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,7 @@
1414

1515
.col-lg-8
1616
- if @new_personal_access_token
17-
.created-personal-access-token-container
18-
%h5.prepend-top-0
19-
Your New Personal Access Token
20-
.form-group
21-
.input-group
22-
= text_field_tag 'created-personal-access-token', @new_personal_access_token, readonly: true, class: "form-control js-select-on-focus", 'aria-describedby' => "created-personal-access-token-help-block"
23-
%span.input-group-append
24-
= clipboard_button(text: @new_personal_access_token, title: "Copy personal access token to clipboard", placement: "left", class: "input-group-text btn-default btn-clipboard")
25-
%span#created-personal-access-token-help-block.form-text.text-muted.text-danger Make sure you save it - you won't be able to access it again.
26-
27-
%hr
17+
= render "shared/personal_access_tokens_created_container", new_token_value: @new_personal_access_token
2818

2919
= render "shared/personal_access_tokens_form", path: profile_personal_access_tokens_path, impersonation: false, token: @personal_access_token, scopes: @scopes
3020

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
- container_title = local_assigns.fetch(:container_title, 'Your New Personal Access Token')
2+
- clipboard_button_title = local_assigns.fetch(:clipboard_button_title, 'Copy personal access token to clipboard')
3+
4+
.created-personal-access-token-container
5+
%h5.prepend-top-0
6+
= container_title
7+
.form-group
8+
.input-group
9+
= text_field_tag 'created-personal-access-token', new_token_value, readonly: true, class: "form-control js-select-on-focus", 'aria-describedby' => "created-token-help-block"
10+
%span.input-group-append
11+
= clipboard_button(text: new_token_value, title: clipboard_button_title, placement: "left", class: "input-group-text btn-default btn-clipboard")
12+
%span#created-token-help-block.form-text.text-muted.text-danger Make sure you save it - you won't be able to access it again.
13+
14+
%hr

app/views/shared/_personal_access_tokens_table.html.haml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
%th Created
1616
%th Expires
1717
%th Scopes
18-
- if impersonation
19-
%th Token
2018
%th
2119
%tbody
2220
- active_tokens.each do |token|
@@ -30,10 +28,6 @@
3028
- else
3129
%span.token-never-expires-label Never
3230
%td= token.scopes.present? ? token.scopes.join(", ") : "<no scopes selected>"
33-
- if impersonation
34-
%td.token-token-container
35-
= text_field_tag 'impersonation-token-token', token.token, readonly: true, class: "form-control"
36-
= clipboard_button(text: token.token)
3731
- path = impersonation ? revoke_admin_user_impersonation_token_path(token.user, token) : revoke_profile_personal_access_token_path(token)
3832
%td= link_to "Revoke", path, method: :put, class: "btn btn-danger float-right", data: { confirm: "Are you sure you want to revoke this #{type} Token? This action cannot be undone." }
3933
- else
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
title: Display impersonation token value only after creation
3+
merge_request: 22916
4+
author:
5+
type: fixed

doc/api/users.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,7 +1072,6 @@ Example response:
10721072
[
10731073
{
10741074
"active" : true,
1075-
"token" : "EsMo-vhKfXGwX9RKrwiy",
10761075
"scopes" : [
10771076
"api"
10781077
],
@@ -1089,7 +1088,6 @@ Example response:
10891088
"read_user"
10901089
],
10911090
"revoked" : true,
1092-
"token" : "ZcZRpLeEuQRprkRjYydY",
10931091
"name" : "mytoken2",
10941092
"created_at" : "2017-03-17T17:19:28.697Z",
10951093
"id" : 3,
@@ -1125,7 +1123,6 @@ Example response:
11251123
```json
11261124
{
11271125
"active" : true,
1128-
"token" : "EsMo-vhKfXGwX9RKrwiy",
11291126
"scopes" : [
11301127
"api"
11311128
],
@@ -1142,6 +1139,8 @@ Example response:
11421139

11431140
> Requires admin permissions.
11441141
1142+
> Token values are returned once. Make sure you save it - you won't be able to access it again.
1143+
11451144
It creates a new impersonation token. Note that only administrators can do this.
11461145
You are only able to create impersonation tokens to impersonate the user and perform
11471146
both API calls and Git reads and writes. The user will not see these tokens in their profile

lib/api/entities.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1263,7 +1263,11 @@ class PersonalAccessTokenWithToken < PersonalAccessToken
12631263
expose :token
12641264
end
12651265

1266-
class ImpersonationToken < PersonalAccessTokenWithToken
1266+
class ImpersonationToken < PersonalAccessToken
1267+
expose :impersonation
1268+
end
1269+
1270+
class ImpersonationTokenWithToken < PersonalAccessTokenWithToken
12671271
expose :impersonation
12681272
end
12691273

lib/api/users.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,7 @@ def find_impersonation_token
531531

532532
desc 'Create a impersonation token. Available only for admins.' do
533533
detail 'This feature was introduced in GitLab 9.0'
534-
success Entities::ImpersonationToken
534+
success Entities::ImpersonationTokenWithToken
535535
end
536536
params do
537537
requires :name, type: String, desc: 'The name of the impersonation token'
@@ -542,7 +542,7 @@ def find_impersonation_token
542542
impersonation_token = finder.build(declared_params(include_missing: false))
543543

544544
if impersonation_token.save
545-
present impersonation_token, with: Entities::ImpersonationToken
545+
present impersonation_token, with: Entities::ImpersonationTokenWithToken
546546
else
547547
render_validation_error!(impersonation_token)
548548
end

qa/qa/page/profile/personal_access_tokens.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class PersonalAccessTokens < Page::Base
88
element :scopes_api_radios, "label :scopes" # rubocop:disable QA/ElementWithPattern
99
end
1010

11-
view 'app/views/profiles/personal_access_tokens/index.html.haml' do
11+
view 'app/views/shared/_personal_access_tokens_created_container.html.haml' do
1212
element :create_token_field, "text_field_tag 'created-personal-access-token'" # rubocop:disable QA/ElementWithPattern
1313
end
1414

spec/controllers/profiles/personal_access_tokens_controller_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@ def created_token
3939
let!(:active_personal_access_token) { create(:personal_access_token, user: user) }
4040
let!(:inactive_personal_access_token) { create(:personal_access_token, :revoked, user: user) }
4141
let!(:impersonation_personal_access_token) { create(:personal_access_token, :impersonation, user: user) }
42+
let(:token_value) { 's3cr3t' }
4243

4344
before do
45+
PersonalAccessToken.redis_store!(user.id, token_value)
4446
get :index
4547
end
4648

@@ -56,5 +58,9 @@ def created_token
5658
expect(assigns(:active_personal_access_tokens)).not_to include(impersonation_personal_access_token)
5759
expect(assigns(:inactive_personal_access_tokens)).not_to include(impersonation_personal_access_token)
5860
end
61+
62+
it "retrieves newly created personal access token value" do
63+
expect(assigns(:new_personal_access_token)).to eql(token_value)
64+
end
5965
end
6066
end

spec/features/admin/admin_users_impersonation_tokens_spec.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ def no_personal_access_tokens_message
1212
find(".settings-message")
1313
end
1414

15+
def created_impersonation_token
16+
find("#created-personal-access-token").value
17+
end
18+
1519
before do
1620
sign_in(admin)
1721
end
@@ -39,6 +43,7 @@ def no_personal_access_tokens_message
3943
expect(active_impersonation_tokens).to have_text('api')
4044
expect(active_impersonation_tokens).to have_text('read_user')
4145
expect(PersonalAccessTokensFinder.new(impersonation: true).execute.count).to equal(1)
46+
expect(created_impersonation_token).not_to be_empty
4247
end
4348
end
4449

spec/features/profiles/personal_access_tokens_spec.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,12 @@ def disallow_personal_access_token_saves!
4343
check "read_user"
4444

4545
click_on "Create personal access token"
46+
4647
expect(active_personal_access_tokens).to have_text(name)
4748
expect(active_personal_access_tokens).to have_text('In')
4849
expect(active_personal_access_tokens).to have_text('api')
4950
expect(active_personal_access_tokens).to have_text('read_user')
51+
expect(created_personal_access_token).not_to be_empty
5052
end
5153

5254
context "when creation fails" do
@@ -57,6 +59,7 @@ def disallow_personal_access_token_saves!
5759

5860
expect { click_on "Create personal access token" }.not_to change { PersonalAccessToken.count }
5961
expect(page).to have_content("Name cannot be nil")
62+
expect(page).not_to have_selector("#created-personal-access-token")
6063
end
6164
end
6265
end

spec/requests/api/users_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2018,11 +2018,11 @@
20182018
expect(json_response['message']).to eq('403 Forbidden')
20192019
end
20202020

2021-
it 'returns a personal access token' do
2021+
it 'returns an impersonation token' do
20222022
get api("/users/#{user.id}/impersonation_tokens/#{impersonation_token.id}", admin)
20232023

20242024
expect(response).to have_gitlab_http_status(200)
2025-
expect(json_response['token']).to be_present
2025+
expect(json_response['token']).not_to be_present
20262026
expect(json_response['impersonation']).to be_truthy
20272027
end
20282028
end

0 commit comments

Comments
 (0)