require 'csv'
module Caboose
class UsersController < ApplicationController
layout 'caboose/admin'
def before_action
@page = Page.page_with_uri(request.host_with_port, '/admin')
end
#===========================================================================
# Non-admin actions
#===========================================================================
#===========================================================================
# Admin actions
#===========================================================================
# @route_priority 100
# @route GET /admin/users
def admin_index
return if !user_is_allowed('users', 'view')
end
# @route GET /admin/users/json
def admin_json
return if !user_is_allowed('users', 'view')
pager = PageBarGenerator.new(params, {
'site_id' => @site.id,
'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
})
render :json => {
:pager => pager,
:models => pager.items.as_json(:include => :roles)
}
end
# @route GET /admin/users/:id/json
def admin_json_single
return if !user_is_allowed('users', 'view')
u = User.find(params[:id])
render :json => u.as_json(:include => :roles)
end
# @route GET /admin/users/new
def admin_new
return if !user_is_allowed('users', 'add')
@newuser = User.new
end
# @route GET /admin/users/import
def admin_import_form
return if !user_is_allowed('users', 'edit')
end
# @route GET /admin/users/:id
def admin_edit
return if !user_is_allowed('users', 'edit')
@edituser = User.find(params[:id])
@all_roles = Role.tree(@site.id)
@roles = Role.roles_with_user(@edituser.id)
end
# @route GET /admin/users/:id/edit-password
def admin_edit_password
return if !user_is_allowed('users', 'edit')
@edituser = User.find(params[:id])
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
# @route POST /admin/users/import
def admin_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),
:site_id => @site.id
)
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
# @route POST /admin/users
def admin_add
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
user.site_id = @site.id
if user.email.length == 0
resp.error = "Please enter a valid email address."
elsif User.where(:site_id => @site.id, :email => user.email).exists?
resp.error = "That email is already in the system for this site."
else
user.save
resp.redirect = "/admin/users/#{user.id}"
end
render :json => resp
end
# @route PUT /admin/users/:id
def admin_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 'site_id' then user.site_id = value
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 'locked' then user.locked = value
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 'role_ids' then user.toggle_roles(value[0], value[1])
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
# @route POST /admin/users/:id/update-pic
def admin_update_pic
@edituser = User.find(params[:id])
@new_value = "Testing"
end
# @route DELETE /admin/users/:id
def admin_delete
return if !user_is_allowed('users', 'delete')
user = User.find(params[:id])
user.destroy
resp = StdClass.new({
'redirect' => '/admin/users'
})
render :json => resp
end
# @route POST /admin/users/:id/roles/:role_id
def admin_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
# @route DELETE /admin/users/:id/roles/:role_id
def admin_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
# @route_priority 1
# @route GET /admin/users/options
def admin_options
return if !user_is_allowed('users', 'view')
@users = User.where(:site_id => @site.id).reorder('last_name, first_name').all
options = @users.collect { |u| { 'value' => u.id, 'text' => "#{u.first_name} #{u.last_name} (#{u.email})"}}
render json: options
end
# @route_priority 1
# @route GET /admin/users/:id/su
def admin_su
return if !user_is_allowed('users', 'sudo')
user = User.find(params[:id])
# See if we're on the default domain
d = Caboose::Domain.where(:domain => request.host_with_port).first
if d.primary == true
logout_user
login_user(user, false) # Login the new user
redirect_to "/"
end
# Set a random token for the user
user.token = (0...20).map { ('a'..'z').to_a[rand(26)] }.join
user.save
redirect_to "http://#{d.site.primary_domain.domain}/admin/users/#{params[:id]}/su/#{user.token}"
end
# @route GET /admin/users/:id/su/:token
def admin_su_token
return if params[:token].nil?
user = User.find(params[:id])
token = params[:token]
if user.token == params[:token]
if logged_in? || logged_in_user.id == User::LOGGED_OUT_USER_ID
Caboose.log(logged_in_user.id)
redirect_to "/logout?return_url=/admin/users/#{params[:id]}/su/#{user.token}"
return
end
user.token = nil
user.save
login_user(user)
redirect_to '/'
else
render :json => false
end
end
end
end