Description:
use uuid cookie
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r852:41c96ab8e589 - - 2 files changed: 19 inserted, 1 deleted

@@ -1,243 +1,251
1 require 'ipaddr'
1 require 'ipaddr'
2 + require "securerandom"
2
3
3 class ApplicationController < ActionController::Base
4 class ApplicationController < ActionController::Base
4 protect_from_forgery
5 protect_from_forgery
5
6
6 before_action :current_user
7 before_action :current_user
7 before_action :nav_announcement
8 before_action :nav_announcement
9 + before_action :unique_visitor_id
8
10
9 SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode'
11 SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode'
10 MULTIPLE_IP_LOGIN_CONF_KEY = 'right.multiple_ip_login'
12 MULTIPLE_IP_LOGIN_CONF_KEY = 'right.multiple_ip_login'
11 WHITELIST_IGNORE_CONF_KEY = 'right.whitelist_ignore'
13 WHITELIST_IGNORE_CONF_KEY = 'right.whitelist_ignore'
12 WHITELIST_IP_CONF_KEY = 'right.whitelist_ip'
14 WHITELIST_IP_CONF_KEY = 'right.whitelist_ip'
13
15
14 #report and redirect for unauthorized activities
16 #report and redirect for unauthorized activities
15 def unauthorized_redirect(notice = 'You are not authorized to view the page you requested')
17 def unauthorized_redirect(notice = 'You are not authorized to view the page you requested')
16 flash[:notice] = notice
18 flash[:notice] = notice
17 redirect_to login_main_path
19 redirect_to login_main_path
18 end
20 end
19
21
20 # Returns the current logged-in user (if any).
22 # Returns the current logged-in user (if any).
21 def current_user
23 def current_user
22 return nil unless session[:user_id]
24 return nil unless session[:user_id]
23 @current_user ||= User.find(session[:user_id])
25 @current_user ||= User.find(session[:user_id])
24 end
26 end
25
27
26 def nav_announcement
28 def nav_announcement
27 @nav_announcement = Announcement.where(on_nav_bar: true)
29 @nav_announcement = Announcement.where(on_nav_bar: true)
28 end
30 end
29
31
30 def admin_authorization
32 def admin_authorization
31 return false unless check_valid_login
33 return false unless check_valid_login
32 user = User.includes(:roles).find(session[:user_id])
34 user = User.includes(:roles).find(session[:user_id])
33 unless user.admin?
35 unless user.admin?
34 unauthorized_redirect
36 unauthorized_redirect
35 return false
37 return false
36 end
38 end
37 return true
39 return true
38 end
40 end
39
41
40 def authorization_by_roles(allowed_roles)
42 def authorization_by_roles(allowed_roles)
41 return false unless check_valid_login
43 return false unless check_valid_login
42 unless @current_user.roles.detect { |role| allowed_roles.member?(role.name) }
44 unless @current_user.roles.detect { |role| allowed_roles.member?(role.name) }
43 unauthorized_redirect
45 unauthorized_redirect
44 return false
46 return false
45 end
47 end
46 end
48 end
47
49
48 def testcase_authorization
50 def testcase_authorization
49 #admin always has privileged
51 #admin always has privileged
50 if @current_user.admin?
52 if @current_user.admin?
51 return true
53 return true
52 end
54 end
53
55
54 unauthorized_redirect unless GraderConfiguration["right.view_testcase"]
56 unauthorized_redirect unless GraderConfiguration["right.view_testcase"]
55 end
57 end
56
58
59 + def unique_visitor_id
60 + unless cookies[:uuid]
61 + value = SecureRandom.uuid
62 + cookies[:uuid] = { value: value, expires: 20.year }
63 + end
64 + end
57
65
58 protected
66 protected
59
67
60 #redirect to root (and also force logout)
68 #redirect to root (and also force logout)
61 #if the user is not logged_in or the system is in "ADMIN ONLY" mode
69 #if the user is not logged_in or the system is in "ADMIN ONLY" mode
62 def check_valid_login
70 def check_valid_login
63 #check if logged in
71 #check if logged in
64 unless session[:user_id]
72 unless session[:user_id]
65 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
73 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
66 unauthorized_redirect('You need to login but you cannot log in at this time')
74 unauthorized_redirect('You need to login but you cannot log in at this time')
67 else
75 else
68 unauthorized_redirect('You need to login')
76 unauthorized_redirect('You need to login')
69 end
77 end
70 return false
78 return false
71 end
79 end
72
80
73 # check if run in single user mode
81 # check if run in single user mode
74 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
82 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
75 if @current_user==nil || (!@current_user.admin?)
83 if @current_user==nil || (!@current_user.admin?)
76 unauthorized_redirect('You cannot log in at this time')
84 unauthorized_redirect('You cannot log in at this time')
77 return false
85 return false
78 end
86 end
79 end
87 end
80
88
81 # check if the user is enabled
89 # check if the user is enabled
82 unless @current_user.enabled? || @current_user.admin?
90 unless @current_user.enabled? || @current_user.admin?
83 unauthorized_redirect 'Your account is disabled'
91 unauthorized_redirect 'Your account is disabled'
84 return false
92 return false
85 end
93 end
86
94
87 # check if user ip is allowed
95 # check if user ip is allowed
88 unless @current_user.admin? || GraderConfiguration[WHITELIST_IGNORE_CONF_KEY]
96 unless @current_user.admin? || GraderConfiguration[WHITELIST_IGNORE_CONF_KEY]
89 unless is_request_ip_allowed?
97 unless is_request_ip_allowed?
90 unauthorized_redirect 'Your IP is not allowed to login at this time.'
98 unauthorized_redirect 'Your IP is not allowed to login at this time.'
91 return false
99 return false
92 end
100 end
93 end
101 end
94
102
95 if GraderConfiguration.multicontests?
103 if GraderConfiguration.multicontests?
96 return true if @current_user.admin?
104 return true if @current_user.admin?
97 begin
105 begin
98 if @current_user.contest_stat(true).forced_logout
106 if @current_user.contest_stat(true).forced_logout
99 flash[:notice] = 'You have been automatically logged out.'
107 flash[:notice] = 'You have been automatically logged out.'
100 redirect_to :controller => 'main', :action => 'index'
108 redirect_to :controller => 'main', :action => 'index'
101 end
109 end
102 rescue
110 rescue
103 end
111 end
104 end
112 end
105 return true
113 return true
106 end
114 end
107
115
108 #redirect to root (and also force logout)
116 #redirect to root (and also force logout)
109 #if the user use different ip from the previous connection
117 #if the user use different ip from the previous connection
110 # only applicable when MULTIPLE_IP_LOGIN options is false only
118 # only applicable when MULTIPLE_IP_LOGIN options is false only
111 def authenticate_by_ip_address
119 def authenticate_by_ip_address
112 #this assume that we have already authenticate normally
120 #this assume that we have already authenticate normally
113 unless GraderConfiguration[MULTIPLE_IP_LOGIN_CONF_KEY]
121 unless GraderConfiguration[MULTIPLE_IP_LOGIN_CONF_KEY]
114 user = User.find(session[:user_id])
122 user = User.find(session[:user_id])
115 if (!user.admin? && user.last_ip && user.last_ip != request.remote_ip)
123 if (!user.admin? && user.last_ip && user.last_ip != request.remote_ip)
116 flash[:notice] = "You cannot use the system from #{request.remote_ip}. Your last ip is #{user.last_ip}"
124 flash[:notice] = "You cannot use the system from #{request.remote_ip}. Your last ip is #{user.last_ip}"
117 redirect_to :controller => 'main', :action => 'login'
125 redirect_to :controller => 'main', :action => 'login'
118 return false
126 return false
119 end
127 end
120 unless user.last_ip
128 unless user.last_ip
121 user.last_ip = request.remote_ip
129 user.last_ip = request.remote_ip
122 user.save
130 user.save
123 end
131 end
124 end
132 end
125 return true
133 return true
126 end
134 end
127
135
128 def authorization
136 def authorization
129 return false unless check_valid_login
137 return false unless check_valid_login
130 user = User.find(session[:user_id])
138 user = User.find(session[:user_id])
131 unless user.roles.detect { |role|
139 unless user.roles.detect { |role|
132 role.rights.detect{ |right|
140 role.rights.detect{ |right|
133 right.controller == self.class.controller_name and
141 right.controller == self.class.controller_name and
134 (right.action == 'all' || right.action == action_name)
142 (right.action == 'all' || right.action == action_name)
135 }
143 }
136 }
144 }
137 flash[:notice] = 'You are not authorized to view the page you requested'
145 flash[:notice] = 'You are not authorized to view the page you requested'
138 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
146 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
139 redirect_to :controller => 'main', :action => 'login'
147 redirect_to :controller => 'main', :action => 'login'
140 return false
148 return false
141 end
149 end
142 end
150 end
143
151
144 def verify_time_limit
152 def verify_time_limit
145 return true if session[:user_id]==nil
153 return true if session[:user_id]==nil
146 user = User.find(session[:user_id], :include => :site)
154 user = User.find(session[:user_id], :include => :site)
147 return true if user==nil || user.site == nil
155 return true if user==nil || user.site == nil
148 if user.contest_finished?
156 if user.contest_finished?
149 flash[:notice] = 'Error: the contest you are participating is over.'
157 flash[:notice] = 'Error: the contest you are participating is over.'
150 redirect_to :back
158 redirect_to :back
151 return false
159 return false
152 end
160 end
153 return true
161 return true
154 end
162 end
155
163
156 def is_request_ip_allowed?
164 def is_request_ip_allowed?
157 unless GraderConfiguration[WHITELIST_IGNORE_CONF_KEY]
165 unless GraderConfiguration[WHITELIST_IGNORE_CONF_KEY]
158 user_ip = IPAddr.new(request.remote_ip)
166 user_ip = IPAddr.new(request.remote_ip)
159 allowed = GraderConfiguration[WHITELIST_IP_CONF_KEY] || ''
167 allowed = GraderConfiguration[WHITELIST_IP_CONF_KEY] || ''
160
168
161 allowed.delete(' ').split(',').each do |ips|
169 allowed.delete(' ').split(',').each do |ips|
162 allow_ips = IPAddr.new(ips)
170 allow_ips = IPAddr.new(ips)
163 if allow_ips.include?(user_ip)
171 if allow_ips.include?(user_ip)
164 return true
172 return true
165 end
173 end
166 end
174 end
167 return false
175 return false
168 end
176 end
169 return true
177 return true
170 end
178 end
171
179
172 #function for datatable ajax query
180 #function for datatable ajax query
173 #return record,total_count,filter_count
181 #return record,total_count,filter_count
174 def process_query_record(record,
182 def process_query_record(record,
175 total_count: nil,
183 total_count: nil,
176 select: '',
184 select: '',
177 global_search: [],
185 global_search: [],
178 no_search: false,
186 no_search: false,
179 force_order: '',
187 force_order: '',
180 date_filter: '', date_param_since: 'date_since',date_param_until: 'date_until',
188 date_filter: '', date_param_since: 'date_since',date_param_until: 'date_until',
181 hard_limit: nil)
189 hard_limit: nil)
182 arel_table = record.model.arel_table
190 arel_table = record.model.arel_table
183
191
184 if !no_search && params['search']
192 if !no_search && params['search']
185 global_value = record.model.sanitize_sql(params['search']['value'].strip.downcase)
193 global_value = record.model.sanitize_sql(params['search']['value'].strip.downcase)
186 if !global_value.blank?
194 if !global_value.blank?
187 global_value.split.each do |value|
195 global_value.split.each do |value|
188 global_where = global_search.map{|f| "LOWER(#{f}) like '%#{value}%'"}.join(' OR ')
196 global_where = global_search.map{|f| "LOWER(#{f}) like '%#{value}%'"}.join(' OR ')
189 record = record.where(global_where)
197 record = record.where(global_where)
190 end
198 end
191 end
199 end
192
200
193 params['columns'].each do |i, col|
201 params['columns'].each do |i, col|
194 if !col['search']['value'].blank?
202 if !col['search']['value'].blank?
195 record = record.where(arel_table[col['name']].lower.matches("%#{col['search']['value'].strip.downcase}%"))
203 record = record.where(arel_table[col['name']].lower.matches("%#{col['search']['value'].strip.downcase}%"))
196 end
204 end
197 end
205 end
198 end
206 end
199
207
200 if !date_filter.blank?
208 if !date_filter.blank?
201 param_since = params[date_param_since]
209 param_since = params[date_param_since]
202 param_until = params[date_param_until]
210 param_until = params[date_param_until]
203 date_since = Time.zone.parse( param_since ) || Time.new(1,1,1) rescue Time.new(1,1,1)
211 date_since = Time.zone.parse( param_since ) || Time.new(1,1,1) rescue Time.new(1,1,1)
204 date_until = Time.zone.parse( param_until ) || Time.zone.now() rescue Time.zone.now()
212 date_until = Time.zone.parse( param_until ) || Time.zone.now() rescue Time.zone.now()
205 date_range = date_since..(date_until.end_of_day)
213 date_range = date_since..(date_until.end_of_day)
206 record = record.where(date_filter.to_sym => date_range)
214 record = record.where(date_filter.to_sym => date_range)
207 end
215 end
208
216
209 if force_order.blank?
217 if force_order.blank?
210 if params['order']
218 if params['order']
211 params['order'].each do |i, o|
219 params['order'].each do |i, o|
212 colName = params['columns'][o['column']]['name']
220 colName = params['columns'][o['column']]['name']
213 colName = "#{record.model.table_name}.#{colName}" if colName.upcase == 'ID'
221 colName = "#{record.model.table_name}.#{colName}" if colName.upcase == 'ID'
214 record = record.order("#{colName} #{o['dir'].casecmp('desc') != 0 ? 'ASC' : 'DESC'}") unless colName.blank?
222 record = record.order("#{colName} #{o['dir'].casecmp('desc') != 0 ? 'ASC' : 'DESC'}") unless colName.blank?
215 end
223 end
216 end
224 end
217 else
225 else
218 record = record.order(force_order)
226 record = record.order(force_order)
219 end
227 end
220
228
221 filterCount = record.count(record.model.primary_key)
229 filterCount = record.count(record.model.primary_key)
222 # if .group() is used, filterCount might be like {id_1: count_1, id_2: count_2, ...}
230 # if .group() is used, filterCount might be like {id_1: count_1, id_2: count_2, ...}
223 # so we should count the result again..
231 # so we should count the result again..
224 if filterCount.is_a? Hash
232 if filterCount.is_a? Hash
225 filterCount = filterCount.count
233 filterCount = filterCount.count
226 end
234 end
227
235
228
236
229 record = record.offset(params['start'] || 0)
237 record = record.offset(params['start'] || 0)
230 record = record.limit(hard_limit)
238 record = record.limit(hard_limit)
231 if (params['length'])
239 if (params['length'])
232 limit = params['length'].to_i
240 limit = params['length'].to_i
233 limit == hard_limit if (hard_limit && hard_limit < limit)
241 limit == hard_limit if (hard_limit && hard_limit < limit)
234 record = record.limit(limit)
242 record = record.limit(limit)
235 end
243 end
236 if (!select.blank?)
244 if (!select.blank?)
237 record = record.select(select)
245 record = record.select(select)
238 end
246 end
239
247
240 return record, total_count || record.model.count, filterCount
248 return record, total_count || record.model.count, filterCount
241 end
249 end
242
250
243 end
251 end
@@ -1,89 +1,99
1 class LoginController < ApplicationController
1 class LoginController < ApplicationController
2
2
3 @@authenticators = []
3 @@authenticators = []
4
4
5 def index
5 def index
6 # show login screen
6 # show login screen
7 reset_session
7 reset_session
8 redirect_to :controller => 'main', :action => 'login'
8 redirect_to :controller => 'main', :action => 'login'
9 end
9 end
10
10
11 def login
11 def login
12 user = get_authenticated_user(params[:login], params[:password])
12 user = get_authenticated_user(params[:login], params[:password])
13 unless user
13 unless user
14 flash[:notice] = 'Wrong password'
14 flash[:notice] = 'Wrong password'
15 redirect_to :controller => 'main', :action => 'login'
15 redirect_to :controller => 'main', :action => 'login'
16 return
16 return
17 end
17 end
18
18
19 if (!GraderConfiguration['right.bypass_agreement']) and (!params[:accept_agree]) and !user.admin?
19 if (!GraderConfiguration['right.bypass_agreement']) and (!params[:accept_agree]) and !user.admin?
20 flash[:notice] = 'You must accept the agreement before logging in'
20 flash[:notice] = 'You must accept the agreement before logging in'
21 redirect_to :controller => 'main', :action => 'login'
21 redirect_to :controller => 'main', :action => 'login'
22 return
22 return
23 end
23 end
24
24
25 + #store uuid when login
26 + if user.last_ip.nil?
27 + user.last_ip = cookies[:uuid]
28 + else
29 + if user.last_ip != cookies[:uuid]
30 + user.last_ip =cookies[:uuid]
31 + #log different login
32 + end
33 + end
34 +
25 #process logging in
35 #process logging in
26 session[:user_id] = user.id
36 session[:user_id] = user.id
27 session[:admin] = user.admin?
37 session[:admin] = user.admin?
28
38
29 # clear forced logout flag for multicontests contest change
39 # clear forced logout flag for multicontests contest change
30 if GraderConfiguration.multicontests?
40 if GraderConfiguration.multicontests?
31 contest_stat = user.contest_stat
41 contest_stat = user.contest_stat
32 if contest_stat.respond_to? :forced_logout
42 if contest_stat.respond_to? :forced_logout
33 if contest_stat.forced_logout
43 if contest_stat.forced_logout
34 contest_stat.forced_logout = false
44 contest_stat.forced_logout = false
35 contest_stat.save
45 contest_stat.save
36 end
46 end
37 end
47 end
38 end
48 end
39
49
40 #save login information
50 #save login information
41 - Login.create(user_id: user.id, ip_address: request.remote_ip)
51 + Login.create(user_id: user.id, ip_address: cookies[:uuid])
42
52
43 redirect_to :controller => 'main', :action => 'list'
53 redirect_to :controller => 'main', :action => 'list'
44 end
54 end
45
55
46 def site_login
56 def site_login
47 begin
57 begin
48 site = Site.find(params[:login][:site_id])
58 site = Site.find(params[:login][:site_id])
49 rescue ActiveRecord::RecordNotFound
59 rescue ActiveRecord::RecordNotFound
50 site = nil
60 site = nil
51 end
61 end
52 if site==nil
62 if site==nil
53 flash[:notice] = 'Wrong site'
63 flash[:notice] = 'Wrong site'
54 redirect_to :controller => 'main', :action => 'login' and return
64 redirect_to :controller => 'main', :action => 'login' and return
55 end
65 end
56 if (site.password) and (site.password == params[:login][:password])
66 if (site.password) and (site.password == params[:login][:password])
57 session[:site_id] = site.id
67 session[:site_id] = site.id
58 redirect_to :controller => 'site', :action => 'index'
68 redirect_to :controller => 'site', :action => 'index'
59 else
69 else
60 flash[:notice] = 'Wrong site password'
70 flash[:notice] = 'Wrong site password'
61 redirect_to :controller => 'site', :action => 'login'
71 redirect_to :controller => 'site', :action => 'login'
62 end
72 end
63 end
73 end
64
74
65 def logout
75 def logout
66 redirect_to root_path
76 redirect_to root_path
67 end
77 end
68
78
69 def self.add_authenticator(authenticator)
79 def self.add_authenticator(authenticator)
70 @@authenticators << authenticator
80 @@authenticators << authenticator
71 end
81 end
72
82
73 protected
83 protected
74
84
75 def get_authenticated_user(login, password)
85 def get_authenticated_user(login, password)
76 if @@authenticators.empty?
86 if @@authenticators.empty?
77 return User.authenticate(login, password)
87 return User.authenticate(login, password)
78 else
88 else
79 user = User.authenticate(login, password)
89 user = User.authenticate(login, password)
80 @@authenticators.each do |authenticator|
90 @@authenticators.each do |authenticator|
81 if not user
91 if not user
82 user = authenticator.authenticate(login, password)
92 user = authenticator.authenticate(login, password)
83 end
93 end
84 end
94 end
85 return user
95 return user
86 end
96 end
87 end
97 end
88
98
89 end
99 end
You need to be logged in to leave comments. Login now