monban 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +4 -4
  3. data/README.md +76 -21
  4. data/lib/generators/monban/scaffold/scaffold_generator.rb +1 -6
  5. data/lib/generators/monban/templates/app/controllers/sessions_controller.rb +4 -6
  6. data/lib/generators/monban/templates/app/controllers/users_controller.rb +4 -2
  7. data/lib/monban/configuration.rb +38 -7
  8. data/lib/monban/controller_helpers.rb +17 -9
  9. data/lib/monban/{controller_helpers → services}/authentication.rb +0 -0
  10. data/lib/monban/services/password_reset.rb +14 -0
  11. data/lib/monban/{controller_helpers → services}/sign_in.rb +0 -0
  12. data/lib/monban/{controller_helpers → services}/sign_out.rb +0 -0
  13. data/lib/monban/{controller_helpers → services}/sign_up.rb +0 -0
  14. data/lib/monban/services.rb +5 -0
  15. data/lib/monban/test/helpers.rb +15 -0
  16. data/lib/monban/version.rb +1 -1
  17. data/lib/monban.rb +32 -6
  18. data/monban.gemspec +1 -0
  19. data/spec/features/visitor/visitor_is_unauthorized_spec.rb +8 -0
  20. data/spec/features/visitor/visitor_signs_up_spec.rb +19 -0
  21. data/spec/features/visitor/visitor_uses_remember_token_spec.rb +13 -0
  22. data/spec/monban/controller_helpers_spec.rb +53 -14
  23. data/spec/monban/{controller_helpers → services}/authentication_spec.rb +3 -3
  24. data/spec/monban/services/password_reset_spec.rb +23 -0
  25. data/spec/monban/{controller_helpers → services}/sign_in_spec.rb +1 -1
  26. data/spec/monban/{controller_helpers → services}/sign_out_spec.rb +1 -1
  27. data/spec/monban/{controller_helpers → services}/sign_up_spec.rb +2 -2
  28. data/spec/monban/test_helpers_spec.rb +94 -0
  29. data/spec/monban_spec.rb +6 -0
  30. data/spec/rails_app/app/controllers/failures_controller.rb +5 -0
  31. data/spec/rails_app/app/controllers/posts_controller.rb +0 -1
  32. data/spec/rails_app/app/controllers/sessions_controller.rb +2 -1
  33. data/spec/rails_app/app/views/layouts/application.html.erb +3 -1
  34. data/spec/rails_app/app/views/posts/index.html.erb +1 -0
  35. data/spec/rails_app/app/views/sessions/new.html.erb +5 -0
  36. data/spec/rails_app/config/environments/test.rb +2 -3
  37. data/spec/rails_app/config/routes.rb +2 -0
  38. data/spec/spec_helper.rb +4 -0
  39. metadata +46 -16
  40. data/lib/generators/monban/templates/app/models/user.rb +0 -7
  41. data/lib/generators/monban/templates/db/migrate/create_users.rb +0 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 93dddea63fce739f0a549c7ef8c97b7fee4cd7d7
4
- data.tar.gz: 24df0ad211ea5bd21d23e8fa8607b53854b9be60
3
+ metadata.gz: 1eea738a714fc0f03f4e0a62079eb8fe979a925d
4
+ data.tar.gz: b169d1d7730f4ff61ff1f5783a7588ded2dd63bf
5
5
  SHA512:
6
- metadata.gz: fdbe4a23900c1d89b81aa077b237c394a7120b3840decd40a95bedcb9659bb29697e313aead7f6b837c30f52385bcf3aa2a8c34a7294f0ff658dfbf81c58aba1
7
- data.tar.gz: f618ece4acd9ba1128268b0ace5f78d629febc676e7f9dced7ea4b1eea4abb1811b850c9687040f379d53b6b8bf269abf3fd469d64aaf1e8004a73fb99b8241e
6
+ metadata.gz: df2ae9cdac6f2b795c4b5eb034c712aa0a63ccfe04717431a9ea4b5a4b3d5dc0adc39c749891a81e5d2de93b0183578344dd7e736de6290341ae9deb27a36bd0
7
+ data.tar.gz: 348dd3613602134b6b956a56cac76262927329b6a5d0ca16db0fcb818c27e3da05ed3d8e1d9b0e243ac39ecbab8587fcf0d565fe316fecccd5bec700097f2913
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- monban (0.0.6)
4
+ monban (0.0.7)
5
5
  bcrypt-ruby
6
6
  rails
7
7
  warden
@@ -93,7 +93,7 @@ GEM
93
93
  rake (>= 0.8.7)
94
94
  rdoc (~> 3.4)
95
95
  thor (>= 0.14.6, < 2.0)
96
- rake (10.0.3)
96
+ rake (10.1.1)
97
97
  rdoc (3.12.1)
98
98
  json (~> 1.4)
99
99
  rspec (2.12.0)
@@ -126,10 +126,10 @@ GEM
126
126
  sqlite3 (1.3.7)
127
127
  thor (0.17.0)
128
128
  tilt (1.3.3)
129
- treetop (1.4.12)
129
+ treetop (1.4.14)
130
130
  polyglot
131
131
  polyglot (>= 0.3.1)
132
- tzinfo (0.3.35)
132
+ tzinfo (0.3.37)
133
133
  warden (1.2.1)
