2018-05-10 18:09:22 +00:00
|
|
|
"""Script to manage users for the Home Assistant auth provider."""
|
2024-03-08 18:16:38 +00:00
|
|
|
|
2018-05-10 18:09:22 +00:00
|
|
|
import argparse
|
2018-06-29 04:02:45 +00:00
|
|
|
import asyncio
|
2018-07-13 13:31:20 +00:00
|
|
|
import logging
|
2018-05-10 18:09:22 +00:00
|
|
|
import os
|
|
|
|
|
2020-07-06 22:58:53 +00:00
|
|
|
from homeassistant import runner
|
2018-07-13 13:31:20 +00:00
|
|
|
from homeassistant.auth import auth_manager_from_config
|
2018-08-22 07:52:34 +00:00
|
|
|
from homeassistant.auth.providers import homeassistant as hass_auth
|
2018-05-10 18:09:22 +00:00
|
|
|
from homeassistant.config import get_default_config_dir
|
2019-12-09 15:42:10 +00:00
|
|
|
from homeassistant.core import HomeAssistant
|
2024-01-21 02:16:43 +00:00
|
|
|
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
2018-05-10 18:09:22 +00:00
|
|
|
|
2019-07-24 20:18:40 +00:00
|
|
|
# mypy: allow-untyped-calls, allow-untyped-defs
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
|
2018-05-10 18:09:22 +00:00
|
|
|
def run(args):
|
|
|
|
"""Handle Home Assistant auth provider script."""
|
2019-07-31 19:25:30 +00:00
|
|
|
parser = argparse.ArgumentParser(description="Manage Home Assistant users")
|
|
|
|
parser.add_argument("--script", choices=["auth"])
|
2018-05-10 18:09:22 +00:00
|
|
|
parser.add_argument(
|
2019-07-31 19:25:30 +00:00
|
|
|
"-c",
|
|
|
|
"--config",
|
2018-05-10 18:09:22 +00:00
|
|
|
default=get_default_config_dir(),
|
2019-07-31 19:25:30 +00:00
|
|
|
help="Directory that contains the Home Assistant configuration",
|
|
|
|
)
|
2018-05-10 18:09:22 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
subparsers = parser.add_subparsers(dest="func")
|
2018-06-29 04:02:45 +00:00
|
|
|
subparsers.required = True
|
2019-07-31 19:25:30 +00:00
|
|
|
parser_list = subparsers.add_parser("list")
|
2018-05-10 18:09:22 +00:00
|
|
|
parser_list.set_defaults(func=list_users)
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
parser_add = subparsers.add_parser("add")
|
|
|
|
parser_add.add_argument("username", type=str)
|
|
|
|
parser_add.add_argument("password", type=str)
|
2018-05-10 18:09:22 +00:00
|
|
|
parser_add.set_defaults(func=add_user)
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
parser_validate_login = subparsers.add_parser("validate")
|
|
|
|
parser_validate_login.add_argument("username", type=str)
|
|
|
|
parser_validate_login.add_argument("password", type=str)
|
2018-05-10 18:09:22 +00:00
|
|
|
parser_validate_login.set_defaults(func=validate_login)
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
parser_change_pw = subparsers.add_parser("change_password")
|
|
|
|
parser_change_pw.add_argument("username", type=str)
|
|
|
|
parser_change_pw.add_argument("new_password", type=str)
|
2018-05-10 18:09:22 +00:00
|
|
|
parser_change_pw.set_defaults(func=change_password)
|
|
|
|
|
2020-07-06 22:58:53 +00:00
|
|
|
asyncio.set_event_loop_policy(runner.HassEventLoopPolicy(False))
|
|
|
|
asyncio.run(run_command(parser.parse_args(args)))
|
2018-07-13 13:31:20 +00:00
|
|
|
|
|
|
|
|
2020-07-06 22:58:53 +00:00
|
|
|
async def run_command(args):
|
2018-07-13 13:31:20 +00:00
|
|
|
"""Run the command."""
|
2023-08-16 11:00:14 +00:00
|
|
|
hass = HomeAssistant(os.path.join(os.getcwd(), args.config))
|
2024-01-21 02:16:43 +00:00
|
|
|
await asyncio.gather(dr.async_load(hass), er.async_load(hass))
|
2019-07-31 19:25:30 +00:00
|
|
|
hass.auth = await auth_manager_from_config(hass, [{"type": "homeassistant"}], [])
|
2018-07-13 13:31:20 +00:00
|
|
|
provider = hass.auth.auth_providers[0]
|
|
|
|
await provider.async_initialize()
|
|
|
|
await args.func(hass, provider, args)
|
2018-05-10 18:09:22 +00:00
|
|
|
|
2020-07-06 22:58:53 +00:00
|
|
|
# Triggers save on used storage helpers with delay (core auth)
|
|
|
|
logging.getLogger("homeassistant.core").setLevel(logging.WARNING)
|
|
|
|
|
|
|
|
await hass.async_stop()
|
|
|
|
|
2018-05-10 18:09:22 +00:00
|
|
|
|
2018-07-13 13:31:20 +00:00
|
|
|
async def list_users(hass, provider, args):
|
2018-05-10 18:09:22 +00:00
|
|
|
"""List the users."""
|
|
|
|
count = 0
|
2018-07-13 13:31:20 +00:00
|
|
|
for user in provider.data.users:
|
2018-05-10 18:09:22 +00:00
|
|
|
count += 1
|
2019-07-31 19:25:30 +00:00
|
|
|
print(user["username"])
|
2018-05-10 18:09:22 +00:00
|
|
|
|
|
|
|
print()
|
|
|
|
print("Total users:", count)
|
|
|
|
|
|
|
|
|
2018-07-13 13:31:20 +00:00
|
|
|
async def add_user(hass, provider, args):
|
2018-05-10 18:09:22 +00:00
|
|
|
"""Create a user."""
|
2018-07-13 13:31:20 +00:00
|
|
|
try:
|
|
|
|
provider.data.add_auth(args.username, args.password)
|
|
|
|
except hass_auth.InvalidUser:
|
|
|
|
print("Username already exists!")
|
|
|
|
return
|
|
|
|
|
|
|
|
# Save username/password
|
|
|
|
await provider.data.async_save()
|
2018-07-19 20:10:36 +00:00
|
|
|
print("Auth created")
|
2018-05-10 18:09:22 +00:00
|
|
|
|
|
|
|
|
2018-07-13 13:31:20 +00:00
|
|
|
async def validate_login(hass, provider, args):
|
2018-05-10 18:09:22 +00:00
|
|
|
"""Validate a login."""
|
|
|
|
try:
|
2018-07-13 13:31:20 +00:00
|
|
|
provider.data.validate_login(args.username, args.password)
|
2018-05-10 18:09:22 +00:00
|
|
|
print("Auth valid")
|
|
|
|
except hass_auth.InvalidAuth:
|
|
|
|
print("Auth invalid")
|
|
|
|
|
|
|
|
|
2018-07-13 13:31:20 +00:00
|
|
|
async def change_password(hass, provider, args):
|
2018-05-10 18:09:22 +00:00
|
|
|
"""Change password."""
|
|
|
|
try:
|
2018-07-13 13:31:20 +00:00
|
|
|
provider.data.change_password(args.username, args.new_password)
|
|
|
|
await provider.data.async_save()
|
2018-05-10 18:09:22 +00:00
|
|
|
print("Password changed")
|
|
|
|
except hass_auth.InvalidUser:
|
|
|
|
print("User not found")
|