kopia lustrzana https://gitlab.com/marnanel/chapeau
Uncouple validation of incoming messages from checking the status codes of their referents
rodzic
4b4fffba66
commit
adb474be5e
|
@ -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
|
||||
|
|
Ładowanie…
Reference in New Issue