From 62d02dacc0c32405b508e2cea898bbf5a7dad4d3 Mon Sep 17 00:00:00 2001
From: Barnaby Walters Default Authorization Form This implementation of When the form is submitted, any granted scopes are then added to the authorization code data. You can customise the authorization template used by passing a path to your own template to
+the constructor. Refer to the default template If you want to add additional form controls (e.g. configurable token lifetimes), as well as
+making a new template, you’ll need to make a subclass which overrides For any more involved customisation (for example using a templating library of your choice), it
+may make sense to create your own implementation of Constructor The path to a custom template. Uses the default if null. The key used to retrieve a CSRF token from the request attributes, and as its form data name. Uses the default defined in Server if null. Only change this if you’re using a custom CSRF middleware. A logger. Show Form Transform Authorization Code Single User Password Authentication Callback A simple example authentication callback which performs authentication itself rather
+than redirecting to an existing authentication flow. In some cases, it may make sense for your IndieAuth server to be able to authenticate
+users itself, rather than redirecting them to an existing authentication flow. This
+implementation provides a simple single-user password authentication method intended
+for bootstrapping and testing purposes. The sign-in form can be customised by making your own template and passing the path to
+the constructor. Minimal usage: See documentation for Constructor An array representing the user, which will be returned on a successful authentication. MUST include a 'me' key, may also contain a 'profile' key, or other keys at your discretion. The password used to authenticate as $user, hashed by The path to a template used to render the sign-in form. Uses default if null. The key under which to fetch a CSRF token from Filesystem JSON Token Storage An implementation of This is intended as a default, example implementation with minimal requirements.
+In practise, most people should probably be using an SQLite3 version of this
+which I haven’t written yet. I haven’t extensively documented this class, as it
+will likely be superceded by the SQLite version. Create Auth CodeAuthorizationFormInterface
is used by Server
if the user doesn’t
+provide one of their own. It presents the user with a simple consent screen, showing any
+available details about the client app, and allowing the user to grant any requested scopes./templates/default_authorization_page.html.php
+as a starting point.transformAuthorizationCode()
+to additionally handle your new form data.AuthorizationFormInterface
.
public
__construct([string|null $formTemplatePath = null ][, string|null $csrfKey = null ][, LoggerInterface|null $logger = null ]) : mixed
-
+
+
Parameters
@@ -351,7 +373,7 @@
@@ -393,7 +415,7 @@
+// One-off during app configuration:
+YOUR_HASHED_PASSWORD = password_hash('my super strong password', PASSWORD_DEFAULT);
+
+// In your app:
+use Taproot\IndieAuth;
+$server = new IndieAuth\Server([
+ …
+ 'handleAuthenticationRequestCallback' => new IndieAuth\Callback\SingleUserPasswordAuthenticationCallback(
+ ['me' => 'https://me.example.com/'],
+ YOUR_HASHED_PASSWORD
+ )
+ …
+]);
+
__construct()
for information about customising behaviour.
public
- __construct(array<string|int, mixed> $user, string $hashedPassword[, string|null $csrfKey = null ][, string|null $formTemplate = null ]) : mixed
+ __construct(array<string|int, mixed> $user, string $hashedPassword[, string|null $formTemplate = null ][, string|null $csrfKey = null ]) : mixed
+
+
-
Parameters
@@ -405,7 +439,7 @@
diff --git a/docs/classes/Taproot-IndieAuth-Storage-FilesystemJsonStorage.html b/docs/classes/Taproot-IndieAuth-Storage-FilesystemJsonStorage.html
index 1ad0d31..853fe2a 100644
--- a/docs/classes/Taproot-IndieAuth-Storage-FilesystemJsonStorage.html
+++ b/docs/classes/Taproot-IndieAuth-Storage-FilesystemJsonStorage.html
@@ -93,10 +93,19 @@
-
+ password_hash($pass, PASSWORD_DEFAULT)
$request
attributes, and as the CSRF token name in submitted form data. Defaults to the Server default, only change if you’re using a custom CSRF middleware.TokenStorageInterface
which stores authorization codes
+and access tokens in the filesystem as JSON files, and supports custom access
+token lifetimes.
Exchange Authorization Code for Access Token
@@ -829,7 +838,7 @@ expiry time, usually in avalid_until
key.
@@ -871,7 +880,7 @@ expiry time, usually in a valid_until
key.
Get Access Token
@@ -918,7 +927,7 @@ exactly the same way it was stored byexchangeAuthCode
@@ -960,7 +969,7 @@ exactly the same way it was stored by exchangeAuthCode
@@ -1009,7 +1018,7 @@ exactly the same way it was stored by exchangeAuthCode
Revoke Access Token
@@ -1055,7 +1064,7 @@ or false on error, including if the token did not exist.
@@ -1097,7 +1106,7 @@ or false on error, including if the token did not exist.
@@ -1139,7 +1148,7 @@ or false on error, including if the token did not exist.
diff --git a/docs/files/src-callback-defaultauthorizationform.html b/docs/files/src-callback-defaultauthorizationform.html
index 3d2730d..c992ad7 100644
--- a/docs/files/src-callback-defaultauthorizationform.html
+++ b/docs/files/src-callback-defaultauthorizationform.html
@@ -88,7 +88,7 @@
- DefaultAuthorizationForm
-
+ - Default Authorization Form
diff --git a/docs/files/src-storage-filesystemjsonstorage.html b/docs/files/src-storage-filesystemjsonstorage.html
index b87a170..12c2ef6 100644
--- a/docs/files/src-storage-filesystemjsonstorage.html
+++ b/docs/files/src-storage-filesystemjsonstorage.html
@@ -88,7 +88,7 @@
- FilesystemJsonStorage
-
+ - Filesystem JSON Token Storage
diff --git a/docs/js/searchIndex.js b/docs/js/searchIndex.js
index 7566d6e..9bf81cb 100644
--- a/docs/js/searchIndex.js
+++ b/docs/js/searchIndex.js
@@ -18,12 +18,12 @@ Search.appendIndex(
}, {
"fqsen": "\\Taproot\\IndieAuth\\Callback\\DefaultAuthorizationForm",
"name": "DefaultAuthorizationForm",
- "summary": "",
+ "summary": "Default\u0020Authorization\u0020Form",
"url": "classes/Taproot-IndieAuth-Callback-DefaultAuthorizationForm.html"
}, {
"fqsen": "\\Taproot\\IndieAuth\\Callback\\DefaultAuthorizationForm\u003A\u003A__construct\u0028\u0029",
"name": "__construct",
- "summary": "",
+ "summary": "Constructor",
"url": "classes/Taproot-IndieAuth-Callback-DefaultAuthorizationForm.html#method___construct"
}, {
"fqsen": "\\Taproot\\IndieAuth\\Callback\\DefaultAuthorizationForm\u003A\u003AshowForm\u0028\u0029",
@@ -63,7 +63,7 @@ Search.appendIndex(
}, {
"fqsen": "\\Taproot\\IndieAuth\\Callback\\SingleUserPasswordAuthenticationCallback\u003A\u003A__construct\u0028\u0029",
"name": "__construct",
- "summary": "",
+ "summary": "Constructor",
"url": "classes/Taproot-IndieAuth-Callback-SingleUserPasswordAuthenticationCallback.html#method___construct"
}, {
"fqsen": "\\Taproot\\IndieAuth\\Callback\\SingleUserPasswordAuthenticationCallback\u003A\u003A__invoke\u0028\u0029",
@@ -528,7 +528,7 @@ Search.appendIndex(
}, {
"fqsen": "\\Taproot\\IndieAuth\\Storage\\FilesystemJsonStorage",
"name": "FilesystemJsonStorage",
- "summary": "",
+ "summary": "Filesystem\u0020JSON\u0020Token\u0020Storage",
"url": "classes/Taproot-IndieAuth-Storage-FilesystemJsonStorage.html"
}, {
"fqsen": "\\Taproot\\IndieAuth\\Storage\\FilesystemJsonStorage\u003A\u003A__construct\u0028\u0029",
diff --git a/docs/namespaces/taproot-indieauth-callback.html b/docs/namespaces/taproot-indieauth-callback.html
index 3de8d79..a756b55 100644
--- a/docs/namespaces/taproot-indieauth-callback.html
+++ b/docs/namespaces/taproot-indieauth-callback.html
@@ -92,7 +92,7 @@
Authorization Form Interface
DefaultAuthorizationForm
-
+ Default Authorization Form
SingleUserPasswordAuthenticationCallback
Single User Password Authentication Callback
diff --git a/docs/namespaces/taproot-indieauth-storage.html b/docs/namespaces/taproot-indieauth-storage.html
index d535d55..0f990b3 100644
--- a/docs/namespaces/taproot-indieauth-storage.html
+++ b/docs/namespaces/taproot-indieauth-storage.html
@@ -92,7 +92,7 @@
Token Storage Interface
FilesystemJsonStorage
-
+ Filesystem JSON Token Storage
Sqlite3Storage
Token
diff --git a/docs/packages/default.html b/docs/packages/default.html
index a2bbab7..8b723fd 100644
--- a/docs/packages/default.html
+++ b/docs/packages/default.html
@@ -92,7 +92,7 @@
Token Storage Interface
DefaultAuthorizationForm
-
+ Default Authorization Form
SingleUserPasswordAuthenticationCallback
Single User Password Authentication Callback
IndieAuthException
@@ -108,7 +108,7 @@
Server
IndieAuth Server
FilesystemJsonStorage
-
+ Filesystem JSON Token Storage
Sqlite3Storage
Token
diff --git a/src/Callback/DefaultAuthorizationForm.php b/src/Callback/DefaultAuthorizationForm.php
index b07a2bf..69b7786 100644
--- a/src/Callback/DefaultAuthorizationForm.php
+++ b/src/Callback/DefaultAuthorizationForm.php
@@ -12,6 +12,26 @@ use Psr\Log\NullLogger;
use function Taproot\IndieAuth\renderTemplate;
+/**
+ * Default Authorization Form
+ *
+ * This implementation of `AuthorizationFormInterface` is used by `Server` if the user doesn’t
+ * provide one of their own. It presents the user with a simple consent screen, showing any
+ * available details about the client app, and allowing the user to grant any requested scopes.
+ *
+ * When the form is submitted, any granted scopes are then added to the authorization code data.
+ *
+ * You can customise the authorization template used by passing a path to your own template to
+ * the constructor. Refer to the default template `/templates/default_authorization_page.html.php`
+ * as a starting point.
+ *
+ * If you want to add additional form controls (e.g. configurable token lifetimes), as well as
+ * making a new template, you’ll need to make a subclass which overrides `transformAuthorizationCode()`
+ * to additionally handle your new form data.
+ *
+ * For any more involved customisation (for example using a templating library of your choice), it
+ * may make sense to create your own implementation of `AuthorizationFormInterface`.
+ */
class DefaultAuthorizationForm implements AuthorizationFormInterface, LoggerAwareInterface {
public string $csrfKey;
@@ -19,6 +39,13 @@ class DefaultAuthorizationForm implements AuthorizationFormInterface, LoggerAwar
public LoggerInterface $logger;
+ /**
+ * Constructor
+ *
+ * @param string|null $formTemplatePath The path to a custom template. Uses the default if null.
+ * @param string|null $csrfKey The key used to retrieve a CSRF token from the request attributes, and as its form data name. Uses the default defined in Server if null. Only change this if you’re using a custom CSRF middleware.
+ * @param LoggerInterface|null $logger A logger.
+ */
public function __construct(?string $formTemplatePath=null, ?string $csrfKey=null, ?LoggerInterface $logger=null) {
$this->formTemplatePath = $formTemplatePath ?? __DIR__ . '/../../templates/default_authorization_page.html.php';
$this->csrfKey = $csrfKey ?? \Taproot\IndieAuth\Server::DEFAULT_CSRF_KEY;
diff --git a/src/Callback/SingleUserPasswordAuthenticationCallback.php b/src/Callback/SingleUserPasswordAuthenticationCallback.php
index 80889b3..37f2658 100644
--- a/src/Callback/SingleUserPasswordAuthenticationCallback.php
+++ b/src/Callback/SingleUserPasswordAuthenticationCallback.php
@@ -11,7 +11,34 @@ use function Taproot\IndieAuth\renderTemplate;
/**
* Single User Password Authentication Callback
*
+ * A simple example authentication callback which performs authentication itself rather
+ * than redirecting to an existing authentication flow.
*
+ * In some cases, it may make sense for your IndieAuth server to be able to authenticate
+ * users itself, rather than redirecting them to an existing authentication flow. This
+ * implementation provides a simple single-user password authentication method intended
+ * for bootstrapping and testing purposes.
+ *
+ * The sign-in form can be customised by making your own template and passing the path to
+ * the constructor.
+ *
+ * Minimal usage:
+ *
+ * // One-off during app configuration:
+ * YOUR_HASHED_PASSWORD = password_hash('my super strong password', PASSWORD_DEFAULT);
+ *
+ * // In your app:
+ * use Taproot\IndieAuth;
+ * $server = new IndieAuth\Server([
+ * …
+ * 'handleAuthenticationRequestCallback' => new IndieAuth\Callback\SingleUserPasswordAuthenticationCallback(
+ * ['me' => 'https://me.example.com/'],
+ * YOUR_HASHED_PASSWORD
+ * )
+ * …
+ * ]);
+ *
+ * See documentation for `__construct()` for information about customising behaviour.
*/
class SingleUserPasswordAuthenticationCallback {
const PASSWORD_FORM_PARAMETER = 'taproot_indieauth_server_password';
@@ -20,8 +47,16 @@ class SingleUserPasswordAuthenticationCallback {
public string $formTemplate;
protected array $user;
protected string $hashedPassword;
-
- public function __construct(array $user, string $hashedPassword, ?string $csrfKey=null, ?string $formTemplate=null) {
+
+ /**
+ * Constructor
+ *
+ * @param array $user An array representing the user, which will be returned on a successful authentication. MUST include a 'me' key, may also contain a 'profile' key, or other keys at your discretion.
+ * @param string $hashedPassword The password used to authenticate as $user, hashed by `password_hash($pass, PASSWORD_DEFAULT)`
+ * @param string|null $formTemplate The path to a template used to render the sign-in form. Uses default if null.
+ * @param string|null $csrfKey The key under which to fetch a CSRF token from `$request` attributes, and as the CSRF token name in submitted form data. Defaults to the Server default, only change if you’re using a custom CSRF middleware.
+ */
+ public function __construct(array $user, string $hashedPassword, ?string $formTemplate=null, ?string $csrfKey=null) {
if (!array_key_exists('me', $user) || !is_string($user['me'])) {
throw new Exception('The $user array MUST contain a “me” key, the value which must be the user’s canonical URL as a string.');
}
diff --git a/src/Storage/FilesystemJsonStorage.php b/src/Storage/FilesystemJsonStorage.php
index c8b914e..b5b7742 100644
--- a/src/Storage/FilesystemJsonStorage.php
+++ b/src/Storage/FilesystemJsonStorage.php
@@ -10,6 +10,18 @@ use Psr\Log\NullLogger;
use function Taproot\IndieAuth\generateRandomString;
+/**
+ * Filesystem JSON Token Storage
+ *
+ * An implementation of `TokenStorageInterface` which stores authorization codes
+ * and access tokens in the filesystem as JSON files, and supports custom access
+ * token lifetimes.
+ *
+ * This is intended as a default, example implementation with minimal requirements.
+ * In practise, most people should probably be using an SQLite3 version of this
+ * which I haven’t written yet. I haven’t extensively documented this class, as it
+ * will likely be superceded by the SQLite version.
+ */
class FilesystemJsonStorage implements TokenStorageInterface, LoggerAwareInterface {
const DEFAULT_AUTH_CODE_TTL = 60 * 5; // Five minutes.
const DEFAULT_ACCESS_TOKEN_TTL = 60 * 60 * 24 * 7; // One week.