Description:
add TA roles
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r799:584294790340 - - 6 files changed: 82 inserted, 53 deleted

@@ -1,112 +1,111
1 1 class SubmissionsController < ApplicationController
2 2 before_action :check_valid_login
3 3 before_action :submission_authorization, only: [:show, :download, :edit]
4 4 before_action :admin_authorization, only: [:rejudge]
5 5
6 6 # GET /submissions
7 7 # GET /submissions.json
8 8 # Show problem selection and user's submission of that problem
9 9 def index
10 10 @user = @current_user
11 11 @problems = @user.available_problems
12 12
13 13 if params[:problem_id]==nil
14 14 @problem = nil
15 15 @submissions = nil
16 16 else
17 17 @problem = Problem.find_by_id(params[:problem_id])
18 18 if (@problem == nil) or (not @problem.available)
19 19 redirect_to list_main_path
20 20 flash[:error] = 'Authorization error: You have no right to view submissions for this problem'
21 21 return
22 22 end
23 23 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id).order(id: :desc)
24 24 end
25 25 end
26 26
27 27 # GET /submissions/1
28 28 # GET /submissions/1.json
29 29 def show
30 30 @submission = Submission.find(params[:id])
31 31
32 32 #log the viewing
33 33 user = User.find(session[:user_id])
34 34 SubmissionViewLog.create(user_id: session[:user_id],submission_id: @submission.id) unless user.admin?
35 35
36 36 @task = @submission.task
37 37 end
38 38
39 39 def download
40 40 @submission = Submission.find(params[:id])
41 41 send_data(@submission.source, {:filename => @submission.download_filename, :type => 'text/plain'})
42 42 end
43 43
44 44 def compiler_msg
45 45 @submission = Submission.find(params[:id])
46 46 respond_to do |format|
47 47 format.js
48 48 end
49 49 end
50 50
51 51 #on-site new submission on specific problem
52 52 def direct_edit_problem
53 53 @problem = Problem.find(params[:problem_id])
54 54 unless @current_user.can_view_problem?(@problem)
55 55 unauthorized_redirect
56 56 return
57 57 end
58 58 @source = ''
59 59 if (params[:view_latest])
60 60 sub = Submission.find_last_by_user_and_problem(@current_user.id,@problem.id)
61 61 @source = @submission.source.to_s if @submission and @submission.source
62 62 end
63 63 render 'edit'
64 64 end
65 65
66 66 # GET /submissions/1/edit
67 67 def edit
68 68 @submission = Submission.find(params[:id])
69 69 @source = @submission.source.to_s
70 70 @problem = @submission.problem
71 71 @lang_id = @submission.language.id
72 72 end
73 73
74 74
75 75 def get_latest_submission_status
76 76 @problem = Problem.find(params[:pid])
77 77 @submission = Submission.find_last_by_user_and_problem(params[:uid],params[:pid])
78 78 respond_to do |format|
79 79 format.js
80 80 end
81 81 end
82 82
83 83 # GET /submissions/:id/rejudge
84 84 def rejudge
85 85 @submission = Submission.find(params[:id])
86 86 @task = @submission.task
87 87 @task.status_inqueue! if @task
88 88 respond_to do |format|
89 89 format.js
90 90 end
91 91 end
92 92
93 93 protected
94 94
95 95 def submission_authorization
96 96 #admin always has privileged
97 - if @current_user.admin?
98 - return true
99 - end
97 + return true if @current_user.admin?
98 + return true if @current_user.has_role?('TA') && (['show','download'].include? action_name)
100 99
101 100 sub = Submission.find(params[:id])
102 101 if @current_user.available_problems.include? sub.problem
103 102 return true if GraderConfiguration["right.user_view_submission"] or sub.user == @current_user
104 103 end
105 104
106 105 #default to NO
107 106 unauthorized_redirect
108 107 return false
109 108 end
110 109
111 110
112 111 end
@@ -1,631 +1,628
1 1 require 'csv'
2 2
3 3 class UserAdminController < ApplicationController
4 4
5 5 include MailHelperMethods
6 6
7 7 before_action :admin_authorization
8 8
9 9 def index
10 10 @user_count = User.count
11 11 if params[:page] == 'all'
12 12 @users = User.all
13 13 @paginated = false
14 14 else
15 15 @users = User.paginate :page => params[:page]
16 16 @paginated = true
17 17 end
18 18 @users = User.all
19 19 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
20 20 @contests = Contest.enabled
21 21 end
22 22
23 23 def active
24 24 sessions = ActiveRecord::SessionStore::Session.where("updated_at >= ?", 60.minutes.ago)
25 25 @users = []
26 26 sessions.each do |session|
27 27 if session.data[:user_id]
28 28 @users << User.find(session.data[:user_id])
29 29 end
30 30 end
31 31 end
32 32
33 33 def show
34 34 @user = User.find(params[:id])
35 35 end
36 36
37 37 def new
38 38 @user = User.new
39 39 end
40 40
41 41 def create
42 42 @user = User.new(user_params)
43 43 @user.activated = true
44 44 if @user.save
45 45 flash[:notice] = 'User was successfully created.'
46 46 redirect_to :action => 'index'
47 47 else
48 48 render :action => 'new'
49 49 end
50 50 end
51 51
52 52 def clear_last_ip
53 53 @user = User.find(params[:id])
54 54 @user.last_ip = nil
55 55 @user.save
56 56 redirect_to action: 'index', page: params[:page]
57 57 end
58 58
59 59 def create_from_list
60 60 lines = params[:user_list]
61 61
62 62 note = []
63 63 error_note = []
64 64 error_msg = nil
65 65 ok_user = []
66 66
67 67 lines.split("\n").each do |line|
68 68 #split with large limit, this will cause consecutive ',' to be result in a blank
69 69 items = line.chomp.split(',',1000)
70 70 if items.length>=2
71 71 login = items[0]
72 72 full_name = items[1]
73 73 remark =''
74 74 user_alias = ''
75 75
76 76 added_random_password = false
77 77 added_password = false
78 78 if items.length >= 3
79 79 if items[2].chomp(" ").length > 0
80 80 password = items[2].chomp(" ")
81 81 added_password = true
82 82 end
83 83 else
84 84 password = random_password
85 85 added_random_password=true;
86 86 end
87 87
88 88 if items.length>= 4 and items[3].chomp(" ").length > 0;
89 89 user_alias = items[3].chomp(" ")
90 90 else
91 91 user_alias = login
92 92 end
93 93
94 94
95 95 has_remark = false
96 96 if items.length>=5
97 97 remark = items[4].strip;
98 98 has_remark = true
99 99 end
100 100
101 101 user = User.find_by_login(login)
102 102 if (user)
103 103 user.full_name = full_name
104 104 user.remark = remark if has_remark
105 105 user.password = password if added_password || added_random_password
106 106 else
107 107 #create a random password if none are given
108 108 password = random_password unless password
109 109 user = User.new({:login => login,
110 110 :full_name => full_name,
111 111 :password => password,
112 112 :password_confirmation => password,
113 113 :alias => user_alias,
114 114 :remark => remark})
115 115 end
116 116 user.activated = true
117 117
118 118 if user.save
119 119 if added_random_password
120 120 note << "'#{login}' (+)"
121 121 else
122 122 note << login
123 123 end
124 124 ok_user << user
125 125 else
126 126 error_note << "'#{login}'"
127 127 error_msg = user.errors.full_messages.to_sentence unless error_msg
128 128 end
129 129
130 130 end
131 131 end
132 132
133 133 #add to group
134 134 if params[:add_to_group]
135 135 group = Group.where(id: params[:group_id]).first
136 136 if group
137 137 group.users << ok_user
138 138 end
139 139 end
140 140
141 141 # show flash
142 142 if note.size > 0
143 143 flash[:success] = 'User(s) ' + note.join(', ') +
144 144 ' were successfully created. ' +
145 145 '( (+) - created with random passwords.)'
146 146 end
147 147 if error_note.size > 0
148 148 flash[:error] = "Following user(s) failed to be created: " + error_note.join(', ') + ". The error of the first failed one are: " + error_msg;
149 149 end
150 150 redirect_to :action => 'index'
151 151 end
152 152
153 153 def edit
154 154 @user = User.find(params[:id])
155 155 end
156 156
157 157 def update
158 158 @user = User.find(params[:id])
159 159 if @user.update_attributes(user_params)
160 160 flash[:notice] = 'User was successfully updated.'
161 161 redirect_to :action => 'show', :id => @user
162 162 else
163 163 render :action => 'edit'
164 164 end
165 165 end
166 166
167 167 def destroy
168 168 User.find(params[:id]).destroy
169 169 redirect_to :action => 'index'
170 170 end
171 171
172 172 def user_stat
173 173 if params[:commit] == 'download csv'
174 174 @problems = Problem.all
175 175 else
176 176 @problems = Problem.available_problems
177 177 end
178 178 @users = User.includes(:contests, :contest_stat).where(enabled: true)
179 179 @scorearray = Array.new
180 180 @users.each do |u|
181 181 ustat = Array.new
182 182 ustat[0] = u
183 183 @problems.each do |p|
184 184 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
185 185 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
186 186 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
187 187 else
188 188 ustat << [0,false]
189 189 end
190 190 end
191 191 @scorearray << ustat
192 192 end
193 193 if params[:commit] == 'download csv' then
194 194 csv = gen_csv_from_scorearray(@scorearray,@problems)
195 195 send_data csv, filename: 'last_score.csv'
196 196 else
197 197 render template: 'user_admin/user_stat'
198 198 end
199 199 end
200 200
201 201 def user_stat_max
202 202 if params[:commit] == 'download csv'
203 203 @problems = Problem.all
204 204 else
205 205 @problems = Problem.available_problems
206 206 end
207 207 @users = User.includes(:contests).includes(:contest_stat).all
208 208 @scorearray = Array.new
209 209 #set up range from param
210 210 since_id = params.fetch(:since_id, 0).to_i
211 211 until_id = params.fetch(:until_id, 0).to_i
212 212 @users.each do |u|
213 213 ustat = Array.new
214 214 ustat[0] = u
215 215 @problems.each do |p|
216 216 max_points = 0
217 217 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
218 218 max_points = sub.points if sub and sub.points and (sub.points > max_points)
219 219 end
220 220 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
221 221 end
222 222 @scorearray << ustat
223 223 end
224 224
225 225 if params[:commit] == 'download csv' then
226 226 csv = gen_csv_from_scorearray(@scorearray,@problems)
227 227 send_data csv, filename: 'max_score.csv'
228 228 else
229 229 render template: 'user_admin/user_stat'
230 230 end
231 231 end
232 232
233 233 def import
234 234 if params[:file]==''
235 235 flash[:notice] = 'Error importing no file'
236 236 redirect_to :action => 'index' and return
237 237 end
238 238 import_from_file(params[:file])
239 239 end
240 240
241 241 def random_all_passwords
242 242 users = User.all
243 243 @prefix = params[:prefix] || ''
244 244 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
245 245 @changed = false
246 246 if params[:commit] == 'Go ahead'
247 247 @non_admin_users.each do |user|
248 248 password = random_password
249 249 user.password = password
250 250 user.password_confirmation = password
251 251 user.save
252 252 end
253 253 @changed = true
254 254 end
255 255 end
256 256
257 257 # contest management
258 258
259 259 def contests
260 260 @contest, @users = find_contest_and_user_from_contest_id(params[:id])
261 261 @contests = Contest.enabled
262 262 end
263 263
264 264 def assign_from_list
265 265 contest_id = params[:users_contest_id]
266 266 org_contest, users = find_contest_and_user_from_contest_id(contest_id)
267 267 contest = Contest.find(params[:new_contest][:id])
268 268 if !contest
269 269 flash[:notice] = 'Error: no contest'
270 270 redirect_to :action => 'contests', :id =>contest_id
271 271 end
272 272
273 273 note = []
274 274 users.each do |u|
275 275 u.contests = [contest]
276 276 note << u.login
277 277 end
278 278 flash[:notice] = 'User(s) ' + note.join(', ') +
279 279 " were successfully reassigned to #{contest.title}."
280 280 redirect_to :action => 'contests', :id =>contest.id
281 281 end
282 282
283 283 def add_to_contest
284 284 user = User.find(params[:id])
285 285 contest = Contest.find(params[:contest_id])
286 286 if user and contest
287 287 user.contests << contest
288 288 end
289 289 redirect_to :action => 'index'
290 290 end
291 291
292 292 def remove_from_contest
293 293 user = User.find(params[:id])
294 294 contest = Contest.find(params[:contest_id])
295 295 if user and contest
296 296 user.contests.delete(contest)
297 297 end
298 298 redirect_to :action => 'index'
299 299 end
300 300
301 301 def contest_management
302 302 end
303 303
304 304 def manage_contest
305 305 contest = Contest.find(params[:contest][:id])
306 306 if !contest
307 307 flash[:notice] = 'You did not choose the contest.'
308 308 redirect_to :action => 'contest_management' and return
309 309 end
310 310
311 311 operation = params[:operation]
312 312
313 313 if not ['add','remove','assign'].include? operation
314 314 flash[:notice] = 'You did not choose the operation to perform.'
315 315 redirect_to :action => 'contest_management' and return
316 316 end
317 317
318 318 lines = params[:login_list]
319 319 if !lines or lines.blank?
320 320 flash[:notice] = 'You entered an empty list.'
321 321 redirect_to :action => 'contest_management' and return
322 322 end
323 323
324 324 note = []
325 325 users = []
326 326 lines.split("\n").each do |line|
327 327 user = User.find_by_login(line.chomp)
328 328 if user
329 329 if operation=='add'
330 330 if ! user.contests.include? contest
331 331 user.contests << contest
332 332 end
333 333 elsif operation=='remove'
334 334 user.contests.delete(contest)
335 335 else
336 336 user.contests = [contest]
337 337 end
338 338
339 339 if params[:reset_timer]
340 340 user.contest_stat.forced_logout = true
341 341 user.contest_stat.reset_timer_and_save
342 342 end
343 343
344 344 if params[:notification_emails]
345 345 send_contest_update_notification_email(user, contest)
346 346 end
347 347
348 348 note << user.login
349 349 users << user
350 350 end
351 351 end
352 352
353 353 if params[:reset_timer]
354 354 logout_users(users)
355 355 end
356 356
357 357 flash[:notice] = 'User(s) ' + note.join(', ') +
358 358 ' were successfully modified. '
359 359 redirect_to :action => 'contest_management'
360 360 end
361 361
362 362 # admin management
363 363
364 364 def admin
365 - @admins = User.all.find_all {|user| user.admin? }
365 + @admins = Role.where(name: 'admin').take.users
366 + @tas = Role.where(name: 'ta').take.users
366 367 end
367 368
368 - def grant_admin
369 - login = params[:login]
370 - user = User.find_by_login(login)
371 - if user!=nil
372 - admin_role = Role.find_by_name('admin')
373 - user.roles << admin_role
374 - else
375 - flash[:notice] = 'Unknown user'
369 + def modify_role
370 + user = User.find_by_login(params[:login])
371 + role = Role.find_by_name(params[:role])
372 + unless user && role
373 + flash[:error] = 'Unknown user or role'
374 + redirect_to admin_user_admin_index_path
375 + return
376 376 end
377 - flash[:notice] = 'User added as admins'
378 - redirect_to :action => 'admin'
379 - end
380 -
381 - def revoke_admin
382 - user = User.find(params[:id])
383 - if user==nil
384 - flash[:notice] = 'Unknown user'
385 - redirect_to :action => 'admin' and return
386 - elsif user.login == 'root'
387 - flash[:notice] = 'You cannot revoke admisnistrator permission from root.'
388 - redirect_to :action => 'admin' and return
377 + if params[:commit] == 'Grant'
378 + #grant role
379 + user.roles << role
380 + flash[:notice] = "User '#{user.login}' has been granted the role '#{role.name}'"
381 + else
382 + #revoke role
383 + if user.login == 'root' && role.name == 'admin'
384 + flash[:error] = 'You cannot revoke admisnistrator permission from root.'
385 + redirect_to admin_user_admin_index_path
386 + return
387 + end
388 + user.roles.delete(role)
389 + flash[:notice] = "The role '#{role.name}' has been revoked from User '#{user.login}'"
389 390 end
390 -
391 - admin_role = Role.find_by_name('admin')
392 - user.roles.delete(admin_role)
393 - flash[:notice] = 'User permission revoked'
394 - redirect_to :action => 'admin'
391 + redirect_to admin_user_admin_index_path
395 392 end
396 393
397 394 # mass mailing
398 395
399 396 def mass_mailing
400 397 end
401 398
402 399 def bulk_mail
403 400 lines = params[:login_list]
404 401 if !lines or lines.blank?
405 402 flash[:notice] = 'You entered an empty list.'
406 403 redirect_to :action => 'mass_mailing' and return
407 404 end
408 405
409 406 mail_subject = params[:subject]
410 407 if !mail_subject or mail_subject.blank?
411 408 flash[:notice] = 'You entered an empty mail subject.'
412 409 redirect_to :action => 'mass_mailing' and return
413 410 end
414 411
415 412 mail_body = params[:email_body]
416 413 if !mail_body or mail_body.blank?
417 414 flash[:notice] = 'You entered an empty mail body.'
418 415 redirect_to :action => 'mass_mailing' and return
419 416 end
420 417
421 418 note = []
422 419 users = []
423 420 lines.split("\n").each do |line|
424 421 user = User.find_by_login(line.chomp)
425 422 if user
426 423 send_mail(user.email, mail_subject, mail_body)
427 424 note << user.login
428 425 end
429 426 end
430 427
431 428 flash[:notice] = 'User(s) ' + note.join(', ') +
432 429 ' were successfully modified. '
433 430 redirect_to :action => 'mass_mailing'
434 431 end
435 432
436 433 #bulk manage
437 434 def bulk_manage
438 435
439 436 begin
440 437 @users = User.where('(login REGEXP ?) OR (remark REGEXP ?)',params[:regex],params[:regex]) if params[:regex]
441 438 @users.count if @users #i don't know why I have to call count, but if I won't exception is not raised
442 439 rescue Exception
443 440 flash[:error] = 'Regular Expression is malformed'
444 441 @users = nil
445 442 end
446 443
447 444 if params[:commit]
448 445 @action = {}
449 446 @action[:set_enable] = params[:enabled]
450 447 @action[:enabled] = params[:enable] == "1"
451 448 @action[:gen_password] = params[:gen_password]
452 449 @action[:add_group] = params[:add_group]
453 450 @action[:group_name] = params[:group_name]
454 451 end
455 452
456 453 if params[:commit] == "Perform"
457 454 if @action[:set_enable]
458 455 @users.update_all(enabled: @action[:enabled])
459 456 end
460 457 if @action[:gen_password]
461 458 @users.each do |u|
462 459 password = random_password
463 460 u.password = password
464 461 u.password_confirmation = password
465 462 u.save
466 463 end
467 464 end
468 465 if @action[:add_group] and @action[:group_name]
469 466 @group = Group.find(@action[:group_name])
470 467 ok = []
471 468 failed = []
472 469 @users.each do |user|
473 470 begin
474 471 @group.users << user
475 472 ok << user.login
476 473 rescue => e
477 474 failed << user.login
478 475 end
479 476 end
480 477 flash[:success] = "The following users are added to the 'group #{@group.name}': " + ok.join(', ') if ok.count > 0
481 478 flash[:alert] = "The following users are already in the 'group #{@group.name}': " + failed.join(', ') if failed.count > 0
482 479 end
483 480 end
484 481 end
485 482
486 483 protected
487 484
488 485 def random_password(length=5)
489 486 chars = 'abcdefghijkmnopqrstuvwxyz23456789'
490 487 newpass = ""
491 488 length.times { newpass << chars[rand(chars.size-1)] }
492 489 return newpass
493 490 end
494 491
495 492 def import_from_file(f)
496 493 data_hash = YAML.load(f)
497 494 @import_log = ""
498 495
499 496 country_data = data_hash[:countries]
500 497 site_data = data_hash[:sites]
501 498 user_data = data_hash[:users]
502 499
503 500 # import country
504 501 countries = {}
505 502 country_data.each_pair do |id,country|
506 503 c = Country.find_by_name(country[:name])
507 504 if c!=nil
508 505 countries[id] = c
509 506 @import_log << "Found #{country[:name]}\n"
510 507 else
511 508 countries[id] = Country.new(:name => country[:name])
512 509 countries[id].save
513 510 @import_log << "Created #{country[:name]}\n"
514 511 end
515 512 end
516 513
517 514 # import sites
518 515 sites = {}
519 516 site_data.each_pair do |id,site|
520 517 s = Site.find_by_name(site[:name])
521 518 if s!=nil
522 519 @import_log << "Found #{site[:name]}\n"
523 520 else
524 521 s = Site.new(:name => site[:name])
525 522 @import_log << "Created #{site[:name]}\n"
526 523 end
527 524 s.password = site[:password]
528 525 s.country = countries[site[:country_id]]
529 526 s.save
530 527 sites[id] = s
531 528 end
532 529
533 530 # import users
534 531 user_data.each_pair do |id,user|
535 532 u = User.find_by_login(user[:login])
536 533 if u!=nil
537 534 @import_log << "Found #{user[:login]}\n"
538 535 else
539 536 u = User.new(:login => user[:login])
540 537 @import_log << "Created #{user[:login]}\n"
541 538 end
542 539 u.full_name = user[:name]
543 540 u.password = user[:password]
544 541 u.country = countries[user[:country_id]]
545 542 u.site = sites[user[:site_id]]
546 543 u.activated = true
547 544 u.email = "empty-#{u.login}@none.com"
548 545 if not u.save
549 546 @import_log << "Errors\n"
550 547 u.errors.each { |attr,msg| @import_log << "#{attr} - #{msg}\n" }
551 548 end
552 549 end
553 550
554 551 end
555 552
556 553 def logout_users(users)
557 554 users.each do |user|
558 555 contest_stat = user.contest_stat(true)
559 556 if contest_stat and !contest_stat.forced_logout
560 557 contest_stat.forced_logout = true
561 558 contest_stat.save
562 559 end
563 560 end
564 561 end
565 562
566 563 def send_contest_update_notification_email(user, contest)
567 564 contest_title_name = GraderConfiguration['contest.name']
568 565 contest_name = contest.name
569 566 mail_subject = t('contest.notification.email_subject', {
570 567 :contest_title_name => contest_title_name,
571 568 :contest_name => contest_name })
572 569 mail_body = t('contest.notification.email_body', {
573 570 :full_name => user.full_name,
574 571 :contest_title_name => contest_title_name,
575 572 :contest_name => contest.name,
576 573 })
577 574
578 575 logger.info mail_body
579 576 send_mail(user.email, mail_subject, mail_body)
580 577 end
581 578
582 579 def find_contest_and_user_from_contest_id(id)
583 580 if id!='none'
584 581 @contest = Contest.find(id)
585 582 else
586 583 @contest = nil
587 584 end
588 585 if @contest
589 586 @users = @contest.users
590 587 else
591 588 @users = User.find_users_with_no_contest
592 589 end
593 590 return [@contest, @users]
594 591 end
595 592
596 593 def gen_csv_from_scorearray(scorearray,problem)
597 594 CSV.generate do |csv|
598 595 #add header
599 596 header = ['User','Name', 'Activated?', 'Logged in', 'Contest']
600 597 problem.each { |p| header << p.name }
601 598 header += ['Total','Passed']
602 599 csv << header
603 600 #add data
604 601 scorearray.each do |sc|
605 602 total = num_passed = 0
606 603 row = Array.new
607 604 sc.each_index do |i|
608 605 if i == 0
609 606 row << sc[i].login
610 607 row << sc[i].full_name
611 608 row << sc[i].activated
612 609 row << (sc[i].try(:contest_stat).try(:started_at).nil? ? 'no' : 'yes')
613 610 row << sc[i].contests.collect {|c| c.name}.join(', ')
614 611 else
615 612 row << sc[i][0]
616 613 total += sc[i][0]
617 614 num_passed += 1 if sc[i][1]
618 615 end
619 616 end
620 617 row << total
621 618 row << num_passed
622 619 csv << row
623 620 end
624 621 end
625 622 end
626 623
627 624 private
628 625 def user_params
629 626 params.require(:user).permit(:login,:password,:password_confirmation,:email, :alias, :full_name,:remark)
630 627 end
631 628 end
@@ -1,377 +1,381
1 1 require 'digest/sha1'
2 2 require 'net/pop'
3 3 require 'net/https'
4 4 require 'net/http'
5 5 require 'json'
6 6
7 7 class User < ActiveRecord::Base
8 8
9 9 has_and_belongs_to_many :roles
10 10
11 11 #has_and_belongs_to_many :groups
12 12 has_many :groups_users, class_name: 'GroupUser'
13 13 has_many :groups, :through => :groups_users
14 14
15 15 has_many :test_requests, -> {order(submitted_at: :desc)}
16 16
17 17 has_many :messages, -> { order(created_at: :desc) },
18 18 :class_name => "Message",
19 19 :foreign_key => "sender_id"
20 20
21 21 has_many :replied_messages, -> { order(created_at: :desc) },
22 22 :class_name => "Message",
23 23 :foreign_key => "receiver_id"
24 24
25 25 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
26 26
27 27 belongs_to :site
28 28 belongs_to :country
29 29
30 30 has_and_belongs_to_many :contests, -> { order(:name)}
31 31
32 32 scope :activated_users, -> {where activated: true}
33 33
34 34 validates_presence_of :login
35 35 validates_uniqueness_of :login
36 36 validates_format_of :login, :with => /\A[\_A-Za-z0-9]+\z/
37 37 validates_length_of :login, :within => 3..30
38 38
39 39 validates_presence_of :full_name
40 40 validates_length_of :full_name, :minimum => 1
41 41
42 42 validates_presence_of :password, :if => :password_required?
43 43 validates_length_of :password, :within => 4..50, :if => :password_required?
44 44 validates_confirmation_of :password, :if => :password_required?
45 45
46 46 validates_format_of :email,
47 47 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
48 48 :if => :email_validation?
49 49 validate :uniqueness_of_email_from_activated_users,
50 50 :if => :email_validation?
51 51 validate :enough_time_interval_between_same_email_registrations,
52 52 :if => :email_validation?
53 53
54 54 # these are for ytopc
55 55 # disable for now
56 56 #validates_presence_of :province
57 57
58 58 attr_accessor :password
59 59
60 60 before_save :encrypt_new_password
61 61 before_save :assign_default_site
62 62 before_save :assign_default_contest
63 63
64 64 # this is for will_paginate
65 65 cattr_reader :per_page
66 66 @@per_page = 50
67 67
68 68 def self.authenticate(login, password)
69 69 user = find_by_login(login)
70 70 if user
71 71 return user if user.authenticated?(password)
72 72 end
73 73 end
74 74
75 75 def authenticated?(password)
76 76 if self.activated
77 77 hashed_password == User.encrypt(password,self.salt)
78 78 else
79 79 false
80 80 end
81 81 end
82 82
83 83 def admin?
84 - self.roles.where(name: 'admin').count > 0
84 + has_role?('admin')
85 + end
86 +
87 + def has_role?(role)
88 + self.roles.where(name: role).count > 0
85 89 end
86 90
87 91 def email_for_editing
88 92 if self.email==nil
89 93 "(unknown)"
90 94 elsif self.email==''
91 95 "(blank)"
92 96 else
93 97 self.email
94 98 end
95 99 end
96 100
97 101 def email_for_editing=(e)
98 102 self.email=e
99 103 end
100 104
101 105 def alias_for_editing
102 106 if self.alias==nil
103 107 "(unknown)"
104 108 elsif self.alias==''
105 109 "(blank)"
106 110 else
107 111 self.alias
108 112 end
109 113 end
110 114
111 115 def alias_for_editing=(e)
112 116 self.alias=e
113 117 end
114 118
115 119 def activation_key
116 120 if self.hashed_password==nil
117 121 encrypt_new_password
118 122 end
119 123 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
120 124 end
121 125
122 126 def verify_activation_key(key)
123 127 key == activation_key
124 128 end
125 129
126 130 def self.random_password(length=5)
127 131 chars = 'abcdefghjkmnopqrstuvwxyz'
128 132 password = ''
129 133 length.times { password << chars[rand(chars.length - 1)] }
130 134 password
131 135 end
132 136
133 137 def self.find_non_admin_with_prefix(prefix='')
134 138 users = User.all
135 139 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
136 140 end
137 141
138 142 # Contest information
139 143
140 144 def self.find_users_with_no_contest()
141 145 users = User.all
142 146 return users.find_all { |u| u.contests.length == 0 }
143 147 end
144 148
145 149
146 150 def contest_time_left
147 151 if GraderConfiguration.contest_mode?
148 152 return nil if site==nil
149 153 return site.time_left
150 154 elsif GraderConfiguration.indv_contest_mode?
151 155 time_limit = GraderConfiguration.contest_time_limit
152 156 if time_limit == nil
153 157 return nil
154 158 end
155 159 if contest_stat==nil or contest_stat.started_at==nil
156 160 return (Time.now.gmtime + time_limit) - Time.now.gmtime
157 161 else
158 162 finish_time = contest_stat.started_at + time_limit
159 163 current_time = Time.now.gmtime
160 164 if current_time > finish_time
161 165 return 0
162 166 else
163 167 return finish_time - current_time
164 168 end
165 169 end
166 170 else
167 171 return nil
168 172 end
169 173 end
170 174
171 175 def contest_finished?
172 176 if GraderConfiguration.contest_mode?
173 177 return false if site==nil
174 178 return site.finished?
175 179 elsif GraderConfiguration.indv_contest_mode?
176 180 return false if self.contest_stat==nil
177 181 return contest_time_left == 0
178 182 else
179 183 return false
180 184 end
181 185 end
182 186
183 187 def contest_started?
184 188 if GraderConfiguration.indv_contest_mode?
185 189 stat = self.contest_stat
186 190 return ((stat != nil) and (stat.started_at != nil))
187 191 elsif GraderConfiguration.contest_mode?
188 192 return true if site==nil
189 193 return site.started
190 194 else
191 195 return true
192 196 end
193 197 end
194 198
195 199 def update_start_time
196 200 stat = self.contest_stat
197 201 if stat.nil? or stat.started_at.nil?
198 202 stat ||= UserContestStat.new(:user => self)
199 203 stat.started_at = Time.now.gmtime
200 204 stat.save
201 205 end
202 206 end
203 207
204 208 def problem_in_user_contests?(problem)
205 209 problem_contests = problem.contests.all
206 210
207 211 if problem_contests.length == 0 # this is public contest
208 212 return true
209 213 end
210 214
211 215 contests.each do |contest|
212 216 if problem_contests.find {|c| c.id == contest.id }
213 217 return true
214 218 end
215 219 end
216 220 return false
217 221 end
218 222
219 223 def available_problems_group_by_contests
220 224 contest_problems = []
221 225 pin = {}
222 226 contests.enabled.each do |contest|
223 227 available_problems = contest.problems.available
224 228 contest_problems << {
225 229 :contest => contest,
226 230 :problems => available_problems
227 231 }
228 232 available_problems.each {|p| pin[p.id] = true}
229 233 end
230 234 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
231 235 contest_problems << {
232 236 :contest => nil,
233 237 :problems => other_avaiable_problems
234 238 }
235 239 return contest_problems
236 240 end
237 241
238 242 def solve_all_available_problems?
239 243 available_problems.each do |p|
240 244 u = self
241 245 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
242 246 return false if !p or !sub or sub.points < p.full_score
243 247 end
244 248 return true
245 249 end
246 250
247 251 #get a list of available problem
248 252 def available_problems
249 253 # first, we check if this is normal mode
250 254 if not GraderConfiguration.multicontests?
251 255
252 256 #if this is a normal mode
253 257 #we show problem based on problem_group, if the config said so
254 258 if GraderConfiguration.use_problem_group?
255 259 return available_problems_in_group
256 260 else
257 261 return Problem.available_problems
258 262 end
259 263 else
260 264 #this is multi contest mode
261 265 contest_problems = []
262 266 pin = {}
263 267 contests.enabled.each do |contest|
264 268 contest.problems.available.each do |problem|
265 269 if not pin.has_key? problem.id
266 270 contest_problems << problem
267 271 end
268 272 pin[problem.id] = true
269 273 end
270 274 end
271 275 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
272 276 return contest_problems + other_avaiable_problems
273 277 end
274 278 end
275 279
276 280 # new feature, get list of available problem in all enabled group that the user belongs to
277 281 def available_problems_in_group
278 282 problem = []
279 283 self.groups.where(enabled: true).each do |group|
280 284 group.problems.where(available: true).each { |p| problem << p }
281 285 end
282 286 problem.uniq!
283 287 if problem
284 288 problem.sort! do |a,b|
285 289 case
286 290 when a.date_added < b.date_added
287 291 1
288 292 when a.date_added > b.date_added
289 293 -1
290 294 else
291 295 a.name <=> b.name
292 296 end
293 297 end
294 298 return problem
295 299 else
296 300 return []
297 301 end
298 302 end
299 303
300 304 #check if the user has the right to view that problem
301 305 #this also consider group based problem policy
302 306 def can_view_problem?(problem)
303 307 return true if admin?
304 308 return available_problems.include? problem
305 309 end
306 310
307 311 def self.clear_last_login
308 312 User.update_all(:last_ip => nil)
309 313 end
310 314
311 315 protected
312 316 def encrypt_new_password
313 317 return if password.blank?
314 318 self.salt = (10+rand(90)).to_s
315 319 self.hashed_password = User.encrypt(self.password,self.salt)
316 320 end
317 321
318 322 def assign_default_site
319 323 # have to catch error when migrating (because self.site is not available).
320 324 begin
321 325 if self.site==nil
322 326 self.site = Site.find_by_name('default')
323 327 if self.site==nil
324 328 self.site = Site.find(1) # when 'default has be renamed'
325 329 end
326 330 end
327 331 rescue
328 332 end
329 333 end
330 334
331 335 def assign_default_contest
332 336 # have to catch error when migrating (because self.site is not available).
333 337 begin
334 338 if self.contests.length == 0
335 339 default_contest = Contest.find_by_name(GraderConfiguration['contest.default_contest_name'])
336 340 if default_contest
337 341 self.contests = [default_contest]
338 342 end
339 343 end
340 344 rescue
341 345 end
342 346 end
343 347
344 348 def password_required?
345 349 self.hashed_password.blank? || !self.password.blank?
346 350 end
347 351
348 352 def self.encrypt(string,salt)
349 353 Digest::SHA1.hexdigest(salt + string)
350 354 end
351 355
352 356 def uniqueness_of_email_from_activated_users
353 357 user = User.activated_users.find_by_email(self.email)
354 358 if user and (user.login != self.login)
355 359 self.errors.add(:base,"Email has already been taken")
356 360 end
357 361 end
358 362
359 363 def enough_time_interval_between_same_email_registrations
360 364 return if !self.new_record?
361 365 return if self.activated
362 366 open_user = User.find_by_email(self.email,
363 367 :order => 'created_at DESC')
364 368 if open_user and open_user.created_at and
365 369 (open_user.created_at > Time.now.gmtime - 5.minutes)
366 370 self.errors.add(:base,"There are already unactivated registrations with this e-mail address (please wait for 5 minutes)")
367 371 end
368 372 end
369 373
370 374 def email_validation?
371 375 begin
372 376 return VALIDATE_USER_EMAILS
373 377 rescue
374 378 return false
375 379 end
376 380 end
377 381 end
@@ -1,25 +1,54
1 - %h1 Administrators
1 + %h1 Modify Role
2 + .row
3 + .col-md-6
4 + %h4 Administrators
5 + = form_tag modify_role_user_admin_index_path, method: 'post', class: 'form-inline' do
6 + = hidden_field_tag :role, 'admin'
7 + .form-group
8 + = label_tag :login, 'Grant admin role to:'
9 + = text_field_tag 'login',nil, class: 'form-control'
10 + .form-group
11 + = submit_tag 'Grant', class: 'btn btn-primary'
12 + %br
13 + %table.table.table-condense.table-hover.table-striped.table-bordered
14 + %thead{:class => 'info-head'}
15 + %th #
16 + %th Login
17 + %th Full name
18 + %th
19 + - @admins.each_with_index do |user, i|
20 + %tr
21 + %td= i+1
22 + %td= user.login
23 + %td= user.full_name
24 + %td
25 + - if user.login!='root'
26 + = link_to '[revoke]', modify_role_user_admin_index_path( login: user.login, role: 'admin', commit: 'revoke')
27 + .col-md-6
28 + %h4 Teacher Assistants (TA)
29 + = form_tag modify_role_user_admin_index_path, method: 'post', class: 'form-inline' do
30 + = hidden_field_tag :role, 'TA'
31 + .form-group
32 + = label_tag :login, 'Grant TA role to:'
33 + = text_field_tag 'login',nil, class: 'form-control'
34 + .form-group
35 + = submit_tag 'Grant', class: 'btn btn-primary'
36 + %br
37 + %table.table.table-condense.table-hover.table-striped.table-bordered
38 + %thead{:class => 'info-head'}
39 + %th #
40 + %th Login
41 + %th Full name
42 + %th
43 + - @tas.each_with_index do |user, i|
44 + %tr
45 + %td= i+1
46 + %td= user.login
47 + %td= user.full_name
48 + %td
49 + - if user.login!='root'
50 + = link_to '[revoke]', modify_role_user_admin_index_path( login: user.login, role: 'TA', commit: 'revoke')
2 51
3 - %table{:class => 'info'}
4 - %tr{:class => 'info-head'}
5 - %th #
6 - %th Login
7 - %th Full name
8 - %th
9 - - @admins.each_with_index do |user, i|
10 - %tr
11 - %td= i+1
12 - %td= user.login
13 - %td= user.full_name
14 - %td
15 - - if user.login!='root'
16 - = link_to '[revoke]', :action => 'revoke_admin', :id => user.id
17 - %hr
18 -
19 - = form_tag :action => 'grant_admin' do
20 - = label_tag :login, 'Grant admin permission to:'
21 - = text_field_tag 'login',nil, class: 'input-field'
22 - = submit_tag 'Grant', class: 'btn btn-primary'
23 52
24 53 %hr/
25 54 = link_to '[go back to index]', :action => 'index'
@@ -1,204 +1,203
1 1 Rails.application.routes.draw do
2 2 resources :tags
3 3 get "sources/direct_edit"
4 4
5 5 root :to => 'main#login'
6 6
7 7 #logins
8 8 match 'login/login', to: 'login#login', via: [:get,:post]
9 9
10 10 resources :contests
11 11 resources :sites
12 12 resources :test
13 13
14 14 resources :messages do
15 15 member do
16 16 get 'hide'
17 17 post 'reply'
18 18 end
19 19 collection do
20 20 get 'console'
21 21 get 'list_all'
22 22 end
23 23 end
24 24
25 25 resources :announcements do
26 26 member do
27 27 get 'toggle','toggle_front'
28 28 end
29 29 end
30 30
31 31 resources :problems do
32 32 member do
33 33 get 'toggle'
34 34 get 'toggle_test'
35 35 get 'toggle_view_testcase'
36 36 get 'stat'
37 37 end
38 38 collection do
39 39 get 'turn_all_off'
40 40 get 'turn_all_on'
41 41 get 'import'
42 42 get 'manage'
43 43 get 'quick_create'
44 44 post 'do_manage'
45 45 post 'do_import'
46 46 end
47 47 end
48 48
49 49 resources :groups do
50 50 member do
51 51 post 'add_user', to: 'groups#add_user', as: 'add_user'
52 52 delete 'remove_user/:user_id', to: 'groups#remove_user', as: 'remove_user'
53 53 delete 'remove_all_user', to: 'groups#remove_all_user', as: 'remove_all_user'
54 54 post 'add_problem', to: 'groups#add_problem', as: 'add_problem'
55 55 delete 'remove_problem/:problem_id', to: 'groups#remove_problem', as: 'remove_problem'
56 56 delete 'remove_all_problem', to: 'groups#remove_all_problem', as: 'remove_all_problem'
57 57 get 'toggle'
58 58 end
59 59 collection do
60 60
61 61 end
62 62 end
63 63
64 64 resources :testcases, only: [] do
65 65 member do
66 66 get 'download_input'
67 67 get 'download_sol'
68 68 end
69 69 collection do
70 70 get 'show_problem/:problem_id(/:test_num)' => 'testcases#show_problem', as: 'show_problem'
71 71 end
72 72 end
73 73
74 74 resources :grader_configuration, controller: 'configurations' do
75 75 collection do
76 76 get 'set_exam_right(/:value)', action: 'set_exam_right', as: 'set_exam_right'
77 77 end
78 78 end
79 79
80 80 resources :users do
81 81 member do
82 82 get 'toggle_activate', 'toggle_enable'
83 83 get 'stat'
84 84 end
85 85 collection do
86 86 get 'profile'
87 87 post 'chg_passwd'
88 88 end
89 89 end
90 90
91 91 resources :submissions do
92 92 member do
93 93 get 'download'
94 94 get 'compiler_msg'
95 95 get 'rejudge'
96 96 end
97 97 collection do
98 98 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
99 99 get 'direct_edit_problem/:problem_id(/:user_id)', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
100 100 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
101 101 end
102 102 end
103 103
104 104
105 105 #user admin
106 106 resources :user_admin do
107 107 collection do
108 108 match 'bulk_manage', via: [:get, :post]
109 109 get 'bulk_mail'
110 110 get 'user_stat'
111 111 get 'import'
112 112 get 'new_list'
113 113 get 'admin'
114 114 get 'active'
115 115 get 'mass_mailing'
116 - get 'revoke_admin'
117 - post 'grant_admin'
116 + match 'modify_role', via: [:get, :post]
118 117 match 'create_from_list', via: [:get, :post]
119 118 match 'random_all_passwords', via: [:get, :post]
120 119 end
121 120 member do
122 121 get 'clear_last_ip'
123 122 end
124 123 end
125 124
126 125 resources :contest_management, only: [:index] do
127 126 collection do
128 127 get 'user_stat'
129 128 get 'clear_stat'
130 129 get 'clear_all_stat'
131 130 get 'change_contest_mode'
132 131 end
133 132 end
134 133
135 134 #get 'user_admin', to: 'user_admin#index'
136 135 #get 'user_admin/bulk_manage', to: 'user_admin#bulk_manage', as: 'bulk_manage_user_admin'
137 136 #post 'user_admin', to: 'user_admin#create'
138 137 #delete 'user_admin/:id', to: 'user_admin#destroy', as: 'user_admin_destroy'
139 138
140 139 #singular resource
141 140 #---- BEWARE ---- singular resource maps to plural controller by default, we can override by provide controller name directly
142 141 #report
143 142 resource :report, only: [], controller: 'report' do
144 143 get 'login'
145 144 get 'multiple_login'
146 145 get 'problem_hof(/:id)', action: 'problem_hof', as: 'problem_hof'
147 146 get 'current_score(/:group_id)', action: 'current_score', as: 'current_score'
148 147 get 'max_score'
149 148 post 'show_max_score'
150 149 get 'stuck'
151 150 get 'cheat_report'
152 151 post 'cheat_report'
153 152 get 'cheat_scruntinize'
154 153 post 'cheat_scruntinize'
155 154 end
156 155 #get 'report/current_score', to: 'report#current_score', as: 'report_current_score'
157 156 #get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
158 157 #get "report/login"
159 158 #get 'report/max_score', to: 'report#max_score', as: 'report_max_score'
160 159 #post 'report/show_max_score', to: 'report#show_max_score', as: 'report_show_max_score'
161 160
162 161 resource :main, only: [], controller: 'main' do
163 162 get 'login'
164 163 get 'logout'
165 164 get 'list'
166 165 get 'submission(/:id)', action: 'submission', as: 'main_submission'
167 166 get 'announcements'
168 167 get 'help'
169 168 post 'submit'
170 169 end
171 170 #main
172 171 #get "main/list"
173 172 #get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
174 173 #post 'main/submit', to: 'main#submit'
175 174 #get 'main/announcements', to: 'main#announcements'
176 175
177 176
178 177 #
179 178 get 'tasks/view/:file.:ext' => 'tasks#view'
180 179 get 'tasks/download/:id/:file.:ext' => 'tasks#download', as: 'download_task'
181 180 get 'heartbeat/:id/edit' => 'heartbeat#edit'
182 181
183 182 #grader
184 183 get 'graders/list', to: 'graders#list', as: 'grader_list'
185 184 namespace :graders do
186 185 get 'task/:id/:type', action: 'task', as: 'task'
187 186 get 'view/:id/:type', action: 'view', as: 'view'
188 187 get 'clear/:id', action: 'clear', as: 'clear'
189 188 get 'stop'
190 189 get 'stop_all'
191 190 get 'clear_all'
192 191 get 'clear_terminated'
193 192 get 'start_grading'
194 193 get 'start_exam'
195 194
196 195 end
197 196
198 197
199 198 # See how all your routes lay out with "rake routes"
200 199
201 200 # This is a legacy wild controller route that's not recommended for RESTful applications.
202 201 # Note: This route will make all actions in every controller accessible via GET requests.
203 202 # match ':controller(/:action(/:id))(.:format)', via: [:get, :post]
204 203 end
@@ -1,288 +1,289
1 1 CONFIGURATIONS =
2 2 [
3 3 {
4 4 :key => 'system.single_user_mode',
5 5 :value_type => 'boolean',
6 6 :default_value => 'false',
7 7 :description => 'Only admins can log in to the system when running under single user mode.'
8 8 },
9 9
10 10 {
11 11 :key => 'ui.front.title',
12 12 :value_type => 'string',
13 13 :default_value => 'Grader'
14 14 },
15 15
16 16 {
17 17 :key => 'ui.front.welcome_message',
18 18 :value_type => 'string',
19 19 :default_value => 'Welcome!'
20 20 },
21 21
22 22 {
23 23 :key => 'ui.show_score',
24 24 :value_type => 'boolean',
25 25 :default_value => 'true'
26 26 },
27 27
28 28 {
29 29 :key => 'contest.time_limit',
30 30 :value_type => 'string',
31 31 :default_value => 'unlimited',
32 32 :description => 'Time limit in format hh:mm, or "unlimited" for contests with no time limits. This config is CACHED. Restart the server before the change can take effect.'
33 33 },
34 34
35 35 {
36 36 :key => 'system.mode',
37 37 :value_type => 'string',
38 38 :default_value => 'standard',
39 39 :description => 'Current modes are "standard", "contest", "indv-contest", and "analysis".'
40 40 },
41 41
42 42 {
43 43 :key => 'contest.name',
44 44 :value_type => 'string',
45 45 :default_value => 'Grader',
46 46 :description => 'This name will be shown on the user header bar.'
47 47 },
48 48
49 49 {
50 50 :key => 'contest.multisites',
51 51 :value_type => 'boolean',
52 52 :default_value => 'false',
53 53 :description => 'If the server is in contest mode and this option is true, on the log in of the admin a menu for site selections is shown.'
54 54 },
55 55
56 56 #---------------------------- right --------------------------------
57 57 {
58 58 :key => 'right.user_hall_of_fame',
59 59 :value_type => 'boolean',
60 60 :default_value => 'false',
61 61 :description => 'If true, any user can access hall of fame page.'
62 62 },
63 63
64 64 {
65 65 :key => 'right.multiple_ip_login',
66 66 :value_type => 'boolean',
67 67 :default_value => 'true',
68 68 :description => 'When change from true to false, a user can login from the first IP they logged into afterward.'
69 69 },
70 70
71 71 {
72 72 :key => 'right.user_view_submission',
73 73 :value_type => 'boolean',
74 74 :default_value => 'false',
75 75 :description => 'If true, any user can view submissions of every one.'
76 76 },
77 77
78 78 {
79 79 :key => 'right.bypass_agreement',
80 80 :value_type => 'boolean',
81 81 :default_value => 'true',
82 82 :description => 'When false, a user must accept usage agreement before login'
83 83 },
84 84
85 85 {
86 86 :key => 'right.heartbeat_response',
87 87 :value_type => 'string',
88 88 :default_value => 'OK',
89 89 :description => 'Heart beat response text'
90 90 },
91 91
92 92 {
93 93 :key => 'right.heartbeat_response_full',
94 94 :value_type => 'string',
95 95 :default_value => 'OK',
96 96 :description => 'Heart beat response text when user got full score (set this value to the empty string to disable this feature)'
97 97 },
98 98
99 99 {
100 100 :key => 'right.view_testcase',
101 101 :value_type => 'boolean',
102 102 :default_value => 'false',
103 103 :description => 'If true, any user can view/download test data'
104 104 },
105 105
106 106 {
107 107 :key => 'system.online_registration',
108 108 :value_type => 'boolean',
109 109 :default_value => 'false',
110 110 :description => 'This option enables online registration.'
111 111 },
112 112
113 113 # If Configuration['system.online_registration'] is true, the
114 114 # system allows online registration, and will use these
115 115 # information for sending confirmation emails.
116 116 {
117 117 :key => 'system.online_registration.smtp',
118 118 :value_type => 'string',
119 119 :default_value => 'smtp.somehost.com'
120 120 },
121 121
122 122 {
123 123 :key => 'system.online_registration.from',
124 124 :value_type => 'string',
125 125 :default_value => 'your.email@address'
126 126 },
127 127
128 128 {
129 129 :key => 'system.admin_email',
130 130 :value_type => 'string',
131 131 :default_value => 'admin@admin.email'
132 132 },
133 133
134 134 {
135 135 :key => 'system.user_setting_enabled',
136 136 :value_type => 'boolean',
137 137 :default_value => 'true',
138 138 :description => 'If this option is true, users can change their settings'
139 139 },
140 140
141 141 {
142 142 :key => 'system.user_setting_enabled',
143 143 :value_type => 'boolean',
144 144 :default_value => 'true',
145 145 :description => 'If this option is true, users can change their settings'
146 146 },
147 147
148 148 # If Configuration['contest.test_request.early_timeout'] is true
149 149 # the user will not be able to use test request at 30 minutes
150 150 # before the contest ends.
151 151 {
152 152 :key => 'contest.test_request.early_timeout',
153 153 :value_type => 'boolean',
154 154 :default_value => 'false'
155 155 },
156 156
157 157 {
158 158 :key => 'system.multicontests',
159 159 :value_type => 'boolean',
160 160 :default_value => 'false'
161 161 },
162 162
163 163 {
164 164 :key => 'contest.confirm_indv_contest_start',
165 165 :value_type => 'boolean',
166 166 :default_value => 'false'
167 167 },
168 168
169 169 {
170 170 :key => 'contest.default_contest_name',
171 171 :value_type => 'string',
172 172 :default_value => 'none',
173 173 :description => "New user will be assigned to this contest automatically, if it exists. Set to 'none' if there is no default contest."
174 174 },
175 175
176 176 {
177 177 :key => 'system.use_problem_group',
178 178 :value_type => 'boolean',
179 179 :default_value => 'false',
180 180 :description => "If true, available problem to the user will be only ones associated with the group of the user."
181 181 },
182 182
183 183
184 184 {
185 185 :key => 'right.whitelist_ignore',
186 186 :value_type => 'boolean',
187 187 :default_value => 'true',
188 188 :description => "If true, no IP check against whitelist_ip is perform. However, when false, non-admin user must have their ip in 'whitelist_ip' to be able to login."
189 189 },
190 190
191 191 {
192 192 :key => 'right.whitelist_ip',
193 193 :value_type => 'string',
194 194 :default_value => '0.0.0.0/0',
195 195 :description => "list of whitelist ip, given in comma separated CIDR notation. For example '192.168.90.0/23, 192.168.1.23/32'"
196 196 },
197 197
198 198 ]
199 199
200 200
201 201 def create_configuration_key(key,
202 202 value_type,
203 203 default_value,
204 204 description='')
205 205 conf = (GraderConfiguration.find_by_key(key) ||
206 206 GraderConfiguration.new(:key => key,
207 207 :value_type => value_type,
208 208 :value => default_value))
209 209 conf.description = description
210 210 conf.save
211 211 end
212 212
213 213 def seed_config
214 214 CONFIGURATIONS.each do |conf|
215 215 if conf.has_key? :description
216 216 desc = conf[:description]
217 217 else
218 218 desc = ''
219 219 end
220 220 create_configuration_key(conf[:key],
221 221 conf[:value_type],
222 222 conf[:default_value],
223 223 desc)
224 224 end
225 225 end
226 226
227 227 def seed_roles
228 + Role.find_or_create_by(name: 'TA')
228 229 return if Role.find_by_name('admin')
229 230
230 231 role = Role.create(:name => 'admin')
231 232 user_admin_right = Right.create(:name => 'user_admin',
232 233 :controller => 'user_admin',
233 234 :action => 'all')
234 235 problem_admin_right = Right.create(:name=> 'problem_admin',
235 236 :controller => 'problems',
236 237 :action => 'all')
237 238
238 239 graders_right = Right.create(:name => 'graders_admin',
239 240 :controller => 'graders',
240 241 :action => 'all')
241 242
242 243 role.rights << user_admin_right;
243 244 role.rights << problem_admin_right;
244 245 role.rights << graders_right;
245 246 role.save
246 247 end
247 248
248 249 def seed_root
249 250 return if User.find_by_login('root')
250 251
251 252 root = User.new(:login => 'root',
252 253 :full_name => 'Administrator',
253 254 :alias => 'root')
254 255 root.password = 'ioionrails';
255 256
256 257 class << root
257 258 public :encrypt_new_password
258 259 def valid?(context=nil)
259 260 true
260 261 end
261 262 end
262 263
263 264 root.encrypt_new_password
264 265
265 266 root.roles << Role.find_by_name('admin')
266 267
267 268 root.activated = true
268 269 root.save
269 270 end
270 271
271 272 def seed_users_and_roles
272 273 seed_roles
273 274 seed_root
274 275 end
275 276
276 277 def seed_more_languages
277 278 #Language.delete_all
278 279 Language.find_or_create_by( name: 'c', pretty_name: 'C', ext: 'c', common_ext: 'c' )
279 280 Language.find_or_create_by( name: 'cpp', pretty_name: 'C++', ext: 'cpp', common_ext: 'cpp,cc' )
280 281 Language.find_or_create_by( name: 'pas', pretty_name: 'Pascal', ext: 'pas', common_ext: 'pas' )
281 282 Language.find_or_create_by( name: 'ruby', pretty_name: 'Ruby', ext: 'rb', common_ext: 'rb' )
282 283 Language.find_or_create_by( name: 'python', pretty_name: 'Python', ext: 'py', common_ext: 'py' )
283 284 Language.find_or_create_by( name: 'java', pretty_name: 'Java', ext: 'java', common_ext: 'java' )
284 285 end
285 286
286 287 seed_config
287 288 seed_users_and_roles
288 289 seed_more_languages
You need to be logged in to leave comments. Login now