Completed
Pull Request — develop (#107)
by
unknown
20:35
created

Arp   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 157
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

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

7 Methods

Rating   Name   Duplication   Size   Complexity  
A createWith() 0 14 4
B __construct() 0 28 5
B isValidAttribute() 0 16 5
A getNonIdpAttributes() 0 6 1
A getAttributesGroupedBySource() 0 4 1
A hasMotivations() 0 13 4
B 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 (!array_key_exists('value', $attributeInformationEntry)) {
126
                return false;
127
            }
128
129
            foreach ($attributeInformationEntry as $key => $value) {
130
                if (!is_string($value)) {
131
                    return false;
132
                }
133
            }
134
135
        }
136
        return true;
137
    }
138
139
    /**
140
     * @return array
141
     */
142
    public function getNonIdpAttributes()
143
    {
144
        $attributes = $this->getAttributesGroupedBySource();
145
        unset($attributes['idp']);
146
        return $attributes;
147
    }
148
149
    public function getAttributesGroupedBySource()
150
    {
151
        return $this->arp;
152
    }
153
154
    /**
155
     * @return bool
156
     */
157
    public function hasMotivations()
158
    {
159
        foreach ($this->arp as $arpSource) {
160
            foreach ($arpSource as $arpEntry) {
161
                $values = $arpEntry->getValue();
162
                $attributeValue = reset($values);
163
                if (array_key_exists('motivation', $attributeValue)) {
164
                    return true;
165
                }
166
            }
167
        }
168
        return false;
169
    }
170
171
    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...
172
    {
173
        foreach ($this->arp as $arpSource) {
174
            foreach ($arpSource as $arpEntry) {
175
                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...
176
                    $values = $arpEntry->getValue();
177
                    $attributeValue = reset($values);
178
                    if (array_key_exists('motivation', $attributeValue)) {
179
                        return $attributeValue['motivation'];
180
                    }
181
                }
182
            }
183
        }
184
        return '';
185
    }
186
}
187