authkit 0.0.1

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.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/FEATURES.md +73 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +168 -0
  7. data/Rakefile +60 -0
  8. data/authkit.gemspec +27 -0
  9. data/config/database.yml.example +19 -0
  10. data/lib/authkit.rb +5 -0
  11. data/lib/authkit/engine.rb +7 -0
  12. data/lib/authkit/version.rb +3 -0
  13. data/lib/generators/authkit/USAGE +18 -0
  14. data/lib/generators/authkit/install_generator.rb +113 -0
  15. data/lib/generators/authkit/templates/app/controllers/application_controller.rb +94 -0
  16. data/lib/generators/authkit/templates/app/controllers/email_confirmation_controller.rb +25 -0
  17. data/lib/generators/authkit/templates/app/controllers/password_change_controller.rb +29 -0
  18. data/lib/generators/authkit/templates/app/controllers/password_reset_controller.rb +29 -0
  19. data/lib/generators/authkit/templates/app/controllers/sessions_controller.rb +35 -0
  20. data/lib/generators/authkit/templates/app/controllers/users_controller.rb +89 -0
  21. data/lib/generators/authkit/templates/app/models/user.rb +170 -0
  22. data/lib/generators/authkit/templates/app/views/password_change/show.html.erb +16 -0
  23. data/lib/generators/authkit/templates/app/views/password_reset/show.html.erb +12 -0
  24. data/lib/generators/authkit/templates/app/views/sessions/new.html.erb +13 -0
  25. data/lib/generators/authkit/templates/app/views/users/edit.html.erb +58 -0
  26. data/lib/generators/authkit/templates/app/views/users/new.html.erb +58 -0
  27. data/lib/generators/authkit/templates/db/migrate/add_authkit_fields_to_users.rb +110 -0
  28. data/lib/generators/authkit/templates/db/migrate/create_users.rb +17 -0
  29. data/lib/generators/authkit/templates/lib/email_format_validator.rb +11 -0
  30. data/lib/generators/authkit/templates/spec/controllers/application_controller_spec.rb +188 -0
  31. data/lib/generators/authkit/templates/spec/controllers/email_confirmation_controller_spec.rb +80 -0
  32. data/lib/generators/authkit/templates/spec/controllers/password_change_controller_spec.rb +98 -0
  33. data/lib/generators/authkit/templates/spec/controllers/password_reset_controller_spec.rb +87 -0
  34. data/lib/generators/authkit/templates/spec/controllers/sessions_controller_spec.rb +111 -0
  35. data/lib/generators/authkit/templates/spec/controllers/users_controller_spec.rb +195 -0
  36. data/lib/generators/authkit/templates/spec/models/user_spec.rb +268 -0
  37. data/spec/spec_helper.rb +16 -0
  38. metadata +165 -0
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ describe EmailConfirmationController do
4
+ render_views
5
+
6
+ let(:user_params) { { email: "test@example.com", username: "test", password: "example", password_confirmation: "example" } }
7
+ let(:user) { User.new(user_params) }
8
+ let(:token) { "TOKEN" }
9
+
10
+ describe "GET 'show'" do
11
+ it "requires a valid token" do
12
+ User.should_receive(:user_from_token).with(token).and_return(nil)
13
+ get 'show', token: token
14
+ response.should be_redirect
15
+ flash[:error].should_not be_empty
16
+ end
17
+
18
+ describe "with a valid token" do
19
+ before(:each) do
20
+ user.confirmation_email = "new@example.com"
21
+ user.confirmation_token = token
22
+ end
23
+
24
+ describe "when the confirmation is successful" do
25
+ it "confirms the user email" do
26
+ User.should_receive(:user_from_token).with(token).and_return(user)
27
+ user.should_receive(:email_confirmed).and_return(true)
28
+ get 'show', token: token
29
+ end
30
+
31
+ it "signs the user in" do
32
+ User.should_receive(:user_from_token).with(token).and_return(user)
33
+ controller.should_receive(:login).with(user)
34
+ get 'show', token: token
35
+ end
36
+
37
+ it "sets the flash" do
38
+ User.should_receive(:user_from_token).with(token).and_return(user)
39
+ get 'show', token: token
40
+ flash[:notice].should_not be_nil
41
+ end
42
+
43
+ it "redirects the user" do
44
+ User.should_receive(:user_from_token).with(token).and_return(user)
45
+ get 'show', token: token
46
+ response.should be_redirect
47
+ end
48
+
49
+ describe "from json" do
50
+ it "returns http success" do
51
+ User.should_receive(:user_from_token).with(token).and_return(user)
52
+ get 'show', token: token, format: 'json'
53
+ response.should be_success
54
+ end
55
+ end
56
+
57
+ end
58
+
59
+ describe "when the confirmation is not successful" do
60
+ it "handles invalid confirmations" do
61
+ User.should_receive(:user_from_token).with(token).and_return(user)
62
+ user.should_receive(:email_confirmed).and_return(false)
63
+ get 'show', token: token
64
+ flash[:error].should_not be_empty
65
+ response.should be_redirect
66
+ end
67
+
68
+ describe "from json" do
69
+ it "returns a 422" do
70
+ User.should_receive(:user_from_token).with(token).and_return(user)
71
+ user.should_receive(:email_confirmed).and_return(false)
72
+ get 'show', token: token, format: 'json'
73
+ response.code.should == '422'
74
+ end
75
+ end
76
+
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+
3
+ describe PasswordChangeController do
4
+ render_views
5
+
6
+ let(:user_params) { { email: "test@example.com", username: "test", password: "example", password_confirmation: "example" } }
7
+ let(:user) { User.new(user_params) }
8
+ let(:token) { "TOKEN" }
9
+
10
+ describe "GET 'show'" do
11
+ it "requires a valid token" do
12
+ User.should_receive(:user_from_token).with(token).and_return(nil)
13
+ get 'show', token: token
14
+ response.should be_redirect
15
+ flash[:error].should_not be_empty
16
+ end
17
+
18
+ it "returns http success" do
19
+ User.should_receive(:user_from_token).with(token).and_return(user)
20
+ get 'show', token: token
21
+ response.should be_success
22
+ end
23
+ end
24
+
25
+ describe "POST 'create'" do
26
+ it "requires a valid token" do
27
+ User.should_receive(:user_from_token).with(token).and_return(nil)
28
+ post 'create', {token: token, password: 'newpassword', password_confirmation: 'newpassword'}
29
+ response.should be_redirect
30
+ flash[:error].should_not be_empty
31
+ end
32
+
33
+ describe "with valid params" do
34
+ before(:each) do
35
+ User.should_receive(:user_from_token).with(token).and_return(user)
36
+ end
37
+
38
+ it "changes the password" do
39
+ expect {
40
+ post 'create', {token: token, password: 'newpassword', password_confirmation: 'newpassword'}
41
+ }.to change(user, :password_digest)
42
+
43
+ user.should be_valid
44
+ end
45
+
46
+ it "signs the user in" do
47
+ controller.should_receive(:login).with(user)
48
+ post 'create', {token: token, password: 'newpassword', password_confirmation: 'newpassword'}
49
+ end
50
+
51
+ it "redirects the user" do
52
+ post 'create', {token: token, password: 'newpassword', password_confirmation: 'newpassword'}
53
+ response.should be_redirect
54
+ end
55
+
56
+ it "sets the flash" do
57
+ post 'create', {token: token, password: 'newpassword', password_confirmation: 'newpassword'}
58
+ flash[:notice].should =~ /successfully/i
59
+ end
60
+
61
+ describe "from json" do
62
+ it "returns http success" do
63
+ post 'create', {token: token, password: 'newpassword', password_confirmation: 'newpassword', format: 'json'}
64
+ response.should be_success
65
+ end
66
+ end
67
+ end
68
+
69
+ describe "with invalid params" do
70
+ before(:each) do
71
+ User.should_receive(:user_from_token).with(token).and_return(user)
72
+ end
73
+
74
+ it "doesn't sign the user in" do
75
+ controller.should_not_receive(:login)
76
+ post 'create', {token: token, password: 'newpassword', password_confirmation: 'invalid'}
77
+ end
78
+
79
+ it "renders the show template" do
80
+ post 'create', {token: token, password: 'newpassword', password_confirmation: 'invalid'}
81
+ response.should render_template(:show)
82
+ end
83
+
84
+ it "has errors" do
85
+ post 'create', {token: token, password: 'newpassword', password_confirmation: 'invalid'}
86
+ assigns(:user).should have(2).errors_on(:password_confirmation)
87
+ end
88
+
89
+ describe "from json" do
90
+ it "returns an error" do
91
+ post 'create', {token: token, password: 'newpassword', password_confirmation: 'invalid', format: 'json'}
92
+ response.code.should == '422'
93
+ response.body.should =~ /doesn't match/i
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+
3
+ describe PasswordResetController do
4
+ render_views
5
+
6
+ let(:user_params) { { email: "test@example.com", username: "test", password: "example", password_confirmation: "example" } }
7
+ let(:user) { User.new(user_params) }
8
+
9
+ describe "GET 'show'" do
10
+ it "returns http success" do
11
+ get 'show'
12
+ response.should be_success
13
+ end
14
+ end
15
+
16
+ describe "POST 'create'" do
17
+ before(:each) do
18
+ User.stub(:find_by_username_or_email).with("test@example.com").and_return(user)
19
+ User.stub(:find_by_username_or_email).with("unknown@example.com").and_return(nil)
20
+ user.stub(:persisted?).and_return(true)
21
+ user.stub(:id).and_return(1)
22
+ end
23
+
24
+ it "redirects the user" do
25
+ post :create, {email: "test@example.com"}
26
+ response.should be_redirect
27
+ end
28
+
29
+ it "finds the user by the email or user name" do
30
+ User.should_receive(:find_by_username_or_email).with("test@example.com").and_return(user)
31
+ post :create, {email: "test@example.com"}
32
+ end
33
+
34
+ it "downcases the email or user name" do
35
+ User.should_receive(:find_by_username_or_email).with("test@example.com").and_return(user)
36
+ post :create, {email: "TEST@EXAMPLE.COM"}
37
+ end
38
+
39
+ it "logs any current user out if it finds the user" do
40
+ controller.should_receive(:logout)
41
+ post :create, {email: "test@example.com"}
42
+ end
43
+
44
+ it "resets the password if it finds the user" do
45
+ user.should_receive(:send_reset_password).and_return(true)
46
+ post :create, {email: "test@example.com"}
47
+ end
48
+
49
+ it "does not reset the password if it does not find a user" do
50
+ User.any_instance.should_not_receive(:send_reset_password)
51
+ post :create, {email: "unknown@example.com"}
52
+ end
53
+
54
+ describe "from json" do
55
+ it "returns http success" do
56
+ post :create, {email: "test@example.com", format: "json"}
57
+ response.should be_success
58
+ end
59
+ end
60
+
61
+ describe "with invalid email" do
62
+ describe "from html" do
63
+ it "sets the flash message" do
64
+ post :create, {email: "unknown@example.com"}
65
+ flash.now[:error].should_not be_empty
66
+ end
67
+
68
+ it "renders the show page" do
69
+ post :create, {email: "unknown@example.com"}
70
+ response.should render_template(:show)
71
+ end
72
+ end
73
+
74
+ describe "from json" do
75
+ it "returns an error" do
76
+ post :create, {email: "unknown@example.com", format: "json"}
77
+ response.body.should =~ /invalid user name or email/i
78
+ end
79
+
80
+ it "returns forbidden status" do
81
+ post :create, {email: "unknown@example.com", format: "json"}
82
+ response.code.should == '422'
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,111 @@
1
+ require 'spec_helper'
2
+
3
+ describe SessionsController do
4
+ render_views
5
+
6
+ let(:user_params) { { email: "test@example.com", username: "test", password: "example", password_confirmation: "example" } }
7
+ let(:user) { User.new(user_params) }
8
+ let(:logged_in_session) { { user_id: "1" } }
9
+
10
+ before(:each) do
11
+ User.stub(:find_by).with("1").and_return(user)
12
+ end
13
+
14
+ describe "GET 'new'" do
15
+ it "returns http success" do
16
+ get 'new'
17
+ response.should be_success
18
+ end
19
+ end
20
+
21
+ describe "POST 'create'" do
22
+ before(:each) do
23
+ User.stub(:find_by_username_or_email).with("test@example.com").and_return(user)
24
+ User.stub(:find_by_username_or_email).with("unknown@example.com").and_return(nil)
25
+ end
26
+
27
+ it "redirects the user" do
28
+ post :create, {email: "test@example.com", password: "example"}
29
+ response.should be_redirect
30
+ end
31
+
32
+ it "finds the user by the email or user name" do
33
+ User.should_receive(:find_by_username_or_email).with("test@example.com").and_return(user)
34
+ post :create, {email: "test@example.com", password: "example"}
35
+ end
36
+
37
+ it "downcases the email or user name" do
38
+ User.should_receive(:find_by_username_or_email).with("test@example.com").and_return(user)
39
+ post :create, {email: "TEST@EXAMPLE.COM", password: "example"}
40
+ end
41
+
42
+ it "authenticates if it finds the user" do
43
+ user.should_receive(:authenticate).and_return(true)
44
+ post :create, {email: "test@example.com", password: "example"}
45
+ end
46
+
47
+ it "does not authenticate if it does not find a user" do
48
+ User.any_instance.should_not_receive(:authenticate)
49
+ post :create, {email: "unknown@example.com", password: "example"}
50
+ end
51
+
52
+ it "signs the user in" do
53
+ post :create, {email: "test@example.com", password: "example"}
54
+ controller.send(:current_user).should == user
55
+ end
56
+
57
+ describe "from json" do
58
+ it "returns http success" do
59
+ post :create, {email: "test@example.com", password: "example", format: "json"}
60
+ response.should be_success
61
+ end
62
+ end
63
+
64
+ describe "with invalid password" do
65
+ describe "from html" do
66
+ it "sets the flash message" do
67
+ post :create, {email: "test@example.com", password: "wrongpassword"}
68
+ flash.now[:error].should_not be_empty
69
+ end
70
+
71
+ it "renders the new page" do
72
+ post :create, {email: "test@example.com", password: "wrongpassword"}
73
+ response.should render_template(:new)
74
+ end
75
+ end
76
+
77
+ describe "from json" do
78
+ it "returns an error" do
79
+ post :create, {email: "test@example.com", password: "wrongpassword", format: "json"}
80
+ response.body.should =~ /invalid user name or password/i
81
+ end
82
+
83
+ it "returns forbidden status" do
84
+ post :create, {email: "test@example.com", password: "wrongpassword", format: "json"}
85
+ response.code.should == '422'
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ describe "DELETE 'destroy'" do
92
+ it "logs the user out" do
93
+ delete "destroy", {}, logged_in_session
94
+ controller.send(:current_user).should be_nil
95
+ end
96
+
97
+ describe "from html" do
98
+ it "redirects the user" do
99
+ delete "destroy", {}, logged_in_session
100
+ response.should redirect_to(root_path)
101
+ end
102
+ end
103
+
104
+ describe "from json" do
105
+ it "returns http success" do
106
+ delete "destroy", {format: 'json'}, logged_in_session
107
+ response.should be_success
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,195 @@
1
+ require 'spec_helper'
2
+
3
+ describe UsersController do
4
+ render_views
5
+
6
+ let(:user_params) { { email: "test@example.com", username: "test", password: "example", password_confirmation: "example" } }
7
+ let(:invalid_params) { user_params.merge(password: 'newpassword', password_confirmation: 'wrongpassword') }
8
+ let(:user) { User.new(user_params) }
9
+ let(:logged_in_session) { { user_id: "1" } }
10
+
11
+ before(:each) do
12
+ User.stub(:find_by).with("1").and_return(user)
13
+ end
14
+
15
+ describe "GET 'new'" do
16
+ it "returns http success" do
17
+ get :new
18
+ response.should be_success
19
+ assigns(:user).should be_a_new(User)
20
+ end
21
+ end
22
+
23
+ describe "POST 'create'" do
24
+ describe "with valid params" do
25
+ describe "from html" do
26
+ it "creates a new user" do
27
+ expect {
28
+ post :create, {user: user_params}, {}
29
+ }.to change(User, :count).by(1)
30
+ end
31
+
32
+ it "confirms the email" do
33
+ User.any_instance.should_receive(:send_confirmation)
34
+ post :create, {user: user_params}, {}
35
+ end
36
+
37
+ it "signs the user in" do
38
+ post :create, {user: user_params}, {}
39
+ controller.send(:current_user).should == assigns(:user)
40
+ end
41
+
42
+ it "redirects to the root" do
43
+ post :create, {user: user_params}
44
+ response.should be_redirect
45
+ end
46
+ end
47
+
48
+ describe "from json" do
49
+ it "creates the user" do
50
+ expect {
51
+ post :create, {user: user_params, format: 'json'}, {}
52
+ }.to change(User, :count).by(1)
53
+ end
54
+
55
+ it "signs the user in" do
56
+ post :create, {user: user_params, format: 'json'}, {}
57
+ controller.send(:current_user).should == assigns(:user)
58
+ end
59
+
60
+ it "returns http success" do
61
+ post :create, {user: user_params, format: 'json'}
62
+ response.should be_success
63
+ end
64
+ end
65
+ end
66
+
67
+ describe "with invalid params" do
68
+ describe "from html" do
69
+ it "renders the new page" do
70
+ post :create, {user: invalid_params}, {}
71
+ response.should render_template("new")
72
+ end
73
+
74
+ it "does not create a user" do
75
+ expect {
76
+ post :create, {user: invalid_params}, {}
77
+ }.to_not change(User, :count)
78
+ end
79
+
80
+ it "sets the errors" do
81
+ post :create, {user: invalid_params}, {}
82
+ assigns(:user).should have(2).errors_on(:password_confirmation)
83
+ end
84
+ end
85
+
86
+ describe "from json" do
87
+ it "returns a 422" do
88
+ post :create, {user: invalid_params, format: 'json'}, {}
89
+ response.code.should == '422'
90
+ end
91
+
92
+ it "includes the errors in the json" do
93
+ post :create, {user: invalid_params, format: 'json'}, {}
94
+ assigns(:user).should have(2).errors_on(:password_confirmation)
95
+ response.body.should =~ /doesn't match Password/i
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+ describe "GET 'edit'" do
102
+ it "redirects if there is no current user" do
103
+ get :edit
104
+ response.should be_redirect
105
+ end
106
+
107
+ it "edits the current user" do
108
+ get :edit, {}, logged_in_session
109
+ response.should be_success
110
+ end
111
+ end
112
+
113
+ describe "PUT 'update'" do
114
+ it "redirects if there is no current user" do
115
+ put :update, {user: user_params.merge(first_name: "Alvarez")}
116
+ response.should be_redirect
117
+ end
118
+
119
+ describe "with valid params" do
120
+ describe "when changing the email" do
121
+ it "doesn't send the confirmation the email if unchanged" do
122
+ user.email = user.confirmation_email
123
+ user.confirmation_email = nil
124
+ user.should_not_receive(:send_confirmation)
125
+ put :update, {user: user_params.merge(confirmation_email: "test@example.com")}, logged_in_session
126
+ end
127
+
128
+ it "doesn't reconfirm if the confirmation email is unchanged" do
129
+ user.should_not_receive(:send_confirmation)
130
+ put :update, {user: user_params.merge(confirmation_email: "test@example.com")}, logged_in_session
131
+ end
132
+
133
+ it "confirms the confirmation email" do
134
+ user.email = "old@example.com"
135
+ user.should_receive(:send_confirmation).and_return(true)
136
+ put :update, {user: user_params.merge(confirmation_email: "new@example.com")}, logged_in_session
137
+ end
138
+ end
139
+
140
+ describe "from html" do
141
+ it "updates the user" do
142
+ expect {
143
+ put :update, {user: user_params.merge(first_name: "Alvarez")}, logged_in_session
144
+ }.to change(user, :first_name)
145
+ end
146
+
147
+ it "redirects the user" do
148
+ put :update, {user: user_params}, logged_in_session
149
+ response.should be_redirect
150
+ end
151
+ end
152
+
153
+ describe "from json" do
154
+ it "updates the user" do
155
+ expect {
156
+ put :update, {user: user_params.merge(first_name: "Alvarez"), format: 'json'}, logged_in_session
157
+ }.to change(user, :first_name)
158
+ end
159
+ end
160
+ end
161
+
162
+ describe "with invalid params" do
163
+ describe "from html" do
164
+ before(:each) do
165
+ put :update, {user: invalid_params}, logged_in_session
166
+ end
167
+
168
+ it "renders the edit page" do
169
+ response.should render_template('edit')
170
+ response.should be_success
171
+ end
172
+
173
+ it "sets the errors" do
174
+ user.should have(2).errors_on(:password_confirmation)
175
+ end
176
+ end
177
+
178
+ describe "from json" do
179
+ before(:each) do
180
+ put :update, {user: invalid_params, format: 'json'}, logged_in_session
181
+ end
182
+
183
+ it "returns a 422" do
184
+ response.code.should == '422'
185
+ end
186
+
187
+ it "includes the errors in the json" do
188
+ user.should have(2).errors_on(:password_confirmation)
189
+ response.body.should =~ /doesn't match Password/i
190
+ end
191
+ end
192
+ end
193
+ end
194
+ end
195
+