api06: Move version-checking into the models, raising an exception on mismatch
[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 :authorize_web, :only => [:account, :go_public, :view, :diary, :make_friend, :remove_friend, :upload_image]
6   before_filter :require_user, :only => [:set_home, :account, :go_public, :make_friend, :remove_friend, :upload_image]
7
8   filter_parameter_logging :password, :pass_crypt, :pass_crypt_confirmation
9
10   def save
11     @title = 'create account'
12     @user = User.new(params[:user])
13
14     @user.data_public = true
15       
16     if @user.save
17       token = @user.tokens.create
18       flash[:notice] = "User was successfully created. Check your email for a confirmation note, and you\'ll be mapping in no time :-)<br>Please note that you won't be able to login until you've received and confirmed your email address."
19       Notifier::deliver_signup_confirm(@user, token)
20       redirect_to :action => 'login'
21     else
22       render :action => 'new'
23     end
24   end
25
26   def account
27     @title = 'edit account'
28     if params[:user] and params[:user][:display_name] and params[:user][:description]
29       home_lat =  params[:user][:home_lat]
30       home_lon =  params[:user][:home_lon]
31
32       @user.display_name = params[:user][:display_name]
33       if params[:user][:pass_crypt].length > 0 or params[:user][:pass_crypt_confirmation].length > 0
34         @user.pass_crypt = params[:user][:pass_crypt]
35         @user.pass_crypt_confirmation = params[:user][:pass_crypt_confirmation]
36       end
37       @user.description = params[:user][:description]
38       @user.home_lat = home_lat
39       @user.home_lon = home_lon
40       if @user.save
41         flash[:notice] = "User information updated successfully."
42       else
43         flash.delete(:notice)
44       end
45     end
46   end
47
48   def set_home
49     if params[:user][:home_lat] and params[:user][:home_lon]
50       @user.home_lat = params[:user][:home_lat].to_f
51       @user.home_lon = params[:user][:home_lon].to_f
52       if @user.save
53         flash[:notice] = "Home location saved successfully."
54         redirect_to :controller => 'user', :action => 'account'
55       end
56     end
57   end
58
59   def go_public
60     @user.data_public = true
61     @user.save
62     flash[:notice] = 'All your edits are now public.'
63     redirect_to :controller => 'user', :action => 'account', :display_name => @user.display_name
64   end
65
66   def lost_password
67     @title = 'lost password'
68     if params[:user] and params[:user][:email]
69       user = User.find_by_email(params[:user][:email])
70       if user
71         token = user.tokens.create
72         Notifier::deliver_lost_password(user, token)
73         flash[:notice] = "Sorry you lost it :-( but an email is on its way so you can reset it soon."
74       else
75         flash[:notice] = "Couldn't find that email address, sorry."
76       end
77     else
78       render :action => 'lost_password'
79     end
80   end
81
82   def reset_password
83     @title = 'reset password'
84     if params['token']
85       token = UserToken.find_by_token(params[:token])
86       if token
87         pass = OSM::make_token(8)
88         user = token.user
89         user.pass_crypt = pass
90         user.pass_crypt_confirmation = pass
91         user.active = true
92         user.save!
93         token.destroy
94         Notifier::deliver_reset_password(user, pass)
95         flash[:notice] = "Your password has been changed and is on its way to your mailbox :-)"
96       else
97         flash[:notice] = "Didn't find that token, check the URL maybe?"
98       end
99     end
100     redirect_to :action => 'login'
101   end
102
103   def new
104     @title = 'create account'
105   end
106
107   def login
108     @title = 'login'
109     if params[:user]
110       email_or_display_name = params[:user][:email]
111       pass = params[:user][:password]
112       user = User.authenticate(:username => email_or_display_name, :password => pass)
113       if user
114         session[:user] = user.id
115         if params[:referer]
116           redirect_to params[:referer]
117         else
118           redirect_to :controller => 'site', :action => 'index'
119         end
120         return
121       elsif User.authenticate(:username => email_or_display_name, :password => pass, :inactive => true)
122         flash[:notice] = "Sorry, your account is not active yet.<br>Please click on the link in the account confirmation email to activate your account."
123       else
124         flash[:notice] = "Sorry, couldn't log in with those details."
125       end
126     end
127   end
128
129   def logout
130     if session[:token]
131       token = UserToken.find_by_token(session[:token])
132       if token
133         token.destroy
134       end
135       session[:token] = nil
136     end
137     session[:user] = nil
138     if params[:referer]
139       redirect_to params[:referer]
140     else
141       redirect_to :controller => 'site', :action => 'index'
142     end
143   end
144
145   def confirm
146     token = UserToken.find_by_token(params[:confirm_string])
147     if token and !token.user.active?
148       @user = token.user
149       @user.active = true
150       @user.save!
151       token.destroy
152       flash[:notice] = 'Confirmed your account, thanks for signing up!'
153       session[:user] = @user.id
154       redirect_to :action => 'account', :display_name => @user.display_name
155     else
156       flash[:notice] = 'Something went wrong confirming that user.'
157     end
158   end
159
160   def upload_image
161     @user.image = params[:user][:image]
162     @user.save!
163     redirect_to :controller => 'user', :action => 'view', :display_name => @user.display_name
164   end
165
166   def api_details
167     render :text => @user.to_xml.to_s, :content_type => "text/xml"
168   end
169
170   def api_gpx_files
171     doc = OSM::API.new.get_xml_doc
172     @user.traces.each do |trace|
173       doc.root << trace.to_xml_node() if trace.public? or trace.user == @user
174     end
175     render :text => doc.to_s, :content_type => "text/xml"
176   end
177
178   def view
179     @this_user = User.find_by_display_name(params[:display_name])
180
181     if @this_user
182       @title = @this_user.display_name
183     else
184       @not_found_user = params[:display_name]
185       render :action => 'no_such_user', :status => :not_found
186     end
187   end
188
189   def make_friend
190     if params[:display_name]     
191       name = params[:display_name]
192       new_friend = User.find_by_display_name(name)
193       friend = Friend.new
194       friend.user_id = @user.id
195       friend.friend_user_id = new_friend.id
196       unless @user.is_friends_with?(new_friend)
197         if friend.save
198           flash[:notice] = "#{name} is now your friend."
199           Notifier::deliver_friend_notification(friend)
200         else
201           friend.add_error("Sorry, failed to add #{name} as a friend.")
202         end
203       else
204         flash[:notice] = "You are already friends with #{name}."  
205       end
206       redirect_to :controller => 'user', :action => 'view'
207     end
208   end
209
210   def remove_friend
211     if params[:display_name]     
212       name = params[:display_name]
213       friend = User.find_by_display_name(name)
214       if @user.is_friends_with?(friend)
215         Friend.delete_all "user_id = #{@user.id} AND friend_user_id = #{friend.id}"
216         flash[:notice] = "#{friend.display_name} was removed from your friends."
217       else
218         flash[:notice] = "#{friend.display_name} was not already one of your friends."
219       end
220       redirect_to :controller => 'user', :action => 'view'
221     end
222   end
223
224 end
225