Example #1
0
async def test_cookie_jar_clear_domain() -> None:
    sut = CookieJar()
    cookie = SimpleCookie()
    cookie["foo"] = "bar"
    cookie["domain_cookie"] = "value"
    cookie["domain_cookie"]["domain"] = "example.com"
    cookie["subdomain_cookie"] = "value"
    cookie["subdomain_cookie"]["domain"] = "test.example.com"
    sut.update_cookies(cookie)

    sut.clear_domain("example.com")
    iterator = iter(sut)
    morsel = next(iterator)
    assert morsel.key == "foo"
    assert morsel.value == "bar"
    with pytest.raises(StopIteration):
        next(iterator)
Example #2
0
async def raw_data():
    session = ClientSession(cookie_jar=CookieJar(unsafe=True))

    # Log in to Unifi Protect
    unifiprotect = UpvServer(
        session,
        UFP_IPADDRESS,
        UFP_PORT,
        UFP_USERNAME,
        UFP_PASSWORD,
    )

    data = await unifiprotect.get_raw_device_info()
    print(json.dumps(data, indent=1))

    # Close the Session
    await session.close()
async def test_loose_cookies_types() -> None:
    jar = CookieJar()

    accepted_types = [
        [("str", BaseCookie())],
        [("str", Morsel())],
        [
            ("str", "str"),
        ],
        {"str": BaseCookie()},
        {"str": Morsel()},
        {"str": "str"},
        SimpleCookie(),
    ]

    for loose_cookies_type in accepted_types:
        jar.update_cookies(cookies=loose_cookies_type)
async def get_controller(hass,
                         host,
                         username,
                         password,
                         port,
                         site,
                         verify_ssl,
                         async_callback=None):
    """Create a controller object and verify authentication."""
    sslcontext = None

    if verify_ssl:
        session = aiohttp_client.async_get_clientsession(hass)
        if isinstance(verify_ssl, str):
            sslcontext = ssl.create_default_context(cafile=verify_ssl)
    else:
        session = aiohttp_client.async_create_clientsession(
            hass, verify_ssl=verify_ssl, cookie_jar=CookieJar(unsafe=True))

    controller = aiounifi.Controller(
        host,
        username=username,
        password=password,
        port=port,
        site=site,
        websession=session,
        sslcontext=sslcontext,
        callback=async_callback,
    )

    try:
        with async_timeout.timeout(10):
            await controller.login()
        return controller

    except aiounifi.Unauthorized:
        LOGGER.warning("Connected to UniFi at %s but not registered.", host)
        raise AuthenticationRequired

    except (asyncio.TimeoutError, aiounifi.RequestError):
        LOGGER.error("Error connecting to the UniFi controller at %s", host)
        raise CannotConnect

    except aiounifi.AiounifiException:
        LOGGER.exception("Unknown UniFi communication error occurred")
        raise AuthenticationRequired
Example #5
0
    def test_cookie_not_expired_when_added_after_removal(self):
        """Test case for https://github.com/aio-libs/aiohttp/issues/2084"""
        timestamps = [533588.993, 533588.993, 533588.993,
                      533588.993, 533589.093, 533589.093]

        loop = mock.Mock()
        loop.time.side_effect = itertools.chain(
            timestamps, itertools.cycle([timestamps[-1]]))

        jar = CookieJar(unsafe=True, loop=loop)
        # Remove `foo` cookie.
        jar.update_cookies(SimpleCookie('foo=""; Max-Age=0'))
        # Set `foo` cookie to `bar`.
        jar.update_cookies(SimpleCookie('foo="bar"'))

        # Assert that there is a cookie.
        assert len(jar) == 1
