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:
Bob Trahan
2012-02-22 10:21:39 -08:00
parent 5f46a61e6d
commit 3c4070a168
35 changed files with 1450 additions and 78 deletions

View File

@@ -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'));
}
}

View File

@@ -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');

View File

@@ -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);
}
}

View File

@@ -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');

View File

@@ -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)
);
}
}

View File

@@ -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');

View File

@@ -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;
}
}

View File

@@ -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');