1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-29 08:50:58 +01:00

Legalpad - add policy rule for legalpad document signatures

Summary:
Ref T3116. This creates a policy rule where you can require a signature on a given legalpad document.

NOTE: signatures must be for the *latest* document version.

Test Plan: made a task have a custom policy requiring a legalpad signature. verified non-signers were locked out.

Reviewers: epriestley

Reviewed By: epriestley

CC: Korvin, epriestley, aran

Maniphest Tasks: T3116

Differential Revision: https://secure.phabricator.com/D7977
This commit is contained in:
Bob Trahan 2014-01-15 16:48:44 -08:00
parent acb141cf52
commit d740374cca
6 changed files with 122 additions and 3 deletions

View file

@ -0,0 +1,5 @@
ALTER TABLE {$NAMESPACE}_legalpad.legalpad_documentsignature
DROP KEY `key_document`;
ALTER TABLE {$NAMESPACE}_legalpad.legalpad_documentsignature
ADD KEY `key_document` (`documentPHID`,`signerPHID`, `documentVersion`);

View file

@ -1764,6 +1764,7 @@ phutil_register_library_map(array(
'PhabricatorPolicyQuery' => 'applications/policy/query/PhabricatorPolicyQuery.php', 'PhabricatorPolicyQuery' => 'applications/policy/query/PhabricatorPolicyQuery.php',
'PhabricatorPolicyRule' => 'applications/policy/rule/PhabricatorPolicyRule.php', 'PhabricatorPolicyRule' => 'applications/policy/rule/PhabricatorPolicyRule.php',
'PhabricatorPolicyRuleAdministrators' => 'applications/policy/rule/PhabricatorPolicyRuleAdministrators.php', 'PhabricatorPolicyRuleAdministrators' => 'applications/policy/rule/PhabricatorPolicyRuleAdministrators.php',
'PhabricatorPolicyRuleLegalpadSignature' => 'applications/policy/rule/PhabricatorPolicyRuleLegalpadSignature.php',
'PhabricatorPolicyRuleLunarPhase' => 'applications/policy/rule/PhabricatorPolicyRuleLunarPhase.php', 'PhabricatorPolicyRuleLunarPhase' => 'applications/policy/rule/PhabricatorPolicyRuleLunarPhase.php',
'PhabricatorPolicyRuleProjects' => 'applications/policy/rule/PhabricatorPolicyRuleProjects.php', 'PhabricatorPolicyRuleProjects' => 'applications/policy/rule/PhabricatorPolicyRuleProjects.php',
'PhabricatorPolicyRuleUsers' => 'applications/policy/rule/PhabricatorPolicyRuleUsers.php', 'PhabricatorPolicyRuleUsers' => 'applications/policy/rule/PhabricatorPolicyRuleUsers.php',
@ -4395,6 +4396,7 @@ phutil_register_library_map(array(
'PhabricatorPolicyPHIDTypePolicy' => 'PhabricatorPHIDType', 'PhabricatorPolicyPHIDTypePolicy' => 'PhabricatorPHIDType',
'PhabricatorPolicyQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorPolicyQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorPolicyRuleAdministrators' => 'PhabricatorPolicyRule', 'PhabricatorPolicyRuleAdministrators' => 'PhabricatorPolicyRule',
'PhabricatorPolicyRuleLegalpadSignature' => 'PhabricatorPolicyRule',
'PhabricatorPolicyRuleLunarPhase' => 'PhabricatorPolicyRule', 'PhabricatorPolicyRuleLunarPhase' => 'PhabricatorPolicyRule',
'PhabricatorPolicyRuleProjects' => 'PhabricatorPolicyRule', 'PhabricatorPolicyRuleProjects' => 'PhabricatorPolicyRule',
'PhabricatorPolicyRuleUsers' => 'PhabricatorPolicyRule', 'PhabricatorPolicyRuleUsers' => 'PhabricatorPolicyRule',

View file

@ -58,10 +58,10 @@ final class LegalpadDocumentSignController extends LegalpadController {
if ($signer_phid) { if ($signer_phid) {
$signature = id(new LegalpadDocumentSignature()) $signature = id(new LegalpadDocumentSignature())
->loadOneWhere( ->loadOneWhere(
'documentPHID = %s AND documentVersion = %d AND signerPHID = %s', 'documentPHID = %s AND signerPHID = %s AND documentVersion = %d',
$document->getPHID(), $document->getPHID(),
$document->getVersions(), $signer_phid,
$signer_phid); $document->getVersions());
} }
if (!$signature) { if (!$signature) {

View file

@ -10,6 +10,7 @@ final class LegalpadDocumentQuery
private $phids; private $phids;
private $creatorPHIDs; private $creatorPHIDs;
private $contributorPHIDs; private $contributorPHIDs;
private $signerPHIDs;
private $dateCreatedAfter; private $dateCreatedAfter;
private $dateCreatedBefore; private $dateCreatedBefore;
@ -36,6 +37,11 @@ final class LegalpadDocumentQuery
return $this; return $this;
} }
public function withSignerPHIDs(array $phids) {
$this->signerPHIDs = $phids;
return $this;
}
public function needDocumentBodies($need_bodies) { public function needDocumentBodies($need_bodies) {
$this->needDocumentBodies = $need_bodies; $this->needDocumentBodies = $need_bodies;
return $this; return $this;
@ -75,6 +81,27 @@ final class LegalpadDocumentQuery
} }
protected function willFilterPage(array $documents) { protected function willFilterPage(array $documents) {
if ($this->signerPHIDs) {
$document_map = mpull($documents, null, 'getPHID');
$signatures = id(new LegalpadDocumentSignature())
->loadAllWhere(
'documentPHID IN (%Ls) AND signerPHID IN (%Ls)',
array_keys($document_map),
$this->signerPHIDs);
$signatures = mgroup($signatures, 'getDocumentPHID');
foreach ($document_map as $document_phid => $document) {
$sigs = idx($signatures, $document_phid, array());
foreach ($sigs as $index => $sig) {
if ($sig->getDocumentVersion() != $document->getVersions()) {
unset($sigs[$index]);
}
}
$signer_phids = mpull($sigs, 'getSignerPHID');
if (array_diff($this->signerPHIDs, $signer_phids)) {
unset($documents[$document->getID()]);
}
}
}
if ($this->needDocumentBodies) { if ($this->needDocumentBodies) {
$documents = $this->loadDocumentBodies($documents); $documents = $this->loadDocumentBodies($documents);
} }

View file

@ -0,0 +1,69 @@
<?php
final class PhabricatorPolicyRuleLegalpadSignature
extends PhabricatorPolicyRule {
private $signatures = array();
public function getRuleDescription() {
return pht('signers of legalpad documents');
}
public function willApplyRules(PhabricatorUser $viewer, array $values) {
$values = array_unique(array_filter(array_mergev($values)));
if (!$values) {
return;
}
$documents = id(new LegalpadDocumentQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withPHIDs($values)
->withSignerPHIDs(array($viewer->getPHID()))
->execute();
$this->signatures = mpull($documents, 'getPHID', 'getPHID');
}
public function applyRule(PhabricatorUser $viewer, $value) {
foreach ($value as $document_phid) {
if (!isset($this->signatures[$document_phid])) {
return false;
}
}
return true;
}
public function getValueControlType() {
return self::CONTROL_TYPE_TOKENIZER;
}
public function getValueControlTemplate() {
return array(
'markup' => new AphrontTokenizerTemplateView(),
'uri' => '/typeahead/common/legalpaddocuments/',
'placeholder' => pht('Type a document title...'),
);
}
public function getRuleOrder() {
return 900;
}
public function getValueForStorage($value) {
PhutilTypeSpec::newFromString('list<string>')->check($value);
return array_values($value);
}
public function getValueForDisplay(PhabricatorUser $viewer, $value) {
$handles = id(new PhabricatorHandleQuery())
->setViewer($viewer)
->withPHIDs($value)
->execute();
return mpull($handles, 'getFullName', 'getPHID');
}
public function ruleHasEffect($value) {
return (bool)$value;
}
}

View file

@ -37,6 +37,7 @@ final class PhabricatorTypeaheadCommonDatasourceController
$need_jump_objects = false; $need_jump_objects = false;
$need_build_plans = false; $need_build_plans = false;
$need_macros = false; $need_macros = false;
$need_legalpad_documents = false;
switch ($this->type) { switch ($this->type) {
case 'mainsearch': case 'mainsearch':
$need_users = true; $need_users = true;
@ -101,6 +102,9 @@ final class PhabricatorTypeaheadCommonDatasourceController
case 'macros': case 'macros':
$need_macros = true; $need_macros = true;
break; break;
case 'legalpaddocuments':
$need_legalpad_documents = true;
break;
} }
$results = array(); $results = array();
@ -252,6 +256,18 @@ final class PhabricatorTypeaheadCommonDatasourceController
} }
} }
if ($need_legalpad_documents) {
$documents = id(new LegalpadDocumentQuery())
->setViewer($viewer)
->execute();
$documents = mpull($documents, 'getTitle', 'getPHID');
foreach ($documents as $phid => $title) {
$results[] = id(new PhabricatorTypeaheadResult())
->setPHID($phid)
->setName($title);
}
}
if ($need_projs) { if ($need_projs) {
$projs = id(new PhabricatorProjectQuery()) $projs = id(new PhabricatorProjectQuery())
->setViewer($viewer) ->setViewer($viewer)