Skip to content

Commit

Permalink
Black
Browse files Browse the repository at this point in the history
  • Loading branch information
balloob committed Jul 31, 2019
1 parent da05dfe commit 4de97ab
Show file tree
Hide file tree
Showing 2,676 changed files with 164,941 additions and 141,859 deletions.
212 changes: 118 additions & 94 deletions homeassistant/__main__.py

Large diffs are not rendered by default.

301 changes: 163 additions & 138 deletions homeassistant/auth/__init__.py

Large diffs are not rendered by default.

267 changes: 138 additions & 129 deletions homeassistant/auth/auth_store.py

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions homeassistant/auth/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
ACCESS_TOKEN_EXPIRATION = timedelta(minutes=30)
MFA_SESSION_EXPIRATION = timedelta(minutes=5)

GROUP_ID_ADMIN = 'system-admin'
GROUP_ID_USER = 'system-users'
GROUP_ID_READ_ONLY = 'system-read-only'
GROUP_ID_ADMIN = "system-admin"
GROUP_ID_USER = "system-users"
GROUP_ID_READ_ONLY = "system-read-only"
78 changes: 40 additions & 38 deletions homeassistant/auth/mfa_modules/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,25 @@

MULTI_FACTOR_AUTH_MODULES = Registry()

MULTI_FACTOR_AUTH_MODULE_SCHEMA = vol.Schema({
vol.Required(CONF_TYPE): str,
vol.Optional(CONF_NAME): str,
# Specify ID if you have two mfa auth module for same type.
vol.Optional(CONF_ID): str,
}, extra=vol.ALLOW_EXTRA)

DATA_REQS = 'mfa_auth_module_reqs_processed'
MULTI_FACTOR_AUTH_MODULE_SCHEMA = vol.Schema(
{
vol.Required(CONF_TYPE): str,
vol.Optional(CONF_NAME): str,
# Specify ID if you have two mfa auth module for same type.
vol.Optional(CONF_ID): str,
},
extra=vol.ALLOW_EXTRA,
)

DATA_REQS = "mfa_auth_module_reqs_processed"

_LOGGER = logging.getLogger(__name__)


class MultiFactorAuthModule:
"""Multi-factor Auth Module of validation function."""

DEFAULT_TITLE = 'Unnamed auth module'
DEFAULT_TITLE = "Unnamed auth module"
MAX_RETRY_TIME = 3

def __init__(self, hass: HomeAssistant, config: Dict[str, Any]) -> None:
Expand Down Expand Up @@ -63,7 +66,7 @@ def input_schema(self) -> vol.Schema:
"""Return a voluptuous schema to define mfa auth module's input."""
raise NotImplementedError

async def async_setup_flow(self, user_id: str) -> 'SetupFlow':
async def async_setup_flow(self, user_id: str) -> "SetupFlow":
"""Return a data entry flow handler for setup module.
Mfa module should extend SetupFlow
Expand All @@ -82,26 +85,25 @@ async def async_is_user_setup(self, user_id: str) -> bool:
"""Return whether user is setup."""
raise NotImplementedError

async def async_validate(
self, user_id: str, user_input: Dict[str, Any]) -> bool:
async def async_validate(self, user_id: str, user_input: Dict[str, Any]) -> bool:
"""Return True if validation passed."""
raise NotImplementedError


class SetupFlow(data_entry_flow.FlowHandler):
"""Handler for the setup flow."""

def __init__(self, auth_module: MultiFactorAuthModule,
setup_schema: vol.Schema,
user_id: str) -> None:
def __init__(
self, auth_module: MultiFactorAuthModule, setup_schema: vol.Schema, user_id: str
) -> None:
"""Initialize the setup flow."""
self._auth_module = auth_module
self._setup_schema = setup_schema
self._user_id = user_id

async def async_step_init(
self, user_input: Optional[Dict[str, str]] = None) \
-> Dict[str, Any]:
self, user_input: Optional[Dict[str, str]] = None
) -> Dict[str, Any]:
"""Handle the first step of setup flow.
Return self.async_show_form(step_id='init') if user_input is None.
Expand All @@ -110,50 +112,49 @@ async def async_step_init(
errors = {} # type: Dict[str, str]

if user_input:
result = await self._auth_module.async_setup_user(
self._user_id, user_input)
result = await self._auth_module.async_setup_user(self._user_id, user_input)
return self.async_create_entry(
title=self._auth_module.name,
data={'result': result}
title=self._auth_module.name, data={"result": result}
)

return self.async_show_form(
step_id='init',
data_schema=self._setup_schema,
errors=errors
step_id="init", data_schema=self._setup_schema, errors=errors
)


async def auth_mfa_module_from_config(
hass: HomeAssistant, config: Dict[str, Any]) \
-> MultiFactorAuthModule:
hass: HomeAssistant, config: Dict[str, Any]
) -> MultiFactorAuthModule:
"""Initialize an auth module from a config."""
module_name = config[CONF_TYPE]
module = await _load_mfa_module(hass, module_name)

try:
config = module.CONFIG_SCHEMA(config) # type: ignore
except vol.Invalid as err:
_LOGGER.error('Invalid configuration for multi-factor module %s: %s',
module_name, humanize_error(config, err))
_LOGGER.error(
"Invalid configuration for multi-factor module %s: %s",
module_name,
humanize_error(config, err),
)
raise

return MULTI_FACTOR_AUTH_MODULES[module_name](hass, config) # type: ignore


