AttributeReleasePolicyService   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 99
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 14

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 14
dl 0
loc 99
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
C applyAttributeReleasePolicies() 0 73 10
1
<?php
2
3
/**
4
 * Copyright 2016 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\EngineBlockApiClientBundle\Service;
20
21
use OpenConext\EngineBlockApiClientBundle\Exception\InvalidResponseException;
22
use OpenConext\EngineBlockApiClientBundle\Http\JsonApiClient;
23
use OpenConext\Profile\Value\Arp;
24
use OpenConext\Profile\Value\Consent;
25
use OpenConext\Profile\Value\ConsentList;
26
use OpenConext\Profile\Value\SpecifiedConsent;
27
use OpenConext\Profile\Value\SpecifiedConsentList;
28
use OpenConext\ProfileBundle\Attribute\AttributeSetWithFallbacks;
29
use stdClass;
30
use Surfnet\SamlBundle\Exception\UnknownUrnException;
31
use Surfnet\SamlBundle\SAML2\Attribute\Attribute;
32
use Surfnet\SamlBundle\SAML2\Attribute\AttributeDefinition;
33
use Surfnet\SamlBundle\SAML2\Attribute\AttributeDictionary;
34
use Surfnet\SamlBundle\SAML2\Attribute\AttributeSetInterface;
35
36
/**
37
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects) Build and mapping logic causes complexity
38
 */
39
final class AttributeReleasePolicyService
40
{
41
    /**
42
     * @var JsonApiClient
43
     */
44
    private $jsonApiClient;
45
46
    /**
47
     * @var AttributeDictionary
48
     */
49
    private $attributeDictionary;
50
51
    public function __construct(JsonApiClient $jsonApiClient, AttributeDictionary $attributeDictionary)
52
    {
53
        $this->jsonApiClient = $jsonApiClient;
54
        $this->attributeDictionary = $attributeDictionary;
55
    }
56
57
    /**
58
     * @param ConsentList $consentList
59
     * @param AttributeSetInterface $attributeSet
60
     * @return SpecifiedConsentList
61
     * @SuppressWarnings(PHPMD.NPathComplexity) Build and mapping logic causes complexity
62
     * @SuppressWarnings(PHPMD.CyclomaticComplexity) Build and mapping logic causes complexity
63
     */
64
    public function applyAttributeReleasePolicies(ConsentList $consentList, AttributeSetInterface $attributeSet)
65
    {
66
        $entityIds = $consentList->map(function (Consent $consent) {
67
            return $consent->getServiceProvider()->getEntity()->getEntityId()->getEntityId();
68
        });
69
70
        $mappedAttributes = [];
71
        foreach ($attributeSet as $attribute) {
72
            $mace = $attribute->getAttributeDefinition()->getUrnMace();
73
            $oid  = $attribute->getAttributeDefinition()->getUrnOid();
74
75
            if ($mace !== null) {
76
                $mappedAttributes[$mace] = $attribute->getValue();
77
            }
78
79
            if ($oid !== null) {
80
                $mappedAttributes[$oid] = $attribute->getValue();
81
            }
82
        }
83
84
        $data = [
85
            'entityIds'  => $entityIds,
86
            'attributes' => !empty($mappedAttributes) ? $mappedAttributes : new stdClass(),
87
            'showSources' => true,
88
        ];
89
        // Arp is applied for all entities
90
        $response = $this->jsonApiClient->post($data, '/arp');
91
92
        $data = [
93
            'entityIds'  => $entityIds,
94
        ];
95
96
        // Arp information is retrieved for all entities with arp enabled.
97
        $arpResponse = $this->jsonApiClient->post($data, '/read-arp');
98
99
        $specifiedConsents = $consentList->map(
100
            function (Consent $consent) use ($response, $arpResponse) {
101
                $entityId = $consent->getServiceProvider()->getEntity()->getEntityId()->getEntityId();
102
103
                if (!isset($response[$entityId])) {
104
                    throw new InvalidResponseException(
105
                        sprintf(
106
                            'EntityID "%s" was not found in the ARP response (entityIDs: %s)',
107
                            $entityId,
108
                            join(', ', array_keys($response))
109
                        )
110
                    );
111
                }
112
113
                $attributes = [];
114
                foreach ($response[$entityId] as $attributeName => $attributeValue) {
115
                    try {
116
                        $attributeDefinition = $this->attributeDictionary->getAttributeDefinitionByUrn($attributeName);
117
                    } catch (UnknownUrnException $exception) {
118
                        $attributeDefinition = new AttributeDefinition($attributeName, $attributeName, $attributeName);
119
                    }
120
121
                    $attribute = new Attribute($attributeDefinition, $attributeValue);
122
                    if (!in_array($attribute, $attributes)) {
123
                        $attributes[] = $attribute;
124
                    }
125
                }
126
                $arp = Arp::createWith([], null);
127
                if (isset($arpResponse[$entityId])) {
128
                    $arp = Arp::createWith($arpResponse[$entityId], $this->attributeDictionary);
129
                }
130
131
                return SpecifiedConsent::specifies($consent, AttributeSetWithFallbacks::create($attributes), $arp);
132
            }
133
        );
134
135
        return SpecifiedConsentList::createWith($specifiedConsents);
136
    }
137
}
138