diff options
-rw-r--r-- | app/controllers/remote_interaction_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/statuses_controller.rb | 4 | ||||
-rw-r--r-- | app/lib/activitypub/activity/create.rb | 3 | ||||
-rw-r--r-- | app/lib/bangtags.rb | 7 | ||||
-rw-r--r-- | app/models/imported_status.rb | 13 | ||||
-rw-r--r-- | app/models/normalized_status.rb | 1 | ||||
-rw-r--r-- | app/models/sharekey.rb | 13 | ||||
-rw-r--r-- | app/models/status.rb | 49 | ||||
-rw-r--r-- | app/serializers/rest/status_serializer.rb | 10 | ||||
-rw-r--r-- | app/services/post_status_service.rb | 2 | ||||
-rw-r--r-- | db/migrate/20191211235208_create_normalized_statuses.rb | 2 | ||||
-rw-r--r-- | db/migrate/20191212022020_create_sharekeys.rb | 19 | ||||
-rw-r--r-- | db/migrate/20191212022653_create_imported_statuses.rb | 21 | ||||
-rw-r--r-- | db/schema.rb | 21 | ||||
-rw-r--r-- | spec/fabricators/imported_status_fabricator.rb | 4 | ||||
-rw-r--r-- | spec/fabricators/sharekey_fabricator.rb | 4 | ||||
-rw-r--r-- | spec/models/imported_status_spec.rb | 5 | ||||
-rw-r--r-- | spec/models/sharekey_spec.rb | 5 |
18 files changed, 155 insertions, 30 deletions
diff --git a/app/controllers/remote_interaction_controller.rb b/app/controllers/remote_interaction_controller.rb index aa8f73ac8..7ecf95400 100644 --- a/app/controllers/remote_interaction_controller.rb +++ b/app/controllers/remote_interaction_controller.rb @@ -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? diff --git a/app/controllers/statuses_controller.rb b/app/controllers/statuses_controller.rb index eeece1785..f8e81864c 100644 --- a/app/controllers/statuses_controller.rb +++ b/app/controllers/statuses_controller.rb @@ -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 diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 4e7f922e9..1839a649e 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -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 diff --git a/app/lib/bangtags.rb b/app/lib/bangtags.rb index 5d8389892..a1963aa6c 100644 --- a/app/lib/bangtags.rb +++ b/app/lib/bangtags.rb @@ -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 diff --git a/app/models/imported_status.rb b/app/models/imported_status.rb new file mode 100644 index 000000000..038301f3e --- /dev/null +++ b/app/models/imported_status.rb @@ -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 diff --git a/app/models/normalized_status.rb b/app/models/normalized_status.rb index 10c2bf788..ad1ffaffc 100644 --- a/app/models/normalized_status.rb +++ b/app/models/normalized_status.rb @@ -9,4 +9,5 @@ class NormalizedStatus < ApplicationRecord belongs_to :status, inverse_of: :normalized_status + validates_uniqueness_of :status_id end diff --git a/app/models/sharekey.rb b/app/models/sharekey.rb new file mode 100644 index 000000000..baa1c20a0 --- /dev/null +++ b/app/models/sharekey.rb @@ -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 diff --git a/app/models/status.rb b/app/models/status.rb index 27184591b..e46e36403 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -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) diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb index 75a1dc591..8b0bce61e 100644 --- a/app/serializers/rest/status_serializer.rb +++ b/app/serializers/rest/status_serializer.rb @@ -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 diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index 04be5e4db..f070e7900 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -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, diff --git a/db/migrate/20191211235208_create_normalized_statuses.rb b/db/migrate/20191211235208_create_normalized_statuses.rb index 9baaa3f62..d47c4feb4 100644 --- a/db/migrate/20191211235208_create_normalized_statuses.rb +++ b/db/migrate/20191211235208_create_normalized_statuses.rb @@ -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 diff --git a/db/migrate/20191212022020_create_sharekeys.rb b/db/migrate/20191212022020_create_sharekeys.rb new file mode 100644 index 000000000..c0027babe --- /dev/null +++ b/db/migrate/20191212022020_create_sharekeys.rb @@ -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 diff --git a/db/migrate/20191212022653_create_imported_statuses.rb b/db/migrate/20191212022653_create_imported_statuses.rb new file mode 100644 index 000000000..3d7a9c99d --- /dev/null +++ b/db/migrate/20191212022653_create_imported_statuses.rb @@ -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 diff --git a/db/schema.rb b/db/schema.rb index 96e9148ed..47b792a8b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -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 diff --git a/spec/fabricators/imported_status_fabricator.rb b/spec/fabricators/imported_status_fabricator.rb new file mode 100644 index 000000000..475ecd94f --- /dev/null +++ b/spec/fabricators/imported_status_fabricator.rb @@ -0,0 +1,4 @@ +Fabricator(:imported_status) do + status nil + origin "MyString" +end diff --git a/spec/fabricators/sharekey_fabricator.rb b/spec/fabricators/sharekey_fabricator.rb new file mode 100644 index 000000000..9e346603a --- /dev/null +++ b/spec/fabricators/sharekey_fabricator.rb @@ -0,0 +1,4 @@ +Fabricator(:sharekey) do + status nil + key "MyString" +end diff --git a/spec/models/imported_status_spec.rb b/spec/models/imported_status_spec.rb new file mode 100644 index 000000000..f571a561a --- /dev/null +++ b/spec/models/imported_status_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe ImportedStatus, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/sharekey_spec.rb b/spec/models/sharekey_spec.rb new file mode 100644 index 000000000..99fbf0d8c --- /dev/null +++ b/spec/models/sharekey_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Sharekey, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end |