about summary refs log tree commit diff
path: root/app/lib/command_tag/command/account_tools.rb
blob: b433c32d46922a4b32de36e62565e83eea4082fa (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# frozen_string_literal: true
module CommandTag::Command::AccountTools
  def handle_account_at_start(args)
    return if args[0].blank?

    case args[0].downcase
    when 'set'
      handle_account_set(args[1..-1])
    end
  end

  alias handle_acct_at_start handle_account_at_start

  def handle_delete_before_save(args)
    unless args
      RemovalWorker.perform_async(@parent.id, immediate: true) if author_of_parent? && status_text_blank?
      return
    end

    args.flat_map(&:split).uniq.each do |id|
      if id.match?(/\A\d+\z/)
        object = @account.statuses.find_by(id: id)
      elsif id.start_with?('https://')
        begin
          object = ActivityPub::TagManager.instance.uri_to_resource(id, Status)
          if object.blank? && ActivityPub::TagManager.instance.local_uri?(id)
            id = Addressable::URI.parse(id)&.normalized_path&.sub(/\A.*\/([^\/]*)\/*/, '\1')
            next unless id.present? && id.match?(/\A\d+\z/)

            object = find_status_or_create_stub(id)
          end
        rescue Addressable::URI::InvalidURIError
          next
        end
      end

      next if object.blank? || object.account_id != @account.id

      RemovalWorker.perform_async(object.id, immediate: true, unpublished: true)
    end
  end

  alias handle_destroy_before_save handle_delete_before_save

  private

  def handle_account_set(args)
    return if args[0].blank?

    case args[0].downcase
    when 'v', 'p', 'visibility', 'privacy', 'default-visibility', 'default-privacy'
      args[1] = read_visibility_from(args[1])
      return if args[1].blank?

      if args[2].blank?
        @account.user.settings.default_privacy = args[1]
      elsif args[1] == 'public'
        domains = args[2..-1].map { |domain| normalize_domain(domain) unless domain == '*' }.uniq.compact
        @account.domain_permissions.where(domain: domains).destroy_all if domains.present?
      elsif args[1] != 'cc'
        args[2..-1].flat_map(&:split).uniq.each do |domain|
          domain = normalize_domain(domain) unless domain == '*'
          @account.domain_permissions.create_or_update(domain: domain, visibility: args[1]) if domain.present?
        end
      end
    end
  end

  def find_status_or_create_stub(id)
    status_params = {
      id: id,
      account: @account,
      text: '(Deleted)',
      local: true,
      visibility: :public,
      local_only: false,
      published: false,
    }
    Status.where(id: id).first_or_create(status_params)
  end
end