Completed
Pull Request — develop (#49)
by A.
03:13
created

AuthenticatedUser   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 6

Importance

Changes 7
Bugs 0 Features 2
Metric Value
wmc 10
c 7
b 0
f 2
lcom 0
cbo 6
dl 0
loc 110
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
B createFrom() 0 34 5
A __construct() 0 9 1
A getNameId() 0 4 1
A getAttributes() 0 4 1
A getAuthenticatingAuthorities() 0 4 1
A __toString() 0 4 1
1
<?php
2
3
/**
4
 * Copyright 2015 SURFnet B.V.
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
namespace OpenConext\Profile\Entity;
20
21
use OpenConext\Profile\Assert;
22
use OpenConext\Profile\Exception\InvalidEptiAttributeException;
23
use OpenConext\Profile\Exception\RuntimeException;
24
use OpenConext\Profile\Value\EntityId;
25
use SAML2_Utils;
26
use Surfnet\SamlBundle\SAML2\Attribute\Attribute;
27
use Surfnet\SamlBundle\SAML2\Attribute\AttributeSet;
28
use Surfnet\SamlBundle\SAML2\Response\AssertionAdapter;
29
30
final class AuthenticatedUser
31
{
32
    /**
33
     * @var string
34
     */
35
    private $nameId;
36
37
    /**
38
     * @var AttributeSet
39
     */
40
    private $attributes;
41
42
    /**
43
     * @var EntityId[]
44
     */
45
    private $authenticatingAuthorities;
46
47
    /**
48
     * @param AssertionAdapter $assertionAdapter
49
     * @param EntityId[] $authenticatingAuthorities
50
     *
51
     * @return AuthenticatedUser
52
     * @throws RuntimeException
53
     */
54
    public static function createFrom(AssertionAdapter $assertionAdapter, array $authenticatingAuthorities)
55
    {
56
        $attributes = [];
57
58
        /** @var Attribute $attribute */
59
        foreach ($assertionAdapter->getAttributeSet() as $attribute) {
60
            $definition = $attribute->getAttributeDefinition();
61
62
            // We only want to replace the eduPersonTargetedID attribute value as that is a nested NameID attribute
63
            if ($definition->getName() !== 'eduPersonTargetedID') {
64
                $attributes[] = $attribute;
65
                continue;
66
            }
67
68
            /** @var \DOMNodeList[] $eptiValues */
69
            $eptiValues = $attribute->getValue();
70
            $eptiDomNodeList = $eptiValues[0];
71
72
            if (!$eptiDomNodeList instanceof \DOMNodeList || $eptiDomNodeList->length !== 1) {
73
                throw InvalidEptiAttributeException::invalidValue($eptiDomNodeList);
74
            }
75
76
            $eptiValue  = $eptiDomNodeList->item(0);
77
            $eptiNameId = SAML2_Utils::parseNameId($eptiValue);
0 ignored issues
show
Compatibility introduced by
$eptiValue of type object<DOMNode> is not a sub-type of object<DOMElement>. It seems like you assume a child class of the class DOMNode to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
78
79
            $attributes[] = new Attribute($definition, [$eptiNameId['Value']]);
80
        }
81
82
        return new self(
83
            $assertionAdapter->getNameId(),
84
            AttributeSet::create($attributes),
85
            $authenticatingAuthorities
86
        );
87
    }
88
89
    /**
90
     * @param string $nameId
91
     * @param AttributeSet $attributes
92
     * @param EntityId[] $authenticatingAuthorities
93
     */
94
    private function __construct($nameId, AttributeSet $attributes, array $authenticatingAuthorities)
95
    {
96
        Assert::string($nameId);
97
        Assert::allIsInstanceOf($authenticatingAuthorities, '\OpenConext\Profile\Value\EntityId');
98
99
        $this->nameId                    = $nameId;
100
        $this->attributes                = $attributes;
101
        $this->authenticatingAuthorities = $authenticatingAuthorities;
102
    }
103
104
    /**
105
     * @return string
106
     */
107
    public function getNameId()
108
    {
109
        return $this->nameId;
110
    }
111
112
    /**
113
     * @return AttributeSet
114
     */
115
    public function getAttributes()
116
    {
117
        return $this->attributes;
118
    }
119
120
    /**
121
     * @return EntityId[]
122
     */
123
    public function getAuthenticatingAuthorities()
124
    {
125
        return $this->authenticatingAuthorities;
126
    }
127
128
    /**
129
     * Using toString in order to comply with AbstractToken's setUser method,
130
     * which uses the string representation to detect changes in the user object.
131
     * Not implementing a UserInterface, because methods defined there will not be used.
132
     *
133
     * @return string
134
     */
135
    public function __toString()
136
    {
137
        return $this->nameId;
138
    }
139
}
140