简体   繁体   English

Pundit authorizaton用于使用Refile gem上传的文件

[英]Pundit authorizaton for files uploaded with Refile gem

How would I do authorization on files uploaded with Refile gem using Pundit? 如何使用Pundit对使用Refile gem上传的文件进行授权? I have uploaded files which should be restricted to the user that uploaded them, but anyone with the url that Refile's attachment_url generates can access the file. 我上传的文件应该仅限于上传它们的用户,但是任何拥有Refile的attachment_url生成的网址的人都可以访问该文件。 Since Refile uses it's own Sinatra app, there's no rails controller for me to call Pundit's authorize method in. 由于Refile使用它自己的Sinatra应用程序,因此我没有使用rails控制器来调用Pundit的授权方法。

In your controller, you can have a method which will download the file. 在您的控制器中,您可以使用下载文件的方法。 For a more complicated example, let's say that you have a download action in your UsersController controller. 对于更复杂的示例,假设您在UsersController控制器中有download操作。 From within here, you can use pundit as you normally would. 从这里开始,您可以像往常一样使用pundit This download action grabs the image of the user. download操作会抓取用户的图像。

Disclaimer: This is a horrible example of production practice as you are going to be hammering the server if this action is called a lot. 免责声明:这是一个生产实践的可怕例子,因为如果这个动作被大量调用,你将会敲击服务器。 You are essentially resizing the image every single time this action is called. 实际上,每次调用此操作时,您都要调整图像大小。 However, as a proof of concept to go outside of how refile file download normally works and adds in the authorization you're seeking. 但是,作为一个概念证明,除了重新refile文件下载通常如何工作,并添加您正在寻求的授权。

We create a processor variable which initializes the ImageProcessor fill option. 我们创建一个processor变量来初始化ImageProcessor填充选项。 We then create a temporary file and set it to binary mode. 然后,我们创建一个临时文件并将其设置为二进制模式。 We take the file from our user model and read it into the temporary file. 我们从用户模型中获取文件并将其读入临时文件。 Rewind the temporary file to the beginning of the file and read it into MiniMagick . 将临时文件倒回到文件的开头并将其读入MiniMagick We then call on our processor to convert the temporary file (leaving the original intact). 然后我们调用我们的processor来转换临时文件(保留原始文件)。 We then send the file to the user. 然后我们将文件发送给用户。

  def download
    @user = User.find(params[:id])
    authorize @user
    processor = Refile.processor(:fill, Refile::ImageProcessor.new(:fill))
    temp_file = Tempfile.new('profile_image')
    temp_file.binmode
    temp_file.write @user.profile_image.read
    temp_file.rewind
    image_file = MiniMagick::Image.new(temp_file.path)
    file = processor.fill(image_file, 150, 150)
    temp_file.close
    send_file file.path
  end  

Here is the example of it rendering the file as an image_tag 以下是将文件呈现为image_tag的示例

在此输入图像描述

Along with the code that calls the image to be resized and downloaded. 以及调用要调整大小和下载的图像的代码。

<%= image_tag user_download_path(@user), class: 'img-circle img-thumbnail' %>

You can set your action to accept various other processing options and dimensions. 您可以将操作设置为接受各种其他处理选项和维度。 For this example, I'm showing how to fill a size of 150x150 pixels. 对于此示例,我将展示如何填充150x150像素的大小。

Edit to add more clarity: 编辑以增加更多清晰度:

The function of the temp_file is to leave the original image alone. temp_file的功能是保留原始图像。 If you are looking to simply provide an unprocessed download of the original file, you could do something like this below. 如果您只想提供原始文件的未经处理的下载,您可以在下面执行以下操作。 You should also read on send_file and send_data as they provide other things like filename , disposition , content_type , etc. options for customizing the download and how it should be handled. 您还应该阅读send_filesend_data因为它们提供了其他内容,如filenamedispositioncontent_type等,用于自定义下载以及如何处理下载。

  def download
    @user = User.find(params[:id])
    authorize @user
    send_file @user.profile_image.download
  end

Edit: I looked further into the Refile source and found that the creation of the file links is caused by the mounting of the engine within the routes. 编辑:我进一步研究了Refile源代码,发现文件链接的创建是由引擎在路径中的安装引起的。 Create an initializer file and place the code below in there. 创建初始化文件并将下面的代码放在那里。 This will allow you to keep the existing functionality described above while removing the public links to the files uploaded. 这将允许您在删除上传文件的公共链接时保留上述现有功能。

Refile.configure do |config|
  # config.direct_upload = ["cache"]
  # config.allow_origin = "*"
  # config.logger = Logger.new(STDOUT)
  # config.mount_point = "attachments"
  config.automount = false
  # config.content_max_age = 60 * 60 * 24 * 365
  # config.types[:image] = Refile::Type.new(:image, content_type: %w[image/jpeg image/gif image/png])
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM