diff options
author | ThibG <thib@sitedethib.com> | 2019-05-23 15:22:39 +0200 |
---|---|---|
committer | Eugen Rochko <eugen@zeonfederated.com> | 2019-05-23 15:22:39 +0200 |
commit | 89d600bedb023a9656b98d22deab10f8c051a664 (patch) | |
tree | a41002eecde6b82c0c2af50c48310efe1bee0996 /app | |
parent | 369eb63321bd76b58202c537445d91e15e12ff3a (diff) |
Move signature verification stoplight to the requests themselves (#10813)
* Move signature verification stoplight to the requests themselves This avoids blocking messages from known keys for 5 minutes when only one fails… * Put the stoplight on the actual client IP, not a potential reverse proxy
Diffstat (limited to 'app')
-rw-r--r-- | app/controllers/concerns/signature_verification.rb | 29 |
1 files changed, 13 insertions, 16 deletions
diff --git a/app/controllers/concerns/signature_verification.rb b/app/controllers/concerns/signature_verification.rb index 91566c4fa..90a57197c 100644 --- a/app/controllers/concerns/signature_verification.rb +++ b/app/controllers/concerns/signature_verification.rb @@ -43,13 +43,7 @@ module SignatureVerification return end - account_stoplight = Stoplight("source:#{request.ip}") { account_from_key_id(signature_params['keyId']) } - .with_fallback { nil } - .with_threshold(1) - .with_cool_off_time(5.minutes.seconds) - .with_error_handler { |error, handle| error.is_a?(HTTP::Error) ? handle.call(error) : raise(error) } - - account = account_stoplight.run + account = account_from_key_id(signature_params['keyId']) if account.nil? @signature_verification_failure_reason = "Public key not found for key #{signature_params['keyId']}" @@ -62,13 +56,7 @@ module SignatureVerification return account unless verify_signature(account, signature, compare_signed_string).nil? - account_stoplight = Stoplight("source:#{request.ip}") { account.possibly_stale? ? account.refresh! : account_refresh_key(account) } - .with_fallback { nil } - .with_threshold(1) - .with_cool_off_time(5.minutes.seconds) - .with_error_handler { |error, handle| error.is_a?(HTTP::Error) ? handle.call(error) : raise(error) } - - account = account_stoplight.run + account = stoplight_wrap_request { account.possibly_stale? ? account.refresh! : account_refresh_key(account) } if account.nil? @signature_verification_failure_reason = "Public key not found for key #{signature_params['keyId']}" @@ -136,14 +124,23 @@ module SignatureVerification def account_from_key_id(key_id) if key_id.start_with?('acct:') - ResolveAccountService.new.call(key_id.gsub(/\Aacct:/, '')) + stoplight_wrap_request { ResolveAccountService.new.call(key_id.gsub(/\Aacct:/, '')) } elsif !ActivityPub::TagManager.instance.local_uri?(key_id) account = ActivityPub::TagManager.instance.uri_to_resource(key_id, Account) - account ||= ActivityPub::FetchRemoteKeyService.new.call(key_id, id: false) + account ||= stoplight_wrap_request { ActivityPub::FetchRemoteKeyService.new.call(key_id, id: false) } account end end + def stoplight_wrap_request(&block) + Stoplight("source:#{request.remote_ip}", &block) + .with_fallback { nil } + .with_threshold(1) + .with_cool_off_time(5.minutes.seconds) + .with_error_handler { |error, handle| error.is_a?(HTTP::Error) ? handle.call(error) : raise(error) } + .run + end + def account_refresh_key(account) return if account.local? || !account.activitypub? ActivityPub::FetchRemoteAccountService.new.call(account.uri, only_key: true) |