134
134
  rack (>= 1.0)
135
135
  websocket (1.0.7)
data/README.md CHANGED
@@ -14,7 +14,7 @@ Monban makes authentication simple:
14
14
  - Uses warden
15
15
  - Provides convenient controller helpers
16
16
  - Provides a rails generator for default controllers and views
17
- - TODO: Very customizable
17
+ - Very customizable
18
18
 
19
19
  Monban doesn't do the following:
20
20
 
@@ -25,7 +25,7 @@ Monban doesn't do the following:
25
25
 
26
26
  ## Installation
27
27
 
28
- Monban was designed to work with Rails > 3.1. Add this line to your Gemfile:
28
+ Monban was designed to work with Rails > 4.0. Add this line to your Gemfile:
29
29
 
30
30
  gem 'monban'
31
31
 
@@ -43,10 +43,10 @@ This will generate a bare bones starting point. If you don't want the full stack
43
43
 
44
44
  ## Usage
45
45
 
46
- Monban does currently have some expectations, but these will change. Here are the current requirements:
46
+ Monban does currently have some out of the box expectations, but you can configure any of these:
47
47
 
48
- - Your model must be called `User`
49
- - You must have an `email` and `password_digest` column on your `User`
48
+ - By default the model should be called `User`
49
+ - You should have an `email` and `password_digest` column on your `User`
50
50
  - Passwords will be run through BCrypt
51
51
 
52
52
  ### Controller Additions
@@ -68,31 +68,86 @@ And this filter:
68
68
 
69
69
  - `require_login`
70
70
 
71
- ### Advanced Functionality
71
+ ## Usage in Tests
72
72
 
73
- You may perform a look up on a user using multiple fields by doing something like the following:
73
+ ### Test mode
74
+
75
+ Monban provides the follow:
76
+
77
+ ```ruby
78
+ Monban.test_mode!
79
+ ```
80
+
81
+ Which will change password encryption to provide plaintext responses instead of using BCrypt. This will allow you to write factories using the password_digest field:
82
+
83
+ ```ruby
84
+ FactoryGirl.define do
85
+ factory :user do
86
+ username 'wombat'
87
+ password_digest 'password'
88
+ end
89
+ end
90
+ ```
91
+
92
+ ### Spec helpers
93
+
94
+ A couple of convenience methods are available in your tests.
95
+
96
+ ```ruby
97
+ require 'monban/test/helpers'
74
98
 
75
- class SessionsController < ApplicationController
76
- def create
77
- if user = authenticate_session(session_params, email_or_username: [:email, :username])
78
- sign_in user
79
- redirect_to root_path
80
- else
81
- flash.now.notice = "Invalid username or password"
82
- render :new
83
- end
84
- end
99
+ Monban.test_mode!
85
100
 
86
- private
101
+ RSpec.configure do |config|
102
+ config.include Monban::Test::Helpers, type: :feature
103
+ config.after :each do
104
+ Monban.test_reset!
105
+ end
106
+ end
107
+ ```
87
108
 
88
- def session_params
89
- params.require(:session).permit(:email_or_username, :password)
90
- end
109
+ ```ruby
110
+ feature "A feature spec" do
111
+ scenario "that requires login" do
112
+ user = create(:user)
113
+ sign_in(user)
114
+ # do something
115
+ sign_out
116
+ # do something else
117
+ end
118
+ end
119
+ ```
91
120
 
121
+ ## Advanced Functionality
122
+
123
+ You may perform a look up on a user using multiple fields by doing something like the following:
124
+
125
+ ```ruby
126
+ class SessionsController < ApplicationController
127
+ def create
128
+ user = authenticate_session(session_params, email_or_username: [:email, :username])
129
+ sign_in(user) do
130
+ redirect_to(root_path) and return
92
131
  end
132
+ render :new
133
+ end
134
+
135
+ private
136
+
137
+ def session_params
138
+ params.require(:session).permit(:email_or_username, :password)
139
+ end
140
+
141
+ end
142
+ ```
93
143
 
94
144
  This will allow the user to enter either their username or email to login
95
145
 
146
+ ### Limitations
147
+
148
+ Here are a few of the current limitations of monban:
149
+
150
+ - Monban assumes you only have one user model.
96
151
 
97
152
  ## Contributing
98
153
 
@@ -17,10 +17,6 @@ module Monban
17
17
  copy_file 'app/views/sessions/new.html.erb'
18
18
  end
19
19
 
20
- def copy_migration
21
- migration_template 'db/migrate/create_users.rb'
22
- end
23
-
24
20
  def add_helper_module_to_application_controller
25
21
  inject_into_class "app/controllers/application_controller.rb", ApplicationController, " include Monban::ControllerHelpers\n"
26
22
  end
@@ -30,13 +26,12 @@ module Monban
30
26
  end
31
27
 
32
28
  def add_model
33
- template 'app/models/user.rb', 'app/models/user.rb', config
29
+ generate 'model', 'user email password_digest'
34
30
  end
35
31
 
36
32
  def display_readme
37
33
  readme 'scaffold_readme'
38
34
  end
39
-
40
35
  end
41
36
  end
42
37
  end
@@ -6,8 +6,10 @@ class SessionsController < ApplicationController
6
6
 
7
7
  def create
8
8
  user = authenticate_session(session_params)
