goma 0.0.1.gamma → 0.0.1.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -1
  3. data/Gemfile.lock +13 -9
  4. data/Rakefile +14 -0
  5. data/goma.gemspec +6 -0
  6. data/lib/generators/goma/erb/templates/confirmation/new.html.erb +2 -2
  7. data/lib/generators/goma/erb/templates/password/edit.html.erb +6 -6
  8. data/lib/generators/goma/erb/templates/unlock/new.html.erb +1 -1
  9. data/lib/generators/goma/erb/templates/user/_form.html.erb +1 -1
  10. data/lib/generators/goma/erb/templates/user/new.html.erb +4 -0
  11. data/lib/generators/goma/mailer/erb/templates/activation_needed_email.text.erb +1 -1
  12. data/lib/generators/goma/model/active_record_generator.rb +1 -0
  13. data/lib/generators/goma/model/oauth/active_record_generator.rb +3 -3
  14. data/lib/generators/goma/resource_route/resource_route_generator.rb +13 -9
  15. data/lib/generators/goma/scaffold_controller/templates/confirmation_controller.rb +8 -4
  16. data/lib/generators/goma/scaffold_controller/templates/oauth_controller.rb +5 -0
  17. data/lib/generators/goma/scaffold_controller/templates/password_controller.rb +9 -4
  18. data/lib/generators/goma/scaffold_controller/templates/unlock_controller.rb +1 -0
  19. data/lib/generators/goma/scaffold_controller/templates/user_controller.rb +41 -1
  20. data/lib/goma/config.rb +4 -4
  21. data/lib/goma/models/authenticatable.rb +20 -9
  22. data/lib/goma/models/confirmable.rb +15 -9
  23. data/lib/goma/models/password_authenticatable.rb +2 -1
  24. data/lib/goma/models/recoverable.rb +1 -1
  25. data/lib/goma/models/validatable.rb +4 -4
  26. data/lib/goma/railtie.rb +1 -0
  27. data/lib/goma/version.rb +1 -1
  28. data/test/integration/confirmable_integration_test.rb +185 -0
  29. data/test/integration/lockable_integration_test.rb +49 -0
  30. data/test/integration/omniauthable_integration_test.rb +64 -12
  31. data/test/integration/password_authenticatable_integration_test.rb +40 -0
  32. data/test/integration/recoverable_integration_test.rb +96 -0
  33. data/test/integration/rememberable_integration_test.rb +14 -0
  34. data/test/models/confirmable_test.rb +6 -6
  35. data/test/models/omniauthable_test.rb +2 -2
  36. data/test/rails_app/app/controllers/authentications_controller.rb +5 -0
  37. data/test/rails_app/app/controllers/confirmations_controller.rb +8 -4
  38. data/test/rails_app/app/controllers/passwords_controller.rb +9 -4
  39. data/test/rails_app/app/controllers/unlocks_controller.rb +1 -0
  40. data/test/rails_app/app/controllers/users_controller.rb +25 -2
  41. data/test/rails_app/app/views/confirmations/new.html.erb +2 -2
  42. data/test/rails_app/app/views/layouts/application.html.erb +3 -1
  43. data/test/rails_app/app/views/passwords/edit.html.erb +6 -6
  44. data/test/rails_app/app/views/unlocks/new.html.erb +1 -1
  45. data/test/rails_app/app/views/user_mailer/activation_needed_email.text.erb +1 -1
  46. data/test/rails_app/app/views/users/_form.html.erb +1 -1
  47. data/test/rails_app/app/views/users/new.html.erb +1 -0
  48. data/test/rails_app/config/initializers/omniauth.rb +0 -1
  49. data/test/rails_app/config/routes.rb +6 -10
  50. data/test/rails_app/db/migrate/{20140512081308_create_users.rb → 20140515111009_create_users.rb} +0 -0
  51. data/test/rails_app/db/migrate/{20140512081309_create_authentications.rb → 20140515111010_create_authentications.rb} +0 -0
  52. data/test/rails_app/db/schema.rb +1 -1
  53. data/test/test_helper.rb +43 -0
  54. metadata +33 -13
  55. data/test/controllers/confirmations_controller_test.rb +0 -14
  56. data/test/controllers/users_controller_test.rb +0 -12
  57. data/test/integration/authenticatable_integration_test.rb +0 -26
