Completed
Pull Request — develop (#72)
by A.
06:49 queued 02:30
created

applyAttributeReleasePolicies()   C

Complexity

Conditions 9
Paths 10

Size

Total Lines 60
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 60
rs 6.8358
cc 9
eloc 35
nc 10
nop 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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