9
- sign_in(user) or set_flash_message
10
- respond_with user, location: root_path
9
+ sign_in(user) do
10
+ respond_with(user, location: root_path) and return
11
+ end
12
+ render :new
11
13
  end
12
14
 
13
15
  def destroy
@@ -17,10 +19,6 @@ class SessionsController < ApplicationController
17
19
 
18
20
  private
19
21
 
20
- def set_flash_message
21
- flash.now.notice = "Invalid username or password"
22
- end
23
-
24
22
  def session_params
25
23
  <% if config[:use_strong_parameters] -%>
26
24
  params.require(:session).permit(:email, :password)
@@ -7,8 +7,10 @@ class UsersController < ApplicationController
7
7
 
8
8
  def create
9
9
  @user = sign_up(user_params)
10
- sign_in(@user)
11
- respond_with @user, location: root_path
10
+ sign_in(@user) do
11
+ respond_with(@user, location: root_path) and return
12
+ end
13
+ render :new
12
14
  end
13
15
 
14
16
  private
@@ -3,15 +3,16 @@ module Monban
3
3
  attr_accessor :user_class, :user_token_field, :user_token_store_field
4
4
  attr_accessor :encryption_method, :token_comparison, :user_lookup_field
5
5
  attr_accessor :sign_in_notice
6
+ attr_accessor :sign_in_service, :sign_up_service, :sign_out_service
7
+ attr_accessor :authentication_service, :password_reset_service
8
+ attr_accessor :failure_app
6
9
 
7
10
  def initialize
8
- @user_class = 'User'
9
- @user_token_field = 'password'
10
- @user_token_store_field = 'password_digest'
11
- @user_lookup_field = 'email'
12
- @encryption_method = default_encryption_method
13
- @token_comparison = default_password_comparison
14
- @sign_in_notice = 'You must be signed in'
11
+ setup_class_defaults
12
+ setup_token_encryption
13
+ setup_notices
14
+ setup_services
15
+ setup_requirements
15
16
  end
16
17
 
17
18
  def default_encryption_method
@@ -23,5 +24,35 @@ module Monban
23
24
  BCrypt::Password.new(digest) == unencrypted_token
24
25
  end
25
26
  end
27
+
28
+ private
29
+
30
+ def setup_token_encryption
31
+ @encryption_method = default_encryption_method
32
+ @token_comparison = default_password_comparison
33
+ end
34
+
35
+ def setup_notices
36
+ @sign_in_notice = 'You must be signed in'
37
+ end
38
+
39
+ def setup_class_defaults
40
+ @user_class = 'User'
41
+ @user_token_field = :password
42
+ @user_token_store_field = :password_digest
43
+ @user_lookup_field = :email
44
+ end
45
+
46
+ def setup_services
47
+ @authentication_service = Monban::Authentication
48
+ @sign_in_service = Monban::SignIn
49
+ @sign_up_service = Monban::SignUp
50
+ @sign_out_service = Monban::SignOut
51
+ @password_reset_service = Monban::PasswordReset
52
+ end
53
+
54
+ def setup_requirements
55
+ @failure_app = lambda{|e|[401, {"Content-Type" => "text/plain"}, ["Authorization Failed"]] }
56
+ end
26
57
  end
27
58
  end
@@ -1,8 +1,4 @@
1
1
  require 'bcrypt'
2
- require 'monban/controller_helpers/sign_in'
3
- require 'monban/controller_helpers/sign_out'
4
- require 'monban/controller_helpers/sign_up'
5
- require 'monban/controller_helpers/authentication'
6
2
  require 'active_support/concern'
7
3
 
8
4
  module Monban
@@ -13,15 +9,23 @@ module Monban
13
9
  end
14
10
 
15
11
  def sign_in user
16
- SignIn.new(user, warden).perform
12
+ Monban.config.sign_in_service.new(user, warden).perform.tap do |status|
13
+ if status && block_given?
14
+ yield
15
+ end
16
+ end
17
17
  end
18
18
 
19
19
  def sign_out
20
- SignOut.new(warden).perform
20
+ Monban.config.sign_out_service.new(warden).perform
21
21
  end
22
22
 
23
23
  def sign_up user_params
24
- SignUp.new(user_params).perform
24
+ Monban.config.sign_up_service.new(user_params).perform.tap do |status|
25
+ if status && block_given?
26
+ yield
27
+ end
28
+ end
25
29
  end
26
30
 
27
31
  def authenticate_session session_params, field_map = nil
@@ -31,7 +35,11 @@ module Monban
31
35
  end
32
36
 
33
37
  def authenticate user, password
34
- Authentication.new(user, password).perform
38
+ Monban.config.authentication_service.new(user, password).perform
39
+ end
40
+
41
+ def reset_password user, password
42
+ Monban.config.password_reset_service.new(user, password).perform
35
43
  end
36
44
 
37
45
  def warden
@@ -43,7 +51,7 @@ module Monban
43
51
  end
44
52
 
45
53
  def signed_in?
46
- current_user
54
+ warden.user
47
55
  end
48
56
 
49
57
  def require_login
