about summary refs log tree commit diff
path: root/app/services
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2017-08-26 13:47:38 +0200
committerGitHub <noreply@github.com>2017-08-26 13:47:38 +0200
commit00840f4f2edb8d1d46638ccbc90a1f4462d0867a (patch)
treec4f6c9a4967df5d5f23094ddefed88c621d6c3ff /app/services
parent1cebfed23e03b9d31796cdc139acde1b6dccd9f3 (diff)
Add handling of Linked Data Signatures in payloads (#4687)
* Add handling of Linked Data Signatures in payloads

* Add a way to sign JSON, fix canonicalization of signature options

* Fix signatureValue encoding, send out signed JSON when distributing

* Add missing security context
Diffstat (limited to 'app/services')
-rw-r--r--app/services/activitypub/process_collection_service.rb11
-rw-r--r--app/services/authorize_follow_service.rb4
-rw-r--r--app/services/batched_remove_status_service.rb8
-rw-r--r--app/services/block_service.rb4
-rw-r--r--app/services/favourite_service.rb4
-rw-r--r--app/services/follow_service.rb4
-rw-r--r--app/services/process_mentions_service.rb4
-rw-r--r--app/services/reblog_service.rb4
-rw-r--r--app/services/reject_follow_service.rb4
-rw-r--r--app/services/remove_status_service.rb10
-rw-r--r--app/services/unblock_service.rb4
-rw-r--r--app/services/unfavourite_service.rb4
-rw-r--r--app/services/unfollow_service.rb4
13 files changed, 44 insertions, 25 deletions
diff --git a/app/services/activitypub/process_collection_service.rb b/app/services/activitypub/process_collection_service.rb
index cd861c075..2cf15553d 100644
--- a/app/services/activitypub/process_collection_service.rb
+++ b/app/services/activitypub/process_collection_service.rb
@@ -9,6 +9,8 @@ class ActivityPub::ProcessCollectionService < BaseService
 
     return if @account.suspended? || !supported_context?
 
+    verify_account! if different_actor?
+
     case @json['type']
     when 'Collection', 'CollectionPage'
       process_items @json['items']
@@ -23,6 +25,10 @@ class ActivityPub::ProcessCollectionService < BaseService
 
   private
 
+  def different_actor?
+    @json['actor'].present? && value_or_id(@json['actor']) != @account.uri && @json['signature'].present?
+  end
+
   def process_items(items)
     items.reverse_each.map { |item| process_item(item) }.compact
   end
@@ -35,4 +41,9 @@ class ActivityPub::ProcessCollectionService < BaseService
     activity = ActivityPub::Activity.factory(item, @account)
     activity&.perform
   end
+
+  def verify_account!
+    account  = ActivityPub::LinkedDataSignature.new(@json).verify_account!
+    @account = account unless account.nil?
+  end
 end
diff --git a/app/services/authorize_follow_service.rb b/app/services/authorize_follow_service.rb
index 6f036dc5a..b1bff8962 100644
--- a/app/services/authorize_follow_service.rb
+++ b/app/services/authorize_follow_service.rb
@@ -24,11 +24,11 @@ class AuthorizeFollowService < BaseService
   end
 
   def build_json(follow_request)
-    ActiveModelSerializers::SerializableResource.new(
+    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
       follow_request,
       serializer: ActivityPub::AcceptFollowSerializer,
       adapter: ActivityPub::Adapter
-    ).to_json
+    ).as_json).sign!(follow_request.target_account))
   end
 
   def build_xml(follow_request)
diff --git a/app/services/batched_remove_status_service.rb b/app/services/batched_remove_status_service.rb
index e6c8c9208..c90f4401d 100644
--- a/app/services/batched_remove_status_service.rb
+++ b/app/services/batched_remove_status_service.rb
@@ -138,10 +138,14 @@ class BatchedRemoveStatusService < BaseService
   def build_json(status)
     return @activity_json[status.id] if @activity_json.key?(status.id)
 