Example #6
0
    async def download(self, request: Request) -> Union[Response, Exception]:
        session = self._default_session
        new_session = False
        proxy = None

        if request.proxy:
            proxy_url = URL(request.proxy)
            if proxy_url.scheme in ('sock4', 'sock5'):
                connector = SocksConnector.from_url(request.url)
                session = ClientSession(cookie_jar=CookieJar(unsafe=True), connector=connector)
                new_session = True
            elif proxy_url.scheme == 'https' and URL(request.url).scheme == 'https':
                return await self.download_by_requests(request)
            else:
                proxy = request.proxy

        try:
            if request.cookies:
                session.cookie_jar.update_cookies(request.cookies)

            resp = await session.request(method=request.method,
                                         url=request.url,
                                         params=request.params,
                                         data=request.data,
                                         proxy=proxy,
                                         headers=request.headers,
                                         timeout=request.timeout)

            status = resp.status
            text = await resp.text(encoding=request.encoding)
            cookies = resp.cookies

            response = Response(text=text, status=status, cookies=cookies)
            if request.cookies:
                response.cookies.update(request.cookies)

            return response

        except Exception as e:
            self.logger.error(traceback.format_exc(limit=10))
            return e

        finally:
            if new_session:
                await session.close()
Example #7
0
    async def async_step_user(self, user_input=None):
        """Handle a flow initiated by the user."""
        if user_input is None:
            return await self._show_setup_form(user_input)

        errors = {}

        session = async_create_clientsession(self.hass,
                                             cookie_jar=CookieJar(unsafe=True))

        unifiprotect = UpvServer(
            session,
            user_input[CONF_HOST],
            user_input[CONF_PORT],
            user_input[CONF_USERNAME],
            user_input[CONF_PASSWORD],
        )

        try:
            unique_id = await unifiprotect.unique_id()
        except NotAuthorized:
            errors["base"] = "connection_error"
            return await self._show_setup_form(errors)
        except NvrError:
            errors["base"] = "nvr_error"
            return await self._show_setup_form(errors)

        entries = self._async_current_entries()
        for entry in entries:
            if entry.data[CONF_ID] == unique_id:
                return self.async_abort(reason="server_exists")

        return self.async_create_entry(
            title=unique_id,
            data={
                CONF_ID: unique_id,
                CONF_HOST: user_input[CONF_HOST],
                CONF_PORT: user_input[CONF_PORT],
                CONF_USERNAME: user_input.get(CONF_USERNAME),
                CONF_PASSWORD: user_input.get(CONF_PASSWORD),
                CONF_SCAN_INTERVAL: user_input.get(CONF_SCAN_INTERVAL),
                CONF_IR_ON: user_input.get(CONF_IR_ON),
                CONF_IR_OFF: user_input.get(CONF_IR_OFF),
            },
        )
    async def _getRecordingMode(self):
        recordingMode = None
        session = ClientSession(cookie_jar=CookieJar(unsafe=True))

        unifiprotect = UpvServer(session, self.parent.unifi_host,
                                 self.parent.unifi_port,
                                 self.parent.unifi_userid,
                                 self.parent.unifi_password)
        await unifiprotect.ensure_authenticated()

        cams = await unifiprotect.update()
        cam = cams[self.cameraId]
        recordingMode = cam["recording_mode"]

        await session.close()
        await unifiprotect.async_disconnect_ws()

        return recordingMode
Example #9
0
async def import_aiohttp_cookies(cookiestxt_filename):
    cookies_obj = MozillaCookieJar(cookiestxt_filename)
    cookies_obj.load(ignore_discard=True, ignore_expires=True)

    cookies = CookieJar()

    cookies_list = []
    for domain in cookies_obj._cookies.values():
        for key, cookie in list(domain.values())[0].items():
            c = Morsel()
            c.set(key, cookie.value, cookie.value)
            c['domain'] = cookie.domain
            c['path'] = cookie.path
            cookies_list.append((key, c))

    cookies.update_cookies(cookies_list)

    return cookies
Example #10
0
    async def init_session(self, session: Optional[ClientSession] = None):
        """
        初始化 ClientSession, 使用 get/post/head 方法之前需要调用一次

        ClientSession 内部维护了连接池, 因此不建议每一个请求创建一个 session
        这里默认为每一个类创建一个 persistent session, 或者手动设置一个, 以实现复用
        在 __init__ 中初始化 session 会出现 warning, 官方在 aiohttp 4.0 之后将只允许在协程中创建 session

        See: https://github.com/aio-libs/aiohttp/issues/3658
             https://github.com/aio-libs/aiohttp/issues/4932
        """
        if not self.session:
            if session:
                self.session = session
            else:
                con = TCPConnector(ssl=False)
                jar = CookieJar(unsafe=True)
                self.session = ClientSession(connector=con, cookie_jar=jar)
