Description:
added contest problem access control
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r282:6dab27215603 - - 5 files changed: 77 inserted, 18 deleted

@@ -8,22 +8,45
8
8
9 def list
9 def list
10 @problems = Problem.find_available_problems
10 @problems = Problem.find_available_problems
11 - @user = User.find(session[:user_id])
12 end
11 end
13
12
13 + # this has contest-wide access control
14 def view
14 def view
15 base_name = params[:file]
15 base_name = params[:file]
16 - if !check_user_viewability(base_name)
16 + base_filename = File.basename("#{base_name}.#{params[:ext]}")
17 + filename = "#{Problem.download_file_basedir}/#{base_filename}"
18 +
19 + if !FileTest.exists?(filename)
17 redirect_to :action => 'index' and return
20 redirect_to :action => 'index' and return
18 end
21 end
19
22
20 - base_filename = File.basename("#{base_name}.#{params[:ext]}")
23 + send_file_to_user(filename, base_filename)
21 - filename = "#{Problem.download_file_basedir}/#{base_filename}"
24 + end
22
25
23 - if !check_user_viewability(base_name) or !FileTest.exists?(filename)
26 + # this has problem-level access control
27 + def download
28 + problem = Problem.find(params[:id])
29 + if !problem or !problem.available or !@user.can_view_problem? problem
24 redirect_to :action => 'index' and return
30 redirect_to :action => 'index' and return
25 end
31 end
26
32
33 + base_name = params[:file]
34 + base_filename = File.basename("#{base_name}.#{params[:ext]}")
35 + filename = "#{Problem.download_file_basedir}/#{params[:id]}/#{base_filename}"
36 + puts "SENDING: #{filename}"
37 +
38 + if !FileTest.exists?(filename)
39 + redirect_to :action => 'index' and return
40 + end
41 +
42 + puts "SENDING: #{filename}"
43 +
44 + send_file_to_user(filename, base_filename)
45 + end
46 +
47 + protected
48 +
49 + def send_file_to_user(filename, base_filename)
27 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
50 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
28 response.headers['Content-Type'] = "application/force-download"
51 response.headers['Content-Type'] = "application/force-download"
29 response.headers['Content-Disposition'] = "attachment; filename=\"#{File.basename(filename)}\""
52 response.headers['Content-Disposition'] = "attachment; filename=\"#{File.basename(filename)}\""
@@ -41,8 +64,6
41 end
64 end
42 end
65 end
43
66
44 - protected
45 -
46 def check_viewability
67 def check_viewability
47 @user = User.find(session[:user_id])
68 @user = User.find(session[:user_id])
48 if @user==nil or !Configuration.show_tasks_to?(@user)
69 if @user==nil or !Configuration.show_tasks_to?(@user)
@@ -51,10 +72,4
51 end
72 end
52 end
73 end
53
74
54 - def check_user_viewability(filename)
55 - # individual file access control shall be added here
56 - return false if not @user
57 - return Configuration.show_tasks_to?(@user)
58 - end
59 -
60 end
75 end
@@ -6,7 +6,8
6 elsif !problem.description_filename.blank?
6 elsif !problem.description_filename.blank?
7 basename, ext = problem.description_filename.split('.')
7 basename, ext = problem.description_filename.split('.')
8 options[:controller] = 'tasks'
8 options[:controller] = 'tasks'
9 - options[:action] = 'view'
9 + options[:action] = 'download'
10 + options[:id] = problem.id
10 options[:file] = basename
11 options[:file] = basename
11 options[:ext] = ext
12 options[:ext] = ext
12 return link_to name, options
13 return link_to name, options
@@ -182,6 +182,29
182 end
182 end
183 end
183 end
184
184
185 + def problem_in_user_contests?(problem)
186 + problem_contests = problem.contests.all
187 +
188 + if problem_contests.length == 0 # this is public contest
189 + return true
190 + end
191 +
192 + contests.each do |contest|
193 + if problem_contests.find {|c| c.id == contest.id }
194 + return true
195 + end
196 + end
197 + return false
198 + end
199 +
200 + def can_view_problem?(problem)
201 + if not Configuration.multicontests?
202 + return problem.available
203 + else
204 + return problem_in_user_contests? problem
205 + end
206 + end
207 +
185 protected
208 protected
186 def encrypt_new_password
209 def encrypt_new_password
187 return if password.blank?
210 return if password.blank?
@@ -23,6 +23,7
23 map.connect ':controller/service.wsdl', :action => 'wsdl'
23 map.connect ':controller/service.wsdl', :action => 'wsdl'
24
24
25 map.connect 'tasks/view/:file.:ext', :controller => 'tasks', :action => 'view'
25 map.connect 'tasks/view/:file.:ext', :controller => 'tasks', :action => 'view'
26 + map.connect 'tasks/download/:id/:file.:ext', :controller => 'tasks', :action => 'download'
26
27
27 # Install the default route as the lowest priority.
28 # Install the default route as the lowest priority.
28 map.connect ':controller/:action/:id.:format'
29 map.connect ':controller/:action/:id.:format'
@@ -51,10 +51,15
51 ext = TestdataImporter.long_ext(tempfile.original_filename)
51 ext = TestdataImporter.long_ext(tempfile.original_filename)
52
52
53 extract_dir = File.join(GraderScript.raw_dir, @problem.name)
53 extract_dir = File.join(GraderScript.raw_dir, @problem.name)
54 - begin
54 + if File.exists? extract_dir
55 - Dir.mkdir extract_dir
55 + backup_count = 0
56 - rescue Errno::EEXIST
56 + begin
57 + backup_count += 1
58 + backup_dirname = "#{extract_dir}.backup.#{backup_count}"
59 + end while File.exists? backup_dirname
60 + File.rename(extract_dir, backup_dirname)
57 end
61 end
62 + Dir.mkdir extract_dir
58
63
59 if ext=='.tar.gz' or ext=='.tgz'
64 if ext=='.tar.gz' or ext=='.tgz'
60 cmd = "tar -zxvf #{testdata_filename} -C #{extract_dir}"
65 cmd = "tar -zxvf #{testdata_filename} -C #{extract_dir}"
@@ -138,9 +143,23
138
143
139 def import_problem_pdf(dirname)
144 def import_problem_pdf(dirname)
140 pdf_files = Dir["#{dirname}/*.pdf"]
145 pdf_files = Dir["#{dirname}/*.pdf"]
146 + puts "CHECKING... #{dirname}"
141 if pdf_files.length != 0
147 if pdf_files.length != 0
148 + puts "HAS PDF FILE"
142 filename = pdf_files[0]
149 filename = pdf_files[0]
143 - out_filename = "#{Problem.download_file_basedir}/#{@problem.name}.pdf"
150 +
151 + @problem.save if not @problem.id
152 + out_dirname = "#{Problem.download_file_basedir}/#{@problem.id}"
153 + if not FileTest.exists? out_dirname
154 + Dir.mkdir out_dirname
155 + end
156 +
157 + out_filename = "#{out_dirname}/#{@problem.name}.pdf"
158 +
159 + if FileTest.exists? out_filename
160 + File.delete out_filename
161 + end
162 +
144 File.rename(filename, out_filename)
163 File.rename(filename, out_filename)
145 @problem.description_filename = "#{@problem.name}.pdf"
164 @problem.description_filename = "#{@problem.name}.pdf"
146 @problem.save
165 @problem.save
You need to be logged in to leave comments. Login now