Passed
Pull Request — master (#226)
by Jaime Pérez
02:37
created

AttributeQuery::setAttributes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SAML2\XML\samlp;
6
7
use DOMElement;
8
use SAML2\Utils;
9
use SAML2\XML\ds\Signature;
10
use SAML2\XML\saml\Attribute;
11
use SAML2\XML\saml\Issuer;
12
use SAML2\XML\saml\Subject;
13
use Webmozart\Assert\Assert;
14
15
/**
16
 * Class for SAML 2 attribute query messages.
17
 *
18
 * An attribute query asks for a set of attributes. The following
19
 * rules apply:
20
 *
21
 * - If no attributes are present in the query, all attributes should be
22
 *   returned.
23
 * - If any attributes are present, only those attributes which are present
24
 *   in the query should be returned.
25
 * - If an attribute contains any attribute values, only the attribute values
26
 *   which match those in the query should be returned.
27
 *
28
 * @package SimpleSAMLphp
29
 */
30
class AttributeQuery extends AbstractSubjectQuery
31
{
32
    /**
33
     * The attributes, as an associative array.
34
     *
35
     * @var \SAML2\XML\saml\Attribute[]
36
     */
37
    protected $attributes = [];
38
39
40
    /**
41
     * Constructor for SAML 2 AttributeQuery.
42
     *
43
     * @param \SAML2\XML\saml\Subject $subject
44
     * @param \SAML2\XML\saml\Attribute[] $attributes
45
     * @param \SAML2\XML\saml\Issuer $issuer
46
     * @param string $id
47
     * @param int $issueInstant
48
     * @param string|null $destination
49
     * @param string|null $consent
50
     * @param \SAML2\XML\samlp\Extensions $extensions
51
     */
52
    public function __construct(
53
        Subject $subject,
54
        array $attributes = [],
55
        ?Issuer $issuer = null,
56
        ?string $id = null,
57
        ?int $issueInstant = null,
58
        ?string $destination = null,
59
        ?string $consent = null,
60
        ?Extensions $extensions = null
61
    ) {
62
        parent::__construct($subject, $issuer, $id, $issueInstant, $destination, $consent, $extensions);
63
64
        $this->setAttributes($attributes);
65
    }
66
67
68
    /**
69
     * Retrieve all requested attributes.
70
     *
71
     * @return \SAML2\XML\saml\Attribute[] All requested attributes, as an associative array.
72
     */
73
    public function getAttributes(): array
74
    {
75
        return $this->attributes;
76
    }
77
78
79
    /**
80
     * Set all requested attributes.
81
     *
82
     * @param \SAML2\XML\saml\Attribute[] $attributes All requested attributes, as an associative array.
83
     * @return void
84
     */
85
    public function setAttributes(array $attributes): void
86
    {
87
        Assert::allIsInstanceOf($attributes, Attribute::class);
88
        $this->attributes = $attributes;
89
    }
90
91
92
    /**
93
     * Create a class from XML
94
     *
95
     * @param \DOMElement $xml
96
     * @return self
97
     */
98
    public static function fromXML(DOMElement $xml): object
99
    {
100
        Assert::same($xml->localName, 'AttributeQuery');
101
        Assert::same($xml->namespaceURI, AttributeQuery::NS);
102
        Assert::same('2.0', self::getAttribute($xml, 'Version'));
103
104
        $id = self::getAttribute($xml, 'ID');
105
        $issueInstant = Utils::xsDateTimeToTimestamp(self::getAttribute($xml, 'IssueInstant'));
106
        $destination = self::getAttribute($xml, 'Destination', null);
107
        $consent = self::getAttribute($xml, 'Consent', null);
108
109
        $issuer = Issuer::getChildrenOfClass($xml);
110
        Assert::countBetween($issuer, 0, 1);
111
112
        $extensions = Extensions::getChildrenOfClass($xml);
113
        Assert::maxCount($extensions, 1, 'Only one saml:Extensions element is allowed.');
114
115
        $subject = Subject::getChildrenOfClass($xml);
116
        Assert::notEmpty($subject, 'Missing subject in subject query.');
117
        Assert::maxCount($subject, 1, 'More than one <saml:Subject> in AttributeQuery');
118
119
        $signature = Signature::getChildrenOfClass($xml);
120
        Assert::maxCount($signature, 1, 'Only one ds:Signature element is allowed.');
121
122
        $request = new self(
123
            array_pop($subject),
124
            Attribute::getChildrenOfClass($xml),
125
            array_pop($issuer),
126
            $id,
127
            $issueInstant,
128
            $destination,
129
            $consent,
130
            array_pop($extensions)
131
        );
132
133
        if (!empty($signature)) {
134
            $request->setSignature($signature[0]);
135
        }
136
137
        return $request;
138
    }
139
140
141
    /**
142
     * Convert the attribute query message to an XML element.
143
     *
144
     * @return \DOMElement This attribute query.
145
     */
146
    public function toXML(?DOMElement $parent = null): DOMElement
147
    {
148
        $parent = parent::toXML($parent);
149
150
        foreach ($this->attributes as $attribute) {
151
            $attribute->toXML($parent);
152
        }
153
154
        return $this->signElement($parent);
155
    }
156
}
157