Skip to content
Snippets Groups Projects
Commit e5cf527f authored by Timothy Andrew's avatar Timothy Andrew
Browse files

Allow expiration of personal access tokens.

parent 1541d1de
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -207,4 +207,8 @@
}
.personal-access-tokens-revoked-label {
color: #bbb;
}
.personal-access-tokens-never-expires-label {
color: #bbb;
}
\ No newline at end of file
Loading
Loading
@@ -31,6 +31,6 @@ class Profiles::PersonalAccessTokensController < ApplicationController
private
 
def personal_access_token_params
params.require(:personal_access_token).permit(:name)
params.require(:personal_access_token).permit(:name, :expires_at)
end
end
class PersonalAccessToken < ActiveRecord::Base
belongs_to :user
 
scope :active, -> { where.not(revoked: true) }
scope :active, -> { where.not(revoked: true).where("expires_at >= :current", current: Time.current) }
 
def self.generate(params)
personal_access_token = self.new(params)
Loading
Loading
Loading
Loading
@@ -18,6 +18,10 @@
= 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: "form-control datepicker", required: false
.prepend-top-default
= f.submit 'Add Personal Access Token', class: "btn btn-create"
 
Loading
Loading
@@ -34,13 +38,19 @@
%th Name
%th Token
%th Created At
%th Expires At
%th Actions
%tbody
- @user.personal_access_tokens.order(:revoked).each do |token|
- @user.personal_access_tokens.order("revoked, expires_at").each do |token|
%tr
%td= token.name
%td= token.token
%td= token.created_at
- if token.expires_at.present?
%td= token.expires_at.to_date
- else
%td
%span.personal-access-tokens-never-expires-label Never
- if token.revoked?
%td
%span.personal-access-tokens-revoked-label Revoked
Loading
Loading
@@ -48,4 +58,10 @@
%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
%span You don't have any tokens yet.
:javascript
$(".datepicker").datepicker({
dateFormat: "yy-mm-dd",
onSelect: function(dateText, inst) { $("#personal_access_token_expires_at").val(dateText) }
}).datepicker("setDate", $.datepicker.parseDate('yy-mm-dd', $('#personal_access_token_expires_at').val()));
\ No newline at end of file
class AddColumnExpiresAtToPersonalAccessTokens < ActiveRecord::Migration
def change
add_column :personal_access_tokens, :expires_at, :datetime
end
end
FactoryGirl.define do
factory :personal_access_token do
user
token { SecureRandom.hex(50) }
name { FFaker::Product.brand }
revoked false
expires_at { 5.days.from_now }
end
end
Loading
Loading
@@ -41,24 +41,64 @@ describe API::Helpers::Authentication, api: true do
end
 
describe ".current_user" do
it "should return nil for an invalid token" do
env[API::Helpers::Authentication::PRIVATE_TOKEN_HEADER] = 'invalid token'
allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ false }
expect(current_user).to be_nil
describe "when authenticating using a user's private token" do
it "should return nil for an invalid token" do
env[API::Helpers::Authentication::PRIVATE_TOKEN_HEADER] = 'invalid token'
allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ false }
expect(current_user).to be_nil
end
it "should return nil for a user without access" do
env[API::Helpers::Authentication::PRIVATE_TOKEN_HEADER] = user.private_token
allow(Gitlab::UserAccess).to receive(:allowed?).and_return(false)
expect(current_user).to be_nil
end
it "should leave user as is when sudo not specified" do
env[API::Helpers::Authentication::PRIVATE_TOKEN_HEADER] = user.private_token
expect(current_user).to eq(user)
clear_env
params[API::Helpers::Authentication::PRIVATE_TOKEN_PARAM] = user.private_token
expect(current_user).to eq(user)
end
end
 
it "should return nil for a user without access" do
env[API::Helpers::Authentication::PRIVATE_TOKEN_HEADER] = user.private_token
allow(Gitlab::UserAccess).to receive(:allowed?).and_return(false)
expect(current_user).to be_nil
end
it "should leave user as is when sudo not specified" do
env[API::Helpers::Authentication::PRIVATE_TOKEN_HEADER] = user.private_token
expect(current_user).to eq(user)
clear_env
params[API::Helpers::Authentication::PRIVATE_TOKEN_PARAM] = user.private_token
expect(current_user).to eq(user)
describe "when authenticating using a user's personal access tokens" do
let(:personal_access_token) { create(:personal_access_token, user: user) }
it "should return nil for an invalid token" do
env[API::Helpers::Authentication::PERSONAL_ACCESS_TOKEN_HEADER] = 'invalid token'
allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ false }
expect(current_user).to be_nil
end
it "should return nil for a user without access" do
env[API::Helpers::Authentication::PERSONAL_ACCESS_TOKEN_HEADER] = personal_access_token.token
allow(Gitlab::UserAccess).to receive(:allowed?).and_return(false)
expect(current_user).to be_nil
end
it "should leave user as is when sudo not specified" do
env[API::Helpers::Authentication::PERSONAL_ACCESS_TOKEN_HEADER] = personal_access_token.token
expect(current_user).to eq(user)
clear_env
params[API::Helpers::Authentication::PERSONAL_ACCESS_TOKEN_PARAM] = personal_access_token.token
expect(current_user).to eq(user)
end
it 'does not allow revoked tokens' do
personal_access_token.revoke!
env[API::Helpers::Authentication::PERSONAL_ACCESS_TOKEN_HEADER] = personal_access_token.token
allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ false }
expect(current_user).to be_nil
end
it 'does not allow expired tokens' do
personal_access_token.update_attributes!(expires_at: 1.day.ago)
env[API::Helpers::Authentication::PERSONAL_ACCESS_TOKEN_HEADER] = personal_access_token.token
allow_any_instance_of(self.class).to receive(:doorkeeper_guard){ false }
expect(current_user).to be_nil
end
end
 
it "should change current user to sudo when admin" do
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment