diff options
Diffstat (limited to 'app/lib')
-rw-r--r-- | app/lib/activitypub/adapter.rb | 1 | ||||
-rw-r--r-- | app/lib/proof_provider.rb | 12 | ||||
-rw-r--r-- | app/lib/proof_provider/keybase.rb | 69 | ||||
-rw-r--r-- | app/lib/proof_provider/keybase/badge.rb | 45 | ||||
-rw-r--r-- | app/lib/proof_provider/keybase/config_serializer.rb | 76 | ||||
-rw-r--r-- | app/lib/proof_provider/keybase/serializer.rb | 25 | ||||
-rw-r--r-- | app/lib/proof_provider/keybase/verifier.rb | 59 | ||||
-rw-r--r-- | app/lib/proof_provider/keybase/worker.rb | 32 |
8 files changed, 0 insertions, 319 deletions
diff --git a/app/lib/activitypub/adapter.rb b/app/lib/activitypub/adapter.rb index 2d6b87659..776e1d3da 100644 --- a/app/lib/activitypub/adapter.rb +++ b/app/lib/activitypub/adapter.rb @@ -18,7 +18,6 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base atom_uri: { 'ostatus' => 'http://ostatus.org#', 'atomUri' => 'ostatus:atomUri' }, conversation: { 'ostatus' => 'http://ostatus.org#', 'inReplyToAtomUri' => 'ostatus:inReplyToAtomUri', 'conversation' => 'ostatus:conversation' }, focal_point: { 'toot' => 'http://joinmastodon.org/ns#', 'focalPoint' => { '@container' => '@list', '@id' => 'toot:focalPoint' } }, - identity_proof: { 'toot' => 'http://joinmastodon.org/ns#', 'IdentityProof' => 'toot:IdentityProof' }, blurhash: { 'toot' => 'http://joinmastodon.org/ns#', 'blurhash' => 'toot:blurhash' }, discoverable: { 'toot' => 'http://joinmastodon.org/ns#', 'discoverable' => 'toot:discoverable' }, voters_count: { 'toot' => 'http://joinmastodon.org/ns#', 'votersCount' => 'toot:votersCount' }, diff --git a/app/lib/proof_provider.rb b/app/lib/proof_provider.rb deleted file mode 100644 index 102c50f4f..000000000 --- a/app/lib/proof_provider.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -module ProofProvider - SUPPORTED_PROVIDERS = %w(keybase).freeze - - def self.find(identifier, proof = nil) - case identifier - when 'keybase' - ProofProvider::Keybase.new(proof) - end - end -end diff --git a/app/lib/proof_provider/keybase.rb b/app/lib/proof_provider/keybase.rb deleted file mode 100644 index 8e51d7146..000000000 --- a/app/lib/proof_provider/keybase.rb +++ /dev/null @@ -1,69 +0,0 @@ -# frozen_string_literal: true - -class ProofProvider::Keybase - BASE_URL = ENV.fetch('KEYBASE_BASE_URL', 'https://keybase.io') - DOMAIN = ENV.fetch('KEYBASE_DOMAIN', Rails.configuration.x.web_domain) - - class Error < StandardError; end - - class ExpectedProofLiveError < Error; end - - class UnexpectedResponseError < Error; end - - def initialize(proof = nil) - @proof = proof - end - - def serializer_class - ProofProvider::Keybase::Serializer - end - - def worker_class - ProofProvider::Keybase::Worker - end - - def validate! - unless @proof.token&.size == 66 - @proof.errors.add(:base, I18n.t('identity_proofs.errors.keybase.invalid_token')) - return - end - - # Do not perform synchronous validation for remote accounts - return if @proof.provider_username.blank? || !@proof.account.local? - - if verifier.valid? - @proof.verified = true - @proof.live = false - else - @proof.errors.add(:base, I18n.t('identity_proofs.errors.keybase.verification_failed', kb_username: @proof.provider_username)) - end - end - - def refresh! - worker_class.new.perform(@proof) - rescue ProofProvider::Keybase::Error - nil - end - - def on_success_path(user_agent = nil) - verifier.on_success_path(user_agent) - end - - def badge - @badge ||= ProofProvider::Keybase::Badge.new(@proof.account.username, @proof.provider_username, @proof.token, domain) - end - - def verifier - @verifier ||= ProofProvider::Keybase::Verifier.new(@proof.account.username, @proof.provider_username, @proof.token, domain) - end - - private - - def domain - if @proof.account.local? - DOMAIN - else - @proof.account.domain - end - end -end diff --git a/app/lib/proof_provider/keybase/badge.rb b/app/lib/proof_provider/keybase/badge.rb deleted file mode 100644 index f587b1cc7..000000000 --- a/app/lib/proof_provider/keybase/badge.rb +++ /dev/null @@ -1,45 +0,0 @@ -# frozen_string_literal: true - -class ProofProvider::Keybase::Badge - include RoutingHelper - - def initialize(local_username, provider_username, token, domain) - @local_username = local_username - @provider_username = provider_username - @token = token - @domain = domain - end - - def proof_url - "#{ProofProvider::Keybase::BASE_URL}/#{@provider_username}/sigchain\##{@token}" - end - - def profile_url - "#{ProofProvider::Keybase::BASE_URL}/#{@provider_username}" - end - - def icon_url - "#{ProofProvider::Keybase::BASE_URL}/#{@provider_username}/proof_badge/#{@token}?username=#{@local_username}&domain=#{@domain}" - end - - def avatar_url - Rails.cache.fetch("proof_providers/keybase/#{@provider_username}/avatar_url", expires_in: 5.minutes) { remote_avatar_url } || default_avatar_url - end - - private - - def remote_avatar_url - request = Request.new(:get, "#{ProofProvider::Keybase::BASE_URL}/_/api/1.0/user/pic_url.json", params: { username: @provider_username }) - - request.perform do |res| - json = Oj.load(res.body_with_limit, mode: :strict) - json['pic_url'] if json.is_a?(Hash) - end - rescue Oj::ParseError, HTTP::Error, OpenSSL::SSL::SSLError - nil - end - - def default_avatar_url - asset_pack_path('media/images/proof_providers/keybase.png') - end -end diff --git a/app/lib/proof_provider/keybase/config_serializer.rb b/app/lib/proof_provider/keybase/config_serializer.rb deleted file mode 100644 index c6c364d31..000000000 --- a/app/lib/proof_provider/keybase/config_serializer.rb +++ /dev/null @@ -1,76 +0,0 @@ -# frozen_string_literal: true - -class ProofProvider::Keybase::ConfigSerializer < ActiveModel::Serializer - include RoutingHelper - include ActionView::Helpers::TextHelper - - attributes :version, :domain, :display_name, :username, - :brand_color, :logo, :description, :prefill_url, - :profile_url, :check_url, :check_path, :avatar_path, - :contact - - def version - 1 - end - - def domain - ProofProvider::Keybase::DOMAIN - end - - def display_name - Setting.site_title - end - - def logo - { - svg_black: full_asset_url(asset_pack_path('media/images/logo_transparent_black.svg')), - svg_white: full_asset_url(asset_pack_path('media/images/logo_transparent_white.svg')), - svg_full: full_asset_url(asset_pack_path('media/images/logo.svg')), - svg_full_darkmode: full_asset_url(asset_pack_path('media/images/logo.svg')), - } - end - - def brand_color - '#282c37' - end - - def description - strip_tags(Setting.site_short_description.presence || I18n.t('about.about_mastodon_html')) - end - - def username - { min: 1, max: 30, re: '[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?' } - end - - def prefill_url - params = { - provider: 'keybase', - token: '%{sig_hash}', - provider_username: '%{kb_username}', - username: '%{username}', - user_agent: '%{kb_ua}', - } - - CGI.unescape(new_settings_identity_proof_url(params)) - end - - def profile_url - CGI.unescape(short_account_url('%{username}')) - end - - def check_url - CGI.unescape(api_proofs_url(username: '%{username}', provider: 'keybase')) - end - - def check_path - ['signatures'] - end - - def avatar_path - ['avatar'] - end - - def contact - [Setting.site_contact_email.presence || 'unknown'].compact - end -end diff --git a/app/lib/proof_provider/keybase/serializer.rb b/app/lib/proof_provider/keybase/serializer.rb deleted file mode 100644 index d29283600..000000000 --- a/app/lib/proof_provider/keybase/serializer.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -class ProofProvider::Keybase::Serializer < ActiveModel::Serializer - include RoutingHelper - - attribute :avatar - - has_many :identity_proofs, key: :signatures - - def avatar - full_asset_url(object.avatar_original_url) - end - - class AccountIdentityProofSerializer < ActiveModel::Serializer - attributes :sig_hash, :kb_username - - def sig_hash - object.token - end - - def kb_username - object.provider_username - end - end -end diff --git a/app/lib/proof_provider/keybase/verifier.rb b/app/lib/proof_provider/keybase/verifier.rb deleted file mode 100644 index af69b1bfc..000000000 --- a/app/lib/proof_provider/keybase/verifier.rb +++ /dev/null @@ -1,59 +0,0 @@ -# frozen_string_literal: true - -class ProofProvider::Keybase::Verifier - def initialize(local_username, provider_username, token, domain) - @local_username = local_username - @provider_username = provider_username - @token = token - @domain = domain - end - - def valid? - request = Request.new(:get, "#{ProofProvider::Keybase::BASE_URL}/_/api/1.0/sig/proof_valid.json", params: query_params) - - request.perform do |res| - json = Oj.load(res.body_with_limit, mode: :strict) - - if json.is_a?(Hash) - json.fetch('proof_valid', false) - else - false - end - end - rescue Oj::ParseError, HTTP::Error, OpenSSL::SSL::SSLError - false - end - - def on_success_path(user_agent = nil) - url = Addressable::URI.parse("#{ProofProvider::Keybase::BASE_URL}/_/proof_creation_success") - url.query_values = query_params.merge(kb_ua: user_agent || 'unknown') - url.to_s - end - - def status - request = Request.new(:get, "#{ProofProvider::Keybase::BASE_URL}/_/api/1.0/sig/proof_live.json", params: query_params) - - request.perform do |res| - raise ProofProvider::Keybase::UnexpectedResponseError unless res.code == 200 - - json = Oj.load(res.body_with_limit, mode: :strict) - - raise ProofProvider::Keybase::UnexpectedResponseError unless json.is_a?(Hash) && json.key?('proof_valid') && json.key?('proof_live') - - json - end - rescue Oj::ParseError, HTTP::Error, OpenSSL::SSL::SSLError - raise ProofProvider::Keybase::UnexpectedResponseError - end - - private - - def query_params - { - domain: @domain, - kb_username: @provider_username, - username: @local_username, - sig_hash: @token, - } - end -end diff --git a/app/lib/proof_provider/keybase/worker.rb b/app/lib/proof_provider/keybase/worker.rb deleted file mode 100644 index bcdd18cc5..000000000 --- a/app/lib/proof_provider/keybase/worker.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -class ProofProvider::Keybase::Worker - include Sidekiq::Worker - - sidekiq_options queue: 'pull', retry: 20, unique: :until_executed - - sidekiq_retry_in do |count, exception| - # Retry aggressively when the proof is valid but not live in Keybase. - # This is likely because Keybase just hasn't noticed the proof being - # served from here yet. - - if exception.class == ProofProvider::Keybase::ExpectedProofLiveError - case count - when 0..2 then 0.seconds - when 2..6 then 1.second - end - end - end - - def perform(proof_id) - proof = proof_id.is_a?(AccountIdentityProof) ? proof_id : AccountIdentityProof.find(proof_id) - status = proof.provider_instance.verifier.status - - # If Keybase thinks the proof is valid, and it exists here in Mastodon, - # then it should be live. Keybase just has to notice that it's here - # and then update its state. That might take a couple seconds. - raise ProofProvider::Keybase::ExpectedProofLiveError if status['proof_valid'] && !status['proof_live'] - - proof.update!(verified: status['proof_valid'], live: status['proof_live']) - end -end |