monban 0.0.7 → 0.0.8
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/Gemfile.lock +4 -4
- data/README.md +76 -21
- data/lib/generators/monban/scaffold/scaffold_generator.rb +1 -6
- data/lib/generators/monban/templates/app/controllers/sessions_controller.rb +4 -6
- data/lib/generators/monban/templates/app/controllers/users_controller.rb +4 -2
- data/lib/monban/configuration.rb +38 -7
- data/lib/monban/controller_helpers.rb +17 -9
- data/lib/monban/{controller_helpers → services}/authentication.rb +0 -0
- data/lib/monban/services/password_reset.rb +14 -0
- data/lib/monban/{controller_helpers → services}/sign_in.rb +0 -0
- data/lib/monban/{controller_helpers → services}/sign_out.rb +0 -0
- data/lib/monban/{controller_helpers → services}/sign_up.rb +0 -0
- data/lib/monban/services.rb +5 -0
- data/lib/monban/test/helpers.rb +15 -0
- data/lib/monban/version.rb +1 -1
- data/lib/monban.rb +32 -6
- data/monban.gemspec +1 -0
- data/spec/features/visitor/visitor_is_unauthorized_spec.rb +8 -0
- data/spec/features/visitor/visitor_signs_up_spec.rb +19 -0
- data/spec/features/visitor/visitor_uses_remember_token_spec.rb +13 -0
- data/spec/monban/controller_helpers_spec.rb +53 -14
- data/spec/monban/{controller_helpers → services}/authentication_spec.rb +3 -3
- data/spec/monban/services/password_reset_spec.rb +23 -0
- data/spec/monban/{controller_helpers → services}/sign_in_spec.rb +1 -1
- data/spec/monban/{controller_helpers → services}/sign_out_spec.rb +1 -1
- data/spec/monban/{controller_helpers → services}/sign_up_spec.rb +2 -2
- data/spec/monban/test_helpers_spec.rb +94 -0
- data/spec/monban_spec.rb +6 -0
- data/spec/rails_app/app/controllers/failures_controller.rb +5 -0
- data/spec/rails_app/app/controllers/posts_controller.rb +0 -1
- data/spec/rails_app/app/controllers/sessions_controller.rb +2 -1
- data/spec/rails_app/app/views/layouts/application.html.erb +3 -1
- 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/config/environments/test.rb +2 -3
- data/spec/rails_app/config/routes.rb +2 -0
- data/spec/spec_helper.rb +4 -0
- metadata +46 -16
- data/lib/generators/monban/templates/app/models/user.rb +0 -7
- 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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1eea738a714fc0f03f4e0a62079eb8fe979a925d
|
|
4
|
+
data.tar.gz: b169d1d7730f4ff61ff1f5783a7588ded2dd63bf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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.
|
|
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.
|
|
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.
|
|
129
|
+
treetop (1.4.14)
|
|
130
130
|
polyglot
|
|
131
131
|
polyglot (>= 0.3.1)
|
|
132
|
-
tzinfo (0.3.
|
|
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
|
-
-
|
|
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 >
|
|
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
|
|
46
|
+
Monban does currently have some out of the box expectations, but you can configure any of these:
|
|
47
47
|
|
|
48
|
-
-
|
|
49
|
-
- You
|
|
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
|
-
|
|
71
|
+
## Usage in Tests
|
|
72
72
|
|
|
73
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
|
|
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)
|
|
10
|
-
|
|
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
|
-
|
|
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
|
data/lib/monban/configuration.rb
CHANGED
|
@@ -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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
|
|
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
|
-
|
|
20
|
+
Monban.config.sign_out_service.new(warden).perform
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def sign_up user_params
|
|
24
|
-
|
|
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
|
-
|
|
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
|
-
|
|
54
|
+
warden.user
|
|
47
55
|
end
|
|
48
56
|
|
|
49
57
|
def require_login
|
|
File without changes
|
|
@@ -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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
data/lib/monban/version.rb
CHANGED
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
@@ -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 =
|
|
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 =
|
|
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 = {
|
|
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({
|
|
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 = {
|
|
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(
|
|
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(
|
|
79
|
-
session_params.should_receive(:except).with(
|
|
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/
|
|
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 =
|
|
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 =
|
|
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,11 +1,11 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
|
-
require 'monban/
|
|
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 = {
|
|
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
|
|
@@ -2,10 +2,11 @@ class SessionsController < ApplicationController
|
|
|
2
2
|
def new; end
|
|
3
3
|
|
|
4
4
|
def create
|
|
5
|
-
user = User.
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Posts
|
|
@@ -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
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.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:
|
|
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/
|
|
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/
|
|
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:
|