diff --git a/github/api/client.py b/github/api/client.py index 9d5dcae..e771edc 100644 --- a/github/api/client.py +++ b/github/api/client.py @@ -64,8 +64,10 @@ def __init__(self, http: ClientSession, client_id: str, client_secret: str, toke self.token = token self._login_state = "" - def get_login_url(self, redirect_uri: Union[str, URL], scope: str = "user repo") -> URL: - self._login_state = "".join(random.choices(string.ascii_lowercase + string.digits, k=64)) + def get_login_url(self, user_id: str, scope: str = "user repo") -> URL: + user_id = user_id + "%" + self._randomState = "".join(random.choices(string.ascii_lowercase + string.digits, k=64)) + self._login_state = user_id+self._randomState return self.login_url.with_query({ "client_id": self.client_id, "redirect_uri": str(redirect_uri), diff --git a/github/client_manager.py b/github/client_manager.py index 52a0d38..fbef630 100644 --- a/github/client_manager.py +++ b/github/client_manager.py @@ -92,20 +92,22 @@ async def login_callback(self, request: web.Request) -> web.Response: f"{error_msg}\n\n" f"More info at {error_uri}") try: - user_id = UserID(request.query["user_id"]) + user_id_raw, randomState = (request.query["state"]).split('%') + user_id = UserID(user_id_raw) code = request.query["code"] state = request.query["state"] + except KeyError as e: return web.Response(status=400, text=f"Missing {e.args[0]} parameter") client = self.get(user_id) if not client: - return web.Response(status=401, text="Invalid state token") + return web.Response(status=401, text="Invalid state token because no client") try: await client.finish_login(code, state) except ValueError: - return web.Response(status=401, text="Invalid state token") + return web.Response(status=401, text="Invalid state token because of ValueError") except (KeyError, ClientError): - return web.Response(status=401, text="Failed to finish login") + return web.Response(status=401, text=f"Failed to finish login") resp = await client.query("viewer { login }") user = resp["viewer"]["login"] self.put(user_id, client.token) diff --git a/github/commands.py b/github/commands.py index 7b91e57..49068ae 100644 --- a/github/commands.py +++ b/github/commands.py @@ -111,7 +111,6 @@ async def github(self, evt: MessageEvent) -> None: @command.argument("flags", required=False, pass_raw=True) @authenticated(required=False) async def login(self, evt: MessageEvent, flags: str, client: Optional[GitHubClient]) -> None: - redirect_url = (self.bot.webapp_url / "auth").with_query({"user_id": evt.sender}) flags = flags.lower() scopes = ["user:user", "public_repo", "admin:repo_hook"] if "--no-repo" in flags: @@ -120,8 +119,10 @@ async def login(self, evt: MessageEvent, flags: str, client: Optional[GitHubClie scopes.remove("admin:repo_hook") if "--private" in flags: scopes.append("repo") + # Pass user_id for state in Oauth + user_id = evt.sender login_url = str(self.bot.clients.get(evt.sender, create=True).get_login_url( - redirect_uri=redirect_url, scope=" ".join(scopes))) + user_id=user_id, scope=" ".join(scopes))) if client: username = await client.query("viewer { login }", path="viewer.login") await evt.reply(f"You're already logged in as @{username}, but you can "