ruby-on-rails – 使用Refile gem上传的文件的Pundit authorizaton

如何使用Pundit对使用Refile gem上传的文件进行授权?我上传的文件应该仅限于上传它们的用户,但是任何拥有Refile的attachment_url生成的网址的人都可以访问该文件.由于Refile使用它自己的Sinatra应用程序,因此我没有使用rails控制器来调用Pundit的授权方法. 最佳答案 在您的控制器中,您可以使用下载文件的方法.对于更复杂的示例,假设您在UsersController控制器中有下载操作.从这里开始,您可以像往常一样使用权威.此下载操作会抓取用户的图像.

免责声明:这是一个生产实践的可怕例子,因为如果这个动作被大量调用,你将会敲击服务器.实际上,每次调用此操作时,您都要调整图像大小.但是,作为一个概念证明,除了重新编译文件下载通常如何工作,并添加您正在寻求的授权.

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

  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' %>

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

编辑以增加更多清晰度:

temp_file的功能是保留原始图像.如果您只想提供原始文件的未经处理的下载,您可以在下面执行以下操作.您还应该阅读send_file和send_data,因为它们提供了其他内容,如文件名,处置,content_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
点赞