Passed
Pull Request — master (#226)
by Jaime Pérez
03:06
created

AuthnRequest::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 35
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 12
nc 1
nop 17
dl 0
loc 35
rs 9.8666
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace SAML2\XML\samlp;
6
7
use DOMElement;
8
use SAML2\XML\ds\Signature;
9
use SAML2\XML\saml\Conditions;
10
use SAML2\XML\saml\Issuer;
11
use SAML2\XML\saml\Subject;
12
use SAML2\XML\saml\SubjectConfirmation;
13
use SAML2\Utils;
14
use Webmozart\Assert\Assert;
15
16
/**
17
 * Class for SAML 2 authentication request messages.
18
 *
19
 * @package SimpleSAMLphp
20
 */
21
class AuthnRequest extends AbstractRequest
22
{
23
    /**
24
     * @var \SAML2\XML\saml\Subject|null
25
     */
26
    protected $subject = null;
27
28
    /**
29
     * @var \SAML2\XML\samlp\Scoping|null
30
     */
31
    protected $scoping = null;
32
33
    /**
34
     * The options for what type of name identifier should be returned.
35
     *
36
     * @var \SAML2\XML\samlp\NameIDPolicy|null
37
     */
38
    protected $nameIdPolicy = null;
39
40
    /**
41
     * Whether the Identity Provider must authenticate the user again.
42
     *
43
     * @var bool|null
44
     */
45
    protected $forceAuthn = false;
46
47
    /**
48
     * Optional ProviderID attribute
49
     *
50
     * @var string|null
51
     */
52
    protected $ProviderName = null;
53
54
    /**
55
     * Set to true if this request is passive.
56
     *
57
     * @var bool|null
58
     */
59
    protected $isPassive = false;
60
61
    /**
62
     * The URL of the assertion consumer service where the response should be delivered.
63
     *
64
     * @var string|null
65
     */
66
    protected $assertionConsumerServiceURL;
67
68
    /**
69
     * What binding should be used when sending the response.
70
     *
71
     * @var string|null
72
     */
73
    protected $protocolBinding;
74
75
    /**
76
     * The index of the AttributeConsumingService.
77
     *
78
     * @var int|null
79
     */
80
    protected $attributeConsumingServiceIndex;
81
82
    /**
83
     * The index of the AssertionConsumerService.
84
     *
85
     * @var int|null
86
     */
87
    protected $assertionConsumerServiceIndex;
88
89
    /**
90
     * What authentication context was requested.
91
     *
92
     * @var \SAML2\XML\samlp\RequestedAuthnContext|null
93
     */
94
    protected $requestedAuthnContext;
95
96
    /**
97
     * @var \SAML2\XML\saml\Conditions|null
98
     */
99
    protected $conditions = null;
100
101
    /**
102
     * @var \SAML2\XML\saml\SubjectConfirmation[]
103
     */
104
    protected $subjectConfirmation = [];
105
106
107
    /**
108
     * Constructor for SAML 2 AuthnRequest
109
     *
110
     * @param \SAML2\XML\samlp\RequestedAuthnContext $requestedAuthnContext
111
     * @param \SAML2\XML\saml\Subject $subject
112
     * @param \SAML2\XML\samlp\NameIDPolicy $nameIdPolicy
113
     * @param \SAML2\XML\saml\Conditions $conditions
114
     * @param bool $forceAuthn
115
     * @param bool $isPassive
116
     * @param string $assertionConsumerServiceUrl
117
     * @param string $protocolBinding
118
     * @param int $attributeConsumingServiceIndex
119
     * @param string $providerName
120
     * @param \SAML2\XML\saml\Issuer|null $issuer
121
     * @param string|null $id
122
     * @param int|null $issueInstant
123
     * @param string|null $destination
124
     * @param string|null $consent
125
     * @param \SAML2\XML\samlp\Extensions|null $extensions
126
     * @param \SAML2\XML\samlp\Scoping|null $scoping
127
     */
128
    public function __construct(
129
        ?RequestedAuthnContext $requestedAuthnContext = null,
130
        ?Subject $subject = null,
131
        ?NameIDPolicy $nameIdPolicy = null,
132
        Conditions $conditions = null,
133
134
        ?bool $forceAuthn = null,
135
        ?bool $isPassive = null,
136
        ?string $assertionConsumerServiceUrl = null,
137
        ?string $protocolBinding = null,
138
        ?int $attributeConsumingServiceIndex = null,
139
        ?string $providerName = null,
140
141
        ?Issuer $issuer = null,
142
        ?string $id = null,
143
        ?int $issueInstant = null,
144
        ?string $destination = null,
145
        ?string $consent = null,
146
        ?Extensions $extensions = null,
147
        ?Scoping $scoping = null
148
    ) {
149
        parent::__construct($issuer, $id, $issueInstant, $destination, $consent, $extensions);
150
151
        $this->setRequestedAuthnContext($requestedAuthnContext);
152
        $this->setSubject($subject);
153
        $this->setNameIdPolicy($nameIdPolicy);
154
        $this->setConditions($conditions);
155
156
        $this->setForceAuthn($forceAuthn);
157
        $this->setIsPassive($isPassive);
158
        $this->setAssertionConsumerServiceUrl($assertionConsumerServiceUrl);
159
        $this->setProtocolBinding($protocolBinding);
160
        $this->setAttributeConsumingServiceIndex($attributeConsumingServiceIndex);
161
        $this->setProviderName($providerName);
162
        $this->setScoping($scoping);
163
    }
164
165
166
    /**
167
     * @param \SAML2\XML\saml\Subject|null $subject
168
     * @return void
169
     */
170
    private function setSubject(?Subject $subject): void
171
    {
172
        $this->subject = $subject;
173
    }
174
175
176
    /**
177
     * @return \SAML2\XML\saml\Subject|null
178
     */
179
    public function getSubject(): ?Subject
180
    {
181
        return $this->subject;
182
    }
183
184
185
    /**
186
     * @param \SAML2\XML\samlp\Scoping|null $scoping
187
     * @return void
188
     */
189
    private function setScoping(?Scoping $scoping): void
190
    {
191
        $this->scoping = $scoping;
192
    }
193
194
195
    /**
196
     * @return \SAML2\XML\samlp\Scoping|null
197
     */
198
    public function getScoping(): ?Scoping
199
    {
200
        return $this->scoping;
201
    }
202
203
204
    /**
205
     * @param \SAML2\XML\saml\Conditions|null $conditions
206
     * @return void
207
     */
208
    private function setConditions(?Conditions $conditions): void
209
    {
210
        $this->conditions = $conditions;
211
    }
212
213
214
    /**
215
     * @return \SAML2\XML\saml\Conditions|null
216
     */
217
    public function getConditions(): ?Conditions
218
    {
219
        return $this->conditions;
220
    }
221
222
223
    /**
224
     * Retrieve the NameIdPolicy.
225
     *
226
     * @see \SAML2\AuthnRequest::setNameIdPolicy()
227
     * @return \SAML2\XML\samlp\NameIDPolicy|null The NameIdPolicy.
228
     */
229
    public function getNameIdPolicy(): ?NameIDPolicy
230
    {
231
        return $this->nameIdPolicy;
232
    }
233
234
235
    /**
236
     * Set the NameIDPolicy.
237
     *
238
     * @param \SAML2\XML\samlp\NameIDPolicy|null $nameIdPolicy The NameIDPolicy.
239
     * @return void
240
     */
241
    private function setNameIdPolicy(?NameIDPolicy $nameIdPolicy): void
242
    {
243
        $this->nameIdPolicy = $nameIdPolicy;
244
    }
245
246
247
    /**
248
     * Retrieve the value of the ForceAuthn attribute.
249
     *
250
     * @return bool|null The ForceAuthn attribute.
251
     */
252
    public function getForceAuthn(): ?bool
253
    {
254
        return $this->forceAuthn;
255
    }
256
257
258
    /**
259
     * Set the value of the ForceAuthn attribute.
260
     *
261
     * @param bool $forceAuthn The ForceAuthn attribute.
262
     * @return void
263
     */
264
    private function setForceAuthn(?bool $forceAuthn): void
265
    {
266
        $this->forceAuthn = $forceAuthn;
267
    }
268
269
270
    /**
271
     * Retrieve the value of the ProviderName attribute.
272
     *
273
     * @return string|null The ProviderName attribute.
274
     */
275
    public function getProviderName(): ?string
276
    {
277
        return $this->ProviderName;
278
    }
279
280
281
    /**
282
     * Set the value of the ProviderName attribute.
283
     *
284
     * @param string|null $ProviderName The ProviderName attribute.
285
     * @return void
286
     */
287
    private function setProviderName(?string $ProviderName): void
288
    {
289
        $this->ProviderName = $ProviderName;
290
    }
291
292
293
    /**
294
     * Retrieve the value of the IsPassive attribute.
295
     *
296
     * @return bool|null The IsPassive attribute.
297
     */
298
    public function getIsPassive(): ?bool
299
    {
300
        return $this->isPassive;
301
    }
302
303
304
    /**
305
     * Set the value of the IsPassive attribute.
306
     *
307
     * @param bool|null $isPassive The IsPassive attribute.
308
     * @return void
309
     */
310
    private function setIsPassive(?bool $isPassive): void
311
    {
312
        $this->isPassive = $isPassive;
313
    }
314
315
316
    /**
317
     * Retrieve the value of the AssertionConsumerServiceURL attribute.
318
     *
319
     * @return string|null The AssertionConsumerServiceURL attribute.
320
     */
321
    public function getAssertionConsumerServiceURL(): ?string
322
    {
323
        return $this->assertionConsumerServiceURL;
324
    }
325
326
327
    /**
328
     * Set the value of the AssertionConsumerServiceURL attribute.
329
     *
330
     * @param string|null $assertionConsumerServiceURL The AssertionConsumerServiceURL attribute.
331
     * @return void
332
     */
333
    private function setAssertionConsumerServiceURL(string $assertionConsumerServiceURL = null): void
334
    {
335
        $this->assertionConsumerServiceURL = $assertionConsumerServiceURL;
336
    }
337
338
339
    /**
340
     * Retrieve the value of the ProtocolBinding attribute.
341
     *
342
     * @return string|null The ProtocolBinding attribute.
343
     */
344
    public function getProtocolBinding(): ?string
345
    {
346
        return $this->protocolBinding;
347
    }
348
349
350
    /**
351
     * Set the value of the ProtocolBinding attribute.
352
     *
353
     * @param string $protocolBinding The ProtocolBinding attribute.
354
     * @return void
355
     */
356
    private function setProtocolBinding(string $protocolBinding = null): void
357
    {
358
        $this->protocolBinding = $protocolBinding;
359
    }
360
361
362
    /**
363
     * Retrieve the value of the AttributeConsumingServiceIndex attribute.
364
     *
365
     * @return int|null The AttributeConsumingServiceIndex attribute.
366
     */
367
    public function getAttributeConsumingServiceIndex(): ?int
368
    {
369
        return $this->attributeConsumingServiceIndex;
370
    }
371
372
373
    /**
374
     * Set the value of the AttributeConsumingServiceIndex attribute.
375
     *
376
     * @param int|null $attributeConsumingServiceIndex The AttributeConsumingServiceIndex attribute.
377
     * @return void
378
     */
379
    private function setAttributeConsumingServiceIndex(int $attributeConsumingServiceIndex = null): void
380
    {
381
        $this->attributeConsumingServiceIndex = $attributeConsumingServiceIndex;
382
    }
383
384
385
    /**
386
     * Retrieve the value of the AssertionConsumerServiceIndex attribute.
387
     *
388
     * @return int|null The AssertionConsumerServiceIndex attribute.
389
     */
390
    public function getAssertionConsumerServiceIndex(): ?int
391
    {
392
        return $this->assertionConsumerServiceIndex;
393
    }
394
395
396
    /**
397
     * Set the value of the AssertionConsumerServiceIndex attribute.
398
     *
399
     * @param int|null $assertionConsumerServiceIndex The AssertionConsumerServiceIndex attribute.
400
     * @return void
401
     */
402
    private function setAssertionConsumerServiceIndex(int $assertionConsumerServiceIndex = null): void
0 ignored issues
show
Unused Code introduced by
The method setAssertionConsumerServiceIndex() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
403
    {
404
        $this->assertionConsumerServiceIndex = $assertionConsumerServiceIndex;
405
    }
406
407
408
    /**
409
     * Retrieve the RequestedAuthnContext.
410
     *
411
     * @return \SAML2\XML\samlp\RequestedAuthnContext|null The RequestedAuthnContext.
412
     */
413
    public function getRequestedAuthnContext(): ?RequestedAuthnContext
414
    {
415
        return $this->requestedAuthnContext;
416
    }
417
418
419
    /**
420
     * Set the RequestedAuthnContext.
421
     *
422
     * @param \SAML2\XML\samlp\RequestedAuthnContext|null $requestedAuthnContext The RequestedAuthnContext.
423
     * @return void
424
     */
425
    private function setRequestedAuthnContext(RequestedAuthnContext $requestedAuthnContext = null): void
426
    {
427
        $this->requestedAuthnContext = $requestedAuthnContext;
428
    }
429
430
431
    /**
432
     * Retrieve the SubjectConfirmation elements we have in our Subject element.
433
     *
434
     * @return \SAML2\XML\saml\SubjectConfirmation[]
435
     */
436
    public function getSubjectConfirmation(): array
437
    {
438
        return $this->subjectConfirmation;
439
    }
440
441
442
    /**
443
     * Set the SubjectConfirmation elements that should be included in the assertion.
444
     *
445
     * @param array \SAML2\XML\saml\SubjectConfirmation[]
446
     * @return void
447
     */
448
    private function setSubjectConfirmation(array $subjectConfirmation): void
0 ignored issues
show
Unused Code introduced by
The method setSubjectConfirmation() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
449
    {
450
        Assert::allIsInstanceOf($subjectConfirmation, SubjectConfirmation::class);
451
        $this->subjectConfirmation = $subjectConfirmation;
452
    }
453
454
455
    /**
456
     * Convert XML into an AuthnRequest
457
     *
458
     * @param \DOMElement $xml The XML element we should load
459
     * @return \SAML2\XML\samlp\AuthnRequest
460
     * @throws \InvalidArgumentException if the qualified name of the supplied element is wrong
461
     */
462
    public static function fromXML(DOMElement $xml): object
463
    {
464
        Assert::same($xml->localName, 'AuthnRequest');
465
        Assert::same($xml->namespaceURI, AuthnRequest::NS);
466
        Assert::same('2.0', self::getAttribute($xml, 'Version'));
467
468
        $issueInstant = Utils::xsDateTimeToTimestamp(self::getAttribute($xml, 'IssueInstant'));
469
470
        $attributeConsumingServiceIndex = self::getAttribute($xml, 'AttributeConsumingServiceIndex', null);
471
        if ($attributeConsumingServiceIndex !== null) {
472
            $attributeConsumingServiceIndex = intval($attributeConsumingServiceIndex);
473
        }
474
475
        $conditions = Conditions::getChildrenOfClass($xml);
476
        Assert::maxCount($conditions, 1, 'Only one <saml:Conditions> element is allowed.');
477
478
        $nameIdPolicy = NameIDPolicy::getChildrenOfClass($xml);
479
        Assert::maxCount($nameIdPolicy, 1, 'Only one <samlp:NameIDPolicy> element is allowed.');
480
481
        $subject = Subject::getChildrenOfClass($xml);
482
        Assert::maxCount($subject, 1, 'Only one <saml:Subject> element is allowed.');
483
484
        $issuer = Issuer::getChildrenOfClass($xml);
485
        Assert::maxCount($issuer, 1, 'Only one <saml:Issuer> element is allowed.');
486
487
        $requestedAuthnContext = RequestedAuthnContext::getChildrenOfClass($xml);
488
        Assert::maxCount($requestedAuthnContext, 1, 'Only one <samlp:RequestedAuthnContext> element is allowed.');
489
490
        $extensions = Extensions::getChildrenOfClass($xml);
491
        Assert::maxCount($extensions, 1, 'Only one <samlp:Extensions> element is allowed.');
492
493
        $signature = Signature::getChildrenOfClass($xml);
494
        Assert::maxCount($signature, 1, 'Only one <ds:Signature> element is allowed.');
495
496
        $scoping = Scoping::getChildrenOfClass($xml);
497
        Assert::maxCount($scoping, 1, 'Only one <samlp:Scoping> element is allowed.');
498
499
500
        $request = new self(
501
            array_pop($requestedAuthnContext),
502
            array_pop($subject),
503
            array_pop($nameIdPolicy),
504
            array_pop($conditions),
505
506
            self::getBooleanAttribute($xml, 'ForceAuthn', null),
507
            self::getBooleanAttribute($xml, 'IsPassive', null),
508
            self::getAttribute($xml, 'AssertionConsumerServiceURL', null),
509
            self::getAttribute($xml, 'ProtocolBinding', null),
510
            $attributeConsumingServiceIndex,
511
            self::getAttribute($xml, 'ProviderName', null),
512
513
            array_pop($issuer),
514
            self::getAttribute($xml, 'ID'),
515
            $issueInstant,
516
            self::getAttribute($xml, 'Destination', null),
517
            self::getAttribute($xml, 'Consent', null),
518
            array_pop($extensions),
519
            array_pop($scoping)
520
        );
521
522
        if (!empty($signature)) {
523
            $request->setSignature($signature[0]);
524
            $request->messageContainedSignatureUponConstruction = true;
525
        }
526
527
        return $request;
528
    }
529
530
531
    /**
532
     * Convert this authentication request to an XML element.
533
     *
534
     * @return \DOMElement This authentication request.
535
     */
536
    public function toXML(?DOMElement $parent = null): DOMElement
537
    {
538
        $parent = parent::toXML($parent);
539
540
        if ($this->forceAuthn == true) {
541
            $parent->setAttribute('ForceAuthn', 'true');
542
        }
543
544
        if (!empty($this->ProviderName)) {
545
            $parent->setAttribute('ProviderName', $this->ProviderName);
546
        }
547
548
        if ($this->isPassive === true) {
549
            $parent->setAttribute('IsPassive', 'true');
550
        }
551
552
        if ($this->assertionConsumerServiceIndex !== null) {
553
            $parent->setAttribute('AssertionConsumerServiceIndex', strval($this->assertionConsumerServiceIndex));
554
        } else {
555
            if ($this->assertionConsumerServiceURL !== null) {
556
                $parent->setAttribute('AssertionConsumerServiceURL', $this->assertionConsumerServiceURL);
557
            }
558
            if ($this->protocolBinding !== null) {
559
                $parent->setAttribute('ProtocolBinding', $this->protocolBinding);
560
            }
561
        }
562
563
        if ($this->attributeConsumingServiceIndex !== null) {
564
            $parent->setAttribute('AttributeConsumingServiceIndex', strval($this->attributeConsumingServiceIndex));
565
        }
566
567
        if ($this->subject !== null) {
568
            $this->subject->toXML($parent);
569
        }
570
571
        if ($this->nameIdPolicy !== null) {
572
            if (!$this->nameIdPolicy->isEmptyElement()) {
573
                $this->nameIdPolicy->toXML($parent);
574
            }
575
        }
576
577
        if ($this->conditions !== null) {
578
            if (!$this->conditions->isEmptyElement()) {
579
                $this->conditions->toXML($parent);
580
            }
581
        }
582
583
        if (!empty($this->requestedAuthnContext)) {
584
            $this->requestedAuthnContext->toXML($parent);
585
        }
586
587
        if ($this->scoping !== null) {
588
            if (!$this->scoping->isEmptyElement()) {
589
                $this->scoping->toXML($parent);
590
            }
591
        }
592
593
        return $this->signElement($parent);
594
    }
595
}
596