4

如何使用 Pundit 对通过 Refile gem 上传的文件进行授权?我上传的文件应该仅限于上传它们的用户,但是任何拥有 Refile 的 attachment_url 生成的 url 的人都可以访问该文件。由于 Refile 使用它自己的 Sinatra 应用程序,因此我没有 Rails 控制器可以调用 Pundit 的授权方法。

4

1 回答 1

2

在您的控制器中,您可以有一个下载文件的方法。对于更复杂的示例,假设您的控制器download中有一个操作。UsersController从这里,您可以pundit像往常一样使用。此download操作抓取用户的图像。

免责声明:这是生产实践的一个可怕示例,因为如果多次调用此操作,您将敲击服务器。每次调用此操作时,您实际上都在调整图像大小。但是,作为概念证明,可以超越refile文件下载的正常工作方式并添加您正在寻求的授权。

我们创建一个processor变量来初始化ImageProcessor填充选项。然后我们创建一个临时文件并将其设置为二进制模式。我们从用户模型中获取文件并将其读入临时文件。将临时文件倒回到文件的开头并将其读入MiniMagick. 然后我们调用我们processor来转换临时文件(保持原始文件不变)。然后我们将文件发送给用户。

  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  

这是将文件呈现为的示例image_tag

在此处输入图像描述

连同调用要调整大小和下载的图像的代码。

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

您可以将操作设置为接受各种其他处理选项和维度。对于这个例子,我将展示如何填充 150x150 像素的大小。

编辑以增加清晰度:

的功能temp_file是保留原始图像。如果您只想提供原始文件的未处理下载,您可以在下面执行类似的操作。您还应该继续阅读send_filesend_data因为它们提供了其他内容,例如filenamedispositioncontent_type等,用于自定义下载以及如何处理它。

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

编辑:我进一步查看了Refile源代码,发现文件链接的创建是由在路由中安装引擎引起的。创建一个初始化文件并将下面的代码放在那里。这将允许您保留上述现有功能,同时删除上传文件的公共链接。

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
于 2015-03-14T20:44:51.680 回答