devise_active_directory_authenticatable 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/devise_active_directory_authenticatable.gemspec +7 -5
- data/lib/devise_active_directory_authenticatable.rb +17 -5
- data/lib/devise_active_directory_authenticatable/{model.rb → models/ad_group.rb} +1 -9
- data/lib/devise_active_directory_authenticatable/models/ad_object.rb +72 -0
- data/lib/devise_active_directory_authenticatable/models/ad_user.rb +115 -0
- data/lib/generators/devise_active_directory_authenticatable/install_generator.rb +0 -1
- metadata +10 -8
data/Rakefile
CHANGED
@@ -22,7 +22,7 @@ begin
|
|
22
22
|
gemspec.homepage = "http://github.com/ajrkerr/devise_activedirectory_authenticatable"
|
23
23
|
gemspec.authors = ["Adam Kerr"]
|
24
24
|
gemspec.add_dependency "devise", ">= 1.1.5"
|
25
|
-
gemspec.add_dependency "active_directory", ">= 1.
|
25
|
+
gemspec.add_dependency "active_directory", ">= 1.2.0"
|
26
26
|
end
|
27
27
|
Jeweler::GemcutterTasks.new
|
28
28
|
rescue LoadError
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{devise_active_directory_authenticatable}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.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 Kerr"]
|
@@ -25,7 +25,9 @@ Gem::Specification.new do |s|
|
|
25
25
|
"lib/devise_active_directory_authenticatable.rb",
|
26
26
|
"lib/devise_active_directory_authenticatable/exception.rb",
|
27
27
|
"lib/devise_active_directory_authenticatable/logger.rb",
|
28
|
-
"lib/devise_active_directory_authenticatable/
|
28
|
+
"lib/devise_active_directory_authenticatable/models/ad_group.rb",
|
29
|
+
"lib/devise_active_directory_authenticatable/models/ad_object.rb",
|
30
|
+
"lib/devise_active_directory_authenticatable/models/ad_user.rb",
|
29
31
|
"lib/devise_active_directory_authenticatable/strategy.rb",
|
30
32
|
"lib/generators/devise_active_directory_authenticatable/install_generator.rb",
|
31
33
|
"rails/init.rb"
|
@@ -40,14 +42,14 @@ Gem::Specification.new do |s|
|
|
40
42
|
|
41
43
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
42
44
|
s.add_runtime_dependency(%q<devise>, [">= 1.1.5"])
|
43
|
-
s.add_runtime_dependency(%q<active_directory>, [">= 1.
|
45
|
+
s.add_runtime_dependency(%q<active_directory>, [">= 1.2.0"])
|
44
46
|
else
|
45
47
|
s.add_dependency(%q<devise>, [">= 1.1.5"])
|
46
|
-
s.add_dependency(%q<active_directory>, [">= 1.
|
48
|
+
s.add_dependency(%q<active_directory>, [">= 1.2.0"])
|
47
49
|
end
|
48
50
|
else
|
49
51
|
s.add_dependency(%q<devise>, [">= 1.1.5"])
|
50
|
-
s.add_dependency(%q<active_directory>, [">= 1.
|
52
|
+
s.add_dependency(%q<active_directory>, [">= 1.2.0"])
|
51
53
|
end
|
52
54
|
end
|
53
55
|
|
@@ -8,8 +8,6 @@ require 'devise_active_directory_authenticatable/logger'
|
|
8
8
|
# Get ldap information from config/ldap.yml now
|
9
9
|
module Devise
|
10
10
|
|
11
|
-
##TODO Revise these options/vars and their corresponding generator
|
12
|
-
|
13
11
|
#Active Directory settings
|
14
12
|
mattr_accessor :ad_settings
|
15
13
|
@@ad_settings = {
|
@@ -23,13 +21,24 @@ module Devise
|
|
23
21
|
}
|
24
22
|
|
25
23
|
#Attribute mapping for user object
|
26
|
-
mattr_accessor :
|
27
|
-
@@
|
24
|
+
mattr_accessor :ad_user_mapping
|
25
|
+
@@ad_user_mapping = {
|
28
26
|
:objectGUID => :objectGUID, #Required
|
29
27
|
:username => :userPrincipalName,
|
30
28
|
:dn => :dn,
|
31
29
|
:firstname => :givenName,
|
32
30
|
:lastname => :sn,
|
31
|
+
:whenChanged => :whenChanged,
|
32
|
+
}
|
33
|
+
|
34
|
+
#Attribute mapping for group objects
|
35
|
+
mattr_accessor :ad_group_mapping
|
36
|
+
@@ad_group_mapping = {
|
37
|
+
:objectGUID => :objectGUID, #Required
|
38
|
+
:dn => :dn,
|
39
|
+
:name => :name,
|
40
|
+
:description => :description,
|
41
|
+
:whenCreated => :whenChanged,
|
33
42
|
}
|
34
43
|
|
35
44
|
#Username attribute
|
@@ -51,4 +60,7 @@ Devise.add_module(:ad_user,
|
|
51
60
|
:route => :session, ## This will add the routes, rather than in the routes.rb
|
52
61
|
:strategy => true,
|
53
62
|
:controller => :sessions,
|
54
|
-
:model => 'devise_active_directory_authenticatable/
|
63
|
+
:model => 'devise_active_directory_authenticatable/models/ad_user')
|
64
|
+
|
65
|
+
Devise.add_module(:ad_group,
|
66
|
+
:model => 'devise_active_directory_authenticatable/models/ad_group')
|
@@ -5,7 +5,7 @@ module Devise
|
|
5
5
|
module Models
|
6
6
|
# Active Directory Module, responsible for validating the user credentials via Active Directory
|
7
7
|
#
|
8
|
-
module
|
8
|
+
module AdGroup
|
9
9
|
|
10
10
|
#Remove this before production
|
11
11
|
ADConnect = DeviseActiveDirectoryAuthenticatable
|
@@ -14,10 +14,6 @@ module Devise
|
|
14
14
|
|
15
15
|
extend ActiveSupport::Concern
|
16
16
|
|
17
|
-
included do
|
18
|
-
serialize :objectGUID
|
19
|
-
end
|
20
|
-
|
21
17
|
## Devise key
|
22
18
|
def login_with
|
23
19
|
self[::Devise.authentication_keys.first]
|
@@ -45,10 +41,6 @@ module Devise
|
|
45
41
|
super if defined? super
|
46
42
|
end
|
47
43
|
|
48
|
-
def guid
|
49
|
-
objectGUID.unpack("H*")
|
50
|
-
end
|
51
|
-
|
52
44
|
|
53
45
|
module ClassMethods
|
54
46
|
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Devise
|
2
|
+
module Models
|
3
|
+
|
4
|
+
#Basic functions and shared methods for AD objects in ActiveRecord
|
5
|
+
module AdObject
|
6
|
+
|
7
|
+
ADConnect = DeviseActiveDirectoryAuthenticatable
|
8
|
+
Logger = DeviseActiveDirectoryAuthenticatable::Logger
|
9
|
+
|
10
|
+
extend ActiveSupport::Concern
|
11
|
+
|
12
|
+
included do
|
13
|
+
#Serialize all binary fields
|
14
|
+
# ::Devise.ad_special_fields[:binary].each do |field|
|
15
|
+
# serialize field
|
16
|
+
# end
|
17
|
+
end
|
18
|
+
|
19
|
+
## Devise key
|
20
|
+
def login_with
|
21
|
+
self[::Devise.authentication_keys.first]
|
22
|
+
end
|
23
|
+
|
24
|
+
# Update the attributes of the current object from the AD
|
25
|
+
# Defaults to current user if no parameters given
|
26
|
+
def sync_with_activedirectory(params = {})
|
27
|
+
params[:objectGUID] = self.objectGUID if params.empty?
|
28
|
+
user = params[:user] || User.find_in_activedirectory(params)
|
29
|
+
|
30
|
+
return false if user.nil?
|
31
|
+
|
32
|
+
Logger.send "Updating #{params.inspect}"
|
33
|
+
|
34
|
+
#Grab attributes from Devise mapping
|
35
|
+
::Devise.ad_attr_mapping.each do |user_attr, active_directory_attr|
|
36
|
+
self[user_attr] = user.send(active_directory_attr)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
module ClassMethods
|
42
|
+
|
43
|
+
#Search based on GUID, DN or Username primarily
|
44
|
+
def find_in_activedirectory(params = {})
|
45
|
+
|
46
|
+
#Reverse mappings
|
47
|
+
params[::Devise.ad_username] ||= params[:username] if params[:username].present?
|
48
|
+
params[::Devise.ad_username] ||= params[@login_with] if params[@login_with].present?
|
49
|
+
|
50
|
+
params.delete(:username)
|
51
|
+
params.delete(@login_with)
|
52
|
+
|
53
|
+
Logger.send "Searching for #{params.inspect}"
|
54
|
+
user = ADUser.find(:first, params)
|
55
|
+
Logger.send "Found: #{user}"
|
56
|
+
|
57
|
+
return user
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def ad_connect(params = {})
|
63
|
+
#Used for username and password
|
64
|
+
::Devise.ad_settings[:auth].merge! params
|
65
|
+
|
66
|
+
ActiveDirectory::Base.setup(::Devise.ad_settings)
|
67
|
+
Logger.send "Connection Result: #{ActiveDirectory::Base.error}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'devise_active_directory_authenticatable/strategy'
|
2
|
+
require 'devise_active_directory_authenticatable/exception'
|
3
|
+
|
4
|
+
module Devise
|
5
|
+
module Models
|
6
|
+
# Active Directory Module, responsible for validating the user credentials via Active Directory
|
7
|
+
#
|
8
|
+
module AdUser
|
9
|
+
|
10
|
+
#Remove this before production
|
11
|
+
ADConnect = DeviseActiveDirectoryAuthenticatable
|
12
|
+
ADUser = ActiveDirectory::User
|
13
|
+
Logger = DeviseActiveDirectoryAuthenticatable::Logger
|
14
|
+
|
15
|
+
extend ActiveSupport::Concern
|
16
|
+
|
17
|
+
## Devise key
|
18
|
+
def login_with
|
19
|
+
self[::Devise.authentication_keys.first]
|
20
|
+
end
|
21
|
+
|
22
|
+
# Update the attributes of the current object from the AD
|
23
|
+
# Defaults to current user if no parameters given
|
24
|
+
def sync_with_activedirectory(params = {})
|
25
|
+
params[:objectGUID] = self.objectGUID if params.empty?
|
26
|
+
user = params[:user] || User.find_in_activedirectory(params)
|
27
|
+
|
28
|
+
return false if user.nil?
|
29
|
+
|
30
|
+
Logger.send "Updating #{params.inspect}"
|
31
|
+
|
32
|
+
#Grab attributes from Devise mapping
|
33
|
+
::Devise.ad_user_mapping.each do |user_attr, active_directory_attr|
|
34
|
+
Logger.send "Settings #{user_attr} = #{user.send(active_directory_attr)}"
|
35
|
+
self[user_attr] = user.send(active_directory_attr)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Login event handler. Triggered after authentication.
|
40
|
+
def login
|
41
|
+
sync_with_activedirectory
|
42
|
+
super if defined? super
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
module ClassMethods
|
47
|
+
|
48
|
+
# Authenticate a user based on configured attribute keys. Returns the
|
49
|
+
# authenticated user if it's valid or nil.
|
50
|
+
def authenticate_with_activedirectory(attributes={})
|
51
|
+
@login_with = ::Devise.authentication_keys.first
|
52
|
+
|
53
|
+
username = attributes[@login_with]
|
54
|
+
password = attributes[:password]
|
55
|
+
|
56
|
+
Logger.send "Attempting to login :#{@login_with} => #{username}"
|
57
|
+
ad_connect(:username => username, :password => password)
|
58
|
+
ad_user = find_in_activedirectory(:username => username)
|
59
|
+
Logger.send "Attempt Result: #{ActiveDirectory::Base.error}"
|
60
|
+
|
61
|
+
raise ADConnect::ActiveDirectoryException, "Could not connect with Active Directory. Check your username, password, and ensure that your account is not locked." unless ad_user
|
62
|
+
|
63
|
+
# Find them in the local database
|
64
|
+
user = scoped.where(@login_with => attributes[@login_with]).first
|
65
|
+
|
66
|
+
if user.blank? and ::Devise.ad_create_user
|
67
|
+
Logger.send "Creating new user in database"
|
68
|
+
user = new
|
69
|
+
user[@login_with] = attributes[@login_with]
|
70
|
+
user.sync_with_activedirectory(:user => ad_user)
|
71
|
+
Logger.send "Created: #{user.inspect}"
|
72
|
+
end
|
73
|
+
Logger.send "User: #{user.inspect}"
|
74
|
+
Logger.send "Checking: #{ad_user.objectGUID.inspect} == #{user.objectGUID.inspect}"
|
75
|
+
# Check to see if we have the same user
|
76
|
+
if ad_user == user
|
77
|
+
user.save if user.new_record?
|
78
|
+
user.login if user.respond_to?(:login)
|
79
|
+
return user
|
80
|
+
else
|
81
|
+
raise ADConnect::ActiveDirectoryException, "Invalid Username or Password. Possible database inconsistency."
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
#Search based on GUID, DN or Username primarily
|
87
|
+
def find_in_activedirectory(params = {})
|
88
|
+
|
89
|
+
#Reverse mappings
|
90
|
+
params[::Devise.ad_username] ||= params[:username] if params[:username].present?
|
91
|
+
params[::Devise.ad_username] ||= params[@login_with] if params[@login_with].present?
|
92
|
+
|
93
|
+
params.delete(:username)
|
94
|
+
params.delete(@login_with)
|
95
|
+
|
96
|
+
Logger.send "Searching for #{params.inspect}"
|
97
|
+
user = ADUser.find(:first, params)
|
98
|
+
Logger.send "Found: #{user}"
|
99
|
+
|
100
|
+
return user
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def ad_connect(params = {})
|
106
|
+
#Used for username and password
|
107
|
+
::Devise.ad_settings[:auth].merge! params
|
108
|
+
|
109
|
+
ActiveDirectory::Base.setup(::Devise.ad_settings)
|
110
|
+
Logger.send "Connection Result: #{ActiveDirectory::Base.error}"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: devise_active_directory_authenticatable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Adam Kerr
|
@@ -42,12 +42,12 @@ dependencies:
|
|
42
42
|
requirements:
|
43
43
|
- - ">="
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
hash:
|
45
|
+
hash: 31
|
46
46
|
segments:
|
47
47
|
- 1
|
48
|
-
-
|
48
|
+
- 2
|
49
49
|
- 0
|
50
|
-
version: 1.
|
50
|
+
version: 1.2.0
|
51
51
|
type: :runtime
|
52
52
|
version_requirements: *id002
|
53
53
|
description: Active Directory authentication module for Devise, based off of LDAP Authentication
|
@@ -68,7 +68,9 @@ files:
|
|
68
68
|
- lib/devise_active_directory_authenticatable.rb
|
69
69
|
- lib/devise_active_directory_authenticatable/exception.rb
|
70
70
|
- lib/devise_active_directory_authenticatable/logger.rb
|
71
|
-
- lib/devise_active_directory_authenticatable/
|
71
|
+
- lib/devise_active_directory_authenticatable/models/ad_group.rb
|
72
|
+
- lib/devise_active_directory_authenticatable/models/ad_object.rb
|
73
|
+
- lib/devise_active_directory_authenticatable/models/ad_user.rb
|
72
74
|
- lib/devise_active_directory_authenticatable/strategy.rb
|
73
75
|
- lib/generators/devise_active_directory_authenticatable/install_generator.rb
|
74
76
|
- rails/init.rb
|