Example #11
0
async def raw_data():
    session = ClientSession(cookie_jar=CookieJar(unsafe=True))

    # Log in to Unifi Protect
    unifiprotect = UpvServer(
        session,
        UFP_IPADDRESS,
        UFP_PORT,
        UFP_USERNAME,
        UFP_PASSWORD,
    )

    await unifiprotect.update(True)
    data = await unifiprotect.set_doorbell_chime(CAM_ID, True)
    print(data)

    # Close the Session
    await session.close()
Example #12
0
async def http_client(arguments: SimpleNamespace,
                      event_loop: asyncio.AbstractEventLoop, app: Application):

    server = aiohttp.test_utils.TestServer(app, loop=event_loop)
    client = aiohttp.test_utils.TestClient(
        server, loop=event_loop, cookie_jar=CookieJar(
            unsafe=True))  # type: aiohttp.test_utils.TestClient

    await client.start_server()

    try:
        arguments.http_host = server.host
        arguments.http_port = server.port
        yield client
    finally:
        await client.close()
        await server.close()
        arguments.http_host = None
        arguments.http_port = None
async def event_data():
    session = ClientSession(cookie_jar=CookieJar(unsafe=True))

    # Log in to Unifi Protect
    unifiprotect = UpvServer(
        session,
        UFP_IPADDRESS,
        UFP_PORT,
        UFP_USERNAME,
        UFP_PASSWORD,
    )

    for i in range(15):
        data = await unifiprotect.get_raw_events(10)
        print(json.dumps(data, indent=1))
        time.sleep(2)

    # Close the Session
    await session.close()
Example #14
0
async def validate_input(hass: core.HomeAssistant, data):
    """Validate the user input allows us to connect.
    Data has the keys from DATA_SCHEMA with values provided by the user.
    """

    session = async_create_clientsession(hass,
                                         cookie_jar=CookieJar(unsafe=True))

    unifiprotect = UpvServer(
        session,
        data[CONF_HOST],
        data[CONF_PORT],
        data[CONF_USERNAME],
        data[CONF_PASSWORD],
    )

    unique_id = await unifiprotect.unique_id()

    return unique_id
Example #15
0
    async def _async_get_nvr_data(
        self,
        user_input: dict[str, Any],
    ) -> tuple[NVR | None, dict[str, str]]:
        session = async_create_clientsession(
            self.hass, cookie_jar=CookieJar(unsafe=True)
        )

        host = user_input[CONF_HOST]
        port = user_input.get(CONF_PORT, DEFAULT_PORT)
        verify_ssl = user_input.get(CONF_VERIFY_SSL, DEFAULT_VERIFY_SSL)

        protect = ProtectApiClient(
            session=session,
            host=host,
            port=port,
            username=user_input[CONF_USERNAME],
            password=user_input[CONF_PASSWORD],
            verify_ssl=verify_ssl,
        )

        errors = {}
        nvr_data = None
        try:
            nvr_data = await protect.get_nvr()
        except NotAuthorized as ex:
            _LOGGER.debug(ex)
            errors[CONF_PASSWORD] = "invalid_auth"
        except NvrError as ex:
            _LOGGER.debug(ex)
            errors["base"] = "cannot_connect"
        else:
            if nvr_data.version < MIN_REQUIRED_PROTECT_V:
                _LOGGER.debug(
                    OUTDATED_LOG_MESSAGE,
                    nvr_data.version,
                    MIN_REQUIRED_PROTECT_V,
                )
                errors["base"] = "protect_version"

        return nvr_data, errors
Example #16
0
async def test_main_cookie(aiohttp_client, loop, mocker):
    dummy = DummyConn()
    mocker.patch("modules.server.acquire", return_value=dummy)

    text = "Hello, world right!"
    res = web.Response(text=text)
    mocker.patch("modules.server.fetch", return_value=(text, None, res))

    app = web.Application()
    app.router.add_get(r"/{path:.*}", server.handle)

    from aiohttp import CookieJar

    cookies = {"auth": "true"}
    jar = CookieJar()
    jar.update_cookies(cookies)
    client = await aiohttp_client(app, cookie_jar=jar)

    resp = await client.get("/?user=foo&password=bar")
    assert resp.status == 200
    text = await resp.text()
    assert "Hello, world" in text
Example #17
0
async def get_api_controller(hass, url, username, password, site, verify_ssl):

    ssl_context = None

    if verify_ssl:
        session = aiohttp_client.async_get_clientsession(hass)
        if isinstance(verify_ssl, str):
            ssl_context = ssl.create_default_context(cafile=verify_ssl)
    else:
        session = aiohttp_client.async_create_clientsession(
            hass, verify_ssl=verify_ssl, cookie_jar=CookieJar(unsafe=True)
        )

    controller = Controller(url, username, password, session, site=site, ssl_context=ssl_context)

    try:
        with async_timeout.timeout(10):
            await controller.login()

        with async_timeout.timeout(10):
            await controller.update_status()

        with async_timeout.timeout(10):
            try:
                await controller.update_ssids()
            except OperationForbidden as err:
                if controller.version < "5.0.0":
                    LOGGER.warning("API returned 'operation forbidden' while retrieving SSID stats. This is indicative of an invalid site id.")
                    raise UnknownSite(f"Possible invalid site '{site}'.")
                else:
                    raise err

        return controller
    except LoginFailed as err:
        LOGGER.warning("Connected to Omada at %s but unauthorized: %s", url, err)
        raise err
    except OmadaApiException as err:
        LOGGER.warning("Unable to connect to Omada at %s: %s", url, err)
        raise err
Example #18
0
    def setUp(self):
        super().setUp()

        self.cookies_to_send = SimpleCookie(
            "shared-cookie=first; "
            "domain-cookie=second; Domain=example.com; "
            "subdomain1-cookie=third; Domain=test1.example.com; "
            "subdomain2-cookie=fourth; Domain=test2.example.com; "
            "dotted-domain-cookie=fifth; Domain=.example.com; "
            "different-domain-cookie=sixth; Domain=different.org; "
            "secure-cookie=seventh; Domain=secure.com; Secure; "
            "no-path-cookie=eighth; Domain=pathtest.com; "
            "path1-cookie=nineth; Domain=pathtest.com; Path=/; "
            "path2-cookie=tenth; Domain=pathtest.com; Path=/one; "
            "path3-cookie=eleventh; Domain=pathtest.com; Path=/one/two; "
            "path4-cookie=twelfth; Domain=pathtest.com; Path=/one/two/; "
            "expires-cookie=thirteenth; Domain=expirestest.com; Path=/;"
            " Expires=Tue, 1 Jan 1980 12:00:00 GMT; "
            "max-age-cookie=fourteenth; Domain=maxagetest.com; Path=/;"
            " Max-Age=60; "
            "invalid-max-age-cookie=fifteenth; Domain=invalid-values.com; "
            " Max-Age=string; "
            "invalid-expires-cookie=sixteenth; Domain=invalid-values.com; "
            " Expires=string;"
        )

        self.cookies_to_receive = SimpleCookie(
            "unconstrained-cookie=first; Path=/; "
            "domain-cookie=second; Domain=example.com; Path=/; "
            "subdomain1-cookie=third; Domain=test1.example.com; Path=/; "
            "subdomain2-cookie=fourth; Domain=test2.example.com; Path=/; "
            "dotted-domain-cookie=fifth; Domain=.example.com; Path=/; "
            "different-domain-cookie=sixth; Domain=different.org; Path=/; "
            "no-path-cookie=seventh; Domain=pathtest.com; "
            "path-cookie=eighth; Domain=pathtest.com; Path=/somepath; "
            "wrong-path-cookie=nineth; Domain=pathtest.com; Path=somepath;"
        )

        self.jar = CookieJar(loop=self.loop)
Example #19
0
async def test_loose_cookies_types() -> None:
    jar = CookieJar()

    accepted_types = [
        [('str', BaseCookie())],
        [('str', Morsel())],
        [
            ('str', 'str'),
        ],
        {
            'str': BaseCookie()
        },
        {
            'str': Morsel()
        },
        {
            'str': 'str'
        },
        SimpleCookie(),
    ]

    for loose_cookies_type in accepted_types:
        jar.update_cookies(cookies=loose_cookies_type)
