dangerzone 0.0.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. data/README.md +21 -11
  2. data/lib/dangerzone/dangerzone_generator.rb +73 -59
  3. data/lib/dangerzone/templates/controllers/application_controller.rb +5 -6
  4. data/lib/dangerzone/templates/controllers/create_accounts_controller.rb +11 -15
  5. data/lib/dangerzone/templates/controllers/reset_passwords_controller.rb +12 -16
  6. data/lib/dangerzone/templates/controllers/sessions_controller.rb +19 -16
  7. data/lib/dangerzone/templates/migration.rb +2 -4
  8. data/lib/dangerzone/templates/models/user.rb +38 -12
  9. data/lib/dangerzone/templates/routes.rb +1 -1
  10. data/lib/dangerzone/templates/spec/controllers/create_accounts_controller_spec.rb +179 -0
  11. data/lib/dangerzone/templates/spec/controllers/reset_passwords_controller_spec.rb +131 -0
  12. data/lib/dangerzone/templates/spec/controllers/sessions_controller_spec.rb +135 -0
  13. data/lib/dangerzone/templates/spec/factories/users_factory.rb +15 -0
  14. data/lib/dangerzone/templates/spec/models/user_spec.rb +172 -0
  15. data/lib/dangerzone/templates/spec/spec_helper.rb +36 -0
  16. data/lib/dangerzone/templates/views/create_accounts/check_your_email.html.erb +1 -1
  17. data/lib/dangerzone/templates/views/create_accounts/new.html.erb +1 -1
  18. data/lib/dangerzone/templates/views/layouts/_dangerzone_nav.html.erb +10 -0
  19. data/lib/dangerzone/templates/views/layouts/application.html.erb +18 -0
  20. data/lib/dangerzone/templates/views/reset_passwords/new.html.erb +1 -1
  21. data/lib/dangerzone/templates/views/reset_passwords/reset_password_form.html.erb +2 -1
  22. data/lib/dangerzone/templates/views/sessions/new.html.erb +2 -2
  23. metadata +41 -22
  24. data/dangerzone.gemspec +0 -18
  25. data/lib/.DS_Store +0 -0
  26. data/lib/dangerzone/.DS_Store +0 -0
  27. data/lib/dangerzone/templates/.DS_Store +0 -0
  28. data/lib/dangerzone/templates/views/.DS_Store +0 -0
  29. data/lib/dangerzone/templates/views/nav.html.erb +0 -10
@@ -3,15 +3,13 @@ class CreateUsersTableViaDangerzone < ActiveRecord::Migration
3
3
  def up
4
4
  create_table :users do |t|
5
5
  t.string :email
6
- t.string :password
7
- t.string :password_confirmation
8
6
  t.string :password_digest
9
7
  t.string :sign_in_ip
10
8
  t.string :remember_token
11
9
  t.string :reset_password_token
12
10
  t.datetime :reset_password_sent_at
13
- t.boolean :confirmed, :default => false
14
- t.integer :sign_in_count, :default => 1
11
+ t.boolean :confirmed, default: false
12
+ t.integer :sign_in_count, default: 1
15
13
 
16
14
  t.timestamps
17
15
  end
@@ -1,25 +1,51 @@
1
1
  class User < ActiveRecord::Base
2
-
3
2
  has_secure_password
4
3
 
5
- attr_accessible :email, :password, :password_confirmation
4
+ attr_accessible(
5
+ :email,
6
+ :password,
7
+ :password_confirmation,
8
+ :reset_password_token,
9
+ :reset_password_sent_at,
10
+ :sign_in_ip,
11
+ :sign_in_count,
12
+ :confirmed,
13
+ :remember_token )
6
14
 
7
15
  validates_presence_of :email
8
16
  validates_uniqueness_of :email
9
- validates_format_of :email, :with => /.+@.+\..+/i
17
+ validates :password, :password_confirmation, presence: true, if: :new_record?
18
+ validates_format_of :email, with: /.+@.+\..+/i
19
+
20
+ before_save { self.email = self.email.try(:downcase) }
10
21
 
11
22
  def update_reset_password_credentials
