move sharekeys & import metadata to own tables

master
multiple creatures 2019-12-11 22:00:22 -06:00
parent 9a435494c2
commit dae7cda4ab
18 changed files with 155 additions and 30 deletions

View File

@ -49,7 +49,7 @@ class RemoteInteractionController < ApplicationController
@status = Status.find(params[:id])
@sharekey = params[:key]
if @status.sharekey.present? && @sharekey == @status.sharekey
if @status.sharekey.present? && @sharekey == @status.sharekey.key
skip_authorization
else
authorize @status, :show?

View File

@ -185,7 +185,7 @@ class StatusesController < ApplicationController
@type = @stream_entry.activity_type.downcase
@sharekey = params[:key]
if @status.sharekey.present? && @sharekey == @status.sharekey
if @status.sharekey.present? && @sharekey == @status.sharekey.key
skip_authorization
elsif @account.block_anon && !user_signed_in?
raise ActiveRecord::RecordNotFound
@ -203,11 +203,9 @@ class StatusesController < ApplicationController
case params[:rekey]
when '1'
@status.sharekey = SecureRandom.urlsafe_base64(32)
@status.save
Rails.cache.delete("statuses/#{@status.id}")
when '0'
@status.sharekey = nil
@status.save
Rails.cache.delete("statuses/#{@status.id}")
end
end

View File

@ -92,7 +92,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
end
def find_imported_status
status = Status.find_by(origin: @origin_hash)
status = Status.joins(:imported_status).select('statuses.*').find_by(origin: @origin_hash)
end
def obfuscate_origin(key)
@ -138,7 +138,6 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
if @options[:imported]
@params.except!(:uri, :url)
@params[:content_type] = 'text/html'
@params[:imported] = true
@params[:origin] = @origin_hash unless @origin_hash.nil?
end

View File

@ -303,7 +303,6 @@ class Bangtags
roars.each do |roar|
if roar.sharekey.present?
roar.sharekey = nil
roar.save
Rails.cache.delete("statuses/#{roar.id}")
end
end
@ -315,15 +314,13 @@ class Bangtags
if cmd[2] == 'new' || earliest_roar.sharekey.blank?
sharekey = SecureRandom.urlsafe_base64(32)
earliest_roar.sharekey = sharekey
earliest_roar.save
Rails.cache.delete("statuses/#{earliest_roar.id}")
else
sharekey = earliest_roar.sharekey
sharekey = earliest_roar.sharekey.key
end
roars.each do |roar|
if roar.sharekey != sharekey
if roar.sharekey.nil? || roar.sharekey.key != sharekey
roar.sharekey = sharekey
roar.save
Rails.cache.delete("statuses/#{roar.id}")
end
end

View File

@ -0,0 +1,13 @@
# == Schema Information
#
# Table name: imported_statuses
#
# id :bigint(8) not null, primary key
# status_id :bigint(8)
# origin :string
#
class ImportedStatus < ApplicationRecord
belongs_to :status, inverse_of: :imported_status
validates_uniqueness_of :status_id
end

View File

@ -9,4 +9,5 @@
class NormalizedStatus < ApplicationRecord
belongs_to :status, inverse_of: :normalized_status
validates_uniqueness_of :status_id
end

13
app/models/sharekey.rb Normal file
View File

@ -0,0 +1,13 @@
# == Schema Information
#
# Table name: sharekeys
#
# id :bigint(8) not null, primary key
# status_id :bigint(8)
# key :string
#
class Sharekey < ApplicationRecord
belongs_to :status, inverse_of: :sharekey
validates_uniqueness_of :status_id
end

View File

@ -24,13 +24,10 @@
# local_only :boolean
# poll_id :bigint(8)
# curated :boolean default(FALSE), not null
# sharekey :string
# network :boolean default(FALSE), not null
# content_type :string
# footer :text
# edited :boolean
# imported :boolean
# origin :string
# boostable :boolean
# reject_replies :boolean
#
@ -86,6 +83,8 @@ class Status < ApplicationRecord
has_one :poll, inverse_of: :status, dependent: :destroy
has_one :destructing_status, inverse_of: :status, dependent: :destroy
has_one :normalized_status, inverse_of: :status, dependent: :destroy
has_one :imported_status, inverse_of: :status, dependent: :destroy
has_one :sharekey, inverse_of: :status, dependent: :destroy
validates :uri, uniqueness: true, presence: true, unless: :local?
validates :text, presence: true, unless: -> { with_media? || reblog? }
@ -318,12 +317,22 @@ class Status < ApplicationRecord
update_status_stat!(key => [public_send(key) - 1, 0].max)
end
def session=(value)
@session = value
def sharekey=(value)
if value.nil? && !(new_record? || self.sharekey.nil?)
self.sharekey.destroy
else
@_sharekey = value
update_sharekey unless new_record? || changed?
end
end
def session
@session || nil
def origin=(value)
if value.nil? && !(new_record? || self.imported_status.nil?)
self.imported_status.destroy
else
@_origin = value
update_origin unless new_record? || changed?
end
end
after_create_commit :increment_counter_caches
@ -344,8 +353,11 @@ class Status < ApplicationRecord
before_validation :infer_reject_replies
after_create :set_poll_id
after_create :update_normalized_text
after_create :process_bangtags, if: :local?
after_save :update_sharekey, if: :local?
after_save :update_origin, if: :local?
after_save :update_normalized_text
after_save :process_bangtags, if: :local?
class << self
include SearchHelper
@ -629,9 +641,28 @@ class Status < ApplicationRecord
end
def process_bangtags
return unless text_changed? || saved_change_to_text?
Bangtags.new(self).process
end
def update_sharekey
return if @_sharekey.nil?
if self.sharekey.nil?
self.create_sharekey(key: @_sharekey)
else
self.sharekey.update_attributes(key: @_sharekey)
end
end
def update_origin
return if @_origin.nil?
if self.imported_status.nil?
self.create_imported_status(origin: @_origin)
else
self.imported_status.update_attributes(origin: @_origin)
end
end
def update_normalized_text
return if destroyed? || text.blank? || !(text_changed? || saved_change_to_text?)
normalized_text = normalize_status(self)

View File

@ -14,7 +14,7 @@ class REST::StatusSerializer < ActiveModel::Serializer
attribute :bookmarked, if: :current_user?
attribute :pinned, if: :pinnable?
attribute :local_only if :local?
attribute :sharekey, if: :owner?
attribute :sharekey, if: :has_sharekey?
attribute :delete_after, if: :current_user?
attribute :content, unless: :source_requested?
@ -53,12 +53,16 @@ class REST::StatusSerializer < ActiveModel::Serializer
current_user? && current_user.account_id == object.account_id
end
def has_sharekey?
owner? && object.sharekey.present?
end
def show_application?
object.account.user_shows_application? || owner?
end
def spoiler_text
redis.hget("custom_cw:#{current_user&.account_id}", object.id) || redis.hget("custom_cw:#{current_user&.account_id}", "c#{object.conversation_id}") || object.spoiler_text
def sharekey
object.sharekey.key
end
def visibility

View File

@ -285,7 +285,7 @@ class PostStatusService < BaseService
local_only: @local_only,
delete_after: @delete_after,
reject_replies: @options[:noreplies] || false,
sharekey: @sharekey,
sharekey: @options[:sharekey],
language: language_from_option(@options[:language]) || @account.user_default_language&.presence || 'en',
application: @options[:application],
content_type: @options[:content_type] || @account.user&.setting_default_content_type,

View File

@ -1,7 +1,7 @@
class CreateNormalizedStatuses < ActiveRecord::Migration[5.2]
def up
create_table :normalized_statuses do |t|
t.references :status, foreign_key: true
t.references :status, foreign_key: true, index: {unique: true}
t.text :text
end

View File

@ -0,0 +1,19 @@
class CreateSharekeys < ActiveRecord::Migration[5.2]
def up
create_table :sharekeys do |t|
t.references :status, foreign_key: true, index: {unique: true}
t.string :key
end
safety_assured do
execute 'INSERT INTO sharekeys (status_id, key) SELECT id, sharekey FROM statuses WHERE local AND sharekey IS NOT NULL'
remove_column :statuses, :sharekey
end
end
def down
add_column :statuses, :sharekey, :string
execute 'UPDATE statuses SET sharekey = s.key FROM (SELECT status_id, key FROM sharekeys) AS s WHERE statuses.id = s.id'
drop_table :sharekeys
end
end

View File

@ -0,0 +1,21 @@
class CreateImportedStatuses < ActiveRecord::Migration[5.2]
def up
create_table :imported_statuses do |t|
t.references :status, foreign_key: true, index: {unique: true}
t.string :origin, index: {unique: true}
end
safety_assured { execute 'INSERT INTO imported_statuses (status_id, origin) SELECT id, origin FROM statuses WHERE imported' }
safety_assured do
remove_column :statuses, :imported
remove_column :statuses, :origin
end
end
def down
add_column :statuses, :imported, :boolean
add_column :statuses, :origin, :string, index: { unique: true }
execute 'UPDATE statuses SET imported = true, origin = s.origin FROM (SELECT status_id, origin FROM imported_statuses) AS s WHERE statuses.id = s.id'
drop_table :imported_statuses
end
end

View File

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2019_12_12_002705) do
ActiveRecord::Schema.define(version: 2019_12_12_022653) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm"
@ -335,6 +335,13 @@ ActiveRecord::Schema.define(version: 2019_12_12_002705) do
t.index ["user_id"], name: "index_identities_on_user_id"
end
create_table "imported_statuses", force: :cascade do |t|
t.bigint "status_id"
t.string "origin"
t.index ["origin"], name: "index_imported_statuses_on_origin", unique: true
t.index ["status_id"], name: "index_imported_statuses_on_status_id", unique: true
end
create_table "imports", force: :cascade do |t|
t.integer "type", null: false
t.boolean "approved", default: false, null: false
@ -636,6 +643,12 @@ ActiveRecord::Schema.define(version: 2019_12_12_002705) do
t.index ["thing_type", "thing_id", "var"], name: "index_settings_on_thing_type_and_thing_id_and_var", unique: true
end
create_table "sharekeys", force: :cascade do |t|
t.bigint "status_id"
t.string "key"
t.index ["status_id"], name: "index_sharekeys_on_status_id", unique: true
end
create_table "site_uploads", force: :cascade do |t|
t.string "var", default: "", null: false
t.string "file_file_name"
@ -687,13 +700,10 @@ ActiveRecord::Schema.define(version: 2019_12_12_002705) do
t.boolean "local_only"
t.bigint "poll_id"
t.boolean "curated", default: false, null: false
t.string "sharekey"
t.boolean "network", default: false, null: false
t.string "content_type"
t.text "footer"
t.boolean "edited"
t.boolean "imported"
t.string "origin"
t.boolean "boostable"
t.boolean "reject_replies"
t.index ["account_id", "id", "visibility", "updated_at"], name: "index_statuses_20180106", order: { id: :desc }
@ -701,7 +711,6 @@ ActiveRecord::Schema.define(version: 2019_12_12_002705) do
t.index ["in_reply_to_account_id"], name: "index_statuses_on_in_reply_to_account_id"
t.index ["in_reply_to_id"], name: "index_statuses_on_in_reply_to_id"
t.index ["network"], name: "index_statuses_on_network", where: "network"
t.index ["origin"], name: "index_statuses_on_origin", unique: true
t.index ["reblog_of_id", "account_id"], name: "index_statuses_on_reblog_of_id_and_account_id"
t.index ["uri"], name: "index_statuses_on_uri", unique: true
end
@ -850,6 +859,7 @@ ActiveRecord::Schema.define(version: 2019_12_12_002705) do
add_foreign_key "follows", "accounts", column: "target_account_id", name: "fk_745ca29eac", on_delete: :cascade
add_foreign_key "follows", "accounts", name: "fk_32ed1b5560", on_delete: :cascade
add_foreign_key "identities", "users", name: "fk_bea040f377", on_delete: :cascade
add_foreign_key "imported_statuses", "statuses"
add_foreign_key "imports", "accounts", name: "fk_6db1b6e408", on_delete: :cascade
add_foreign_key "invites", "users", on_delete: :cascade
add_foreign_key "linked_users", "users", column: "target_user_id", on_delete: :cascade
@ -888,6 +898,7 @@ ActiveRecord::Schema.define(version: 2019_12_12_002705) do
add_foreign_key "scheduled_statuses", "accounts", on_delete: :cascade
add_foreign_key "session_activations", "oauth_access_tokens", column: "access_token_id", name: "fk_957e5bda89", on_delete: :cascade
add_foreign_key "session_activations", "users", name: "fk_e5fda67334", on_delete: :cascade
add_foreign_key "sharekeys", "statuses"
add_foreign_key "status_pins", "accounts", name: "fk_d4cb435b62", on_delete: :cascade
add_foreign_key "status_pins", "statuses", on_delete: :cascade
add_foreign_key "status_stats", "statuses", on_delete: :cascade

View File

@ -0,0 +1,4 @@
Fabricator(:imported_status) do
status nil
origin "MyString"
end

View File

@ -0,0 +1,4 @@
Fabricator(:sharekey) do
status nil
key "MyString"
end

View File

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe ImportedStatus, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe Sharekey, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end