DEV: Add SecureUploadEndpointHelpers for controllers (#25758) (#25769)

This commit moves some code out of UploadController#show_secure
so it can be reused in other controllers if a secure upload
needs to have permission checks run.

Co-authored-by: Martin Brennan <martin@discourse.org>
This commit is contained in:
Penar Musaraj 2024-02-20 10:34:29 -05:00 committed by GitHub
parent 92749b7384
commit d85414f885
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 28 additions and 11 deletions

View File

@ -4,6 +4,7 @@ require "mini_mime"
class UploadsController < ApplicationController class UploadsController < ApplicationController
include ExternalUploadHelpers include ExternalUploadHelpers
include SecureUploadEndpointHelpers
requires_login except: %i[show show_short _show_secure_deprecated show_secure] requires_login except: %i[show show_short _show_secure_deprecated show_secure]
@ -143,12 +144,8 @@ class UploadsController < ApplicationController
return xhr_not_allowed if request.xhr? return xhr_not_allowed if request.xhr?
path_with_ext = "#{params[:path]}.#{params[:extension]}" path_with_ext = "#{params[:path]}.#{params[:extension]}"
upload = upload_from_path_and_extension(path_with_ext)
sha1 = File.basename(path_with_ext, File.extname(path_with_ext))
# this takes care of optimized image requests
sha1 = sha1.partition("_").first if sha1.include?("_")
upload = Upload.find_by(sha1: sha1)
return render_404 if upload.blank? return render_404 if upload.blank?
return render_404 if SiteSetting.prevent_anons_from_downloading_files && current_user.nil? return render_404 if SiteSetting.prevent_anons_from_downloading_files && current_user.nil?
@ -167,12 +164,7 @@ class UploadsController < ApplicationController
end end
def handle_secure_upload_request(upload, path_with_ext = nil) def handle_secure_upload_request(upload, path_with_ext = nil)
if upload.access_control_post_id.present? check_secure_upload_permission(upload)
raise Discourse::InvalidAccess if current_user.nil? && SiteSetting.login_required
raise Discourse::InvalidAccess if !guardian.can_see?(upload.access_control_post)
else
return render_404 if current_user.nil?
end
# defaults to public: false, so only cached by the client browser # defaults to public: false, so only cached by the client browser
cache_seconds = cache_seconds =

View File

@ -0,0 +1,25 @@
# frozen_string_literal: true
module SecureUploadEndpointHelpers
include ActiveSupport::Concern
def upload_from_path_and_extension(path_with_ext)
sha1 = File.basename(path_with_ext, File.extname(path_with_ext))
# this takes care of optimized image requests
sha1 = sha1.partition("_").first if sha1.include?("_")
Upload.find_by(sha1: sha1)
end
def upload_from_full_url(url)
Upload.find_by(sha1: Upload.sha1_from_long_url(url))
end
def check_secure_upload_permission(upload)
if upload.access_control_post_id.present?
raise Discourse::InvalidAccess if current_user.nil? && SiteSetting.login_required
raise Discourse::InvalidAccess if !guardian.can_see?(upload.access_control_post)
else
raise Discourse::NotFound if current_user.nil?
end
end
end