active_directory_login 0.0.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 63d211b6c19283ade2b7a91ecde8921897628c65
4
+ data.tar.gz: 86cbf612ecbe3cae984232fad88e0407b10b5ad2
5
+ SHA512:
6
+ metadata.gz: 3ef4e694e3546391df61ac16852e7648189e0f2673f40d336d9d8aed19ac89051560eff7c896436bcdeff9c2a16271d7c4e04b04be20bed1798aef31c997a536
7
+ data.tar.gz: f0a7c74005dbb3b6de2127611ba9013ddad988a788f5a16ae8ca3b1e0ce947dfa68525df1426e95cc1c2171029f191d6aa91d8acc48e7701923ab1664c4e839b
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+
19
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'datacom_active_directory'
6
+ gem 'datacom-net-ldap'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Brad Murray
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # ActiveDirectoryLogin
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'active_directory_login'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install active_directory_login
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'active_directory_login/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "active_directory_login"
8
+ spec.version = ActiveDirectoryLogin::VERSION
9
+ spec.authors = ["Brad Murray"]
10
+ spec.email = ["wyaeld@gmail.com"]
11
+ spec.description = "Devise based AD User Logins"
12
+ spec.summary = "Devise based AD User Logins"
13
+ spec.homepage = %q{http://github.com/datacom/active_directory_login}
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+
24
+ spec.add_development_dependency "rails", "~> 4.0"
25
+ spec.add_development_dependency "devise", "3.0.0"
26
+ spec.add_development_dependency "warden"
27
+
28
+ spec.add_development_dependency 'rspec', '~> 2.14'
29
+ spec.add_development_dependency 'rspec-rails', '~> 2.14'
30
+ spec.add_development_dependency 'flexmock'
31
+ spec.add_development_dependency 'pry'
32
+
33
+ spec.add_dependency "datacom_active_directory", '1.5.5.datacom'
34
+ spec.add_dependency "datacom-net-ldap", '0.5.0.datacom'
35
+ end
@@ -0,0 +1,54 @@
1
+ autoload 'Logger', 'logger'
2
+
3
+ require 'forwardable'
4
+ require "active_directory"
5
+ require "active_directory_login/client"
6
+
7
+
8
+ require 'warden'
9
+ require 'devise/strategies/authenticatable'
10
+ require 'devise/strategies/active_directory_authenticatable'
11
+
12
+ module ActiveDirectoryLogin
13
+
14
+ class Error < RuntimeError; end
15
+ class AuthenticationError < Error; end
16
+ class NoUserError < Error; end
17
+ class ConfigurationError < Error; end
18
+ class NoSearchKey < Error; end
19
+
20
+ class << self
21
+ extend Forwardable
22
+
23
+ def_delegators :default_client, :auth_method, :username, :password, :host, :port, :base, :auth
24
+ def_delegators :default_client, :auth_method=, :username=, :password=, :host=, :port=, :base=, :auth=
25
+
26
+ def_delegators :default_client, :staff_dn, :superuser_dn, :user_dn
27
+ def_delegators :default_client, :staff_dn=, :superuser_dn=, :user_dn=
28
+
29
+ def_delegators :default_client, :validate!, :sync_groups, :benched
30
+
31
+ def_delegators :default_client, :with_user, :lock_user, :authenticate_user, :has_member_access?, :create_or_update_user
32
+
33
+ #logger modelled on https://github.com/pusher/pusher-gem/blob/master/lib/pusher.rb
34
+ attr_writer :logger
35
+
36
+ def logger
37
+ @logger ||= begin
38
+ log = Logger.new($stdout)
39
+ log.level = Logger::INFO
40
+ log
41
+ end
42
+ end
43
+
44
+ def default_client
45
+ @default_client ||= ActiveDirectoryLogin::Client.new
46
+ end
47
+ end
48
+
49
+
50
+ end
51
+ require "active_directory_login/version"
52
+ require "active_directory_login/health_check"
53
+
54
+ Warden::Strategies.add(:active_directory_authenticatable, Devise::Strategies::ActiveDirectoryAuthenticatable)
@@ -0,0 +1,302 @@
1
+ require 'active_directory'
2
+ # require 'secure_random'
3
+
4
+ module ActiveDirectoryLogin
5
+ class Client
6
+
7
+ attr_accessor :host, :auth_method, :username, :password, :port, :base
8
+ attr_accessor :staff_dn, :superuser_dn, :user_dn
9
+ attr_reader :auth
10
+
11
+
12
+
13
+ def initialize(options = {})
14
+ options = {
15
+ auth_method: 'anonymous',
16
+ port: '389',
17
+ }.merge(options)
18
+ @host, @port, @base, @auth_method, @password, @username, @staff_dn, @superuser_dn, @user_dn = options.values_at(
19
+ :host, :port, :base, :auth_method, :password, :username, :staff_dn, :superuser_dn, :user_dn
20
+ )
21
+ end
22
+
23
+ def validate!
24
+ %W(
25
+ host
26
+ port
27
+ base
28
+ auth_method
29
+ username
30
+ password
31
+ staff_dn
32
+ superuser_dn
33
+ user_dn
34
+ ).each do |key|
35
+ # puts "KEY #{key} VALUE #{self.send(key)}"
36
+ raise ConfigurationError if self.send(key).nil?
37
+ end
38
+ true
39
+ end
40
+
41
+ def settings
42
+ {
43
+ host: host,
44
+ port: port,
45
+ base: base,
46
+ auth: {
47
+ method: auth_method.to_sym,
48
+ username: username,
49
+ password: password
50
+ }
51
+ }
52
+
53
+ end
54
+
55
+ def ensure_connection
56
+ if !ActiveDirectory::Base.connected?
57
+ validate!
58
+ ActiveDirectory::Base.setup(settings)
59
+ # ActiveDirectory::Base.enable_cache
60
+ end
61
+ end
62
+
63
+ def with_user(username_or_email, password, &block)
64
+ raise Error, "block required" if block.nil?
65
+
66
+ @ad_user = find_user(username_or_email)
67
+ @ad_user_password = password
68
+ @query = query(username_or_email)
69
+ @app_user = @query.first
70
+
71
+ value = block.call
72
+
73
+ reset_ivars
74
+
75
+ return value
76
+ end
77
+
78
+ def reset_ivars
79
+ @ad_user = nil
80
+ @app_user = nil
81
+ @query = nil
82
+ @groups = nil
83
+ @ad_user_password = nil
84
+ end
85
+
86
+ def lock_user
87
+ raise NoUserError, "need to call inside a .with_user block" if @ad_user.nil?
88
+ @app_user.try(:lock_access!) #its ok if no user
89
+ end
90
+
91
+ def authenticate_user
92
+ raise NoUserError, "need to call inside a .with_user block" if @ad_user.nil?
93
+ @ad_user.try(:authenticate, @ad_user_password)
94
+ end
95
+
96
+ def query(username_or_email)
97
+ @query ||= (username_or_email =~ /@/) ?
98
+ User.where { (provider == User::LDAP) & (email =~ username_or_email) } :
99
+ User.where { (provider == User::LDAP) & (username =~ username_or_email) }
100
+ end
101
+
102
+ def create_or_update_user
103
+
104
+ user = @query.first_or_initialize(
105
+ name: "#{@ad_user.givenname} #{@ad_user.sn}",
106
+ email: @ad_user.mail.downcase,
107
+ username: @ad_user[:sAMAccountName]
108
+ )
109
+
110
+ # Update the user's password and permissions (can't use update_attributes as it might not be saved yet)
111
+ user.password = @ad_user_password
112
+ user.password_confirmation = @ad_user_password
113
+
114
+ user.staff = staff_access?
115
+ user.superuser = superuser_access?
116
+ user.locked_at = nil # unlock_access! saves without validating so no good
117
+ user.save! # only saves if changed or new
118
+
119
+ return user
120
+ end
121
+
122
+
123
+
124
+ def find_user username_or_email
125
+ ensure_connection
126
+ raise NoSearchKey unless username_or_email && !username_or_email.empty?
127
+
128
+ ad_key = (username_or_email =~ /@/) ? :mail : :sAMAccountName
129
+ ad_user = ActiveDirectory::User.find(:first, ad_key => username_or_email)
130
+ end
131
+
132
+
133
+ def find_group group_dn
134
+ ensure_connection
135
+ raise NoSearchKey unless group_dn && !group_dn.empty?
136
+
137
+ ActiveDirectory::Group.find(:first, distinguishedname: group_dn)
138
+ end
139
+
140
+ # def groups
141
+ # @staff_group ||= ActiveDirectory::Group.find(:first, distinguishedname: staff_dn)
142
+ # @superuser_group ||= ActiveDirectory::Group.find(:first, distinguishedname: superuser_dn)
143
+ # @user_group ||= ActiveDirectory::Group.find(:first, distinguishedname: user_dn)
144
+ # [@staff_group, @superuser_group, @user_group]
145
+ # end
146
+
147
+
148
+ def has_member_access?
149
+ raise NoUserError, "need to call inside a .with_user block" if @ad_user.nil?
150
+ staff_access? || superuser_access? || user_access?
151
+ end
152
+
153
+ def sync_all
154
+ [staff_dn, superuser_dn, user_dn].each do |dn|
155
+ sync_group(dn)
156
+ end
157
+ end
158
+
159
+ def benched
160
+ bench = Benchmark.realtime{ Devise.stretches = 2; sync_groups }
161
+ ActiveDirectoryLogin.logger.info "Benchmark"
162
+ ActiveDirectoryLogin.logger.info bench
163
+ end
164
+
165
+ def sync_groups
166
+ ensure_connection
167
+
168
+ ActiveRecord::Base.transaction do
169
+
170
+ # update staff
171
+ staff_group = find_group(staff_dn)
172
+ staff_member_emails = staff_group.member.collect(&:mail).map(&:downcase)
173
+
174
+ allowed = User.where(email: staff_member_emails, staff: false)
175
+ staff_allowed_emails = allowed.collect(&:email)
176
+ allowed.update_all(staff: true)
177
+ pending = staff_member_emails - staff_allowed_emails
178
+
179
+ disallowed = User.where.not(email: staff_member_emails).where(staff: true)
180
+ staff_disallowed_emails = disallowed.collect(&:email)
181
+ disallowed.update_all(staff: false)
182
+ pending = pending - staff_disallowed_emails
183
+
184
+ staff_unchanged = User.where(email: staff_member_emails, staff: true)
185
+ staff_unchanged_emails = staff_unchanged.collect(&:email)
186
+ pending = pending - staff_unchanged_emails
187
+
188
+ # create any new staff
189
+ pending.each do |pending_email|
190
+ with_user(pending_email, SecureRandom.hex){ create_or_update_user }
191
+ end
192
+ staff_created_emails = pending
193
+
194
+
195
+ ## update superuser
196
+ superuser_group = find_group(superuser_dn)
197
+ superuser_member_emails = superuser_group.member.collect(&:mail).map(&:downcase)
198
+ superuser_member_emails = superuser_member_emails - staff_member_emails
199
+
200
+ allowed = User.where(email: superuser_member_emails, superuser: false)
201
+ superuser_allowed_emails = allowed.collect(&:email)
202
+ allowed.update_all(superuser: true)
203
+ pending = superuser_member_emails - superuser_allowed_emails
204
+
205
+ disallowed = User.where.not(email: superuser_member_emails).where(superuser: true)
206
+ superuser_disallowed_emails = disallowed.collect(&:email)
207
+ disallowed.update_all(superuser: false)
208
+ pending = pending - superuser_disallowed_emails
209
+
210
+ superuser_unchanged = User.where(email: superuser_member_emails, superuser: true)
211
+ superuser_unchanged_emails = superuser_unchanged.collect(&:email)
212
+ pending = pending - superuser_unchanged_emails
213
+
214
+ # create any new superuser
215
+ pending.each do |pending_email|
216
+ with_user(pending_email, SecureRandom.hex){ create_or_update_user }
217
+ end
218
+ superuser_created_emails = pending
219
+
220
+
221
+
222
+
223
+ ## update users
224
+ user_group = find_group(user_dn)
225
+ # member_cns = user_group.entry[:member]
226
+
227
+ member_emails = user_group.member.collect(&:mail).map(&:downcase)
228
+ member_emails = member_emails - superuser_member_emails - staff_member_emails
229
+
230
+ allowed = User.where(email: member_emails, staff: false, superuser: false).where.not(locked_at: nil)
231
+ user_allowed_emails = allowed.collect(&:email)
232
+ allowed.update_all(locked_at: nil)
233
+ pending = member_emails - user_allowed_emails
234
+
235
+ disallowed = User.where.not(email: member_emails, staff: false, superuser: false)
236
+ user_disallowed_emails = disallowed.collect(&:email)
237
+ disallowed.each {|u| u.lock_access! }
238
+
239
+ user_unchanged = User.where(email: member_emails, staff: false, superuser: false)
240
+ user_unchanged_emails = user_unchanged.collect(&:email)
241
+ pending = pending - user_unchanged_emails
242
+
243
+ # binding.pry
244
+
245
+ #create any new superuser
246
+ pending.each do |pending_email|
247
+ with_user(pending_email, SecureRandom.hex){ create_or_update_user }
248
+ end
249
+ user_created_emails = pending
250
+
251
+ #report on changes
252
+ ActiveDirectoryLogin.logger.info "Staff allowed: #{staff_allowed_emails}"
253
+ ActiveDirectoryLogin.logger.info "Staff disallowed: #{staff_disallowed_emails}"
254
+ ActiveDirectoryLogin.logger.info "Staff created: #{staff_created_emails}"
255
+ ActiveDirectoryLogin.logger.info "Staff unchanged: #{staff_unchanged_emails}"
256
+
257
+ ActiveDirectoryLogin.logger.info "Superusers allowed: #{superuser_allowed_emails}"
258
+ ActiveDirectoryLogin.logger.info "Superusers disallowed: #{superuser_disallowed_emails}"
259
+ ActiveDirectoryLogin.logger.info "Superusers created: #{superuser_created_emails}"
260
+ ActiveDirectoryLogin.logger.info "Superusers unchanged: #{superuser_unchanged_emails}"
261
+
262
+ ActiveDirectoryLogin.logger.info "User allowed: #{user_allowed_emails}"
263
+ ActiveDirectoryLogin.logger.info "User disallowed: #{user_disallowed_emails}"
264
+ ActiveDirectoryLogin.logger.info "User created: #{user_created_emails}"
265
+ ActiveDirectoryLogin.logger.info "User unchanged: #{user_unchanged_emails}"
266
+
267
+
268
+
269
+ end
270
+
271
+
272
+
273
+ ActiveDirectoryLogin.logger.info "Staff: #{User.staff.count}"
274
+ ActiveDirectoryLogin.logger.info "Superusers: #{User.superusers.count}"
275
+ ActiveDirectoryLogin.logger.info "Users: #{User.normals.count}"
276
+
277
+ end
278
+
279
+ private
280
+
281
+
282
+ def group_names
283
+ @groups ||= @ad_user.entry[:memberof]
284
+ end
285
+
286
+ def staff_access?
287
+ group_names.include? staff_dn
288
+ end
289
+
290
+ def superuser_access?
291
+ group_names.include? superuser_dn
292
+ end
293
+
294
+ def user_access?
295
+ group_names.include? user_dn
296
+ end
297
+
298
+
299
+
300
+
301
+ end #class
302
+ end
@@ -0,0 +1,41 @@
1
+ module ActiveDirectoryLogin
2
+ class GroupResource
3
+
4
+ def initialize(client)
5
+ @client = client
6
+
7
+ end
8
+
9
+ def self.find group_name
10
+ ActiveDirectory::Group.find(:first, distinguishedname: group_name)
11
+ end
12
+
13
+ def self.member_names group
14
+ group.member.map &:name
15
+ end
16
+
17
+ def self.member_emails group
18
+ group.member.map &:mail
19
+ end
20
+
21
+ def self.has_group_access? groups
22
+ staff = staff_group? groups
23
+ system = system_group? groups
24
+ general = general_group? groups
25
+ staff || system || general
26
+ end
27
+
28
+ def self.staff_group? groups
29
+ groups.include? ENV['DG_STAFF_DN']
30
+ end
31
+
32
+ def self.system_group? groups
33
+ groups.include? ENV['DG_SYSTEM_DN']
34
+ end
35
+
36
+ def self.general_group? groups
37
+ groups.include? ENV['DG_USER_DN']
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,37 @@
1
+ module ActiveDirectoryLogin
2
+ module HealthCheck
3
+ def self.valid_config?
4
+ ActiveDirectoryLogin.default_client.validate!
5
+ end
6
+
7
+ def self.health_check_errors
8
+ # We use these twice
9
+ output = []
10
+
11
+ begin
12
+ ActiveDirectoryLogin.default_client.ensure_connection
13
+ rescue => e
14
+ output << "LDAP: Connecting: #{e.message}"
15
+ end
16
+
17
+ begin
18
+ ActiveDirectoryLogin.default_client.ensure_connection
19
+ rescue => e
20
+ output << "LDAP: Authorizing: #{e.message}" unless output.include?("LDAP: Connecting: #{e.message}")
21
+ end
22
+ output << "LDAP: Authorizing: #{ActiveDirectory::Base.error}" if ActiveDirectory::Base.error?
23
+
24
+ begin
25
+ ActiveDirectory::Group.find(:first, distinguishedname: ActiveDirectoryLogin.user_dn)
26
+ rescue
27
+ output << 'LDAP: Searching failed; check base and authorisation config'
28
+ end
29
+
30
+ output.to_sentence
31
+ end
32
+
33
+ def self.healthy?
34
+ health_check_errors.empty?
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,3 @@
1
+ module ActiveDirectoryLogin
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,35 @@
1
+ require 'devise/strategies/authenticatable'
2
+ require 'pry'
3
+
4
+ module Devise
5
+ module Strategies
6
+ class ActiveDirectoryAuthenticatable < Authenticatable
7
+
8
+ def authenticate!
9
+ #FIXME enterprise mode was here
10
+ if params[:user]
11
+
12
+ username_or_email = params[:user][:login]
13
+
14
+ ActiveDirectoryLogin.with_user(username_or_email, params[:user][:password]) do
15
+
16
+ if ActiveDirectoryLogin.authenticate_user
17
+ if ActiveDirectoryLogin.has_member_access?
18
+ user = ActiveDirectoryLogin.create_or_update_user
19
+ success!(user)
20
+ else
21
+ ActiveDirectoryLogin.lock_user
22
+ fail(:locked)
23
+ end
24
+ else
25
+ fail(:invalid)
26
+ end
27
+
28
+ end #with_user
29
+
30
+ end
31
+ end
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+ require 'active_directory_login'
3
+ require 'active_directory_login/group_resource'
4
+ require 'active_directory_login/user_resource'
5
+ require 'devise/strategies/authenticatable'
6
+ require 'devise'
7
+ describe ActiveDirectoryLogin do
8
+
9
+ before do
10
+ @client = ActiveDirectoryLogin::Client.new({
11
+ auth_method: 'simple',
12
+ username: 'svcdgauth',
13
+ password: 'Friday10',
14
+ host: 'dnzdc3.datacom.co.nz',
15
+ port: '389',
16
+ base: 'DC=datacom,DC=co,DC=nz'
17
+ })
18
+ @client.connect!
19
+ @user_resource = ActiveDirectoryLogin::UserResource
20
+ @group_resource = ActiveDirectoryLogin::GroupResource
21
+
22
+ end
23
+
24
+ let(:staff_group) {"CN=DocGenie-Staff,OU=Datacom Systems Wellington,OU=Datacom Systems,OU=Groups - Universal Distribution Lists,DC=datacom,DC=co,DC=nz"}
25
+
26
+ describe '.user' do
27
+
28
+ it 'requires a value' do
29
+ expect { @user_resource.find nil
30
+ }.to raise_error ActiveDirectoryLogin::NoSearchKey
31
+ end
32
+
33
+ it 'requires a value' do
34
+ expect { @user_resource.find ''
35
+ }.to raise_error ActiveDirectoryLogin::NoSearchKey
36
+ end
37
+
38
+ end
39
+
40
+ it 'finds me by username' do
41
+ login = 'bradmu'
42
+ user = @user_resource.find login
43
+ user[:cn].should == "Brad Murray [DATACOM]"
44
+ end
45
+
46
+ it 'finds me by email' do
47
+ login = 'brad.murray@datacom.co.nz'
48
+ user = @user_resource.find login
49
+ user[:cn].should == "Brad Murray [DATACOM]"
50
+ end
51
+
52
+
53
+ it 'finds me by email' do
54
+ login = 'brad.murray@datacom.co.nz'
55
+ user = @user_resource.find login
56
+ user[:cn].should == "Brad Murray [DATACOM]"
57
+ end
58
+
59
+ it 'finds DocGenie staff group' do
60
+ group = @group_resource.find staff_group
61
+ group.name.should == "DocGenie-Staff"
62
+ end
63
+
64
+ it 'can get members of DocGenie staff group' do
65
+ group = @group_resource.find staff_group
66
+ group.member.count.should == 5
67
+ @group_resource.member_names(group).should == ["Patrick Copeland [DATACOM]",
68
+ "Owen Bannister [DATACOM]",
69
+ "Tatyana Kudiyarova [DATACOM]",
70
+ "Brad Murray [DATACOM]",
71
+ "Blair Nilsson [DATACOM]"]
72
+ end
73
+
74
+ it 'can find user groups' do
75
+ login = 'owen.bannister@datacom.co.nz'
76
+ user = @user_resource.find login
77
+ groups = @user_resource.groups user
78
+ groups.count.should > 0
79
+ groups.include?(staff_group).should == true
80
+ end
81
+
82
+ # let(:User) { stub 'User'}
83
+ it 'can validate me by my groups' do
84
+ login = 'owen.bannister@datacom.co.nz'
85
+ user = @user_resource.find login
86
+
87
+ permission = @group_resource.has_group_access? @user_resource.groups(user)
88
+ permission.should == false
89
+
90
+ ENV['DG_STAFF_DN'] = staff_group
91
+ permission = @group_resource.has_group_access? @user_resource.groups(user)
92
+ permission.should == true
93
+ end
94
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+ require 'active_directory_login/client'
3
+
4
+ describe ActiveDirectoryLogin::Client do
5
+
6
+ def valid_options
7
+ options = {}
8
+ options[:auth_method] = 'simple'
9
+ options[:username] = 'foo'
10
+ options[:password] = 'bar'
11
+ options[:host] = 'ldap.example.com'
12
+ options[:port] = '633'
13
+ options[:base] = 'DC=example,DC=com'
14
+ options
15
+ end
16
+
17
+
18
+ describe 'initialize' do
19
+
20
+ subject { ActiveDirectoryLogin::Client.new options}
21
+
22
+ describe 'with defaults' do
23
+ let(:options) { Hash.new }
24
+
25
+ its(:host) { should == nil}
26
+ its(:port) { should == '389'}
27
+ its(:base) { should == nil}
28
+ its(:username) { should == nil }
29
+ its(:password) { should == nil}
30
+ its(:auth_method) { should == 'anonymous'}
31
+ end
32
+
33
+ describe 'with values' do
34
+ let(:options) { valid_options }
35
+
36
+ its(:host) { should == 'ldap.example.com'}
37
+ its(:port) { should == '633'}
38
+ its(:base) { should == 'DC=example,DC=com'}
39
+ its(:username) { should == 'foo'}
40
+ its(:password) { should == 'bar'}
41
+ its(:auth_method) { should == 'simple'}
42
+
43
+ end
44
+
45
+ end
46
+
47
+
48
+
49
+
50
+
51
+
52
+ end
@@ -0,0 +1,23 @@
1
+ # require 'active_model/naming'
2
+ # require 'active_model/model'
3
+ require 'active_model'
4
+ class User
5
+ include ActiveModel::Model
6
+
7
+ # after_initialize :defaults
8
+
9
+ # def defaults
10
+ # binding.pry
11
+ # end
12
+
13
+ # def init(args)
14
+ # args.each_pair do |k,v|
15
+ # self[k] = v
16
+ # end
17
+ # end
18
+
19
+ attr_accessor :name, :email, :staff
20
+
21
+ alias_method :staff?, :staff
22
+
23
+ end
@@ -0,0 +1,27 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'although not required, it is recommended that you use bundler when running the tests'
5
+ end
6
+
7
+
8
+
9
+ require 'rails'
10
+ require 'rspec'
11
+ # require 'rspec/rails'
12
+ require 'rspec/autorun'
13
+ # require 'flexmock/rspec/configure'
14
+
15
+ require 'pry'
16
+
17
+
18
+ unless Object.const_defined? 'User'
19
+ # binding.pry
20
+ require 'models/user'
21
+ # mock_model 'User'
22
+ end
23
+
24
+ RSpec.configure do |config|
25
+
26
+ # co
27
+ end
metadata ADDED
@@ -0,0 +1,218 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: active_directory_login
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Brad Murray
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rails
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '4.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '4.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: devise
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 3.0.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: 3.0.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: warden
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '2.14'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '2.14'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec-rails
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '2.14'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: '2.14'
111
+ - !ruby/object:Gem::Dependency
112
+ name: flexmock
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: pry
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: datacom_active_directory
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - '='
144
+ - !ruby/object:Gem::Version
145
+ version: 1.5.5.datacom
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - '='
151
+ - !ruby/object:Gem::Version
152
+ version: 1.5.5.datacom
153
+ - !ruby/object:Gem::Dependency
154
+ name: datacom-net-ldap
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - '='
158
+ - !ruby/object:Gem::Version
159
+ version: 0.5.0.datacom
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - '='
165
+ - !ruby/object:Gem::Version
166
+ version: 0.5.0.datacom
167
+ description: Devise based AD User Logins
168
+ email:
169
+ - wyaeld@gmail.com
170
+ executables: []
171
+ extensions: []
172
+ extra_rdoc_files: []
173
+ files:
174
+ - .gitignore
175
+ - Gemfile
176
+ - LICENSE.txt
177
+ - README.md
178
+ - Rakefile
179
+ - active_directory_login.gemspec
180
+ - lib/active_directory_login.rb
181
+ - lib/active_directory_login/client.rb
182
+ - lib/active_directory_login/group_resource.rb
183
+ - lib/active_directory_login/health_check.rb
184
+ - lib/active_directory_login/version.rb
185
+ - lib/devise/strategies/active_directory_authenticatable.rb
186
+ - spec/active_directory_login_spec.rb
187
+ - spec/client_spec.rb
188
+ - spec/models/user.rb
189
+ - spec/spec_helper.rb
190
+ homepage: http://github.com/datacom/active_directory_login
191
+ licenses:
192
+ - MIT
193
+ metadata: {}
194
+ post_install_message:
195
+ rdoc_options: []
196
+ require_paths:
197
+ - lib
198
+ required_ruby_version: !ruby/object:Gem::Requirement
199
+ requirements:
200
+ - - '>='
201
+ - !ruby/object:Gem::Version
202
+ version: '0'
203
+ required_rubygems_version: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - '>='
206
+ - !ruby/object:Gem::Version
207
+ version: '0'
208
+ requirements: []
209
+ rubyforge_project:
210
+ rubygems_version: 2.2.2
211
+ signing_key:
212
+ specification_version: 4
213
+ summary: Devise based AD User Logins
214
+ test_files:
215
+ - spec/active_directory_login_spec.rb
216
+ - spec/client_spec.rb
217
+ - spec/models/user.rb
218
+ - spec/spec_helper.rb