Commit 41f143f7 authored by epriestley's avatar epriestley
Browse files

Respect repository identities when figuring out authors/committers in Herald pre-commit hook rules

Summary:
Ref T13480. Currently, Herald commit hook rules use a raw address resolution query to identify the author and committer for a commit. This will get the wrong answer when the raw identity string has been explicitly bound to some non-default user (most often, it will fail to identify an author when one exists).

Instead, use the "IdentityEngine" to properly resolve identities.

Test Plan: Authored a commit as `X <y@example.com>`, a raw identity with no "natural" matches to users (e.g., no user with that email or username). Bound the identity to a particular user in Diffusion. Wrote a Herald pre-commit content rule, pushed the commit. Saw Herald recognize the correct user when evaluating rules.

Maniphest Tasks: T13480

Differential Revision: https://secure.phabricator.com/D20953
parent a0a346be
......@@ -8,6 +8,7 @@ final class HeraldPreCommitContentAdapter extends HeraldPreCommitAdapter {
private $revision = false;
private $affectedPackages;
private $identityCache = array();
public function getAdapterContentName() {
return pht('Commit Hook: Commit Content');
......@@ -166,10 +167,39 @@ final class HeraldPreCommitContentAdapter extends HeraldPreCommitAdapter {
}
}
private function lookupUser($author) {
return id(new DiffusionResolveUserQuery())
->withName($author)
->execute();
private function lookupUser($raw_identity) {
// See T13480. After the move to repository identities, we want to look
// users up in the identity table. If you push a commit which is authored
// by "A Duck <duck@example.org>" and that identity is bound to user
// "@mallard" in the identity table, Herald should see the author of the
// commit as "@mallard" when evaluating pre-commit content rules.
if (!array_key_exists($raw_identity, $this->identityCache)) {
$repository = $this->getHookEngine()->getRepository();
$viewer = $this->getHookEngine()->getViewer();
$identity_engine = id(new DiffusionRepositoryIdentityEngine())
->setViewer($viewer);
// We must provide a "sourcePHID" when resolving identities, but don't
// have a legitimate one yet. Just use the repository PHID as a
// reasonable value. This won't actually be written to storage.
$source_phid = $repository->getPHID();
$identity_engine->setSourcePHID($source_phid);
// If the identity doesn't exist yet, we don't want to create it if
// we haven't seen it before. It will be created later when we actually
// import the commit.
$identity_engine->setDryRun(true);
$author_identity = $identity_engine->newResolvedIdentity($raw_identity);
$effective_phid = $author_identity->getCurrentEffectiveUserPHID();
$this->identityCache[$raw_identity] = $effective_phid;
}
return $this->identityCache[$raw_identity];
}
private function getCommitFields() {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment