github-ldap 1.1.5 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 64a07fbfbd7d8fd5486e4d211698d803071909e7
4
- data.tar.gz: 1a4508994676bcd35676000b9f8d8f5c719c543e
3
+ metadata.gz: 64ef77cae7b6d41804fd11a87a169001313320ec
4
+ data.tar.gz: 0d9fc6ed121d40dfcead6c8cd1c29cedc7598672
5
5
  SHA512:
6
- metadata.gz: 2b6dedbd71a4f0bd1a0a542c73f5ea90c41864448daef057acbd6b9c7fa7880d892dffb9a274b1658980442a32e8034d95af125663b9fff3915a588440ebdd80
7
- data.tar.gz: c43d7601a75c38577a8a922b550d4fec7efdc8102308bb10b652b9f6ae9d88c3d997deefb4fc1a936693edee67bf25fcbfe67349b99a88689d9bd93110dc241f
6
+ metadata.gz: 55c95dda73fffdce9e46a9718a8d1d58f32c9e47fc367b73c835a0f2e17b161a764c46cdeac24fc67331978764289696a99ea5586fc6c0382bf7d77ece583ad0
7
+ data.tar.gz: 8cb01bc061b35bf11f00b34c4340fe08ebe826f419f142c4e3949c720d0e54857ac15066d0c49ef29f26d60f8b85402718fabd13c0e2c648f4b04017ce7bbd7b
data/.travis.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
- - 2.0.0
5
-
4
+ - 2.1.0
5
+
6
6
  notifications:
7
7
  email: false
data/github-ldap.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "github-ldap"
5
- spec.version = "1.1.5"
5
+ spec.version = "1.2.0"
6
6
  spec.authors = ["David Calavera"]
7
7
  spec.email = ["david.calavera@gmail.com"]
8
8
  spec.description = %q{Ldap authentication for humans}
data/lib/github/ldap.rb CHANGED
@@ -5,18 +5,12 @@ module GitHub
5
5
  require 'github/ldap/filter'
6
6
  require 'github/ldap/domain'
7
7
  require 'github/ldap/group'
8
+ require 'github/ldap/posix_group'
8
9
  require 'github/ldap/virtual_group'
9
10
  require 'github/ldap/virtual_attributes'
10
11
 
11
12
  extend Forwardable
12
13
 
13
- # Utility method to perform searches against the ldap server.
14
- #
15
- # It takes the same arguments than Net::LDAP::Connection#search.
16
- # Returns an Array with the entries that match the search.
17
- # Returns nil if there are no entries that match the search.
18
- def_delegator :@connection, :search
19
-
20
14
  # Utility method to get the last operation result with a human friendly message.
21
15
  #
22
16
  # Returns an OpenStruct with `code` and `message`.
@@ -29,7 +23,7 @@ module GitHub
29
23
  # Returns a Net::LDAP::Entry if the operation succeeded.
30
24
  def_delegator :@connection, :bind
31
25
 
32
- attr_reader :virtual_attributes
26
+ attr_reader :uid, :virtual_attributes, :search_domains
33
27
 
34
28
  def initialize(options = {})
35
29
  @uid = options[:uid] || "sAMAccountName"
@@ -45,25 +39,13 @@ module GitHub
45
39
  end
46
40
 
47
41
  configure_virtual_attributes(options[:virtual_attributes])
48
- end
49
42
 
50
- # Determine whether to use encryption or not.
51
- #
52
- # encryption: is the encryption method, either 'ssl', 'tls', 'simple_tls' or 'start_tls'.
53
- #
54
- # Returns the real encryption type.
55
- def check_encryption(encryption)
56
- return unless encryption
57
-
58
- case encryption.downcase.to_sym
59
- when :ssl, :simple_tls
60
- :simple_tls
61
- when :tls, :start_tls
62
- :start_tls
63
- end
43
+ # search_domains is a connection of bases to perform searches
44
+ # when a base is not explicitly provided.
45
+ @search_domains = Array(options[:search_domains])
64
46
  end
65
47
 
66
- # Utility method to check if the connection with the server can be stablished.
48
+ # Public - Utility method to check if the connection with the server can be stablished.
67
49
  # It tries to bind with the ldap auth default configuration.
68
50
  #
69
51
  # Returns an OpenStruct with `code` and `message`.
@@ -73,7 +55,7 @@ module GitHub
73
55
  last_operation_result
74
56
  end
75
57
 
76
- # Creates a new domain object to perform operations
58
+ # Public - Creates a new domain object to perform operations
77
59
  #
78
60
  # base_name: is the dn of the base root.
79
61
  #
@@ -82,7 +64,7 @@ module GitHub
82
64
  Domain.new(self, base_name, @uid)
83
65
  end
84
66
 
85
- # Creates a new group object to perform operations
67
+ # Public - Creates a new group object to perform operations
86
68
  #
87
69
  # base_name: is the dn of the base root.
88
70
  #
@@ -92,14 +74,60 @@ module GitHub
92
74
  entry = domain(base_name).bind
93
75
  return unless entry
94
76
 
77
+ load_group(entry)
78
+ end
79
+
80
+ # Public - Create a new group object based on a Net::LDAP::Entry.
81
+ #
82
+ # group_entry: is a Net::LDAP::Entry.
83
+ #
84
+ # Returns a Group, PosixGroup or VirtualGroup object.
85
+ def load_group(group_entry)
95
86
  if @virtual_attributes.enabled?
96
- VirtualGroup.new(self, entry)
87
+ VirtualGroup.new(self, group_entry)
88
+ elsif PosixGroup.valid?(group_entry)
89
+ PosixGroup.new(self, group_entry)
90
+ else
91
+ Group.new(self, group_entry)
92
+ end
93
+ end
94
+
95
+ # Public - Search entries in the ldap server.
96
+ #
97
+ # options: is a hash with the same options that Net::LDAP::Connection#search supports.
98
+ #
99
+ # Returns an Array of Net::LDAP::Entry.
100
+ def search(options)
101
+ result = if options[:base]
102
+ @connection.search(options)
97
103
  else
98
- Group.new(self, entry)
104
+ search_domains.each_with_object([]) do |base, result|
105
+ rs = @connection.search(options.merge(:base => base))
106
+ result.concat Array(rs) unless rs == false
107
+ end
108
+ end
109
+
110
+ return [] if result == false
111
+ Array(result)
112
+ end
113
+
114
+ # Internal - Determine whether to use encryption or not.
115
+ #
116
+ # encryption: is the encryption method, either 'ssl', 'tls', 'simple_tls' or 'start_tls'.
117
+ #
118
+ # Returns the real encryption type.
119
+ def check_encryption(encryption)
120
+ return unless encryption
121
+
122
+ case encryption.downcase.to_sym
123
+ when :ssl, :simple_tls
124
+ :simple_tls
125
+ when :tls, :start_tls
126
+ :start_tls
99
127
  end
100
128
  end
101
129
 
102
- # Configure virtual attributes for this server.
130
+ # Internal - Configure virtual attributes for this server.
103
131
  # If the option is `true`, we'll use the default virual attributes.
104
132
  # If it's a Hash we'll map the attributes in the hash.
105
133
  #
@@ -55,8 +55,8 @@ module GitHub
55
55
  member_of = groups_map.keys & user_entry[@ldap.virtual_attributes.virtual_membership]
56
56
  member_of.map {|dn| groups_map[dn]}
57
57
  else
58
- groups_map.each_with_object([]) do |(dn, group), acc|
59
- acc << group if Group.new(@ldap, group).is_member?(user_entry.dn)
58
+ groups_map.each_with_object([]) do |(dn, group_entry), acc|
59
+ acc << group_entry if @ldap.load_group(group_entry).is_member?(user_entry)
60
60
  end
61
61
  end
62
62
  end
@@ -134,13 +134,9 @@ module GitHub
134
134
  def search(options)
135
135
  options[:base] = @base_name
136
136
  options[:attributes] ||= []
137
- options[:ignore_server_caps] ||= true
138
- options[:paged_searches_supported] ||= true
137
+ options[:paged_searches_supported] = true
139
138
 
140
- rs = @ldap.search(options)
141
- return [] if rs == false
142
-
143
- Array(rs)
139
+ @ldap.search(options)
144
140
  end
145
141
 
146
142
  # Provide a meaningful result after a protocol operation (for example,
@@ -2,19 +2,20 @@ module GitHub
2
2
  class Ldap
3
3
  module Filter
4
4
  ALL_GROUPS_FILTER = Net::LDAP::Filter.eq("objectClass", "groupOfNames") |
5
- Net::LDAP::Filter.eq("objectClass", "groupOfUniqueNames")
5
+ Net::LDAP::Filter.eq("objectClass", "groupOfUniqueNames") |
6
+ Net::LDAP::Filter.eq("objectClass", "posixGroup")
7
+
8
+ MEMBERSHIP_NAMES = %w(member uniqueMember)
6
9
 
