Browse Source

use the user's own authz endpoint if one is defined

also updates to the latest indieauth client library as of 20201126
main
Aaron Parecki 4 months ago
parent
commit
6babb2250c
3 changed files with 108 additions and 66 deletions
  1. +1
    -1
      composer.json
  2. +62
    -55
      composer.lock
  3. +45
    -10
      controllers/Auth.php

+ 1
- 1
composer.json View File

@ -4,7 +4,7 @@
"mf2/mf2": "^0.4.3",
"indieweb/mention-client": "~1.1",
"indieweb/representative-h-card": "0.1.*",
"indieauth/client": "0.2.*",
"indieauth/client": "^1.0",
"firebase/php-jwt": "~3.0",
"league/route": "~1.2",
"league/plates": "~3.1",

+ 62
- 55
composer.lock View File

@ -1,51 +1,11 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "d36cff93d0bbe63f248f5c5ad541f2c9",
"content-hash": "2e3a9f1ddef93aa21e064fcee6c98176",
"packages": [
{
"name": "barnabywalters/mf-cleaner",
"version": "v0.1.4",
"source": {
"type": "git",
"url": "https://github.com/barnabywalters/php-mf-cleaner.git",
"reference": "ef6a16628db6e8aee2b4f8bb8093d18c24b74cd4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/barnabywalters/php-mf-cleaner/zipball/ef6a16628db6e8aee2b4f8bb8093d18c24b74cd4",
"reference": "ef6a16628db6e8aee2b4f8bb8093d18c24b74cd4",
"shasum": ""
},
"require-dev": {
"php": ">=5.3",
"phpunit/phpunit": "*"
},
"suggest": {
"mf2/mf2": "To parse microformats2 structures from (X)HTML"
},
"type": "library",
"autoload": {
"files": [
"src/BarnabyWalters/Mf2/Functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Barnaby Walters",
"email": "barnaby@waterpigs.co.uk"
}
],
"description": "Cleans up microformats2 array structures",
"time": "2014-10-06T23:11:15+00:00"
},
{
"name": "camspiers/json-pretty",
"version": "1.0.2",
@ -400,24 +360,27 @@
},
{
"name": "indieauth/client",
"version": "0.2.2",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/indieweb/indieauth-client-php.git",
"reference": "225ece31ddafaee3348eabdc915422c457498a84"
"reference": "d551eeb268100b87ebc7a05ae796a858550e700a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/indieweb/indieauth-client-php/zipball/225ece31ddafaee3348eabdc915422c457498a84",
"reference": "225ece31ddafaee3348eabdc915422c457498a84",
"url": "https://api.github.com/repos/indieweb/indieauth-client-php/zipball/d551eeb268100b87ebc7a05ae796a858550e700a",
"reference": "d551eeb268100b87ebc7a05ae796a858550e700a",
"shasum": ""
},
"require": {
"barnabywalters/mf-cleaner": "0.*",
"indieweb/link-rel-parser": "0.1.*",
"mf2/mf2": "~0.3",
"indieweb/representative-h-card": "^0.1.2",
"mf2/mf2": ">=0.3.2",
"p3k/http": ">=0.1.6",
"php": ">5.3.0"
},
"require-dev": {
"phpunit/phpunit": "4.8.*"
},
"type": "library",
"autoload": {
"psr-0": {
@ -426,16 +389,16 @@
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache 2.0"
"Apache-2.0"
],
"authors": [
{
"name": "Aaron Parecki",
"homepage": "http://aaronparecki.com"
"homepage": "https://aaronparecki.com"
}
],
"description": "IndieAuth Client Library",
"time": "2017-07-01T15:43:45+00:00"
"time": "2020-11-26T19:41:45+00:00"
},
{
"name": "indieweb/link-rel-parser",
@ -1385,12 +1348,12 @@
"version": "v1.0.3",
"source": {
"type": "git",
"url": "https://github.com/nrk/predis.git",
"url": "https://github.com/predis/predis.git",
"reference": "84060b9034d756b4d79641667d7f9efe1aeb8e04"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nrk/predis/zipball/84060b9034d756b4d79641667d7f9efe1aeb8e04",
"url": "https://api.github.com/repos/predis/predis/zipball/84060b9034d756b4d79641667d7f9efe1aeb8e04",
"reference": "84060b9034d756b4d79641667d7f9efe1aeb8e04",
"shasum": ""
},
@ -1740,10 +1703,51 @@
"xml",
"zf"
],
"abandoned": "laminas/laminas-xml",
"time": "2018-04-30T15:11:04+00:00"
}
],
"packages-dev": [
{
"name": "barnabywalters/mf-cleaner",
"version": "v0.1.4",
"source": {
"type": "git",
"url": "https://github.com/barnabywalters/php-mf-cleaner.git",
"reference": "ef6a16628db6e8aee2b4f8bb8093d18c24b74cd4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/barnabywalters/php-mf-cleaner/zipball/ef6a16628db6e8aee2b4f8bb8093d18c24b74cd4",
"reference": "ef6a16628db6e8aee2b4f8bb8093d18c24b74cd4",
"shasum": ""
},
"require-dev": {
"php": ">=5.3",
"phpunit/phpunit": "*"
},
"suggest": {
"mf2/mf2": "To parse microformats2 structures from (X)HTML"
},
"type": "library",
"autoload": {
"files": [
"src/BarnabyWalters/Mf2/Functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Barnaby Walters",
"email": "barnaby@waterpigs.co.uk"
}
],
"description": "Cleans up microformats2 array structures",
"time": "2014-10-06T23:11:15+00:00"
},
{
"name": "doctrine/instantiator",
"version": "1.0.5",
@ -2190,6 +2194,7 @@
"keywords": [
"tokenizer"
],
"abandoned": true,
"time": "2015-09-15T10:49:45+00:00"
},
{
@ -2321,6 +2326,7 @@
"mock",
"xunit"
],
"abandoned": true,
"time": "2016-03-24T05:58:25+00:00"
},
{
@ -2893,5 +2899,6 @@
"platform": {
"php": ">=5.5"
},
"platform-dev": []
"platform-dev": [],
"plugin-api-version": "1.1.0"
}

+ 45
- 10
controllers/Auth.php View File

@ -41,14 +41,29 @@ class Auth {
return $response;
}
// Check if the user's URL defines an authorization endpoint
$authorizationEndpoint = IndieAuth\Client::discoverAuthorizationEndpoint($me);
if(!$authorizationEndpoint) {
$authorizationEndpoint = Config::$defaultAuthorizationEndpoint;
}
$codeVerifier = IndieAuth\Client::generatePKCECodeVerifier();
$state = JWT::encode([
'az' => $authorizationEndpoint,
'me' => $me,
'code_verifier' => $codeVerifier,
'return_to' => $request->get('return_to'),
'time' => time(),
'exp' => time()+300 // verified by the JWT library
], Config::$secretKey);
$authorizationURL = IndieAuth\Client::buildAuthorizationURL(Config::$defaultAuthorizationEndpoint, $me, self::_buildRedirectURI(), Config::$clientID, $state);
$authorizationURL = IndieAuth\Client::buildAuthorizationURL($authorizationEndpoint, [
'me' => $me,
'redirect_uri' => self::_buildRedirectURI(),
'client_id' => Config::$clientID,
'state' => $state,
'code_verifier' => $codeVerifier,
]);
$response->setStatusCode(302);
$response->headers->set('Location', $authorizationURL);
@ -87,26 +102,46 @@ class Auth {
return $response;
}
$authorizationEndpoint = Config::$defaultAuthorizationEndpoint;
$authorizationEndpoint = $state->az;
// Verify the code with the auth server
$token = IndieAuth\Client::verifyIndieAuthCode($authorizationEndpoint, $request->get('code'), $state->me, self::_buildRedirectURI(), Config::$clientID, true);
if(!array_key_exists('auth', $token) || !array_key_exists('me', $token['auth'])) {
// The auth server didn't return a "me" URL
$data = IndieAuth\Client::exchangeAuthorizationCode($state->az, [
'code' => $request->get('code'),
'redirect_uri' => self::_buildRedirectURI(),
'client_id' => Config::$clientID,
'code_verifier' => $state->code_verifier,
]);
if(!isset($data['response']['me'])) {
// The authorization server didn't return a "me" URL
$response->setContent(view('login', [
'title' => 'Sign In to Telegraph',
'error' => 'Invalid Auth Server Response',
'error_description' => 'The authorization server ('.$authorizationEndpoint.') did not return a valid response:<br><pre style="text-align:left; max-height: 400px; overflow: scroll;">HTTP '.$token['response_code']."\n\n".htmlspecialchars($token['response']).'</pre>'
'error_description' => 'The authorization server ('.$authorizationEndpoint.') did not return a valid response:<br><pre style="text-align:left; max-height: 400px; overflow: scroll;">HTTP '.$data['response_code']."\n\n".htmlspecialchars(json_encode($data)).'</pre>'
]));
return $response;
}
// Verify the authorization endpoint matches
if($data['response']['me'] != $state->me) {
$newAuthorizationEndpoint = IndieAuth\Client::discoverAuthorizationEndpoint($data['response']['me']);
if($newAuthorizationEndpoint != $authorizationEndpoint) {
$response->setContent(view('login', [
'title' => 'Sign In to Telegraph',
'error' => 'Invalid Authorization Endpoint',
'error_description' => 'The authorization endpoint for the returned profile URL ('.$data['response']['me'].') did not match the authorization endpoint used to begin the login.'
]));
return $response;
}
}
$me = $data['response']['me'];
// Create or load the user
$user = ORM::for_table('users')->where('url', $token['auth']['me'])->find_one();
$user = ORM::for_table('users')->where('url', $me)->find_one();
if(!$user) {
$user = ORM::for_table('users')->create();
$user->url = $token['auth']['me'];
$user->url = $me;
$user->created_at = date('Y-m-d H:i:s');
$user->last_login = date('Y-m-d H:i:s');
$user->save();
@ -114,7 +149,7 @@ class Auth {
// Create a site for them with the default role
$site = ORM::for_table('sites')->create();
$site->name = 'My Website';
$site->url = $token['auth']['me'];
$site->url = $me;
$site->created_by = $user->id;
$site->created_at = date('Y-m-d H:i:s');
$site->save();

Loading…
Cancel
Save