Might be useful to set the locale everywhere we need the web, rather than just the...
[rails.git] / app / controllers / user_controller.rb
1 class UserController < ApplicationController
2   layout 'site'
3
4   before_filter :authorize, :only => [:api_details, :api_gpx_files]
5   before_filter :set_locale, :except => [:api_details, :api_gpx_files]
6   before_filter :authorize_web, :except => [:api_details, :api_gpx_files]
7   before_filter :require_user, :only => [:set_home, :account, :go_public, :make_friend, :remove_friend, :upload_image, :delete_image]
8   before_filter :check_database_readable, :except => [:api_details, :api_gpx_files]
9   before_filter :check_database_writable, :only => [:login, :new, :set_home, :account, :go_public, :make_friend, :remove_friend, :upload_image, :delete_image]
10   before_filter :check_api_readable, :only => [:api_details, :api_gpx_files]
11
12   filter_parameter_logging :password, :pass_crypt, :pass_crypt_confirmation
13
14   def save
15     @title = 'create account'
16
17     if Acl.find_by_address(request.remote_ip, :conditions => {:k => "no_account_creation"})
18       render :action => 'new'
19     else
20       @user = User.new(params[:user])
21
22       @user.visible = true
23       @user.data_public = true
24       @user.description = "" if @user.description.nil?
25       @user.creation_ip = request.remote_ip
26
27       if @user.save
28         flash[:notice] = "User was successfully created. Check your email for a confirmation note, and you\'ll be mapping in no time :-)<br /><br />Please note that you won't be able to login until you've received and confirmed your email address.<br /><br />If you use an antispam system which sends confirmation requests then please make sure you whitelist webmaster@openstreetmap.org as we are unable to reply to any confirmation requests."
29         Notifier.deliver_signup_confirm(@user, @user.tokens.create)
30         redirect_to :action => 'login'
31       else
32         render :action => 'new'
33       end
34     end
35   end
36
37   def account
38     @title = 'edit account'
39     if params[:user] and params[:user][:display_name] and params[:user][:description]
40       if params[:user][:email] != @user.email
41         @user.new_email = params[:user][:email]
42       end
43
44       @user.display_name = params[:user][:display_name]
45
46       if params[:user][:pass_crypt].length > 0 or params[:user][:pass_crypt_confirmation].length > 0
47         @user.pass_crypt = params[:user][:pass_crypt]
48         @user.pass_crypt_confirmation = params[:user][:pass_crypt_confirmation]
49       end
50
51       @user.description = params[:user][:description]
52       @user.home_lat = params[:user][:home_lat]
53       @user.home_lon = params[:user][:home_lon]
54
55       if @user.save
56         if params[:user][:email] == @user.new_email
57           @notice = "User information updated successfully. Check your email for a note to confirm your new email address."
58           Notifier.deliver_email_confirm(@user, @user.tokens.create)
59         else
60           @notice = "User information updated successfully."
61         end
62       end
63     end
64   end
65
66   def set_home
67     if params[:user][:home_lat] and params[:user][:home_lon]
68       @user.home_lat = params[:user][:home_lat].to_f
69       @user.home_lon = params[:user][:home_lon].to_f
70       if @user.save
71         flash[:notice] = "Home location saved successfully."
72         redirect_to :controller => 'user', :action => 'account'
73       end
74     end
75   end
76
77   def go_public
78     @user.data_public = true
79     @user.save
80     flash[:notice] = 'All your edits are now public.'
81     redirect_to :controller => 'user', :action => 'account', :display_name => @user.display_name
82   end
83
84   def lost_password
85     @title = 'lost password'
86     if params[:user] and params[:user][:email]
87       user = User.find_by_email(params[:user][:email], :conditions => {:visible => true})
88
89       if user
90         token = user.tokens.create
91         Notifier.deliver_lost_password(user, token)
92         @notice = "Sorry you lost it :-( but an email is on its way so you can reset it soon."
93       else
94         @notice = "Couldn't find that email address, sorry."
95       end
96     end
97   end
98
99   def reset_password
100     @title = 'reset password'
101     if params['token']
102       token = UserToken.find_by_token(params[:token])
103       if token
104         pass = OSM::make_token(8)
105         user = token.user
106         user.pass_crypt = pass
107         user.pass_crypt_confirmation = pass
108         user.active = true
109         user.email_valid = true
110         user.save!
111         token.destroy
112         Notifier.deliver_reset_password(user, pass)
113         flash[:notice] = "Your password has been changed and is on its way to your mailbox :-)"
114       else
115         flash[:notice] = "Didn't find that token, check the URL maybe?"
116       end
117     end
118
119     redirect_to :action => 'login'
120   end
121
122   def new
123     @title = 'create account'
124     # The user is logged in already, so don't show them the signup page, instead
125     # send them to the home page
126     redirect_to :controller => 'site', :action => 'index' if session[:user]
127   end
128
129   def login
130     if session[:user]
131       # The user is logged in already, if the referer param exists, redirect them to that
132       if params[:referer]
133         redirect_to params[:referer]
134       else
135         redirect_to :controller => 'site', :action => 'index'
136       end
137       return
138     end
139     @title = 'login'
140     if params[:user]
141       email_or_display_name = params[:user][:email]
142       pass = params[:user][:password]
143       user = User.authenticate(:username => email_or_display_name, :password => pass)
144       if user
145         session[:user] = user.id
146         if params[:referer]
147           redirect_to params[:referer]
148         else
149           redirect_to :controller => 'site', :action => 'index'
150         end
151         return
152       elsif User.authenticate(:username => email_or_display_name, :password => pass, :inactive => true)
153         @notice = "Sorry, your account is not active yet.<br>Please click on the link in the account confirmation email to activate your account."
154       else
155         @notice = "Sorry, couldn't log in with those details."
156       end
157     end
158   end
159
160   def logout
161     if session[:token]
162       token = UserToken.find_by_token(session[:token])
163       if token
164         token.destroy
165       end
166       session[:token] = nil
167     end
168     session[:user] = nil
169     if params[:referer]
170       redirect_to params[:referer]
171     else
172       redirect_to :controller => 'site', :action => 'index'
173     end
174   end
175
176   def confirm
177     if params[:confirm_action]
178       token = UserToken.find_by_token(params[:confirm_string])
179       if token and !token.user.active?
180         @user = token.user
181         @user.active = true
182         @user.email_valid = true
183         @user.save!
184         token.destroy
185         flash[:notice] = 'Confirmed your account, thanks for signing up!'
186         session[:user] = @user.id
187         redirect_to :action => 'account', :display_name => @user.display_name
188       else
189         @notice = 'Something went wrong confirming that user.'
190       end
191     end
192   end
193
194   def confirm_email
195     if params[:confirm_action]
196       token = UserToken.find_by_token(params[:confirm_string])
197       if token and token.user.new_email?
198         @user = token.user
199         @user.email = @user.new_email
200         @user.new_email = nil
201         @user.active = true
202         @user.email_valid = true
203         @user.save!
204         token.destroy
205         flash[:notice] = 'Confirmed your email address, thanks for signing up!'
206         session[:user] = @user.id
207         redirect_to :action => 'account', :display_name => @user.display_name
208       else
209         @notice = 'Something went wrong confirming that email address.'
210       end
211     end
212   end
213
214   def upload_image
215     @user.image = params[:user][:image]
216     @user.save!
217     redirect_to :controller => 'user', :action => 'view', :display_name => @user.display_name
218   end
219
220   def delete_image
221     @user.image = nil
222     @user.save!
223     redirect_to :controller => 'user', :action => 'view', :display_name => @user.display_name
224   end
225
226   def api_details
227     render :text => @user.to_xml.to_s, :content_type => "text/xml"
228   end
229
230   def api_gpx_files
231     doc = OSM::API.new.get_xml_doc
232     @user.traces.each do |trace|
233       doc.root << trace.to_xml_node() if trace.public? or trace.user == @user
234     end
235     render :text => doc.to_s, :content_type => "text/xml"
236   end
237
238   def view
239     @this_user = User.find_by_display_name(params[:display_name], :conditions => {:visible => true})
240
241     if @this_user
242       @title = @this_user.display_name
243     else
244       @not_found_user = params[:display_name]
245       render :action => 'no_such_user', :status => :not_found
246     end
247   end
248
249   def make_friend
250     if params[:display_name]     
251       name = params[:display_name]
252       new_friend = User.find_by_display_name(name, :conditions => {:visible => true})
253       friend = Friend.new
254       friend.user_id = @user.id
255       friend.friend_user_id = new_friend.id
256       unless @user.is_friends_with?(new_friend)
257         if friend.save
258           flash[:notice] = "#{name} is now your friend."
259           Notifier.deliver_friend_notification(friend)
260         else
261           friend.add_error("Sorry, failed to add #{name} as a friend.")
262         end
263       else
264         flash[:notice] = "You are already friends with #{name}."  
265       end
266
267       redirect_to :controller => 'user', :action => 'view'
268     end
269   end
270
271   def remove_friend
272     if params[:display_name]     
273       name = params[:display_name]
274       friend = User.find_by_display_name(name, :conditions => {:visible => true})
275       if @user.is_friends_with?(friend)
276         Friend.delete_all "user_id = #{@user.id} AND friend_user_id = #{friend.id}"
277         flash[:notice] = "#{friend.display_name} was removed from your friends."
278       else
279         flash[:notice] = "#{friend.display_name} is not one of your friends."
280       end
281
282       redirect_to :controller => 'user', :action => 'view'
283     end
284   end
285 end