EntityDescriptorHelper::getDescriptors()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
cc 3
nc 3
nop 2
1
<?php
2
3
4
namespace flipbox\saml\core\helpers;
5
6
use flipbox\saml\core\AbstractPlugin;
7
use SAML2\XML\md\EndpointType;
8
use SAML2\XML\md\EntityDescriptor;
9
use SAML2\XML\md\IDPSSODescriptor;
10
use SAML2\XML\md\IndexedEndpointType;
11
use SAML2\XML\md\SPSSODescriptor;
12
use SAML2\XML\md\SSODescriptorType;
13
14
class EntityDescriptorHelper
15
{
16
    const ENDPOINT_SERVICE_ARTIFACT_RESOLUTION = 'ArtifactResolution';
17
    const ENDPOINT_SERVICE_SINGLE_LOGOUT = 'SingleLogout';
18
    const ENDPOINT_SERVICE_MANAGE_NAME_ID = 'ManageNameID';
19
20
    const ENDPOINT_SERVICE_ASSERTION_CONSUMER = 'AssertionConsumer';
21
    const ENDPOINT_SERVICE_ATTRIBUTE_CONSUMING = 'AttributeConsuming';
22
23
    const ENDPOINT_SERVICE_SINGLE_SIGN_ON = 'SingleSignOn';
24
    const ENDPOINT_SERVICE_ASSERTION_ID_REQUEST = 'AssertionIDRequest';
25
    const ENDPOINT_SERVICE_NAME_ID_MAPPING = 'NameIDMapping';
26
27
    const ENDPOINT_SERVICE_OPTIONS = [
28
        // Common
29
        self::ENDPOINT_SERVICE_ARTIFACT_RESOLUTION,
30
        self::ENDPOINT_SERVICE_SINGLE_LOGOUT,
31
        self::ENDPOINT_SERVICE_MANAGE_NAME_ID,
32
33
        // SP
34
        self::ENDPOINT_SERVICE_ASSERTION_CONSUMER,
35
        self::ENDPOINT_SERVICE_ATTRIBUTE_CONSUMING,
36
37
        // IDP
38
        self::ENDPOINT_SERVICE_SINGLE_SIGN_ON,
39
        self::ENDPOINT_SERVICE_ASSERTION_ID_REQUEST,
40
        self::ENDPOINT_SERVICE_NAME_ID_MAPPING,
41
    ];
42
43
    /**
44
     * @param EntityDescriptor $entityDescriptor
45
     * @return IDPSSODescriptor[]
46
     */
47
    public static function getIdpDescriptors(EntityDescriptor $entityDescriptor)
48
    {
49
        return static::getDescriptors($entityDescriptor, IDPSSODescriptor::class);
50
    }
51
52
    /**
53
     * @param EntityDescriptor $entityDescriptor
54
     * @return SPSSODescriptor[]
55
     */
56
    public static function getSpDescriptors(EntityDescriptor $entityDescriptor)
57
    {
58
        return static::getDescriptors($entityDescriptor, SPSSODescriptor::class);
59
    }
60
61
    /**
62
     * @param EntityDescriptor $entityDescriptor
63
     * @param string $type
64
     * @return SSODescriptorType[]
65
     */
66
    protected static function getDescriptors(EntityDescriptor $entityDescriptor, string $type)
67
    {
68
        $descriptors = [];
69
        foreach ($entityDescriptor->getRoleDescriptor() as $roleDescriptor) {
70
            if ($roleDescriptor instanceof $type) {
71
                $descriptors[] = $roleDescriptor;
72
            }
73
        }
74
75
        return $descriptors;
76
    }
77
78
    /**
79
     * Common
80
     */
81
82
    /**
83
     * @param SSODescriptorType[] $roleDescriptors
84
     * @param string $binding
85
     * @return EndpointType|null
86
     */
87
    public static function getFirstArtifactResolutionService(array $roleDescriptors, string $binding = null)
88
    {
89
        return static::getFirstService(self::ENDPOINT_SERVICE_ARTIFACT_RESOLUTION, $roleDescriptors, $binding);
90
    }
91
92
    /**
93
     * @param SSODescriptorType[] $roleDescriptors
94
     * @param string $binding
95
     * @return EndpointType|null
96
     */
97
    public static function getFirstSLOService(array $roleDescriptors, string $binding = null)
98
    {
99
        return static::getFirstService(self::ENDPOINT_SERVICE_SINGLE_LOGOUT, $roleDescriptors, $binding);
100
    }
101
102
    /**
103
     * @param SSODescriptorType[] $roleDescriptors
104
     * @param string $binding
105
     * @return EndpointType|null
106
     */
107
    public static function getFirstManageNameIDService(array $roleDescriptors, string $binding = null)
108
    {
109
        return static::getFirstService(self::ENDPOINT_SERVICE_MANAGE_NAME_ID, $roleDescriptors, $binding);
110
    }
111
112
    /**
113
     * Get First SP Services
114
     */
115
116
    /**
117
     * @param SPSSODescriptor[] $roleDescriptors
118
     * @param string $binding
119
     * @return EndpointType|null
120
     */
121
    public static function getFirstSpAssertionConsumerService(array $roleDescriptors, string $binding = null)
122
    {
123
        return static::getFirstService(self::ENDPOINT_SERVICE_ASSERTION_CONSUMER, $roleDescriptors, $binding);
124
    }
125
126
    /**
127
     * @param SPSSODescriptor[] $roleDescriptors
128
     * @param string $binding
129
     * @return EndpointType|null
130
     */
131
    public static function getFirstSpAttributeConsumingService(array $roleDescriptors, string $binding = null)
132
    {
133
        return static::getFirstService(self::ENDPOINT_SERVICE_ATTRIBUTE_CONSUMING, $roleDescriptors, $binding);
134
    }
135
136
    /**
137
     * Get First IDP Services
138
     */
139
140
    /**
141
     * @param IDPSSODescriptor[] $roleDescriptors
142
     * @param string $binding
143
     * @return EndpointType|null
144
     */
145
    public static function getFirstIdpSSOService(array $roleDescriptors, string $binding = null)
146
    {
147
        return static::getFirstService(self::ENDPOINT_SERVICE_SINGLE_SIGN_ON, $roleDescriptors, $binding);
148
    }
149
150
    /**
151
     * @param IDPSSODescriptor[] $roleDescriptors
152
     * @param string $binding
153
     * @return EndpointType|null
154
     */
155
    public static function getFirstIdpAssertionIdRequestService(array $roleDescriptors, string $binding = null)
156
    {
157
        return static::getFirstService(self::ENDPOINT_SERVICE_ASSERTION_ID_REQUEST, $roleDescriptors, $binding);
158
    }
159
160
    /**
161
     * @param IDPSSODescriptor[] $roleDescriptors
162
     * @param string $binding
163
     * @return EndpointType|null
164
     */
165
    public static function getFirstIdpNameIDMappingService(array $roleDescriptors, string $binding = null)
166
    {
167
        return static::getFirstService(self::ENDPOINT_SERVICE_NAME_ID_MAPPING, $roleDescriptors, $binding);
168
    }
169
170
    /**
171
     * @param SSODescriptorType[] $roleDescriptors
172
     * @param string $binding
173
     * @param string $service
174
     * @return EndpointType|null
175
     */
176
    protected static function getFirstService(string $service, array $roleDescriptors, string $binding = null)
177
    {
178
179
        if (! in_array($service, static::ENDPOINT_SERVICE_OPTIONS)) {
180
            throw new \InvalidArgumentException('Unknown service passed: ' . $service);
181
        }
182
183
        \Craft::info(
184
            sprintf(
185
                'Looping thru %s role descriptors',
186
                count($roleDescriptors)
187
            ),
188
            'saml-core'
189
        );
190
191
        $serviceMethod = 'get' . $service . 'Service';
192
193
        \Craft::info(
194
            'Using Service method: ' . $serviceMethod,
195
            'saml-core'
196
        );
197
198
        $return = null;
199
        foreach ($roleDescriptors as $descriptor) {
200
            if ($return = static::getFirstIndexedEndpointType(
201
                call_user_func([$descriptor, $serviceMethod]),
202
                $binding
203
            )
204
            ) {
205
                break;
206
            }
207
        }
208
209
        return $return;
210
    }
211
212
    /**
213
     * @param IndexedEndpointType[] $endpointTypes
214
     * @param $binding
215
     * @return EndpointType|null
216
     */
217
    protected static function getFirstIndexedEndpointType(array $endpointTypes, string $binding = null)
218
    {
219
220
        // Is there one?
221
        if (!isset($endpointTypes[0])) {
222
            return null;
223
        }
224
225
        // Default to the first one
226
        $return = $endpointTypes[0];
227
        if (is_null($binding)) {
228
            return $return;
229
        }
230
231
        // Reset the return
232
        $return = null;
233
234
        /** @var EndpointType $endpointType */
235
        foreach ($endpointTypes as $endpointType) {
236
            if (! $endpointType instanceof EndpointType) {
237
                throw new \InvalidArgumentException();
238
            }
239
240
            if ($endpointType->getBinding() === $binding) {
241
                $return = $endpointType;
242
                break;
243
            }
244
        }
245
246
        return $return;
247
    }
248
}
249