CAS::linkback()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 29
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 4
eloc 15
c 3
b 0
f 0
nc 4
nop 1
dl 0
loc 29
rs 9.7666
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\Module\cas\Controller;
6
7
use Exception;
8
use SimpleSAML\Assert\Assert;
9
use SimpleSAML\Auth;
10
use SimpleSAML\Configuration;
11
use SimpleSAML\Error;
12
use SimpleSAML\HTTP\RunnableResponse;
13
use SimpleSAML\Module\cas\Auth\Source\CAS as CASSource;
14
use Symfony\Component\HttpFoundation\Request;
15
16
/**
17
 * Controller class for the cas module.
18
 *
19
 * This class serves the different views available in the module.
20
 *
21
 * @package simplesamlphp/simplesamlphp-module-cas
22
 */
23
class CAS
24
{
25
    /**
26
     * @var \SimpleSAML\Auth\State|string
27
     * @psalm-var \SimpleSAML\Auth\State|class-string
28
     */
29
    protected $authState = Auth\State::class;
30
31
    /**
32
     * @var \SimpleSAML\Auth\Source|string
33
     * @psalm-var \SimpleSAML\Auth\Source|class-string
34
     */
35
    protected $authSource = Auth\Source::class;
36
37
38
    /**
39
     * Controller constructor.
40
     *
41
     * It initializes the global configuration and session for the controllers implemented here.
42
     *
43
     * @param \SimpleSAML\Configuration $config The configuration to use by the controllers.
44
     *
45
     * @throws \Exception
46
     */
47
    public function __construct(
48
        protected Configuration $config,
49
    ) {
50
    }
51
52
53
    /**
54
     * Inject the \SimpleSAML\Auth\State dependency.
55
     *
56
     * @param \SimpleSAML\Auth\State $authState
57
     */
58
    public function setAuthState(Auth\State $authState): void
59
    {
60
        $this->authState = $authState;
61
    }
62
63
64
    /**
65
     * Inject the \SimpleSAML\Auth\Source dependency.
66
     *
67
     * @param \SimpleSAML\Auth\Source $authSource
68
     */
69
    public function setAuthSource(Auth\Source $authSource): void
70
    {
71
        $this->authSource = $authSource;
72
    }
73
74
75
    /**
76
     * Handle linkback-response from CAS.
77
     *
78
     * @param \Symfony\Component\HttpFoundation\Request $request
79
     * @return \SimpleSAML\HTTP\RunnableResponse
80
     */
81
    public function linkback(Request $request): RunnableResponse
82
    {
83
        if (!$request->query->has('stateId')) {
84
            throw new Error\BadRequest('Missing stateId parameter.');
85
        }
86
87
        $stateId = $request->query->getString('stateId');
88
        /** @var array<mixed> $state */
89
        $state = $this->authState::loadState($stateId, CASSource::STAGE_INIT);
90
91
        if (!$request->query->has('ticket')) {
92
            throw new Error\BadRequest('Missing ticket parameter.');
93
        }
94
95
        $ticket = $request->query->getString('ticket');
96
        $state['cas:ticket'] = $ticket;
97
98
        // Find authentication source
99
        Assert::keyExists($state, CASSource::AUTHID);
100
        $sourceId = $state[CASSource::AUTHID];
101
102
        /** @var \SimpleSAML\Module\cas\Auth\Source\CAS|null $source */
103
        $source = $this->authSource::getById($sourceId);
104
        if ($source === null) {
105
            throw new Exception('Could not find authentication source with id ' . $sourceId);
106
        }
107
108
        $source->finalStep($state);
109
        return new RunnableResponse([Auth\Source::class, 'completeAuth'], [&$state]);
110
    }
111
}
112