Description:
allow ta to view problem stat
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r803:30dd5b343f6b - - 2 files changed: 5 inserted, 3 deleted

@@ -1,230 +1,229
1 1 require 'ipaddr'
2 2
3 3 class ApplicationController < ActionController::Base
4 4 protect_from_forgery
5 5
6 6 before_action :current_user
7 7
8 8 SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode'
9 9 MULTIPLE_IP_LOGIN_CONF_KEY = 'right.multiple_ip_login'
10 10 WHITELIST_IGNORE_CONF_KEY = 'right.whitelist_ignore'
11 11 WHITELIST_IP_CONF_KEY = 'right.whitelist_ip'
12 12
13 13 #report and redirect for unauthorized activities
14 14 def unauthorized_redirect(notice = 'You are not authorized to view the page you requested')
15 15 flash[:notice] = notice
16 16 redirect_to login_main_path
17 17 end
18 18
19 19 # Returns the current logged-in user (if any).
20 20 def current_user
21 21 return nil unless session[:user_id]
22 22 @current_user ||= User.find(session[:user_id])
23 23 end
24 24
25 25 def admin_authorization
26 26 return false unless check_valid_login
27 27 user = User.includes(:roles).find(session[:user_id])
28 28 unless user.admin?
29 29 unauthorized_redirect
30 30 return false
31 31 end
32 32 return true
33 33 end
34 34
35 35 def authorization_by_roles(allowed_roles)
36 36 return false unless check_valid_login
37 - user = User.find(session[:user_id])
38 - unless user.roles.detect { |role| allowed_roles.member?(role.name) }
37 + unless @current_user.roles.detect { |role| allowed_roles.member?(role.name) }
39 38 unauthorized_redirect
40 39 return false
41 40 end
42 41 end
43 42
44 43 def testcase_authorization
45 44 #admin always has privileged
46 45 if @current_user.admin?
47 46 return true
48 47 end
49 48
50 49 unauthorized_redirect unless GraderConfiguration["right.view_testcase"]
51 50 end
52 51
53 52
54 53 protected
55 54
56 55 #redirect to root (and also force logout)
57 56 #if the user is not logged_in or the system is in "ADMIN ONLY" mode
58 57 def check_valid_login
59 58 #check if logged in
60 59 unless session[:user_id]
61 60 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
62 61 unauthorized_redirect('You need to login but you cannot log in at this time')
63 62 else
64 63 unauthorized_redirect('You need to login')
65 64 end
66 65 return false
67 66 end
68 67
69 68 # check if run in single user mode
70 69 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
71 70 if @current_user==nil || (!@current_user.admin?)
72 71 unauthorized_redirect('You cannot log in at this time')
73 72 return false
74 73 end
75 74 end
76 75
77 76 # check if the user is enabled
78 77 unless @current_user.enabled? || @current_user.admin?
79 78 unauthorized_redirect 'Your account is disabled'
80 79 return false
81 80 end
82 81
83 82 # check if user ip is allowed
84 83 unless @current_user.admin? || GraderConfiguration[WHITELIST_IGNORE_CONF_KEY]
85 84 unless is_request_ip_allowed?
86 85 unauthorized_redirect 'Your IP is not allowed to login at this time.'
87 86 return false
88 87 end
89 88 end
90 89
91 90 if GraderConfiguration.multicontests?
92 91 return true if @current_user.admin?
93 92 begin
94 93 if @current_user.contest_stat(true).forced_logout
95 94 flash[:notice] = 'You have been automatically logged out.'
96 95 redirect_to :controller => 'main', :action => 'index'
97 96 end
98 97 rescue
99 98 end
100 99 end
101 100 return true
102 101 end
103 102
104 103 #redirect to root (and also force logout)
105 104 #if the user use different ip from the previous connection
106 105 # only applicable when MULTIPLE_IP_LOGIN options is false only
107 106 def authenticate_by_ip_address
108 107 #this assume that we have already authenticate normally
109 108 unless GraderConfiguration[MULTIPLE_IP_LOGIN_CONF_KEY]
110 109 user = User.find(session[:user_id])
111 110 if (!user.admin? && user.last_ip && user.last_ip != request.remote_ip)
112 111 flash[:notice] = "You cannot use the system from #{request.remote_ip}. Your last ip is #{user.last_ip}"
113 112 redirect_to :controller => 'main', :action => 'login'
114 113 return false
115 114 end
116 115 unless user.last_ip
117 116 user.last_ip = request.remote_ip
118 117 user.save
119 118 end
120 119 end
121 120 return true
122 121 end
123 122
124 123 def authorization
125 124 return false unless check_valid_login
126 125 user = User.find(session[:user_id])
127 126 unless user.roles.detect { |role|
128 127 role.rights.detect{ |right|
129 128 right.controller == self.class.controller_name and
130 129 (right.action == 'all' || right.action == action_name)
131 130 }
132 131 }
133 132 flash[:notice] = 'You are not authorized to view the page you requested'
134 133 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
135 134 redirect_to :controller => 'main', :action => 'login'
136 135 return false
137 136 end
138 137 end
139 138
140 139 def verify_time_limit
141 140 return true if session[:user_id]==nil
142 141 user = User.find(session[:user_id], :include => :site)
143 142 return true if user==nil || user.site == nil
144 143 if user.contest_finished?
145 144 flash[:notice] = 'Error: the contest you are participating is over.'
146 145 redirect_to :back
147 146 return false
148 147 end
149 148 return true
150 149 end
151 150
152 151 def is_request_ip_allowed?
153 152 unless GraderConfiguration[WHITELIST_IGNORE_CONF_KEY]
154 153 user_ip = IPAddr.new(request.remote_ip)
155 154 allowed = GraderConfiguration[WHITELIST_IP_CONF_KEY] || ''
156 155
157 156 allowed.delete(' ').split(',').each do |ips|
158 157 allow_ips = IPAddr.new(ips)
159 158 if allow_ips.include?(user_ip)
160 159 return true
161 160 end
162 161 end
163 162 return false
164 163 end
165 164 return true
166 165 end
167 166
168 167 #function for datatable ajax query
169 168 #return record,total_count,filter_count
170 169 def process_query_record(record,
171 170 total_count: nil,
172 171 select: '',
173 172 global_search: [],
174 173 no_search: false,
175 174 force_order: '',
176 175 date_filter: '', date_param_since: 'date_since',date_param_until: 'date_until',
177 176 hard_limit: nil)
178 177 arel_table = record.model.arel_table
179 178
180 179 if !no_search && params['search']
181 180 global_value = record.model.sanitize_sql(params['search']['value'].strip.downcase)
182 181 if !global_value.blank?
183 182 global_value.split.each do |value|
184 183 global_where = global_search.map{|f| "LOWER(#{f}) like '%#{value}%'"}.join(' OR ')
185 184 record = record.where(global_where)
186 185 end
187 186 end
188 187
189 188 params['columns'].each do |i, col|
190 189 if !col['search']['value'].blank?
191 190 record = record.where(arel_table[col['name']].lower.matches("%#{col['search']['value'].strip.downcase}%"))
192 191 end
193 192 end
194 193 end
195 194
196 195 if !date_filter.blank?
197 196 param_since = params[date_param_since]
198 197 param_until = params[date_param_until]
199 198 date_since = Time.zone.parse( param_since ) || Time.new(1,1,1) rescue Time.new(1,1,1)
200 199 date_until = Time.zone.parse( param_until ) || Time.zone.now() rescue Time.zone.now()
201 200 date_range = date_since..(date_until.end_of_day)
202 201 record = record.where(date_filter.to_sym => date_range)
203 202 end
204 203
205 204 if force_order.blank?
206 205 if params['order']
207 206 params['order'].each do |i, o|
208 207 colName = params['columns'][o['column']]['name']
209 208 colName = "#{record.model.table_name}.#{colName}" if colName.upcase == 'ID'
210 209 record = record.order("#{colName} #{o['dir'].casecmp('desc') != 0 ? 'ASC' : 'DESC'}") unless colName.blank?
211 210 end
212 211 end
213 212 else
214 213 record = record.order(force_order)
215 214 end
216 215
217 216 filterCount = record.count(record.model.primary_key)
218 217 # if .group() is used, filterCount might be like {id_1: count_1, id_2: count_2, ...}
219 218 # so we should count the result again..
220 219 if filterCount.is_a? Hash
221 220 filterCount = filterCount.count
222 221 end
223 222
224 223
225 224 record = record.offset(params['start'] || 0)
226 225 record = record.limit(hard_limit)
227 226 if (params['length'])
228 227 limit = params['length'].to_i
229 228 limit == hard_limit if (hard_limit && hard_limit < limit)
230 229 record = record.limit(limit)
@@ -1,195 +1,198
1 1 class ProblemsController < ApplicationController
2 2
3 - before_action :admin_authorization
3 + before_action :admin_authorization, except: [:stat]
4 + before_action only: [:stat] do
5 + authorization_by_roles(['admin','ta'])
6 + end
4 7
5 8 in_place_edit_for :problem, :name
6 9 in_place_edit_for :problem, :full_name
7 10 in_place_edit_for :problem, :full_score
8 11
9 12 def index
10 13 @problems = Problem.order(date_added: :desc)
11 14 end
12 15
13 16
14 17 def show
15 18 @problem = Problem.find(params[:id])
16 19 end
17 20
18 21 def new
19 22 @problem = Problem.new
20 23 @description = nil
21 24 end
22 25
23 26 def create
24 27 @problem = Problem.new(problem_params)
25 28 @description = Description.new(description_params)
26 29 if @description.body!=''
27 30 if !@description.save
28 31 render :action => new and return
29 32 end
30 33 else
31 34 @description = nil
32 35 end
33 36 @problem.description = @description
34 37 if @problem.save
35 38 flash[:notice] = 'Problem was successfully created.'
36 39 redirect_to action: :index
37 40 else
38 41 render :action => 'new'
39 42 end
40 43 end
41 44
42 45 def quick_create
43 46 @problem = Problem.new(problem_params)
44 47 @problem.full_name = @problem.name if @problem.full_name == ''
45 48 @problem.full_score = 100
46 49 @problem.available = false
47 50 @problem.test_allowed = true
48 51 @problem.output_only = false
49 52 @problem.date_added = Time.new
50 53 if @problem.save
51 54 flash[:notice] = 'Problem was successfully created.'
52 55 redirect_to action: :index
53 56 else
54 57 flash[:notice] = 'Error saving problem'
55 58 redirect_to action: :index
56 59 end
57 60 end
58 61
59 62 def edit
60 63 @problem = Problem.find(params[:id])
61 64 @description = @problem.description
62 65 end
63 66
64 67 def update
65 68 @problem = Problem.find(params[:id])
66 69 @description = @problem.description
67 70 if @description.nil? and params[:description][:body]!=''
68 71 @description = Description.new(description_params)
69 72 if !@description.save
70 73 flash[:notice] = 'Error saving description'
71 74 render :action => 'edit' and return
72 75 end
73 76 @problem.description = @description
74 77 elsif @description
75 78 if !@description.update_attributes(description_params)
76 79 flash[:notice] = 'Error saving description'
77 80 render :action => 'edit' and return
78 81 end
79 82 end
80 83 if params[:file] and params[:file].content_type != 'application/pdf'
81 84 flash[:notice] = 'Error: Uploaded file is not PDF'
82 85 render :action => 'edit' and return
83 86 end
84 87 if @problem.update_attributes(problem_params)
85 88 flash[:notice] = 'Problem was successfully updated.'
86 89 unless params[:file] == nil or params[:file] == ''
87 90 flash[:notice] = 'Problem was successfully updated and a new PDF file is uploaded.'
88 91 out_dirname = "#{Problem.download_file_basedir}/#{@problem.id}"
89 92 if not FileTest.exists? out_dirname
90 93 Dir.mkdir out_dirname
91 94 end
92 95
93 96 out_filename = "#{out_dirname}/#{@problem.name}.pdf"
94 97 if FileTest.exists? out_filename
95 98 File.delete out_filename
96 99 end
97 100
98 101 File.open(out_filename,"wb") do |file|
99 102 file.write(params[:file].read)
100 103 end
101 104 @problem.description_filename = "#{@problem.name}.pdf"
102 105 @problem.save
103 106 end
104 107 redirect_to :action => 'show', :id => @problem
105 108 else
106 109 render :action => 'edit'
107 110 end
108 111 end
109 112
110 113 def destroy
111 114 p = Problem.find(params[:id]).destroy
112 115 redirect_to action: :index
113 116 end
114 117
115 118 def toggle
116 119 @problem = Problem.find(params[:id])
117 120 @problem.update_attributes(available: !(@problem.available) )
118 121 respond_to do |format|
119 122 format.js { }
120 123 end
121 124 end
122 125
123 126 def toggle_test
124 127 @problem = Problem.find(params[:id])
125 128 @problem.update_attributes(test_allowed: !(@problem.test_allowed?) )
126 129 respond_to do |format|
127 130 format.js { }
128 131 end
129 132 end
130 133
131 134 def toggle_view_testcase
132 135 @problem = Problem.find(params[:id])
133 136 @problem.update_attributes(view_testcase: !(@problem.view_testcase?) )
134 137 respond_to do |format|
135 138 format.js { }
136 139 end
137 140 end
138 141
139 142 def turn_all_off
140 143 Problem.available.all.each do |problem|
141 144 problem.available = false
142 145 problem.save
143 146 end
144 147 redirect_to action: :index
145 148 end
146 149
147 150 def turn_all_on
148 151 Problem.where.not(available: true).each do |problem|
149 152 problem.available = true
150 153 problem.save
151 154 end
152 155 redirect_to action: :index
153 156 end
154 157
155 158 def stat
156 159 @problem = Problem.find(params[:id])
157 160 unless @problem.available or session[:admin]
158 161 redirect_to :controller => 'main', :action => 'list'
159 162 return
160 163 end
161 164 @submissions = Submission.includes(:user).includes(:language).where(problem_id: params[:id]).order(:user_id,:id)
162 165
163 166 #stat summary
164 167 range =65
165 168 @histogram = { data: Array.new(range,0), summary: {} }
166 169 user = Hash.new(0)
167 170 @submissions.find_each do |sub|
168 171 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
169 172 @histogram[:data][d.to_i] += 1 if d < range
170 173 user[sub.user_id] = [user[sub.user_id], ((sub.try(:points) || 0) >= @problem.full_score) ? 1 : 0].max
171 174 end
172 175 @histogram[:summary][:max] = [@histogram[:data].max,1].max
173 176
174 177 @summary = { attempt: user.count, solve: 0 }
175 178 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
176 179 end
177 180
178 181 def manage
179 182 @problems = Problem.order(date_added: :desc)
180 183 end
181 184
182 185 def do_manage
183 186 if params.has_key? 'change_date_added' and params[:date_added].strip.empty? == false
184 187 change_date_added
185 188 elsif params.has_key? 'add_to_contest'
186 189 add_to_contest
187 190 elsif params.has_key? 'enable_problem'
188 191 set_available(true)
189 192 elsif params.has_key? 'disable_problem'
190 193 set_available(false)
191 194 elsif params.has_key? 'add_group'
192 195 group = Group.find(params[:group_id])
193 196 ok = []
194 197 failed = []
195 198 get_problems_from_params.each do |p|
You need to be logged in to leave comments. Login now