Commit 53fcba83 authored by Robert Speicher's avatar Robert Speicher

Merge branch 'fix_ldap_user_removed' into 'master'

Remove user from groups when they are removed from LDAP

Fixes #159 

Currently, we only update user permissions if they come back from LDAP
as a valid user. I refactored some things in the `access.rb` file so we
update permissions no matter what. Now the user is removed from groups
and admin access is revoked, in addition to the previous behavior of
blocking the user.

See merge request !124
parents 51f1a875 a024312d
...@@ -12,6 +12,7 @@ v 8.4.0 (unreleased) ...@@ -12,6 +12,7 @@ v 8.4.0 (unreleased)
- Add user's last used IP addresses to admin page (Stan Hu) - Add user's last used IP addresses to admin page (Stan Hu)
- Add housekeeping function to project settings page - Add housekeeping function to project settings page
- The default GitLab logo now acts as a loading indicator - The default GitLab logo now acts as a loading indicator
- LDAP group sync: Remove user from group when they are removed from LDAP
- Fix caching issue where build status was not updating in project dashboard (Stan Hu) - Fix caching issue where build status was not updating in project dashboard (Stan Hu)
- Accept 2xx status codes for successful Web hook triggers (Stan Hu) - Accept 2xx status codes for successful Web hook triggers (Stan Hu)
- Fix missing date of month in network graph when commits span a month (Stan Hu) - Fix missing date of month in network graph when commits span a month (Stan Hu)
......
...@@ -70,28 +70,28 @@ gitlab_rails['gitlab_default_can_create_group'] = false ...@@ -70,28 +70,28 @@ gitlab_rails['gitlab_default_can_create_group'] = false
# line in /home/git/gitlab/config/gitlab.yml # line in /home/git/gitlab/config/gitlab.yml
``` ```
## Lock project membership to members of the group ## Lock project membership to members of this group
In GitLab Enterprise Edition it is possible to lock membership in project to the level of members in group. In GitLab Enterprise Edition it is possible to lock membership in project to the
level of members in group.
This allows group owner to lock down any new project membership to any of the projects within the group allowing tighter control over project membership. This allows group owner to lock down any new project membership to any of the
projects within the group allowing tighter control over project membership.
To enable this feature, navigate to group settings page, select `Member lock` and `Save group`. To enable this feature, navigate to group settings page, select `Member lock`
and `Save group`.
![Checkbox for membership lock](groups/membership_lock.png) ![Checkbox for membership lock](groups/membership_lock.png)
This will disable the option for all users who previously had permissions to operate project memberships so no new users can be added. Furthermore, any request to add new user to project through API will not be possible. This will disable the option for all users who previously had permissions to
operate project memberships so no new users can be added. Furthermore, any
request to add new user to project through API will not be possible.
## Namespaces in groups ## Prevent projects in this group from sharing a project with another group
By default, groups only get 20 namespaces at a time because the API results are paginated. In GitLab Enterprise it is possible to prevent projects in a group from sharing
a project with another group. This allows for tighter control over project
access.
To get more (up to 100), pass the following as an argument to the API call: To enable this feature, navigate to the group settings page. Select `Share with
``` group lock` and save the group.
/groups?per_page=100
```
And to switch pages add:
```
/groups?per_page=100&page=2
```
...@@ -16,9 +16,11 @@ module Gitlab ...@@ -16,9 +16,11 @@ module Gitlab
def self.allowed?(user) def self.allowed?(user)
self.open(user) do |access| self.open(user) do |access|
# Whether user is allowed, or not, we should update
# permissions to keep things clean
access.update_permissions
if access.allowed? if access.allowed?
access.update_permissions access.update_user
access.update_email
user.last_credential_check_at = Time.now user.last_credential_check_at = Time.now
user.save user.save
true true
...@@ -67,22 +69,15 @@ module Gitlab ...@@ -67,22 +69,15 @@ module Gitlab
@ldap_user ||= Gitlab::LDAP::Person.find_by_dn(user.ldap_identity.extern_uid, adapter) @ldap_user ||= Gitlab::LDAP::Person.find_by_dn(user.ldap_identity.extern_uid, adapter)
end end
def update_permissions def update_user
if sync_ssh_keys? update_email
update_ssh_keys update_ssh_keys if sync_ssh_keys?
end
update_kerberos_identity if import_kerberos_identities? update_kerberos_identity if import_kerberos_identities?
end
# Skip updating group permissions def update_permissions
# if instance does not use group_base setting update_ldap_group_links if group_base.present?
return true unless group_base.present? update_admin_status if admin_group.present?
update_ldap_group_links
if admin_group.present?
update_admin_status
end
end end
# Update user ssh keys if they changed in LDAP # Update user ssh keys if they changed in LDAP
...@@ -191,6 +186,7 @@ module Gitlab ...@@ -191,6 +186,7 @@ module Gitlab
# returns a collection of cn strings to which the user has access # returns a collection of cn strings to which the user has access
def cns_with_access def cns_with_access
return [] unless ldap_user.present?
@ldap_groups_with_access ||= ldap_groups.select do |ldap_group| @ldap_groups_with_access ||= ldap_groups.select do |ldap_group|
ldap_group.has_member?(ldap_user) ldap_group.has_member?(ldap_user)
end.map(&:cn) end.map(&:cn)
......
...@@ -4,7 +4,7 @@ describe Gitlab::LDAP::Access, lib: true do ...@@ -4,7 +4,7 @@ describe Gitlab::LDAP::Access, lib: true do
let(:access) { Gitlab::LDAP::Access.new user } let(:access) { Gitlab::LDAP::Access.new user }
let(:user) { create(:omniauth_user) } let(:user) { create(:omniauth_user) }
describe :allowed? do describe '#allowed?' do
subject { access.allowed? } subject { access.allowed? }
context 'when the user cannot be found' do context 'when the user cannot be found' do
...@@ -40,7 +40,7 @@ describe Gitlab::LDAP::Access, lib: true do ...@@ -40,7 +40,7 @@ describe Gitlab::LDAP::Access, lib: true do
end end
end end
context 'and has no disabled flag in active diretory' do context 'and has no disabled flag in active directory' do
before do before do
allow(Gitlab::LDAP::Person).to receive(:disabled_via_active_directory?).and_return(false) allow(Gitlab::LDAP::Person).to receive(:disabled_via_active_directory?).and_return(false)
end end
...@@ -71,7 +71,7 @@ describe Gitlab::LDAP::Access, lib: true do ...@@ -71,7 +71,7 @@ describe Gitlab::LDAP::Access, lib: true do
end end
end end
context 'withoud ActiveDirectory enabled' do context 'without ActiveDirectory enabled' do
before do before do
allow(Gitlab::LDAP::Config).to receive(:enabled?).and_return(true) allow(Gitlab::LDAP::Config).to receive(:enabled?).and_return(true)
allow_any_instance_of(Gitlab::LDAP::Config).to receive(:active_directory).and_return(false) allow_any_instance_of(Gitlab::LDAP::Config).to receive(:active_directory).and_return(false)
...@@ -82,41 +82,67 @@ describe Gitlab::LDAP::Access, lib: true do ...@@ -82,41 +82,67 @@ describe Gitlab::LDAP::Access, lib: true do
end end
end end
describe :update_permissions do describe '#update_user' do
subject { access.update_permissions } subject { access.update_user }
let(:entry) do
Net::LDAP::Entry.from_single_ldif_string("dn: cn=foo, dc=bar, dc=com")
end
before do
allow(access).to(
receive_messages(
ldap_user: Gitlab::LDAP::Person.new(entry, user.ldap_identity.provider)
)
)
end
it 'updates email address' do
expect(access).to receive(:update_email).once
subject
end
it "syncs ssh keys if enabled by configuration" do it 'syncs ssh keys if enabled by configuration' do
allow(access).to receive_messages(group_base: '', sync_ssh_keys?: 'sshpublickey', import_kerberos_identities?: false) allow(access).to receive_messages(group_base: '', sync_ssh_keys?: true)
expect(access).to receive(:update_ssh_keys).once expect(access).to receive(:update_ssh_keys).once
subject subject
end end
it "does update group permissions with a group base configured" do it 'update_kerberos_identity' do
allow(access).to receive_messages(group_base: 'my-group-base', sync_ssh_keys?: false, import_kerberos_identities?: false) allow(access).to receive_messages(import_kerberos_identities?: true)
expect(access).to receive(:update_kerberos_identity).once
subject
end
end
describe '#update_permissions' do
subject { access.update_permissions }
it 'does update group permissions with a group base configured' do
allow(access).to receive_messages(group_base: 'my-group-base')
expect(access).to receive(:update_ldap_group_links) expect(access).to receive(:update_ldap_group_links)
subject subject
end end
it "does not update group permissions without a group base configured" do it 'does not update group permissions without a group base configured' do
allow(access).to receive_messages(group_base: '', sync_ssh_keys?: false, import_kerberos_identities?: false) allow(access).to receive_messages(group_base: '')
expect(access).not_to receive(:update_ldap_group_links) expect(access).not_to receive(:update_ldap_group_links)
subject subject
end end
it "does update admin group permissions if admin group is configured" do it 'does update admin group permissions if admin group is configured' do
allow(access).to receive_messages(admin_group: 'my-admin-group', update_ldap_group_links: nil, sync_ssh_keys?: false, import_kerberos_identities?: false) allow(access).to receive_messages(admin_group: 'my-admin-group')
expect(access).to receive(:update_admin_status) expect(access).to receive(:update_admin_status)
subject subject
end end
it "does update Kerberos identities if Kerberos is enabled and the LDAP server is Active Directory" do it 'does not update admin status when admin group is not configured' do
allow(access).to receive_messages(group_base: '', sync_ssh_keys?: false, import_kerberos_identities?: true) allow(access).to receive_messages(admin_group: '')
expect(access).not_to receive(:update_admin_status)
expect(access).to receive(:update_kerberos_identity)
subject subject
end end
...@@ -451,17 +477,33 @@ objectclass: posixGroup ...@@ -451,17 +477,33 @@ objectclass: posixGroup
] ]
end end
let(:ldap_user) { Gitlab::LDAP::Person.new(Net::LDAP::Entry.new, user.ldap_identity.provider) }
before do before do
allow(access).to receive_messages(ldap_user: ldap_user)
allow(ldap_user).to receive(:uid) { 'user1' }
allow(ldap_user).to receive(:dn) { 'uid=user1,ou=People,dc=example' } allow(ldap_user).to receive(:dn) { 'uid=user1,ou=People,dc=example' }
allow(access).to receive_messages(ldap_groups: ldap_groups)
end end
it "only returns ldap cns to which the user has access" do context 'when the LDAP user exists' do
allow(access).to receive_messages(ldap_groups: ldap_groups) let(:ldap_user) { Gitlab::LDAP::Person.new(Net::LDAP::Entry.new, user.ldap_identity.provider) }
expect(access.cns_with_access).to eql ['group1']
before do
allow(access).to receive_messages(ldap_user: ldap_user)
allow(ldap_user).to receive(:uid) { 'user1' }
end
it 'only returns ldap cns to which the user has access' do
expect(access.cns_with_access).to eq(['group1'])
end
end
context 'when the LADP user does not exist' do
let(:ldap_user) { nil }
before do
allow(access).to receive_messages(ldap_user: ldap_user)
end
it 'returns an empty array' do
expect(access.cns_with_access).to eq([])
end
end end
end end
end end
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