12
- self.reset_password_sent_at = Time.now
13
- self.reset_password_token = SecureRandom.urlsafe_base64
14
- self.save
23
+ self.update_attributes(
24
+ reset_password_sent_at: Time.now,
25
+ reset_password_token: SecureRandom.urlsafe_base64 )
26
+ end
27
+
28
+ def sign_in!(ip, password_param)
29
+ return false unless self.confirmed && self.authenticate(password_param)
30
+ self.update_attributes(
31
+ sign_in_ip: ip,
32
+ sign_in_count: (self.sign_in_count + 1),
33
+ remember_token: SecureRandom.urlsafe_base64 )
15
34
  end
16
35
 
17
- def confirm(request_remote_ip)
18
- self.confirmed = true
19
- self.reset_password_sent_at = nil
20
- self.reset_password_token = nil
21
- self.sign_in_ip = request_remote_ip
22
- self.save
36
+ def confirm!(ip)
37
+ self.update_attributes(
38
+ sign_in_ip: ip,
39
+ confirmed: true,
40
+ reset_password_sent_at: nil,
41
+ reset_password_token: nil )
23
42
  end
24
43
 
44
+ def in_time?
45
+ (Time.now - self.reset_password_sent_at) < 24.hours if self.reset_password_sent_at
46
+ end
47
+
48
+ def token_matches?(token)
49
+ self.reset_password_token == token
50
+ end
25
51
  end
@@ -13,6 +13,6 @@
13
13
  put '/resend_confirmation_email' => 'create_accounts#resend_confirmation_email', as: 'resend_confirmation_email'
14
14
 
15
15
  get '/forgot_password' => 'reset_passwords#new', as: 'forgot_password'
16
- put '/reset_password' => 'reset_passwords#send_reset_password', as: 'send_reset_password'
16
+ put '/reset_password' => 'reset_passwords#requested_reset_password', as: 'requested_reset_password'
17
17
  get '/reset_password/:id/:reset_password_token' => 'reset_passwords#reset_password_form', as: 'reset_password_form'
18
18
  put '/update_password' => 'reset_passwords#update_password', as: 'update_password'
