Add account migration UI (#11846)
Fix #10736 - Change data export to be available for non-functional accounts - Change non-functional accounts to include redirecting accounts
This commit is contained in:
parent
b6df9c1067
commit
3ed94dcc1a
31 changed files with 542 additions and 73 deletions
41
app/models/account_alias.rb
Normal file
41
app/models/account_alias.rb
Normal file
|
@ -0,0 +1,41 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: account_aliases
|
||||
#
|
||||
# id :bigint(8) not null, primary key
|
||||
# account_id :bigint(8)
|
||||
# acct :string default(""), not null
|
||||
# uri :string default(""), not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
|
||||
class AccountAlias < ApplicationRecord
|
||||
belongs_to :account
|
||||
|
||||
validates :acct, presence: true, domain: { acct: true }
|
||||
validates :uri, presence: true
|
||||
|
||||
before_validation :set_uri
|
||||
after_create :add_to_account
|
||||
after_destroy :remove_from_account
|
||||
|
||||
private
|
||||
|
||||
def set_uri
|
||||
target_account = ResolveAccountService.new.call(acct)
|
||||
self.uri = ActivityPub::TagManager.instance.uri_for(target_account) unless target_account.nil?
|
||||
rescue Goldfinger::Error, HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::Error
|
||||
# Validation will take care of it
|
||||
end
|
||||
|
||||
def add_to_account
|
||||
account.update(also_known_as: account.also_known_as + [uri])
|
||||
end
|
||||
|
||||
def remove_from_account
|
||||
account.update(also_known_as: account.also_known_as.reject { |x| x == uri })
|
||||
end
|
||||
end
|
74
app/models/account_migration.rb
Normal file
74
app/models/account_migration.rb
Normal file
|
@ -0,0 +1,74 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: account_migrations
|
||||
#
|
||||
# id :bigint(8) not null, primary key
|
||||
# account_id :bigint(8)
|
||||
# acct :string default(""), not null
|
||||
# followers_count :bigint(8) default(0), not null
|
||||
# target_account_id :bigint(8)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
|
||||
class AccountMigration < ApplicationRecord
|
||||
COOLDOWN_PERIOD = 30.days.freeze
|
||||
|
||||
belongs_to :account
|
||||
belongs_to :target_account, class_name: 'Account'
|
||||
|
||||
before_validation :set_target_account
|
||||
before_validation :set_followers_count
|
||||
|
||||
validates :acct, presence: true, domain: { acct: true }
|
||||
validate :validate_migration_cooldown
|
||||
validate :validate_target_account
|
||||
|
||||
scope :within_cooldown, ->(now = Time.now.utc) { where(arel_table[:created_at].gteq(now - COOLDOWN_PERIOD)) }
|
||||
|
||||
attr_accessor :current_password, :current_username
|
||||
|
||||
def save_with_challenge(current_user)
|
||||
if current_user.encrypted_password.present?
|
||||
errors.add(:current_password, :invalid) unless current_user.valid_password?(current_password)
|
||||
else
|
||||
errors.add(:current_username, :invalid) unless account.username == current_username
|
||||
end
|
||||
|
||||
return false unless errors.empty?
|
||||
|
||||
save
|
||||
end
|
||||
|
||||
def cooldown_at
|
||||
created_at + COOLDOWN_PERIOD
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_target_account
|
||||
self.target_account = ResolveAccountService.new.call(acct)
|
||||
rescue Goldfinger::Error, HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::Error
|
||||
# Validation will take care of it
|
||||
end
|
||||
|
||||
def set_followers_count
|
||||
self.followers_count = account.followers_count
|
||||
end
|
||||
|
||||
def validate_target_account
|
||||
if target_account.nil?
|
||||
errors.add(:acct, I18n.t('migrations.errors.not_found'))
|
||||
else
|
||||
errors.add(:acct, I18n.t('migrations.errors.missing_also_known_as')) unless target_account.also_known_as.include?(ActivityPub::TagManager.instance.uri_for(account))
|
||||
errors.add(:acct, I18n.t('migrations.errors.already_moved')) if account.moved_to_account_id.present? && account.moved_to_account_id == target_account.id
|
||||
errors.add(:acct, I18n.t('migrations.errors.move_to_self')) if account.id == target_account.id
|
||||
end
|
||||
end
|
||||
|
||||
def validate_migration_cooldown
|
||||
errors.add(:base, I18n.t('migrations.errors.on_cooldown')) if account.migrations.within_cooldown.exists?
|
||||
end
|
||||
end
|
|
@ -52,6 +52,8 @@ module AccountAssociations
|
|||
|
||||
# Account migrations
|
||||
belongs_to :moved_to_account, class_name: 'Account', optional: true
|
||||
has_many :migrations, class_name: 'AccountMigration', dependent: :destroy, inverse_of: :account
|
||||
has_many :aliases, class_name: 'AccountAlias', dependent: :destroy, inverse_of: :account
|
||||
|
||||
# Hashtags
|
||||
has_and_belongs_to_many :tags
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Form::Migration
|
||||
include ActiveModel::Validations
|
||||
|
||||
attr_accessor :acct, :account
|
||||
|
||||
def initialize(attrs = {})
|
||||
@account = attrs[:account]
|
||||
@acct = attrs[:account].acct unless @account.nil?
|
||||
@acct = attrs[:acct].gsub(/\A@/, '').strip unless attrs[:acct].nil?
|
||||
end
|
||||
|
||||
def valid?
|
||||
return false unless super
|
||||
set_account
|
||||
errors.empty?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_account
|
||||
self.account = (ResolveAccountService.new.call(acct) if account.nil? && acct.present?)
|
||||
end
|
||||
end
|
|
@ -49,7 +49,7 @@ class RemoteFollow
|
|||
end
|
||||
|
||||
def fetch_template!
|
||||
return missing_resource if acct.blank?
|
||||
return missing_resource_error if acct.blank?
|
||||
|
||||
_, domain = acct.split('@')
|
||||
|
||||
|
|
|
@ -168,7 +168,7 @@ class User < ApplicationRecord
|
|||
end
|
||||
|
||||
def functional?
|
||||
confirmed? && approved? && !disabled? && !account.suspended?
|
||||
confirmed? && approved? && !disabled? && !account.suspended? && account.moved_to_account_id.nil?
|
||||
end
|
||||
|
||||
def unconfirmed_or_pending?
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue