adauth 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.travis.yml +8 -1
- data/Gemfile +1 -1
- data/Gemfile.lock +10 -2
- data/LICENSE.txt +21 -0
- data/Rakefile +10 -1
- data/Readme.md +2 -1
- data/adauth.gemspec +2 -0
- data/lib/adauth.rb +6 -2
- data/lib/adauth/ad_object.rb +41 -15
- data/lib/adauth/ad_objects/group.rb +8 -3
- data/lib/adauth/ad_objects/user.rb +5 -5
- data/lib/adauth/authenticate.rb +11 -61
- data/lib/adauth/config.rb +2 -1
- data/lib/adauth/connection.rb +6 -0
- data/lib/adauth/net-ldap/string.rb +1 -0
- data/lib/adauth/version.rb +1 -1
- data/rspec_results.txt +10 -0
- data/spec/adauth_ad_object_computer_spec.rb +9 -4
- data/spec/adauth_ad_object_folder_spec.rb +7 -3
- data/spec/adauth_ad_object_group_spec.rb +8 -6
- data/spec/adauth_ad_object_ou_spec.rb +4 -0
- data/spec/adauth_ad_object_spec.rb +22 -0
- data/spec/adauth_ad_object_user_spec.rb +30 -20
- data/spec/adauth_authenticate_spec.rb +26 -0
- data/spec/adauth_connection_spec.rb +33 -0
- data/spec/adauth_rails_model_bridge_spec.rb +1 -1
- data/spec/spec_helper.rb +12 -9
- data/spec/test_data.example.yml +6 -2
- metadata +47 -21
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: cffe1ba97471be1224d557a5df97bd0e16e5eb59
|
4
|
+
data.tar.gz: d080e1a4e3a065c57da6c7281c60c79e0fe82f07
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 12b8d3a9a46735f4528a890272db9c52434883bbc922f46f243957e87fb6acdf1e7f4abf42d70ca0bed4af8ad2ade0947b5918496af5fbca9e89495e8acab224
|
7
|
+
data.tar.gz: 94ec81bf3fb570be993eb87d51de4543ff11c91de5742e30ef26a7f7acefef8aca2866d76fdde8f87750eb71ffccf7e53f2c05acef3e381959b067d95e0db6a3
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -2,11 +2,18 @@ language: ruby
|
|
2
2
|
rvm:
|
3
3
|
- 1.8.7
|
4
4
|
- 1.9.3
|
5
|
+
- 2.0.0
|
5
6
|
- rbx-18mode
|
6
7
|
- rbx-19mode
|
8
|
+
- ruby-head
|
7
9
|
env:
|
8
|
-
- "rake=0.8"
|
9
10
|
- "rake=0.9"
|
10
11
|
script: "bundle exec rspec -t no_ad"
|
12
|
+
before_script: "mkdir log"
|
11
13
|
notifications:
|
12
14
|
email: false
|
15
|
+
matrix:
|
16
|
+
allow_failures:
|
17
|
+
- rvm: 1.8.7
|
18
|
+
- rvm: rbx-18mode
|
19
|
+
- rvm: ruby-head
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
adauth (2.0.
|
4
|
+
adauth (2.0.0)
|
5
5
|
net-ldap
|
6
6
|
|
7
7
|
GEM
|
8
|
-
remote:
|
8
|
+
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
10
|
diff-lcs (1.1.3)
|
11
|
+
multi_json (1.7.7)
|
11
12
|
net-ldap (0.3.1)
|
12
13
|
rake (0.9.2.2)
|
13
14
|
rspec (2.11.0)
|
@@ -18,6 +19,11 @@ GEM
|
|
18
19
|
rspec-expectations (2.11.2)
|
19
20
|
diff-lcs (~> 1.1.3)
|
20
21
|
rspec-mocks (2.11.2)
|
22
|
+
simplecov (0.7.1)
|
23
|
+
multi_json (~> 1.0)
|
24
|
+
simplecov-html (~> 0.7.1)
|
25
|
+
simplecov-html (0.7.1)
|
26
|
+
yard (0.8.6.2)
|
21
27
|
|
22
28
|
PLATFORMS
|
23
29
|
ruby
|
@@ -26,3 +32,5 @@ DEPENDENCIES
|
|
26
32
|
adauth!
|
27
33
|
rake
|
28
34
|
rspec
|
35
|
+
simplecov
|
36
|
+
yard
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 Adam Laycock
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/Rakefile
CHANGED
@@ -1,4 +1,13 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'bundler'
|
3
3
|
|
4
|
-
Bundler::GemHelper.install_tasks
|
4
|
+
Bundler::GemHelper.install_tasks
|
5
|
+
|
6
|
+
desc "Save test results to a file"
|
7
|
+
task :generate_test_results do
|
8
|
+
puts "Running Tests"
|
9
|
+
system("rspec -c > rspec_results.txt")
|
10
|
+
puts "Saved!"
|
11
|
+
puts "Results:"
|
12
|
+
system("cat rspec_results.txt")
|
13
|
+
end
|
data/Readme.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Adauth
|
2
|
-
[RDoc](http://rubydoc.info/github/Arcath/Adauth/master/frames) | [www](http://adauth.arcath.net) | [Gempage](http://rubygems.org/gems/adauth) | [![Status](https://secure.travis-ci.org/Arcath/Adauth.png?branch=master)](http://travis-ci.org/Arcath/Adauth)
|
2
|
+
[RDoc](http://rubydoc.info/github/Arcath/Adauth/master/frames) | [www](http://adauth.arcath.net) | [Gempage](http://rubygems.org/gems/adauth) | [![Status](https://secure.travis-ci.org/Arcath/Adauth.png?branch=master)](http://travis-ci.org/Arcath/Adauth) | [![Code Climate](https://codeclimate.com/github/Arcath/Adauth.png)](https://codeclimate.com/github/Arcath/Adauth) | [![Dependency Status](https://gemnasium.com/Arcath/Adauth.png)](https://gemnasium.com/Arcath/Adauth)
|
3
|
+
|
3
4
|
|
4
5
|
Easy to use Active Directory Authentication for Rails.
|
5
6
|
|
data/adauth.gemspec
CHANGED
@@ -14,6 +14,8 @@ Gem::Specification.new do |s|
|
|
14
14
|
|
15
15
|
s.add_development_dependency "rake"
|
16
16
|
s.add_development_dependency "rspec"
|
17
|
+
s.add_development_dependency "simplecov"
|
18
|
+
s.add_development_dependency "yard"
|
17
19
|
s.add_dependency "net-ldap"
|
18
20
|
|
19
21
|
s.files = `git ls-files`.split("\n")
|
data/lib/adauth.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Requires
|
2
|
+
require 'logger'
|
2
3
|
require 'net/ldap'
|
3
4
|
require 'timeout'
|
4
|
-
require 'logger'
|
5
5
|
# Version
|
6
6
|
require 'adauth/version'
|
7
7
|
# Classes
|
@@ -28,6 +28,7 @@ module Adauth
|
|
28
28
|
def self.configure
|
29
29
|
@logger ||= Logger.new('log/adauth.log', 'weekly')
|
30
30
|
@logger.info('load') { "Loading new config" }
|
31
|
+
@connection = nil
|
31
32
|
@config = Config.new
|
32
33
|
yield(@config)
|
33
34
|
end
|
@@ -53,16 +54,19 @@ module Adauth
|
|
53
54
|
:server => @config.server,
|
54
55
|
:port => @config.port,
|
55
56
|
:base => @config.base,
|
56
|
-
:encryption => @config.encryption,
|
57
|
+
:encryption => @config.encryption,
|
58
|
+
:allow_fallback => @config.allow_fallback,
|
57
59
|
:username => user,
|
58
60
|
:password => password
|
59
61
|
}
|
60
62
|
end
|
61
63
|
|
64
|
+
# Returns the logger object
|
62
65
|
def self.logger
|
63
66
|
@logger
|
64
67
|
end
|
65
68
|
|
69
|
+
# Lets you set a new logger
|
66
70
|
def self.logger=(inputs)
|
67
71
|
@logger = inputs
|
68
72
|
end
|
data/lib/adauth/ad_object.rb
CHANGED
@@ -14,10 +14,10 @@ module Adauth
|
|
14
14
|
# Objects inherit from this class.
|
15
15
|
#
|
16
16
|
# Provides all the common functions for Active Directory.
|
17
|
-
class AdObject
|
17
|
+
class AdObject
|
18
18
|
# Returns all objects which have the ObjectClass of the inherited class
|
19
19
|
def self.all
|
20
|
-
Adauth.logger.info(self.inspect) { "Searching for all objects matching filter \"#{self::ObjectFilter}\"" }
|
20
|
+
Adauth.logger.info(self.class.inspect) { "Searching for all objects matching filter \"#{self::ObjectFilter}\"" }
|
21
21
|
self.filter(self::ObjectFilter)
|
22
22
|
end
|
23
23
|
|
@@ -26,7 +26,7 @@ module Adauth
|
|
26
26
|
# Uses ObjectFilter to restrict to the current object
|
27
27
|
def self.where(field, value)
|
28
28
|
search_filter = Net::LDAP::Filter.eq(field, value)
|
29
|
-
Adauth.logger.info(self.inspect) { "Searching for all \"#{self::ObjectFilter}\" where #{field} = #{value}" }
|
29
|
+
Adauth.logger.info(self.class.inspect) { "Searching for all \"#{self::ObjectFilter}\" where #{field} = #{value}" }
|
30
30
|
filter(add_object_filter(search_filter))
|
31
31
|
end
|
32
32
|
|
@@ -62,18 +62,19 @@ module Adauth
|
|
62
62
|
@ldap_object
|
63
63
|
end
|
64
64
|
|
65
|
-
# Over
|
65
|
+
# Over ride method missing to see if the object has a field by that name
|
66
66
|
def method_missing(method, *args)
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
67
|
+
field = self.class::Fields[method]
|
68
|
+
return handle_field(field) if field
|
69
|
+
return super
|
70
|
+
end
|
71
|
+
|
72
|
+
# Handle the output for the given field
|
73
|
+
def handle_field(field)
|
74
|
+
case field
|
75
|
+
when Symbol then return return_symbol_value(field)
|
76
|
+
when Array then return @ldap_object.send(field.first).collect(&field.last)
|
77
|
+
end
|
77
78
|
end
|
78
79
|
|
79
80
|
# Returns all the groups the object is a member of
|
@@ -84,6 +85,19 @@ module Adauth
|
|
84
85
|
@groups
|
85
86
|
end
|
86
87
|
|
88
|
+
# The same as cn_groups, but with the parent groups included
|
89
|
+
def cn_groups_nested
|
90
|
+
@cn_groups_nested = cn_groups
|
91
|
+
cn_groups.each do |group|
|
92
|
+
ado = Adauth::AdObjects::Group.where('name', group).first
|
93
|
+
groups = convert_to_objects ado.cn_groups
|
94
|
+
groups.each do |g|
|
95
|
+
@cn_groups_nested.push g if !(@cn_groups_nested.include?(g))
|
96
|
+
end
|
97
|
+
end
|
98
|
+
return @cn_groups_nested
|
99
|
+
end
|
100
|
+
|
87
101
|
# Returns all the ous the object is in
|
88
102
|
def ous
|
89
103
|
unless @ous
|
@@ -108,7 +122,11 @@ module Adauth
|
|
108
122
|
|
109
123
|
# Runs a modify action on the current object, takes an aray of operations
|
110
124
|
def modify(operations)
|
111
|
-
|
125
|
+
Adauth.logger.info(self.class.inspect) { "Attempting modify operation" }
|
126
|
+
unless Adauth.connection.modify :dn => @ldap_object.dn, :operations => operations
|
127
|
+
Adauth.logger.fatal(self.class.inspect) { "Modify Operation Failed! Code: #{Adauth.connection.get_operation_result.code} Message: #{Adauth.connection.get_operation_result.message}" }
|
128
|
+
raise 'Modify Operation Failed (see log for details)'
|
129
|
+
end
|
112
130
|
end
|
113
131
|
|
114
132
|
# Returns an array of member objects for this object
|
@@ -149,5 +167,13 @@ module Adauth
|
|
149
167
|
group = Adauth::AdObjects::Group.where('sAMAccountName', entity).first
|
150
168
|
(user || group)
|
151
169
|
end
|
170
|
+
|
171
|
+
def return_symbol_value(field)
|
172
|
+
value = @ldap_object.send(field)
|
173
|
+
case value
|
174
|
+
when String then return value
|
175
|
+
when Net::BER::BerIdentifiedArray then return value.first
|
176
|
+
end
|
177
|
+
end
|
152
178
|
end
|
153
179
|
end
|
@@ -19,8 +19,9 @@ module Adauth
|
|
19
19
|
:name => :samaccountname,
|
20
20
|
:cn_members => [ :member,
|
21
21
|
Proc.new {|g| g.sub(/.*?CN=(.*?),.*/, '\1')} ],
|
22
|
-
:
|
23
|
-
|
22
|
+
:memberof => :member
|
23
|
+
#:cn_groups => [ :memberof,
|
24
|
+
# Proc.new {|g| g.sub(/.*?CN=(.*?),.*/, '\1')} ]
|
24
25
|
}
|
25
26
|
|
26
27
|
# Object Net::LDAP filter
|
@@ -30,12 +31,16 @@ module Adauth
|
|
30
31
|
|
31
32
|
# Returns all the objects which are members of this group
|
32
33
|
def members
|
33
|
-
Adauth.logger.info(self.inspect) { "Getting group members for #{self.name}" }
|
34
|
+
Adauth.logger.info(self.class.inspect) { "Getting group members for #{self.name}" }
|
34
35
|
unless @members
|
35
36
|
@members = convert_to_objects(cn_members)
|
36
37
|
end
|
37
38
|
@members
|
38
39
|
end
|
40
|
+
|
41
|
+
def cn_groups
|
42
|
+
memberof.split(/.*?CN=(.*?),.*/)
|
43
|
+
end
|
39
44
|
end
|
40
45
|
end
|
41
46
|
end
|
@@ -42,11 +42,11 @@ module Adauth
|
|
42
42
|
end
|
43
43
|
|
44
44
|
# Changes the password to the supplied value
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
45
|
+
def set_password(new_password)
|
46
|
+
Adauth.logger.info("password management") { "Attempting password reset for #{self.login}" }
|
47
|
+
password = microsoft_encode_password(new_password)
|
48
|
+
modify([[:replace, :unicodePwd, password]])
|
49
|
+
end
|
50
50
|
|
51
51
|
private
|
52
52
|
|
data/lib/adauth/authenticate.rb
CHANGED
@@ -7,16 +7,13 @@ module Adauth
|
|
7
7
|
Adauth.logger.info("authentication") { "Attempting to authenticate as #{username}" }
|
8
8
|
if Adauth::AdObjects::User.authenticate(username, password)
|
9
9
|
user = Adauth::AdObjects::User.where('sAMAccountName', username).first
|
10
|
-
if
|
10
|
+
if allowed_to_login(user)
|
11
11
|
Adauth.logger.info("authentication") { "Authentication succesful" }
|
12
12
|
return user
|
13
13
|
else
|
14
|
-
Adauth.logger.info("authentication") { "Authentication failed (not in allowed group)" }
|
14
|
+
Adauth.logger.info("authentication") { "Authentication failed (not in allowed group or ou)" }
|
15
15
|
return false
|
16
16
|
end
|
17
|
-
else
|
18
|
-
Adauth.logger.info("authentication") { "Authentication failed (bad username/password)" }
|
19
|
-
return false
|
20
17
|
end
|
21
18
|
rescue RuntimeError
|
22
19
|
Adauth.logger.info("authentication") { "Authentication failed (RuntimeError)" }
|
@@ -24,63 +21,16 @@ module Adauth
|
|
24
21
|
end
|
25
22
|
end
|
26
23
|
|
27
|
-
#
|
28
|
-
def self.
|
29
|
-
|
30
|
-
allowed = (user && @config.allowed_groups != (@config.allowed_groups - user.cn_groups)) ? user : nil
|
31
|
-
|
32
|
-
if allowed == nil
|
33
|
-
allowed = is_group_in_group(user) != nil ? user : nil
|
34
|
-
end
|
35
|
-
else
|
36
|
-
allowed = user
|
37
|
-
end
|
38
|
-
|
39
|
-
if @config.denied_groups != []
|
40
|
-
denied = (user && @config.denied_groups == (@config.denied_groups - user.cn_groups)) ? user : nil
|
41
|
-
else
|
42
|
-
denied = user
|
43
|
-
end
|
44
|
-
|
45
|
-
allowed == denied
|
24
|
+
# Check if the user is allowed to login
|
25
|
+
def self.allowed_to_login(user)
|
26
|
+
(allowed_from_arrays(@config.allowed_groups, @config.denied_groups, user.cn_groups_nested) && allowed_from_arrays(@config.allowed_ous, @config.denied_ous, user.dn_ous))
|
46
27
|
end
|
47
28
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
end
|
55
|
-
|
56
|
-
if @config.denied_ous != []
|
57
|
-
denied = (user && @config.denied_ous == (@config.denied_ous - user.dn_ous)) ? user : nil
|
58
|
-
else
|
59
|
-
denied = user
|
60
|
-
end
|
61
|
-
|
62
|
-
allowed == denied
|
63
|
-
end
|
64
|
-
|
65
|
-
def self.is_group_in_group(adobject)
|
66
|
-
# Loop through each users group and see if it's a member of an allowed group
|
67
|
-
begin
|
68
|
-
adobject.cn_groups.each do |group|
|
69
|
-
|
70
|
-
if @config.allowed_groups.include?(group)
|
71
|
-
return group
|
72
|
-
end
|
73
|
-
|
74
|
-
adGroup = Adauth::AdObjects::Group.where('name', group).first
|
75
|
-
|
76
|
-
unless self.is_group_in_group(adGroup) == nil
|
77
|
-
return true
|
78
|
-
end
|
79
|
-
end
|
80
|
-
rescue
|
81
|
-
return nil
|
29
|
+
private
|
30
|
+
|
31
|
+
def self.allowed_from_arrays(allowed, denied, test)
|
32
|
+
return true if allowed.empty? && denied.empty?
|
33
|
+
return true if !((allowed & test).empty?)
|
34
|
+
return false if !((denied & test).empty?)
|
82
35
|
end
|
83
|
-
|
84
|
-
nil
|
85
|
-
end
|
86
36
|
end
|
data/lib/adauth/config.rb
CHANGED
@@ -3,7 +3,7 @@ module Adauth
|
|
3
3
|
#
|
4
4
|
# Sets the defaults an create and generates guess values.
|
5
5
|
class Config
|
6
|
-
attr_accessor :domain, :port, :base, :server, :encryption, :query_user, :query_password,
|
6
|
+
attr_accessor :domain, :port, :base, :server, :encryption, :query_user, :query_password, :allow_fallback,
|
7
7
|
:allowed_groups, :denied_groups, :allowed_ous, :denied_ous, :contains_nested_groups
|
8
8
|
|
9
9
|
def initialize
|
@@ -12,6 +12,7 @@ module Adauth
|
|
12
12
|
@allowed_ous = []
|
13
13
|
@denied_groups =[]
|
14
14
|
@denied_ous = []
|
15
|
+
@allow_fallback = false
|
15
16
|
@contains_nested_groups = false
|
16
17
|
end
|
17
18
|
|
data/lib/adauth/connection.rb
CHANGED
@@ -32,6 +32,12 @@ module Adauth
|
|
32
32
|
}
|
33
33
|
rescue Timeout::Error
|
34
34
|
raise 'Unable to connect to LDAP Server'
|
35
|
+
rescue Errno::ECONNRESET
|
36
|
+
if @config[:allow_fallback]
|
37
|
+
@config[:port] = @config[:allow_fallback]
|
38
|
+
@config[:encryption] = false
|
39
|
+
return Adauth::Connection.new(@config).bind
|
40
|
+
end
|
35
41
|
end
|
36
42
|
end
|
37
43
|
end
|
data/lib/adauth/version.rb
CHANGED
data/rspec_results.txt
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
...................*...............
|
2
|
+
|
3
|
+
Pending:
|
4
|
+
Adauth::AdObjects::User should allow you to reset the password
|
5
|
+
# Insecure connection, unable to test change password
|
6
|
+
# ./spec/adauth_ad_object_user_spec.rb:49
|
7
|
+
|
8
|
+
Finished in 12.3 seconds
|
9
|
+
35 examples, 0 failures, 1 pending
|
10
|
+
Coverage report generated for RSpec to /Users/arcath/Code/Gems/Adauth/coverage. 472 / 489 LOC (96.52%) covered.
|
@@ -1,9 +1,14 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Adauth::AdObjects::Computer do
|
4
|
+
let(:computer) do
|
5
|
+
ou = Adauth::AdObjects::OU.where('name', 'Domain Controllers').first
|
6
|
+
ou.members.first
|
7
|
+
end
|
8
|
+
|
4
9
|
it "Should find a computer" do
|
5
10
|
default_config
|
6
|
-
|
11
|
+
computer.should be_a Adauth::AdObjects::Computer
|
7
12
|
end
|
8
13
|
|
9
14
|
it "should only find computers" do
|
@@ -15,8 +20,8 @@ describe Adauth::AdObjects::Computer do
|
|
15
20
|
|
16
21
|
it "should be in an ou" do
|
17
22
|
default_config
|
18
|
-
|
19
|
-
|
20
|
-
|
23
|
+
computer.ous.should be_a Array
|
24
|
+
computer.ous.first.should be_a Adauth::AdObjects::OU
|
25
|
+
computer.ous.first.name.should eq "Domain Controllers"
|
21
26
|
end
|
22
27
|
end
|
@@ -1,13 +1,17 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Adauth::AdObjects::Folder do
|
4
|
-
|
4
|
+
let(:root_folder) do
|
5
|
+
Adauth::AdObjects::Folder.root
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should find the root of the domain" do
|
5
9
|
default_config
|
6
|
-
|
10
|
+
root_folder.should be_a Adauth::AdObjects::Folder
|
7
11
|
end
|
8
12
|
|
9
13
|
it "should have members" do
|
10
14
|
default_config
|
11
|
-
|
15
|
+
root_folder.members.should be_a Array
|
12
16
|
end
|
13
17
|
end
|
@@ -1,21 +1,23 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Adauth::AdObjects::Group do
|
4
|
+
let(:domain_admins) do
|
5
|
+
Adauth::AdObjects::Group.where('name', 'Domain Admins').first
|
6
|
+
end
|
7
|
+
|
4
8
|
it "should have a name" do
|
5
9
|
default_config
|
6
|
-
|
7
|
-
group.name.should eq "Domain Admins"
|
10
|
+
domain_admins.name.should eq "Domain Admins"
|
8
11
|
end
|
9
12
|
|
10
13
|
it "should have a members list" do
|
11
14
|
default_config
|
12
|
-
|
13
|
-
|
15
|
+
domain_admins.members.should be_a Array
|
16
|
+
domain_admins.members.first.name.should be_a String
|
14
17
|
end
|
15
18
|
|
16
19
|
it "should be a member of" do
|
17
20
|
default_config
|
18
|
-
|
19
|
-
group.groups.should be_a Array
|
21
|
+
domain_admins.groups.should be_a Array
|
20
22
|
end
|
21
23
|
end
|
@@ -1,6 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Adauth::AdObjects::OU do
|
4
|
+
let(:domain_controllers) do
|
5
|
+
Adauth::AdObjects::OU.where('name', 'Domain Controllers').first
|
6
|
+
end
|
7
|
+
|
4
8
|
it "should find Domain Controllers" do
|
5
9
|
default_config
|
6
10
|
domain_controllers.should be_a Adauth::AdObjects::OU
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Adauth::AdObject do
|
4
|
+
let(:computer) do
|
5
|
+
ou = Adauth::AdObjects::OU.where('name', 'Domain Controllers').first
|
6
|
+
ou.members.first
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:user) do
|
10
|
+
Adauth::AdObjects::User.where('sAMAccountName', test_data("domain", "breakable_user")).first
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should still have method missing" do
|
14
|
+
default_config
|
15
|
+
computer.should be_a Adauth::AdObjects::Computer
|
16
|
+
lambda { computer.foo_bar }.should raise_exception NoMethodError
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should generate a nested group list" do
|
20
|
+
user.cn_groups.should_not eq user.cn_groups_nested
|
21
|
+
end
|
22
|
+
end
|
@@ -1,10 +1,13 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Adauth::AdObjects::User do
|
4
|
+
let(:user) do
|
5
|
+
Adauth::AdObjects::User.where('sAMAccountName', test_data("domain", "breakable_user")).first
|
6
|
+
end
|
7
|
+
|
4
8
|
it "should find administrator" do
|
5
9
|
default_config
|
6
|
-
user
|
7
|
-
user.login.should eq "Administrator"
|
10
|
+
user.login.should eq test_data("domain", "breakable_user")
|
8
11
|
end
|
9
12
|
|
10
13
|
it "should authenticate a user" do
|
@@ -14,40 +17,47 @@ describe Adauth::AdObjects::User do
|
|
14
17
|
|
15
18
|
it "should find groups" do
|
16
19
|
default_config
|
17
|
-
user = administrator
|
18
20
|
user.groups.should be_a Array
|
19
21
|
user.groups.first.should be_a Adauth::AdObjects::Group
|
20
22
|
end
|
21
23
|
|
22
|
-
it "should return
|
24
|
+
it "should return boolean for member_of" do
|
23
25
|
default_config
|
24
|
-
user
|
25
|
-
user.member_of?("Domain Admins").should be_true
|
26
|
+
user.member_of?("A Group").should be_false
|
26
27
|
end
|
27
28
|
|
28
29
|
it "should allow for modification" do
|
29
30
|
default_config
|
30
31
|
Adauth.add_field(Adauth::AdObjects::User, :phone, :homePhone)
|
31
|
-
number =
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
number = user.phone
|
33
|
+
user.modify([[:replace, :homephone, "8765"]])
|
34
|
+
new_user = Adauth::AdObjects::User.where('sAMAccountName', test_data("domain", "breakable_user")).first
|
35
|
+
new_user.phone.should eq "8765"
|
36
|
+
new_user.modify([[:replace, :homephone, number]])
|
37
|
+
new2_user = Adauth::AdObjects::User.where('sAMAccountName', test_data("domain", "breakable_user")).first
|
38
|
+
new2_user.phone.should eq number
|
35
39
|
end
|
36
40
|
|
37
41
|
it "should allow for additional methods" do
|
38
42
|
default_config
|
39
43
|
Adauth.add_field(Adauth::AdObjects::User, :description, :description)
|
40
44
|
administrator.description.should be_a String
|
45
|
+
Adauth.add_field(Adauth::AdObjects::User, :objectguid, :objectguid)
|
46
|
+
administrator.objectguid.should be_a String
|
41
47
|
end
|
42
48
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
49
|
+
it "should allow you to reset the password" do
|
50
|
+
default_config
|
51
|
+
begin
|
52
|
+
Adauth::AdObjects::User.authenticate(test_data("domain", "breakable_user"), test_data("domain", "breakable_password")).should be_true
|
53
|
+
user = Adauth::AdObjects::User.where('sAMAccountName', test_data("domain", "breakable_user")).first
|
54
|
+
user.login.should eq test_data("domain", "breakable_user")
|
55
|
+
user.set_password("adauth_test")
|
56
|
+
Adauth::AdObjects::User.authenticate(test_data("domain", "breakable_user"), "adauth_test").should be_true
|
57
|
+
user.set_password(test_data("domain", "breakable_password"))
|
58
|
+
Adauth::AdObjects::User.authenticate(test_data("domain", "breakable_user"), test_data("domain", "breakable_password")).should be_true
|
59
|
+
rescue RuntimeError
|
60
|
+
pending("Insecure connection, unable to test change password")
|
61
|
+
end
|
62
|
+
end
|
53
63
|
end
|
@@ -11,6 +11,32 @@ describe Adauth, "#authenticate" do
|
|
11
11
|
Adauth.authenticate(test_data("domain", "query_user"), "foo").should be_false
|
12
12
|
end
|
13
13
|
|
14
|
+
it "should allow the user if allowed groups are used" do
|
15
|
+
Adauth.configure do |c|
|
16
|
+
c.domain = test_data("domain", "domain")
|
17
|
+
c.port = test_data("domain", "port")
|
18
|
+
c.base = test_data("domain", "base")
|
19
|
+
c.server = test_data("domain", "server")
|
20
|
+
c.query_user = test_data("domain", "query_user")
|
21
|
+
c.query_password = test_data("domain", "query_password")
|
22
|
+
c.allowed_groups = ["Administrators"]
|
23
|
+
end
|
24
|
+
Adauth.authenticate(test_data("domain", "query_user"), test_data("domain", "query_password")).should be_a Adauth::AdObjects::User
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should allow the user if allowed ous are used" do
|
28
|
+
Adauth.configure do |c|
|
29
|
+
c.domain = test_data("domain", "domain")
|
30
|
+
c.port = test_data("domain", "port")
|
31
|
+
c.base = test_data("domain", "base")
|
32
|
+
c.server = test_data("domain", "server")
|
33
|
+
c.query_user = test_data("domain", "query_user")
|
34
|
+
c.query_password = test_data("domain", "query_password")
|
35
|
+
c.allowed_ous = ["Users"]
|
36
|
+
end
|
37
|
+
Adauth.authenticate(test_data("domain", "query_user"), test_data("domain", "query_password")).should be_a Adauth::AdObjects::User
|
38
|
+
end
|
39
|
+
|
14
40
|
it "should reject a user if denied group is used" do
|
15
41
|
Adauth.configure do |c|
|
16
42
|
c.domain = test_data("domain", "domain")
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Adauth::Connection do
|
4
|
+
it "should support encryption" do
|
5
|
+
Adauth.configure do |c|
|
6
|
+
c.domain = test_data("domain", "domain")
|
7
|
+
c.port = test_data("domain", "port")
|
8
|
+
c.base = test_data("domain", "base")
|
9
|
+
c.server = test_data("domain", "server")
|
10
|
+
c.encryption = :simple_tls
|
11
|
+
c.query_user = test_data("domain", "query_user")
|
12
|
+
c.query_password = test_data("domain", "query_password")
|
13
|
+
end
|
14
|
+
begin
|
15
|
+
Adauth.authenticate(test_data("domain", "query_user"), test_data("domain", "query_password"))
|
16
|
+
rescue
|
17
|
+
# Failed to authenticate due to encryption (not what we are testing here)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should timeout if asked to connect to a server that doesn't exist" do
|
22
|
+
Adauth.configure do |c|
|
23
|
+
c.domain = test_data("domain", "domain")
|
24
|
+
c.port = test_data("domain", "port")
|
25
|
+
c.base = test_data("domain", "base")
|
26
|
+
c.server = "127.0.0.2"
|
27
|
+
c.query_user = test_data("domain", "query_user")
|
28
|
+
c.query_password = test_data("domain", "query_password")
|
29
|
+
end
|
30
|
+
|
31
|
+
lambda { Adauth::AdObjects::User.all }.should raise_exception
|
32
|
+
end
|
33
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# Test coverage
|
2
|
+
require 'simplecov'
|
3
|
+
SimpleCov.start
|
4
|
+
|
5
|
+
# Requires
|
1
6
|
require 'adauth'
|
2
7
|
require 'yaml'
|
3
8
|
|
@@ -7,6 +12,8 @@ def default_config
|
|
7
12
|
c.port = test_data("domain", "port")
|
8
13
|
c.base = test_data("domain", "base")
|
9
14
|
c.server = test_data("domain", "server")
|
15
|
+
c.encryption = test_data("domain", "encryption").to_sym if test_data("domain", "encryption")
|
16
|
+
c.allow_fallback = test_data("domain", "allow_fallback") if test_data("domain", "allow_fallback")
|
10
17
|
c.query_user = test_data("domain", "query_user")
|
11
18
|
c.query_password = test_data("domain", "query_password")
|
12
19
|
end
|
@@ -21,14 +28,10 @@ def administrator
|
|
21
28
|
Adauth::AdObjects::User.where('sAMAccountName', "administrator").first
|
22
29
|
end
|
23
30
|
|
24
|
-
def
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
def domain_controllers
|
29
|
-
Adauth::AdObjects::OU.where('name', 'Domain Controllers').first
|
30
|
-
end
|
31
|
+
#def breakable_user
|
32
|
+
# Adauth::AdObjects::User.where('sAMAccountName', test_data("domain", "breakable_user")).first
|
33
|
+
#end
|
31
34
|
|
32
|
-
def
|
33
|
-
|
35
|
+
def query_user
|
36
|
+
Adauth::AdObjects::User.where('sAMAccountName', test_data("domain", "query_user")).first
|
34
37
|
end
|
data/spec/test_data.example.yml
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
domain:
|
2
2
|
domain: example.com
|
3
|
-
port: 389
|
3
|
+
port: 389 # Change to 636 for ssl encryption
|
4
|
+
#encryption: simple_tls
|
5
|
+
#allow_fallback: 389 # Used to fallback to insecure
|
4
6
|
base: "dc=example, dc=com"
|
5
7
|
server: dc1.example.com
|
6
8
|
query_user: User.Name
|
7
|
-
query_password: Password
|
9
|
+
query_password: Password
|
10
|
+
breakable_user: User.Name
|
11
|
+
breakable_password: Password
|
metadata
CHANGED
@@ -1,62 +1,83 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adauth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
5
|
-
prerelease:
|
4
|
+
version: 2.0.1
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Adam "Arcath" Laycock
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-07-14 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rake
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rspec
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: simplecov
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: yard
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
44
67
|
- !ruby/object:Gem::Version
|
45
68
|
version: '0'
|
46
69
|
- !ruby/object:Gem::Dependency
|
47
70
|
name: net-ldap
|
48
71
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
72
|
requirements:
|
51
|
-
- -
|
73
|
+
- - '>='
|
52
74
|
- !ruby/object:Gem::Version
|
53
75
|
version: '0'
|
54
76
|
type: :runtime
|
55
77
|
prerelease: false
|
56
78
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
79
|
requirements:
|
59
|
-
- -
|
80
|
+
- - '>='
|
60
81
|
- !ruby/object:Gem::Version
|
61
82
|
version: '0'
|
62
83
|
description: A full featured library for working with Microsofts Active Directory
|
@@ -71,6 +92,7 @@ files:
|
|
71
92
|
- .travis.yml
|
72
93
|
- Gemfile
|
73
94
|
- Gemfile.lock
|
95
|
+
- LICENSE.txt
|
74
96
|
- Rakefile
|
75
97
|
- Readme.md
|
76
98
|
- adauth.gemspec
|
@@ -96,49 +118,53 @@ files:
|
|
96
118
|
- lib/generators/adauth/sessions/sessions_generator.rb
|
97
119
|
- lib/generators/adauth/sessions/templates/new.html.erb
|
98
120
|
- lib/generators/adauth/sessions/templates/sessions_controller.rb.erb
|
121
|
+
- rspec_results.txt
|
99
122
|
- spec/adauth_ad_object_computer_spec.rb
|
100
123
|
- spec/adauth_ad_object_folder_spec.rb
|
101
124
|
- spec/adauth_ad_object_group_spec.rb
|
102
125
|
- spec/adauth_ad_object_ou_spec.rb
|
126
|
+
- spec/adauth_ad_object_spec.rb
|
103
127
|
- spec/adauth_ad_object_user_spec.rb
|
104
128
|
- spec/adauth_authenticate_spec.rb
|
105
129
|
- spec/adauth_config_spec.rb
|
130
|
+
- spec/adauth_connection_spec.rb
|
106
131
|
- spec/adauth_rails_model_bridge_spec.rb
|
107
132
|
- spec/adauth_spec.rb
|
108
133
|
- spec/spec_helper.rb
|
109
134
|
- spec/test_data.example.yml
|
110
135
|
homepage: http://adauth.arcath.net
|
111
136
|
licenses: []
|
137
|
+
metadata: {}
|
112
138
|
post_install_message:
|
113
139
|
rdoc_options: []
|
114
140
|
require_paths:
|
115
141
|
- lib
|
116
142
|
required_ruby_version: !ruby/object:Gem::Requirement
|
117
|
-
none: false
|
118
143
|
requirements:
|
119
|
-
- -
|
144
|
+
- - '>='
|
120
145
|
- !ruby/object:Gem::Version
|
121
146
|
version: '0'
|
122
147
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
|
-
none: false
|
124
148
|
requirements:
|
125
|
-
- -
|
149
|
+
- - '>='
|
126
150
|
- !ruby/object:Gem::Version
|
127
151
|
version: '0'
|
128
152
|
requirements: []
|
129
153
|
rubyforge_project:
|
130
|
-
rubygems_version:
|
154
|
+
rubygems_version: 2.0.0
|
131
155
|
signing_key:
|
132
|
-
specification_version:
|
156
|
+
specification_version: 4
|
133
157
|
summary: Provides Active Directory authentication for Rails
|
134
158
|
test_files:
|
135
159
|
- spec/adauth_ad_object_computer_spec.rb
|
136
160
|
- spec/adauth_ad_object_folder_spec.rb
|
137
161
|
- spec/adauth_ad_object_group_spec.rb
|
138
162
|
- spec/adauth_ad_object_ou_spec.rb
|
163
|
+
- spec/adauth_ad_object_spec.rb
|
139
164
|
- spec/adauth_ad_object_user_spec.rb
|
140
165
|
- spec/adauth_authenticate_spec.rb
|
141
166
|
- spec/adauth_config_spec.rb
|
167
|
+
- spec/adauth_connection_spec.rb
|
142
168
|
- spec/adauth_rails_model_bridge_spec.rb
|
143
169
|
- spec/adauth_spec.rb
|
144
170
|
- spec/spec_helper.rb
|