7
10
  # Filter to get the configured groups in the ldap server.
8
11
  # Takes the list of the group names and generate a filter for the groups
9
- # with cn that match and also include members:
12
+ # with cn that match.
10
13
  #
11
14
  # group_names: is an array of group CNs.
12
- # user_dn: is an optional member to scope the search to.
13
15
  #
14
16
  # Returns a Net::LDAP::Filter.
15
- def group_filter(group_names, user_dn = nil)
16
- or_filters = group_names.map {|g| Net::LDAP::Filter.eq("cn", g)}.reduce(:|)
17
- member_filter(user_dn) & or_filters
17
+ def group_filter(group_names)
18
+ group_names.map {|g| Net::LDAP::Filter.eq("cn", g)}.reduce(:|)
18
19
  end
19
20
 
20
21
  # Filter to check a group membership.
@@ -24,9 +25,9 @@ module GitHub
24
25
  # Returns a Net::LDAP::Filter.
25
26
  def member_filter(user_dn = nil)
26
27
  if user_dn
27
- Net::LDAP::Filter.eq("member", user_dn) | Net::LDAP::Filter.eq("uniqueMember", user_dn)
28
+ MEMBERSHIP_NAMES.map {|n| Net::LDAP::Filter.eq(n, user_dn)}.reduce(:|)
28
29
  else
29
- Net::LDAP::Filter.pres("member") | Net::LDAP::Filter.pres("uniqueMember")
30
+ MEMBERSHIP_NAMES.map {|n| Net::LDAP::Filter.pres(n)}.reduce(:|)
30
31
  end
31
32
  end
32
33
 
@@ -69,6 +70,16 @@ module GitHub
69
70
  def subgroups_of_group(group_dn, attr = 'memberOf')
70
71
  Net::LDAP::Filter.eq(attr, group_dn) & ALL_GROUPS_FILTER
71
72
  end
73
+
74
+ # Filter to get all the members of a group which uid is included in `memberUid`.
75
+ #
76
+ # uids: is an array with all the uids to search.
77
+ # uid_attr: is the names of the uid attribute in the directory.
78
+ #
79
+ # Returns a Net::LDAP::Filter
80
+ def all_members_by_uid(uids, uid_attr)
81
+ uids.map {|uid| Net::LDAP::Filter.eq(uid_attr, uid)}.reduce(:|)
82
+ end
72
83
  end
73
84
  end
74
85
  end
@@ -10,7 +10,11 @@ module GitHub
10
10
  # domain = GitHub::Ldap.new(options).group("cn=enterprise,dc=github,dc=com")
11
11
  #
12
12
  class Group
13
- GROUP_CLASS_NAMES = %w(groupOfNames groupOfUniqueNames)
13
+ include Filter
14
+
15
+ GROUP_CLASS_NAMES = %w(groupOfNames groupOfUniqueNames posixGroup)
16
+
17
+ attr_reader :ldap, :entry
14
18
 
15
19
  def initialize(ldap, entry)
16
20
  @ldap, @entry = ldap, entry
@@ -37,12 +41,12 @@ module GitHub
37
41
 
38
42
  # Public - Check if a user dn is included in the members of this group and its subgroups.
39
43
  #
40
- # user_dn: is the dn to check.
44
+ # user_entry: is the user entry to check the membership.
41
45
  #
42
46
  # Returns true if the dn is in the list of members.
43
- def is_member?(user_dn)
44
- member_names.include?(user_dn) ||
45
- members.detect {|entry| entry.dn == user_dn}
47
+ def is_member?(user_entry)
48
+ member_names.include?(user_entry.dn) ||
49
+ members.detect {|entry| entry.dn == user_entry.dn}
46
50
  end
47
51
 
48
52
 
@@ -60,7 +64,9 @@ module GitHub
60
64
  #
61
65
  # Returns an array with all the DN members.
62
66
  def member_names
63
- @entry[:member] + @entry[:uniqueMember]
67
+ MEMBERSHIP_NAMES.each_with_object([]) do |n, cache|
68
+ cache.concat @entry[n]
69
+ end
64
70
  end
65
71
 
66
72
  # Internal - Check if an object class includes the member names
