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: 76 inserted, 17 deleted

@@ -5,28 +5,51
5 def index
5 def index
6 redirect_to :action => 'list'
6 redirect_to :action => 'list'
7 end
7 end
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)}\""
30 response.headers["X-Sendfile"] = filename
53 response.headers["X-Sendfile"] = filename
31 response.headers['Content-length'] = File.size(filename)
54 response.headers['Content-length'] = File.size(filename)
32 render :nothing => true
55 render :nothing => true
@@ -38,23 +61,15
38 end
61 end
39
62
40 send_file filename, :stream => false, :filename => base_filename, :type => content_type
63 send_file filename, :stream => false, :filename => base_filename, :type => content_type
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)
49 redirect_to :controller => 'main', :action => 'list'
70 redirect_to :controller => 'main', :action => 'list'
50 return false
71 return false
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
75 end
59 -
60 - end
@@ -3,13 +3,14
3 def link_to_description_if_any(name, problem, options={})
3 def link_to_description_if_any(name, problem, options={})
4 if !problem.url.blank?
4 if !problem.url.blank?
5 return link_to name, problem.url, options
5 return link_to name, problem.url, options
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
13 else
14 else
14 return ''
15 return ''
15 end
16 end
@@ -179,12 +179,35
179 stat = UserContestStat.new(:user => self,
179 stat = UserContestStat.new(:user => self,
180 :started_at => Time.now.gmtime)
180 :started_at => Time.now.gmtime)
181 stat.save
181 stat.save
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?
188 self.salt = (10+rand(90)).to_s
211 self.salt = (10+rand(90)).to_s
189 self.hashed_password = User.encrypt(self.password,self.salt)
212 self.hashed_password = User.encrypt(self.password,self.salt)
190 end
213 end
@@ -20,11 +20,12
20
20
21 # Allow downloading Web Service WSDL as a file with an extension
21 # Allow downloading Web Service WSDL as a file with an extension
22 # instead of a file named 'wsdl'
22 # instead of a file named 'wsdl'
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'
29 map.connect ':controller/:action/:id'
30 map.connect ':controller/:action/:id'
30 end
31 end
@@ -48,16 +48,21
48
48
49 def extract(tempfile)
49 def extract(tempfile)
50 testdata_filename = save_testdata_file(tempfile)
50 testdata_filename = save_testdata_file(tempfile)
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 + if File.exists? extract_dir
55 + backup_count = 0
54 begin
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)
61 + end
55 Dir.mkdir extract_dir
62 Dir.mkdir extract_dir
56 - rescue Errno::EEXIST
57 - end
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}"
61 elsif ext=='.tar'
66 elsif ext=='.tar'
62 cmd = "tar -xvf #{testdata_filename} -C #{extract_dir}"
67 cmd = "tar -xvf #{testdata_filename} -C #{extract_dir}"
63 elsif ext=='.zip'
68 elsif ext=='.zip'
@@ -135,15 +140,29
135 return ''
140 return ''
136 end
141 end
137 end
142 end
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
147 return "\nProblem pdf imported from #{filename}."
166 return "\nProblem pdf imported from #{filename}."
148 else
167 else
149 return ""
168 return ""
You need to be logged in to leave comments. Login now