@@ -0,0 +1,14 @@
1
+ module Monban
2
+ class PasswordReset
3
+ def initialize user, password
4
+ @user = user
5
+ @password = password
6
+ end
7
+
8
+ def perform
9
+ field = Monban.config.user_token_store_field
10
+ encrypted_password = Monban.encrypt_token(@password)
11
+ @user[field] = encrypted_password
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ require 'monban/services/sign_in'
2
+ require 'monban/services/sign_out'
3
+ require 'monban/services/sign_up'
4
+ require 'monban/services/authentication'
5
+ require 'monban/services/password_reset'
@@ -0,0 +1,15 @@
1
+ module Monban
2
+ module Test
3
+ module Helpers
4
+ include Warden::Test::Helpers
5
+
6
+ def sign_in user
7
+ login_as user
8
+ end
9
+
10
+ def sign_out
11
+ logout
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,3 +1,3 @@
1
1
  module Monban
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
data/lib/monban.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "monban/version"
2
2
  require "monban/configuration"
3
+ require "monban/services"
3
4
  require "monban/controller_helpers"
4
5
  require "monban/railtie"
5
6
  require "monban/warden_setup"
@@ -11,12 +12,13 @@ module Monban
11
12
  mattr_accessor :warden_config
12
13
  mattr_accessor :config
13
14
 
14
- def self.initialize warden_config
15
- self.warden_config = warden_config
16
- self.config = Monban::Configuration.new
17
- if block_given?
18
- yield config
19
- end
15
+ module Test
16
+ autoload :Helpers, "monban/test/helpers"
17
+ end
18
+
19
+ def self.initialize warden_config, &block
20
+ setup_config(&block)
21
+ setup_warden_config(warden_config)
20
22
  end
21
23
 
22
24
  def self.compare_token(digest, token)
@@ -35,4 +37,28 @@ module Monban
35
37
  fields = FieldMap.new(params, field_map).to_fields
36
38
  user_class.where(fields).first
37
39
  end
40
+
41
+ def self.test_mode!
42
+ Warden.test_mode!
43
+ config.encryption_method = ->(password) { password }
44
+ config.token_comparison = ->(digest, unencrypted_password) { digest == unencrypted_password }
45
+ end
46
+
47
+ def self.test_reset!
48
+ Warden.test_reset!
49
+ end
50
+
51
+ private
52
+
53
+ def self.setup_config
54
+ self.config = Monban::Configuration.new
55
+ if block_given?
56
+ yield config
57
+ end
58
+ end
59
+
60
+ def self.setup_warden_config(warden_config)
61
+ warden_config.failure_app = self.config.failure_app
62
+ self.warden_config = warden_config
63
+ end
38
64
  end
data/monban.gemspec CHANGED
@@ -27,4 +27,5 @@ Gem::Specification.new do |gem|
27
27
  gem.add_development_dependency 'pry'
28
28
  gem.add_development_dependency 'sqlite3'
29
29
  gem.add_development_dependency 'active_hash'
30
+ gem.add_development_dependency 'pry'
30
31
  end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ feature 'Visitor is unauthorzed' do
4
+ scenario 'when visiting a resource' do
5
+ visit failure_path
6
+ expect(page.status_code).to eq(401)
7
+ end
8
+ end
@@ -9,4 +9,23 @@ feature 'Visitor signs up' do
9
9
 
10
10
  page.current_path.should eq(posts_path)
11
11
  end
12
+
13
+ scenario 'multiple users' do
14
+ visit sign_up_path
15
+ fill_in 'user_email', with: 'email@example.com'
16
+ fill_in 'user_password', with: 'password'
17
+ click_on 'go'
18
+ click_on 'Sign out'
19
+ visit sign_up_path
20
+ fill_in 'user_email', with: 'email2@example.com'
21
+ fill_in 'user_password', with: 'password2'
22
+ click_on 'go'
23
+ click_on 'Sign out'
24
+ visit sign_in_path
25
+ fill_in 'session_email', with: 'email@example.com'
26
+ fill_in 'session_password', with: 'password'
27
+ click_on 'go'
28
+
29
+ page.current_path.should eq(posts_path)
30
+ end
12
31
  end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+
3
+ feature 'Visitor signs in' do
4
+ scenario 'with remember token' do
5
+ pending
6
+ Monban::SignUp.new(email: "email@example.com", password: "password").perform
7
+ visit sign_in_path
8
+ fill_in 'session_email', with: 'email@example.com'
9
+ fill_in 'session_password', with: 'password'
10
+ check 'Remember me'
11
+ click_on 'go'
12
+ end
13
+ end
@@ -30,13 +30,24 @@ module Monban
30
30
  end
31
31
 
32
32
  it 'performs a sign in' do
33
- user = double()
34
- sign_in = double()
35
- sign_in.should_receive(:perform)
36
- SignIn.should_receive(:new).with(user, @warden).and_return(sign_in)
33
+ user = stub_sign_in
37
34
  @dummy.sign_in user
38
35
  end
39
36
 
37
+ it 'runs the block when user is signed in' do
38
+ user = stub_sign_in
39
+ expectation = double()
40
+ expectation.should_receive(:success)
41
+ @dummy.sign_in(user) { expectation.success }
42
+ end
43
+
44
+ it 'does not run the block when user can not be signed in' do
45
+ user = stub_sign_in(false)
46
+ expectation = double()
47
+ expectation.should_not_receive(:failure)
48
+ @dummy.sign_in(user) { expectation.failure }
49
+ end
50
+
40
51
  it 'performs a sign out' do
