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 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.1.0"
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.1
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.1.1"
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/model.rb",
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.1.0"])
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.1.0"])
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.1.0"])
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 :ad_attr_mapping
27
- @@ad_attr_mapping = {
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/model')
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 AdUser
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
@@ -37,7 +37,6 @@ module DeviseActiveDirectoryAuthenticatable
37
37
  # }
38
38
 
39
39
  ##Attribute mapping for user object
40
- # mattr_accessor :ad_attr_mapping
41
40
  # config.ad_attr_mapping = {
42
41
  # :objectGUID => :objectGUID, #Required
43
42
  # :username => :userPrincipalName,
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: 25
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
9
- - 1
10
- version: 0.1.1
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: 19
45
+ hash: 31
46
46
  segments:
47
47
  - 1
48
- - 1
48
+ - 2
49
49
  - 0
50
- version: 1.1.0
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/model.rb
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