active_directory 1.1.1 → 1.2.0
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/VERSION +1 -1
- data/active_directory.gemspec +1 -3
- data/lib/active_directory.rb +13 -10
- data/lib/active_directory/base.rb +13 -9
- data/lib/active_directory/field_type/binary.rb +2 -2
- data/lib/active_directory/field_type/password.rb +16 -14
- data/lib/active_directory/user.rb +1 -1
- metadata +4 -6
- data/lib/active_directory/rails/synchronizer.rb +0 -234
- data/lib/active_directory/rails/user.rb +0 -141
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.2.0
|
data/active_directory.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{active_directory}
|
8
|
-
s.version = "1.
|
8
|
+
s.version = "1.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Adam T Kerr"]
|
@@ -31,8 +31,6 @@ Gem::Specification.new do |s|
|
|
31
31
|
"lib/active_directory/field_type/timestamp.rb",
|
32
32
|
"lib/active_directory/group.rb",
|
33
33
|
"lib/active_directory/member.rb",
|
34
|
-
"lib/active_directory/rails/synchronizer.rb",
|
35
|
-
"lib/active_directory/rails/user.rb",
|
36
34
|
"lib/active_directory/user.rb"
|
37
35
|
]
|
38
36
|
s.homepage = %q{http://github.com/ajrkerr/active_directory}
|
data/lib/active_directory.rb
CHANGED
@@ -45,24 +45,27 @@ module ActiveDirectory
|
|
45
45
|
|
46
46
|
#All objects in the AD
|
47
47
|
:Base => {
|
48
|
-
:
|
49
|
-
:
|
50
|
-
:
|
48
|
+
:objectguid => :binary,
|
49
|
+
:whencreated => :date,
|
50
|
+
:whenchanged => :date
|
51
51
|
},
|
52
52
|
|
53
53
|
#User objects
|
54
54
|
:User => {
|
55
|
-
:
|
56
|
-
:
|
57
|
-
:
|
58
|
-
:
|
59
|
-
:
|
60
|
-
:
|
55
|
+
:objectguid => :binary,
|
56
|
+
:whencreated => :date,
|
57
|
+
:whenchanged => :date,
|
58
|
+
:objectsid => :binary,
|
59
|
+
:msexchmailboxguid => :binary,
|
60
|
+
:msexchmailboxsecuritydescriptor => :binary,
|
61
|
+
:lastlogontimestamp => :timestamp,
|
62
|
+
:pwdlastset => :timestamp,
|
63
|
+
:accountexpires => :timestamp
|
61
64
|
},
|
62
65
|
|
63
66
|
#Group objects
|
64
67
|
:Group => {
|
65
|
-
:
|
68
|
+
:objectsid => :binary,
|
66
69
|
},
|
67
70
|
}
|
68
71
|
end
|
@@ -399,24 +399,26 @@ module ActiveDirectory
|
|
399
399
|
end
|
400
400
|
|
401
401
|
def get_field_type(name)
|
402
|
-
|
403
|
-
|
402
|
+
#Extract class name
|
403
|
+
klass = self.class.name[/.*::(.*)/, 1]
|
404
|
+
::Rails.logger.add 0, "special_fields[#{klass.classify.to_sym}][#{name.downcase.to_sym}] = #{::ActiveDirectory.special_fields[klass.classify.to_sym][name.downcase.to_sym]}"
|
405
|
+
type = ::ActiveDirectory.special_fields[klass.classify.to_sym][name.downcase.to_sym]
|
406
|
+
type.to_s.classify unless type.nil?
|
404
407
|
end
|
405
408
|
|
406
409
|
def decode_field(name, value)
|
407
|
-
|
408
|
-
::Rails.logger.add 0, "Encoding #{name}, #{value}"
|
410
|
+
::Rails.logger.add 0, "Decoding #{name}, #{value}"
|
409
411
|
type = get_field_type name
|
410
|
-
|
412
|
+
::Rails.logger.add 0, "Type: #{type} Const: #{::ActiveDirectory::FieldType::const_get type unless type.nil?}"
|
413
|
+
return ::ActiveDirectory::FieldType::const_get(type).decode(value) if !type.nil? and ::ActiveDirectory::FieldType::const_defined? type
|
411
414
|
return value
|
412
415
|
end
|
413
416
|
|
414
417
|
def encode_field(name, value)
|
415
|
-
|
416
|
-
::Rails.logger.add 0, "Encoding #{first}, #{name}, #{value}"
|
418
|
+
::Rails.logger.add 0, "Encoding #{name}, #{value}"
|
417
419
|
type = get_field_type name
|
418
|
-
|
419
|
-
return ::ActiveDirectory::const_get(type).encode(value) if ::ActiveDirectory::const_defined? type
|
420
|
+
::Rails.logger.add 0, "Type: #{type} Const: #{::ActiveDirectory::FieldType::const_get type}"
|
421
|
+
return ::ActiveDirectory::FieldType::const_get(type).encode(value) if ::ActiveDirectory::FieldType::const_defined? type
|
420
422
|
return value
|
421
423
|
end
|
422
424
|
|
@@ -435,6 +437,8 @@ module ActiveDirectory
|
|
435
437
|
value = @entry.send(name.to_sym)
|
436
438
|
value = value.first if value.kind_of?(Array) && value.size == 1
|
437
439
|
value = value.to_s if value.nil? || value.size == 1
|
440
|
+
::Rails.logger.add 0, "Decoded as #{decode_field(name, value)}\n"
|
441
|
+
::Rails.logger.add 0, ""
|
438
442
|
return decode_field(name, value)
|
439
443
|
# rescue NoMethodError => e
|
440
444
|
# ::Rails.logger.add 0, "#{e.inspect}"
|
@@ -23,7 +23,7 @@
|
|
23
23
|
|
24
24
|
module ActiveDirectory
|
25
25
|
module FieldType
|
26
|
-
class
|
26
|
+
class Binary
|
27
27
|
#
|
28
28
|
# Encodes a hex string into a GUID
|
29
29
|
#
|
@@ -35,7 +35,7 @@ module ActiveDirectory
|
|
35
35
|
# Decodes a binary GUID as a hex string
|
36
36
|
#
|
37
37
|
def self.decode(guid)
|
38
|
-
guid.unpack("H*")
|
38
|
+
guid.unpack("H*").to_s
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
@@ -22,21 +22,23 @@
|
|
22
22
|
#++ license
|
23
23
|
|
24
24
|
module ActiveDirectory
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
(
|
32
|
-
|
25
|
+
module FieldType
|
26
|
+
class Password
|
27
|
+
#
|
28
|
+
# Encodes an unencrypted password into an encrypted password
|
29
|
+
# that the Active Directory server will understand.
|
30
|
+
#
|
31
|
+
def self.encode(password)
|
32
|
+
("\"#{password}\"".split(//).collect { |c| "#{c}\000" }).join
|
33
|
+
end
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
35
|
+
#
|
36
|
+
# Always returns nil, since you can't decrypt the User's encrypted
|
37
|
+
# password.
|
38
|
+
#
|
39
|
+
def self.decode(hashed)
|
40
|
+
nil
|
41
|
+
end
|
40
42
|
end
|
41
43
|
end
|
42
44
|
end
|
@@ -138,7 +138,7 @@ module ActiveDirectory
|
|
138
138
|
:dn => distinguishedName,
|
139
139
|
:operations => [
|
140
140
|
[ :replace, :lockoutTime, [ '0' ] ],
|
141
|
-
[ :replace, :unicodePwd, [ Password.encode(new_password) ] ],
|
141
|
+
[ :replace, :unicodePwd, [ FieldType::Password.encode(new_password) ] ],
|
142
142
|
[ :replace, :userAccountControl, [ UAC_NORMAL_ACCOUNT.to_s ] ],
|
143
143
|
[ :replace, :pwdLastSet, [ (force_change ? '0' : '-1') ] ]
|
144
144
|
]
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_directory
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 1.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 1.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Adam T Kerr
|
@@ -58,8 +58,6 @@ files:
|
|
58
58
|
- lib/active_directory/field_type/timestamp.rb
|
59
59
|
- lib/active_directory/group.rb
|
60
60
|
- lib/active_directory/member.rb
|
61
|
-
- lib/active_directory/rails/synchronizer.rb
|
62
|
-
- lib/active_directory/rails/user.rb
|
63
61
|
- lib/active_directory/user.rb
|
64
62
|
has_rdoc: true
|
65
63
|
homepage: http://github.com/ajrkerr/active_directory
|
@@ -1,234 +0,0 @@
|
|
1
|
-
#-- license
|
2
|
-
#
|
3
|
-
# This file is part of the Ruby Active Directory Project
|
4
|
-
# on the web at http://rubyforge.org/projects/activedirectory
|
5
|
-
#
|
6
|
-
# Copyright (c) 2008, James Hunt <filefrog@gmail.com>
|
7
|
-
# based on original code by Justin Mecham
|
8
|
-
#
|
9
|
-
# This program is free software: you can redistribute it and/or modify
|
10
|
-
# it under the terms of the GNU General Public License as published by
|
11
|
-
# the Free Software Foundation, either version 3 of the License, or
|
12
|
-
# (at your option) any later version.
|
13
|
-
#
|
14
|
-
# This program is distributed in the hope that it will be useful,
|
15
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
-
# GNU General Public License for more details.
|
18
|
-
#
|
19
|
-
# You should have received a copy of the GNU General Public License
|
20
|
-
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
21
|
-
#
|
22
|
-
#++ license
|
23
|
-
|
24
|
-
# UserSynchronizer is a utility class that encapsulates dealings
|
25
|
-
# with the Active Directory backend. It is primarily responsible for
|
26
|
-
# updating Active Directory people in the local database from the
|
27
|
-
# Active Directory store. In this fashion, name changes, email address
|
28
|
-
# changes and such are all handled invisibly.
|
29
|
-
#
|
30
|
-
# UserSynchronizer is also responsible for disabling people who are no
|
31
|
-
# longer in the Sales Tracker group, and creating people who are in the group,
|
32
|
-
# but not in the local database. This gives us another administrative
|
33
|
-
# convenience, since new hires will be added to the system with some
|
34
|
-
# regularity, and terminations are eventually cleaned out.
|
35
|
-
#
|
36
|
-
# UserSynchronizer.sync_users_in_group will return a hash with the following keys:
|
37
|
-
# * :added - An array of ActiveDirectory::User objects that were added.
|
38
|
-
# * :disabled - An array of ActiveDirectory::User objects that were disabled.
|
39
|
-
# * :updated - An array of ActiveDirectory::User objects that were updated.
|
40
|
-
#
|
41
|
-
# The following method illustrates how this would be used to notify a site
|
42
|
-
# administrator to changes brought about by synchronization:
|
43
|
-
#
|
44
|
-
# def report(results)
|
45
|
-
# puts "#####################################################"
|
46
|
-
# puts "# Active Directory People Synchronization Summary #"
|
47
|
-
# puts "#####################################################"
|
48
|
-
# puts
|
49
|
-
#
|
50
|
-
# puts "New People Added (#{results[:added].size})"
|
51
|
-
# puts "-----------------------------------------------------"
|
52
|
-
# results[:added].sort_by(&:name).each { |p| out.puts " + #{p.name}" }
|
53
|
-
# puts
|
54
|
-
#
|
55
|
-
# puts "People Disabled (#{results[:disabled].size})"
|
56
|
-
# puts "-----------------------------------------------------"
|
57
|
-
# results[:disabled].sort_by(&:name).each { |p| out.puts " - #{p.name}" }
|
58
|
-
# puts
|
59
|
-
#
|
60
|
-
# puts "Existing People Updated (#{results[:updated].size})"
|
61
|
-
# puts "-----------------------------------------------------"
|
62
|
-
# results[:updated].sort_by(&:name).each { |p| out.puts " u #{p.name}" }
|
63
|
-
# puts
|
64
|
-
# end
|
65
|
-
#
|
66
|
-
class ActiveDirectory::Rails::UserSynchronizer
|
67
|
-
@@default_group = nil
|
68
|
-
cattr_accessor :default_group
|
69
|
-
|
70
|
-
@@run_handler = nil
|
71
|
-
cattr_accessor :run_handler
|
72
|
-
|
73
|
-
@@attribute_map = {
|
74
|
-
:first_name => :givenName,
|
75
|
-
:last_name => :sn,
|
76
|
-
:username => :sAMAccountName,
|
77
|
-
:email => :mail,
|
78
|
-
}
|
79
|
-
cattr_accessor :attribute_map
|
80
|
-
|
81
|
-
@@person_class = Person
|
82
|
-
cattr_accessor :person_class
|
83
|
-
|
84
|
-
class << self
|
85
|
-
# The primary interface to synchronization, run processes
|
86
|
-
# all of the Active Directory changes, additions and removals
|
87
|
-
# through sync_users_in_group, and then notifies administrators
|
88
|
-
# if it finds anyone new.
|
89
|
-
#
|
90
|
-
# This is the preferred way to run the UserSynchronizer.
|
91
|
-
#
|
92
|
-
def run
|
93
|
-
results = sync_users_in_group
|
94
|
-
@@run_handler.nil? results : @@run_handler.call(results)
|
95
|
-
end
|
96
|
-
|
97
|
-
# Compares the membership of the Active Directory group named
|
98
|
-
# `group_name' and AD-enabled accounts in the local database.
|
99
|
-
#
|
100
|
-
# This method is the workhorse of UserSynchronizer, handling
|
101
|
-
# the addition, removal and updates of AD people.
|
102
|
-
#
|
103
|
-
# It will return either false, or a hash with three keys, :added, :updated
|
104
|
-
# and :disabled, each of which contains an array of the Person
|
105
|
-
# objects that were (respectively) added, updated and disabled.
|
106
|
-
#
|
107
|
-
# If the given group_name does not resolve to a valid
|
108
|
-
# ActiveDirectory::Group object, sync_users_in_group will return
|
109
|
-
# false.
|
110
|
-
#
|
111
|
-
# The return value (for example) can be used by a notification process
|
112
|
-
# to construct a message detailing who was added, removed, etc.
|
113
|
-
#
|
114
|
-
def sync_users_in_group(group_name = nil)
|
115
|
-
group_name ||= @@default_group
|
116
|
-
return false unless group_name
|
117
|
-
|
118
|
-
ad_group = ActiveDirectory::Group.find_by_sAMAccountName(group_name)
|
119
|
-
return false unless ad_group
|
120
|
-
|
121
|
-
@people = person_class.in_active_directory.index_by(&:guid)
|
122
|
-
|
123
|
-
summary = {
|
124
|
-
:added => [],
|
125
|
-
:disabled => [],
|
126
|
-
:updated => []
|
127
|
-
}
|
128
|
-
|
129
|
-
# Find all member users (recursively looking at member groups)
|
130
|
-
# and synchronize! them with their Person counterparts.
|
131
|
-
#
|
132
|
-
ad_group.member_users(true).each do |ad_user|
|
133
|
-
person = @people[ad_user.objectGUID]
|
134
|
-
if person
|
135
|
-
synchronize!(person, ad_user)
|
136
|
-
@people.delete(ad_user.objectGUID)
|
137
|
-
summary[:updated] << person
|
138
|
-
else
|
139
|
-
person = create_from(ad_user)
|
140
|
-
summary[:added] << person
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
# Disable AD users we didn't find in AD.
|
145
|
-
# Because we are not clearing the GUID in the disable! call,
|
146
|
-
# we may process someone more than once.
|
147
|
-
#
|
148
|
-
@people.each do |guid, person|
|
149
|
-
disable!(person)
|
150
|
-
summary[:disabled] << person
|
151
|
-
end
|
152
|
-
|
153
|
-
summary
|
154
|
-
end
|
155
|
-
|
156
|
-
# Synchronize a peron with AD store by looking up their username.
|
157
|
-
#
|
158
|
-
# This is used for the initial bootstrap, because we don't know
|
159
|
-
# a person's objectGUID offhand. It will probably never be seen
|
160
|
-
# in any production code.
|
161
|
-
#
|
162
|
-
def update_using_username(person)
|
163
|
-
ad_user = ActiveDirectory::User.find_by_sAMAccountName(person.username)
|
164
|
-
synchronize!(person, ad_user)
|
165
|
-
end
|
166
|
-
|
167
|
-
# Sync a person with AD store by looking up their GUID
|
168
|
-
# (This is the most reliable option, as a username can change,
|
169
|
-
# but the GUID will stay the same).
|
170
|
-
#
|
171
|
-
# This method is not used in production, but can be useful in
|
172
|
-
# a console'd environment to selectively update just a few people.
|
173
|
-
#
|
174
|
-
def update_using_guid(person)
|
175
|
-
ad_user = ActiveDirectory::User.find_by_objectGUID(person.guid)
|
176
|
-
synchronize!(person, ad_user)
|
177
|
-
end
|
178
|
-
|
179
|
-
# Synchronize the attributes of the given Person with those
|
180
|
-
# found in the (hopefully associated) Active Directory user
|
181
|
-
#
|
182
|
-
# Because we are managing a mixed database of both AD and non-AD
|
183
|
-
# people, we have to be careful. We cannot assume that a nil
|
184
|
-
# ad_user argument means the person should be disabled.
|
185
|
-
#
|
186
|
-
def synchronize!(person, ad_user)
|
187
|
-
person.update_attributes(attributes_from(ad_user)) if ad_user
|
188
|
-
end
|
189
|
-
|
190
|
-
# Disable a person, and clear out their authentication information.
|
191
|
-
# This is primarily used when we find terminated employees who are
|
192
|
-
# still in the local database as AD users, but no longer have an
|
193
|
-
# AD account.
|
194
|
-
#
|
195
|
-
# There is a special case for people who have not logged sales.
|
196
|
-
# They are removed outright, to keep terminated trainees from
|
197
|
-
# cluttering up the Person table.
|
198
|
-
#
|
199
|
-
# Note that we do not clear their GUID. Active Directory is not
|
200
|
-
# supposed to re-use its GUIDs, so we should be safe there.
|
201
|
-
#
|
202
|
-
def disable!(person)
|
203
|
-
if person.respond_to? :removable? and !person.removable?
|
204
|
-
person.update_attribute(:username, '')
|
205
|
-
person.update_attribute(:email, '')
|
206
|
-
else
|
207
|
-
person.destroy
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
# Creates a new Person object based on the attributes of
|
212
|
-
# an Active Directory user. sync_users_in_group uses this when
|
213
|
-
# it finds new people.
|
214
|
-
#
|
215
|
-
# All Person objects will be created as generic Persons,
|
216
|
-
# not CSRs or TeamLeaders. Administrators are responsible
|
217
|
-
# for promoting and associating new people in the backend.
|
218
|
-
#
|
219
|
-
def create_from(ad_user)
|
220
|
-
person = person_class.create(attributes_from(ad_user))
|
221
|
-
end
|
222
|
-
|
223
|
-
# Translates the attributes of ad_user into a hash that can
|
224
|
-
# be used to create or update a Person object.
|
225
|
-
#
|
226
|
-
def attributes_from(ad_user)
|
227
|
-
h = {}
|
228
|
-
@@attribute_map.each { |local, remote| h[local] = ad_user.send(remote) }
|
229
|
-
h[:guid] = ad_user.objectGUID
|
230
|
-
h[:password => '']
|
231
|
-
h
|
232
|
-
end
|
233
|
-
end
|
234
|
-
end
|
@@ -1,141 +0,0 @@
|
|
1
|
-
#-- license
|
2
|
-
#
|
3
|
-
# This file is part of the Ruby Active Directory Project
|
4
|
-
# on the web at http://rubyforge.org/projects/activedirectory
|
5
|
-
#
|
6
|
-
# Copyright (c) 2008, James Hunt <filefrog@gmail.com>
|
7
|
-
# based on original code by Justin Mecham
|
8
|
-
#
|
9
|
-
# This program is free software: you can redistribute it and/or modify
|
10
|
-
# it under the terms of the GNU General Public License as published by
|
11
|
-
# the Free Software Foundation, either version 3 of the License, or
|
12
|
-
# (at your option) any later version.
|
13
|
-
#
|
14
|
-
# This program is distributed in the hope that it will be useful,
|
15
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
16
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
17
|
-
# GNU General Public License for more details.
|
18
|
-
#
|
19
|
-
# You should have received a copy of the GNU General Public License
|
20
|
-
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
21
|
-
#
|
22
|
-
#++ license
|
23
|
-
|
24
|
-
module ActiveDirectory
|
25
|
-
module Rails
|
26
|
-
module User
|
27
|
-
def self.included(klass)
|
28
|
-
klass.extend(ClassMethods)
|
29
|
-
klass.send(:include, InstanceMethods)
|
30
|
-
end
|
31
|
-
|
32
|
-
module InstanceMethods
|
33
|
-
# Is this Person active? Active people have valid
|
34
|
-
# usernames. Inactive people have empty usernames.
|
35
|
-
#
|
36
|
-
def active?
|
37
|
-
username != ""
|
38
|
-
end
|
39
|
-
|
40
|
-
# Whether or not this Person has a corresponding Active Directory
|
41
|
-
# account that we can synchronize with, through the PeopleSynchronizer.
|
42
|
-
#
|
43
|
-
def in_active_directory?
|
44
|
-
!guid.blank?
|
45
|
-
end
|
46
|
-
|
47
|
-
# Whether or not this Person can be authenticated with the
|
48
|
-
# given password, against Active Directory.
|
49
|
-
#
|
50
|
-
# For Active Directory authentication, we attempt to bind to the
|
51
|
-
# configured AD server as the user, and supply the password for
|
52
|
-
# authentication.
|
53
|
-
#
|
54
|
-
# There are two special cases for authentication, related to the
|
55
|
-
# environment the app is currently running in:
|
56
|
-
#
|
57
|
-
# *Development*
|
58
|
-
#
|
59
|
-
# In development, the blank password ('') will always cause this method
|
60
|
-
# to return true, thereby allowing developers to test functionality
|
61
|
-
# for a variety of roles.
|
62
|
-
#
|
63
|
-
# *Training*
|
64
|
-
#
|
65
|
-
# In training, a special training password ('trainme') will always
|
66
|
-
# cause this method to return true, thereby allowing trainers to
|
67
|
-
# use other people accounts to illustrate certain restricted processes.
|
68
|
-
#
|
69
|
-
def authenticates?(password)
|
70
|
-
# Never allow inactive users.
|
71
|
-
return false unless active?
|
72
|
-
|
73
|
-
# Allow blank password for any account in development.
|
74
|
-
return true if password == "" and ENV['RAILS_ENV'] == 'development'
|
75
|
-
return true if password == "trainme" and ENV['RAILS_ENV'] == 'training'
|
76
|
-
|
77
|
-
# Don't go against AD unless we really mean it.
|
78
|
-
return false unless ENV['RAILS_ENV'] == 'production'
|
79
|
-
|
80
|
-
# If they are not in AD, fail.
|
81
|
-
return false unless in_active_directory?
|
82
|
-
|
83
|
-
ad_user = ActiveDirectory::User.find_by_sAMAccountName(self.username)
|
84
|
-
ad_user and ad_user.authenticate(password)
|
85
|
-
end
|
86
|
-
|
87
|
-
def active_directory_equivalent=(ad_user)
|
88
|
-
return unless ad_user
|
89
|
-
update_attributes(
|
90
|
-
:first_name => ad_user.givenName,
|
91
|
-
:middle_name => ad_user.initials,
|
92
|
-
:last_name => ad_user.sn,
|
93
|
-
:username => ad_user.sAMAccountName,
|
94
|
-
:email => ad_user.mail,
|
95
|
-
:guid => ad_user.objectGUID
|
96
|
-
)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
module ClassMethods
|
101
|
-
# Attempt to authenticate someone with a username and password.
|
102
|
-
# This method properly handles both local store users and AD
|
103
|
-
# users.
|
104
|
-
#
|
105
|
-
# If the username is valid, and the password matches the username,
|
106
|
-
# the Person object corresponding to the username is return.
|
107
|
-
#
|
108
|
-
# Otherwise, nil is returned, to indicate an authentication failure.
|
109
|
-
#
|
110
|
-
def authenticate(username, password)
|
111
|
-
person = find_by_username(username)
|
112
|
-
return person if (person and person.authenticates?(password))
|
113
|
-
nil
|
114
|
-
end
|
115
|
-
|
116
|
-
# Retrieves all of the Person objects that have corresponding
|
117
|
-
# Active Directory accounts. This method does not contact
|
118
|
-
# the AD servers to retrieve the AD objects -- that is left up
|
119
|
-
# to the caller.
|
120
|
-
#
|
121
|
-
def in_active_directory
|
122
|
-
find(:all, :conditions => 'guid IS NOT NULL AND guid != ""')
|
123
|
-
end
|
124
|
-
|
125
|
-
# Retrieves all Person objects that are currently active,
|
126
|
-
# meaning they have not been disabled by PeopleSynchronizer.
|
127
|
-
#
|
128
|
-
def active
|
129
|
-
find(:all, :conditions => 'username != ""')
|
130
|
-
end
|
131
|
-
|
132
|
-
# Retrieves all Person objects that are currently inactive,
|
133
|
-
# meaning they have been disabled by PeopleSynchronizer.
|
134
|
-
#
|
135
|
-
def inactive
|
136
|
-
find(:all, :conditions => 'username = ""')
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end # module User
|
140
|
-
end # module Rails
|
141
|
-
end #module ActiveDirectory
|