async def _load_mfa_module(hass: HomeAssistant, module_name: str) \
-> types.ModuleType:
async def _load_mfa_module(hass: HomeAssistant, module_name: str) -> types.ModuleType:
"""Load an mfa auth module."""
module_path = 'homeassistant.auth.mfa_modules.{}'.format(module_name)
module_path = "homeassistant.auth.mfa_modules.{}".format(module_name)

try:
module = importlib.import_module(module_path)
except ImportError as err:
_LOGGER.error('Unable to load mfa module %s: %s', module_name, err)
raise HomeAssistantError('Unable to load mfa module {}: {}'.format(
module_name, err))
_LOGGER.error("Unable to load mfa module %s: %s", module_name, err)
raise HomeAssistantError(
"Unable to load mfa module {}: {}".format(module_name, err)
)

if hass.config.skip_pip or not hasattr(module, 'REQUIREMENTS'):
if hass.config.skip_pip or not hasattr(module, "REQUIREMENTS"):
return module

processed = hass.data.get(DATA_REQS)
Expand All @@ -164,12 +165,13 @@ async def _load_mfa_module(hass: HomeAssistant, module_name: str) \

# https://github.com/python/mypy/issues/1424
req_success = await requirements.async_process_requirements(
hass, module_path, module.REQUIREMENTS) # type: ignore
hass, module_path, module.REQUIREMENTS
) # type: ignore

if not req_success:
raise HomeAssistantError(
'Unable to process requirements of mfa module {}'.format(
module_name))
"Unable to process requirements of mfa module {}".format(module_name)
)

processed.add(module_name)
return module
53 changes: 29 additions & 24 deletions homeassistant/auth/mfa_modules/insecure_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,45 @@

from homeassistant.core import HomeAssistant

from . import MultiFactorAuthModule, MULTI_FACTOR_AUTH_MODULES, \
MULTI_FACTOR_AUTH_MODULE_SCHEMA, SetupFlow

CONFIG_SCHEMA = MULTI_FACTOR_AUTH_MODULE_SCHEMA.extend({
vol.Required('data'): [vol.Schema({
vol.Required('user_id'): str,
vol.Required('pin'): str,
})]
}, extra=vol.PREVENT_EXTRA)
from . import (
MultiFactorAuthModule,
MULTI_FACTOR_AUTH_MODULES,
MULTI_FACTOR_AUTH_MODULE_SCHEMA,
SetupFlow,
)

CONFIG_SCHEMA = MULTI_FACTOR_AUTH_MODULE_SCHEMA.extend(
{
vol.Required("data"): [
vol.Schema({vol.Required("user_id"): str, vol.Required("pin"): str})
]
},
extra=vol.PREVENT_EXTRA,
)

_LOGGER = logging.getLogger(__name__)


@MULTI_FACTOR_AUTH_MODULES.register('insecure_example')
@MULTI_FACTOR_AUTH_MODULES.register("insecure_example")
class InsecureExampleModule(MultiFactorAuthModule):
"""Example auth module validate pin."""

DEFAULT_TITLE = 'Insecure Personal Identify Number'
DEFAULT_TITLE = "Insecure Personal Identify Number"

def __init__(self, hass: HomeAssistant, config: Dict[str, Any]) -> None:
"""Initialize the user data store."""
super().__init__(hass, config)
self._data = config['data']
self._data = config["data"]

@property
def input_schema(self) -> vol.Schema:
"""Validate login flow input data."""
return vol.Schema({'pin': str})
return vol.Schema({"pin": str})

@property
def setup_schema(self) -> vol.Schema:
"""Validate async_setup_user input data."""
return vol.Schema({'pin': str})
return vol.Schema({"pin": str})

async def async_setup_flow(self, user_id: str) -> SetupFlow:
"""Return a data entry flow handler for setup module.
Expand All @@ -50,21 +56,21 @@ async def async_setup_flow(self, user_id: str) -> SetupFlow:
async def async_setup_user(self, user_id: str, setup_data: Any) -> Any:
"""Set up user to use mfa module."""
# data shall has been validate in caller
pin = setup_data['pin']
pin = setup_data["pin"]

for data in self._data:
if data['user_id'] == user_id:
if data["user_id"] == user_id:
# already setup, override
data['pin'] = pin
data["pin"] = pin
return

self._data.append({'user_id': user_id, 'pin': pin})
self._data.append({"user_id": user_id, "pin": pin})

async def async_depose_user(self, user_id: str) -> None:
"""Remove user from mfa module."""
found = None
for data in self._data:
if data['user_id'] == user_id:
if data["user_id"] == user_id:
found = data
break
if found:
Expand All @@ -73,17 +79,16 @@ async def async_depose_user(self, user_id: str) -> None:
async def async_is_user_setup(self, user_id: str) -> bool:
"""Return whether user is setup."""
for data in self._data:
if data['user_id'] == user_id:
if data["user_id"] == user_id:
return True
return False

async def async_validate(
self, user_id: str, user_input: Dict[str, Any]) -> bool:
async def async_validate(self, user_id: str, user_input: Dict[str, Any]) -> bool:
"""Return True if validation passed."""
for data in self._data:
if data['user_id'] == user_id:
if data["user_id"] == user_id:
# user_input has been validate in caller
if data['pin'] == user_input['pin']:
if data["pin"] == user_input["pin"]:
return True

return False
Loading

0 comments on commit 4de97ab

Please sign in to comment.