Commit 294fa6fc authored by Douwe Maan's avatar Douwe Maan

Remove authentication using user.private_token

parent c03d39df
...@@ -11,7 +11,7 @@ class ApplicationController < ActionController::Base ...@@ -11,7 +11,7 @@ class ApplicationController < ActionController::Base
include EnforcesTwoFactorAuthentication include EnforcesTwoFactorAuthentication
include WithPerformanceBar include WithPerformanceBar
before_action :authenticate_user_from_private_token! before_action :authenticate_user_from_personal_access_token!
before_action :authenticate_user_from_rss_token! before_action :authenticate_user_from_rss_token!
before_action :authenticate_user! before_action :authenticate_user!
before_action :validate_user_service_ticket! before_action :validate_user_service_ticket!
...@@ -100,13 +100,12 @@ class ApplicationController < ActionController::Base ...@@ -100,13 +100,12 @@ class ApplicationController < ActionController::Base
return try(:authenticated_user) return try(:authenticated_user)
end end
# This filter handles both private tokens and personal access tokens def authenticate_user_from_personal_access_token!
def authenticate_user_from_private_token!
token = params[:private_token].presence || request.headers['PRIVATE-TOKEN'].presence token = params[:private_token].presence || request.headers['PRIVATE-TOKEN'].presence
return unless token.present? return unless token.present?
user = User.find_by_authentication_token(token) || User.find_by_personal_access_token(token) user = User.find_by_personal_access_token(token)
sessionless_sign_in(user) sessionless_sign_in(user)
end end
......
...@@ -517,7 +517,7 @@ Feature.get(:auto_devops_banner_disabled).enable ...@@ -517,7 +517,7 @@ Feature.get(:auto_devops_banner_disabled).enable
Or through the HTTP API with an admin access token: Or through the HTTP API with an admin access token:
```sh ```sh
curl --data "value=true" --header "PRIVATE-TOKEN: private_token" https://gitlab.example.com/api/v4/features/auto_devops_banner_disabled curl --data "value=true" --header "PRIVATE-TOKEN: personal_access_token" https://gitlab.example.com/api/v4/features/auto_devops_banner_disabled
``` ```
[ce-37115]: https://gitlab.com/gitlab-org/gitlab-ce/issues/37115 [ce-37115]: https://gitlab.com/gitlab-org/gitlab-ce/issues/37115
......
...@@ -44,7 +44,7 @@ module API ...@@ -44,7 +44,7 @@ module API
module HelperMethods module HelperMethods
def find_current_user def find_current_user
user = user =
find_user_from_private_token || find_user_from_personal_access_token ||
find_user_from_oauth_token || find_user_from_oauth_token ||
find_user_from_warden find_user_from_warden
...@@ -61,13 +61,14 @@ module API ...@@ -61,13 +61,14 @@ module API
private private
def find_user_from_private_token def find_user_from_personal_access_token
token_string = private_token.to_s token_string = private_token.to_s
return nil unless token_string.present? return nil unless token_string.present?
user = access_token = PersonalAccessToken.find_by_token(token_string)
find_user_by_authentication_token(token_string) || raise UnauthorizedError unless access_token
find_user_by_personal_access_token(token_string)
user = find_user_by_access_token(access_token)
raise UnauthorizedError unless user raise UnauthorizedError unless user
...@@ -99,17 +100,6 @@ module API ...@@ -99,17 +100,6 @@ module API
find_user_by_access_token(access_token) find_user_by_access_token(access_token)
end end
def find_user_by_authentication_token(token_string)
User.find_by_authentication_token(token_string)
end
def find_user_by_personal_access_token(token_string)
access_token = PersonalAccessToken.find_by_token(token_string)
return unless access_token
find_user_by_access_token(access_token)
end
# Check the Rails session for valid authentication details # Check the Rails session for valid authentication details
def find_user_from_warden def find_user_from_warden
warden.try(:authenticate) if verified_request? warden.try(:authenticate) if verified_request?
......
...@@ -50,70 +50,36 @@ describe ApplicationController do ...@@ -50,70 +50,36 @@ describe ApplicationController do
end end
end end
describe "#authenticate_user_from_token!" do describe "#authenticate_user_from_personal_access_token!" do
describe "authenticating a user from a private token" do controller(described_class) do
controller(described_class) do def index
def index render text: 'authenticated'
render text: "authenticated"
end
end
context "when the 'private_token' param is populated with the private token" do
it "logs the user in" do
get :index, private_token: user.private_token
expect(response).to have_gitlab_http_status(200)
expect(response.body).to eq("authenticated")
end
end
context "when the 'PRIVATE-TOKEN' header is populated with the private token" do
it "logs the user in" do
@request.headers['PRIVATE-TOKEN'] = user.private_token
get :index
expect(response).to have_gitlab_http_status(200)
expect(response.body).to eq("authenticated")
end
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).not_to eq(200)
expect(response.body).not_to eq("authenticated")
end end
end end
describe "authenticating a user from a personal access token" do let(:personal_access_token) { create(:personal_access_token, user: user) }
controller(described_class) do
def index
render text: 'authenticated'
end
end
let(:personal_access_token) { create(:personal_access_token, user: user) }
context "when the 'personal_access_token' param is populated with the personal access token" do context "when the 'personal_access_token' param is populated with the personal access token" do
it "logs the user in" do it "logs the user in" do
get :index, private_token: personal_access_token.token get :index, private_token: personal_access_token.token
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
expect(response.body).to eq('authenticated') expect(response.body).to eq('authenticated')
end
end end
end
context "when the 'PERSONAL_ACCESS_TOKEN' header is populated with the personal access token" do context "when the 'PERSONAL_ACCESS_TOKEN' header is populated with the personal access token" do
it "logs the user in" do it "logs the user in" do
@request.headers["PRIVATE-TOKEN"] = personal_access_token.token @request.headers["PRIVATE-TOKEN"] = personal_access_token.token
get :index get :index
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
expect(response.body).to eq('authenticated') expect(response.body).to eq('authenticated')
end
end end
end
it "doesn't log the user in otherwise" do it "doesn't log the user in otherwise" do
get :index, private_token: "token" get :index, private_token: "token"
expect(response.status).not_to eq(200) expect(response.status).not_to eq(200)
expect(response.body).not_to eq('authenticated') expect(response.body).not_to eq('authenticated')
end
end end
end end
...@@ -152,11 +118,15 @@ describe ApplicationController do ...@@ -152,11 +118,15 @@ describe ApplicationController do
end end
end end
before do
sign_in user
end
context 'when format is handled' do context 'when format is handled' do
let(:requested_format) { :json } let(:requested_format) { :json }
it 'returns 200 response' do it 'returns 200 response' do
get :index, private_token: user.private_token, format: requested_format get :index, format: requested_format
expect(response).to have_gitlab_http_status 200 expect(response).to have_gitlab_http_status 200
end end
...@@ -164,7 +134,7 @@ describe ApplicationController do ...@@ -164,7 +134,7 @@ describe ApplicationController do
context 'when format is not handled' do context 'when format is not handled' do
it 'returns 404 response' do it 'returns 404 response' do
get :index, private_token: user.private_token get :index
expect(response).to have_gitlab_http_status 404 expect(response).to have_gitlab_http_status 404
end end
......
...@@ -13,8 +13,10 @@ describe "Dashboard Issues Feed" do ...@@ -13,8 +13,10 @@ describe "Dashboard Issues Feed" do
end end
describe "atom feed" do describe "atom feed" do
it "renders atom feed via private token" do it "renders atom feed via personal access token" do
visit issues_dashboard_path(:atom, private_token: user.private_token) personal_access_token = create(:personal_access_token, user: user)
visit issues_dashboard_path(:atom, private_token: personal_access_token.token)
expect(response_headers['Content-Type']).to have_content('application/atom+xml') expect(response_headers['Content-Type']).to have_content('application/atom+xml')
expect(body).to have_selector('title', text: "#{user.name} issues") expect(body).to have_selector('title', text: "#{user.name} issues")
......
...@@ -4,9 +4,11 @@ describe "Dashboard Feed" do ...@@ -4,9 +4,11 @@ describe "Dashboard Feed" do
describe "GET /" do describe "GET /" do
let!(:user) { create(:user, name: "Jonh") } let!(:user) { create(:user, name: "Jonh") }
context "projects atom feed via private token" do context "projects atom feed via personal access token" do
it "renders projects atom feed" do it "renders projects atom feed" do
visit dashboard_projects_path(:atom, private_token: user.private_token) personal_access_token = create(:personal_access_token, user: user)
visit dashboard_projects_path(:atom, private_token: personal_access_token.token)
expect(body).to have_selector('feed title') expect(body).to have_selector('feed title')
end end
end end
......
...@@ -28,10 +28,12 @@ describe 'Issues Feed' do ...@@ -28,10 +28,12 @@ describe 'Issues Feed' do
end end
end end
context 'when authenticated via private token' do context 'when authenticated via personal access token' do
it 'renders atom feed' do it 'renders atom feed' do
personal_access_token = create(:personal_access_token, user: user)
visit project_issues_path(project, :atom, visit project_issues_path(project, :atom,
private_token: user.private_token) private_token: personal_access_token.token)
expect(response_headers['Content-Type']) expect(response_headers['Content-Type'])
.to have_content('application/atom+xml') .to have_content('application/atom+xml')
......
...@@ -4,9 +4,11 @@ describe "User Feed" do ...@@ -4,9 +4,11 @@ describe "User Feed" do
describe "GET /" do describe "GET /" do
let!(:user) { create(:user) } let!(:user) { create(:user) }
context 'user atom feed via private token' do context 'user atom feed via personal access token' do
it "renders user atom feed" do it "renders user atom feed" do
visit user_path(user, :atom, private_token: user.private_token) personal_access_token = create(:personal_access_token, user: user)
visit user_path(user, :atom, private_token: personal_access_token.token)
expect(body).to have_selector('feed title') expect(body).to have_selector('feed title')
end end
end end
......
...@@ -56,20 +56,6 @@ describe 'Profile account page' do ...@@ -56,20 +56,6 @@ describe 'Profile account page' do
end end
end end
describe 'when I reset private token' do
before do
visit profile_account_path
end
it 'resets private token' do
previous_token = find("#private-token").value
click_link('Reset private token')
expect(find('#private-token').value).not_to eq(previous_token)
end
end
describe 'when I reset RSS token' do describe 'when I reset RSS token' do
before do before do
visit profile_account_path visit profile_account_path
......
...@@ -12,7 +12,7 @@ shared_examples 'TokenAuthenticatable' do ...@@ -12,7 +12,7 @@ shared_examples 'TokenAuthenticatable' do
end end
describe User, 'TokenAuthenticatable' do describe User, 'TokenAuthenticatable' do
let(:token_field) { :authentication_token } let(:token_field) { :rss_token }
it_behaves_like 'TokenAuthenticatable' it_behaves_like 'TokenAuthenticatable'
describe 'ensures authentication token' do describe 'ensures authentication token' do
......
...@@ -346,7 +346,6 @@ describe User do ...@@ -346,7 +346,6 @@ describe User do
describe "Respond to" do describe "Respond to" do
it { is_expected.to respond_to(:admin?) } it { is_expected.to respond_to(:admin?) }
it { is_expected.to respond_to(:name) } it { is_expected.to respond_to(:name) }
it { is_expected.to respond_to(:private_token) }
it { is_expected.to respond_to(:external?) } it { is_expected.to respond_to(:external?) }
end end
...@@ -526,14 +525,6 @@ describe User do ...@@ -526,14 +525,6 @@ describe User do
end end
end end
describe 'authentication token' do
it "has authentication token" do
user = create(:user)
expect(user.authentication_token).not_to be_blank
end
end
describe 'ensure incoming email token' do describe 'ensure incoming email token' do
it 'has incoming email token' do it 'has incoming email token' do
user = create(:user) user = create(:user)
......
...@@ -25,7 +25,7 @@ describe 'doorkeeper access' do ...@@ -25,7 +25,7 @@ describe 'doorkeeper access' do
end end
end end
describe "authorization by private token" do describe "authorization by OAuth token" do
it "returns authentication success" do it "returns authentication success" do
get api("/user", user) get api("/user", user)
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
......
...@@ -28,17 +28,17 @@ describe API::Helpers do ...@@ -28,17 +28,17 @@ describe API::Helpers do
allow_any_instance_of(self.class).to receive(:options).and_return({}) allow_any_instance_of(self.class).to receive(:options).and_return({})
end end
def set_env(user_or_token, identifier) def set_env(token, identifier)
clear_env clear_env
clear_param clear_param
env[API::APIGuard::PRIVATE_TOKEN_HEADER] = user_or_token.respond_to?(:private_token) ? user_or_token.private_token : user_or_token env[API::APIGuard::PRIVATE_TOKEN_HEADER] = token
env[API::Helpers::SUDO_HEADER] = identifier.to_s env[API::Helpers::SUDO_HEADER] = identifier.to_s
end end
def set_param(user_or_token, identifier) def set_param(token, identifier)
clear_env clear_env
clear_param clear_param
params[API::APIGuard::PRIVATE_TOKEN_PARAM] = user_or_token.respond_to?(:private_token) ? user_or_token.private_token : user_or_token params[API::APIGuard::PRIVATE_TOKEN_PARAM] = token
params[API::Helpers::SUDO_PARAM] = identifier.to_s params[API::Helpers::SUDO_PARAM] = identifier.to_s
end end
...@@ -160,41 +160,6 @@ describe API::Helpers do ...@@ -160,41 +160,6 @@ describe API::Helpers do
end end
end end
describe "when authenticating using a user's private token" do
it "returns a 401 response for an invalid token" do
env[API::APIGuard::PRIVATE_TOKEN_HEADER] = 'invalid token'
allow_any_instance_of(self.class).to receive(:doorkeeper_guard) { false }
expect { current_user }.to raise_error /401/
end
it "returns a 401 response for a user without access" do
env[API::APIGuard::PRIVATE_TOKEN_HEADER] = user.private_token
allow_any_instance_of(Gitlab::UserAccess).to receive(:allowed?).and_return(false)
expect { current_user }.to raise_error /401/
end
it 'returns a 401 response for a user who is blocked' do
user.block!
env[API::APIGuard::PRIVATE_TOKEN_HEADER] = user.private_token
expect { current_user }.to raise_error /401/
end
it "leaves user as is when sudo not specified" do
env[API::APIGuard::PRIVATE_TOKEN_HEADER] = user.private_token
expect(current_user).to eq(user)
clear_env
params[API::APIGuard::PRIVATE_TOKEN_PARAM] = user.private_token
expect(current_user).to eq(user)
end
end
describe "when authenticating using a user's personal access tokens" do describe "when authenticating using a user's personal access tokens" do
let(:personal_access_token) { create(:personal_access_token, user: user) } let(:personal_access_token) { create(:personal_access_token, user: user) }
...@@ -445,16 +410,6 @@ describe API::Helpers do ...@@ -445,16 +410,6 @@ describe API::Helpers do
expect { sudo? }.to raise_error '403 - {"message"=>"403 Forbidden - Private token must be specified in order to use sudo"}' expect { sudo? }.to raise_error '403 - {"message"=>"403 Forbidden - Private token must be specified in order to use sudo"}'
end end
end end
context 'private access token is used' do
before do
set_env(admin.private_token, user.id)
end
it 'returns true' do
expect(sudo?).to be_truthy
end
end
end end
end end
......
...@@ -1097,14 +1097,6 @@ describe API::Users do ...@@ -1097,14 +1097,6 @@ describe API::Users do
end end
end end
context 'with private token' do
it 'returns 403 without private token when sudo defined' do
get api("/user?private_token=#{user.private_token}&sudo=123")
expect(response).to have_gitlab_http_status(403)
end
end
it 'returns current user without private token when sudo not defined' do it 'returns current user without private token when sudo not defined' do
get api("/user", user) get api("/user", user)
...@@ -1139,24 +1131,6 @@ describe API::Users do ...@@ -1139,24 +1131,6 @@ describe API::Users do
expect(json_response['id']).to eq(admin.id) expect(json_response['id']).to eq(admin.id)
end end
end end
context 'with private token' do
it 'returns sudoed user with private token when sudo defined' do
get api("/user?private_token=#{admin.private_token}&sudo=#{user.id}")
expect(response).to have_gitlab_http_status(200)
expect(response).to match_response_schema('public_api/v4/user/login')
expect(json_response['id']).to eq(user.id)
end
it 'returns initial current user without private token but with is_admin when sudo not defined' do
get api("/user?private_token=#{admin.private_token}")
expect(response).to have_gitlab_http_status(200)
expect(response).to match_response_schema('public_api/v4/user/admin')
expect(json_response['id']).to eq(admin.id)
end
end
end end
context 'with unauthenticated user' do context 'with unauthenticated user' do
......
...@@ -18,21 +18,23 @@ module ApiHelpers ...@@ -18,21 +18,23 @@ module ApiHelpers
# #
# Returns the relative path to the requested API resource # Returns the relative path to the requested API resource
def api(path, user = nil, version: API::API.version, personal_access_token: nil, oauth_access_token: nil) def api(path, user = nil, version: API::API.version, personal_access_token: nil, oauth_access_token: nil)
"/api/#{version}#{path}" + full_path = "/api/#{version}#{path}"
# Normalize query string if oauth_access_token
(path.index('?') ? '' : '?') + query_string = "access_token=#{oauth_access_token.token}"
elsif personal_access_token
query_string = "private_token=#{personal_access_token.token}"
elsif user
personal_access_token = create(:personal_access_token, user: user)
query_string = "private_token=#{personal_access_token.token}"
end
if personal_access_token.present? if query_string
"&private_token=#{personal_access_token.token}" full_path << (path.index('?') ? '&' : '?')
elsif oauth_access_token.present? full_path << query_string
"&access_token=#{oauth_access_token.token}" end
# Append private_token if given a User object
elsif user.respond_to?(:private_token) full_path
"&private_token=#{user.private_token}"
else
''
end
end end
# Temporary helper method for simplifying V3 exclusive API specs # Temporary helper method for simplifying V3 exclusive API specs
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment