federails 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +28 -2
  3. data/app/controllers/federails/client/activities_controller.rb +8 -2
  4. data/app/controllers/federails/client/actors_controller.rb +4 -1
  5. data/app/controllers/federails/client/followings_controller.rb +4 -2
  6. data/app/controllers/federails/client_controller.rb +9 -0
  7. data/app/controllers/federails/server/activities_controller.rb +6 -1
  8. data/app/controllers/federails/server/actors_controller.rb +5 -1
  9. data/app/controllers/federails/server/followings_controller.rb +1 -1
  10. data/app/controllers/federails/server/nodeinfo_controller.rb +11 -5
  11. data/app/controllers/federails/server/web_finger_controller.rb +5 -1
  12. data/app/controllers/federails/{application_controller.rb → server_controller.rb} +6 -3
  13. data/app/helpers/federails/{application_helper.rb → server_helper.rb} +1 -1
  14. data/app/models/concerns/federails/entity.rb +55 -14
  15. data/app/models/federails/actor.rb +3 -1
  16. data/app/policies/federails/client/activity_policy.rb +3 -0
  17. data/app/policies/federails/client/actor_policy.rb +1 -1
  18. data/app/policies/federails/client/following_policy.rb +2 -2
  19. data/app/policies/federails/federails_policy.rb +4 -0
  20. data/app/policies/federails/server/activity_policy.rb +3 -0
  21. data/app/views/federails/client/activities/_activity.html.erb +1 -1
  22. data/app/views/federails/client/activities/feed.html.erb +8 -1
  23. data/app/views/federails/client/activities/index.html.erb +1 -1
  24. data/app/views/federails/client/actors/index.html.erb +14 -0
  25. data/app/views/federails/client/actors/show.html.erb +101 -89
  26. data/app/views/federails/client/common/_client_links.html.erb +24 -0
  27. data/app/views/federails/client/followings/_follow_actions.html.erb +32 -0
  28. data/app/views/federails/client/followings/_form.html.erb +1 -0
  29. data/app/views/federails/server/actors/_actor.activitypub.jbuilder +7 -2
  30. data/app/views/federails/server/nodeinfo/show.nodeinfo.jbuilder +8 -7
  31. data/config/initializers/mime_types.rb +1 -1
  32. data/config/routes.rb +6 -2
  33. data/db/migrate/20200712133150_create_federails_actors.rb +3 -5
  34. data/lib/federails/configuration.rb +9 -30
  35. data/lib/federails/version.rb +1 -1
  36. data/lib/federails.rb +11 -4
  37. data/lib/fediverse/inbox.rb +33 -37
  38. data/lib/fediverse/notifier.rb +1 -1
  39. data/lib/generators/federails/copy_client_views/USAGE +8 -0
  40. data/lib/generators/federails/copy_client_views/copy_client_views_generator.rb +9 -0
  41. data/lib/generators/federails/install/install_generator.rb +2 -2
  42. data/lib/generators/federails/install/templates/federails.yml +2 -0
  43. metadata +10 -7
  44. data/app/controllers/federails/server/server_controller.rb +0 -17
  45. data/db/migrate/20240731145400_change_actor_entity_rel_to_polymorphic.rb +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 070da5d2cc3d016475a69f797c6280595618d5f60de95cf7506bb2a1e9cbce4c
4
- data.tar.gz: a954535a092fa71fdb911f973363d8372b6d56e42b32190394e92026567c6913
3
+ metadata.gz: e489a0088b05ef80d9cc112164f054a030f0cb007406cb14789372a5a52c490f
4
+ data.tar.gz: b6832c622e5c33bf85f520839604a9e6e516821097d70bb6c6acb7df92f0d4b3
5
5
  SHA512:
6
- metadata.gz: 69fba1438beef26a150079c2a39eb185903025dcad3c24f5dfee941d844710d12938cf5546f0dc488f725096a2c4e6f32dfba4d1d3c825b9ba9418f063bb4ec9
7
- data.tar.gz: 01ef6821f7b1aa9422f013e23ed20b1225f0e630d4925ca81c7490f43d790a1d77a3b93e8d72783d93aee59f1760b48bbdd71a59feca353bca0a1277a6bd03c0
6
+ metadata.gz: 59e24e51b83545daabfa7dc0c878183d8b0bc14276b559b529fb5ee48183739c49b1a1987eb4a5e8d0d795dcfbe6970d6a3478691f9a13cd12c399903df61695
7
+ data.tar.gz: 01f6e7bef60bd2d15e142b7b55fecf25dd76ab67571c994c3c8aae1eba23fbcc75d02fb03775131a070b3cc6c18021d33ce91bb8645e937d94c1425a0a7433a3
data/README.md CHANGED
@@ -92,7 +92,7 @@ With `routes_path = 'federation'`, routes will be:
92
92
 
93
93
  Some routes can be disabled in configuration if you don't want to expose particular features:
94
94
 
95
- ```
95
+ ```rb
96
96
  Federails.configure do |config|
97
97
  # Disable routing for .well-known and nodeinfo
98
98
  config.enable_discovery = false
@@ -107,7 +107,7 @@ end
107
107
  By default, remote follow requests (where you press a follow button on another server and get redirected home to complete the follow)
108
108
  will use the built-in client paths. If you're not using the client, or want to provide your own user interface, you can set the path like this, assuming that `new_follow_url` is a valid route in your app. A `uri` query parameter template will be automatically appended, you don't need to specify that.
109
109
 
110
- ```
110
+ ```rb
111
111
  Federails.configure do |config|
112
112
  config.remote_follow_url_method = :new_follow_url
113
113
  end
@@ -154,6 +154,32 @@ actor.following
154
154
  #...
155
155
  ```
156
156
 
157
+ ### Using the Federails client
158
+
159
+ Federails comes with a client, enabled by default, that provides basic views to display and interact with Federails data,
160
+ accessible on `/app` by default (changeable with the configuration option `client_routes_path`)
161
+
162
+ If it's a good starting point, it might be disabled once you made your own integration by setting `client_routes_path`
163
+ to a `nil` value.
164
+
165
+ If you want to override the client's views, copy them in your application:
166
+
167
+ ```sh
168
+ rails generate federails:copy_client_views
169
+ ```
170
+
171
+ ## Common questions
172
+
173
+ - **I override the base controller and the links breaks in my layout**
174
+
175
+ Use `main_app.<url_helper>` for links to your application; `federails.<federails_url_helper>` for links to the Federails client.
176
+ - **I specified a custom layout and the links breaks in it**
177
+
178
+ Use `main_app.<url_helper>` for links to your application; `federails.<federails_url_helper>` for links to the Federails client.
179
+ - **I specified a custom layout and my helpers are not available**
180
+
181
+ You will have better results if you specify a `base_controller` from your application as Federails base controller is isolated from the main app and does not have access to its helpers.
182
+
157
183
  ## Contributing
158
184
 
159
185
  Contributions are welcome, may it be issues, ideas, code or whatever you want to share. Please note:
@@ -1,8 +1,8 @@
1
1
  module Federails
2
2
  module Client
3
- class ActivitiesController < Federails::ApplicationController
3
+ class ActivitiesController < Federails::ClientController
4
4
  before_action :authenticate_user!, only: [:feed]
5
- # layout 'layouts/application'
5
+ before_action :authorize_action!
6
6
 
7
7
  # GET /app/activities
8
8
  # GET /app/activities.json
@@ -16,6 +16,12 @@ module Federails
16
16
  def feed
17
17
  @activities = Activity.feed_for(current_user.actor)
18
18
  end
19
+
20
+ private
21
+
22
+ def authorize_action!
23
+ authorize(Federails::Activity, policy_class: Federails::Client::ActivityPolicy)
24
+ end
19
25
  end
20
26
  end
21
27
  end
@@ -1,12 +1,15 @@
1
1
  module Federails
2
2
  module Client
3
- class ActorsController < Federails::ApplicationController
3
+ class ActorsController < Federails::ClientController
4
4
  before_action :set_actor, only: [:show]
5
5
 
6
6
  # GET /app/actors
7
7
  # GET /app/actors.json
8
8
  def index
9
+ authorize Federails::Actor, policy_class: Federails::Client::ActorPolicy
10
+
9
11
  @actors = policy_scope(Federails::Actor, policy_scope_class: Federails::Client::ActorPolicy::Scope).all
12
+ @actors = @actors.local if params[:local_only]
10
13
  end
11
14
 
12
15
  # GET /app/actors/1
@@ -1,7 +1,8 @@
1
1
  module Federails
2
2
  module Client
3
- class FollowingsController < Federails::ApplicationController
3
+ class FollowingsController < Federails::ClientController
4
4
  before_action :authenticate_user!
5
+ before_action :skip_authorization, only: [:new, :create]
5
6
  before_action :set_following, only: [:accept, :destroy]
6
7
 
7
8
  # GET /app/followings/new?uri={uri}
@@ -40,9 +41,10 @@ module Federails
40
41
  # POST /app/followings/follow
41
42
  # POST /app/followings/follow.json
42
43
  def follow
44
+ authorize Federails::Following, policy_class: Federails::Client::FollowingPolicy
45
+
43
46
  begin
44
47
  @following = Following.new_from_account following_account_params, actor: current_user.actor
45
- authorize @following, policy_class: Federails::Client::FollowingPolicy
46
48
  rescue ::ActiveRecord::RecordNotFound
47
49
  # Renders a 422 instead of a 404
48
50
  respond_to do |format|
@@ -0,0 +1,9 @@
1
+ module Federails
2
+ class ClientController < Federails.configuration.base_client_controller.constantize
3
+ include Pundit::Authorization
4
+
5
+ after_action :verify_authorized
6
+
7
+ layout Federails.configuration.app_layout if Federails.configuration.app_layout
8
+ end
9
+ end
@@ -2,12 +2,14 @@ require 'fediverse/inbox'
2
2
 
3
3
  module Federails
4
4
  module Server
5
- class ActivitiesController < ServerController
5
+ class ActivitiesController < Federails::ServerController
6
6
  before_action :set_activity, only: [:show]
7
7
 
8
8
  # GET /federation/activities
9
9
  # GET /federation/actors/1/outbox.json
10
10
  def outbox
11
+ authorize Federails::Activity, policy_class: Federails::Server::ActivityPolicy
12
+
11
13
  @actor = Actor.find_param(params[:actor_id])
12
14
  @activities = policy_scope(Federails::Activity, policy_scope_class: Federails::Server::ActivityPolicy::Scope).where(actor: @actor).order(created_at: :desc)
13
15
  @total_activities = @activities.count
@@ -19,6 +21,8 @@ module Federails
19
21
 
20
22
  # POST /federation/actors/1/inbox
21
23
  def create
24
+ skip_authorization
25
+
22
26
  payload = payload_from_params
23
27
  return head :unprocessable_entity unless payload
24
28
 
@@ -34,6 +38,7 @@ module Federails
34
38
  # Use callbacks to share common setup or constraints between actions.
35
39
  def set_activity
36
40
  @activity = Actor.find_param(params[:actor_id]).activities.find_param(params[:id])
41
+ authorize @activity, policy_class: Federails::Server::ActivityPolicy
37
42
  end
38
43
 
39
44
  # Only allow a list of trusted parameters through.
@@ -1,17 +1,21 @@
1
1
  module Federails
2
2
  module Server
3
- class ActorsController < ServerController
3
+ class ActorsController < Federails::ServerController
4
4
  before_action :set_actor, only: [:show, :followers, :following]
5
5
 
6
6
  # GET /federation/actors/1
7
7
  # GET /federation/actors/1.json
8
8
  def show; end
9
9
 
10
+ # GET /federation/actors/:id/followers
11
+ # GET /federation/actors/:id/followers.json
10
12
  def followers
11
13
  @actors = @actor.followers.order(created_at: :desc)
12
14
  followings_queries
13
15
  end
14
16
 
17
+ # GET /federation/actors/:id/followers
18
+ # GET /federation/actors/:id/followers.json
15
19
  def following
16
20
  @actors = @actor.follows.order(created_at: :desc)
17
21
  followings_queries
@@ -1,6 +1,6 @@
1
1
  module Federails
2
2
  module Server
3
- class FollowingsController < ServerController
3
+ class FollowingsController < Federails::ServerController
4
4
  before_action :set_following, only: [:show]
5
5
 
6
6
  # GET /federation/actors/1/followings/1.json
@@ -1,19 +1,25 @@
1
1
  module Federails
2
2
  module Server
3
- class NodeinfoController < ServerController
3
+ class NodeinfoController < Federails::ServerController
4
4
  def index
5
+ skip_authorization
6
+
5
7
  render formats: [:nodeinfo]
6
8
  end
7
9
 
8
10
  def show # rubocop:todo Metrics/AbcSize
11
+ skip_authorization
12
+
9
13
  @total = @active_halfyear = @active_month = 0
14
+ @has_user_counts = false
10
15
  Federails::Configuration.entity_types.each_value do |config|
11
- next unless config[:include_in_user_count]
16
+ next unless (method = config[:user_count_method]&.to_sym)
12
17
 
18
+ @has_user_counts = true
13
19
  model = config[:class]
14
- @total += model.count
15
- @active_month += model.where(created_at: ((30.days.ago)...Time.current)).count
16
- @active_halfyear += model.where(created_at: ((180.days.ago)...Time.current)).count
20
+ @total += model.send(method, nil)
21
+ @active_month += model.send(method, ((30.days.ago)...Time.current))
22
+ @active_halfyear += model.send(method, ((180.days.ago)...Time.current))
17
23
  end
18
24
  render formats: [:nodeinfo]
19
25
  end
@@ -2,8 +2,10 @@ require 'fediverse/webfinger'
2
2
 
3
3
  module Federails
4
4
  module Server
5
- class WebFingerController < ServerController
5
+ class WebFingerController < Federails::ServerController
6
6
  def find
7
+ skip_authorization
8
+
7
9
  resource = params.require(:resource)
8
10
  case resource
9
11
  when %r{^https?://.+}
@@ -19,6 +21,8 @@ module Federails
19
21
  end
20
22
 
21
23
  def host_meta
24
+ skip_authorization
25
+
22
26
  render formats: [:xrd]
23
27
  end
24
28
 
@@ -1,10 +1,13 @@
1
1
  module Federails
2
- class ApplicationController < ActionController::Base
2
+ class ServerController < ::ActionController::Base # rubocop:disable Rails/ApplicationController
3
3
  include Pundit::Authorization
4
4
 
5
- rescue_from ActiveRecord::RecordNotFound, with: :error_not_found
5
+ after_action :verify_authorized
6
+
7
+ protect_from_forgery with: :null_session
8
+ helper Federails::ServerHelper
6
9
 
7
- layout Federails.configuration.app_layout if Federails.configuration.app_layout
10
+ rescue_from ActiveRecord::RecordNotFound, with: :error_not_found
8
11
 
9
12
  private
10
13
 
@@ -1,5 +1,5 @@
1
1
  module Federails
2
- module ApplicationHelper
2
+ module ServerHelper
3
3
  def remote_follow_url
4
4
  method_name = Federails.configuration.remote_follow_url_method.to_s
5
5
  if method_name.starts_with? 'federails.'
@@ -14,38 +14,79 @@ module Federails
14
14
  set_callback :followed, :after, method
15
15
  end
16
16
 
17
+ # Define a method that will be called after an activity has been received
18
+ # @param activity_type [String] The activity action to handle, e.g. 'Create'. If you specify '*', the handler will be called for any activity type.
19
+ # @param object_type [String] The object type to handle, e.g. 'Note'. If you specify '*', the handler will be called for any object type.
20
+ # @param method [Symbol] The name of the class method to call. The method will receive the complete activity payload as a parameter.
21
+ # @example
22
+ # after_activity_received 'Create', 'Note', :create_note
23
+ def self.after_activity_received(activity_type, object_type, method)
24
+ Fediverse::Inbox.register_handler(activity_type, object_type, self, method)
25
+ end
26
+
17
27
  has_one :actor, class_name: 'Federails::Actor', as: :entity, dependent: :destroy
18
28
 
19
- after_create :create_actor
29
+ after_create :create_actor, if: lambda {
30
+ raise("Entity not configured for #{self.class.name}. Did you use \"acts_as_federails_actor\"?") unless Federails::Configuration.entity_types.key? self.class.name
31
+
32
+ Federails::Configuration.entity_types[self.class.name][:auto_create_actors]
33
+ }
20
34
 
21
35
  # Configures the mapping between entity and actor
22
36
  # @param username_field [Symbol] The method or attribute name that returns the preferred username for ActivityPub
23
37
  # @param name_field [Symbol] The method or attribute name that returns the preferred name for ActivityPub
24
38
  # @param profile_url_method [Symbol] The route method name that will generate the profile URL for ActivityPub
25
39
  # @param actor_type [String] The ActivityStreams Actor type for this entity; defaults to 'Person'
26
- # @param include_in_user_count [boolean] Should this entity be included in the nodeinfo user count? Defaults to true
40
+ # @param user_count_method [Symbol] A class method to call to count active users. Leave unspecified to leave this
41
+ # entity out of user counts. Method signature should accept a single parameter which will specify a date range
42
+ # If parameter is nil, the total user count should be returned. If the parameter is specified, the number of users
43
+ # active during the time period should be returned.
44
+ # @param auto_create_actors [Boolean] Whether to automatically create an actor when the entity is created
27
45
  # @example
28
46
  # acts_as_federails_actor username_field: :username, name_field: :display_name, profile_url_method: :url_for, actor_type: 'Person'
47
+ # rubocop:disable Metrics/ParameterLists
29
48
  def self.acts_as_federails_actor(
30
- username_field: Federails::Configuration.user_username_field,
31
- name_field: Federails::Configuration.user_name_field,
32
- profile_url_method: Federails.configuration.user_profile_url_method,
49
+ name_field:,
50
+ username_field:,
51
+ profile_url_method: nil,
33
52
  actor_type: 'Person',
34
- include_in_user_count: true
53
+ user_count_method: nil,
54
+ auto_create_actors: true
35
55
  )
36
56
  Federails::Configuration.register_entity(
37
57
  self,
38
- username_field: username_field,
39
- name_field: name_field,
40
- profile_url_method: profile_url_method,
41
- actor_type: actor_type,
42
- include_in_user_count: include_in_user_count
58
+ username_field: username_field,
59
+ name_field: name_field,
60
+ profile_url_method: profile_url_method,
61
+ actor_type: actor_type,
62
+ user_count_method: user_count_method,
63
+ auto_create_actors: auto_create_actors
43
64
  )
44
65
  end
66
+ # rubocop:enable Metrics/ParameterLists
45
67
 
46
- # Automatically run default acts_as_federails_actor
47
- # this can be optionally called again with different configuration in the entity
48
- acts_as_federails_actor
68
+ # Add custom data to actor responses.
69
+ # Override in your own model to add extra data, which will be merged into the actor response
70
+ # generated by Federails. You can include extra `@context` for activitypub extensions and it will
71
+ # be merged with the main response context.
72
+ # @example
73
+ # def to_activitypub_object
74
+ # {
75
+ # "@context": {
76
+ # toot: "http://joinmastodon.org/ns#",
77
+ # attributionDomains: {
78
+ # "@id": "toot:attributionDomains",
79
+ # "@type": "@id"
80
+ # }
81
+ # },
82
+ # attributionDomains: [
83
+ # "example.com"
84
+ # ]
85
+ # }
86
+ # end
87
+ def to_activitypub_object
88
+ {}
89
+ end
49
90
 
50
91
  private
51
92
 
@@ -91,7 +91,9 @@ module Federails
91
91
  end
92
92
 
93
93
  def entity_configuration
94
- Federails::Configuration.entity_types[entity.class.name]
94
+ raise("Entity not configured for #{entity_type}. Did you use \"acts_as_federails_actor\"?") unless Federails::Configuration.entity_types.key? entity_type
95
+
96
+ Federails::Configuration.entity_types[entity_type]
95
97
  end
96
98
 
97
99
  class << self
@@ -1,6 +1,9 @@
1
1
  module Federails
2
2
  module Client
3
3
  class ActivityPolicy < Federails::FederailsPolicy
4
+ def feed?
5
+ user_with_actor?
6
+ end
4
7
  end
5
8
  end
6
9
  end
@@ -7,7 +7,7 @@ module Federails
7
7
 
8
8
  class Scope < Scope
9
9
  def resolve
10
- scope.local
10
+ scope
11
11
  end
12
12
  end
13
13
  end
@@ -26,9 +26,9 @@ module Federails
26
26
  private
27
27
 
28
28
  def in_following?
29
- return false if @user.blank?
29
+ return false unless user_with_actor?
30
30
 
31
- @record.actor_id == @user.actor.id || @record.target_actor_id == @user.actor.id
31
+ @record.actor_id == @user.actor&.id || @record.target_actor_id == @user.actor&.id
32
32
  end
33
33
  end
34
34
  end
@@ -55,5 +55,9 @@ module Federails
55
55
 
56
56
  @record.actor_id == @user.actor.id
57
57
  end
58
+
59
+ def user_with_actor?
60
+ @user && Federails.actor_entity?(@user) && !!@user.actor
61
+ end
58
62
  end
59
63
  end
@@ -1,6 +1,9 @@
1
1
  module Federails
2
2
  module Server
3
3
  class ActivityPolicy < Federails::FederailsPolicy
4
+ def outbox?
5
+ true
6
+ end
4
7
  end
5
8
  end
6
9
  end
@@ -1,5 +1,5 @@
1
1
  <div>
2
- <b><%= activity.actor.name %></b>
2
+ <b><%= link_to activity.actor.name, federails.client_actor_url(activity.actor) %></b>
3
3
  <code><%= activity.action %></code>
4
4
  <!-- < %= link_to activity.entity_type, activity.entity %>-->
5
5
  </div>
@@ -1,4 +1,11 @@
1
- <h1>Your feed !</h1>
1
+ <h1>Your feed</h1>
2
+ <p>
3
+ This is the list of activities from actors you follow.
4
+ </p>
5
+
6
+ <% if @activities.size.zero? %>
7
+ <p>There is nothing to display. Start following things!</p>
8
+ <% end %>
2
9
  <% @activities.each do |activity| %>
3
10
  <%= render 'activity', activity: activity %>
4
11
  <% end %>
@@ -1,5 +1,5 @@
1
1
  <h1>Listing activities</h1>
2
2
 
3
- <%= @activities.each do |activity| %>
3
+ <% @activities.each do |activity| %>
4
4
  <%= render 'activity', activity: activity %>
5
5
  <% end %>
@@ -1,5 +1,14 @@
1
1
  <h1>Listing actors</h1>
2
2
 
3
+ <section>
4
+ Filters:
5
+ <% if params[:local_only] %>
6
+ <%= link_to 'All actors', federails.client_actors_url %>
7
+ <% else %>
8
+ <%= link_to 'Only local actors', federails.client_actors_url(local_only: true) %>
9
+ <% end %>
10
+ </section>
11
+
3
12
  <table>
4
13
  <thead>
5
14
  <tr>
@@ -11,6 +20,11 @@
11
20
  </tr>
12
21
  </thead>
13
22
  <tbody>
23
+ <% if @actors.size.zero? %>
24
+ <tr>
25
+ <td colspan="5">There are no actors to display</td>
26
+ </tr>
27
+ <% end %>
14
28
  <% @actors.each do |actor| %>
15
29
  <tr>
16
30
  <td><%= actor.name %></td>
@@ -1,100 +1,112 @@
1
- <h2><%= @actor.name %></h2>
1
+ <h1><%= @actor.name %></h1>
2
+
3
+ <section>
4
+ <%= render 'federails/client/followings/follow_actions', user: current_user, actor: @actor %>
5
+ </section>
6
+
7
+ <section>
8
+ <% if @actor.local? %>
9
+ <%= link_to 'All activities', federails.client_actor_activities_path(@actor) %>
10
+ <% elsif @actor.profile_url %>
11
+ <%= link_to 'Visit profile', @actor.profile_url %>
12
+ <% end %>
13
+ </section>
14
+
15
+ <section>
16
+ <h2>Actor details</h2>
17
+
18
+ <p>
19
+ <b>Federated url:</b>
20
+ <%= @actor.federated_url %>
21
+ </p>
22
+
23
+ <p>
24
+ <b>Username:</b>
25
+ <%= @actor.username %>
26
+ </p>
27
+
28
+ <p>
29
+ <b>Inbox URL:</b>
30
+ <%= @actor.inbox_url %>
31
+ </p>
32
+
33
+ <p>
34
+ <b>Outbox URL:</b>
35
+ <%= @actor.outbox_url %>
36
+ </p>
37
+
38
+ <p>
39
+ <b>Followers URL:</b>
40
+ <%= @actor.followers_url %>
41
+ </p>
42
+
43
+ <p>
44
+ <b>Followings URL:</b>
45
+ <%= @actor.followings_url %>
46
+ </p>
47
+
48
+ <p>
49
+ <b>Profile url:</b>
50
+ <% if @actor.profile_url %>
51
+ <%= link_to 'Profile', @actor.profile_url %>
52
+ <% end %>
53
+ </p>
2
54
 
3
- <% if Federails::Client::FollowingPolicy.new(current_user, Federails::Following).create? %>
4
55
  <p>
5
- <%
6
- follow = current_user.actor.follows? @actor
7
- if @actor.entity == current_user
8
- %>
9
- <button role="button" disabled="disabled">That's you</button>
10
- <% elsif follow %>
11
- Already following (<%= follow.status %>)
12
- <%= button_to 'Revoke', federails.client_following_path(follow), method: :delete %>
56
+ <b>Federation address:</b>
57
+ <%= @actor.at_address %>
58
+ </p>
59
+
60
+ <p>
61
+ <% if @actor.local? && @actor.entity_configuration[:profile_url_method] %>
62
+ <b>Home page:</b>
63
+ <%= link_to @actor.entity.send(@actor.entity_configuration[:username_field]),
64
+ Rails.application.routes.url_helpers.send(@actor.entity_configuration[:profile_url_method], @actor.entity)
65
+ %>
66
+ <% elsif @actor.profile_url %>
67
+ <b>Federation profile URL (JSON):</b>
68
+ <%= link_to @actor.name, @actor.profile_url %>
13
69
  <% else %>
14
- <%= button_to 'Follow!', federails.follow_client_followings_path, params: { account: @actor.at_address }, method: :post %>
70
+ (No homepage)
15
71
  <% end %>
16
72
  </p>
17
- <% end %>
18
-
19
- <p>
20
- <b>Federated url:</b>
21
- <%= @actor.federated_url %>
22
- </p>
23
-
24
- <p>
25
- <b>Username:</b>
26
- <%= @actor.username %>
27
- </p>
28
-
29
- <p>
30
- <b>Inbox URL:</b>
31
- <%= @actor.inbox_url %>
32
- </p>
33
-
34
- <p>
35
- <b>Outbox URL:</b>
36
- <%= @actor.outbox_url %>
37
- </p>
38
-
39
- <p>
40
- <b>Followers URL:</b>
41
- <%= @actor.followers_url %>
42
- </p>
43
-
44
- <p>
45
- <b>Followings URL:</b>
46
- <%= @actor.followings_url %>
47
- </p>
48
-
49
- <p>
50
- <b>Profile url:</b>
51
- <% if @actor.profile_url %>
52
- <%= link_to 'Profile', @actor.profile_url %>
73
+ </section>
74
+
75
+ <hr>
76
+
77
+ <section>
78
+ <h2>Follows <small>(<em>Who is followed?</em>)</small></h2>
79
+
80
+ <% if @actor.following_follows.size.zero? %>
81
+ <p><%= @actor.username %> follows nothing</p>
53
82
  <% end %>
54
- </p>
55
83
 
56
- <p>
57
- <b>Federation address:</b>
58
- <%= @actor.at_address %>
59
- </p>
84
+ <% @actor.following_follows.each do |following| %>
85
+ <%= render 'federails/client/followings/follow', following: following %>
86
+ <% end %>
87
+ </section>
60
88
 
61
- <p>
62
- <b>Home page:</b>
63
- <% if @actor.local? && Federails::Configuration.user_profile_url_method %>
64
- <%= link_to @actor.send(Federails::Configuration.user_username_field), Rails.application.routes.url_helpers.send(Federails::Configuration.user_profile_url_method, @actor.user) %>
65
- <% elsif @actor.profile_url %>
66
- <%= link_to @actor.name, @actor.profile_url %>
67
- <% else %>
68
- (No homepage)
89
+ <section>
90
+ <h2>Followers <small>(<em>Who follows?</em>)</small></h2>
91
+
92
+ <% if @actor.following_followers.size.zero? %>
93
+ <p>Nothing follows <%= @actor.username %></p>
69
94
  <% end %>
70
- </p>
71
95
 
72
- <hr>
96
+ <% @actor.following_followers.each do |following| %>
97
+ <%= render 'federails/client/followings/follower', following: following %>
98
+ <% end %>
99
+ </section>
100
+
101
+ <section>
102
+ <%# FIXME: Fetch distant content somehow %>
103
+ <h2>10 last activities</h2>
73
104
 
74
- <h2>Follows</h2>
75
- <% if current_user && current_user == @actor.entity %>
76
- <%= render 'federails/client/followings/form', following: Federails::Following.new %>
77
- <% end %>
78
-
79
- <% @actor.following_follows.each do |following| %>
80
- <%= render 'federails/client/followings/follow', following: following %>
81
- <% end %>
82
-
83
- <h2>Followers</h2>
84
- <% @actor.following_followers.each do |following| %>
85
- <%= render 'federails/client/followings/follower', following: following %>
86
- <% end %>
87
-
88
- <%= link_to 'Back', federails.client_actors_url %>
89
-
90
- <!-- FIXME: Fetch distant content somehow -->
91
- <h2>10 last activities</h2>
92
- <% if @actor.local? %>
93
- <%= link_to 'All', federails.client_actor_activities_path(@actor) %>
94
- <% elsif @actor.profile_url %>
95
- <%= link_to 'Visit profile', @actor.profile_url %>
96
- <% end %>
97
-
98
- <% @actor.activities.last(10).each do |activity| %>
99
- <%= render 'federails/client/activities/activity', activity: activity %>
100
- <% end %>
105
+ <% activities = @actor.activities.last(10) %>
106
+ <% if activities.size.zero? %>
107
+ <p>No activity to display</p>
108
+ <% end %>
109
+ <% activities.each do |activity| %>
110
+ <%= render 'federails/client/activities/activity', activity: activity %>
111
+ <% end %>
112
+ </section>
@@ -0,0 +1,24 @@
1
+ Federation:
2
+
3
+ <ul>
4
+ <%# Available publicly %>
5
+ <li><%= link_to 'Actors', federails.client_actors_url %></li>
6
+ <li><%= link_to 'Activities', federails.client_activities_url %></li>
7
+
8
+ <%# Available when user has an associated actor %>
9
+ <% if Federails::Client::ActivityPolicy.new(user, nil).feed? %>
10
+ <li><%= link_to 'Feed', federails.client_feed_url %></li>
11
+ <%end %>
12
+
13
+ <%# Available when user has an associated actor. The actor must exist to create the link %>
14
+ <% if Federails.actor_entity?(user) && user.actor.present? %>
15
+ <li><%= link_to "You (#{user.actor.username})", federails.client_actor_path(user.actor) %></li>
16
+ <% end %>
17
+ </ul>
18
+
19
+ <%# Debug information%>
20
+ <% if !Federails::actor_entity?(user) %>
21
+ <p><%= user.class.name %> is not configured to have an associated actor; you won't be allowed to follow or be followed</p>
22
+ <% elsif !user.actor.present? %>
23
+ <p>Your account does not have an associated actor; you won't be allowed to follow or be followed</p>
24
+ <% end %>
@@ -0,0 +1,32 @@
1
+ <%#
2
+ Displays buttons to follow/revoke following on a given actor.
3
+ Requires variables:
4
+ - user (usually user)
5
+ - actor (target actor)
6
+ %>
7
+ <p>
8
+ <% if Federails::Client::FollowingPolicy.new(user, Federails::Following).create? %>
9
+ <% follow = user.actor.follows? actor %>
10
+ <% if actor.entity == user %>
11
+ <button type="button" role="button" disabled="disabled">That's you</button>
12
+ <% elsif follow %>
13
+ Already following (<%= follow.status %>)
14
+ <%= button_to 'Cancel', federails.client_following_path(follow), method: :delete %>
15
+ <% else %>
16
+ <%= button_to "Follow #{actor.username}", federails.follow_client_followings_path, params: { account: actor.at_address }, method: :post %>
17
+ <% end %>
18
+
19
+ <% followed = actor.follows? user.actor %>
20
+ <% if followed %>
21
+ <% if followed.pending? %>
22
+ <%= actor.username %> wants to follow you.
23
+ <%= button_to 'Accept request', federails.accept_client_following_path(followed), method: :put %>
24
+ <% else %>
25
+ <%= actor.username %> follows you.
26
+ <%= button_to 'Revoke', federails.client_following_path(followed), method: :delete %>
27
+ <% end %>
28
+ <% end %>
29
+ <% else %>
30
+ <%= user.class.name %> is not configured to follow/be followed, or has no associated actor.
31
+ <% end %>
32
+ </p>
@@ -1,4 +1,5 @@
1
1
  <%= form_for following, url: federails.client_following_url do |f| %>
2
+ <h1>DELETE ME</h1>
2
3
  <% if following.errors.any? %>
3
4
  <div class="error_explanation">
4
5
  <h2><%= pluralize(following.errors.count, 'error') %> prohibited this following from being saved:</h2>
@@ -1,7 +1,11 @@
1
- json.set! '@context', [
1
+ actor_data = actor.entity.to_activitypub_object
2
+
3
+ json.set! '@context', ([
2
4
  'https://www.w3.org/ns/activitystreams',
3
5
  'https://w3id.org/security/v1',
4
- ]
6
+ ] + [
7
+ actor_data&.delete(:@context),
8
+ ].flatten).compact
5
9
 
6
10
  json.id actor.federated_url
7
11
  json.name actor.name
@@ -19,3 +23,4 @@ if actor.public_key
19
23
  json.publicKeyPem actor.public_key
20
24
  end
21
25
  end
26
+ json.merge! actor_data
@@ -9,11 +9,12 @@ json.protocols [
9
9
  # http://nodeinfo.diaspora.software/ns/schema/2.0 for possible values
10
10
  json.services inbound: [],
11
11
  outbound: []
12
- # FIXME: Don't hardcode this
13
- json.openRegistrations true
14
- json.usage users: {
15
- total: @total,
16
- activeMonth: @active_month,
17
- activeHalfyear: @active_halfyear,
18
- }
12
+ json.openRegistrations Federails::Configuration.open_registrations
13
+ if @has_user_counts
14
+ json.usage users: {
15
+ total: @total,
16
+ activeMonth: @active_month,
17
+ activeHalfyear: @active_halfyear,
18
+ }
19
+ end
19
20
  json.metadata({})
@@ -3,7 +3,7 @@ Mime::Type.register 'application/jrd+json', :jrd
3
3
  Mime::Type.register 'application/xrd+xml', :xrd
4
4
 
5
5
  # ActivityPub: https://www.w3.org/TR/activitypub/#retrieving-objects
6
- Mime::Type.register 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', :activitypub, ['application/activity+json', 'application/json']
6
+ Mime::Type.register 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', :activitypub, ['application/activity+json']
7
7
 
8
8
  # Nodeinfo: https://github.com/jhass/nodeinfo/blob/main/PROTOCOL.md#retrieval
9
9
  Mime::Type.register 'application/json; profile="http://nodeinfo.diaspora.software/ns/schema/2.0#"', :nodeinfo
data/config/routes.rb CHANGED
@@ -10,7 +10,11 @@ Federails::Engine.routes.draw do
10
10
 
11
11
  if Federails.configuration.client_routes_path
12
12
  scope Federails.configuration.client_routes_path, module: :client, as: :client do
13
- resources :activities, only: [:index, :feed]
13
+ resources :activities, only: [:index] do
14
+ collection do
15
+ get :feed, to: 'activities#feed'
16
+ end
17
+ end
14
18
  resources :actors, only: [:index, :show] do
15
19
  collection do
16
20
  get :lookup, to: 'actors#lookup'
@@ -30,7 +34,7 @@ Federails::Engine.routes.draw do
30
34
  end
31
35
  end
32
36
 
33
- scope Federails.configuration.server_routes_path, module: :server, as: :server do
37
+ scope Federails.configuration.server_routes_path, module: :server, as: :server, defaults: { format: :activitypub } do
34
38
  resources :actors, only: [:show] do
35
39
  member do
36
40
  get :followers
@@ -11,14 +11,12 @@ class CreateFederailsActors < ActiveRecord::Migration[7.0]
11
11
  t.string :followings_url
12
12
  t.string :profile_url
13
13
 
14
- t.references :user, null: true, foreign_key: { to_table: Federails.configuration.user_table }
14
+ t.integer :entity_id, null: true
15
+ t.string :entity_type, null: true
15
16
 
16
17
  t.timestamps
17
18
  t.index :federated_url, unique: true
19
+ t.index [:entity_type, :entity_id], name: 'index_federails_actors_on_entity', unique: true
18
20
  end
19
- remove_foreign_key :federails_actors, :users if foreign_key_exists?(:federails_actors, :users)
20
- remove_index :federails_actors, :user_id
21
- add_index :federails_actors, :user_id, unique: true
22
- add_foreign_key :federails_actors, :users
23
21
  end
24
22
  end
@@ -25,15 +25,14 @@ module Federails
25
25
  mattr_accessor :enable_discovery
26
26
  @@enable_discovery = true
27
27
 
28
- # Site port
28
+ # Does the site allow open registrations? (only used for nodeinfo reporting)
29
+ mattr_accessor :open_registrations
30
+ @@open_registrations = false
31
+
32
+ # Application layout
29
33
  mattr_accessor :app_layout
30
34
  @@app_layout = nil
31
35
 
32
- # User class name
33
- # @deprecated Kept for upgrade compatibility only
34
- mattr_accessor :user_class
35
- @@user_class = '::User'
36
-
37
36
  # Route path for the federation URLs (to "Federails::Server::*" controllers)
38
37
  mattr_accessor :server_routes_path
39
38
  @@server_routes_path = :federation
@@ -42,34 +41,14 @@ module Federails
42
41
  mattr_accessor :client_routes_path
43
42
  @@client_routes_path = :app
44
43
 
44
+ # Default controller to use as base for client controllers
45
+ mattr_accessor :base_client_controller
46
+ @@base_client_controller = 'ActionController::Base'
47
+
45
48
  # Route method for remote-following requests
46
49
  mattr_accessor :remote_follow_url_method
47
50
  @@remote_follow_url_method = 'federails.new_client_following_url'
48
51
 
49
- # Method to use for links to user profiles
50
- # @deprecated Set profile_url_method option on acts_as_federails_actor instead
51
- mattr_accessor :user_profile_url_method
52
- @@user_profile_url_method = nil
53
-
54
- # Attribute in the user model to use as the user's name
55
- # @deprecated Set name_field option on acts_as_federails_actor instead
56
- #
57
- # It only have sense if you have a separate username attribute
58
- mattr_accessor :user_name_field
59
- @@user_name_field = nil
60
-
61
- # Attribute in the user model to use as the username for local actors
62
- # @deprecated Set username_field option on acts_as_federails_actor instead
63
- mattr_accessor :user_username_field
64
- @@user_username_field = :id
65
-
66
- ##
67
- # @return [String] Table used for user model
68
- # @deprecated Kept for upgrade compatibility only
69
- def self.user_table
70
- @@user_class&.constantize&.table_name
71
- end
72
-
73
52
  def self.site_host=(value)
74
53
  @@site_host = value
75
54
  Federails::Engine.routes.default_url_options[:host] = value
@@ -1,3 +1,3 @@
1
1
  module Federails
2
- VERSION = '0.2.0'.freeze
2
+ VERSION = '0.3.0'.freeze
3
3
  end
data/lib/federails.rb CHANGED
@@ -23,15 +23,22 @@ module Federails
23
23
  :site_host,
24
24
  :site_port,
25
25
  :enable_discovery,
26
+ :open_registrations,
26
27
  :app_layout,
27
- :user_class, # @deprecated
28
28
  :server_routes_path,
29
29
  :client_routes_path,
30
30
  :remote_follow_url_method,
31
- :user_profile_url_method, # @deprecated
32
- :user_name_field, # @deprecated
33
- :user_username_field, # @deprecated
31
+ :base_client_controller,
34
32
  ].each { |key| Configuration.send :"#{key}=", config[key] if config.key?(key) }
35
33
  end
34
+
35
+ # @return [Boolean] True if the given model is a possible entity
36
+ #
37
+ # @example
38
+ # puts "Follow #{some_actor.name}" if actor_entity? current_user
39
+ def self.actor_entity?(class_or_instance)
40
+ klass = class_or_instance.is_a?(Class) ? class_or_instance.name : class_or_instance.class.name
41
+ Configuration.entity_types.key? klass
42
+ end
36
43
  end
37
44
  # rubocop:enable Style/ClassVars
@@ -2,34 +2,33 @@ require 'fediverse/request'
2
2
 
3
3
  module Fediverse
4
4
  class Inbox
5
+ @@handlers = {} # rubocop:todo Style/ClassVars
5
6
  class << self
7
+ def register_handler(activity_type, object_type, klass, method)
8
+ @@handlers[activity_type] ||= {}
9
+ @@handlers[activity_type][object_type] ||= {}
10
+ @@handlers[activity_type][object_type][klass] = method
11
+ end
12
+
6
13
  def dispatch_request(payload)
7
- case payload['type']
8
- when 'Create'
9
- handle_create_request payload
10
- when 'Follow'
11
- handle_create_follow_request payload
12
- when 'Accept'
13
- handle_accept_request payload
14
- when 'Undo'
15
- handle_undo_request payload
16
- else
17
- # FIXME: Fails silently
18
- # raise NotImplementedError
19
- Rails.logger.debug { "Unhandled activity type: #{payload['type']}" }
14
+ handlers = get_handlers(payload['type'], payload['object'].is_a?(Hash) ? payload.dig('object', 'type') : nil)
15
+ handlers.each_pair do |klass, method|
16
+ klass.send method, payload
20
17
  end
18
+ return unless handlers.empty?
19
+
20
+ # FIXME: Fails silently
21
+ # raise NotImplementedError
22
+ Rails.logger.debug { "Unhandled activity type: #{payload['type']}" }
21
23
  end
22
24
 
23
25
  private
24
26
 
25
- def handle_create_request(payload)
26
- activity = Request.get(payload['object'])
27
- case activity['type']
28
- when 'Follow'
29
- handle_create_follow_request activity
30
- when 'Note'
31
- handle_create_note activity
32
- end
27
+ def get_handlers(activity_type, object_type)
28
+ {}.merge(@@handlers.dig(activity_type, object_type) || {})
29
+ .merge(@@handlers.dig(activity_type, '*') || {})
30
+ .merge(@@handlers.dig('*', '*') || {})
31
+ .merge(@@handlers.dig('*', object_type) || {})
33
32
  end
34
33
 
35
34
  def handle_create_follow_request(activity)
@@ -39,33 +38,30 @@ module Fediverse
39
38
  Federails::Following.create! actor: actor, target_actor: target_actor, federated_url: activity['id']
40
39
  end
41
40
 
42
- def handle_create_note(activity)
43
- actor = Federails::Actor.find_or_create_by_object activity['attributedTo']
44
- Note.create! actor: actor, content: activity['content'], federated_url: activity['id']
45
- end
41
+ def handle_accept_request(activity)
42
+ original_activity = Request.get(activity['object'])
46
43
 
47
- def handle_accept_request(payload)
48
- activity = Request.get(payload['object'])
49
- raise "Can't accept things that are not Follow" unless activity['type'] == 'Follow'
50
-
51
- actor = Federails::Actor.find_or_create_by_object activity['actor']
52
- target_actor = Federails::Actor.find_or_create_by_object activity['object']
53
- raise 'Follow not accepted by target actor but by someone else' if payload['actor'] != target_actor.federated_url
44
+ actor = Federails::Actor.find_or_create_by_object original_activity['actor']
45
+ target_actor = Federails::Actor.find_or_create_by_object original_activity['object']
46
+ raise 'Follow not accepted by target actor but by someone else' if activity['actor'] != target_actor.federated_url
54
47
 
55
48
  follow = Federails::Following.find_by actor: actor, target_actor: target_actor
56
49
  follow.accept!
57
50
  end
58
51
 
59
- def handle_undo_request(payload)
60
- activity = payload['object']
61
- raise "Can't undo things that are not Follow" unless activity['type'] == 'Follow'
52
+ def handle_undo_request(activity)
53
+ original_activity = activity['object']
62
54
 
63
- actor = Federails::Actor.find_or_create_by_object activity['actor']
64
- target_actor = Federails::Actor.find_or_create_by_object activity['object']
55
+ actor = Federails::Actor.find_or_create_by_object original_activity['actor']
56
+ target_actor = Federails::Actor.find_or_create_by_object original_activity['object']
65
57
 
66
58
  follow = Federails::Following.find_by actor: actor, target_actor: target_actor
67
59
  follow&.destroy
68
60
  end
69
61
  end
62
+
63
+ register_handler 'Follow', '*', self, :handle_create_follow_request
64
+ register_handler 'Accept', 'Follow', self, :handle_accept_request
65
+ register_handler 'Undo', 'Follow', self, :handle_undo_request
70
66
  end
71
67
  end
@@ -17,7 +17,7 @@ module Fediverse
17
17
  private
18
18
 
19
19
  def payload(activity)
20
- Federails::ApplicationController.renderer.new.render(
20
+ Federails::ServerController.renderer.new.render(
21
21
  template: 'federails/server/activities/show',
22
22
  assigns: { activity: activity },
23
23
  format: :json
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Copies the client views to be overridden in main application
3
+
4
+ Example:
5
+ bin/rails generate copy_client_views
6
+
7
+ This will create:
8
+ app/views/federails/client/**/*
@@ -0,0 +1,9 @@
1
+ module Federails
2
+ class CopyClientViewsGenerator < Rails::Generators::Base
3
+ source_root File.expand_path('../../../../app/views', __dir__)
4
+
5
+ def copy_views
6
+ directory 'federails/client', Rails.root.join('app', 'views', 'federails', 'client')
7
+ end
8
+ end
9
+ end
@@ -3,8 +3,8 @@ module Federails
3
3
  source_root File.expand_path('templates', __dir__)
4
4
 
5
5
  def copy_files
6
- copy_file 'federails.yml', 'config/federails.yml'
7
- copy_file 'federails.rb', 'config/initializers/federails.rb'
6
+ copy_file 'federails.yml', Rails.root.join('config', 'federails.yml')
7
+ copy_file 'federails.rb', Rails.root.join('config', 'initializers', 'federails.rb')
8
8
  end
9
9
  end
10
10
  end
@@ -6,9 +6,11 @@ defaults: &defaults
6
6
  site_host: http://localhost
7
7
  site_port: 3000
8
8
  enable_discovery: true
9
+ open_registrations: false
9
10
  app_layout: 'layouts/application'
10
11
  server_routes_path: federation
11
12
  client_routes_path: app
13
+ #base_client_controller: ::ActionController::Base
12
14
 
13
15
  development:
14
16
  <<: *defaults
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: federails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manuel Tancoigne
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-13 00:00:00.000000000 Z
11
+ date: 2024-11-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -119,17 +119,17 @@ files:
119
119
  - Rakefile
120
120
  - app/assets/config/federails_manifest.js
121
121
  - app/assets/stylesheets/federails/application.css
122
- - app/controllers/federails/application_controller.rb
123
122
  - app/controllers/federails/client/activities_controller.rb
124
123
  - app/controllers/federails/client/actors_controller.rb
125
124
  - app/controllers/federails/client/followings_controller.rb
125
+ - app/controllers/federails/client_controller.rb
126
126
  - app/controllers/federails/server/activities_controller.rb
127
127
  - app/controllers/federails/server/actors_controller.rb
128
128
  - app/controllers/federails/server/followings_controller.rb
129
129
  - app/controllers/federails/server/nodeinfo_controller.rb
130
- - app/controllers/federails/server/server_controller.rb
131
130
  - app/controllers/federails/server/web_finger_controller.rb
132
- - app/helpers/federails/application_helper.rb
131
+ - app/controllers/federails/server_controller.rb
132
+ - app/helpers/federails/server_helper.rb
133
133
  - app/jobs/federails/application_job.rb
134
134
  - app/jobs/federails/notify_inbox_job.rb
135
135
  - app/mailers/federails/application_mailer.rb
@@ -159,7 +159,9 @@ files:
159
159
  - app/views/federails/client/actors/index.json.jbuilder
160
160
  - app/views/federails/client/actors/show.html.erb
161
161
  - app/views/federails/client/actors/show.json.jbuilder
162
+ - app/views/federails/client/common/_client_links.html.erb
162
163
  - app/views/federails/client/followings/_follow.html.erb
164
+ - app/views/federails/client/followings/_follow_actions.html.erb
163
165
  - app/views/federails/client/followings/_follower.html.erb
164
166
  - app/views/federails/client/followings/_following.json.jbuilder
165
167
  - app/views/federails/client/followings/_form.html.erb
@@ -185,7 +187,6 @@ files:
185
187
  - db/migrate/20200712133150_create_federails_actors.rb
186
188
  - db/migrate/20200712143127_create_federails_followings.rb
187
189
  - db/migrate/20200712174938_create_federails_activities.rb
188
- - db/migrate/20240731145400_change_actor_entity_rel_to_polymorphic.rb
189
190
  - db/migrate/20241002094500_add_uuids.rb
190
191
  - db/migrate/20241002094501_add_keypair_to_actors.rb
191
192
  - lib/federails.rb
@@ -198,6 +199,8 @@ files:
198
199
  - lib/fediverse/request.rb
199
200
  - lib/fediverse/signature.rb
200
201
  - lib/fediverse/webfinger.rb
202
+ - lib/generators/federails/copy_client_views/USAGE
203
+ - lib/generators/federails/copy_client_views/copy_client_views_generator.rb
201
204
  - lib/generators/federails/install/USAGE
202
205
  - lib/generators/federails/install/install_generator.rb
203
206
  - lib/generators/federails/install/templates/federails.rb
@@ -227,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
227
230
  - !ruby/object:Gem::Version
228
231
  version: '0'
229
232
  requirements: []
230
- rubygems_version: 3.4.15
233
+ rubygems_version: 3.3.7
231
234
  signing_key:
232
235
  specification_version: 4
233
236
  summary: An ActivityPub engine for Ruby on Rails
@@ -1,17 +0,0 @@
1
- module Federails
2
- module Server
3
- class ServerController < Federails::ApplicationController
4
- protect_from_forgery with: :null_session
5
-
6
- # def policy_scope(scope, policy_scope_class: nil)
7
- # scope = [scope, :server] unless policy_scope_class
8
- # super(scope, policy_scope_class: policy_scope_class)
9
- # end
10
-
11
- # def authorize(record, query = nil, policy_class: nil)
12
- # record = [:server, record] unless policy_class
13
- # super(record, query, policy_class: policy_class)
14
- # end
15
- end
16
- end
17
- end
@@ -1,11 +0,0 @@
1
- class ChangeActorEntityRelToPolymorphic < ActiveRecord::Migration[7.0]
2
- def change
3
- remove_foreign_key :federails_actors, column: :user_id, to_table: Federails::Configuration.user_table
4
- remove_index :federails_actors, :user_id, unique: true
5
- change_table :federails_actors do |t|
6
- t.rename :user_id, :entity_id
7
- t.string :entity_type, null: true, default: Federails::Configuration.user_class&.demodulize
8
- t.index [:entity_type, :entity_id], name: 'index_federails_actors_on_entity', unique: true
9
- end
10
- end
11
- end