federails 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +26 -1
- data/app/controllers/federails/client/actors_controller.rb +18 -4
- data/app/controllers/federails/server/actors_controller.rb +4 -1
- data/app/controllers/federails/server/published_controller.rb +1 -1
- data/app/controllers/federails/server/web_finger_controller.rb +9 -6
- data/app/controllers/federails/server_controller.rb +7 -0
- data/app/models/concerns/federails/actor_entity.rb +40 -8
- data/app/models/concerns/federails/data_entity.rb +49 -22
- data/app/models/concerns/federails/handles_delete_requests.rb +31 -0
- data/app/models/federails/activity.rb +15 -4
- data/app/models/federails/actor.rb +87 -31
- data/app/models/federails/following.rb +28 -9
- data/app/views/federails/client/actors/_actor.json.jbuilder +4 -1
- data/app/views/federails/client/actors/gone.html.erb +1 -0
- data/app/views/federails/client/actors/index.html.erb +7 -1
- data/app/views/federails/server/activities/_activity.activitypub.jbuilder +8 -3
- data/app/views/federails/server/actors/_actor.activitypub.jbuilder +2 -2
- data/app/views/federails/server/actors/_tombstone.activitypub.jbuilder +9 -0
- data/app/views/federails/server/actors/show.activitypub.jbuilder +5 -1
- data/app/views/federails/server/published/_tombstone.activitypub.jbuilder +9 -0
- data/app/views/federails/server/published/show.activitypub.jbuilder +5 -1
- data/db/migrate/20250122160618_add_extensions_to_federails_actors.rb +5 -0
- data/db/migrate/20250301082500_add_local_to_actors.rb +11 -0
- data/db/migrate/20250329123939_add_actor_type_to_actors.rb +5 -0
- data/db/migrate/20250329123940_add_tombstoned_at_to_actors.rb +5 -0
- data/lib/federails/configuration.rb +5 -1
- data/lib/federails/data_transformer/note.rb +1 -1
- data/lib/federails/maintenance/actors_updater.rb +67 -0
- data/lib/federails/utils/actor.rb +53 -0
- data/lib/federails/utils/object.rb +25 -0
- data/lib/federails/version.rb +1 -1
- data/lib/fediverse/inbox.rb +25 -4
- data/lib/fediverse/webfinger.rb +19 -23
- data/lib/tasks/federails_tasks.rake +8 -4
- metadata +13 -6
@@ -9,17 +9,21 @@ module Federails
|
|
9
9
|
|
10
10
|
belongs_to :actor
|
11
11
|
belongs_to :target_actor, class_name: 'Federails::Actor'
|
12
|
-
# FIXME: Handle this with something like undelete
|
13
12
|
has_many :activities, as: :entity, dependent: :destroy
|
14
13
|
|
15
14
|
after_create :after_follow
|
16
|
-
after_create :create_activity
|
17
|
-
|
15
|
+
after_create :create_activity, if: :locally_instigated?
|
16
|
+
after_update :after_follow_accepted
|
17
|
+
after_destroy :destroy_activity, if: :locally_instigated?
|
18
|
+
|
19
|
+
define_callbacks :on_federails_delete_requested
|
20
|
+
|
21
|
+
set_callback :on_federails_delete_requested, -> { destroy! unless locally_instigated? }
|
18
22
|
|
19
23
|
scope :with_actor, ->(actor) { where(actor_id: actor.id).or(where(target_actor_id: actor.id)) }
|
20
24
|
|
21
25
|
def federated_url
|
22
|
-
attributes['federated_url'].presence || Federails::Engine.routes.url_helpers.server_actor_following_url(actor_id:
|
26
|
+
attributes['federated_url'].presence || Federails::Engine.routes.url_helpers.server_actor_following_url(actor_id: actor.to_param, id: to_param)
|
23
27
|
end
|
24
28
|
|
25
29
|
def accept!
|
@@ -27,6 +31,10 @@ module Federails
|
|
27
31
|
Activity.create! actor: target_actor, action: 'Accept', entity: self
|
28
32
|
end
|
29
33
|
|
34
|
+
def follow_activity
|
35
|
+
Activity.find_by actor: actor, action: 'Follow', entity: target_actor
|
36
|
+
end
|
37
|
+
|
30
38
|
class << self
|
31
39
|
def new_from_account(account, actor:)
|
32
40
|
target_actor = Actor.find_or_create_by_account account
|
@@ -36,18 +44,29 @@ module Federails
|
|
36
44
|
|
37
45
|
private
|
38
46
|
|
47
|
+
def locally_instigated?
|
48
|
+
actor.local?
|
49
|
+
end
|
50
|
+
|
39
51
|
def after_follow
|
40
|
-
target_actor&.entity
|
41
|
-
|
42
|
-
|
52
|
+
return unless target_actor&.entity
|
53
|
+
|
54
|
+
target_actor.entity.class.send(:dispatch_callback, :after_followed, target_actor.entity, self)
|
55
|
+
end
|
56
|
+
|
57
|
+
def after_follow_accepted
|
58
|
+
return unless status_previously_changed? && status == 'accepted'
|
59
|
+
return unless actor&.entity
|
60
|
+
|
61
|
+
actor.entity.class.send(:dispatch_callback, :after_follow_accepted, actor.entity, self)
|
43
62
|
end
|
44
63
|
|
45
64
|
def create_activity
|
46
|
-
Activity.create! actor: actor, action: '
|
65
|
+
Activity.create! actor: actor, action: 'Follow', entity: target_actor
|
47
66
|
end
|
48
67
|
|
49
68
|
def destroy_activity
|
50
|
-
Activity.create! actor: actor, action: 'Undo', entity:
|
69
|
+
Activity.create! actor: actor, action: 'Undo', entity: follow_activity
|
51
70
|
end
|
52
71
|
end
|
53
72
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= t('.gone') %>
|
@@ -27,7 +27,13 @@
|
|
27
27
|
<% end %>
|
28
28
|
<% @actors.each do |actor| %>
|
29
29
|
<tr>
|
30
|
-
<td
|
30
|
+
<td>
|
31
|
+
<% if actor.tombstoned? %>
|
32
|
+
<del><%= actor.name %></del>
|
33
|
+
<% else %>
|
34
|
+
<%= actor.name %>
|
35
|
+
<% end %>
|
36
|
+
</td>
|
31
37
|
<td><%= actor.username %></td>
|
32
38
|
<td><%= actor.at_address %></td>
|
33
39
|
<td><%= actor.local? %></td>
|
@@ -1,13 +1,18 @@
|
|
1
1
|
context = true unless context == false
|
2
|
+
addressing = true unless addressing == false
|
2
3
|
json.set! '@context', 'https://www.w3.org/ns/activitystreams' if context
|
3
4
|
|
4
5
|
json.id Federails::Engine.routes.url_helpers.server_actor_activity_url activity.actor, activity
|
5
6
|
json.type activity.action
|
6
7
|
json.actor activity.actor.federated_url
|
7
|
-
|
8
|
-
json.
|
8
|
+
if addressing
|
9
|
+
json.to ['https://www.w3.org/ns/activitystreams#Public']
|
10
|
+
json.cc [activity.actor.followers_url]
|
11
|
+
end
|
9
12
|
|
10
|
-
if activity.entity.
|
13
|
+
if activity.entity.is_a? Federails::Activity
|
14
|
+
json.object { json.partial!('federails/server/activities/activity', activity: activity.entity, context: false, addressing: false) }
|
15
|
+
elsif activity.entity.respond_to? :to_activitypub_object
|
11
16
|
json.object activity.entity.to_activitypub_object
|
12
17
|
elsif activity.entity.respond_to? :federated_url
|
13
18
|
json.object activity.entity.federated_url
|
@@ -1,4 +1,4 @@
|
|
1
|
-
actor_data = actor.entity
|
1
|
+
actor_data = actor.entity&.to_activitypub_object || {}
|
2
2
|
|
3
3
|
json.set! '@context', ([
|
4
4
|
'https://www.w3.org/ns/activitystreams',
|
@@ -9,7 +9,7 @@ json.set! '@context', ([
|
|
9
9
|
|
10
10
|
json.id actor.federated_url
|
11
11
|
json.name actor.name
|
12
|
-
json.type actor.
|
12
|
+
json.type actor.actor_type
|
13
13
|
json.preferredUsername actor.username
|
14
14
|
json.inbox actor.inbox_url
|
15
15
|
json.outbox actor.outbox_url
|
@@ -0,0 +1,9 @@
|
|
1
|
+
json.set! '@context', [
|
2
|
+
'https://www.w3.org/ns/activitystreams',
|
3
|
+
'https://w3id.org/security/v1',
|
4
|
+
]
|
5
|
+
|
6
|
+
json.id publishable.federated_url
|
7
|
+
json.type 'Tombstone'
|
8
|
+
json.deleted publishable.federails_tombstoned_at
|
9
|
+
json.formerType publishable.federails_data_configuration[:handles]
|
@@ -1 +1,5 @@
|
|
1
|
-
|
1
|
+
if @publishable.federails_tombstoned?
|
2
|
+
json.partial! 'federails/server/published/tombstone', publishable: @publishable
|
3
|
+
else
|
4
|
+
json.partial! 'federails/server/published/publishable', publishable: @publishable
|
5
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class AddLocalToActors < ActiveRecord::Migration[7.0]
|
2
|
+
def change
|
3
|
+
add_column :federails_actors, :local, :boolean, null: false, default: false
|
4
|
+
|
5
|
+
reversible do |dir|
|
6
|
+
dir.up do
|
7
|
+
exec_update 'UPDATE federails_actors SET local=true WHERE entity_type IS NOT NULL'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -28,8 +28,12 @@ module Federails
|
|
28
28
|
@@enable_discovery = true
|
29
29
|
|
30
30
|
# Does the site allow open registrations? (only used for nodeinfo reporting)
|
31
|
-
|
31
|
+
# Can either be a static boolean, or a Proc which will be called to get the state.
|
32
|
+
mattr_writer :open_registrations
|
32
33
|
@@open_registrations = false
|
34
|
+
def self.open_registrations
|
35
|
+
@@open_registrations.is_a?(Proc) ? @@open_registrations.call : @@open_registrations
|
36
|
+
end
|
33
37
|
|
34
38
|
# Application layout
|
35
39
|
mattr_accessor :app_layout
|
@@ -3,7 +3,7 @@ module Federails
|
|
3
3
|
module Note
|
4
4
|
# Renders a Note. The entity is used to determine actor and generic fields data
|
5
5
|
#
|
6
|
-
# @param entity [#federail_actor] A model instance
|
6
|
+
# @param entity [#federail_actor, #federated_url, #created_at, #updated_at] A model instance
|
7
7
|
# @param content [String] Note content
|
8
8
|
# @param name [String, nil] Optional name/title
|
9
9
|
# @param custom [Hash] Optional additional keys (e.g.: attachment, icon, ...). Defaults will override these.
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Federails
|
2
|
+
module Maintenance
|
3
|
+
class ActorsUpdater
|
4
|
+
class << self
|
5
|
+
# Fetches all distant actors again and update their local copy
|
6
|
+
#
|
7
|
+
# A block can be passed with two arguments: the actor being updated and the update status
|
8
|
+
#
|
9
|
+
# @param actors [Integer, Federails::Actor, Array<Federails::Actor>, nil] Actor ID, Actor or list of actors to update.
|
10
|
+
# If nothing is passed, all distant actors are processed
|
11
|
+
# @example
|
12
|
+
# Update all distant actors
|
13
|
+
# Federails::Maintenance::ActorUpdater.run
|
14
|
+
# With an actor id:
|
15
|
+
# Federails::Maintenance::ActorUpdater.run 1
|
16
|
+
# With a federated URL:
|
17
|
+
# Federails::Maintenance::ActorUpdater.run 'https://example.com/actor'
|
18
|
+
# With a federated URL:
|
19
|
+
# Federails::Maintenance::ActorUpdater.run ['https://example.com/actors/1', 'https://example.com/actors/1']
|
20
|
+
# With actors:
|
21
|
+
# Federails::Maintenance::ActorUpdater.run Federails::Actor.last(10)
|
22
|
+
# Update all distant actors and puts status for each actor
|
23
|
+
# Federails::Maintenance::ActorUpdater.run {|actor, status| puts "#{actor.federated_url}: #{status}"}
|
24
|
+
def run(actors = nil, &block)
|
25
|
+
actors_list(actors).each do |actor|
|
26
|
+
status = update(actor)
|
27
|
+
|
28
|
+
yield(actor, status) if block
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# Make a list of actors to update from the passed attribute
|
35
|
+
def actors_list(param) # rubocop:disable Metrics/PerceivedComplexity, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/AbcSize
|
36
|
+
if param.nil?
|
37
|
+
Federails::Actor.distant
|
38
|
+
elsif param.is_a? String
|
39
|
+
[Federails::Actor.distant.find_by!(federated_url: param)]
|
40
|
+
elsif param.is_a? Integer
|
41
|
+
[Federails::Actor.distant.find(param)]
|
42
|
+
elsif param.is_a?(Federails::Actor)
|
43
|
+
[param]
|
44
|
+
elsif param.respond_to?(:pluck) && param.first.is_a?(Federails::Actor)
|
45
|
+
param
|
46
|
+
elsif param.is_a?(Array) && param.first.is_a?(String)
|
47
|
+
Federails::Actor.distant.where(federated_url: param)
|
48
|
+
else
|
49
|
+
raise "Cannot extract actors from #{param.class}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# @param actor [Federails::Actor]
|
54
|
+
def update(actor)
|
55
|
+
return :ignored_local if actor.local?
|
56
|
+
|
57
|
+
response = Fediverse::Webfinger.fetch_actor_url(actor.federated_url)
|
58
|
+
new_attributes = response.attributes.except 'id', 'uuid', 'created_at', 'updated_at', 'local'
|
59
|
+
|
60
|
+
actor.update(new_attributes) ? :updated : :failed
|
61
|
+
rescue ActiveRecord::RecordNotFound
|
62
|
+
:not_found
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Federails
|
2
|
+
module Utils
|
3
|
+
class Actor
|
4
|
+
# List of the attributes computed for local actors
|
5
|
+
COMPUTED_ATTRIBUTES = [
|
6
|
+
:federated_url,
|
7
|
+
:username,
|
8
|
+
:name,
|
9
|
+
:server,
|
10
|
+
:inbox_url,
|
11
|
+
:outbox_url,
|
12
|
+
:followers_url,
|
13
|
+
:followings_url,
|
14
|
+
:profile_url,
|
15
|
+
].freeze
|
16
|
+
|
17
|
+
class << self
|
18
|
+
# @param actor [Federails::Actor]
|
19
|
+
# @return [Federails::Actor]
|
20
|
+
def tombstone!(actor)
|
21
|
+
if actor.local?
|
22
|
+
tombstone_local_actor actor
|
23
|
+
else
|
24
|
+
tombstone_distant_actor actor
|
25
|
+
end
|
26
|
+
|
27
|
+
actor
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def tombstone_local_actor(actor)
|
33
|
+
Federails::Actor.transaction do
|
34
|
+
hash = {
|
35
|
+
tombstoned_at: Time.current,
|
36
|
+
entity: nil,
|
37
|
+
}
|
38
|
+
# Hardcode attributes depending on the actor's entity
|
39
|
+
COMPUTED_ATTRIBUTES.each { |attribute| hash[attribute] = actor.send(attribute) }
|
40
|
+
|
41
|
+
actor.update! hash
|
42
|
+
|
43
|
+
Activity.create! actor: actor, action: 'Delete', entity: actor
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def tombstone_distant_actor(actor)
|
48
|
+
actor.update! tombstoned_at: Time.current
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -20,6 +20,31 @@ module Federails
|
|
20
20
|
from_distant_server(object_or_id)
|
21
21
|
end
|
22
22
|
|
23
|
+
# Search for a distant object in actors and configured data entities.
|
24
|
+
#
|
25
|
+
# This is useful to find something when the type is unknown, as an object from a Delete activity.
|
26
|
+
#
|
27
|
+
# @param federated_url [String] Object identifier
|
28
|
+
# @return [Federails::Actor, Federails::DataEntity, Federails::Following, nil]
|
29
|
+
def find_distant_object_in_all(federated_url)
|
30
|
+
# Search in actors
|
31
|
+
object = Federails::Actor.find_by federated_url: federated_url
|
32
|
+
return object if object.present?
|
33
|
+
|
34
|
+
# Search in followings
|
35
|
+
object = Federails::Following.find_by federated_url: federated_url
|
36
|
+
return object if object.present?
|
37
|
+
|
38
|
+
# Search in data entities
|
39
|
+
Federails.configuration.data_types.keys.sort.each do |klass|
|
40
|
+
object = klass.constantize.find_by federated_url: federated_url
|
41
|
+
|
42
|
+
break if object.present?
|
43
|
+
end
|
44
|
+
|
45
|
+
object
|
46
|
+
end
|
47
|
+
|
23
48
|
# Finds or initializes an entity from an ActivityPub object or id
|
24
49
|
#
|
25
50
|
# @see .find_or_initialize
|
data/lib/federails/version.rb
CHANGED
data/lib/fediverse/inbox.rb
CHANGED
@@ -6,6 +6,9 @@ module Fediverse
|
|
6
6
|
class << self
|
7
7
|
# Registers a handler for incoming data
|
8
8
|
#
|
9
|
+
# Unless a specific type is not implemented in Federails, you should leave the 'Delete' activity to Federails:
|
10
|
+
# it will dispatch a `on_federails_delete_requested` event on the right objects.
|
11
|
+
#
|
9
12
|
# @param activity_type [String] Target activity type ('Create', 'Follow', 'Like', ...)
|
10
13
|
# See https://www.w3.org/TR/activitystreams-vocabulary/#activity-types for a list of common ones
|
11
14
|
# @param object_type [String] Type of the related object ('Article', 'Note', ...)
|
@@ -22,6 +25,8 @@ module Fediverse
|
|
22
25
|
#
|
23
26
|
# @param payload [Hash] Dereferenced activity
|
24
27
|
def dispatch_request(payload)
|
28
|
+
return dispatch_delete_request(payload) if payload['type'] == 'Delete'
|
29
|
+
|
25
30
|
payload['object'] = Fediverse::Request.dereference(payload['object']) if payload.key? 'object'
|
26
31
|
|
27
32
|
handlers = get_handlers(payload['type'], payload.dig('object', 'type'))
|
@@ -36,6 +41,14 @@ module Fediverse
|
|
36
41
|
|
37
42
|
private
|
38
43
|
|
44
|
+
def dispatch_delete_request(payload)
|
45
|
+
payload['object'] = payload['object']['id'] unless payload['object'].is_a? String
|
46
|
+
object = Federails::Utils::Object.find_distant_object_in_all payload['object']
|
47
|
+
return if object.blank?
|
48
|
+
|
49
|
+
object.run_callbacks :on_federails_delete_requested
|
50
|
+
end
|
51
|
+
|
39
52
|
def get_handlers(activity_type, object_type)
|
40
53
|
{}.merge(@@handlers.dig(activity_type, object_type) || {})
|
41
54
|
.merge(@@handlers.dig(activity_type, '*') || {})
|
@@ -50,7 +63,7 @@ module Fediverse
|
|
50
63
|
Federails::Following.create! actor: actor, target_actor: target_actor, federated_url: activity['id']
|
51
64
|
end
|
52
65
|
|
53
|
-
def
|
66
|
+
def handle_accept_follow_request(activity)
|
54
67
|
original_activity = Request.dereference(activity['object'])
|
55
68
|
|
56
69
|
actor = Federails::Actor.find_or_create_by_object original_activity['actor']
|
@@ -61,7 +74,7 @@ module Fediverse
|
|
61
74
|
follow.accept!
|
62
75
|
end
|
63
76
|
|
64
|
-
def
|
77
|
+
def handle_undo_follow_request(activity)
|
65
78
|
original_activity = activity['object']
|
66
79
|
|
67
80
|
actor = Federails::Actor.find_or_create_by_object original_activity['actor']
|
@@ -70,10 +83,18 @@ module Fediverse
|
|
70
83
|
follow = Federails::Following.find_by actor: actor, target_actor: target_actor
|
71
84
|
follow&.destroy
|
72
85
|
end
|
86
|
+
|
87
|
+
def handle_delete_request(activity)
|
88
|
+
object = Federails::Utils::Object.find_distant_object_in_all(activity['object'])
|
89
|
+
return if object.blank?
|
90
|
+
|
91
|
+
object.run_callbacks :on_federails_delete_requested
|
92
|
+
end
|
73
93
|
end
|
74
94
|
|
75
95
|
register_handler 'Follow', '*', self, :handle_create_follow_request
|
76
|
-
register_handler 'Accept', 'Follow', self, :
|
77
|
-
register_handler 'Undo', 'Follow', self, :
|
96
|
+
register_handler 'Accept', 'Follow', self, :handle_accept_follow_request
|
97
|
+
register_handler 'Undo', 'Follow', self, :handle_undo_follow_request
|
98
|
+
register_handler 'Delete', '*', self, :handle_delete_request
|
78
99
|
end
|
79
100
|
end
|
data/lib/fediverse/webfinger.rb
CHANGED
@@ -9,22 +9,14 @@ module Fediverse
|
|
9
9
|
class << self
|
10
10
|
ACCOUNT_REGEX = /(?<username>[a-z0-9\-_.]+)(?:@(?<domain>.*))?/
|
11
11
|
|
12
|
-
# Extracts username and domain from
|
13
|
-
#
|
14
|
-
# @param account [String] Account string
|
15
|
-
#
|
16
|
-
# @return [MatchData, nil] Matches with +:username+ and +:domain+ or +nil+
|
17
|
-
def split_resource_account(account)
|
18
|
-
/\Aacct:#{ACCOUNT_REGEX}\z/io.match account
|
19
|
-
end
|
20
|
-
|
21
|
-
# Extracts username and domain from a "username@domain" string
|
12
|
+
# Extracts username and domain from an account string.
|
13
|
+
# Accepts forms "user@domain", "@user@domain" and "acct:user@domain"
|
22
14
|
#
|
23
15
|
# @param account [String] Account string
|
24
16
|
#
|
25
17
|
# @return [MatchData, nil] Matches with +:username+ and +:domain+ or +nil+
|
26
18
|
def split_account(account)
|
27
|
-
/\A
|
19
|
+
/\A(acct:|@)?#{ACCOUNT_REGEX}\z/io.match account
|
28
20
|
end
|
29
21
|
|
30
22
|
# Determines if a given account string should be a local account (same host as configured one)
|
@@ -63,7 +55,7 @@ module Fediverse
|
|
63
55
|
# @return [String, nil] Federation URL if found
|
64
56
|
def webfinger(username, domain)
|
65
57
|
json = webfinger_response(username, domain)
|
66
|
-
link = json['links'].find { |l| l['type'] ==
|
58
|
+
link = json['links'].find { |l| Mime::Type.lookup(l['type']).to_sym == :activitypub }
|
67
59
|
|
68
60
|
link['href'] if link
|
69
61
|
end
|
@@ -110,17 +102,21 @@ module Fediverse
|
|
110
102
|
# Builds a +Federails::Actor+ from a Webfinger response
|
111
103
|
# @param data [Hash] Webfinger response
|
112
104
|
# @return [Federails::Actor]
|
113
|
-
def webfinger_to_actor(data)
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
105
|
+
def webfinger_to_actor(data) # rubocop:disable Metrics/MethodLength
|
106
|
+
data = data.clone
|
107
|
+
id = data.delete('id')
|
108
|
+
Federails::Actor.new federated_url: id,
|
109
|
+
username: data.delete('preferredUsername'),
|
110
|
+
actor_type: data.delete('type'),
|
111
|
+
name: data.delete('name'),
|
112
|
+
server: server_and_port(id),
|
113
|
+
inbox_url: data.delete('inbox'),
|
114
|
+
outbox_url: data.delete('outbox'),
|
115
|
+
followers_url: data.delete('followers'),
|
116
|
+
followings_url: data.delete('following'),
|
117
|
+
profile_url: data.delete('url'),
|
118
|
+
public_key: data.delete('publicKey')&.dig('publicKeyPem'),
|
119
|
+
extensions: data.except('@context')
|
124
120
|
end
|
125
121
|
|
126
122
|
# Makes a simple GET request and returns a +Hash+ from the parsed body
|
@@ -1,4 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
namespace :federails do
|
2
|
+
desc 'Re-fetches every remote actors to update database'
|
3
|
+
task sync_actors: :environment do
|
4
|
+
Federails::Maintenance::ActorUpdater.run do |actor, status|
|
5
|
+
puts "#{actor.federated_url}: #{status}"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: federails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Manuel Tancoigne
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date: 2025-
|
10
|
+
date: 2025-04-07 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: faraday
|
@@ -137,6 +136,7 @@ files:
|
|
137
136
|
- app/mailers/federails/application_mailer.rb
|
138
137
|
- app/models/concerns/federails/actor_entity.rb
|
139
138
|
- app/models/concerns/federails/data_entity.rb
|
139
|
+
- app/models/concerns/federails/handles_delete_requests.rb
|
140
140
|
- app/models/concerns/federails/has_uuid.rb
|
141
141
|
- app/models/federails/activity.rb
|
142
142
|
- app/models/federails/actor.rb
|
@@ -159,6 +159,7 @@ files:
|
|
159
159
|
- app/views/federails/client/activities/index.json.jbuilder
|
160
160
|
- app/views/federails/client/actors/_actor.json.jbuilder
|
161
161
|
- app/views/federails/client/actors/_lookup_form.html.erb
|
162
|
+
- app/views/federails/client/actors/gone.html.erb
|
162
163
|
- app/views/federails/client/actors/index.html.erb
|
163
164
|
- app/views/federails/client/actors/index.json.jbuilder
|
164
165
|
- app/views/federails/client/actors/show.html.erb
|
@@ -177,6 +178,7 @@ files:
|
|
177
178
|
- app/views/federails/server/activities/outbox.activitypub.jbuilder
|
178
179
|
- app/views/federails/server/activities/show.activitypub.jbuilder
|
179
180
|
- app/views/federails/server/actors/_actor.activitypub.jbuilder
|
181
|
+
- app/views/federails/server/actors/_tombstone.activitypub.jbuilder
|
180
182
|
- app/views/federails/server/actors/followers.activitypub.jbuilder
|
181
183
|
- app/views/federails/server/actors/following.activitypub.jbuilder
|
182
184
|
- app/views/federails/server/actors/show.activitypub.jbuilder
|
@@ -185,6 +187,7 @@ files:
|
|
185
187
|
- app/views/federails/server/nodeinfo/index.nodeinfo.jbuilder
|
186
188
|
- app/views/federails/server/nodeinfo/show.nodeinfo.jbuilder
|
187
189
|
- app/views/federails/server/published/_publishable.activitypub.jbuilder
|
190
|
+
- app/views/federails/server/published/_tombstone.activitypub.jbuilder
|
188
191
|
- app/views/federails/server/published/show.activitypub.jbuilder
|
189
192
|
- app/views/federails/server/web_finger/find.jrd.jbuilder
|
190
193
|
- app/views/federails/server/web_finger/host_meta.xrd.erb
|
@@ -195,10 +198,16 @@ files:
|
|
195
198
|
- db/migrate/20200712174938_create_federails_activities.rb
|
196
199
|
- db/migrate/20241002094500_add_uuids.rb
|
197
200
|
- db/migrate/20241002094501_add_keypair_to_actors.rb
|
201
|
+
- db/migrate/20250122160618_add_extensions_to_federails_actors.rb
|
202
|
+
- db/migrate/20250301082500_add_local_to_actors.rb
|
203
|
+
- db/migrate/20250329123939_add_actor_type_to_actors.rb
|
204
|
+
- db/migrate/20250329123940_add_tombstoned_at_to_actors.rb
|
198
205
|
- lib/federails.rb
|
199
206
|
- lib/federails/configuration.rb
|
200
207
|
- lib/federails/data_transformer/note.rb
|
201
208
|
- lib/federails/engine.rb
|
209
|
+
- lib/federails/maintenance/actors_updater.rb
|
210
|
+
- lib/federails/utils/actor.rb
|
202
211
|
- lib/federails/utils/host.rb
|
203
212
|
- lib/federails/utils/object.rb
|
204
213
|
- lib/federails/version.rb
|
@@ -224,7 +233,6 @@ metadata:
|
|
224
233
|
homepage_uri: https://experimentslabs.com
|
225
234
|
source_code_uri: https://gitlab.com/experimentslabs/federails/
|
226
235
|
changelog_uri: https://gitlab.com/experimentslabs/federails/-/blob/main/CHANGELOG.md
|
227
|
-
post_install_message:
|
228
236
|
rdoc_options: []
|
229
237
|
require_paths:
|
230
238
|
- lib
|
@@ -239,8 +247,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
239
247
|
- !ruby/object:Gem::Version
|
240
248
|
version: '0'
|
241
249
|
requirements: []
|
242
|
-
rubygems_version: 3.5
|
243
|
-
signing_key:
|
250
|
+
rubygems_version: 3.6.5
|
244
251
|
specification_version: 4
|
245
252
|
summary: An ActivityPub engine for Ruby on Rails
|
246
253
|
test_files: []
|