41
52
  sign_out = double()
42
53
  sign_out.should_receive(:perform)
@@ -45,38 +56,49 @@ module Monban
45
56
  end
46
57
 
47
58
  it 'performs a sign_up' do
48
- user_params = double()
49
- sign_up = double()
50
- sign_up.should_receive(:perform)
51
- SignUp.should_receive(:new).with(user_params).and_return(sign_up)
59
+ user_params = stub_sign_up
52
60
  @dummy.sign_up user_params
53
61
  end
54
62
 
63
+ it 'runs the block when user is signed up' do
64
+ user_params = stub_sign_up
65
+ expectation = double()
66
+ expectation.should_receive(:success)
67
+ @dummy.sign_up(user_params) { expectation.success }
68
+ end
69
+
70
+ it 'does not run the block when user can not be signed up' do
71
+ user_params = stub_sign_up(false)
72
+ expectation = double()
73
+ expectation.should_not_receive(:failure)
74
+ @dummy.sign_up(user_params) { expecation.failure }
75
+ end
76
+
55
77
  it 'authenticates a session' do
56
- session_params = { 'password' => 'password', 'email' => 'a@b.com' }
78
+ session_params = { password: 'password', email: 'a@b.com' }
57
79
  user = double()
58
80
  authentication = double()
59
81
  authentication.should_receive(:perform).and_return(user)
60
- Monban.should_receive(:lookup).with({'email' => 'a@b.com'}, nil).and_return(user)
82
+ Monban.should_receive(:lookup).with({email: 'a@b.com'}, nil).and_return(user)
61
83
  Authentication.should_receive(:new).with(user, 'password').and_return(authentication)
62
84
  @dummy.authenticate_session(session_params).should == user
63
85
  end
64
86
 
65
87
  it 'authenticates a session against multiple fields' do
66
- session_params = { 'email_or_username' => 'foo', 'password' => 'password' }
88
+ session_params = { email_or_username: 'foo', password: 'password' }
67
89
  field_map = { email_or_username: [:email, :username] }
68
90
  user = double()
69
91
  authentication = double()
70
92
  authentication.should_receive(:perform).and_return(user)
71
- Monban.should_receive(:lookup).with(session_params.except('password'), field_map).and_return(user)
93
+ Monban.should_receive(:lookup).with(session_params.except(:password), field_map).and_return(user)
72
94
  Authentication.should_receive(:new).with(user, 'password').and_return(authentication)
73
95
  @dummy.authenticate_session(session_params, field_map).should == user
74
96
  end
75
97
 
76
98
  it 'returns false when it could not authenticate the user' do
77
99
  session_params = double()
78
- session_params.should_receive(:fetch).with('password').and_return('password')
79
- session_params.should_receive(:except).with('password').and_return(session_params)
100
+ session_params.should_receive(:fetch).with(:password).and_return('password')
101
+ session_params.should_receive(:except).with(:password).and_return(session_params)
80
102
  user = double()
81
103
  authentication = double()
82
104
  authentication.should_receive(:perform).and_return(false)
@@ -101,6 +123,7 @@ module Monban
101
123
 
102
124
  it 'returns signed_in?' do
103
125
  @warden.should_receive(:user)
126
+ @dummy.should_not_receive(:current_user)
104
127
  @dummy.signed_in?
105
128
  end
106
129
 
@@ -120,5 +143,21 @@ module Monban
120
143
  it 'returns warden' do
121
144
  @dummy.warden.should == @warden
122
145
  end
146
+
147
+ def stub_sign_in(success = true)
148
+ user = double()
149
+ sign_in = double()
150
+ sign_in.should_receive(:perform).and_return(success)
151
+ SignIn.should_receive(:new).with(user, @warden).and_return(sign_in)
152
+ user
153
+ end
154
+
155
+ def stub_sign_up(success = true)
156
+ user_params = double()
157
+ sign_up = double()
158
+ sign_up.should_receive(:perform).and_return(success)
159
+ SignUp.should_receive(:new).with(user_params).and_return(sign_up)
160
+ user_params
161
+ end
123
162
  end
124
163
  end
@@ -1,10 +1,10 @@
1
1
  require 'spec_helper'
2
- require 'monban/controller_helpers/authentication'
2
+ require 'monban/services/authentication'
3
3
 
4
4
  describe Monban::Authentication, '#authentication' do
5
5
  it 'is authenticated for a valid password' do
6
6
  password_digest = BCrypt::Password.create('password')
7
- user = stub(password_digest: password_digest)
7
+ user = double(password_digest: password_digest)
8
8
  auth = Monban::Authentication.new(user, 'password')
9
9
 
10
10
  expect(auth.perform).to eq(user)
@@ -12,7 +12,7 @@ describe Monban::Authentication, '#authentication' do
12
12
 
13
13
  it 'is not authenticated for the wrong password' do
14
14
  password_digest = BCrypt::Password.create('password')
15
- user = stub(password_digest: password_digest)
15
+ user = double(password_digest: password_digest)
16
16
  auth = Monban::Authentication.new(user, 'drowssap')
17
17
 
18
18
  expect(auth.perform).to eq(false)
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+ require 'monban/services/password_reset'
3
+ require 'ostruct'
4
+
5
+ describe Monban::PasswordReset do
6
+ before do
7
+ Monban.config.encryption_method = ->(password) { password + "secret" }
8
+ end
9
+
10
+ it 'updates the password with the encryption strategy' do
11
+ password_digest = Monban.encrypt_token('password')
12
+ user = double()
13
+ field = Monban.config.user_token_store_field
14
+ user.should_receive(:[]=).with(field, 'passwordsecret')
15
+ password_reset = Monban::PasswordReset.new(user, 'password')
16
+
17
+ password_reset.perform
18
+ end
19
+
20
+ after do
21
+ Monban.config.encryption_method = Monban.config.default_encryption_method
22
+ end
23
+ end
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
- require 'monban/controller_helpers/sign_in'
2
+ require 'monban/services/sign_in'
3
3
 
4
4
  describe Monban::SignIn, '#perform' do
5
5
  it 'signs the user in' do
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
- require 'monban/controller_helpers/sign_out'
2
+ require 'monban/services/sign_out'
3
3
 
4
4
  describe Monban::SignOut, '#perform' do
5
5
  it 'signs out the user' do
@@ -1,11 +1,11 @@
1
1
  require 'spec_helper'
2
- require 'monban/controller_helpers/sign_up'
2
+ require 'monban/services/sign_up'
3
3
 
4
4
  describe Monban::SignUp, '#perform' do
5
5
  it 'creates a user with the right parameters' do
6
6
  create = double
7
7
  stub_const('User', create)
8
- user_params = { 'email' => 'email@example.com', 'password' => 'password' }
8
+ user_params = { email: 'email@example.com', password: 'password' }
9
9
 
10
10
  create.should_receive(:create) do |args|
11
11
  args[:email].should eq(user_params[:email])
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+ require 'monban/test/helpers'
3
+
4
+ module Warden::Spec
5
+ module Helpers
6
+ FAILURE_APP = lambda{|e|[401, {"Content-Type" => "text/plain"}, ["You Fail!"]] }
7
+
8
+ def env_with_params(path = "/", params = {}, env = {})
9
+ method = params.delete(:method) || "GET"
10
+ env = { 'HTTP_VERSION' => '1.1', 'REQUEST_METHOD' => "#{method}" }.merge(env)
11
+ Rack::MockRequest.env_for("#{path}?#{Rack::Utils.build_query(params)}", env)
12
+ end
13
+
14
+ def setup_rack(app = nil, opts = {}, &block)
15
+ app ||= block if block_given?
16
+
17
+ opts[:failure_app] ||= failure_app
18
+ opts[:default_strategies] ||= [:password]
19
+ opts[:default_serializers] ||= [:session]
20
+ blk = opts[:configurator] || proc{}
21
+
22
+ Rack::Builder.new do
23
+ use opts[:session] || Warden::Spec::Helpers::Session unless opts[:nil_session]
24
+ use Warden::Manager, opts, &blk
25
+ run app
26
+ end
27
+ end
28
+
29
+ def valid_response
30
+ Rack::Response.new("OK").finish
31
+ end
32
+
33
+ def failure_app
34
+ Warden::Spec::Helpers::FAILURE_APP
35
+ end
36
+
37
+ def success_app
38
+ lambda{|e| [200, {"Content-Type" => "text/plain"}, ["You Win"]]}
39
+ end
40
+
41
+ class Session
42
+ attr_accessor :app
43
+ def initialize(app,configs = {})
44
+ @app = app
45
+ end
46
+
47
+ def call(e)
48
+ e['rack.session'] ||= {}
49
+ @app.call(e)
50
+ end
51
+ end # session
52
+ end
53
+ end
54
+
55
+ module Monban
56
+ module Test
57
+ describe Helpers do
58
+ include Monban::Test::Helpers
59
+ include Warden::Spec::Helpers
60
+
61
+ before { $captures = [] }
62
+ after { Monban.test_reset! }
63
+
64
+ it 'performs a sign in' do
65
+ user = double(id: 1)
66
+ sign_in(user)
67
+ app = lambda do |env|
68
+ $captures << :run
69
+ env['warden'].should be_authenticated
70
+ env['warden'].user.should eq(user)
71
+ valid_response
72
+ end
73
+ setup_rack(app).call(env_with_params)
74
+ $captures.should eq([:run])
75
+ end
76
+
77
+ it 'performs a sign out' do
78
+ user = double(id: 1)
79
+ sign_in(user)
80
+ sign_out
81
+
82
+ app = lambda do |env|
83
+ $captures << :run
84
+ warden = env['warden']
85
+ warden.user.should be_nil
86
+ warden.should_not be_authenticated
87
+ end
88
+
89
+ setup_rack(app).call(env_with_params)
90
+ $captures.should eq([:run])
91
+ end
92
+ end
93
+ end
94
+ end
data/spec/monban_spec.rb CHANGED
@@ -4,4 +4,10 @@ describe 'Monban' do
4
4
  it "stores the warden config" do
5
5
  expect(Monban.warden_config).to be_a Warden::Config
6
6
  end
7
+
8
+ it "provides a .test_mode!" do
9
+ Monban.test_mode!
10
+ expect(Monban.encrypt_token('password')).to eql('password')
11
+ expect(Monban.compare_token('password', 'password')).to be_true
12
+ end
7
13
  end
