1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-20 13:52:40 +01:00

Fix OAuth Client Authorization bugs

Summary: ajtrichards reported an error creating a brand new authorization. fixed that and generally made this flow work well

Test Plan:
- created a fresh test client
-- noted "new=<PHID>" with appropriate highlighting
- visited http://phabricator.dev/oauthserver/auth/?client_id=PHID-OASC-jwgdrqdpzomtxyg3q3yf&response_type=code&scope=offline_access
-- clicked "cancel", verified result
-- clicked "approve", verfied result
- visited http://phabricator.dev/oauthserver/auth/?client_id=PHID-OASC-jwgdrqdpzomtxyg3q3yf&response_type=code&scope=whoami
-- noted got the dialog
-- noted that it had the union of desired and existing so user could update it properly! (NB - its up to the client to react to whatever specific scope(s) the user decides to grant)
-- noted it actually updated when I hit "approve"

Reviewers: epriestley, ajtrichards

Reviewed By: epriestley

CC: aran, epriestley

Maniphest Tasks: T933

Differential Revision: https://secure.phabricator.com/D1775
This commit is contained in:
Bob Trahan 2012-03-05 13:27:20 -08:00
parent d94129b739
commit 8f2c426ff2
4 changed files with 33 additions and 11 deletions

View file

@ -115,13 +115,18 @@ extends PhabricatorAuthController {
$scope = PhabricatorOAuthServerScope::scopesListToDict($scope);
}
$authorization = $server->userHasAuthorizedClient($scope);
if ($authorization) {
list($is_authorized,
$authorization) = $server->userHasAuthorizedClient($scope);
if ($is_authorized) {
$return_auth_code = true;
$unguarded_write = AphrontWriteGuard::beginScopedUnguardedWrites();
} else if ($request->isFormPost()) {
$scope = PhabricatorOAuthServerScope::getScopesFromRequest($request);
$authorization = $server->authorizeClient($scope);
if ($authorization) {
$authorization->setScope($scope)->save();
} else {
$authorization = $server->authorizeClient($scope);
}
$return_auth_code = true;
$unguarded_write = null;
} else {
@ -140,7 +145,7 @@ extends PhabricatorAuthController {
'scope' => $authorization->getScopeString(),
);
$response->setContent($content);
return $response->setClientURI($uri);
return $response;
}
unset($unguarded_write);
} catch (Exception $e) {
@ -167,7 +172,12 @@ extends PhabricatorAuthController {
"Phabricator account data?";
if ($scope) {
$desired_scopes = $scope;
if ($authorization) {
$desired_scopes = array_merge($scope,
$authorization->getScope());
} else {
$desired_scopes = $scope;
}
if (!PhabricatorOAuthServerScope::validateScopesDict($desired_scopes)) {
$response->setError('invalid_scope');
$response->setErrorDescription(
@ -182,7 +192,7 @@ extends PhabricatorAuthController {
);
}
$cancel_uri = $this->getClientURI($client, $redirect_uri);
$cancel_uri = clone $uri;
$cancel_params = array(
'error' => 'access_denied',
'error_description' =>
@ -197,7 +207,7 @@ extends PhabricatorAuthController {
->setValue($description)
)
->appendChild(
PhabricatorOAuthServerScope::getCheckboxControl()
PhabricatorOAuthServerScope::getCheckboxControl($desired_scopes)
)
->appendChild(
id(new AphrontFormSubmitControl())

View file

@ -109,6 +109,8 @@ extends PhabricatorOAuthClientBaseController {
$bad_redirect = true;
} else {
$client->save();
// refresh the phid in case its a create
$phid = $client->getPHID();
if ($this->isClientEdit()) {
return id(new AphrontRedirectResponse())
->setURI('/oauthserver/client/?edited='.$phid);

View file

@ -110,8 +110,14 @@ final class PhabricatorOAuthServerScope {
return empty($unknown_scopes);
}
static public function scopesListToDict($scope_list) {
return array_fill_keys($scope_list, 1);
/**
* Transforms a space-delimited scopes list into a scopes dict. The list
* should be validated by @{method:validateScopesList} before
* transformation.
*/
static public function scopesListToDict($scope_list) {
$scopes = explode(' ', $scope_list);
return array_fill_keys($scopes, 1);
}
}

View file

@ -84,6 +84,7 @@ final class PhabricatorOAuthServer {
/**
* @task auth
* @return tuple <bool hasAuthorized, ClientAuthorization or null>
*/
public function userHasAuthorizedClient(array $scope) {
@ -91,6 +92,9 @@ final class PhabricatorOAuthServer {
loadOneWhere('userPHID = %s AND clientPHID = %s',
$this->getUser()->getPHID(),
$this->getClient()->getPHID());
if (empty($authorization)) {
return array(false, null);
}
if ($scope) {
$missing_scope = array_diff_key($scope,
@ -100,10 +104,10 @@ final class PhabricatorOAuthServer {
}
if ($missing_scope) {
return false;
return array(false, $authorization);
}
return $authorization;
return array(true, $authorization);
}
/**