oath 1.1.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.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/.travis.yml +3 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +165 -0
- data/LICENSE.txt +22 -0
- data/NEWS.rdoc +118 -0
- data/README.md +384 -0
- data/Rakefile +6 -0
- data/lib/oath.rb +132 -0
- data/lib/oath/back_door.rb +53 -0
- data/lib/oath/configuration.rb +149 -0
- data/lib/oath/constraints/signed_in.rb +14 -0
- data/lib/oath/constraints/signed_out.rb +14 -0
- data/lib/oath/controller_helpers.rb +161 -0
- data/lib/oath/failure_app.rb +48 -0
- data/lib/oath/field_map.rb +56 -0
- data/lib/oath/param_transformer.rb +38 -0
- data/lib/oath/railtie.rb +11 -0
- data/lib/oath/services.rb +5 -0
- data/lib/oath/services/authentication.rb +40 -0
- data/lib/oath/services/password_reset.rb +27 -0
- data/lib/oath/services/sign_in.rb +25 -0
- data/lib/oath/services/sign_out.rb +24 -0
- data/lib/oath/services/sign_up.rb +42 -0
- data/lib/oath/strategies/password_strategy.rb +42 -0
- data/lib/oath/test/controller_helpers.rb +43 -0
- data/lib/oath/test/helpers.rb +24 -0
- data/lib/oath/version.rb +4 -0
- data/lib/oath/warden_setup.rb +47 -0
- data/oath.gemspec +30 -0
- data/spec/features/user/user_signs_in_spec.rb +14 -0
- data/spec/features/user/user_signs_in_through_back_door_spec.rb +11 -0
- data/spec/features/user/user_tries_to_access_constrained_routes_spec.rb +18 -0
- data/spec/features/user/user_tries_to_access_http_auth_page_spec.rb +9 -0
- data/spec/features/visitor/visitor_fails_to_sign_up_spec.rb +10 -0
- data/spec/features/visitor/visitor_is_unauthorized_spec.rb +8 -0
- data/spec/features/visitor/visitor_signs_in_via_invalid_form_spec.rb +11 -0
- data/spec/features/visitor/visitor_signs_up_spec.rb +40 -0
- data/spec/features/visitor/visitor_tries_to_access_constrained_routes_spec.rb +14 -0
- data/spec/features/visitor/visitor_uses_remember_token_spec.rb +13 -0
- data/spec/oath/configuration_spec.rb +11 -0
- data/spec/oath/controller_helpers_spec.rb +180 -0
- data/spec/oath/field_map_spec.rb +19 -0
- data/spec/oath/services/authentication_spec.rb +25 -0
- data/spec/oath/services/password_reset_spec.rb +24 -0
- data/spec/oath/services/sign_in_spec.rb +13 -0
- data/spec/oath/services/sign_out_spec.rb +13 -0
- data/spec/oath/services/sign_up_spec.rb +49 -0
- data/spec/oath/strategies/password_strategy_spec.rb +23 -0
- data/spec/oath/test_controller_helpers_spec.rb +63 -0
- data/spec/oath/test_helpers_spec.rb +97 -0
- data/spec/oath_spec.rb +27 -0
- data/spec/rails_app/Rakefile +7 -0
- data/spec/rails_app/app/assets/images/rails.png +0 -0
- data/spec/rails_app/app/assets/javascripts/application.js +13 -0
- data/spec/rails_app/app/assets/stylesheets/application.css +13 -0
- data/spec/rails_app/app/controllers/application_controller.rb +4 -0
- data/spec/rails_app/app/controllers/basic_auth_controller.rb +7 -0
- data/spec/rails_app/app/controllers/constrained_to_users_controller.rb +5 -0
- data/spec/rails_app/app/controllers/constrained_to_visitors_controller.rb +5 -0
- data/spec/rails_app/app/controllers/failures_controller.rb +5 -0
- data/spec/rails_app/app/controllers/invalid_sessions_controller.rb +2 -0
- data/spec/rails_app/app/controllers/posts_controller.rb +6 -0
- data/spec/rails_app/app/controllers/sessions_controller.rb +26 -0
- data/spec/rails_app/app/controllers/users_controller.rb +23 -0
- data/spec/rails_app/app/helpers/application_helper.rb +2 -0
- data/spec/rails_app/app/models/user.rb +10 -0
- data/spec/rails_app/app/views/invalid_sessions/new.html.erb +4 -0
- data/spec/rails_app/app/views/layouts/application.html.erb +18 -0
- data/spec/rails_app/app/views/posts/index.html.erb +1 -0
- data/spec/rails_app/app/views/sessions/new.html.erb +5 -0
- data/spec/rails_app/app/views/users/new.html.erb +5 -0
- data/spec/rails_app/config.ru +4 -0
- data/spec/rails_app/config/application.rb +58 -0
- data/spec/rails_app/config/boot.rb +6 -0
- data/spec/rails_app/config/database.yml +25 -0
- data/spec/rails_app/config/environment.rb +5 -0
- data/spec/rails_app/config/environments/development.rb +29 -0
- data/spec/rails_app/config/environments/production.rb +54 -0
- data/spec/rails_app/config/environments/test.rb +29 -0
- data/spec/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/rails_app/config/initializers/inflections.rb +15 -0
- data/spec/rails_app/config/initializers/secret_token.rb +7 -0
- data/spec/rails_app/config/routes.rb +24 -0
- data/spec/rails_app/db/seeds.rb +7 -0
- data/spec/rails_app/public/404.html +26 -0
- data/spec/rails_app/public/422.html +26 -0
- data/spec/rails_app/public/500.html +25 -0
- data/spec/rails_app/public/favicon.ico +0 -0
- data/spec/rails_app/script/rails +6 -0
- data/spec/spec_helper.rb +37 -0
- metadata +325 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 68aae5082f1c535f427988290c1424f11b415313
|
4
|
+
data.tar.gz: 680198b631bfc9e899c17ed0618cd62d0af0d4f4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 953c7077d5abff66905acdd54eee2de098ade20a6d39edc7ca3f718d97ae26b6a52a9c3dbbc7c846f3c55ac0b79ab87cb53139e046a192b8e46ff05517180a63
|
7
|
+
data.tar.gz: b389a8c3bea393096bc1114f0de8aa5ece4332019ad7e4d8c7de36cff6e197e2269a3528ec6231d02cf5be3405fb21da9403e63fc59be0fc888856cfb4ba73db
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
oath (1.1.0)
|
5
|
+
bcrypt
|
6
|
+
rails
|
7
|
+
warden
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
actioncable (5.1.4)
|
13
|
+
actionpack (= 5.1.4)
|
14
|
+
nio4r (~> 2.0)
|
15
|
+
websocket-driver (~> 0.6.1)
|
16
|
+
actionmailer (5.1.4)
|
17
|
+
actionpack (= 5.1.4)
|
18
|
+
actionview (= 5.1.4)
|
19
|
+
activejob (= 5.1.4)
|
20
|
+
mail (~> 2.5, >= 2.5.4)
|
21
|
+
rails-dom-testing (~> 2.0)
|
22
|
+
actionpack (5.1.4)
|
23
|
+
actionview (= 5.1.4)
|
24
|
+
activesupport (= 5.1.4)
|
25
|
+
rack (~> 2.0)
|
26
|
+
rack-test (>= 0.6.3)
|
27
|
+
rails-dom-testing (~> 2.0)
|
28
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
29
|
+
actionview (5.1.4)
|
30
|
+
activesupport (= 5.1.4)
|
31
|
+
builder (~> 3.1)
|
32
|
+
erubi (~> 1.4)
|
33
|
+
rails-dom-testing (~> 2.0)
|
34
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
35
|
+
active_hash (1.5.2)
|
36
|
+
activesupport (>= 2.2.2)
|
37
|
+
activejob (5.1.4)
|
38
|
+
activesupport (= 5.1.4)
|
39
|
+
globalid (>= 0.3.6)
|
40
|
+
activemodel (5.1.4)
|
41
|
+
activesupport (= 5.1.4)
|
42
|
+
activerecord (5.1.4)
|
43
|
+
activemodel (= 5.1.4)
|
44
|
+
activesupport (= 5.1.4)
|
45
|
+
arel (~> 8.0)
|
46
|
+
activesupport (5.1.4)
|
47
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
48
|
+
i18n (~> 0.7)
|
49
|
+
minitest (~> 5.1)
|
50
|
+
tzinfo (~> 1.1)
|
51
|
+
addressable (2.5.2)
|
52
|
+
public_suffix (>= 2.0.2, < 4.0)
|
53
|
+
arel (8.0.0)
|
54
|
+
bcrypt (3.1.11)
|
55
|
+
builder (3.2.3)
|
56
|
+
capybara (2.16.1)
|
57
|
+
addressable
|
58
|
+
mini_mime (>= 0.1.3)
|
59
|
+
nokogiri (>= 1.3.3)
|
60
|
+
rack (>= 1.0.0)
|
61
|
+
rack-test (>= 0.5.4)
|
62
|
+
xpath (~> 2.0)
|
63
|
+
concurrent-ruby (1.0.5)
|
64
|
+
crass (1.0.3)
|
65
|
+
diff-lcs (1.3)
|
66
|
+
erubi (1.7.0)
|
67
|
+
globalid (0.4.1)
|
68
|
+
activesupport (>= 4.2.0)
|
69
|
+
i18n (0.9.1)
|
70
|
+
concurrent-ruby (~> 1.0)
|
71
|
+
loofah (2.1.1)
|
72
|
+
crass (~> 1.0.2)
|
73
|
+
nokogiri (>= 1.5.9)
|
74
|
+
mail (2.7.0)
|
75
|
+
mini_mime (>= 0.1.1)
|
76
|
+
method_source (0.9.0)
|
77
|
+
mini_mime (1.0.0)
|
78
|
+
mini_portile2 (2.3.0)
|
79
|
+
minitest (5.10.3)
|
80
|
+
nio4r (2.1.0)
|
81
|
+
nokogiri (1.8.1)
|
82
|
+
mini_portile2 (~> 2.3.0)
|
83
|
+
public_suffix (3.0.1)
|
84
|
+
rack (2.0.3)
|
85
|
+
rack-test (0.8.2)
|
86
|
+
rack (>= 1.0, < 3)
|
87
|
+
rails (5.1.4)
|
88
|
+
actioncable (= 5.1.4)
|
89
|
+
actionmailer (= 5.1.4)
|
90
|
+
actionpack (= 5.1.4)
|
91
|
+
actionview (= 5.1.4)
|
92
|
+
activejob (= 5.1.4)
|
93
|
+
activemodel (= 5.1.4)
|
94
|
+
activerecord (= 5.1.4)
|
95
|
+
activesupport (= 5.1.4)
|
96
|
+
bundler (>= 1.3.0)
|
97
|
+
railties (= 5.1.4)
|
98
|
+
sprockets-rails (>= 2.0.0)
|
99
|
+
rails-dom-testing (2.0.3)
|
100
|
+
activesupport (>= 4.2.0)
|
101
|
+
nokogiri (>= 1.6)
|
102
|
+
rails-html-sanitizer (1.0.3)
|
103
|
+
loofah (~> 2.0)
|
104
|
+
railties (5.1.4)
|
105
|
+
actionpack (= 5.1.4)
|
106
|
+
activesupport (= 5.1.4)
|
107
|
+
method_source
|
108
|
+
rake (>= 0.8.7)
|
109
|
+
thor (>= 0.18.1, < 2.0)
|
110
|
+
rake (12.3.0)
|
111
|
+
rspec (3.7.0)
|
112
|
+
rspec-core (~> 3.7.0)
|
113
|
+
rspec-expectations (~> 3.7.0)
|
114
|
+
rspec-mocks (~> 3.7.0)
|
115
|
+
rspec-core (3.7.0)
|
116
|
+
rspec-support (~> 3.7.0)
|
117
|
+
rspec-expectations (3.7.0)
|
118
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
119
|
+
rspec-support (~> 3.7.0)
|
120
|
+
rspec-mocks (3.7.0)
|
121
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
122
|
+
rspec-support (~> 3.7.0)
|
123
|
+
rspec-rails (3.7.2)
|
124
|
+
actionpack (>= 3.0)
|
125
|
+
activesupport (>= 3.0)
|
126
|
+
railties (>= 3.0)
|
127
|
+
rspec-core (~> 3.7.0)
|
128
|
+
rspec-expectations (~> 3.7.0)
|
129
|
+
rspec-mocks (~> 3.7.0)
|
130
|
+
rspec-support (~> 3.7.0)
|
131
|
+
rspec-support (3.7.0)
|
132
|
+
sprockets (3.7.1)
|
133
|
+
concurrent-ruby (~> 1.0)
|
134
|
+
rack (> 1, < 3)
|
135
|
+
sprockets-rails (3.2.1)
|
136
|
+
actionpack (>= 4.0)
|
137
|
+
activesupport (>= 4.0)
|
138
|
+
sprockets (>= 3.0.0)
|
139
|
+
sqlite3 (1.3.13)
|
140
|
+
thor (0.20.0)
|
141
|
+
thread_safe (0.3.6)
|
142
|
+
tzinfo (1.2.4)
|
143
|
+
thread_safe (~> 0.1)
|
144
|
+
warden (1.2.7)
|
145
|
+
rack (>= 1.0)
|
146
|
+
websocket-driver (0.6.5)
|
147
|
+
websocket-extensions (>= 0.1.0)
|
148
|
+
websocket-extensions (0.1.3)
|
149
|
+
xpath (2.1.0)
|
150
|
+
nokogiri (~> 1.3)
|
151
|
+
|
152
|
+
PLATFORMS
|
153
|
+
ruby
|
154
|
+
|
155
|
+
DEPENDENCIES
|
156
|
+
active_hash
|
157
|
+
capybara
|
158
|
+
oath!
|
159
|
+
rake
|
160
|
+
rspec
|
161
|
+
rspec-rails
|
162
|
+
sqlite3
|
163
|
+
|
164
|
+
BUNDLED WITH
|
165
|
+
1.16.0
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 halogenandtoast
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/NEWS.rdoc
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
== 1.1.0
|
2
|
+
* `Oath.config.sign_in_notice` should now be a callable object in order for I18n to work correctly
|
3
|
+
* [DEPRECATED] you should no longer set `Oath.config.sign_in_notice` to a string value
|
4
|
+
|
5
|
+
== 1.0.1
|
6
|
+
* Wrap helper_method calls in respond_to?(:helper_method)
|
7
|
+
* param_transformations now correctly use string keys
|
8
|
+
|
9
|
+
== 1.0.0
|
10
|
+
* Do not perform lookup if no params are passed to lookup
|
11
|
+
* Add param transformer for sanitizing and normalizing
|
12
|
+
|
13
|
+
== 0.3.1
|
14
|
+
* Extend private interface for services
|
15
|
+
|
16
|
+
== 0.3.0
|
17
|
+
* Warden serialization is now configurable
|
18
|
+
|
19
|
+
== 0.2.1
|
20
|
+
* Updated documentation for test helpers
|
21
|
+
* Updated documentation for using oath in console
|
22
|
+
* Fixed bug with failure app now allowing actual http auth to occur
|
23
|
+
|
24
|
+
== 0.2.0
|
25
|
+
* `sign_in` test helper now returns the user
|
26
|
+
* `authenticate_session` arguments are coerced to Hash
|
27
|
+
* Oath::BackDoor can be configured with a block
|
28
|
+
* Document validation suggestions
|
29
|
+
* Document locale suggestions
|
30
|
+
* Deprecate usage of Oath.user_class in favor of Oath.config.user_class
|
31
|
+
* Make warden strategy configurable via Oath.config.authentication_strategy
|
32
|
+
* Extract warden setup into the WardenSetup class
|
33
|
+
* Document layout suggestions
|
34
|
+
|
35
|
+
== 0.1.1
|
36
|
+
* Link to Rubydoc in documentation
|
37
|
+
* Fix header in documentation
|
38
|
+
* Fix no_login_redirect to default to a properly named controller
|
39
|
+
* Fix documentation reference to sign_up to mention user_params instead of user
|
40
|
+
|
41
|
+
== 0.1.0
|
42
|
+
* Fix PasswordStrategy to use configuration options
|
43
|
+
* Documentation
|
44
|
+
* Renamed encryption to hashing
|
45
|
+
* Renamed encrypted to digested
|
46
|
+
* Renamed unencrypted to undigested
|
47
|
+
* A configuration for `no_login_redirect` was added. This accepts anything that
|
48
|
+
can be passed to `redirect_to` and is used when `require_login` is called with
|
49
|
+
no logged in user.
|
50
|
+
* A configuration for `no_login_handler` was added. This allows developers to
|
51
|
+
completely customize the response when `require_login` is called with no
|
52
|
+
logged in user.
|
53
|
+
|
54
|
+
== 0.0.15
|
55
|
+
* Delegate user_class correctly so that config returns class
|
56
|
+
* Fixed issue authenticate session not allowing for multiple fields
|
57
|
+
* Do not hardcode User class
|
58
|
+
* Add signed out routing constraint
|
59
|
+
* Backfill NEWS.md
|
60
|
+
|
61
|
+
== 0.0.14
|
62
|
+
* Encryption of empty string is empty string.
|
63
|
+
* Remove last trace of generators.
|
64
|
+
|
65
|
+
== 0.0.13
|
66
|
+
* Oath requires Rails 4+.
|
67
|
+
* Move generators to the oath-generators gem.
|
68
|
+
|
69
|
+
== 0.0.12
|
70
|
+
* Ensure forms can't be tampered with by providing no username.
|
71
|
+
* Prevent hashing of empty string passwords.
|
72
|
+
* Memoize the configuration.
|
73
|
+
|
74
|
+
== 0.0.11
|
75
|
+
* Add `Oath::Backdoor` for easier tests.
|
76
|
+
|
77
|
+
== 0.0.10
|
78
|
+
* Add Oath::Test::ControllerHelpers for controller specs.
|
79
|
+
* Depend on the bcrypt gem, not the bcrypt-ruby gem.
|
80
|
+
|
81
|
+
== 0.0.9
|
82
|
+
* Make user creation method configurable.
|
83
|
+
* Redirect to SessionsController#new, ignoring namespace.
|
84
|
+
* Add `Oath.config.creation_method`.
|
85
|
+
|
86
|
+
== 0.0.8
|
87
|
+
* Now configurable via `Oath.configure`:
|
88
|
+
* sign in service
|
89
|
+
* sign up service
|
90
|
+
* authentication service
|
91
|
+
* user_token_store_field
|
92
|
+
* user_token_field
|
93
|
+
* Add PasswordReset service.
|
94
|
+
* Rename controller_helpers to services.
|
95
|
+
* Allos blocks to be passed into sign_in and sign_up.
|
96
|
+
* Fix error on trying to respond with HTTP 401.
|
97
|
+
* Oath does not generate a User model for you.
|
98
|
+
* Add `Oath.test_mode!` and `Oath.test_reset!`.
|
99
|
+
* Add a lot of tests.
|
100
|
+
|
101
|
+
== 0.0.7
|
102
|
+
* Check for Rails 4 or the strong_parameters gem, not just the strong_parameters gem
|
103
|
+
|
104
|
+
== 0.0.6
|
105
|
+
* [FIX] require_login should use controller and action for routing.
|
106
|
+
|
107
|
+
== 0.0.5
|
108
|
+
* [FIX] Scaffolded SessionsController should have respond_to.
|
109
|
+
* [FIX] SignUp should get the value instead of slicing.
|
110
|
+
|
111
|
+
== 0.0.4
|
112
|
+
* Cleaned up generated controllers.
|
113
|
+
* Use find_by_id instead of find so invalid sessions don't cause apps to crash.
|
114
|
+
* Hashes passed in are no longer mutated via delete.
|
115
|
+
|
116
|
+
== 0.0.3
|
117
|
+
|
118
|
+
* Fixed bug where password wasn't deleted from session params which would cause lookup to fail.
|
data/README.md
ADDED
@@ -0,0 +1,384 @@
|
|
1
|
+
|
2
|
+
# Oath
|
3
|
+
|
4
|
+
[](https://gitter.im/halogenandtoast/oath?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
5
|
+
|
6
|
+
[](https://travis-ci.org/halogenandtoast/oath)
|
7
|
+
[](https://codeclimate.com/github/halogenandtoast/oath)
|
8
|
+
|
9
|
+
Oath is designed to be a very simple and extensible user authentication
|
10
|
+
library for rails. Its goal is to give all the power to the developer instead
|
11
|
+
of forcing them to make Oath work with their system.
|
12
|
+
|
13
|
+
## Why use Oath?
|
14
|
+
|
15
|
+
Oath makes authentication simple:
|
16
|
+
|
17
|
+
- Easy to use in tests with dependency injection
|
18
|
+
- Provides convenient controller helpers
|
19
|
+
- Very customizable
|
20
|
+
|
21
|
+
Oath doesn't do the following:
|
22
|
+
|
23
|
+
- Doesn't automatically add routes to your application
|
24
|
+
- Doesn't force you to use engine based controllers or views
|
25
|
+
- Doesn't require you to make changes to your user model
|
26
|
+
|
27
|
+
## Documentation
|
28
|
+
|
29
|
+
You can read the full documentation at [rubydoc](http://rubydoc.info/github/halogenandtoast/oath)
|
30
|
+
|
31
|
+
## Installation
|
32
|
+
|
33
|
+
Oath was designed to work with Rails > 4.0. Add this line to your Gemfile:
|
34
|
+
|
35
|
+
gem 'oath'
|
36
|
+
|
37
|
+
Then inside of your ApplicationController add the following:
|
38
|
+
|
39
|
+
include Oath::ControllerHelpers
|
40
|
+
|
41
|
+
And you're ready to start designing your authentication system.
|
42
|
+
|
43
|
+
## Generators
|
44
|
+
|
45
|
+
If you'd like a good starting point for building an app using Oath, it is suggested to use the [oath generators]
|
46
|
+
|
47
|
+
## Usage
|
48
|
+
|
49
|
+
Oath does currently have some out-of-the-box expectations, but you can
|
50
|
+
configure and change any of these:
|
51
|
+
|
52
|
+
- By default the model should be called `User`
|
53
|
+
- Oath expects your user model to respond to `create`, `id`, and `find_by`
|
54
|
+
- You should have an `email` and `password_digest` column on your `User`
|
55
|
+
- Passwords will be handled with BCrypt
|
56
|
+
|
57
|
+
### Suggestions
|
58
|
+
|
59
|
+
#### Console Usage
|
60
|
+
|
61
|
+
If you're trying to sign up a User in a console you won't be able to call User#new or User#create because the User model does not know how to encrypt passwords.
|
62
|
+
You should instead use the sign up service in order to create the user:
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
Oath.config.sign_up_service.new(email: "foo@example.com", password: "password").perform
|
66
|
+
```
|
67
|
+
|
68
|
+
#### Validations
|
69
|
+
|
70
|
+
Oath doesn't add validations to your user model unless you're using [oath generators] so it's suggested to add the following validations:
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
validates :email, presence: true, uniqueness: true
|
74
|
+
validates :password_digest, presence: true
|
75
|
+
```
|
76
|
+
|
77
|
+
In addition to that you'll want to add the following to your `config/locale/en.yml`:
|
78
|
+
|
79
|
+
```yaml
|
80
|
+
en:
|
81
|
+
activerecord:
|
82
|
+
attributes:
|
83
|
+
user:
|
84
|
+
password_digest: "Password"
|
85
|
+
```
|
86
|
+
|
87
|
+
Which will generate the error message `Password can't be blank` instead of `Password digest can't be blank`.
|
88
|
+
|
89
|
+
#### Layout changes
|
90
|
+
|
91
|
+
It is suggested you add something like this to your application layout:
|
92
|
+
|
93
|
+
```erb
|
94
|
+
<% if signed_in? %>
|
95
|
+
<%= link_to "Sign out", session_path, method: :delete %>
|
96
|
+
<% else %>
|
97
|
+
<%= link_to "Sign in", new_session_path %>
|
98
|
+
<%= link_to "Sign up", new_user_path %>
|
99
|
+
<% end %>
|
100
|
+
```
|
101
|
+
|
102
|
+
#### Guest user
|
103
|
+
|
104
|
+
If you want to introduce a Guest object when a user is not signed in, you can override Oath's `current_user` method in your `ApplicationController`:
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
def current_user
|
108
|
+
super || Guest.new
|
109
|
+
end
|
110
|
+
```
|
111
|
+
|
112
|
+
In `app/models/`, define a `Guest` class:
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
class Guest
|
116
|
+
def name
|
117
|
+
"Guest"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
```
|
121
|
+
|
122
|
+
This article on the [Null Object Pattern](http://robots.thoughtbot.com/handling-associations-on-null-objects) provides a good explanation of why you might want to do this.
|
123
|
+
|
124
|
+
#### Using I18n for sign in notice
|
125
|
+
|
126
|
+
If you want to use I18n for the notice instructing users to sign in when they try to access an unauthorized page you can do so with the following configuration:
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
Oath.configure do |config|
|
130
|
+
config.sign_in_notice = -> { I18n.t("sign_in_notice") }
|
131
|
+
end
|
132
|
+
```
|
133
|
+
|
134
|
+
It is suggested to store this file at `config/initializers/oath.rb`
|
135
|
+
|
136
|
+
### Controller Additions
|
137
|
+
|
138
|
+
Oath provides the following controller methods:
|
139
|
+
|
140
|
+
- `sign_in(user)`
|
141
|
+
- `sign_out`
|
142
|
+
- `sign_up(user_params)`
|
143
|
+
- `authenticate(user, password)`
|
144
|
+
- `authenticate_session(session_params)`
|
145
|
+
- `reset_password(user, password)`
|
146
|
+
|
147
|
+
These helpers:
|
148
|
+
|
149
|
+
- `current_user`
|
150
|
+
- `signed_in?`
|
151
|
+
|
152
|
+
And this filter:
|
153
|
+
|
154
|
+
- `require_login`
|
155
|
+
|
156
|
+
### Routing Constraints
|
157
|
+
|
158
|
+
To authorize users in `config/routes.rb`:
|
159
|
+
|
160
|
+
```ruby
|
161
|
+
require "oath/constraints/signed_in"
|
162
|
+
require "oath/constraints/signed_out"
|
163
|
+
|
164
|
+
Blog::Application.routes.draw do
|
165
|
+
constraints Oath::Constraints::SignedIn.new do
|
166
|
+
root "dashboards#show", as: :dashboard
|
167
|
+
end
|
168
|
+
|
169
|
+
constraints Oath::Constraints::SignedOut.new do
|
170
|
+
root "landings#show"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
```
|
174
|
+
|
175
|
+
## Usage in Tests
|
176
|
+
|
177
|
+
### Test mode
|
178
|
+
|
179
|
+
Oath provides the following:
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
Oath.test_mode!
|
183
|
+
```
|
184
|
+
|
185
|
+
Which will change password hashing method to provide plaintext responses instead of using BCrypt. This will allow you to write factories using the password_digest field:
|
186
|
+
|
187
|
+
```ruby
|
188
|
+
FactoryBot.define do
|
189
|
+
factory :user do
|
190
|
+
username 'wombat'
|
191
|
+
password_digest 'password'
|
192
|
+
end
|
193
|
+
end
|
194
|
+
```
|
195
|
+
|
196
|
+
### Spec helpers
|
197
|
+
|
198
|
+
A couple of convenience methods are available in your tests. In order to set this up you'll want to add the following to `rails_helper.rb` or if that doesn't exist `spec_helper.rb`
|
199
|
+
|
200
|
+
```ruby
|
201
|
+
Oath.test_mode!
|
202
|
+
|
203
|
+
RSpec.configure do |config|
|
204
|
+
config.include Oath::Test::Helpers, type: :feature
|
205
|
+
config.after :each do
|
206
|
+
Oath.test_reset!
|
207
|
+
end
|
208
|
+
end
|
209
|
+
```
|
210
|
+
|
211
|
+
Then you can use any of the [test helpers] in your scenarios
|
212
|
+
|
213
|
+
```ruby
|
214
|
+
feature "A feature spec" do
|
215
|
+
scenario "that requires login" do
|
216
|
+
user = create(:user)
|
217
|
+
sign_in(user)
|
218
|
+
# do something
|
219
|
+
sign_out
|
220
|
+
# do something else
|
221
|
+
end
|
222
|
+
end
|
223
|
+
```
|
224
|
+
|
225
|
+
### Oath Backdoor
|
226
|
+
|
227
|
+
Similar to clearance's backdoor you can visit a path and sign in quickly via
|
228
|
+
|
229
|
+
```ruby
|
230
|
+
user = create(:user)
|
231
|
+
visit dashboard_path(as: user)
|
232
|
+
```
|
233
|
+
|
234
|
+
To enable this functionality you'll want to add the following to `config/environments/test.rb`:
|
235
|
+
|
236
|
+
```ruby
|
237
|
+
config.middleware.insert_after Warden::Manager, Oath::BackDoor
|
238
|
+
```
|
239
|
+
|
240
|
+
If you'd like to find your User model by a field other than `id`, insert the
|
241
|
+
middleware with a block that accepts the `as` query parameter and returns an
|
242
|
+
instance of your User model:
|
243
|
+
|
244
|
+
```ruby
|
245
|
+
config.middleware.insert_after Warden::Manager, Oath::BackDoor do |user_param|
|
246
|
+
User.find_by(username: user_param)
|
247
|
+
end
|
248
|
+
```
|
249
|
+
|
250
|
+
### Controller Specs
|
251
|
+
|
252
|
+
If you are going to write controller tests, helpers are provided for those as well:
|
253
|
+
|
254
|
+
```ruby
|
255
|
+
Oath.test_mode!
|
256
|
+
|
257
|
+
RSpec.configure do |config|
|
258
|
+
config.include Oath::Test::ControllerHelpers, type: :controller
|
259
|
+
config.after :each do
|
260
|
+
Oath.test_reset!
|
261
|
+
end
|
262
|
+
end
|
263
|
+
```
|
264
|
+
|
265
|
+
```ruby
|
266
|
+
require 'spec_helper'
|
267
|
+
|
268
|
+
describe ProtectedController do
|
269
|
+
|
270
|
+
describe "GET 'index'" do
|
271
|
+
it "returns http success when signed in" do
|
272
|
+
user = create(:user)
|
273
|
+
sign_in(user)
|
274
|
+
get 'index'
|
275
|
+
response.should be_success
|
276
|
+
end
|
277
|
+
|
278
|
+
it "redirects when not signed in" do
|
279
|
+
get 'index'
|
280
|
+
response.should be_redirect
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
```
|
285
|
+
|
286
|
+
## Advanced Functionality
|
287
|
+
|
288
|
+
### Authentication with username instead of email
|
289
|
+
|
290
|
+
If you want to sign in with username instead of email just change the configuration option
|
291
|
+
|
292
|
+
```ruby
|
293
|
+
# config/initializers/oath.rb
|
294
|
+
Oath.configure do |config|
|
295
|
+
config.user_lookup_field = :username
|
296
|
+
end
|
297
|
+
```
|
298
|
+
|
299
|
+
If you used the oath:scaffold generator from [oath generators] you'll have to change the following four references to email.
|
300
|
+
|
301
|
+
* In SessionsController#session_params
|
302
|
+
* In UsersController#user_params
|
303
|
+
* The email form field on sessions#new
|
304
|
+
* The email form field on users#new
|
305
|
+
|
306
|
+
### Using multiple lookup fields
|
307
|
+
|
308
|
+
You may perform a look up on a user using multiple fields by doing something like the following:
|
309
|
+
|
310
|
+
```ruby
|
311
|
+
class SessionsController < ApplicationController
|
312
|
+
def create
|
313
|
+
user = authenticate_session(session_params, email_or_username: [:email, :username])
|
314
|
+
|
315
|
+
if sign_in(user)
|
316
|
+
redirect_to(root_path)
|
317
|
+
else
|
318
|
+
render :new
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
private
|
323
|
+
|
324
|
+
def session_params
|
325
|
+
params.require(:session).permit(:email_or_username, :password)
|
326
|
+
end
|
327
|
+
|
328
|
+
end
|
329
|
+
```
|
330
|
+
|
331
|
+
This will allow the user to enter either their username or email to login
|
332
|
+
|
333
|
+
## Configuration
|
334
|
+
|
335
|
+
Oath::Configuration has lots of options for changing how oath works. Currently the options you can change are as follows:
|
336
|
+
|
337
|
+
### User values
|
338
|
+
|
339
|
+
* **user_lookup_field**: (default `:email`) Field in the database to lookup a user by.
|
340
|
+
* **user_token_field**: (default `:password`) Field the form submits containing the undigested password.
|
341
|
+
* **user_token_store_field**: (default: `:password_digest`) Field in the database that stores the user's digested password.
|
342
|
+
* **user_class**: (default: `'User'`) The user class.
|
343
|
+
|
344
|
+
### Services
|
345
|
+
|
346
|
+
* **sign_in_notice**: (default: `You must be signed in`) Rails flash message to set when user signs in.
|
347
|
+
* **sign_in_service**: (default: `Oath::Services::SignIn`) Service for signing a user in.
|
348
|
+
* **sign_up_service**: (default: `Oath::Services::SignUp`) Service for signing a user up.
|
349
|
+
* **sign_out_service**: (default: `Oath::Services::SignOut`) Service for signing a user out.
|
350
|
+
* **authentication_service**: (default: `Oath::Services::Authentication`) Service for authenticated a user.
|
351
|
+
* **password_reset_service**: (default: `Oath::Services::PasswordReset`) Service for resetting a user's password.
|
352
|
+
|
353
|
+
### Rails values
|
354
|
+
|
355
|
+
* **no_login_handler**: A before_action for rails that handles when a user is not signed in.
|
356
|
+
* **no_login_redirect**: Used by the no_login_handler to redirect the user
|
357
|
+
|
358
|
+
### Methods
|
359
|
+
|
360
|
+
* **hashing_method**: Method to hash an undigested password.
|
361
|
+
* **token_comparison**: Method to compare a digested and undigested password.
|
362
|
+
* **creation_method**: Method for creating a user.
|
363
|
+
* **find_method**: Method for finding a user.
|
364
|
+
|
365
|
+
### Warden Settings
|
366
|
+
|
367
|
+
* **failure_app**: Necessary for warden to work. A rack app that handles failures in authentication.
|
368
|
+
|
369
|
+
## Limitations
|
370
|
+
|
371
|
+
Here are a few of the current limitations of oath:
|
372
|
+
|
373
|
+
- Oath assumes you only have one user model.
|
374
|
+
|
375
|
+
## Contributing
|
376
|
+
|
377
|
+
1. [Fork it](https://github.com/halogenandtoast/oath/fork)
|
378
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
379
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
380
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
381
|
+
5. Create new Pull Request
|
382
|
+
|
383
|
+
[oath generators]: https://github.com/halogenandtoast/oath-generators
|
384
|
+
[test helpers]: https://github.com/halogenandtoast/oath/blob/master/lib/oath/test/helpers.rb
|