Skip to content
Snippets Groups Projects
Commit cb5a5eb8 authored by Robin Bobbitt's avatar Robin Bobbitt
Browse files

Instruct user to use a personal access token for Git over HTTP

If internal auth is disabled and LDAP is not configured on the instance,
present the user with a message to create a personal access token if his
Git over HTTP auth attempt fails.
parent 359a8f1f
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -39,7 +39,7 @@ class JwtController < ApplicationController
errors: [
{ code: 'UNAUTHORIZED',
message: "HTTP Basic: Access denied\n" \
"You have 2FA enabled, please use a personal access token for Git over HTTP.\n" \
"You must use a personal access token with 'api' scope for Git over HTTP.\n" \
"You can generate one at #{profile_personal_access_tokens_url}" }
]
}, status: 401
Loading
Loading
Loading
Loading
@@ -104,7 +104,7 @@ class Projects::GitHttpClientController < Projects::ApplicationController
 
def render_missing_personal_token
render plain: "HTTP Basic: Access denied\n" \
"You have 2FA enabled, please use a personal access token for Git over HTTP.\n" \
"You must use a personal access token with 'api' scope for Git over HTTP.\n" \
"You can generate one at #{profile_personal_access_tokens_url}",
status: 401
end
Loading
Loading
---
title: Instruct user to use personal access token for Git over HTTP
merge_request: 11986
author: Robin Bobbitt
Loading
Loading
@@ -37,7 +37,11 @@ module Gitlab
rate_limit!(ip, success: result.success?, login: login)
Gitlab::Auth::UniqueIpsLimiter.limit_user!(result.actor)
 
result
return result if result.success? || current_application_settings.signin_enabled? || Gitlab::LDAP::Config.enabled?
# If sign-in is disabled and LDAP is not configured, recommend a
# personal access token on failed auth attempts
raise Gitlab::Auth::MissingPersonalTokenError
end
 
def find_with_user_password(login, password)
Loading
Loading
Loading
Loading
@@ -204,6 +204,12 @@ describe Gitlab::Auth, lib: true do
expect(gl_auth).to receive(:rate_limit!).with('ip', success: false, login: login)
expect(gl_auth.find_for_git_client(login, 'bar', project: nil, ip: 'ip')).to eq(Gitlab::Auth::Result.new)
end
it 'throws an error suggesting user create a PAT when internal auth is disabled' do
allow_any_instance_of(ApplicationSetting).to receive(:signin_enabled?) { false }
expect { gl_auth.find_for_git_client('foo', 'bar', project: nil, ip: 'ip') }.to raise_error(Gitlab::Auth::MissingPersonalTokenError)
end
end
 
describe 'find_with_user_password' do
Loading
Loading
Loading
Loading
@@ -418,17 +418,17 @@ describe 'Git HTTP requests', lib: true do
end
 
context 'when username and password are provided' do
it 'rejects pulls with 2FA error message' do
it 'rejects pulls with personal access token error message' do
download(path, user: user.username, password: user.password) do |response|
expect(response).to have_http_status(:unauthorized)
expect(response.body).to include('You have 2FA enabled, please use a personal access token for Git over HTTP')
expect(response.body).to include('You must use a personal access token with \'api\' scope for Git over HTTP')
end
end
 
it 'rejects the push attempt' do
it 'rejects the push attempt with personal access token error message' do
upload(path, user: user.username, password: user.password) do |response|
expect(response).to have_http_status(:unauthorized)
expect(response.body).to include('You have 2FA enabled, please use a personal access token for Git over HTTP')
expect(response.body).to include('You must use a personal access token with \'api\' scope for Git over HTTP')
end
end
end
Loading
Loading
@@ -441,6 +441,41 @@ describe 'Git HTTP requests', lib: true do
end
end
 
context 'when internal auth is disabled' do
before do
allow_any_instance_of(ApplicationSetting).to receive(:signin_enabled?) { false }
end
it 'rejects pulls with personal access token error message' do
download(path, user: 'foo', password: 'bar') do |response|
expect(response).to have_http_status(:unauthorized)
expect(response.body).to include('You must use a personal access token with \'api\' scope for Git over HTTP')
end
end
it 'rejects pushes with personal access token error message' do
upload(path, user: 'foo', password: 'bar') do |response|
expect(response).to have_http_status(:unauthorized)
expect(response.body).to include('You must use a personal access token with \'api\' scope for Git over HTTP')
end
end
context 'when LDAP is configured' do
before do
allow(Gitlab::LDAP::Config).to receive(:enabled?).and_return(true)
allow_any_instance_of(Gitlab::LDAP::Authentication).
to receive(:login).and_return(nil)
end
it 'does not display the personal access token error message' do
upload(path, user: 'foo', password: 'bar') do |response|
expect(response).to have_http_status(:unauthorized)
expect(response.body).not_to include('You must use a personal access token with \'api\' scope for Git over HTTP')
end
end
end
end
context "when blank password attempts follow a valid login" do
def attempt_login(include_password)
password = include_password ? user.password : ""
Loading
Loading
Loading
Loading
@@ -70,7 +70,7 @@ describe JwtController do
context 'without personal token' do
it 'rejects the authorization attempt' do
expect(response).to have_http_status(401)
expect(response.body).to include('You have 2FA enabled, please use a personal access token for Git over HTTP')
expect(response.body).to include('You must use a personal access token with \'api\' scope for Git over HTTP')
end
end
 
Loading
Loading
@@ -88,9 +88,24 @@ describe JwtController do
context 'using invalid login' do
let(:headers) { { authorization: credentials('invalid', 'password') } }
 
subject! { get '/jwt/auth', parameters, headers }
context 'when internal auth is enabled' do
it 'rejects the authorization attempt' do
get '/jwt/auth', parameters, headers
expect(response).to have_http_status(401)
expect(response.body).not_to include('You must use a personal access token with \'api\' scope for Git over HTTP')
end
end
 
it { expect(response).to have_http_status(401) }
context 'when internal auth is disabled' do
it 'rejects the authorization attempt with personal access token message' do
allow_any_instance_of(ApplicationSetting).to receive(:signin_enabled?) { false }
get '/jwt/auth', parameters, headers
expect(response).to have_http_status(401)
expect(response.body).to include('You must use a personal access token with \'api\' scope for Git over HTTP')
end
end
end
end
 
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