github-ldap 1.0.9 → 1.0.10

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.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- ![Build Status](https://travis-ci.org/github/github-ldap.png)
1
+ <a href="https://travis-ci.org/github/github-ldap">![Build Status](https://travis-ci.org/github/github-ldap.png)</a>
2
2
 
3
3
  # Github::Ldap
4
4
 
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.0.9"
5
+ spec.version = "1.0.10"
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
@@ -2,6 +2,7 @@ module GitHub
2
2
  class Ldap
3
3
  require 'net/ldap'
4
4
  require 'forwardable'
5
+ require 'github/ldap/filter'
5
6
  require 'github/ldap/domain'
6
7
 
7
8
  extend Forwardable
@@ -12,31 +12,19 @@ module GitHub
12
12
  # domain = GitHub::Ldap.new(options).domain("dc=github,dc=com")
13
13
  #
14
14
  class Domain
15
+ include Filter
16
+
15
17
  def initialize(base_name, connection, uid)
16
18
  @base_name, @connection, @uid = base_name, connection, uid
17
19
  end
18
20
 
19
- # Generate a filter to get the configured groups in the ldap server.
20
- # Takes the list of the group names and generate a filter for the groups
21
- # with cn that match and also include members:
22
- #
23
- # group_names: is an array of group CNs.
24
- #
25
- # Returns the ldap filter.
26
- def group_filter(group_names)
27
- or_filters = group_names.map {|g| Net::LDAP::Filter.eq("cn", g)}.reduce(:|)
28
- Net::LDAP::Filter.pres("member") & or_filters
29
- end
30
-
31
21
  # List the groups in the ldap server that match the configured ones.
32
22
  #
33
23
  # group_names: is an array of group CNs.
34
24
  #
35
25
  # Returns a list of ldap entries for the configured groups.
36
26
  def groups(group_names)
37
- filter = group_filter(group_names)
38
-
39
- search(attributes: %w{ou cn dn sAMAccountName member}, filter: filter)
27
+ search(filter: group_filter(group_names))
40
28
  end
41
29
 
42
30
  # List the groups that a user is member of.
@@ -46,10 +34,7 @@ module GitHub
46
34
  #
47
35
  # Return an Array with the groups that the given user is member of that belong to the given group list.
48
36
  def membership(user_dn, group_names)
49
- or_filters = group_names.map {|g| Net::LDAP::Filter.eq("cn", g)}.reduce(:|)
50
- member_filter = Net::LDAP::Filter.eq("member", user_dn) & or_filters
51
-
52
- search(attributes: %w{ou cn dn sAMAccountName member}, filter: member_filter)
37
+ search(filter: group_filter(group_names, user_dn))
53
38
  end
54
39
 
55
40
  # Check if the user is include in any of the configured groups.
@@ -76,13 +61,30 @@ module GitHub
76
61
  # Returns a Ldap::Entry if the credentials are valid.
77
62
  # Returns nil if the credentials are invalid.
78
63
  def valid_login?(login, password)
79
- result = @connection.bind_as(
80
- base: @base_name,
81
- limit: 1,
82
- filter: Net::LDAP::Filter.eq(@uid, login),
83
- password: password)
64
+ if user = user?(login) and auth(user, password)
65
+ return user
66
+ end
67
+ end
68
+
69
+ # Check if a user exists based in the `uid`.
70
+ #
71
+ # login: is the user's login
72
+ #
73
+ # Returns the user if the login matches any `uid`.
74
+ # Returns nil if there are no matches.
75
+ def user?(login)
76
+ rs = search(limit: 1, filter: Net::LDAP::Filter.eq(@uid, login))
77
+ rs and rs.first
78
+ end
84
79
 
85
- return result.first if result.is_a?(Array)
80
+ # Check if a user can be bound with a password.
81
+ #
82
+ # user: is a ldap entry representing the user.
83
+ # password: is the user's password.
84
+ #
85
+ # Returns true if the user can be bound.
86
+ def auth(user, password)
87
+ @connection.bind(method: :simple, username: user.dn, password: password)
86
88
  end
87
89
 
88
90
  # Authenticate a user with the ldap server.
@@ -109,6 +111,7 @@ module GitHub
109
111
  # Returns nil if there are no entries.
110
112
  def search(options)
111
113
  options[:base] = @base_name
114
+ options[:attributes] ||= %w{ou cn dn sAMAccountName member}
112
115
 
113
116
  @connection.search(options)
114
117
  end
@@ -0,0 +1,31 @@
1
+ module GitHub
2
+ class Ldap
3
+ module Filter
4
+ # Filter to get the configured groups in the ldap server.
5
+ # Takes the list of the group names and generate a filter for the groups
6
+ # with cn that match and also include members:
7
+ #
8
+ # group_names: is an array of group CNs.
9
+ # user_dn: is an optional member to scope the search to.
10
+ #
11
+ # Returns a Net::LDAP::Filter.
12
+ def group_filter(group_names, user_dn = nil)
13
+ or_filters = group_names.map {|g| Net::LDAP::Filter.eq("cn", g)}.reduce(:|)
14
+ member_filter(user_dn) & or_filters
15
+ end
16
+
17
+ # Filter to check a group membership.
18
+ #
19
+ # user_dn: is an optional user_dn to scope the search to.
20
+ #
21
+ # Returns a Net::LDAP::Filter.
22
+ def member_filter(user_dn = nil)
23
+ if user_dn
24
+ Net::LDAP::Filter.eq("member", user_dn)
25
+ else
26
+ Net::LDAP::Filter.pres("member")
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
data/test/domain_test.rb CHANGED
@@ -100,5 +100,23 @@ class GitHubLdapDomainTest < Minitest::Test
100
100
  attributes: %w(uid),
101
101
  filter: Net::LDAP::Filter.eq('uid', 'calavera')).size
102
102
  end
103
+
104
+ def test_user_exists
105
+ assert_equal 'uid=calavera,dc=github,dc=com', @domain.user?('calavera').dn
106
+ end
107
+
108
+ def test_user_does_not_exist
109
+ assert !@domain.user?('foobar'), 'Expected uid `foobar` to not exist.'
110
+ end
111
+
112
+ def test_auth_binds
113
+ user = @domain.user?('calavera')
114
+ assert @domain.auth(user, 'secret'), 'Expected user to be bound.'
115
+ end
116
+
117
+ def test_auth_does_not_bind
118
+ user = @domain.user?('calavera')
119
+ assert !@domain.auth(user, 'foo'), 'Expected user not to be bound.'
120
+ end
103
121
  end
104
122
 
@@ -0,0 +1,28 @@
1
+ require 'test_helper'
2
+
3
+ class FilterTest < Minitest::Test
4
+ class Subject; include GitHub::Ldap::Filter; end
5
+
6
+ def setup
7
+ @subject = Subject.new
8
+ @me = 'uid=calavera,dc=github,dc=com'
9
+ end
10
+
11
+ def test_member_present
12
+ assert_equal "(member=*)", @subject.member_filter.to_s
13
+ end
14
+
15
+ def test_member_equal
16
+ assert_equal "(member=#{@me})", @subject.member_filter(@me).to_s
17
+ end
18
+
19
+ def test_groups_reduced
20
+ assert_equal "(&(member=*)(|(cn=Enterprise)(cn=People)))",
21
+ @subject.group_filter(%w(Enterprise People)).to_s
22
+ end
23
+
24
+ def test_groups_for_member
25
+ assert_equal "(&(member=#{@me})(|(cn=Enterprise)(cn=People)))",
26
+ @subject.group_filter(%w(Enterprise People), @me).to_s
27
+ end
28
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: github-ldap
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.9
4
+ version: 1.0.10
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-22 00:00:00.000000000 Z
12
+ date: 2013-07-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: net-ldap
@@ -107,9 +107,11 @@ files:
107
107
  - github-ldap.gemspec
108
108
  - lib/github/ldap.rb
109
109
  - lib/github/ldap/domain.rb
110
+ - lib/github/ldap/filter.rb
110
111
  - lib/github/ldap/fixtures.ldif
111
112
  - lib/github/ldap/server.rb
112
113
  - test/domain_test.rb
114
+ - test/filter_test.rb
113
115
  - test/ldap_test.rb
114
116
  - test/test_helper.rb
115
117
  homepage: https://github.com/github/github-ldap
@@ -139,6 +141,7 @@ specification_version: 3
139
141
  summary: Ldap client authentication wrapper without all the boilerplate
140
142
  test_files:
141
143
  - test/domain_test.rb
144
+ - test/filter_test.rb
142
145
  - test/ldap_test.rb
143
146
  - test/test_helper.rb
144
147
  has_rdoc: