Exemple #1
0
async def _refresh(owner, repo, action="user", **extra_data):
    event_type = "refresh"
    try:
        installation = github.get_installation(owner, repo)
    except exceptions.MergifyNotInstalled:
        return responses.Response("Mergify not installed", status_code=404)

    data = {
        "installation": installation,
        "action": action,
        "repository": {
            "name": repo,
            "owner": {
                "login": owner
            },
            "full_name": f"{owner}/{repo}",
        },
        "sender": {
            "login": "******"
        },
    }
    data.update(extra_data)

    await github_events.job_filter_and_dispatch(event_type, str(uuid.uuid4()),
                                                data)

    return responses.Response("Refresh queued", status_code=202)
Exemple #2
0
async def subscription_cache_update(
        installation_id, request: requests.Request):  # pragma: no cover
    sub = await request.json()
    if sub is None:
        return responses.Response("Empty content", status_code=400)
    await sub_utils.save_subscription_to_cache(installation_id, sub)
    return responses.Response("Cache updated", status_code=200)
Exemple #3
0
async def subscription_cache_update(
        owner_id, request: requests.Request):  # pragma: no cover
    sub = await request.json()
    if sub is None:
        return responses.Response("Empty content", status_code=400)
    await subscription.Subscription.from_dict(
        owner_id, sub).save_subscription_to_cache()
    return responses.Response("Cache updated", status_code=200)
async def subscription_cache_update(
        owner_id: str,
        request: requests.Request) -> responses.Response:  # pragma: no cover
    sub = await request.json()
    if sub is None:
        return responses.Response("Empty content", status_code=400)
    global _AREDIS_CACHE
    await subscription.Subscription.from_dict(
        _AREDIS_CACHE, int(owner_id), sub).save_subscription_to_cache()
    return responses.Response("Cache updated", status_code=200)
Exemple #5
0
async def tokens_cache_delete(
    owner_id: github_types.GitHubAccountIdType,
    redis_cache: utils.RedisCache = fastapi.Depends(  # noqa: B008
        redis.get_redis_cache),
) -> responses.Response:
    try:
        await user_tokens.UserTokens.delete(redis_cache, owner_id)
    except NotImplementedError:
        return responses.Response("Deleting tokens is disabled",
                                  status_code=400)
    return responses.Response("Cache cleaned", status_code=200)
Exemple #6
0
async def application_cache_delete(
    api_access_key: str,
    redis_links: redis_utils.RedisLinks = fastapi.Depends(  # noqa: B008
        redis.get_redis_links
    ),
) -> responses.Response:
    try:
        await application.Application.delete(redis_links.cache, api_access_key)
    except NotImplementedError:
        return responses.Response("Deleting subscription is disabled", status_code=400)
    return responses.Response("Cache cleaned", status_code=200)
Exemple #7
0
async def subscription_cache_delete(
    owner_id: github_types.GitHubAccountIdType,
    redis_links: redis_utils.RedisLinks = fastapi.Depends(  # noqa: B008
        redis.get_redis_links
    ),
) -> responses.Response:
    try:
        await subscription.Subscription.delete_subscription(redis_links.cache, owner_id)
    except NotImplementedError:
        return responses.Response("Deleting subscription is disabled", status_code=400)
    return responses.Response("Cache cleaned", status_code=200)
Exemple #8
0
async def subscription_cache_update(
    owner_id: github_types.GitHubAccountIdType,
    request: requests.Request,
    redis_cache: utils.RedisCache = fastapi.Depends(  # noqa: B008
        redis.get_redis_cache),
) -> responses.Response:
    sub = await request.json()
    if sub is None:
        return responses.Response("Empty content", status_code=400)
    await subscription.Subscription.from_dict(
        redis_cache, int(owner_id), sub).save_subscription_to_cache()
    return responses.Response("Cache updated", status_code=200)
Exemple #9
0
async def refresh_pull(
    owner: github_types.GitHubLogin,
    repo_name: github_types.GitHubRepositoryName,
    pull_request_number: github_types.GitHubPullRequestNumber,
    action: github_types.GitHubEventRefreshActionType = "user",
    redis_cache: utils.RedisCache = fastapi.Depends(  # noqa: B008
        redis.get_redis_cache),
    redis_stream: utils.RedisStream = fastapi.Depends(  # noqa: B008
        redis.get_redis_stream),
) -> responses.Response:
    action = RefreshActionSchema(action)
    async with github.aget_client(owner_name=owner) as client:
        try:
            repository = await client.item(f"/repos/{owner}/{repo_name}")
        except http.HTTPNotFound:
            return responses.JSONResponse(status_code=404,
                                          content="repository not found")

    await utils.send_refresh(
        redis_cache,
        redis_stream,
        repository,
        pull_request_number=pull_request_number,
        action=action,
    )
    return responses.Response("Refresh queued", status_code=202)
Exemple #10
0
async def event_handler(request: requests.Request):
    event_type = request.headers.get("X-GitHub-Event")
    event_id = request.headers.get("X-GitHub-Delivery")
    data = await request.json()

    await github_events.job_filter_and_dispatch(event_type, event_id, data)

    if (config.WEBHOOK_APP_FORWARD_URL
            and config.WEBHOOK_FORWARD_EVENT_TYPES is not None
            and event_type in config.WEBHOOK_FORWARD_EVENT_TYPES):
        raw = await request.body()

        loop = asyncio.get_running_loop()
        await loop.run_in_executor(
            None,
            forward_events.post.s(
                config.WEBHOOK_APP_FORWARD_URL,
                data=raw.decode(),
                headers={
                    "X-GitHub-Event": event_type,
                    "X-GitHub-Delivery": event_id,
                    "X-Hub-Signature": request.headers.get("X-Hub-Signature"),
                    "User-Agent": request.headers.get("User-Agent"),
                    "Content-Type": request.headers.get("Content-Type"),
                },
            ).delay,
        )

    return responses.Response("Event queued", status_code=202)
Exemple #11
0
async def marketplace_handler(request: requests.Request):  # pragma: no cover
    event_type = request.headers.get("X-GitHub-Event")
    event_id = request.headers.get("X-GitHub-Delivery")
    data = await request.json()

    loop = asyncio.get_running_loop()
    await loop.run_in_executor(
        None,
        legacy_github_events.job_marketplace.s(event_type, event_id,
                                               data).apply_async,
    )

    if config.WEBHOOK_MARKETPLACE_FORWARD_URL:
        raw = await request.body()
        await loop.run_in_executor(
            None,
            forward_events.post.s(
                config.WEBHOOK_MARKETPLACE_FORWARD_URL,
                data=raw.decode(),
                headers={
                    "X-GitHub-Event": event_type,
                    "X-GitHub-Delivery": event_id,
                    "X-Hub-Signature": request.headers.get("X-Hub-Signature"),
                    "User-Agent": request.headers.get("User-Agent"),
                    "Content-Type": request.headers.get("Content-Type"),
                },
            ).delay,
        )

    return responses.Response("Event queued", status_code=202)
Exemple #12
0
async def refresh_branch(
    owner: github_types.GitHubLogin,
    repo_name: github_types.GitHubRepositoryName,
    branch: str,
    redis_cache: utils.RedisCache = fastapi.Depends(  # noqa: B008
        redis.get_redis_cache
    ),
    redis_stream: utils.RedisStream = fastapi.Depends(  # noqa: B008
        redis.get_redis_stream
    ),
) -> responses.Response:
    async with github.aget_client(owner_name=owner) as client:
        try:
            repository = await client.item(f"/repos/{owner}/{repo_name}")
        except http.HTTPNotFound:
            return responses.JSONResponse(
                status_code=404, content="repository not found"
            )

    await github_events.send_refresh(
        redis_cache,
        redis_stream,
        repository,
        ref=github_types.GitHubRefType(f"refs/heads/{branch}"),
    )
    return responses.Response("Refresh queued", status_code=202)
Exemple #13
0
async def subscription_cache_delete(
    owner_id: github_types.GitHubAccountIdType,
    redis_cache: utils.RedisCache = fastapi.Depends(  # noqa: B008
        redis.get_redis_cache),
) -> responses.Response:
    await subscription.Subscription.delete(redis_cache, owner_id)
    return responses.Response("Cache cleaned", status_code=200)
Exemple #14
0
async def refresh_pull(
    owner_login: github_types.GitHubLogin,
    repo_name: github_types.GitHubRepositoryName,
    pull_request_number: github_types.GitHubPullRequestNumber,
    action: github_types.GitHubEventRefreshActionType = "user",
    redis_links: redis_utils.RedisLinks = fastapi.Depends(  # noqa: B008
        redis.get_redis_links),
) -> responses.Response:
    action = RefreshActionSchema(action)

    installation_json = await github.get_installation_from_login(owner_login)
    async with github.aget_client(installation_json) as client:
        try:
            repository = await client.item(f"/repos/{owner_login}/{repo_name}")
        except http.HTTPNotFound:
            return responses.JSONResponse(status_code=404,
                                          content="repository not found")

    await utils.send_pull_refresh(
        redis_links.stream,
        repository,
        action=action,
        pull_request_number=pull_request_number,
        source="API",
    )
    return responses.Response("Refresh queued", status_code=202)
Exemple #15
0
async def refresh_branch(
    owner_login: github_types.GitHubLogin,
    repo_name: github_types.GitHubRepositoryName,
    branch: str,
    redis_cache: utils.RedisCache = fastapi.Depends(  # noqa: B008
        redis.get_redis_cache),
    redis_stream: utils.RedisStream = fastapi.Depends(  # noqa: B008
        redis.get_redis_stream),
) -> responses.Response:
    installation_json = await github.get_installation_from_login(owner_login)
    async with github.aget_client(installation_json) as client:
        try:
            repository = await client.item(f"/repos/{owner_login}/{repo_name}")
        except http.HTTPNotFound:
            return responses.JSONResponse(status_code=404,
                                          content="repository not found")

    await utils.send_branch_refresh(
        redis_cache,
        redis_stream,
        repository,
        action="user",
        source="API",
        ref=github_types.GitHubRefType(f"refs/heads/{branch}"),
    )
    return responses.Response("Refresh queued", status_code=202)
Exemple #16
0
async def event_handler(request: requests.Request, ) -> responses.Response:
    event_type = request.headers.get("X-GitHub-Event")
    event_id = request.headers.get("X-GitHub-Delivery")
    data = await request.json()

    try:
        await github_events.job_filter_and_dispatch(_AREDIS_STREAM, event_type,
                                                    event_id, data)
    except github_events.IgnoredEvent as ie:
        status_code = 200
        reason = f"Event ignored: {ie.reason}"
    else:
        status_code = 202
        reason = "Event queued"

    if (config.WEBHOOK_APP_FORWARD_URL
            and config.WEBHOOK_FORWARD_EVENT_TYPES is not None
            and event_type in config.WEBHOOK_FORWARD_EVENT_TYPES):
        raw = await request.body()
        await http_post(
            config.WEBHOOK_APP_FORWARD_URL,
            data=raw.decode(),
            headers={
                "X-GitHub-Event": event_type,
                "X-GitHub-Delivery": event_id,
                "X-Hub-Signature": request.headers.get("X-Hub-Signature"),
                "User-Agent": request.headers.get("User-Agent"),
                "Content-Type": request.headers.get("Content-Type"),
            },
        )

    return responses.Response(reason, status_code=status_code)
Exemple #17
0
async def marketplace_handler(
    request: requests.Request, ) -> responses.Response:  # pragma: no cover
    event_type = request.headers.get("X-GitHub-Event")
    event_id = request.headers.get("X-GitHub-Delivery")
    data = await request.json()

    LOG.info(
        "Marketplace event",
        event_type=event_type,
        event_id=event_id,
        sender=data["sender"]["login"],
        gh_owner=data["marketplace_purchase"]["account"]["login"],
    )

    await cleanup_subscription(data)

    if config.WEBHOOK_MARKETPLACE_FORWARD_URL:
        raw = await request.body()
        await http_post(
            config.WEBHOOK_MARKETPLACE_FORWARD_URL,
            data=raw.decode(),
            headers={
                "X-GitHub-Event": event_type,
                "X-GitHub-Delivery": event_id,
                "X-Hub-Signature": request.headers.get("X-Hub-Signature"),
                "User-Agent": request.headers.get("User-Agent"),
                "Content-Type": request.headers.get("Content-Type"),
            },
        )

    return responses.Response("Event queued", status_code=202)
def test_database_status_without_exception():
    expected = 'UP'
    response = responses.Response()

    actual = healthcheck.database(response, MockSession())

    assert expected == actual['status']
    assert status.HTTP_200_OK == response.status_code
Exemple #19
0
async def subscription_cache_update(
    owner_id: github_types.GitHubAccountIdType,
    request: requests.Request,
    redis_cache: utils.RedisCache = fastapi.Depends(  # noqa: B008
        redis.get_redis_cache),
) -> responses.Response:
    sub = await request.json()
    if sub is None:
        return responses.Response("Empty content", status_code=400)
    try:
        await subscription.Subscription.update_subscription(
            redis_cache, int(owner_id), sub)
    except NotImplementedError:
        return responses.Response("updating subscription is disabled",
                                  status_code=400)

    return responses.Response("Cache updated", status_code=200)
