devise-basecamper 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +62 -21
- data/lib/devise-basecamper/model.rb +15 -3
- data/lib/devise-basecamper/version.rb +1 -1
- metadata +2 -8
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# Devise::Basecamper
|
2
2
|
|
3
|
-
Devise-Basecamper was built to allow users of [Devise](https://github.com/plataformatec/devise) to implement "Basecamp" style subdomain scoped authentication with
|
4
|
-
support for multiple users. There are a lot of [great tutorials](https://github.com/RailsApps/rails3-subdomains) out
|
3
|
+
Devise-Basecamper was built to allow users of [Devise](https://github.com/plataformatec/devise) to implement "Basecamp" style subdomain scoped authentication with
|
4
|
+
support for multiple users. There are a lot of [great tutorials](https://github.com/RailsApps/rails3-subdomains) out
|
5
5
|
there on doing subdomain authentication with devise, but none of them seemed to fit my particular use cases. So I took
|
6
|
-
a stab at extending the functionality of [Devise](https://github.com/plataformatec/devise), which has been a great
|
6
|
+
a stab at extending the functionality of [Devise](https://github.com/plataformatec/devise), which has been a great
|
7
7
|
Gem, and community, to work with.
|
8
8
|
|
9
9
|
### Use Case
|
@@ -26,12 +26,12 @@ Or install it yourself as:
|
|
26
26
|
|
27
27
|
## Usage
|
28
28
|
|
29
|
-
To make Devise-Basecamper work properly, there are several steps that need to be taken to adjust the "out-of-the-box"
|
30
|
-
behavior of Devise. None of the changes require doing any "hacking" of Devise, as they are all steps/actions and
|
31
|
-
configuration options that are already a part of Devise itself.
|
29
|
+
To make Devise-Basecamper work properly, there are several steps that need to be taken to adjust the "out-of-the-box"
|
30
|
+
behavior of Devise. None of the changes require doing any "hacking" of Devise, as they are all steps/actions and
|
31
|
+
configuration options that are already a part of Devise itself.
|
32
32
|
|
33
33
|
### Devise Configuration
|
34
|
-
Open the Devise initializer file, which can be found in `config/initializers/devise.rb`. Add `:subdomain` to the
|
34
|
+
Open the Devise initializer file, which can be found in `config/initializers/devise.rb`. Add `:subdomain` to the
|
35
35
|
`config.request_keys` array like below.
|
36
36
|
|
37
37
|
config.request_keys = [:subdomain]
|
@@ -40,27 +40,26 @@ This will make sure to pass the subdomain value from the request to the appropri
|
|
40
40
|
|
41
41
|
### Configuring models
|
42
42
|
|
43
|
-
Which ever model you would like to have subdomain based authentication scoping on, just add `:basecamper` to your
|
43
|
+
Which ever model you would like to have subdomain based authentication scoping on, just add `:basecamper` to your
|
44
44
|
included devise modules.
|
45
45
|
|
46
46
|
```
|
47
47
|
class User
|
48
48
|
include Mongoid::Document
|
49
49
|
include Mongoid::Timestamps
|
50
|
-
|
50
|
+
|
51
51
|
devise :database_authenticatable,
|
52
52
|
:recoverable,
|
53
53
|
:trackable,
|
54
54
|
:validatable,
|
55
55
|
:basecamper
|
56
|
-
|
57
56
|
...
|
58
57
|
end
|
59
58
|
```
|
60
59
|
|
61
60
|
By default, Devise-Basecamper assumes that your devise model "belongs to" an Account and has a field called `account_id`
|
62
61
|
as the foreign key to that table. Devise-Basecamper also assumes that the subdomain field exists in your Account model
|
63
|
-
and is called `subdomain`. Now that's a lot of assumptions, but never fear...they can be changed.
|
62
|
+
and is called `subdomain`. Now that's a lot of assumptions, but never fear...they can be changed.
|
64
63
|
|
65
64
|
If you need to change any of these assumptions, you can do so by calling the `devise_basecamper` method in your devise
|
66
65
|
model.
|
@@ -69,22 +68,22 @@ model.
|
|
69
68
|
class User
|
70
69
|
include Mongoid::Document
|
71
70
|
include Mongoid::Timestamps
|
72
|
-
|
71
|
+
|
73
72
|
devise :database_authenticatable,
|
74
73
|
:recoverable,
|
75
74
|
:trackable,
|
76
75
|
:validatable,
|
77
76
|
:basecamper
|
78
|
-
|
77
|
+
|
79
78
|
devise_basecamper :subdomain_class => :my_parent_class,
|
80
79
|
:subdomain_field => :my_field_name,
|
81
80
|
:scope_field => :field_to_scope_against
|
82
|
-
|
81
|
+
|
83
82
|
...
|
84
83
|
end
|
85
84
|
```
|
86
85
|
|
87
|
-
The `devise_basecamper` method has 3 options that can be set: subdomain_class, subdomain_field and scope_field.
|
86
|
+
The `devise_basecamper` method has 3 options that can be set: subdomain_class, subdomain_field and scope_field.
|
88
87
|
|
89
88
|
**subdomain_class**
|
90
89
|
|
@@ -93,7 +92,7 @@ to be an `Account` object.
|
|
93
92
|
|
94
93
|
**subdomain_field**
|
95
94
|
|
96
|
-
This option allows you to specify the name of the field within the `subdomain_class` that the subdomain string is stored
|
95
|
+
This option allows you to specify the name of the field within the `subdomain_class` that the subdomain string is stored
|
97
96
|
in. By default, devise_basecamper assumes this to be `subdomain`.
|
98
97
|
|
99
98
|
**scope_field**
|
@@ -119,27 +118,65 @@ class ApplicationController < ActionController::Base
|
|
119
118
|
protect_from_forgery
|
120
119
|
helper_method :subdomain, :current_account
|
121
120
|
before_filter :validate_subdomain, :authenticate_user!
|
122
|
-
|
121
|
+
|
123
122
|
private # ----------------------------------------------------
|
124
|
-
|
123
|
+
|
125
124
|
def current_acount
|
126
125
|
# The where clause is assuming you are using Mongoid, change appropriately
|
127
126
|
# for ActiveRecord or a different supported ORM.
|
128
127
|
@current_account ||= Association.where(subdomain: subdomain).first
|
129
128
|
end
|
130
|
-
|
129
|
+
|
131
130
|
def subdomain
|
132
131
|
request.subdomain
|
133
132
|
end
|
134
|
-
|
133
|
+
|
135
134
|
# This will redirect the user to your 404 page if the account can not be found
|
136
|
-
# based on the subdomain. You can change this to whatever best fits your
|
135
|
+
# based on the subdomain. You can change this to whatever best fits your
|
137
136
|
# application.
|
138
137
|
def validate_subdomain
|
139
138
|
redirect_to '/404.html' if current_account.nil?
|
140
139
|
end
|
141
140
|
end
|
142
141
|
```
|
142
|
+
### Devise Recoverable ###
|
143
|
+
|
144
|
+
Devise provides the Recoverable module to implement standard password recovery practices. This module needs a little help working with the *basecamp style*
|
145
|
+
authentication, making sure to find the correct user account, under the correct subdomain.
|
146
|
+
|
147
|
+
To implement subdomain-based lookups using the devise Recoverable module, you will need to uncomment the `reset_password_keys` section in `devise.rb`.
|
148
|
+
This should be around line 158 in your devise.rb file. Then update the line to look like the following:
|
149
|
+
|
150
|
+
```
|
151
|
+
# ==> Configuration for :recoverable
|
152
|
+
#
|
153
|
+
# Defines which key will be used when recovering the password for an account
|
154
|
+
config.reset_password_keys = [ :email, :subdomain ]
|
155
|
+
```
|
156
|
+
You can add whatever field name you would like here, but :subdomain is probably the best choice.
|
157
|
+
|
158
|
+
Next we will need to override the default view for the passwords controller. Follow the directions from the
|
159
|
+
[devise readme](https://github.com/plataformatec/devise) if you don't know how to do this. Find the proper view
|
160
|
+
equivelant in your application for `devise/passwords/new.html.erb` and add a hidden field for the subdomain value.
|
161
|
+
You will then want to default its value to the subdomain we are scoping to. This value will then be included in the
|
162
|
+
form submit and processed properly by devise-basecamper.
|
163
|
+
|
164
|
+
Support has also been added for confirmation emails thanks to juliobetta.
|
165
|
+
|
166
|
+
Example form:
|
167
|
+
```
|
168
|
+
<h2>Forgot your password?</h2>
|
169
|
+
<%= render "flashes" %>
|
170
|
+
<%= simple_form_for resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post } do |f| %>
|
171
|
+
<%= hidden_field_tag 'user[subdomain]', subdomain %>
|
172
|
+
<%= f.input :email %>
|
173
|
+
<%= f.button :submit, "Send me reset password instructions" %>
|
174
|
+
<% end %>
|
175
|
+
|
176
|
+
<%= render "devise/shared/links" %>
|
177
|
+
```
|
178
|
+
**NOTE** Notice that the hidden field is named 'user[subdomain]'. This is absolutely necessary to make sure that the value is passed
|
179
|
+
to the handling devise methods. However, *user* is **NOT** the hard rule, use whatever the appropriate model name is for your application.
|
143
180
|
|
144
181
|
### ORM Compatability
|
145
182
|
|
@@ -148,6 +185,10 @@ and should work just fine with all of the ORM's supported by Devise.
|
|
148
185
|
|
149
186
|
MORE TO COME
|
150
187
|
|
188
|
+
### Contributing ###
|
189
|
+
|
190
|
+
If you would like to contribute to this project, please fork it and submit pull requests with your code changes. I'm pretty much making updates to this as needed for my own projects right now, so it doesn't change super often and help would definately be appreciated.
|
191
|
+
|
151
192
|
## License
|
152
193
|
|
153
194
|
MIT License. Copyright © 2012 Digital Opera, LLC. [www.digitalopera.com](http://www.digitalopera.com/ "Digital Opera, LLC")
|
@@ -35,11 +35,23 @@ module Devise
|
|
35
35
|
# We want to override this method to find our users within the scope
|
36
36
|
# of our subdomain.
|
37
37
|
def send_reset_password_instructions(attributes={})
|
38
|
+
send_instructions_for(:reset_password, attributes)
|
39
|
+
end
|
40
|
+
|
41
|
+
def send_confirmation_instructions(attributes={})
|
42
|
+
send_instructions_for(:confirmation, attributes)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def send_instructions_for(action_method, attributes={})
|
38
48
|
resource = self.basecamper[:subdomain_class].to_s.camelize.constantize
|
39
49
|
subdomain_source = resource.to_adapter.find_first(self.basecamper[:subdomain_field] => attributes[:subdomain])
|
40
|
-
|
41
|
-
|
42
|
-
|
50
|
+
action_object = find_or_initialize_with_errors([self.basecamper[:scope_field], :email], {
|
51
|
+
:email => attributes[:email], self.basecamper[:scope_field] => (subdomain_source.nil? ? nil : subdomain_source.id.to_s)
|
52
|
+
})
|
53
|
+
action_object.send("send_#{action_method.to_s}_instructions") if action_object.persisted?
|
54
|
+
action_object
|
43
55
|
end
|
44
56
|
end
|
45
57
|
end
|
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.2.
|
4
|
+
version: 0.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-11-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: orm_adapter
|
@@ -73,18 +73,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
73
73
|
- - ! '>='
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
|
-
segments:
|
77
|
-
- 0
|
78
|
-
hash: -987934111135055412
|
79
76
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
77
|
none: false
|
81
78
|
requirements:
|
82
79
|
- - ! '>='
|
83
80
|
- !ruby/object:Gem::Version
|
84
81
|
version: '0'
|
85
|
-
segments:
|
86
|
-
- 0
|
87
|
-
hash: -987934111135055412
|
88
82
|
requirements: []
|
89
83
|
rubyforge_project:
|
90
84
|
rubygems_version: 1.8.24
|