From dae7cda4abe135b3bb5fe9cfb3380721a2feb03e Mon Sep 17 00:00:00 2001 From: multiple creatures Date: Wed, 11 Dec 2019 22:00:22 -0600 Subject: move sharekeys & import metadata to own tables --- app/controllers/remote_interaction_controller.rb | 2 +- app/controllers/statuses_controller.rb | 4 +- app/lib/activitypub/activity/create.rb | 3 +- app/lib/bangtags.rb | 7 +--- app/models/imported_status.rb | 13 +++++++ app/models/normalized_status.rb | 1 + app/models/sharekey.rb | 13 +++++++ app/models/status.rb | 49 +++++++++++++++++++----- app/serializers/rest/status_serializer.rb | 10 +++-- app/services/post_status_service.rb | 2 +- 10 files changed, 80 insertions(+), 24 deletions(-) create mode 100644 app/models/imported_status.rb create mode 100644 app/models/sharekey.rb (limited to 'app') 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, -- cgit