diff --git a/docs/classes/Taproot-IndieAuth-Callback-DefaultAuthorizationForm.html b/docs/classes/Taproot-IndieAuth-Callback-DefaultAuthorizationForm.html index a21095c..6e97e16 100644 --- a/docs/classes/Taproot-IndieAuth-Callback-DefaultAuthorizationForm.html +++ b/docs/classes/Taproot-IndieAuth-Callback-DefaultAuthorizationForm.html @@ -93,10 +93,24 @@ - +

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.

+
@@ -150,7 +164,7 @@  : mixed -
+
Constructor
setLogger() @@ -201,7 +215,7 @@ @@ -231,7 +245,7 @@ @@ -261,7 +275,7 @@ @@ -295,15 +309,17 @@ - +

Constructor

+ public __construct([string|null $formTemplatePath = null ][, string|null $csrfKey = null ][, LoggerInterface|null $logger = null ]) : mixed - +
+
Parameters
@@ -311,21 +327,27 @@ : string|null = null
- +

The path to a custom template. Uses the default if null.

+
+
$csrfKey : string|null = 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.

+
+
$logger : LoggerInterface|null = null
- +

A logger.

+
+
@@ -351,7 +373,7 @@ @@ -393,7 +415,7 @@

Show Form

@@ -499,7 +521,7 @@ library, but, if stored on the access token, will be available to your app for u

Transform Authorization Code

diff --git a/docs/classes/Taproot-IndieAuth-Callback-SingleUserPasswordAuthenticationCallback.html b/docs/classes/Taproot-IndieAuth-Callback-SingleUserPasswordAuthenticationCallback.html index c1f57fd..cd5d488 100644 --- a/docs/classes/Taproot-IndieAuth-Callback-SingleUserPasswordAuthenticationCallback.html +++ b/docs/classes/Taproot-IndieAuth-Callback-SingleUserPasswordAuthenticationCallback.html @@ -90,12 +90,36 @@

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.

+
@@ -150,7 +174,7 @@  : mixed
-
+
Constructor
__invoke() @@ -178,7 +202,7 @@ @@ -218,7 +242,7 @@ @@ -248,7 +272,7 @@ @@ -278,7 +302,7 @@ @@ -308,7 +332,7 @@ @@ -342,15 +366,17 @@ - +

Constructor

+ 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
@@ -358,28 +384,36 @@ : array<string|int, mixed>
- +

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.

+
+
$hashedPassword : string
- -
-
- $csrfKey - : string|null - = null
-
- +

The password used to authenticate as $user, hashed by password_hash($pass, PASSWORD_DEFAULT)

+
+
$formTemplate : string|null = null
- +

The path to a template used to render the sign-in form. Uses default if null.

+
+ +
+
+ $csrfKey + : string|null + = null
+
+

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.

+
+
@@ -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 @@ - +

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.

+
@@ -290,7 +299,7 @@ @@ -315,7 +324,7 @@ @@ -340,7 +349,7 @@ @@ -380,7 +389,7 @@ @@ -410,7 +419,7 @@ @@ -440,7 +449,7 @@ @@ -470,7 +479,7 @@ @@ -500,7 +509,7 @@ @@ -534,7 +543,7 @@ @@ -611,7 +620,7 @@

Create Auth Code

@@ -697,7 +706,7 @@ throw exceptions.

@@ -739,7 +748,7 @@ throw exceptions.

@@ -771,7 +780,7 @@ throw exceptions.

Exchange Authorization Code for Access Token

@@ -829,7 +838,7 @@ expiry time, usually in a valid_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 by exchangeAuthCode @@ -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.