Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support the 'password' grant type for OAuth2 clients #25894

Open
p5n opened this issue Mar 2, 2021 · 2 comments
Open

Support the 'password' grant type for OAuth2 clients #25894

p5n opened this issue Mar 2, 2021 · 2 comments

Comments

@p5n
Copy link
Contributor

p5n commented Mar 2, 2021

How to use GitHub

  • Please use the 👍 reaction to show that you are interested into the same feature.
  • Please don't comment if you have no relevant information to add. It's just extra noise for everyone subscribed to this issue.
  • Subscribe to receive notifications on status change and new comments.

grant_type=password is convenient way to set up application passwords for mail clients using dovecot mail server. I implemented draft which looks working but only for dovecot, Dovecot just checks token existence to decide if user can login or not.

--- OauthApiController.php	2021-02-21 10:56:58.000000000 -0700
+++ OauthApiController.php.my	2021-03-02 12:22:31.023346218 -0700
@@ -90,15 +90,38 @@
 	 * @param string $client_secret
 	 * @return JSONResponse
 	 */
-	public function getToken($grant_type, $code, $refresh_token, $client_id, $client_secret): JSONResponse {
+	public function getToken($grant_type, $code, $refresh_token, $client_id, $client_secret, $username, $password): JSONResponse {
 
 		// We only handle two types
-		if ($grant_type !== 'authorization_code' && $grant_type !== 'refresh_token') {
+		if ($grant_type !== 'authorization_code' && $grant_type !== 'refresh_token' && $grant_type !== 'password') {
 			return new JSONResponse([
 				'error' => 'invalid_grant',
 			], Http::STATUS_BAD_REQUEST);
 		}
 
+		if ($grant_type === 'password') {
+			try {
+				$client = $this->clientMapper->getByIdentifier($client_id);
+			} catch (ClientNotFoundException $e) {
+				return new JSONResponse(['error' => 'invalid_client'], Http::STATUS_BAD_REQUEST);
+			}
+
+			if ($client->getClientIdentifier() !== $client_id || $client->getSecret() !== $client_secret) {
+				return new JSONResponse(['error' => 'invalid_client'], Http::STATUS_BAD_REQUEST);
+			}
+
+			try {
+				$token = $this->tokenProvider->getToken($password);
+				if ($token->getLoginName() !== $username) {
+					return new JSONResponse(['error' => 'Forbidden'], Http::STATUS_FORBIDDEN);
+				}
+			} catch (InvalidTokenException $e) {
+				return new JSONResponse(['error' => 'Invalid app password'], Http::STATUS_FORBIDDEN);
+			}
+
+			return new JSONResponse(['access_token' => 'fake-for-dovecot', 'username' => $username], Http::STATUS_OK);
+		}
+
 		// We handle the initial and refresh tokens the same way
 		if ($grant_type === 'refresh_token') {
 			$code = $refresh_token;
@p5n p5n added enhancement 0. Needs triage Pending check for reproducibility or if it fits our roadmap labels Mar 2, 2021
@szaimen
Copy link
Contributor

szaimen commented Jun 23, 2021

Hi p5n, do you mind creating a PR with your patch for discussion?
Thank you!

@p5n
Copy link
Contributor Author

p5n commented Jul 5, 2021

#27806

Not sure about access-token. It works with dovecot as implemented, but maybe we need to get something more proper.

@szaimen szaimen added 2. developing Work in progress feature: authentication and removed 0. Needs triage Pending check for reproducibility or if it fits our roadmap needs info labels Jul 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants