Browse Source

Complete IndieAuth authorizer

microsub
J. King 5 years ago
parent
commit
dd3e143212
  1. 28
      lib/Misc/URL.php
  2. 12
      lib/REST/Microsub/Auth.php

28
lib/Misc/URL.php

@ -6,10 +6,18 @@
declare(strict_types=1);
namespace JKingWeb\Arsse\Misc;
use function GuzzleHttp\Psr7\parse_header;
/**
* A collection of functions for manipulating URLs
*/
class URL {
/** Returns whether a URL is absolute i.e. has a scheme */
public static function absolute(string $url): bool {
return (bool) strlen((string) parse_url($url, \PHP_URL_SCHEME));
}
/** Normalizes a URL
*
* Normalizations performed are:
@ -137,4 +145,24 @@ class URL {
$out = ($absolute ? "/" : "").$out.($index ? "/" : "");
return str_replace("//", "/", $out);
}
/** Appends data to a URL's query component
*
* @param string $url The input URL
* @param string $data The data to append. This should already be escaped where necessary and not start with any delimiter
* @param string $glue The query subcomponent delimiter, usually "&". If the URL has no query, "?" will be prepended instead
*/
public function queryAppend(string $url, string $data, string $glue = "&"): string {
$insPos = strpos($url, "#");
$insPos = $insPos === false ? strlen($url) : $insPos;
$hasQuery = strpos($url, "?") !== false;
$glue = $hasQuery ? $glue : "?";
if ($hasQuery && $insPos > 0) {
if ($url[$insPos - 1] === $glue) {
// if the URL already has excess glue, use it
$glue = "";
}
}
return substr($url, 0, $insPos).$glue.$data.substr($url, $insPos);
}
}

12
lib/REST/Microsub/Auth.php

@ -8,6 +8,7 @@ namespace JKingWeb\Arsse\REST\Microsub;
use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Misc\URL;
use JKingWeb\Arsse\Misc\Date;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Zend\Diactoros\Response\HtmlResponse as Response;
@ -75,7 +76,16 @@ class Auth extends \JKingWeb\Arsse\REST\AbstractHandler {
if ($user !== $id || URL::normalize($query['me']) !== $url) {
return new EmptyResponse(403);
} else {
// redirect
$redir = URL::normalize(rawurldecode($query['redirect_uri']));
$state = $query['state'] ?? "";
// check that the redirect URL is an absolute one
if (!URL::absolute($redir)) {
return new EmptyResponse(400);
}
// issue an authorization code and build the redirect URL
$code = Arsse::$db->tokenCreate($id, "microsub.auth", null, Date::add("PT2M"));
$next = URL::queryAppend($redir, "code=$code&state=$state");
return new EmptyResponse(302, ["Location: $next"]);
}
}
}

Loading…
Cancel
Save