openstreetmap-website/app/controllers/user_controller.rb
Tom Hughes 1eba060929 Redirect after processing user changes
After we have processed the requested user changes, redirect back
to the list so that the resulting page is reloadable without getting
resubmission warnings from the browser.
2010-05-07 14:27:52 +01:00

382 lines
12 KiB
Ruby

class UserController < ApplicationController
layout 'site', :except => :api_details
before_filter :authorize, :only => [:api_details, :api_gpx_files]
before_filter :authorize_web, :except => [:api_details, :api_gpx_files]
before_filter :set_locale, :except => [:api_details, :api_gpx_files]
before_filter :require_user, :only => [:account, :go_public, :make_friend, :remove_friend]
before_filter :check_database_readable, :except => [:api_details, :api_gpx_files]
before_filter :check_database_writable, :only => [:login, :new, :account, :go_public, :make_friend, :remove_friend]
before_filter :check_api_readable, :only => [:api_details, :api_gpx_files]
before_filter :require_allow_read_prefs, :only => [:api_details]
before_filter :require_allow_read_gpx, :only => [:api_gpx_files]
before_filter :require_cookies, :only => [:login, :confirm]
before_filter :require_administrator, :only => [:set_status, :delete, :list]
before_filter :lookup_this_user, :only => [:set_status, :delete]
filter_parameter_logging :password, :pass_crypt, :pass_crypt_confirmation
cache_sweeper :user_sweeper, :only => [:account, :set_status, :delete]
def save
@title = t 'user.new.title'
if Acl.find_by_address(request.remote_ip, :conditions => {:k => "no_account_creation"})
render :action => 'new'
else
@user = User.new(params[:user])
@user.status = "pending"
@user.data_public = true
@user.description = "" if @user.description.nil?
@user.creation_ip = request.remote_ip
@user.languages = request.user_preferred_languages
if @user.save
flash[:notice] = t 'user.new.flash create success message'
Notifier.deliver_signup_confirm(@user, @user.tokens.create(:referer => params[:referer]))
redirect_to :action => 'login'
else
render :action => 'new'
end
end
end
def account
@title = t 'user.account.title'
@tokens = @user.oauth_tokens.find :all, :conditions => 'oauth_tokens.invalidated_at is null and oauth_tokens.authorized_at is not null'
if params[:user] and params[:user][:display_name] and params[:user][:description]
@user.display_name = params[:user][:display_name]
@user.new_email = params[:user][:new_email]
if params[:user][:pass_crypt].length > 0 or params[:user][:pass_crypt_confirmation].length > 0
@user.pass_crypt = params[:user][:pass_crypt]
@user.pass_crypt_confirmation = params[:user][:pass_crypt_confirmation]
end
@user.description = params[:user][:description]
@user.languages = params[:user][:languages].split(",")
case params[:image_action]
when "new" then @user.image = params[:user][:image]
when "delete" then @user.image = nil
end
@user.home_lat = params[:user][:home_lat]
@user.home_lon = params[:user][:home_lon]
if @user.save
set_locale
if @user.new_email.nil? or @user.new_email.empty?
flash[:notice] = t 'user.account.flash update success'
else
flash[:notice] = t 'user.account.flash update success confirm needed'
begin
Notifier.deliver_email_confirm(@user, @user.tokens.create)
rescue
# Ignore errors sending email
end
end
redirect_to :action => "account", :display_name => @user.display_name
end
else
if flash[:errors]
flash[:errors].each do |attr,msg|
attr = "new_email" if attr == "email"
@user.errors.add(attr,msg)
end
end
end
end
def go_public
@user.data_public = true
@user.save
flash[:notice] = t 'user.go_public.flash success'
redirect_to :controller => 'user', :action => 'account', :display_name => @user.display_name
end
def lost_password
@title = t 'user.lost_password.title'
if params[:user] and params[:user][:email]
user = User.find_by_email(params[:user][:email], :conditions => {:status => ["pending", "active", "confirmed"]})
if user
token = user.tokens.create
Notifier.deliver_lost_password(user, token)
flash[:notice] = t 'user.lost_password.notice email on way'
redirect_to :action => 'login'
else
flash.now[:error] = t 'user.lost_password.notice email cannot find'
end
end
end
def reset_password
@title = t 'user.reset_password.title'
if params[:token]
token = UserToken.find_by_token(params[:token])
if token
@user = token.user
if params[:user]
@user.pass_crypt = params[:user][:pass_crypt]
@user.pass_crypt_confirmation = params[:user][:pass_crypt_confirmation]
@user.status = "active"
@user.email_valid = true
if @user.save
token.destroy
flash[:notice] = t 'user.reset_password.flash changed'
redirect_to :action => 'login'
end
end
else
flash[:error] = t 'user.reset_password.flash token bad'
redirect_to :action => 'lost_password'
end
end
end
def new
@title = t 'user.new.title'
# The user is logged in already, so don't show them the signup
# page, instead send them to the home page
redirect_to :controller => 'site', :action => 'index' if session[:user]
end
def login
@title = t 'user.login.title'
if params[:user]
email_or_display_name = params[:user][:email]
pass = params[:user][:password]
user = User.authenticate(:username => email_or_display_name, :password => pass)
if user
session[:user] = user.id
session_expires_after 1.month if params[:remember_me]
# The user is logged in, if the referer param exists, redirect
# them to that unless they've also got a block on them, in
# which case redirect them to the block so they can clear it.
if user.blocked_on_view
redirect_to user.blocked_on_view, :referrer => params[:referrer]
elsif params[:referer]
redirect_to params[:referer]
else
redirect_to :controller => 'site', :action => 'index'
end
elsif User.authenticate(:username => email_or_display_name, :password => pass, :pending => true)
flash.now[:error] = t 'user.login.account not active'
elsif User.authenticate(:username => email_or_display_name, :password => pass, :suspended => true)
flash.now[:error] = t 'user.login.account suspended'
else
flash.now[:error] = t 'user.login.auth failure'
end
end
end
def logout
@title = t 'user.logout.title'
if params[:session] == request.session_options[:id]
if session[:token]
token = UserToken.find_by_token(session[:token])
if token
token.destroy
end
session[:token] = nil
end
session[:user] = nil
session_expires_automatically
if params[:referer]
redirect_to params[:referer]
else
redirect_to :controller => 'site', :action => 'index'
end
end
end
def confirm
if params[:confirm_action]
token = UserToken.find_by_token(params[:confirm_string])
if token and !token.user.active?
@user = token.user
@user.status = "active"
@user.email_valid = true
@user.save!
referer = token.referer
token.destroy
flash[:notice] = t 'user.confirm.success'
session[:user] = @user.id
unless referer.nil?
redirect_to referer
else
redirect_to :action => 'account', :display_name => @user.display_name
end
else
flash.now[:error] = t 'user.confirm.failure'
end
end
end
def confirm_email
if params[:confirm_action]
token = UserToken.find_by_token(params[:confirm_string])
if token and token.user.new_email?
@user = token.user
@user.email = @user.new_email
@user.new_email = nil
@user.email_valid = true
if @user.save
flash[:notice] = t 'user.confirm_email.success'
else
flash[:errors] = @user.errors
end
token.destroy
session[:user] = @user.id
redirect_to :action => 'account', :display_name => @user.display_name
else
flash.now[:error] = t 'user.confirm_email.failure'
end
end
end
def api_gpx_files
doc = OSM::API.new.get_xml_doc
@user.traces.each do |trace|
doc.root << trace.to_xml_node() if trace.public? or trace.user == @user
end
render :text => doc.to_s, :content_type => "text/xml"
end
def view
@this_user = User.find_by_display_name(params[:display_name])
if @this_user and
(@this_user.visible? or (@user and @user.administrator?))
@title = @this_user.display_name
else
@title = t 'user.no_such_user.title'
@not_found_user = params[:display_name]
render :action => 'no_such_user', :status => :not_found
end
end
def make_friend
if params[:display_name]
name = params[:display_name]
new_friend = User.find_by_display_name(name, :conditions => {:status => ["active", "confirmed"]})
friend = Friend.new
friend.user_id = @user.id
friend.friend_user_id = new_friend.id
unless @user.is_friends_with?(new_friend)
if friend.save
flash[:notice] = t 'user.make_friend.success', :name => name
Notifier.deliver_friend_notification(friend)
else
friend.add_error(t('user.make_friend.failed', :name => name))
end
else
flash[:warning] = t 'user.make_friend.already_a_friend', :name => name
end
if params[:referer]
redirect_to params[:referer]
else
redirect_to :controller => 'user', :action => 'view'
end
end
end
def remove_friend
if params[:display_name]
name = params[:display_name]
friend = User.find_by_display_name(name, :conditions => {:status => ["active", "confirmed"]})
if @user.is_friends_with?(friend)
Friend.delete_all "user_id = #{@user.id} AND friend_user_id = #{friend.id}"
flash[:notice] = t 'user.remove_friend.success', :name => friend.display_name
else
flash[:error] = t 'user.remove_friend.not_a_friend', :name => friend.display_name
end
if params[:referer]
redirect_to params[:referer]
else
redirect_to :controller => 'user', :action => 'view'
end
end
end
##
# sets a user's status
def set_status
@this_user.update_attributes(:status => params[:status])
redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name]
end
##
# delete a user, marking them as deleted and removing personal data
def delete
@this_user.delete
redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name]
end
##
# display a list of users matching specified criteria
def list
if request.post?
ids = params[:user].keys.collect { |id| id.to_i }
User.update_all("status = 'confirmed'", :id => ids) if params[:confirm]
User.update_all("status = 'deleted'", :id => ids) if params[:hide]
redirect_to url_for(:status => params[:status], :ip => params[:ip], :page => params[:page])
else
conditions = Hash.new
conditions[:status] = params[:status] if params[:status]
conditions[:creation_ip] = params[:ip] if params[:ip]
@user_pages, @users = paginate(:users,
:conditions => conditions,
:order => :id,
:per_page => 50)
end
end
private
##
# require that the user is a administrator, or fill out a helpful error message
# and return them to the user page.
def require_administrator
if @user and not @user.administrator?
flash[:error] = t('user.filter.not_an_administrator')
if params[:display_name]
redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name]
else
redirect_to :controller => 'user', :action => 'login', :referer => request.request_uri
end
elsif not @user
redirect_to :controller => 'user', :action => 'login', :referer => request.request_uri
end
end
##
# ensure that there is a "this_user" instance variable
def lookup_this_user
@this_user = User.find_by_display_name(params[:display_name])
rescue ActiveRecord::RecordNotFound
redirect_to :controller => 'user', :action => 'view', :display_name => params[:display_name] unless @this_user
end
end