Ejemplo n.º 1
0
    async def async_play_media(self, media_type, media_id, **kwargs):
        """Play a piece of media."""
        # Handle media_source
        if media_source.is_media_source_id(media_id):
            sourced_media = await media_source.async_resolve_media(
                self.opp, media_id)
            media_type = sourced_media.mime_type
            media_id = sourced_media.url

        # If media ID is a relative URL, we serve it from HA.
        # Create a signed path.
        if media_id[0] == "/":
            # Sign URL with Open Peer Power Cast User
            config_entry_id = self.registry_entry.config_entry_id
            config_entry = self.opp.config_entries.async_get_entry(
                config_entry_id)
            user_id = config_entry.data["user_id"]
            user = await self.opp.auth.async_get_user(user_id)
            if user.refresh_tokens:
                refresh_token: RefreshToken = list(
                    user.refresh_tokens.values())[0]

                media_id = async_sign_path(
                    self.opp,
                    refresh_token.id,
                    quote(media_id),
                    timedelta(seconds=media_source.DEFAULT_EXPIRY_TIME),
                )

            # prepend external URL
            hass_url = get_url(self.opp, prefer_external=True)
            media_id = f"{hass_url}{media_id}"

        await self.opp.async_add_executor_job(
            ft.partial(self.play_media, media_type, media_id, **kwargs))
Ejemplo n.º 2
0
async def test_auth_access_signed_path(opp, app, aiohttp_client,
                                       opp_access_token):
    """Test access with signed url."""
    app.router.add_post("/", mock_handler)
    app.router.add_get("/another_path", mock_handler)
    setup_auth(opp, app)
    client = await aiohttp_client(app)

    refresh_token = await opp.auth.async_validate_access_token(opp_access_token
                                                               )

    signed_path = async_sign_path(opp, refresh_token.id, "/",
                                  timedelta(seconds=5))

    req = await client.get(signed_path)
    assert req.status == 200
    data = await req.json()
    assert data["user_id"] == refresh_token.user.id

    # Use signature on other path
    req = await client.get("/another_path?{}".format(
        signed_path.split("?")[1]))
    assert req.status == 401

    # We only allow GET
    req = await client.post(signed_path)
    assert req.status == 401

    # Never valid as expired in the past.
    expired_signed_path = async_sign_path(opp, refresh_token.id, "/",
                                          timedelta(seconds=-5))

    req = await client.get(expired_signed_path)
    assert req.status == 401

    # refresh token gone should also invalidate signature
    await opp.auth.async_remove_refresh_token(refresh_token)
    req = await client.get(signed_path)
    assert req.status == 401
Ejemplo n.º 3
0
def websocket_sign_path(opp: OpenPeerPower,
                        connection: websocket_api.ActiveConnection, msg):
    """Handle a sign path request."""
    connection.send_message(
        websocket_api.result_message(
            msg["id"],
            {
                "path":
                async_sign_path(
                    opp,
                    connection.refresh_token_id,
                    msg["path"],
                    timedelta(seconds=msg["expires"]),
                )
            },
        ))
Ejemplo n.º 4
0
async def websocket_resolve_media(opp, connection, msg):
    """Resolve media."""
    try:
        media = await async_resolve_media(opp, msg["media_content_id"])
        url = media.url
    except Unresolvable as err:
        connection.send_error(msg["id"], "resolve_media_failed", str(err))
    else:
        if url[0] == "/":
            url = async_sign_path(
                opp,
                connection.refresh_token_id,
                quote(url),
                timedelta(seconds=msg["expires"]),
            )

        connection.send_result(msg["id"], {
            "url": url,
            "mime_type": media.mime_type
        })