@@ -0,0 +1,179 @@
1
+ require 'spec_helper'
2
+
3
+ describe CreateAccountsController do
4
+ before { ActionMailer::Base.deliveries = [] }
5
+
6
+ describe '#create' do
7
+
8
+ it "saves an unconfirmed user" do
9
+ params = { user: FactoryGirl.attributes_for(:user, :confirmed) }
10
+ post :create, params
11
+ expect(assigns(:user).confirmed).to be_false
12
+ end
13
+
14
+ describe 'when successful' do
15
+ let(:valid_params) { { user: FactoryGirl.attributes_for(:user) } }
16
+ before { post :create, valid_params }
17
+
18
+ it "assigns a user with the values in valid_params" do
19
+ expect(assigns(:user).email).to eq(valid_params[:user][:email])
20
+ end
21
+
22
+ it "sends them a confirmation email" do
23
+ expect(ActionMailer::Base.deliveries).to_not be_empty
24
+ end
25
+
26
+ it "saves the user" do
27
+ expect(assigns(:user)).to be_persisted
28
+ end
29
+
30
+ it "redirects them to check_your_email" do
31
+ expect(response).to redirect_to :check_your_email
32
+ end
33
+ end
34
+
35
+ describe 'when unsuccessful' do
36
+ let(:invalid_params) { {:user => { email: 'x' }}}
37
+ before(:each) { post :create, invalid_params }
38
+
39
+ it "redirects them to the sign up page" do
40
+ expect(response).to redirect_to :sign_up
41
+ end
42
+
43
+ it "does not persist @user" do
44
+ expect(assigns(:user)).to be_new_record
45
+ end
46
+
47
+ it "does not send them an email" do
48
+ expect(ActionMailer::Base.deliveries).to be_empty
49
+ end
50
+ end
51
+ end
52
+
53
+ describe '#new' do
54
+ it "renders the new template" do
55
+ get :new
56
+ expect(response).to render_template :new
57
+ end
58
+ end
59
+
60
+ describe '#resend_confirmation_email' do
61
+ let(:user){ FactoryGirl.create(:user) }
62
+
63
+ describe "when user is not confirmed and has valid email" do
64
+
65
+ it "redirects to the check_your_email page" do
66
+ put :resend_confirmation_email, email: user.email
67
+ expect(response).to redirect_to :check_your_email
68
+ end
69
+
70
+ it "sends a confirmation email" do
71
+ put :resend_confirmation_email, email: user.email
72
+ expect(ActionMailer::Base.deliveries).to_not be_empty
73
+ end
74
+
75
+ it "updates the user's reset password credentials" do
76
+ old_token = user.reset_password_token
77
+ old_time = user.reset_password_sent_at
78
+ put :resend_confirmation_email, email: user.email
79
+ user.reload
80
+ expect(user.reset_password_token).to_not eq(old_token)
81
+ expect(user.reset_password_sent_at).to_not eq(old_time)
82
+ end
83
+ end
84
+
85
+ describe "when user is already confirmed" do
86
+ let(:confirmed_user) { FactoryGirl.create(:user, :confirmed) }
87
+
88
+ it "redirects to the check_your_email page" do
89
+ put :resend_confirmation_email, email: confirmed_user.email
90
+ expect(response).to redirect_to :check_your_email
91
+ end
92
+
93
+ it "does not send an email" do
94
+ put :resend_confirmation_email, email: confirmed_user.email
95
+ expect(ActionMailer::Base.deliveries).to be_empty
96
+ end
97
+
98
+ it "does not update their reset password credentials" do
99
+ user.should_not_receive :update_reset_password_credentials
100
+ put :resend_confirmation_email, email: confirmed_user.email
101
+ end
102
+ end
103
+
104
+ describe "when email in params does not belong to any user" do
105
+
106
+ it "redirects to the check_your_email page when there is no email in params" do
107
+ put :resend_confirmation_email
108
+ expect(response).to redirect_to :check_your_email
109
+ end
110
+
111
+ it "does not send an email" do
112
+ put :resend_confirmation_email, email: 'not_there@example.com'
113
+ expect(ActionMailer::Base.deliveries).to be_empty
114
+ end
115
+
116
+ it "does not update their reset password credentials" do
117
+ user.should_not_receive :update_reset_password_credentials
118
+ put :resend_confirmation_email, email: 'not_there@example.com'
119
+ end
120
+ end
121
+ end
122
+
123
+ describe "#confirm" do
124
+ let(:user){ FactoryGirl.create(:user) }
125
+ before { user.update_reset_password_credentials }
126
+
127
+ context "user has proper reset password credentials" do
128
+ before { get :confirm, id: user.id, reset_password_token: user.reset_password_token }
129
+
130
+ it "redirects to the root_url" do
131
+ expect(response).to redirect_to root_url
132
+ end
133
+
134
+ it "confirms the user" do
135
+ expect(User.first.confirmed).to be_true
136
+ end
137
+
138
+ it "puts the user's id in the session hash" do
139
+ expect(session[:user_id]).to eq(user.id)
140
+ end
141
+ end
142
+
143
+ context "user does not have right token" do
144
+ before { get :confirm, id: user.id, reset_password_token: 'wrong'}
145
+
146
+ it "redirects them to the sign up page" do
147
+ expect(response).to redirect_to :sign_up
148
+ end
149
+
150
+ it "does not confirm the user" do
151
+ expect(User.first.confirmed).to be_false
152
+ end
153
+
154
+ it "does not set the session hash to the user's id" do
155
+ expect(session[:user_id]).to be_nil
156
+ end
157
+ end
158
+
159
+ context "user is trying to confirm after more than an hour" do
160
+ before do
161
+ user.reset_password_sent_at = Time.now - 2.days
162
+ user.save
163
+ get :confirm, id: user.id, reset_password_token: user.reset_password_token
164
+ end
165
+
166
+ it "redirects them to the sign up page" do
167
+ expect(response).to redirect_to :sign_up
168
+ end
169
+
170
+ it "does not confirm the user" do
171
+ expect(User.first.confirmed).to be_false
172
+ end
173
+
174
+ it "does not set the session hash to the user's id" do
175
+ expect(session[:user_id]).to be_nil
176
+ end
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,131 @@
1
+ require 'spec_helper'
2
+
3
+ describe ResetPasswordsController do
4
+
5
+ describe '#requested_reset_password' do
6
+ before { ActionMailer::Base.deliveries = []}
7
+ let(:user) { FactoryGirl.create(:user) }
8
+
9
+ it "renders to forgot_password page (:new)" do
10
+ put :requested_reset_password, email: user.email
11
+ expect(response).to redirect_to :forgot_password
12
+ end
13
+
14
+ context 'when update_reset_password_credentials is successful' do
15
+
16
+ it "sends an email" do
17
+ put :requested_reset_password, email: user.email
18
+ expect(ActionMailer::Base.deliveries).to_not be_empty
19
+ end
20
+
21
+ it "updates the user's reset password credentials" do
22
+ old_token = user.reset_password_token
23
+ old_time = user.reset_password_sent_at
24
+ put :requested_reset_password, email: user.email
25
+ expect(User.first.reset_password_token).to_not eq(old_token)
26
+ expect(User.first.reset_password_sent_at).to_not eq(old_time)
27
+ end
28
+ end
29
+
30
+ context 'when update_reset_password_credentials fails' do
31
+ it "doesn't send an email" do
32
+ put :requested_reset_password, email: "not an email"
33
+ expect(ActionMailer::Base.deliveries).to be_empty
34
+ end
35
+ end
36
+ end
37
+
38
+ describe '#reset_password_form' do
39
+ let(:user){ FactoryGirl.create(:user) }
40
+ before { user.update_reset_password_credentials }
41
+
42
+ context "user has proper reset password credentials" do
43
+ it "renders reset password form" do
44
+ get :reset_password_form, id: user.id, reset_password_token: user.reset_password_token
45
+ expect(response).to render_template :reset_password_form
46
+ end
47
+ end
48
+
49
+ context "user does not have right token" do
50
+ before { get :reset_password_form, id: user.id, reset_password_token: 'wrong'}
51
+
52
+ it "renders the forgot password page" do
53
+ expect(response).to redirect_to :forgot_password
54
+ end
55
+
56
+ it "does not set the session hash to the user's id" do
57
+ expect(session[:reset_password_user_id]).to be_nil
58
+ end
59
+ end
60
+
61
+ context "user is trying to reset password after more than an hour" do
62
+ before do
63
+ user.reset_password_sent_at = Time.now - 2.days
64
+ user.save
65
+ get :reset_password_form, id: user.id, reset_password_token: user.reset_password_token
66
+ end
67
+
68
+ it "renders the forgot password page" do
69
+ expect(response).to redirect_to :forgot_password
70
+ end
71
+
72
+ it "does not set the session hash to the user's id" do
73
+ expect(session[:reset_password_user_id]).to be_nil
74
+ end
75
+ end
76
+ end
77
+
78
+ describe '#update_password' do
79
+ let(:user){ FactoryGirl.create(:user) }
80
+ before do
81
+ user.update_reset_password_credentials
82
+ session[:reset_password_user_id] = user.id
83
+ end
84
+
85
+ context 'the user is in time' do
86
+
87
+ context 'and their password and confirmation match' do
88
+ before { put :update_password, password: 'new_password', password_confirmation: 'new_password', id: user.id }
89
+
90
+ it "sets session[:user_id] to their user id" do
91
+ expect(session[:user_id]).to eq(user.id)
92
+ end
93
+
94
+ it "redirects them to the root_url" do
95
+ expect(response).to redirect_to :root
96
+ end
97
+ end
98
+
99
+ context "but their password and confirmation don't match" do
100
+ it "redirects them to the reset password form" do
101
+ put :update_password, password: 'new_password', password_confirmation: "doesn't match", id: user.id
102
+ expect(response).to redirect_to reset_password_form_path(user.id, user.reset_password_token)
103
+ end
104
+ end
105
+
106
+ end
107
+
108
+ context "user is too late" do
109
+ it "redirects to #requested_reset_password" do
110
+ user.reset_password_sent_at = Time.now - 2.days
111
+ user.save
112
+ put :update_password, password: 'new_password', password_confirmation: 'new_password', id: user.id
113
+ expect(response).to redirect_to :forgot_password
114
+ end
115
+ end
116
+
117
+ context "incorrect id comes in" do
118
+ it "redirects to #forgot_password" do
119
+ put :update_password, password: 'new_password', password_confirmation: 'new_password', id: 1234124
120
+ expect(response).to redirect_to :forgot_password
121
+ end
122
+ end
123
+ end
124
+
125
+ describe '#new' do
126
+ it "renders the new template" do
127
+ get :new
128
+ expect(response).to render_template :new
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,135 @@
1
+ require 'spec_helper'
2
+
3
+ describe SessionsController do
4
+
5
+ describe '#new' do
6
+ let(:confirmed_user) { FactoryGirl.create(:user) }
7
+
8
+ it 'renders the :new page' do
9
+ get :new
10
+ expect(response).to render_template :new
11
+ end
12
+
13
+ it 'redirects to root if user is already signed in' do
14
+ session[:user_id] = 5
15
+ get :new
16
+ expect(response).to redirect_to :root
17
+ end
18
+ end
19
+
20
+ describe '#destroy' do
21
+
22
+ it 'clears the permanent cookies' do
23
+ cookies.permanent[:remember_token] = 'remember token'
24
+ delete :destroy
25
+ expect(cookies[:remember_token]).to be_nil
26
+ end
27
+
28
+ it 'clears the session hash' do
29
+ session[:user_id] = 5
30
+ delete :destroy
31
+ expect(session[:user_id]).to be_nil
32
+ end
33
+
34
+ it 'redirects to the sign in page' do
35
+ delete :destroy
36
+ expect(response).to redirect_to :sign_in
37
+ end
38
+ end
39
+
40
+ describe '#create' do
41
+ let(:user){ FactoryGirl.create(:user, :confirmed) }
42
+ let(:params){ {email: user.email, password: 'password1234'} }
43
+
44
+ before { controller.reset_session }
45
+
46
+ it 'clears cookies before signing in so 2 people cannot be signed in at once (w/out remember me)' do
47
+ session[:user_id] = 'x'
48
+ cookies.permanent[:remember_token] = 'some token'
49
+ post :create, params
50
+ expect(session[:user_id]).to eq(user.id)
51
+ expect(cookies[:remember_token]).to be_nil
52
+ end
53
+
54
+ it 'clears cookies before signing in so 2 people cannot be signed in at once (with remember me)' do
55
+ session[:user_id] = 'x'
56
+ cookies.permanent[:remember_token] = 'some token'
57
+ params[:remember_me] = '1'
58
+ post :create, params
59
+ expect(session[:user_id]).to be_nil
60
+ expect(cookies[:remember_token]).to eq(assigns(:user).remember_token)
61
+ end
62
+
63
+ context 'when a non user email tries to login' do
64
+ it 'redirects to the sign in page' do
65
+ post :create
66
+ expect(response).to redirect_to :sign_in
67
+ end
68
+ end
69
+
70
+ context 'incorrect password' do
71
+ it 'redirects to the sign in page' do
72
+ params[:password] = 'wrong'
73
+ post :create, params
74
+ expect(response).to redirect_to :sign_in
75
+ end
76
+ end
77
+
78
+ context 'user is not confirmed' do
79
+ it 'redirects to the sign in page' do
80
+ params[:email] = FactoryGirl.create(:user).email
81
+ post :create, params
82
+ expect(response).to redirect_to :sign_in
83
+ end
84
+ end
85
+
86
+ context 'password is correct and user is confirmed' do
87
+
88
+ it 'updates the their sign in ip' do
89
+ user.sign_in_ip = 'old ip'
90
+ user.save
91
+ post :create, params
92
+ expect(assigns(:user)).to_not eq('old ip')
93
+ end
94
+
95
+ it 'increments the their sign in count' do
96
+ old_sign_in_count = user.sign_in_count
97
+ post :create, params
98
+ expect(assigns(:user).sign_in_count).to eq(old_sign_in_count + 1)
99
+ end
100
+
101
+ it 'redirects to the root url' do
102
+ post :create, params
103
+ expect(response).to redirect_to :root
104
+ end
105
+
106
+ it 'saves the user' do
107
+ old_updated_at = user.updated_at
108
+ post :create, params
109
+ expect(assigns(:user)).to_not eq(old_updated_at)
110
+ end
111
+
112
+ context 'user has selected remember me' do
113
+ before { params[:remember_me] = '1' }
114
+
115
+ it 'gives the user a new remember token' do
116
+ old_token = user.remember_token
117
+ post :create, params
118
+ expect(assigns(:user)).to_not eq(old_token)
119
+ end
120
+
121
+ it 'puts the their id in the permanent cookies' do
122
+ post :create, params
123
+ expect(cookies[:remember_token]).to_not be_nil
124
+ end
125
+ end
126
+
127
+ context 'user has not selected remember me' do
128
+ it 'puts the their id in the session hash' do
129
+ post :create, params
130
+ expect(session[:user_id]).to eq(user.id)
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end