Skip to content

Commit

Permalink
Avoid conversion of timestamps in jwt auth (home-assistant#101856)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco authored Oct 13, 2023
1 parent 4e9ec82 commit 2dfc8b9
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 7 deletions.
7 changes: 4 additions & 3 deletions homeassistant/auth/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
from collections import OrderedDict
from collections.abc import Mapping
from datetime import timedelta
import time
from typing import Any, cast

import jwt

from homeassistant import data_entry_flow
from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
from homeassistant.data_entry_flow import FlowResult
from homeassistant.util import dt as dt_util

from . import auth_store, jwt_wrapper, models
from .const import ACCESS_TOKEN_EXPIRATION, GROUP_ID_ADMIN
Expand Down Expand Up @@ -505,12 +505,13 @@ def async_create_access_token(

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(
{
"iss": refresh_token.id,
"iat": now,
"exp": now + refresh_token.access_token_expiration,
"exp": now + expire_seconds,
},
refresh_token.jwt_key,
algorithm="HS256",
Expand Down
13 changes: 9 additions & 4 deletions tests/auth/test_init.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Tests for the Home Assistant auth module."""
from datetime import timedelta
import time
from typing import Any
from unittest.mock import patch

Expand Down Expand Up @@ -371,11 +372,15 @@ async def test_cannot_retrieve_expired_access_token(hass: HomeAssistant) -> None
access_token = manager.async_create_access_token(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(
"homeassistant.util.dt.utcnow",
return_value=dt_util.utcnow()
- auth_const.ACCESS_TOKEN_EXPIRATION
- timedelta(seconds=11),
"homeassistant.auth.time.time",
return_value=time.time()
- auth_const.ACCESS_TOKEN_EXPIRATION.total_seconds()
- 11,
):
access_token = manager.async_create_access_token(refresh_token)

Expand Down

0 comments on commit 2dfc8b9

Please sign in to comment.