-
Notifications
You must be signed in to change notification settings - Fork 30
Expand file tree
/
Copy pathfiles_controller.rb
More file actions
91 lines (77 loc) · 3.54 KB
/
files_controller.rb
File metadata and controls
91 lines (77 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# frozen_string_literal: true
module CodeOcean
class FilesController < ApplicationController
include CommonBehavior
include FileParameters
before_action :set_content_type_nosniff
# Overwrite the CSP header and some default actions for the :render_protected_upload action
content_security_policy false, only: :render_protected_upload
skip_before_action :deny_access_from_render_host, only: :render_protected_upload
skip_before_action :verify_authenticity_token, only: :render_protected_upload
skip_before_action :set_sentry_context, only: :render_protected_upload
skip_before_action :require_fully_authenticated_user!, only: :render_protected_upload
# In case the .realpath cannot resolve a file (for example because it is no longer available)
rescue_from Errno::ENOENT, with: :render_not_found
def authorize!
authorize(@file)
end
private :authorize!
def show_protected_upload
@file = CodeOcean::File.find(params[:id])
authorize!
# The `@file.name_with_extension` is assembled based on the user-selected file type, not on the actual file name stored on disk.
raise Pundit::NotAuthorizedError if @embed_options[:disable_download] || @file.filepath != params[:filename] || @file.attachment.blank?
url = rails_blob_path(@file.attachment, disposition: 'attachment', expires_in: 5.minutes)
redirect_to url, allow_other_host: true
end
def render_protected_upload
# Set @current_user with a new *learner* for Pundit checks
@current_user = ExternalUser.new
@file = authorize AuthenticatedUrlHelper.retrieve!(CodeOcean::File, request)
# The `@file.name_with_extension` is assembled based on the user-selected file type, not on the actual file name stored on disk.
raise Pundit::NotAuthorizedError unless @file.filepath == params[:filename] || @file.attachment.present?
url = rails_blob_path(@file.attachment, disposition: 'inline', expires_in: 5.minutes)
redirect_to url, allow_other_host: true
end
def create
@file = CodeOcean::File.new(file_params)
if @file.file_template_id
content = FileTemplate.find(@file.file_template_id).content
content.sub! '{{file_name}}', @file.name
@file.content = content
end
authorize!
create_and_respond(object: @file, path: proc { implement_exercise_path(@file.context.exercise) })
end
def create_and_respond(options = {})
@object = options[:object]
respond_to do |format|
if @object.save
yield if block_given?
path = options[:path].try(:call) || @object
respond_with_valid_object(format, notice: t('shared.object_created', model: @object.class.model_name.human),
path:, status: :created)
else
filename = "#{@object.path || ''}/#{@object.name || ''}#{@object.file_type.try(:file_extension) || ''}"
format.html do
flash[:danger] = t('code_ocean/files.error.filename', name: filename)
redirect_to options[:path], status: :see_other
end
format.json { render json: @object.errors, status: :unprocessable_content }
end
end
end
def destroy
@file = CodeOcean::File.find(params[:id])
authorize!
destroy_and_respond(object: @file, path: @file.context)
end
def file_params
if params[:code_ocean_file].present?
params[:code_ocean_file].permit(file_attributes).merge(context_type: 'Submission',
role: 'user_defined_file')
end
end
private :file_params
end
end