Skip to content

Commit 8f2c426

Browse files
committed
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
1 parent d94129b commit 8f2c426

File tree

4 files changed

+33
-11
lines changed

4 files changed

+33
-11
lines changed

src/applications/oauthserver/controller/auth/PhabricatorOAuthServerAuthController.php

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,18 @@ public function processRequest() {
115115
$scope = PhabricatorOAuthServerScope::scopesListToDict($scope);
116116
}
117117

118-
$authorization = $server->userHasAuthorizedClient($scope);
119-
if ($authorization) {
118+
list($is_authorized,
119+
$authorization) = $server->userHasAuthorizedClient($scope);
120+
if ($is_authorized) {
120121
$return_auth_code = true;
121122
$unguarded_write = AphrontWriteGuard::beginScopedUnguardedWrites();
122123
} else if ($request->isFormPost()) {
123124
$scope = PhabricatorOAuthServerScope::getScopesFromRequest($request);
124-
$authorization = $server->authorizeClient($scope);
125+
if ($authorization) {
126+
$authorization->setScope($scope)->save();
127+
} else {
128+
$authorization = $server->authorizeClient($scope);
129+
}
125130
$return_auth_code = true;
126131
$unguarded_write = null;
127132
} else {
@@ -140,7 +145,7 @@ public function processRequest() {
140145
'scope' => $authorization->getScopeString(),
141146
);
142147
$response->setContent($content);
143-
return $response->setClientURI($uri);
148+
return $response;
144149
}
145150
unset($unguarded_write);
146151
} catch (Exception $e) {
@@ -167,7 +172,12 @@ public function processRequest() {
167172
"Phabricator account data?";
168173

169174
if ($scope) {
170-
$desired_scopes = $scope;
175+
if ($authorization) {
176+
$desired_scopes = array_merge($scope,
177+
$authorization->getScope());
178+
} else {
179+
$desired_scopes = $scope;
180+
}
171181
if (!PhabricatorOAuthServerScope::validateScopesDict($desired_scopes)) {
172182
$response->setError('invalid_scope');
173183
$response->setErrorDescription(
@@ -182,7 +192,7 @@ public function processRequest() {
182192
);
183193
}
184194

185-
$cancel_uri = $this->getClientURI($client, $redirect_uri);
195+
$cancel_uri = clone $uri;
186196
$cancel_params = array(
187197
'error' => 'access_denied',
188198
'error_description' =>
@@ -197,7 +207,7 @@ public function processRequest() {
197207
->setValue($description)
198208
)
199209
->appendChild(
200-
PhabricatorOAuthServerScope::getCheckboxControl()
210+
PhabricatorOAuthServerScope::getCheckboxControl($desired_scopes)
201211
)
202212
->appendChild(
203213
id(new AphrontFormSubmitControl())

src/applications/oauthserver/controller/client/edit/PhabricatorOAuthClientEditController.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ public function processRequest() {
109109
$bad_redirect = true;
110110
} else {
111111
$client->save();
112+
// refresh the phid in case its a create
113+
$phid = $client->getPHID();
112114
if ($this->isClientEdit()) {
113115
return id(new AphrontRedirectResponse())
114116
->setURI('/oauthserver/client/?edited='.$phid);

src/applications/oauthserver/scope/PhabricatorOAuthServerScope.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,14 @@ static public function validateScopesDict($scope_dict) {
110110
return empty($unknown_scopes);
111111
}
112112

113-
static public function scopesListToDict($scope_list) {
114-
return array_fill_keys($scope_list, 1);
113+
/**
114+
* Transforms a space-delimited scopes list into a scopes dict. The list
115+
* should be validated by @{method:validateScopesList} before
116+
* transformation.
117+
*/
118+
static public function scopesListToDict($scope_list) {
119+
$scopes = explode(' ', $scope_list);
120+
return array_fill_keys($scopes, 1);
115121
}
116122

117123
}

src/applications/oauthserver/server/PhabricatorOAuthServer.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,17 @@ public function setClient(PhabricatorOAuthServerClient $client) {
8484

8585
/**
8686
* @task auth
87+
* @return tuple <bool hasAuthorized, ClientAuthorization or null>
8788
*/
8889
public function userHasAuthorizedClient(array $scope) {
8990

9091
$authorization = id(new PhabricatorOAuthClientAuthorization())->
9192
loadOneWhere('userPHID = %s AND clientPHID = %s',
9293
$this->getUser()->getPHID(),
9394
$this->getClient()->getPHID());
95+
if (empty($authorization)) {
96+
return array(false, null);
97+
}
9498

9599
if ($scope) {
96100
$missing_scope = array_diff_key($scope,
@@ -100,10 +104,10 @@ public function userHasAuthorizedClient(array $scope) {
100104
}
101105

102106
if ($missing_scope) {
103-
return false;
107+
return array(false, $authorization);
104108
}
105109

106-
return $authorization;
110+
return array(true, $authorization);
107111
}
108112

109113
/**

0 commit comments

Comments
 (0)