github-ldap 1.0.9 → 1.0.10

Sign up to get free protection for your applications and to get access to all the features.
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: