mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
OAuth Server -- add controllers to RUD client authorizations and CRUD clients
Summary: beyond the title, this diff tweaks the test console to have a bit more functionality. also makes a small change to CSS for AphrontFormControlMarkup, which IMO fixes a display issue on https://secure.phabricator.com/settings/page/profile/ where the Profile URI is all up in the air and whatnot I think this is missing pagination. I am getting tired of the size though and will add later. See T905. Test Plan: viewed, updated and deleted client authorizations. viewed, created, updated and deleted clients Reviewers: epriestley Reviewed By: epriestley CC: aran, epriestley Maniphest Tasks: T849, T850, T848 Differential Revision: https://secure.phabricator.com/D1683
This commit is contained in:
parent
5f46a61e6d
commit
3c4070a168
35 changed files with 1450 additions and 78 deletions
3
resources/sql/patches/109.oauthclientphidkey.sql
Normal file
3
resources/sql/patches/109.oauthclientphidkey.sql
Normal file
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE `phabricator_oauth_server`.`oauth_server_oauthserverclient`
|
||||
ADD KEY `creatorPHID` (`creatorPHID`)
|
||||
|
|
@ -609,6 +609,15 @@ phutil_register_library_map(array(
|
|||
'PhabricatorMetaMTAViewController' => 'applications/metamta/controller/view',
|
||||
'PhabricatorMySQLFileStorageEngine' => 'applications/files/engine/mysql',
|
||||
'PhabricatorOAuthClientAuthorization' => 'applications/oauthserver/storage/clientauthorization',
|
||||
'PhabricatorOAuthClientAuthorizationBaseController' => 'applications/oauthserver/controller/clientauthorization/base',
|
||||
'PhabricatorOAuthClientAuthorizationDeleteController' => 'applications/oauthserver/controller/clientauthorization/delete',
|
||||
'PhabricatorOAuthClientAuthorizationEditController' => 'applications/oauthserver/controller/clientauthorization/edit',
|
||||
'PhabricatorOAuthClientAuthorizationListController' => 'applications/oauthserver/controller/clientauthorization/list',
|
||||
'PhabricatorOAuthClientBaseController' => 'applications/oauthserver/controller/client/base',
|
||||
'PhabricatorOAuthClientDeleteController' => 'applications/oauthserver/controller/client/delete',
|
||||
'PhabricatorOAuthClientEditController' => 'applications/oauthserver/controller/client/edit',
|
||||
'PhabricatorOAuthClientListController' => 'applications/oauthserver/controller/client/list',
|
||||
'PhabricatorOAuthClientViewController' => 'applications/oauthserver/controller/client/view',
|
||||
'PhabricatorOAuthDefaultRegistrationController' => 'applications/auth/controller/oauthregistration/default',
|
||||
'PhabricatorOAuthDiagnosticsController' => 'applications/auth/controller/oauthdiagnostics',
|
||||
'PhabricatorOAuthFailureView' => 'applications/auth/view/oauthfailure',
|
||||
|
@ -625,6 +634,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorOAuthServerAuthController' => 'applications/oauthserver/controller/auth',
|
||||
'PhabricatorOAuthServerAuthorizationCode' => 'applications/oauthserver/storage/authorizationcode',
|
||||
'PhabricatorOAuthServerClient' => 'applications/oauthserver/storage/client',
|
||||
'PhabricatorOAuthServerController' => 'applications/oauthserver/controller/base',
|
||||
'PhabricatorOAuthServerDAO' => 'applications/oauthserver/storage/base',
|
||||
'PhabricatorOAuthServerScope' => 'applications/oauthserver/scope',
|
||||
'PhabricatorOAuthServerTestController' => 'applications/oauthserver/controller/test',
|
||||
|
@ -1360,6 +1370,15 @@ phutil_register_library_map(array(
|
|||
'PhabricatorMetaMTAViewController' => 'PhabricatorMetaMTAController',
|
||||
'PhabricatorMySQLFileStorageEngine' => 'PhabricatorFileStorageEngine',
|
||||
'PhabricatorOAuthClientAuthorization' => 'PhabricatorOAuthServerDAO',
|
||||
'PhabricatorOAuthClientAuthorizationBaseController' => 'PhabricatorOAuthServerController',
|
||||
'PhabricatorOAuthClientAuthorizationDeleteController' => 'PhabricatorOAuthClientAuthorizationBaseController',
|
||||
'PhabricatorOAuthClientAuthorizationEditController' => 'PhabricatorOAuthClientAuthorizationBaseController',
|
||||
'PhabricatorOAuthClientAuthorizationListController' => 'PhabricatorOAuthClientAuthorizationBaseController',
|
||||
'PhabricatorOAuthClientBaseController' => 'PhabricatorOAuthServerController',
|
||||
'PhabricatorOAuthClientDeleteController' => 'PhabricatorOAuthClientBaseController',
|
||||
'PhabricatorOAuthClientEditController' => 'PhabricatorOAuthClientBaseController',
|
||||
'PhabricatorOAuthClientListController' => 'PhabricatorOAuthClientBaseController',
|
||||
'PhabricatorOAuthClientViewController' => 'PhabricatorOAuthClientBaseController',
|
||||
'PhabricatorOAuthDefaultRegistrationController' => 'PhabricatorOAuthRegistrationController',
|
||||
'PhabricatorOAuthDiagnosticsController' => 'PhabricatorAuthController',
|
||||
'PhabricatorOAuthFailureView' => 'AphrontView',
|
||||
|
@ -1374,8 +1393,9 @@ phutil_register_library_map(array(
|
|||
'PhabricatorOAuthServerAuthController' => 'PhabricatorAuthController',
|
||||
'PhabricatorOAuthServerAuthorizationCode' => 'PhabricatorOAuthServerDAO',
|
||||
'PhabricatorOAuthServerClient' => 'PhabricatorOAuthServerDAO',
|
||||
'PhabricatorOAuthServerController' => 'PhabricatorController',
|
||||
'PhabricatorOAuthServerDAO' => 'PhabricatorLiskDAO',
|
||||
'PhabricatorOAuthServerTestController' => 'PhabricatorAuthController',
|
||||
'PhabricatorOAuthServerTestController' => 'PhabricatorOAuthServerController',
|
||||
'PhabricatorOAuthServerTokenController' => 'PhabricatorAuthController',
|
||||
'PhabricatorOAuthUnlinkController' => 'PhabricatorAuthController',
|
||||
'PhabricatorObjectGraph' => 'AbstractDirectedGraph',
|
||||
|
|
|
@ -159,8 +159,23 @@ class AphrontDefaultApplicationConfiguration
|
|||
|
||||
'/oauthserver/' => array(
|
||||
'auth/' => 'PhabricatorOAuthServerAuthController',
|
||||
'token/' => 'PhabricatorOAuthServerTokenController',
|
||||
'test/' => 'PhabricatorOAuthServerTestController',
|
||||
'token/' => 'PhabricatorOAuthServerTokenController',
|
||||
'clientauthorization/' => array(
|
||||
'$' => 'PhabricatorOAuthClientAuthorizationListController',
|
||||
'delete/(?P<phid>[^/]+)/' =>
|
||||
'PhabricatorOAuthClientAuthorizationDeleteController',
|
||||
'edit/(?P<phid>[^/]+)/' =>
|
||||
'PhabricatorOAuthClientAuthorizationEditController',
|
||||
),
|
||||
'client/' => array(
|
||||
'$' => 'PhabricatorOAuthClientListController',
|
||||
'create/$' => 'PhabricatorOAuthClientEditController',
|
||||
'delete/(?P<phid>[^/]+)/$' =>
|
||||
'PhabricatorOAuthClientDeleteController',
|
||||
'edit/(?P<phid>[^/]+)/$' => 'PhabricatorOAuthClientEditController',
|
||||
'view/(?P<phid>[^/]+)/$' => 'PhabricatorOAuthClientViewController',
|
||||
),
|
||||
),
|
||||
|
||||
'/xhprof/' => array(
|
||||
|
|
|
@ -21,15 +21,28 @@
|
|||
*/
|
||||
class Aphront403Response extends AphrontWebpageResponse {
|
||||
|
||||
private $forbiddenText;
|
||||
public function setForbiddenText($text) {
|
||||
$this->forbiddenText = $text;
|
||||
return $this;
|
||||
}
|
||||
private function getForbiddenText() {
|
||||
return $this->forbiddenText;
|
||||
}
|
||||
|
||||
public function getHTTPResponseCode() {
|
||||
return 403;
|
||||
}
|
||||
|
||||
public function buildResponseString() {
|
||||
$forbidden_text = $this->getForbiddenText();
|
||||
if (!$forbidden_text) {
|
||||
$forbidden_text =
|
||||
'You do not have privileges to access the requested page.';
|
||||
}
|
||||
$failure = new AphrontRequestFailureView();
|
||||
$failure->setHeader('403 Forbidden');
|
||||
$failure->appendChild(
|
||||
'<p>You do not have privileges to access the requested page.</p>');
|
||||
$failure->appendChild('<p>'.$forbidden_text.'</p>');
|
||||
|
||||
$view = new PhabricatorStandardPageView();
|
||||
$view->setTitle('403 Forbidden');
|
||||
|
|
|
@ -54,9 +54,7 @@ extends PhabricatorAuthController {
|
|||
$return_auth_code = true;
|
||||
$unguarded_write = AphrontWriteGuard::beginScopedUnguardedWrites();
|
||||
} else if ($request->isFormPost()) {
|
||||
// TODO -- T848 (add scope to Phabricator OAuth)
|
||||
// should have some $scope based off of user submission here...!
|
||||
$scope = array(PhabricatorOAuthServerScope::SCOPE_WHOAMI => 1);
|
||||
$scope = PhabricatorOAuthServerScope::getScopesFromRequest($request);
|
||||
$server->authorizeClient($scope);
|
||||
$return_auth_code = true;
|
||||
$unguarded_write = null;
|
||||
|
@ -107,21 +105,28 @@ extends PhabricatorAuthController {
|
|||
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
||||
$panel->setHeader($title);
|
||||
|
||||
// TODO -- T848 (add scope to Phabricator OAuth)
|
||||
// generally inform user what this means as this fleshes out
|
||||
$description =
|
||||
"Do want to authorize {$name} to access your ".
|
||||
"Phabricator account data?";
|
||||
|
||||
$desired_scopes = array(
|
||||
PhabricatorOAuthServerScope::SCOPE_WHOAMI => 1,
|
||||
PhabricatorOAuthServerScope::SCOPE_OFFLINE_ACCESS => 1
|
||||
);
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($current_user)
|
||||
->appendChild(
|
||||
id(new AphrontFormStaticControl())
|
||||
->setValue($description))
|
||||
->setValue($description)
|
||||
)
|
||||
->appendChild(
|
||||
PhabricatorOAuthServerScope::getCheckboxControl()
|
||||
)
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue('Authorize')
|
||||
->addCancelButton('/'));
|
||||
->addCancelButton('/')
|
||||
);
|
||||
// TODO -- T889 (make "cancel" do something more sensible)
|
||||
|
||||
$panel->appendChild($form);
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
abstract class PhabricatorOAuthServerController
|
||||
extends PhabricatorController {
|
||||
|
||||
public function buildStandardPageResponse($view, array $data) {
|
||||
$user = $this->getRequest()->getUser();
|
||||
$page = $this->buildStandardPageView();
|
||||
$page->setApplicationName('OAuth Server');
|
||||
$page->setBaseURI('/oauthserver/');
|
||||
$page->setTitle(idx($data, 'title'));
|
||||
|
||||
$nav = new AphrontSideNavFilterView();
|
||||
$nav->setBaseURI(new PhutilURI('/oauthserver/'));
|
||||
$nav->addLabel('Client Authorizations');
|
||||
$nav->addFilter('clientauthorization',
|
||||
'My Authorizations');
|
||||
$nav->addSpacer();
|
||||
$nav->addLabel('Clients');
|
||||
$nav->addFilter('client/create',
|
||||
'Create Client');
|
||||
foreach ($this->getExtraClientFilters() as $filter) {
|
||||
$nav->addFilter($filter['url'],
|
||||
$filter['label']);
|
||||
}
|
||||
$nav->addFilter('client',
|
||||
'My Clients');
|
||||
$nav->selectFilter($this->getFilter(),
|
||||
'clientauthorization');
|
||||
|
||||
$nav->appendChild($view);
|
||||
|
||||
$page->appendChild($nav);
|
||||
|
||||
$response = new AphrontWebpageResponse();
|
||||
return $response->setContent($page->render());
|
||||
}
|
||||
|
||||
protected function getFilter() {
|
||||
return 'clientauthorization';
|
||||
}
|
||||
|
||||
protected function getExtraClientFilters() {
|
||||
return array();
|
||||
}
|
||||
|
||||
protected function getHighlightPHIDs() {
|
||||
$phids = array();
|
||||
$request = $this->getRequest();
|
||||
$edited = $request->getStr('edited');
|
||||
$new = $request->getStr('new');
|
||||
if ($edited) {
|
||||
$phids[$edited] = $edited;
|
||||
}
|
||||
if ($new) {
|
||||
$phids[$new] = $new;
|
||||
}
|
||||
return $phids;
|
||||
}
|
||||
|
||||
protected function buildErrorView($error_message) {
|
||||
$error = new AphrontErrorView();
|
||||
$error->setSeverity(AphrontErrorView::SEVERITY_ERROR);
|
||||
$error->setTitle($error_message);
|
||||
|
||||
return $error;
|
||||
}
|
||||
}
|
18
src/applications/oauthserver/controller/base/__init__.php
Normal file
18
src/applications/oauthserver/controller/base/__init__.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'aphront/response/webpage');
|
||||
phutil_require_module('phabricator', 'applications/base/controller/base');
|
||||
phutil_require_module('phabricator', 'view/form/error');
|
||||
phutil_require_module('phabricator', 'view/layout/sidenavfilter');
|
||||
|
||||
phutil_require_module('phutil', 'parser/uri');
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorOAuthServerController.php');
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group oauthserver
|
||||
*/
|
||||
abstract class PhabricatorOAuthClientBaseController
|
||||
extends PhabricatorOAuthServerController {
|
||||
|
||||
private $clientPHID;
|
||||
protected function getClientPHID() {
|
||||
return $this->clientPHID;
|
||||
}
|
||||
private function setClientPHID($phid) {
|
||||
$this->clientPHID = $phid;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function shouldRequireLogin() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->setClientPHID(idx($data, 'phid'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/controller/base');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorOAuthClientBaseController.php');
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group oauthserver
|
||||
*/
|
||||
final class PhabricatorOAuthClientDeleteController
|
||||
extends PhabricatorOAuthClientBaseController {
|
||||
|
||||
public function processRequest() {
|
||||
$phid = $this->getClientPHID();
|
||||
$title = 'Delete OAuth Client';
|
||||
$request = $this->getRequest();
|
||||
$current_user = $request->getUser();
|
||||
$client = id(new PhabricatorOAuthServerClient())
|
||||
->loadOneWhere('phid = %s',
|
||||
$phid);
|
||||
|
||||
if (empty($client)) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
if ($client->getCreatorPHID() != $current_user->getPHID()) {
|
||||
$message = 'Access denied to client with phid '.$phid.'. '.
|
||||
'Only the user who created the client has permission to '.
|
||||
'delete the client.';
|
||||
return id(new Aphront403Response())
|
||||
->setForbiddenText($message);
|
||||
}
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$client->delete();
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/oauthserver/client/?deleted=1');
|
||||
}
|
||||
|
||||
$client_name = phutil_escape_html($client->getName());
|
||||
$title .= ' '.$client_name;
|
||||
|
||||
$dialog = new AphrontDialogView();
|
||||
$dialog->setUser($current_user);
|
||||
$dialog->setTitle($title);
|
||||
$dialog->appendChild(
|
||||
'<p>Are you sure you want to delete this client?</p>'
|
||||
);
|
||||
$dialog->addSubmitButton();
|
||||
$dialog->addCancelButton($client->getEditURI());
|
||||
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'aphront/response/403');
|
||||
phutil_require_module('phabricator', 'aphront/response/404');
|
||||
phutil_require_module('phabricator', 'aphront/response/dialog');
|
||||
phutil_require_module('phabricator', 'aphront/response/redirect');
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/controller/client/base');
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/storage/client');
|
||||
phutil_require_module('phabricator', 'view/dialog');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorOAuthClientDeleteController.php');
|
|
@ -0,0 +1,197 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group oauthserver
|
||||
*/
|
||||
final class PhabricatorOAuthClientEditController
|
||||
extends PhabricatorOAuthClientBaseController {
|
||||
|
||||
private $isEdit;
|
||||
protected function isClientEdit() {
|
||||
return $this->isEdit;
|
||||
}
|
||||
private function setIsClientEdit($is_edit) {
|
||||
$this->isEdit = (bool) $is_edit;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function getExtraClientFilters() {
|
||||
if ($this->isClientEdit()) {
|
||||
$filters = array(
|
||||
array('url' => $this->getFilter(),
|
||||
'label' => 'Edit Client')
|
||||
);
|
||||
} else {
|
||||
$filters = array();
|
||||
}
|
||||
return $filters;
|
||||
}
|
||||
|
||||
public function getFilter() {
|
||||
if ($this->isClientEdit()) {
|
||||
$filter = 'client/edit/'.$this->getClientPHID();
|
||||
} else {
|
||||
$filter = 'client/create';
|
||||
}
|
||||
return $filter;
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$current_user = $request->getUser();
|
||||
$error = null;
|
||||
$bad_redirect = false;
|
||||
$phid = $this->getClientPHID();
|
||||
// if we have a phid, then we're editing
|
||||
$this->setIsClientEdit($phid);
|
||||
|
||||
if ($this->isClientEdit()) {
|
||||
$client = id(new PhabricatorOAuthServerClient())
|
||||
->loadOneWhere('phid = %s',
|
||||
$phid);
|
||||
$title = 'Edit OAuth Client';
|
||||
// validate the client
|
||||
if (empty($client)) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
if ($client->getCreatorPHID() != $current_user->getPHID()) {
|
||||
$message = 'Access denied to edit client with id '.$phid.'. '.
|
||||
'Only the user who created the client has permission to '.
|
||||
'edit the client.';
|
||||
return id(new Aphront403Response())
|
||||
->setForbiddenText($message);
|
||||
}
|
||||
$submit_button = 'Save OAuth Client';
|
||||
// new client - much simpler
|
||||
} else {
|
||||
$client = new PhabricatorOAuthServerClient();
|
||||
$title = 'Create OAuth Client';
|
||||
$submit_button = 'Create OAuth Client';
|
||||
}
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$redirect_uri = $request->getStr('redirect_uri');
|
||||
$client->setName($request->getStr('name'));
|
||||
$client->setRedirectURI($redirect_uri);
|
||||
$client->setSecret(Filesystem::readRandomCharacters(32));
|
||||
$client->setCreatorPHID($current_user->getPHID());
|
||||
$uri = new PhutilURI($redirect_uri);
|
||||
if (!$this->validateRedirectURI($uri)) {
|
||||
$error = new AphrontErrorView();
|
||||
$error->setSeverity(AphrontErrorView::SEVERITY_ERROR);
|
||||
$error->setTitle(
|
||||
'Redirect URI must be a fully qualified domain name.'
|
||||
);
|
||||
$bad_redirect = true;
|
||||
} else {
|
||||
$client->save();
|
||||
if ($this->isClientEdit()) {
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/oauthserver/client/?edited='.$phid);
|
||||
} else {
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/oauthserver/client/?new='.$phid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$panel = new AphrontPanelView();
|
||||
if ($this->isClientEdit()) {
|
||||
$delete_button = phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $client->getDeleteURI(),
|
||||
'class' => 'grey button',
|
||||
),
|
||||
'Delete OAuth Client');
|
||||
$panel->addButton($delete_button);
|
||||
}
|
||||
$panel->setHeader($title);
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($current_user)
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel('Name')
|
||||
->setName('name')
|
||||
->setValue($client->getName())
|
||||
);
|
||||
if ($this->isClientEdit()) {
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel('ID')
|
||||
->setValue($phid)
|
||||
)
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel('Secret')
|
||||
->setValue($client->getSecret())
|
||||
);
|
||||
}
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel('Redirect URI')
|
||||
->setName('redirect_uri')
|
||||
->setValue($client->getRedirectURI())
|
||||
->setError($bad_redirect)
|
||||
);
|
||||
if ($this->isClientEdit()) {
|
||||
$created = phabricator_datetime($client->getDateCreated(),
|
||||
$current_user);
|
||||
$updated = phabricator_datetime($client->getDateModified(),
|
||||
$current_user);
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormStaticControl())
|
||||
->setLabel('Created')
|
||||
->setValue($created)
|
||||
)
|
||||
->appendChild(
|
||||
id(new AphrontFormStaticControl())
|
||||
->setLabel('Last Updated')
|
||||
->setValue($updated)
|
||||
);
|
||||
}
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue($submit_button)
|
||||
);
|
||||
|
||||
$panel->appendChild($form);
|
||||
return $this->buildStandardPageResponse(
|
||||
array($error,
|
||||
$panel
|
||||
),
|
||||
array('title' => $title)
|
||||
);
|
||||
}
|
||||
|
||||
private function validateRedirectURI(PhutilURI $uri) {
|
||||
if (PhabricatorEnv::isValidRemoteWebResource($uri)) {
|
||||
if ($uri->getDomain()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'aphront/response/403');
|
||||
phutil_require_module('phabricator', 'aphront/response/404');
|
||||
phutil_require_module('phabricator', 'aphront/response/redirect');
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/controller/client/base');
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/storage/client');
|
||||
phutil_require_module('phabricator', 'infrastructure/env');
|
||||
phutil_require_module('phabricator', 'view/form/base');
|
||||
phutil_require_module('phabricator', 'view/form/control/static');
|
||||
phutil_require_module('phabricator', 'view/form/control/submit');
|
||||
phutil_require_module('phabricator', 'view/form/control/text');
|
||||
phutil_require_module('phabricator', 'view/form/error');
|
||||
phutil_require_module('phabricator', 'view/layout/panel');
|
||||
phutil_require_module('phabricator', 'view/utils');
|
||||
|
||||
phutil_require_module('phutil', 'filesystem');
|
||||
phutil_require_module('phutil', 'markup');
|
||||
phutil_require_module('phutil', 'parser/uri');
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorOAuthClientEditController.php');
|
|
@ -0,0 +1,140 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group oauthserver
|
||||
*/
|
||||
final class PhabricatorOAuthClientListController
|
||||
extends PhabricatorOAuthClientBaseController {
|
||||
|
||||
public function getFilter() {
|
||||
return 'client';
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$title = 'OAuth Clients';
|
||||
$request = $this->getRequest();
|
||||
$current_user = $request->getUser();
|
||||
$clients = id(new PhabricatorOAuthServerClient())
|
||||
->loadAllWhere('creatorPHID = %s',
|
||||
$current_user->getPHID());
|
||||
|
||||
$rows = array();
|
||||
$rowc = array();
|
||||
$highlight = $this->getHighlightPHIDs();
|
||||
foreach ($clients as $client) {
|
||||
$row = array(
|
||||
phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $client->getViewURI(),
|
||||
),
|
||||
phutil_escape_html($client->getName())
|
||||
),
|
||||
$client->getPHID(),
|
||||
phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $client->getRedirectURI(),
|
||||
),
|
||||
phutil_escape_html($client->getRedirectURI())
|
||||
),
|
||||
phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'class' => 'small button grey',
|
||||
'href' => $client->getEditURI(),
|
||||
),
|
||||
'Edit'
|
||||
),
|
||||
);
|
||||
|
||||
$rows[] = $row;
|
||||
if (isset($highlight[$client->getPHID()])) {
|
||||
$rowc[] = 'highlighted';
|
||||
} else {
|
||||
$rowc[] = '';
|
||||
}
|
||||
}
|
||||
|
||||
$panel = $this->buildClientList($rows, $rowc, $title);
|
||||
|
||||
return $this->buildStandardPageResponse(
|
||||
array($this->getNoticeView(),
|
||||
$panel),
|
||||
array('title' => $title)
|
||||
);
|
||||
}
|
||||
|
||||
private function buildClientList($rows, $rowc, $title) {
|
||||
$table = new AphrontTableView($rows);
|
||||
$table->setRowClasses($rowc);
|
||||
$table->setHeaders(
|
||||
array(
|
||||
'Client',
|
||||
'ID',
|
||||
'Redirect URI',
|
||||
'',
|
||||
));
|
||||
$table->setColumnClasses(
|
||||
array(
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'action',
|
||||
));
|
||||
if (empty($rows)) {
|
||||
$table->setNoDataString(
|
||||
'You have not created any clients for this OAuthServer.'
|
||||
);
|
||||
}
|
||||
|
||||
$panel = new AphrontPanelView();
|
||||
$panel->appendChild($table);
|
||||
$panel->setHeader($title);
|
||||
|
||||
return $panel;
|
||||
}
|
||||
|
||||
private function getNoticeView() {
|
||||
$edited = $this->getRequest()->getStr('edited');
|
||||
$new = $this->getRequest()->getStr('new');
|
||||
$deleted = $this->getRequest()->getBool('deleted');
|
||||
if ($edited) {
|
||||
$edited = phutil_escape_html($edited);
|
||||
$title = 'Successfully edited client with id '.$edited.'.';
|
||||
} else if ($new) {
|
||||
$new = phutil_escape_html($new);
|
||||
$title = 'Successfully created client with id '.$new.'.';
|
||||
} else if ($deleted) {
|
||||
$title = 'Successfully deleted client.';
|
||||
} else {
|
||||
$title = null;
|
||||
}
|
||||
|
||||
if ($title) {
|
||||
$view = new AphrontErrorView();
|
||||
$view->setTitle($title);
|
||||
$view->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
|
||||
} else {
|
||||
$view = null;
|
||||
}
|
||||
|
||||
return $view;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/controller/client/base');
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/storage/client');
|
||||
phutil_require_module('phabricator', 'view/control/table');
|
||||
phutil_require_module('phabricator', 'view/form/error');
|
||||
phutil_require_module('phabricator', 'view/layout/panel');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorOAuthClientListController.php');
|
|
@ -0,0 +1,134 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group oauthserver
|
||||
*/
|
||||
final class PhabricatorOAuthClientViewController
|
||||
extends PhabricatorOAuthClientBaseController {
|
||||
|
||||
protected function getFilter() {
|
||||
return 'client/view/'.$this->getClientPHID();
|
||||
}
|
||||
|
||||
protected function getExtraClientFilters() {
|
||||
return array(
|
||||
array('url' => $this->getFilter(),
|
||||
'label' => 'View Client')
|
||||
);
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$current_user = $request->getUser();
|
||||
$error = null;
|
||||
$phid = $this->getClientPHID();
|
||||
|
||||
$client = id(new PhabricatorOAuthServerClient())
|
||||
->loadOneWhere('phid = %s',
|
||||
$phid);
|
||||
$title = 'View OAuth Client';
|
||||
|
||||
// validate the client
|
||||
if (empty($client)) {
|
||||
$message = 'No client found with id '.$phid.'.';
|
||||
return $this->buildStandardPageResponse(
|
||||
$this->buildErrorView($message),
|
||||
array('title' => $title)
|
||||
);
|
||||
}
|
||||
|
||||
$panel = new AphrontPanelView();
|
||||
$panel->setHeader($title);
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($current_user)
|
||||
->appendChild(
|
||||
id(new AphrontFormStaticControl())
|
||||
->setLabel('Name')
|
||||
->setValue($client->getName())
|
||||
)
|
||||
->appendChild(
|
||||
id(new AphrontFormStaticControl())
|
||||
->setLabel('ID')
|
||||
->setValue($phid)
|
||||
);
|
||||
if ($current_user->getPHID() == $client->getCreatorPHID()) {
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormStaticControl())
|
||||
->setLabel('Secret')
|
||||
->setValue($client->getSecret())
|
||||
);
|
||||
}
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormStaticControl())
|
||||
->setLabel('Redirect URI')
|
||||
->setValue($client->getRedirectURI())
|
||||
);
|
||||
$created = phabricator_datetime($client->getDateCreated(),
|
||||
$current_user);
|
||||
$updated = phabricator_datetime($client->getDateModified(),
|
||||
$current_user);
|
||||
$form
|
||||
->appendChild(
|
||||
id(new AphrontFormStaticControl())
|
||||
->setLabel('Created')
|
||||
->setValue($created)
|
||||
)
|
||||
->appendChild(
|
||||
id(new AphrontFormStaticControl())
|
||||
->setLabel('Last Updated')
|
||||
->setValue($updated)
|
||||
);
|
||||
$panel->appendChild($form);
|
||||
$admin_panel = null;
|
||||
if ($client->getCreatorPHID() == $current_user->getPHID()) {
|
||||
$edit_button = phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $client->getEditURI(),
|
||||
'class' => 'grey button',
|
||||
),
|
||||
'Edit OAuth Client');
|
||||
$panel->addButton($edit_button);
|
||||
|
||||
$create_authorization_form = id(new AphrontFormView())
|
||||
->setUser($current_user)
|
||||
->addHiddenInput('action', 'testclientauthorization')
|
||||
->addHiddenInput('client_phid', $phid)
|
||||
->setAction('/oauthserver/test/')
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue('Create Scopeless Test Authorization')
|
||||
);
|
||||
$admin_panel = id(new AphrontPanelView())
|
||||
->setHeader('Admin Tools')
|
||||
->appendChild($create_authorization_form);
|
||||
}
|
||||
|
||||
return $this->buildStandardPageResponse(
|
||||
array($error,
|
||||
$panel,
|
||||
$admin_panel
|
||||
),
|
||||
array('title' => $title)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/controller/client/base');
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/storage/client');
|
||||
phutil_require_module('phabricator', 'view/form/base');
|
||||
phutil_require_module('phabricator', 'view/form/control/static');
|
||||
phutil_require_module('phabricator', 'view/form/control/submit');
|
||||
phutil_require_module('phabricator', 'view/layout/panel');
|
||||
phutil_require_module('phabricator', 'view/utils');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorOAuthClientViewController.php');
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group oauthserver
|
||||
*/
|
||||
abstract class PhabricatorOAuthClientAuthorizationBaseController
|
||||
extends PhabricatorOAuthServerController {
|
||||
|
||||
private $authorizationPHID;
|
||||
protected function getAuthorizationPHID() {
|
||||
return $this->authorizationPHID;
|
||||
}
|
||||
private function setAuthorizationPHID($phid) {
|
||||
$this->authorizationPHID = $phid;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function shouldRequireLogin() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->setAuthorizationPHID(idx($data, 'phid'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/controller/base');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorOAuthClientAuthorizationBaseController.php');
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group oauthserver
|
||||
*/
|
||||
final class PhabricatorOAuthClientAuthorizationDeleteController
|
||||
extends PhabricatorOAuthClientAuthorizationBaseController {
|
||||
|
||||
public function processRequest() {
|
||||
$phid = $this->getAuthorizationPHID();
|
||||
$title = 'Delete OAuth Client Authorization';
|
||||
$request = $this->getRequest();
|
||||
$current_user = $request->getUser();
|
||||
$authorization = id(new PhabricatorOAuthClientAuthorization())
|
||||
->loadOneWhere('phid = %s',
|
||||
$phid);
|
||||
|
||||
if (empty($authorization)) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
if ($authorization->getUserPHID() != $current_user->getPHID()) {
|
||||
$message = 'Access denied to client authorization with phid '.$phid.'. '.
|
||||
'Only the user who authorized the client has permission to '.
|
||||
'delete the authorization.';
|
||||
return id(new Aphront403Response())
|
||||
->setForbiddenText($message);
|
||||
}
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$authorization->delete();
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/oauthserver/clientauthorization/?notice=deleted');
|
||||
}
|
||||
|
||||
$client_phid = $authorization->getClientPHID();
|
||||
$client = id(new PhabricatorOAuthServerClient())
|
||||
->loadOneWhere('phid = %s',
|
||||
$client_phid);
|
||||
if ($client) {
|
||||
$client_name = phutil_escape_html($client->getName());
|
||||
$title .= ' for '.$client_name;
|
||||
} else {
|
||||
// the client does not exist so token is dead already (but
|
||||
// let's let the user clean this up anyway in that case)
|
||||
$client_name = '';
|
||||
}
|
||||
|
||||
$dialog = new AphrontDialogView();
|
||||
$dialog->setUser($current_user);
|
||||
$dialog->setTitle($title);
|
||||
$dialog->appendChild(
|
||||
'<p>Are you sure you want to delete this client authorization?</p>'
|
||||
);
|
||||
$dialog->addSubmitButton();
|
||||
$dialog->addCancelButton($authorization->getEditURI());
|
||||
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'aphront/response/403');
|
||||
phutil_require_module('phabricator', 'aphront/response/404');
|
||||
phutil_require_module('phabricator', 'aphront/response/dialog');
|
||||
phutil_require_module('phabricator', 'aphront/response/redirect');
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/controller/clientauthorization/base');
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/storage/client');
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/storage/clientauthorization');
|
||||
phutil_require_module('phabricator', 'view/dialog');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorOAuthClientAuthorizationDeleteController.php');
|
|
@ -0,0 +1,114 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group oauthserver
|
||||
*/
|
||||
final class PhabricatorOAuthClientAuthorizationEditController
|
||||
extends PhabricatorOAuthClientAuthorizationBaseController {
|
||||
|
||||
public function processRequest() {
|
||||
$phid = $this->getAuthorizationPHID();
|
||||
$title = 'Edit OAuth Client Authorization';
|
||||
$request = $this->getRequest();
|
||||
$current_user = $request->getUser();
|
||||
$authorization = id(new PhabricatorOAuthClientAuthorization())
|
||||
->loadOneWhere('phid = %s',
|
||||
$phid);
|
||||
|
||||
if (empty($authorization)) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
if ($authorization->getUserPHID() != $current_user->getPHID()) {
|
||||
$message = 'Access denied to client authorization with phid '.$phid.'. '.
|
||||
'Only the user who authorized the client has permission to '.
|
||||
'edit the authorization.';
|
||||
return id(new Aphront403Response())
|
||||
->setForbiddenText($message);
|
||||
}
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$scopes = PhabricatorOAuthServerScope::getScopesFromRequest($request);
|
||||
$authorization->setScope($scopes);
|
||||
$authorization->save();
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/oauthserver/clientauthorization/?edited='.$phid);
|
||||
}
|
||||
|
||||
$client_phid = $authorization->getClientPHID();
|
||||
$client = id(new PhabricatorOAuthServerClient())
|
||||
->loadOneWhere('phid = %s',
|
||||
$client_phid);
|
||||
|
||||
$created = phabricator_datetime($authorization->getDateCreated(),
|
||||
$current_user);
|
||||
$updated = phabricator_datetime($authorization->getDateModified(),
|
||||
$current_user);
|
||||
|
||||
$panel = new AphrontPanelView();
|
||||
$delete_button = phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $authorization->getDeleteURI(),
|
||||
'class' => 'grey button',
|
||||
),
|
||||
'Delete OAuth Client Authorization');
|
||||
$panel->addButton($delete_button);
|
||||
$panel->setHeader($title);
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($current_user)
|
||||
->appendChild(
|
||||
id(new AphrontFormMarkupControl())
|
||||
->setLabel('Client')
|
||||
->setValue(
|
||||
phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $client->getViewURI(),
|
||||
),
|
||||
phutil_escape_html($client->getName())))
|
||||
)
|
||||
->appendChild(
|
||||
id(new AphrontFormStaticControl())
|
||||
->setLabel('Created')
|
||||
->setValue($created)
|
||||
)
|
||||
->appendChild(
|
||||
id(new AphrontFormStaticControl())
|
||||
->setLabel('Last Updated')
|
||||
->setValue($updated)
|
||||
)
|
||||
->appendChild(
|
||||
PhabricatorOAuthServerScope::getCheckboxControl(
|
||||
$authorization->getScope()
|
||||
)
|
||||
)
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue('Save OAuth Client Authorization')
|
||||
->addCancelButton('/oauthserver/clientauthorization/')
|
||||
);
|
||||
|
||||
$panel->appendChild($form);
|
||||
return $this->buildStandardPageResponse(
|
||||
$panel,
|
||||
array('title' => $title)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'aphront/response/403');
|
||||
phutil_require_module('phabricator', 'aphront/response/404');
|
||||
phutil_require_module('phabricator', 'aphront/response/redirect');
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/controller/clientauthorization/base');
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/scope');
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/storage/client');
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/storage/clientauthorization');
|
||||
phutil_require_module('phabricator', 'view/form/base');
|
||||
phutil_require_module('phabricator', 'view/form/control/markup');
|
||||
phutil_require_module('phabricator', 'view/form/control/static');
|
||||
phutil_require_module('phabricator', 'view/form/control/submit');
|
||||
phutil_require_module('phabricator', 'view/layout/panel');
|
||||
phutil_require_module('phabricator', 'view/utils');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorOAuthClientAuthorizationEditController.php');
|
|
@ -0,0 +1,161 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Copyright 2012 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @group oauthserver
|
||||
*/
|
||||
final class PhabricatorOAuthClientAuthorizationListController
|
||||
extends PhabricatorOAuthClientAuthorizationBaseController {
|
||||
|
||||
protected function getFilter() {
|
||||
return 'clientauthorization';
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$title = 'OAuth Client Authorizations';
|
||||
$request = $this->getRequest();
|
||||
$current_user = $request->getUser();
|
||||
$authorizations = id(new PhabricatorOAuthClientAuthorization())
|
||||
->loadAllWhere('userPHID = %s',
|
||||
$current_user->getPHID());
|
||||
|
||||
$client_authorizations = mpull($authorizations, null, 'getClientPHID');
|
||||
$client_phids = array_keys($client_authorizations);
|
||||
if ($client_phids) {
|
||||
$clients = id(new PhabricatorOAuthServerClient())
|
||||
->loadAllWhere('phid in (%Ls)',
|
||||
$client_phids);
|
||||
} else {
|
||||
$clients = array();
|
||||
}
|
||||
$client_dict = mpull($clients, null, 'getPHID');
|
||||
|
||||
$rows = array();
|
||||
$rowc = array();
|
||||
$highlight = $this->getHighlightPHIDs();
|
||||
foreach ($client_authorizations as $client_phid => $authorization) {
|
||||
$client = $client_dict[$client_phid];
|
||||
$created = phabricator_datetime($authorization->getDateCreated(),
|
||||
$current_user);
|
||||
$updated = phabricator_datetime($authorization->getDateModified(),
|
||||
$current_user);
|
||||
$row = array(
|
||||
phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $client->getViewURI(),
|
||||
),
|
||||
phutil_escape_html($client->getName())
|
||||
),
|
||||
phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => 'TODO - link to scope about',
|
||||
),
|
||||
$authorization->getScopeString()
|
||||
),
|
||||
phabricator_datetime(
|
||||
$authorization->getDateCreated(),
|
||||
$current_user
|
||||
),
|
||||
phabricator_datetime(
|
||||
$authorization->getDateModified(),
|
||||
$current_user
|
||||
),
|
||||
phutil_render_tag(
|
||||
'a',
|
||||
array(
|
||||
'class' => 'small button grey',
|
||||
'href' => $authorization->getEditURI(),
|
||||
),
|
||||
'Edit'
|
||||
),
|
||||
);
|
||||
|
||||
$rows[] = $row;
|
||||
if (isset($highlight[$authorization->getPHID()])) {
|
||||
$rowc[] = 'highlighted';
|
||||
} else {
|
||||
$rowc[] = '';
|
||||
}
|
||||
}
|
||||
|
||||
$panel = $this->buildClientAuthorizationList($rows, $rowc, $title);
|
||||
|
||||
return $this->buildStandardPageResponse(
|
||||
array($this->getNoticeView(),
|
||||
$panel),
|
||||
array('title' => $title)
|
||||
);
|
||||
}
|
||||
|
||||
private function buildClientAuthorizationList($rows, $rowc, $title) {
|
||||
$table = new AphrontTableView($rows);
|
||||
$table->setRowClasses($rowc);
|
||||
$table->setHeaders(
|
||||
array(
|
||||
'Client',
|
||||
'Scope',
|
||||
'Created',
|
||||
'Updated',
|
||||
'',
|
||||
));
|
||||
$table->setColumnClasses(
|
||||
array(
|
||||
'wide pri',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'action',
|
||||
));
|
||||
if (empty($rows)) {
|
||||
$table->setNoDataString(
|
||||
'You have not authorized any clients for this OAuthServer.'
|
||||
);
|
||||
}
|
||||
|
||||
$panel = new AphrontPanelView();
|
||||
$panel->appendChild($table);
|
||||
$panel->setHeader($title);
|
||||
|
||||
return $panel;
|
||||
}
|
||||
|
||||
private function getNoticeView() {
|
||||
$edited = $this->getRequest()->getStr('edited');
|
||||
$deleted = $this->getRequest()->getBool('deleted');
|
||||
if ($edited) {
|
||||
$edited = phutil_escape_html($edited);
|
||||
$title = 'Successfully edited client authorization.';
|
||||
} else if ($deleted) {
|
||||
$title = 'Successfully deleted client authorization.';
|
||||
} else {
|
||||
$title = null;
|
||||
}
|
||||
|
||||
if ($title) {
|
||||
$view = new AphrontErrorView();
|
||||
$view->setTitle($title);
|
||||
$view->setSeverity(AphrontErrorView::SEVERITY_NOTICE);
|
||||
} else {
|
||||
$view = null;
|
||||
}
|
||||
|
||||
return $view;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/controller/clientauthorization/base');
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/storage/client');
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/storage/clientauthorization');
|
||||
phutil_require_module('phabricator', 'view/control/table');
|
||||
phutil_require_module('phabricator', 'view/form/error');
|
||||
phutil_require_module('phabricator', 'view/layout/panel');
|
||||
phutil_require_module('phabricator', 'view/utils');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorOAuthClientAuthorizationListController.php');
|
|
@ -20,69 +20,50 @@
|
|||
* @group oauthserver
|
||||
*/
|
||||
final class PhabricatorOAuthServerTestController
|
||||
extends PhabricatorAuthController {
|
||||
extends PhabricatorOAuthServerController {
|
||||
|
||||
public function shouldRequireLogin() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function shouldRequireAdmin() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$current_user = $request->getUser();
|
||||
$server = new PhabricatorOAuthServer($current_user);
|
||||
|
||||
$forms = array();
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($current_user)
|
||||
->appendChild(
|
||||
id(new AphrontFormStaticControl())
|
||||
->setValue('Create Test Client'))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel('Name')
|
||||
->setName('name')
|
||||
->setValue(''))
|
||||
->appendChild(
|
||||
id(new AphrontFormTextControl())
|
||||
->setLabel('Redirect URI')
|
||||
->setName('redirect_uri')
|
||||
->setValue(''))
|
||||
->appendChild(
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue('Create Client'));
|
||||
$forms[] = $form;
|
||||
$result = array();
|
||||
if ($request->isFormPost()) {
|
||||
$name = $request->getStr('name');
|
||||
$redirect_uri = $request->getStr('redirect_uri');
|
||||
$secret = Filesystem::readRandomCharacters(32);
|
||||
$client = new PhabricatorOAuthServerClient();
|
||||
$client->setName($name);
|
||||
$client->setSecret($secret);
|
||||
$client->setCreatorPHID($current_user->getPHID());
|
||||
$client->setRedirectURI($redirect_uri);
|
||||
$client->save();
|
||||
$id = $client->getID();
|
||||
$phid = $client->getPHID();
|
||||
$name = phutil_escape_html($name);
|
||||
$panels = array();
|
||||
$results = array();
|
||||
$results[] = "New client named {$name} with secret {$secret}.";
|
||||
$results[] = "Client has id {$id} and phid {$phid}.";
|
||||
$result = implode('<br />', $results);
|
||||
}
|
||||
$title = 'Test OAuthServer Stuff';
|
||||
$panel = new AphrontPanelView();
|
||||
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
|
||||
$panel->setHeader($title);
|
||||
$panel->appendChild($result);
|
||||
$panel->appendChild($forms);
|
||||
|
||||
return $this->buildStandardPageResponse(
|
||||
$panel,
|
||||
array('title' => $title));
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$action = $request->getStr('action');
|
||||
switch ($action) {
|
||||
case 'testclientauthorization':
|
||||
$user_phid = $current_user->getPHID();
|
||||
$client_phid = $request->getStr('client_phid');
|
||||
$client = id(new PhabricatorOAuthServerClient)
|
||||
->loadOneWhere('phid = %s', $client_phid);
|
||||
if (!$client) {
|
||||
throw new Exception('Failed to load client!');
|
||||
}
|
||||
if ($client->getCreatorPHID() != $user_phid ||
|
||||
$current_user->getPHID() != $user_phid) {
|
||||
throw new Exception(
|
||||
'Only allowed to make test data for yourself '.
|
||||
'for clients you own!'
|
||||
);
|
||||
}
|
||||
// blankclientauthorizations don't get scope
|
||||
$scope = array();
|
||||
$server->setUser($current_user);
|
||||
$server->setClient($client);
|
||||
$authorization = $server->authorizeClient($scope);
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI('/oauthserver/clientauthorization/?edited='.
|
||||
$authorization->getPHID());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,17 +6,11 @@
|
|||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/auth/controller/base');
|
||||
phutil_require_module('phabricator', 'aphront/response/redirect');
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/controller/base');
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/server');
|
||||
phutil_require_module('phabricator', 'applications/oauthserver/storage/client');
|
||||
phutil_require_module('phabricator', 'view/form/base');
|
||||
phutil_require_module('phabricator', 'view/form/control/static');
|
||||
phutil_require_module('phabricator', 'view/form/control/submit');
|
||||
phutil_require_module('phabricator', 'view/form/control/text');
|
||||
phutil_require_module('phabricator', 'view/layout/panel');
|
||||
|
||||
phutil_require_module('phutil', 'filesystem');
|
||||
phutil_require_module('phutil', 'markup');
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
|
|
|
@ -34,4 +34,48 @@ final class PhabricatorOAuthServerScope {
|
|||
);
|
||||
}
|
||||
|
||||
static public function getCheckboxControl($current_scopes) {
|
||||
$scopes = self::getScopesDict();
|
||||
$scope_keys = array_keys($scopes);
|
||||
sort($scope_keys);
|
||||
|
||||
$checkboxes = new AphrontFormCheckboxControl();
|
||||
foreach ($scope_keys as $scope) {
|
||||
$checkboxes->addCheckbox(
|
||||
$name = $scope,
|
||||
$value = 1,
|
||||
$label = self::getCheckboxLabel($scope),
|
||||
$checked = isset($current_scopes[$scope])
|
||||
);
|
||||
}
|
||||
$checkboxes->setLabel('Scope');
|
||||
|
||||
return $checkboxes;
|
||||
}
|
||||
|
||||
static private function getCheckboxLabel($scope) {
|
||||
$label = null;
|
||||
switch ($scope) {
|
||||
case self::SCOPE_OFFLINE_ACCESS:
|
||||
$label = 'Make access tokens granted to this client never expire.';
|
||||
break;
|
||||
case self::SCOPE_WHOAMI:
|
||||
$label = 'Read access to Conduit method user.whoami.';
|
||||
break;
|
||||
}
|
||||
|
||||
return $label;
|
||||
}
|
||||
|
||||
static public function getScopesFromRequest(AphrontRequest $request) {
|
||||
$scopes = self::getScopesDict();
|
||||
$requested_scopes = array();
|
||||
foreach ($scopes as $scope => $bit) {
|
||||
if ($request->getBool($scope)) {
|
||||
$requested_scopes[$scope] = 1;
|
||||
}
|
||||
}
|
||||
return $requested_scopes;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,5 +6,7 @@
|
|||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'view/form/control/checkbox');
|
||||
|
||||
|
||||
phutil_require_source('PhabricatorOAuthServerScope.php');
|
||||
|
|
|
@ -108,6 +108,8 @@ final class PhabricatorOAuthServer {
|
|||
$authorization->setClientPHID($this->getClient()->getPHID());
|
||||
$authorization->setScope($scope);
|
||||
$authorization->save();
|
||||
|
||||
return $authorization;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -29,6 +29,18 @@ extends PhabricatorOAuthServerDAO {
|
|||
protected $redirectURI;
|
||||
protected $creatorPHID;
|
||||
|
||||
public function getEditURI() {
|
||||
return '/oauthserver/client/edit/'.$this->getPHID().'/';
|
||||
}
|
||||
|
||||
public function getViewURI() {
|
||||
return '/oauthserver/client/view/'.$this->getPHID().'/';
|
||||
}
|
||||
|
||||
public function getDeleteURI() {
|
||||
return '/oauthserver/client/delete/'.$this->getPHID().'/';
|
||||
}
|
||||
|
||||
public function getConfiguration() {
|
||||
return array(
|
||||
self::CONFIG_AUX_PHID => true,
|
||||
|
|
|
@ -28,6 +28,21 @@ extends PhabricatorOAuthServerDAO {
|
|||
protected $clientPHID;
|
||||
protected $scope;
|
||||
|
||||
public function getEditURI() {
|
||||
return '/oauthserver/clientauthorization/edit/'.$this->getPHID().'/';
|
||||
}
|
||||
|
||||
public function getDeleteURI() {
|
||||
return '/oauthserver/clientauthorization/delete/'.$this->getPHID().'/';
|
||||
}
|
||||
|
||||
public function getScopeString() {
|
||||
$scope = $this->getScope();
|
||||
$scopes = array_keys($scope);
|
||||
sort($scopes);
|
||||
return implode(', ', $scopes);
|
||||
}
|
||||
|
||||
public function getConfiguration() {
|
||||
return array(
|
||||
self::CONFIG_AUX_PHID => true,
|
||||
|
|
|
@ -95,7 +95,10 @@ final class AphrontPanelView extends AphrontView {
|
|||
implode(" ", $this->buttons).
|
||||
'</div>';
|
||||
}
|
||||
|
||||
$header_elements =
|
||||
'<div class="aphront-panel-header">'.
|
||||
$buttons.$header.$caption.
|
||||
'</div>';
|
||||
$table = $this->renderChildren();
|
||||
|
||||
require_celerity_resource('aphront-panel-view-css');
|
||||
|
@ -112,7 +115,7 @@ final class AphrontPanelView extends AphrontView {
|
|||
'class' => implode(' ', $classes),
|
||||
'id' => $this->id,
|
||||
),
|
||||
$buttons.$header.$caption.$table);
|
||||
$header_elements.$table);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -99,7 +99,8 @@
|
|||
}
|
||||
|
||||
|
||||
.aphront-form-control-static .aphront-form-input {
|
||||
.aphront-form-control-static .aphront-form-input,
|
||||
.aphront-form-control-markup .aphront-form-input {
|
||||
padding-top: 4px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
|
|
@ -11,16 +11,20 @@
|
|||
margin: 1em 2em;
|
||||
}
|
||||
|
||||
.aphront-panel-view .aphront-panel-header {
|
||||
margin: 0 0 1em 0;
|
||||
}
|
||||
|
||||
.aphront-panel-view h1 {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
padding: 2px 0 8px;
|
||||
padding: 4px 0 0 0;
|
||||
}
|
||||
|
||||
.aphront-panel-view-caption {
|
||||
font-size: 11px;
|
||||
color: #666666;
|
||||
margin-top: -0.75em;
|
||||
margin-top: -0.1em;
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue