devise-basecamper 0.4.5 → 0.5.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.
@@ -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: