From 42a2f3fa38d433b00d8271ce1eef8ed434ea2d3a Mon Sep 17 00:00:00 2001 From: RogerSelwyn Date: Mon, 7 Feb 2022 13:17:18 +0000 Subject: [PATCH] Fix storing of token in the config durectory --- custom_components/o365/__init__.py | 39 +++++++++++------------------- custom_components/o365/calendar.py | 9 +++---- custom_components/o365/const.py | 6 ++--- custom_components/o365/utils.py | 20 +++++++++------ 4 files changed, 32 insertions(+), 42 deletions(-) diff --git a/custom_components/o365/__init__.py b/custom_components/o365/__init__.py index 71fe610..3561890 100644 --- a/custom_components/o365/__init__.py +++ b/custom_components/o365/__init__.py @@ -5,40 +5,27 @@ from homeassistant.components.http import HomeAssistantView from homeassistant.core import callback from homeassistant.helpers import discovery -from O365 import Account +from O365 import Account, FileSystemTokenBackend try: from homeassistant.helpers.network import get_url except ImportError: pass -from .const import ( - AUTH_CALLBACK_NAME, - AUTH_CALLBACK_PATH, - AUTH_CALLBACK_PATH_ALT, - CONF_ALT_CONFIG, - CONF_CALENDARS, - CONF_CLIENT_ID, - CONF_CLIENT_SECRET, - CONF_EMAIL_SENSORS, - CONF_QUERY_SENSORS, - CONF_TRACK_NEW, - CONFIG_SCHEMA, - CONFIGURATOR_DESCRIPTION, - CONFIGURATOR_LINK_NAME, - CONFIGURATOR_SUBMIT_CAPTION, - DEFAULT_NAME, - DOMAIN, - SCOPE, - TOKEN_BACKEND, -) -from .utils import validate_permissions +from .const import (AUTH_CALLBACK_NAME, AUTH_CALLBACK_PATH, + AUTH_CALLBACK_PATH_ALT, CONF_ALT_CONFIG, CONF_CALENDARS, + CONF_CLIENT_ID, CONF_CLIENT_SECRET, CONF_EMAIL_SENSORS, + CONF_QUERY_SENSORS, CONF_TRACK_NEW, CONFIG_SCHEMA, + CONFIGURATOR_DESCRIPTION, CONFIGURATOR_LINK_NAME, + CONFIGURATOR_SUBMIT_CAPTION, DEFAULT_CACHE_PATH, + DEFAULT_NAME, DOMAIN, SCOPE, TOKEN_FILENAME) +from .utils import build_config_file_path, validate_permissions _LOGGER = logging.getLogger(__name__) async def async_setup(hass, config): """Set up the O365 platform.""" - validate_permissions() + validate_permissions(hass) conf = config.get(DOMAIN, {}) CONFIG_SCHEMA(conf) credentials = (conf.get(CONF_CLIENT_ID), conf.get(CONF_CLIENT_SECRET)) @@ -50,10 +37,12 @@ async def async_setup(hass, config): callback_url = f"{get_url(hass, prefer_external=True)}{AUTH_CALLBACK_PATH}" except NameError: callback_url = f"{hass.config.api.base_url}{AUTH_CALLBACK_PATH}" + token_path = build_config_file_path(hass, DEFAULT_CACHE_PATH) + token_backend = FileSystemTokenBackend(token_path=token_path, token_filename=TOKEN_FILENAME) - account = Account(credentials, token_backend=TOKEN_BACKEND, timezone="UTC") + account = Account(credentials, token_backend=token_backend, timezone="UTC") is_authenticated = account.is_authenticated - permissions = validate_permissions() + permissions = validate_permissions(hass) if is_authenticated and permissions: do_setup(hass, conf, account) else: diff --git a/custom_components/o365/calendar.py b/custom_components/o365/calendar.py index 355ee3e..64925a8 100644 --- a/custom_components/o365/calendar.py +++ b/custom_components/o365/calendar.py @@ -18,8 +18,8 @@ CONF_HOURS_FORWARD_TO_GET, CONF_MAX_RESULTS, CONF_NAME, CONF_SEARCH, CONF_TRACK, CONF_TRACK_NEW, DEFAULT_OFFSET, DOMAIN, MIN_TIME_BETWEEN_UPDATES, YAML_CALENDARS) -from .utils import (add_call_data_to_event, clean_html, format_event_data, - load_calendars, update_calendar_file) +from .utils import (add_call_data_to_event, build_config_file_path, clean_html, + format_event_data, load_calendars, update_calendar_file) _LOGGER = logging.getLogger(__name__) @@ -38,10 +38,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): calendar_services = CalendarServices(account, track_new, hass) calendar_services.scan_for_calendars(None) - root = hass.config.config_dir - if root[-1] != "/": - root += "/" - calendars = load_calendars(root + YAML_CALENDARS) + calendars = load_calendars(build_config_file_path(hass, YAML_CALENDARS)) devices = [] for cal_id, calendar in calendars.items(): diff --git a/custom_components/o365/const.py b/custom_components/o365/const.py index 0578ab8..5f6e659 100644 --- a/custom_components/o365/const.py +++ b/custom_components/o365/const.py @@ -4,10 +4,10 @@ import homeassistant.helpers.config_validation as cv import voluptuous as vol -from homeassistant.components.notify import ATTR_DATA, ATTR_MESSAGE, ATTR_TARGET, ATTR_TITLE +from homeassistant.components.notify import (ATTR_DATA, ATTR_MESSAGE, + ATTR_TARGET, ATTR_TITLE) from homeassistant.config import get_default_config_dir from homeassistant.const import CONF_NAME -from O365 import FileSystemTokenBackend from O365.calendar import AttendeeType, EventSensitivity, EventShowAs @@ -80,6 +80,7 @@ class EventResponse(Enum): CONFIGURATOR_SUBMIT_CAPTION = "I authorized successfully" DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S%z" DEFAULT_CACHE_PATH = ".O365-token-cache" +TOKEN_FILENAME = "o365.token" DEFAULT_HOURS_BACKWARD_TO_GET = 0 DEFAULT_HOURS_FORWARD_TO_GET = 24 DEFAULT_NAME = "O365" @@ -103,7 +104,6 @@ class EventResponse(Enum): "Mail.ReadWrite", "Mail.Send", ] -TOKEN_BACKEND = FileSystemTokenBackend(token_path=DEFAULT_CACHE_PATH, token_filename="o365.token") YAML_CALENDARS = f"{DOMAIN}_calendars.yaml" CALENDAR_SCHEMA = vol.Schema( diff --git a/custom_components/o365/utils.py b/custom_components/o365/utils.py index 649cf09..d499cf0 100644 --- a/custom_components/o365/utils.py +++ b/custom_components/o365/utils.py @@ -15,7 +15,7 @@ from .const import (CALENDAR_DEVICE_SCHEMA, CONF_CAL_ID, CONF_DEVICE_ID, CONF_ENTITIES, CONF_NAME, CONF_TRACK, CONFIG_BASE_DIR, DATETIME_FORMAT, DEFAULT_CACHE_PATH, - MINIMUM_REQUIRED_SCOPES) + MINIMUM_REQUIRED_SCOPES, TOKEN_FILENAME) _LOGGER = logging.getLogger(__name__) @@ -30,9 +30,10 @@ def clean_html(html): return html -def validate_permissions(token_path=DEFAULT_CACHE_PATH, filename="o365.token"): +def validate_permissions(hass, token_path=DEFAULT_CACHE_PATH, filename=TOKEN_FILENAME): """Validate the permissions.""" - full_token_path = os.path.join(token_path, filename) + config_path = build_config_file_path(hass, token_path) + full_token_path = os.path.join(config_path, filename) if not os.path.exists(full_token_path) or not os.path.isfile(full_token_path): _LOGGER.warning(f"Could not loacte token at {full_token_path}") return False @@ -197,14 +198,17 @@ def get_calendar_info(hass, calendar, track_new_devices): def update_calendar_file(path, calendar, hass, track_new_devices): """Update the calendar file.""" - root = hass.config.config_dir - if root[-1] != "/": - root += "/" - - existing_calendars = load_calendars(root + path) + existing_calendars = load_calendars(build_config_file_path(hass, path)) cal = get_calendar_info(hass, calendar, track_new_devices) if cal[CONF_CAL_ID] in existing_calendars: return with open(path, "a", encoding="UTF8") as out: out.write("\n") yaml.dump([cal], out, default_flow_style=False, encoding="UTF8") + + +def build_config_file_path(hass, filename): + """Create filename in config path.""" + root = hass.config.config_dir + + return os.path.join(root, filename)