From 6d76f14f54eb1af0e5c29eff1b8f5e70d2264ffd Mon Sep 17 00:00:00 2001 From: Timothy Andrew Date: Fri, 15 Apr 2016 20:54:20 +0530 Subject: [PATCH] Allow revoking personal access tokens. --- app/assets/stylesheets/pages/profile.scss | 3 +++ .../personal_access_tokens_controller.rb | 16 +++++++++++++++- app/models/personal_access_token.rb | 7 +++++++ .../personal_access_tokens/index.html.haml | 9 ++++++++- config/locales/en.yml | 4 ++++ config/routes.rb | 6 +++++- ...d_column_revoked_to_personal_access_tokens.rb | 5 +++++ lib/api/helpers/authentication.rb | 2 +- 8 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 db/migrate/20160415144643_add_column_revoked_to_personal_access_tokens.rb diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss index 01f98479623..5a4d0a5c8b0 100644 --- a/app/assets/stylesheets/pages/profile.scss +++ b/app/assets/stylesheets/pages/profile.scss @@ -205,3 +205,6 @@ text-align: center; } } +.personal-access-tokens-revoked-label { + color: #bbb; +} \ No newline at end of file diff --git a/app/controllers/profiles/personal_access_tokens_controller.rb b/app/controllers/profiles/personal_access_tokens_controller.rb index dbf06cb4c6d..59de0b26eee 100644 --- a/app/controllers/profiles/personal_access_tokens_controller.rb +++ b/app/controllers/profiles/personal_access_tokens_controller.rb @@ -1,7 +1,11 @@ class Profiles::PersonalAccessTokensController < ApplicationController def index @user = current_user - @personal_access_token = current_user.personal_access_tokens.new + + # Prefer this to `@user.personal_access_tokens.new`, because it + # litters the view's call to `@user.personal_access_tokens` with + # this stub personal access token. + @personal_access_token = PersonalAccessToken.new(user: @user) end def create @@ -14,6 +18,16 @@ class Profiles::PersonalAccessTokensController < ApplicationController end end + def revoke + @personal_access_token = current_user.personal_access_tokens.find(params[:id]) + + if @personal_access_token.revoke! + redirect_to profile_personal_access_tokens_path, notice: "Revoked personal access token #{@personal_access_token.name}!" + else + render :index + end + end + private def personal_access_token_params diff --git a/app/models/personal_access_token.rb b/app/models/personal_access_token.rb index 29f2275475f..e5f1f9749f8 100644 --- a/app/models/personal_access_token.rb +++ b/app/models/personal_access_token.rb @@ -1,9 +1,16 @@ class PersonalAccessToken < ActiveRecord::Base belongs_to :user + scope :active, -> { where.not(revoked: true) } + def self.generate(params) personal_access_token = self.new(params) personal_access_token.token = Devise.friendly_token(50) personal_access_token end + + def revoke! + self.revoked = true + self.save + end end diff --git a/app/views/profiles/personal_access_tokens/index.html.haml b/app/views/profiles/personal_access_tokens/index.html.haml index 05eed3c5c3c..02d15269c85 100644 --- a/app/views/profiles/personal_access_tokens/index.html.haml +++ b/app/views/profiles/personal_access_tokens/index.html.haml @@ -34,11 +34,18 @@ %th Name %th Token %th Created At + %th Actions %tbody - - @user.personal_access_tokens.each do |token| + - @user.personal_access_tokens.order(:revoked).each do |token| %tr %td= token.name %td= token.token %td= token.created_at + - if token.revoked? + %td + %span.personal-access-tokens-revoked-label Revoked + - else + %td= link_to "Revoke", revoke_profile_personal_access_token_path(token), method: :put, class: "btn btn-danger", data: {confirm: t('profile.personal_access_tokens.revoke.confirmation')} + - else %span You don't have any tokens yet. \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index cedb5e207bd..b5b8c4467b0 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -12,3 +12,7 @@ en: pagination: previous: "Prev" next: "Next" + profile: + personal_access_tokens: + revoke: + confirmation: "Are you sure? This cannot be undone." diff --git a/config/routes.rb b/config/routes.rb index d1be826d2a1..4e4666762f8 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -333,7 +333,11 @@ Rails.application.routes.draw do resources :keys resources :emails, only: [:index, :create, :destroy] resource :avatar, only: [:destroy] - resources :personal_access_tokens, only: [:index, :create] + resources :personal_access_tokens, only: [:index, :create] do + member do + put :revoke + end + end resource :two_factor_auth, only: [:new, :create, :destroy] do member do post :codes diff --git a/db/migrate/20160415144643_add_column_revoked_to_personal_access_tokens.rb b/db/migrate/20160415144643_add_column_revoked_to_personal_access_tokens.rb new file mode 100644 index 00000000000..8eecdfc5a1c --- /dev/null +++ b/db/migrate/20160415144643_add_column_revoked_to_personal_access_tokens.rb @@ -0,0 +1,5 @@ +class AddColumnRevokedToPersonalAccessTokens < ActiveRecord::Migration + def change + add_column :personal_access_tokens, :revoked, :boolean, default: false + end +end diff --git a/lib/api/helpers/authentication.rb b/lib/api/helpers/authentication.rb index e1d7ac83ff6..666bf3ffa16 100644 --- a/lib/api/helpers/authentication.rb +++ b/lib/api/helpers/authentication.rb @@ -15,7 +15,7 @@ module API def find_user_by_personal_access_token personal_access_token_string = (params[PERSONAL_ACCESS_TOKEN_PARAM] || env[PERSONAL_ACCESS_TOKEN_HEADER]).to_s - personal_access_token = PersonalAccessToken.find_by_token(personal_access_token_string) + personal_access_token = PersonalAccessToken.active.find_by_token(personal_access_token_string) personal_access_token.user if personal_access_token end