mirror of
https://github.com/home-assistant/core.git
synced 2025-04-26 10:17:51 +00:00
Expire auth code after 10 minutes (#15381)
This commit is contained in:
parent
df8c59406b
commit
dbdd0a1f56
@ -102,6 +102,7 @@ a limited expiration.
|
||||
"token_type": "Bearer"
|
||||
}
|
||||
"""
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
import uuid
|
||||
|
||||
@ -114,6 +115,7 @@ from homeassistant.helpers.data_entry_flow import (
|
||||
FlowManagerIndexView, FlowManagerResourceView)
|
||||
from homeassistant.components.http.view import HomeAssistantView
|
||||
from homeassistant.components.http.data_validator import RequestDataValidator
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from . import indieauth
|
||||
|
||||
@ -349,12 +351,26 @@ def _create_cred_store():
|
||||
def store_credentials(client_id, credentials):
|
||||
"""Store credentials and return a code to retrieve it."""
|
||||
code = uuid.uuid4().hex
|
||||
temp_credentials[(client_id, code)] = credentials
|
||||
temp_credentials[(client_id, code)] = (dt_util.utcnow(), credentials)
|
||||
return code
|
||||
|
||||
@callback
|
||||
def retrieve_credentials(client_id, code):
|
||||
"""Retrieve credentials."""
|
||||
return temp_credentials.pop((client_id, code), None)
|
||||
key = (client_id, code)
|
||||
|
||||
if key not in temp_credentials:
|
||||
return None
|
||||
|
||||
created, credentials = temp_credentials.pop(key)
|
||||
|
||||
# OAuth 4.2.1
|
||||
# The authorization code MUST expire shortly after it is issued to
|
||||
# mitigate the risk of leaks. A maximum authorization code lifetime of
|
||||
# 10 minutes is RECOMMENDED.
|
||||
if dt_util.utcnow() - created < timedelta(minutes=10):
|
||||
return credentials
|
||||
|
||||
return None
|
||||
|
||||
return store_credentials, retrieve_credentials
|
||||
|
@ -1,4 +1,10 @@
|
||||
"""Integration tests for the auth component."""
|
||||
from datetime import timedelta
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.util.dt import utcnow
|
||||
from homeassistant.components import auth
|
||||
|
||||
from . import async_setup_auth
|
||||
|
||||
from tests.common import CLIENT_ID, CLIENT_REDIRECT_URI
|
||||
@ -58,3 +64,25 @@ async def test_login_new_user_and_refresh_token(hass, aiohttp_client):
|
||||
'authorization': 'Bearer {}'.format(tokens['access_token'])
|
||||
})
|
||||
assert resp.status == 200
|
||||
|
||||
|
||||
def test_credential_store_expiration():
|
||||
"""Test that the credential store will not return expired tokens."""
|
||||
store, retrieve = auth._create_cred_store()
|
||||
client_id = 'bla'
|
||||
credentials = 'creds'
|
||||
now = utcnow()
|
||||
|
||||
with patch('homeassistant.util.dt.utcnow', return_value=now):
|
||||
code = store(client_id, credentials)
|
||||
|
||||
with patch('homeassistant.util.dt.utcnow',
|
||||
return_value=now + timedelta(minutes=10)):
|
||||
assert retrieve(client_id, code) is None
|
||||
|
||||
with patch('homeassistant.util.dt.utcnow', return_value=now):
|
||||
code = store(client_id, credentials)
|
||||
|
||||
with patch('homeassistant.util.dt.utcnow',
|
||||
return_value=now + timedelta(minutes=9, seconds=59)):
|
||||
assert retrieve(client_id, code) == credentials
|
||||
|
Loading…
x
Reference in New Issue
Block a user