Skip to content

Commit

Permalink
verify SSL option for self-signed certs
Browse files Browse the repository at this point in the history
  • Loading branch information
maciej-or committed Nov 5, 2024
1 parent 6a2fac2 commit 9598813
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 22 deletions.
17 changes: 7 additions & 10 deletions custom_components/hikvision_next/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@

from homeassistant.components.network import async_get_source_ip
from homeassistant.config_entries import ConfigEntry, ConfigFlow
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME, CONF_VERIFY_SSL
from homeassistant.data_entry_flow import FlowResult
from homeassistant.helpers.httpx_client import get_async_client

from .const import CONF_ALARM_SERVER_HOST, CONF_SET_ALARM_SERVER, DOMAIN
from .isapi import ISAPIClient
from .hikvision_device import HikvisionDevice

_LOGGER = logging.getLogger(__name__)

Expand All @@ -37,6 +36,7 @@ async def get_schema(self, user_input: dict[str, Any]):
vol.Required(CONF_HOST, default=user_input.get(CONF_HOST, "http://")): str,
vol.Required(CONF_USERNAME, default=user_input.get(CONF_USERNAME, "")): str,
vol.Required(CONF_PASSWORD, default=user_input.get(CONF_PASSWORD, "")): str,
vol.Required(CONF_VERIFY_SSL, default=True): bool,
vol.Required(
CONF_SET_ALARM_SERVER,
default=user_input.get(CONF_SET_ALARM_SERVER, True),
Expand All @@ -56,23 +56,20 @@ async def async_step_user(self, user_input: dict[str, Any] | None = None) -> Flo
if user_input is not None:
try:
host = user_input[CONF_HOST].rstrip("/")
username = user_input[CONF_USERNAME]
password = user_input[CONF_PASSWORD]
user_input_validated = {
**user_input,
CONF_HOST: host,
}

session = get_async_client(self.hass)
isapi = ISAPIClient(host, username, password, session)
await isapi.get_device_info()
device = HikvisionDevice(self.hass, data=user_input_validated)
await device.get_device_info()

if self._reauth_entry:
self.hass.config_entries.async_update_entry(self._reauth_entry, data=user_input_validated)
self.hass.async_create_task(self.hass.config_entries.async_reload(self._reauth_entry.entry_id))
return self.async_abort(reason="reauth_successful")

await self.async_set_unique_id(isapi.device_info.serial_no)
await self.async_set_unique_id(device.device_info.serial_no)
self._abort_if_unique_id_configured()

except HTTPStatusError as error:
Expand All @@ -88,7 +85,7 @@ async def async_step_user(self, user_input: dict[str, Any] | None = None) -> Flo
_LOGGER.error("Unexpected %s %s", {type(ex).__name__}, ex)
errors["base"] = f"Unexpected {type(ex).__name__}: {ex}"
else:
return self.async_create_entry(title=isapi.device_info.name, data=user_input_validated)
return self.async_create_entry(title=device.device_info.name, data=user_input_validated)

schema = await self.get_schema(user_input or {})
return self.async_show_form(step_id="user", data_schema=schema, errors=errors)
Expand Down
28 changes: 18 additions & 10 deletions custom_components/hikvision_next/hikvision_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@
import asyncio
from http import HTTPStatus
import logging
from typing import Any

import httpx

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME, CONF_VERIFY_SSL
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.httpx_client import get_async_client
from homeassistant.util import slugify

from .isapi.const import CONNECTION_TYPE_DIRECT, EVENT_IO
from .const import (
ALARM_SERVER_PATH,
CONF_ALARM_SERVER_HOST,
Expand All @@ -26,26 +26,34 @@
SECONDARY_COORDINATOR,
)
from .coordinator import EventsCoordinator, SecondaryCoordinator
from .isapi import EventInfo, ISAPIClient, IPCamera
from .isapi import EventInfo, IPCamera, ISAPIClient
from .isapi.const import CONNECTION_TYPE_DIRECT, EVENT_IO

_LOGGER = logging.getLogger(__name__)


class HikvisionDevice(ISAPIClient):
"""Hikvision device for Home Assistant integration."""

def __init__(self, hass: HomeAssistant, entry: ConfigEntry) -> None:
def __init__(
self,
hass: HomeAssistant,
entry: ConfigEntry | None = None,
data: dict[str, Any] | None = None,
) -> None:
"""Initialize device."""

config = entry.data if entry else data
self.hass = hass
self.control_alarm_server_host = entry.data[CONF_SET_ALARM_SERVER]
self.alarm_server_host = entry.data[CONF_ALARM_SERVER_HOST]
self.control_alarm_server_host = config[CONF_SET_ALARM_SERVER]
self.alarm_server_host = config[CONF_ALARM_SERVER_HOST]

# init ISAPI client
host = entry.data[CONF_HOST]
username = entry.data[CONF_USERNAME]
password = entry.data[CONF_PASSWORD]
session = get_async_client(hass)
host = config[CONF_HOST]
username = config[CONF_USERNAME]
password = config[CONF_PASSWORD]
varify_ssl = config.get(CONF_VERIFY_SSL, True)
session = get_async_client(hass, varify_ssl)
super().__init__(host, username, password, session)

self.events_info: list[EventInfo] = []
Expand Down
1 change: 1 addition & 0 deletions custom_components/hikvision_next/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"host": "URL",
"password": "Password",
"username": "Username",
"verify_ssl": "Verify Hikvision device SSL certificate",
"set_alarm_server": "Set notifications host using following address:",
"alarm_server": "Home Assistant address accessible by Hikvison device"
}
Expand Down
1 change: 1 addition & 0 deletions custom_components/hikvision_next/translations/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"host": "URL",
"password": "Hasło",
"username": "Nazwa użytkownika",
"verify_ssl": "Zweryfikuj certyfikat SSL urządzenia Hikvision",
"set_alarm_server": "Ustaw host powiadomień używając następującego adresu:",
"alarm_server": "Adres Home Assistant dostępny dla urządzenia Hikvision"
}
Expand Down
5 changes: 3 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import respx
import xmltodict
from custom_components.hikvision_next.const import DOMAIN, CONF_SET_ALARM_SERVER, CONF_ALARM_SERVER_HOST
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME, CONF_VERIFY_SSL
from pytest_homeassistant_custom_component.common import MockConfigEntry
from custom_components.hikvision_next.isapi import ISAPIClient
from homeassistant.core import HomeAssistant
Expand All @@ -17,9 +17,10 @@
CONF_USERNAME: "u1",
CONF_PASSWORD: "***",
}
TEST_CONFIG = {**TEST_CLIENT, CONF_SET_ALARM_SERVER: False, CONF_ALARM_SERVER_HOST: ""}
TEST_CONFIG = {**TEST_CLIENT, CONF_VERIFY_SSL: True, CONF_SET_ALARM_SERVER: False, CONF_ALARM_SERVER_HOST: ""}
TEST_CONFIG_WITH_ALARM_SERVER = {
**TEST_CLIENT,
CONF_VERIFY_SSL: True,
CONF_SET_ALARM_SERVER: True,
CONF_ALARM_SERVER_HOST: "http://1.0.0.11:8123",
}
Expand Down

0 comments on commit 9598813

Please sign in to comment.