Make oauth provider login generic
This commit is contained in:
parent
62d6f1ed66
commit
6d3cb7e22e
8 changed files with 86 additions and 20 deletions
4
changelogs/unreleased/oauth_generic_provider.yml
Normal file
4
changelogs/unreleased/oauth_generic_provider.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Make oauth provider login generic
|
||||
merge_request: 8809
|
||||
author: Horatiu Eugen Vlad
|
|
@ -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
|
||||
|
||||
|
|
16
lib/gitlab/auth/database/authentication.rb
Normal file
16
lib/gitlab/auth/database/authentication.rb
Normal 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
|
|
@ -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
|
||||
|
|
21
lib/gitlab/auth/o_auth/authentication.rb
Normal file
21
lib/gitlab/auth/o_auth/authentication.rb
Normal 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
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'
|
||||
|
|
Loading…
Reference in a new issue