Avoid conversion of timestamps in jwt auth (#101856)

This commit is contained in:
J. Nick Koston 2023-10-13 02:11:17 -10:00 committed by GitHub
parent 4e9ec82082
commit 2dfc8b9d7f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 13 additions and 7 deletions

View file

@ -5,6 +5,7 @@ import asyncio
from collections import OrderedDict from collections import OrderedDict
from collections.abc import Mapping from collections.abc import Mapping
from datetime import timedelta from datetime import timedelta
import time
from typing import Any, cast from typing import Any, cast
import jwt import jwt
@ -12,7 +13,6 @@ import jwt
from homeassistant import data_entry_flow from homeassistant import data_entry_flow
from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
from homeassistant.data_entry_flow import FlowResult from homeassistant.data_entry_flow import FlowResult
from homeassistant.util import dt as dt_util
from . import auth_store, jwt_wrapper, models from . import auth_store, jwt_wrapper, models
from .const import ACCESS_TOKEN_EXPIRATION, GROUP_ID_ADMIN from .const import ACCESS_TOKEN_EXPIRATION, GROUP_ID_ADMIN
@ -505,12 +505,13 @@ class AuthManager:
self._store.async_log_refresh_token_usage(refresh_token, remote_ip) self._store.async_log_refresh_token_usage(refresh_token, remote_ip)
now = dt_util.utcnow() now = int(time.time())
expire_seconds = int(refresh_token.access_token_expiration.total_seconds())
return jwt.encode( return jwt.encode(
{ {
"iss": refresh_token.id, "iss": refresh_token.id,
"iat": now, "iat": now,
"exp": now + refresh_token.access_token_expiration, "exp": now + expire_seconds,
}, },
refresh_token.jwt_key, refresh_token.jwt_key,
algorithm="HS256", algorithm="HS256",

View file

@ -1,5 +1,6 @@
"""Tests for the Home Assistant auth module.""" """Tests for the Home Assistant auth module."""
from datetime import timedelta from datetime import timedelta
import time
from typing import Any from typing import Any
from unittest.mock import patch from unittest.mock import patch
@ -371,11 +372,15 @@ async def test_cannot_retrieve_expired_access_token(hass: HomeAssistant) -> None
access_token = manager.async_create_access_token(refresh_token) access_token = manager.async_create_access_token(refresh_token)
assert await manager.async_validate_access_token(access_token) is refresh_token assert await manager.async_validate_access_token(access_token) is refresh_token
# We patch time directly here because we want the access token to be created with
# an expired time, but we do not want to freeze time so that jwt will compare it
# to the patched time. If we freeze time for the test it will be frozen for jwt
# as well and the token will not be expired.
with patch( with patch(
"homeassistant.util.dt.utcnow", "homeassistant.auth.time.time",
return_value=dt_util.utcnow() return_value=time.time()
- auth_const.ACCESS_TOKEN_EXPIRATION - auth_const.ACCESS_TOKEN_EXPIRATION.total_seconds()
- timedelta(seconds=11), - 11,
): ):
access_token = manager.async_create_access_token(refresh_token) access_token = manager.async_create_access_token(refresh_token)