--- /dev/null
+class UserController < ApplicationController
+ model :user
+
+ # Override this function in your own application to define a custom home action.
+ def home
+ if user?
+ @fullname = "#{current_user.firstname} #{current_user.lastname}"
+ else
+ @fullname = "Not logged in..."
+ end # this is a bit of a hack since the home action is used to verify user
+ # keys, where noone is logged in. We should probably create a unique
+ # 'validate_key' action instead.
+ end
+
+ # The action used to log a user in. If the user was redirected to the login page
+ # by the login_required method, they should be sent back to the page they were
+ # trying to access. If not, they will be sent to "/user/home".
+ def login
+ return if generate_blank
+ @user = User.new(params[:user])
+ if session[:user] = User.authenticate(params[:user][:login], params[:user][:password])
+ session[:user].logged_in_at = Time.now
+ session[:user].save
+ flash[:notice] = 'Login successful'
+ redirect_to_stored_or_default :action => 'home'
+ else
+ @login = params[:user][:login]
+ flash.now[:warning] = 'Login unsuccessful'
+ end
+ end
+
+ # Register as a new user. Upon successful registration, the user will be sent to
+ # "/user/login" to enter their details.
+ def signup
+ return if generate_blank
+ params[:user].delete('form')
+ params[:user].delete('verified') # you CANNOT pass this as part of the request
+ @user = User.new(params[:user])
+ begin
+ User.transaction(@user) do
+ @user.new_password = true
+ unless LoginEngine.config(:use_email_notification) and LoginEngine.config(:confirm_account)
+ @user.verified = 1
+ end
+ if @user.save
+ key = @user.generate_security_token
+ url = url_for(:action => 'home', :user_id => @user.id, :key => key)
+ flash[:notice] = 'Signup successful!'
+ if LoginEngine.config(:use_email_notification) and LoginEngine.config(:confirm_account)
+ UserNotify.deliver_signup(@user, params[:user][:password], url)
+ flash[:notice] << ' Please check your registered email account to verify your account registration and continue with the login.'
+ else
+ flash[:notice] << ' Please log in.'
+ end
+ redirect_to :action => 'login'
+ end
+ end
+ rescue Exception => e
+ flash.now[:notice] = nil
+ flash.now[:warning] = 'Error creating account: confirmation email not sent'
+ logger.error "Unable to send confirmation E-Mail:"
+ logger.error e
+ end
+ end
+
+ def logout
+ session[:user] = nil
+ redirect_to :action => 'login'
+ end
+
+ def change_password
+ return if generate_filled_in
+ if do_change_password_for(@user)
+ # since sometimes we're changing the password from within another action/template...
+ #redirect_to :action => params[:back_to] if params[:back_to]
+ redirect_back_or_default :action => 'change_password'
+ end
+ end
+
+ protected
+ def do_change_password_for(user)
+ begin
+ User.transaction(user) do
+ user.change_password(params[:user][:password], params[:user][:password_confirmation])
+ if user.save
+ if LoginEngine.config(:use_email_notification)
+ UserNotify.deliver_change_password(user, params[:user][:password])
+ flash[:notice] = "Updated password emailed to #{@user.email}"
+ else
+ flash[:notice] = "Password updated."
+ end
+ return true
+ else
+ flash[:warning] = 'There was a problem saving the password. Please retry.'
+ return false
+ end
+ end
+ rescue
+ flash[:warning] = 'Password could not be changed at this time. Please retry.'
+ end
+ end
+
+ public
+
+
+ def forgot_password
+ # Always redirect if logged in
+ if user?
+ flash[:message] = 'You are currently logged in. You may change your password now.'
+ redirect_to :action => 'change_password'
+ return
+ end
+
+ # Email disabled... we are unable to provide the password
+ if !LoginEngine.config(:use_email_notification)
+ flash[:message] = "Please contact the system admin at #{LoginEngine.config(:admin_email)} to reset your password."
+ redirect_back_or_default :action => 'login'
+ return
+ end
+
+ # Render on :get and render
+ return if generate_blank
+
+ # Handle the :post
+ if params[:user][:email].empty?
+ flash.now[:warning] = 'Please enter a valid email address.'
+ elsif (user = User.find_by_email(params[:user][:email])).nil?
+ flash.now[:warning] = "We could not find a user with the email address #{params[:user][:email]}"
+ else
+ begin
+ User.transaction(user) do
+ key = user.generate_security_token
+ url = url_for(:action => 'change_password', :user_id => user.id, :key => key)
+ UserNotify.deliver_forgot_password(user, url)
+ flash[:notice] = "Instructions on resetting your password have been emailed to #{params[:user][:email]}"
+ end
+ unless user?
+ redirect_to :action => 'login'
+ return
+ end
+ redirect_back_or_default :action => 'home'
+ rescue
+ flash.now[:warning] = "Your password could not be emailed to #{params[:user][:email]}"
+ end
+ end
+ end
+
+ def edit
+ return if generate_filled_in
+ do_edit_user(@user)
+ end
+
+ protected
+ def do_edit_user(user)
+ begin
+ User.transaction(user) do
+ user.attributes = params[:user].delete_if { |k,v| not LoginEngine.config(:changeable_fields).include?(k) }
+ if user.save
+ flash[:notice] = "User details updated"
+ else
+ flash[:warning] = "Details could not be updated! Please retry."
+ end
+ end
+ rescue
+ flash.now[:warning] = "Error updating user details. Please try again later."
+ end
+ end
+
+ public
+
+ def delete
+ get_user_to_act_on
+ if do_delete_user(@user)
+ logout
+ else
+ redirect_back_or_default :action => 'home'
+ end
+ end
+
+ protected
+ def do_delete_user(user)
+ begin
+ if LoginEngine.config(:delayed_delete)
+ User.transaction(user) do
+ key = user.set_delete_after
+ if LoginEngine.config(:use_email_notification)
+ url = url_for(:action => 'restore_deleted', :user_id => user.id, :key => key)
+ UserNotify.deliver_pending_delete(user, url)
+ end
+ end
+ else
+ destroy(@user)
+ end
+ return true
+ rescue
+ if LoginEngine.config(:use_email_notification)
+ flash.now[:warning] = 'The delete instructions were not sent. Please try again later.'
+ else
+ flash.now[:notice] = 'The account has been scheduled for deletion. It will be removed in #{LoginEngine.config(:delayed_delete_days)} days.'
+ end
+ return false
+ end
+ end
+
+ public
+
+ def restore_deleted
+ get_user_to_act_on
+ @user.deleted = 0
+ if not @user.save
+ flash.now[:warning] = "The account for #{@user['login']} was not restored. Please try the link again."
+ redirect_to :action => 'login'
+ else
+ redirect_to :action => 'home'
+ end
+ end
+
+ protected
+
+ def destroy(user)
+ UserNotify.deliver_delete(user) if LoginEngine.config(:use_email_notification)
+ flash[:notice] = "The account for #{user['login']} was successfully deleted."
+ user.destroy()
+ end
+
+ def protect?(action)
+ if ['login', 'signup', 'forgot_password'].include?(action)
+ return false
+ else
+ return true
+ end
+ end
+
+ # Generate a template user for certain actions on get
+ def generate_blank
+ case request.method
+ when :get
+ @user = User.new
+ render
+ return true
+ end
+ return false
+ end
+
+ # Generate a template user for certain actions on get
+ def generate_filled_in
+ get_user_to_act_on
+ case request.method
+ when :get
+ render
+ return true
+ end
+ return false
+ end
+
+ # returns the user object this method should act upon; only really
+ # exists for other engines operating on top of this one to redefine...
+ def get_user_to_act_on
+ @user = session[:user]
+ end
+end