From 56d47ae8401b952bb3ae2fa29df495113e992987 Mon Sep 17 00:00:00 2001
From: flashwave
Date: Sat, 20 Jul 2024 00:26:16 +0000
Subject: [PATCH] Added refresh token flow.
---
oatmeal.php | 2 +-
src/HomeRoutes.php | 2 +-
src/RefreshTokenRoutes.php | 166 ++++++++++++++++++++++++++++++++++++-
3 files changed, 165 insertions(+), 5 deletions(-)
diff --git a/oatmeal.php b/oatmeal.php
index 8c5fc35..c4ad18f 100644
--- a/oatmeal.php
+++ b/oatmeal.php
@@ -25,7 +25,7 @@ $oatmeal = new OatmealContext((function() {
})());
$oatmeal->register(new HomeRoutes);
$oatmeal->register(new AuthzCodeRoutes($oatmeal->getCSRFP()));
-$oatmeal->register(new RefreshTokenRoutes);
+$oatmeal->register(new RefreshTokenRoutes($oatmeal->getCSRFP()));
$oatmeal->register(new ClientCredsRoutes);
$oatmeal->register(new PasswordRoutes);
$oatmeal->register(new DeviceCodeRoutes);
diff --git a/src/HomeRoutes.php b/src/HomeRoutes.php
index 313cd74..f4da78b 100644
--- a/src/HomeRoutes.php
+++ b/src/HomeRoutes.php
@@ -19,7 +19,7 @@ final class HomeRoutes extends RouteHandler {
I'm not going to bother with making this page look nice, the most you'll get it functional Javascript and/or CSS touch ups if really necessary.
-Select A Flow
+Select A Flow™
Authorisation code
Refresh token
diff --git a/src/RefreshTokenRoutes.php b/src/RefreshTokenRoutes.php
index 7b3d7c7..7063c2d 100644
--- a/src/RefreshTokenRoutes.php
+++ b/src/RefreshTokenRoutes.php
@@ -1,11 +1,171 @@
+
+Oatmeal / Refresh token
+
+Oatmeal / Refresh token
+
+ Enter the refresh token you obtained through the authorisation code flow to obtain a new access token.
+
+
+Return
+HTML;
+ }
+
+ #[HttpPost('/refresh_token')]
+ public function postRefreshToken($response, $request): string {
+ if(!$request->isFormContent())
+ return 400;
+ $content = $request->getContent();
+
+ $csrfp = (string)$content->getParam('csrfp');
+ if(!$this->csrfp->verifyToken($csrfp))
+ return 403;
+
+ $tokenUri = (string)$content->getParam('token_uri');
+ if(filter_var($tokenUri, FILTER_VALIDATE_URL) === false) {
+ $response->setStatusCode(400);
+ return <<
+
+Oatmeal / Refresh token
+Oatmeal / Refresh token
+Provided Token URI was not a valid absolute URI.
+Return
+HTML;
+ }
+
+ $clientId = (string)$content->getParam('client_id');
+ $clientSecret = (string)$content->getParam('client_secret');
+ $refreshToken = (string)$content->getParam('refresh_token');
+ $auth = (string)$content->getParam('auth');
+
+ $headers = [];
+ $body = [
+ 'grant_type' => 'refresh_token',
+ 'refresh_token' => $refreshToken,
+ ];
+
+ if($clientSecret === '')
+ $body['client_id'] = $clientId;
+ elseif($auth === 'body' || ($auth !== 'header' && mt_rand(0, 10) > 5)) {
+ $body['client_id'] = $clientId;
+ $body['client_secret'] = $clientSecret;
+ } else
+ $headers[] = sprintf('Authorization: Basic %s', base64_encode(sprintf('%s:%s', $clientId, $clientSecret)));
+
+ $body = Tools::shuffleArray($body);
+ $response = Tools::fetch($tokenUri, headers: $headers, body: $body);
+
+ $tokenUri = htmlspecialchars($tokenUri);
+ $headers = htmlspecialchars(json_encode($headers, JSON_PRETTY_PRINT));
+ $body = htmlspecialchars(json_encode($body, JSON_PRETTY_PRINT));
+
+ $decoded = json_decode($response);
+ if($decoded !== null)
+ $response = json_encode($decoded, JSON_PRETTY_PRINT);
+
+ $response = htmlspecialchars($response);
+
+ return <<
+
+Oatmeal / Refresh token
+
+Oatmeal / Refresh token
+Below is the request and response data from your request token result. If the response contains a refresh_token field, you can restart the Refresh token flow again and again and again and again!
+
+
+ Token URI (POST):
+
+
+
+
+
+ Headers:
+
+
+
+
+
+ Request body (sent as application/x-www-form-urlencoded, presented as JSON for consistency):
+
+
+
+
+
+ Response body:
+
+
+
+Return
+HTML;
}
}