4

Pundit を使用して Refile gem でアップロードされたファイルの認証を行うにはどうすればよいですか? ファイルをアップロードしたユーザーに制限する必要があるファイルをアップロードしましたが、Refile の attachment_url が生成する URL を持つ人は誰でもファイルにアクセスできます。Refile は独自の Sinatra アプリを使用しているため、Pundit の authorize メソッドを呼び出すための Rails コントローラーはありません。

4

1 に答える 1

2

コントローラーでは、ファイルをダウンロードするメソッドを使用できます。downloadより複雑な例として、コントローラーにアクションがあるとしましょうUsersControllerpunditここからは通常通りご利用いただけます。このdownloadアクションは、ユーザーの画像を取得します。

免責事項: これは、このアクションが頻繁に呼び出されるとサーバーに打撃を与えることになるため、プロダクション プラクティスの恐ろしい例です。このアクションが呼び出されるたびに、基本的に画像のサイズを変更しています。ただし、概念実証として、refileファイルのダウンロードが通常どのように機能するかを超えて、求めている承認を追加します。

fill オプション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_fileます。send_datafilenamedispositioncontent_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 に答える