Remove no longer needed auth.util, use secrets instead (#29861)

This commit is contained in:
Ville Skyttä 2019-12-12 17:46:33 +02:00 committed by Paulus Schoutsen
parent c58c10ab7c
commit 130571c478
11 changed files with 24 additions and 34 deletions

View File

@ -1,5 +1,6 @@
"""Auth models.""" """Auth models."""
from datetime import datetime, timedelta from datetime import datetime, timedelta
import secrets
from typing import Dict, List, NamedTuple, Optional from typing import Dict, List, NamedTuple, Optional
import uuid import uuid
@ -9,7 +10,6 @@ from homeassistant.util import dt as dt_util
from . import permissions as perm_mdl from . import permissions as perm_mdl
from .const import GROUP_ID_ADMIN from .const import GROUP_ID_ADMIN
from .util import generate_secret
TOKEN_TYPE_NORMAL = "normal" TOKEN_TYPE_NORMAL = "normal"
TOKEN_TYPE_SYSTEM = "system" TOKEN_TYPE_SYSTEM = "system"
@ -96,8 +96,8 @@ class RefreshToken:
) )
id = attr.ib(type=str, factory=lambda: uuid.uuid4().hex) id = attr.ib(type=str, factory=lambda: uuid.uuid4().hex)
created_at = attr.ib(type=datetime, factory=dt_util.utcnow) created_at = attr.ib(type=datetime, factory=dt_util.utcnow)
token = attr.ib(type=str, factory=lambda: generate_secret(64)) token = attr.ib(type=str, factory=lambda: secrets.token_hex(64))
jwt_key = attr.ib(type=str, factory=lambda: generate_secret(64)) jwt_key = attr.ib(type=str, factory=lambda: secrets.token_hex(64))
last_used_at = attr.ib(type=Optional[datetime], default=None) last_used_at = attr.ib(type=Optional[datetime], default=None)
last_used_ip = attr.ib(type=Optional[str], default=None) last_used_ip = attr.ib(type=Optional[str], default=None)

View File

@ -1,13 +0,0 @@
"""Auth utils."""
import binascii
import os
def generate_secret(entropy: int = 32) -> str:
"""Generate a secret.
Backport of secrets.token_hex from Python 3.6
Event loop friendly.
"""
return binascii.hexlify(os.urandom(entropy)).decode("ascii")

View File

@ -1,11 +1,11 @@
"""Authentication for HTTP component.""" """Authentication for HTTP component."""
import logging import logging
import secrets
from aiohttp import hdrs from aiohttp import hdrs
from aiohttp.web import middleware from aiohttp.web import middleware
import jwt import jwt
from homeassistant.auth.util import generate_secret
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
@ -26,7 +26,7 @@ def async_sign_path(hass, refresh_token_id, path, expiration):
secret = hass.data.get(DATA_SIGN_SECRET) secret = hass.data.get(DATA_SIGN_SECRET)
if secret is None: if secret is None:
secret = hass.data[DATA_SIGN_SECRET] = generate_secret() secret = hass.data[DATA_SIGN_SECRET] = secrets.token_hex()
now = dt_util.utcnow() now = dt_util.utcnow()
return "{}?{}={}".format( return "{}?{}={}".format(

View File

@ -1,11 +1,11 @@
"""Provides an HTTP API for mobile_app.""" """Provides an HTTP API for mobile_app."""
import secrets
from typing import Dict from typing import Dict
import uuid import uuid
from aiohttp.web import Request, Response from aiohttp.web import Request, Response
from nacl.secret import SecretBox from nacl.secret import SecretBox
from homeassistant.auth.util import generate_secret
from homeassistant.components.http import HomeAssistantView from homeassistant.components.http import HomeAssistantView
from homeassistant.components.http.data_validator import RequestDataValidator from homeassistant.components.http.data_validator import RequestDataValidator
from homeassistant.const import CONF_WEBHOOK_ID, HTTP_CREATED from homeassistant.const import CONF_WEBHOOK_ID, HTTP_CREATED
@ -34,7 +34,7 @@ class RegistrationsView(HomeAssistantView):
"""Handle the POST request for registration.""" """Handle the POST request for registration."""
hass = request.app["hass"] hass = request.app["hass"]
webhook_id = generate_secret() webhook_id = secrets.token_hex()
if hass.components.cloud.async_active_subscription(): if hass.components.cloud.async_active_subscription():
data[ data[
@ -46,7 +46,7 @@ class RegistrationsView(HomeAssistantView):
data[CONF_WEBHOOK_ID] = webhook_id data[CONF_WEBHOOK_ID] = webhook_id
if data[ATTR_SUPPORTS_ENCRYPTION] and supports_encryption(): if data[ATTR_SUPPORTS_ENCRYPTION] and supports_encryption():
data[CONF_SECRET] = generate_secret(SecretBox.KEY_SIZE) data[CONF_SECRET] = secrets.token_hex(SecretBox.KEY_SIZE)
data[CONF_USER_ID] = request["hass_user"].id data[CONF_USER_ID] = request["hass_user"].id

View File

@ -1,6 +1,7 @@
"""Config flow for OwnTracks.""" """Config flow for OwnTracks."""
import secrets
from homeassistant import config_entries from homeassistant import config_entries
from homeassistant.auth.util import generate_secret
from homeassistant.const import CONF_WEBHOOK_ID from homeassistant.const import CONF_WEBHOOK_ID
from .const import DOMAIN # noqa pylint: disable=unused-import from .const import DOMAIN # noqa pylint: disable=unused-import
@ -25,7 +26,7 @@ class OwnTracksFlow(config_entries.ConfigFlow, domain=DOMAIN):
webhook_id, webhook_url, cloudhook = await self._get_webhook_id() webhook_id, webhook_url, cloudhook = await self._get_webhook_id()
secret = generate_secret(16) secret = secrets.token_hex(16)
if supports_encryption(): if supports_encryption():
secret_desc = f"The encryption key is {secret} (on Android under preferences -> advanced)" secret_desc = f"The encryption key is {secret} (on Android under preferences -> advanced)"
@ -53,7 +54,7 @@ class OwnTracksFlow(config_entries.ConfigFlow, domain=DOMAIN):
if self._async_current_entries(): if self._async_current_entries():
return self.async_abort(reason="one_instance_allowed") return self.async_abort(reason="one_instance_allowed")
webhook_id, _webhook_url, cloudhook = await self._get_webhook_id() webhook_id, _webhook_url, cloudhook = await self._get_webhook_id()
secret = generate_secret(16) secret = secrets.token_hex(16)
return self.async_create_entry( return self.async_create_entry(
title="OwnTracks", title="OwnTracks",
data={ data={

View File

@ -1,13 +1,13 @@
"""Integration with the Rachio Iro sprinkler system controller.""" """Integration with the Rachio Iro sprinkler system controller."""
import asyncio import asyncio
import logging import logging
import secrets
from typing import Optional from typing import Optional
from aiohttp import web from aiohttp import web
from rachiopy import Rachio from rachiopy import Rachio
import voluptuous as vol import voluptuous as vol
from homeassistant.auth.util import generate_secret
from homeassistant.components.http import HomeAssistantView from homeassistant.components.http import HomeAssistantView
from homeassistant.const import CONF_API_KEY, EVENT_HOMEASSISTANT_STOP, URL_API from homeassistant.const import CONF_API_KEY, EVENT_HOMEASSISTANT_STOP, URL_API
from homeassistant.helpers import config_validation as cv, discovery from homeassistant.helpers import config_validation as cv, discovery
@ -115,7 +115,7 @@ def setup(hass, config) -> bool:
# Get the URL of this server # Get the URL of this server
custom_url = config[DOMAIN].get(CONF_CUSTOM_URL) custom_url = config[DOMAIN].get(CONF_CUSTOM_URL)
hass_url = hass.config.api.base_url if custom_url is None else custom_url hass_url = hass.config.api.base_url if custom_url is None else custom_url
rachio.webhook_auth = generate_secret() rachio.webhook_auth = secrets.token_hex()
rachio.webhook_url = hass_url + WEBHOOK_PATH rachio.webhook_url = hass_url + WEBHOOK_PATH
# Get the API user # Get the API user

View File

@ -2,6 +2,7 @@
import asyncio import asyncio
import functools import functools
import logging import logging
import secrets
from urllib.parse import urlparse from urllib.parse import urlparse
from uuid import uuid4 from uuid import uuid4
@ -208,7 +209,7 @@ async def setup_smartapp_endpoint(hass: HomeAssistantType):
# Create config # Create config
config = { config = {
CONF_INSTANCE_ID: str(uuid4()), CONF_INSTANCE_ID: str(uuid4()),
CONF_WEBHOOK_ID: webhook.generate_secret(), CONF_WEBHOOK_ID: secrets.token_hex(),
CONF_CLOUDHOOK_URL: None, CONF_CLOUDHOOK_URL: None,
} }
await store.async_save(config) await store.async_save(config)

View File

@ -1,10 +1,10 @@
"""Provide functionality to stream video source.""" """Provide functionality to stream video source."""
import logging import logging
import secrets
import threading import threading
import voluptuous as vol import voluptuous as vol
from homeassistant.auth.util import generate_secret
from homeassistant.const import CONF_FILENAME, EVENT_HOMEASSISTANT_STOP from homeassistant.const import CONF_FILENAME, EVENT_HOMEASSISTANT_STOP
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
@ -72,7 +72,7 @@ def request_stream(hass, stream_source, *, fmt="hls", keepalive=False, options=N
stream.add_provider(fmt) stream.add_provider(fmt)
if not stream.access_token: if not stream.access_token:
stream.access_token = generate_secret() stream.access_token = secrets.token_hex()
stream.start() stream.start()
return hass.data[DOMAIN][ATTR_ENDPOINTS][fmt].format(stream.access_token) return hass.data[DOMAIN][ATTR_ENDPOINTS][fmt].format(stream.access_token)
except Exception: except Exception:

View File

@ -1,10 +1,10 @@
"""Webhooks for Home Assistant.""" """Webhooks for Home Assistant."""
import logging import logging
import secrets
from aiohttp.web import Request, Response from aiohttp.web import Request, Response
import voluptuous as vol import voluptuous as vol
from homeassistant.auth.util import generate_secret
from homeassistant.components import websocket_api from homeassistant.components import websocket_api
from homeassistant.components.http.view import HomeAssistantView from homeassistant.components.http.view import HomeAssistantView
from homeassistant.core import callback from homeassistant.core import callback
@ -46,7 +46,7 @@ def async_unregister(hass, webhook_id):
@callback @callback
def async_generate_id(): def async_generate_id():
"""Generate a webhook_id.""" """Generate a webhook_id."""
return generate_secret(entropy=32) return secrets.token_hex(32)
@callback @callback

View File

@ -8,6 +8,7 @@ This module exists of the following parts:
from abc import ABC, ABCMeta, abstractmethod from abc import ABC, ABCMeta, abstractmethod
import asyncio import asyncio
import logging import logging
import secrets
import time import time
from typing import Any, Awaitable, Callable, Dict, Optional, cast from typing import Any, Awaitable, Callable, Dict, Optional, cast
@ -18,7 +19,6 @@ import voluptuous as vol
from yarl import URL from yarl import URL
from homeassistant import config_entries from homeassistant import config_entries
from homeassistant.auth.util import generate_secret
from homeassistant.components.http import HomeAssistantView from homeassistant.components.http import HomeAssistantView
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
@ -441,7 +441,7 @@ def _encode_jwt(hass: HomeAssistant, data: dict) -> str:
secret = hass.data.get(DATA_JWT_SECRET) secret = hass.data.get(DATA_JWT_SECRET)
if secret is None: if secret is None:
secret = hass.data[DATA_JWT_SECRET] = generate_secret() secret = hass.data[DATA_JWT_SECRET] = secrets.token_hex()
return jwt.encode(data, secret, algorithm="HS256").decode() return jwt.encode(data, secret, algorithm="HS256").decode()

View File

@ -1,4 +1,5 @@
"""Test configuration and mocks for the SmartThings component.""" """Test configuration and mocks for the SmartThings component."""
import secrets
from uuid import uuid4 from uuid import uuid4
from asynctest import Mock, patch from asynctest import Mock, patch
@ -160,7 +161,7 @@ def installed_apps_fixture(installed_app, locations, app):
@pytest.fixture(name="config_file") @pytest.fixture(name="config_file")
def config_file_fixture(): def config_file_fixture():
"""Fixture representing the local config file contents.""" """Fixture representing the local config file contents."""
return {CONF_INSTANCE_ID: str(uuid4()), CONF_WEBHOOK_ID: webhook.generate_secret()} return {CONF_INSTANCE_ID: str(uuid4()), CONF_WEBHOOK_ID: secrets.token_hex()}
@pytest.fixture(name="smartthings_mock") @pytest.fixture(name="smartthings_mock")