1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* This file is part of the LightSAML-Core package. |
5
|
|
|
* |
6
|
|
|
* (c) Milos Tomic <[email protected]> |
7
|
|
|
* |
8
|
|
|
* This source file is subject to the MIT license that is bundled |
9
|
|
|
* with this source code in the file LICENSE. |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace LightSaml\Model\Metadata; |
13
|
|
|
|
14
|
|
|
use LightSaml\Helper; |
15
|
|
|
use LightSaml\Model\Context\DeserializationContext; |
16
|
|
|
use LightSaml\Model\Context\SerializationContext; |
17
|
|
|
use LightSaml\Model\XmlDSig\Signature; |
18
|
|
|
use LightSaml\SamlConstants; |
19
|
|
|
|
20
|
|
|
class EntitiesDescriptor extends Metadata |
21
|
|
|
{ |
22
|
|
|
/** @var int */ |
23
|
|
|
protected $validUntil; |
24
|
|
|
|
25
|
|
|
/** @var string */ |
26
|
|
|
protected $cacheDuration; |
27
|
|
|
|
28
|
|
|
/** @var string */ |
29
|
|
|
protected $id; |
30
|
|
|
|
31
|
|
|
/** @var string */ |
32
|
|
|
protected $name; |
33
|
|
|
|
34
|
|
|
/** @var Signature */ |
35
|
|
|
protected $signature; |
36
|
|
|
|
37
|
|
|
/** @var EntitiesDescriptor[]|EntityDescriptor[] */ |
38
|
|
|
protected $items = array(); |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* @param string $filename |
42
|
|
|
* |
43
|
|
|
* @return EntitiesDescriptor |
44
|
|
|
*/ |
45
|
6 |
|
public static function load($filename) |
46
|
|
|
{ |
47
|
6 |
|
return self::loadXml(file_get_contents($filename)); |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* @param string $xml |
52
|
|
|
* |
53
|
|
|
* @return EntitiesDescriptor |
54
|
|
|
*/ |
55
|
6 |
View Code Duplication |
public static function loadXml($xml) |
|
|
|
|
56
|
|
|
{ |
57
|
6 |
|
$context = new DeserializationContext(); |
58
|
6 |
|
$context->getDocument()->loadXML($xml); |
59
|
6 |
|
$ed = new self(); |
60
|
6 |
|
$ed->deserialize($context->getDocument(), $context); |
61
|
|
|
|
62
|
5 |
|
return $ed; |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* @param string $cacheDuration |
67
|
|
|
* |
68
|
|
|
* @return EntitiesDescriptor |
69
|
|
|
* |
70
|
|
|
* @throws \InvalidArgumentException |
71
|
|
|
*/ |
72
|
3 |
|
public function setCacheDuration($cacheDuration) |
73
|
|
|
{ |
74
|
3 |
|
Helper::validateDurationString($cacheDuration); |
75
|
|
|
|
76
|
2 |
|
$this->cacheDuration = $cacheDuration; |
77
|
|
|
|
78
|
2 |
|
return $this; |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* @return string |
83
|
|
|
*/ |
84
|
3 |
|
public function getCacheDuration() |
85
|
|
|
{ |
86
|
3 |
|
return $this->cacheDuration; |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* @param string $id |
91
|
|
|
* |
92
|
|
|
* @return EntitiesDescriptor |
93
|
|
|
*/ |
94
|
2 |
|
public function setID($id) |
95
|
|
|
{ |
96
|
2 |
|
$this->id = (string) $id; |
97
|
|
|
|
98
|
2 |
|
return $this; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* @return string |
103
|
|
|
*/ |
104
|
3 |
|
public function getID() |
105
|
|
|
{ |
106
|
3 |
|
return $this->id; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* @param string $name |
111
|
|
|
* |
112
|
|
|
* @return EntitiesDescriptor |
113
|
|
|
*/ |
114
|
11 |
|
public function setName($name) |
115
|
|
|
{ |
116
|
11 |
|
$this->name = (string) $name; |
117
|
|
|
|
118
|
11 |
|
return $this; |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
/** |
122
|
|
|
* @return string |
123
|
|
|
*/ |
124
|
4 |
|
public function getName() |
125
|
|
|
{ |
126
|
4 |
|
return $this->name; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* @param \LightSaml\Model\XmlDSig\Signature $signature |
131
|
|
|
* |
132
|
|
|
* @return EntitiesDescriptor |
133
|
|
|
*/ |
134
|
2 |
|
public function setSignature(Signature $signature) |
135
|
|
|
{ |
136
|
2 |
|
$this->signature = $signature; |
137
|
|
|
|
138
|
2 |
|
return $this; |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* @return \LightSaml\Model\XmlDSig\Signature |
143
|
|
|
*/ |
144
|
2 |
|
public function getSignature() |
145
|
|
|
{ |
146
|
2 |
|
return $this->signature; |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
/** |
150
|
|
|
* @param int|string $validUntil |
151
|
|
|
* |
152
|
|
|
* @return EntitiesDescriptor |
153
|
|
|
* |
154
|
|
|
* @throws \InvalidArgumentException |
155
|
|
|
*/ |
156
|
6 |
|
public function setValidUntil($validUntil) |
157
|
|
|
{ |
158
|
6 |
|
$value = Helper::getTimestampFromValue($validUntil); |
159
|
5 |
|
if ($value < 0) { |
160
|
1 |
|
throw new \InvalidArgumentException('Invalid validUntil'); |
161
|
|
|
} |
162
|
4 |
|
$this->validUntil = $value; |
163
|
|
|
|
164
|
4 |
|
return $this; |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
/** |
168
|
|
|
* @return string |
169
|
|
|
*/ |
170
|
2 |
|
public function getValidUntilString() |
171
|
|
|
{ |
172
|
2 |
|
if ($this->validUntil) { |
173
|
|
|
return Helper::time2string($this->validUntil); |
174
|
|
|
} |
175
|
|
|
|
176
|
2 |
|
return null; |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* @return int |
181
|
|
|
*/ |
182
|
1 |
|
public function getValidUntilTimestamp() |
183
|
|
|
{ |
184
|
1 |
|
return $this->validUntil; |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
/** |
188
|
|
|
* @return \DateTime|null |
189
|
|
|
*/ |
190
|
|
|
public function getValidUntilDateTime() |
191
|
|
|
{ |
192
|
|
|
if ($this->validUntil) { |
193
|
|
|
return new \DateTime('@'.$this->validUntil); |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
return null; |
197
|
|
|
} |
198
|
|
|
|
199
|
|
|
/** |
200
|
|
|
* @param EntitiesDescriptor|EntityDescriptor $item |
201
|
|
|
* |
202
|
|
|
* @return EntitiesDescriptor |
203
|
|
|
* |
204
|
|
|
* @throws \InvalidArgumentException |
205
|
|
|
*/ |
206
|
25 |
|
public function addItem($item) |
207
|
|
|
{ |
208
|
25 |
View Code Duplication |
if (false == $item instanceof self && false == $item instanceof EntityDescriptor) { |
|
|
|
|
209
|
4 |
|
throw new \InvalidArgumentException('Expected EntitiesDescriptor or EntityDescriptor'); |
210
|
|
|
} |
211
|
21 |
|
if ($item === $this) { |
212
|
1 |
|
throw new \InvalidArgumentException('Circular reference detected'); |
213
|
|
|
} |
214
|
20 |
|
if ($item instanceof self) { |
215
|
7 |
|
if ($item->containsItem($this)) { |
216
|
1 |
|
throw new \InvalidArgumentException('Circular reference detected'); |
217
|
|
|
} |
218
|
|
|
} |
219
|
20 |
|
$this->items[] = $item; |
220
|
|
|
|
221
|
20 |
|
return $this; |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
/** |
225
|
|
|
* @param EntitiesDescriptor|EntityDescriptor $item |
226
|
|
|
* |
227
|
|
|
* @return bool |
228
|
|
|
* |
229
|
|
|
* @throws \InvalidArgumentException |
230
|
|
|
*/ |
231
|
7 |
|
public function containsItem($item) |
232
|
|
|
{ |
233
|
7 |
View Code Duplication |
if (false == $item instanceof self && false == $item instanceof EntityDescriptor) { |
|
|
|
|
234
|
|
|
throw new \InvalidArgumentException('Expected EntitiesDescriptor or EntityDescriptor'); |
235
|
|
|
} |
236
|
7 |
|
foreach ($this->items as $i) { |
237
|
5 |
|
if ($i === $item) { |
238
|
2 |
|
return true; |
239
|
|
|
} |
240
|
5 |
|
if ($i instanceof self) { |
241
|
2 |
|
if ($i->containsItem($item)) { |
242
|
5 |
|
return true; |
243
|
|
|
} |
244
|
|
|
} |
245
|
|
|
} |
246
|
|
|
|
247
|
7 |
|
return false; |
248
|
|
|
} |
249
|
|
|
|
250
|
|
|
/** |
251
|
|
|
* @return EntitiesDescriptor[]|EntityDescriptor[] |
252
|
|
|
*/ |
253
|
8 |
|
public function getAllItems() |
254
|
|
|
{ |
255
|
8 |
|
return $this->items; |
256
|
|
|
} |
257
|
|
|
|
258
|
|
|
/** |
259
|
|
|
* @return EntityDescriptor[] |
260
|
|
|
*/ |
261
|
8 |
|
public function getAllEntityDescriptors() |
262
|
|
|
{ |
263
|
8 |
|
$result = array(); |
264
|
8 |
|
foreach ($this->items as $item) { |
265
|
8 |
|
if ($item instanceof self) { |
266
|
1 |
|
$result = array_merge($result, $item->getAllEntityDescriptors()); |
267
|
|
|
} else { |
268
|
8 |
|
$result[] = $item; |
269
|
|
|
} |
270
|
|
|
} |
271
|
|
|
|
272
|
8 |
|
return $result; |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
/** |
276
|
|
|
* @param string $entityId |
277
|
|
|
* |
278
|
|
|
* @return EntityDescriptor|null |
279
|
|
|
*/ |
280
|
4 |
|
public function getByEntityId($entityId) |
281
|
|
|
{ |
282
|
4 |
|
foreach ($this->getAllEntityDescriptors() as $entityDescriptor) { |
283
|
4 |
|
if ($entityDescriptor->getEntityID() == $entityId) { |
284
|
4 |
|
return $entityDescriptor; |
285
|
|
|
} |
286
|
|
|
} |
287
|
|
|
|
288
|
|
|
return null; |
289
|
|
|
} |
290
|
|
|
|
291
|
|
|
/** |
292
|
|
|
* @param \DOMNode $parent |
293
|
|
|
* @param SerializationContext $context |
294
|
|
|
* |
295
|
|
|
* @return void |
296
|
|
|
*/ |
297
|
2 |
|
public function serialize(\DOMNode $parent, SerializationContext $context) |
298
|
|
|
{ |
299
|
2 |
|
$result = $this->createElement('EntitiesDescriptor', SamlConstants::NS_METADATA, $parent, $context); |
300
|
|
|
|
301
|
2 |
|
$this->attributesToXml(array('validUntil', 'cacheDuration', 'ID', 'Name'), $result); |
302
|
|
|
|
303
|
2 |
|
$this->singleElementsToXml(array('Signature'), $result, $context); |
304
|
|
|
|
305
|
2 |
|
$this->manyElementsToXml($this->getAllItems(), $result, $context); |
306
|
2 |
|
} |
307
|
|
|
|
308
|
|
|
/** |
309
|
|
|
* @param \DOMNode $node |
310
|
|
|
* @param DeserializationContext $context |
311
|
|
|
*/ |
312
|
12 |
|
public function deserialize(\DOMNode $node, DeserializationContext $context) |
313
|
|
|
{ |
314
|
12 |
|
$this->checkXmlNodeName($node, 'EntitiesDescriptor', SamlConstants::NS_METADATA); |
315
|
|
|
|
316
|
11 |
|
$this->attributesFromXml($node, array('validUntil', 'cacheDuration', 'ID', 'Name')); |
|
|
|
|
317
|
|
|
|
318
|
11 |
|
$this->singleElementsFromXml($node, $context, array( |
|
|
|
|
319
|
11 |
|
'Signature' => array('ds', 'LightSaml\Model\XmlDSig\SignatureXmlReader'), |
320
|
|
|
)); |
321
|
|
|
|
322
|
11 |
|
$this->manyElementsFromXml( |
323
|
11 |
|
$node, |
|
|
|
|
324
|
11 |
|
$context, |
325
|
11 |
|
'EntityDescriptor', |
326
|
11 |
|
'md', |
327
|
11 |
|
'LightSaml\Model\Metadata\EntityDescriptor', |
328
|
11 |
|
'addItem' |
329
|
|
|
); |
330
|
11 |
|
$this->manyElementsFromXml( |
331
|
11 |
|
$node, |
|
|
|
|
332
|
11 |
|
$context, |
333
|
11 |
|
'EntitiesDescriptor', |
334
|
11 |
|
'md', |
335
|
11 |
|
'LightSaml\Model\Metadata\EntitiesDescriptor', |
336
|
11 |
|
'addItem' |
337
|
|
|
); |
338
|
11 |
|
} |
339
|
|
|
} |
340
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.