mirror of
https://github.com/glitch-soc/mastodon
synced 2025-04-25 00:44:51 +00:00
142 lines
4 KiB
Ruby
142 lines
4 KiB
Ruby
|
# frozen_string_literal: true
|
||
|
|
||
|
# == Schema Information
|
||
|
#
|
||
|
# Table name: fasp_providers
|
||
|
#
|
||
|
# id :bigint(8) not null, primary key
|
||
|
# base_url :string not null
|
||
|
# capabilities :jsonb not null
|
||
|
# confirmed :boolean default(FALSE), not null
|
||
|
# contact_email :string
|
||
|
# fediverse_account :string
|
||
|
# name :string not null
|
||
|
# privacy_policy :jsonb
|
||
|
# provider_public_key_pem :string not null
|
||
|
# remote_identifier :string not null
|
||
|
# server_private_key_pem :string not null
|
||
|
# sign_in_url :string
|
||
|
# created_at :datetime not null
|
||
|
# updated_at :datetime not null
|
||
|
#
|
||
|
class Fasp::Provider < ApplicationRecord
|
||
|
include DebugConcern
|
||
|
|
||
|
has_many :fasp_debug_callbacks, inverse_of: :fasp_provider, class_name: 'Fasp::DebugCallback', dependent: :delete_all
|
||
|
|
||
|
validates :name, presence: true
|
||
|
validates :base_url, presence: true, url: true
|
||
|
validates :provider_public_key_pem, presence: true
|
||
|
validates :remote_identifier, presence: true
|
||
|
|
||
|
before_create :create_keypair
|
||
|
after_commit :update_remote_capabilities
|
||
|
|
||
|
def capabilities
|
||
|
read_attribute(:capabilities).map do |attributes|
|
||
|
Fasp::Capability.new(attributes)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def capabilities_attributes=(attributes)
|
||
|
capability_objects = attributes.values.map { |a| Fasp::Capability.new(a) }
|
||
|
self[:capabilities] = capability_objects.map(&:attributes)
|
||
|
end
|
||
|
|
||
|
def enabled_capabilities
|
||
|
capabilities.select(&:enabled).map(&:id)
|
||
|
end
|
||
|
|
||
|
def capability?(capability_name)
|
||
|
return false unless confirmed?
|
||
|
|
||
|
capabilities.present? && capabilities.any? do |capability|
|
||
|
capability.id == capability_name
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def capability_enabled?(capability_name)
|
||
|
return false unless confirmed?
|
||
|
|
||
|
capabilities.present? && capabilities.any? do |capability|
|
||
|
capability.id == capability_name && capability.enabled
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def server_private_key
|
||
|
@server_private_key ||= OpenSSL::PKey.read(server_private_key_pem)
|
||
|
end
|
||
|
|
||
|
def server_public_key_base64
|
||
|
Base64.strict_encode64(server_private_key.raw_public_key)
|
||
|
end
|
||
|
|
||
|
def provider_public_key_base64=(string)
|
||
|
return if string.blank?
|
||
|
|
||
|
self.provider_public_key_pem =
|
||
|
OpenSSL::PKey.new_raw_public_key(
|
||
|
'ed25519',
|
||
|
Base64.strict_decode64(string)
|
||
|
).public_to_pem
|
||
|
end
|
||
|
|
||
|
def provider_public_key
|
||
|
@provider_public_key ||= OpenSSL::PKey.read(provider_public_key_pem)
|
||
|
end
|
||
|
|
||
|
def provider_public_key_raw
|
||
|
provider_public_key.raw_public_key
|
||
|
end
|
||
|
|
||
|
def provider_public_key_fingerprint
|
||
|
OpenSSL::Digest.base64digest('sha256', provider_public_key_raw)
|
||
|
end
|
||
|
|
||
|
def url(path)
|
||
|
base = base_url
|
||
|
base = base.chomp('/') if path.start_with?('/')
|
||
|
"#{base}#{path}"
|
||
|
end
|
||
|
|
||
|
def update_info!(confirm: false)
|
||
|
self.confirmed = true if confirm
|
||
|
provider_info = Fasp::Request.new(self).get('/provider_info')
|
||
|
assign_attributes(
|
||
|
privacy_policy: provider_info['privacyPolicy'],
|
||
|
capabilities: provider_info['capabilities'],
|
||
|
sign_in_url: provider_info['signInUrl'],
|
||
|
contact_email: provider_info['contactEmail'],
|
||
|
fediverse_account: provider_info['fediverseAccount']
|
||
|
)
|
||
|
save!
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
def create_keypair
|
||
|
self.server_private_key_pem ||=
|
||
|
OpenSSL::PKey.generate_key('ed25519').private_to_pem
|
||
|
end
|
||
|
|
||
|
def update_remote_capabilities
|
||
|
return unless saved_change_to_attribute?(:capabilities)
|
||
|
|
||
|
old, current = saved_change_to_attribute(:capabilities)
|
||
|
old ||= []
|
||
|
current.each do |capability|
|
||
|
update_remote_capability(capability) if capability.key?('enabled') && !old.include?(capability)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def update_remote_capability(capability)
|
||
|
version, = capability['version'].split('.')
|
||
|
path = "/capabilities/#{capability['id']}/#{version}/activation"
|
||
|
if capability['enabled']
|
||
|
Fasp::Request.new(self).post(path)
|
||
|
else
|
||
|
Fasp::Request.new(self).delete(path)
|
||
|
end
|
||
|
end
|
||
|
end
|