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
This commit is contained in:
		
							parent
							
								
									9a881c70e2
								
							
						
					
					
						commit
						39d1d022de
					
				| @ -43,13 +43,7 @@ module SignatureVerification | |||||||
|       return |       return | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     account_stoplight = Stoplight("source:#{request.ip}") { account_from_key_id(signature_params['keyId']) } |     account = 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 |  | ||||||
| 
 | 
 | ||||||
|     if account.nil? |     if account.nil? | ||||||
|       @signature_verification_failure_reason = "Public key not found for key #{signature_params['keyId']}" |       @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? |     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) } |     account = stoplight_wrap_request { 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 |  | ||||||
| 
 | 
 | ||||||
|     if account.nil? |     if account.nil? | ||||||
|       @signature_verification_failure_reason = "Public key not found for key #{signature_params['keyId']}" |       @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) |   def account_from_key_id(key_id) | ||||||
|     if key_id.start_with?('acct:') |     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) |     elsif !ActivityPub::TagManager.instance.local_uri?(key_id) | ||||||
|       account   = ActivityPub::TagManager.instance.uri_to_resource(key_id, Account) |       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 |       account | ||||||
|     end |     end | ||||||
|   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) |   def account_refresh_key(account) | ||||||
|     return if account.local? || !account.activitypub? |     return if account.local? || !account.activitypub? | ||||||
|     ActivityPub::FetchRemoteAccountService.new.call(account.uri, only_key: true) |     ActivityPub::FetchRemoteAccountService.new.call(account.uri, only_key: true) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user