@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator

Modernize some OAuth Server code

Summary:
Ref T7303. This inches toward properly-behaved cluster logout.

- Use IDs instead of PHIDs in URIs.
- Slightly more modern code.
- Fix some crumb stuff.

Test Plan: Created, edited, viewed, deleted, showed secret for, authorized, test-auth'd an application.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T7303

Differential Revision: https://secure.phabricator.com/D15592

+59 -79
+2 -2
src/__phutil_library_map__.php
··· 2705 2705 'PhabricatorOAuthClientEditController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientEditController.php', 2706 2706 'PhabricatorOAuthClientListController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientListController.php', 2707 2707 'PhabricatorOAuthClientSecretController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientSecretController.php', 2708 + 'PhabricatorOAuthClientTestController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientTestController.php', 2708 2709 'PhabricatorOAuthClientViewController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientViewController.php', 2709 2710 'PhabricatorOAuthResponse' => 'applications/oauthserver/PhabricatorOAuthResponse.php', 2710 2711 'PhabricatorOAuthServer' => 'applications/oauthserver/PhabricatorOAuthServer.php', ··· 2723 2724 'PhabricatorOAuthServerDAO' => 'applications/oauthserver/storage/PhabricatorOAuthServerDAO.php', 2724 2725 'PhabricatorOAuthServerScope' => 'applications/oauthserver/PhabricatorOAuthServerScope.php', 2725 2726 'PhabricatorOAuthServerTestCase' => 'applications/oauthserver/__tests__/PhabricatorOAuthServerTestCase.php', 2726 - 'PhabricatorOAuthServerTestController' => 'applications/oauthserver/controller/PhabricatorOAuthServerTestController.php', 2727 2727 'PhabricatorOAuthServerTokenController' => 'applications/oauthserver/controller/PhabricatorOAuthServerTokenController.php', 2728 2728 'PhabricatorObjectHandle' => 'applications/phid/PhabricatorObjectHandle.php', 2729 2729 'PhabricatorObjectHasAsanaSubtaskEdgeType' => 'applications/doorkeeper/edge/PhabricatorObjectHasAsanaSubtaskEdgeType.php', ··· 7192 7192 'PhabricatorOAuthClientEditController' => 'PhabricatorOAuthClientController', 7193 7193 'PhabricatorOAuthClientListController' => 'PhabricatorOAuthClientController', 7194 7194 'PhabricatorOAuthClientSecretController' => 'PhabricatorOAuthClientController', 7195 + 'PhabricatorOAuthClientTestController' => 'PhabricatorOAuthClientController', 7195 7196 'PhabricatorOAuthClientViewController' => 'PhabricatorOAuthClientController', 7196 7197 'PhabricatorOAuthResponse' => 'AphrontResponse', 7197 7198 'PhabricatorOAuthServer' => 'Phobject', ··· 7214 7215 'PhabricatorOAuthServerDAO' => 'PhabricatorLiskDAO', 7215 7216 'PhabricatorOAuthServerScope' => 'Phobject', 7216 7217 'PhabricatorOAuthServerTestCase' => 'PhabricatorTestCase', 7217 - 'PhabricatorOAuthServerTestController' => 'PhabricatorOAuthServerController', 7218 7218 'PhabricatorOAuthServerTokenController' => 'PhabricatorOAuthServerController', 7219 7219 'PhabricatorObjectHandle' => array( 7220 7220 'Phobject',
+5 -5
src/applications/oauthserver/application/PhabricatorOAuthServerApplication.php
··· 50 50 '(?:query/(?P<queryKey>[^/]+)/)?' 51 51 => 'PhabricatorOAuthClientListController', 52 52 'auth/' => 'PhabricatorOAuthServerAuthController', 53 - 'test/(?P<id>\d+)/' => 'PhabricatorOAuthServerTestController', 54 53 'token/' => 'PhabricatorOAuthServerTokenController', 55 54 'client/' => array( 56 55 'create/' => 'PhabricatorOAuthClientEditController', 57 - 'delete/(?P<phid>[^/]+)/' => 'PhabricatorOAuthClientDeleteController', 58 - 'edit/(?P<phid>[^/]+)/' => 'PhabricatorOAuthClientEditController', 59 - 'view/(?P<phid>[^/]+)/' => 'PhabricatorOAuthClientViewController', 60 - 'secret/(?P<phid>[^/]+)/' => 'PhabricatorOAuthClientSecretController', 56 + 'delete/(?P<id>\d+)/' => 'PhabricatorOAuthClientDeleteController', 57 + 'edit/(?P<id>\d+)/' => 'PhabricatorOAuthClientEditController', 58 + 'view/(?P<id>\d+)/' => 'PhabricatorOAuthClientViewController', 59 + 'secret/(?P<id>\d+)/' => 'PhabricatorOAuthClientSecretController', 60 + 'test/(?P<id>\d+)/' => 'PhabricatorOAuthClientTestController', 61 61 ), 62 62 ), 63 63 );
+6
src/applications/oauthserver/controller/PhabricatorOAuthServerAuthController.php
··· 3 3 final class PhabricatorOAuthServerAuthController 4 4 extends PhabricatorOAuthServerController { 5 5 6 + protected function buildApplicationCrumbs() { 7 + // We're specifically not putting an "OAuth Server" application crumb 8 + // on the auth pages because it doesn't make sense to send users there. 9 + return new PHUICrumbsView(); 10 + } 11 + 6 12 public function handleRequest(AphrontRequest $request) { 7 13 $viewer = $this->getViewer(); 8 14
-7
src/applications/oauthserver/controller/PhabricatorOAuthServerController.php
··· 5 5 6 6 const CONTEXT_AUTHORIZE = 'oauthserver.authorize'; 7 7 8 - protected function buildApplicationCrumbs() { 9 - // We're specifically not putting an "OAuth Server" application crumb 10 - // on these pages because it doesn't make sense to send users there on 11 - // the auth workflows. 12 - return new PHUICrumbsView(); 13 - } 14 - 15 8 }
+2 -2
src/applications/oauthserver/controller/PhabricatorOAuthServerTestController.php src/applications/oauthserver/controller/client/PhabricatorOAuthClientTestController.php
··· 1 1 <?php 2 2 3 - final class PhabricatorOAuthServerTestController 4 - extends PhabricatorOAuthServerController { 3 + final class PhabricatorOAuthClientTestController 4 + extends PhabricatorOAuthClientController { 5 5 6 6 public function handleRequest(AphrontRequest $request) { 7 7 $viewer = $this->getViewer();
+6 -8
src/applications/oauthserver/controller/client/PhabricatorOAuthClientDeleteController.php
··· 3 3 final class PhabricatorOAuthClientDeleteController 4 4 extends PhabricatorOAuthClientController { 5 5 6 - public function processRequest() { 7 - $request = $this->getRequest(); 8 - $viewer = $request->getUser(); 6 + public function handleRequest(AphrontRequest $request) { 7 + $viewer = $this->getViewer(); 9 8 10 9 $client = id(new PhabricatorOAuthServerClientQuery()) 11 10 ->setViewer($viewer) 12 - ->withPHIDs(array($this->getClientPHID())) 11 + ->withIDs(array($request->getURIData('id'))) 13 12 ->requireCapabilities( 14 13 array( 15 14 PhabricatorPolicyCapability::CAN_VIEW, ··· 20 19 return new Aphront404Response(); 21 20 } 22 21 22 + // TODO: This should be "disable", not "delete"! 23 + 23 24 if ($request->isFormPost()) { 24 25 $client->delete(); 25 26 $app_uri = $this->getApplicationURI(); 26 27 return id(new AphrontRedirectResponse())->setURI($app_uri); 27 28 } 28 29 29 - $dialog = id(new AphrontDialogView()) 30 - ->setUser($viewer) 30 + return $this->newDialog() 31 31 ->setTitle(pht('Delete OAuth Application?')) 32 32 ->appendParagraph( 33 33 pht( ··· 35 35 phutil_tag('strong', array(), $client->getName()))) 36 36 ->addCancelButton($client->getViewURI()) 37 37 ->addSubmitButton(pht('Delete Application')); 38 - 39 - return id(new AphrontDialogResponse())->setDialog($dialog); 40 38 } 41 39 42 40 }
+9 -14
src/applications/oauthserver/controller/client/PhabricatorOAuthClientEditController.php
··· 3 3 final class PhabricatorOAuthClientEditController 4 4 extends PhabricatorOAuthClientController { 5 5 6 - public function processRequest() { 7 - $request = $this->getRequest(); 8 - $viewer = $request->getUser(); 6 + public function handleRequest(AphrontRequest $request) { 7 + $viewer = $this->getViewer(); 8 + $id = $request->getURIData('id'); 9 9 10 - $phid = $this->getClientPHID(); 11 - if ($phid) { 10 + if ($id) { 12 11 $client = id(new PhabricatorOAuthServerClientQuery()) 13 12 ->setViewer($viewer) 14 - ->withPHIDs(array($phid)) 13 + ->withIDs(array($id)) 15 14 ->requireCapabilities( 16 15 array( 17 16 PhabricatorPolicyCapability::CAN_VIEW, ··· 124 123 ->setFormErrors($errors) 125 124 ->setForm($form); 126 125 127 - return $this->buildApplicationPage( 128 - array( 129 - $crumbs, 130 - $box, 131 - ), 132 - array( 133 - 'title' => $title, 134 - )); 126 + return $this->newPage() 127 + ->setCrumbs($crumbs) 128 + ->setTitle($title) 129 + ->appendChild($box); 135 130 } 136 131 137 132 }
+8 -10
src/applications/oauthserver/controller/client/PhabricatorOAuthClientSecretController.php
··· 8 8 9 9 $client = id(new PhabricatorOAuthServerClientQuery()) 10 10 ->setViewer($viewer) 11 - ->withPHIDs(array($this->getClientPHID())) 11 + ->withIDs(array($request->getURIData('id'))) 12 12 ->requireCapabilities( 13 13 array( 14 14 PhabricatorPolicyCapability::CAN_VIEW, ··· 27 27 28 28 if ($request->isFormPost()) { 29 29 $secret = $client->getSecret(); 30 + 30 31 $body = id(new PHUIFormLayoutView()) 31 32 ->appendChild( 32 33 id(new AphrontFormTextAreaControl()) 33 - ->setLabel(pht('Plaintext')) 34 - ->setReadOnly(true) 35 - ->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_SHORT) 36 - ->setValue($secret)); 34 + ->setLabel(pht('Plaintext')) 35 + ->setReadOnly(true) 36 + ->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_SHORT) 37 + ->setValue($secret)); 37 38 38 - $dialog = id(new AphrontDialogView()) 39 - ->setUser($viewer) 39 + return $this->newDialog() 40 40 ->setWidth(AphrontDialogView::WIDTH_FORM) 41 41 ->setTitle(pht('Application Secret')) 42 42 ->appendChild($body) 43 43 ->addCancelButton($view_uri, pht('Done')); 44 - 45 - return id(new AphrontDialogResponse())->setDialog($dialog); 46 44 } 47 45 48 46 ··· 59 57 'your monitor to create a human shield, keeping it safe from prying '. 60 58 'eyes. Protect company secrets!'); 61 59 } 60 + 62 61 return $this->newDialog() 63 - ->setUser($viewer) 64 62 ->setTitle(pht('Really show application secret?')) 65 63 ->appendChild($body) 66 64 ->addSubmitButton(pht('Show Application Secret'))
+14 -18
src/applications/oauthserver/controller/client/PhabricatorOAuthClientViewController.php
··· 3 3 final class PhabricatorOAuthClientViewController 4 4 extends PhabricatorOAuthClientController { 5 5 6 - public function processRequest() { 7 - $request = $this->getRequest(); 8 - $viewer = $request->getUser(); 6 + public function handleRequest(AphrontRequest $request) { 7 + $viewer = $this->getViewer(); 9 8 10 9 $client = id(new PhabricatorOAuthServerClientQuery()) 11 10 ->setViewer($viewer) 12 - ->withPHIDs(array($this->getClientPHID())) 11 + ->withIDs(array($request->getURIData('id'))) 13 12 ->executeOne(); 14 13 if (!$client) { 15 14 return new Aphront404Response(); ··· 27 26 ->setHeader($header) 28 27 ->addPropertyList($properties); 29 28 30 - return $this->buildApplicationPage( 31 - array( 32 - $crumbs, 33 - $box, 34 - ), 35 - array( 36 - 'title' => pht('OAuth Application: %s', $client->getName()), 37 - )); 29 + $title = pht('OAuth Application: %s', $client->getName()); 30 + 31 + return $this->newPage() 32 + ->setCrumbs($crumbs) 33 + ->setTitle($title) 34 + ->appendChild($box); 38 35 } 39 36 40 37 private function buildHeaderView(PhabricatorOAuthServerClient $client) { 41 - $viewer = $this->getRequest()->getUser(); 38 + $viewer = $this->getViewer(); 42 39 43 40 $header = id(new PHUIHeaderView()) 44 41 ->setUser($viewer) ··· 49 46 } 50 47 51 48 private function buildActionView(PhabricatorOAuthServerClient $client) { 52 - $viewer = $this->getRequest()->getUser(); 49 + $viewer = $this->getViewer(); 53 50 54 51 $can_edit = PhabricatorPolicyFilter::hasCapability( 55 52 $viewer, ··· 63 60 ->executeOne(); 64 61 $is_authorized = (bool)$authorization; 65 62 $id = $client->getID(); 66 - $phid = $client->getPHID(); 67 63 68 64 $view = id(new PhabricatorActionListView()) 69 65 ->setUser($viewer); ··· 80 76 id(new PhabricatorActionView()) 81 77 ->setName(pht('Show Application Secret')) 82 78 ->setIcon('fa-eye') 83 - ->setHref($this->getApplicationURI("client/secret/{$phid}/")) 79 + ->setHref($this->getApplicationURI("client/secret/{$id}/")) 84 80 ->setDisabled(!$can_edit) 85 81 ->setWorkflow(true)); 86 82 ··· 98 94 ->setIcon('fa-wrench') 99 95 ->setWorkflow(true) 100 96 ->setDisabled($is_authorized) 101 - ->setHref($this->getApplicationURI('test/'.$id.'/'))); 97 + ->setHref($this->getApplicationURI("client/test/{$id}/"))); 102 98 103 99 return $view; 104 100 } ··· 110 106 ->setUser($viewer); 111 107 112 108 $view->addProperty( 113 - pht('Client ID'), 109 + pht('Client PHID'), 114 110 $client->getPHID()); 115 111 116 112 $view->addProperty(
+1 -10
src/applications/oauthserver/query/PhabricatorOAuthServerClientSearchEngine.php
··· 79 79 return parent::buildSavedQueryFromBuiltin($query_key); 80 80 } 81 81 82 - protected function getRequiredHandlePHIDsForResultList( 83 - array $clients, 84 - PhabricatorSavedQuery $query) { 85 - return mpull($clients, 'getCreatorPHID'); 86 - } 87 - 88 82 protected function renderResultList( 89 83 array $clients, 90 84 PhabricatorSavedQuery $query, ··· 96 90 $list = id(new PHUIObjectItemListView()) 97 91 ->setUser($viewer); 98 92 foreach ($clients as $client) { 99 - $creator = $handles[$client->getCreatorPHID()]; 100 - 101 93 $item = id(new PHUIObjectItemView()) 102 94 ->setObjectName(pht('Application %d', $client->getID())) 103 95 ->setHeader($client->getName()) 104 96 ->setHref($client->getViewURI()) 105 - ->setObject($client) 106 - ->addByline(pht('Creator: %s', $creator->renderLink())); 97 + ->setObject($client); 107 98 108 99 $list->addItem($item); 109 100 }
+6 -3
src/applications/oauthserver/storage/PhabricatorOAuthServerClient.php
··· 15 15 protected $editPolicy; 16 16 17 17 public function getEditURI() { 18 - return '/oauthserver/client/edit/'.$this->getPHID().'/'; 18 + $id = $this->getID(); 19 + return "/oauthserver/client/edit/{$id}/"; 19 20 } 20 21 21 22 public function getViewURI() { 22 - return '/oauthserver/client/view/'.$this->getPHID().'/'; 23 + $id = $this->getID(); 24 + return "/oauthserver/client/view/{$id}/"; 23 25 } 24 26 25 27 public function getDeleteURI() { 26 - return '/oauthserver/client/delete/'.$this->getPHID().'/'; 28 + $id = $this->getID(); 29 + return "/oauthserver/client/delete/{$id}/"; 27 30 } 28 31 29 32 public static function initializeNewClient(PhabricatorUser $actor) {