@@ -0,0 +1,81 @@
1
+ module GitHub
2
+ class Ldap
3
+ # This class represents a POSIX group.
4
+ #
5
+ # To get a POSIX group, you'll need to create a `Ldap` object and then call the method `group`.
6
+ # The parameter for `group` must be a dn to a group entry with `posixGroup` amongs the values for the attribute `objectClass`.
7
+ #
8
+ # For example:
9
+ #
10
+ # domain = GitHub::Ldap.new(options).group("cn=enterprise,dc=github,dc=com")
11
+ #
12
+ class PosixGroup < Group
13
+ # Public - Check if an ldap entry is a valid posixGroup.
14
+ #
15
+ # entry: is the ldap entry to check.
16
+ #
17
+ # Returns true if the entry includes the objectClass `posixGroup`.
18
+ def self.valid?(entry)
19
+ entry[:objectClass].any? {|oc| oc.downcase == 'posixgroup'}
20
+ end
21
+
22
+ # Public - Overrides Group#members
23
+ #
24
+ # Search the entries corresponding to the members in the `memberUid` attribute.
25
+ # It calls `super` if the group entry includes `member` or `uniqueMember`.
26
+ #
27
+ # Returns an array with the members of this group and its submembers if there is any.
28
+ def members
29
+ return @all_posix_members if @all_posix_members
30
+
31
+ @all_posix_members = search_members_by_uids
32
+ @all_posix_members.concat super if combined_group?
33
+
34
+ @all_posix_members.uniq! {|m| m.dn }
35
+ @all_posix_members
36
+ end
37
+
38
+ # Public - Overrides Group#subgroups
39
+ #
40
+ # Prevent to call super when the group entry does not include `member` or `uniqueMember`.
41
+ #
42
+ # Returns an array with the subgroups of this group.
43
+ def subgroups
44
+ return [] unless combined_group?
45
+
46
+ super
47
+ end
48
+
49
+ # Public - Overrides Group#is_member?
50
+ #
51
+ # Chech if the user entry uid exists in the collection of `memberUid`.
52
+ # It calls `super` if the group entry includes `member` or `uniqueMember`.
53
+ #
54
+ # Return true if the user is member if this group or any subgroup.
55
+ def is_member?(user_entry)
56
+ entry_uids = user_entry[ldap.uid]
57
+ return true if !(entry_uids & entry[:memberUid]).empty?
58
+
59
+ super if combined_group?
60
+ end
61
+
62
+ # Internal - Check if this posix group also includes `member` and `uniqueMember` entries.
63
+ #
64
+ # Returns true if any of the membership names is include in this group entry.
65
+ def combined_group?
66
+ MEMBERSHIP_NAMES.any? {|name| !entry[name].empty? }
67
+ end
68
+
69
+ # Internal - Search all members by uid.
70
+ #
71
+ # Return an array of user entries.
72
+ def search_members_by_uids
73
+ member_uids = entry[:memberUid]
74
+ return [] if member_uids.empty?
75
+
76
+ filter = all_members_by_uid(member_uids, ldap.uid)
77
+ ldap.search(filter: filter)
78
+ end
79
+ end
80
+ end
81
+ end
data/test/filter_test.rb CHANGED
@@ -17,15 +17,10 @@ class FilterTest < Minitest::Test
17
17
  end
18
18
 
19
19
  def test_groups_reduced
20
- assert_equal "(&(|(member=*)(uniqueMember=*))(|(cn=Enterprise)(cn=People)))",
20
+ assert_equal "(|(cn=Enterprise)(cn=People))",
21
21
  @subject.group_filter(%w(Enterprise People)).to_s
22
22
  end
23
23
 
24
- def test_groups_for_member
25
- assert_equal "(&(|(member=#{@me})(uniqueMember=#{@me}))(|(cn=Enterprise)(cn=People)))",
26
- @subject.group_filter(%w(Enterprise People), @me).to_s
27
- end
28
-
29
24
  def test_members_of_group
30
25
  assert_equal "(memberOf=cn=group,dc=github,dc=com)",
31
26
  @subject.members_of_group('cn=group,dc=github,dc=com').to_s
@@ -41,4 +36,9 @@ class FilterTest < Minitest::Test
41
36
  assert_equal "(&(isMemberOf=cn=group,dc=github,dc=com)#{Subject::ALL_GROUPS_FILTER})",
42
37
  @subject.subgroups_of_group('cn=group,dc=github,dc=com', 'isMemberOf').to_s
43
38
  end
39
+
40
+ def test_all_members_by_uid
41
+ assert_equal "(|(uid=calavera)(uid=mtodd))",
42
+ @subject.all_members_by_uid(%w(calavera mtodd), :uid).to_s
43
+ end
44
44
  end
@@ -3,7 +3,6 @@ version: 1
3
3
  # Organizations
4
4
 
5
5
  dn: dc=github,dc=com
6
- cn: github
7
6
  objectClass: dcObject
8
7
  objectClass: organization
9
8
  dc: github
@@ -26,6 +25,7 @@ userPassword: secret
26
25
 
27
26
  dn: ou=groups,dc=github,dc=com
28
27
  objectclass: organizationalUnit
28
+ ou: groups
29
29
 
30
30
  dn: cn=enterprise,ou=groups,dc=github,dc=com
31
31
  cn: Enterprise
@@ -55,6 +55,7 @@ member: uid=rubiojr,ou=users,dc=github,dc=com
55
55
 
56
56
  dn: ou=users,dc=github,dc=com
57
57
  objectclass: organizationalUnit
58
+ ou: users
58
59
 
59
60
  dn: uid=calavera,ou=users,dc=github,dc=com
60
61
  cn: David Calavera
@@ -88,3 +89,11 @@ uid: rubiojr
88
89
  userPassword: passworD1
89
90
  mail: rubiojr@github.com
90
91
  objectClass: inetOrgPerson
92
+
93
+ dn: uid=mtodd,ou=users,dc=github,dc=com
94
+ cn: mtodd
95
+ sn: mtodd
96
+ uid: mtodd
97
+ userPassword: passworD1
98
+ mail: mtodd@github.com
99
+ objectClass: inetOrgPerson
data/test/ldap_test.rb CHANGED
@@ -29,6 +29,7 @@ module GitHubLdapTestCases
29
29
  :attributes => %w(uid),
30
30
  :filter => Net::LDAP::Filter.eq('uid', 'calavera')})
31
31
 
32
+ refute result.empty?
32
33
  assert_equal 'calavera', result.first[:uid].first
33
34
  end
34
35
 
@@ -56,6 +57,14 @@ module GitHubLdapTestCases
56
57
  def test_virtual_attributes_disabled
57
58
  refute @ldap.virtual_attributes.enabled?, "Expected to have virtual attributes disabled"
58
59
  end
60
+
61
+ def test_search_domains
62
+ ldap = GitHub::Ldap.new(options.merge(search_domains: ['dc=github,dc=com']))
63
+ result = ldap.search(filter: Net::LDAP::Filter.eq('uid', 'calavera'))
64
+
65
+ refute result.empty?
66
+ assert_equal 'calavera', result.first[:uid].first
67
+ end
59
68
  end
60
69
 
61
70
  class GitHubLdapTest < GitHub::Ldap::Test
