Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
2405e0bd
Commit
2405e0bd
authored
Aug 22, 2018
by
Douglas Barbosa Alexandre
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
LDAP - Does not update permissions on a read-only database
parent
4f277d3c
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
302 additions
and
266 deletions
+302
-266
ee/lib/ee/gitlab/auth/ldap/access.rb
ee/lib/ee/gitlab/auth/ldap/access.rb
+13
-9
ee/spec/lib/gitlab/auth/ldap/access_spec.rb
ee/spec/lib/gitlab/auth/ldap/access_spec.rb
+171
-178
lib/gitlab/auth/ldap/access.rb
lib/gitlab/auth/ldap/access.rb
+14
-10
spec/lib/gitlab/auth/ldap/access_spec.rb
spec/lib/gitlab/auth/ldap/access_spec.rb
+83
-69
spec/support/helpers/ldap_helpers.rb
spec/support/helpers/ldap_helpers.rb
+17
-0
spec/support/helpers/stub_configuration.rb
spec/support/helpers/stub_configuration.rb
+4
-0
No files found.
ee/lib/ee/gitlab/auth/ldap/access.rb
View file @
2405e0bd
...
@@ -6,6 +6,19 @@ module EE
...
@@ -6,6 +6,19 @@ module EE
extend
ActiveSupport
::
Concern
extend
ActiveSupport
::
Concern
extend
::
Gitlab
::
Utils
::
Override
extend
::
Gitlab
::
Utils
::
Override
override
:update_user
def
update_user
return
if
::
Gitlab
::
Database
.
read_only?
update_email
update_memberships
update_identity
update_ssh_keys
if
sync_ssh_keys?
update_kerberos_identity
if
import_kerberos_identities?
end
private
override
:find_ldap_user
override
:find_ldap_user
def
find_ldap_user
def
find_ldap_user
found_user
=
super
found_user
=
super
...
@@ -16,15 +29,6 @@ module EE
...
@@ -16,15 +29,6 @@ module EE
end
end
end
end
override
:update_user
def
update_user
update_email
update_memberships
update_identity
update_ssh_keys
if
sync_ssh_keys?
update_kerberos_identity
if
import_kerberos_identities?
end
# Update user ssh keys if they changed in LDAP
# Update user ssh keys if they changed in LDAP
def
update_ssh_keys
def
update_ssh_keys
remove_old_ssh_keys
remove_old_ssh_keys
...
...
ee/spec/lib/gitlab/auth/ldap/access_spec.rb
View file @
2405e0bd
...
@@ -3,259 +3,252 @@ require 'spec_helper'
...
@@ -3,259 +3,252 @@ require 'spec_helper'
describe
Gitlab
::
Auth
::
LDAP
::
Access
do
describe
Gitlab
::
Auth
::
LDAP
::
Access
do
include
LdapHelpers
include
LdapHelpers
let
(
:access
)
{
described_class
.
new
user
}
let
(
:user
)
{
create
(
:omniauth_user
)
}
let
(
:user
)
{
create
(
:omniauth_user
)
}
let
(
:provider
)
{
user
.
ldap_identity
.
provider
}
describe
'#find_ldap_user'
do
subject
(
:access
)
{
described_class
.
new
(
user
)
}
it
'finds a user by email if the email came from LDAP'
do
expect
(
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive
(
:find_by_dn
).
and_return
(
nil
)
expect
(
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive
(
:find_by_email
)
access
.
find_ldap_user
end
end
describe
'#allowed?'
do
describe
'#allowed?'
do
subject
{
access
.
allowed?
}
context
'LDAP user'
do
it
'finds a user by dn first'
do
expect
(
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive
(
:find_by_dn
).
and_return
(
:ldap_user
)
expect
(
Gitlab
::
Auth
::
LDAP
::
Person
).
not_to
receive
(
:find_by_email
)
context
'when the user cannot be found'
do
access
.
allowed?
before
do
allow
(
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive
(
:find_by_dn
).
and_return
(
nil
)
allow
(
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive
(
:find_by_email
).
and_return
(
nil
)
end
end
context
'when looking for a user by email'
do
it
'finds a user by email if not found by dn'
do
let
(
:user
)
{
create
(
:omniauth_user
,
extern_uid:
'my-uid'
,
provider:
'my-provider'
)
}
expect
(
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive
(
:find_by_dn
).
and_return
(
nil
)
expect
(
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive
(
:find_by_email
)
it
{
is_expected
.
to
be_falsey
}
access
.
allowed?
end
it
'returns false if user cannot be found'
do
stub_ldap_person_find_by_dn
(
nil
)
stub_ldap_person_find_by_email
(
user
.
email
,
nil
)
expect
(
access
.
allowed?
).
to
be_falsey
end
end
end
end
end
end
describe
'#update_user'
do
describe
'#update_user'
do
subject
{
access
.
update_user
}
let
(
:entry
)
{
Net
::
LDAP
::
Entry
.
from_single_ldif_string
(
"dn: cn=foo, dc=bar, dc=com"
)
}
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
::
Auth
::
LDAP
::
Person
.
new
(
entry
,
user
.
ldap_identity
.
provider
)
)
)
end
it
'updates email address'
do
context
'email address'
do
expect
(
access
).
to
receive
(
:update_email
).
once
before
do
stub_ldap_person_find_by_dn
(
entry
,
provider
)
end
subject
it
'does not update email if email attribute is not set'
do
end
expect
{
access
.
update_user
}.
not_to
change
(
user
,
:email
)
end
it
'updates the group memberships
'
do
it
'does not update the email if the user has the same email in GitLab and in LDAP
'
do
expect
(
access
).
to
receive
(
:update_memberships
).
once
entry
[
'mail'
]
=
[
user
.
email
]
subject
expect
{
access
.
update_user
}.
not_to
change
(
user
,
:email
)
end
end
it
'syncs ssh keys if enabled by configuration'
do
it
'does not update the email if the user has the same email GitLab and in LDAP, but with upper case in LDAP'
do
allow
(
access
).
to
receive_messages
(
group_base:
''
,
sync_ssh_keys?:
true
)
entry
[
'mail'
]
=
[
user
.
email
.
upcase
]
expect
(
access
).
to
receive
(
:update_ssh_keys
).
once
subject
expect
{
access
.
update_user
}.
not_to
change
(
user
,
:email
)
end
end
it
'update_kerberos_identity'
do
it
'does not update the email when in a read-only GitLab instance'
do
allow
(
access
).
to
receive_messages
(
import_kerberos_identities?:
true
)
allow
(
Gitlab
::
Database
).
to
receive
(
:read_only?
).
and_return
(
true
)
expect
(
access
).
to
receive
(
:update_kerberos_identity
).
once
subject
entry
[
'mail'
]
=
[
'new_email@example.com'
]
end
it
'updates the ldap identity'
do
expect
{
access
.
update_user
}.
not_to
change
(
user
,
:email
)
e
xpect
(
access
).
to
receive
(
:update_identity
)
e
nd
subject
it
'updates the email if the user email is different'
do
end
entry
[
'mail'
]
=
[
'new_email@example.com'
]
end
describe
'#update_kerberos_identity'
do
expect
{
access
.
update_user
}.
to
change
(
user
,
:email
)
let
(
:entry
)
do
end
Net
::
LDAP
::
Entry
.
from_single_ldif_string
(
"dn: cn=foo, dc=bar, dc=com"
)
end
end
before
do
context
'group memberships'
do
allow
(
access
).
to
receive_messages
(
ldap_user:
Gitlab
::
Auth
::
LDAP
::
Person
.
new
(
entry
,
user
.
ldap_identity
.
provider
))
context
'when there is `memberof` param'
do
end
before
do
entry
[
'memberof'
]
=
[
'CN=Group1,CN=Users,DC=The dc,DC=com'
,
'CN=Group2,CN=Builtin,DC=The dc,DC=com'
]
it
"adds a Kerberos identity if it is in Active Directory but not in GitLab"
do
stub_ldap_person_find_by_dn
(
entry
,
provider
)
allow_any_instance_of
(
EE
::
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive_messages
(
kerberos_principal:
"mylogin@FOO.COM"
)
end
expect
{
access
.
update_kerberos_identity
}.
to
change
(
user
.
identities
.
where
(
provider: :kerberos
),
:count
).
from
(
0
).
to
(
1
)
it
'triggers a sync for all groups found in `memberof`'
do
expect
(
user
.
identities
.
where
(
provider:
"kerberos"
).
last
.
extern_uid
).
to
eq
(
"mylogin@FOO.COM"
)
group_link_1
=
create
(
:ldap_group_link
,
cn:
'Group1'
,
provider:
provider
)
end
group_link_2
=
create
(
:ldap_group_link
,
cn:
'Group2'
,
provider:
provider
)
group_ids
=
[
group_link_1
,
group_link_2
].
map
(
&
:group_id
)
it
"updates existing Kerberos identity in GitLab if Active Directory has a different one"
do
expect
(
LdapGroupSyncWorker
).
to
receive
(
:perform_async
)
allow_any_instance_of
(
EE
::
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive_messages
(
kerberos_principal:
"otherlogin@BAR.COM"
)
.
with
(
a_collection_containing_exactly
(
*
group_ids
),
provider
)
user
.
identities
.
build
(
provider:
"kerberos"
,
extern_uid:
"mylogin@FOO.COM"
).
save
expect
{
access
.
update_kerberos_identity
}.
not_to
change
(
user
.
identities
.
where
(
provider:
"kerberos"
),
:count
)
access
.
update_user
expect
(
user
.
identities
.
where
(
provider:
"kerberos"
).
last
.
extern_uid
).
to
eq
(
"otherlogin@BAR.COM"
)
end
end
it
"does not remove Kerberos identities from GitLab if they are none in the LDAP provider"
do
it
"doesn't trigger a sync when in a read-only GitLab instance"
do
allow_any_instance_of
(
EE
::
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive_messages
(
kerberos_principal:
nil
)
allow
(
Gitlab
::
Database
).
to
receive
(
:read_only?
).
and_return
(
true
)
user
.
identities
.
build
(
provider:
"kerberos"
,
extern_uid:
"otherlogin@BAR.COM"
).
save
create
(
:ldap_group_link
,
cn:
'Group1'
,
provider:
provider
)
create
(
:ldap_group_link
,
cn:
'Group2'
,
provider:
provider
)
expect
{
access
.
update_kerberos_identity
}.
not_to
change
(
user
.
identities
.
where
(
provider:
"kerberos"
),
:count
)
expect
(
LdapGroupSyncWorker
).
not_to
receive
(
:perform_async
)
expect
(
user
.
identities
.
where
(
provider:
"kerberos"
).
last
.
extern_uid
).
to
eq
(
"otherlogin@BAR.COM"
)
end
it
"does not modify identities in GitLab if they are no kerberos principal in the LDAP provider"
do
access
.
update_user
allow_any_instance_of
(
EE
::
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive_messages
(
kerberos_principal:
nil
)
end
expect
{
access
.
update_kerberos_identity
}.
not_to
change
(
user
.
identities
,
:count
)
it
"doesn't trigger a sync when there are no links for the provider"
do
end
_another_provider
=
create
(
:ldap_group_link
,
end
cn:
'Group1'
,
provider:
'not-this-ldap'
)
describe
'#update_ssh_keys'
do
expect
(
LdapGroupSyncWorker
).
not_to
receive
(
:perform_async
)
let
(
:ssh_key
)
{
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCrSQHff6a1rMqBdHFt+FwIbytMZ+hJKN3KLkTtOWtSvNIriGhnTdn4rs+tjD/w+z+revytyWnMDM9dS7J8vQi006B16+hc9Xf82crqRoPRDnBytgAFFQY1G/55ql2zdfsC5yvpDOFzuwIJq5dNGsojS82t6HNmmKPq130fzsenFnj5v1pl3OJvk513oduUyKiZBGTroWTn7H/eOPtu7s9MD7pAdEjqYKFLeaKmyidiLmLqQlCRj3Tl2U9oyFg4PYNc0bL5FZJ/Z6t0Ds3i/a2RanQiKxrvgu3GSnUKMx7WIX373baL4jeM7cprRGiOY/1NcS+1cAjfJ8oaxQF/1dYj"
}
let
(
:ssh_key_attribute_name
)
{
'altSecurityIdentities'
}
let
(
:entry
)
do
Net
::
LDAP
::
Entry
.
from_single_ldif_string
(
"dn: cn=foo, dc=bar, dc=com
\n
#{
ssh_key_attribute_name
}
: SSHKey:
#{
ssh_key
}
\n
#{
ssh_key_attribute_name
}
: KerberosKey:bogus"
)
end
before
do
allow_any_instance_of
(
Gitlab
::
Auth
::
LDAP
::
Config
).
to
receive_messages
(
sync_ssh_keys:
ssh_key_attribute_name
)
allow
(
access
).
to
receive_messages
(
sync_ssh_keys?:
true
)
end
it
"adds a SSH key if it is in LDAP but not in gitlab"
do
access
.
update_user
allow_any_instance_of
(
Gitlab
::
Auth
::
LDAP
::
Adapter
).
to
receive
(
:user
)
{
Gitlab
::
Auth
::
LDAP
::
Person
.
new
(
entry
,
'ldapmain'
)
}
end
end
expect
{
access
.
update_ssh_keys
}.
to
change
(
user
.
keys
,
:count
).
from
(
0
).
to
(
1
)
it
"doesn't continue when there is no `memberOf` param"
do
end
stub_ldap_person_find_by_dn
(
entry
,
provider
)
it
"adds a SSH key and give it a proper name"
do
expect
(
LdapGroupLink
).
not_to
receive
(
:where
)
allow_any_instance_of
(
Gitlab
::
Auth
::
LDAP
::
Adapter
).
to
receive
(
:user
)
{
Gitlab
::
Auth
::
LDAP
::
Person
.
new
(
entry
,
'ldapmain'
)
}
expect
(
LdapGroupSyncWorker
).
not_to
receive
(
:perform_async
)
access
.
update_ssh_keys
access
.
update_user
expect
(
user
.
keys
.
last
.
title
).
to
match
(
/LDAP/
)
end
expect
(
user
.
keys
.
last
.
title
).
to
match
(
/
#{
access
.
ldap_config
.
sync_ssh_keys
}
/
)
end
end
it
"does not add a SSH key if it is invalid"
do
context
'SSH keys'
do
entry
=
Net
::
LDAP
::
Entry
.
from_single_ldif_string
(
"dn: cn=foo, dc=bar, dc=com
\n
#{
ssh_key_attribute_name
}
: I am not a valid key"
)
let
(
:ssh_key
)
{
'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCrSQHff6a1rMqBdHFt+FwIbytMZ+hJKN3KLkTtOWtSvNIriGhnTdn4rs+tjD/w+z+revytyWnMDM9dS7J8vQi006B16+hc9Xf82crqRoPRDnBytgAFFQY1G/55ql2zdfsC5yvpDOFzuwIJq5dNGsojS82t6HNmmKPq130fzsenFnj5v1pl3OJvk513oduUyKiZBGTroWTn7H/eOPtu7s9MD7pAdEjqYKFLeaKmyidiLmLqQlCRj3Tl2U9oyFg4PYNc0bL5FZJ/Z6t0Ds3i/a2RanQiKxrvgu3GSnUKMx7WIX373baL4jeM7cprRGiOY/1NcS+1cAjfJ8oaxQF/1dYj'
}
allow_any_instance_of
(
Gitlab
::
Auth
::
LDAP
::
Adapter
).
to
receive
(
:user
)
{
Gitlab
::
Auth
::
LDAP
::
Person
.
new
(
entry
,
'ldapmain'
)
}
let
(
:ssh_key_attribute_name
)
{
'altSecurityIdentities'
}
let
(
:entry
)
{
Net
::
LDAP
::
Entry
.
from_single_ldif_string
(
"dn: cn=foo, dc=bar, dc=com
\n
#{
ssh_key_attribute_name
}
: SSHKey:
#{
ssh_key
}
\n
#{
ssh_key_attribute_name
}
: KerberosKey:bogus"
)
}
expect
{
access
.
update_ssh_keys
}.
not_to
change
(
user
.
keys
,
:count
)
end
context
'user has at least one LDAPKey'
do
before
do
before
do
user
.
keys
.
ldap
.
create
key:
ssh_key
,
title:
'to be removed'
stub_ldap_config
(
sync_ssh_keys:
ssh_key_attribute_name
,
sync_ssh_keys?:
true
)
end
end
it
"removes a SSH key if it is no longer in LDAP"
do
it
'adds a SSH key if it is in LDAP but not in gitlab'
do
entry
=
Net
::
LDAP
::
Entry
.
from_single_ldif_string
(
"dn: cn=foo, dc=bar, dc=com
\n
#{
ssh_key_attribute_name
}
:
\n
"
)
stub_ldap_person_find_by_dn
(
entry
,
provider
)
allow_any_instance_of
(
Gitlab
::
Auth
::
LDAP
::
Adapter
).
to
receive
(
:user
)
{
Gitlab
::
Auth
::
LDAP
::
Person
.
new
(
entry
,
'ldapmain'
)
}
expect
{
access
.
update_
ssh_keys
}.
to
change
(
user
.
keys
,
:count
).
from
(
1
).
to
(
0
)
expect
{
access
.
update_
user
}.
to
change
(
user
.
keys
,
:count
).
from
(
0
).
to
(
1
)
end
end
it
"removes a SSH key if the ldap attribute was removed"
do
it
'adds a SSH key and give it a proper name'
do
entry
=
Net
::
LDAP
::
Entry
.
from_single_ldif_string
(
"dn: cn=foo, dc=bar, dc=com"
)
stub_ldap_person_find_by_dn
(
entry
,
provider
)
allow_any_instance_of
(
Gitlab
::
Auth
::
LDAP
::
Adapter
).
to
receive
(
:user
)
{
Gitlab
::
Auth
::
LDAP
::
Person
.
new
(
entry
,
'ldapmain'
)
}
access
.
update_user
expect
{
access
.
update_ssh_keys
}.
to
change
(
user
.
keys
,
:count
).
from
(
1
).
to
(
0
)
expect
(
user
.
keys
.
last
.
title
).
to
match
(
/LDAP/
)
expect
(
user
.
keys
.
last
.
title
).
to
match
(
/
#{
ssh_key_attribute_name
}
/
)
end
end
end
end
describe
'#update_user_email'
do
it
'does not add a SSH key if it is invalid'
do
let
(
:entry
)
{
Net
::
LDAP
::
Entry
.
new
}
entry
=
Net
::
LDAP
::
Entry
.
from_single_ldif_string
(
"dn: cn=foo, dc=bar, dc=com
\n
#{
ssh_key_attribute_name
}
: I am not a valid key"
)
stub_ldap_person_find_by_dn
(
entry
,
provider
)
before
do
expect
{
access
.
update_user
}.
not_to
change
(
user
.
keys
,
:count
)
allow
(
access
).
to
receive_messages
(
ldap_user:
Gitlab
::
Auth
::
LDAP
::
Person
.
new
(
entry
,
user
.
ldap_identity
.
provider
))
end
end
it
"does not update email if email attribute is not set"
do
it
'does not add a SSH key when in a read-only GitLab instance'
do
expect
{
access
.
update_email
}.
not_to
change
(
user
,
:email
)
allow
(
Gitlab
::
Database
).
to
receive
(
:read_only?
).
and_return
(
true
)
end
stub_ldap_person_find_by_dn
(
entry
,
provider
)
it
"does not update the email if the user has the same email in GitLab and in LDAP"
do
expect
{
access
.
update_user
}.
not_to
change
(
user
.
keys
,
:count
)
entry
[
'mail'
]
=
[
user
.
email
]
end
expect
{
access
.
update_email
}.
not_to
change
(
user
,
:email
)
end
it
"does not update the email if the user has the same email GitLab and in LDAP, but with upper case in LDAP"
do
context
'user has at least one LDAPKey'
do
entry
[
'mail'
]
=
[
user
.
email
.
upcase
]
before
do
expect
{
access
.
update_email
}.
not_to
change
(
user
,
:email
)
user
.
keys
.
ldap
.
create
key:
ssh_key
,
title:
'to be removed'
end
end
it
"updates the email if the user email is different"
do
it
'removes a SSH key if it is no longer in LDAP'
do
entry
[
'mail'
]
=
[
"new_email@example.com"
]
entry
=
Net
::
LDAP
::
Entry
.
from_single_ldif_string
(
"dn: cn=foo, dc=bar, dc=com
\n
#{
ssh_key_attribute_name
}
:
\n
"
)
expect
{
access
.
update_email
}.
to
change
(
user
,
:email
)
stub_ldap_person_find_by_dn
(
entry
,
provider
)
end
end
describe
'#update_memberships'
do
expect
{
access
.
update_user
}.
to
change
(
user
.
keys
,
:count
).
from
(
1
).
to
(
0
)
let
(
:provider
)
{
user
.
ldap_identity
.
provider
}
end
let
(
:entry
)
{
ldap_user_entry
(
user
.
ldap_identity
.
extern_uid
)
}
let
(
:person_with_memberof
)
do
it
'removes a SSH key if the ldap attribute was removed'
do
entry
[
'memberof'
]
=
[
'CN=Group1,CN=Users,DC=The dc,DC=com'
,
entry
=
Net
::
LDAP
::
Entry
.
from_single_ldif_string
(
"dn: cn=foo, dc=bar, dc=com"
)
'CN=Group2,CN=Builtin,DC=The dc,DC=com'
]
stub_ldap_person_find_by_dn
(
entry
,
provider
)
Gitlab
::
Auth
::
LDAP
::
Person
.
new
(
entry
,
provider
)
expect
{
access
.
update_user
}.
to
change
(
user
.
keys
,
:count
).
from
(
1
).
to
(
0
)
end
end
end
end
it
'triggers a sync for all groups found in `memberof`'
do
context
'kerberos identity'
do
group_link_1
=
create
(
:ldap_group_link
,
cn:
'Group1'
,
provider:
provider
)
before
do
group_link_2
=
create
(
:ldap_group_link
,
cn:
'Group2'
,
provider:
provider
)
stub_ldap_config
(
active_directory:
true
)
group_ids
=
[
group_link_1
,
group_link_2
].
map
(
&
:group_id
)
stub_kerberos_setting
(
enabled:
true
)
stub_ldap_person_find_by_dn
(
entry
,
provider
)
end
allow
(
access
).
to
receive
(
:ldap_user
).
and_return
(
person_with_memberof
)
it
'adds a Kerberos identity if it is in Active Directory but not in GitLab'
do
allow_any_instance_of
(
EE
::
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive_messages
(
kerberos_principal:
'mylogin@FOO.COM'
)
expect
(
LdapGroupSyncWorker
).
to
receive
(
:perform_async
)
expect
{
access
.
update_user
}.
to
change
(
user
.
identities
.
where
(
provider: :kerberos
),
:count
).
from
(
0
).
to
(
1
)
.
with
(
a_collection_containing_exactly
(
*
group_ids
),
provider
)
expect
(
user
.
identities
.
where
(
provider:
'kerberos'
).
last
.
extern_uid
).
to
eq
(
'mylogin@FOO.COM'
)
end
access
.
update_memberships
it
'updates existing Kerberos identity in GitLab if Active Directory has a different one'
do
end
allow_any_instance_of
(
EE
::
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive_messages
(
kerberos_principal:
'otherlogin@BAR.COM'
)
user
.
identities
.
build
(
provider:
'kerberos'
,
extern_uid:
'mylogin@FOO.COM'
).
save
it
"doesn't continue when there is no `memberOf` param"
do
expect
{
access
.
update_user
}.
not_to
change
(
user
.
identities
.
where
(
provider:
'kerberos'
),
:count
)
allow
(
access
).
to
receive
(
:ldap_user
)
expect
(
user
.
identities
.
where
(
provider:
'kerberos'
).
last
.
extern_uid
).
to
eq
(
'otherlogin@BAR.COM'
)
.
and_return
(
Gitlab
::
Auth
::
LDAP
::
Person
.
new
(
entry
,
provider
))
end
expect
(
LdapGroupLink
).
not_to
receive
(
:where
)
it
'does not remove Kerberos identities from GitLab if they are none in the LDAP provider'
do
expect
(
LdapGroupSyncWorker
).
not_to
receive
(
:perform_async
)
allow_any_instance_of
(
EE
::
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive_messages
(
kerberos_principal:
nil
)
user
.
identities
.
build
(
provider:
'kerberos'
,
extern_uid:
'otherlogin@BAR.COM'
).
save
access
.
update_memberships
expect
{
access
.
update_user
}.
not_to
change
(
user
.
identities
.
where
(
provider:
'kerberos'
),
:count
)
end
expect
(
user
.
identities
.
where
(
provider:
'kerberos'
).
last
.
extern_uid
).
to
eq
(
'otherlogin@BAR.COM'
)
end
it
"doesn't trigger a sync when there are no links for the provider"
do
it
'does not modify identities in GitLab if they are no kerberos principal in the LDAP provider'
do
_another_provider
=
create
(
:ldap_group_link
,
allow_any_instance_of
(
EE
::
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive_messages
(
kerberos_principal:
nil
)
cn:
'Group1'
,
provider:
'not-this-ldap'
)
allow
(
access
).
to
receive
(
:ldap_user
).
and_return
(
person_with_memberof
)
expect
{
access
.
update_user
}.
not_to
change
(
user
.
identities
,
:count
)
end
expect
(
LdapGroupSyncWorker
).
not_to
receive
(
:perform_async
)
it
'does not add a Kerberos identity when in a read-only GitLab instance'
do
allow
(
Gitlab
::
Database
).
to
receive
(
:read_only?
).
and_return
(
true
)
allow_any_instance_of
(
EE
::
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive_messages
(
kerberos_principal:
'mylogin@FOO.COM'
)
access
.
update_memberships
expect
{
access
.
update_user
}.
not_to
change
(
user
.
identities
.
where
(
provider: :kerberos
),
:count
)
end
end
end
end
describe
'#update_id
entity'
do
context
'LDAP
entity'
do
it
'updates the external UID if it
changed in the entry'
do
context
'whent external UID
changed in the entry'
do
entry
=
ldap_user_entry
(
'another uid'
)
before
do
provider
=
user
.
ldap_identity
.
provider
stub_ldap_person_find_by_dn
(
ldap_user_entry
(
'another uid'
),
provider
)
person
=
Gitlab
::
Auth
::
LDAP
::
Person
.
new
(
entry
,
provider
)
end
allow
(
access
).
to
receive
(
:ldap_user
).
and_return
(
person
)
it
'updates the external UID'
do
access
.
update_user
access
.
update_identity
expect
(
user
.
ldap_identity
.
reload
.
extern_uid
)
.
to
eq
(
'uid=another uid,ou=users,dc=example,dc=com'
)
end
expect
(
user
.
ldap_identity
.
reload
.
extern_uid
)
it
'does not update the external UID when in a read-only GitLab instance'
do
.
to
eq
(
'uid=another uid,ou=users,dc=example,dc=com'
)
allow
(
Gitlab
::
Database
).
to
receive
(
:read_only?
).
and_return
(
true
)
access
.
update_user
expect
(
user
.
ldap_identity
.
reload
.
extern_uid
).
to
eq
(
'123456'
)
end
end
end
end
end
end
end
end
lib/gitlab/auth/ldap/access.rb
View file @
2405e0bd
...
@@ -21,8 +21,10 @@ module Gitlab
...
@@ -21,8 +21,10 @@ module Gitlab
# Whether user is allowed, or not, we should update
# Whether user is allowed, or not, we should update
# permissions to keep things clean
# permissions to keep things clean
if
access
.
allowed?
if
access
.
allowed?
access
.
update_user
unless
Gitlab
::
Database
.
read_only?
Users
::
UpdateService
.
new
(
user
,
user:
user
,
last_credential_check_at:
Time
.
now
).
execute
access
.
update_user
Users
::
UpdateService
.
new
(
user
,
user:
user
,
last_credential_check_at:
Time
.
now
).
execute
end
true
true
else
else
...
@@ -62,6 +64,12 @@ module Gitlab
...
@@ -62,6 +64,12 @@ module Gitlab
false
false
end
end
def
update_user
# no-op in CE
end
private
def
adapter
def
adapter
@adapter
||=
Gitlab
::
Auth
::
LDAP
::
Adapter
.
new
(
provider
)
@adapter
||=
Gitlab
::
Auth
::
LDAP
::
Adapter
.
new
(
provider
)
end
end
...
@@ -70,16 +78,16 @@ module Gitlab
...
@@ -70,16 +78,16 @@ module Gitlab
Gitlab
::
Auth
::
LDAP
::
Config
.
new
(
provider
)
Gitlab
::
Auth
::
LDAP
::
Config
.
new
(
provider
)
end
end
def
find_ldap_user
Gitlab
::
Auth
::
LDAP
::
Person
.
find_by_dn
(
ldap_identity
.
extern_uid
,
adapter
)
end
def
ldap_user
def
ldap_user
return
unless
provider
return
unless
provider
@ldap_user
||=
find_ldap_user
@ldap_user
||=
find_ldap_user
end
end
def
find_ldap_user
Gitlab
::
Auth
::
LDAP
::
Person
.
find_by_dn
(
ldap_identity
.
extern_uid
,
adapter
)
end
def
block_user
(
user
,
reason
)
def
block_user
(
user
,
reason
)
user
.
ldap_block
user
.
ldap_block
...
@@ -104,10 +112,6 @@ module Gitlab
...
@@ -104,10 +112,6 @@ module Gitlab
"unblocking Gitlab user
\"
#{
user
.
name
}
\"
(
#{
user
.
email
}
)"
"unblocking Gitlab user
\"
#{
user
.
name
}
\"
(
#{
user
.
email
}
)"
)
)
end
end
def
update_user
# no-op in CE
end
end
end
end
end
end
end
...
...
spec/lib/gitlab/auth/ldap/access_spec.rb
View file @
2405e0bd
...
@@ -3,51 +3,61 @@ require 'spec_helper'
...
@@ -3,51 +3,61 @@ require 'spec_helper'
describe
Gitlab
::
Auth
::
LDAP
::
Access
do
describe
Gitlab
::
Auth
::
LDAP
::
Access
do
include
LdapHelpers
include
LdapHelpers
let
(
:access
)
{
described_class
.
new
user
}
let
(
:user
)
{
create
(
:omniauth_user
)
}
let
(
:user
)
{
create
(
:omniauth_user
)
}
subject
(
:access
)
{
described_class
.
new
(
user
)
}
describe
'.allowed?'
do
describe
'.allowed?'
do
it
'updates the users `last_credential_check_at'
do
before
do
allow
(
access
).
to
receive
(
:update_user
)
allow
(
access
).
to
receive
(
:update_user
)
expect
(
access
).
to
receive
(
:allowed?
)
{
true
}
allow
(
access
).
to
receive
(
:allowed?
).
and_return
(
true
)
expect
(
described_class
).
to
receive
(
:open
).
and_yield
(
access
)
allow
(
described_class
).
to
receive
(
:open
).
and_yield
(
access
)
end
it
"updates the user's `last_credential_check_at`"
do
expect
{
described_class
.
allowed?
(
user
)
}
expect
{
described_class
.
allowed?
(
user
)
}
.
to
change
{
user
.
last_credential_check_at
}
.
to
change
{
user
.
last_credential_check_at
}
end
end
end
describe
'#find_ldap_user'
do
it
"does not update user's `last_credential_check_at` when in a read-only GitLab instance"
do
it
'finds a user by dn first'
do
allow
(
Gitlab
::
Database
).
to
receive
(
:read_only?
).
and_return
(
true
)
expect
(
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive
(
:find_by_dn
).
and_return
(
:ldap_user
)
access
.
find_ldap_user
expect
{
described_class
.
allowed?
(
user
)
}
.
not_to
change
{
user
.
last_credential_check_at
}
end
end
end
end
describe
'#allowed?'
do
describe
'#allowed?'
do
subject
{
access
.
allowed?
}
context
'when the user cannot be found'
do
context
'when the user cannot be found'
do
before
do
before
do
allow
(
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive
(
:find_by_dn
).
and_retur
n
(
nil
)
stub_ldap_person_find_by_d
n
(
nil
)
allow
(
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive
(
:find_by_email
).
and_return
(
nil
)
stub_ldap_person_find_by_email
(
user
.
email
,
nil
)
end
end
it
{
is_expected
.
to
be_falsey
}
it
'returns false'
do
expect
(
access
.
allowed?
).
to
be_falsey
end
it
'blocks user in GitLab'
do
it
'blocks user in GitLab'
do
expect
(
access
).
to
receive
(
:block_user
).
with
(
user
,
'does not exist anymore'
)
access
.
allowed?
expect
(
user
).
to
be_blocked
expect
(
user
).
to
be_ldap_blocked
end
it
'logs the reason'
do
expect
(
Gitlab
::
AppLogger
).
to
receive
(
:info
).
with
(
"LDAP account
\"
123456
\"
does not exist anymore, "
\
"blocking Gitlab user
\"
#{
user
.
name
}
\"
(
#{
user
.
email
}
)"
)
access
.
allowed?
access
.
allowed?
end
end
end
end
context
'when the user is found'
do
context
'when the user is found'
do
let
(
:ldap_user
)
{
Gitlab
::
Auth
::
LDAP
::
Person
.
new
(
Net
::
LDAP
::
Entry
.
new
,
'ldapmain'
)
}
before
do
before
do
allow
(
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive
(
:find_by_dn
).
and_return
(
ldap_user
)
stub_ldap_person_find_by_dn
(
Net
::
LDAP
::
Entry
.
new
)
end
end
context
'and the user is disabled via active directory'
do
context
'and the user is disabled via active directory'
do
...
@@ -55,10 +65,22 @@ describe Gitlab::Auth::LDAP::Access do
...
@@ -55,10 +65,22 @@ describe Gitlab::Auth::LDAP::Access do
allow
(
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive
(
:disabled_via_active_directory?
).
and_return
(
true
)
allow
(
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive
(
:disabled_via_active_directory?
).
and_return
(
true
)
end
end
it
{
is_expected
.
to
be_falsey
}
it
'returns false'
do
expect
(
access
.
allowed?
).
to
be_falsey
end
it
'blocks user in GitLab'
do
it
'blocks user in GitLab'
do
expect
(
access
).
to
receive
(
:block_user
).
with
(
user
,
'is disabled in Active Directory'
)
access
.
allowed?
expect
(
user
).
to
be_blocked
expect
(
user
).
to
be_ldap_blocked
end
it
'logs the reason'
do
expect
(
Gitlab
::
AppLogger
).
to
receive
(
:info
).
with
(
"LDAP account
\"
123456
\"
is disabled in Active Directory, "
\
"blocking Gitlab user
\"
#{
user
.
name
}
\"
(
#{
user
.
email
}
)"
)
access
.
allowed?
access
.
allowed?
end
end
...
@@ -92,7 +114,17 @@ describe Gitlab::Auth::LDAP::Access do
...
@@ -92,7 +114,17 @@ describe Gitlab::Auth::LDAP::Access do
end
end
it
'unblocks user in GitLab'
do
it
'unblocks user in GitLab'
do
expect
(
access
).
to
receive
(
:unblock_user
).
with
(
user
,
'is not disabled anymore'
)
access
.
allowed?
expect
(
user
).
not_to
be_blocked
expect
(
user
).
not_to
be_ldap_blocked
end
it
'logs the reason'
do
expect
(
Gitlab
::
AppLogger
).
to
receive
(
:info
).
with
(
"LDAP account
\"
123456
\"
is not disabled anymore, "
\
"unblocking Gitlab user
\"
#{
user
.
name
}
\"
(
#{
user
.
email
}
)"
)
access
.
allowed?
access
.
allowed?
end
end
...
@@ -105,18 +137,32 @@ describe Gitlab::Auth::LDAP::Access do
...
@@ -105,18 +137,32 @@ describe Gitlab::Auth::LDAP::Access do
allow_any_instance_of
(
Gitlab
::
Auth
::
LDAP
::
Config
).
to
receive
(
:active_directory
).
and_return
(
false
)
allow_any_instance_of
(
Gitlab
::
Auth
::
LDAP
::
Config
).
to
receive
(
:active_directory
).
and_return
(
false
)
end
end
it
{
is_expected
.
to
be_truthy
}
it
'returns true'
do
expect
(
access
.
allowed?
).
to
be_truthy
end
context
'when user cannot be found'
do
context
'when user cannot be found'
do
before
do
before
do
allow
(
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive
(
:find_by_dn
).
and_retur
n
(
nil
)
stub_ldap_person_find_by_d
n
(
nil
)
allow
(
Gitlab
::
Auth
::
LDAP
::
Person
).
to
receive
(
:find_by_email
).
and_return
(
nil
)
stub_ldap_person_find_by_email
(
user
.
email
,
nil
)
end
end
it
{
is_expected
.
to
be_falsey
}
it
'returns false'
do
expect
(
access
.
allowed?
).
to
be_falsey
end
it
'blocks user in GitLab'
do
it
'blocks user in GitLab'
do
expect
(
access
).
to
receive
(
:block_user
).
with
(
user
,
'does not exist anymore'
)
access
.
allowed?
expect
(
user
).
to
be_blocked
expect
(
user
).
to
be_ldap_blocked
end
it
'logs the reason'
do
expect
(
Gitlab
::
AppLogger
).
to
receive
(
:info
).
with
(
"LDAP account
\"
123456
\"
does not exist anymore, "
\
"blocking Gitlab user
\"
#{
user
.
name
}
\"
(
#{
user
.
email
}
)"
)
access
.
allowed?
access
.
allowed?
end
end
...
@@ -128,7 +174,17 @@ describe Gitlab::Auth::LDAP::Access do
...
@@ -128,7 +174,17 @@ describe Gitlab::Auth::LDAP::Access do
end
end
it
'unblocks the user if it exists'
do
it
'unblocks the user if it exists'
do
expect
(
access
).
to
receive
(
:unblock_user
).
with
(
user
,
'is available again'
)
access
.
allowed?
expect
(
user
).
not_to
be_blocked
expect
(
user
).
not_to
be_ldap_blocked
end
it
'logs the reason'
do
expect
(
Gitlab
::
AppLogger
).
to
receive
(
:info
).
with
(
"LDAP account
\"
123456
\"
is available again, "
\
"unblocking Gitlab user
\"
#{
user
.
name
}
\"
(
#{
user
.
email
}
)"
)
access
.
allowed?
access
.
allowed?
end
end
...
@@ -152,46 +208,4 @@ describe Gitlab::Auth::LDAP::Access do
...
@@ -152,46 +208,4 @@ describe Gitlab::Auth::LDAP::Access do
end
end
end
end
end
end
describe
'#block_user'
do
before
do
user
.
activate
allow
(
Gitlab
::
AppLogger
).
to
receive
(
:info
)
access
.
block_user
user
,
'reason'
end
it
'blocks the user'
do
expect
(
user
).
to
be_blocked
expect
(
user
).
to
be_ldap_blocked
end
it
'logs the reason'
do
expect
(
Gitlab
::
AppLogger
).
to
have_received
(
:info
).
with
(
"LDAP account
\"
123456
\"
reason, "
\
"blocking Gitlab user
\"
#{
user
.
name
}
\"
(
#{
user
.
email
}
)"
)
end
end
describe
'#unblock_user'
do
before
do
user
.
ldap_block
allow
(
Gitlab
::
AppLogger
).
to
receive
(
:info
)
access
.
unblock_user
user
,
'reason'
end
it
'activates the user'
do
expect
(
user
).
not_to
be_blocked
expect
(
user
).
not_to
be_ldap_blocked
end
it
'logs the reason'
do
Gitlab
::
AppLogger
.
info
(
"LDAP account
\"
123456
\"
reason, "
\
"unblocking Gitlab user
\"
#{
user
.
name
}
\"
(
#{
user
.
email
}
)"
)
end
end
end
end
spec/support/helpers/ldap_helpers.rb
View file @
2405e0bd
...
@@ -45,6 +45,23 @@ module LdapHelpers
...
@@ -45,6 +45,23 @@ module LdapHelpers
.
to
receive
(
:find_by_uid
).
with
(
uid
,
any_args
).
and_return
(
return_value
)
.
to
receive
(
:find_by_uid
).
with
(
uid
,
any_args
).
and_return
(
return_value
)
end
end
def
stub_ldap_person_find_by_dn
(
entry
,
provider
=
'ldapmain'
)
person
=
::
Gitlab
::
Auth
::
LDAP
::
Person
.
new
(
entry
,
provider
)
if
entry
.
present?
allow
(
::
Gitlab
::
Auth
::
LDAP
::
Person
)
.
to
receive
(
:find_by_dn
)
.
and_return
(
person
)
end
def
stub_ldap_person_find_by_email
(
email
,
entry
,
provider
=
'ldapmain'
)
person
=
::
Gitlab
::
Auth
::
LDAP
::
Person
.
new
(
entry
,
provider
)
if
entry
.
present?
allow
(
::
Gitlab
::
Auth
::
LDAP
::
Person
)
.
to
receive
(
:find_by_email
)
.
with
(
email
,
anything
)
.
and_return
(
person
)
end
# Create a simple LDAP user entry.
# Create a simple LDAP user entry.
def
ldap_user_entry
(
uid
)
def
ldap_user_entry
(
uid
)
entry
=
Net
::
LDAP
::
Entry
.
new
entry
=
Net
::
LDAP
::
Entry
.
new
...
...
spec/support/helpers/stub_configuration.rb
View file @
2405e0bd
...
@@ -82,6 +82,10 @@ module StubConfiguration
...
@@ -82,6 +82,10 @@ module StubConfiguration
allow
(
Gitlab
.
config
.
repositories
).
to
receive
(
:storages
).
and_return
(
Settingslogic
.
new
(
messages
))
allow
(
Gitlab
.
config
.
repositories
).
to
receive
(
:storages
).
and_return
(
Settingslogic
.
new
(
messages
))
end
end
def
stub_kerberos_setting
(
messages
)
allow
(
Gitlab
.
config
.
kerberos
).
to
receive_messages
(
to_settings
(
messages
))
end
private
private
# Modifies stubbed messages to also stub possible predicate versions
# Modifies stubbed messages to also stub possible predicate versions
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment