about summary refs log tree commit diff
path: root/app/models
diff options
context:
space:
mode:
authorStarfall <root@starfall.blue>2020-05-10 02:59:07 -0500
committerStarfall <root@starfall.blue>2020-05-10 02:59:07 -0500
commit77fa1183cc113e3d3d20140e3545443cf6c7f170 (patch)
tree2ce4e4dd5235999d163350779f18cf74fe1ff0d1 /app/models
parentb107e4f771f036b214563764fcd95786f8016ee7 (diff)
parentc6ff4c634caf718adf7280e04909c091d15add1d (diff)
Merge branch 'glitch'
Diffstat (limited to 'app/models')
-rw-r--r--app/models/account.rb92
-rw-r--r--app/models/account_alias.rb10
-rw-r--r--app/models/announcement.rb2
-rw-r--r--app/models/concerns/omniauthable.rb2
-rw-r--r--app/models/custom_emoji.rb29
-rw-r--r--app/models/media_attachment.rb35
-rw-r--r--app/models/preview_card.rb43
-rw-r--r--app/models/relay.rb4
-rw-r--r--app/models/status.rb8
-rw-r--r--app/models/unavailable_domain.rb22
-rw-r--r--app/models/user.rb30
11 files changed, 170 insertions, 107 deletions
diff --git a/app/models/account.rb b/app/models/account.rb
index 82d4d10de..5038d4768 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -3,50 +3,52 @@
 #
 # Table name: accounts
 #
-#  id                      :bigint(8)        not null, primary key
-#  username                :string           default(""), not null
-#  domain                  :string
-#  secret                  :string           default(""), not null
-#  private_key             :text
-#  public_key              :text             default(""), not null
-#  remote_url              :string           default(""), not null
-#  salmon_url              :string           default(""), not null
-#  hub_url                 :string           default(""), not null
-#  created_at              :datetime         not null
-#  updated_at              :datetime         not null
-#  note                    :text             default(""), not null
-#  display_name            :string           default(""), not null
-#  uri                     :string           default(""), not null
-#  url                     :string
-#  avatar_file_name        :string
-#  avatar_content_type     :string
-#  avatar_file_size        :integer
-#  avatar_updated_at       :datetime
-#  header_file_name        :string
-#  header_content_type     :string
-#  header_file_size        :integer
-#  header_updated_at       :datetime
-#  avatar_remote_url       :string
-#  subscription_expires_at :datetime
-#  locked                  :boolean          default(FALSE), not null
-#  header_remote_url       :string           default(""), not null
-#  last_webfingered_at     :datetime
-#  inbox_url               :string           default(""), not null
-#  outbox_url              :string           default(""), not null
-#  shared_inbox_url        :string           default(""), not null
-#  followers_url           :string           default(""), not null
-#  protocol                :integer          default("ostatus"), not null
-#  memorial                :boolean          default(FALSE), not null
-#  moved_to_account_id     :bigint(8)
-#  featured_collection_url :string
-#  fields                  :jsonb
-#  actor_type              :string
-#  discoverable            :boolean
-#  also_known_as           :string           is an Array
-#  silenced_at             :datetime
-#  suspended_at            :datetime
-#  trust_level             :integer
-#  hide_collections        :boolean
+#  id                            :bigint(8)        not null, primary key
+#  username                      :string           default(""), not null
+#  domain                        :string
+#  secret                        :string           default(""), not null
+#  private_key                   :text
+#  public_key                    :text             default(""), not null
+#  remote_url                    :string           default(""), not null
+#  salmon_url                    :string           default(""), not null
+#  hub_url                       :string           default(""), not null
+#  created_at                    :datetime         not null
+#  updated_at                    :datetime         not null
+#  note                          :text             default(""), not null
+#  display_name                  :string           default(""), not null
+#  uri                           :string           default(""), not null
+#  url                           :string
+#  avatar_file_name              :string
+#  avatar_content_type           :string
+#  avatar_file_size              :integer
+#  avatar_updated_at             :datetime
+#  header_file_name              :string
+#  header_content_type           :string
+#  header_file_size              :integer
+#  header_updated_at             :datetime
+#  avatar_remote_url             :string
+#  subscription_expires_at       :datetime
+#  locked                        :boolean          default(FALSE), not null
+#  header_remote_url             :string           default(""), not null
+#  last_webfingered_at           :datetime
+#  inbox_url                     :string           default(""), not null
+#  outbox_url                    :string           default(""), not null
+#  shared_inbox_url              :string           default(""), not null
+#  followers_url                 :string           default(""), not null
+#  protocol                      :integer          default("ostatus"), not null
+#  memorial                      :boolean          default(FALSE), not null
+#  moved_to_account_id           :bigint(8)
+#  featured_collection_url       :string
+#  fields                        :jsonb
+#  actor_type                    :string
+#  discoverable                  :boolean
+#  also_known_as                 :string           is an Array
+#  silenced_at                   :datetime
+#  suspended_at                  :datetime
+#  trust_level                   :integer
+#  hide_collections              :boolean
+#  avatar_storage_schema_version :integer
+#  header_storage_schema_version :integer
 #
 
 class Account < ApplicationRecord
@@ -415,7 +417,7 @@ class Account < ApplicationRecord
 
     def inboxes
       urls = reorder(nil).where(protocol: :activitypub).pluck(Arel.sql("distinct coalesce(nullif(accounts.shared_inbox_url, ''), accounts.inbox_url)"))
-      DeliveryFailureTracker.filter(urls)
+      DeliveryFailureTracker.without_unavailable(urls)
     end
 
     def search_for(terms, limit = 10, offset = 0)
diff --git a/app/models/account_alias.rb b/app/models/account_alias.rb
index 66f8ce409..792e9e8d4 100644
--- a/app/models/account_alias.rb
+++ b/app/models/account_alias.rb
@@ -16,8 +16,8 @@ class AccountAlias < ApplicationRecord
   belongs_to :account
 
   validates :acct, presence: true, domain: { acct: true }
-  validates :uri, presence: true
   validates :uri, uniqueness: { scope: :account_id }
+  validate :validate_target_account
 
   before_validation :set_uri
   after_create :add_to_account
@@ -44,4 +44,12 @@ class AccountAlias < ApplicationRecord
   def remove_from_account
     account.update(also_known_as: account.also_known_as.reject { |x| x == uri })
   end
+
+  def validate_target_account
+    if uri.blank?
+      errors.add(:acct, I18n.t('migrations.errors.not_found'))
+    elsif ActivityPub::TagManager.instance.uri_for(account) == uri
+      errors.add(:acct, I18n.t('migrations.errors.move_to_self'))
+    end
+  end
 end
diff --git a/app/models/announcement.rb b/app/models/announcement.rb
index a4e427b49..c493604c2 100644
--- a/app/models/announcement.rb
+++ b/app/models/announcement.rb
@@ -14,7 +14,7 @@
 #  created_at   :datetime         not null
 #  updated_at   :datetime         not null
 #  published_at :datetime
-#  status_ids   :bigint           is an Array
+#  status_ids   :bigint(8)        is an Array
 #
 
 class Announcement < ApplicationRecord
diff --git a/app/models/concerns/omniauthable.rb b/app/models/concerns/omniauthable.rb
index 960784222..736da6c1d 100644
--- a/app/models/concerns/omniauthable.rb
+++ b/app/models/concerns/omniauthable.rb
@@ -82,7 +82,7 @@ module Omniauthable
       username = starting_username
       i        = 0
 
-      while Account.exists?(username: username)
+      while Account.exists?(username: username, domain: nil)
         i       += 1
         username = "#{starting_username}_#{i}"
       end
diff --git a/app/models/custom_emoji.rb b/app/models/custom_emoji.rb
index d177cf281..7cb03b819 100644
--- a/app/models/custom_emoji.rb
+++ b/app/models/custom_emoji.rb
@@ -3,20 +3,21 @@
 #
 # Table name: custom_emojis
 #
-#  id                 :bigint(8)        not null, primary key
-#  shortcode          :string           default(""), not null
-#  domain             :string
-#  image_file_name    :string
-#  image_content_type :string
-#  image_file_size    :integer
-#  image_updated_at   :datetime
-#  created_at         :datetime         not null
-#  updated_at         :datetime         not null
-#  disabled           :boolean          default(FALSE), not null
-#  uri                :string
-#  image_remote_url   :string
-#  visible_in_picker  :boolean          default(TRUE), not null
-#  category_id        :bigint(8)
+#  id                           :bigint(8)        not null, primary key
+#  shortcode                    :string           default(""), not null
+#  domain                       :string
+#  image_file_name              :string
+#  image_content_type           :string
+#  image_file_size              :integer
+#  image_updated_at             :datetime
+#  created_at                   :datetime         not null
+#  updated_at                   :datetime         not null
+#  disabled                     :boolean          default(FALSE), not null
+#  uri                          :string
+#  image_remote_url             :string
+#  visible_in_picker            :boolean          default(TRUE), not null
+#  category_id                  :bigint(8)
+#  image_storage_schema_version :integer
 #
 
 class CustomEmoji < ApplicationRecord
diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb
index 40624c73c..f789bdc55 100644
--- a/app/models/media_attachment.rb
+++ b/app/models/media_attachment.rb
@@ -3,23 +3,24 @@
 #
 # Table name: media_attachments
 #
-#  id                  :bigint(8)        not null, primary key
-#  status_id           :bigint(8)
-#  file_file_name      :string
-#  file_content_type   :string
-#  file_file_size      :integer
-#  file_updated_at     :datetime
-#  remote_url          :string           default(""), not null
-#  created_at          :datetime         not null
-#  updated_at          :datetime         not null
-#  shortcode           :string
-#  type                :integer          default("image"), not null
-#  file_meta           :json
-#  account_id          :bigint(8)
-#  description         :text
-#  scheduled_status_id :bigint(8)
-#  blurhash            :string
-#  processing          :integer
+#  id                          :bigint(8)        not null, primary key
+#  status_id                   :bigint(8)
+#  file_file_name              :string
+#  file_content_type           :string
+#  file_file_size              :integer
+#  file_updated_at             :datetime
+#  remote_url                  :string           default(""), not null
+#  created_at                  :datetime         not null
+#  updated_at                  :datetime         not null
+#  shortcode                   :string
+#  type                        :integer          default("image"), not null
+#  file_meta                   :json
+#  account_id                  :bigint(8)
+#  description                 :text
+#  scheduled_status_id         :bigint(8)
+#  blurhash                    :string
+#  processing                  :integer
+#  file_storage_schema_version :integer
 #
 
 class MediaAttachment < ApplicationRecord
diff --git a/app/models/preview_card.rb b/app/models/preview_card.rb
index 4e89fbf85..2802f4667 100644
--- a/app/models/preview_card.rb
+++ b/app/models/preview_card.rb
@@ -3,25 +3,26 @@
 #
 # Table name: preview_cards
 #
-#  id                 :bigint(8)        not null, primary key
-#  url                :string           default(""), not null
-#  title              :string           default(""), not null
-#  description        :string           default(""), not null
-#  image_file_name    :string
-#  image_content_type :string
-#  image_file_size    :integer
-#  image_updated_at   :datetime
-#  type               :integer          default("link"), not null
-#  html               :text             default(""), not null
-#  author_name        :string           default(""), not null
-#  author_url         :string           default(""), not null
-#  provider_name      :string           default(""), not null
-#  provider_url       :string           default(""), not null
-#  width              :integer          default(0), not null
-#  height             :integer          default(0), not null
-#  created_at         :datetime         not null
-#  updated_at         :datetime         not null
-#  embed_url          :string           default(""), not null
+#  id                           :bigint(8)        not null, primary key
+#  url                          :string           default(""), not null
+#  title                        :string           default(""), not null
+#  description                  :string           default(""), not null
+#  image_file_name              :string
+#  image_content_type           :string
+#  image_file_size              :integer
+#  image_updated_at             :datetime
+#  type                         :integer          default("link"), not null
+#  html                         :text             default(""), not null
+#  author_name                  :string           default(""), not null
+#  author_url                   :string           default(""), not null
+#  provider_name                :string           default(""), not null
+#  provider_url                 :string           default(""), not null
+#  width                        :integer          default(0), not null
+#  height                       :integer          default(0), not null
+#  created_at                   :datetime         not null
+#  updated_at                   :datetime         not null
+#  embed_url                    :string           default(""), not null
+#  image_storage_schema_version :integer
 #
 
 class PreviewCard < ApplicationRecord
@@ -47,6 +48,10 @@ class PreviewCard < ApplicationRecord
 
   before_save :extract_dimensions, if: :link?
 
+  def local?
+    false
+  end
+
   def missing_image?
     width.present? && height.present? && image_file_name.blank?
   end
diff --git a/app/models/relay.rb b/app/models/relay.rb
index 8c8a97db3..d6ddd30ed 100644
--- a/app/models/relay.rb
+++ b/app/models/relay.rb
@@ -27,7 +27,7 @@ class Relay < ApplicationRecord
     payload     = Oj.dump(follow_activity(activity_id))
 
     update!(state: :pending, follow_activity_id: activity_id)
-    DeliveryFailureTracker.new(inbox_url).track_success!
+    DeliveryFailureTracker.reset!(inbox_url)
     ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
   end
 
@@ -36,7 +36,7 @@ class Relay < ApplicationRecord
     payload     = Oj.dump(unfollow_activity(activity_id))
 
     update!(state: :idle, follow_activity_id: nil)
-    DeliveryFailureTracker.new(inbox_url).track_success!
+    DeliveryFailureTracker.reset!(inbox_url)
     ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
   end
 
diff --git a/app/models/status.rb b/app/models/status.rb
index 31e77770d..34fa00912 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -206,12 +206,8 @@ class Status < ApplicationRecord
   def title
     if destroyed?
       "#{account.acct} deleted status"
-    elsif reblog?
-      preview = sensitive ? '<sensitive>' : text.slice(0, 10).split("\n")[0]
-      "#{account.acct} shared #{reblog.account.acct}'s: #{preview}"
     else
-      preview = sensitive ? '<sensitive>' : text.slice(0, 20).split("\n")[0]
-      "#{account.acct}: #{preview}"
+      reblog? ? "#{account.acct} shared a status by #{reblog.account.acct}" : "New status by #{account.acct}"
     end
   end
 
@@ -404,7 +400,7 @@ class Status < ApplicationRecord
 
       if account.nil?
         where(visibility: visibility).not_local_only
-      elsif target_account.blocking?(account) # get rid of blocked peeps
+      elsif target_account.blocking?(account) || (account.domain.present? && target_account.domain_blocking?(account.domain)) # get rid of blocked peeps
         none
       elsif account.id == target_account.id # author can see own stuff
         all
diff --git a/app/models/unavailable_domain.rb b/app/models/unavailable_domain.rb
new file mode 100644
index 000000000..e2918b586
--- /dev/null
+++ b/app/models/unavailable_domain.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+# == Schema Information
+#
+# Table name: unavailable_domains
+#
+#  id         :bigint(8)        not null, primary key
+#  domain     :string           default(""), not null
+#  created_at :datetime         not null
+#  updated_at :datetime         not null
+#
+
+class UnavailableDomain < ApplicationRecord
+  include DomainNormalizable
+
+  after_commit :reset_cache!
+
+  private
+
+  def reset_cache!
+    Rails.cache.delete('unavailable_domains')
+  end
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index cd8a6f273..c8dbd2fd3 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -98,6 +98,7 @@ class User < ApplicationRecord
 
   before_validation :sanitize_languages
   before_create :set_approved
+  after_commit :send_pending_devise_notifications
 
   # This avoids a deprecation warning from Rails 5.1
   # It seems possible that a future release of devise-two-factor will
@@ -307,11 +308,38 @@ class User < ApplicationRecord
   protected
 
   def send_devise_notification(notification, *args)
-    devise_mailer.send(notification, self, *args).deliver_later
+    # This method can be called in `after_update` and `after_commit` hooks,
+    # but we must make sure the mailer is actually called *after* commit,
+    # otherwise it may work on stale data. To do this, figure out if we are
+    # within a transaction.
+    if ActiveRecord::Base.connection.current_transaction.try(:records)&.include?(self)
+      pending_devise_notifications << [notification, args]
+    else
+      render_and_send_devise_message(notification, *args)
+    end
   end
 
   private
 
+  def send_pending_devise_notifications
+    pending_devise_notifications.each do |notification, args|
+      render_and_send_devise_message(notification, *args)
+    end
+
+    # Empty the pending notifications array because the
+    # after_commit hook can be called multiple times which
+    # could cause multiple emails to be sent.
+    pending_devise_notifications.clear
+  end
+
+  def pending_devise_notifications
+    @pending_devise_notifications ||= []
+  end
+
+  def render_and_send_devise_message(notification, *args)
+    devise_mailer.send(notification, self, *args).deliver_later
+  end
+
   def set_approved
     self.approved = open_registrations? || valid_invitation? || external?
   end