Commit e2f9c876 authored by Patricio Cano's avatar Patricio Cano

Added checks for 2FA to the API `/sessions` endpoint and the Resource Owner...

Added checks for 2FA to the API `/sessions` endpoint and the Resource Owner Password Credentials flow.
parent 717366d2
class UserRetrievalService
attr_accessor :login, :password
def initialize(login, password)
@login = login
@password = password
end
def execute
user = Gitlab::Auth.find_with_user_password(login, password)
user unless user.two_factor_enabled?
end
end
\ No newline at end of file
......@@ -12,7 +12,7 @@ Doorkeeper.configure do
end
resource_owner_from_credentials do |routes|
Gitlab::Auth.find_with_user_password(params[:username], params[:password])
UserRetrievalService.new(params[:username], params[:password]).execute
end
# If you want to restrict access to the web interface for adding oauth authorized applications, you need to declare the block below.
......
......@@ -275,6 +275,10 @@ module API
end
end
def render_2fa_error!
render_api_error!('401 You have 2FA enabled. Please use a personal access token to access the API', 401)
end
def render_api_error!(message, status)
error!({ 'message' => message }, status)
end
......
......@@ -14,6 +14,7 @@ module API
user = Gitlab::Auth.find_with_user_password(params[:email] || params[:login], params[:password])
return unauthorized! unless user
return render_2fa_error! if user.two_factor_enabled?
present user, with: Entities::UserLogin
end
end
......
require 'spec_helper'
describe API::API, api: true do
include ApiHelpers
context 'Resource Owner Password Credentials' do
def request_oauth_token(user)
post '/oauth/token', username: user.username, password: user.password, grant_type: 'password'
end
context 'when user has 2FA enabled' do
it 'does not create an access token' do
user = create(:user, :two_factor)
request_oauth_token(user)
expect(response).to have_http_status(401)
expect(json_response['error']).to eq('invalid_grant')
end
end
context 'when user does not have 2FA enabled' do
it 'creates an access token' do
user = create(:user)
request_oauth_token(user)
expect(response).to have_http_status(200)
expect(json_response['access_token']).not_to be_nil
end
end
end
end
\ No newline at end of file
......@@ -17,6 +17,16 @@ describe API::API, api: true do
expect(json_response['can_create_project']).to eq(user.can_create_project?)
expect(json_response['can_create_group']).to eq(user.can_create_group?)
end
context 'with 2FA enabled' do
it 'rejects sign in attempts' do
user = create(:user, :two_factor)
post api('/session'), email: user.email, password: user.password
expect(response).to have_http_status(401)
end
end
end
context 'when email has case-typo and password is valid' do
......
require 'spec_helper'
describe UserRetrievalService, services: true do
context 'user retrieval' do
it 'retrieves the correct user' do
user = create(:user)
retrieved_user = described_class.new(user.username, user.password).execute
expect(retrieved_user).to eq(user)
end
it 'returns nil when 2FA is enabled' do
user = create(:user, :two_factor)
retrieved_user = described_class.new(user.username, user.password).execute
expect(retrieved_user).to be_nil
end
end
end
\ No newline at end of file
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