Authenticate non-API requests with personal access tokens.

- Rename the `authenticate_user_from_token!` filter to
  `authenticate_user_from_private_token!`
- Add a new `authenticate_user_from_personal_access_token!` filter
- Add tests for both.
This commit is contained in:
Timothy Andrew 2016-04-19 16:22:15 +05:30
parent fb2da6795c
commit ade40fdcd2
2 changed files with 83 additions and 2 deletions

View File

@ -7,7 +7,8 @@ class ApplicationController < ActionController::Base
include GitlabRoutingHelper
include PageLayoutHelper
before_action :authenticate_user_from_token!
before_action :authenticate_user_from_private_token!
before_action :authenticate_user_from_personal_access_token!
before_action :authenticate_user!
before_action :validate_user_service_ticket!
before_action :reject_blocked!
@ -65,7 +66,7 @@ class ApplicationController < ActionController::Base
# From https://github.com/plataformatec/devise/wiki/How-To:-Simple-Token-Authentication-Example
# https://gist.github.com/josevalim/fb706b1e933ef01e4fb6
def authenticate_user_from_token!
def authenticate_user_from_private_token!
user_token = if params[:authenticity_token].presence
params[:authenticity_token].presence
elsif params[:private_token].presence
@ -84,6 +85,20 @@ class ApplicationController < ActionController::Base
end
end
def authenticate_user_from_personal_access_token!
token_string = params[:personal_access_token].presence || request.headers['PERSONAL_ACCESS_TOKEN'].presence
personal_access_token = PersonalAccessToken.active.find_by_token(token_string)
user = personal_access_token && personal_access_token.user
if user
# Notice we are passing store false, so the user is not
# actually stored in the session and a token is needed
# for every request. If you want the token to work as a
# sign in token, you can simply remove store: false.
sign_in user, store: false
end
end
def authenticate_user!(*args)
if redirect_to_home_page_url?
redirect_to current_application_settings.home_page_url and return

View File

@ -30,4 +30,70 @@ describe ApplicationController do
controller.send(:check_password_expiration)
end
end
describe "#authenticate_user_from_private_token!" do
controller(ApplicationController) do
def index
render text: "authenticated"
end
end
let(:user) { create(:user) }
it "logs the user in when the 'authenticity_token' param is populated with the private token" do
get :index, authenticity_token: user.private_token
expect(response.status).to eq(200)
expect(response.body).to eq("authenticated")
end
it "logs the user in when the 'private_token' param is populated with the private token" do
get :index, private_token: user.private_token
expect(response.status).to eq(200)
expect(response.body).to eq("authenticated")
end
it "logs the user in when the 'PRIVATE-TOKEN' header is populated with the private token" do
@request.headers['PRIVATE-TOKEN'] = user.private_token
get :index
expect(response.status).to eq(200)
expect(response.body).to eq("authenticated")
end
it "doesn't log the user in otherwise" do
@request.headers['PRIVATE-TOKEN'] = "token"
get :index, private_token: "token", authenticity_token: "token"
expect(response.status).to_not eq(200)
expect(response.body).to_not eq("authenticated")
end
end
describe "#authenticate_user_from_personal_access_token!" do
controller(ApplicationController) do
def index
render text: 'authenticated'
end
end
let(:user) { create(:user) }
let(:personal_access_token) { create(:personal_access_token, user: user) }
it "logs the user in when the 'personal_access_token' param is populated with the personal access token" do
get :index, personal_access_token: personal_access_token.token
expect(response.status).to eq(200)
expect(response.body).to eq('authenticated')
end
it "logs the user in when the 'PERSONAL_ACCESS_TOKEN' header is populated with the personal access token" do
@request.headers["PERSONAL_ACCESS_TOKEN"] = personal_access_token.token
get :index
expect(response.status).to eq(200)
expect(response.body).to eq('authenticated')
end
it "doesn't log the user in otherwise" do
get :index, personal_access_token: "token"
expect(response.status).to_not eq(200)
expect(response.body).to_not eq('authenticated')
end
end
end