Fix #431: make OAuth expires_at optional in model and DB schemas

This commit is contained in:
François Voron
2020-12-28 08:53:31 +01:00
parent 8940f6b9f8
commit 7cf7154e27
6 changed files with 24 additions and 29 deletions

View File

@@ -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.

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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,

View File

@@ -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: