Page MenuHomePhabricator

D11945.id28770.diff
No OneTemporary

D11945.id28770.diff

diff --git a/src/applications/people/storage/PhabricatorUser.php b/src/applications/people/storage/PhabricatorUser.php
--- a/src/applications/people/storage/PhabricatorUser.php
+++ b/src/applications/people/storage/PhabricatorUser.php
@@ -50,6 +50,8 @@
private $alternateCSRFString = self::ATTACHABLE;
private $session = self::ATTACHABLE;
+ private $authorities = array();
+
protected function readField($field) {
switch ($field) {
case 'timezoneIdentifier':
@@ -694,6 +696,25 @@
$email->getUserPHID());
}
+
+ /**
+ * Grant a user a source of authority, to let them bypass policy checks they
+ * could not otherwise.
+ */
+ public function grantAuthority($authority) {
+ $this->authorities[] = $authority;
+ return $this;
+ }
+
+
+ /**
+ * Get authorities granted to the user.
+ */
+ public function getAuthorities() {
+ return $this->authorities;
+ }
+
+
/* -( Multi-Factor Authentication )---------------------------------------- */
diff --git a/src/applications/phortune/application/PhabricatorPhortuneApplication.php b/src/applications/phortune/application/PhabricatorPhortuneApplication.php
--- a/src/applications/phortune/application/PhabricatorPhortuneApplication.php
+++ b/src/applications/phortune/application/PhabricatorPhortuneApplication.php
@@ -85,6 +85,12 @@
'edit/(?:(?P<id>\d+)/)?' => 'PhortuneMerchantEditController',
'orders/(?P<merchantID>\d+)/(?:query/(?P<queryKey>[^/]+)/)?'
=> 'PhortuneCartListController',
+ '(?P<merchantID>\d+)/cart/(?P<id>\d+)/' => array(
+ '' => 'PhortuneCartViewController',
+ '(?P<action>cancel|refund)/' => 'PhortuneCartCancelController',
+ 'update/' => 'PhortuneCartUpdateController',
+ 'accept/' => 'PhortuneCartAcceptController',
+ ),
'(?P<merchantID>\d+)/subscription/' => array(
'(?:query/(?P<queryKey>[^/]+)/)?'
=> 'PhortuneSubscriptionListController',
diff --git a/src/applications/phortune/controller/PhortuneCartListController.php b/src/applications/phortune/controller/PhortuneCartListController.php
--- a/src/applications/phortune/controller/PhortuneCartListController.php
+++ b/src/applications/phortune/controller/PhortuneCartListController.php
@@ -42,6 +42,7 @@
return new Aphront404Response();
}
$this->merchant = $merchant;
+ $viewer->grantAuthority($merchant);
$engine->setMerchant($merchant);
} else if ($account_id) {
$account = id(new PhortuneAccountQuery())
diff --git a/src/applications/phortune/controller/PhortuneCartViewController.php b/src/applications/phortune/controller/PhortuneCartViewController.php
--- a/src/applications/phortune/controller/PhortuneCartViewController.php
+++ b/src/applications/phortune/controller/PhortuneCartViewController.php
@@ -13,6 +13,11 @@
$request = $this->getRequest();
$viewer = $request->getUser();
+ $authority = $this->loadMerchantAuthority();
+
+ // TODO: This (and the rest of the Cart controllers) need to be updated
+ // to use merchant URIs and merchant authority.
+
$cart = id(new PhortuneCartQuery())
->setViewer($viewer)
->withIDs(array($this->id))
@@ -157,7 +162,11 @@
$account = $cart->getAccount();
$crumbs = $this->buildApplicationCrumbs();
- $this->addAccountCrumb($crumbs, $cart->getAccount());
+ if ($authority) {
+ $this->addMerchantCrumb($crumbs, $authority);
+ } else {
+ $this->addAccountCrumb($crumbs, $cart->getAccount());
+ }
$crumbs->addTextCrumb(pht('Cart %d', $cart->getID()));
$timeline = $this->buildTransactionTimeline(
diff --git a/src/applications/phortune/controller/PhortuneController.php b/src/applications/phortune/controller/PhortuneController.php
--- a/src/applications/phortune/controller/PhortuneController.php
+++ b/src/applications/phortune/controller/PhortuneController.php
@@ -84,4 +84,30 @@
return $providers;
}
+ protected function loadMerchantAuthority() {
+ $request = $this->getRequest();
+ $viewer = $this->getViewer();
+
+ $is_merchant = (bool)$request->getURIData('merchantID');
+ if (!$is_merchant) {
+ return null;
+ }
+
+ $merchant = id(new PhortuneMerchantQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($request->getURIData('merchantID')))
+ ->requireCapabilities(
+ array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ ))
+ ->executeOne();
+ if (!$merchant) {
+ return null;
+ }
+
+ $viewer->grantAuthority($merchant);
+ return $merchant;
+ }
+
}
diff --git a/src/applications/phortune/controller/PhortuneSubscriptionListController.php b/src/applications/phortune/controller/PhortuneSubscriptionListController.php
--- a/src/applications/phortune/controller/PhortuneSubscriptionListController.php
+++ b/src/applications/phortune/controller/PhortuneSubscriptionListController.php
@@ -36,6 +36,7 @@
return new Aphront404Response();
}
$this->merchant = $merchant;
+ $viewer->grantAuthority($merchant);
$engine->setMerchant($merchant);
} else if ($this->accountID) {
$account = id(new PhortuneAccountQuery())
diff --git a/src/applications/phortune/controller/PhortuneSubscriptionViewController.php b/src/applications/phortune/controller/PhortuneSubscriptionViewController.php
--- a/src/applications/phortune/controller/PhortuneSubscriptionViewController.php
+++ b/src/applications/phortune/controller/PhortuneSubscriptionViewController.php
@@ -5,6 +5,8 @@
public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
+ $is_merchant = (bool)$this->loadMerchantAuthority();
+
$subscription = id(new PhortuneSubscriptionQuery())
->setViewer($viewer)
->withIDs(array($request->getURIData('id')))
@@ -19,7 +21,6 @@
$subscription,
PhabricatorPolicyCapability::CAN_EDIT);
- $is_merchant = (bool)$request->getURIData('merchantID');
$merchant = $subscription->getMerchant();
$account = $subscription->getAccount();
diff --git a/src/applications/phortune/query/PhortuneCartQuery.php b/src/applications/phortune/query/PhortuneCartQuery.php
--- a/src/applications/phortune/query/PhortuneCartQuery.php
+++ b/src/applications/phortune/query/PhortuneCartQuery.php
@@ -91,6 +91,10 @@
$cart->attachAccount($account);
}
+ if (!$carts) {
+ return array();
+ }
+
$merchants = id(new PhortuneMerchantQuery())
->setViewer($this->getViewer())
->withPHIDs(mpull($carts, 'getMerchantPHID'))
@@ -106,6 +110,10 @@
$cart->attachMerchant($merchant);
}
+ if (!$carts) {
+ return array();
+ }
+
$implementations = array();
$cart_map = mgroup($carts, 'getCartClass');
diff --git a/src/applications/phortune/query/PhortuneCartSearchEngine.php b/src/applications/phortune/query/PhortuneCartSearchEngine.php
--- a/src/applications/phortune/query/PhortuneCartSearchEngine.php
+++ b/src/applications/phortune/query/PhortuneCartSearchEngine.php
@@ -166,8 +166,21 @@
foreach ($carts as $cart) {
$merchant = $cart->getMerchant();
+ if ($this->getMerchant()) {
+ $href = $this->getApplicationURI(
+ 'merchant/'.$merchant->getID().'/cart/'.$cart->getID().'/');
+ } else {
+ $href = $cart->getDetailURI();
+ }
+
$rows[] = array(
$cart->getID(),
+ phutil_tag(
+ 'a',
+ array(
+ 'href' => $href,
+ ),
+ $cart->getName()),
$handles[$cart->getPHID()]->renderLink(),
$handles[$merchant->getPHID()]->renderLink(),
$handles[$cart->getAuthorPHID()]->renderLink(),
diff --git a/src/applications/phortune/query/PhortunePaymentMethodQuery.php b/src/applications/phortune/query/PhortunePaymentMethodQuery.php
--- a/src/applications/phortune/query/PhortunePaymentMethodQuery.php
+++ b/src/applications/phortune/query/PhortunePaymentMethodQuery.php
@@ -65,6 +65,10 @@
$method->attachAccount($account);
}
+ if (!$methods) {
+ return $methods;
+ }
+
$merchants = id(new PhortuneMerchantQuery())
->setViewer($this->getViewer())
->withPHIDs(mpull($methods, 'getMerchantPHID'))
@@ -80,6 +84,10 @@
$method->attachMerchant($merchant);
}
+ if (!$methods) {
+ return $methods;
+ }
+
$provider_configs = id(new PhortunePaymentProviderConfigQuery())
->setViewer($this->getViewer())
->withPHIDs(mpull($methods, 'getProviderPHID'))
diff --git a/src/applications/phortune/storage/PhortuneAccount.php b/src/applications/phortune/storage/PhortuneAccount.php
--- a/src/applications/phortune/storage/PhortuneAccount.php
+++ b/src/applications/phortune/storage/PhortuneAccount.php
@@ -133,10 +133,6 @@
public function getPolicy($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
- // Accounts are technically visible to all users, because merchant
- // controllers need to be able to see accounts in order to process
- // orders. We lock things down more tightly at the application level.
- return PhabricatorPolicies::POLICY_USER;
case PhabricatorPolicyCapability::CAN_EDIT:
if ($this->getPHID() === null) {
// Allow a user to create an account for themselves.
@@ -149,7 +145,21 @@
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
$members = array_fuse($this->getMemberPHIDs());
- return isset($members[$viewer->getPHID()]);
+ if (isset($members[$viewer->getPHID()])) {
+ return true;
+ }
+
+ // If the viewer is acting on behalf of a merchant, they can see
+ // payment accounts.
+ if ($capability == PhabricatorPolicyCapability::CAN_VIEW) {
+ foreach ($viewer->getAuthorities() as $authority) {
+ if ($authority instanceof PhortuneMerchant) {
+ return true;
+ }
+ }
+ }
+
+ return false;
}
public function describeAutomaticCapability($capability) {

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 27, 10:50 AM (21 h, 10 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6793698
Default Alt Text
D11945.id28770.diff (9 KB)

Event Timeline