Uncouple validation of incoming messages from checking the status codes of their referents

trilby-heavy
Marnanel Thurman 2020-07-01 18:50:05 +01:00
rodzic 4b4fffba66
commit adb474be5e
1 zmienionych plików z 44 dodań i 26 usunięć

Wyświetl plik

@ -144,20 +144,6 @@ def _run_validation(
message_id,
):
"""
Validates a message. Don't call this function directly;
call validate(), above.
If the message is successfully validated, we will
...
message_id -- the primary key of an IncomingMessage
that was generated by validate().
"""
logger.info('%s: begin validation',
message_id)
try:
message = IncomingMessage.objects.get(id=message_id)
except django.core.exceptions.ValidationError:
@ -166,28 +152,62 @@ def _run_validation(
# primitive types.
raise ValueError("_run_validation()'s message_id parameter takes a UUID string")
valid = _run_validation_inner(message)
if valid:
result = create(message)
return result
return None
def _run_validation_inner(
message,
):
"""
Validates a message. Don't call this function directly;
call validate(), above.
Returns True iff the message is valid.
message_id -- the primary key of an IncomingMessage
that was generated by validate().
"""
logger.info('%s: begin validation',
message)
try:
key_id = message.key_id
except ValueError:
logger.warn('%s: message is unsigned; dropping',
message)
return None
return False
# XXX how do we look up an actor? trilby will have a way.
try:
actor = fetch_user(message.actor)
except json.decoder.JSONDecodeError as jde:
logger.info('%s: invalid JSON; dropping: %s',
message, jde)
return None
return False
except UnicodeDecodeError:
logger.info('%s: invalid UTF-8; dropping', message)
return None
return False
if actor is None:
logger.info('%s: actor does not exist; dropping message',
if actor is None or actor.status==404:
logger.info('%s: remote actor does not exist; dropping message',
message)
return None
return False
elif actor.status==410:
logger.info('%s: remote actor has Gone',
message)
# FIXME: If this message is an instruction to delete a remote user,
# it's valid if the remote user is Gone.
return False
elif actor.status!=200:
logger.info('%s: remote actor could not be fetched (status %d)',
message, actor.status)
return False
logger.debug('%s: message signature is: %s',
message, message.signature)
@ -205,7 +225,7 @@ def _run_validation(
logger.info('%s: actor has an invalid public key (%s); dropping message',
message, te,
)
return None
return False
logger.debug('Verifying; key=%s, path=%s, host=%s',
key, message.path, message.host)
@ -243,10 +263,8 @@ def _run_validation(
if not hv.verify():
logger.info('%s: spoofing attempt; message dropped',
message)
return None
return False
logger.debug('%s: validation passed!', message)
result = create(message)
return result
return True