Fix #416 - Generate random unique 14-byte (19 characters) shortcodes
for local attachments, use them in URLs. Check status privacy before redirecting to actual file.
This commit is contained in:
		@@ -10,6 +10,7 @@ class MediaController < ApplicationController
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
  def set_media_attachment
 | 
			
		||||
    @media_attachment = MediaAttachment.where.not(status_id: nil).find(params[:id])
 | 
			
		||||
    @media_attachment = MediaAttachment.where.not(status_id: nil).find_by!(shortcode: params[:id])
 | 
			
		||||
    raise ActiveRecord::RecordNotFound unless @media_attachment.status.permitted?(current_account)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@ class MediaAttachment < ApplicationRecord
 | 
			
		||||
 | 
			
		||||
  validates :account, presence: true
 | 
			
		||||
 | 
			
		||||
  scope :local, -> { where(remote_url: '') }
 | 
			
		||||
  default_scope { order('id asc') }
 | 
			
		||||
 | 
			
		||||
  def local?
 | 
			
		||||
@@ -38,6 +39,12 @@ class MediaAttachment < ApplicationRecord
 | 
			
		||||
    image? ? 'image' : 'video'
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def to_param
 | 
			
		||||
    shortcode
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  before_create :set_shortcode
 | 
			
		||||
 | 
			
		||||
  class << self
 | 
			
		||||
    private
 | 
			
		||||
 | 
			
		||||
@@ -62,4 +69,15 @@ class MediaAttachment < ApplicationRecord
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
  def set_shortcode
 | 
			
		||||
    return unless local?
 | 
			
		||||
 | 
			
		||||
    loop do
 | 
			
		||||
      self.shortcode = SecureRandom.urlsafe_base64(14)
 | 
			
		||||
      break if MediaAttachment.find_by(shortcode: shortcode).nil?
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,14 @@
 | 
			
		||||
class AddShortcodeToMediaAttachments < ActiveRecord::Migration[5.0]
 | 
			
		||||
  def up
 | 
			
		||||
    add_column :media_attachments, :shortcode, :string, null: true, default: nil
 | 
			
		||||
    add_index :media_attachments, :shortcode, unique: true
 | 
			
		||||
 | 
			
		||||
    # Migrate old links
 | 
			
		||||
    MediaAttachment.local.update_all('shortcode = id')
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def down
 | 
			
		||||
  	remove_index :media_attachments, :shortcode
 | 
			
		||||
  	remove_column :media_attachments, :shortcode
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
@@ -10,7 +10,7 @@
 | 
			
		||||
#
 | 
			
		||||
# It's strongly recommended that you check this file into your version control system.
 | 
			
		||||
 | 
			
		||||
ActiveRecord::Schema.define(version: 20161222204147) do
 | 
			
		||||
ActiveRecord::Schema.define(version: 20170105224407) do
 | 
			
		||||
 | 
			
		||||
  # These are extensions that must be enabled in order to support this database
 | 
			
		||||
  enable_extension "plpgsql"
 | 
			
		||||
@@ -95,6 +95,8 @@ ActiveRecord::Schema.define(version: 20161222204147) do
 | 
			
		||||
    t.integer  "account_id"
 | 
			
		||||
    t.datetime "created_at",                     null: false
 | 
			
		||||
    t.datetime "updated_at",                     null: false
 | 
			
		||||
    t.string   "shortcode"
 | 
			
		||||
    t.index ["shortcode"], name: "index_media_attachments_on_shortcode", unique: true, using: :btree
 | 
			
		||||
    t.index ["status_id"], name: "index_media_attachments_on_status_id", using: :btree
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user