devise-basecamper 0.4.5 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,95 @@
1
+ # lib/devise-basecamper/authentication.rb
2
+
3
+ module DeviseBasecamper
4
+ module Authentication
5
+ extend ActiveSupport::Concern
6
+
7
+ module ClassMethods
8
+ ## Override the find_for_authentication finder
9
+ ##
10
+ ## We will clean the conditions provided to make sure that the proper
11
+ ## resource can/will be found.
12
+ ##
13
+ ##
14
+ def find_for_authentication(conditions={})
15
+ conditions = clean_conditions_for_subdomain(conditions)
16
+
17
+ ## Process if "login" key used instead of default (:email)
18
+ if authenticate_with_login?(conditions)
19
+ find_for_authentication_with_login( authentication_keys, conditions )
20
+ else
21
+ super ## Execute original find_for_authentication code
22
+ end
23
+ end
24
+
25
+ def authenticate_with_login?(conditions={})
26
+ if conditions.any?
27
+ authentication_keys.include?(basecamper[:login_attribute]) && conditions.include?(basecamper[:login_attribute])
28
+ else
29
+ authentication_keys.include? basecamper[:login_attribute]
30
+ end
31
+ end
32
+
33
+ private # -------------------------------------------
34
+
35
+ ## Search for the resource identified in the basecamper config and return it
36
+ ## to the caller
37
+ def find_resource_by_subdomain(conditions)
38
+ resource = self.basecamper[:subdomain_class].to_s.camelize.constantize
39
+ subdomain_field = self.basecamper[:subdomain_field]
40
+
41
+ return resource.to_adapter.find_first(subdomain_field => conditions[:subdomain])
42
+ end
43
+
44
+ ## We are going to look for the subdomain condition. If present, we will translate
45
+ ## the subdomain to a valid "id", add the ID to the conditions for use in the DB
46
+ ## query built and remove thd field from the conditions to avoid issues down the
47
+ ## chain.
48
+ ##
49
+ def clean_conditions_for_subdomain(conditions={})
50
+ if conditions[:subdomain].present?
51
+ scope_field, subdomain_field = [self.basecamper[:scope_field], self.basecamper[:subdomain_field]]
52
+ subdomain_resource = find_resource_by_subdomain conditions
53
+ conditions[scope_field] = (subdomain_resource.nil?) ? nil : subdomain_resource.id
54
+ conditions.delete(subdomain_field)
55
+ end
56
+
57
+ return conditions
58
+ end
59
+
60
+ ## If devise is configured to allow authentication using either a username
61
+ ## or email, as described in the wiki we will need to process the find
62
+ ## appropriately.
63
+ def find_for_authentication_with_login(required_attributes={}, attributes={}, error=:invalid)
64
+ resource = nil
65
+ attributes = devise_parameter_filter.filter(attributes)
66
+
67
+ basecamper[:login_fields].each do |field|
68
+ login_field = field.downcase.to_sym
69
+
70
+ resource = to_adapter.find_first({
71
+ login_field => attributes[ basecamper[:login_attribute] ],
72
+ basecamper[:scope_field] => attributes[basecamper[:scope_field]]
73
+ })
74
+
75
+ break unless resource.nil?
76
+ end
77
+
78
+ unless resource
79
+ resource = new
80
+
81
+ required_attributes.each do |key|
82
+ unless key == basecamper[:subdomain_field]
83
+ resource.send("#{ key }=", attributes[key])
84
+ resource.errors.add(key, attributes[key].present? ? error : :blank)
85
+ end
86
+ end
87
+ end
88
+
89
+ return resource
90
+ end
91
+
92
+ ## --------------------------------------------------
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,32 @@
1
+ # lib/devise-basecamper/basecamper.rb
2
+
3
+ module DeviseBasecamper
4
+ module Basecamper
5
+ extend ActiveSupport::Concern
6
+
7
+ module ClassMethods
8
+ ## Helper method for configuration options on the model
9
+ ##
10
+ def devise_basecamper(opts={})
11
+ defaults = {
12
+ subdomain_class: :account,
13
+ subdomain_field: :subdomain,
14
+ scope_field: :account_id,
15
+ login_fields: [:username, :email],
16
+ login_attribute: :login
17
+ }
18
+
19
+ @devise_basecamper_settings = defaults.merge(opts)
20
+ end
21
+
22
+ ## Quick access to the models configuration ---------
23
+ ##
24
+ def basecamper
25
+ self.devise_basecamper if @devise_basecamper_settings.nil?
26
+ return @devise_basecamper_settings
27
+ end
28
+ end
29
+
30
+ ## ----------------------------------------------------
31
+ end
32
+ end
@@ -0,0 +1,32 @@
1
+ module DeviseBasecamper
2
+ module Confirmable
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ ## Override for password resets -------------------
7
+ def send_confirmation_instructions(attributes={})
8
+ if confirm_with_login?
9
+ subdomain_resource = find_resource_by_subdomain(attributes)
10
+ attributes[ basecamper[:scope_field] ] = subdomain_resource.nil? ? nil : subdomain_resource.id
11
+ recoverable = find_for_authentication_with_login(reset_password_keys, attributes, :not_found)
12
+ else
13
+ recoverable = find_or_initialize_with_errors(reset_password_keys, attributes, :not_found)
14
+ end
15
+
16
+ ## Now that we have found the recoverable, we are going to call the
17
+ ## send_reset_password_instructions on the specific recoverable
18
+ ##
19
+ recoverable.send_confirmation_instructions if recoverable.persisted?
20
+ recoverable
21
+ end
22
+
23
+ def confirm_with_login?(attributes={})
24
+ if attributes.any?
25
+ attributes.include?( basecamper[:login_attribute] ) && confirmation_keys.include?( basecamper[:login_attribute] )
26
+ else
27
+ reset_password_keys.include?( basecamper[:login_attribute] )
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,3 +1,10 @@
1
+ # lib/devise-basecamper/devise/models/authenticatable.rb
2
+ #
3
+ # This module will make sure to remove the subdomain field by default
4
+ # from devise models that are NOT using basecamper. That way the
5
+ # finders will try searching on fields in your database that may not
6
+ # exist.
7
+ ##
1
8
  module Devise
2
9
  module Models
3
10
  module Authenticatable
@@ -3,139 +3,11 @@ module Devise
3
3
  module Basecamper
4
4
  extend ActiveSupport::Concern
5
5
 
6
- module ClassMethods
7
- def devise_basecamper(opts={})
8
- defaults = {
9
- :subdomain_class => :account,
10
- :subdomain_field => :subdomain,
11
- :scope_field => :account_id,
12
- :login_fields => [:username, :email]
13
- }
14
- @devise_basecamper_settings = defaults.merge(opts)
15
- end
16
-
17
- def basecamper
18
- self.devise_basecamper if @devise_basecamper_settings.nil?
19
- return @devise_basecamper_settings
20
- end
21
-
22
- ## Methods ------------------------------------------------------------
23
-
24
- def find_for_authentication(conditions={})
25
- authentication_keys = Devise.authentication_keys
26
-
27
- ## Process subdomain info by finding the parent resource id into the conditions
28
- conditions = clean_conditions_for_subdomain(conditions)
29
-
30
- ## Process if "login" key used instead of default (:email)
31
- if conditions[:login].present? && authentication_keys.include?(:login)
32
- resource = find_with_login_instead_of_default( authentication_keys, conditions )
33
- return resource
34
- end
35
-
36
- ## Execute original find_for_authentication code
37
- super
38
- end
39
-
40
- # TODO: Probably should break this out or atleast put some conditions in place
41
- # so that this method is only included when "RECOVERABLE" is a specified option
42
- # for the resource.
43
- #
44
- # We want to override this method to find our users within the scope
45
- # of our subdomain.
46
- def send_reset_password_instructions(attributes={})
47
- send_instructions_for(:reset_password, attributes)
48
- end
49
-
50
- def send_confirmation_instructions(attributes={})
51
- send_instructions_for(:confirmation, attributes)
52
- end
53
-
54
- private
55
-
56
- def send_instructions_for(action_method, attributes={})
57
- scope_field = self.basecamper[:scope_field].downcase.to_sym
58
- subdomain_resource = find_subdomain_resource(attributes[:subdomain])
59
- subdomain_resource_id = subdomain_resource.nil? ? nil : subdomain_resource.id
60
- required_keys = Devise.send "#{action_method.to_s}_keys".to_sym
61
-
62
- ## Find our resource for sending the email
63
- if attributes[:login].present? && reset_password_keys.include?(:login)
64
- attributes[scope_field] = subdomain_resource_id
65
- resource = find_with_login_instead_of_default(required_keys, attributes)
66
- else
67
- resource = find_or_initialize_with_errors(reset_password_keys,{
68
- :email => attributes[:email], scope_field => subdomain_resource_id
69
- })
70
- end
71
-
72
- resource.send("send_#{action_method.to_s}_instructions") if !resource.nil? && resource.persisted?
73
- return resource
74
- end
75
-
76
- private # -------------------------------------------------------------
77
-
78
- ## If devise is configured to allow authentication using either a username
79
- ## or email, as described in the wiki we will need to process the find
80
- ## appropriately.
81
- def find_with_login_instead_of_default(required_attributes={}, attributes={}, error=:invalid)
82
- resource = nil
83
- scope_field = self.basecamper[:scope_field]
84
- login_fields = self.basecamper[:login_fields]
85
-
86
- attributes = devise_parameter_filter.filter(attributes)
87
-
88
- login_fields.each do |login_field|
89
- login_field = login_field.downcase.to_sym
90
-
91
- resource = to_adapter.find_first({
92
- login_field => attributes[:login],
93
- scope_field => attributes[scope_field]
94
- })
95
-
96
- break unless resource.nil?
97
- end
98
-
99
- unless resource
100
- resource = new
101
-
102
- required_attributes.each do |key|
103
- unless key == self.basecamper[:subdomain_field]
104
- value = attributes[key]
105
- resource.send("#{key}=", value)
106
- resource.errors.add(key, value.present? ? error : :blank)
107
- end
108
- end
109
- end
110
-
111
- return resource
112
- end
113
-
114
- ## Clean the conditions and set them appropriately for finding the resource
115
- ## with proper scoping.
116
- def clean_conditions_for_subdomain(conditions={})
117
- if conditions[:subdomain].present?
118
- subdomain = conditions[:subdomain]
119
- scope_field = self.basecamper[:scope_field]
120
- subdomain_field = self.basecamper[:subdomain_field]
121
- subdomain_resource = find_subdomain_resource(subdomain)
122
- conditions[scope_field] = (subdomain_resource.nil?) ? nil : subdomain_resource.id
123
-
124
- ## Remove the subdomain_field from the conditions - it is not needed
125
- conditions.delete(subdomain_field)
126
- end
127
-
128
- return conditions
129
- end
130
-
131
- ## Search for the resource identified in the basecamper config and return it
132
- ## to the caller
133
- def find_subdomain_resource(subdomain)
134
- resource = self.basecamper[:subdomain_class].to_s.camelize.constantize
135
- subdomain_field = self.basecamper[:subdomain_field]
136
-
137
- return resource.to_adapter.find_first(subdomain_field => subdomain)
138
- end
6
+ included do
7
+ include DeviseBasecamper::Basecamper
8
+ include DeviseBasecamper::Authentication
9
+ include DeviseBasecamper::Recoverable
10
+ include DeviseBasecamper::Confirmable
139
11
  end