@@ -0,0 +1,40 @@
1
+ require 'test_helper'
2
+
3
+ class PasswordAuthenticatableIntegrationTest < ActionDispatch::IntegrationTest
4
+ def setup
5
+ @user = Fabricate(:user)
6
+ end
7
+
8
+ test 'should login' do
9
+ visit new_session_url
10
+ fill_in :username_or_email, with: @user.email
11
+ fill_in :password, with: 'password'
12
+ click_button 'Login'
13
+ assert_equal root_url, current_url
14
+ assert_equal @user, _current_user
15
+ end
16
+
17
+ test 'should redirect back' do
18
+ visit secret_url
19
+ assert_equal root_url, current_url
20
+
21
+ visit new_session_url
22
+ fill_in :username_or_email, with: @user.email
23
+ fill_in :password, with: 'password'
24
+ click_button 'Login'
25
+ assert_equal secret_url, current_url
26
+ assert_equal @user, _current_user
27
+ end
28
+
29
+ test 'should redirect back to url with parameters' do
30
+ visit secret_url(page: 100)
31
+ assert_equal root_url, current_url
32
+
33
+ visit new_session_url
34
+ fill_in :username_or_email, with: @user.email
35
+ fill_in :password, with: 'password'
36
+ click_button 'Login'
37
+ assert_equal secret_url(page: 100), current_url
38
+ assert_equal @user, _current_user
39
+ end
40
+ end
@@ -0,0 +1,96 @@
1
+ require 'test_helper'
2
+
3
+ class RecoverableIntegrationTest < ActionDispatch::IntegrationTest
4
+ def setup
5
+ @user = Fabricate(:user)
6
+ end
7
+
8
+ test 'should work reset password proccess' do
9
+ Goma.token_generator.stubs(:friendly_token).returns('sesame')
10
+ visit new_password_url
11
+ fill_in :username_or_email, with: @user.email
12
+ assert_difference 'ActionMailer::Base.deliveries.size', 1 do
13
+ click_button 'Send me reset password instructions'
14
+ end
15
+
16
+ email = ActionMailer::Base.deliveries.last
17
+ assert_match %r{/passwords/sesame/edit}, email.body.encoded
18
+
19
+ visit edit_password_url('sesame')
20
+ fill_in :user_password, with: 'newpassword'
21
+ fill_in :user_password_confirmation, with: 'newpassword'
22
+ click_button 'Change my password'
23
+ assert_equal root_url, current_url
24
+ assert_equal @user, _current_user
25
+
26
+ @user.reload
27
+ assert @user.valid_password?('newpassword')
28
+ end
29
+
30
+ test 'should execute validation check' do
31
+ Goma.token_generator.stubs(:friendly_token).returns('sesame')
32
+ visit new_password_url
33
+ fill_in :username_or_email, with: @user.email
34
+ assert_difference 'ActionMailer::Base.deliveries.size', 1 do
35
+ click_button 'Send me reset password instructions'
36
+ end
37
+
38
+ mail = ActionMailer::Base.deliveries.last
39
+ assert_match %r{/passwords/sesame/edit}, mail.body.encoded
40
+
41
+ visit edit_password_url('sesame')
42
+ fill_in :user_password, with: 'short'
43
+ fill_in :user_password_confirmation, with: 'short'
44
+ click_button 'Change my password'
45
+ assert_nil _current_user
46
+ @user.reload
47
+ assert @user.valid_password?('password')
48
+
49
+ fill_in :user_password, with: 'newpassword'
50
+ fill_in :user_password_confirmation, with: 'newpassword'
51
+ click_button 'Change my password'
52
+ assert_equal root_url, current_url
53
+ assert_equal @user, _current_user
54
+
55
+ @user.reload
56
+ assert @user.valid_password?('newpassword')
57
+ end
58
+
59
+ test 'should not accept wrong reset password token URL' do
60
+ Goma.token_generator.stubs(:friendly_token).returns('sesame')
61
+ visit new_password_url
62
+ fill_in :username_or_email, with: @user.email
63
+ click_button 'Send me reset password instructions'
64
+
65
+ visit edit_password_url('beans')
66
+ fill_in :user_password, with: 'newpassword'
67
+ fill_in :user_password_confirmation, with: 'newpassword'
68
+ click_button 'Change my password'
69
+
70
+ assert_match /You can't change your password in this page without coming from a password reset email/, _flash[:alert]
71
+ assert_match /Change my password/, page.body, 'should render "passwords/{token}/edit" template'
72
+
73
+ @user.reload
74
+ assert @user.valid_password?('password')
75
+ end
76
+
77
+ test 'should not accept expired reset password token URL' do
78
+ Goma.token_generator.stubs(:friendly_token).returns('sesame')
79
+ visit new_password_url
80
+ fill_in :username_or_email, with: @user.email
81
+ click_button 'Send me reset password instructions'
82
+
83
+ Timecop.travel 7.hours.from_now
84
+ visit edit_password_url('sesame')
85
+ fill_in :user_password, with: 'newpassword'
86
+ fill_in :user_password_confirmation, with: 'newpassword'
87
+ click_button 'Change my password'
88
+
89
+ assert_match /The password reset URL you visited has expired, please request a new one/, _flash[:alert]
90
+ assert_match /Forget your password\?/, page.body, 'should render "passwords/new" template'
91
+
92
+ @user.reload
93
+ assert @user.valid_password?('password')
94
+ Timecop.return
95
+ end
96
+ end
@@ -92,4 +92,18 @@ class RememberableIntegrationTest < ActionDispatch::IntegrationTest
92
92
  refute request.env['warden'].user(:user)
