From c01ad45b163908854f9397ff24ef33dbbc6da1ea Mon Sep 17 00:00:00 2001 From: db0 Date: Tue, 5 Sep 2023 11:22:52 +0200 Subject: [PATCH] allow local key resets --- fediseer/apis/v1/whitelist.py | 20 ++++++++++++++------ fediseer/messaging.py | 13 +++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/fediseer/apis/v1/whitelist.py b/fediseer/apis/v1/whitelist.py index 6277343..8deed62 100644 --- a/fediseer/apis/v1/whitelist.py +++ b/fediseer/apis/v1/whitelist.py @@ -104,7 +104,8 @@ class WhitelistDomain(Resource): patch_parser = reqparse.RequestParser() patch_parser.add_argument("apikey", type=str, required=True, help="The sending instance's API key.", location='headers') patch_parser.add_argument("Client-Agent", default="unknown:0:unknown", type=str, required=False, help="The client name and version.", location="headers") - patch_parser.add_argument("regenerate_key", required=False, type=str, help="If a username is given, their API will be reset. This can be initiated by other instance admins or the fediseer.", location="json") + patch_parser.add_argument("admin_username", required=False, type=str, help="If a username is given, their API key will be reset. Otherwise the user's whose API key was provided will be reset. This allows can be initiated by other instance admins or the fediseer.", location="json") + patch_parser.add_argument("return_new_key", required=False, type=bool, help="If True, the key will be returned as part of the response instead of PM'd. IT will still PM a notification to you.", location="json") @api.expect(patch_parser) @@ -121,16 +122,23 @@ class WhitelistDomain(Resource): if not user: raise e.Forbidden("You have not yet claimed an instance. Use the POST method to do so.") instance = database.find_instance_by_user(user) - if self.args.regenerate_key: + if self.args.admin_username: requestor = None - if self.args.regenerate_key != user.username or user.username == "fediseer": + if self.args.admin_username != user.username or user.username == "fediseer": requestor = user.username - instance_to_reset = database.find_instance_by_account(f"@{self.args.regenerate_key}@{domain}") + instance_to_reset = database.find_instance_by_account(f"@{self.args.admin_username}@{domain}") + if instance_to_reset is None: + raise e.NotFound(f"No Instance found matching provided domain. Have you remembered to register it?") if instance != instance_to_reset and user.username != "fediseer": raise e.BadRequest("Only other admins of the same instance or the fediseer can request API key reset for others.") instance = instance_to_reset - user = database.find_user_by_account(f"@{self.args.regenerate_key}@{domain}") - new_key = activitypub_pm.pm_new_api_key(domain, self.args.regenerate_key, instance.software, requestor=requestor) + user = database.find_user_by_account(f"@{self.args.admin_username}@{domain}") + if self.args.return_new_key: + if requestor is None: + requestor = requestor = user.username + new_key = activitypub_pm.pm_new_key_notification(domain, self.args.admin_username, instance.software, requestor=requestor) + else: + new_key = activitypub_pm.pm_new_api_key(domain, self.args.admin_username, instance.software, requestor=requestor) user.api_key = hash_api_key(new_key) db.session.commit() return {"message": "Changed"},200 diff --git a/fediseer/messaging.py b/fediseer/messaging.py index a401ba0..f3eb3c2 100644 --- a/fediseer/messaging.py +++ b/fediseer/messaging.py @@ -130,6 +130,19 @@ class ActivityPubPM: raise e.BadRequest("API Key PM failed") return api_key + def pm_new_key_notification(self, domain: str, username: str, software: str, requestor: str): + api_key = secrets.token_urlsafe(16) + pm_content = f"user '{requestor}' has initiated an API Key reset for your domain {domain} on the [Fediseer](https://fediseer.com)\n\nThe new API key was provided in the response already\n" + logger.info(f"user '{requestor}' reset the API key for {username}@{domain} on the response.") + if not self.send_pm_to_right_software( + message=pm_content, + username=username, + domain=domain, + software=software + ): + raise e.BadRequest("API Key PM failed") + return api_key + def pm_admins(self, message: str, domain: str, software: str, instance): if software not in SUPPORTED_SOFTWARE: