aboutsummaryrefslogtreecommitdiff
path: root/routes
diff options
context:
space:
mode:
authorwinter Sparkles2026-08-09 15:44:18 +0100
committerwinter Sparkles2026-08-09 15:44:18 +0100
commit96387025da63025894f6259f7eebed0fc6fc53ac (patch)
treea83d73eeb7ec419b24ff78291634503d4ebceec1 /routes
parentc8998ccdff070d7c73a634e031a041260b87c3b1 (diff)
implement the rest of login process incl. cookie redirects and 'next'
Diffstat (limited to 'routes')
-rw-r--r--routes/continue.php33
-rw-r--r--routes/integration/auth-request.php24
-rw-r--r--routes/login.php47
-rw-r--r--routes/logout.php1
4 files changed, 92 insertions, 13 deletions
diff --git a/routes/continue.php b/routes/continue.php
new file mode 100644
index 0000000..2839ef9
--- /dev/null
+++ b/routes/continue.php
@@ -0,0 +1,33 @@
+<?php
+
+// this is the confusingly named cookie-relay page
+
+function GET(array $config) {
+ $ci = array_search($_SERVER['HTTP_HOST'],
+ $config['site']['cookie-domains'] ?? []);
+ if ($ci === false) {
+ header('Location: https://' . $config['site']['primary-domain']);
+ return;
+ }
+ if (!isset($_GET['sid'])) {
+ header('Location: /');
+ return;
+ }
+
+ Psso\Session::override($_GET['sid']);
+
+ $nextDomain = $config['site']['cookie-domains'][$ci + 1] ?? null;
+ if (!isset($nextDomain)) {
+ $redir = $_GET['next'] ?? null;
+ if (isset($redir) && Psso\isValidRedirect($redir, $config)) {
+ header('Location: ' . $redir);
+ } else {
+ header('Location: https://' . $config['site']['primary-domain']);
+ }
+ return;
+ }
+ $target = 'Location: https://' . $nextDomain . '/continue'
+ . '?sid=' . urlencode($_GET['sid']);
+ if (isset($_GET['next'])) $target .= '&next=' . urlencode($_GET['next']);
+ header('Location: ' . $target);
+}
diff --git a/routes/integration/auth-request.php b/routes/integration/auth-request.php
index 82d1f03..51b54d8 100644
--- a/routes/integration/auth-request.php
+++ b/routes/integration/auth-request.php
@@ -4,11 +4,27 @@
// returns 200 for allowed requests
// otherwise, returns 401 and sends the login page url as a header
+function addHeader(array $config, string $baseName, string $value): void {
+ $prefix = $config['integration']['header-prefix'];
+ header("$prefix-$baseName: $value");
+}
+
function GET(array $config) {
- // in the absence of any auth backends i will say No to all requests
+ $session = Psso\Session::get();
+ $identity = $session->getIdentity();
+ if (isset($identity)) {
+ // ok
+ addHeader($config, 'User', $identity->user);
+ addHeader($config, 'Groups', implode(',', $identity->groups));
+ foreach ($identity->extras as $key => $value) {
+ if ($value !== null) addHeader($config, ucfirst($key), $value);
+ }
+ return;
+ }
+
http_response_code(401);
- header(
- $config['integration']['header-prefix'] . '-Location: https://'
- . $config['site']['primary-domain'] . '/login'
+ addHeader(
+ $config, 'Location',
+ 'https://' . $config['site']['primary-domain'] . '/login'
);
}
diff --git a/routes/login.php b/routes/login.php
index 2f73271..ea81c3b 100644
--- a/routes/login.php
+++ b/routes/login.php
@@ -1,16 +1,33 @@
<?php
+function nextTarget(array $config, string $sid): string {
+ if (count($config['site']['cookie-domains'] ?? []) > 0) {
+ $next = 'https://' . $config['site']['cookie-domains'][0] . '/continue'
+ . '?sid=' . urlencode($sid);
+ if (isset($_GET['next'])) {
+ $next .= '&next=' . urlencode($_GET['next']);
+ }
+ return $next;
+ }
+ if (isset($_GET['next']) && Psso\isValidRedirect($_GET['next'], $config)) {
+ return $_GET['next'];
+ }
+ return '/';
+}
+
+
function presentChallenges(
- Psso\Session $session, Psso\Context $context, ?string $message = null
+ array $config,
+ Psso\Session $session,
+ Psso\Context $context,
+ ?string $message = null
) {
$challengeTypes = Psso\AuthFlow::nextStep($context);
if ($challengeTypes === true) {
// auth finished! all good
$session->setChallenges(null);
- $session->setIdentity(
- new Psso\Identity($context->user, $context->groups)
- );
- header('Location: /'); //temporary crap for testing
+ $session->setIdentity(Psso\Identity::fromContext($context));
+ header('Location: ' . nextTarget($config, $session->token));
return;
}
if (count($challengeTypes) == 0) {
@@ -27,6 +44,7 @@ function presentChallenges(
// send challenges to user
$resp = new Psso\XMLResponse;
$resp->doc->addAttribute('title', L('login.title'));
+ $resp->doc->addAttribute('kind', 'challenges');
if (isset($message)) {
$resp->doc->addChild('challenge-message', L($message));
}
@@ -39,7 +57,8 @@ function presentChallenges(
$session->setChallenges($challenges);
}
-function GET() {
+
+function GET(array $config) {
$session = Psso\Session::get();
if ($session->getIdentity() !== null) {
// already logged in
@@ -47,9 +66,10 @@ function GET() {
}
$context = new Psso\Context;
- presentChallenges($session, $context);
+ presentChallenges($config, $session, $context);
}
+
function POST(array $config) {
$session = Psso\Session::get();
@@ -75,9 +95,18 @@ function POST(array $config) {
$context = $answeredChallenge->context;
$context->addResult($result);
- // also set the user in context if we're able to
+ // also set the user and groups in context if we're able to
if ($result->successful && isset($result->user) && !isset($context->user)) {
$context->user = $result->user;
+ if ($provider instanceof Psso\AuthInterface\Groups) {
+ $context->groups = $provider->userGroups($context->user);
+ }
+ if ($provider instanceof Psso\AuthInterface\UserExtra) {
+ $context->extras['name'] =
+ $provider->userDisplayName($context->user);
+ $context->extras['email'] =
+ $provider->userEmailAddress($context->user);
+ }
}
- presentChallenges($session, $context, $result->message);
+ presentChallenges($config, $session, $context, $result->message);
}
diff --git a/routes/logout.php b/routes/logout.php
index 21b2179..14fcedb 100644
--- a/routes/logout.php
+++ b/routes/logout.php
@@ -10,6 +10,7 @@ function GET() {
$resp = new Psso\XMLResponse;
$resp->doc->addAttribute('title', L('logout.title'));
+ $resp->doc->addAttribute('kind', 'challenges');
$form = $resp->doc->addChild('form');
$form->addChild('p', L('logout.warning'));
$form->addAttribute('method', 'post');