Commit 1ad5df49 authored by Horatiu Eugen Vlad's avatar Horatiu Eugen Vlad

Moved o_auth/saml/ldap modules under gitlab/auth

parent 77097c91
......@@ -124,8 +124,8 @@ Lint/DuplicateMethods:
- 'lib/gitlab/git/repository.rb'
- 'lib/gitlab/git/tree.rb'
- 'lib/gitlab/git/wiki_page.rb'
- 'lib/gitlab/ldap/person.rb'
- 'lib/gitlab/o_auth/user.rb'
- 'lib/gitlab/auth/ldap/person.rb'
- 'lib/gitlab/auth/o_auth/user.rb'
# Offense count: 4
Lint/InterpolationCheck:
......@@ -812,7 +812,7 @@ Style/TrivialAccessors:
Exclude:
- 'app/models/external_issue.rb'
- 'app/serializers/base_serializer.rb'
- 'lib/gitlab/ldap/person.rb'
- 'lib/gitlab/auth/ldap/person.rb'
- 'lib/system_check/base_check.rb'
# Offense count: 4
......
......@@ -191,7 +191,7 @@ class ApplicationController < ActionController::Base
return unless signed_in? && session[:service_tickets]
valid = session[:service_tickets].all? do |provider, ticket|
Gitlab::OAuth::Session.valid?(provider, ticket)
Gitlab::Auth::OAuth::Session.valid?(provider, ticket)
end
unless valid
......@@ -215,7 +215,7 @@ class ApplicationController < ActionController::Base
if current_user && current_user.requires_ldap_check?
return unless current_user.try_obtain_ldap_lease
unless Gitlab::LDAP::Access.allowed?(current_user)
unless Gitlab::Auth::LDAP::Access.allowed?(current_user)
sign_out current_user
flash[:alert] = "Access denied for your LDAP account."
redirect_to new_user_session_path
......@@ -230,7 +230,7 @@ class ApplicationController < ActionController::Base
end
def gitlab_ldap_access(&block)
Gitlab::LDAP::Access.open { |access| yield(access) }
Gitlab::Auth::LDAP::Access.open { |access| yield(access) }
end
# JSON for infinite scroll via Pager object
......@@ -284,7 +284,7 @@ class ApplicationController < ActionController::Base
end
def github_import_configured?
Gitlab::OAuth::Provider.enabled?(:github)
Gitlab::Auth::OAuth::Provider.enabled?(:github)
end
def gitlab_import_enabled?
......@@ -292,7 +292,7 @@ class ApplicationController < ActionController::Base
end
def gitlab_import_configured?
Gitlab::OAuth::Provider.enabled?(:gitlab)
Gitlab::Auth::OAuth::Provider.enabled?(:gitlab)
end
def bitbucket_import_enabled?
......@@ -300,7 +300,7 @@ class ApplicationController < ActionController::Base
end
def bitbucket_import_configured?
Gitlab::OAuth::Provider.enabled?(:bitbucket)
Gitlab::Auth::OAuth::Provider.enabled?(:bitbucket)
end
def google_code_import_enabled?
......
......@@ -71,7 +71,7 @@ class Import::BitbucketController < Import::BaseController
end
def provider
Gitlab::OAuth::Provider.config_for('bitbucket')
Gitlab::Auth::OAuth::Provider.config_for('bitbucket')
end
def options
......
......@@ -10,8 +10,8 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
end
end
if Gitlab::LDAP::Config.enabled?
Gitlab::LDAP::Config.available_servers.each do |server|
if Gitlab::Auth::LDAP::Config.enabled?
Gitlab::Auth::LDAP::Config.available_servers.each do |server|
define_method server['provider_name'] do
ldap
end
......@@ -31,7 +31,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
# We only find ourselves here
# if the authentication to LDAP was successful.
def ldap
ldap_user = Gitlab::LDAP::User.new(oauth)
ldap_user = Gitlab::Auth::LDAP::User.new(oauth)
ldap_user.save if ldap_user.changed? # will also save new users
@user = ldap_user.gl_user
......@@ -62,13 +62,13 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
redirect_to after_sign_in_path_for(current_user)
end
else
saml_user = Gitlab::Saml::User.new(oauth)
saml_user = Gitlab::Auth::Saml::User.new(oauth)
saml_user.save if saml_user.changed?
@user = saml_user.gl_user
continue_login_process
end
rescue Gitlab::OAuth::SignupDisabledError
rescue Gitlab::Auth::OAuth::User::SignupDisabledError
handle_signup_error
end
......@@ -106,20 +106,20 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
log_audit_event(current_user, with: oauth['provider'])
redirect_to profile_account_path, notice: 'Authentication method updated'
else
oauth_user = Gitlab::OAuth::User.new(oauth)
oauth_user = Gitlab::Auth::OAuth::User.new(oauth)
oauth_user.save
@user = oauth_user.gl_user
continue_login_process
end
rescue Gitlab::OAuth::SigninDisabledForProviderError
rescue Gitlab::Auth::OAuth::User::SigninDisabledForProviderError
handle_disabled_provider
rescue Gitlab::OAuth::SignupDisabledError
rescue Gitlab::Auth::OAuth::User::SignupDisabledError
handle_signup_error
end
def handle_service_ticket(provider, ticket)
Gitlab::OAuth::Session.create provider, ticket
Gitlab::Auth::OAuth::Session.create provider, ticket
session[:service_tickets] ||= {}
session[:service_tickets][provider] = ticket
end
......@@ -142,7 +142,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
end
def handle_signup_error
label = Gitlab::OAuth::Provider.label_for(oauth['provider'])
label = Gitlab::Auth::OAuth::Provider.label_for(oauth['provider'])
message = "Signing in using your #{label} account without a pre-existing GitLab account is not allowed."
if Gitlab::CurrentSettings.allow_signup?
......@@ -171,7 +171,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
end
def handle_disabled_provider
label = Gitlab::OAuth::Provider.label_for(oauth['provider'])
label = Gitlab::Auth::OAuth::Provider.label_for(oauth['provider'])
flash[:alert] = "Signing in using #{label} has been disabled"
redirect_to new_user_session_path
......
......@@ -16,7 +16,7 @@ class SessionsController < Devise::SessionsController
def new
set_minimum_password_length
@ldap_servers = Gitlab::LDAP::Config.available_servers
@ldap_servers = Gitlab::Auth::LDAP::Config.available_servers
super
end
......
......@@ -77,7 +77,7 @@ module ApplicationSettingsHelper
label_tag(checkbox_name, class: css_class) do
check_box_tag(checkbox_name, source, !disabled,
autocomplete: 'off') + Gitlab::OAuth::Provider.label_for(source)
autocomplete: 'off') + Gitlab::Auth::OAuth::Provider.label_for(source)
end
end
end
......
......@@ -3,7 +3,7 @@ module AuthHelper
FORM_BASED_PROVIDERS = [/\Aldap/, 'crowd'].freeze
def ldap_enabled?
Gitlab::LDAP::Config.enabled?
Gitlab::Auth::LDAP::Config.enabled?
end
def omniauth_enabled?
......@@ -15,11 +15,11 @@ module AuthHelper
end
def auth_providers
Gitlab::OAuth::Provider.providers
Gitlab::Auth::OAuth::Provider.providers
end
def label_for_provider(name)
Gitlab::OAuth::Provider.label_for(name)
Gitlab::Auth::OAuth::Provider.label_for(name)
end
def form_based_provider?(name)
......
......@@ -3,7 +3,7 @@ module ProfilesHelper
user_synced_attributes_metadata = current_user.user_synced_attributes_metadata
if user_synced_attributes_metadata&.synced?(attribute)
if user_synced_attributes_metadata.provider
Gitlab::OAuth::Provider.label_for(user_synced_attributes_metadata.provider)
Gitlab::Auth::OAuth::Provider.label_for(user_synced_attributes_metadata.provider)
else
'LDAP'
end
......
......@@ -17,12 +17,12 @@ class Identity < ActiveRecord::Base
end
def ldap?
Gitlab::OAuth::Provider.ldap_provider?(provider)
Gitlab::Auth::OAuth::Provider.ldap_provider?(provider)
end
def self.normalize_uid(provider, uid)
if Gitlab::OAuth::Provider.ldap_provider?(provider)
Gitlab::LDAP::Person.normalize_dn(uid)
if Gitlab::Auth::OAuth::Provider.ldap_provider?(provider)
Gitlab::Auth::LDAP::Person.normalize_dn(uid)
else
uid.to_s
end
......
......@@ -728,7 +728,7 @@ class User < ActiveRecord::Base
def ldap_user?
if identities.loaded?
identities.find { |identity| Gitlab::OAuth::Provider.ldap_provider?(identity.provider) && !identity.extern_uid.nil? }
identities.find { |identity| Gitlab::Auth::OAuth::Provider.ldap_provider?(identity.provider) && !identity.extern_uid.nil? }
else
identities.exists?(["provider LIKE ? AND extern_uid IS NOT NULL", "ldap%"])
end
......
......@@ -26,6 +26,6 @@ class UserSyncedAttributesMetadata < ActiveRecord::Base
private
def sync_profile_from_provider?
Gitlab::OAuth::Provider.sync_profile_from_provider?(provider)
Gitlab::Auth::OAuth::Provider.sync_profile_from_provider?(provider)
end
end
......@@ -173,7 +173,7 @@
Password authentication enabled for Git over HTTP(S)
.help-block
When disabled, a Personal Access Token
- if Gitlab::LDAP::Config.enabled?
- if Gitlab::Auth::LDAP::Config.enabled?
or LDAP password
must be used to authenticate.
- if omniauth_enabled? && button_based_providers.any?
......
......@@ -4,7 +4,7 @@
.form-group
= f.label :provider, class: 'control-label'
.col-sm-10
- values = Gitlab::OAuth::Provider.providers.map { |name| ["#{Gitlab::OAuth::Provider.label_for(name)} (#{name})", name] }
- values = Gitlab::Auth::OAuth::Provider.providers.map { |name| ["#{Gitlab::Auth::OAuth::Provider.label_for(name)} (#{name})", name] }
= f.select :provider, values, { allow_blank: false }, class: 'form-control'
.form-group
= f.label :extern_uid, "Identifier", class: 'control-label'
......
%tr
%td
#{Gitlab::OAuth::Provider.label_for(identity.provider)} (#{identity.provider})
#{Gitlab::Auth::OAuth::Provider.label_for(identity.provider)} (#{identity.provider})
%td
= identity.extern_uid
%td
......
---
title: Moved o_auth/saml/ldap modules under gitlab/auth
merge_request: 17359
author: Horatiu Eugen Vlad
......@@ -212,9 +212,9 @@ Devise.setup do |config|
# manager.default_strategies(scope: :user).unshift :some_external_strategy
# end
if Gitlab::LDAP::Config.enabled?
Gitlab::LDAP::Config.providers.each do |provider|
ldap_config = Gitlab::LDAP::Config.new(provider)
if Gitlab::Auth::LDAP::Config.enabled?
Gitlab::Auth::LDAP::Config.providers.each do |provider|
ldap_config = Gitlab::Auth::LDAP::Config.new(provider)
config.omniauth(provider, ldap_config.omniauth_options)
end
end
......@@ -235,9 +235,9 @@ Devise.setup do |config|
if provider['name'] == 'cas3'
provider['args'][:on_single_sign_out] = lambda do |request|
ticket = request.params[:session_index]
raise "Service Ticket not found." unless Gitlab::OAuth::Session.valid?(:cas3, ticket)
raise "Service Ticket not found." unless Gitlab::Auth::OAuth::Session.valid?(:cas3, ticket)
Gitlab::OAuth::Session.destroy(:cas3, ticket)
Gitlab::Auth::OAuth::Session.destroy(:cas3, ticket)
true
end
end
......@@ -245,8 +245,8 @@ Devise.setup do |config|
if provider['name'] == 'authentiq'
provider['args'][:remote_sign_out_handler] = lambda do |request|
authentiq_session = request.params['sid']
if Gitlab::OAuth::Session.valid?(:authentiq, authentiq_session)
Gitlab::OAuth::Session.destroy(:authentiq, authentiq_session)
if Gitlab::Auth::OAuth::Session.valid?(:authentiq, authentiq_session)
Gitlab::Auth::OAuth::Session.destroy(:authentiq, authentiq_session)
true
else
false
......
if Gitlab::LDAP::Config.enabled?
if Gitlab::Auth::LDAP::Config.enabled?
module OmniAuth::Strategies
Gitlab::LDAP::Config.available_servers.each do |server|
Gitlab::Auth::LDAP::Config.available_servers.each do |server|
# do not redeclare LDAP
next if server['provider_name'] == 'ldap'
......
......@@ -57,7 +57,7 @@ module Bitbucket
end
def provider
Gitlab::OAuth::Provider.config_for('bitbucket')
Gitlab::Auth::OAuth::Provider.config_for('bitbucket')
end
def options
......
......@@ -54,7 +54,7 @@ module Gitlab
# LDAP users are only authenticated via LDAP
if user.nil? || user.ldap_user?
# Second chance - try LDAP authentication
Gitlab::LDAP::Authentication.login(login, password)
Gitlab::Auth::LDAP::Authentication.login(login, password)
elsif Gitlab::CurrentSettings.password_authentication_enabled_for_git?
user if user.active? && user.valid_password?(password)
end
......@@ -85,7 +85,7 @@ module Gitlab
private
def authenticate_using_internal_or_ldap_password?
Gitlab::CurrentSettings.password_authentication_enabled_for_git? || Gitlab::LDAP::Config.enabled?
Gitlab::CurrentSettings.password_authentication_enabled_for_git? || Gitlab::Auth::LDAP::Config.enabled?
end
def service_request_check(login, password, project)
......
# LDAP authorization model
#
# * Check if we are allowed access (not blocked)
#
module Gitlab
module Auth
module LDAP
class Access
attr_reader :provider, :user
def self.open(user, &block)
Gitlab::Auth::LDAP::Adapter.open(user.ldap_identity.provider) do |adapter|
block.call(self.new(user, adapter))
end
end
def self.allowed?(user)
self.open(user) do |access|
if access.allowed?
Users::UpdateService.new(user, user: user, last_credential_check_at: Time.now).execute
true
else
false
end
end
end
def initialize(user, adapter = nil)
@adapter = adapter
@user = user
@provider = user.ldap_identity.provider
end
def allowed?
if ldap_user
unless ldap_config.active_directory
unblock_user(user, 'is available again') if user.ldap_blocked?
return true
end
# Block user in GitLab if he/she was blocked in AD
if Gitlab::Auth::LDAP::Person.disabled_via_active_directory?(user.ldap_identity.extern_uid, adapter)
block_user(user, 'is disabled in Active Directory')
false
else
unblock_user(user, 'is not disabled anymore') if user.ldap_blocked?
true
end
else
# Block the user if they no longer exist in LDAP/AD
block_user(user, 'does not exist anymore')
false
end
end
def adapter
@adapter ||= Gitlab::Auth::LDAP::Adapter.new(provider)
end
def ldap_config
Gitlab::Auth::LDAP::Config.new(provider)
end
def ldap_user
@ldap_user ||= Gitlab::Auth::LDAP::Person.find_by_dn(user.ldap_identity.extern_uid, adapter)
end
def block_user(user, reason)
user.ldap_block
Gitlab::AppLogger.info(
"LDAP account \"#{user.ldap_identity.extern_uid}\" #{reason}, " \
"blocking Gitlab user \"#{user.name}\" (#{user.email})"
)
end
def unblock_user(user, reason)
user.activate
Gitlab::AppLogger.info(
"LDAP account \"#{user.ldap_identity.extern_uid}\" #{reason}, " \
"unblocking Gitlab user \"#{user.name}\" (#{user.email})"
)
end
end
end
end
end
module Gitlab
module Auth
module LDAP
class Adapter
attr_reader :provider, :ldap
def self.open(provider, &block)
Net::LDAP.open(config(provider).adapter_options) do |ldap|
block.call(self.new(provider, ldap))
end
end
def self.config(provider)
Gitlab::Auth::LDAP::Config.new(provider)
end
def initialize(provider, ldap = nil)
@provider = provider
@ldap = ldap || Net::LDAP.new(config.adapter_options)
end
def config
Gitlab::Auth::LDAP::Config.new(provider)
end
def users(fields, value, limit = nil)
options = user_options(Array(fields), value, limit)
entries = ldap_search(options).select do |entry|
entry.respond_to? config.uid
end
entries.map do |entry|
Gitlab::Auth::LDAP::Person.new(entry, provider)
end
end
def user(*args)
users(*args).first
end
def dn_matches_filter?(dn, filter)
ldap_search(base: dn,
filter: filter,
scope: Net::LDAP::SearchScope_BaseObject,
attributes: %w{dn}).any?
end
def ldap_search(*args)
# Net::LDAP's `time` argument doesn't work. Use Ruby `Timeout` instead.
Timeout.timeout(config.timeout) do
results = ldap.search(*args)
if results.nil?
response = ldap.get_operation_result
unless response.code.zero?
Rails.logger.warn("LDAP search error: #{response.message}")
end
[]
else
results
end
end
rescue Net::LDAP::Error => error
Rails.logger.warn("LDAP search raised exception #{error.class}: #{error.message}")
[]
rescue Timeout::Error
Rails.logger.warn("LDAP search timed out after #{config.timeout} seconds")
[]
end
private
def user_options(fields, value, limit)
options = {
attributes: Gitlab::Auth::LDAP::Person.ldap_attributes(config),
base: config.base
}
options[:size] = limit if limit
if fields.include?('dn')
raise ArgumentError, 'It is not currently possible to search the DN and other fields at the same time.' if fields.size > 1
options[:base] = value
options[:scope] = Net::LDAP::SearchScope_BaseObject
else
filter = fields.map { |field| Net::LDAP::Filter.eq(field, value) }.inject(:|)
end
options.merge(filter: user_filter(filter))
end
def user_filter(filter = nil)
user_filter = config.constructed_user_filter if config.user_filter.present?
if user_filter && filter
Net::LDAP::Filter.join(filter, user_filter)
elsif user_filter
user_filter
else
filter
end
end
end
end
end
end
# Class to parse and transform the info provided by omniauth
#
module Gitlab
module Auth
module LDAP
class AuthHash < Gitlab::Auth::OAuth::AuthHash
def uid
@uid ||= Gitlab::Auth::LDAP::Person.normalize_dn(super)
end
def username
super.tap do |username|
username.downcase! if ldap_config.lowercase_usernames
end
end
private
def get_info(key)
attributes = ldap_config.attributes[key.to_s]
return super unless attributes
attributes = Array(attributes)
value = nil
attributes.each do |attribute|
value = get_raw(attribute)
value = value.first if value
break if value.present?
end
return super unless value
Gitlab::Utils.force_utf8(value)
value
end
def get_raw(key)
auth_hash.extra[:raw_info][key] if auth_hash.extra
end
def ldap_config
@ldap_config ||= Gitlab::Auth::LDAP::Config.new(self.provider)
end
end
end
end
end
# These calls help to authenticate to LDAP by providing username and password
#
# Since multiple LDAP servers are supported, it will loop through all of them
# until a valid bind is found
#
module Gitlab
module Auth
module LDAP
class Authentication
def self.login(login, password)
return unless Gitlab::Auth::LDAP::Config.enabled?
return unless login.present? && password.present?
auth = nil
# loop through providers until valid bind
providers.find do |provider|
auth = new(provider)
auth.login(login, password) # true will exit the loop
end
# If (login, password) was invalid for all providers, the value of auth is now the last
# Gitlab::Auth::LDAP::Authentication instance we tried.
auth.user
end
def self.providers
Gitlab::Auth::LDAP::Config.providers
end
attr_accessor :provider, :ldap_user
def initialize(provider)
@provider = provider
end
def login(login, password)
@ldap_user = adapter.bind_as(
filter: user_filter(login),
size: 1,
password: password
)
end
def adapter
OmniAuth::LDAP::Adaptor.new(config.omniauth_options)
end
def config
Gitlab::Auth::LDAP::Config.new(provider)
end
def user_filter(login)
filter = Net::LDAP::Filter.equals(config.uid, login)
# Apply LDAP user filter if present
if config.user_filter.present?
filter = Net::LDAP::Filter.join(filter, config.constructed_user_filter)
end
filter
end
def user
return nil unless ldap_user
Gitlab::Auth::LDAP::User.find_by_uid_and_provider(ldap_user.dn, provider)
end
end
end
end
end
# Load a specific server configuration
module Gitlab
module Auth
module LDAP
class Config
NET_LDAP_ENCRYPTION_METHOD = {
simple_tls: :simple_tls,
start_tls: :start_tls,
plain: nil
}.freeze
attr_accessor :provider, :options
def self.enabled?
Gitlab.config.ldap.enabled
end