@@ -0,0 +1,120 @@
1
+ require 'test_helper'
2
+
3
+ class GitHubLdapPosixGroupTest < 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 setup
9
+ @simple_group = Net::LDAP::Entry._load("""
10
+ dn: cn=enterprise-posix-devs,ou=groups,dc=github,dc=com
11
+ cn: enterprise-posix-devs
12
+ objectClass: posixGroup
13
+ memberUid: benburkert
14
+ memberUid: mtodd""")
15
+
16
+ @one_level_deep_group = Net::LDAP::Entry._load("""
17
+ dn: cn=enterprise-posix-ops,ou=groups,dc=github,dc=com
18
+ cn: enterprise-posix-ops
19
+ objectClass: posixGroup
20
+ objectClass: groupOfNames
21
+ memberUid: sbryant
22
+ member: cn=spaniards,ou=groups,dc=github,dc=com""")
23
+
24
+ @two_levels_deep_group = Net::LDAP::Entry._load("""
25
+ dn: cn=enterprise-posix,ou=groups,dc=github,dc=com
26
+ cn: Enterprise Posix
27
+ objectClass: posixGroup
28
+ objectClass: groupOfNames
29
+ memberUid: calavera
30
+ member: cn=enterprise-devs,ou=groups,dc=github,dc=com
31
+ member: cn=enterprise-ops,ou=groups,dc=github,dc=com""")
32
+
33
+ @empty_group = Net::LDAP::Entry._load("""
34
+ dn: cn=enterprise-posix-empty,ou=groups,dc=github,dc=com
35
+ cn: enterprise-posix-empty
36
+ objectClass: posixGroup""")
37
+
38
+ @ldap = GitHub::Ldap.new(options.merge(search_domains: %w(dc=github,dc=com)))
39
+ end
40
+
41
+ def test_posix_group
42
+ assert GitHub::Ldap::PosixGroup.valid?(@simple_group),
43
+ "Expected entry to be a valid posixGroup"
44
+ end
45
+
46
+ def test_posix_simple_members
47
+ group = GitHub::Ldap::PosixGroup.new(@ldap, @simple_group)
48
+ members = group.members
49
+
50
+ assert_equal 2, members.size
51
+ assert_equal 'benburkert', members.first[:uid].first
52
+ end
53
+
54
+ def test_posix_combined_group
55
+ group = GitHub::Ldap::PosixGroup.new(@ldap, @one_level_deep_group)
56
+ members = group.members
57
+
58
+ assert_equal 3, members.size
59
+ end
60
+
61
+ def test_posix_combined_group_unique_members
62
+ group = GitHub::Ldap::PosixGroup.new(@ldap, @two_levels_deep_group)
63
+ members = group.members
64
+
65
+ assert_equal 4, members.size
66
+ end
67
+
68
+ def test_empty_subgroups
69
+ group = GitHub::Ldap::PosixGroup.new(@ldap, @simple_group)
70
+ subgroups = group.subgroups
71
+
72
+ assert subgroups.empty?, "Simple posixgroup expected to not have subgroups"
73
+ end
74
+
75
+ def test_posix_combined_group_subgroups
76
+ group = GitHub::Ldap::PosixGroup.new(@ldap, @one_level_deep_group)
77
+ subgroups = group.subgroups
78
+
79
+ assert_equal 1, subgroups.size
80
+ end
81
+
82
+ def test_is_member_simple_group
83
+ group = GitHub::Ldap::PosixGroup.new(@ldap, @simple_group)
84
+ user = @ldap.domain("uid=benburkert,ou=users,dc=github,dc=com").bind
85
+
86
+ assert group.is_member?(user),
87
+ "Expected user in the memberUid list to be a member of the posixgroup"
88
+ end
89
+
90
+ def test_is_member_combined_group
91
+ group = GitHub::Ldap::PosixGroup.new(@ldap, @one_level_deep_group)
92
+ user = @ldap.domain("uid=calavera,ou=users,dc=github,dc=com").bind
93
+
94
+ assert group.is_member?(user),
95
+ "Expected user in a subgroup to be a member of the posixgroup"
96
+ end
97
+
98
+ def test_is_not_member_simple_group
99
+ group = GitHub::Ldap::PosixGroup.new(@ldap, @simple_group)
100
+ user = @ldap.domain("uid=calavera,ou=users,dc=github,dc=com").bind
101
+
102
+ refute group.is_member?(user),
103
+ "Expected user to not be member when her uid is not in the list of memberUid"
104
+ end
105
+
106
+ def test_is_member_combined_group
107
+ group = GitHub::Ldap::PosixGroup.new(@ldap, @one_level_deep_group)
108
+ user = @ldap.domain("uid=benburkert,ou=users,dc=github,dc=com").bind
109
+
110
+ refute group.is_member?(user),
111
+ "Expected user to not be member when she's not member of any subgroup"
112
+ end
113
+
114
+ def test_empty_posix_group
115
+ group = GitHub::Ldap::PosixGroup.new(@ldap, @empty_group)
116
+
117
+ assert group.members.empty?,
118
+ "Expected members to be an empty array"
119
+ end
120
+ end
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.1.5
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Calavera
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-11 00:00:00.000000000 Z
11
+ date: 2014-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-ldap
@@ -99,6 +99,7 @@ files:
99
99
  - lib/github/ldap/filter.rb
100
100
  - lib/github/ldap/fixtures.ldif
101
101
  - lib/github/ldap/group.rb
102
+ - lib/github/ldap/posix_group.rb
102
103
  - lib/github/ldap/server.rb
103
104
  - lib/github/ldap/virtual_attributes.rb
104
105
  - lib/github/ldap/virtual_group.rb
@@ -109,6 +110,7 @@ files:
109
110
  - test/fixtures/github-with-subgroups.ldif
110
111
  - test/group_test.rb
111
112
  - test/ldap_test.rb
113
+ - test/posix_group_test.rb
112
114
  - test/test_helper.rb
113
115
  homepage: https://github.com/github/github-ldap
114
116
  licenses:
@@ -142,5 +144,6 @@ test_files:
142
144
  - test/fixtures/github-with-subgroups.ldif
143
145
  - test/group_test.rb
144
146
  - test/ldap_test.rb
147
+ - test/posix_group_test.rb
145
148
  - test/test_helper.rb
146
149
  has_rdoc: