Passed
Push — master ( 84fc9f...75fc4a )
by Jaime Pérez
03:54
created

NegotiateController::getMetadataStorageHandler()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SimpleSAML\Module\negotiate\Controller;
4
5
use Exception;
6
use SimpleSAML\Auth;
7
use SimpleSAML\Configuration;
8
use SimpleSAML\Error;
9
use SimpleSAML\HTTP\RunnableResponse;
10
use SimpleSAML\Logger;
11
use SimpleSAML\Metadata\MetaDataStorageHandler;
12
use SimpleSAML\Module;
13
use SimpleSAML\Module\negotiate\Auth\Source\Negotiate;
14
use SimpleSAML\Session;
15
use SimpleSAML\XHTML\Template;
16
use Symfony\Component\HttpFoundation\Cookie;
17
use Symfony\Component\HttpFoundation\Request;
18
19
/**
20
 * Controller class for the negotiate module.
21
 *
22
 * This class serves the different views available in the module.
23
 *
24
 * @package simplesamlphp/simplesamlphp-module-negotiate
25
 */
26
class NegotiateController
27
{
28
    /** @var \SimpleSAML\Auth\Source|string */
29
    protected $authSource = Auth\Source::class;
30
31
    /** @var \SimpleSAML\Auth\State|string */
32
    protected $authState = Auth\State::class;
33
34
    /** @var \SimpleSAML\Configuration */
35
    protected $config;
36
37
    /** @var \SimpleSAML\Logger|string */
38
    protected $logger = Logger::class;
39
40
    /** @var \SimpleSAML\Metadata\MetaDataStorageHandler|null */
41
    protected $metadataHandler = null;
42
43
    /** @var \SimpleSAML\Module|string */
44
    protected $module = Module::class;
45
46
    /** @var \SimpleSAML\Session */
47
    protected $session;
48
49
50
    /**
51
     * Controller constructor.
52
     *
53
     * It initializes the global configuration and session for the controllers implemented here.
54
     *
55
     * @param \SimpleSAML\Configuration $config The configuration to use by the controllers.
56
     * @param \SimpleSAML\Session $session The session to use by the controllers.
57
     *
58
     * @throws \Exception
59
     */
60
    public function __construct(
61
        Configuration $config,
62
        Session $session
63
    ) {
64
        $this->config = $config;
65
        $this->session = $session;
66
    }
67
68
69
    /**
70
     * Inject the \SimpleSAML\Auth\Source dependency.
71
     *
72
     * @param \SimpleSAML\Auth\Source $authSource
73
     */
74
    public function setAuthSource(Auth\Source $authSource): void
75
    {
76
        $this->authSource = $authSource;
77
    }
78
79
80
    /**
81
     * Inject the \SimpleSAML\Auth\State dependency.
82
     *
83
     * @param \SimpleSAML\Auth\State $authState
84
     */
85
    public function setAuthState(Auth\State $authState): void
86
    {
87
        $this->authState = $authState;
88
    }
89
90
91
    /**
92
     * Inject the \SimpleSAML\Logger dependency.
93
     *
94
     * @param \SimpleSAML\Logger $logger
95
     */
96
    public function setLogger(Logger $logger): void
97
    {
98
        $this->logger = $logger;
99
    }
100
101
102
    /**
103
     * Get the metadata storage handler instance.
104
     *
105
     * @return MetaDataStorageHandler
106
     */
107
    protected function getMetadataStorageHandler(): MetaDataStorageHandler
108
    {
109
        return $this->metadataHandler ?: MetaDataStorageHandler::getMetadataHandler();
110
    }
111
112
113
    /**
114
     * Inject the \SimpleSAML\Metadata\MetaDataStorageHandler dependency.
115
     *
116
     * @param \SimpleSAML\Metadata\MetaDataStorageHandler $handler
117
     */
118
    public function setMetadataStorageHandler(MetaDataStorageHandler $handler): void
119
    {
120
        $this->metadataHandler = $handler;
121
    }
122
123
124
    /**
125
     * Inject the \SimpleSAML\Module dependency.
126
     *
127
     * @param \SimpleSAML\Module $module
128
     */
129
    public function setModule(Module $module): void
130
    {
131
        $this->module = $module;
132
    }
133
134
135
    /**
136
     * Show enable.
137
     *
138
     * @return \SimpleSAML\XHTML\Template
139
     * @throws Exception
140
     */
141
    public function enable(): Template
142
    {
143
        $this->session->setData('negotiate:disable', 'session', false, 86400); // 24*60*60=86400
144
145
        $cookie = new Cookie(
146
            'NEGOTIATE_AUTOLOGIN_DISABLE_PERMANENT',
147
            null, // value
148
            mktime(0, 0, 0, 1, 1, 2038), // expire
149
            '/', // path
150
            '', // domain
151
            true, // secure
152
            true // httponly
153
        );
154
155
        $t = new Template($this->config, 'negotiate:enable.twig');
156
        $t->headers->setCookie($cookie);
157
        $t->data['url'] = $this->module::getModuleURL('negotiate/disable');
158
159
        return $t;
160
    }
161
162
163
    /**
164
     * Show disable.
165
     *
166
     * @return \SimpleSAML\XHTML\Template
167
     * @throws Exception
168
     */
169
    public function disable(): Template
170
    {
171
        $this->session->setData('negotiate:disable', 'session', false, 86400); //24*60*60=86400
172
173
        $cookie = new Cookie(
174
            'NEGOTIATE_AUTOLOGIN_DISABLE_PERMANENT',
175
            true, // value
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type null|string expected by parameter $value of Symfony\Component\HttpFo...n\Cookie::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

175
            /** @scrutinizer ignore-type */ true, // value
Loading history...
176
            mktime(0, 0, 0, 1, 1, 2038), // expire
177
            '/', // path
178
            '', // domain
179
            true, // secure
180
            true // httponly
181
        );
182
183
        $t = new Template($this->config, 'negotiate:disable.twig');
184
        $t->headers->setCookie($cookie);
185
        $t->data['url'] = $this->module::getModuleURL('negotiate/enable');
186
187
        return $t;
188
    }
189
190
191
    /**
192
     * Show retry
193
     *
194
     * @param Request $request The request that lead to this retry operation.
195
     * @return \SimpleSAML\HTTP\RunnableResponse
196
     * @throws \Exception
197
     * @throws \SimpleSAML\Error\BadRequest
198
     */
199
    public function retry(Request $request): RunnableResponse
200
    {
201
        $authState = $request->get('AuthState', null);
202
        if ($authState === null) {
203
            throw new Error\BadRequest('Missing required AuthState query parameter.');
204
        }
205
206
        /** @psalm-var array $state */
207
        $state = $this->authState::loadState($authState, Negotiate::STAGEID);
208
209
        $mdh = $this->getMetadataStorageHandler();
210
        $idpid = $mdh->getMetaDataCurrentEntityID('saml20-idp-hosted', 'metaindex');
211
        $idpmeta = $mdh->getMetaData($idpid, 'saml20-idp-hosted');
212
213
        if (isset($idpmeta['auth'])) {
214
            $source = $this->authSource::getById($idpmeta['auth']);
215
            if ($source === null) {
216
                throw new Error\BadRequest('Invalid AuthId "' . $idpmeta['auth'] . '" - not found.');
217
            }
218
219
            $this->session->setData('negotiate:disable', 'session', false, 86400); //24*60*60=86400
220
            $this->logger::debug('Negotiate(retry) - session enabled, retrying.');
221
222
            return new RunnableResponse([$source, 'authenticate'], [$state]);
223
        }
224
        throw new Exception('Negotiate - retry - no "auth" parameter found in IdP metadata.');
225
    }
226
227
228
    /**
229
     * Show fallback
230
     *
231
     * @param Request $request The request that lead to this retry operation.
232
     *
233
     * @return \SimpleSAML\HTTP\RunnableResponse
234
     * @throws \SimpleSAML\Error\BadRequest
235
     * @throws \SimpleSAML\Error\NoState
236
     */
237
    public function fallback(Request $request): RunnableResponse
238
    {
239
        $authState = $request->get('AuthState', null);
240
        if ($authState === null) {
241
            throw new Error\BadRequest('Missing required AuthState query parameter.');
242
        }
243
244
        /** @psalm-var array $state */
245
        $state = $this->authState::loadState($authState, Negotiate::STAGEID);
246
247
        $this->logger::debug('backend - fallback: ' . $state['LogoutState']['negotiate:backend']);
248
249
        return new RunnableResponse([Negotiate::class, 'fallback'], [$state]);
250
    }
251
}
252