93
93
  end
94
94
  end
95
+
96
+ test 'should exist remember view element' do
97
+ visit new_session_url
98
+ fill_in :username_or_email, with: @user.email
99
+ fill_in :password, with: 'password'
100
+ check :remember_me
101
+ click_button 'Login'
102
+
103
+ @user.reload
104
+ assert_equal root_url, current_url
105
+ assert_equal @user, _current_user
106
+ assert _cookies['remember_user_token']
107
+ assert_equal @user.serialize_into_cookie, _signed_cookie('remember_user_token')
108
+ end
95
109
  end
@@ -27,7 +27,7 @@ class ConfirmableTest < ActiveSupport::TestCase
27
27
  should "load user record with correct activation token" do
28
28
  raw_token = @user.raw_confirmation_token
29
29
  loaded_user = User.load_from_activation_token!(raw_token)
30
- assert_equal @user.id, loaded_user.id
30
+ assert_equal @user, loaded_user
31
31
  end
32
32
 
33
33
  should "raise exception with incorrect activation token" do
@@ -54,7 +54,7 @@ class ConfirmableTest < ActiveSupport::TestCase
54
54
  should "return user record and nil with correct activation token" do
55
55
  raw_token = @user.raw_confirmation_token
56
56
  loaded_user, error = User.load_from_activation_token_with_error(raw_token)
57
- assert_equal @user.id, loaded_user.id
57
+ assert_equal @user, loaded_user
58
58
  assert_nil error
59
59
  end
60
60
 
@@ -82,7 +82,7 @@ class ConfirmableTest < ActiveSupport::TestCase
82
82
  should "return user record with correct activation token" do
83
83
  raw_token = @user.raw_confirmation_token
84
84
  loaded_user = User.load_from_activation_token(raw_token)
