Skip to content

Commit cc0dbaf

Browse files
committed
Loggout Controller
1 parent c497868 commit cc0dbaf

File tree

4 files changed

+125
-92
lines changed

4 files changed

+125
-92
lines changed

public/logout.php

Lines changed: 0 additions & 91 deletions
This file was deleted.

routing/routes/routes.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use SimpleSAML\Module\casserver\Codebooks\RoutesEnum;
1010
use SimpleSAML\Module\casserver\Codebooks\LegacyRoutesEnum;
1111
use SimpleSAML\Module\casserver\Controller\Cas10Controller;
12+
use SimpleSAML\Module\casserver\Controller\LogoutController;
1213
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
1314

1415
/** @psalm-suppress InvalidArgument */
@@ -18,8 +19,12 @@
1819
// New Routes
1920
$routes->add(RoutesEnum::Validate->name, RoutesEnum::Validate->value)
2021
->controller([Cas10Controller::class, 'validate']);
22+
$routes->add(RoutesEnum::Validate->name, RoutesEnum::Logout->value)
23+
->controller([LogoutController::class, 'logout']);
2124

2225
// Legacy Routes
2326
$routes->add(LegacyRoutesEnum::LegacyValidate->name, LegacyRoutesEnum::LegacyValidate->value)
2427
->controller([Cas10Controller::class, 'validate']);
28+
$routes->add(LegacyRoutesEnum::LegacyValidate->name, LegacyRoutesEnum::LegacyLogout->value)
29+
->controller([LogoutController::class, 'logout']);
2530
};

src/Controller/Cas10Controller.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ class Cas10Controller
4343
*
4444
* It initializes the global configuration for the controllers implemented here.
4545
*
46-
* @throws Exception
4746
*/
4847
public function __construct()
4948
{
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\Module\casserver\Controller;
6+
7+
use SimpleSAML\Auth\Simple;
8+
use SimpleSAML\Configuration;
9+
use SimpleSAML\Logger;
10+
use SimpleSAML\Module\casserver\Cas\Factories\TicketFactory;
11+
use SimpleSAML\Module\casserver\Controller\Traits\UrlTrait;
12+
use SimpleSAML\Session;
13+
use Symfony\Component\HttpFoundation\RedirectResponse;
14+
use Symfony\Component\HttpKernel\Attribute\MapQueryParameter;
15+
16+
class LogoutController
17+
{
18+
use UrlTrait;
19+
20+
/** @var Logger */
21+
protected Logger $logger;
22+
23+
/** @var Configuration */
24+
protected Configuration $casConfig;
25+
26+
/** @var TicketFactory */
27+
protected TicketFactory $ticketFactory;
28+
29+
/** @var Simple */
30+
protected Simple $authSource;
31+
32+
// this could be any configured ticket store
33+
/** @var mixed */
34+
protected mixed $ticketStore;
35+
36+
/**
37+
* Controller constructor.
38+
*
39+
* It initializes the global configuration for the controllers implemented here.
40+
*
41+
*/
42+
public function __construct()
43+
{
44+
$this->casConfig = Configuration::getConfig('module_casserver.php');
45+
/* Instantiate ticket factory */
46+
$this->ticketFactory = new TicketFactory($this->casConfig);
47+
/* Instantiate ticket store */
48+
$ticketStoreConfig = $this->casConfig->getOptionalValue(
49+
'ticketstore',
50+
['class' => 'casserver:FileSystemTicketStore'],
51+
);
52+
$ticketStoreClass = 'SimpleSAML\\Module\\casserver\\Cas\\Ticket\\'
53+
. explode(':', $ticketStoreConfig['class'])[1];
54+
$this->ticketStore = new $ticketStoreClass($this->casConfig);
55+
$this->authSource = new Simple($this->casConfig->getValue('authsource'));
56+
}
57+
58+
/**
59+
*
60+
* @param string|null $url
61+
*
62+
* @return RedirectResponse|null
63+
*/
64+
public function logout(
65+
#[MapQueryParameter] ?string $url = null,
66+
): RedirectResponse|null {
67+
if (!$this->casConfig->getOptionalValue('enable_logout', false)) {
68+
$this->handleExceptionThrown('Logout not allowed');
69+
}
70+
71+
// Skip Logout Page configuration
72+
$skipLogoutPage = $this->casConfig->getOptionalValue('skip_logout_page', false);
73+
74+
if ($skipLogoutPage && $url === null) {
75+
$this->handleExceptionThrown('Required URL query parameter [url] not provided. (CAS Server)');
76+
}
77+
78+
// Construct the logout redirect url
79+
$logoutRedirectUrl = ($skipLogoutPage || $url === null) ? $url
80+
: $url . '?' . http_build_query(['url' => $url]);
81+
82+
// Delete the ticket from the session
83+
$session = $this->getSession();
84+
if ($session !== null) {
85+
$this->ticketStore->deleteTicket($session->getSessionId());
86+
}
87+
88+
// Redirect
89+
if (!$this->authSource->isAuthenticated()) {
90+
$this->redirect($logoutRedirectUrl);
91+
}
92+
93+
// Logout and redirect
94+
$this->authSource->logout($logoutRedirectUrl);
95+
96+
// We should never get here
97+
return null;
98+
}
99+
100+
/**
101+
* @param string $message
102+
*
103+
* @return void
104+
*/
105+
protected function handleExceptionThrown(string $message): void
106+
{
107+
Logger::debug('casserver:' . $message);
108+
throw new \RuntimeException($message);
109+
}
110+
111+
/**
112+
* Get the Session
113+
*
114+
* @return Session|null
115+
*/
116+
protected function getSession(): ?Session
117+
{
118+
return Session::getSession();
119+
}
120+
}

0 commit comments

Comments
 (0)