source: subversion/sites/rails_port/app/controllers/user_controller.rb @ 20189

Revision 20189, 11.8 KB checked in by tomhughes, 4 years ago (diff)

Rework the user details screen to be less crap... Highlights include:

  • Map is smaller and placed to the side with lists of friends and nearby users (now excluding friends) beside it.
  • Map includes friends as well as nearby users.
  • Friend and nearby user lists include photos and links to friend/unfriend as appropriate.
  • OAuth settings link moved up with all the other links in the main navigation bar.

The addition of friends to the map also carries through to the user
settings page.

Line 
1class UserController < ApplicationController
2  layout 'site', :except => :api_details
3
4  before_filter :authorize, :only => [:api_details, :api_gpx_files]
5  before_filter :authorize_web, :except => [:api_details, :api_gpx_files]
6  before_filter :set_locale, :except => [:api_details, :api_gpx_files]
7  before_filter :require_user, :only => [:account, :go_public, :make_friend, :remove_friend]
8  before_filter :check_database_readable, :except => [:api_details, :api_gpx_files]
9  before_filter :check_database_writable, :only => [:login, :new, :account, :go_public, :make_friend, :remove_friend]
10  before_filter :check_api_readable, :only => [:api_details, :api_gpx_files]
11  before_filter :require_allow_read_prefs, :only => [:api_details]
12  before_filter :require_allow_read_gpx, :only => [:api_gpx_files]
13  before_filter :require_cookies, :only => [:login, :confirm]
14  before_filter :require_administrator, :only => [:activate, :deactivate, :hide, :unhide, :delete]
15  before_filter :lookup_this_user, :only => [:activate, :deactivate, :hide, :unhide, :delete]
16
17  filter_parameter_logging :password, :pass_crypt, :pass_crypt_confirmation
18
19  cache_sweeper :user_sweeper, :only => [:account, :hide, :unhide, :delete]
20
21  def save
22    @title = t 'user.new.title'
23
24    if Acl.find_by_address(request.remote_ip, :conditions => {:k => "no_account_creation"})
25      render :action => 'new'
26    else
27      @user = User.new(params[:user])
28
29      @user.visible = true
30      @user.data_public = true
31      @user.description = "" if @user.description.nil?
32      @user.creation_ip = request.remote_ip
33      @user.languages = request.user_preferred_languages
34
35      if @user.save
36        flash[:notice] = t 'user.new.flash create success message'
37        Notifier.deliver_signup_confirm(@user, @user.tokens.create(:referer => params[:referer]))
38        redirect_to :action => 'login'
39      else
40        render :action => 'new'
41      end
42    end
43  end
44
45  def account
46    @title = t 'user.account.title'
47    @tokens = @user.oauth_tokens.find :all, :conditions => 'oauth_tokens.invalidated_at is null and oauth_tokens.authorized_at is not null'
48
49    if params[:user] and params[:user][:display_name] and params[:user][:description]
50      @user.display_name = params[:user][:display_name]
51      @user.new_email = params[:user][:new_email]
52
53      if params[:user][:pass_crypt].length > 0 or params[:user][:pass_crypt_confirmation].length > 0
54        @user.pass_crypt = params[:user][:pass_crypt]
55        @user.pass_crypt_confirmation = params[:user][:pass_crypt_confirmation]
56      end
57
58      @user.description = params[:user][:description]
59      @user.languages = params[:user][:languages].split(",")
60
61      case params[:image_action]
62        when "new" then @user.image = params[:user][:image]
63        when "delete" then @user.image = nil
64      end
65
66      @user.home_lat = params[:user][:home_lat]
67      @user.home_lon = params[:user][:home_lon]
68
69      if @user.save
70        set_locale
71
72        if @user.new_email.nil? or @user.new_email.empty?
73          flash.now[:notice] = t 'user.account.flash update success'
74        else
75          flash.now[:notice] = t 'user.account.flash update success confirm needed'
76
77          begin
78            Notifier.deliver_email_confirm(@user, @user.tokens.create)
79          rescue
80            # Ignore errors sending email
81          end
82        end
83      end
84    else
85      if flash[:errors]
86        flash[:errors].each do |attr,msg|
87          attr = "new_email" if attr == "email"
88          @user.errors.add(attr,msg)
89        end
90      end
91    end
92  end
93
94  def go_public
95    @user.data_public = true
96    @user.save
97    flash[:notice] = t 'user.go_public.flash success'
98    redirect_to :controller => 'user', :action => 'account', :display_name => @user.display_name
99  end
100
101  def lost_password
102    @title = t 'user.lost_password.title'
103
104    if params[:user] and params[:user][:email]
105      user = User.find_by_email(params[:user][:email], :conditions => {:visible => true})
106
107      if user
108        token = user.tokens.create
109        Notifier.deliver_lost_password(user, token)
110        flash[:notice] = t 'user.lost_password.notice email on way'
111        redirect_to :action => 'login'
112      else
113        flash.now[:error] = t 'user.lost_password.notice email cannot find'
114      end
115    end
116  end
117
118  def reset_password
119    @title = t 'user.reset_password.title'
120
121    if params[:token]
122      token = UserToken.find_by_token(params[:token])
123
124      if token
125        @user = token.user
126
127        if params[:user]
128          @user.pass_crypt = params[:user][:pass_crypt]
129          @user.pass_crypt_confirmation = params[:user][:pass_crypt_confirmation]
130          @user.active = true
131          @user.email_valid = true
132
133          if @user.save
134            token.destroy
135            flash[:notice] = t 'user.reset_password.flash changed'
136            redirect_to :action => 'login'
137          end
138        end
139      else
140        flash[:error] = t 'user.reset_password.flash token bad'
141        redirect_to :action => 'lost_password'
142      end
143    end
144  end
145
146  def new
147    @title = t 'user.new.title'
148
149    # The user is logged in already, so don't show them the signup page, instead
150    # send them to the home page
151    redirect_to :controller => 'site', :action => 'index' if session[:user]
152  end
153
154  def login
155    if params[:user] and session[:user].nil?
156      email_or_display_name = params[:user][:email]
157      pass = params[:user][:password]
158      user = User.authenticate(:username => email_or_display_name, :password => pass)
159      if user
160        session[:user] = user.id
161        session_expires_after 1.month if params[:remember_me]
162      elsif User.authenticate(:username => email_or_display_name, :password => pass, :inactive => true)
163        flash.now[:error] = t 'user.login.account not active'
164      else
165        flash.now[:error] = t 'user.login.auth failure'
166      end
167    end
168
169    if session[:user]
170      # The user is logged in, if the referer param exists, redirect them to that
171      # unless they've also got a block on them, in which case redirect them to
172      # the block so they can clear it.
173      user = User.find(session[:user])
174      block = user.blocked_on_view
175      if block
176        redirect_to block, :referrer => params[:referrer]
177      elsif params[:referer]
178        redirect_to params[:referer]
179      else
180        redirect_to :controller => 'site', :action => 'index'
181      end
182      return
183    end
184
185    @title = t 'user.login.title'
186  end
187
188  def logout
189    if session[:token]
190      token = UserToken.find_by_token(session[:token])
191      if token
192        token.destroy
193      end
194      session[:token] = nil
195    end
196    session[:user] = nil
197    session_expires_automatically
198    if params[:referer]
199      redirect_to params[:referer]
200    else
201      redirect_to :controller => 'site', :action => 'index'
202    end
203  end
204
205  def confirm
206    if params[:confirm_action]
207      token = UserToken.find_by_token(params[:confirm_string])
208      if token and !token.user.active?
209        @user = token.user
210        @user.active = true
211        @user.email_valid = true
212        @user.save!
213        referer = token.referer
214        token.destroy
215        flash[:notice] = t 'user.confirm.success'
216        session[:user] = @user.id
217        unless referer.nil?
218          redirect_to referer
219        else
220          redirect_to :action => 'account', :display_name => @user.display_name
221        end
222      else
223        flash.now[:error] = t 'user.confirm.failure'
224      end
225    end
226  end
227
228  def confirm_email
229    if params[:confirm_action]
230      token = UserToken.find_by_token(params[:confirm_string])
231      if token and token.user.new_email?
232        @user = token.user
233        @user.email = @user.new_email
234        @user.new_email = nil
235        @user.active = true
236        @user.email_valid = true
237        if @user.save
238          flash[:notice] = t 'user.confirm_email.success'
239        else
240          flash[:errors] = @user.errors
241        end
242        token.destroy
243        session[:user] = @user.id
244        redirect_to :action => 'account', :display_name => @user.display_name
245      else
246        flash.now[:error] = t 'user.confirm_email.failure'
247      end
248    end
249  end
250
251  def api_gpx_files
252    doc = OSM::API.new.get_xml_doc
253    @user.traces.each do |trace|
254      doc.root << trace.to_xml_node() if trace.public? or trace.user == @user
255    end
256    render :text => doc.to_s, :content_type => "text/xml"
257  end
258
259  def view
260    @this_user = User.find_by_display_name(params[:display_name])
261
262    if @this_user and
263       (@this_user.visible? or (@user and @user.administrator?))
264      @title = @this_user.display_name
265    else
266      @title = t 'user.no_such_user.title'
267      @not_found_user = params[:display_name]
268      render :action => 'no_such_user', :status => :not_found
269    end
270  end
271
272  def make_friend
273    if params[:display_name]
274      name = params[:display_name]
275      new_friend = User.find_by_display_name(name, :conditions => {:visible => true})
276      friend = Friend.new
277      friend.user_id = @user.id
278      friend.friend_user_id = new_friend.id
279      unless @user.is_friends_with?(new_friend)
280        if friend.save
281          flash[:notice] = t 'user.make_friend.success', :name => name
282          Notifier.deliver_friend_notification(friend)
283        else
284          friend.add_error(t('user.make_friend.failed', :name => name))
285        end
286      else
287        flash[:warning] = t 'user.make_friend.already_a_friend', :name => name
288      end
289
290      if params[:referer]
291        redirect_to params[:referer]
292      else
293        redirect_to :controller => 'user', :action => 'view'
294      end
295    end
296  end
297
298  def remove_friend
299    if params[:display_name]
300      name = params[:display_name]
301      friend = User.find_by_display_name(name, :conditions => {:visible => true})
302      if @user.is_friends_with?(friend)
303        Friend.delete_all "user_id = #{@user.id} AND friend_user_id = #{friend.id}"
304        flash[:notice] = t 'user.remove_friend.success', :name => friend.display_name
305      else
306        flash[:error] = t 'user.remove_friend.not_a_friend', :name => friend.display_name
307      end
308
309      if params[:referer]
310        redirect_to params[:referer]
311      else
312        redirect_to :controller => 'user', :action => 'view'
313      end
314    end
315  end
316
317  ##
318  # activate a user, allowing them to log in
319  def activate
320    @this_user.update_attributes(:active => true)
321    redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name]
322  end
323
324  ##
325  # deactivate a user, preventing them from logging in
326  def deactivate
327    @this_user.update_attributes(:active => false)
328    redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name]
329  end
330
331  ##
332  # hide a user, marking them as logically deleted
333  def hide
334    @this_user.update_attributes(:visible => false)
335    redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name]
336  end
337
338  ##
339  # unhide a user, clearing the logically deleted flag
340  def unhide
341    @this_user.update_attributes(:visible => true)
342    redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name]
343  end
344
345  ##
346  # delete a user, marking them as deleted and removing personal data
347  def delete
348    @this_user.delete
349    redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name]
350  end
351private
352  ##
353  # require that the user is a administrator, or fill out a helpful error message
354  # and return them to the user page.
355  def require_administrator
356    unless @user.administrator?
357      flash[:error] = t('user.filter.not_an_administrator')
358      redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name]
359    end
360  end
361
362  ##
363  # ensure that there is a "this_user" instance variable
364  def lookup_this_user
365    @this_user = User.find_by_display_name(params[:display_name])
366  rescue ActiveRecord::RecordNotFound
367    redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name] unless @this_user
368  end
369end
Note: See TracBrowser for help on using the repository browser.