85
- assert_equal @user.id, loaded_user.id
85
+ assert_equal @user, loaded_user
86
86
  end
87
87
 
88
88
  should "return nil with incorrect activation token" do
@@ -148,7 +148,7 @@ class ConfirmableTest < ActiveSupport::TestCase
148
148
  should "find user record with correct email confirmation token" do
149
149
  raw_token = @user.raw_confirmation_token
150
150
  loaded_user = User.load_from_email_confirmation_token!(raw_token)
151
- assert_equal @user.id, loaded_user.id
151
+ assert_equal @user, loaded_user
152
152
  end
153
153
 
154
154
  should "not find user record with incorrect confirmation token" do
@@ -177,7 +177,7 @@ class ConfirmableTest < ActiveSupport::TestCase
177
177
  should "return user record and nil with correct email_confirmation token" do
178
178
  raw_token = @user.raw_confirmation_token
179
179
  loaded_user, error = User.load_from_email_confirmation_token_with_error(raw_token)
180
- assert_equal @user.id, loaded_user.id
180
+ assert_equal @user, loaded_user
181
181
  assert_nil error
182
182
  end
183
183
 
@@ -207,7 +207,7 @@ class ConfirmableTest < ActiveSupport::TestCase
207
207
  should "return user record with correct email_confirmation token" do
208
208
  raw_token = @user.raw_confirmation_token
209
209
  loaded_user = User.load_from_email_confirmation_token(raw_token)
210
- assert_equal @user.id, loaded_user.id
210
+ assert_equal @user, loaded_user
211
211
  end
212
212
 
213
213
  should "return nil with incorrect email_confirmation token" do
@@ -7,8 +7,8 @@ class OmniauthableTest < ActiveSupport::TestCase
7
7
  end
8
8
 
9
9
  should "create user from omniauth" do
10
- User.any_instance.stubs(:fill_with_omniauth).with(@omniauth)
11
- Authentication.any_instance.stubs(:fill_with_omniauth).with(@omniauth)
10
+ User.any_instance.expects(:fill_with_omniauth).with(@omniauth)
11
+ Authentication.any_instance.expects(:fill_with_omniauth).with(@omniauth)
12
12
 
13
13
  u = nil
14
14
  assert_difference ['User.count', 'Authentication.count'], 1 do
@@ -12,4 +12,9 @@ class AuthenticationsController < ApplicationController
12
12
  force_login(user)
13
13
  redirect_back_or_to root_url, notice: "Successfully authenticated from #{omniauth[:provider]} account."
14
14
  end
15
+
16
+ def failure
17
+ flash[:alert] = "Could not authenticate you from #{params[:strategy].capitalize} because \"#{params[:message].humanize}\"."
18
+ redirect_to new_session_url
19
+ end
15
20
  end
@@ -8,8 +8,7 @@ class ConfirmationsController < ApplicationController
8
8
  # POST /confirmations
9
9
  def create
10
10
  @user = User.find_by_identifier(params[:username_or_email])
11
- @user.generate_confirmation_token
12
- @user.send_activation_needed_email
11
+ @user.resend_activation_needed_email
13
12
 
14
13
  redirect_to new_session_url, notice: "We are processing your request. You will receive new activation email in a few minutes."
15
14
  end
@@ -39,14 +38,19 @@ class ConfirmationsController < ApplicationController
39
38
 
40
39
  if @user
41
40
  @user.confirm_email!
42
- redirect_to edit_user_url, notice: 'Your new email was successfully confirmed.'
41
+ redirect_to root_url, notice: 'Your new email was successfully confirmed.'
43
42
  else
44
43
  if err == :token_expired
45
44
  flash.now[:alert] = "Your email confirmation URL has expired, please change your email again."
46
45
  else
47
46
  flash.now[:alert] = "Email confirmation failed. Please make sure you used the full URL provided."
48
47
  end
