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.
- data/lib/devise-basecamper/authentication.rb +95 -0
- data/lib/devise-basecamper/basecamper.rb +32 -0
- data/lib/devise-basecamper/confirmable.rb +32 -0
- data/lib/devise-basecamper/devise/models/authenticatable.rb +7 -0
- data/lib/devise-basecamper/model.rb +5 -133
- data/lib/devise-basecamper/recoverable.rb +32 -0
- data/lib/devise-basecamper/version.rb +1 -1
- data/lib/devise-basecamper.rb +9 -0
- metadata +6 -2
@@ -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
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
data/lib/devise-basecamper.rb
CHANGED
@@ -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
|
+
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-
|
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:
|