Added the RoR Login-Engine and activated it on the site.
[selectricity-live] / vendor / plugins / login_engine / app / controllers / user_controller.rb
diff --git a/vendor/plugins/login_engine/app/controllers/user_controller.rb b/vendor/plugins/login_engine/app/controllers/user_controller.rb
new file mode 100644 (file)
index 0000000..397f06b
--- /dev/null
@@ -0,0 +1,261 @@
+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

Benjamin Mako Hill || Want to submit a patch?