Completed
Pull Request — develop (#49)
by A.
08:05 queued 02:47
created

AuthenticatedUser   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 116
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 5

Importance

Changes 5
Bugs 0 Features 2
Metric Value
wmc 10
c 5
b 0
f 2
lcom 0
cbo 5
dl 0
loc 116
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
B createFrom() 0 40 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\Value\EntityId;
23
use RuntimeException;
24
use Surfnet\SamlBundle\SAML2\Attribute\Attribute;
25
use Surfnet\SamlBundle\SAML2\Attribute\AttributeSet;
26
use Surfnet\SamlBundle\SAML2\Response\AssertionAdapter;
27
28
final class AuthenticatedUser
29
{
30
    /**
31
     * @var string
32
     */
33
    private $nameId;
34
35
    /**
36
     * @var AttributeSet
37
     */
38
    private $attributes;
39
40
    /**
41
     * @var EntityId[]
42
     */
43
    private $authenticatingAuthorities;
44
45
    /**
46
     * @param AssertionAdapter $assertionAdapter
47
     * @param EntityId[] $authenticatingAuthorities
48
     *
49
     * @return AuthenticatedUser
50
     * @throws RuntimeException
51
     */
52
    public static function createFrom(AssertionAdapter $assertionAdapter, array $authenticatingAuthorities)
53
    {
54
        $attributes = [];
55
56
        /** @var Attribute $attribute */
57
        foreach ($assertionAdapter->getAttributeSet() as $attribute) {
58
            $definition = $attribute->getAttributeDefinition();
59
60
            // We need to replace the eduPersonTargetedID attribute value as that is a nested NameID attribute.
61
            if ($definition->getName() === 'eduPersonTargetedID') {
62
63
                /** @var \DOMNodeList[] $eptiValues */
64
                $eptiValues = $attribute->getValue();
65
                $eptiDomNodeList = $eptiValues[0];
66
67
                if (!$eptiDomNodeList instanceof \DOMNodeList || $eptiDomNodeList->length !== 1) {
68
                    throw new RuntimeException(
69
                        sprintf(
70
                            'EPTI attribute must contain exactly one NameID element as value, received: %s',
71
                            print_r($eptiValues, true)
72
                        )
73
                    );
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
                continue;
81
            }
82
83
            $attributes[] = $attribute;
84
        }
85
86
        return new self(
87
            $assertionAdapter->getNameId(),
88
            AttributeSet::create($attributes),
89
            $authenticatingAuthorities
90
        );
91
    }
92
93
    /**
94
     * @param string $nameId
95
     * @param AttributeSet $attributes
96
     * @param EntityId[] $authenticatingAuthorities
97
     */
98
    private function __construct($nameId, AttributeSet $attributes, array $authenticatingAuthorities)
99
    {
100
        Assert::string($nameId);
101
        Assert::allIsInstanceOf($authenticatingAuthorities, '\OpenConext\Profile\Value\EntityId');
102
103
        $this->nameId                    = $nameId;
104
        $this->attributes                = $attributes;
105
        $this->authenticatingAuthorities = $authenticatingAuthorities;
106
    }
107
108
    /**
109
     * @return string
110
     */
111
    public function getNameId()
112
    {
113
        return $this->nameId;
114
    }
115
116
    /**
117
     * @return AttributeSet
118
     */
119
    public function getAttributes()
120
    {
121
        return $this->attributes;
122
    }
123
124
    /**
125
     * @return EntityId[]
126
     */
127
    public function getAuthenticatingAuthorities()
128
    {
129
        return $this->authenticatingAuthorities;
130
    }
131
132
    /**
133
     * Using toString in order to comply with AbstractToken's setUser method,
134
     * which uses the string representation to detect changes in the user object.
135
     * Not implementing a UserInterface, because methods defined there will not be used.
136
     *
137
     * @return string
138
     */
139
    public function __toString()
140
    {
141
        return $this->nameId;
142
    }
143
}
144