about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2018-08-12 18:16:26 +0200
committerGitHub <noreply@github.com>2018-08-12 18:16:26 +0200
commit39e361a56d849a027ed12df69122a369bc6ff39d (patch)
treecf178ca2ebfda1c101bba438b42e472926647067
parent2aeeffc3ec421111f751cab61a15642cbddd9f0d (diff)
Expect relays to answer with accept/reject (#8179)
-rw-r--r--app/lib/activitypub/activity/accept.rb14
-rw-r--r--app/lib/activitypub/activity/reject.rb14
-rw-r--r--app/models/relay.rb12
-rw-r--r--db/migrate/20180812123222_change_relays_enabled.rb19
-rw-r--r--db/schema.rb5
5 files changed, 57 insertions, 7 deletions
diff --git a/app/lib/activitypub/activity/accept.rb b/app/lib/activitypub/activity/accept.rb
index bd90c9019..7e60b2c00 100644
--- a/app/lib/activitypub/activity/accept.rb
+++ b/app/lib/activitypub/activity/accept.rb
@@ -11,6 +11,8 @@ class ActivityPub::Activity::Accept < ActivityPub::Activity
   private
 
   def accept_follow
+    return accept_follow_for_relay if relay_follow?
+
     target_account = account_from_uri(target_uri)
 
     return if target_account.nil? || !target_account.local?
@@ -19,6 +21,18 @@ class ActivityPub::Activity::Accept < ActivityPub::Activity
     follow_request&.authorize!
   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
     @target_uri ||= value_or_id(@object['actor'])
   end
diff --git a/app/lib/activitypub/activity/reject.rb b/app/lib/activitypub/activity/reject.rb
index 28d472883..d81b157de 100644
--- a/app/lib/activitypub/activity/reject.rb
+++ b/app/lib/activitypub/activity/reject.rb
@@ -11,6 +11,8 @@ class ActivityPub::Activity::Reject < ActivityPub::Activity
   private
 
   def reject_follow
+    return reject_follow_for_relay if relay_follow?
+
     target_account = account_from_uri(target_uri)
 
     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)
   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
     @target_uri ||= value_or_id(@object['actor'])
   end
diff --git a/app/models/relay.rb b/app/models/relay.rb
index 76143bb27..75cb060b2 100644
--- a/app/models/relay.rb
+++ b/app/models/relay.rb
@@ -5,10 +5,10 @@
 #
 #  id                 :bigint(8)        not null, primary key
 #  inbox_url          :string           default(""), not null
-#  enabled            :boolean          default(FALSE), not null
 #  follow_activity_id :string
 #  created_at         :datetime         not null
 #  updated_at         :datetime         not null
+#  state              :integer          default("idle"), not null
 #
 
 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?
 
-  scope :enabled, -> { where(enabled: true) }
+  enum state: [:idle, :pending, :accepted, :rejected]
+
+  scope :enabled, -> { accepted }
 
   before_destroy :ensure_disabled
 
+  alias enabled? accepted?
+
   def enable!
     activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil)
     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)
-    update(enabled: true, follow_activity_id: activity_id)
   end
 
   def disable!
     activity_id = ActivityPub::TagManager.instance.generate_uri_for(nil)
     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)
-    update(enabled: false, follow_activity_id: nil)
   end
 
   private
diff --git a/db/migrate/20180812123222_change_relays_enabled.rb b/db/migrate/20180812123222_change_relays_enabled.rb
new file mode 100644
index 000000000..c4fd8179b
--- /dev/null
+++ b/db/migrate/20180812123222_change_relays_enabled.rb
@@ -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
diff --git a/db/schema.rb b/db/schema.rb
index 46ee42714..edb5a023c 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
 #
 # 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
   enable_extension "plpgsql"
@@ -383,11 +383,10 @@ ActiveRecord::Schema.define(version: 2018_08_08_175627) do
 
   create_table "relays", force: :cascade do |t|
     t.string "inbox_url", default: "", null: false
-    t.boolean "enabled", default: false, null: false
     t.string "follow_activity_id"
     t.datetime "created_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
 
   create_table "report_notes", force: :cascade do |t|