Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-10-26 06:11:53 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-10-26 06:11:53 +0300
commit40512a72dfb1e73836effc10c201eae9f6c10e28 (patch)
treedee9077bc44729820327bed27dee1be655439bb7 /app
parent9a02cb29182ae369f98a8b04840144c67b544a7a (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/services/activity_pub/accept_follow_service.rb55
-rw-r--r--app/services/activity_pub/inbox_resolver_service.rb50
-rw-r--r--app/services/activity_pub/third_party_error.rb5
-rw-r--r--app/workers/activity_pub/projects/releases_subscription_worker.rb39
-rw-r--r--app/workers/all_queues.yml9
5 files changed, 158 insertions, 0 deletions
diff --git a/app/services/activity_pub/accept_follow_service.rb b/app/services/activity_pub/accept_follow_service.rb
new file mode 100644
index 00000000000..0ec440fa972
--- /dev/null
+++ b/app/services/activity_pub/accept_follow_service.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+module ActivityPub
+ class AcceptFollowService
+ MissingInboxURLError = Class.new(StandardError)
+
+ attr_reader :subscription, :actor
+
+ def initialize(subscription, actor)
+ @subscription = subscription
+ @actor = actor
+ end
+
+ def execute
+ return if subscription.accepted?
+ raise MissingInboxURLError unless subscription.subscriber_inbox_url.present?
+
+ upload_accept_activity
+ subscription.accepted!
+ end
+
+ private
+
+ def upload_accept_activity
+ body = Gitlab::Json::LimitedEncoder.encode(payload, limit: 1.megabyte)
+
+ begin
+ Gitlab::HTTP.post(subscription.subscriber_inbox_url, body: body, headers: headers)
+ rescue StandardError => e
+ raise ThirdPartyError, e.message
+ end
+ end
+
+ def payload
+ follow = subscription.payload.dup
+ follow.delete('@context')
+
+ {
+ '@context': 'https://www.w3.org/ns/activitystreams',
+ id: "#{actor}#follow/#{subscription.id}/accept",
+ type: 'Accept',
+ actor: actor,
+ object: follow
+ }
+ end
+
+ def headers
+ {
+ 'User-Agent' => "GitLab/#{Gitlab::VERSION}",
+ 'Content-Type' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
+ 'Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'
+ }
+ end
+ end
+end
diff --git a/app/services/activity_pub/inbox_resolver_service.rb b/app/services/activity_pub/inbox_resolver_service.rb
new file mode 100644
index 00000000000..c2bd2112b16
--- /dev/null
+++ b/app/services/activity_pub/inbox_resolver_service.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+module ActivityPub
+ class InboxResolverService
+ attr_reader :subscription
+
+ def initialize(subscription)
+ @subscription = subscription
+ end
+
+ def execute
+ profile = subscriber_profile
+ unless profile.has_key?('inbox') && profile['inbox'].is_a?(String)
+ raise ThirdPartyError, 'Inbox parameter absent or invalid'
+ end
+
+ subscription.subscriber_inbox_url = profile['inbox']
+ subscription.shared_inbox_url = profile.dig('entrypoints', 'sharedInbox')
+ subscription.save!
+ end
+
+ private
+
+ def subscriber_profile
+ raw_data = download_subscriber_profile
+
+ begin
+ profile = Gitlab::Json.parse(raw_data)
+ rescue JSON::ParserError => e
+ raise ThirdPartyError, e.message
+ end
+
+ profile
+ end
+
+ def download_subscriber_profile
+ begin
+ response = Gitlab::HTTP.get(subscription.subscriber_url,
+ headers: {
+ 'Accept' => 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'
+ }
+ )
+ rescue StandardError => e
+ raise ThirdPartyError, e.message
+ end
+
+ response.body
+ end
+ end
+end
diff --git a/app/services/activity_pub/third_party_error.rb b/app/services/activity_pub/third_party_error.rb
new file mode 100644
index 00000000000..473a67984a4
--- /dev/null
+++ b/app/services/activity_pub/third_party_error.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+module ActivityPub
+ ThirdPartyError = Class.new(StandardError)
+end
diff --git a/app/workers/activity_pub/projects/releases_subscription_worker.rb b/app/workers/activity_pub/projects/releases_subscription_worker.rb
new file mode 100644
index 00000000000..c392726a469
--- /dev/null
+++ b/app/workers/activity_pub/projects/releases_subscription_worker.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module ActivityPub
+ module Projects
+ class ReleasesSubscriptionWorker
+ include ApplicationWorker
+ include Gitlab::Routing.url_helpers
+
+ idempotent!
+ worker_has_external_dependencies!
+ feature_category :release_orchestration
+ data_consistency :delayed
+ queue_namespace :activity_pub
+
+ sidekiq_retries_exhausted do |msg, _ex|
+ subscription_id = msg['args'].second
+ subscription = ActivityPub::ReleasesSubscription.find_by_id(subscription_id)
+ subscription&.destroy
+ end
+
+ def perform(subscription_id)
+ subscription = ActivityPub::ReleasesSubscription.find_by_id(subscription_id)
+ return if subscription.nil?
+
+ unless subscription.project.public?
+ subscription.destroy
+ return
+ end
+
+ InboxResolverService.new(subscription).execute if needs_resolving?(subscription)
+ AcceptFollowService.new(subscription, project_releases_url(subscription.project)).execute
+ end
+
+ def needs_resolving?(subscription)
+ subscription.subscriber_inbox_url.blank? || subscription.shared_inbox_url.blank?
+ end
+ end
+ end
+end
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index c758708c58f..96514f64c26 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -3,6 +3,15 @@
#
# Do not edit it manually!
---
+- :name: activity_pub:activity_pub_projects_releases_subscription
+ :worker_name: ActivityPub::Projects::ReleasesSubscriptionWorker
+ :feature_category: :release_orchestration
+ :has_external_dependencies: true
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 1
+ :idempotent: true
+ :tags: []
- :name: authorized_project_update:authorized_project_update_project_recalculate
:worker_name: AuthorizedProjectUpdate::ProjectRecalculateWorker
:feature_category: :system_access