Example #20
0
async def event_data():
    session = ClientSession(cookie_jar=CookieJar(unsafe=True))

    # Log in to Unifi Protect
    unifiprotect = UpvServer(
        session,
        UFP_IPADDRESS,
        UFP_PORT,
        UFP_USERNAME,
        UFP_PASSWORD,
    )

    await unifiprotect.ensure_authenticated()
    await unifiprotect.update()

    unsub = unifiprotect.subscribe_websocket(subscriber)

    for i in range(15000):
        await asyncio.sleep(1)

    # Close the Session
    await session.close()
    await unifiprotect.async_disconnect_ws()
    unsub()
Example #21
0
async def test_preserving_quoted_cookies(loop) -> None:
    jar = CookieJar(unsafe=True)
    jar.update_cookies(SimpleCookie("ip-cookie=\"second\"; Domain=127.0.0.1;"))
    cookies_sent = jar.filter_cookies(
        URL("http://127.0.0.1/")).output(header='Cookie:')
    assert cookies_sent == 'Cookie: ip-cookie=\"second\"'
Example #22
0
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

        # N.B. those need to be overriden in child test cases
        self.jar = CookieJar(loop=self.loop)
Example #23
0
def test_domain_filter_ip_cookie_receive(loop, cookies_to_receive):
    jar = CookieJar(loop=loop)

    jar.update_cookies(cookies_to_receive, "http://1.2.3.4/")
    assert len(jar) == 0
Example #24
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
    """Set up TaHoma from a config entry."""
    hass.data.setdefault(DOMAIN, {})

    username = entry.data.get(CONF_USERNAME)
    password = entry.data.get(CONF_PASSWORD)

    session = aiohttp_client.async_create_clientsession(
        hass, cookie_jar=CookieJar(unsafe=True))

    client = TahomaClient(username, password, session=session)

    try:
        await client.login()
    except TooManyRequestsException:
        _LOGGER.error("too_many_requests")
        return False
    except BadCredentialsException:
        _LOGGER.error("invalid_auth")
        return False
    except Exception as exception:  # pylint: disable=broad-except
        _LOGGER.exception(exception)
        return False

    update_interval = entry.options.get(CONF_UPDATE_INTERVAL,
                                        DEFAULT_UPDATE_INTERVAL)

    tahoma_coordinator = TahomaDataUpdateCoordinator(
        hass,
        _LOGGER,
        name="TaHoma Event Fetcher",
        client=client,
        devices=await client.get_devices(),
        update_interval=timedelta(seconds=update_interval),
    )

    await tahoma_coordinator.async_refresh()

    entities = defaultdict(list)
    entities[SCENE] = await client.get_scenarios()

    hass.data[DOMAIN][entry.entry_id] = {
        "entities": entities,
        "coordinator": tahoma_coordinator,
        "update_listener": entry.add_update_listener(update_listener),
    }

    for device in tahoma_coordinator.data.values():
        platform = TAHOMA_TYPES.get(device.widget) or TAHOMA_TYPES.get(
            device.ui_class)
        if platform:
            entities[platform].append(device)
        elif (device.widget not in IGNORED_TAHOMA_TYPES
              and device.ui_class not in IGNORED_TAHOMA_TYPES):
            _LOGGER.debug(
                "Unsupported TaHoma device detected (%s - %s - %s)",
                device.controllable_name,
                device.ui_class,
                device.widget,
            )

    for platform in entities:
        hass.async_create_task(
            hass.config_entries.async_forward_entry_setup(entry, platform))

    return True