@@ -0,0 +1,5 @@
1
+ class FailuresController < ApplicationController
2
+ def show
3
+ render status: :unauthorized, text: "Unauthorized"
4
+ end
5
+ end
@@ -2,6 +2,5 @@ class PostsController < ApplicationController
2
2
  before_filter :require_login
3
3
 
4
4
  def index
5
- render nothing: true
6
5
  end
7
6
  end
@@ -2,10 +2,11 @@ class SessionsController < ApplicationController
2
2
  def new; end
3
3
 
4
4
  def create
5
- user = User.find_by_email(params[:session][:email])
5
+ user = User.where(email: params[:session][:email]).first
6
6
 
7
7
  if authenticate(user, params[:session][:password])
8
8
  sign_in user
9
+ redirect_to posts_path
9
10
  else
10
11
  redirect_to root_path, notice: "Invalid email or password"
11
12
  end
@@ -7,7 +7,9 @@
7
7
  <%= csrf_meta_tags %>
8
8
  </head>
9
9
  <body>
10
-
10
+ <% if signed_in? %>
11
+ <%= link_to "Sign out", sign_out_path, method: :delete %>
12
+ <% end %>
11
13
  <%= yield %>
12
14
 
13
15
  </body>
@@ -0,0 +1 @@
1
+ Posts
@@ -0,0 +1,5 @@
1
+ <%= form_for :session do |f| %>
2
+ <%= f.text_field :email %>
3
+ <%= f.text_field :password %>
4
+ <%= f.submit 'go' %>
5
+ <% end %>
@@ -11,9 +11,6 @@ RailsApp::Application.configure do
11
11
  config.serve_static_assets = true
12
12
  config.static_cache_control = "public, max-age=3600"
13
13
 
14
- # Log error messages when you accidentally call methods on nil
15
- config.whiny_nils = true
16
-
17
14
  # Show full error reports and disable caching
18
15
  config.consider_all_requests_local = true
19
16
  config.action_controller.perform_caching = false
@@ -26,4 +23,6 @@ RailsApp::Application.configure do
26
23
 
27
24
  # Print deprecation notices to the stderr
28
25
  config.active_support.deprecation = :stderr
26
+ config.eager_load = false
27
+ config.secret_key_base = "1"
29
28
  end
@@ -1,6 +1,8 @@
1
1
  RailsApp::Application.routes.draw do
2
2
  resources :posts, only: [:index]
3
3
  resources :users, only: [:create]
4
+ resource :failure, only: [:show]
5
+ root to: "users#new"
4
6
  get "sign_in" => "sessions#new"
5
7
  post "sign_in" => "sessions#create"
6
8
  delete "sign_out" => "sessions#destroy"
data/spec/spec_helper.rb CHANGED
@@ -5,3 +5,7 @@ require 'rails_app/config/environment'
5
5
  require 'rspec/rails'
6
6
  require 'monban'
7
7
  require 'capybara'
8
+
9
+ RSpec.configure do |config|
10
+ config.include Warden::Test::Helpers
11
+ end
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.7
4
+ version: 0.0.8
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: 2013-06-24 00:00:00.000000000 Z
12
+ date: 2014-01-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -151,6 +151,20 @@ dependencies:
151
151
  - - '>='
152
152
  - !ruby/object:Gem::Version
153
153
  version: '0'
154
+ - !ruby/object:Gem::Dependency
155
+ name: pry
156
+ requirement: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - '>='
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ type: :development
162
+ prerelease: false
163
+ version_requirements: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - '>='
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
154
168
  description: simple rails authentication
155
169
  email:
156
170
  - halogenandtoast@gmail.com
@@ -169,43 +183,51 @@ files:
169
183
  - lib/generators/monban/scaffold/scaffold_generator.rb
170
184
  - lib/generators/monban/templates/app/controllers/sessions_controller.rb
171
185
  - lib/generators/monban/templates/app/controllers/users_controller.rb
172
- - lib/generators/monban/templates/app/models/user.rb
173
186
  - lib/generators/monban/templates/app/views/sessions/new.html.erb
174
187
  - lib/generators/monban/templates/app/views/users/new.html.erb
175
- - lib/generators/monban/templates/db/migrate/create_users.rb
176
188
  - lib/generators/monban/templates/scaffold_readme
177
189
  - lib/monban.rb
178
190
  - lib/monban/configuration.rb
179
191
  - lib/monban/controller_helpers.rb
180
- - lib/monban/controller_helpers/authentication.rb
181
- - lib/monban/controller_helpers/sign_in.rb
182
- - lib/monban/controller_helpers/sign_out.rb
183
- - lib/monban/controller_helpers/sign_up.rb
184
192
  - lib/monban/field_map.rb
185
193
  - lib/monban/railtie.rb
194
+ - lib/monban/services.rb
195
+ - lib/monban/services/authentication.rb
196
+ - lib/monban/services/password_reset.rb
197
+ - lib/monban/services/sign_in.rb
198
+ - lib/monban/services/sign_out.rb
199
+ - lib/monban/services/sign_up.rb
186
200
  - lib/monban/strategies/password_strategy.rb
201
+ - lib/monban/test/helpers.rb
187
202
  - lib/monban/version.rb
188
203
  - lib/monban/warden_setup.rb
189
204
  - monban.gemspec
