Make oauth provider login generic

This commit is contained in:
Horatiu Eugen Vlad 2018-03-05 22:26:40 +00:00 committed by Douwe Maan
parent 62d6f1ed66
commit 6d3cb7e22e
8 changed files with 86 additions and 20 deletions

View file

@ -0,0 +1,4 @@
---
title: Make oauth provider login generic
merge_request: 8809
author: Horatiu Eugen Vlad

View file

@ -40,8 +40,8 @@ module Gitlab
end
def find_with_user_password(login, password)
# Avoid resource intensive login checks if password is not provided
return unless password.present?
# Avoid resource intensive checks if login credentials are not provided
return unless login.present? && password.present?
# Nothing to do here if internal auth is disabled and LDAP is
# not configured
@ -50,14 +50,26 @@ module Gitlab
Gitlab::Auth::UniqueIpsLimiter.limit_user! do
user = User.by_login(login)
# If no user is found, or it's an LDAP server, try LDAP.
# LDAP users are only authenticated via LDAP
if user.nil? || user.ldap_user?
# Second chance - try LDAP authentication
Gitlab::Auth::LDAP::Authentication.login(login, password)
elsif Gitlab::CurrentSettings.password_authentication_enabled_for_git?
user if user.active? && user.valid_password?(password)
return if user && !user.active?
authenticators = []
if user
authenticators << Gitlab::Auth::OAuth::Provider.authentication(user, 'database')
# Add authenticators for all identities if user is not nil
user&.identities&.each do |identity|
authenticators << Gitlab::Auth::OAuth::Provider.authentication(user, identity.provider)
end
else
# If no user is provided, try LDAP.
# LDAP users are only authenticated via LDAP
authenticators << Gitlab::Auth::LDAP::Authentication
end
authenticators.compact!
user if authenticators.find { |auth| auth.login(login, password) }
end
end

View file

@ -0,0 +1,16 @@
# These calls help to authenticate to OAuth provider by providing username and password
#
module Gitlab
module Auth
module Database
class Authentication < Gitlab::Auth::OAuth::Authentication
def login(login, password)
return false unless Gitlab::CurrentSettings.password_authentication_enabled_for_git?
user&.valid_password?(password)
end
end
end
end
end

View file

@ -7,7 +7,7 @@
module Gitlab
module Auth
module LDAP
class Authentication
class Authentication < Gitlab::Auth::OAuth::Authentication
def self.login(login, password)
return unless Gitlab::Auth::LDAP::Config.enabled?
return unless login.present? && password.present?
@ -28,11 +28,7 @@ module Gitlab
Gitlab::Auth::LDAP::Config.providers
end
attr_accessor :provider, :ldap_user
def initialize(provider)
@provider = provider
end
attr_accessor :ldap_user
def login(login, password)
@ldap_user = adapter.bind_as(
@ -62,7 +58,7 @@ module Gitlab
end
def user
return nil unless ldap_user
return unless ldap_user
Gitlab::Auth::LDAP::User.find_by_uid_and_provider(ldap_user.dn, provider)
end

View file

@ -0,0 +1,21 @@
# These calls help to authenticate to OAuth provider by providing username and password
#
module Gitlab
module Auth
module OAuth
class Authentication
attr_reader :provider, :user
def initialize(provider, user = nil)
@provider = provider
@user = user
end
def login(login, password)
raise NotImplementedError
end
end
end
end
end

View file

@ -8,11 +8,28 @@ module Gitlab
"google_oauth2" => "Google"
}.freeze
def self.authentication(user, provider)
return unless user
return unless enabled?(provider)
authenticator =
case provider
when /^ldap/
Gitlab::Auth::LDAP::Authentication
when 'database'
Gitlab::Auth::Database::Authentication
end
authenticator&.new(provider, user)
end
def self.providers
Devise.omniauth_providers
end
def self.enabled?(name)
return true if name == 'database'
providers.include?(name.to_sym)
end

View file

@ -161,7 +161,7 @@ module Gitlab
def find_by_uid_and_provider
identity = Identity.with_extern_uid(auth_hash.provider, auth_hash.uid).take
identity && identity.user
identity&.user
end
def build_new_user

View file

@ -795,9 +795,9 @@ describe 'Git HTTP requests' do
let(:path) { 'doesnt/exist.git' }
before do
allow(Gitlab::Auth::LDAP::Config).to receive(:enabled?).and_return(true)
allow(Gitlab::Auth::LDAP::Authentication).to receive(:login).and_return(nil)
allow(Gitlab::Auth::LDAP::Authentication).to receive(:login).with(user.username, user.password).and_return(user)
allow(Gitlab::Auth::OAuth::Provider).to receive(:enabled?).and_return(true)
allow_any_instance_of(Gitlab::Auth::LDAP::Authentication).to receive(:login).and_return(nil)
allow_any_instance_of(Gitlab::Auth::LDAP::Authentication).to receive(:login).with(user.username, user.password).and_return(user)
end
it_behaves_like 'pulls require Basic HTTP Authentication'