From 4419f9e8166cd17c7a7f256b571c14f71a729fe9 Mon Sep 17 00:00:00 2001 From: Wu Clan Date: Tue, 6 Feb 2024 14:48:13 +0800 Subject: [PATCH] Add Gitee OAuth2 (#2) --- README.md | 4 +-- example/main.py | 1 - src/fastapi_oauth20/clients/gitee.py | 36 +++++++++++++++++++++++++++ src/fastapi_oauth20/clients/google.py | 4 +-- src/fastapi_oauth20/oauth20.py | 8 ++++++ 5 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 src/fastapi_oauth20/clients/gitee.py diff --git a/README.md b/README.md index b8eb832..3637a7e 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ 如果我们能够很容易获取测试客户端,对接将会很快发生 -- [ ] tests +- [x] Google - [ ] 微信 - [ ] QQ - [ ] 抖音 @@ -20,7 +20,7 @@ - [ ] 钉钉 - [ ] 微博 - [ ] 百度 -- [ ] Gitee +- [x] Gitee - [ ] Github - [ ] 开源中国 - [ ] 阿里云 diff --git a/example/main.py b/example/main.py index 49924e7..e9575bc 100644 --- a/example/main.py +++ b/example/main.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- - import uvicorn from fastapi import Depends, FastAPI diff --git a/src/fastapi_oauth20/clients/gitee.py b/src/fastapi_oauth20/clients/gitee.py new file mode 100644 index 0000000..853891f --- /dev/null +++ b/src/fastapi_oauth20/clients/gitee.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +import httpx + +from fastapi_oauth20.oauth20 import OAuth20Base + +AUTHORIZE_ENDPOINT = 'https://gitee.com/oauth/authorize' +ACCESS_TOKEN_ENDPOINT = 'https://gitee.com/oauth/token' +REFRESH_TOKEN_ENDPOINT = ACCESS_TOKEN_ENDPOINT +DEFAULT_SCOPES = ['user_info'] +PROFILE_ENDPOINT = 'https://gitee.com/api/v5/user' + + +class GiteeOAuth20(OAuth20Base): + def __init__(self, client_id: str, client_secret: str): + super().__init__( + client_id=client_id, + client_secret=client_secret, + authorize_endpoint=AUTHORIZE_ENDPOINT, + access_token_endpoint=ACCESS_TOKEN_ENDPOINT, + refresh_token_endpoint=REFRESH_TOKEN_ENDPOINT, + revoke_token_endpoint=None, + oauth_callback_route_name='gitee', + default_scopes=DEFAULT_SCOPES, + ) + + async def get_userinfo(self, access_token: str) -> dict: + """Get user info from Gitee""" + headers = {'Authorization': f'Bearer {access_token}'} + async with httpx.AsyncClient() as client: + response = await client.get(PROFILE_ENDPOINT, headers=headers) + await self.raise_httpx_oauth20_errors(response) + + res = response.json() + + return res diff --git a/src/fastapi_oauth20/clients/google.py b/src/fastapi_oauth20/clients/google.py index e74fa6c..d7c30f9 100644 --- a/src/fastapi_oauth20/clients/google.py +++ b/src/fastapi_oauth20/clients/google.py @@ -32,6 +32,6 @@ async def get_userinfo(self, access_token: str) -> dict: response = await client.get(PROFILE_ENDPOINT, headers=headers) await self.raise_httpx_oauth20_errors(response) - res = response.json() + res = response.json() - return res + return res diff --git a/src/fastapi_oauth20/oauth20.py b/src/fastapi_oauth20/oauth20.py index a38870b..ef48604 100644 --- a/src/fastapi_oauth20/oauth20.py +++ b/src/fastapi_oauth20/oauth20.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +import abc + from urllib.parse import urlencode, urljoin import httpx @@ -126,7 +128,13 @@ async def revoke_token(self, token: str, token_type_hint: str | None = None) -> @staticmethod async def raise_httpx_oauth20_errors(response: httpx.Response) -> None: + """Raise HTTPXOAuth20Error if the response is invalid""" try: response.raise_for_status() except httpx.HTTPStatusError as e: raise HTTPXOAuth20Error(e) from e + + @abc.abstractmethod + async def get_userinfo(self, access_token: str) -> dict: + """Get user info""" + ...