<?php
-require_once 'Net/URL2.php';
+namespace anoweco;
+/**
+ * IndieAuth endpoint
+ *
+ * @author Christian Weiske <cweiske@cweiske.de>
+ */
+header('HTTP/1.0 500 Internal Server Error');
+require 'www-header.php';
+
+function getOrCreateUser($mode, $name, $email)
+{
+ if ($mode == 'anonymous') {
+ $name = 'Anonymous';
+ $email = '';
+ } else {
+ if ($name == '') {
+ $name = 'Anonymous';
+ }
+ }
+ $imageurl = getImageUrl($email);
+
+ $storage = new Storage();
+ $id = $storage->findUser($name, $imageurl);
+ if ($id !== null) {
+ return $id;
+ }
+ $id = $storage->createUser($name, $imageurl);
+ return $id;
+}
+
+function getImageUrl($email)
+{
+ //FIXME: libravatar
+ return Urls::userImg((object)['user_imageurl' => '']);
+}
header('IndieAuth: authorization_endpoint');
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
- //var_dump($_GET);die();
- $token = 'keinthema';
- $url = new Net_URL2($_GET['redirect_uri']);
- $url->setQueryVariable('code', $token);
- $url->setQueryVariable('me', $_GET['me']);
- $url->setQueryVariable('state', $_GET['state']);
- header('Location: ' . $url->getURL());
+ if (count($_GET) == 0) {
+ //no parameters - show the index page
+ header('HTTP/1.0 200 OK');
+ header('Content-Type: text/html');
+ render('auth-index', ['baseurl' => Urls::full('/')]);
+ exit();
+ }
+
+ $me = verifyUrlParameter($_GET, 'me');
+ $redirect_uri = verifyUrlParameter($_GET, 'redirect_uri');
+ $client_id = verifyUrlParameter($_GET, 'client_id');
+ $state = getOptionalParameter($_GET, 'state', null);
+ $response_type = getOptionalParameter($_GET, 'response_type', 'id');
+ $scope = getOptionalParameter($_GET, 'scope', null);
+
+ //FIXME: if $me is an actual user, load his data
+
+ //let the user choose his identity
+ header('HTTP/1.0 200 OK');
+ render(
+ 'auth-choose',
+ array(
+ 'auth' => array(
+ 'redirect_uri' => $redirect_uri,
+ 'client_id' => $client_id,
+ 'state' => $state,
+ 'response_type' => $response_type,
+ 'scope' => $scope,
+ ),
+ 'formaction' => '/auth.php?action=login',
+ )
+ );
exit();
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+ if (isset($_GET['action']) && $_GET['action'] == 'login') {
+ //log the user in
+ $auth = $_POST['auth'];
+ $redirect_uri = verifyUrlParameter($auth, 'redirect_uri');
+ $client_id = verifyUrlParameter($auth, 'client_id');
+ $state = getOptionalParameter($auth, 'state', null);
+ $response_type = getOptionalParameter($auth, 'response_type', 'id');
+ $scope = getOptionalParameter($auth, 'scope', null);
+
+ $id = $_POST['id'];
+ verifyParameter($id, 'mode');
+
+ $userId = getOrCreateUser(
+ $id['mode'], trim($id['name']), trim($id['email'])
+ );
+ $me = Urls::full(Urls::user($userId));
+
+ $code = base64_encode(
+ http_build_query(
+ [
+ 'emoji' => '\360\237\222\251',
+ 'me' => $me,
+ 'scope' => $scope,
+ 'signature' => 'FIXME',
+ ]
+ )
+ );
+
+ //redirect back to client
+ $url = new \Net_URL2($redirect_uri);
+ if ($response_type == 'code') {
+ $url->setQueryVariable('code', $code);
+ }
+ $url->setQueryVariable('me', $me);
+ $url->setQueryVariable('state', $state);
+ header('Location: ' . $url->getURL());
+ exit();
+ } else {
+ //auth code verification
+ $code = base64_decode(verifyParameter($_POST, 'code'));
+ $redirect_uri = verifyUrlParameter($_POST, 'redirect_uri');
+ $client_id = verifyUrlParameter($_POST, 'client_id');
+ $state = getOptionalParameter($_POST, 'state', null);
+
+ parse_str($code, $codeParts);
+ $emoji = verifyParameter($codeParts, 'emoji');
+ $signature = verifyParameter($codeParts, 'signature');
+ $me = verifyUrlParameter($codeParts, 'me');
+ if ($emoji != '\360\237\222\251') {
+ error('Dog poo missing');
+ }
+ if ($signature != 'FIXME') {
+ error('Invalid signature');
+ }
+ header('HTTP/1.0 200 OK');
+ header('Content-type: application/x-www-form-urlencoded');
+ echo http_build_query(['me' => $me]);
+ exit();
+ }
}
?>
);
//$twig->addExtension(new Twig_Extension_Debug());
+function verifyParameter($givenParams, $paramName)
+{
+ if (!isset($givenParams[$paramName])) {
+ error('"' . $paramName . '" parameter missing');
+ }
+ return $givenParams[$paramName];
+}
+
+function verifyUrlParameter($givenParams, $paramName)
+{
+ verifyParameter($givenParams, $paramName);
+ $url = parse_url($givenParams[$paramName]);
+ if (!isset($url['scheme'])) {
+ error('Invalid URL in "' . $paramName . '" parameter: scheme missing');
+ }
+ if (!isset($url['host'])) {
+ error('Invalid URL in "' . $paramName . '" parameter: host missing');
+ }
+
+ return $givenParams[$paramName];
+}
+
+function getOptionalParameter($givenParams, $paramName, $default)
+{
+ if (!isset($givenParams[$paramName])) {
+ return $default;
+ }
+ return $givenParams[$paramName];
+}
+
+/**
+ * Send out an error
+ *
+ * @param string $status HTTP status code line
+ * @param string $code One of the allowed status types:
+ * - forbidden
+ * - insufficient_scope
+ * - invalid_request
+ * - not_found
+ * @param string $description
+ */
+function error($description, $status = 'HTTP/1.0 400 Bad Request')
+{
+ header($status);
+ header('Content-Type: text/plain');
+ echo $description . "\n";
+ exit(1);
+}
+
function render($tplname, $vars = array(), $return = false)
{
$template = $GLOBALS['twig']->loadTemplate($tplname . '.htm');