Description:
fig bugs in login report
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r858:21c0ea2ca2c0 - - 2 files changed: 7 inserted, 6 deleted

@@ -1,172 +1,170
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 74 end
75 - puts "encrypt " + cookies.encrypted[:uuid]
76 - puts cookies[:uuid]
77 75 end
78 76
79 77 protected
80 78
81 79 #redirect to root (and also force logout)
82 80 #if the user is not logged_in or the system is in "ADMIN ONLY" mode
83 81 def check_valid_login
84 82 #check if logged in
85 83 unless session[:user_id]
86 84 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
87 85 unauthorized_redirect('You need to login but you cannot log in at this time')
88 86 else
89 87 unauthorized_redirect('You need to login')
90 88 end
91 89 return false
92 90 end
93 91
94 92 # check if run in single user mode
95 93 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
96 94 if @current_user==nil || (!@current_user.admin?)
97 95 unauthorized_redirect('You cannot log in at this time')
98 96 return false
99 97 end
100 98 end
101 99
102 100 # check if the user is enabled
103 101 unless @current_user.enabled? || @current_user.admin?
104 102 unauthorized_redirect 'Your account is disabled'
105 103 return false
106 104 end
107 105
108 106 # check if user ip is allowed
109 107 unless @current_user.admin? || GraderConfiguration[WHITELIST_IGNORE_CONF_KEY]
110 108 unless is_request_ip_allowed?
111 109 unauthorized_redirect 'Your IP is not allowed to login at this time.'
112 110 return false
113 111 end
114 112 end
115 113
116 114 if GraderConfiguration.multicontests?
117 115 return true if @current_user.admin?
118 116 begin
119 117 if @current_user.contest_stat(true).forced_logout
120 118 flash[:notice] = 'You have been automatically logged out.'
121 119 redirect_to :controller => 'main', :action => 'index'
122 120 end
123 121 rescue
124 122 end
125 123 end
126 124 return true
127 125 end
128 126
129 127 #redirect to root (and also force logout)
130 128 #if the user use different ip from the previous connection
131 129 # only applicable when MULTIPLE_IP_LOGIN options is false only
132 130 def authenticate_by_ip_address
133 131 #this assume that we have already authenticate normally
134 132 unless GraderConfiguration[MULTIPLE_IP_LOGIN_CONF_KEY]
135 133 user = User.find(session[:user_id])
136 134 if (!user.admin? && user.last_ip && user.last_ip != request.remote_ip)
137 135 flash[:notice] = "You cannot use the system from #{request.remote_ip}. Your last ip is #{user.last_ip}"
138 136 redirect_to :controller => 'main', :action => 'login'
139 137 return false
140 138 end
141 139 unless user.last_ip
142 140 user.last_ip = request.remote_ip
143 141 user.save
144 142 end
145 143 end
146 144 return true
147 145 end
148 146
149 147 def authorization
150 148 return false unless check_valid_login
151 149 user = User.find(session[:user_id])
152 150 unless user.roles.detect { |role|
153 151 role.rights.detect{ |right|
154 152 right.controller == self.class.controller_name and
155 153 (right.action == 'all' || right.action == action_name)
156 154 }
157 155 }
158 156 flash[:notice] = 'You are not authorized to view the page you requested'
159 157 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
160 158 redirect_to :controller => 'main', :action => 'login'
161 159 return false
162 160 end
163 161 end
164 162
165 163 def verify_time_limit
166 164 return true if session[:user_id]==nil
167 165 user = User.find(session[:user_id], :include => :site)
168 166 return true if user==nil || user.site == nil
169 167 if user.contest_finished?
170 168 flash[:notice] = 'Error: the contest you are participating is over.'
171 169 redirect_to :back
172 170 return false
@@ -26,236 +26,239
26 26 @users = User.includes(:contests).includes(:contest_stat).where(enabled: true)
27 27 end
28 28 @scorearray = calculate_max_score(@problems, @users,0,0,true)
29 29
30 30 #rencer accordingly
31 31 if params[:button] == 'download' then
32 32 csv = gen_csv_from_scorearray(@scorearray,@problems)
33 33 send_data csv, filename: 'max_score.csv'
34 34 else
35 35 #render template: 'user_admin/user_stat'
36 36 render 'current_score'
37 37 end
38 38 end
39 39
40 40 def show_max_score
41 41 #process parameters
42 42 #problems
43 43 @problems = []
44 44 if params[:problem_id]
45 45 params[:problem_id].each do |id|
46 46 next unless id.strip != ""
47 47 pid = Problem.find_by_id(id.to_i)
48 48 @problems << pid if pid
49 49 end
50 50 end
51 51
52 52 #users
53 53 @users = if params[:users] == "group" then
54 54 Group.find(params[:group_id]).users.all
55 55 elsif params[:users] == 'enabled'
56 56 User.includes(:contests).includes(:contest_stat).where(enabled: true)
57 57 else
58 58 User.includes(:contests).includes(:contest_stat)
59 59 end
60 60
61 61 #set up range from param
62 62 @since_id = params.fetch(:from_id, 0).to_i
63 63 @until_id = params.fetch(:to_id, 0).to_i
64 64 @since_id = nil if @since_id == 0
65 65 @until_id = nil if @until_id == 0
66 66
67 67 #calculate the routine
68 68 @scorearray = calculate_max_score(@problems, @users, @since_id, @until_id)
69 69
70 70 #rencer accordingly
71 71 if params[:button] == 'download' then
72 72 csv = gen_csv_from_scorearray(@scorearray,@problems)
73 73 send_data csv, filename: 'max_score.csv'
74 74 else
75 75 #render template: 'user_admin/user_stat'
76 76 render 'max_score'
77 77 end
78 78
79 79 end
80 80
81 81 def score
82 82 if params[:commit] == 'download csv'
83 83 @problems = Problem.all
84 84 else
85 85 @problems = Problem.available_problems
86 86 end
87 87 @users = User.includes(:contests, :contest_stat).where(enabled: true)
88 88 @scorearray = Array.new
89 89 @users.each do |u|
90 90 ustat = Array.new
91 91 ustat[0] = u
92 92 @problems.each do |p|
93 93 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
94 94 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
95 95 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
96 96 else
97 97 ustat << [0,false]
98 98 end
99 99 end
100 100 @scorearray << ustat
101 101 end
102 102 if params[:commit] == 'download csv' then
103 103 csv = gen_csv_from_scorearray(@scorearray,@problems)
104 104 send_data csv, filename: 'last_score.csv'
105 105 else
106 106 render template: 'user_admin/user_stat'
107 107 end
108 108
109 109 end
110 110
111 111 def login
112 112 end
113 113
114 114 def login_summary_query
115 115 @users = Array.new
116 116
117 117 date_and_time = '%Y-%m-%d %H:%M'
118 118 begin
119 119 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
120 120 @since_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
121 121 rescue
122 - @since_time = DateTime.new(1000,1,1)
122 + @since_time = Time.zone.now
123 123 end
124 + puts @since_time
124 125 begin
125 126 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
126 127 @until_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
127 128 rescue
128 129 @until_time = DateTime.new(3000,1,1)
129 130 end
130 131
131 132 record = User
132 133 .left_outer_joins(:logins).group('users.id')
133 134 .where("logins.created_at >= ? AND logins.created_at <= ?",@since_time, @until_time)
134 135 case params[:users]
135 136 when 'enabled'
136 137 record = record.where(enabled: true)
137 138 when 'group'
138 139 record = record.joins(:groups).where(groups: {id: params[:groups]}) if params[:groups]
139 140 end
140 141
141 142 record = record.pluck("users.id,users.login,users.full_name,count(logins.created_at),min(logins.created_at),max(logins.created_at)")
142 143 record.each do |user|
143 144 x = Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
144 145 user[0],@since_time,@until_time)
145 146 .pluck(:ip_address).uniq
147 + puts user[4]
148 + puts user[5]
146 149 @users << { id: user[0],
147 150 login: user[1],
148 151 full_name: user[2],
149 152 count: user[3],
150 - min: user[4],
151 - max: user[5],
153 + min: user[4].in_time_zone,
154 + max: user[5].in_time_zone,
152 155 ip: x
153 156 }
154 157 end
155 158 end
156 159
157 160 def login_detail_query
158 161 @logins = Array.new
159 162
160 163 date_and_time = '%Y-%m-%d %H:%M'
161 164 begin
162 165 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
163 166 @since_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
164 167 rescue
165 - @since_time = DateTime.new(1000,1,1)
168 + @since_time = Time.zone.now
166 169 end
167 170 begin
168 171 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
169 172 @until_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
170 173 rescue
171 174 @until_time = DateTime.new(3000,1,1)
172 175 end
173 176
174 177 @logins = Login.includes(:user).where("logins.created_at >= ? AND logins.created_at <= ?",@since_time, @until_time)
175 178 case params[:users]
176 179 when 'enabled'
177 180 @logins = @logins.where(users: {enabled: true})
178 181 when 'group'
179 182 @logins = @logins.joins(user: :groups).where(user: {groups: {id: params[:groups]}}) if params[:groups]
180 183 end
181 184 end
182 185
183 186 def submission
184 187 end
185 188
186 189 def submission_query
187 190 @submissions = Submission
188 191 .includes(:problem).includes(:user).includes(:language)
189 192
190 193 case params[:users]
191 194 when 'enabled'
192 195 @submissions = @submissions.where(users: {enabled: true})
193 196 when 'group'
194 197 @submissions = @submissions.joins(user: :groups).where(user: {groups: {id: params[:groups]}}) if params[:groups]
195 198 end
196 199
197 200 case params[:problems]
198 201 when 'enabled'
199 202 @submissions = @submissions.where(problems: {available: true})
200 203 when 'selected'
201 204 @submissions = @submissions.where(problem_id: params[:problem_id])
202 205 end
203 206
204 207 #set default
205 208 params[:since_datetime] = Date.today.to_s if params[:since_datetime].blank?
206 209
207 210 @submissions, @recordsTotal, @recordsFiltered = process_query_record( @submissions,
208 211 global_search: ['user.login','user.full_name','problem.name','problem.full_name','points'],
209 212 date_filter: 'submitted_at',
210 213 date_param_since: 'since_datetime',
211 214 date_param_until: 'until_datetime',
212 215 hard_limit: 100_000
213 216 )
214 217 end
215 218
216 219 def login
217 220 end
218 221
219 222 def problem_hof
220 223 # gen problem list
221 224 @user = User.find(session[:user_id])
222 225 @problems = @user.available_problems
223 226
224 227 # get selected problems or the default
225 228 if params[:id]
226 229 begin
227 230 @problem = Problem.available.find(params[:id])
228 231 rescue
229 232 redirect_to action: :problem_hof
230 233 flash[:notice] = 'Error: submissions for that problem are not viewable.'
231 234 return
232 235 end
233 236 end
234 237
235 238 return unless @problem
236 239
237 240 #model submisssion
238 241 @model_subs = Submission.where(problem: @problem,tag: Submission.tags[:model])
239 242
240 243
241 244 #calculate best submission
242 245 @by_lang = {} #aggregrate by language
243 246
244 247 range =65
245 248 #@histogram = { data: Array.new(range,0), summary: {} }
246 249 @summary = {count: 0, solve: 0, attempt: 0}
247 250 user = Hash.new(0)
248 251 Submission.where(problem_id: @problem.id).find_each do |sub|
249 252 #histogram
250 253 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
251 254 #@histogram[:data][d.to_i] += 1 if d < range
252 255
253 256 next unless sub.points
254 257 @summary[:count] += 1
255 258 user[sub.user_id] = [user[sub.user_id], (sub.points >= @problem.full_score) ? 1 : 0].max
256 259
257 260 lang = Language.find_by_id(sub.language_id)
258 261 next unless lang
259 262 next unless sub.points >= @problem.full_score
260 263
261 264 #initialize
You need to be logged in to leave comments. Login now