-    @activity_json[status.id] = ActiveModelSerializers::SerializableResource.new(
+    @activity_json[status.id] = sign_json(status, ActiveModelSerializers::SerializableResource.new(
       status,
       serializer: ActivityPub::DeleteSerializer,
       adapter: ActivityPub::Adapter
-    ).to_json
+    ).as_json)
+  end
+
+  def sign_json(status, json)
+    Oj.dump(ActivityPub::LinkedDataSignature.new(json).sign!(status.account))
   end
 end
diff --git a/app/services/block_service.rb b/app/services/block_service.rb
index f2253226b..b39c3eef2 100644
--- a/app/services/block_service.rb
+++ b/app/services/block_service.rb
@@ -27,11 +27,11 @@ class BlockService < BaseService
   end
 
   def build_json(block)
-    ActiveModelSerializers::SerializableResource.new(
+    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
       block,
       serializer: ActivityPub::BlockSerializer,
       adapter: ActivityPub::Adapter
-    ).to_json
+    ).as_json).sign!(block.account))
   end
 
   def build_xml(block)
diff --git a/app/services/favourite_service.rb b/app/services/favourite_service.rb
index 4aa935170..44df3ed13 100644
--- a/app/services/favourite_service.rb
+++ b/app/services/favourite_service.rb
@@ -34,11 +34,11 @@ class FavouriteService < BaseService
   end
 
   def build_json(favourite)
-    ActiveModelSerializers::SerializableResource.new(
+    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
       favourite,
       serializer: ActivityPub::LikeSerializer,
       adapter: ActivityPub::Adapter
-    ).to_json
+    ).as_json).sign!(favourite.account))
   end
 
   def build_xml(favourite)
diff --git a/app/services/follow_service.rb b/app/services/follow_service.rb
index 2be625cd8..a92eb6b88 100644
--- a/app/services/follow_service.rb
+++ b/app/services/follow_service.rb
@@ -67,10 +67,10 @@ class FollowService < BaseService
   end
 
   def build_json(follow_request)
-    ActiveModelSerializers::SerializableResource.new(
+    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
       follow_request,
       serializer: ActivityPub::FollowSerializer,
       adapter: ActivityPub::Adapter
-    ).to_json
+    ).as_json).sign!(follow_request.account))
   end
 end
diff --git a/app/services/process_mentions_service.rb b/app/services/process_mentions_service.rb
index 2b8a77147..f123bf869 100644
--- a/app/services/process_mentions_service.rb
+++ b/app/services/process_mentions_service.rb
@@ -47,11 +47,11 @@ class ProcessMentionsService < BaseService
   end
 
   def build_json(status)
-    ActiveModelSerializers::SerializableResource.new(
+    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
       status,
       serializer: ActivityPub::ActivitySerializer,
       adapter: ActivityPub::Adapter
-    ).to_json
+    ).as_json).sign!(status.account))
   end
 
   def follow_remote_account_service
diff --git a/app/services/reblog_service.rb b/app/services/reblog_service.rb
index 7f886af7c..5ed16c64b 100644
--- a/app/services/reblog_service.rb
+++ b/app/services/reblog_service.rb
@@ -42,10 +42,10 @@ class ReblogService < BaseService
   end
 
   def build_json(reblog)
-    ActiveModelSerializers::SerializableResource.new(
+    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
       reblog,
       serializer: ActivityPub::ActivitySerializer,
       adapter: ActivityPub::Adapter
-    ).to_json
+    ).as_json).sign!(reblog.account))
   end
 end
diff --git a/app/services/reject_follow_service.rb b/app/services/reject_follow_service.rb
index a91266aa4..c1f7bcb60 100644
--- a/app/services/reject_follow_service.rb
+++ b/app/services/reject_follow_service.rb
@@ -19,11 +19,11 @@ class RejectFollowService < BaseService
   end
 
   def build_json(follow_request)
-    ActiveModelSerializers::SerializableResource.new(
+    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
       follow_request,
       serializer: ActivityPub::RejectFollowSerializer,
       adapter: ActivityPub::Adapter
-    ).to_json
+    ).as_json).sign!(follow_request.target_account))
   end
 
   def build_xml(follow_request)
diff --git a/app/services/remove_status_service.rb b/app/services/remove_status_service.rb
index fcccbaa24..62eea677f 100644
--- a/app/services/remove_status_service.rb
+++ b/app/services/remove_status_service.rb
@@ -56,7 +56,7 @@ class RemoveStatusService < BaseService
 
     # ActivityPub
     ActivityPub::DeliveryWorker.push_bulk(target_accounts.select(&:activitypub?).uniq(&:inbox_url)) do |inbox_url|
-      [activity_json, @account.id, inbox_url]
+      [signed_activity_json, @account.id, inbox_url]
     end
   end
 
@@ -66,7 +66,7 @@ class RemoveStatusService < BaseService
 
     # ActivityPub
     ActivityPub::DeliveryWorker.push_bulk(@account.followers.inboxes) do |inbox_url|
-      [activity_json, @account.id, inbox_url]
+      [signed_activity_json, @account.id, inbox_url]
     end
   end
 
@@ -74,12 +74,16 @@ class RemoveStatusService < BaseService
     @salmon_xml ||= stream_entry_to_xml(@stream_entry)
   end
 
+  def signed_activity_json
+    @signed_activity_json ||= Oj.dump(ActivityPub::LinkedDataSignature.new(activity_json).sign!(@account))
+  end
+
   def activity_json
     @activity_json ||= ActiveModelSerializers::SerializableResource.new(
       @status,
       serializer: ActivityPub::DeleteSerializer,
       adapter: ActivityPub::Adapter
-    ).to_json
+    ).as_json
   end
 
   def remove_reblogs
diff --git a/app/services/unblock_service.rb b/app/services/unblock_service.rb
index 72fc5ab15..869f62d1c 100644
--- a/app/services/unblock_service.rb
+++ b/app/services/unblock_service.rb
@@ -20,11 +20,11 @@ class UnblockService < BaseService
   end
 
   def build_json(unblock)
-    ActiveModelSerializers::SerializableResource.new(
+    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
       unblock,
       serializer: ActivityPub::UndoBlockSerializer,
       adapter: ActivityPub::Adapter
-    ).to_json
+    ).as_json).sign!(unblock.account))
   end
 
   def build_xml(block)
diff --git a/app/services/unfavourite_service.rb b/app/services/unfavourite_service.rb
index e53798e66..2fda11bd6 100644
--- a/app/services/unfavourite_service.rb
+++ b/app/services/unfavourite_service.rb
@@ -21,11 +21,11 @@ class UnfavouriteService < BaseService
   end
 
   def build_json(favourite)
-    ActiveModelSerializers::SerializableResource.new(
+    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
       favourite,
       serializer: ActivityPub::UndoLikeSerializer,
       adapter: ActivityPub::Adapter
-    ).to_json
+    ).as_json).sign!(favourite.account))
   end
 
   def build_xml(favourite)
diff --git a/app/services/unfollow_service.rb b/app/services/unfollow_service.rb
index 10af75146..bf151ee28 100644
--- a/app/services/unfollow_service.rb
+++ b/app/services/unfollow_service.rb
@@ -23,11 +23,11 @@ class UnfollowService < BaseService
   end
 
   def build_json(follow)
-    ActiveModelSerializers::SerializableResource.new(
+    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
       follow,
       serializer: ActivityPub::UndoFollowSerializer,
       adapter: ActivityPub::Adapter
-    ).to_json
+    ).as_json).sign!(follow.account))
   end
 
   def build_xml(follow)