Skip to content

Commit 207adaa

Browse files
authored
Merge pull request #31 from xp-forge/feature/cas-session-namespace
Make it possible to change the session namespace (CAS)
2 parents 1ce8c99 + 5c88986 commit 207adaa

File tree

4 files changed

+43
-20
lines changed

4 files changed

+43
-20
lines changed

src/main/php/web/auth/Flow.class.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@ abstract class Flow {
66
const FRAGMENT= '_';
77

88
private $url= null;
9+
protected $namespace;
10+
11+
/**
12+
* Sets session namespace for this flow. Used to prevent conflicts
13+
* in session state with multiple OAuth flows in place.
14+
*
15+
* @param string $namespace
16+
* @return self
17+
*/
18+
public function namespaced($namespace) {
19+
$this->namespace= $namespace;
20+
return $this;
21+
}
922

1023
/**
1124
* Targets a given URL

src/main/php/web/auth/cas/CasFlow.class.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
use web\{Cookie, Error, Filter};
99

1010
class CasFlow extends Flow {
11-
const SESSION_KEY = 'cas::flow';
12-
1311
private $sso;
1412

1513
/**
@@ -19,6 +17,7 @@ class CasFlow extends Flow {
1917
*/
2018
public function __construct($sso) {
2119
$this->sso= rtrim($sso, '/');
20+
$this->namespace= 'cas::flow';
2221
}
2322

2423
/**
@@ -44,7 +43,7 @@ protected function validate($ticket, $service) {
4443
* @return var
4544
*/
4645
public function authenticate($request, $response, $session) {
47-
$state= $session->value(self::SESSION_KEY);
46+
$state= $session->value($this->namespace);
4847
if (isset($state['username'])) return $state;
4948

5049
// If no ticket is present, redirect to SSO. Otherwise, validate ticket,
@@ -104,7 +103,7 @@ public function authenticate($request, $response, $session) {
104103

105104
// Success-oriented
106105
if ($user= $result['user'] ?? null) {
107-
$session->register(self::SESSION_KEY, $user);
106+
$session->register($this->namespace, $user);
108107
$session->transmit($response);
109108
$this->finalize($response, $service);
110109
return null;

src/main/php/web/auth/oauth/OAuthFlow.class.php

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use web\auth\{Flow, UserInfo, AuthenticationError};
55

66
abstract class OAuthFlow extends Flow {
7-
protected $callback, $namespace;
7+
protected $callback;
88

99
/** @return ?util.URI */
1010
public function callback() { return $this->callback; }
@@ -15,18 +15,6 @@ public function calling($callback): self {
1515
return $this;
1616
}
1717

18-
/**
19-
* Sets session namespace for this flow. Used to prevent conflicts
20-
* in session state with multiple OAuth flows in place.
21-
*
22-
* @param string $namespace
23-
* @return self
24-
*/
25-
public function namespaced($namespace) {
26-
$this->namespace= $namespace;
27-
return $this;
28-
}
29-
3018
/**
3119
* Returns user info which fetched from the given endpoint using the
3220
* authorized OAuth client

src/test/php/web/auth/unittest/CasFlowTest.class.php

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use web\{Error, Request, Response};
1212

1313
class CasFlowTest extends FlowTest {
14+
const SNS = 'cas::flow';
1415
const SSO = 'https://example.com/sso';
1516
const SERVICE = 'https://service.example.com';
1617
const TICKET = 'ST-1856339-aA5Yuvrxzpv8Tau1cYQ7';
@@ -147,7 +148,29 @@ public function validate($ticket, $service) {
147148
$this->authenticate($fixture, '/?ticket='.self::TICKET, $session);
148149
Assert::equals(
149150
['username' => 'test'],
150-
$session->value(CasFlow::SESSION_KEY)
151+
$session->value(self::SNS)
152+
);
153+
}
154+
155+
#[Test, Values(['cas::flow', 'flow'])]
156+
public function session_namespace($namespace) {
157+
$fixture= new class(self::SSO) extends CasFlow {
158+
public function validate($ticket, $service) {
159+
return CasFlowTest::response('
160+
<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">
161+
<cas:authenticationSuccess>
162+
<cas:user>test</cas:user>
163+
</cas:authenticationSuccess>
164+
</cas:serviceResponse>
165+
');
166+
}
167+
};
168+
$session= (new ForTesting())->create();
169+
170+
$this->authenticate($fixture->namespaced($namespace), '/?ticket='.self::TICKET, $session);
171+
Assert::equals(
172+
['username' => 'test'],
173+
$session->value($namespace)
151174
);
152175
}
153176

@@ -173,7 +196,7 @@ public function validate($ticket, $service) {
173196
$this->authenticate($fixture, '/?ticket='.self::TICKET, $session);
174197
Assert::equals(
175198
['username' => 'test', 'givenName' => 'John Doe', 'email' => '[email protected]'],
176-
$session->value(CasFlow::SESSION_KEY)
199+
$session->value(self::SNS)
177200
);
178201
}
179202

@@ -183,7 +206,7 @@ public function returns_user_in_final_step() {
183206

184207
$fixture= new CasFlow(self::SSO);
185208
$session= (new ForTesting())->create();
186-
$session->register(CasFlow::SESSION_KEY, $user);
209+
$session->register(self::SNS, $user);
187210

188211
$req= new Request(new TestInput('GET', '/'));
189212
$res= new Response(new TestOutput());

0 commit comments

Comments
 (0)