mirror of
https://github.com/fastapi-users/fastapi-users.git
synced 2026-03-13 07:49:55 +08:00
Fix #431: make OAuth expires_at optional in model and DB schemas
This commit is contained in:
@@ -59,7 +59,7 @@ Notice that we inherit from the `BaseOAuthAccountMixin`, which adds a `List` of
|
||||
* `id` (`UUID4`) – Unique identifier of the OAuth account information. Default to a **UUID4**.
|
||||
* `oauth_name` (`str`) – Name of the OAuth service. It corresponds to the `name` property of the OAuth client.
|
||||
* `access_token` (`str`) – Access token.
|
||||
* `expires_at` (`int`) - Timestamp at which the access token is expired.
|
||||
* `expires_at` (`Optional[int]`) - Timestamp at which the access token is expired.
|
||||
* `refresh_token` (`Optional[str]`) – On services that support it, a token to get a fresh access token.
|
||||
* `account_id` (`str`) - Identifier of the OAuth account on the corresponding service.
|
||||
* `account_email` (`str`) - Email address of the OAuth account on the corresponding service.
|
||||
|
||||
@@ -67,7 +67,7 @@ class SQLAlchemyBaseOAuthAccountTable:
|
||||
id = Column(GUID, primary_key=True)
|
||||
oauth_name = Column(String(length=100), index=True, nullable=False)
|
||||
access_token = Column(String(length=1024), nullable=False)
|
||||
expires_at = Column(Integer, nullable=False)
|
||||
expires_at = Column(Integer, nullable=True)
|
||||
refresh_token = Column(String(length=1024), nullable=True)
|
||||
account_id = Column(String(length=320), index=True, nullable=False)
|
||||
account_email = Column(String(length=320), nullable=False)
|
||||
|
||||
@@ -31,7 +31,7 @@ class TortoiseBaseOAuthAccountModel(models.Model):
|
||||
id = fields.UUIDField(pk=True, generated=False, max_length=255)
|
||||
oauth_name = fields.CharField(null=False, max_length=255)
|
||||
access_token = fields.CharField(null=False, max_length=255)
|
||||
expires_at = fields.IntField(null=False)
|
||||
expires_at = fields.IntField(null=True)
|
||||
refresh_token = fields.CharField(null=True, max_length=255)
|
||||
account_id = fields.CharField(index=True, null=False, max_length=255)
|
||||
account_email = fields.CharField(null=False, max_length=255)
|
||||
|
||||
@@ -56,7 +56,7 @@ class BaseOAuthAccount(BaseModel):
|
||||
id: Optional[UUID4] = None
|
||||
oauth_name: str
|
||||
access_token: str
|
||||
expires_at: int
|
||||
expires_at: Optional[int] = None
|
||||
refresh_token: Optional[str] = None
|
||||
account_id: str
|
||||
account_email: str
|
||||
|
||||
@@ -108,7 +108,7 @@ def get_oauth_router(
|
||||
new_oauth_account = models.BaseOAuthAccount(
|
||||
oauth_name=oauth_client.name,
|
||||
access_token=token["access_token"],
|
||||
expires_at=token["expires_at"],
|
||||
expires_at=token.get("expires_at"),
|
||||
refresh_token=token.get("refresh_token"),
|
||||
account_id=account_id,
|
||||
account_email=account_email,
|
||||
|
||||
@@ -147,10 +147,18 @@ class TestAuthorize:
|
||||
@pytest.mark.router
|
||||
@pytest.mark.oauth
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
"access_token",
|
||||
[
|
||||
({"access_token": "TOKEN", "expires_at": 1579179542}),
|
||||
({"access_token": "TOKEN"}),
|
||||
],
|
||||
)
|
||||
class TestCallback:
|
||||
async def test_invalid_state(
|
||||
self,
|
||||
test_app_client: httpx.AsyncClient,
|
||||
access_token,
|
||||
oauth_client,
|
||||
user_oauth,
|
||||
after_register,
|
||||
@@ -158,10 +166,7 @@ class TestCallback:
|
||||
with asynctest.patch.object(
|
||||
oauth_client, "get_access_token"
|
||||
) as get_access_token_mock:
|
||||
get_access_token_mock.return_value = {
|
||||
"access_token": "TOKEN",
|
||||
"expires_at": 1579179542,
|
||||
}
|
||||
get_access_token_mock.return_value = access_token
|
||||
with asynctest.patch.object(
|
||||
oauth_client, "get_id_email"
|
||||
) as get_id_email_mock:
|
||||
@@ -180,6 +185,7 @@ class TestCallback:
|
||||
self,
|
||||
mock_user_db_oauth,
|
||||
test_app_client: httpx.AsyncClient,
|
||||
access_token,
|
||||
oauth_client,
|
||||
user_oauth,
|
||||
after_register,
|
||||
@@ -188,10 +194,7 @@ class TestCallback:
|
||||
with asynctest.patch.object(
|
||||
oauth_client, "get_access_token"
|
||||
) as get_access_token_mock:
|
||||
get_access_token_mock.return_value = {
|
||||
"access_token": "TOKEN",
|
||||
"expires_at": 1579179542,
|
||||
}
|
||||
get_access_token_mock.return_value = access_token
|
||||
with asynctest.patch.object(
|
||||
oauth_client, "get_id_email"
|
||||
) as get_id_email_mock:
|
||||
@@ -216,6 +219,7 @@ class TestCallback:
|
||||
self,
|
||||
mock_user_db_oauth,
|
||||
test_app_client: httpx.AsyncClient,
|
||||
access_token,
|
||||
oauth_client,
|
||||
superuser_oauth,
|
||||
after_register,
|
||||
@@ -224,10 +228,7 @@ class TestCallback:
|
||||
with asynctest.patch.object(
|
||||
oauth_client, "get_access_token"
|
||||
) as get_access_token_mock:
|
||||
get_access_token_mock.return_value = {
|
||||
"access_token": "TOKEN",
|
||||
"expires_at": 1579179542,
|
||||
}
|
||||
get_access_token_mock.return_value = access_token
|
||||
with asynctest.patch.object(
|
||||
oauth_client, "get_id_email"
|
||||
) as get_id_email_mock:
|
||||
@@ -255,6 +256,7 @@ class TestCallback:
|
||||
self,
|
||||
mock_user_db_oauth,
|
||||
test_app_client: httpx.AsyncClient,
|
||||
access_token,
|
||||
oauth_client,
|
||||
after_register,
|
||||
):
|
||||
@@ -262,10 +264,7 @@ class TestCallback:
|
||||
with asynctest.patch.object(
|
||||
oauth_client, "get_access_token"
|
||||
) as get_access_token_mock:
|
||||
get_access_token_mock.return_value = {
|
||||
"access_token": "TOKEN",
|
||||
"expires_at": 1579179542,
|
||||
}
|
||||
get_access_token_mock.return_value = access_token
|
||||
with asynctest.patch.object(
|
||||
oauth_client, "get_id_email"
|
||||
) as get_id_email_mock:
|
||||
@@ -297,6 +296,7 @@ class TestCallback:
|
||||
self,
|
||||
mock_user_db_oauth,
|
||||
test_app_client: httpx.AsyncClient,
|
||||
access_token,
|
||||
oauth_client,
|
||||
inactive_user_oauth,
|
||||
after_register,
|
||||
@@ -305,10 +305,7 @@ class TestCallback:
|
||||
with asynctest.patch.object(
|
||||
oauth_client, "get_access_token"
|
||||
) as get_access_token_mock:
|
||||
get_access_token_mock.return_value = {
|
||||
"access_token": "TOKEN",
|
||||
"expires_at": 1579179542,
|
||||
}
|
||||
get_access_token_mock.return_value = access_token
|
||||
with asynctest.patch.object(
|
||||
oauth_client, "get_id_email"
|
||||
) as get_id_email_mock:
|
||||
@@ -331,6 +328,7 @@ class TestCallback:
|
||||
self,
|
||||
mock_user_db_oauth,
|
||||
test_app_client_redirect_url: httpx.AsyncClient,
|
||||
access_token,
|
||||
oauth_client,
|
||||
user_oauth,
|
||||
):
|
||||
@@ -338,10 +336,7 @@ class TestCallback:
|
||||
with asynctest.patch.object(
|
||||
oauth_client, "get_access_token"
|
||||
) as get_access_token_mock:
|
||||
get_access_token_mock.return_value = {
|
||||
"access_token": "TOKEN",
|
||||
"expires_at": 1579179542,
|
||||
}
|
||||
get_access_token_mock.return_value = access_token
|
||||
with asynctest.patch.object(
|
||||
oauth_client, "get_id_email"
|
||||
) as get_id_email_mock:
|
||||
|
||||
Reference in New Issue
Block a user