def test_database_status_with_exception():
    expected = 'DOWN'
    response = responses.Response()

    actual = healthcheck.database(response, MockSession(True))

    assert expected == actual['status']
    assert status.HTTP_503_SERVICE_UNAVAILABLE == response.status_code
Exemple #21
0
async def event_testing_handler_post(request: requests.Request):  # pragma: no cover
    event_type = request.headers.get("X-GitHub-Event")
    event_id = request.headers.get("X-GitHub-Delivery")
    data = await request.json()
    await _AREDIS_CACHE.rpush(
        "events-testing",
        json.dumps({"id": event_id, "type": event_type, "payload": data}),
    )
    return responses.Response("Event queued", status_code=202)
Exemple #22
0
async def application_cache_update(
    api_access_key: str,
    request: requests.Request,
    redis_cache: utils.RedisCache = fastapi.Depends(  # noqa: B008
        redis.get_redis_cache),
) -> responses.Response:
    data = typing.cast(typing.Optional[application.ApplicationDashboardJSON],
                       await request.json())
    if data is None:
        return responses.Response("Empty content", status_code=400)

    try:
        await application.Application.update(redis_cache, api_access_key, data)
    except NotImplementedError:
        return responses.Response("Updating application is disabled",
                                  status_code=400)

    return responses.Response("Cache updated", status_code=200)
Exemple #23
0
async def index(
    setup_action: typing.Optional[str] = None,
) -> responses.Response:  # pragma: no cover
    if setup_action:
        return responses.Response(
            "Your Mergify installation succeeded.",
            status_code=200,
        )
    return responses.RedirectResponse(url="https://mergify.com")
Exemple #24
0
async def marketplace_testng_handler(request: requests.Request):  # pragma: no cover
    event_type = request.headers.get("X-GitHub-Event")
    event_id = request.headers.get("X-GitHub-Delivery")
    data = await request.json()
    LOG.debug(
        "received marketplace testing events",
        event_type=event_type,
        event_id=event_id,
        data=data,
    )
    return responses.Response("Event ignored", status_code=202)
Exemple #25
0
async def event_handler(
    request: requests.Request,
    redis_cache: utils.RedisCache = fastapi.Depends(  # noqa: B008
        redis.get_redis_cache
    ),
    redis_stream: utils.RedisStream = fastapi.Depends(  # noqa: B008
        redis.get_redis_stream
    ),
) -> responses.Response:
    event_type = request.headers.get("X-GitHub-Event")
    event_id = request.headers.get("X-GitHub-Delivery")
    data = await request.json()

    try:
        await github_events.filter_and_dispatch(
            redis_cache, redis_stream, event_type, event_id, data
        )
    except github_events.IgnoredEvent as ie:
        status_code = 200
        reason = f"Event ignored: {ie.reason}"
    else:
        status_code = 202
        reason = "Event queued"

    if (
        config.WEBHOOK_APP_FORWARD_URL
        and config.WEBHOOK_FORWARD_EVENT_TYPES is not None
        and event_type in config.WEBHOOK_FORWARD_EVENT_TYPES
    ):
        raw = await request.body()
        try:
            async with http.AsyncClient(timeout=EVENT_FORWARD_TIMEOUT) as client:
                await client.post(
                    config.WEBHOOK_APP_FORWARD_URL,
                    content=raw.decode(),
                    headers={
                        "X-GitHub-Event": event_type,
                        "X-GitHub-Delivery": event_id,
                        "X-Hub-Signature": request.headers.get("X-Hub-Signature"),
                        "User-Agent": request.headers.get("User-Agent"),
                        "Content-Type": request.headers.get("Content-Type"),
                    },
                )
        except httpx.TimeoutException:
            LOG.warning(
                "Fail to forward GitHub event",
                event_type=event_type,
                event_id=event_id,
                sender=data["sender"]["login"],
            )

    return responses.Response(reason, status_code=status_code)
async def refresh_repo(
        owner: github_types.GitHubLogin,
        repo_name: github_types.GitHubRepositoryName) -> responses.Response:
    global _AREDIS_STREAM, _AREDIS_CACHE
    async with github.aget_client(owner_name=owner) as client:
        try:
            repository = await client.item(f"/repos/{owner}/{repo_name}")
        except http.HTTPNotFound:
            return responses.JSONResponse(status_code=404,
                                          content="repository not found")

    await github_events.send_refresh(_AREDIS_CACHE, _AREDIS_STREAM, repository)
    return responses.Response("Refresh queued", status_code=202)
Exemple #27
0
async def _refresh(
    owner: github_types.GitHubLogin,
    repo: str,
    action: github_types.GitHubEventRefreshActionType = "user",
    ref: typing.Optional[github_types.GitHubRefType] = None,
    pull_request: typing.Optional[github_types.GitHubPullRequest] = None,
) -> responses.Response:
    data = github_types.GitHubEventRefresh({
        "action": action,
        "organization": {
            "login": owner,
            "id": github_types.GitHubAccountIdType(0),
            "type": "Organization",
        },
        "installation": {
            "id": 0,
            "account": {
                "login": owner,
                "id": github_types.GitHubAccountIdType(0),
                "type": "Organization",
            },
        },
        "repository": {
            "default_branch": github_types.GitHubRefType(""),
            "id": github_types.GitHubRepositoryIdType(0),
            "private": False,
            "archived": False,
            "url": "",
            "name": repo,
            "owner": {
                "login": owner,
                "id": github_types.GitHubAccountIdType(0),
                "type": "Organization",
            },
            "full_name": f"{owner}/{repo}",
        },
        "sender": {
            "login": github_types.GitHubLogin("<internal>"),
            "id": github_types.GitHubAccountIdType(0),
            "type": "User",
        },
        "ref": ref,
        "pull_request": pull_request,
    })

    await github_events.filter_and_dispatch(_AREDIS_STREAM, "refresh",
                                            str(uuid.uuid4()), data)

    return responses.Response("Refresh queued", status_code=202)
Exemple #28
0
async def marketplace_handler(
    request: requests.Request,
    redis_links: redis_utils.RedisLinks = fastapi.Depends(  # noqa: B008
        redis.get_redis_links),
) -> responses.Response:
    event_type = request.headers.get("X-GitHub-Event")
    event_id = request.headers.get("X-GitHub-Delivery")
    data = await request.json()

    LOG.info(
        "Marketplace event",
        event_type=event_type,
        event_id=event_id,
        sender=data["sender"]["login"],
        gh_owner=data["marketplace_purchase"]["account"]["login"],
    )

    await subscription.Subscription.delete_subscription(
        redis_links.cache, data["marketplace_purchase"]["account"]["id"])

    if config.WEBHOOK_MARKETPLACE_FORWARD_URL:
        raw = await request.body()
        try:
            async with http.AsyncClient(
                    timeout=EVENT_FORWARD_TIMEOUT) as client:
                await client.post(
                    config.WEBHOOK_MARKETPLACE_FORWARD_URL,
                    content=raw.decode(),
                    headers={
                        "X-GitHub-Event": event_type,
                        "X-GitHub-Delivery": event_id,
                        "X-Hub-Signature":
                        request.headers.get("X-Hub-Signature"),
                        "User-Agent": request.headers.get("User-Agent"),
                        "Content-Type": request.headers.get("Content-Type"),
                    },
                )
        except httpx.TimeoutException:
            LOG.warning(
                "Fail to forward Marketplace event",
                event_type=event_type,
                event_id=event_id,
                sender=data["sender"]["login"],
                gh_owner=data["marketplace_purchase"]["account"]["login"],
            )

    return responses.Response("Event queued", status_code=202)
Exemple #29
0
async def _refresh(owner, repo, action="user", **extra_data):
    event_type = "refresh"
    data = {
        "action": action,
        "repository": {
            "name": repo,
            "owner": {"login": owner},
            "full_name": f"{owner}/{repo}",
        },
        "sender": {"login": "******"},
    }
    data.update(extra_data)

    await github_events.job_filter_and_dispatch(
        app.aredis_stream, event_type, str(uuid.uuid4()), data
    )

    return responses.Response("Refresh queued", status_code=202)
async def refresh_pull(
    owner: github_types.GitHubLogin,
    repo_name: github_types.GitHubRepositoryName,
    pull_request_number: github_types.GitHubPullRequestNumber,
    action: github_types.GitHubEventRefreshActionType = "user",
) -> responses.Response:
    action = RefreshActionSchema(action)
    async with github.aget_client(owner_name=owner) as client:
        try:
            repository = await client.item(f"/repos/{owner}/{repo_name}")
        except http.HTTPNotFound:
            return responses.JSONResponse(status_code=404,
                                          content="repository not found")

    global _AREDIS_STREAM, _AREDIS_CACHE
    await github_events.send_refresh(
        _AREDIS_CACHE,
        _AREDIS_STREAM,
        repository,
        pull_request_number=pull_request_number,
        action=action,
    )
    return responses.Response("Refresh queued", status_code=202)