diff options
author | Simon Vocella <voxsim@gmail.com> | 2017-01-06 17:00:46 +0100 |
---|---|---|
committer | Tiago Botelho <tiagonbotelho@hotmail.com> | 2017-02-28 22:15:39 +0000 |
commit | c2b1cdef7e8cdaec35bd0844301ce8f06ed742b7 (patch) | |
tree | 072d178375afe0875fe2f4342e4f167848213939 /app | |
parent | 09dd6a7ead97122385f13265ea147ab689994244 (diff) | |
download | gitlab-ce-c2b1cdef7e8cdaec35bd0844301ce8f06ed742b7.tar.gz |
add admin panel for personal access tokens
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/stylesheets/pages/settings.scss | 11 | ||||
-rw-r--r-- | app/controllers/admin/personal_access_tokens_controller.rb | 48 | ||||
-rw-r--r-- | app/views/admin/personal_access_tokens/_form.html.haml | 28 | ||||
-rw-r--r-- | app/views/admin/personal_access_tokens/index.html.haml | 80 | ||||
-rw-r--r-- | app/views/admin/users/_head.html.haml | 2 |
5 files changed, 169 insertions, 0 deletions
diff --git a/app/assets/stylesheets/pages/settings.scss b/app/assets/stylesheets/pages/settings.scss index a28a87ed4f8..905ecbff57c 100644 --- a/app/assets/stylesheets/pages/settings.scss +++ b/app/assets/stylesheets/pages/settings.scss @@ -24,3 +24,14 @@ .service-settings .control-label { padding-top: 0; } + +.personal-access-token-token-container { + #personal-access-token-token { + width: 80%; + display: inline; + } + + .btn-clipboard { + margin-left: 5px; + } +} diff --git a/app/controllers/admin/personal_access_tokens_controller.rb b/app/controllers/admin/personal_access_tokens_controller.rb new file mode 100644 index 00000000000..7202d80ce1b --- /dev/null +++ b/app/controllers/admin/personal_access_tokens_controller.rb @@ -0,0 +1,48 @@ +class Admin::PersonalAccessTokensController < Admin::ApplicationController + before_action :user + + def index + set_index_vars + end + + def create + @personal_access_token = user.personal_access_tokens.generate(personal_access_token_params) + + if @personal_access_token.save + flash[:personal_access_token] = @personal_access_token.token + redirect_to admin_user_personal_access_tokens_path, notice: "A new personal access token has been created." + else + set_index_vars + render :index + end + end + + def revoke + @personal_access_token = user.personal_access_tokens.find(params[:id]) + + if @personal_access_token.revoke! + flash[:notice] = "Revoked personal access token #{@personal_access_token.name}!" + else + flash[:alert] = "Could not revoke personal access token #{@personal_access_token.name}." + end + + redirect_to admin_user_personal_access_tokens_path + end + + private + + def user + @user ||= User.find_by!(username: params[:user_id]) + end + + def personal_access_token_params + params.require(:personal_access_token).permit(:name, :expires_at, :impersonation, scopes: []) + end + + def set_index_vars + @personal_access_token ||= user.personal_access_tokens.build + @scopes = Gitlab::Auth::SCOPES + @active_personal_access_tokens = PersonalAccessToken.and_impersonation_tokens.where(user_id: user.id).active.order(:expires_at) + @inactive_personal_access_tokens = PersonalAccessToken.and_impersonation_tokens.where(user_id: user.id).inactive + end +end diff --git a/app/views/admin/personal_access_tokens/_form.html.haml b/app/views/admin/personal_access_tokens/_form.html.haml new file mode 100644 index 00000000000..d194a0fd511 --- /dev/null +++ b/app/views/admin/personal_access_tokens/_form.html.haml @@ -0,0 +1,28 @@ +- personal_access_token = local_assigns.fetch(:personal_access_token) +- scopes = local_assigns.fetch(:scopes) + += form_for [:admin_user, personal_access_token], method: :post, html: { class: 'js-requires-input' } do |f| + + = form_errors(personal_access_token) + + .form-group + = f.label :name, class: 'label-light' + = f.text_field :name, class: "form-control", required: true + + .form-group + = f.label :expires_at, class: 'label-light' + = f.text_field :expires_at, class: "datepicker form-control" + + .form-group + = f.label :scopes, class: 'label-light' + = render 'shared/tokens/scopes_form', prefix: 'personal_access_token', token: personal_access_token, scopes: scopes + + .form-group + = f.label :impersonation, class: 'label-light' + %fieldset + = f.check_box :impersonation + = f.label 'impersonation', 'You can impersonate the user' + %span= "(Normal users will not see this type of token)" + + .prepend-top-default + = f.submit 'Create Personal Access Token', class: "btn btn-create" diff --git a/app/views/admin/personal_access_tokens/index.html.haml b/app/views/admin/personal_access_tokens/index.html.haml new file mode 100644 index 00000000000..90aade17e1b --- /dev/null +++ b/app/views/admin/personal_access_tokens/index.html.haml @@ -0,0 +1,80 @@ +- page_title "Personal Access Tokens" += render 'admin/users/head' + +.row.prepend-top-default + .col-lg-12 + + %h5.prepend-top-0 + Add a Personal Access Token + %p.profile-settings-content + Pick a name for the application, and we'll give you a unique token. + + = render "form", personal_access_token: @personal_access_token, scopes: @scopes + + %hr + + %h5 Active Personal Access Tokens (#{@active_personal_access_tokens.length}) + + - if @active_personal_access_tokens.present? + .table-responsive + %table.table.active-personal-access-tokens + %thead + %tr + %th Name + %th Created + %th Expires + %th Scopes + %th Token + %th Impersonation + %th + %tbody + - @active_personal_access_tokens.each do |personal_access_token| + %tr + %td= personal_access_token.name + %td= personal_access_token.created_at.to_date.to_s(:medium) + %td + - if personal_access_token.expires? + %span{ class: ('text-warning' if personal_access_token.expires_soon?) } + In #{distance_of_time_in_words_to_now(personal_access_token.expires_at)} + - else + %span.personal-access-personal_access_tokens-never-expires-label Never + %td= personal_access_token.scopes.present? ? personal_access_token.scopes.join(", ") : "<no scopes selected>" + %td.personal-access-token-token-container + = text_field_tag 'personal-access-token-token', personal_access_token.token, readonly: true, class: "form-control" + = clipboard_button(clipboard_text: personal_access_token.token) + %td= personal_access_token.impersonation + %td= link_to "Revoke", revoke_admin_user_personal_access_token_path(id: personal_access_token.id, user_id: personal_access_token.user.username), method: :put, class: "btn btn-danger pull-right", data: { confirm: "Are you sure you want to revoke this token? This action cannot be undone." } + + - else + .settings-message.text-center + This user has no active tokens. + + %hr + + %h5 Inactive Personal Access Tokens (#{@inactive_personal_access_tokens.length}) + + - if @inactive_personal_access_tokens.present? + .table-responsive + %table.table.inactive-personal-access-tokens + %thead + %tr + %th Name + %th Created + %tbody + - @inactive_personal_access_tokens.each do |token| + %tr + %td= token.name + %td= token.created_at.to_date.to_s(:medium) + + - else + .settings-message.text-center + This user has no inactive tokens. + + +:javascript + var date = $('#personal_access_token_expires_at').val(); + + var datepicker = $(".datepicker").datepicker({ + dateFormat: "yy-mm-dd", + minDate: 0 + }); diff --git a/app/views/admin/users/_head.html.haml b/app/views/admin/users/_head.html.haml index 9984e733956..c95ae93b710 100644 --- a/app/views/admin/users/_head.html.haml +++ b/app/views/admin/users/_head.html.haml @@ -21,4 +21,6 @@ = link_to "SSH keys", keys_admin_user_path(@user) = nav_link(controller: :identities) do = link_to "Identities", admin_user_identities_path(@user) + = nav_link(controller: :personal_access_tokens) do + = link_to "Access Tokens", admin_user_personal_access_tokens_path(@user) .append-bottom-default |