diff --git a/CHANGELOG.md b/CHANGELOG.md index ef75761..92739f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).All notable changes to this project will be documented in this file. -## [Unreleased](https://github.com/nxtlo/aiobungie/compare/0.2.9...HEAD) +## [Unreleased](https://github.com/nxtlo/aiobungie/compare/0.2.10...HEAD) +## [0.2.10](https://github.com/nxtlo/aiobungie/compare/0.2.9...0.2.19) - 2023-12-12 + +## Fixed +* Fixed `fetch_oauth2_tokens` and `refresh_access_token` raising `BadRequest`. +* `client_secret` was being logged in the headers when enabling `TRACE` log level. ## [0.2.9](https://github.com/nxtlo/aiobungie/compare/0.2.8...0.2.9) - 2023-12-1 diff --git a/README.md b/README.md index e48445d..b193ae7 100644 --- a/README.md +++ b/README.md @@ -120,7 +120,7 @@ If you have used aiobungie and want to show your work, Feel free to Open a PR in * [Fated](https://github.com/nxtlo/Fated/blob/master/core/components/destiny.py): My Discord BOT for testing purposes. ## Useful Resources -* Discord Username: `fateq` +* Discord Username: `vfate` * aiobungie Documentation: [Here](https://nxtlo.github.io/aiobungie/). * BungieAPI Discord: [Here](https://discord.gg/vP7VC7TKUG) * Official Bungie Documentation: [Here](https://bungie-net.github.io/multi/index.html) diff --git a/aiobungie/error.py b/aiobungie/error.py index ea51f9a..ed4ec88 100644 --- a/aiobungie/error.py +++ b/aiobungie/error.py @@ -438,7 +438,7 @@ def stringify_http_message(headers: collections.Mapping[str, str]) -> str: "{ \n" + "\n".join( # noqa: W503 f"{f' {key}'}: {value}" - if key not in ("Authorization", "X-API-KEY") + if key not in ("Authorization", "X-API-KEY", "client_secret", "client_id") else f" {key}: REDACTED_TOKEN" for key, value in headers.items() ) diff --git a/aiobungie/metadata.py b/aiobungie/metadata.py index 8635fdc..c17aa7b 100644 --- a/aiobungie/metadata.py +++ b/aiobungie/metadata.py @@ -36,7 +36,7 @@ import typing -__version__: typing.Final[str] = "0.2.9" +__version__: typing.Final[str] = "0.2.10" __about__: typing.Final[ str ] = "A statically typed, asynchronous API wrapper for building clients for Bungie's API in Python." diff --git a/aiobungie/rest.py b/aiobungie/rest.py index cbb2e83..882d99e 100644 --- a/aiobungie/rest.py +++ b/aiobungie/rest.py @@ -172,6 +172,13 @@ def _write_sqlite_bytes( pathlib.Path(tmp.name).unlink(missing_ok=True) +class _JSONPayload(aiohttp.BytesPayload): + def __init__( + self, value: typing.Any, dumps: typedefs.Dumps = helpers.dumps + ) -> None: + super().__init__(dumps(value), content_type=_APP_JSON, encoding="UTF-8") + + class RequestMethod(str, enums.Enum): """HTTP request methods enum.""" @@ -473,7 +480,8 @@ async def _request( oauth2: bool = False, auth: str | None = None, unwrapping: typing.Literal["json", "read"] = "json", - json: collections.Mapping[str, typing.Any] | str | None = None, + json: collections.Mapping[str, typing.Any] | None = None, + data: collections.Mapping[str, typing.Any] | None = None, params: collections.Mapping[str, typing.Any] | None = None, headers: dict[str, typing.Any] | None = None, ) -> typedefs.JSONIsh: @@ -502,18 +510,20 @@ async def _request( if self._lock is None: self._lock = asyncio.Lock() + if json: + headers["Content-Type"] = _APP_JSON + while True: async with (stack := contextlib.AsyncExitStack()): await stack.enter_async_context(self._lock) - data = self._dumps(json) if isinstance(json, dict) else json # We make the request here. taken_time = time.monotonic() response = await self._session.request( method=method, url=f"{endpoint}/{route}", headers=headers, - data=data, + data=_JSONPayload(json) if json else data, params=params, ) response_time = (time.monotonic() - taken_time) * 1_000 @@ -648,13 +658,15 @@ async def fetch_oauth2_tokens(self, code: str, /) -> builders.OAuth2Response: "client_secret": self._client_secret, } - data = ( - f"grant_type=authorization_code&code={code}" - f"&client_id={self._client_id}&client_secret={self._client_secret}" - ) + data = { + "grant_type": "authorization_code", + "code": code, + "client_id": self._client_id, + "client_secret": self._client_secret, + } response = await self._request( - RequestMethod.POST, "", headers=headers, json=data, oauth2=True + RequestMethod.POST, "", headers=headers, data=data, oauth2=True ) assert isinstance(response, dict) return builders.OAuth2Response.build_response(response) @@ -672,10 +684,9 @@ async def refresh_access_token( "refresh_token": refresh_token, "client_id": self._client_id, "client_secret": self._client_secret, - "Content-Type": "application/x-www-form-urlencoded", } - response = await self._request(RequestMethod.POST, "", json=data, oauth2=True) + response = await self._request(RequestMethod.POST, "", data=data, oauth2=True) assert isinstance(response, dict) return builders.OAuth2Response.build_response(response) diff --git a/pyproject.toml b/pyproject.toml index ec84bc0..4c1fc3b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aiobungie" -version = "0.2.9" +version = "0.2.10" description = "A Python and Asyncio API wrapper for Bungie's API." authors = ["nxtlo "] license = "MIT"