Commit 3bc59fbb authored by Robert Speicher's avatar Robert Speicher

Merge branch 'ldap_external_users' into 'master'

Allow LDAP to handle external users, based on users' group memberships

Fixes gitlab-org/gitlab-ce#4009

These MR adds functionality to the `LdapGroupSync` feature that allows
it to receive an array of group names, in order for the members of these
groups to be marked as external users.

See merge request !432
parents 2331ec25 f7fee132
......@@ -2,6 +2,7 @@ Please view this file on the master branch, on stable branches it's out of date.
v 8.9.0 (unreleased)
- Fix nil user handling in UpdateMirrorService
- Allow LDAP to mark users as external based on their group membership. !432
v 8.8.3
- Add standard web hook headers to Jenkins CI post. !374
......
......@@ -351,6 +351,12 @@ production: &base
#
admin_group: ''
# LDAP group of users who should be marked as external users in GitLab
#
# Ex. ['Contractors', 'Interns']
#
external_groups: []
# Name of attribute which holds a ssh public key of the user object.
# If false or nil, SSH key syncronisation will be disabled.
#
......
......@@ -157,6 +157,7 @@ if Settings.ldap['enabled'] || Rails.env.test?
server['attributes'] = {} if server['attributes'].nil?
server['provider_name'] ||= "ldap#{key}".downcase
server['provider_class'] = OmniAuth::Utils.camelize(server['provider_name'])
server['external_groups'] = [] if server['external_groups'].nil?
Settings.ldap['servers'][key] = server
end
end
......
......@@ -146,6 +146,14 @@ main: # 'main' is the GitLab 'provider ID' of this LDAP server
#
admin_group: ''
# An array of CNs of groups containing users that should be considered external
#
# Ex. ['interns', 'contractors']
#
# Note: Not `cn=interns` or the full DN
#
external_groups: []
# The LDAP attribute containing a user's public SSH key
#
# Ex. ssh_public_key
......@@ -184,6 +192,28 @@ production:
# snip...
```
### External Groups
>**Note:** External Groups configuration is only available in GitLab EE Version
8.9 and above.
Using the `external_groups` setting will allow you to mark all users belonging
to these groups as [external users](../../permissions/). Group membership is
checked periodically through the `LdapGroupSync` background task.
**Configuration**
```yaml
# An array of CNs of groups containing users that should be considered external
#
# Ex. ['interns', 'contractors']
#
# Note: Not `cn=interns` or the full DN
#
external_groups: []
```
## Using an LDAP filter to limit access to your GitLab server
If you want to limit all GitLab access to a subset of the LDAP users on your
......
......@@ -101,6 +101,10 @@ module Gitlab
options['timeout'].to_i
end
def external_groups
options['external_groups']
end
protected
def base_config
......
......@@ -49,6 +49,14 @@ module Gitlab
logger.debug { "No `admin_group` configured for '#{provider}' provider. Skipping" }
end
if external_groups.empty?
logger.debug { "No `external_groups` configured for '#{provider}' provider. Skipping" }
else
logger.debug { "Syncing external users for '#{provider}' provider" }
sync_external_users
logger.debug { "Finished syncing external users for '#{provider}' provider" }
end
nil
end
......@@ -121,6 +129,36 @@ module Gitlab
end
end
# Update external users based on the specified external groups CN
def sync_external_users
current_external_users = ::User.external.with_provider(provider)
verified_external_users = []
external_groups.each do |group|
group_dns = dns_for_group_cn(group)
group_dns.each do |member_dn|
user = Gitlab::LDAP::User.find_by_uid_and_provider(member_dn, provider)
if user.present?
user.external = true
user.save
verified_external_users << user
else
logger.debug do
<<-MSG.strip_heredoc.tr("\n", ' ')
#{self.class.name}: User with DN `#{member_dn}` should be marked as
external but there is no user in GitLab with that identity.
Membership will be updated once the user signs in for the first time.
MSG
end
end
end
end
update_external_permissions(current_external_users, verified_external_users)
end
private
# Cache LDAP group member DNs so we don't query LDAP groups more than once.
......@@ -151,6 +189,10 @@ module Gitlab
config.admin_group
end
def external_groups
config.external_groups
end
def ldap_group_member_dns(ldap_group_cn)
ldap_group = Gitlab::LDAP::Group.find_by_cn(ldap_group_cn, adapter)
unless ldap_group.present?
......@@ -277,6 +319,16 @@ module Gitlab
end
end
def update_external_permissions(users, verified)
# Restore normal access to users no longer found in the external groups
users.each do |user|
unless verified.include?(user)
user.external = false
user.save
end
end
end
def add_new_members(group, access_levels)
logger.debug { "Adding new members to '#{group.name}' group" }
......
This diff is collapsed.
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