Maarten van den Berg лет назад: 8
Родитель
Сommit
825d1a828c

+ 57 - 5
app/controllers/authentication_controller.rb

@@ -11,11 +11,14 @@ class AuthenticationController < ApplicationController
11 11
     else
12 12
       u = User.find_by(email: params[:session][:email])
13 13
 
14
-      if u && u.authenticate(params[:session][:password])
14
+      if u && u.confirmed && u.authenticate(params[:session][:password])
15 15
         log_in(u, params[:session][:remember_me].to_i)
16 16
 
17 17
         flash[:success] = "Hello, #{u.person.full_name}!"
18 18
         redirect_to root_path
19
+      elsif u and not u.confirmed
20
+        flash[:warning] = "Your account has not been activated yet, please confirm using the email you have received."
21
+        redirect_to action: 'login_form'
19 22
       else
20 23
         flash[:danger] = "Invalid username/password combination!"
21 24
         redirect_to action: 'login_form'
@@ -41,7 +44,32 @@ class AuthenticationController < ApplicationController
41 44
   end
42 45
 
43 46
   def create_password
44
-    flash[:danger] = "Not yet implemented."
47
+    person = Person.find_by(email: params[:user][:email])
48
+
49
+    if not person
50
+      flash[:warning] = "That email address is unknown!"
51
+      redirect_to action: 'create_password_form'
52
+      return
53
+    end
54
+
55
+    user = User.find_by(person: person)
56
+    if user and user.confirmed
57
+      flash[:warning] = "Your account has already been activated, please use the login form if you have forgotten your password."
58
+      redirect_to action: 'login'
59
+      return
60
+    end
61
+
62
+    if not user
63
+      user = User.new
64
+      user.person = person
65
+      user.email = person.email
66
+      user.password = user.password_confirmation = SecureRandom::urlsafe_base64 32
67
+      user.confirmed = false
68
+      user.save!
69
+    end
70
+
71
+    AuthenticationMailer::password_confirm_email(user).deliver_now
72
+    flash[:success] = "An email has been sent, check your inbox!"
45 73
     redirect_to action: 'login'
46 74
   end
47 75
 
@@ -63,7 +91,7 @@ class AuthenticationController < ApplicationController
63 91
 
64 92
   def reset_password_form
65 93
     token = Token.find_by(token: params[:token], tokentype: Token::TYPES[:password_reset])
66
-    if not password_reset_token_valid? token
94
+    if not token_valid? token
67 95
       return
68 96
     end
69 97
     render layout: 'void'
@@ -71,7 +99,7 @@ class AuthenticationController < ApplicationController
71 99
 
72 100
   def reset_password
73 101
     token = Token.find_by(token: params[:token], tokentype: Token::TYPES[:password_reset])
74
-    if not password_reset_token_valid? token
102
+    if not token_valid? token
75 103
       return
76 104
     end
77 105
 
@@ -92,12 +120,36 @@ class AuthenticationController < ApplicationController
92 120
     redirect_to action: 'login'
93 121
   end
94 122
 
123
+  def confirm_account_form
124
+    token = Token.find_by(token: params[:token], tokentype: Token::TYPES[:account_confirmation])
125
+    return unless token_valid? token
126
+
127
+    @user = token.user
128
+    render layout: 'void'
129
+  end
130
+
131
+  def confirm_account
132
+    token = Token.find_by(token: params[:token], tokentype: Token::TYPES[:account_confirmation])
133
+    return unless token_valid? token
134
+
135
+    user = token.user
136
+    user.password = params[:account_confirmation][:password]
137
+    user.password_confirmation = params[:account_confirmation][:password_confirmation]
138
+    user.confirmed = true
139
+    user.save!
140
+
141
+    token.destroy!
142
+
143
+    flash[:success] = "Your account has been confirmed, you may now log in."
144
+    redirect_to action: 'login'
145
+  end
146
+
95 147
   private
96 148
   def session_params
97 149
     params.require(:session).permit(:email, :password, :remember_me)
98 150
   end
99 151
 
100
-  def password_reset_token_valid?(token)
152
+  def token_valid?(token)
101 153
     if token.nil?
102 154
       flash[:warning] = "No valid token specified!"
103 155
       redirect_to action: 'login'

+ 12 - 0
app/mailers/authentication_mailer.rb

@@ -10,4 +10,16 @@ class AuthenticationMailer < ApplicationMailer
10 10
 
11 11
     mail(to: @user.email, subject: "Reset your Aardbei-password")
12 12
   end
13
+
14
+  def password_confirm_email(user)
15
+    token = Token.new
16
+    token.user = user
17
+    token.tokentype = Token::TYPES[:account_confirmation]
18
+    token.save!
19
+
20
+    @token = token
21
+    @user = user
22
+
23
+    mail(to: @user.email, subject: "Confirm your Aardbei-account")
24
+  end
13 25
 end

+ 2 - 2
app/models/activity.rb

@@ -87,8 +87,8 @@ class Activity < ApplicationRecord
87 87
   # Determine whether the passed Person may change this activity.
88 88
   def may_change?(person)
89 89
     person.is_admin ||
90
-    self.is_organizer(person) ||
91
-    self.group.is_leader(person)
90
+    self.is_organizer?(person) ||
91
+    self.group.is_leader?(person)
92 92
   end
93 93
 
94 94
   # Create Participants for all People that

+ 4 - 0
app/models/user.rb

@@ -5,6 +5,10 @@ class User < ApplicationRecord
5 5
   #   @return [String]
6 6
   #     the user's email address. Should be the same as the associated Person's
7 7
   #     email address.
8
+  #
9
+  # @!attribute confirmed
10
+  #   @return [Boolean]
11
+  #     whether or not this account has been activated yet.
8 12
 
9 13
   has_secure_password
10 14
   belongs_to :person

+ 18 - 0
app/views/authentication/confirm_account_form.html.haml

@@ -0,0 +1,18 @@
1
+- content_for :title do
2
+  Confirm account
3
+.container
4
+  = render 'shared/alerts'
5
+  = form_for :account_confirmation, url: {action: 'confirm_account', token: params[:token]}, html: { class: 'central-form'} do |f|
6
+    %h2.central-form-header.text-center
7
+      Confirm account
8
+
9
+    = f.password_field :password, placeholder: "New password", class: 'form-control input-top'
10
+    = f.password_field :password_confirmation, placeholder: "Confirm new password", class: 'form-control input-bottom'
11
+    = f.submit "Confirm account", class: 'btn btn-primary btn-lg btn-block'
12
+
13
+  .central-form
14
+    %ul.hdis
15
+      %li
16
+        = link_to "Login",          {action: 'login',           controller: 'authentication'}, {class: 'btn btn-secondary'}
17
+      %li
18
+        = link_to "Create account", {action: 'create_password', controller: 'authentication'}, {class: 'btn btn-secondary'}

+ 9 - 0
app/views/authentication_mailer/password_confirm_email.text.erb

@@ -0,0 +1,9 @@
1
+Hello <%= @user.person.first_name %>,
2
+
3
+Please confirm your account for Aardbei by clicking on the following link:
4
+
5
+<%= confirm_url(token: @token.token) %>
6
+
7
+This link will expire <%= @token.expires %>.
8
+
9
+Aardbei

+ 3 - 0
config/routes.rb

@@ -9,6 +9,9 @@ Rails.application.routes.draw do
9 9
   get  'register', to: 'authentication#create_password_form'
10 10
   post 'register', to: 'authentication#create_password'
11 11
 
12
+  get  'confirm', to: 'authentication#confirm_account_form'
13
+  post 'confirm', to: 'authentication#confirm_account'
14
+
12 15
   get  'forgot', to: 'authentication#forgotten_password_form'
13 16
   post 'forgot', to: 'authentication#forgotten_password'
14 17
 

+ 5 - 0
db/migrate/20170222104408_add_confirmed_to_user.rb

@@ -0,0 +1,5 @@
1
+class AddConfirmedToUser < ActiveRecord::Migration[5.0]
2
+  def change
3
+    add_column :users, :confirmed, :boolean
4
+  end
5
+end

+ 2 - 1
db/schema.rb

@@ -10,7 +10,7 @@
10 10
 #
11 11
 # It's strongly recommended that you check this file into your version control system.
12 12
 
13
-ActiveRecord::Schema.define(version: 20170210180426) do
13
+ActiveRecord::Schema.define(version: 20170222104408) do
14 14
 
15 15
   create_table "activities", force: :cascade do |t|
16 16
     t.string   "public_name"
@@ -94,6 +94,7 @@ ActiveRecord::Schema.define(version: 20170210180426) do
94 94
     t.integer  "person_id"
95 95
     t.datetime "created_at",      null: false
96 96
     t.datetime "updated_at",      null: false
97
+    t.boolean  "confirmed"
97 98
     t.index ["email"], name: "index_users_on_email", unique: true
98 99
     t.index ["person_id"], name: "index_users_on_person_id", unique: true
99 100
   end