Browse Source

Store URIs of follows, follow requests and blocks for ActivityPub (#7160)

Same URI passed between follow request and follow, since they are
the same thing in ActivityPub. Local URIs are generated during
creation using UUIDs and are passed to serializers.
master
Eugen Rochko 6 years ago
committed by GitHub
parent
commit
6793bec4c6
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 64 additions and 13 deletions
  1. +1
    -1
      app/lib/activitypub/activity/block.rb
  2. +1
    -1
      app/lib/activitypub/activity/follow.rb
  3. +4
    -0
      app/lib/activitypub/tag_manager.rb
  4. +10
    -0
      app/models/block.rb
  5. +8
    -5
      app/models/concerns/account_interactions.rb
  6. +13
    -0
      app/models/follow.rb
  7. +14
    -2
      app/models/follow_request.rb
  8. +1
    -1
      app/serializers/activitypub/follow_serializer.rb
  9. +7
    -0
      db/migrate/20180416210259_add_uri_to_relationships.rb
  10. +4
    -2
      db/schema.rb
  11. +1
    -1
      spec/models/follow_request_spec.rb

+ 1
- 1
app/lib/activitypub/activity/block.rb View File

@ -7,6 +7,6 @@ class ActivityPub::Activity::Block < ActivityPub::Activity
return if target_account.nil? || !target_account.local? || delete_arrived_first?(@json['id']) || @account.blocking?(target_account)
UnfollowService.new.call(target_account, @account) if target_account.following?(@account)
@account.block!(target_account)
@account.block!(target_account, uri: @json['id'])
end
end

+ 1
- 1
app/lib/activitypub/activity/follow.rb View File

@ -12,7 +12,7 @@ class ActivityPub::Activity::Follow < ActivityPub::Activity
return
end
follow_request = FollowRequest.create!(account: @account, target_account: target_account)
follow_request = FollowRequest.create!(account: @account, target_account: target_account, uri: @json['id'])
if target_account.locked?
NotifyService.new.call(target_account, follow_request)

+ 4
- 0
app/lib/activitypub/tag_manager.rb View File

@ -38,6 +38,10 @@ class ActivityPub::TagManager
end
end
def generate_uri_for(_target)
URI.join(root_url, 'payloads', SecureRandom.uuid)
end
def activity_uri_for(target)
raise ArgumentError, 'target must be a local activity' unless %i(note comment activity).include?(target.object_type) && target.local?

+ 10
- 0
app/models/block.rb View File

@ -8,6 +8,7 @@
# updated_at :datetime not null
# account_id :bigint(8) not null
# target_account_id :bigint(8) not null
# uri :string
#
class Block < ApplicationRecord
@ -19,7 +20,12 @@ class Block < ApplicationRecord
validates :account_id, uniqueness: { scope: :target_account_id }
def local?
false # Force uri_for to use uri attribute
end
after_commit :remove_blocking_cache
before_validation :set_uri, only: :create
private
@ -27,4 +33,8 @@ class Block < ApplicationRecord
Rails.cache.delete("exclude_account_ids_for:#{account_id}")
Rails.cache.delete("exclude_account_ids_for:#{target_account_id}")
end
def set_uri
self.uri = ActivityPub::TagManager.instance.generate_uri_for(self) if uri.nil?
end
end

+ 8
- 5
app/models/concerns/account_interactions.rb View File

@ -82,16 +82,19 @@ module AccountInteractions
has_many :domain_blocks, class_name: 'AccountDomainBlock', dependent: :destroy
end
def follow!(other_account, reblogs: nil)
def follow!(other_account, reblogs: nil, uri: nil)
reblogs = true if reblogs.nil?
rel = active_relationships.create_with(show_reblogs: reblogs).find_or_create_by!(target_account: other_account)
rel.update!(show_reblogs: reblogs)
rel = active_relationships.create_with(show_reblogs: reblogs, uri: uri)
.find_or_create_by!(target_account: other_account)
rel.update!(show_reblogs: reblogs)
rel
end
def block!(other_account)
block_relationships.find_or_create_by!(target_account: other_account)
def block!(other_account, uri: nil)
block_relationships.create_with(uri: uri)
.find_or_create_by!(target_account: other_account)
end
def mute!(other_account, notifications: nil)

+ 13
- 0
app/models/follow.rb View File

@ -9,6 +9,7 @@
# account_id :bigint(8) not null
# target_account_id :bigint(8) not null
# show_reblogs :boolean default(TRUE), not null
# uri :string
#
class Follow < ApplicationRecord
@ -26,4 +27,16 @@ class Follow < ApplicationRecord
validates :account_id, uniqueness: { scope: :target_account_id }
scope :recent, -> { reorder(id: :desc) }
def local?
false # Force uri_for to use uri attribute
end
before_validation :set_uri, only: :create
private
def set_uri
self.uri = ActivityPub::TagManager.instance.generate_uri_for(self) if uri.nil?
end
end

+ 14
- 2
app/models/follow_request.rb View File

@ -9,6 +9,7 @@
# account_id :bigint(8) not null
# target_account_id :bigint(8) not null
# show_reblogs :boolean default(TRUE), not null
# uri :string
#
class FollowRequest < ApplicationRecord
@ -23,11 +24,22 @@ class FollowRequest < ApplicationRecord
validates :account_id, uniqueness: { scope: :target_account_id }
def authorize!
account.follow!(target_account, reblogs: show_reblogs)
account.follow!(target_account, reblogs: show_reblogs, uri: uri)
MergeWorker.perform_async(target_account.id, account.id)
destroy!
end
alias reject! destroy!
def local?
false # Force uri_for to use uri attribute
end
before_validation :set_uri, only: :create
private
def set_uri
self.uri = ActivityPub::TagManager.instance.generate_uri_for(self) if uri.nil?
end
end

+ 1
- 1
app/serializers/activitypub/follow_serializer.rb View File

@ -5,7 +5,7 @@ class ActivityPub::FollowSerializer < ActiveModel::Serializer
attribute :virtual_object, key: :object
def id
[ActivityPub::TagManager.instance.uri_for(object.account), '#follows/', object.id].join
ActivityPub::TagManager.instance.uri_for(object)
end
def type

+ 7
- 0
db/migrate/20180416210259_add_uri_to_relationships.rb View File

@ -0,0 +1,7 @@
class AddUriToRelationships < ActiveRecord::Migration[5.2]
def change
add_column :follows, :uri, :string
add_column :follow_requests, :uri, :string
add_column :blocks, :uri, :string
end
end

+ 4
- 2
db/schema.rb View File

@ -10,10 +10,9 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2018_04_10_204633) do
ActiveRecord::Schema.define(version: 2018_04_16_210259) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_stat_statements"
enable_extension "plpgsql"
create_table "account_domain_blocks", force: :cascade do |t|
@ -112,6 +111,7 @@ ActiveRecord::Schema.define(version: 2018_04_10_204633) do
t.datetime "updated_at", null: false
t.bigint "account_id", null: false
t.bigint "target_account_id", null: false
t.string "uri"
t.index ["account_id", "target_account_id"], name: "index_blocks_on_account_id_and_target_account_id", unique: true
end
@ -176,6 +176,7 @@ ActiveRecord::Schema.define(version: 2018_04_10_204633) do
t.bigint "account_id", null: false
t.bigint "target_account_id", null: false
t.boolean "show_reblogs", default: true, null: false
t.string "uri"
t.index ["account_id", "target_account_id"], name: "index_follow_requests_on_account_id_and_target_account_id", unique: true
end
@ -185,6 +186,7 @@ ActiveRecord::Schema.define(version: 2018_04_10_204633) do
t.bigint "account_id", null: false
t.bigint "target_account_id", null: false
t.boolean "show_reblogs", default: true, null: false
t.string "uri"
t.index ["account_id", "target_account_id"], name: "index_follows_on_account_id_and_target_account_id", unique: true
end

+ 1
- 1
spec/models/follow_request_spec.rb View File

@ -7,7 +7,7 @@ RSpec.describe FollowRequest, type: :model do
let(:target_account) { Fabricate(:account) }
it 'calls Account#follow!, MergeWorker.perform_async, and #destroy!' do
expect(account).to receive(:follow!).with(target_account, reblogs: true)
expect(account).to receive(:follow!).with(target_account, reblogs: true, uri: follow_request.uri)
expect(MergeWorker).to receive(:perform_async).with(target_account.id, account.id)
expect(follow_request).to receive(:destroy!)
follow_request.authorize!

Loading…
Cancel
Save