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