49
- render edit_user_url(current_user)
48
+
49
+ if current_user
50
+ render edit_user_url(current_user)
51
+ else
52
+ render root_url
53
+ end
50
54
  end
51
55
  end
52
56
  end
@@ -16,16 +16,17 @@ class PasswordsController < ApplicationController
16
16
 
17
17
  # GET /passwords/1/edit
18
18
  def edit
19
- @reset_password_token = params[:id]
19
+ @user = User.new
20
+ @user.raw_reset_password_token = params[:id]
20
21
  end
21
22
 
22
23
  # PATCH/PUT /passwords/1
23
24
  def update
24
- @user, err = User.load_from_reset_password_token_with_error(params[:id])
25
+ @user, err = User.load_from_reset_password_token_with_error(params[:user][:raw_reset_password_token])
25
26
 
26
27
  if @user
27
28
  @user.unlock_access! if @user.lockable? && @user.access_locked?
28
- @user.change_password!(params[:password], params[:password_confirmation])
29
+ @user.change_password!(params[:user][:password], params[:user][:password_confirmation])
29
30
  force_login(@user)
30
31
  redirect_back_or_to root_url, notice: 'Your password was changed successfully. You are now logged in.'
31
32
  else
@@ -33,9 +34,13 @@ class PasswordsController < ApplicationController
33
34
  flash.now[:alert] = "The password reset URL you visited has expired, please request a new one."
34
35
  render :new
35
36
  else
36
- flash.now[:alert] = "You can't access this page without comming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
37
+ @user = User.new
38
+ flash.now[:alert] = "You can't change your password in this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
37
39
  render :edit
38
40
  end
39
41
  end
42
+ rescue ActiveRecord::RecordInvalid
43
+ @user.raw_reset_password_token = params[:user][:raw_reset_password_token]
44
+ render :edit
40
45
  end
41
46
  end
@@ -4,6 +4,7 @@ class UnlocksController < ApplicationController
4
4
  def show
5
5
  @user, err = User.load_from_unlock_token_with_error(params[:id])
6
6
  if @user
7
+ @user.unlock_access!
7
8
  flash[:notice] = "Your account has been unlocked successfully. Please continue to login."
8
9
  redirect_to new_session_url
9
10
  else
@@ -1,4 +1,5 @@
1
1
  class UsersController < ApplicationController
2
+ before_action :require_user_login, only: [:edit, :update, :destroy]
2
3
  before_action :set_user, only: [:show, :edit, :update, :destroy]
3
4
 
4
5
  # GET /users
@@ -17,6 +18,7 @@ class UsersController < ApplicationController
17
18
 
18
19
  # GET /users/1/edit
19
20
  def edit
21
+ not_authenticated unless current_user = @user
20
22
  end
21
23
 
22
24
  # POST /users
@@ -26,14 +28,18 @@ class UsersController < ApplicationController
26
28
  if @user.save
27
29
  redirect_to new_session_url, notice: "You have signed up successfully. However, we could not sign you in because your account is not yet activated. You will receive an email with instructions about how to activate your account in a few minutes."
28
30
  else
29
- render :new
31
+ update_email or render :new
30
32
  end
31
33
  end
32
34
 
33
35
  # PATCH/PUT /users/1
34
36
  def update
37
+ not_authenticated unless current_user = @user
35
38
  if @user.update(user_params)
36
- redirect_to @user, notice: 'User was successfully updated.'
39
+ flash[:notice] = @user.raw_confirmation_token ?
40
+ 'You updated your account successfully, but we need to verify your new email address. Please check your email and click on the confirmation link to finalize confirming your new email address.' :
41
+ 'You updated your account successfully'
42
+ redirect_to @user
37
43
  else
38
44
  render :edit
39
45
  end
@@ -41,6 +47,7 @@ class UsersController < ApplicationController
41
47
 
42
48
  # DELETE /users/1
43
49
  def destroy
50
+ not_authenticated unless current_user = @user
44
51
  @user.destroy
45
52
  redirect_to users_url, notice: 'User was successfully destroyed.'
46
53
  end
@@ -55,4 +62,20 @@ class UsersController < ApplicationController
55
62
  def user_params
56
63
  params.require(:user).permit(:username, :email, :password, :password_confirmation)
57
64
  end
65
+
66
+ def update_email
67
+ @user = User.find_by(username: params[:user][:username])
68
+ if @user.activated?
69
+ return false
70
+ end
71
+
72
+ if ( Time.now <= @user.confirmation_token_sent_at + 259200 ) &&
73
+ !@user.valid_password?(params[:user][:password])
74
+ flash[:alert] = 'This username was already registered. If you want to change your email address, please make sure you entered correct password.'
75
+ return false
76
+ end
77
+
78
+ @user.resend_activation_needed_email(to: params[:user][:email])
79
+ redirect_to new_session_url
80
+ end
58
81
  end
@@ -1,9 +1,9 @@
1
1
  <h1>Resend activation instructions</h1>
2
2
 
3
- <%= form_tag(:confirmations_url, method: :post) do %>
3
+ <%= form_tag(confirmations_url, method: :post) do %>
4
4
  <div class="field">
5
5
  <%= label_tag :username_or_email %><br>
6
- <%= text_field_tag :username_or_email
6
+ <%= text_field_tag :username_or_email %>
7
7
  </div>
8
8
  <div class="actions">
9
9
  <%= submit_tag "Resend activation instructions" %>
@@ -7,7 +7,9 @@
7
7
  <%= csrf_meta_tags %>
8
8
  </head>
9
9
  <body>
10
-
10
+ <% flash.each do |k, v| -%>
11
+ <%= content_tag :div, v, id: "flash_#{k}" %>
12
+ <% end -%>
11
13
  <%= yield %>
12
14
 
13
15
  </body>
@@ -1,18 +1,18 @@
1
1
  <h1>Change your password</h1>
2
2
 
3
- <%= form_for(@password) do |f| %>
4
- <% if @password.errors.any? %>
3
+ <%= form_for(@user, url: password_url, html: {method: :put}) do |f| %>
4
+ <% if @user && @user.errors.any? %>
5
5
  <div id="error_explanation">
6
- <h2><%= pluralize(@password.errors.count, "error") %> prohibited this password from being saved:</h2>
6
+ <h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:</h2>
7
7
 
8
8
  <ul>
9
- <% @password.errors.full_messages.each do |msg| %>
9
+ <% @user.errors.full_messages.each do |msg| %>
10
10
  <li><%= msg %></li>
11
11
  <% end %>
12
12
  </ul>
13
13
  </div>
14
14
  <% end %>
15
-
15
+ <%= f.hidden_field :raw_reset_password_token %>
16
16
  <div class="field">
17
17
  <%= f.label :password %><br>
18
18
  <%= f.password_field :password %>
@@ -22,6 +22,6 @@
22
22
  <%= f.password_field :password_confirmation %>
23
23
  </div>
24
24
  <div class="actions">
25
- <%= f.submit %>
25
+ <%= f.submit 'Change my password' %>
26
26
  </div>
27
27
  <% end %>
@@ -3,7 +3,7 @@
3
3
  <%= form_tag(unlocks_url, method: :post) do %>
4
4
  <div class="field">
5
5
  <%= label_tag :username_or_email %><br>
6
- <%= text_field_tag :username_or_email
6
+ <%= text_field_tag :username_or_email %>
7
7
  </div>
8
8
  <div class="actions">
9
9
  <%= submit_tag "Resend unlock instructions" %>
@@ -3,4 +3,4 @@ Welcome, <%= @user.email %>
3
3
 
4
4
  You can activate your account through the link below:
5
5
 
6
- <%= activate_confirmation_url(@user.raw_confirmation_token) %>
6
+ <%= confirmation_url(@user.raw_confirmation_token) %>