Commit 3201a490 authored by Douwe Maan's avatar Douwe Maan

Merge branch 'mk-sync-ldap-external-groups-on-login' into 'master'

Sync ldap external groups on login

Closes #2468

See merge request !2720
parents be329e94 b7ee1288
---
title: Check if LDAP users are in external groups on login
merge_request: 2720
author:
type: security
# LDAP User EE mixin
#
# This module is intended to encapsulate EE-specific User methods
# and be **prepended** in the `Gitlab::LDAP::User` class.
module EE
module Gitlab
module LDAP
module User
def initialize(auth_hash)
super
set_external_with_external_groups
end
private
# Intended to be called during #initialize, and #save should be called
# after initialize.
def set_external_with_external_groups
gl_user.external = in_any_external_group?
end
# Returns true if the User is found in an external group listed in the
# config.
def in_any_external_group?
with_proxy do |proxy|
external_groups = proxy.adapter.config.external_groups
external_groups.any? do |group_cn|
in_group?(group_cn, proxy)
end
end
end
# Returns true if the User is a member of the group.
def in_group?(group_cn, proxy)
member_dns = proxy.dns_for_group_cn(group_cn)
member_dns.include?(auth_hash.uid)
end
def with_proxy(&block)
::EE::Gitlab::LDAP::Sync::Proxy.open(auth_hash.provider, &block)
end
end
end
end
end
......@@ -7,6 +7,8 @@
module Gitlab
module LDAP
class User < Gitlab::OAuth::User
prepend ::EE::Gitlab::LDAP::User
class << self
def find_by_uid_and_provider(uid, provider)
# LDAP distinguished name is case-insensitive
......
require 'spec_helper'
describe Gitlab::LDAP::User do
include LdapHelpers
let(:ldap_user) { described_class.new(auth_hash) }
let(:gl_user) { ldap_user.gl_user }
let(:info) do
{
name: 'John',
email: 'john@example.com',
nickname: 'john'
}
end
let(:auth_hash) do
OmniAuth::AuthHash.new(uid: 'uid=john,ou=people,dc=example,dc=com', provider: 'ldapmain', info: info)
end
let(:group_cn) { 'foo' }
let(:group_member_dns) { [auth_hash.uid] }
let(:external_groups) { [] }
let!(:fake_proxy) { fake_ldap_sync_proxy(auth_hash.provider) }
before do
allow(fake_proxy).to receive(:dns_for_group_cn).with(group_cn).and_return(group_member_dns)
stub_ldap_config(external_groups: external_groups)
end
it 'includes the EE module' do
expect(described_class).to include_module(EE::Gitlab::LDAP::User)
end
describe '#initialize' do
context 'when there is one external group' do
let(:external_groups) { [group_cn] }
context 'when there is another user in the external group' do
context 'when the user is in the external group' do
let(:group_member_dns) { ['uid=someone_else,ou=people,dc=example,dc=com', auth_hash.uid] }
it "sets the user's external flag to true" do
expect(gl_user.external).to be_truthy
end
end
context 'when the user is not in the external group' do
let(:group_member_dns) { ['uid=someone_else,ou=people,dc=example,dc=com'] }
it "sets the user's external flag to false" do
expect(gl_user.external).to be_falsey
end
end
end
context 'when there are no other users in the external group' do
context 'when the user is in the external group' do
let(:group_member_dns) { [auth_hash.uid] }
it "sets the user's external flag to true" do
expect(gl_user.external).to be_truthy
end
end
context 'when the user is not in the external group' do
let(:group_member_dns) { [] }
it "sets the user's external flag to false" do
expect(gl_user.external).to be_falsey
end
end
end
end
context 'when there is more than one external group' do
let(:external_groups) { ['bar', group_cn] }
before do
allow(fake_proxy).to receive(:dns_for_group_cn).with('bar').and_return(['uid=someone_else,ou=people,dc=example,dc=com'])
end
context 'when the user is in an external group' do
let(:group_member_dns) { [auth_hash.uid] }
it "sets the user's external flag to true" do
expect(gl_user.external).to be_truthy
end
end
context 'when the user is not in an external group' do
let(:group_member_dns) { [] }
it "sets the user's external flag to false" do
expect(gl_user.external).to be_falsey
end
end
end
context 'when there are no external groups' do
let(:external_groups) { [] }
it "sets the user's external flag to false" do
expect(gl_user.external).to be_falsey
end
end
end
end
require 'spec_helper'
describe Gitlab::LDAP::User do
include LdapHelpers
let(:ldap_user) { described_class.new(auth_hash) }
let(:gl_user) { ldap_user.gl_user }
let(:info) do
......@@ -24,6 +26,7 @@ describe Gitlab::LDAP::User do
let(:auth_hash_upper_case) do
OmniAuth::AuthHash.new(uid: 'my-uid', provider: 'ldapmain', info: info_upper_case)
end
let!(:fake_proxy) { fake_ldap_sync_proxy('ldapmain') }
describe '#changed?' do
it "marks existing ldap user as changed" do
......@@ -167,8 +170,7 @@ describe Gitlab::LDAP::User do
describe 'blocking' do
def configure_block(value)
allow_any_instance_of(Gitlab::LDAP::Config)
.to receive(:block_auto_created_users).and_return(value)
stub_ldap_config(block_auto_created_users: value)
end
context 'signup' do
......
......@@ -5,6 +5,12 @@ module LdapHelpers
::Gitlab::LDAP::Adapter.new(provider, ldap)
end
def fake_ldap_sync_proxy(provider)
fake_proxy = double(:proxy, adapter: ldap_adapter)
allow(::EE::Gitlab::LDAP::Sync::Proxy).to receive(:open).with(provider).and_yield(fake_proxy)
fake_proxy
end
def user_dn(uid)
"uid=#{uid},ou=users,dc=example,dc=com"
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