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

r883:327f656f4545 - - 1 file changed: 6 inserted, 3 deleted

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