require 'csv' module Caboose class UsersController < ApplicationController layout 'caboose/admin' def before_action @page = Page.page_with_uri('/admin') end #=========================================================================== # Non-admin actions #=========================================================================== # GET /my-account def my_account return if !logged_in? @user = logged_in_user render :layout => 'caboose/modal' end # PUT /my-account def update_my_account return if !logged_in? resp = StdClass.new user = logged_in_user save = true params.each do |name,value| case name when "first_name", "last_name", "username", "email", "phone" user[name.to_sym] = value when "password" confirm = params[:confirm] if (value != confirm) resp.error = "Passwords do not match."; save = false elsif (value.length < 8) resp.error = "Passwords must be at least 8 characters."; save = false else user.password = Digest::SHA1.hexdigest(Caboose::salt + value) end end end resp.success = save && user.save render json: resp end #=========================================================================== # Admin actions #=========================================================================== # GET /admin/users def index return if !user_is_allowed('users', 'view') @gen = PageBarGenerator.new(params, { 'first_name_like' => '', 'last_name_like' => '', 'username_like' => '', 'email_like' => '', },{ 'model' => 'Caboose::User', 'sort' => 'last_name, first_name', 'desc' => false, 'base_url' => '/admin/users', 'use_url_params' => false }) @users = @gen.items end # GET /admin/users def index return if !user_is_allowed('users', 'view') @gen = PageBarGenerator.new(params, { 'first_name_like' => '', 'last_name_like' => '', 'username_like' => '', 'email_like' => '', },{ 'model' => 'Caboose::User', 'sort' => 'last_name, first_name', 'desc' => false, 'base_url' => '/admin/users', 'use_url_params' => false }) @users = @gen.items end # GET /admin/users/new def new return if !user_is_allowed('users', 'add') @newuser = User.new end # GET /admin/users/1/edit def edit return if !user_is_allowed('users', 'edit') @edituser = User.find(params[:id]) @all_roles = Role.tree @roles = Role.roles_with_user(@edituser.id) end # GET /admin/users/1/edit-password def edit_password return if !user_is_allowed('users', 'edit') @edituser = User.find(params[:id]) end # GET /admin/users/import def import_form return if !user_is_allowed('users', 'edit') end def random_string(length) o = [('a'..'z'),('A'..'Z'),('0'..'9')].map { |i| i.to_a }.flatten return (0...length).map { o[rand(o.length)] }.join end # POST /admin/users/import def import return if !user_is_allowed('users', 'add') resp = StdClass.new csv_data = params[:csv_data] arr = [] good_count = 0 bad_count = 0 csv_data.strip.split("\n").each do |line| data = CSV.parse_line(line) if data.count < 3 arr << [line, true, "Too few columns"] bad_count = bad_count + 1 next end first_name = data[0].nil? ? nil : data[0].strip last_name = data[1].nil? ? nil : data[1].strip email = data[2].nil? ? nil : data[2].strip.downcase username = data.count >= 4 && !data[3].nil? ? data[3].strip.downcase : nil password = data.count >= 5 && !data[4].nil? ? data[4].strip : random_string(8) first_name = data[0] last_name = data[1] email = data[2] username = data.count >= 4 ? data[3] : nil password = data.count >= 5 ? data[4] : random_string(8) if first_name.nil? || first_name.length == 0 arr << [line, false, "Missing first name."] bad_count = bad_count + 1 elsif last_name.nil? || last_name.length == 0 arr << [line, false, "Missing last name."] bad_count = bad_count + 1 elsif email.nil? || email.length == 0 || !email.include?('@') arr << [line, false, "Email is invalid."] bad_count = bad_count + 1 elsif Caboose::User.where(:email => email).exists? arr << [line, false, "Email already exists."] bad_count = bad_count + 1 else Caboose::User.create( :first_name => first_name, :last_name => last_name, :email => email, :username => username, :password => Digest::SHA1.hexdigest(Caboose::salt + password) ) good_count = good_count + 1 end end resp.success = "#{good_count} user#{good_count == 1 ? '' : 's'} were added successfully." if bad_count > 0 resp.success << "
#{bad_count} user#{bad_count == 1 ? '' : 's'} were skipped." resp.success << "

Please check the log below for more details." resp.log = arr end render :json => resp end # POST /admin/users def create return if !user_is_allowed('users', 'add') resp = StdClass.new({ 'error' => nil, 'redirect' => nil }) user = User.new() user.email = params[:email] ? params[:email].strip.downcase : nil if user.email.length == 0 resp.error = "Please enter a valid email address." elsif User.where(:email => user.email).exists? resp.error = "That email is already in the system." else user.save resp.redirect = "/admin/users/#{user.id}/edit" end render :json => resp end # PUT /admin/users/1 def update return if !user_is_allowed('users', 'edit') resp = StdClass.new user = User.find(params[:id]) save = true params.each do |name,value| case name when 'first_name' then user.first_name = value when 'last_name' then user.last_name = value when 'username' then user.username = value when 'email' then user.email = value when 'address' then user.address = value when 'address2' then user.address2 = value when 'city' then user.city = value when 'state' then user.state = value when 'zip' then user.zip = value when 'phone' then user.phone = value when 'fax' then user.fax = value when 'utc_offset' then user.utc_offset = value.to_f when "password" confirm = params[:password2] if (value != confirm) resp.error = "Passwords do not match."; save = false elsif (value.length < 8) resp.error = "Passwords must be at least 8 characters."; save = false else user.password = Digest::SHA1.hexdigest(Caboose::salt + value) end when "roles" user.roles = []; value.each { |rid| user.roles << Role.find(rid) } unless value.nil? resp.attribute = { 'text' => user.roles.collect{ |r| r.name }.join(', ') } end end resp.success = save && user.save render json: resp end # POST /admin/users/1/update-pic def update_pic @edituser = User.find(params[:id]) @new_value = "Testing" end # DELETE /admin/users/1 def destroy return if !user_is_allowed('users', 'delete') user = User.find(params[:id]) user.destroy resp = StdClass.new({ 'redirect' => '/admin/users' }) render :json => resp end # POST /admin/users/:id/roles/:role_id def add_to_role return if !user_is_allowed('users', 'edit') if !RoleMembership.where(:user_id => params[:id], :role_id => params[:role_id]).exists? RoleMembership.create(:user_id => params[:id], :role_id => params[:role_id]) end render :json => true end # DELETE /admin/users/:id/roles/:role_id def remove_from_role return if !user_is_allowed('users', 'edit') RoleMembership.where(:user_id => params[:id], :role_id => params[:role_id]).destroy_all render :json => true end # GET /admin/users/options def options return if !user_is_allowed('users', 'view') @users = User.reorder('last_name, first_name').all options = @users.collect { |u| { 'value' => u.id, 'text' => "#{u.first_name} #{u.last_name}"}} render json: options end # GET /admin/users/:id/su def admin_su return if !user_is_allowed('users', 'sudo') user = User.find(params[:id]) # Log out the current user cookies.delete(:caboose_user_id) reset_session # Login the new user login_user(user, false) redirect_to "/" end end end