Skip to content

Commit

Permalink
Retry signing the request if too slow (#363)
Browse files Browse the repository at this point in the history
There are cases where the cryptographic operation to sign the request
takes unusually long. One example is when using a hardware such as the
YubiKey which is busy signing other stuff.

The Serveradmin server is pretty strict and would reject these as expired
for security reasons.

To gracefully handle temporary congestion in the signing we log an error
and retry the operation up to Settings.tries.
  • Loading branch information
kofrezo authored Jul 2, 2024
1 parent 0572250 commit f09d43a
Showing 1 changed file with 15 additions and 2 deletions.
17 changes: 15 additions & 2 deletions adminapi/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Copyright (c) 2019 InnoGames GmbH
"""

import logging
import os
from hashlib import sha1
import hmac
Expand Down Expand Up @@ -41,6 +41,9 @@
)


logger = logging.getLogger(__name__)


def load_private_key_file(private_key_path):
"""Try to load a private ssh key from disk
Expand Down Expand Up @@ -69,6 +72,7 @@ class Settings:
timeout = 60.0
tries = 3
sleep_interval = 5
grace_period = 15 # <= serveradmin.api.decorators.TIMESTAMP_GRACE_PERIOD


def calc_message(timestamp, data=None):
Expand Down Expand Up @@ -137,7 +141,7 @@ def send_request(endpoint, get_params=None, post_params=None):
return json.loads(response.read().decode())


def _build_request(endpoint, get_params, post_params):
def _build_request(endpoint, get_params, post_params, retry=1):
"""Wrap request data in an urllib Request instance
Aside from preparing the get and post data for transport, this function
Expand Down Expand Up @@ -184,6 +188,15 @@ def _build_request(endpoint, get_params, post_params):
headers['X-PublicKeys'] = ','.join(key_signatures.keys())
headers['X-Signatures'] = ','.join(key_signatures.values())

time_spent_signing = int(time.time()) - timestamp
if time_spent_signing > Settings.grace_period:
if retry <= Settings.tries:
logger.error(
f'Signing the requests took {time_spent_signing} seconds! '
'Serveradmin would reject this request. Maybe your signing '
f'soft-/hardware is congested ? Retry {retry}/{Settings.tries}.')
return _build_request(endpoint, get_params, post_params, retry+1)

if not Settings.base_url:
raise ConfigurationError(
'Environment variable SERVERADMIN_BASE_URL not set'
Expand Down

0 comments on commit f09d43a

Please sign in to comment.