Force absent users to do the access captcha again

Before this, if a request was not coming from an existing user (no token
in the request or no user with the given token), then and only then
would we send the access captcha.  This meant that if a user left a chat
message and became absent, they wouldn't be prompted to do the access
captcha again until their message was eventuallly rotated.  (While
messages exist we don't delete the users who posted them.)

This commit makes it so if user['verified'] is None, the user is kicked
and prompted with the access captcha.  This is automatically done for
absent users by a background task.
このコミットが含まれているのは:
n9k 2022-07-20 07:39:33 +00:00
コミット b1f5bbdecd
3個のファイルの変更34行の追加22行の削除

ファイルの表示

@ -137,6 +137,7 @@ def with_user_from(context, fallback_to_token=False, ignore_allowedness=False):
user['headers'] = tuple(context.headers)
if not ignore_allowedness:
assert_allowedness(timestamp, user)
if user is not None and user['verified'] is not None:
response = await f(timestamp, user, *args, **kwargs)
elif fallback_to_token:
#assert not broadcaster

ファイルの表示

@ -64,9 +64,13 @@ async def t_sunset_users(timestamp, iteration):
if iteration == 0:
return
# Deverify absent users
for user in get_absent_users(timestamp):
user['verified'] = False
# De-access absent users
absent_users = tuple(get_absent_users(timestamp))
for user in absent_users:
user['verified'] = None
# Absent users should have no connected websockets,
# so in normal operation this should always be a no-op
broadcast(users=absent_users, payload={'type': 'kick'})
# Remove as many absent users as possible

ファイルの表示

@ -54,7 +54,11 @@ async def websocket_outbound(queue, user):
await websocket.close(1001)
break
else:
await websocket.send_json(payload)
if user['verified'] is None:
await websocket.send_json({'type': 'kick'})
await websocket.close(1001)
else:
await websocket.send_json(payload)
async def websocket_inbound(queue, user):
while True:
@ -73,25 +77,28 @@ async def websocket_inbound(queue, user):
except AllowednessException:
payload = {'type': 'kick'}
else:
try:
receipt_type, parsed = parse_websocket_data(receipt)
except Malformed as e:
error , *_ = e.args
payload = {
'type': 'error',
'because': error,
}
if user['verified'] is None:
payload = {'type': 'kick'}
else:
match receipt_type:
case WS.MESSAGE:
handle = handle_inbound_message
case WS.APPEARANCE:
handle = handle_inbound_appearance
case WS.CAPTCHA:
handle = handle_inbound_captcha
case WS.PONG:
handle = handle_inbound_pong
payload = handle(timestamp, queue, user, *parsed)
try:
receipt_type, parsed = parse_websocket_data(receipt)
except Malformed as e:
error , *_ = e.args
payload = {
'type': 'error',
'because': error,
}
else:
match receipt_type:
case WS.MESSAGE:
handle = handle_inbound_message
case WS.APPEARANCE:
handle = handle_inbound_appearance
case WS.CAPTCHA:
handle = handle_inbound_captcha
case WS.PONG:
handle = handle_inbound_pong
payload = handle(timestamp, queue, user, *parsed)
# Write to websocket
if payload is not None: