Completed
Push — develop ( ea46a8...47f204 )
by
unknown
13s
created

Arp   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 156
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 25
lcom 1
cbo 4
dl 0
loc 156
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A createWith() 0 14 4
A __construct() 0 28 5
A isValidAttribute() 0 15 5
A getNonIdpAttributes() 0 6 1
A getAttributesGroupedBySource() 0 4 1
A hasMotivations() 0 13 4
A getMotivationFor() 0 15 5
1
<?php
2
3
/**
4
 * Copyright 2017 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\Value;
20
21
use OpenConext\Profile\Exception\InvalidArpDataException;
22
use Surfnet\SamlBundle\Exception\UnknownUrnException;
23
use Surfnet\SamlBundle\SAML2\Attribute\Attribute;
24
use Surfnet\SamlBundle\SAML2\Attribute\AttributeDefinition;
25
use Surfnet\SamlBundle\SAML2\Attribute\AttributeDictionary;
26
27
/**
28
 * The Arp value object represents the Arp configuration for a given entity.
29
 */
30
final class Arp
31
{
32
    /**
33
     * @var array The arp configuration is grouped on source. The source values are a collection of Attribute
34
     */
35
    private $arp;
36
37
    public static function createWith(array $arp, AttributeDictionary $dictionary = null)
38
    {
39
        // Input validation
40
        foreach ($arp as $attributeInformation) {
41
            if (!is_array($attributeInformation)) {
42
                throw new InvalidArpDataException('The attribute information in the arp should be an array.');
43
            }
44
            if (!self::isValidAttribute($attributeInformation)) {
45
                throw new InvalidArpDataException('The attribute information is formatted invalidly.');
46
            }
47
        }
48
49
        return new self($arp, $dictionary);
50
    }
51
52
    private function __construct(array $arp, AttributeDictionary $dictionary = null)
53
    {
54
        $arpCollection = [];
55
56
        // Create Attribute instances for all attributes
57
        foreach ($arp as $attributeName => $attributeDefinitionInformation) {
58
            $attributeSource = 'idp';
59
            $attributeDefinition = new AttributeDefinition($attributeName, $attributeName, $attributeName);
60
61
            // When the dictionary is available. Lookup the attribute in dictionary to load friendly attribute names
62
            if (!is_null($dictionary)) {
63
                try {
64
                    $attributeDefinition = $dictionary->getAttributeDefinitionByUrn($attributeName);
65
                } catch (UnknownUrnException $exception) {
66
                    // Use the previously created attributeDefinition.
67
                }
68
            }
69
70
            if (isset($attributeDefinitionInformation[0]['source'])) {
71
                $attributeSource = $attributeDefinitionInformation[0]['source'];
72
            }
73
74
            // The arp is grouped on attribute source
75
            $arpCollection[$attributeSource][] = new Attribute($attributeDefinition, $attributeDefinitionInformation);
76
        }
77
78
        $this->arp = $arpCollection;
79
    }
80
81
    /**
82
     * Tests the structure of the Arp attribute information.
83
     *
84
     * This information should be an array, should have the attribute names as its keys and have array values.
85
     * These array values can have three keys (value, source and motivation) the values of these entries should
86
     * be of type string.
87
     *
88
     * Example of a valid attribute information array:
89
     *
90
     * [
91
     *   'urn.mace.email' => [
92
     *     ['value' => '*'],
93
     *   ],
94
     *   'urn.mace.eduPersonTargetedId' => [
95
     *     [
96
     *       'value' => '*',
97
     *       'source' => 'sab',
98
     *     ]
99
     *   ],
100
     *   'urn.mace.orcid' => [
101
     *     [
102
     *       'value' => 'orcid.org/\d{4}-\d{4}',
103
     *       'source' => 'orcid',
104
     *     ],
105
     *     [
106
     *       'value' => 'sandbox.orcid.org/\d{4}-\d{4}',
107
     *       'source' => 'orcid',
108
     *     ],
109
     *   ],
110
     *   'urn.mace.eduPersonAffiliation' => [
111
     *     [
112
     *       'value' => '*',
113
     *       'source' => 'sab',
114
     *       'motivation' => 'A motivation provided by the SP.'
115
     *     ]
116
     *   ],
117
     * ]
118
     *
119
     * @param array $attributeInformation
120
     * @return bool
121
     */
122
    private static function isValidAttribute(array $attributeInformation)
123
    {
124
        foreach ($attributeInformation as $attributeInformationEntry) {
125
            if (!isset($attributeInformationEntry['value'])) {
126
                return false;
127
            }
128
129
            foreach ($attributeInformationEntry as $value) {
130
                if (!is_string($value)) {
131
                    return false;
132
                }
133
            }
134
        }
135
        return true;
136
    }
137
138
    /**
139
     * @return array
140
     */
141
    public function getNonIdpAttributes()
142
    {
143
        $attributes = $this->getAttributesGroupedBySource();
144
        unset($attributes['idp']);
145
        return $attributes;
146
    }
147
148
    public function getAttributesGroupedBySource()
149
    {
150
        return $this->arp;
151
    }
152
153
    /**
154
     * @return bool
155
     */
156
    public function hasMotivations()
157
    {
158
        foreach ($this->arp as $arpSource) {
159
            foreach ($arpSource as $arpEntry) {
160
                $values = $arpEntry->getValue();
161
                $attributeValue = reset($values);
162
                if (isset($attributeValue['motivation'])) {
163
                    return true;
164
                }
165
            }
166
        }
167
        return false;
168
    }
169
170
    public function getMotivationFor(Attribute $attribute)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
171
    {
172
        foreach ($this->arp as $arpSource) {
173
            foreach ($arpSource as $arpEntry) {
174
                if ($attribute->getAttributeDefinition()->getUrnMace() == $arpEntry->getAttributeDefinition()->getUrnMace()) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 126 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
175
                    $values = $arpEntry->getValue();
176
                    $attributeValue = reset($values);
177
                    if (isset($attributeValue['motivation'])) {
178
                        return $attributeValue['motivation'];
179
                    }
180
                }
181
            }
182
        }
183
        return '';
184
    }
185
}
186