Description:
- fix ssl, we no longer check SSL for the API call to chula
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r585:0d6ca27c4e8d - - 4 files changed: 8 inserted, 7 deleted

@@ -18,321 +18,322
18 18 has_many :replied_messages,
19 19 :class_name => "Message",
20 20 :foreign_key => "receiver_id",
21 21 :order => 'created_at DESC'
22 22
23 23 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
24 24
25 25 belongs_to :site
26 26 belongs_to :country
27 27
28 28 has_and_belongs_to_many :contests, :uniq => true, :order => 'name'
29 29
30 30 scope :activated_users, :conditions => {:activated => true}
31 31
32 32 validates_presence_of :login
33 33 validates_uniqueness_of :login
34 34 validates_format_of :login, :with => /^[\_A-Za-z0-9]+$/
35 35 validates_length_of :login, :within => 3..30
36 36
37 37 validates_presence_of :full_name
38 38 validates_length_of :full_name, :minimum => 1
39 39
40 40 validates_presence_of :password, :if => :password_required?
41 41 validates_length_of :password, :within => 4..20, :if => :password_required?
42 42 validates_confirmation_of :password, :if => :password_required?
43 43
44 44 validates_format_of :email,
45 45 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
46 46 :if => :email_validation?
47 47 validate :uniqueness_of_email_from_activated_users,
48 48 :if => :email_validation?
49 49 validate :enough_time_interval_between_same_email_registrations,
50 50 :if => :email_validation?
51 51
52 52 # these are for ytopc
53 53 # disable for now
54 54 #validates_presence_of :province
55 55
56 56 attr_accessor :password
57 57
58 58 before_save :encrypt_new_password
59 59 before_save :assign_default_site
60 60 before_save :assign_default_contest
61 61
62 62 # this is for will_paginate
63 63 cattr_reader :per_page
64 64 @@per_page = 50
65 65
66 66 def self.authenticate(login, password)
67 67 user = find_by_login(login)
68 68 if user
69 69 return user if user.authenticated?(password)
70 70 if user.authenticated_by_cucas?(password) or user.authenticated_by_pop3?(password)
71 71 user.password = password
72 72 user.save
73 73 return user
74 74 end
75 75 end
76 76 end
77 77
78 78 def authenticated?(password)
79 79 if self.activated
80 80 hashed_password == User.encrypt(password,self.salt)
81 81 else
82 82 false
83 83 end
84 84 end
85 85
86 86 def authenticated_by_pop3?(password)
87 87 Net::POP3.enable_ssl
88 88 pop = Net::POP3.new('pops.it.chula.ac.th')
89 89 authen = true
90 90 begin
91 91 pop.start(login, password)
92 92 pop.finish
93 93 return true
94 94 rescue
95 95 return false
96 96 end
97 97 end
98 98
99 99 def authenticated_by_cucas?(password)
100 100 url = URI.parse('https://www.cas.chula.ac.th/cas/api/?q=studentAuthenticate')
101 101 appid = '41508763e340d5858c00f8c1a0f5a2bb'
102 102 appsecret ='d9cbb5863091dbe186fded85722a1e31'
103 103 post_args = {
104 104 'appid' => appid,
105 105 'appsecret' => appsecret,
106 106 'username' => login,
107 107 'password' => password
108 108 }
109 109
110 110 #simple call
111 111 begin
112 112 http = Net::HTTP.new('www.cas.chula.ac.th', 443)
113 113 http.use_ssl = true
114 + http.verify_mode = OpenSSL::SSL::VERIFY_NONE
114 115 result = [ ]
115 116 http.start do |http|
116 117 req = Net::HTTP::Post.new('/cas/api/?q=studentAuthenticate')
117 118 param = "appid=#{appid}&appsecret=#{appsecret}&username=#{login}&password=#{password}"
118 119 resp = http.request(req,param)
119 120 result = JSON.parse resp.body
120 121 end
121 122 return true if result["type"] == "beanStudent"
122 - rescue
123 + rescue => e
123 124 return false
124 125 end
125 126 return false
126 127 end
127 128
128 129 def admin?
129 130 self.roles.detect {|r| r.name == 'admin' }
130 131 end
131 132
132 133 def email_for_editing
133 134 if self.email==nil
134 135 "(unknown)"
135 136 elsif self.email==''
136 137 "(blank)"
137 138 else
138 139 self.email
139 140 end
140 141 end
141 142
142 143 def email_for_editing=(e)
143 144 self.email=e
144 145 end
145 146
146 147 def alias_for_editing
147 148 if self.alias==nil
148 149 "(unknown)"
149 150 elsif self.alias==''
150 151 "(blank)"
151 152 else
152 153 self.alias
153 154 end
154 155 end
155 156
156 157 def alias_for_editing=(e)
157 158 self.alias=e
158 159 end
159 160
160 161 def activation_key
161 162 if self.hashed_password==nil
162 163 encrypt_new_password
163 164 end
164 165 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
165 166 end
166 167
167 168 def verify_activation_key(key)
168 169 key == activation_key
169 170 end
170 171
171 172 def self.random_password(length=5)
172 173 chars = 'abcdefghjkmnopqrstuvwxyz'
173 174 password = ''
174 175 length.times { password << chars[rand(chars.length - 1)] }
175 176 password
176 177 end
177 178
178 179 def self.find_non_admin_with_prefix(prefix='')
179 180 users = User.find(:all)
180 181 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
181 182 end
182 183
183 184 # Contest information
184 185
185 186 def self.find_users_with_no_contest()
186 187 users = User.find(:all)
187 188 return users.find_all { |u| u.contests.length == 0 }
188 189 end
189 190
190 191
191 192 def contest_time_left
192 193 if GraderConfiguration.contest_mode?
193 194 return nil if site==nil
194 195 return site.time_left
195 196 elsif GraderConfiguration.indv_contest_mode?
196 197 time_limit = GraderConfiguration.contest_time_limit
197 198 if time_limit == nil
198 199 return nil
199 200 end
200 201 if contest_stat==nil or contest_stat.started_at==nil
201 202 return (Time.now.gmtime + time_limit) - Time.now.gmtime
202 203 else
203 204 finish_time = contest_stat.started_at + time_limit
204 205 current_time = Time.now.gmtime
205 206 if current_time > finish_time
206 207 return 0
207 208 else
208 209 return finish_time - current_time
209 210 end
210 211 end
211 212 else
212 213 return nil
213 214 end
214 215 end
215 216
216 217 def contest_finished?
217 218 if GraderConfiguration.contest_mode?
218 219 return false if site==nil
219 220 return site.finished?
220 221 elsif GraderConfiguration.indv_contest_mode?
221 222 return false if self.contest_stat(true)==nil
222 223 return contest_time_left == 0
223 224 else
224 225 return false
225 226 end
226 227 end
227 228
228 229 def contest_started?
229 230 if GraderConfiguration.indv_contest_mode?
230 231 stat = self.contest_stat
231 232 return ((stat != nil) and (stat.started_at != nil))
232 233 elsif GraderConfiguration.contest_mode?
233 234 return true if site==nil
234 235 return site.started
235 236 else
236 237 return true
237 238 end
238 239 end
239 240
240 241 def update_start_time
241 242 stat = self.contest_stat
242 - if (stat.nil?) or (stat.started_at.nil?)
243 + if stat.nil? or stat.started_at.nil?
243 244 stat ||= UserContestStat.new(:user => self)
244 245 stat.started_at = Time.now.gmtime
245 246 stat.save
246 247 end
247 248 end
248 249
249 250 def problem_in_user_contests?(problem)
250 251 problem_contests = problem.contests.all
251 252
252 253 if problem_contests.length == 0 # this is public contest
253 254 return true
254 255 end
255 256
256 257 contests.each do |contest|
257 258 if problem_contests.find {|c| c.id == contest.id }
258 259 return true
259 260 end
260 261 end
261 262 return false
262 263 end
263 264
264 265 def available_problems_group_by_contests
265 266 contest_problems = []
266 267 pin = {}
267 268 contests.enabled.each do |contest|
268 269 available_problems = contest.problems.available
269 270 contest_problems << {
270 271 :contest => contest,
271 272 :problems => available_problems
272 273 }
273 274 available_problems.each {|p| pin[p.id] = true}
274 275 end
275 276 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
276 277 contest_problems << {
277 278 :contest => nil,
278 279 :problems => other_avaiable_problems
279 280 }
280 281 return contest_problems
281 282 end
282 283
283 284 def available_problems
284 285 if not GraderConfiguration.multicontests?
285 286 return Problem.find_available_problems
286 287 else
287 288 contest_problems = []
288 289 pin = {}
289 290 contests.enabled.each do |contest|
290 291 contest.problems.available.each do |problem|
291 292 if not pin.has_key? problem.id
292 293 contest_problems << problem
293 294 end
294 295 pin[problem.id] = true
295 296 end
296 297 end
297 298 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
298 299 return contest_problems + other_avaiable_problems
299 300 end
300 301 end
301 302
302 303 def can_view_problem?(problem)
303 304 if not GraderConfiguration.multicontests?
304 305 return problem.available
305 306 else
306 307 return problem_in_user_contests? problem
307 308 end
308 309 end
309 310
310 311 def self.clear_last_login
311 312 User.update_all(:last_ip => nil)
312 313 end
313 314
314 315 protected
315 316 def encrypt_new_password
316 317 return if password.blank?
317 318 self.salt = (10+rand(90)).to_s
318 319 self.hashed_password = User.encrypt(self.password,self.salt)
319 320 end
320 321
321 322 def assign_default_site
322 323 # have to catch error when migrating (because self.site is not available).
323 324 begin
324 325 if self.site==nil
325 326 self.site = Site.find_by_name('default')
326 327 if self.site==nil
327 328 self.site = Site.find(1) # when 'default has be renamed'
328 329 end
329 330 end
330 331 rescue
331 332 end
332 333 end
333 334
334 335 def assign_default_contest
335 336 # have to catch error when migrating (because self.site is not available).
336 337 begin
337 338 if self.contests.length == 0
338 339 default_contest = Contest.find_by_name(GraderConfiguration['contest.default_contest_name'])
@@ -1,11 +1,11
1 1
2 2 %td= grader.host
3 3 %td= grader.pid
4 4 %td= grader.mode
5 - %td= grader.updated_at.strftime("%H:%M:%S") unless grader.updated_at.nil?
5 + %td= grader.updated_at.strftime("%H:%M:%S") if grader.updated_at
6 6 %td= grader.task_type
7 7 %td
8 - - if grader.task_id.nil?
8 + - unless grader.task_id
9 9 idle
10 10 - else
11 11 = link_to "#{grader.task_id}", :action => 'view', :id => grader.task_id, :type => grader.task_type
@@ -1,26 +1,26
1 1
2 2 - if submission.nil?
3 3 = "-"
4 4 - else
5 5 - if submission.graded_at.nil?
6 6 =t 'main.submitted_at'
7 7 = format_short_time(submission.submitted_at.localtime)
8 8 - else
9 9 = t 'main.graded_at'
10 10 = "#{format_short_time(submission.graded_at.localtime)}, "
11 11 - if GraderConfiguration['ui.show_score']
12 12 = t 'main.score'
13 13 = "#{(submission.points*100/submission.problem.full_score).to_i} "
14 14 = " ["
15 15 %tt
16 16 = submission.grader_comment
17 17 = "]"
18 18 - if GraderConfiguration.show_grading_result
19 19 = " | "
20 20 = link_to '[detailed result]', :action => 'result', :id => submission.id
21 21 = " | "
22 22 = link_to("[#{t 'main.cmp_msg'}]", {:action => 'compiler_msg', :id => submission.id}, {:popup => true})
23 23 = " | "
24 24 = link_to("[#{t 'main.src_link'}]",{:action => 'source', :id => submission.id})
25 - //= " | "
26 - //= link_to "[#{t 'main.submissions_link'}]", main_submission_path(submission.problem.id)
25 + = " | "
26 + = link_to "[#{t 'main.submissions_link'}]", :action => 'submission', :id => problem_name
@@ -1,61 +1,61
1 1 /- content_for :header do
2 2 / = javascript_include_tag 'local_jquery'
3 3 / = stylesheet_link_tag 'tablesorter-theme.cafe'
4 4
5 5 %script{:type=>"text/javascript"}
6 6 $(function () {
7 7 $('#since_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
8 8 $('#until_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
9 9 /$('#my_table').tablesorter({widgets: ['zebra']});
10 10 });
11 11
12 12 %h1 User grading results
13 13 %h2= params[:action] == 'user_stat' ? "Show scores from latest submission" : "Show max scores in submission range"
14 14
15 15
16 16 - if @problem and @problem.errors
17 17 =error_messages_for 'problem'
18 18
19 19 = render partial: 'submission_range'
20 20
21 21 - if params[:action] == 'user_stat'
22 22 %h3 Latest score
23 23 = link_to '[download csv with all problems]', controller: :user_admin, action: :user_stat, commit: 'download csv'
24 24 - else
25 25 %h3 Max score
26 26 = link_to '[Show only latest submissions]', controller: :user_admin, action: :user_stat
27 27 = link_to '[download csv with all problems]', controller: :user_admin, action: :user_stat_max, commit: 'download csv'
28 28
29 29 %table.table.sortable.table-striped.table-bordered
30 30 %thead
31 31 %tr
32 32 %th Login
33 33 %th Name
34 34 %th Activated?
35 35 %th Logged_in
36 36 %th Contest(s)
37 37 %th Remark
38 38 - @problems.each do |p|
39 39 %th.text-right= p.name
40 40 %th.text-right Total
41 41 %th.text-right Passed
42 42 %tbody
43 43 - @scorearray.each do |sc|
44 44 %tr
45 45 - total,num_passed = 0,0
46 46 - sc.each_index do |i|
47 47 - if i == 0
48 48 %td= link_to sc[i].login, controller: 'users', action: 'profile', id: sc[i]
49 49 %td= sc[i].full_name
50 50 %td= sc[i].activated
51 - %td= sc[i].try(:contest_stat).try(:started_at)!=nil ? 'yes' : 'no'
51 + %td= sc[i].try(:contest_stat).try(:started_at) ? 'yes' : 'no'
52 52 %td= sc[i].contests.collect {|c| c.name}.join(', ')
53 53 %td= sc[i].remark
54 54 - else
55 55 %td.text-right= sc[i][0]
56 56 - total += sc[i][0]
57 57 - num_passed += 1 if sc[i][1]
58 58 %td.text-right= total
59 59 %td.text-right= num_passed
60 60 :javascript
61 61 $.bootstrapSortable(true,'reversed')
You need to be logged in to leave comments. Login now