Example #25
0
async def async_setup(hass: core.HomeAssistant, config: dict) -> bool:
    """Set up the Unifi Protect component."""
    conf = config[DOMAIN]
    host = conf.get(CONF_HOST)
    username = conf.get(CONF_USERNAME)
    password = conf.get(CONF_PASSWORD)
    port = conf.get(CONF_PORT)
    use_ssl = conf.get(CONF_SSL)
    minimum_score = conf.get(CONF_MIN_SCORE)
    scan_interval = conf[CONF_SCAN_INTERVAL]
    session = async_create_clientsession(hass,
                                         cookie_jar=CookieJar(unsafe=True))

    try:
        upv_server = upv.UpvServer(session, host, port, username, password,
                                   use_ssl, minimum_score)
        _LOGGER.debug("Connected to Unifi Protect Platform")
    except upv.NotAuthorized:
        _LOGGER.error("Authorization failure while connecting to NVR")
        return False
    except upv.NvrError as ex:
        _LOGGER.error("NVR refuses to talk to me: %s", str(ex))
        raise PlatformNotReady
    except requests.exceptions.ConnectionError as ex:
        _LOGGER.error("Unable to connect to NVR: %s", str(ex))
        raise PlatformNotReady

    coordinator = DataUpdateCoordinator(
        hass,
        _LOGGER,
        name=DOMAIN,
        update_method=upv_server.update,
        update_interval=scan_interval,
    )
    # Fetch initial data so we have data when entities subscribe
    await coordinator.async_refresh()
    hass.data[UPV_DATA] = {
        "coordinator": coordinator,
        "upv": upv_server,
    }

    async def async_save_thumbnail(call):
        """Call save video service handler."""
        await async_handle_save_thumbnail_service(hass, call)

    async def async_set_recording_mode(call):
        """Call Set Recording Mode."""
        await async_handle_set_recording_mode(hass, call)

    async def async_set_ir_mode(call):
        """Call Set Infrared Mode."""
        await async_handle_set_ir_mode(hass, call)

    hass.services.async_register(
        DOMAIN,
        SERVICE_SAVE_THUMBNAIL,
        async_save_thumbnail,
        schema=SAVE_THUMBNAIL_SCHEMA,
    )

    hass.services.async_register(
        DOMAIN,
        SERVICE_SET_RECORDING_MODE,
        async_set_recording_mode,
        schema=SET_RECORDING_MODE_SCHEMA,
    )

    hass.services.async_register(
        DOMAIN,
        SERVICE_SET_IR_MODE,
        async_set_ir_mode,
        schema=SET_IR_MODE_SCHEMA,
    )

    return True
Example #26
0
async def get_controller(
    hass, host, username, password, port, site, verify_ssl, async_callback=None
):
    """Create a controller object and verify authentication."""
    sslcontext = None

    if verify_ssl:
        session = aiohttp_client.async_get_clientsession(hass)
        if isinstance(verify_ssl, str):
            sslcontext = ssl.create_default_context(cafile=verify_ssl)
    else:
        session = aiohttp_client.async_create_clientsession(
            hass, verify_ssl=verify_ssl, cookie_jar=CookieJar(unsafe=True)
        )

    controller = aiounifi.Controller(
        host,
        username=username,
        password=password,
        port=port,
        site=site,
        websession=session,
        sslcontext=sslcontext,
        callback=async_callback,
    )

    try:
        async with async_timeout.timeout(10):
            await controller.check_unifi_os()
            await controller.login()
        return controller

    except aiounifi.Unauthorized as err:
        LOGGER.warning(
            "Connected to UniFi Network at %s but not registered: %s",
            host,
            err,
        )
        raise AuthenticationRequired from err

    except (
        asyncio.TimeoutError,
        aiounifi.BadGateway,
        aiounifi.ServiceUnavailable,
        aiounifi.RequestError,
        aiounifi.ResponseError,
    ) as err:
        LOGGER.error("Error connecting to the UniFi Network at %s: %s", host, err)
        raise CannotConnect from err

    except aiounifi.LoginRequired as err:
        LOGGER.warning(
            "Connected to UniFi Network at %s but login required: %s",
            host,
            err,
        )
        raise AuthenticationRequired from err

    except aiounifi.AiounifiException as err:
        LOGGER.exception("Unknown UniFi Network communication error occurred: %s", err)
        raise AuthenticationRequired from err
Example #27
0
 async def make_jar():
     return CookieJar(unsafe=True)
Example #28
0
async def test_domain_filter_ip_cookie_receive(cookies_to_receive) -> None:
    jar = CookieJar()

    jar.update_cookies(cookies_to_receive, URL("http://1.2.3.4/"))
    assert len(jar) == 0
Example #29
0
async def test_filter_cookies_str_deprecated(loop) -> None:
    jar = CookieJar()
    with pytest.warns(DeprecationWarning):
        jar.filter_cookies("http://éé.com")
Example #30
0
 async def make_jar():
     return CookieJar()