1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
# app/controllers/user_controller.rb:
# Show information about a user.
#
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
#
# $Id: user_controller.rb,v 1.30 2008-02-27 13:59:52 francis Exp $
class UserController < ApplicationController
# Show page about a set of users with same url name
def show
if MySociety::Format.simplify_url_part(params[:url_name]) != params[:url_name]
redirect_to :url_name => MySociety::Format.simplify_url_part(params[:url_name])
return
end
@display_users = User.find(:all, :conditions => [ "url_name = ?", params[:url_name] ], :order => "created_at desc")
end
# Login form
def signin
work_out_post_redirect
if not params[:user_signin]
# First time page is shown
render :action => 'sign'
return
else
@user_signin = User.authenticate_from_form(params[:user_signin], @post_redirect.reason_params[:user_name] ? true : false)
if @user_signin.errors.size > 0
# Failed to authenticate
render :action => 'sign'
return
else
# Successful login
if @user_signin.email_confirmed
session[:user_id] = @user_signin.id
session[:user_authtype] = :password
do_post_redirect @post_redirect.uri, @post_redirect.post_params
else
send_confirmation_mail @user_signin
end
return
end
end
end
# Create new account form
def signup
work_out_post_redirect
# Make the user and try to save it
@user_signup = User.new(params[:user_signup])
if not @user_signup.valid?
# Show the form
render :action => 'sign'
else
# New unconfirmed user
@user_signup.email_confirmed = false
@user_signup.save!
send_confirmation_mail @user_signup
return
end
end
# Followed link in user account confirmation email
def confirm
post_redirect = PostRedirect.find_by_email_token(params[:email_token])
if post_redirect.nil?
render :template => 'user/bad_token.rhtml'
return
end
@user = post_redirect.user
@user.email_confirmed = true
@user.save!
session[:user_id] = @user.id
session[:user_authtype] = :email
do_post_redirect post_redirect.uri, post_redirect.post_params
end
# Logout form
def signout
session[:user_id] = nil
session[:user_authtype] = nil
if params[:r]
redirect_to params[:r]
else
redirect_to :controller => "request", :action => "frontpage"
end
end
# Change password and/or email - requires email authentication
def signchange
if @user and ((not session[:user_authtype]) or (session[:user_authtype] != :email))
# Not logged in via email, so send confirmation
params[:submitted_signchange_email] = true
params[:signchange] = { :email => @user.email }
end
if params[:submitted_signchange_email]
# They've entered the email, check it is OK and user exists
if not MySociety::Validate.is_valid_email(params[:signchange][:email])
flash[:error] = "That doesn't look like a valid email address. Please check you have typed it correctly."
render :action => 'signchange_email'
return
end
user_signchange = User.find_user_by_email(params[:signchange][:email])
if not user_signchange
flash[:error] = "There is no user with that email, please check you have typed it correctly."
render :action => 'signchange_email'
return
end
# Send email with login link to go to signchange page
url = signchange_url
if params[:pretoken]
url += "?pretoken=" + params[:pretoken]
end
post_redirect = PostRedirect.new(:uri => url , :post_params => {},
:reason_params => {
:web => "",
:email => "Then your can change your password on foi.mysociety.org",
:email_subject => "Change your password on foi.mysociety.org"
})
post_redirect.user = user_signchange
post_redirect.save!
url = confirm_url(:email_token => post_redirect.email_token)
UserMailer.deliver_confirm_login(user_signchange, post_redirect.reason_params, url)
render :action => 'confirm'
elsif not @user
# Not logged in, prompt for email
render :action => 'signchange_email'
else
# Logged in via email link, so can offer form to change email/password
raise "internal error" unless (session[:user_authtype] == :email)
if params[:submitted_signchange_password]
@user.password = params[:user][:password]
@user.password_confirmation = params[:user][:password_confirmation]
if not @user.valid?
render :action => 'signchange'
else
@user.save!
flash[:notice] = "Your password has been changed."
if params[:pretoken] and not params[:pretoken].empty?
post_redirect = PostRedirect.find_by_token(params[:pretoken])
do_post_redirect post_redirect.uri, post_redirect.post_params
else
redirect_to :controller => "request", :action => "frontpage" # XXX should go back to login and where they were!
end
end
else
render :action => 'signchange'
end
end
end
private
# Decide where we are going to redirect back to after signin/signup, and record that
def work_out_post_redirect
# Redirect to front page later if nothing else specified
if not params[:r] and not params[:token]
params[:r] = "/"
end
# The explicit "signin" link uses this to specify where to go back to
if params[:r]
@post_redirect = PostRedirect.new(:uri => params[:r], :post_params => {},
:reason_params => {
:web => "",
:email => "Then your can sign in to foi.mysociety.org",
:email_subject => "Confirm your account on foi.mysociety.org"
})
@post_redirect.save!
params[:token] = @post_redirect.token
elsif params[:token]
# Otherwise we have a token (which represents a saved POST request0
@post_redirect = PostRedirect.find_by_token(params[:token])
end
end
# Ask for email confirmation
def send_confirmation_mail(user)
#raise "user #{user.id} already confirmed" if user.email_confirmed
post_redirect = PostRedirect.find_by_token(params[:token])
post_redirect.user = user
post_redirect.save!
url = confirm_url(:email_token => post_redirect.email_token)
UserMailer.deliver_confirm_login(user, post_redirect.reason_params, url)
render :action => 'confirm'
end
end
|