github-ldap 1.1.5 → 1.2.0

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 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: