blob: a45681078ee2efca935906d0a004dc38369103e1 (
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
# frozen_string_literal: true
class ActivityPub::ProcessAccountService < BaseService
include JsonLdHelper
# Should be called with confirmed valid JSON
# and WebFinger-resolved username and domain
def call(username, domain, json)
return if json['inbox'].blank?
@json = json
@uri = @json['id']
@username = username
@domain = domain
@account = Account.find_by(uri: @uri)
@collections = {}
old_public_key = @account&.public_key
create_account if @account.nil?
upgrade_account if @account.ostatus?
update_account
RefollowWorker.perform_async(@account.id) if !old_public_key.nil? && old_public_key != @account.public_key
@account
rescue Oj::ParseError
nil
end
private
def create_account
@account = Account.new
@account.protocol = :activitypub
@account.username = @username
@account.domain = @domain
@account.uri = @uri
@account.suspended = true if auto_suspend?
@account.silenced = true if auto_silence?
@account.private_key = nil
@account.save!
end
def update_account
@account.last_webfingered_at = Time.now.utc
@account.protocol = :activitypub
@account.inbox_url = @json['inbox'] || ''
@account.outbox_url = @json['outbox'] || ''
@account.shared_inbox_url = (@json['endpoints'].is_a?(Hash) ? @json['endpoints']['sharedInbox'] : @json['sharedInbox']) || ''
@account.followers_url = @json['followers'] || ''
@account.url = url || @uri
@account.display_name = @json['name'] || ''
@account.note = @json['summary'] || ''
@account.avatar_remote_url = image_url('icon') unless skip_download?
@account.header_remote_url = image_url('image') unless skip_download?
@account.public_key = public_key || ''
@account.locked = @json['manuallyApprovesFollowers'] || false
@account.statuses_count = outbox_total_items if outbox_total_items.present?
@account.following_count = following_total_items if following_total_items.present?
@account.followers_count = followers_total_items if followers_total_items.present?
@account.save_with_optional_media!
end
def upgrade_account
ActivityPub::PostUpgradeWorker.perform_async(@account.domain)
end
def image_url(key)
value = first_of_value(@json[key])
return if value.nil?
return value['url'] if value.is_a?(Hash)
image = fetch_resource(value)
image['url'] if image
end
def public_key
value = first_of_value(@json['publicKey'])
return if value.nil?
return value['publicKeyPem'] if value.is_a?(Hash)
key = fetch_resource(value)
key['publicKeyPem'] if key
end
def url
return if @json['url'].blank?
value = first_of_value(@json['url'])
return value if value.is_a?(String)
value['href']
end
def outbox_total_items
collection_total_items('outbox')
end
def following_total_items
collection_total_items('following')
end
def followers_total_items
collection_total_items('followers')
end
def collection_total_items(type)
return if @json[type].blank?
return @collections[type] if @collections.key?(type)
collection = fetch_resource(@json[type])
@collections[type] = collection.is_a?(Hash) && collection['totalItems'].present? && collection['totalItems'].is_a?(Numeric) ? collection['totalItems'] : nil
rescue HTTP::Error, OpenSSL::SSL::SSLError
@collections[type] = nil
end
def skip_download?
@account.suspended? || domain_block&.reject_media?
end
def auto_suspend?
domain_block && domain_block.suspend?
end
def auto_silence?
domain_block && domain_block.silence?
end
def domain_block
return @domain_block if defined?(@domain_block)
@domain_block = DomainBlock.find_by(domain: @domain)
end
end
|