140
12
  end
141
13
  end
@@ -0,0 +1,32 @@
1
+ module DeviseBasecamper
2
+ module Recoverable
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ ## Override for password resets -------------------
7
+ def send_reset_password_instructions(attributes={})
8
+ if recover_with_login?
9
+ subdomain_resource = find_resource_by_subdomain(attributes)
10
+ attributes[ basecamper[:scope_field] ] = subdomain_resource.nil? ? nil : subdomain_resource.id
11
+ recoverable = find_for_authentication_with_login(reset_password_keys, attributes, :not_found)
12
+ else
13
+ recoverable = find_or_initialize_with_errors(reset_password_keys, attributes, :not_found)
14
+ end
15
+
16
+ ## Now that we have found the recoverable, we are going to call the
17
+ ## send_reset_password_instructions on the specific recoverable
18
+ ##
19
+ recoverable.send_reset_password_instructions if recoverable.persisted?
20
+ recoverable
21
+ end
22
+
23
+ def recover_with_login?(attributes={})
24
+ if attributes.any?
25
+ attributes.include?( basecamper[:login_attribute] ) && reset_password_keys.include?( basecamper[:login_attribute] )
26
+ else
27
+ reset_password_keys.include?( basecamper[:login_attribute] )
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,5 +1,5 @@
1
1
  module Devise
2
2
  module Basecamper
3
- VERSION = "0.4.5"
3
+ VERSION = "0.5.0"
4
4
  end
5
5
  end
@@ -1,7 +1,16 @@
1
1
  require 'devise'
2
2
  require 'devise-basecamper/version'
3
3
  require 'devise-basecamper/devise/models/authenticatable'
4
+ require 'devise-basecamper/basecamper'
5
+ require 'devise-basecamper/authentication'
6
+ require 'devise-basecamper/recoverable'
7
+ require 'devise-basecamper/confirmable'
4
8
 
9
+ ## Establish the namespace --------------------------------
10
+ module DeviseBasecamper
11
+ end
12
+
13
+ ## Add the model to devise --------------------------------
5
14
  Devise.add_module(:basecamper,
6
15
  :strategy => false,
7
16
  :route => :session,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise-basecamper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-12-23 00:00:00.000000000 Z
13
+ date: 2013-12-24 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: orm_adapter
@@ -60,8 +60,12 @@ files:
60
60
  - Rakefile
61
61
  - devise-basecamper.gemspec
62
62
  - lib/devise-basecamper.rb
63
+ - lib/devise-basecamper/authentication.rb
64
+ - lib/devise-basecamper/basecamper.rb
65
+ - lib/devise-basecamper/confirmable.rb
63
66
  - lib/devise-basecamper/devise/models/authenticatable.rb
64
67
  - lib/devise-basecamper/model.rb
68
+ - lib/devise-basecamper/recoverable.rb
65
69
  - lib/devise-basecamper/version.rb
66
70
  homepage: https://github.com/digitalopera/devise-basecamper
67
71
  licenses: