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

r836:36fbb20457ec - - 8 files changed: 94 inserted, 60 deleted

@@ -49,64 +49,63
49 end
49 end
50
50
51 #on-site new submission on specific problem
51 #on-site new submission on specific problem
52 def direct_edit_problem
52 def direct_edit_problem
53 @problem = Problem.find(params[:problem_id])
53 @problem = Problem.find(params[:problem_id])
54 unless @current_user.can_view_problem?(@problem)
54 unless @current_user.can_view_problem?(@problem)
55 unauthorized_redirect
55 unauthorized_redirect
56 return
56 return
57 end
57 end
58 @source = ''
58 @source = ''
59 if (params[:view_latest])
59 if (params[:view_latest])
60 sub = Submission.find_last_by_user_and_problem(@current_user.id,@problem.id)
60 sub = Submission.find_last_by_user_and_problem(@current_user.id,@problem.id)
61 @source = @submission.source.to_s if @submission and @submission.source
61 @source = @submission.source.to_s if @submission and @submission.source
62 end
62 end
63 render 'edit'
63 render 'edit'
64 end
64 end
65
65
66 # GET /submissions/1/edit
66 # GET /submissions/1/edit
67 def edit
67 def edit
68 @submission = Submission.find(params[:id])
68 @submission = Submission.find(params[:id])
69 @source = @submission.source.to_s
69 @source = @submission.source.to_s
70 @problem = @submission.problem
70 @problem = @submission.problem
71 @lang_id = @submission.language.id
71 @lang_id = @submission.language.id
72 end
72 end
73
73
74
74
75 def get_latest_submission_status
75 def get_latest_submission_status
76 @problem = Problem.find(params[:pid])
76 @problem = Problem.find(params[:pid])
77 @submission = Submission.find_last_by_user_and_problem(params[:uid],params[:pid])
77 @submission = Submission.find_last_by_user_and_problem(params[:uid],params[:pid])
78 respond_to do |format|
78 respond_to do |format|
79 format.js
79 format.js
80 end
80 end
81 end
81 end
82
82
83 # GET /submissions/:id/rejudge
83 # GET /submissions/:id/rejudge
84 def rejudge
84 def rejudge
85 @submission = Submission.find(params[:id])
85 @submission = Submission.find(params[:id])
86 @task = @submission.task
86 @task = @submission.task
87 @task.status_inqueue! if @task
87 @task.status_inqueue! if @task
88 respond_to do |format|
88 respond_to do |format|
89 format.js
89 format.js
90 end
90 end
91 end
91 end
92
92
93 protected
93 protected
94
94
95 def submission_authorization
95 def submission_authorization
96 #admin always has privileged
96 #admin always has privileged
97 - if @current_user.admin?
97 + return true if @current_user.admin?
98 - return true
98 + return true if @current_user.has_role?('TA') && (['show','download'].include? action_name)
99 - end
100
99
101 sub = Submission.find(params[:id])
100 sub = Submission.find(params[:id])
102 if @current_user.available_problems.include? sub.problem
101 if @current_user.available_problems.include? sub.problem
103 return true if GraderConfiguration["right.user_view_submission"] or sub.user == @current_user
102 return true if GraderConfiguration["right.user_view_submission"] or sub.user == @current_user
104 end
103 end
105
104
106 #default to NO
105 #default to NO
107 unauthorized_redirect
106 unauthorized_redirect
108 return false
107 return false
109 end
108 end
110
109
111
110
112 end
111 end
@@ -310,126 +310,123
310
310
311 lines = params[:login_list]
311 lines = params[:login_list]
312 if !lines or lines.blank?
312 if !lines or lines.blank?
313 flash[:notice] = 'You entered an empty list.'
313 flash[:notice] = 'You entered an empty list.'
314 redirect_to :action => 'contest_management' and return
314 redirect_to :action => 'contest_management' and return
315 end
315 end
316
316
317 note = []
317 note = []
318 users = []
318 users = []
319 lines.split("\n").each do |line|
319 lines.split("\n").each do |line|
320 user = User.find_by_login(line.chomp)
320 user = User.find_by_login(line.chomp)
321 if user
321 if user
322 if operation=='add'
322 if operation=='add'
323 if ! user.contests.include? contest
323 if ! user.contests.include? contest
324 user.contests << contest
324 user.contests << contest
325 end
325 end
326 elsif operation=='remove'
326 elsif operation=='remove'
327 user.contests.delete(contest)
327 user.contests.delete(contest)
328 else
328 else
329 user.contests = [contest]
329 user.contests = [contest]
330 end
330 end
331
331
332 if params[:reset_timer]
332 if params[:reset_timer]
333 user.contest_stat.forced_logout = true
333 user.contest_stat.forced_logout = true
334 user.contest_stat.reset_timer_and_save
334 user.contest_stat.reset_timer_and_save
335 end
335 end
336
336
337 if params[:notification_emails]
337 if params[:notification_emails]
338 send_contest_update_notification_email(user, contest)
338 send_contest_update_notification_email(user, contest)
339 end
339 end
340
340
341 note << user.login
341 note << user.login
342 users << user
342 users << user
343 end
343 end
344 end
344 end
345
345
346 if params[:reset_timer]
346 if params[:reset_timer]
347 logout_users(users)
347 logout_users(users)
348 end
348 end
349
349
350 flash[:notice] = 'User(s) ' + note.join(', ') +
350 flash[:notice] = 'User(s) ' + note.join(', ') +
351 ' were successfully modified. '
351 ' were successfully modified. '
352 redirect_to :action => 'contest_management'
352 redirect_to :action => 'contest_management'
353 end
353 end
354
354
355 # admin management
355 # admin management
356
356
357 def admin
357 def admin
358 - @admins = User.all.find_all {|user| user.admin? }
358 + @admins = Role.where(name: 'admin').take.users
359 + @tas = Role.where(name: 'ta').take.users
359 end
360 end
360
361
361 - def grant_admin
362 + def modify_role
362 - login = params[:login]
363 + user = User.find_by_login(params[:login])
363 - user = User.find_by_login(login)
364 + role = Role.find_by_name(params[:role])
364 - if user!=nil
365 + unless user && role
365 - admin_role = Role.find_by_name('admin')
366 + flash[:error] = 'Unknown user or role'
366 - user.roles << admin_role
367 + redirect_to admin_user_admin_index_path
367 - else
368 + return
368 - flash[:notice] = 'Unknown user'
369 - end
370 - flash[:notice] = 'User added as admins'
371 - redirect_to :action => 'admin'
372 end
369 end
373 -
370 + if params[:commit] == 'Grant'
374 - def revoke_admin
371 + #grant role
375 - user = User.find(params[:id])
372 + user.roles << role
376 - if user==nil
373 + flash[:notice] = "User '#{user.login}' has been granted the role '#{role.name}'"
377 - flash[:notice] = 'Unknown user'
374 + else
378 - redirect_to :action => 'admin' and return
375 + #revoke role
379 - elsif user.login == 'root'
376 + if user.login == 'root' && role.name == 'admin'
380 - flash[:notice] = 'You cannot revoke admisnistrator permission from root.'
377 + flash[:error] = 'You cannot revoke admisnistrator permission from root.'
381 - redirect_to :action => 'admin' and return
378 + redirect_to admin_user_admin_index_path
379 + return
382 end
380 end
383 -
381 + user.roles.delete(role)
384 - admin_role = Role.find_by_name('admin')
382 + flash[:notice] = "The role '#{role.name}' has been revoked from User '#{user.login}'"
385 - user.roles.delete(admin_role)
383 + end
386 - flash[:notice] = 'User permission revoked'
384 + redirect_to admin_user_admin_index_path
387 - redirect_to :action => 'admin'
388 end
385 end
389
386
390 # mass mailing
387 # mass mailing
391
388
392 def mass_mailing
389 def mass_mailing
393 end
390 end
394
391
395 def bulk_mail
392 def bulk_mail
396 lines = params[:login_list]
393 lines = params[:login_list]
397 if !lines or lines.blank?
394 if !lines or lines.blank?
398 flash[:notice] = 'You entered an empty list.'
395 flash[:notice] = 'You entered an empty list.'
399 redirect_to :action => 'mass_mailing' and return
396 redirect_to :action => 'mass_mailing' and return
400 end
397 end
401
398
402 mail_subject = params[:subject]
399 mail_subject = params[:subject]
403 if !mail_subject or mail_subject.blank?
400 if !mail_subject or mail_subject.blank?
404 flash[:notice] = 'You entered an empty mail subject.'
401 flash[:notice] = 'You entered an empty mail subject.'
405 redirect_to :action => 'mass_mailing' and return
402 redirect_to :action => 'mass_mailing' and return
406 end
403 end
407
404
408 mail_body = params[:email_body]
405 mail_body = params[:email_body]
409 if !mail_body or mail_body.blank?
406 if !mail_body or mail_body.blank?
410 flash[:notice] = 'You entered an empty mail body.'
407 flash[:notice] = 'You entered an empty mail body.'
411 redirect_to :action => 'mass_mailing' and return
408 redirect_to :action => 'mass_mailing' and return
412 end
409 end
413
410
414 note = []
411 note = []
415 users = []
412 users = []
416 lines.split("\n").each do |line|
413 lines.split("\n").each do |line|
417 user = User.find_by_login(line.chomp)
414 user = User.find_by_login(line.chomp)
418 if user
415 if user
419 send_mail(user.email, mail_subject, mail_body)
416 send_mail(user.email, mail_subject, mail_body)
420 note << user.login
417 note << user.login
421 end
418 end
422 end
419 end
423
420
424 flash[:notice] = 'User(s) ' + note.join(', ') +
421 flash[:notice] = 'User(s) ' + note.join(', ') +
425 ' were successfully modified. '
422 ' were successfully modified. '
426 redirect_to :action => 'mass_mailing'
423 redirect_to :action => 'mass_mailing'
427 end
424 end
428
425
429 #bulk manage
426 #bulk manage
430 def bulk_manage
427 def bulk_manage
431
428
432 begin
429 begin
433 @users = User.where('(login REGEXP ?) OR (remark REGEXP ?)',params[:regex],params[:regex]) if params[:regex]
430 @users = User.where('(login REGEXP ?) OR (remark REGEXP ?)',params[:regex],params[:regex]) if params[:regex]
434 @users.count if @users #i don't know why I have to call count, but if I won't exception is not raised
431 @users.count if @users #i don't know why I have to call count, but if I won't exception is not raised
435 rescue Exception
432 rescue Exception
@@ -79,97 +79,101
79 end
79 end
80 end
80 end
81
81
82
82
83 def authenticated?(password)
83 def authenticated?(password)
84 if self.activated
84 if self.activated
85 hashed_password == User.encrypt(password,self.salt)
85 hashed_password == User.encrypt(password,self.salt)
86 else
86 else
87 false
87 false
88 end
88 end
89 end
89 end
90
90
91 def authenticated_by_cucas?(password)
91 def authenticated_by_cucas?(password)
92 url = URI.parse('https://www.cas.chula.ac.th/cas/api/?q=studentAuthenticate')
92 url = URI.parse('https://www.cas.chula.ac.th/cas/api/?q=studentAuthenticate')
93 appid = '41508763e340d5858c00f8c1a0f5a2bb'
93 appid = '41508763e340d5858c00f8c1a0f5a2bb'
94 appsecret ='d9cbb5863091dbe186fded85722a1e31'
94 appsecret ='d9cbb5863091dbe186fded85722a1e31'
95 post_args = {
95 post_args = {
96 'appid' => appid,
96 'appid' => appid,
97 'appsecret' => appsecret,
97 'appsecret' => appsecret,
98 'username' => login,
98 'username' => login,
99 'password' => password
99 'password' => password
100 }
100 }
101
101
102 #simple call
102 #simple call
103 begin
103 begin
104 http = Net::HTTP.new('www.cas.chula.ac.th', 443)
104 http = Net::HTTP.new('www.cas.chula.ac.th', 443)
105 http.use_ssl = true
105 http.use_ssl = true
106 http.verify_mode = OpenSSL::SSL::VERIFY_NONE
106 http.verify_mode = OpenSSL::SSL::VERIFY_NONE
107 result = [ ]
107 result = [ ]
108 http.start do |http|
108 http.start do |http|
109 req = Net::HTTP::Post.new('/cas/api/?q=studentAuthenticate')
109 req = Net::HTTP::Post.new('/cas/api/?q=studentAuthenticate')
110 #req = Net::HTTP::Post.new('/appX/prod/?q=studentAuthenticate')
110 #req = Net::HTTP::Post.new('/appX/prod/?q=studentAuthenticate')
111 #req = Net::HTTP::Post.new('/app2/prod/api/?q=studentAuthenticate')
111 #req = Net::HTTP::Post.new('/app2/prod/api/?q=studentAuthenticate')
112 param = "appid=#{appid}&appsecret=#{appsecret}&username=#{login}&password=#{password}"
112 param = "appid=#{appid}&appsecret=#{appsecret}&username=#{login}&password=#{password}"
113 resp = http.request(req,param)
113 resp = http.request(req,param)
114 result = JSON.parse resp.body
114 result = JSON.parse resp.body
115 puts result
115 puts result
116 end
116 end
117 return true if result["type"] == "beanStudent"
117 return true if result["type"] == "beanStudent"
118 rescue => e
118 rescue => e
119 puts e
119 puts e
120 puts e.message
120 puts e.message
121 return false
121 return false
122 end
122 end
123 return false
123 return false
124 end
124 end
125
125
126 def admin?
126 def admin?
127 - self.roles.where(name: 'admin').count > 0
127 + has_role?('admin')
128 + end
129 +
130 + def has_role?(role)
131 + self.roles.where(name: role).count > 0
128 end
132 end
129
133
130 def email_for_editing
134 def email_for_editing
131 if self.email==nil
135 if self.email==nil
132 "(unknown)"
136 "(unknown)"
133 elsif self.email==''
137 elsif self.email==''
134 "(blank)"
138 "(blank)"
135 else
139 else
136 self.email
140 self.email
137 end
141 end
138 end
142 end
139
143
140 def email_for_editing=(e)
144 def email_for_editing=(e)
141 self.email=e
145 self.email=e
142 end
146 end
143
147
144 def alias_for_editing
148 def alias_for_editing
145 if self.alias==nil
149 if self.alias==nil
146 "(unknown)"
150 "(unknown)"
147 elsif self.alias==''
151 elsif self.alias==''
148 "(blank)"
152 "(blank)"
149 else
153 else
150 self.alias
154 self.alias
151 end
155 end
152 end
156 end
153
157
154 def alias_for_editing=(e)
158 def alias_for_editing=(e)
155 self.alias=e
159 self.alias=e
156 end
160 end
157
161
158 def activation_key
162 def activation_key
159 if self.hashed_password==nil
163 if self.hashed_password==nil
160 encrypt_new_password
164 encrypt_new_password
161 end
165 end
162 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
166 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
163 end
167 end
164
168
165 def verify_activation_key(key)
169 def verify_activation_key(key)
166 key == activation_key
170 key == activation_key
167 end
171 end
168
172
169 def self.random_password(length=5)
173 def self.random_password(length=5)
170 chars = 'abcdefghjkmnopqrstuvwxyz'
174 chars = 'abcdefghjkmnopqrstuvwxyz'
171 password = ''
175 password = ''
172 length.times { password << chars[rand(chars.length - 1)] }
176 length.times { password << chars[rand(chars.length - 1)] }
173 password
177 password
174 end
178 end
175
179
@@ -23,74 +23,74
23 = add_menu("Self Test", 'test', 'index')
23 = add_menu("Self Test", 'test', 'index')
24 / hall of fame
24 / hall of fame
25 - if GraderConfiguration['right.user_hall_of_fame']
25 - if GraderConfiguration['right.user_hall_of_fame']
26 = add_menu("#{I18n.t 'menu.hall_of_fame'}", 'report', 'problem_hof')
26 = add_menu("#{I18n.t 'menu.hall_of_fame'}", 'report', 'problem_hof')
27 / display MODE button (with countdown in contest mode)
27 / display MODE button (with countdown in contest mode)
28 - if GraderConfiguration.analysis_mode?
28 - if GraderConfiguration.analysis_mode?
29 %div.navbar-btn.btn.btn-success#countdown= "ANALYSIS MODE"
29 %div.navbar-btn.btn.btn-success#countdown= "ANALYSIS MODE"
30 - elsif GraderConfiguration.time_limit_mode?
30 - elsif GraderConfiguration.time_limit_mode?
31 - if @current_user.contest_finished?
31 - if @current_user.contest_finished?
32 %div.navbar-btn.btn.btn-danger#countdown= "Contest is over"
32 %div.navbar-btn.btn.btn-danger#countdown= "Contest is over"
33 - elsif !@current_user.contest_started?
33 - elsif !@current_user.contest_started?
34 %div.navbar-btn.btn.btn-primary#countdown= (t 'title_bar.contest_not_started')
34 %div.navbar-btn.btn.btn-primary#countdown= (t 'title_bar.contest_not_started')
35 - else
35 - else
36 %div.navbar-btn.btn.btn-primary#countdown asdf
36 %div.navbar-btn.btn.btn-primary#countdown asdf
37 :javascript
37 :javascript
38 $("#countdown").countdown({until: "+#{@current_user.contest_time_left.to_i}s", layout: 'Time left: {hnn}:{mnn}:{snn}'});
38 $("#countdown").countdown({until: "+#{@current_user.contest_time_left.to_i}s", layout: 'Time left: {hnn}:{mnn}:{snn}'});
39 / admin section
39 / admin section
40 - if (@current_user!=nil) and (session[:admin])
40 - if (@current_user!=nil) and (session[:admin])
41 / management
41 / management
42 %li.dropdown
42 %li.dropdown
43 %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
43 %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
44 Manage
44 Manage
45 %span.caret
45 %span.caret
46 %ul.dropdown-menu
46 %ul.dropdown-menu
47 = add_menu( 'Announcements', 'announcements', 'index')
47 = add_menu( 'Announcements', 'announcements', 'index')
48 = add_menu( 'Problems', 'problems', 'index')
48 = add_menu( 'Problems', 'problems', 'index')
49 = add_menu( 'Tags', 'tags', 'index')
49 = add_menu( 'Tags', 'tags', 'index')
50 = add_menu( 'Users', 'user_admin', 'index')
50 = add_menu( 'Users', 'user_admin', 'index')
51 = add_menu( 'User Groups', 'groups', 'index')
51 = add_menu( 'User Groups', 'groups', 'index')
52 = add_menu( 'Graders', 'graders', 'list')
52 = add_menu( 'Graders', 'graders', 'list')
53 = add_menu( 'Message ', 'messages', 'console')
53 = add_menu( 'Message ', 'messages', 'console')
54 %li.divider{role: 'separator'}
54 %li.divider{role: 'separator'}
55 = add_menu( 'System config', 'configurations', 'index')
55 = add_menu( 'System config', 'configurations', 'index')
56 %li.divider{role: 'separator'}
56 %li.divider{role: 'separator'}
57 = add_menu( 'Sites', 'sites', 'index')
57 = add_menu( 'Sites', 'sites', 'index')
58 = add_menu( 'Contests', 'contest_management', 'index')
58 = add_menu( 'Contests', 'contest_management', 'index')
59 / report
59 / report
60 %li.dropdown
60 %li.dropdown
61 %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
61 %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
62 Report
62 Report
63 %span.caret
63 %span.caret
64 %ul.dropdown-menu
64 %ul.dropdown-menu
65 = add_menu( 'Current Score', 'report', 'current_score')
65 = add_menu( 'Current Score', 'report', 'current_score')
66 = add_menu( 'Score Report', 'report', 'max_score')
66 = add_menu( 'Score Report', 'report', 'max_score')
67 = add_menu( 'Submission Report', 'report', 'submission')
67 = add_menu( 'Submission Report', 'report', 'submission')
68 = add_menu( 'Login Report', 'report', 'login')
68 = add_menu( 'Login Report', 'report', 'login')
69 - if (ungraded = Submission.where('graded_at is null').where('submitted_at < ?', 1.minutes.ago).count) > 0
69 - if (ungraded = Submission.where('graded_at is null').where('submitted_at < ?', 1.minutes.ago).count) > 0
70 =link_to "#{ungraded} backlogs!",
70 =link_to "#{ungraded} backlogs!",
71 - grader_list_path,
71 + graders_list_path,
72 class: 'navbar-btn btn btn-default btn-warning', data: {toggle: 'tooltip'},title: 'Number of ungraded submission'
72 class: 'navbar-btn btn btn-default btn-warning', data: {toggle: 'tooltip'},title: 'Number of ungraded submission'
73
73
74 %ul.nav.navbar-nav.navbar-right
74 %ul.nav.navbar-nav.navbar-right
75 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-question-sign')}".html_safe, 'main', 'help')
75 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-question-sign')}".html_safe, 'main', 'help')
76 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-comment')}".html_safe, 'messages', 'index', {title: I18n.t('menu.messages'), data: {toggle: 'tooltip'}})
76 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-comment')}".html_safe, 'messages', 'index', {title: I18n.t('menu.messages'), data: {toggle: 'tooltip'}})
77 - if GraderConfiguration['system.user_setting_enabled']
77 - if GraderConfiguration['system.user_setting_enabled']
78 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-cog', id: 'user_profile')}".html_safe, 'users', 'profile', {title: I18n.t('menu.settings'), data: {toggle: 'tooltip'}})
78 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-cog', id: 'user_profile')}".html_safe, 'users', 'profile', {title: I18n.t('menu.settings'), data: {toggle: 'tooltip'}})
79 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-log-out')} #{@current_user.full_name}".html_safe, 'main', 'login', {title: I18n.t('menu.log_out'), data: {toggle: 'tooltip'}})
79 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-log-out')} #{@current_user.full_name}".html_safe, 'main', 'login', {title: I18n.t('menu.log_out'), data: {toggle: 'tooltip'}})
80
80
81 /
81 /
82 - if (@current_user!=nil) and (session[:admin])
82 - if (@current_user!=nil) and (session[:admin])
83 %nav.navbar.navbar-fixed-top.navbar-inverse.secondnavbar
83 %nav.navbar.navbar-fixed-top.navbar-inverse.secondnavbar
84 .container-fluid
84 .container-fluid
85 .collapse.navbar-collapse
85 .collapse.navbar-collapse
86 %ul.nav.navbar-nav
86 %ul.nav.navbar-nav
87 = add_menu( '[Announcements]', 'announcements', 'index')
87 = add_menu( '[Announcements]', 'announcements', 'index')
88 = add_menu( '[Msg console]', 'messages', 'console')
88 = add_menu( '[Msg console]', 'messages', 'console')
89 = add_menu( '[Problems]', 'problems', 'index')
89 = add_menu( '[Problems]', 'problems', 'index')
90 = add_menu( '[Users]', 'user_admin', 'index')
90 = add_menu( '[Users]', 'user_admin', 'index')
91 = add_menu( '[Results]', 'user_admin', 'user_stat')
91 = add_menu( '[Results]', 'user_admin', 'user_stat')
92 = add_menu( '[Report]', 'report', 'multiple_login')
92 = add_menu( '[Report]', 'report', 'multiple_login')
93 = add_menu( '[Graders]', 'graders', 'list')
93 = add_menu( '[Graders]', 'graders', 'list')
94 = add_menu( '[Contests]', 'contest_management', 'index')
94 = add_menu( '[Contests]', 'contest_management', 'index')
95 = add_menu( '[Sites]', 'sites', 'index')
95 = add_menu( '[Sites]', 'sites', 'index')
96 = add_menu( '[System config]', 'configurations', 'index')
96 = add_menu( '[System config]', 'configurations', 'index')
@@ -1,59 +1,63
1 :css
1 :css
2 .fix-width {
2 .fix-width {
3 font-family: "Consolas, Monaco, Droid Sans Mono,Mono, Monospace,Courier"
3 font-family: "Consolas, Monaco, Droid Sans Mono,Mono, Monospace,Courier"
4 }
4 }
5
5
6 %h1 Problem stat: #{@problem.name}
6 %h1 Problem stat: #{@problem.name}
7 %h2 Overview
7 %h2 Overview
8
8
9 + .row
10 + .col-md-2
11 + %strong Name:
12 + .col-md-10
13 + = @problem.full_name #in_place_editor_field :problem, :full_name, {}, :rows=>1
14 + = link_to_description_if_any "[#{t 'main.problem_desc'}] <span class='glyphicon glyphicon-file'></span>".html_safe, @problem
15 + .row
16 + .col-md-2.strong
17 + %strong Submissions:
18 + .col-md-10
19 + = @submissions.count
20 + .row
21 + .col-md-2.strong
22 + %strong Solved/Attemped User
23 + .col-md-10
24 + #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%)
9
25
10 - %table.info
11 - %thead
12 - %tr.info-head
13 - %th Stat
14 - %th Value
15 - %tbody
16 - %tr{class: cycle('info-even','info-odd')}
17 - %td Submissions
18 - %td= @submissions.count
19 - %tr{class: cycle('info-even','info-odd')}
20 - %td Solved/Attempted User
21 - %td #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%)
22
26
23 %h2 Submissions Count
27 %h2 Submissions Count
24 = render partial: 'application/bar_graph', locals: { histogram: @histogram }
28 = render partial: 'application/bar_graph', locals: { histogram: @histogram }
25
29
26 %h2 Submissions
30 %h2 Submissions
27 - if @submissions and @submissions.count > 0
31 - if @submissions and @submissions.count > 0
28 %table#main_table.table.table-condensed.table-striped
32 %table#main_table.table.table-condensed.table-striped
29 %thead
33 %thead
30 %tr
34 %tr
31 %th ID
35 %th ID
32 %th Login
36 %th Login
33 %th Name
37 %th Name
34 %th Submitted_at
38 %th Submitted_at
35 %th language
39 %th language
36 %th Points
40 %th Points
37 %th comment
41 %th comment
38 %th IP
42 %th IP
39 %tbody
43 %tbody
40 - row_odd,curr = true,''
44 - row_odd,curr = true,''
41 - @submissions.each do |sub|
45 - @submissions.each do |sub|
42 - next unless sub.user
46 - next unless sub.user
43 - row_odd,curr = !row_odd, sub.user if curr != sub.user
47 - row_odd,curr = !row_odd, sub.user if curr != sub.user
44 %tr
48 %tr
45 %td= link_to sub.id, submission_path(sub)
49 %td= link_to sub.id, submission_path(sub)
46 %td= link_to sub.user.login, stat_user_path(sub.user)
50 %td= link_to sub.user.login, stat_user_path(sub.user)
47 %td= sub.user.full_name
51 %td= sub.user.full_name
48 %td{data: {order: sub.submitted_at}}= time_ago_in_words(sub.submitted_at) + " ago"
52 %td{data: {order: sub.submitted_at}}= time_ago_in_words(sub.submitted_at) + " ago"
49 %td= sub.language.name
53 %td= sub.language.name
50 %td= sub.points
54 %td= sub.points
51 %td.fix-width= sub.grader_comment
55 %td.fix-width= sub.grader_comment
52 %td= sub.ip_address
56 %td= sub.ip_address
53 - else
57 - else
54 No submission
58 No submission
55
59
56 :javascript
60 :javascript
57 $("#main_table").DataTable({
61 $("#main_table").DataTable({
58 paging: false
62 paging: false
59 });
63 });
@@ -1,25 +1,54
1 - %h1 Administrators
1 + %h1 Modify Role
2 -
2 + .row
3 - %table{:class => 'info'}
3 + .col-md-6
4 - %tr{:class => 'info-head'}
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'}
5 %th #
15 %th #
6 %th Login
16 %th Login
7 %th Full name
17 %th Full name
8 %th
18 %th
9 - @admins.each_with_index do |user, i|
19 - @admins.each_with_index do |user, i|
10 %tr
20 %tr
11 %td= i+1
21 %td= i+1
12 %td= user.login
22 %td= user.login
13 %td= user.full_name
23 %td= user.full_name
14 %td
24 %td
15 - if user.login!='root'
25 - if user.login!='root'
16 - = link_to '[revoke]', :action => 'revoke_admin', :id => user.id
26 + = link_to '[revoke]', modify_role_user_admin_index_path( login: user.login, role: 'admin', commit: 'revoke')
17 - %hr
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')
18
51
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 %hr/
53 %hr/
25 = link_to '[go back to index]', :action => 'index'
54 = link_to '[go back to index]', :action => 'index'
@@ -68,144 +68,144
68 end
68 end
69 collection do
69 collection do
70 get 'show_problem/:problem_id(/:test_num)' => 'testcases#show_problem', as: 'show_problem'
70 get 'show_problem/:problem_id(/:test_num)' => 'testcases#show_problem', as: 'show_problem'
71 end
71 end
72 end
72 end
73
73
74 resources :grader_configuration, controller: 'configurations' do
74 resources :grader_configuration, controller: 'configurations' do
75 collection do
75 collection do
76 get 'set_exam_right(/:value)', action: 'set_exam_right', as: 'set_exam_right'
76 get 'set_exam_right(/:value)', action: 'set_exam_right', as: 'set_exam_right'
77 end
77 end
78 end
78 end
79
79
80 resources :users do
80 resources :users do
81 member do
81 member do
82 get 'toggle_activate', 'toggle_enable'
82 get 'toggle_activate', 'toggle_enable'
83 get 'stat'
83 get 'stat'
84 end
84 end
85 collection do
85 collection do
86 get 'profile'
86 get 'profile'
87 post 'chg_passwd'
87 post 'chg_passwd'
88 end
88 end
89 end
89 end
90
90
91 resources :submissions do
91 resources :submissions do
92 member do
92 member do
93 get 'download'
93 get 'download'
94 get 'compiler_msg'
94 get 'compiler_msg'
95 get 'rejudge'
95 get 'rejudge'
96 end
96 end
97 collection do
97 collection do
98 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
98 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
99 get 'direct_edit_problem/:problem_id(/:user_id)', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
99 get 'direct_edit_problem/:problem_id(/:user_id)', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
100 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
100 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
101 end
101 end
102 end
102 end
103
103
104
104
105 #user admin
105 #user admin
106 resources :user_admin do
106 resources :user_admin do
107 collection do
107 collection do
108 match 'bulk_manage', via: [:get, :post]
108 match 'bulk_manage', via: [:get, :post]
109 get 'bulk_mail'
109 get 'bulk_mail'
110 get 'user_stat'
110 get 'user_stat'
111 get 'import'
111 get 'import'
112 get 'new_list'
112 get 'new_list'
113 get 'admin'
113 get 'admin'
114 get 'active'
114 get 'active'
115 get 'mass_mailing'
115 get 'mass_mailing'
116 - get 'revoke_admin'
116 + match 'modify_role', via: [:get, :post]
117 - post 'grant_admin'
118 match 'create_from_list', via: [:get, :post]
117 match 'create_from_list', via: [:get, :post]
119 match 'random_all_passwords', via: [:get, :post]
118 match 'random_all_passwords', via: [:get, :post]
120 end
119 end
121 member do
120 member do
122 get 'clear_last_ip'
121 get 'clear_last_ip'
123 end
122 end
124 end
123 end
125
124
126 resources :contest_management, only: [:index] do
125 resources :contest_management, only: [:index] do
127 collection do
126 collection do
128 get 'user_stat'
127 get 'user_stat'
129 get 'clear_stat'
128 get 'clear_stat'
130 get 'clear_all_stat'
129 get 'clear_all_stat'
131 get 'change_contest_mode'
130 get 'change_contest_mode'
132 end
131 end
133 end
132 end
134
133
135 #get 'user_admin', to: 'user_admin#index'
134 #get 'user_admin', to: 'user_admin#index'
136 #get 'user_admin/bulk_manage', to: 'user_admin#bulk_manage', as: 'bulk_manage_user_admin'
135 #get 'user_admin/bulk_manage', to: 'user_admin#bulk_manage', as: 'bulk_manage_user_admin'
137 #post 'user_admin', to: 'user_admin#create'
136 #post 'user_admin', to: 'user_admin#create'
138 #delete 'user_admin/:id', to: 'user_admin#destroy', as: 'user_admin_destroy'
137 #delete 'user_admin/:id', to: 'user_admin#destroy', as: 'user_admin_destroy'
139
138
140 #singular resource
139 #singular resource
141 #---- BEWARE ---- singular resource maps to plural controller by default, we can override by provide controller name directly
140 #---- BEWARE ---- singular resource maps to plural controller by default, we can override by provide controller name directly
142 #report
141 #report
143 resource :report, only: [], controller: 'report' do
142 resource :report, only: [], controller: 'report' do
144 get 'login'
143 get 'login'
145 get 'multiple_login'
144 get 'multiple_login'
146 get 'problem_hof(/:id)', action: 'problem_hof', as: 'problem_hof'
145 get 'problem_hof(/:id)', action: 'problem_hof', as: 'problem_hof'
147 get 'current_score(/:group_id)', action: 'current_score', as: 'current_score'
146 get 'current_score(/:group_id)', action: 'current_score', as: 'current_score'
148 get 'max_score'
147 get 'max_score'
149 post 'show_max_score'
148 post 'show_max_score'
150 get 'stuck'
149 get 'stuck'
151 get 'cheat_report'
150 get 'cheat_report'
152 post 'cheat_report'
151 post 'cheat_report'
153 get 'cheat_scrutinize'
152 get 'cheat_scrutinize'
154 post 'cheat_scrutinize'
153 post 'cheat_scrutinize'
155 get 'submission'
154 get 'submission'
156 post 'submission_query'
155 post 'submission_query'
157 get 'login_stat'
156 get 'login_stat'
158 post 'login_stat'
157 post 'login_stat'
159 get 'login'
158 get 'login'
160 post 'login_summary_query'
159 post 'login_summary_query'
161 post 'login_detail_query'
160 post 'login_detail_query'
162 end
161 end
163 #get 'report/current_score', to: 'report#current_score', as: 'report_current_score'
162 #get 'report/current_score', to: 'report#current_score', as: 'report_current_score'
164 #get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
163 #get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
165 #get "report/login"
164 #get "report/login"
166 #get 'report/max_score', to: 'report#max_score', as: 'report_max_score'
165 #get 'report/max_score', to: 'report#max_score', as: 'report_max_score'
167 #post 'report/show_max_score', to: 'report#show_max_score', as: 'report_show_max_score'
166 #post 'report/show_max_score', to: 'report#show_max_score', as: 'report_show_max_score'
168
167
169 resource :main, only: [], controller: 'main' do
168 resource :main, only: [], controller: 'main' do
170 get 'login'
169 get 'login'
171 get 'logout'
170 get 'logout'
172 get 'list'
171 get 'list'
173 get 'submission(/:id)', action: 'submission', as: 'main_submission'
172 get 'submission(/:id)', action: 'submission', as: 'main_submission'
174 get 'announcements'
173 get 'announcements'
175 get 'help'
174 get 'help'
176 post 'submit'
175 post 'submit'
177 end
176 end
178 #main
177 #main
179 #get "main/list"
178 #get "main/list"
180 #get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
179 #get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
181 #post 'main/submit', to: 'main#submit'
180 #post 'main/submit', to: 'main#submit'
182 #get 'main/announcements', to: 'main#announcements'
181 #get 'main/announcements', to: 'main#announcements'
183
182
184
183
185 #
184 #
186 get 'tasks/view/:file.:ext' => 'tasks#view'
185 get 'tasks/view/:file.:ext' => 'tasks#view'
187 get 'tasks/download/:id/:file.:ext' => 'tasks#download', as: 'download_task'
186 get 'tasks/download/:id/:file.:ext' => 'tasks#download', as: 'download_task'
188 get 'heartbeat/:id/edit' => 'heartbeat#edit'
187 get 'heartbeat/:id/edit' => 'heartbeat#edit'
189
188
190 #grader
189 #grader
191 - get 'graders/list', to: 'graders#list', as: 'grader_list'
190 + #get 'graders/list', to: 'graders#list', as: 'grader_list'
192 namespace :graders do
191 namespace :graders do
193 get 'task/:id/:type', action: 'task', as: 'task'
192 get 'task/:id/:type', action: 'task', as: 'task'
194 get 'view/:id/:type', action: 'view', as: 'view'
193 get 'view/:id/:type', action: 'view', as: 'view'
195 get 'clear/:id', action: 'clear', as: 'clear'
194 get 'clear/:id', action: 'clear', as: 'clear'
196 - get 'stop'
197 - get 'stop_all'
198 - get 'clear_all'
199 - get 'clear_terminated'
200 get 'start_grading'
195 get 'start_grading'
201 get 'start_exam'
196 get 'start_exam'
197 + get 'clear_all'
198 + get 'stop_all'
202
199
200 + get 'stop'
201 + get 'clear_terminated'
202 + get 'list'
203 end
203 end
204
204
205
205
206 # See how all your routes lay out with "rake routes"
206 # See how all your routes lay out with "rake routes"
207
207
208 # This is a legacy wild controller route that's not recommended for RESTful applications.
208 # This is a legacy wild controller route that's not recommended for RESTful applications.
209 # Note: This route will make all actions in every controller accessible via GET requests.
209 # Note: This route will make all actions in every controller accessible via GET requests.
210 # match ':controller(/:action(/:id))(.:format)', via: [:get, :post]
210 # match ':controller(/:action(/:id))(.:format)', via: [:get, :post]
211 end
211 end
@@ -180,96 +180,97
180 :description => "If true, available problem to the user will be only ones associated with the group of the user."
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 :key => 'right.whitelist_ignore',
185 :key => 'right.whitelist_ignore',
186 :value_type => 'boolean',
186 :value_type => 'boolean',
187 :default_value => 'true',
187 :default_value => 'true',
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."
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 :key => 'right.whitelist_ip',
192 :key => 'right.whitelist_ip',
193 :value_type => 'string',
193 :value_type => 'string',
194 :default_value => '0.0.0.0/0',
194 :default_value => '0.0.0.0/0',
195 :description => "list of whitelist ip, given in comma separated CIDR notation. For example '192.168.90.0/23, 192.168.1.23/32'"
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 def create_configuration_key(key,
201 def create_configuration_key(key,
202 value_type,
202 value_type,
203 default_value,
203 default_value,
204 description='')
204 description='')
205 conf = (GraderConfiguration.find_by_key(key) ||
205 conf = (GraderConfiguration.find_by_key(key) ||
206 GraderConfiguration.new(:key => key,
206 GraderConfiguration.new(:key => key,
207 :value_type => value_type,
207 :value_type => value_type,
208 :value => default_value))
208 :value => default_value))
209 conf.description = description
209 conf.description = description
210 conf.save
210 conf.save
211 end
211 end
212
212
213 def seed_config
213 def seed_config
214 CONFIGURATIONS.each do |conf|
214 CONFIGURATIONS.each do |conf|
215 if conf.has_key? :description
215 if conf.has_key? :description
216 desc = conf[:description]
216 desc = conf[:description]
217 else
217 else
218 desc = ''
218 desc = ''
219 end
219 end
220 create_configuration_key(conf[:key],
220 create_configuration_key(conf[:key],
221 conf[:value_type],
221 conf[:value_type],
222 conf[:default_value],
222 conf[:default_value],
223 desc)
223 desc)
224 end
224 end
225 end
225 end
226
226
227 def seed_roles
227 def seed_roles
228 + Role.find_or_create_by(name: 'TA')
228 return if Role.find_by_name('admin')
229 return if Role.find_by_name('admin')
229
230
230 role = Role.create(:name => 'admin')
231 role = Role.create(:name => 'admin')
231 user_admin_right = Right.create(:name => 'user_admin',
232 user_admin_right = Right.create(:name => 'user_admin',
232 :controller => 'user_admin',
233 :controller => 'user_admin',
233 :action => 'all')
234 :action => 'all')
234 problem_admin_right = Right.create(:name=> 'problem_admin',
235 problem_admin_right = Right.create(:name=> 'problem_admin',
235 :controller => 'problems',
236 :controller => 'problems',
236 :action => 'all')
237 :action => 'all')
237
238
238 graders_right = Right.create(:name => 'graders_admin',
239 graders_right = Right.create(:name => 'graders_admin',
239 :controller => 'graders',
240 :controller => 'graders',
240 :action => 'all')
241 :action => 'all')
241
242
242 role.rights << user_admin_right;
243 role.rights << user_admin_right;
243 role.rights << problem_admin_right;
244 role.rights << problem_admin_right;
244 role.rights << graders_right;
245 role.rights << graders_right;
245 role.save
246 role.save
246 end
247 end
247
248
248 def seed_root
249 def seed_root
249 return if User.find_by_login('root')
250 return if User.find_by_login('root')
250
251
251 root = User.new(:login => 'root',
252 root = User.new(:login => 'root',
252 :full_name => 'Administrator',
253 :full_name => 'Administrator',
253 :alias => 'root')
254 :alias => 'root')
254 root.password = 'ioionrails';
255 root.password = 'ioionrails';
255
256
256 class << root
257 class << root
257 public :encrypt_new_password
258 public :encrypt_new_password
258 def valid?(context=nil)
259 def valid?(context=nil)
259 true
260 true
260 end
261 end
261 end
262 end
262
263
263 root.encrypt_new_password
264 root.encrypt_new_password
264
265
265 root.roles << Role.find_by_name('admin')
266 root.roles << Role.find_by_name('admin')
266
267
267 root.activated = true
268 root.activated = true
268 root.save
269 root.save
269 end
270 end
270
271
271 def seed_users_and_roles
272 def seed_users_and_roles
272 seed_roles
273 seed_roles
273 seed_root
274 seed_root
274 end
275 end
275
276
You need to be logged in to leave comments. Login now