@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
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Convert OAuthServer to Transactions + EditEngine

Summary: Ref T7303. This application is currently stone-age tech (no transactions, hard "delete" action). Bring it up to modern specs.

Test Plan:
- Created and edited an OAuth application.
- Viewed transaction record.
- Tried to create something with no name, invalid redirect URI, etc. Was gently rebuffed with detailed explanatory errors.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T7303

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

+415 -165
+19
resources/sql/autopatches/20160404.oauth.1.xaction.sql
··· 1 + CREATE TABLE {$NAMESPACE}_oauth_server.oauth_server_transaction ( 2 + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 3 + phid VARBINARY(64) NOT NULL, 4 + authorPHID VARBINARY(64) NOT NULL, 5 + objectPHID VARBINARY(64) NOT NULL, 6 + viewPolicy VARBINARY(64) NOT NULL, 7 + editPolicy VARBINARY(64) NOT NULL, 8 + commentPHID VARBINARY(64) DEFAULT NULL, 9 + commentVersion INT UNSIGNED NOT NULL, 10 + transactionType VARCHAR(32) COLLATE {$COLLATE_TEXT} NOT NULL, 11 + oldValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL, 12 + newValue LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL, 13 + contentSource LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL, 14 + metadata LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL, 15 + dateCreated INT UNSIGNED NOT NULL, 16 + dateModified INT UNSIGNED NOT NULL, 17 + UNIQUE KEY `key_phid` (`phid`), 18 + KEY `key_object` (`objectPHID`) 19 + ) ENGINE=InnoDB, COLLATE {$COLLATE_TEXT};
+9
src/__phutil_library_map__.php
··· 2723 2723 'PhabricatorOAuthServerController' => 'applications/oauthserver/controller/PhabricatorOAuthServerController.php', 2724 2724 'PhabricatorOAuthServerCreateClientsCapability' => 'applications/oauthserver/capability/PhabricatorOAuthServerCreateClientsCapability.php', 2725 2725 'PhabricatorOAuthServerDAO' => 'applications/oauthserver/storage/PhabricatorOAuthServerDAO.php', 2726 + 'PhabricatorOAuthServerEditEngine' => 'applications/oauthserver/editor/PhabricatorOAuthServerEditEngine.php', 2727 + 'PhabricatorOAuthServerEditor' => 'applications/oauthserver/editor/PhabricatorOAuthServerEditor.php', 2726 2728 'PhabricatorOAuthServerScope' => 'applications/oauthserver/PhabricatorOAuthServerScope.php', 2727 2729 'PhabricatorOAuthServerTestCase' => 'applications/oauthserver/__tests__/PhabricatorOAuthServerTestCase.php', 2728 2730 'PhabricatorOAuthServerTokenController' => 'applications/oauthserver/controller/PhabricatorOAuthServerTokenController.php', 2731 + 'PhabricatorOAuthServerTransaction' => 'applications/oauthserver/storage/PhabricatorOAuthServerTransaction.php', 2732 + 'PhabricatorOAuthServerTransactionQuery' => 'applications/oauthserver/query/PhabricatorOAuthServerTransactionQuery.php', 2729 2733 'PhabricatorObjectHandle' => 'applications/phid/PhabricatorObjectHandle.php', 2730 2734 'PhabricatorObjectHasAsanaSubtaskEdgeType' => 'applications/doorkeeper/edge/PhabricatorObjectHasAsanaSubtaskEdgeType.php', 2731 2735 'PhabricatorObjectHasAsanaTaskEdgeType' => 'applications/doorkeeper/edge/PhabricatorObjectHasAsanaTaskEdgeType.php', ··· 7206 7210 'PhabricatorOAuthServerClient' => array( 7207 7211 'PhabricatorOAuthServerDAO', 7208 7212 'PhabricatorPolicyInterface', 7213 + 'PhabricatorApplicationTransactionInterface', 7209 7214 'PhabricatorDestructibleInterface', 7210 7215 ), 7211 7216 'PhabricatorOAuthServerClientAuthorizationPHIDType' => 'PhabricatorPHIDType', ··· 7215 7220 'PhabricatorOAuthServerController' => 'PhabricatorController', 7216 7221 'PhabricatorOAuthServerCreateClientsCapability' => 'PhabricatorPolicyCapability', 7217 7222 'PhabricatorOAuthServerDAO' => 'PhabricatorLiskDAO', 7223 + 'PhabricatorOAuthServerEditEngine' => 'PhabricatorEditEngine', 7224 + 'PhabricatorOAuthServerEditor' => 'PhabricatorApplicationTransactionEditor', 7218 7225 'PhabricatorOAuthServerScope' => 'Phobject', 7219 7226 'PhabricatorOAuthServerTestCase' => 'PhabricatorTestCase', 7220 7227 'PhabricatorOAuthServerTokenController' => 'PhabricatorOAuthServerController', 7228 + 'PhabricatorOAuthServerTransaction' => 'PhabricatorApplicationTransaction', 7229 + 'PhabricatorOAuthServerTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 7221 7230 'PhabricatorObjectHandle' => array( 7222 7231 'Phobject', 7223 7232 'PhabricatorPolicyInterface',
+35 -10
src/applications/oauthserver/PhabricatorOAuthServer.php
··· 188 188 return $authorization; 189 189 } 190 190 191 + public function validateRedirectURI($uri) { 192 + try { 193 + $this->assertValidRedirectURI($uri); 194 + return true; 195 + } catch (Exception $ex) { 196 + return false; 197 + } 198 + } 199 + 191 200 /** 192 201 * See http://tools.ietf.org/html/draft-ietf-oauth-v2-23#section-3.1.2 193 202 * for details on what makes a given redirect URI "valid". 194 203 */ 195 - public function validateRedirectURI(PhutilURI $uri) { 196 - if (!PhabricatorEnv::isValidRemoteURIForLink($uri)) { 197 - return false; 198 - } 204 + public function assertValidRedirectURI($raw_uri) { 205 + // This covers basics like reasonable formatting and the existence of a 206 + // protocol. 207 + PhabricatorEnv::requireValidRemoteURIForLink($raw_uri); 208 + 209 + $uri = new PhutilURI($raw_uri); 199 210 200 - if ($uri->getFragment()) { 201 - return false; 211 + $fragment = $uri->getFragment(); 212 + if (strlen($fragment)) { 213 + throw new Exception( 214 + pht( 215 + 'OAuth application redirect URIs must not contain URI '. 216 + 'fragments, but the URI "%s" has a fragment ("%s").', 217 + $raw_uri, 218 + $fragment)); 202 219 } 203 220 204 - if (!$uri->getDomain()) { 205 - return false; 221 + $protocol = $uri->getProtocol(); 222 + switch ($protocol) { 223 + case 'http': 224 + case 'https': 225 + break; 226 + default: 227 + throw new Exception( 228 + pht( 229 + 'OAuth application redirect URIs must only use the "http" or '. 230 + '"https" protocols, but the URI "%s" uses the "%s" protocol.', 231 + $raw_uri, 232 + $protocol)); 206 233 } 207 - 208 - return true; 209 234 } 210 235 211 236 /**
+2 -2
src/applications/oauthserver/application/PhabricatorOAuthServerApplication.php
··· 51 51 => 'PhabricatorOAuthClientListController', 52 52 'auth/' => 'PhabricatorOAuthServerAuthController', 53 53 'token/' => 'PhabricatorOAuthServerTokenController', 54 + $this->getEditRoutePattern('edit/') => 55 + 'PhabricatorOAuthClientEditController', 54 56 'client/' => array( 55 - 'create/' => 'PhabricatorOAuthClientEditController', 56 57 'delete/(?P<id>\d+)/' => 'PhabricatorOAuthClientDeleteController', 57 - 'edit/(?P<id>\d+)/' => 'PhabricatorOAuthClientEditController', 58 58 'view/(?P<id>\d+)/' => 'PhabricatorOAuthClientViewController', 59 59 'secret/(?P<id>\d+)/' => 'PhabricatorOAuthClientSecretController', 60 60 'test/(?P<id>\d+)/' => 'PhabricatorOAuthClientTestController',
+3 -123
src/applications/oauthserver/controller/client/PhabricatorOAuthClientEditController.php
··· 4 4 extends PhabricatorOAuthClientController { 5 5 6 6 public function handleRequest(AphrontRequest $request) { 7 - $viewer = $this->getViewer(); 8 - $id = $request->getURIData('id'); 9 - 10 - if ($id) { 11 - $client = id(new PhabricatorOAuthServerClientQuery()) 12 - ->setViewer($viewer) 13 - ->withIDs(array($id)) 14 - ->requireCapabilities( 15 - array( 16 - PhabricatorPolicyCapability::CAN_VIEW, 17 - PhabricatorPolicyCapability::CAN_EDIT, 18 - )) 19 - ->executeOne(); 20 - if (!$client) { 21 - return new Aphront404Response(); 22 - } 23 - 24 - $title = pht('Edit OAuth Application: %s', $client->getName()); 25 - $submit_button = pht('Save Application'); 26 - $crumb_text = pht('Edit'); 27 - $cancel_uri = $client->getViewURI(); 28 - $is_new = false; 29 - } else { 30 - $this->requireApplicationCapability( 31 - PhabricatorOAuthServerCreateClientsCapability::CAPABILITY); 32 - 33 - $client = PhabricatorOAuthServerClient::initializeNewClient($viewer); 34 - 35 - $title = pht('Create OAuth Application'); 36 - $submit_button = pht('Create Application'); 37 - $crumb_text = pht('Create Application'); 38 - $cancel_uri = $this->getApplicationURI(); 39 - $is_new = true; 40 - } 41 - 42 - $errors = array(); 43 - $e_redirect = true; 44 - $e_name = true; 45 - if ($request->isFormPost()) { 46 - $redirect_uri = $request->getStr('redirect_uri'); 47 - $client->setName($request->getStr('name')); 48 - $client->setRedirectURI($redirect_uri); 49 - 50 - if (!strlen($client->getName())) { 51 - $errors[] = pht('You must choose a name for this OAuth application.'); 52 - $e_name = pht('Required'); 53 - } 54 - 55 - $server = new PhabricatorOAuthServer(); 56 - $uri = new PhutilURI($redirect_uri); 57 - if (!$server->validateRedirectURI($uri)) { 58 - $errors[] = pht( 59 - 'Redirect URI must be a fully qualified domain name '. 60 - 'with no fragments. See %s for more information on the correct '. 61 - 'format.', 62 - 'http://tools.ietf.org/html/draft-ietf-oauth-v2-23#section-3.1.2'); 63 - $e_redirect = pht('Invalid'); 64 - } 65 - 66 - $client->setViewPolicy($request->getStr('viewPolicy')); 67 - $client->setEditPolicy($request->getStr('editPolicy')); 68 - if (!$errors) { 69 - $client->save(); 70 - $view_uri = $client->getViewURI(); 71 - return id(new AphrontRedirectResponse())->setURI($view_uri); 72 - } 73 - } 74 - 75 - $policies = id(new PhabricatorPolicyQuery()) 76 - ->setViewer($viewer) 77 - ->setObject($client) 78 - ->execute(); 79 - 80 - $form = id(new AphrontFormView()) 81 - ->setUser($viewer) 82 - ->appendChild( 83 - id(new AphrontFormTextControl()) 84 - ->setLabel(pht('Name')) 85 - ->setName('name') 86 - ->setValue($client->getName()) 87 - ->setError($e_name)) 88 - ->appendChild( 89 - id(new AphrontFormTextControl()) 90 - ->setLabel(pht('Redirect URI')) 91 - ->setName('redirect_uri') 92 - ->setValue($client->getRedirectURI()) 93 - ->setError($e_redirect)) 94 - ->appendChild( 95 - id(new AphrontFormPolicyControl()) 96 - ->setUser($viewer) 97 - ->setCapability(PhabricatorPolicyCapability::CAN_VIEW) 98 - ->setPolicyObject($client) 99 - ->setPolicies($policies) 100 - ->setName('viewPolicy')) 101 - ->appendChild( 102 - id(new AphrontFormPolicyControl()) 103 - ->setUser($viewer) 104 - ->setCapability(PhabricatorPolicyCapability::CAN_EDIT) 105 - ->setPolicyObject($client) 106 - ->setPolicies($policies) 107 - ->setName('editPolicy')) 108 - ->appendChild( 109 - id(new AphrontFormSubmitControl()) 110 - ->addCancelButton($cancel_uri) 111 - ->setValue($submit_button)); 112 - 113 - $crumbs = $this->buildApplicationCrumbs(); 114 - if (!$is_new) { 115 - $crumbs->addTextCrumb( 116 - $client->getName(), 117 - $client->getViewURI()); 118 - } 119 - $crumbs->addTextCrumb($crumb_text); 120 - 121 - $box = id(new PHUIObjectBoxView()) 122 - ->setHeaderText($title) 123 - ->setFormErrors($errors) 124 - ->setForm($form); 125 - 126 - return $this->newPage() 127 - ->setCrumbs($crumbs) 128 - ->setTitle($title) 129 - ->appendChild($box); 7 + return id(new PhabricatorOAuthServerEditEngine()) 8 + ->setController($this) 9 + ->buildResponse(); 130 10 } 131 11 132 12 }
+7 -23
src/applications/oauthserver/controller/client/PhabricatorOAuthClientListController.php
··· 3 3 final class PhabricatorOAuthClientListController 4 4 extends PhabricatorOAuthClientController { 5 5 6 - private $queryKey; 7 - 8 6 public function shouldAllowPublic() { 9 7 return true; 10 8 } 11 9 12 - public function willProcessRequest(array $data) { 13 - $this->queryKey = idx($data, 'queryKey'); 14 - } 15 - 16 - public function processRequest() { 17 - $controller = id(new PhabricatorApplicationSearchController()) 18 - ->setQueryKey($this->queryKey) 19 - ->setSearchEngine(new PhabricatorOAuthServerClientSearchEngine()) 20 - ->setNavigation($this->buildSideNavView()); 21 - 22 - return $this->delegateToController($controller); 10 + public function handleRequest(AphrontRequest $request) { 11 + return id(new PhabricatorOAuthServerClientSearchEngine()) 12 + ->setController($this) 13 + ->buildResponse(); 23 14 } 24 15 25 16 protected function buildApplicationCrumbs() { 26 17 $crumbs = parent::buildApplicationCrumbs(); 27 18 28 - $can_create = $this->hasApplicationCapability( 29 - PhabricatorOAuthServerCreateClientsCapability::CAPABILITY); 30 - 31 - $crumbs->addAction( 32 - id(new PHUIListItemView()) 33 - ->setHref($this->getApplicationURI('client/create/')) 34 - ->setName(pht('Create Application')) 35 - ->setDisabled(!$can_create) 36 - ->setWorkflow(!$can_create) 37 - ->setIcon('fa-plus-square')); 19 + id(new PhabricatorOAuthServerEditEngine()) 20 + ->setViewer($this->getViewer()) 21 + ->addActionToCrumbs($crumbs); 38 22 39 23 return $crumbs; 40 24 }
+10 -1
src/applications/oauthserver/controller/client/PhabricatorOAuthClientViewController.php
··· 22 22 $crumbs = $this->buildApplicationCrumbs(); 23 23 $crumbs->addTextCrumb($client->getName()); 24 24 25 + $timeline = $this->buildTransactionTimeline( 26 + $client, 27 + new PhabricatorOAuthServerTransactionQuery()); 28 + $timeline->setShouldTerminate(true); 29 + 25 30 $box = id(new PHUIObjectBoxView()) 26 31 ->setHeader($header) 27 32 ->addPropertyList($properties); ··· 31 36 return $this->newPage() 32 37 ->setCrumbs($crumbs) 33 38 ->setTitle($title) 34 - ->appendChild($box); 39 + ->appendChild( 40 + array( 41 + $box, 42 + $timeline, 43 + )); 35 44 } 36 45 37 46 private function buildHeaderView(PhabricatorOAuthServerClient $client) {
+100
src/applications/oauthserver/editor/PhabricatorOAuthServerEditEngine.php
··· 1 + <?php 2 + 3 + final class PhabricatorOAuthServerEditEngine 4 + extends PhabricatorEditEngine { 5 + 6 + const ENGINECONST = 'oauthserver.application'; 7 + 8 + public function isEngineConfigurable() { 9 + return false; 10 + } 11 + 12 + public function getEngineName() { 13 + return pht('OAuth Applications'); 14 + } 15 + 16 + public function getSummaryHeader() { 17 + return pht('Edit OAuth Applications'); 18 + } 19 + 20 + public function getSummaryText() { 21 + return pht('This engine manages OAuth client applications.'); 22 + } 23 + 24 + public function getEngineApplicationClass() { 25 + return 'PhabricatorOAuthServerApplication'; 26 + } 27 + 28 + protected function newEditableObject() { 29 + return PhabricatorOAuthServerClient::initializeNewClient( 30 + $this->getViewer()); 31 + } 32 + 33 + protected function newObjectQuery() { 34 + return id(new PhabricatorOAuthServerClientQuery()); 35 + } 36 + 37 + protected function getObjectCreateTitleText($object) { 38 + return pht('Create OAuth Server'); 39 + } 40 + 41 + protected function getObjectCreateButtonText($object) { 42 + return pht('Create OAuth Server'); 43 + } 44 + 45 + protected function getObjectEditTitleText($object) { 46 + return pht('Edit OAuth Server: %s', $object->getName()); 47 + } 48 + 49 + protected function getObjectEditShortText($object) { 50 + return pht('Edit OAuth Server'); 51 + } 52 + 53 + protected function getObjectCreateShortText() { 54 + return pht('Create OAuth Server'); 55 + } 56 + 57 + protected function getObjectName() { 58 + return pht('OAuth Server'); 59 + } 60 + 61 + protected function getObjectViewURI($object) { 62 + return $object->getViewURI(); 63 + } 64 + 65 + protected function getCreateNewObjectPolicy() { 66 + return $this->getApplication()->getPolicy( 67 + PhabricatorOAuthServerCreateClientsCapability::CAPABILITY); 68 + } 69 + 70 + protected function buildCustomEditFields($object) { 71 + return array( 72 + id(new PhabricatorTextEditField()) 73 + ->setKey('name') 74 + ->setLabel(pht('Name')) 75 + ->setIsRequired(true) 76 + ->setTransactionType(PhabricatorOAuthServerTransaction::TYPE_NAME) 77 + ->setDescription(pht('The name of the OAuth application.')) 78 + ->setConduitDescription(pht('Rename the application.')) 79 + ->setConduitTypeDescription(pht('New application name.')) 80 + ->setValue($object->getName()), 81 + id(new PhabricatorTextEditField()) 82 + ->setKey('redirectURI') 83 + ->setLabel(pht('Redirect URI')) 84 + ->setIsRequired(true) 85 + ->setTransactionType( 86 + PhabricatorOAuthServerTransaction::TYPE_REDIRECT_URI) 87 + ->setDescription( 88 + pht('The redirect URI for OAuth handshakes.')) 89 + ->setConduitDescription( 90 + pht( 91 + 'Change where this application redirects users to during OAuth '. 92 + 'handshakes.')) 93 + ->setConduitTypeDescription( 94 + pht( 95 + 'New OAuth application redirect URI.')) 96 + ->setValue($object->getRedirectURI()), 97 + ); 98 + } 99 + 100 + }
+137
src/applications/oauthserver/editor/PhabricatorOAuthServerEditor.php
··· 1 + <?php 2 + 3 + final class PhabricatorOAuthServerEditor 4 + extends PhabricatorApplicationTransactionEditor { 5 + 6 + public function getEditorApplicationClass() { 7 + return 'PhabricatorOAuthServerApplication'; 8 + } 9 + 10 + public function getEditorObjectsDescription() { 11 + return pht('OAuth Applications'); 12 + } 13 + 14 + public function getTransactionTypes() { 15 + $types = parent::getTransactionTypes(); 16 + 17 + $types[] = PhabricatorOAuthServerTransaction::TYPE_NAME; 18 + $types[] = PhabricatorOAuthServerTransaction::TYPE_REDIRECT_URI; 19 + 20 + $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; 21 + $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; 22 + 23 + return $types; 24 + } 25 + 26 + protected function getCustomTransactionOldValue( 27 + PhabricatorLiskDAO $object, 28 + PhabricatorApplicationTransaction $xaction) { 29 + 30 + switch ($xaction->getTransactionType()) { 31 + case PhabricatorOAuthServerTransaction::TYPE_NAME: 32 + return $object->getName(); 33 + case PhabricatorOAuthServerTransaction::TYPE_REDIRECT_URI: 34 + return $object->getRedirectURI(); 35 + } 36 + } 37 + 38 + protected function getCustomTransactionNewValue( 39 + PhabricatorLiskDAO $object, 40 + PhabricatorApplicationTransaction $xaction) { 41 + 42 + switch ($xaction->getTransactionType()) { 43 + case PhabricatorOAuthServerTransaction::TYPE_NAME: 44 + case PhabricatorOAuthServerTransaction::TYPE_REDIRECT_URI: 45 + return $xaction->getNewValue(); 46 + } 47 + } 48 + 49 + protected function applyCustomInternalTransaction( 50 + PhabricatorLiskDAO $object, 51 + PhabricatorApplicationTransaction $xaction) { 52 + 53 + switch ($xaction->getTransactionType()) { 54 + case PhabricatorOAuthServerTransaction::TYPE_NAME: 55 + $object->setName($xaction->getNewValue()); 56 + return; 57 + case PhabricatorOAuthServerTransaction::TYPE_REDIRECT_URI: 58 + $object->setRedirectURI($xaction->getNewValue()); 59 + return; 60 + } 61 + 62 + return parent::applyCustomInternalTransaction($object, $xaction); 63 + } 64 + 65 + protected function applyCustomExternalTransaction( 66 + PhabricatorLiskDAO $object, 67 + PhabricatorApplicationTransaction $xaction) { 68 + 69 + switch ($xaction->getTransactionType()) { 70 + case PhabricatorOAuthServerTransaction::TYPE_NAME: 71 + case PhabricatorOAuthServerTransaction::TYPE_REDIRECT_URI: 72 + return; 73 + } 74 + 75 + return parent::applyCustomExternalTransaction($object, $xaction); 76 + } 77 + 78 + protected function validateTransaction( 79 + PhabricatorLiskDAO $object, 80 + $type, 81 + array $xactions) { 82 + 83 + $errors = parent::validateTransaction($object, $type, $xactions); 84 + 85 + switch ($type) { 86 + case PhabricatorOAuthServerTransaction::TYPE_NAME: 87 + $missing = $this->validateIsEmptyTextField( 88 + $object->getName(), 89 + $xactions); 90 + 91 + if ($missing) { 92 + $error = new PhabricatorApplicationTransactionValidationError( 93 + $type, 94 + pht('Required'), 95 + pht('OAuth applications must have a name.'), 96 + nonempty(last($xactions), null)); 97 + 98 + $error->setIsMissingFieldError(true); 99 + $errors[] = $error; 100 + } 101 + break; 102 + case PhabricatorOAuthServerTransaction::TYPE_REDIRECT_URI: 103 + $missing = $this->validateIsEmptyTextField( 104 + $object->getRedirectURI(), 105 + $xactions); 106 + if ($missing) { 107 + $error = new PhabricatorApplicationTransactionValidationError( 108 + $type, 109 + pht('Required'), 110 + pht('OAuth applications must have a valid redirect URI.'), 111 + nonempty(last($xactions), null)); 112 + 113 + $error->setIsMissingFieldError(true); 114 + $errors[] = $error; 115 + } else { 116 + foreach ($xactions as $xaction) { 117 + $redirect_uri = $xaction->getNewValue(); 118 + 119 + try { 120 + $server = new PhabricatorOAuthServer(); 121 + $server->assertValidRedirectURI($redirect_uri); 122 + } catch (Exception $ex) { 123 + $errors[] = new PhabricatorApplicationTransactionValidationError( 124 + $type, 125 + pht('Invalid'), 126 + $ex->getMessage(), 127 + $xaction); 128 + } 129 + } 130 + } 131 + break; 132 + } 133 + 134 + return $errors; 135 + } 136 + 137 + }
+10
src/applications/oauthserver/query/PhabricatorOAuthServerTransactionQuery.php
··· 1 + <?php 2 + 3 + final class PhabricatorOAuthServerTransactionQuery 4 + extends PhabricatorApplicationTransactionQuery { 5 + 6 + public function getTemplateApplicationTransaction() { 7 + return new PhabricatorOAuthServerTransaction(); 8 + } 9 + 10 + }
+26 -1
src/applications/oauthserver/storage/PhabricatorOAuthServerClient.php
··· 4 4 extends PhabricatorOAuthServerDAO 5 5 implements 6 6 PhabricatorPolicyInterface, 7 + PhabricatorApplicationTransactionInterface, 7 8 PhabricatorDestructibleInterface { 8 9 9 10 protected $secret; ··· 16 17 17 18 public function getEditURI() { 18 19 $id = $this->getID(); 19 - return "/oauthserver/client/edit/{$id}/"; 20 + return "/oauthserver/edit/{$id}/"; 20 21 } 21 22 22 23 public function getViewURI() { ··· 92 93 return null; 93 94 } 94 95 96 + 97 + /* -( PhabricatorApplicationTransactionInterface )------------------------- */ 98 + 99 + 100 + public function getApplicationTransactionEditor() { 101 + return new PhabricatorOAuthServerEditor(); 102 + } 103 + 104 + public function getApplicationTransactionObject() { 105 + return $this; 106 + } 107 + 108 + public function getApplicationTransactionTemplate() { 109 + return new PhabricatorOAuthServerTransaction(); 110 + } 111 + 112 + public function willRenderTimeline( 113 + PhabricatorApplicationTransactionView $timeline, 114 + AphrontRequest $request) { 115 + return $timeline; 116 + } 117 + 118 + 95 119 /* -( PhabricatorDestructibleInterface )----------------------------------- */ 120 + 96 121 97 122 public function destroyObjectPermanently( 98 123 PhabricatorDestructionEngine $engine) {
+52
src/applications/oauthserver/storage/PhabricatorOAuthServerTransaction.php
··· 1 + <?php 2 + 3 + final class PhabricatorOAuthServerTransaction 4 + extends PhabricatorApplicationTransaction { 5 + 6 + const TYPE_NAME = 'oauthserver.name'; 7 + const TYPE_REDIRECT_URI = 'oauthserver.redirect-uri'; 8 + 9 + public function getApplicationName() { 10 + return 'oauth_server'; 11 + } 12 + 13 + public function getTableName() { 14 + return 'oauth_server_transaction'; 15 + } 16 + 17 + public function getApplicationTransactionType() { 18 + return PhabricatorOAuthServerClientPHIDType::TYPECONST; 19 + } 20 + 21 + public function getApplicationTransactionCommentObject() { 22 + return null; 23 + } 24 + 25 + public function getTitle() { 26 + $author_phid = $this->getAuthorPHID(); 27 + $old = $this->getOldValue(); 28 + $new = $this->getNewValue(); 29 + 30 + switch ($this->getTransactionType()) { 31 + case PhabricatorTransactions::TYPE_CREATE: 32 + return pht( 33 + '%s created this OAuth application.', 34 + $this->renderHandleLink($author_phid)); 35 + case self::TYPE_NAME: 36 + return pht( 37 + '%s renamed this application from "%s" to "%s".', 38 + $this->renderHandleLink($author_phid), 39 + $old, 40 + $new); 41 + case self::TYPE_REDIRECT_URI: 42 + return pht( 43 + '%s changed the application redirect URI from "%s" to "%s".', 44 + $this->renderHandleLink($author_phid), 45 + $old, 46 + $new); 47 + } 48 + 49 + return parent::getTitle(); 50 + } 51 + 52 + }
+5 -5
src/infrastructure/env/PhabricatorEnv.php
··· 575 575 * @return void 576 576 * @task uri 577 577 */ 578 - public static function requireValidRemoteURIForLink($uri) { 579 - $uri = new PhutilURI($uri); 578 + public static function requireValidRemoteURIForLink($raw_uri) { 579 + $uri = new PhutilURI($raw_uri); 580 580 581 581 $proto = $uri->getProtocol(); 582 582 if (!strlen($proto)) { ··· 584 584 pht( 585 585 'URI "%s" is not a valid linkable resource. A valid linkable '. 586 586 'resource URI must specify a protocol.', 587 - $uri)); 587 + $raw_uri)); 588 588 } 589 589 590 590 $protocols = self::getEnvConfig('uri.allowed-protocols'); ··· 593 593 pht( 594 594 'URI "%s" is not a valid linkable resource. A valid linkable '. 595 595 'resource URI must use one of these protocols: %s.', 596 - $uri, 596 + $raw_uri, 597 597 implode(', ', array_keys($protocols)))); 598 598 } 599 599 ··· 603 603 pht( 604 604 'URI "%s" is not a valid linkable resource. A valid linkable '. 605 605 'resource URI must specify a domain.', 606 - $uri)); 606 + $raw_uri)); 607 607 } 608 608 } 609 609