Show More
Commit Description:
use uuid cookie
Commit Description:
use uuid cookie
References:
File last commit:
Show/Diff file:
Action:
app/controllers/application_controller.rb
| 251 lines
| 7.8 KiB
| text/x-ruby
| RubyLexer
|
r755 | require 'ipaddr' | |||
r852 | require "securerandom" | |||
r755 | ||||
|
r162 | class ApplicationController < ActionController::Base | ||
|
r318 | protect_from_forgery | ||
|
r162 | |||
r745 | before_action :current_user | |||
r804 | before_action :nav_announcement | |||
r852 | before_action :unique_visitor_id | |||
r554 | ||||
|
r162 | SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode' | ||
r525 | MULTIPLE_IP_LOGIN_CONF_KEY = 'right.multiple_ip_login' | |||
r784 | WHITELIST_IGNORE_CONF_KEY = 'right.whitelist_ignore' | |||
r755 | WHITELIST_IP_CONF_KEY = 'right.whitelist_ip' | |||
|
r162 | |||
r593 | #report and redirect for unauthorized activities | |||
r756 | def unauthorized_redirect(notice = 'You are not authorized to view the page you requested') | |||
flash[:notice] = notice | ||||
redirect_to login_main_path | ||||
r593 | end | |||
r554 | # Returns the current logged-in user (if any). | |||
def current_user | ||||
r556 | return nil unless session[:user_id] | |||
r554 | @current_user ||= User.find(session[:user_id]) | |||
end | ||||
r804 | def nav_announcement | |||
@nav_announcement = Announcement.where(on_nav_bar: true) | ||||
end | ||||
|
r162 | def admin_authorization | ||
r756 | return false unless check_valid_login | |||
r619 | user = User.includes(:roles).find(session[:user_id]) | |||
r425 | unless user.admin? | |||
r593 | unauthorized_redirect | |||
r425 | return false | |||
end | ||||
return true | ||||
|
r162 | end | ||
def authorization_by_roles(allowed_roles) | ||||
r756 | return false unless check_valid_login | |||
r803 | unless @current_user.roles.detect { |role| allowed_roles.member?(role.name) } | |||
r593 | unauthorized_redirect | |||
|
r162 | return false | ||
end | ||||
end | ||||
r625 | def testcase_authorization | |||
#admin always has privileged | ||||
if @current_user.admin? | ||||
return true | ||||
end | ||||
r632 | unauthorized_redirect unless GraderConfiguration["right.view_testcase"] | |||
r625 | end | |||
r852 | def unique_visitor_id | |||
unless cookies[:uuid] | ||||
value = SecureRandom.uuid | ||||
cookies[:uuid] = { value: value, expires: 20.year } | ||||
end | ||||
end | ||||
r755 | ||||
|
r162 | protected | ||
r755 | #redirect to root (and also force logout) | |||
#if the user is not logged_in or the system is in "ADMIN ONLY" mode | ||||
r756 | def check_valid_login | |||
#check if logged in | ||||
|
r162 | unless session[:user_id] | ||
r424 | if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY] | |||
r756 | unauthorized_redirect('You need to login but you cannot log in at this time') | |||
else | ||||
unauthorized_redirect('You need to login') | ||||
r424 | end | |||
|
r162 | return false | ||
end | ||||
# check if run in single user mode | ||||
|
r320 | if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY] | ||
r757 | if @current_user==nil || (!@current_user.admin?) | |||
r756 | unauthorized_redirect('You cannot log in at this time') | |||
|
r162 | return false | ||
end | ||||
end | ||||
r670 | # check if the user is enabled | |||
r755 | unless @current_user.enabled? || @current_user.admin? | |||
r756 | unauthorized_redirect 'Your account is disabled' | |||
r670 | return false | |||
end | ||||
r755 | # check if user ip is allowed | |||
r784 | unless @current_user.admin? || GraderConfiguration[WHITELIST_IGNORE_CONF_KEY] | |||
r755 | unless is_request_ip_allowed? | |||
r784 | unauthorized_redirect 'Your IP is not allowed to login at this time.' | |||
r756 | return false | |||
r755 | end | |||
end | ||||
|
r320 | if GraderConfiguration.multicontests? | ||
r670 | return true if @current_user.admin? | |||
|
r295 | begin | ||
r670 | if @current_user.contest_stat(true).forced_logout | |||
|
r295 | flash[:notice] = 'You have been automatically logged out.' | ||
redirect_to :controller => 'main', :action => 'index' | ||||
end | ||||
rescue | ||||
end | ||||
end | ||||
|
r162 | return true | ||
end | ||||
r755 | #redirect to root (and also force logout) | |||
#if the user use different ip from the previous connection | ||||
# only applicable when MULTIPLE_IP_LOGIN options is false only | ||||
r525 | def authenticate_by_ip_address | |||
#this assume that we have already authenticate normally | ||||
unless GraderConfiguration[MULTIPLE_IP_LOGIN_CONF_KEY] | ||||
user = User.find(session[:user_id]) | ||||
r757 | if (!user.admin? && user.last_ip && user.last_ip != request.remote_ip) | |||
r525 | flash[:notice] = "You cannot use the system from #{request.remote_ip}. Your last ip is #{user.last_ip}" | |||
redirect_to :controller => 'main', :action => 'login' | ||||
return false | ||||
end | ||||
unless user.last_ip | ||||
user.last_ip = request.remote_ip | ||||
user.save | ||||
end | ||||
end | ||||
return true | ||||
end | ||||
|
r162 | def authorization | ||
r756 | return false unless check_valid_login | |||
|
r162 | user = User.find(session[:user_id]) | ||
unless user.roles.detect { |role| | ||||
r632 | role.rights.detect{ |right| | |||
right.controller == self.class.controller_name and | ||||
r755 | (right.action == 'all' || right.action == action_name) | |||
r632 | } | |||
|
r162 | } | ||
flash[:notice] = 'You are not authorized to view the page you requested' | ||||
#request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login') | ||||
redirect_to :controller => 'main', :action => 'login' | ||||
return false | ||||
end | ||||
end | ||||
def verify_time_limit | ||||
return true if session[:user_id]==nil | ||||
user = User.find(session[:user_id], :include => :site) | ||||
r755 | return true if user==nil || user.site == nil | |||
|
r217 | if user.contest_finished? | ||
flash[:notice] = 'Error: the contest you are participating is over.' | ||||
|
r162 | redirect_to :back | ||
return false | ||||
end | ||||
return true | ||||
end | ||||
r755 | def is_request_ip_allowed? | |||
r784 | unless GraderConfiguration[WHITELIST_IGNORE_CONF_KEY] | |||
r755 | user_ip = IPAddr.new(request.remote_ip) | |||
r796 | allowed = GraderConfiguration[WHITELIST_IP_CONF_KEY] || '' | |||
r784 | ||||
r796 | allowed.delete(' ').split(',').each do |ips| | |||
r755 | allow_ips = IPAddr.new(ips) | |||
r784 | if allow_ips.include?(user_ip) | |||
return true | ||||
r755 | end | |||
end | ||||
r784 | return false | |||
r755 | end | |||
return true | ||||
end | ||||
r788 | #function for datatable ajax query | |||
#return record,total_count,filter_count | ||||
def process_query_record(record, | ||||
r790 | total_count: nil, | |||
select: '', | ||||
global_search: [], | ||||
no_search: false, | ||||
force_order: '', | ||||
date_filter: '', date_param_since: 'date_since',date_param_until: 'date_until', | ||||
hard_limit: nil) | ||||
r788 | arel_table = record.model.arel_table | |||
if !no_search && params['search'] | ||||
global_value = record.model.sanitize_sql(params['search']['value'].strip.downcase) | ||||
if !global_value.blank? | ||||
global_value.split.each do |value| | ||||
global_where = global_search.map{|f| "LOWER(#{f}) like '%#{value}%'"}.join(' OR ') | ||||
record = record.where(global_where) | ||||
end | ||||
end | ||||
params['columns'].each do |i, col| | ||||
if !col['search']['value'].blank? | ||||
record = record.where(arel_table[col['name']].lower.matches("%#{col['search']['value'].strip.downcase}%")) | ||||
end | ||||
end | ||||
end | ||||
if !date_filter.blank? | ||||
r790 | param_since = params[date_param_since] | |||
param_until = params[date_param_until] | ||||
date_since = Time.zone.parse( param_since ) || Time.new(1,1,1) rescue Time.new(1,1,1) | ||||
date_until = Time.zone.parse( param_until ) || Time.zone.now() rescue Time.zone.now() | ||||
date_range = date_since..(date_until.end_of_day) | ||||
r788 | record = record.where(date_filter.to_sym => date_range) | |||
end | ||||
if force_order.blank? | ||||
if params['order'] | ||||
params['order'].each do |i, o| | ||||
colName = params['columns'][o['column']]['name'] | ||||
colName = "#{record.model.table_name}.#{colName}" if colName.upcase == 'ID' | ||||
record = record.order("#{colName} #{o['dir'].casecmp('desc') != 0 ? 'ASC' : 'DESC'}") unless colName.blank? | ||||
end | ||||
end | ||||
else | ||||
record = record.order(force_order) | ||||
end | ||||
filterCount = record.count(record.model.primary_key) | ||||
# if .group() is used, filterCount might be like {id_1: count_1, id_2: count_2, ...} | ||||
# so we should count the result again.. | ||||
if filterCount.is_a? Hash | ||||
filterCount = filterCount.count | ||||
end | ||||
r790 | ||||
record = record.offset(params['start'] || 0) | ||||
record = record.limit(hard_limit) | ||||
if (params['length']) | ||||
limit = params['length'].to_i | ||||
limit == hard_limit if (hard_limit && hard_limit < limit) | ||||
record = record.limit(limit) | ||||
end | ||||
r788 | if (!select.blank?) | |||
record = record.select(select) | ||||
end | ||||
return record, total_count || record.model.count, filterCount | ||||
end | ||||
|
r162 | end | ||