diff --git a/app/controllers/admin/base_controller.rb b/app/controllers/admin/base_controller.rb index 964d1bc..051c184 100644 --- a/app/controllers/admin/base_controller.rb +++ b/app/controllers/admin/base_controller.rb @@ -1,32 +1,31 @@ class Admin::BaseController < ApplicationController before_action :require_admin, except: [:login] # GET /admin # POST /admin def index @client_ids = Client.pluck(:ClientId) get_charts @global_stats = GlobalStats.new.stats render 'admin/index' end # GET /admin/login def login render 'admin/login' end protected def get_charts - days_ago = params.fetch(:days_back, 7).to_i rescue 7 @job_status = ChartGenerator.job_statuses(@client_ids, days_ago) @job_stats = ChartGenerator.job_stats(@client_ids, days_ago - 1) end def require_admin return if current_user.try(:has_admin_access?) flash[:alert] = 'You need to log in first' redirect_to admin_login_path end end diff --git a/app/controllers/admin/clients_controller.rb b/app/controllers/admin/clients_controller.rb index db478ff..8c29a4f 100644 --- a/app/controllers/admin/clients_controller.rb +++ b/app/controllers/admin/clients_controller.rb @@ -1,107 +1,106 @@ class Admin::ClientsController < Admin::BaseController before_action :fetch_client, only: [:show, :jobs, :logs, :stats, :configuration, :disable, :revoke, :block, :unblock] before_action :fetch_logs, only: [:logs] # Shows all available clients # # GET /admin/clients def index @clients = Client.includes(:jobs).all @client_ids = @clients.map(&:id) fetch_jobs_info end # Shows a specific client # # GET /admin/clients/1 def show if !@client.host.present? flash[:alert] = 'Client not configured through Archiving' return redirect_to admin_clients_path end get_charts end # GET /admin/clients/1/jobs def jobs @jobs = @client.recent_jobs.page(params[:page]) end # GET /admin/clients/1/logs def logs end # GET /admin/clients/1/stats # POST /admin/clients/1/stats def stats get_charts end # GET /admin/clients/1/configuration def configuration end # POST /admin/clients/1/disable def disable if @client.host.disable_jobs_and_update flash[:success] = 'Client disabled' else flash[:error] = 'Something went wrong, try again later' end redirect_to admin_client_path(@client) end # POST /admin/clients/1/block def block if @client.host.disable_jobs_and_lock flash[:success] = 'Client is disabled and locked' else flash[:error] = 'Something went wrong, try again' end redirect_to admin_client_path(@client) end # POST /admin/clients/1/unblock def unblock if @client.host.unblock flash[:success] = 'Client can know be configured by users' else flash[:error] = 'Client is still locked' end redirect_to admin_client_path(@client) end # DELETE /admin/clients/1/revoke def revoke if @client.host.remove_from_bacula(true) flash[:success] = 'Client removed. It will be visible to until its jobs get cleaned up' else flash[:error] = 'Something went wrong, try again later' end redirect_to admin_clients_path end private # Fetches the client based on the given id def fetch_client @client = Client.find(params[:id]) @client_ids = [@client.id] end def fetch_jobs_info @stats = JobStats.new end def get_charts - days_ago = params.fetch(:days_back, 7).to_i rescue 7 @job_status = ChartGenerator.job_statuses(@client_ids, days_ago) @job_stats = ChartGenerator.job_stats(@client_ids, days_ago - 1) end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c265ed8..ecf3f2b 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,110 +1,112 @@ class ApplicationController < ActionController::Base # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. protect_from_forgery with: :exception - helper_method :current_user, :warden + helper_method :current_user, :warden, :days_ago # GET / def index redirect_to clients_path if current_user end # GET /faq def faq @faqs = Faq.order(priority: :desc).all end # Warden handler for authentication failure def unauthenticated flash[:error] = warden.message || 'There was an error with your login' if attempted_path == '/grnet' redirect_to admin_login_path else redirect_to root_path end end # POST /grnet def grnet if current_user warden.logout reset_current_user end begin warden.authenticate!(:admin) rescue return unauthenticated end current_user redirect_to admin_path end # GET /institutional def institutional begin warden.authenticate!(:institutional) rescue return unauthenticated end current_user redirect_to clients_path end # POST /vima def vima begin warden.authenticate!(:vima) rescue return unauthenticated end current_user redirect_to clients_path end def logout warden.logout reset_current_user redirect_to root_path end protected def warden request.env['warden'] end def current_user @current_user ||= warden.user end def reset_current_user @current_user = nil end def fetch_logs - days_ago = params.fetch(:days_back, 7).to_i rescue 7 - if @client @logs = Log.includes(:job).joins(job: :client).where(Client: { ClientId: @client.id }) else @logs = Log.includes(:job).joins(job: { client: { host: :users } }). where(users: { id: current_user.id }) end @logs = @logs.where('Time > ?', days_ago.days.ago). order(Time: :desc, LogId: :desc).page(params[:page]) end + def days_ago + params.fetch(:days_back, 7).to_i rescue 7 + end + private def require_logged_in return if current_user flash[:alert] = 'You need to log in first' redirect_to root_path end def attempted_path (request.env['warden.options'] || {})[:attempted_path] end end diff --git a/app/controllers/clients_controller.rb b/app/controllers/clients_controller.rb index 1653a86..c7ea95e 100644 --- a/app/controllers/clients_controller.rb +++ b/app/controllers/clients_controller.rb @@ -1,159 +1,158 @@ class ClientsController < ApplicationController before_action :require_logged_in before_action :fetch_client, only: [:show, :jobs, :logs, :stats, :users, :restore, :run_restore, :restore_selected, :remove_user] before_action :fetch_logs, only: [:logs] # GET /clients # POST /clients def index @client_ids = Client.for_user(current_user.id).pluck(:ClientId) @clients = Client.where(ClientId: @client_ids).includes(:jobs) @hosts = current_user.hosts.not_baculized fetch_jobs_info get_charts end # GET /clients/1 def show @schedules = @client.host.job_templates.map(&:schedule) @filesets = @client.host.job_templates.map(&:fileset) end # GET /clients/1/jobs def jobs @jobs = @client.recent_jobs.page(params[:page]) end # GET /clients/1/logs def logs; end # GET /clients/1/stats # POST /clients/1/stats def stats get_charts end # GET /clients/1/users def users @users = @client.host.users if @client.manually_inserted? @invitation = @client.host.invitations.new excluded_ids = @users.pluck(:id) + @client.host.invitations.pluck(:user_id) @available_users = User.institutional.where.not(id: excluded_ids).pluck(:username, :id) end end # DELETE /clients/1/user def remove_user user = @client.host.users.find(params[:user_id]) if @client.host.users.delete(user) flash[:success] = if @client.manually_inserted? 'User successfully removed' else 'User must be removed from the VM\'s list form your VM provider too (ViMa or Okeanos).' end else flash[:alert] = 'User not removed, something went wrong' end redirect_to users_client_path(@client) end # GET /clients/1/restore def restore return if @client.is_backed_up? flash[:error] = 'Can not issue a restore for this client' redirect_to client_path(@client) end # POST /clients/1/run_restore def run_restore @location = params[:restore_location].blank? ? '/tmp/bacula_restore' : params[:restore_location] fileset = params[:fileset] restore_point = fetch_restore_point if params[:commit] == 'Restore All Files' if @location.nil? || fileset.nil? || !@client.host.restore(fileset, @location, restore_point) flash[:error] = 'Something went wrong, try again later' else flash[:success] = "Restore job issued successfully, files will be soon available in #{@location}" end render js: "window.location = '#{client_path(@client)}'" else session[:job_ids] = @client.get_job_ids(fileset, restore_point) Bvfs.new(@client, session[:job_ids]).update_cache render 'select_files' end end # POST /clients/1/restore_selected def restore_selected Bvfs.new(@client, session[:job_ids]).restore_selected_files(params[:files], params[:location]) session.delete(:job_ids) flash[:success] = "Restore job issued successfully, files will be soon available in #{params[:location]}" redirect_to client_path(@client) end # GET /clients/1/tree?id=1 def tree @client = Client.for_user(current_user.id).find(params[:client_id]) bvfs = Bvfs.new(@client, session[:job_ids]) pathid = params[:id].to_i if pathid.nonzero? bvfs.fetch_dirs(pathid) else bvfs.fetch_dirs end tree = bvfs.extract_dir_id_and_name.map do |id, name| { id: id, text: name, state: { checkbox_disabled: true }, children: true } end if pathid.nonzero? bvfs.fetch_files(pathid) bvfs.extract_file_id_and_name.each do |id, name| tree << { id: id, text: name, type: 'file' } end end render json: tree end private def fetch_client @client = Client.for_user(current_user.id).find(params[:id]) @client_ids = [@client.id] end def fetch_jobs_info @stats = JobStats.new(@client_ids) end def get_charts - days_ago = params.fetch(:days_back, 7).to_i rescue 7 @job_status = ChartGenerator.job_statuses(@client_ids, days_ago) @job_stats = ChartGenerator.job_stats(@client_ids, days_ago - 1) end def fetch_restore_point if params['restore_time(4i)'].blank? || params['restore_time(5i)'].blank? || params[:restore_date].blank? return nil end restore_point = "#{params[:restore_date]} #{params['restore_time(4i)']}:#{params['restore_time(5i)']}:00" begin DateTime.strptime(restore_point, '%Y-%m-%d %H:%M:%S') rescue return nil end restore_point end end