mirror of
https://we.phorge.it/source/phorge.git
synced 2025-01-09 14:21:02 +01:00
Legalpad - add a view signatures page
Summary: ...needs to add a LegalpadDocumentSignatureQuery class to get this done, which is also re-deployed everywhere we were issuing raw queries. Ref T3116. Test Plan: viewed some signatures. Verified color and footer icons showed up how I wanted them to. Reviewers: epriestley Reviewed By: epriestley CC: Korvin, epriestley, aran Maniphest Tasks: T3116 Differential Revision: https://secure.phabricator.com/D7986
This commit is contained in:
parent
117519f396
commit
4e6390774f
9 changed files with 295 additions and 30 deletions
|
@ -842,6 +842,8 @@ phutil_register_library_map(array(
|
|||
'LegalpadDocumentSearchEngine' => 'applications/legalpad/query/LegalpadDocumentSearchEngine.php',
|
||||
'LegalpadDocumentSignController' => 'applications/legalpad/controller/LegalpadDocumentSignController.php',
|
||||
'LegalpadDocumentSignature' => 'applications/legalpad/storage/LegalpadDocumentSignature.php',
|
||||
'LegalpadDocumentSignatureListController' => 'applications/legalpad/controller/LegalpadDocumentSignatureListController.php',
|
||||
'LegalpadDocumentSignatureQuery' => 'applications/legalpad/query/LegalpadDocumentSignatureQuery.php',
|
||||
'LegalpadDocumentSignatureVerificationController' => 'applications/legalpad/controller/LegalpadDocumentSignatureVerificationController.php',
|
||||
'LegalpadDocumentViewController' => 'applications/legalpad/controller/LegalpadDocumentViewController.php',
|
||||
'LegalpadMockMailReceiver' => 'applications/legalpad/mail/LegalpadMockMailReceiver.php',
|
||||
|
@ -3374,7 +3376,13 @@ phutil_register_library_map(array(
|
|||
'LegalpadDocumentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'LegalpadDocumentSearchEngine' => 'PhabricatorApplicationSearchEngine',
|
||||
'LegalpadDocumentSignController' => 'LegalpadController',
|
||||
'LegalpadDocumentSignature' => 'LegalpadDAO',
|
||||
'LegalpadDocumentSignature' =>
|
||||
array(
|
||||
0 => 'LegalpadDAO',
|
||||
1 => 'PhabricatorPolicyInterface',
|
||||
),
|
||||
'LegalpadDocumentSignatureListController' => 'LegalpadController',
|
||||
'LegalpadDocumentSignatureQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'LegalpadDocumentSignatureVerificationController' => 'LegalpadController',
|
||||
'LegalpadDocumentViewController' => 'LegalpadController',
|
||||
'LegalpadMockMailReceiver' => 'PhabricatorObjectMailReceiver',
|
||||
|
|
|
@ -49,7 +49,8 @@ final class PhabricatorApplicationLegalpad extends PhabricatorApplication {
|
|||
'comment/(?P<id>\d+)/' => 'LegalpadDocumentCommentController',
|
||||
'view/(?P<id>\d+)/' => 'LegalpadDocumentViewController',
|
||||
'verify/(?P<code>[^/]+)/' =>
|
||||
'LegalpadDocumentSignatureVerificationController',
|
||||
'LegalpadDocumentSignatureVerificationController',
|
||||
'signatures/(?P<id>\d+)/' => 'LegalpadDocumentSignatureListController',
|
||||
'document/' => array(
|
||||
'preview/' => 'PhabricatorMarkupPreviewController'),
|
||||
));
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @group legalpad
|
||||
*/
|
||||
final class LegalpadDocumentSignController extends LegalpadController {
|
||||
|
||||
private $id;
|
||||
|
@ -56,12 +53,12 @@ final class LegalpadDocumentSignController extends LegalpadController {
|
|||
}
|
||||
|
||||
if ($signer_phid) {
|
||||
$signature = id(new LegalpadDocumentSignature())
|
||||
->loadOneWhere(
|
||||
'documentPHID = %s AND signerPHID = %s AND documentVersion = %d',
|
||||
$document->getPHID(),
|
||||
$signer_phid,
|
||||
$document->getVersions());
|
||||
$signature = id(new LegalpadDocumentSignatureQuery())
|
||||
->setViewer($user)
|
||||
->withDocumentPHIDs(array($document->getPHID()))
|
||||
->withSignerPHIDs(array($signer_phid))
|
||||
->withDocumentVersions(array($document->getVersions()))
|
||||
->executeOne();
|
||||
}
|
||||
|
||||
if (!$signature) {
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
final class LegalpadDocumentSignatureListController extends LegalpadController {
|
||||
|
||||
private $documentId;
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->documentId = $data['id'];
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
$document = id(new LegalpadDocumentQuery())
|
||||
->setViewer($user)
|
||||
->withIDs(array($this->documentId))
|
||||
->executeOne();
|
||||
|
||||
if (!$document) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$title = pht('Signatures for %s', $document->getMonogram());
|
||||
|
||||
$pager = id(new AphrontCursorPagerView())
|
||||
->readFromRequest($request);
|
||||
$signatures = id(new LegalpadDocumentSignatureQuery())
|
||||
->setViewer($user)
|
||||
->withDocumentPHIDs(array($document->getPHID()))
|
||||
->executeWithCursorPager($pager);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs($this->buildSideNav());
|
||||
$crumbs->addTextCrumb(
|
||||
$document->getMonogram(),
|
||||
$this->getApplicationURI('view/'.$document->getID()));
|
||||
|
||||
$crumbs->addTextCrumb(
|
||||
pht('Signatures'));
|
||||
$list = $this->renderResultsList($document, $signatures);
|
||||
$list->setPager($pager);
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
array(
|
||||
$crumbs,
|
||||
$list,
|
||||
),
|
||||
array(
|
||||
'title' => $title,
|
||||
'device' => true,
|
||||
));
|
||||
}
|
||||
|
||||
private function renderResultsList(
|
||||
LegalpadDocument $document,
|
||||
array $signatures) {
|
||||
assert_instances_of($signatures, 'LegalpadDocumentSignature');
|
||||
|
||||
$user = $this->getRequest()->getUser();
|
||||
|
||||
$list = new PHUIObjectItemListView();
|
||||
$list->setUser($user);
|
||||
|
||||
foreach ($signatures as $signature) {
|
||||
$created = phabricator_date($signature->getDateCreated(), $user);
|
||||
|
||||
$data = $signature->getSignatureData();
|
||||
|
||||
$sig_data = phutil_tag(
|
||||
'div',
|
||||
array(),
|
||||
array(
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(),
|
||||
phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => 'mailto:'.$data['email'],
|
||||
),
|
||||
$data['email'])),
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(),
|
||||
$data['address_1']),
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(),
|
||||
$data['address_2']),
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(),
|
||||
$data['phone'])
|
||||
));
|
||||
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setObject($signature)
|
||||
->setHeader($data['name'])
|
||||
->setSubhead($sig_data)
|
||||
->addIcon('none', pht('Signed %s', $created));
|
||||
|
||||
$good_sig = true;
|
||||
if (!$signature->isVerified()) {
|
||||
$item->addFootIcon('disable', 'Unverified Email');
|
||||
$good_sig = false;
|
||||
}
|
||||
if ($signature->getDocumentVersion() != $document->getVersions()) {
|
||||
$item->addFootIcon('delete', 'Stale Signature');
|
||||
$good_sig = false;
|
||||
}
|
||||
|
||||
if ($good_sig) {
|
||||
$item->setBarColor('green');
|
||||
}
|
||||
|
||||
$list->addItem($item);
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
}
|
|
@ -21,8 +21,18 @@ extends LegalpadController {
|
|||
$request = $this->getRequest();
|
||||
$user = $request->getUser();
|
||||
|
||||
$signature = id(new LegalpadDocumentSignature())
|
||||
->loadOneWhere('secretKey = %s', $this->code);
|
||||
// this page can be accessed by not logged in users to valid their
|
||||
// signatures. use the omnipotent user for these cases.
|
||||
if (!$user->isLoggedIn()) {
|
||||
$viewer = PhabricatorUser::getOmnipotentUser();
|
||||
} else {
|
||||
$viewer = $user;
|
||||
}
|
||||
|
||||
$signature = id(new LegalpadDocumentSignatureQuery())
|
||||
->setViewer($viewer)
|
||||
->withSecretKeys(array($this->code))
|
||||
->executeOne();
|
||||
|
||||
if (!$signature) {
|
||||
$title = pht('Unable to Verify Signature');
|
||||
|
|
|
@ -132,11 +132,13 @@ final class LegalpadDocumentViewController extends LegalpadController {
|
|||
$document,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$doc_id = $document->getID();
|
||||
|
||||
$actions->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('edit')
|
||||
->setName(pht('Edit Document'))
|
||||
->setHref($this->getApplicationURI('/edit/'.$document->getID().'/'))
|
||||
->setHref($this->getApplicationURI('/edit/'.$doc_id.'/'))
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
|
@ -146,6 +148,12 @@ final class LegalpadDocumentViewController extends LegalpadController {
|
|||
->setName(pht('Sign Document'))
|
||||
->setHref('/'.$document->getMonogram()));
|
||||
|
||||
$actions->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('transcript')
|
||||
->setName(pht('View Signatures'))
|
||||
->setHref($this->getApplicationURI('/signatures/'.$doc_id.'/')));
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @group legalpad
|
||||
*/
|
||||
final class LegalpadDocumentQuery
|
||||
extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||
|
||||
|
@ -89,11 +86,11 @@ final class LegalpadDocumentQuery
|
|||
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 = id(new LegalpadDocumentSignatureQuery())
|
||||
->setViewer($this->getViewer())
|
||||
->withDocumentPHIDs(array_keys($document_map))
|
||||
->wtihSignerPHIDs($this->signerPHIDs)
|
||||
->execute();
|
||||
$signatures = mgroup($signatures, 'getDocumentPHID');
|
||||
foreach ($document_map as $document_phid => $document) {
|
||||
$sigs = idx($signatures, $document_phid, array());
|
||||
|
@ -222,10 +219,10 @@ final class LegalpadDocumentQuery
|
|||
private function loadSignatures(array $documents) {
|
||||
$document_map = mpull($documents, null, 'getPHID');
|
||||
|
||||
$signatures = id(new LegalpadDocumentSignature())
|
||||
->loadAllWhere(
|
||||
'documentPHID IN (%Ls)',
|
||||
array_keys($document_map));
|
||||
$signatures = id(new LegalpadDocumentSignatureQuery())
|
||||
->setViewer($this->getViewer())
|
||||
->withDocumentPHIDs(array_keys($document_map))
|
||||
->execute();
|
||||
$signatures = mgroup($signatures, 'getDocumentPHID');
|
||||
|
||||
foreach ($documents as $document) {
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
<?php
|
||||
|
||||
final class LegalpadDocumentSignatureQuery
|
||||
extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||
|
||||
private $ids;
|
||||
private $documentPHIDs;
|
||||
private $signerPHIDs;
|
||||
private $documentVersions;
|
||||
private $secretKeys;
|
||||
|
||||
public function withIDs(array $ids) {
|
||||
$this->ids = $ids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withDocumentPHIDs(array $phids) {
|
||||
$this->documentPHIDs = $phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withSignerPHIDs(array $phids) {
|
||||
$this->signerPHIDs = $phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withDocumentVersions(array $versions) {
|
||||
$this->documentVersions = $versions;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withSecretKeys(array $keys) {
|
||||
$this->secretKeys = $keys;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function loadPage() {
|
||||
$table = new LegalpadDocumentSignature();
|
||||
$conn_r = $table->establishConnection('r');
|
||||
|
||||
$data = queryfx_all(
|
||||
$conn_r,
|
||||
'SELECT * FROM %T %Q %Q %Q',
|
||||
$table->getTableName(),
|
||||
$this->buildWhereClause($conn_r),
|
||||
$this->buildOrderClause($conn_r),
|
||||
$this->buildLimitClause($conn_r));
|
||||
|
||||
$documents = $table->loadAllFromArray($data);
|
||||
|
||||
return $documents;
|
||||
}
|
||||
|
||||
protected function buildWhereClause($conn_r) {
|
||||
$where = array();
|
||||
|
||||
$where[] = $this->buildPagingClause($conn_r);
|
||||
|
||||
if ($this->ids) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
'id IN (%Ld)',
|
||||
$this->ids);
|
||||
}
|
||||
|
||||
if ($this->documentPHIDs) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
'documentPHID IN (%Ls)',
|
||||
$this->documentPHIDs);
|
||||
}
|
||||
|
||||
if ($this->signerPHIDs) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
'signerPHID IN (%Ls)',
|
||||
$this->signerPHIDs);
|
||||
}
|
||||
|
||||
if ($this->documentVersions) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
'documentVersion IN (%Ld)',
|
||||
$this->documentVersions);
|
||||
}
|
||||
|
||||
if ($this->secretKeys) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
'secretKey IN (%Ls)',
|
||||
$this->secretKeys);
|
||||
}
|
||||
|
||||
return $this->formatWhereClause($where);
|
||||
}
|
||||
|
||||
public function getQueryApplicationClass() {
|
||||
return 'PhabricatorApplicationLegalpad';
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +1,8 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @group legalpad
|
||||
*/
|
||||
final class LegalpadDocumentSignature extends LegalpadDAO {
|
||||
final class LegalpadDocumentSignature
|
||||
extends LegalpadDAO
|
||||
implements PhabricatorPolicyInterface {
|
||||
|
||||
const VERIFIED = 0;
|
||||
const UNVERIFIED = 1;
|
||||
|
@ -33,5 +32,27 @@ final class LegalpadDocumentSignature extends LegalpadDAO {
|
|||
public function isVerified() {
|
||||
return $this->getVerified() != self::UNVERIFIED;
|
||||
}
|
||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||
|
||||
public function getCapabilities() {
|
||||
return array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
);
|
||||
}
|
||||
|
||||
public function getPolicy($capability) {
|
||||
switch ($capability) {
|
||||
case PhabricatorPolicyCapability::CAN_VIEW:
|
||||
return PhabricatorPolicies::POLICY_USER;
|
||||
}
|
||||
}
|
||||
|
||||
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue