monban 0.0.15 → 0.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 +4 -4
- data/.gitignore +3 -0
- data/Gemfile.lock +1 -1
- data/NEWS.rdoc +13 -0
- data/README.md +62 -3
- data/lib/monban.rb +51 -10
- data/lib/monban/back_door.rb +17 -0
- data/lib/monban/configuration.rb +47 -16
- data/lib/monban/constraints/signed_in.rb +4 -0
- data/lib/monban/constraints/signed_out.rb +4 -0
- data/lib/monban/controller_helpers.rb +95 -2
- data/lib/monban/field_map.rb +10 -0
- data/lib/monban/railtie.rb +2 -0
- data/lib/monban/services/authentication.rb +29 -17
- data/lib/monban/services/password_reset.rb +18 -9
- data/lib/monban/services/sign_in.rb +16 -7
- data/lib/monban/services/sign_out.rb +14 -6
- data/lib/monban/services/sign_up.rb +30 -21
- data/lib/monban/strategies/password_strategy.rb +28 -3
- data/lib/monban/test/controller_helpers.rb +13 -4
- data/lib/monban/test/helpers.rb +6 -0
- data/lib/monban/version.rb +2 -1
- data/spec/features/visitor/visitor_signs_in_via_invalid_form_spec.rb +1 -1
- data/spec/monban/controller_helpers_spec.rb +10 -8
- data/spec/monban/services/authentication_spec.rb +4 -4
- data/spec/monban/services/password_reset_spec.rb +6 -6
- data/spec/monban/services/sign_in_spec.rb +2 -2
- data/spec/monban/services/sign_out_spec.rb +2 -2
- data/spec/monban/services/sign_up_spec.rb +4 -4
- data/spec/monban/strategies/password_strategy_spec.rb +23 -0
- data/spec/monban_spec.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4f3908fbff78befaa3da1b03f38c0d65d31727e0
|
4
|
+
data.tar.gz: 084f52a5bd3751d14600a9f7f54a3eb5a279f555
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a71edfc56f62eaa9ce703b94e4475e1546a47da7960c426022f22d8f733989dad0106edf3a9c153ae9e4919e6f4ddfc27c0b71e2015a5219b9484d7bd82d50fc
|
7
|
+
data.tar.gz: f8aa579c7a1e9c9f1b4dfaeb3c13f0173853487f12e63b7abbb618f19f9bddd1d71c11ff928e6ee68fa972ca715a04a5b303d7ca29856ba8b81b0eb9e033c591
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
data/NEWS.rdoc
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
== 0.1.0
|
2
|
+
* Fix PasswordStrategy to use configuration options
|
3
|
+
* Documentation
|
4
|
+
* Renamed encryption to hashing
|
5
|
+
* Renamed encrypted to digested
|
6
|
+
* Renamed unencrypted to undigested
|
7
|
+
* A configuration for `no_login_redirect` was added. This accepts anything that
|
8
|
+
can be passed to `redirect_to` and is used when `require_login` is called with
|
9
|
+
no logged in user.
|
10
|
+
* A configuration for `no_login_handler` was added. This allows developers to
|
11
|
+
completely customize the response when `require_login` is called with no
|
12
|
+
logged in user.
|
13
|
+
|
1
14
|
== 0.0.15
|
2
15
|
* Delegate user_class correctly so that config returns class
|
3
16
|
* Fixed issue authenticate session not allowing for multiple fields
|
data/README.md
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
|
1
2
|
# Monban 門番
|
2
3
|
|
3
4
|
[](https://travis-ci.org/halogenandtoast/monban)
|
@@ -36,7 +37,7 @@ And you're ready to start designing your authentication system.
|
|
36
37
|
|
37
38
|
## Generators
|
38
39
|
|
39
|
-
If you'd like a good starting point for building an app using Monban, it is suggested to use the [monban generators]
|
40
|
+
If you'd like a good starting point for building an app using Monban, it is suggested to use the [monban generators]
|
40
41
|
|
41
42
|
## Usage
|
42
43
|
|
@@ -78,7 +79,7 @@ Monban provides the following:
|
|
78
79
|
Monban.test_mode!
|
79
80
|
```
|
80
81
|
|
81
|
-
Which will change password
|
82
|
+
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:
|
82
83
|
|
83
84
|
```ruby
|
84
85
|
FactoryGirl.define do
|
@@ -169,6 +170,26 @@ end
|
|
169
170
|
|
170
171
|
## Advanced Functionality
|
171
172
|
|
173
|
+
### Authentication with username instead of email
|
174
|
+
|
175
|
+
If you want to sign in with username instead of email just change the configuration option
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
# config/initializers/monban.rb
|
179
|
+
Monban.configure do |config|
|
180
|
+
config.user_lookup_field = :username
|
181
|
+
end
|
182
|
+
```
|
183
|
+
|
184
|
+
If you used the monban:scaffold generator from [monban generators] you'll have to change the following four references to email.
|
185
|
+
|
186
|
+
* In SessionsController#session_params
|
187
|
+
* In UsersController#user_params
|
188
|
+
* The email form field on sessions#new
|
189
|
+
* The email form field on users#new
|
190
|
+
|
191
|
+
### Using multiple lookup fields
|
192
|
+
|
172
193
|
You may perform a look up on a user using multiple fields by doing something like the following:
|
173
194
|
|
174
195
|
```ruby
|
@@ -194,7 +215,43 @@ end
|
|
194
215
|
|
195
216
|
This will allow the user to enter either their username or email to login
|
196
217
|
|
197
|
-
|
218
|
+
## Configuration
|
219
|
+
|
220
|
+
Monban::Configuration has lots of options for changing how monban works. Currently the options you can change are as follows:
|
221
|
+
|
222
|
+
### User values
|
223
|
+
|
224
|
+
* **user_lookup_field**: (default `:email`) Field in the database to lookup a user by.
|
225
|
+
* **user_token_field**: (default `:password`) Field the form submits containing the undigested password.
|
226
|
+
* **user_token_store_field**: (default: `:password_digest`) Field in the database that stores the user's digested password.
|
227
|
+
* **user_class**: (default: `User`) The user class.
|
228
|
+
|
229
|
+
### Services
|
230
|
+
|
231
|
+
* **sign_in_notice**: (default: `You must be signed in`) Rails flash message to set when user signs in.
|
232
|
+
* **sign_in_service**: (default: `Monban::Services::SignIn`) Service for signing a user in.
|
233
|
+
* **sign_up_service**: (default: `Monban::Services::SignUp`) Service for signing a user up.
|
234
|
+
* **sign_out_service**: (default: `Monban::Services::SignOut`) Service for signing a user out.
|
235
|
+
* **authentication_service**: (default: `Monban::Services::Authentication`) Service for authenticated a user.
|
236
|
+
* **password_reset_service**: (default: `Monban::Services::PasswordReset`) Service for resetting a user's password.
|
237
|
+
|
238
|
+
### Rails values
|
239
|
+
|
240
|
+
* **no_login_handler**: A before_action for rails that handles when a user is not signed in.
|
241
|
+
* **no_login_redirect**: Used by the no_login_handler to redirect the user
|
242
|
+
|
243
|
+
### Methods
|
244
|
+
|
245
|
+
* **hashing_method**: Method to hash an undigested password.
|
246
|
+
* **token_comparison**: Method to compare a digested and undigested password.
|
247
|
+
* **creation_method**: Method for creating a user.
|
248
|
+
* **find_method**: Method for finding a user.
|
249
|
+
|
250
|
+
### Warden Settings
|
251
|
+
|
252
|
+
* **failure_app**: Necessary for warden to work. A rack app that handles failures in authentication.
|
253
|
+
|
254
|
+
## Limitations
|
198
255
|
|
199
256
|
Here are a few of the current limitations of monban:
|
200
257
|
|
@@ -207,3 +264,5 @@ Here are a few of the current limitations of monban:
|
|
207
264
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
208
265
|
4. Push to the branch (`git push origin my-new-feature`)
|
209
266
|
5. Create new Pull Request
|
267
|
+
|
268
|
+
[monban generators]: https://github.com/halogenandtoast/monban-generators
|
data/lib/monban.rb
CHANGED
@@ -10,6 +10,10 @@ require "monban/field_map"
|
|
10
10
|
require "monban/strategies/password_strategy"
|
11
11
|
require "active_support/core_ext/module/attribute_accessors"
|
12
12
|
|
13
|
+
# Monban is an authentication toolkit designed to allow developers to create their own
|
14
|
+
# authentication solutions. If you're interested in a default implementation try
|
15
|
+
# {http://github.com/halogenandtoast/monban-generators Monban Generators}
|
16
|
+
# @since 0.0.15
|
13
17
|
module Monban
|
14
18
|
mattr_accessor :warden_config
|
15
19
|
mattr_accessor :config
|
@@ -19,42 +23,82 @@ module Monban
|
|
19
23
|
autoload :ControllerHelpers, "monban/test/controller_helpers"
|
20
24
|
end
|
21
25
|
|
22
|
-
|
23
|
-
|
26
|
+
# initialize Monban. Sets up warden and the default configuration.
|
27
|
+
#
|
28
|
+
# @note This is used in {Monban::Railtie} in order to bootstrap Monban
|
29
|
+
# @param warden_config [Warden::Config] the configuration from warden
|
30
|
+
# @see Monban::Railtie
|
31
|
+
# @see Monban::Configuration
|
32
|
+
def self.initialize warden_config
|
33
|
+
setup_config
|
24
34
|
setup_warden_config(warden_config)
|
25
35
|
end
|
26
36
|
|
37
|
+
# compares the token (undigested password) to a digested password
|
38
|
+
#
|
39
|
+
# @param digest [String] A digested password
|
40
|
+
# @param token [String] An undigested password
|
41
|
+
# @see Monban::Configuration#default_token_comparison
|
42
|
+
# @return [Boolean] whether the token and digest match
|
27
43
|
def self.compare_token(digest, token)
|
28
44
|
config.token_comparison.call(digest, token)
|
29
45
|
end
|
30
46
|
|
31
|
-
|
32
|
-
|
47
|
+
# hashes a token
|
48
|
+
#
|
49
|
+
# @param token [String] the password in undigested form
|
50
|
+
# @see Monban::Configuration#default_hashing_method
|
51
|
+
# @return [String] a digest of the token
|
52
|
+
def self.hash_token(token)
|
53
|
+
config.hashing_method.call(token)
|
33
54
|
end
|
34
55
|
|
56
|
+
# the user class
|
57
|
+
#
|
58
|
+
# @see Monban::Configuration#setup_class_defaults
|
59
|
+
# @return [Class] the User class
|
35
60
|
def self.user_class
|
36
61
|
config.user_class
|
37
62
|
end
|
38
63
|
|
64
|
+
# finds a user based on their credentials
|
65
|
+
#
|
66
|
+
# @param params [Hash] a hash of user parameters
|
67
|
+
# @param field_map [FieldMap] a field map in order to allow multiple lookup fields
|
68
|
+
# @see Monban::Configuration#default_find_method
|
69
|
+
# @return [User] if user is found
|
70
|
+
# @return [nil] if no user is found
|
39
71
|
def self.lookup(params, field_map)
|
40
72
|
fields = FieldMap.new(params, field_map).to_fields
|
41
73
|
self.config.find_method.call(fields)
|
42
74
|
end
|
43
75
|
|
76
|
+
# Puts monban into test mode. This will disable hashing passwords
|
77
|
+
# @note You must call this if you want to use monban in your tests
|
44
78
|
def self.test_mode!
|
45
79
|
Warden.test_mode!
|
46
80
|
self.config ||= Monban::Configuration.new
|
47
|
-
config.
|
48
|
-
config.token_comparison = ->(digest,
|
49
|
-
digest ==
|
81
|
+
config.hashing_method = ->(password) { password }
|
82
|
+
config.token_comparison = ->(digest, undigested_password) do
|
83
|
+
digest == undigested_password
|
50
84
|
end
|
51
85
|
end
|
52
86
|
|
87
|
+
# Configures monban
|
88
|
+
#
|
89
|
+
# @yield [configuration] Yield the current configuration
|
90
|
+
# @example A custom configuration
|
91
|
+
# Monban.configure do |config|
|
92
|
+
# config.user_lookup_field = :username
|
93
|
+
# config.user_token_store_field = :hashed_password
|
94
|
+
# end
|
53
95
|
def self.configure(&block)
|
54
96
|
self.config ||= Monban::Configuration.new
|
55
97
|
yield self.config
|
56
98
|
end
|
57
99
|
|
100
|
+
# Resets monban in between tests.
|
101
|
+
# @note You must call this between tests
|
58
102
|
def self.test_reset!
|
59
103
|
Warden.test_reset!
|
60
104
|
end
|
@@ -63,9 +107,6 @@ module Monban
|
|
63
107
|
|
64
108
|
def self.setup_config
|
65
109
|
self.config ||= Monban::Configuration.new
|
66
|
-
if block_given?
|
67
|
-
yield config
|
68
|
-
end
|
69
110
|
end
|
70
111
|
|
71
112
|
def self.setup_warden_config(warden_config)
|
data/lib/monban/back_door.rb
CHANGED
@@ -1,9 +1,26 @@
|
|
1
1
|
module Monban
|
2
|
+
# Middleware used in tests to allow users to be signed in directly, without
|
3
|
+
# having to load and submit the sign in form. The user should be provided by
|
4
|
+
# using the key :as in a hash passed to the path.
|
5
|
+
#
|
6
|
+
# @note This should only be used for testing purposes
|
7
|
+
# @since 0.0.15
|
8
|
+
# @example Using the backdoor in an rspec feature spec
|
9
|
+
# feature "User dashboard" do
|
10
|
+
# scenario "user visits dashboard" do
|
11
|
+
# user = create(:user)
|
12
|
+
# visit dashboard_path(as: user)
|
13
|
+
# expect(page).to have_css("#dashboard")
|
14
|
+
# end
|
15
|
+
# end
|
2
16
|
class BackDoor
|
17
|
+
# Create the a new BackDoor middleware for test purposes
|
18
|
+
# @return [BackDoor]
|
3
19
|
def initialize(app)
|
4
20
|
@app = app
|
5
21
|
end
|
6
22
|
|
23
|
+
# Execute the BackDoor middleware signing in the user specified with :as
|
7
24
|
def call(env)
|
8
25
|
sign_in_through_the_back_door(env)
|
9
26
|
@app.call(env)
|
data/lib/monban/configuration.rb
CHANGED
@@ -1,29 +1,37 @@
|
|
1
1
|
module Monban
|
2
|
+
# Configuration options for Monban
|
3
|
+
# @since 0.0.15
|
2
4
|
class Configuration
|
3
|
-
|
4
5
|
attr_accessor :user_token_field, :user_token_store_field
|
5
|
-
attr_accessor :
|
6
|
+
attr_accessor :hashing_method, :token_comparison, :user_lookup_field
|
6
7
|
attr_accessor :sign_in_notice
|
7
8
|
attr_accessor :sign_in_service, :sign_up_service, :sign_out_service
|
8
9
|
attr_accessor :authentication_service, :password_reset_service
|
9
10
|
attr_accessor :failure_app
|
10
11
|
attr_accessor :creation_method, :find_method
|
12
|
+
attr_accessor :no_login_handler, :no_login_redirect
|
11
13
|
|
12
14
|
attr_writer :user_class
|
13
15
|
|
14
16
|
def initialize
|
15
17
|
setup_class_defaults
|
16
|
-
|
18
|
+
setup_token_hashing
|
17
19
|
setup_notices
|
18
20
|
setup_services
|
19
21
|
setup_requirements
|
20
22
|
end
|
21
23
|
|
24
|
+
# Default creation method. Can be overriden via {Monban.configure}
|
25
|
+
#
|
26
|
+
# @see #creation_method=
|
22
27
|
def default_creation_method
|
23
28
|
->(params) { Monban.user_class.create(params) }
|
24
29
|
end
|
25
30
|
|
26
|
-
|
31
|
+
# Default hashing method. Can be overriden via {Monban.configure}
|
32
|
+
#
|
33
|
+
# @see #hashing_method=
|
34
|
+
def default_hashing_method
|
27
35
|
->(token) do
|
28
36
|
if token.present?
|
29
37
|
BCrypt::Password.create(token)
|
@@ -33,25 +41,47 @@ module Monban
|
|
33
41
|
end
|
34
42
|
end
|
35
43
|
|
44
|
+
# Default find method. Can be overriden via {Monban.configure}
|
45
|
+
#
|
46
|
+
# @see #find_method=
|
47
|
+
# @see Monban.user_class
|
36
48
|
def default_find_method
|
37
49
|
->(params) { Monban.user_class.find_by(params) }
|
38
50
|
end
|
39
51
|
|
40
|
-
|
41
|
-
|
42
|
-
|
52
|
+
# Default token comparison method. Can be overriden via {Monban.configure}
|
53
|
+
#
|
54
|
+
# @see #token_comparison=
|
55
|
+
def default_token_comparison
|
56
|
+
->(digest, undigested_token) do
|
57
|
+
BCrypt::Password.new(digest) == undigested_token
|
43
58
|
end
|
44
59
|
end
|
45
60
|
|
61
|
+
# Default handler when user is not logged in. Can be overriden via {Monban.configure}
|
62
|
+
#
|
63
|
+
# @see #no_login_handler=
|
64
|
+
# @see #sign_in_notice
|
65
|
+
# @see #no_login_redirect
|
66
|
+
def default_no_login_handler
|
67
|
+
->(controller) do
|
68
|
+
controller.flash.notice = Monban.config.sign_in_notice
|
69
|
+
controller.redirect_to Monban.config.no_login_redirect
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# User class. Can be overriden via {Monban.configure}
|
74
|
+
#
|
75
|
+
# @see #user_class=
|
46
76
|
def user_class
|
47
77
|
@user_class.constantize
|
48
78
|
end
|
49
79
|
|
50
80
|
private
|
51
81
|
|
52
|
-
def
|
53
|
-
@
|
54
|
-
@token_comparison =
|
82
|
+
def setup_token_hashing
|
83
|
+
@hashing_method = default_hashing_method
|
84
|
+
@token_comparison = default_token_comparison
|
55
85
|
end
|
56
86
|
|
57
87
|
def setup_notices
|
@@ -65,19 +95,20 @@ module Monban
|
|
65
95
|
@user_lookup_field = :email
|
66
96
|
@creation_method = default_creation_method
|
67
97
|
@find_method = default_find_method
|
98
|
+
@no_login_redirect = { controller: '/session', action: 'new' }
|
99
|
+
@no_login_handler = default_no_login_handler
|
68
100
|
end
|
69
101
|
|
70
102
|
def setup_services
|
71
|
-
@authentication_service = Monban::Authentication
|
72
|
-
@sign_in_service = Monban::SignIn
|
73
|
-
@sign_up_service = Monban::SignUp
|
74
|
-
@sign_out_service = Monban::SignOut
|
75
|
-
@password_reset_service = Monban::PasswordReset
|
103
|
+
@authentication_service = Monban::Services::Authentication
|
104
|
+
@sign_in_service = Monban::Services::SignIn
|
105
|
+
@sign_up_service = Monban::Services::SignUp
|
106
|
+
@sign_out_service = Monban::Services::SignOut
|
107
|
+
@password_reset_service = Monban::Services::PasswordReset
|
76
108
|
end
|
77
109
|
|
78
110
|
def setup_requirements
|
79
111
|
@failure_app = lambda{|e|[401, {"Content-Type" => "text/plain"}, ["Authorization Failed"]] }
|
80
112
|
end
|
81
113
|
end
|
82
|
-
|
83
114
|
end
|
@@ -1,6 +1,10 @@
|
|
1
1
|
module Monban
|
2
2
|
module Constraints
|
3
|
+
# Rails route constraint for signed in users
|
3
4
|
class SignedIn
|
5
|
+
# Checks to see if the constraint is matched by having a user signed in
|
6
|
+
#
|
7
|
+
# @param request [Rack::Request] A rack request
|
4
8
|
def matches?(request)
|
5
9
|
warden = request.env["warden"]
|
6
10
|
warden && warden.authenticated?
|
@@ -1,6 +1,10 @@
|
|
1
1
|
module Monban
|
2
2
|
module Constraints
|
3
|
+
# Rails route constraint for signed out users
|
3
4
|
class SignedOut
|
5
|
+
# Checks to see if the constraint is matched by not having a user signed in
|
6
|
+
#
|
7
|
+
# @param request [Rack::Request] A rack request
|
4
8
|
def matches?(request)
|
5
9
|
warden = request.env["warden"]
|
6
10
|
warden && warden.unauthenticated?
|
@@ -2,12 +2,21 @@ require 'bcrypt'
|
|
2
2
|
require 'active_support/concern'
|
3
3
|
|
4
4
|
module Monban
|
5
|
+
# Mixin to be included in Rails controllers.
|
6
|
+
# @since 0.0.15
|
5
7
|
module ControllerHelpers
|
6
8
|
extend ActiveSupport::Concern
|
7
9
|
included do
|
8
10
|
helper_method :current_user, :signed_in?
|
9
11
|
end
|
10
12
|
|
13
|
+
# Sign in a user
|
14
|
+
#
|
15
|
+
# @note Uses the {Monban::Services::SignIn} service to create a session
|
16
|
+
#
|
17
|
+
# @param user [User] the user object to sign in
|
18
|
+
# @yield Yields to the block if the user is successfully signed in
|
19
|
+
# @return [Object] returns the value from calling perform on the {Monban::Services::SignIn} service
|
11
20
|
def sign_in user
|
12
21
|
Monban.config.sign_in_service.new(user, warden).perform.tap do |status|
|
13
22
|
if status && block_given?
|
@@ -16,10 +25,22 @@ module Monban
|
|
16
25
|
end
|
17
26
|
end
|
18
27
|
|
28
|
+
# Sign out the current session
|
29
|
+
#
|
30
|
+
# @note Uses the {Monban::Services::SignOut} service to destroy the session
|
31
|
+
#
|
32
|
+
# @return [Object] returns the value from calling perform on the {Monban::Services::SignOut} service
|
19
33
|
def sign_out
|
20
34
|
Monban.config.sign_out_service.new(warden).perform
|
21
35
|
end
|
22
36
|
|
37
|
+
# Sign up a user
|
38
|
+
#
|
39
|
+
# @note Uses the {Monban::Services::SignUp} service to create a user
|
40
|
+
#
|
41
|
+
# @param user_params [Hash] params containing lookup and token fields
|
42
|
+
# @yield Yields to the block if the user is signed up successfully
|
43
|
+
# @return [Object] returns the value from calling perform on the {Monban::Services::SignUp} service
|
23
44
|
def sign_up user_params
|
24
45
|
Monban.config.sign_up_service.new(user_params).perform.tap do |status|
|
25
46
|
if status && block_given?
|
@@ -28,6 +49,53 @@ module Monban
|
|
28
49
|
end
|
29
50
|
end
|
30
51
|
|
52
|
+
# Authenticates a session.
|
53
|
+
#
|
54
|
+
# @note Uses the {Monban::Services::Authentication} service to verify the user's details
|
55
|
+
#
|
56
|
+
# @param session_params [Hash] params containing lookup and token fields
|
57
|
+
# @param field_map [Hash] Field map used for allowing users to sign in with multiple fields e.g. email and username
|
58
|
+
# @return [User] if authentication succeeded
|
59
|
+
# @return [nil] if authentication failed
|
60
|
+
# @example Basic usage
|
61
|
+
# class SessionsController < ApplicationController
|
62
|
+
# def create
|
63
|
+
# user = authenticate_session(session_params)
|
64
|
+
#
|
65
|
+
# if sign_in(user)
|
66
|
+
# redirect_to(root_path)
|
67
|
+
# else
|
68
|
+
# render :new
|
69
|
+
# end
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# private
|
73
|
+
#
|
74
|
+
# def session_params
|
75
|
+
# params.require(:session).permit(:email, :password)
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# end
|
79
|
+
# @example Using the field map to authenticate using multiple lookup fields
|
80
|
+
# class SessionsController < ApplicationController
|
81
|
+
# def create
|
82
|
+
# user = authenticate_session(session_params, email_or_username: [:email, :username])
|
83
|
+
#
|
84
|
+
# if sign_in(user)
|
85
|
+
# redirect_to(root_path)
|
86
|
+
# else
|
87
|
+
# render :new
|
88
|
+
# end
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# private
|
92
|
+
#
|
93
|
+
# def session_params
|
94
|
+
# params.require(:session).permit(:email_or_username, :password)
|
95
|
+
# end
|
96
|
+
#
|
97
|
+
# end
|
98
|
+
|
31
99
|
def authenticate_session session_params, field_map = nil
|
32
100
|
token_field = Monban.config.user_token_field
|
33
101
|
password = session_params.fetch(token_field)
|
@@ -35,30 +103,55 @@ module Monban
|
|
35
103
|
authenticate(user, password)
|
36
104
|
end
|
37
105
|
|
106
|
+
# Authenticates a user given a password
|
107
|
+
#
|
108
|
+
# @note Uses the {Monban::Services::Authentication} service to verify the user's credentials
|
109
|
+
#
|
110
|
+
# @param user [User] the user
|
111
|
+
# @param password [String] the password
|
112
|
+
# @return [User] if authentication succeeded
|
113
|
+
# @return [nil] if authentication failed
|
38
114
|
def authenticate user, password
|
39
115
|
Monban.config.authentication_service.new(user, password).perform
|
40
116
|
end
|
41
117
|
|
118
|
+
# Resets a user's password
|
119
|
+
#
|
120
|
+
# @note Uses the {Monban::Services::PasswordReset} service to change a user's password
|
121
|
+
#
|
122
|
+
# @param user [User] the user
|
123
|
+
# @param password [String] the password
|
42
124
|
def reset_password user, password
|
43
125
|
Monban.config.password_reset_service.new(user, password).perform
|
44
126
|
end
|
45
127
|
|
128
|
+
# @api private
|
46
129
|
def warden
|
47
130
|
request.env['warden']
|
48
131
|
end
|
49
132
|
|
133
|
+
# helper_method that returns the current user
|
134
|
+
#
|
135
|
+
# @return [User] if user is signed in
|
136
|
+
# @return [nil] if user is not signed in
|
50
137
|
def current_user
|
51
138
|
@current_user ||= warden.user
|
52
139
|
end
|
53
140
|
|
141
|
+
# helper_method that checks if there is a user signed in
|
142
|
+
#
|
143
|
+
# @return [User] if user is signed in
|
144
|
+
# @return [nil] if user is not signed in
|
54
145
|
def signed_in?
|
55
146
|
warden.user
|
56
147
|
end
|
57
148
|
|
149
|
+
# before_action that determines what to do when the user is not signed in
|
150
|
+
#
|
151
|
+
# @note Uses the no login handler
|
58
152
|
def require_login
|
59
153
|
unless signed_in?
|
60
|
-
|
61
|
-
redirect_to controller: '/sessions', action: 'new'
|
154
|
+
Monban.config.no_login_handler.call(self)
|
62
155
|
end
|
63
156
|
end
|
64
157
|
end
|
data/lib/monban/field_map.rb
CHANGED
@@ -1,10 +1,20 @@
|
|
1
1
|
module Monban
|
2
|
+
# FieldMap is used to allow multiple lookup fields. For instance if you
|
3
|
+
# wanted to allow a user to sign in via email or username. This is used
|
4
|
+
# internally by the authenticate_session controller helper
|
5
|
+
# @since 0.0.15
|
2
6
|
class FieldMap
|
7
|
+
# @param params [Hash] hash of parameters
|
8
|
+
# @param field_map [Hash] hash of values to map
|
3
9
|
def initialize params, field_map
|
4
10
|
@params = params
|
5
11
|
@field_map = field_map
|
6
12
|
end
|
7
13
|
|
14
|
+
# converts params into values that can be passed into a where clause
|
15
|
+
#
|
16
|
+
# @return [Array] if initialized with field_map
|
17
|
+
# @return [Hash] if not initialized with field_map
|
8
18
|
def to_fields
|
9
19
|
if @field_map
|
10
20
|
params_from_field_map
|
data/lib/monban/railtie.rb
CHANGED
@@ -1,26 +1,38 @@
|
|
1
1
|
module Monban
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
module Services
|
3
|
+
# Authentication service. Checks to see if the credentials provided are valid
|
4
|
+
# @since 0.0.15
|
5
|
+
class Authentication
|
6
|
+
# Initialize service
|
7
|
+
#
|
8
|
+
# @param user [User] A user object
|
9
|
+
# @param undigested_token [String] An undigested password
|
10
|
+
def initialize user, undigested_token
|
11
|
+
@user = user
|
12
|
+
@undigested_token = undigested_token
|
13
|
+
end
|
7
14
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
15
|
+
# Perform the service
|
16
|
+
#
|
17
|
+
# @return [User] if authentication succeeds
|
18
|
+
# @return [false] if authentication fails
|
19
|
+
def perform
|
20
|
+
if authenticated?
|
21
|
+
@user
|
22
|
+
else
|
23
|
+
false
|
24
|
+
end
|
13
25
|
end
|
14
|
-
end
|
15
26
|
|
16
|
-
|
27
|
+
private
|
17
28
|
|
18
|
-
|
19
|
-
|
20
|
-
|
29
|
+
def authenticated?
|
30
|
+
@user && Monban.compare_token(@user.send(token_store_field), @undigested_token)
|
31
|
+
end
|
21
32
|
|
22
|
-
|
23
|
-
|
33
|
+
def token_store_field
|
34
|
+
Monban.config.user_token_store_field
|
35
|
+
end
|
24
36
|
end
|
25
37
|
end
|
26
38
|
end
|
@@ -1,14 +1,23 @@
|
|
1
1
|
module Monban
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
module Services
|
3
|
+
# Password reset service. Updates the password on a User
|
4
|
+
# @since 0.0.15
|
5
|
+
class PasswordReset
|
6
|
+
# Initialize service
|
7
|
+
#
|
8
|
+
# @param user [User] A user object
|
9
|
+
# @param new_password [String] The new undigested password for a user
|
10
|
+
def initialize user, new_password
|
11
|
+
@user = user
|
12
|
+
@new_password = new_password
|
13
|
+
end
|
7
14
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
15
|
+
# Perform the service.
|
16
|
+
def perform
|
17
|
+
field = Monban.config.user_token_store_field
|
18
|
+
digested_password = Monban.hash_token(@new_password)
|
19
|
+
@user[field] = digested_password
|
20
|
+
end
|
12
21
|
end
|
13
22
|
end
|
14
23
|
end
|
@@ -1,12 +1,21 @@
|
|
1
1
|
module Monban
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
module Services
|
3
|
+
# Sign in service. Signs the user in via warden
|
4
|
+
# @since 0.0.15
|
5
|
+
class SignIn
|
6
|
+
# Initialize service
|
7
|
+
#
|
8
|
+
# @param user [User] A user object
|
9
|
+
# @param warden [Warden] warden
|
10
|
+
def initialize user, warden
|
11
|
+
@user = user
|
12
|
+
@warden = warden
|
13
|
+
end
|
7
14
|
|
8
|
-
|
9
|
-
|
15
|
+
# Perform the service
|
16
|
+
def perform
|
17
|
+
@warden.set_user(@user)
|
18
|
+
end
|
10
19
|
end
|
11
20
|
end
|
12
21
|
end
|
@@ -1,11 +1,19 @@
|
|
1
1
|
module Monban
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
module Services
|
3
|
+
# Sign out service. Signs the user out via warden
|
4
|
+
# @since 0.0.15
|
5
|
+
class SignOut
|
6
|
+
# Initialize service
|
7
|
+
#
|
8
|
+
# @param warden [Warden] warden
|
9
|
+
def initialize warden
|
10
|
+
@warden = warden
|
11
|
+
end
|
6
12
|
|
7
|
-
|
8
|
-
|
13
|
+
# Perform the service
|
14
|
+
def perform
|
15
|
+
@warden.logout
|
16
|
+
end
|
9
17
|
end
|
10
18
|
end
|
11
19
|
end
|
@@ -1,31 +1,40 @@
|
|
1
1
|
module Monban
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
2
|
+
module Services
|
3
|
+
# Sign up service. Signs the user up
|
4
|
+
# @since 0.0.15
|
5
|
+
class SignUp
|
6
|
+
# Initialize service
|
7
|
+
#
|
8
|
+
# @param user_params [Hash] A hash of user credentials. Should contain the lookup and token fields
|
9
|
+
def initialize user_params
|
10
|
+
digested_token = token_digest(user_params)
|
11
|
+
@user_params = user_params.
|
12
|
+
except(token_field).
|
13
|
+
merge(token_store_field.to_sym => digested_token)
|
14
|
+
end
|
9
15
|
|
10
|
-
|
11
|
-
Monban.
|
12
|
-
|
16
|
+
# Performs the service
|
17
|
+
# @see Monban::Configuration.default_creation_method
|
18
|
+
def perform
|
19
|
+
Monban.config.creation_method.call(@user_params.to_hash)
|
20
|
+
end
|
13
21
|
|
14
|
-
|
22
|
+
private
|
15
23
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
24
|
+
def token_digest(user_params)
|
25
|
+
undigested_token = user_params[token_field]
|
26
|
+
unless undigested_token.empty?
|
27
|
+
Monban.hash_token(undigested_token)
|
28
|
+
end
|
20
29
|
end
|
21
|
-
end
|
22
30
|
|
23
|
-
|
24
|
-
|
25
|
-
|
31
|
+
def token_store_field
|
32
|
+
Monban.config.user_token_store_field
|
33
|
+
end
|
26
34
|
|
27
|
-
|
28
|
-
|
35
|
+
def token_field
|
36
|
+
Monban.config.user_token_field
|
37
|
+
end
|
29
38
|
end
|
30
39
|
end
|
31
40
|
end
|
@@ -2,16 +2,41 @@ require 'warden'
|
|
2
2
|
|
3
3
|
module Monban
|
4
4
|
module Strategies
|
5
|
+
# Password strategy for warden
|
6
|
+
# @since 0.0.15
|
5
7
|
class PasswordStrategy < ::Warden::Strategies::Base
|
8
|
+
|
9
|
+
# Checks if strategy should be executed
|
10
|
+
# @return [Boolean]
|
6
11
|
def valid?
|
7
|
-
|
12
|
+
lookup_field_value || token_field_value
|
8
13
|
end
|
9
14
|
|
15
|
+
|
16
|
+
# Authenticates for warden
|
10
17
|
def authenticate!
|
11
|
-
user = Monban.user_class.find_by(
|
12
|
-
auth =
|
18
|
+
user = Monban.user_class.find_by(lookup_field => lookup_field_value)
|
19
|
+
auth = Monban.config.authentication_service.new(user, token_field_value)
|
13
20
|
auth.authenticated? ? success!(user) : fail!("Could not log in")
|
14
21
|
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def lookup_field_value
|
26
|
+
params[lookup_field]
|
27
|
+
end
|
28
|
+
|
29
|
+
def token_field_value
|
30
|
+
params[token_field]
|
31
|
+
end
|
32
|
+
|
33
|
+
def lookup_field
|
34
|
+
Monban.config.user_lookup_field
|
35
|
+
end
|
36
|
+
|
37
|
+
def token_field
|
38
|
+
Monban.config.user_token_field
|
39
|
+
end
|
15
40
|
end
|
16
41
|
end
|
17
42
|
end
|
@@ -2,6 +2,9 @@ require 'warden'
|
|
2
2
|
|
3
3
|
module Monban
|
4
4
|
module Test
|
5
|
+
# These are test helpers for controller specs
|
6
|
+
# @note these have only been tested with rspec controller specs
|
7
|
+
# @since 0.0.15
|
5
8
|
module ControllerHelpers
|
6
9
|
def self.included(base)
|
7
10
|
base.class_eval do
|
@@ -9,18 +12,18 @@ module Monban
|
|
9
12
|
end
|
10
13
|
end
|
11
14
|
|
12
|
-
|
13
|
-
|
14
|
-
end
|
15
|
-
|
15
|
+
# Signs a user in for tests
|
16
|
+
# @param user [User] the user to sign in
|
16
17
|
def sign_in(user)
|
17
18
|
@controller.sign_in(user)
|
18
19
|
end
|
19
20
|
|
21
|
+
# Signs the user out in tests
|
20
22
|
def sign_out
|
21
23
|
@controller.sign_out
|
22
24
|
end
|
23
25
|
|
26
|
+
# A mock of warden for tests
|
24
27
|
def warden
|
25
28
|
@warden ||= begin
|
26
29
|
manager = Warden::Manager.new(nil) do |config|
|
@@ -29,6 +32,12 @@ module Monban
|
|
29
32
|
@request.env['warden'] = Warden::Proxy.new(@request.env, manager)
|
30
33
|
end
|
31
34
|
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def store_controller_for_warden
|
38
|
+
@request.env['action_controller.instance'] = @controller
|
39
|
+
end
|
40
|
+
|
32
41
|
end
|
33
42
|
end
|
34
43
|
end
|
data/lib/monban/test/helpers.rb
CHANGED
@@ -1,12 +1,18 @@
|
|
1
1
|
module Monban
|
2
2
|
module Test
|
3
|
+
# Helpers for integration or feature specs
|
4
|
+
# @note these have only been tested with rspec integration and feature specs
|
5
|
+
# @since 0.0.15
|
3
6
|
module Helpers
|
4
7
|
include Warden::Test::Helpers
|
5
8
|
|
9
|
+
# Sign a user in
|
10
|
+
# @param user [User] user to sign in
|
6
11
|
def sign_in user
|
7
12
|
login_as user
|
8
13
|
end
|
9
14
|
|
15
|
+
# Sign a user out
|
10
16
|
def sign_out
|
11
17
|
logout
|
12
18
|
end
|
data/lib/monban/version.rb
CHANGED
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
feature 'Visitor signs in with invalid form' do
|
4
4
|
scenario 'is not signed in' do
|
5
|
-
Monban::SignUp.new(email: 'email@example.com', password: 'password').perform
|
5
|
+
Monban::Services::SignUp.new(email: 'email@example.com', password: 'password').perform
|
6
6
|
visit invalid_sign_in_path
|
7
7
|
fill_in "session_password", with: 'password'
|
8
8
|
click_button 'go'
|
@@ -16,7 +16,7 @@ module Monban
|
|
16
16
|
end
|
17
17
|
|
18
18
|
class Dummy
|
19
|
-
attr_reader :redirected, :flash, :request
|
19
|
+
attr_reader :redirected, :redirected_to, :flash, :request
|
20
20
|
def initialize warden
|
21
21
|
@warden = warden
|
22
22
|
@flash = Flash.new
|
@@ -25,6 +25,7 @@ module Monban
|
|
25
25
|
end
|
26
26
|
def redirect_to path
|
27
27
|
@redirected = true
|
28
|
+
@redirected_to = path
|
28
29
|
end
|
29
30
|
def env
|
30
31
|
{ "warden" => @warden }
|
@@ -59,7 +60,7 @@ module Monban
|
|
59
60
|
it 'performs a sign out' do
|
60
61
|
sign_out = double()
|
61
62
|
sign_out.should_receive(:perform)
|
62
|
-
SignOut.should_receive(:new).with(@warden).and_return(sign_out)
|
63
|
+
Services::SignOut.should_receive(:new).with(@warden).and_return(sign_out)
|
63
64
|
@dummy.sign_out
|
64
65
|
end
|
65
66
|
|
@@ -88,7 +89,7 @@ module Monban
|
|
88
89
|
authentication = double()
|
89
90
|
authentication.should_receive(:perform).and_return(user)
|
90
91
|
Monban.should_receive(:lookup).with({email: 'a@b.com'}, nil).and_return(user)
|
91
|
-
Authentication.should_receive(:new).with(user, 'password').and_return(authentication)
|
92
|
+
Services::Authentication.should_receive(:new).with(user, 'password').and_return(authentication)
|
92
93
|
@dummy.authenticate_session(session_params).should == user
|
93
94
|
end
|
94
95
|
|
@@ -99,7 +100,7 @@ module Monban
|
|
99
100
|
authentication = double()
|
100
101
|
authentication.should_receive(:perform).and_return(user)
|
101
102
|
Monban.should_receive(:lookup).with(session_params.except(:password), field_map).and_return(user)
|
102
|
-
Authentication.should_receive(:new).with(user, 'password').and_return(authentication)
|
103
|
+
Services::Authentication.should_receive(:new).with(user, 'password').and_return(authentication)
|
103
104
|
@dummy.authenticate_session(session_params, field_map).should == user
|
104
105
|
end
|
105
106
|
|
@@ -111,7 +112,7 @@ module Monban
|
|
111
112
|
authentication = double()
|
112
113
|
authentication.should_receive(:perform).and_return(false)
|
113
114
|
Monban.should_receive(:lookup).with(session_params, nil).and_return(user)
|
114
|
-
Authentication.should_receive(:new).with(user, 'password').and_return(authentication)
|
115
|
+
Services::Authentication.should_receive(:new).with(user, 'password').and_return(authentication)
|
115
116
|
@dummy.authenticate_session(session_params).should == false
|
116
117
|
end
|
117
118
|
|
@@ -120,7 +121,7 @@ module Monban
|
|
120
121
|
password = double()
|
121
122
|
authentication = double()
|
122
123
|
authentication.should_receive(:perform)
|
123
|
-
Authentication.should_receive(:new).with(user, password).and_return(authentication)
|
124
|
+
Services::Authentication.should_receive(:new).with(user, password).and_return(authentication)
|
124
125
|
@dummy.authenticate user, password
|
125
126
|
end
|
126
127
|
|
@@ -139,6 +140,7 @@ module Monban
|
|
139
140
|
@warden.should_receive(:user).and_return(false)
|
140
141
|
@dummy.require_login
|
141
142
|
expect(@dummy.redirected).to eq(true)
|
143
|
+
expect(@dummy.redirected_to).to eq(Monban.config.no_login_redirect)
|
142
144
|
expect(@dummy.flash.notice).to eq(Monban.config.sign_in_notice)
|
143
145
|
end
|
144
146
|
|
@@ -156,7 +158,7 @@ module Monban
|
|
156
158
|
user = double()
|
157
159
|
sign_in = double()
|
158
160
|
sign_in.should_receive(:perform).and_return(success)
|
159
|
-
SignIn.should_receive(:new).with(user, @warden).and_return(sign_in)
|
161
|
+
Services::SignIn.should_receive(:new).with(user, @warden).and_return(sign_in)
|
160
162
|
user
|
161
163
|
end
|
162
164
|
|
@@ -164,7 +166,7 @@ module Monban
|
|
164
166
|
user_params = double()
|
165
167
|
sign_up = double()
|
166
168
|
sign_up.should_receive(:perform).and_return(success)
|
167
|
-
SignUp.should_receive(:new).with(user_params).and_return(sign_up)
|
169
|
+
Services::SignUp.should_receive(:new).with(user_params).and_return(sign_up)
|
168
170
|
user_params
|
169
171
|
end
|
170
172
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'monban/services/authentication'
|
3
3
|
|
4
|
-
describe Monban::Authentication, '#authentication' do
|
4
|
+
describe Monban::Services::Authentication, '#authentication' do
|
5
5
|
it 'is authenticated for a valid password' do
|
6
6
|
password_digest = BCrypt::Password.create('password')
|
7
7
|
user = double(password_digest: password_digest)
|
8
|
-
auth = Monban::Authentication.new(user, 'password')
|
8
|
+
auth = Monban::Services::Authentication.new(user, 'password')
|
9
9
|
|
10
10
|
expect(auth.perform).to eq(user)
|
11
11
|
end
|
@@ -13,13 +13,13 @@ describe Monban::Authentication, '#authentication' do
|
|
13
13
|
it 'is not authenticated for the wrong password' do
|
14
14
|
password_digest = BCrypt::Password.create('password')
|
15
15
|
user = double(password_digest: password_digest)
|
16
|
-
auth = Monban::Authentication.new(user, 'drowssap')
|
16
|
+
auth = Monban::Services::Authentication.new(user, 'drowssap')
|
17
17
|
|
18
18
|
expect(auth.perform).to eq(false)
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'is not authenticated without a user' do
|
22
|
-
auth = Monban::Authentication.new(nil, 'password')
|
22
|
+
auth = Monban::Services::Authentication.new(nil, 'password')
|
23
23
|
expect(auth.perform).to eq(false)
|
24
24
|
end
|
25
25
|
end
|
@@ -2,22 +2,22 @@ require 'spec_helper'
|
|
2
2
|
require 'monban/services/password_reset'
|
3
3
|
require 'ostruct'
|
4
4
|
|
5
|
-
describe Monban::PasswordReset do
|
5
|
+
describe Monban::Services::PasswordReset do
|
6
6
|
before do
|
7
|
-
Monban.config.
|
7
|
+
Monban.config.hashing_method = ->(password) { password + "secret" }
|
8
8
|
end
|
9
9
|
|
10
|
-
it 'updates the password with the
|
11
|
-
password_digest = Monban.
|
10
|
+
it 'updates the password with the hashing strategy' do
|
11
|
+
password_digest = Monban.hash_token('password')
|
12
12
|
user = double()
|
13
13
|
field = Monban.config.user_token_store_field
|
14
14
|
user.should_receive(:[]=).with(field, 'passwordsecret')
|
15
|
-
password_reset = Monban::PasswordReset.new(user, 'password')
|
15
|
+
password_reset = Monban::Services::PasswordReset.new(user, 'password')
|
16
16
|
|
17
17
|
password_reset.perform
|
18
18
|
end
|
19
19
|
|
20
20
|
after do
|
21
|
-
Monban.config.
|
21
|
+
Monban.config.hashing_method = Monban.config.default_hashing_method
|
22
22
|
end
|
23
23
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'monban/services/sign_in'
|
3
3
|
|
4
|
-
describe Monban::SignIn, '#perform' do
|
4
|
+
describe Monban::Services::SignIn, '#perform' do
|
5
5
|
it 'signs the user in' do
|
6
6
|
user = double()
|
7
7
|
warden = double()
|
8
8
|
warden.should_receive(:set_user).with(user)
|
9
9
|
|
10
|
-
Monban::SignIn.new(user, warden).perform
|
10
|
+
Monban::Services::SignIn.new(user, warden).perform
|
11
11
|
end
|
12
12
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'monban/services/sign_out'
|
3
3
|
|
4
|
-
describe Monban::SignOut, '#perform' do
|
4
|
+
describe Monban::Services::SignOut, '#perform' do
|
5
5
|
it 'signs out the user' do
|
6
6
|
warden = double()
|
7
7
|
warden.should_receive(:logout)
|
8
8
|
|
9
|
-
Monban::SignOut.new(warden).perform
|
9
|
+
Monban::Services::SignOut.new(warden).perform
|
10
10
|
end
|
11
11
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'monban/services/sign_up'
|
3
3
|
|
4
|
-
describe Monban::SignUp, '#perform' do
|
4
|
+
describe Monban::Services::SignUp, '#perform' do
|
5
5
|
it 'creates a user with the right parameters' do
|
6
6
|
allow(User).to receive(:create)
|
7
7
|
user_params = { email: 'email@example.com', password: 'password' }
|
8
8
|
|
9
|
-
Monban::SignUp.new(user_params).perform
|
9
|
+
Monban::Services::SignUp.new(user_params).perform
|
10
10
|
expect(User).to have_received(:create) do |args|
|
11
11
|
expect(args[:email]).to eq(user_params[:email])
|
12
12
|
expect(Monban.compare_token(args[:password_digest], 'password')).to be_true
|
@@ -19,7 +19,7 @@ describe Monban::SignUp, '#perform' do
|
|
19
19
|
user_params = { email: 'email@example.com', password: 'password' }
|
20
20
|
|
21
21
|
with_monban_config(creation_method: user_create_double) do
|
22
|
-
Monban::SignUp.new(user_params).perform
|
22
|
+
Monban::Services::SignUp.new(user_params).perform
|
23
23
|
end
|
24
24
|
|
25
25
|
expect(user_create_double).to have_received(:call) do |args|
|
@@ -31,7 +31,7 @@ describe Monban::SignUp, '#perform' do
|
|
31
31
|
allow(User).to receive(:create)
|
32
32
|
user_params = { email: 'email@example.com', password: '' }
|
33
33
|
|
34
|
-
Monban::SignUp.new(user_params).perform
|
34
|
+
Monban::Services::SignUp.new(user_params).perform
|
35
35
|
expect(User).to have_received(:create) do |args|
|
36
36
|
expect(args[:password_digest]).to be_nil
|
37
37
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Monban
|
4
|
+
module Strategies
|
5
|
+
describe PasswordStrategy do
|
6
|
+
it "bases lookup and token on config values" do
|
7
|
+
params = HashWithIndifferentAccess.new(username: 'test', the_password: 'password')
|
8
|
+
|
9
|
+
with_monban_config(user_lookup_field: "username", user_token_field: "the_password") do
|
10
|
+
env = Rack::MockRequest.env_for("/", params: params)
|
11
|
+
strategy = PasswordStrategy.new(env)
|
12
|
+
expect(strategy).to be_valid
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it "it doesn't trigger if params are not provided" do
|
17
|
+
env = Rack::MockRequest.env_for("/")
|
18
|
+
strategy = PasswordStrategy.new(env)
|
19
|
+
expect(strategy).not_to be_valid
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/spec/monban_spec.rb
CHANGED
@@ -8,7 +8,7 @@ describe 'Monban' do
|
|
8
8
|
|
9
9
|
it "provides a .test_mode!" do
|
10
10
|
Monban.test_mode!
|
11
|
-
expect(Monban.
|
11
|
+
expect(Monban.hash_token('password')).to eql('password')
|
12
12
|
expect(Monban.compare_token('password', 'password')).to be_true
|
13
13
|
end
|
14
14
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: monban
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- halogenandtoast
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-07-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -186,6 +186,7 @@ files:
|
|
186
186
|
- spec/monban/services/sign_in_spec.rb
|
187
187
|
- spec/monban/services/sign_out_spec.rb
|
188
188
|
- spec/monban/services/sign_up_spec.rb
|
189
|
+
- spec/monban/strategies/password_strategy_spec.rb
|
189
190
|
- spec/monban/test_controller_helpers_spec.rb
|
190
191
|
- spec/monban/test_helpers_spec.rb
|
191
192
|
- spec/monban_spec.rb
|
@@ -266,6 +267,7 @@ test_files:
|
|
266
267
|
- spec/monban/services/sign_in_spec.rb
|
267
268
|
- spec/monban/services/sign_out_spec.rb
|
268
269
|
- spec/monban/services/sign_up_spec.rb
|
270
|
+
- spec/monban/strategies/password_strategy_spec.rb
|
269
271
|
- spec/monban/test_controller_helpers_spec.rb
|
270
272
|
- spec/monban/test_helpers_spec.rb
|
271
273
|
- spec/monban_spec.rb
|