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