Passed
Pull Request — master (#1)
by Tim
01:48
created

AttributeServer::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 4
rs 10
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\HTTP\RunnableResponse;
19
use SimpleSAML\Logger;
20
use SimpleSAML\Session;
21
use SimpleSAML\Metadata\MetaDataStorageHandler;
22
use SimpleSAML\Module\saml\Message;
23
use SimpleSAML\XHTML\Template;
24
use Symfony\Component\HttpFoundation\Request;
25
26
/**
27
 * Controller class for the exampleattributeserver module.
28
 *
29
 * This class serves the attribute server available in the module.
30
 *
31
 * @package SimpleSAML\Module\exampleattributeserver
32
 */
33
class AttributeServer
34
{
35
    /** @var \SimpleSAML\Configuration */
36
    protected $config;
37
38
    /** @var \SimpleSAML\Session */
39
    protected $session;
40
41
42
    /**
43
     * ConfigController constructor.
44
     *
45
     * @param \SimpleSAML\Configuration $config The configuration to use.
46
     * @param \SimpleSAML\Session $session The current user session.
47
     */
48
    public function __construct(Configuration $config, Session $session)
49
    {
50
        $this->config = $config;
51
        $this->session = $session;
52
    }
53
54
55
    /**
56
     * @param \Symfony\Component\HttpFoundation\Request $request The current request.
57
     *
58
     * @return \SimpleSAML\HTTP\RunnableResponse
59
     * @throws \SimpleSAML\Error\BadRequest
60
     */
61
    public function main(/** @scrutinizer ignore-unused */ Request $request): RunnableResponse
62
    {
63
        $metadata = MetaDataStorageHandler::getMetadataHandler();
64
65
        $binding = Binding::getCurrentBinding();
66
        $query = $binding->receive();
67
        if (!($query instanceof AttributeQuery)) {
68
            throw new Error\BadRequest('Invalid message received to AttributeQuery endpoint.');
69
        }
70
71
        $idpEntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted');
72
73
        $issuer = $query->getIssuer();
74
        if ($issuer === null) {
75
            throw new Error\BadRequest('Missing <saml:Issuer> in <samlp:AttributeQuery>.');
76
        } else {
77
            $spEntityId = $issuer->getValue();
78
            if ($spEntityId === '') {
79
                throw new Error\BadRequest('Empty <saml:Issuer> in <samlp:AttributeQuery>.');
80
            }
81
        }
82
83
        $idpMetadata = $metadata->getMetaDataConfig($idpEntityId, 'saml20-idp-hosted');
84
        $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'saml20-sp-remote');
85
86
        // The endpoint we should deliver the message to
87
        $endpoint = $spMetadata->getString('testAttributeEndpoint');
88
89
        // The attributes we will return
90
        $attributes = [
91
            'name' => ['value1', 'value2', 'value3'],
92
            'test' => ['test'],
93
        ];
94
95
        // The name format of the attributes
96
        $attributeNameFormat = Constants::NAMEFORMAT_UNSPECIFIED;
97
98
        // Determine which attributes we will return
99
        $returnAttributes = array_keys($query->getAttributes());
100
        if (count($returnAttributes) === 0) {
101
            Logger::debug('No attributes requested - return all attributes.');
102
            $returnAttributes = $attributes;
103
        } elseif ($query->getAttributeNameFormat() !== $attributeNameFormat) {
104
            Logger::debug('Requested attributes with wrong NameFormat - no attributes returned.');
105
            $returnAttributes = [];
106
        } else {
107
            /** @var array $values */
108
            foreach ($returnAttributes as $name => $values) {
109
                if (!array_key_exists($name, $attributes)) {
110
                    // We don't have this attribute
111
                    unset($returnAttributes[$name]);
112
                    continue;
113
                }
114
                if (count($values) === 0) {
115
                    // Return all attributes
116
                    $returnAttributes[$name] = $attributes[$name];
117
                    continue;
118
                }
119
120
                // Filter which attribute values we should return
121
                $returnAttributes[$name] = array_intersect($values, $attributes[$name]);
122
            }
123
        }
124
125
        // $returnAttributes contains the attributes we should return. Send them
126
        $issuer = new Issuer();
127
        $issuer->setValue($idpEntityId);
128
129
        $assertion = new Assertion();
130
        $assertion->setIssuer($issuer);
131
        $assertion->setNameId($query->getNameId());
132
        $assertion->setNotBefore(time());
133
        $assertion->setNotOnOrAfter(time() + 300); // 60*5 = 5min
134
        $assertion->setValidAudiences([$spEntityId]);
135
        $assertion->setAttributes($returnAttributes);
136
        $assertion->setAttributeNameFormat($attributeNameFormat);
137
138
        $sc = new SubjectConfirmation();
139
        $sc->setMethod(Constants::CM_BEARER);
140
141
        $scd = new SubjectConfirmationData();
142
        $scd->setNotOnOrAfter(time() + 300); // 60*5 = 5min
143
        $scd->setRecipient($endpoint);
144
        $scd->setInResponseTo($query->getId());
145
        $sc->setSubjectConfirmationData($scd);
146
        $assertion->setSubjectConfirmation([$sc]);
147
148
        Message::addSign($idpMetadata, $spMetadata, $assertion);
149
150
        $response = new Response();
151
        $response->setRelayState($query->getRelayState());
152
        $response->setDestination($endpoint);
153
        $response->setIssuer($issuer);
154
        $response->setInResponseTo($query->getId());
155
        $response->setAssertions([$assertion]);
156
        Message::addSign($idpMetadata, $spMetadata, $response);
157
158
        return new RunnableRespons([new HTTPPost(), 'send'], [$response]);
0 ignored issues
show
Bug introduced by
The type SimpleSAML\Module\exampl...troller\RunnableRespons 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...
159
    }
160
}
161