Ejemplo n.º 1
0
def check_approval_state(
    phab: PhabricatorClient, revision_id: int, target_repository_name: str
) -> dict:
    """Helper to load the Phabricator revision and check its approval requirement state

    * if the revision's target repository is the same as its current
      repository, it's an approval
    * otherwise it's an uplift request
    """

    # Load target repo from Phabricator
    target_repo = phab.call_conduit(
        "diffusion.repository.search",
        constraints={"shortNames": [target_repository_name]},
    )
    target_repo = phab.single(target_repo, "data")
    target_repo_phid = phab.expect(target_repo, "phid")

    # Load base revision details from Phabricator
    revision = phab.call_conduit(
        "differential.revision.search", constraints={"ids": [revision_id]}
    )
    revision = phab.single(revision, "data")
    revision_repo_phid = phab.expect(revision, "fields", "repositoryPHID")

    # Lookup if this is an uplift or an approval request
    is_approval = target_repo_phid == revision_repo_phid
    return (is_approval, revision, target_repo)
Ejemplo n.º 2
0
def test_find_txn_with_comment_in_phabricator(phabdouble):
    phab = phabdouble.get_phabricator_client()
    # A sec-approval request adds a comment to a revision.
    mock_comment = phabdouble.comment("my sec-approval request")
    revision = phabdouble.revision()

    # Add the two sec-approval request transactions to Phabricator. This also links the
    # comment transaction to the revision.
    comment_txn = phabdouble.api_object_for(
        phabdouble.transaction("comment", revision, comments=[mock_comment])
    )
    review_txn = phabdouble.api_object_for(
        phabdouble.transaction("reviewers.add", revision)
    )

    # Fetch our comment transaction
    comment = PhabricatorClient.single(comment_txn, "comments")

    # Add the sec-approval request transactions to the database.
    revision = phabdouble.api_object_for(revision)
    sec_approval_request = SecApprovalRequest.build(revision, [comment_txn, review_txn])

    # Search the list of sec-approval transactions for the comment.
    matching_comment = search_sec_approval_request_for_comment(
        phab, sec_approval_request
    )

    assert matching_comment == comment
def test_integrated_secure_stack_has_alternate_commit_message(
    db,
    client,
    phabdouble,
    mock_repo_config,
    secure_project,
    authed_headers,
    monkeypatch,
):
    sanitized_title = "my secure commit title"
    revision_title = "my insecure revision title"

    # Build a revision with an active sec-approval request.
    diff, secure_revision = _make_sec_approval_request(
        sanitized_title,
        revision_title,
        authed_headers,
        client,
        monkeypatch,
        phabdouble,
        secure_project,
    )

    # Request the revision from Lando. It should have our new title and summary.
    response = client.get("/stacks/D{}".format(secure_revision["id"]))
    assert response == 200

    revision = PhabricatorClient.single(response.json, "revisions")
    assert revision["is_secure"]
    assert revision["is_using_secure_commit_message"]
    assert revision["title"] == sanitized_title
    assert revision["summary"] == ""
Ejemplo n.º 4
0
def _get_comment(phabdouble, msg):
    """Retrieve the Phabricator API representation of a raw comment string."""
    revision = phabdouble.revision()
    mock_comment = phabdouble.comment(msg)
    phabdouble.transaction("dummy", revision, comments=[mock_comment])
    transaction = phabdouble.api_object_for(
        phabdouble.transaction("dummy", revision, comments=[mock_comment])
    )
    comment = PhabricatorClient.single(transaction, "comments")
    return comment
def test_integrated_secure_stack_without_sec_approval_does_not_use_secure_message(
        db, client, phabdouble, mock_repo_config, secure_project):
    # Build a plain old secure message, no sec-approval requests made.
    secure_revision = phabdouble.revision(repo=phabdouble.repo(),
                                          projects=[secure_project])

    response = client.get("/stacks/D{}".format(secure_revision["id"]))
    assert response == 200

    revision = PhabricatorClient.single(response.json, "revisions")
    assert revision["is_secure"]
    assert not revision["is_using_secure_commit_message"]
Ejemplo n.º 6
0
def get_release_managers(phab: PhabricatorClient) -> dict:
    """Load the release-managers group details from Phabricator"""
    groups = phab.call_conduit(
        "project.search", constraints={"slugs": ["release-managers"]}
    )
    return phab.single(groups, "data")
def test_integrated_secure_stack_has_alternate_commit_message(
    db,
    client,
    phabdouble,
    mock_repo_config,
    secure_project,
    authed_headers,
    monkeypatch,
):
    # Build a specially formatted sec-approval request comment.
    sanitized_title = "my secure commit title"
    sec_approval_comment = SECURE_COMMENT_TEMPLATE.format(
        message=sanitized_title)
    mock_comment = phabdouble.comment(sec_approval_comment)

    # Build a secure revision.
    secure_revision = phabdouble.revision(
        repo=phabdouble.repo(),
        projects=[secure_project],
        title="my insecure revision title",
    )

    # Add the two sec-approval request transactions to Phabricator. This also links
    # the sec-approval request comment to the secure revision.
    comment_txn = phabdouble.api_object_for(
        phabdouble.transaction("comment",
                               secure_revision,
                               comments=[mock_comment]))
    review_txn = phabdouble.api_object_for(
        phabdouble.transaction("reviewers.add", secure_revision))

    # PhabricatorDouble does not return valid transaction data after editing a
    # revision to ask for sec-approval. Instead of using the PhabricatorDouble fake
    # API call to get the transactions we want we'll use a traditional mock to get
    # them.
    def fake_send_message_for_review(revision_phid, message, phabclient):
        # Respond with the two transactions that should be generated by a successful
        # sec-approval request.
        return [comment_txn, review_txn]

    monkeypatch.setattr(
        "landoapi.api.revisions.send_sanitized_commit_message_for_review",
        fake_send_message_for_review,
    )

    # Post the sec-approval request so that it gets saved into the database.
    response = client.post(
        "/requestSecApproval",
        json={
            "revision_id": f"D{secure_revision['id']}",
            "sanitized_message": sanitized_title,
        },
        headers=authed_headers,
    )
    assert response == 200

    # Request the revision from Lando. It should have our new title and summary.
    response = client.get("/stacks/D{}".format(secure_revision["id"]))
    assert response == 200

    revision = PhabricatorClient.single(response.json, "revisions")
    assert revision["is_secure"]
    assert revision["is_using_secure_commit_message"]
    assert revision["title"] == sanitized_title
    assert revision["summary"] == ""