diff --git a/docs/admin_api.md b/docs/admin_api.md index 53833e3..d19658f 100644 --- a/docs/admin_api.md +++ b/docs/admin_api.md @@ -36,7 +36,18 @@ Returns a list of user objects. ### `DELETE /users/` -**TODO** +Delete a single user. Does not *actually* remove the user from the users row, +it changes the username to `Deleted User `, etc. + +Also disconnects all of the users' devices from the gateway. + +Output: + +| field | type | description | +| --: | :-- | :-- | +| old | user object | old user object pre-delete | +| new | user object | new user object post-delete | + ## Instance invites diff --git a/litecord/blueprints/admin_api/users.py b/litecord/blueprints/admin_api/users.py index 713e065..cc60a69 100644 --- a/litecord/blueprints/admin_api/users.py +++ b/litecord/blueprints/admin_api/users.py @@ -25,6 +25,7 @@ from litecord.schemas import validate from litecord.admin_schemas import USER_CREATE from litecord.errors import BadRequest from litecord.utils import async_map +from litecord.blueprints.users import delete_user, user_disconnect bp = Blueprint('users_admin', __name__) @@ -98,3 +99,20 @@ async def _search_users(): return jsonify( await async_map(app.storage.get_user, rows) ) + + +@bp.route('/', methods=['DELETE']) +async def _delete_single_user(user_id: int): + await admin_check() + + old_user = await app.storage.get_user(user_id) + + await delete_user(user_id) + await user_disconnect(user_id) + + new_user = await app.storage.get_user(user_id) + + return jsonify({ + 'old': old_user, + 'new': new_user + }) diff --git a/litecord/blueprints/users.py b/litecord/blueprints/users.py index 1145b8d..3789eda 100644 --- a/litecord/blueprints/users.py +++ b/litecord/blueprints/users.py @@ -545,7 +545,8 @@ async def delete_user(user_id, *, db=None): await _del_from_table(db, 'channel_overwrites', user_id) -async def _force_disconnect(user_id): +async def user_disconnect(user_id): + """Disconnects the given user's devices.""" # after removing the user from all tables, we need to force # all known user states to reconnect, causing the user to not # be online anymore. @@ -597,6 +598,6 @@ async def delete_account(): raise Unauthorized('password does not match') await delete_user(user_id) - await _force_disconnect(user_id) + await user_disconnect(user_id) return '', 204