github-ldap 1.0.15 → 1.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/github-ldap.gemspec +1 -1
- data/lib/github/ldap.rb +10 -0
- data/lib/github/ldap/domain.rb +25 -9
- data/lib/github/ldap/filter.rb +25 -2
- data/lib/github/ldap/fixtures.ldif +1 -1
- data/lib/github/ldap/group.rb +73 -0
- data/lib/github/ldap/server.rb +5 -5
- data/test/domain_test.rb +7 -7
- data/test/filter_test.rb +4 -4
- data/test/fixtures/github-with-subgroups.ldif +90 -0
- data/test/group_test.rb +33 -0
- data/test/test_helper.rb +5 -1
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1fe44b5c68117c2b0d616f164f8b40901d2ad2dd
|
4
|
+
data.tar.gz: a61c80ebbaabb8ff06793f13910440d403209a7b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 060534d71ad7bfcbd1682699cfa81cebb3552366bd661b94127df79542f97b9c640ebf4414785055ad88923931588bd89ac274a03fc635cb757353c1a717a133
|
7
|
+
data.tar.gz: b20400377b5b2d508a910ba6acc3ffeec0a18e5aae7918290c2622be7536a5f625c74a06a31fc2f3d73c0a65cf425ce89e3de4c037a993c2f343c0c1a2bd82d4
|
data/github-ldap.gemspec
CHANGED
data/lib/github/ldap.rb
CHANGED
@@ -4,6 +4,7 @@ module GitHub
|
|
4
4
|
require 'forwardable'
|
5
5
|
require 'github/ldap/filter'
|
6
6
|
require 'github/ldap/domain'
|
7
|
+
require 'github/ldap/group'
|
7
8
|
|
8
9
|
extend Forwardable
|
9
10
|
|
@@ -69,5 +70,14 @@ module GitHub
|
|
69
70
|
def domain(base_name)
|
70
71
|
Domain.new(base_name, @connection, @uid)
|
71
72
|
end
|
73
|
+
|
74
|
+
# Creates a new group object to perform operations
|
75
|
+
#
|
76
|
+
# base_name: is the dn of the base root.
|
77
|
+
#
|
78
|
+
# Returns a new Group object.
|
79
|
+
def group(base_name)
|
80
|
+
Group.new(self, domain(base_name).bind)
|
81
|
+
end
|
72
82
|
end
|
73
83
|
end
|
data/lib/github/ldap/domain.rb
CHANGED
@@ -18,6 +18,20 @@ module GitHub
|
|
18
18
|
@base_name, @connection, @uid = base_name, connection, uid
|
19
19
|
end
|
20
20
|
|
21
|
+
# List all groups under this tree, including subgroups.
|
22
|
+
#
|
23
|
+
# Returns a list of ldap entries.
|
24
|
+
def all_groups
|
25
|
+
search(filter: ALL_GROUPS_FILTER)
|
26
|
+
end
|
27
|
+
|
28
|
+
# List all groups under this tree that match the query.
|
29
|
+
#
|
30
|
+
# Returns a list of ldap entries.
|
31
|
+
def filter_groups(query)
|
32
|
+
search(filter: group_contains_filter(query))
|
33
|
+
end
|
34
|
+
|
21
35
|
# List the groups in the ldap server that match the configured ones.
|
22
36
|
#
|
23
37
|
# group_names: is an array of group CNs.
|
@@ -73,12 +87,7 @@ module GitHub
|
|
73
87
|
# Returns the user if the login matches any `uid`.
|
74
88
|
# Returns nil if there are no matches.
|
75
89
|
def user?(login)
|
76
|
-
|
77
|
-
rs = search(
|
78
|
-
filter: Net::LDAP::Filter.eq(@uid, escaped_login),
|
79
|
-
attributes: [],
|
80
|
-
limit: 1)
|
81
|
-
rs and rs.first
|
90
|
+
search(filter: login_filter(@uid, login), limit: 1).first
|
82
91
|
end
|
83
92
|
|
84
93
|
# Check if a user can be bound with a password.
|
@@ -112,13 +121,13 @@ module GitHub
|
|
112
121
|
# The base option is always overriden.
|
113
122
|
#
|
114
123
|
# Returns an array with the entries found.
|
115
|
-
# Returns nil if there are no entries.
|
116
124
|
def search(options)
|
117
125
|
options[:base] = @base_name
|
118
|
-
options[:attributes] ||=
|
126
|
+
options[:attributes] ||= []
|
119
127
|
options[:ignore_server_caps] ||= true
|
128
|
+
options[:paged_searches_supported] ||= true
|
120
129
|
|
121
|
-
@connection.search(options)
|
130
|
+
Array(@connection.search(options))
|
122
131
|
end
|
123
132
|
|
124
133
|
# Provide a meaningful result after a protocol operation (for example,
|
@@ -130,6 +139,13 @@ module GitHub
|
|
130
139
|
def get_operation_result
|
131
140
|
@connection.get_operation_result
|
132
141
|
end
|
142
|
+
|
143
|
+
# Get the entry for this domain.
|
144
|
+
#
|
145
|
+
# Returns a Net::LDAP::Entry
|
146
|
+
def bind
|
147
|
+
search({}).first
|
148
|
+
end
|
133
149
|
end
|
134
150
|
end
|
135
151
|
end
|
data/lib/github/ldap/filter.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
module GitHub
|
2
2
|
class Ldap
|
3
3
|
module Filter
|
4
|
+
ALL_GROUPS_FILTER = Net::LDAP::Filter.eq("objectClass", "groupOfNames") |
|
5
|
+
Net::LDAP::Filter.eq("objectClass", "groupOfUniqueNames")
|
6
|
+
|
4
7
|
# Filter to get the configured groups in the ldap server.
|
5
8
|
# Takes the list of the group names and generate a filter for the groups
|
6
9
|
# with cn that match and also include members:
|
@@ -21,11 +24,31 @@ module GitHub
|
|
21
24
|
# Returns a Net::LDAP::Filter.
|
22
25
|
def member_filter(user_dn = nil)
|
23
26
|
if user_dn
|
24
|
-
Net::LDAP::Filter.eq("member", user_dn)
|
27
|
+
Net::LDAP::Filter.eq("member", user_dn) | Net::LDAP::Filter.eq("uniqueMember", user_dn)
|
25
28
|
else
|
26
|
-
Net::LDAP::Filter.pres("member")
|
29
|
+
Net::LDAP::Filter.pres("member") | Net::LDAP::Filter.pres("uniqueMember")
|
27
30
|
end
|
28
31
|
end
|
32
|
+
|
33
|
+
# Filter to map a uid with a login.
|
34
|
+
# It escapes the login before creating the filter.
|
35
|
+
#
|
36
|
+
# uid: the entry field to map.
|
37
|
+
# login: the login to map.
|
38
|
+
#
|
39
|
+
# Returns a Net::LDAP::Filter.
|
40
|
+
def login_filter(uid, login)
|
41
|
+
Net::LDAP::Filter.eq(uid, Net::LDAP::Filter.escape(login))
|
42
|
+
end
|
43
|
+
|
44
|
+
# Filter groups that match a query cn.
|
45
|
+
#
|
46
|
+
# query: is a string to match the cn with.
|
47
|
+
#
|
48
|
+
# Returns a Net::LDAP::Filter.
|
49
|
+
def group_contains_filter(query)
|
50
|
+
Net::LDAP::Filter.contains("cn", query) & ALL_GROUPS_FILTER
|
51
|
+
end
|
29
52
|
end
|
30
53
|
end
|
31
54
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module GitHub
|
2
|
+
class Ldap
|
3
|
+
# This class represents an LDAP group.
|
4
|
+
# It encapsulates operations that you can perform against a group, like retrieving its members.
|
5
|
+
#
|
6
|
+
# To get a group, you'll need to create a `Ldap` object and then call the method `group` with the name of its base.
|
7
|
+
#
|
8
|
+
# For example:
|
9
|
+
#
|
10
|
+
# domain = GitHub::Ldap.new(options).group("cn=enterprise,dc=github,dc=com")
|
11
|
+
#
|
12
|
+
class Group
|
13
|
+
GROUP_CLASS_NAMES = %w(groupOfNames groupOfUniqueNames)
|
14
|
+
|
15
|
+
def initialize(ldap, entry)
|
16
|
+
@ldap, @entry = ldap, entry
|
17
|
+
end
|
18
|
+
|
19
|
+
# Get all members that belong to a group.
|
20
|
+
# This list also includes the members of subgroups.
|
21
|
+
#
|
22
|
+
# Returns an array with all the member entries.
|
23
|
+
def members
|
24
|
+
groups, members = member_entries.partition {|e| group?(e[:objectclass])}
|
25
|
+
results = members
|
26
|
+
|
27
|
+
groups.each do |result|
|
28
|
+
results.concat @ldap.group(result.dn).members
|
29
|
+
end
|
30
|
+
|
31
|
+
results.uniq {|m| m.dn }
|
32
|
+
end
|
33
|
+
|
34
|
+
# Get all the subgroups from a group recursively.
|
35
|
+
#
|
36
|
+
# Returns an array with all the subgroup entries.
|
37
|
+
def subgroups
|
38
|
+
groups, _ = member_entries.partition {|e| group?(e[:objectclass])}
|
39
|
+
results = groups
|
40
|
+
|
41
|
+
groups.each do |result|
|
42
|
+
results.concat @ldap.group(result.dn).subgroups
|
43
|
+
end
|
44
|
+
|
45
|
+
results
|
46
|
+
end
|
47
|
+
|
48
|
+
# Get all the member entries for a group.
|
49
|
+
#
|
50
|
+
# Returns an array of Net::LDAP::Entry.
|
51
|
+
def member_entries
|
52
|
+
@member_entries ||= member_names.map do |m|
|
53
|
+
@ldap.domain(m).bind
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Get all the names under `member` and `uniqueMember`.
|
58
|
+
#
|
59
|
+
# Returns an array with all the DN members.
|
60
|
+
def member_names
|
61
|
+
@entry[:member] + @entry[:uniqueMember]
|
62
|
+
end
|
63
|
+
|
64
|
+
# Check if an object class includes the member names
|
65
|
+
# Use `&` rathen than `include?` because both are arrays.
|
66
|
+
#
|
67
|
+
# Returns true if the object class includes one of the group class names.
|
68
|
+
def group?(object_class)
|
69
|
+
!(GROUP_CLASS_NAMES & object_class).empty?
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/github/ldap/server.rb
CHANGED
@@ -7,11 +7,11 @@ module GitHub
|
|
7
7
|
|
8
8
|
DEFAULT_SERVER_OPTIONS = {
|
9
9
|
user_fixtures: DEFAULT_FIXTURES_PATH,
|
10
|
-
user_domain:
|
11
|
-
admin_user:
|
12
|
-
admin_password:
|
13
|
-
quiet:
|
14
|
-
port:
|
10
|
+
user_domain: 'dc=github,dc=com',
|
11
|
+
admin_user: 'uid=admin,dc=github,dc=com',
|
12
|
+
admin_password: 'secret',
|
13
|
+
quiet: true,
|
14
|
+
port: 3897
|
15
15
|
}
|
16
16
|
|
17
17
|
class << self
|
data/test/domain_test.rb
CHANGED
@@ -6,7 +6,7 @@ module GitHubLdapDomainTestCases
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def test_user_valid_login
|
9
|
-
user = @domain.valid_login?('calavera', '
|
9
|
+
user = @domain.valid_login?('calavera', 'passworD1')
|
10
10
|
assert_equal 'uid=calavera,dc=github,dc=com', user.dn
|
11
11
|
end
|
12
12
|
|
@@ -25,14 +25,14 @@ module GitHubLdapDomainTestCases
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def test_user_in_group
|
28
|
-
user = @domain.valid_login?('calavera', '
|
28
|
+
user = @domain.valid_login?('calavera', 'passworD1')
|
29
29
|
|
30
30
|
assert @domain.is_member?(user.dn, %w(Enterprise People)),
|
31
31
|
"Expected `Enterprise` or `Poeple` to include the member `#{user.dn}`"
|
32
32
|
end
|
33
33
|
|
34
34
|
def test_user_not_in_different_group
|
35
|
-
user = @domain.valid_login?('calavera', '
|
35
|
+
user = @domain.valid_login?('calavera', 'passworD1')
|
36
36
|
|
37
37
|
assert !@domain.is_member?(user.dn, %w(People)),
|
38
38
|
"Expected `Poeple` not to include the member `#{user.dn}`"
|
@@ -46,7 +46,7 @@ module GitHubLdapDomainTestCases
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def test_authenticate_doesnt_return_invalid_users
|
49
|
-
user = @domain.authenticate!('calavera', '
|
49
|
+
user = @domain.authenticate!('calavera', 'passworD1')
|
50
50
|
assert_equal 'uid=calavera,dc=github,dc=com', user.dn
|
51
51
|
end
|
52
52
|
|
@@ -56,13 +56,13 @@ module GitHubLdapDomainTestCases
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def test_authenticate_check_valid_user_and_groups
|
59
|
-
user = @domain.authenticate!('calavera', '
|
59
|
+
user = @domain.authenticate!('calavera', 'passworD1', %w(Enterprise People))
|
60
60
|
|
61
61
|
assert_equal 'uid=calavera,dc=github,dc=com', user.dn
|
62
62
|
end
|
63
63
|
|
64
64
|
def test_authenticate_doesnt_return_valid_users_in_different_groups
|
65
|
-
assert !@domain.authenticate!('calavera', '
|
65
|
+
assert !@domain.authenticate!('calavera', 'passworD1', %w(People)),
|
66
66
|
"Expected `authenticate!` to not return an user"
|
67
67
|
end
|
68
68
|
|
@@ -109,7 +109,7 @@ module GitHubLdapDomainTestCases
|
|
109
109
|
|
110
110
|
def test_auth_binds
|
111
111
|
user = @domain.user?('calavera')
|
112
|
-
assert @domain.auth(user, '
|
112
|
+
assert @domain.auth(user, 'passworD1'), 'Expected user to be bound.'
|
113
113
|
end
|
114
114
|
|
115
115
|
def test_auth_does_not_bind
|
data/test/filter_test.rb
CHANGED
@@ -9,20 +9,20 @@ class FilterTest < Minitest::Test
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def test_member_present
|
12
|
-
assert_equal "(member=*)", @subject.member_filter.to_s
|
12
|
+
assert_equal "(|(member=*)(uniqueMember=*))", @subject.member_filter.to_s
|
13
13
|
end
|
14
14
|
|
15
15
|
def test_member_equal
|
16
|
-
assert_equal "(member=#{@me})", @subject.member_filter(@me).to_s
|
16
|
+
assert_equal "(|(member=#{@me})(uniqueMember=#{@me}))", @subject.member_filter(@me).to_s
|
17
17
|
end
|
18
18
|
|
19
19
|
def test_groups_reduced
|
20
|
-
assert_equal "(&(member=*)(|(cn=Enterprise)(cn=People)))",
|
20
|
+
assert_equal "(&(|(member=*)(uniqueMember=*))(|(cn=Enterprise)(cn=People)))",
|
21
21
|
@subject.group_filter(%w(Enterprise People)).to_s
|
22
22
|
end
|
23
23
|
|
24
24
|
def test_groups_for_member
|
25
|
-
assert_equal "(&(member=#{@me})(|(cn=Enterprise)(cn=People)))",
|
25
|
+
assert_equal "(&(|(member=#{@me})(uniqueMember=#{@me}))(|(cn=Enterprise)(cn=People)))",
|
26
26
|
@subject.group_filter(%w(Enterprise People), @me).to_s
|
27
27
|
end
|
28
28
|
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
version: 1
|
2
|
+
|
3
|
+
# Organizations
|
4
|
+
|
5
|
+
dn: dc=github,dc=com
|
6
|
+
cn: github
|
7
|
+
objectClass: dcObject
|
8
|
+
objectClass: organization
|
9
|
+
dc: github
|
10
|
+
o: GitHub Inc.
|
11
|
+
|
12
|
+
# Admin user
|
13
|
+
|
14
|
+
dn: uid=admin,dc=github,dc=com
|
15
|
+
objectClass: top
|
16
|
+
objectClass: person
|
17
|
+
objectClass: organizationalPerson
|
18
|
+
objectClass: inetOrgPerson
|
19
|
+
cn: system administrator
|
20
|
+
sn: administrator
|
21
|
+
displayName: Directory Superuser
|
22
|
+
uid: admin
|
23
|
+
userPassword: secret
|
24
|
+
|
25
|
+
# Groups
|
26
|
+
|
27
|
+
dn: ou=groups,dc=github,dc=com
|
28
|
+
objectclass: organizationalUnit
|
29
|
+
|
30
|
+
dn: cn=enterprise,ou=groups,dc=github,dc=com
|
31
|
+
cn: Enterprise
|
32
|
+
objectClass: groupOfNames
|
33
|
+
member: uid=calavera,ou=users,dc=github,dc=com
|
34
|
+
member: cn=enterprise-devs,ou=groups,dc=github,dc=com
|
35
|
+
member: cn=enterprise-ops,ou=groups,dc=github,dc=com
|
36
|
+
|
37
|
+
dn: cn=enterprise-devs,ou=groups,dc=github,dc=com
|
38
|
+
cn: enterprise-devs
|
39
|
+
objectClass: groupOfNames
|
40
|
+
member: uid=benburkert,ou=users,dc=github,dc=com
|
41
|
+
|
42
|
+
dn: cn=enterprise-ops,ou=groups,dc=github,dc=com
|
43
|
+
cn: enterprise-ops
|
44
|
+
objectClass: groupOfNames
|
45
|
+
member: uid=sbryant,ou=users,dc=github,dc=com
|
46
|
+
member: cn=spaniards,ou=groups,dc=github,dc=com
|
47
|
+
|
48
|
+
dn: cn=spaniards,ou=groups,dc=github,dc=com
|
49
|
+
cn: spaniards
|
50
|
+
objectClass: groupOfNames
|
51
|
+
member: uid=calavera,ou=users,dc=github,dc=com
|
52
|
+
member: uid=rubiojr,ou=users,dc=github,dc=com
|
53
|
+
|
54
|
+
# Users
|
55
|
+
|
56
|
+
dn: ou=users,dc=github,dc=com
|
57
|
+
objectclass: organizationalUnit
|
58
|
+
|
59
|
+
dn: uid=calavera,ou=users,dc=github,dc=com
|
60
|
+
cn: David Calavera
|
61
|
+
cn: David
|
62
|
+
sn: Calavera
|
63
|
+
uid: calavera
|
64
|
+
userPassword: passworD1
|
65
|
+
mail: calavera@github.com
|
66
|
+
objectClass: inetOrgPerson
|
67
|
+
|
68
|
+
dn: uid=benburkert,ou=users,dc=github,dc=com
|
69
|
+
cn: benburkert
|
70
|
+
sn: benburkert
|
71
|
+
uid: benburkert
|
72
|
+
userPassword: passworD1
|
73
|
+
mail: benburkert@github.com
|
74
|
+
objectClass: inetOrgPerson
|
75
|
+
|
76
|
+
dn: uid=sbryant,ou=users,dc=github,dc=com
|
77
|
+
cn: sbryant
|
78
|
+
sn: sbryant
|
79
|
+
uid: sbryant
|
80
|
+
userPassword: passworD1
|
81
|
+
mail: sbryant@github.com
|
82
|
+
objectClass: inetOrgPerson
|
83
|
+
|
84
|
+
dn: uid=rubiojr,ou=users,dc=github,dc=com
|
85
|
+
cn: rubiojr
|
86
|
+
sn: rubiojr
|
87
|
+
uid: rubiojr
|
88
|
+
userPassword: passworD1
|
89
|
+
mail: rubiojr@github.com
|
90
|
+
objectClass: inetOrgPerson
|
data/test/group_test.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class GitHubLdapGroupTest < GitHub::Ldap::Test
|
4
|
+
def self.test_server_options
|
5
|
+
{user_fixtures: FIXTURES.join('github-with-subgroups.ldif').to_s}
|
6
|
+
end
|
7
|
+
|
8
|
+
def groups_domain
|
9
|
+
GitHub::Ldap.new(options).domain("ou=groups,dc=github,dc=com")
|
10
|
+
end
|
11
|
+
|
12
|
+
def setup
|
13
|
+
@group = GitHub::Ldap.new(options).group("cn=enterprise,ou=groups,dc=github,dc=com")
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_subgroups
|
17
|
+
assert_equal 3, @group.subgroups.size
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_members_from_subgroups
|
21
|
+
assert_equal 4, @group.members.size
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_all_domain_groups
|
25
|
+
groups = groups_domain.all_groups
|
26
|
+
assert_equal 4, groups.size
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_filter_domain_groups
|
30
|
+
groups = groups_domain.filter_groups('devs')
|
31
|
+
assert_equal 1, groups.size
|
32
|
+
end
|
33
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -4,6 +4,9 @@ __lib__ = File.expand_path('lib', File.dirname(__FILE__))
|
|
4
4
|
$LOAD_PATH << __dir__ unless $LOAD_PATH.include?(__dir__)
|
5
5
|
$LOAD_PATH << __lib__ unless $LOAD_PATH.include?(__lib__)
|
6
6
|
|
7
|
+
require 'pathname'
|
8
|
+
FIXTURES = Pathname(File.expand_path('fixtures', __dir__))
|
9
|
+
|
7
10
|
require 'github/ldap'
|
8
11
|
require 'github/ldap/server'
|
9
12
|
|
@@ -21,7 +24,8 @@ class GitHub::Ldap::Test < Minitest::Test
|
|
21
24
|
end
|
22
25
|
|
23
26
|
def self.start_server
|
24
|
-
|
27
|
+
server_opts = respond_to?(:test_server_options) ? test_server_options : {}
|
28
|
+
GitHub::Ldap.start_server(server_opts)
|
25
29
|
end
|
26
30
|
|
27
31
|
def options
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: github-ldap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Calavera
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: net-ldap
|
@@ -98,9 +98,12 @@ files:
|
|
98
98
|
- lib/github/ldap/domain.rb
|
99
99
|
- lib/github/ldap/filter.rb
|
100
100
|
- lib/github/ldap/fixtures.ldif
|
101
|
+
- lib/github/ldap/group.rb
|
101
102
|
- lib/github/ldap/server.rb
|
102
103
|
- test/domain_test.rb
|
103
104
|
- test/filter_test.rb
|
105
|
+
- test/fixtures/github-with-subgroups.ldif
|
106
|
+
- test/group_test.rb
|
104
107
|
- test/ldap_test.rb
|
105
108
|
- test/test_helper.rb
|
106
109
|
homepage: https://github.com/github/github-ldap
|
@@ -130,5 +133,8 @@ summary: Ldap client authentication wrapper without all the boilerplate
|
|
130
133
|
test_files:
|
131
134
|
- test/domain_test.rb
|
132
135
|
- test/filter_test.rb
|
136
|
+
- test/fixtures/github-with-subgroups.ldif
|
137
|
+
- test/group_test.rb
|
133
138
|
- test/ldap_test.rb
|
134
139
|
- test/test_helper.rb
|
140
|
+
has_rdoc:
|