Passed
Pull Request — master (#1)
by Tim
02:07
created

AttributeServer::main()   B

Complexity

Conditions 9
Paths 6

Size

Total Lines 99
Code Lines 64

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 9
eloc 64
c 1
b 0
f 0
nc 6
nop 1
dl 0
loc 99
rs 7.2298

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
declare(strict_types=1);
4
5
namespace SimpleSAML\Module\exampleattributeserver\Controller;
6
7
use SAML2\Assertion;
8
use SAML2\AttributeQuery;
9
use SAML2\Binding;
10
use SAML2\Constants;
11
use SAML2\HTTPPost;
12
use SAML2\Response;
13
use SAML2\XML\saml\Issuer;
14
use SAML2\XML\saml\SubjectConfirmation;
15
use SAML2\XML\saml\SubjectConfirmationData;
16
use SimpleSAML\Configuration;
17
use SimpleSAML\Error;
18
use SimpleSAML\Logger;
19
use SimpleSAML\Session;
20
use SimpleSAML\Metadata\MetaDataStorageHandler;
21
use SimpleSAML\Module\saml\Message;
22
23
/**
24
 * Controller class for the exampleattributeserver module.
25
 *
26
 * This class serves the attribute server available in the module.
27
 *
28
 * @package SimpleSAML\Module\exampleattributeserver
29
 */
30
class AttributeServer
31
{
32
    /** @var \SimpleSAML\Configuration */
33
    protected $config;
34
35
    /** @var \SimpleSAML\Session */
36
    protected $session;
37
38
39
    /**
40
     * ConfigController constructor.
41
     *
42
     * @param \SimpleSAML\Configuration $config The configuration to use.
43
     * @param \SimpleSAML\Session $session The current user session.
44
     */
45
    public function __construct(Configuration $config, Session $session)
46
    {
47
        $this->config = $config;
48
        $this->session = $session;
49
    }
50
51
52
    /**
53
     * @param \Symfony\Component\HttpFoundation\Request $request The current request.
54
     *
55
     * @return \SimpleSAML\XHTML\Template
56
     */
57
    public function main(/** @scrutinizer ignore-unused */ Request $request): Template
0 ignored issues
show
Bug introduced by
The type SimpleSAML\Module\exampl...rver\Controller\Request was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
Bug introduced by
The type SimpleSAML\Module\exampl...ver\Controller\Template was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
58
    {
59
        $metadata = MetaDataStorageHandler::getMetadataHandler();
60
61
        $binding = Binding::getCurrentBinding();
62
        $query = $binding->receive();
63
        if (!($query instanceof AttributeQuery)) {
64
            throw new Error\BadRequest('Invalid message received to AttributeQuery endpoint.');
65
        }
66
67
        $idpEntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
68
69
        $issuer = $query->getIssuer();
70
        if ($issuer === null) {
71
            throw new Error\BadRequest('Missing <saml:Issuer> in <samlp:AttributeQuery>.');
72
        } else {
73
            $spEntityId = $issuer->getValue();
74
            if ($spEntityId === '') {
75
                throw new Error\BadRequest('Empty <saml:Issuer> in <samlp:AttributeQuery>.');
76
            }
77
        }
78
79
        $idpMetadata = $metadata->getMetaDataConfig($idpEntityId, 'saml20-idp-hosted');
80
        $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-remote');
81
82
        // The endpoint we should deliver the message to
83
        $endpoint = $spMetadata->getString('testAttributeEndpoint');
84
85
        // The attributes we will return
86
        $attributes = [
87
            'name' => ['value1', 'value2', 'value3'],
88
            'test' => ['test'],
89
        ];
90
91
        // The name format of the attributes
92
        $attributeNameFormat = Constants::NAMEFORMAT_UNSPECIFIED;
93
94
        // Determine which attributes we will return
95
        $returnAttributes = array_keys($query->getAttributes());
96
        if (count($returnAttributes) === 0) {
97
            Logger::debug('No attributes requested - return all attributes.');
98
            $returnAttributes = $attributes;
99
        } elseif ($query->getAttributeNameFormat() !== $attributeNameFormat) {
100
            Logger::debug('Requested attributes with wrong NameFormat - no attributes returned.');
101
            $returnAttributes = [];
102
        } else {
103
            /** @var array $values */
104
            foreach ($returnAttributes as $name => $values) {
105
                if (!array_key_exists($name, $attributes)) {
106
                    // We don't have this attribute
107
                    unset($returnAttributes[$name]);
108
                    continue;
109
                }
110
                if (count($values) === 0) {
111
                    // Return all attributes
112
                    $returnAttributes[$name] = $attributes[$name];
113
                    continue;
114
                }
115
116
                // Filter which attribute values we should return
117
                $returnAttributes[$name] = array_intersect($values, $attributes[$name]);
118
            }
119
        }
120
121
        // $returnAttributes contains the attributes we should return. Send them
122
        $issuer = new Issuer();
123
        $issuer->setValue($idpEntityId);
124
125
        $assertion = new Assertion();
126
        $assertion->setIssuer($issuer);
127
        $assertion->setNameId($query->getNameId());
128
        $assertion->setNotBefore(time());
129
        $assertion->setNotOnOrAfter(time() + 300); // 60*5 = 5min
130
        $assertion->setValidAudiences([$spEntityId]);
131
        $assertion->setAttributes($returnAttributes);
132
        $assertion->setAttributeNameFormat($attributeNameFormat);
133
134
        $sc = new SubjectConfirmation();
135
        $sc->setMethod(Constants::CM_BEARER);
136
137
        $scd = new SubjectConfirmationData();
138
        $scd->setNotOnOrAfter(time() + 300); // 60*5 = 5min
139
        $scd->setRecipient($endpoint);
140
        $scd->setInResponseTo($query->getId());
141
        $sc->setSubjectConfirmationData($scd);
142
        $assertion->setSubjectConfirmation([$sc]);
143
144
        Message::addSign($idpMetadata, $spMetadata, $assertion);
145
146
        $response = new Response();
147
        $response->setRelayState($query->getRelayState());
148
        $response->setDestination($endpoint);
149
        $response->setIssuer($issuer);
150
        $response->setInResponseTo($query->getId());
151
        $response->setAssertions([$assertion]);
152
        Message::addSign($idpMetadata, $spMetadata, $response);
153
154
        $binding = new HTTPPost();
155
        $binding->send($response);
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return SimpleSAML\Module\exampl...ver\Controller\Template. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
156
    }
157
}
158