205
+ - spec/features/visitor/visitor_is_unauthorized_spec.rb
190
206
  - spec/features/visitor/visitor_signs_up_spec.rb
191
- - spec/monban/controller_helpers/authentication_spec.rb
192
- - spec/monban/controller_helpers/sign_in_spec.rb
193
- - spec/monban/controller_helpers/sign_out_spec.rb
194
- - spec/monban/controller_helpers/sign_up_spec.rb
207
+ - spec/features/visitor/visitor_uses_remember_token_spec.rb
195
208
  - spec/monban/controller_helpers_spec.rb
196
209
  - spec/monban/field_map_spec.rb
210
+ - spec/monban/services/authentication_spec.rb
211
+ - spec/monban/services/password_reset_spec.rb
212
+ - spec/monban/services/sign_in_spec.rb
213
+ - spec/monban/services/sign_out_spec.rb
214
+ - spec/monban/services/sign_up_spec.rb
215
+ - spec/monban/test_helpers_spec.rb
197
216
  - spec/monban_spec.rb
198
217
  - spec/rails_app/Rakefile
199
218
  - spec/rails_app/app/assets/images/rails.png
200
219
  - spec/rails_app/app/assets/javascripts/application.js
201
220
  - spec/rails_app/app/assets/stylesheets/application.css
202
221
  - spec/rails_app/app/controllers/application_controller.rb
222
+ - spec/rails_app/app/controllers/failures_controller.rb
203
223
  - spec/rails_app/app/controllers/posts_controller.rb
204
224
  - spec/rails_app/app/controllers/sessions_controller.rb
205
225
  - spec/rails_app/app/controllers/users_controller.rb
206
226
  - spec/rails_app/app/helpers/application_helper.rb
207
227
  - spec/rails_app/app/models/user.rb
208
228
  - spec/rails_app/app/views/layouts/application.html.erb
229
+ - spec/rails_app/app/views/posts/index.html.erb
230
+ - spec/rails_app/app/views/sessions/new.html.erb
209
231
  - spec/rails_app/app/views/users/new.html.erb
210
232
  - spec/rails_app/config.ru
211
233
  - spec/rails_app/config/application.rb
@@ -251,25 +273,32 @@ signing_key:
251
273
  specification_version: 4
252
274
  summary: Making rails authentication as simple as possible
253
275
  test_files:
276
+ - spec/features/visitor/visitor_is_unauthorized_spec.rb
254
277
  - spec/features/visitor/visitor_signs_up_spec.rb
255
- - spec/monban/controller_helpers/authentication_spec.rb
256
- - spec/monban/controller_helpers/sign_in_spec.rb
257
- - spec/monban/controller_helpers/sign_out_spec.rb
258
- - spec/monban/controller_helpers/sign_up_spec.rb
278
+ - spec/features/visitor/visitor_uses_remember_token_spec.rb
259
279
  - spec/monban/controller_helpers_spec.rb
260
280
  - spec/monban/field_map_spec.rb
281
+ - spec/monban/services/authentication_spec.rb
282
+ - spec/monban/services/password_reset_spec.rb
283
+ - spec/monban/services/sign_in_spec.rb
284
+ - spec/monban/services/sign_out_spec.rb
285
+ - spec/monban/services/sign_up_spec.rb
286
+ - spec/monban/test_helpers_spec.rb
261
287
  - spec/monban_spec.rb
262
288
  - spec/rails_app/Rakefile
263
289
  - spec/rails_app/app/assets/images/rails.png
264
290
  - spec/rails_app/app/assets/javascripts/application.js
265
291
  - spec/rails_app/app/assets/stylesheets/application.css
266
292
  - spec/rails_app/app/controllers/application_controller.rb
293
+ - spec/rails_app/app/controllers/failures_controller.rb
267
294
  - spec/rails_app/app/controllers/posts_controller.rb
268
295
  - spec/rails_app/app/controllers/sessions_controller.rb
269
296
  - spec/rails_app/app/controllers/users_controller.rb
270
297
  - spec/rails_app/app/helpers/application_helper.rb
271
298
  - spec/rails_app/app/models/user.rb
272
299
  - spec/rails_app/app/views/layouts/application.html.erb
300
+ - spec/rails_app/app/views/posts/index.html.erb
301
+ - spec/rails_app/app/views/sessions/new.html.erb
273
302
  - spec/rails_app/app/views/users/new.html.erb
274
303
  - spec/rails_app/config.ru
275
304
  - spec/rails_app/config/application.rb
@@ -291,3 +320,4 @@ test_files:
291
320
  - spec/rails_app/public/favicon.ico
292
321
  - spec/rails_app/script/rails
293
322
  - spec/spec_helper.rb
323
+ has_rdoc:
@@ -1,7 +0,0 @@
1
- class User < ActiveRecord::Base
2
- <% if !config[:use_strong_parameters] -%>
3
- attr_accessible :email, :password_digest
4
- <% elsif Gem::Version.new(Rails.version).segments[0] < 4 -%>
5
- include ActiveModel::ForbiddenAttributesProtection
6
- <% end -%>
7
- end
@@ -1,10 +0,0 @@
1
- class CreateUsers < ActiveRecord::Migration
2
- def change
3
- create_table :users do |t|
4
- t.string :email
5
- t.string :password_digest
6
-
7
- t.timestamps
8
- end
9
- end
10
- end