about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/controllers/remote_interaction_controller.rb2
-rw-r--r--app/controllers/statuses_controller.rb4
-rw-r--r--app/lib/activitypub/activity/create.rb3
-rw-r--r--app/lib/bangtags.rb7
-rw-r--r--app/models/imported_status.rb13
-rw-r--r--app/models/normalized_status.rb1
-rw-r--r--app/models/sharekey.rb13
-rw-r--r--app/models/status.rb49
-rw-r--r--app/serializers/rest/status_serializer.rb10
-rw-r--r--app/services/post_status_service.rb2
10 files changed, 80 insertions, 24 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,