Passed
Push — master ( bb5369...84fc9f )
by Jaime Pérez
03:39
created

NegotiateController::setAuthState()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
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|string */
41
    protected $metadataHandler = MetaDataStorageHandler::class;
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
     * Inject the \SimpleSAML\Metadata\MetaDataStorageHandler dependency.
104
     *
105
     * @param \SimpleSAML\Metadata\MetaDataStorageHandler $handler
106
     */
107
    public function setMetadataStorageHandler(MetaDataStorageHandler $handler): void
108
    {
109
        $this->metadataHandler = $handler;
110
    }
111
112
113
    /**
114
     * Inject the \SimpleSAML\Module dependency.
115
     *
116
     * @param \SimpleSAML\Module $module
117
     */
118
    public function setModule(Module $module): void
119
    {
120
        $this->module = $module;
121
    }
122
123
124
    /**
125
     * Show enable.
126
     *
127
     * @return \SimpleSAML\XHTML\Template
128
     * @throws Exception
129
     */
130
    public function enable(): Template
131
    {
132
        $this->session->setData('negotiate:disable', 'session', false, 86400); // 24*60*60=86400
133
134
        $cookie = new Cookie(
135
            'NEGOTIATE_AUTOLOGIN_DISABLE_PERMANENT',
136
            null, // value
137
            mktime(0, 0, 0, 1, 1, 2038), // expire
138
            '/', // path
139
            '', // domain
140
            true, // secure
141
            true // httponly
142
        );
143
144
        $t = new Template($this->config, 'negotiate:enable.twig');
145
        $t->headers->setCookie($cookie);
146
        $t->data['url'] = $this->module::getModuleURL('negotiate/disable');
147
148
        return $t;
149
    }
150
151
152
    /**
153
     * Show disable.
154
     *
155
     * @return \SimpleSAML\XHTML\Template
156
     * @throws Exception
157
     */
158
    public function disable(): Template
159
    {
160
        $this->session->setData('negotiate:disable', 'session', false, 86400); //24*60*60=86400
161
162
        $cookie = new Cookie(
163
            'NEGOTIATE_AUTOLOGIN_DISABLE_PERMANENT',
164
            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

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