Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14037217
D11759.id28355.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
20 KB
Referenced Files
None
Subscribers
None
D11759.id28355.diff
View Options
diff --git a/resources/sql/autopatches/20150212.legalpad.session.1.sql b/resources/sql/autopatches/20150212.legalpad.session.1.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20150212.legalpad.session.1.sql
@@ -0,0 +1,5 @@
+ALTER TABLE {$NAMESPACE}_user.phabricator_session
+ ADD signedLegalpadDocuments BOOL NOT NULL DEFAULT 0;
+
+ALTER TABLE {$NAMESPACE}_legalpad.legalpad_document
+ ADD requireSignature BOOL NOT NULL DEFAULT 0;
diff --git a/resources/sql/autopatches/20150212.legalpad.session.2.sql b/resources/sql/autopatches/20150212.legalpad.session.2.sql
new file mode 100644
--- /dev/null
+++ b/resources/sql/autopatches/20150212.legalpad.session.2.sql
@@ -0,0 +1,2 @@
+ALTER TABLE {$NAMESPACE}_legalpad.legalpad_document
+ ADD KEY `key_required` (requireSignature, dateModified);
diff --git a/src/applications/auth/controller/PhabricatorAuthFinishController.php b/src/applications/auth/controller/PhabricatorAuthFinishController.php
--- a/src/applications/auth/controller/PhabricatorAuthFinishController.php
+++ b/src/applications/auth/controller/PhabricatorAuthFinishController.php
@@ -11,6 +11,10 @@
return true;
}
+ public function shouldAllowLegallyNonCompliantUsers() {
+ return true;
+ }
+
public function processRequest() {
$request = $this->getRequest();
$viewer = $request->getUser();
diff --git a/src/applications/auth/controller/PhabricatorAuthValidateController.php b/src/applications/auth/controller/PhabricatorAuthValidateController.php
--- a/src/applications/auth/controller/PhabricatorAuthValidateController.php
+++ b/src/applications/auth/controller/PhabricatorAuthValidateController.php
@@ -11,6 +11,10 @@
return true;
}
+ public function shouldAllowLegallyNonCompliantUsers() {
+ return true;
+ }
+
public function processRequest() {
$request = $this->getRequest();
$viewer = $request->getUser();
diff --git a/src/applications/auth/controller/PhabricatorLogoutController.php b/src/applications/auth/controller/PhabricatorLogoutController.php
--- a/src/applications/auth/controller/PhabricatorLogoutController.php
+++ b/src/applications/auth/controller/PhabricatorLogoutController.php
@@ -21,6 +21,10 @@
return true;
}
+ public function shouldAllowLegallyNonCompliantUsers() {
+ return true;
+ }
+
public function handleRequest(AphrontRequest $request) {
$request = $this->getRequest();
$user = $request->getUser();
diff --git a/src/applications/auth/engine/PhabricatorAuthSessionEngine.php b/src/applications/auth/engine/PhabricatorAuthSessionEngine.php
--- a/src/applications/auth/engine/PhabricatorAuthSessionEngine.php
+++ b/src/applications/auth/engine/PhabricatorAuthSessionEngine.php
@@ -134,6 +134,7 @@
s.sessionStart AS s_sessionStart,
s.highSecurityUntil AS s_highSecurityUntil,
s.isPartial AS s_isPartial,
+ s.signedLegalpadDocuments as s_signedLegalpadDocuments,
u.*
FROM %T u JOIN %T s ON u.phid = s.userPHID
AND s.type = %s AND s.sessionKey = %s',
@@ -232,6 +233,7 @@
->setSessionStart(time())
->setSessionExpires(time() + $session_ttl)
->setIsPartial($partial ? 1 : 0)
+ ->setSignedLegalpadDocuments(0)
->save();
$log = PhabricatorUserLog::initializeNewLog(
@@ -553,6 +555,52 @@
}
+/* -( Legalpad Documents )-------------------------------------------------- */
+
+
+ /**
+ * Upgrade a session to have all legalpad documents signed.
+ *
+ * @param PhabricatorUser User whose session should upgrade.
+ * @param array LegalpadDocument objects
+ * @return void
+ * @task partial
+ */
+ public function signLegalpadDocuments(PhabricatorUser $viewer, array $docs) {
+
+ if (!$viewer->hasSession()) {
+ throw new Exception(
+ pht('Signing session legalpad documents of user with no session!'));
+ }
+
+ $session = $viewer->getSession();
+
+ if ($session->getSignedLegalpadDocuments()) {
+ throw new Exception(pht(
+ 'Session has already signed required legalpad documents!'));
+ }
+
+ $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
+ $session->setSignedLegalpadDocuments(1);
+
+ queryfx(
+ $session->establishConnection('w'),
+ 'UPDATE %T SET signedLegalpadDocuments = %d WHERE id = %d',
+ $session->getTableName(),
+ 1,
+ $session->getID());
+
+ if (!empty($docs)) {
+ $log = PhabricatorUserLog::initializeNewLog(
+ $viewer,
+ $viewer->getPHID(),
+ PhabricatorUserLog::ACTION_LOGIN_LEGALPAD);
+ $log->save();
+ }
+ unset($unguarded);
+ }
+
+
/* -( One Time Login URIs )------------------------------------------------ */
diff --git a/src/applications/auth/storage/PhabricatorAuthSession.php b/src/applications/auth/storage/PhabricatorAuthSession.php
--- a/src/applications/auth/storage/PhabricatorAuthSession.php
+++ b/src/applications/auth/storage/PhabricatorAuthSession.php
@@ -13,6 +13,7 @@
protected $sessionExpires;
protected $highSecurityUntil;
protected $isPartial;
+ protected $signedLegalpadDocuments;
private $identityObject = self::ATTACHABLE;
@@ -26,6 +27,7 @@
'sessionExpires' => 'epoch',
'highSecurityUntil' => 'epoch?',
'isPartial' => 'bool',
+ 'signedLegalpadDocuments' => 'bool',
),
self::CONFIG_KEY_SCHEMA => array(
'sessionKey' => array(
diff --git a/src/applications/base/controller/PhabricatorController.php b/src/applications/base/controller/PhabricatorController.php
--- a/src/applications/base/controller/PhabricatorController.php
+++ b/src/applications/base/controller/PhabricatorController.php
@@ -53,6 +53,10 @@
return PhabricatorEnv::getEnvConfig('security.require-multi-factor-auth');
}
+ public function shouldAllowLegallyNonCompliantUsers() {
+ return false;
+ }
+
public function willBeginExecution() {
$request = $this->getRequest();
@@ -221,6 +225,47 @@
}
}
+
+ if (!$this->shouldAllowLegallyNonCompliantUsers()) {
+ $legalpad_class = 'PhabricatorLegalpadApplication';
+ $legalpad = id(new PhabricatorApplicationQuery())
+ ->setViewer($user)
+ ->withClasses(array($legalpad_class))
+ ->withInstalled(true)
+ ->execute();
+ $legalpad = head($legalpad);
+
+ $doc_query = id(new LegalpadDocumentQuery())
+ ->setViewer($user)
+ ->withSignatureRequired(1)
+ ->needViewerSignatures(true);
+
+ if ($user->hasSession() &&
+ !$user->getSession()->getIsPartial() &&
+ !$user->getSession()->getSignedLegalpadDocuments() &&
+ $user->isLoggedIn() &&
+ $legalpad) {
+
+ $sign_docs = $doc_query->execute();
+ $must_sign_docs = array();
+ foreach ($sign_docs as $sign_doc) {
+ if (!$sign_doc->getUserSignature($user->getPHID())) {
+ $must_sign_docs[] = $sign_doc;
+ }
+ }
+ if ($must_sign_docs) {
+ $controller = new LegalpadDocumentSignController();
+ $this->getRequest()->setURIMap(array(
+ 'id' => head($must_sign_docs)->getID(),));
+ $this->setCurrentApplication($legalpad);
+ return $this->delegateToController($controller);
+ } else {
+ $engine = id(new PhabricatorAuthSessionEngine())
+ ->signLegalpadDocuments($user, $sign_docs);
+ }
+ }
+ }
+
// NOTE: We do this last so that users get a login page instead of a 403
// if they need to login.
if ($this->shouldRequireAdmin() && !$user->getIsAdmin()) {
diff --git a/src/applications/base/controller/__tests__/PhabricatorAccessControlTestCase.php b/src/applications/base/controller/__tests__/PhabricatorAccessControlTestCase.php
--- a/src/applications/base/controller/__tests__/PhabricatorAccessControlTestCase.php
+++ b/src/applications/base/controller/__tests__/PhabricatorAccessControlTestCase.php
@@ -170,7 +170,7 @@
// Test public access.
$this->checkAccess(
- 'No Login Required',
+ 'Public Access',
id(clone $controller)->setConfig('public', true),
$request,
array(
diff --git a/src/applications/celerity/controller/CelerityResourceController.php b/src/applications/celerity/controller/CelerityResourceController.php
--- a/src/applications/celerity/controller/CelerityResourceController.php
+++ b/src/applications/celerity/controller/CelerityResourceController.php
@@ -18,6 +18,10 @@
return true;
}
+ public function shouldAllowLegallyNonCompliantUsers() {
+ return true;
+ }
+
abstract public function getCelerityResourceMap();
protected function serveResource($path, $package_hash = null) {
diff --git a/src/applications/legalpad/constants/LegalpadTransactionType.php b/src/applications/legalpad/constants/LegalpadTransactionType.php
--- a/src/applications/legalpad/constants/LegalpadTransactionType.php
+++ b/src/applications/legalpad/constants/LegalpadTransactionType.php
@@ -6,5 +6,6 @@
const TYPE_TEXT = 'text';
const TYPE_SIGNATURE_TYPE = 'legalpad:signature-type';
const TYPE_PREAMBLE = 'legalpad:premable';
+ const TYPE_REQUIRE_SIGNATURE = 'legalpad:require-signature';
}
diff --git a/src/applications/legalpad/controller/LegalpadDocumentEditController.php b/src/applications/legalpad/controller/LegalpadDocumentEditController.php
--- a/src/applications/legalpad/controller/LegalpadDocumentEditController.php
+++ b/src/applications/legalpad/controller/LegalpadDocumentEditController.php
@@ -2,17 +2,11 @@
final class LegalpadDocumentEditController extends LegalpadController {
- private $id;
-
- public function willProcessRequest(array $data) {
- $this->id = idx($data, 'id');
- }
-
- public function processRequest() {
- $request = $this->getRequest();
+ public function handleRequest(AphrontRequest $request) {
$user = $request->getUser();
- if (!$this->id) {
+ $id = $request->getURIData('id');
+ if (!$id) {
$is_create = true;
$this->requireApplicationCapability(
@@ -34,7 +28,7 @@
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
- ->withIDs(array($this->id))
+ ->withIDs(array($id))
->executeOne();
if (!$document) {
return new Aphront404Response();
@@ -48,6 +42,7 @@
$text = $document->getDocumentBody()->getText();
$v_signature_type = $document->getSignatureType();
$v_preamble = $document->getPreamble();
+ $v_require_signature = $document->getRequireSignature();
$errors = array();
$can_view = null;
@@ -97,6 +92,24 @@
->setTransactionType(LegalpadTransactionType::TYPE_PREAMBLE)
->setNewValue($v_preamble);
+ $v_require_signature = $request->getBool('requireSignature', 0);
+ if ($v_require_signature) {
+ if (!$user->getIsAdmin()) {
+ $errors[] = pht('Only admins may require signature.');
+ }
+ $corp = LegalpadDocument::SIGNATURE_TYPE_CORPORATION;
+ if ($v_signature_type == $corp) {
+ $errors[] = pht(
+ 'Only documents ith signature type "individual" may require '.
+ 'signing to use Phabricator.');
+ }
+ }
+ if ($user->getIsAdmin()) {
+ $xactions[] = id(new LegalpadTransaction())
+ ->setTransactionType(LegalpadTransactionType::TYPE_REQUIRE_SIGNATURE)
+ ->setNewValue($v_require_signature);
+ }
+
if (!$errors) {
$editor = id(new LegalpadDocumentEditor())
->setContentSourceFromRequest($request)
@@ -133,11 +146,29 @@
->setName(pht('signatureType'))
->setValue($v_signature_type)
->setOptions(LegalpadDocument::getSignatureTypeMap()));
+ $show_require = true;
} else {
$form->appendChild(
id(new AphrontFormMarkupControl())
->setLabel(pht('Who Should Sign?'))
->setValue($document->getSignatureTypeName()));
+ $individual = LegalpadDocument::SIGNATURE_TYPE_INDIVIDUAL;
+ $show_require = $document->getSignatureType() == $individual;
+ }
+
+ if ($show_require) {
+ $form
+ ->appendChild(
+ id(new AphrontFormCheckboxControl())
+ ->setDisabled(!$user->getIsAdmin())
+ ->setLabel(pht('Require Signature'))
+ ->addCheckbox(
+ 'requireSignature',
+ 'requireSignature',
+ pht(
+ 'Should signing this document be required to use Phabricator? '.
+ 'Applies to invidivuals only.'),
+ $v_require_signature));
}
$form
diff --git a/src/applications/legalpad/controller/LegalpadDocumentSignController.php b/src/applications/legalpad/controller/LegalpadDocumentSignController.php
--- a/src/applications/legalpad/controller/LegalpadDocumentSignController.php
+++ b/src/applications/legalpad/controller/LegalpadDocumentSignController.php
@@ -2,23 +2,16 @@
final class LegalpadDocumentSignController extends LegalpadController {
- private $id;
-
public function shouldAllowPublic() {
return true;
}
- public function willProcessRequest(array $data) {
- $this->id = $data['id'];
- }
-
- public function processRequest() {
- $request = $this->getRequest();
+ public function handleRequest(AphrontRequest $request) {
$viewer = $request->getUser();
$document = id(new LegalpadDocumentQuery())
->setViewer($viewer)
- ->withIDs(array($this->id))
+ ->withIDs(array($request->getURIData('id')))
->needDocumentBodies(true)
->executeOne();
if (!$document) {
diff --git a/src/applications/legalpad/controller/LegalpadDocumentSignatureAddController.php b/src/applications/legalpad/controller/LegalpadDocumentSignatureAddController.php
--- a/src/applications/legalpad/controller/LegalpadDocumentSignatureAddController.php
+++ b/src/applications/legalpad/controller/LegalpadDocumentSignatureAddController.php
@@ -2,13 +2,7 @@
final class LegalpadDocumentSignatureAddController extends LegalpadController {
- private $id;
-
- public function willProcessRequest(array $data) {
- $this->id = $data['id'];
- }
-
- public function processRequest() {
+ public function handleRequest(AphrontRequest $request) {
$request = $this->getRequest();
$viewer = $request->getUser();
@@ -20,7 +14,7 @@
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
- ->withIDs(array($this->id))
+ ->withIDs(array($request->getURIData('id')))
->executeOne();
if (!$document) {
return new Aphront404Response();
diff --git a/src/applications/legalpad/editor/LegalpadDocumentEditor.php b/src/applications/legalpad/editor/LegalpadDocumentEditor.php
--- a/src/applications/legalpad/editor/LegalpadDocumentEditor.php
+++ b/src/applications/legalpad/editor/LegalpadDocumentEditor.php
@@ -32,6 +32,7 @@
$types[] = LegalpadTransactionType::TYPE_TEXT;
$types[] = LegalpadTransactionType::TYPE_SIGNATURE_TYPE;
$types[] = LegalpadTransactionType::TYPE_PREAMBLE;
+ $types[] = LegalpadTransactionType::TYPE_REQUIRE_SIGNATURE;
return $types;
}
@@ -49,6 +50,8 @@
return $object->getSignatureType();
case LegalpadTransactionType::TYPE_PREAMBLE:
return $object->getPreamble();
+ case LegalpadTransactionType::TYPE_REQUIRE_SIGNATURE:
+ return $object->getRequireSignature();
}
}
@@ -61,6 +64,7 @@
case LegalpadTransactionType::TYPE_TEXT:
case LegalpadTransactionType::TYPE_SIGNATURE_TYPE:
case LegalpadTransactionType::TYPE_PREAMBLE:
+ case LegalpadTransactionType::TYPE_REQUIRE_SIGNATURE:
return $xaction->getNewValue();
}
}
@@ -87,12 +91,27 @@
case LegalpadTransactionType::TYPE_PREAMBLE:
$object->setPreamble($xaction->getNewValue());
break;
+ case LegalpadTransactionType::TYPE_REQUIRE_SIGNATURE:
+ $object->setRequireSignature($xaction->getNewValue());
+ break;
}
}
protected function applyCustomExternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
+
+ switch ($xaction->getTransactionType()) {
+ case LegalpadTransactionType::TYPE_REQUIRE_SIGNATURE:
+ if ($xaction->getNewValue()) {
+ $session = new PhabricatorAuthSession();
+ queryfx(
+ $session->establishConnection('w'),
+ 'UPDATE %T SET signedLegalpadDocuments = 0',
+ $session->getTableName());
+ }
+ break;
+ }
return;
}
@@ -138,6 +157,7 @@
case LegalpadTransactionType::TYPE_TEXT:
case LegalpadTransactionType::TYPE_SIGNATURE_TYPE:
case LegalpadTransactionType::TYPE_PREAMBLE:
+ case LegalpadTransactionType::TYPE_REQUIRE_SIGNATURE:
return $v;
}
@@ -182,6 +202,7 @@
case LegalpadTransactionType::TYPE_TEXT:
case LegalpadTransactionType::TYPE_TITLE:
case LegalpadTransactionType::TYPE_PREAMBLE:
+ case LegalpadTransactionType::TYPE_REQUIRE_SIGNATURE:
return true;
}
diff --git a/src/applications/legalpad/query/LegalpadDocumentQuery.php b/src/applications/legalpad/query/LegalpadDocumentQuery.php
--- a/src/applications/legalpad/query/LegalpadDocumentQuery.php
+++ b/src/applications/legalpad/query/LegalpadDocumentQuery.php
@@ -10,6 +10,7 @@
private $signerPHIDs;
private $dateCreatedAfter;
private $dateCreatedBefore;
+ private $signatureRequired;
private $needDocumentBodies;
private $needContributors;
@@ -41,6 +42,11 @@
return $this;
}
+ public function withSignatureRequired($bool) {
+ $this->signatureRequired = $bool;
+ return $this;
+ }
+
public function needDocumentBodies($need_bodies) {
$this->needDocumentBodies = $need_bodies;
return $this;
@@ -204,6 +210,13 @@
$this->contributorPHIDs);
}
+ if ($this->signatureRequired !== null) {
+ $where[] = qsprintf(
+ $conn_r,
+ 'd.requireSignature = %d',
+ $this->signatureRequired);
+ }
+
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
diff --git a/src/applications/legalpad/storage/LegalpadDocument.php b/src/applications/legalpad/storage/LegalpadDocument.php
--- a/src/applications/legalpad/storage/LegalpadDocument.php
+++ b/src/applications/legalpad/storage/LegalpadDocument.php
@@ -18,6 +18,7 @@
protected $mailKey;
protected $signatureType;
protected $preamble;
+ protected $requireSignature;
const SIGNATURE_TYPE_INDIVIDUAL = 'user';
const SIGNATURE_TYPE_CORPORATION = 'corp';
@@ -44,6 +45,7 @@
->attachSignatures(array())
->setSignatureType(self::SIGNATURE_TYPE_INDIVIDUAL)
->setPreamble('')
+ ->setRequireSignature(0)
->setViewPolicy($view_policy)
->setEditPolicy($edit_policy);
}
@@ -61,11 +63,15 @@
'mailKey' => 'bytes20',
'signatureType' => 'text4',
'preamble' => 'text',
+ 'requireSignature' => 'bool',
),
self::CONFIG_KEY_SCHEMA => array(
'key_creator' => array(
'columns' => array('creatorPHID', 'dateModified'),
),
+ 'key_required' => array(
+ 'columns' => array('requireSignature', 'dateModified'),
+ ),
),
) + parent::getConfiguration();
}
diff --git a/src/applications/legalpad/storage/LegalpadTransaction.php b/src/applications/legalpad/storage/LegalpadTransaction.php
--- a/src/applications/legalpad/storage/LegalpadTransaction.php
+++ b/src/applications/legalpad/storage/LegalpadTransaction.php
@@ -54,6 +54,17 @@
return pht(
'%s updated the preamble.',
$this->renderHandleLink($author_phid));
+ case LegalpadTransactionType::TYPE_REQUIRE_SIGNATURE:
+ if ($new) {
+ $text = pht(
+ '%s set the document to require signatures.',
+ $this->renderHandleLink($author_phid));
+ } else {
+ $text = pht(
+ '%s set the document to not require signatures.',
+ $this->renderHandleLink($author_phid));
+ }
+ return $text;
}
return parent::getTitle();
diff --git a/src/applications/people/storage/PhabricatorUserLog.php b/src/applications/people/storage/PhabricatorUserLog.php
--- a/src/applications/people/storage/PhabricatorUserLog.php
+++ b/src/applications/people/storage/PhabricatorUserLog.php
@@ -8,6 +8,7 @@
const ACTION_LOGIN_FULL = 'login-full';
const ACTION_LOGOUT = 'logout';
const ACTION_LOGIN_FAILURE = 'login-fail';
+ const ACTION_LOGIN_LEGALPAD = 'login-legalpad';
const ACTION_RESET_PASSWORD = 'reset-pass';
const ACTION_CREATE = 'create';
@@ -53,6 +54,8 @@
self::ACTION_LOGIN_PARTIAL => pht('Login: Partial Login'),
self::ACTION_LOGIN_FULL => pht('Login: Upgrade to Full'),
self::ACTION_LOGIN_FAILURE => pht('Login: Failure'),
+ self::ACTION_LOGIN_LEGALPAD =>
+ pht('Login: Signed Required Legalpad Documents'),
self::ACTION_LOGOUT => pht('Logout'),
self::ACTION_RESET_PASSWORD => pht('Reset Password'),
self::ACTION_CREATE => pht('Create Account'),
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Nov 11, 2:24 PM (1 w, 7 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6735657
Default Alt Text
D11759.id28355.diff (20 KB)
Attached To
Mode
D11759: Legalpad - allow for legalpad documents to be required to be signed for using Phabricator
Attached
Detach File
Event Timeline
Log In to Comment