@@ -11,6 +11,8 @@ class ActivityPub::Activity::Accept < ActivityPub::Activity | |||||
private | private | ||||
def accept_follow | def accept_follow | ||||
return accept_follow_for_relay if relay_follow? | |||||
target_account = account_from_uri(target_uri) | target_account = account_from_uri(target_uri) | ||||
return if target_account.nil? || !target_account.local? | return if target_account.nil? || !target_account.local? | ||||
@@ -19,6 +21,18 @@ class ActivityPub::Activity::Accept < ActivityPub::Activity | |||||
follow_request&.authorize! | follow_request&.authorize! | ||||
end | end | ||||
def accept_follow_for_relay | |||||
relay.update!(state: :accepted) | |||||
end | |||||
def relay | |||||
@relay ||= Relay.find_by(follow_activity_id: object_uri) | |||||
end | |||||
def relay_follow? | |||||
relay.present? | |||||
end | |||||
def target_uri | def target_uri | ||||
@target_uri ||= value_or_id(@object['actor']) | @target_uri ||= value_or_id(@object['actor']) | ||||
end | end | ||||
@@ -11,6 +11,8 @@ class ActivityPub::Activity::Reject < ActivityPub::Activity | |||||
private | private | ||||
def reject_follow | def reject_follow | ||||
return reject_follow_for_relay if relay_follow? | |||||
target_account = account_from_uri(target_uri) | target_account = account_from_uri(target_uri) | ||||
return if target_account.nil? || !target_account.local? | return if target_account.nil? || !target_account.local? | ||||
@@ -21,6 +23,18 @@ class ActivityPub::Activity::Reject < ActivityPub::Activity | |||||
UnfollowService.new.call(target_account, @account) if target_account.following?(@account) | UnfollowService.new.call(target_account, @account) if target_account.following?(@account) | ||||
end | end | ||||
def reject_follow_for_relay | |||||
relay.update!(state: :rejected) | |||||
end | |||||
def relay | |||||
@relay ||= Relay.find_by(follow_activity_id: object_uri) | |||||
end | |||||
def relay_follow? | |||||
relay.present? | |||||
end | |||||
def target_uri | def target_uri | ||||
@target_uri ||= value_or_id(@object['actor']) | @target_uri ||= value_or_id(@object['actor']) | ||||
end | end | ||||
@@ -5,10 +5,10 @@ | |||||
# | # | ||||
# id :bigint(8) not null, primary key | # id :bigint(8) not null, primary key | ||||
# inbox_url :string default(""), not null | # inbox_url :string default(""), not null | ||||
# enabled :boolean default(FALSE), not null | |||||
# follow_activity_id :string | # follow_activity_id :string | ||||
# created_at :datetime not null | # created_at :datetime not null | ||||
# updated_at :datetime not null | # updated_at :datetime not null | ||||
# state :integer default("idle"), not null | |||||
# | # | ||||
class Relay < ApplicationRecord | class Relay < ApplicationRecord | ||||
@@ -16,24 +16,28 @@ class Relay < ApplicationRecord | |||||
validates :inbox_url, presence: true, uniqueness: true, url: true, if: :will_save_change_to_inbox_url? | validates :inbox_url, presence: true, uniqueness: true, url: true, if: :will_save_change_to_inbox_url? | ||||
scope :enabled, -> { where(enabled: true) } | |||||
enum state: [:idle, :pending, :accepted, :rejected] | |||||
scope :enabled, -> { accepted } | |||||
before_destroy :ensure_disabled | before_destroy :ensure_disabled | ||||
alias enabled? accepted? | |||||
def enable! | def enable! | ||||
activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil) | activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil) | ||||
payload = Oj.dump(follow_activity(activity_id)) | payload = Oj.dump(follow_activity(activity_id)) | ||||
update!(state: :pending, follow_activity_id: activity_id) | |||||
ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url) | ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url) | ||||
update(enabled: true, follow_activity_id: activity_id) | |||||
end | end | ||||
def disable! | def disable! | ||||
activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil) | activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil) | ||||
payload = Oj.dump(unfollow_activity(activity_id)) | payload = Oj.dump(unfollow_activity(activity_id)) | ||||
update!(state: :idle, follow_activity_id: nil) | |||||
ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url) | ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url) | ||||
update(enabled: false, follow_activity_id: nil) | |||||
end | end | ||||
private | private | ||||
@@ -0,0 +1,19 @@ | |||||
class ChangeRelaysEnabled < ActiveRecord::Migration[5.2] | |||||
def up | |||||
# The relays table is supposed to be very small, | |||||
# single-digit number of rows, so this should be fine | |||||
safety_assured do | |||||
add_column :relays, :state, :integer, default: 0, null: false | |||||
# At the time of this migration, no relays reject anyone, so if | |||||
# there are enabled ones, they are accepted | |||||
execute 'UPDATE relays SET state = 2 WHERE enabled = true' | |||||
remove_column :relays, :enabled | |||||
end | |||||
end | |||||
def down | |||||
remove_column :relays, :state | |||||
add_column :relays, :enabled, :boolean, default: false, null: false | |||||
end | |||||
end |
@@ -10,7 +10,7 @@ | |||||
# | # | ||||
# It's strongly recommended that you check this file into your version control system. | # It's strongly recommended that you check this file into your version control system. | ||||
ActiveRecord::Schema.define(version: 2018_08_08_175627) do | |||||
ActiveRecord::Schema.define(version: 2018_08_12_123222) do | |||||
# These are extensions that must be enabled in order to support this database | # These are extensions that must be enabled in order to support this database | ||||
enable_extension "plpgsql" | enable_extension "plpgsql" | ||||
@@ -383,11 +383,10 @@ ActiveRecord::Schema.define(version: 2018_08_08_175627) do | |||||
create_table "relays", force: :cascade do |t| | create_table "relays", force: :cascade do |t| | ||||
t.string "inbox_url", default: "", null: false | t.string "inbox_url", default: "", null: false | ||||
t.boolean "enabled", default: false, null: false | |||||
t.string "follow_activity_id" | t.string "follow_activity_id" | ||||
t.datetime "created_at", null: false | t.datetime "created_at", null: false | ||||
t.datetime "updated_at", null: false | t.datetime "updated_at", null: false | ||||
t.index ["enabled"], name: "index_relays_on_enabled" | |||||
t.integer "state", default: 0, null: false | |||||
end | end | ||||
create_table "report_notes", force: :cascade do |t| | create_table "report_notes", force: :cascade do |t| | ||||