Completed
Push — master ( b09517...57901d )
by
unknown
18:40
created

EditProvider::addUrls()   C

Complexity

Conditions 10
Paths 5

Size

Total Lines 67

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 67
rs 6.8533
c 0
b 0
f 0
cc 10
nc 5
nop 1

How to fix   Long Method    Complexity   

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
4
namespace flipbox\saml\core\services;
5
6
use craft\base\Component;
7
use craft\helpers\UrlHelper;
8
use flipbox\keychain\KeyChain;
9
use flipbox\saml\core\AbstractPlugin;
10
use flipbox\saml\core\models\AbstractSettings;
11
use flipbox\saml\core\models\SettingsInterface;
12
use flipbox\saml\core\records\ProviderInterface;
13
use SAML2\XML\md\EndpointType;
14
use SAML2\XML\md\IDPSSODescriptor;
15
use SAML2\XML\md\IndexedEndpointType;
16
use SAML2\XML\md\SPSSODescriptor;
17
18
class EditProvider extends Component
19
{
20
    /**
21
     * @var AbstractPlugin
22
     */
23
    private $plugin;
24
25
    /**
26
     * @param AbstractPlugin $plugin
27
     * @return $this
28
     */
29
    public function setPlugin(AbstractPlugin $plugin)
30
    {
31
        $this->plugin = $plugin;
32
        return $this;
33
    }
34
35
    /**
36
     * @return AbstractPlugin
37
     */
38
    public function getPlugin()
39
    {
40
        return $this->plugin;
41
    }
42
43
    /**
44
     * @param ProviderInterface $provider
45
     * @return array
46
     */
47
    public function getActions(ProviderInterface $provider)
48
    {
49
        $actions = [];
50
51
        if ($provider->id) {
0 ignored issues
show
Bug introduced by
Accessing id on the interface flipbox\saml\core\records\ProviderInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
52
            $actions = [
53
                [
54
                    //action list 1
55
                    [
56
                        'action' => $this->getPlugin()->getHandle() . '/metadata/change-status',
57
                        'label' => $provider->enabled ? 'Disable' : 'Enable',
0 ignored issues
show
Bug introduced by
Accessing enabled on the interface flipbox\saml\core\records\ProviderInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
58
                    ],
59
                    [
60
                        'action' => $this->getPlugin()->getHandle() . '/metadata/delete',
61
                        'label' => 'Delete',
62
                    ],
63
                ],
64
            ];
65
        }
66
        return $actions;
67
    }
68
69
    /**
70
     * @return array
71
     */
72
    public function getBaseVariables()
73
    {
74
75
        return array_merge(
76
            $this->getVariables(),
77
            [
78
                'autoCreate' => false,
79
                'myEntityId' => $this->getPlugin()->getSettings()->getEntityId(),
80
                'myType' => $this->getPlugin()->getSettings(),
81
            ]
82
        );
83
    }
84
85
    /**
86
     * @param string|null|ProviderInterface $provider
87
     * @return array
88
     */
89
    public function prepVariables($provider = null)
90
    {
91
        $variables = $this->getBaseVariables();
92
93
        $variables['title'] = \Craft::t(
94
            $this->getPlugin()->getHandle(),
95
            $this->getPlugin()->name
96
        );
97
98
99
        /**
100
         * TYPES
101
         */
102
        $variables['myType'] = $this->getPlugin()->getMyType();
103
        $variables['remoteType'] = $this->getPlugin()->getRemoteType();
104
        $variables['createType'] = $variables['remoteType'];
105
106
        if ($provider) {
107
            /**
108
             * @var ProviderInterface $provider
109
             */
110
            $provider = $variables['provider'] = (
111
                /**
112
                 * Is instance provider
113
                 */
114
            $provider instanceof ProviderInterface ?
115
                $provider :
116
                $provider = $this->getPlugin()->getProviderRecordClass()::find()->where([
0 ignored issues
show
Bug introduced by
The method find cannot be called on $this->getPlugin()->getProviderRecordClass() (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
117
                    /**
118
                     * Is ID
119
                     */
120
                    'id' => $provider,
121
                ])->one()
122
            );
123
124
            $variables['title'] .= ': Edit';
125
126
            $crumb = [
127
                [
128
                    'url' => UrlHelper::cpUrl(
129
                        implode(
130
                            '/',
131
                            [
132
                                $this->getPlugin()->getHandle(),
133
                                'metadata',
134
                            ]
135
                        )
136
                    ),
137
                    'label' => 'Provider List',
138
                ], [
139
                    'url' => UrlHelper::cpUrl(
140
                        $this->getPlugin()->getHandle() . '/metadata/' . $provider->id
0 ignored issues
show
Bug introduced by
Accessing id on the interface flipbox\saml\core\records\ProviderInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
141
                    ),
142
                    'label' => $provider->label ?: $provider->entityId,
0 ignored issues
show
Bug introduced by
Accessing label on the interface flipbox\saml\core\records\ProviderInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
Bug introduced by
Accessing entityId on the interface flipbox\saml\core\records\ProviderInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
143
                ],
144
            ];
145
            $variables['keypair'] = $provider->keychain;
0 ignored issues
show
Bug introduced by
Accessing keychain on the interface flipbox\saml\core\records\ProviderInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
146
147
            $variables = array_merge(
148
                $variables,
149
                $this->addUrls($provider)
150
            );
151
        } else {
152
            $record = $this->getPlugin()->getProviderRecordClass();
153
154
            $provider = $variables['provider'] = new $record([
0 ignored issues
show
Unused Code introduced by
$provider is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
155
                'providerType' => SettingsInterface::IDP,
156
            ]);
157
158
            $variables['title'] .= ': Create';
159
160
            $crumb = [
161
                [
162
                    'url' => UrlHelper::cpUrl(
163
                        $this->getPlugin()->getHandle() . '/new'
164
                    ),
165
                    'label' => 'New',
166
                ],
167
            ];
168
        }
169
170
        $variables['allkeypairs'] = [];
171
172
        $keypairs = KeyChain::getInstance()->getService()->findByPlugin($this->getPlugin())->all();
173
174
        foreach ($keypairs as $keypair) {
175
            $variables['allkeypairs'][] = [
176
                'label' => $keypair->description,
177
                'value' => $keypair->id,
178
            ];
179
        }
180
181
        $variables['crumbs'] = array_merge([
182
            [
183
                'url' => UrlHelper::cpUrl($this->getPlugin()->getHandle()),
184
                'label' => \Craft::t($this->getPlugin()->getHandle(), $this->getPlugin()->name),
185
            ],
186
        ], $crumb);
187
188
        return $variables;
189
    }
190
191
    protected function getCraftMappingOptions()
192
    {
193
    }
194
195
    /**
196
     * @return string
197
     */
198
    public function getTemplateIndex()
199
    {
200
        return $this->getPlugin()->getTemplateRootKey();
201
    }
202
203
    /**
204
     * @return array
205
     */
206
    protected function getVariables()
207
    {
208
        $variables = [
209
            'plugin' => $this->getPlugin(),
210
            'title' => $this->getPlugin()->name,
211
            'pluginVariable' => $this->getPlugin()->getPluginVariableHandle(),
212
            'ownEntityId' => $this->getPlugin()->getSettings()->getEntityId(),
213
            'settings' => $this->getPlugin()->getSettings(),
214
215
            // Set the "Continue Editing" URL
216
            'continueEditingUrl' => $this->getBaseCpPath(),
217
            'baseActionPath' => $this->getBaseCpPath(),
218
            'baseCpPath' => $this->getBaseCpPath(),
219
            'templateIndex' => $this->getTemplateIndex(),
220
            'ownProvider' => $ownProvider = $this->getPlugin()->getProvider()->findOwn(),
221
222
            'actions' => [],
223
        ];
224
225
        $variables['selectedSubnavItem'] = $this->getSubNavKey();
226
227
        /** @var ProviderInterface $ownProvider */
228
        if ($ownProvider) {
229
            $variables = array_merge(
230
                $this->addUrls($ownProvider),
231
                $variables
232
            );
233
        }
234
235
        return $variables;
236
    }
237
238
    /**
239
     * @return null|string
240
     */
241
    protected function getSubNavKey()
242
    {
243
        $request = \Craft::$app->request;
244
245
        $key = null;
246
        $path = implode(
247
            '/',
248
            [
249
                $request->getSegment(2),
250
                $request->getSegment(3),
251
                $request->getSegment(4),
252
            ]
253
        );
254
255
        if (preg_match('#^/+$#', $path)) {
256
            $key = 'saml.setup';
257
        } elseif (preg_match('#metadata/my-provider/#', $path)) {
258
            $key = 'saml.myProvider';
259
        } elseif (preg_match('#metadata/+$#', $path)) {
260
            $key = 'saml.providers';
261
        } elseif (preg_match('#keychain/+$#', $path)) {
262
            $key = 'saml.keychain';
263
        } elseif (preg_match('#settings/+$#', $path)) {
264
            $key = 'saml.settings';
265
        }
266
        return $key;
267
    }
268
269
    /**
270
     * @return string
271
     */
272
    protected function getBaseCpPath(): string
273
    {
274
        return $this->getPlugin()->getHandle();
275
    }
276
277
    /**
278
     * @param ProviderInterface $provider
279
     * @param array $variables
0 ignored issues
show
Bug introduced by
There is no parameter named $variables. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
280
     * @return array
281
     */
282
    public function addUrls(ProviderInterface $provider)
283
    {
284
285
        $variables = [];
286
        $variables['assertionConsumerServices'] = null;
287
        $variables['singleLogoutServices'] = null;
288
        $variables['singleSignOnServices'] = null;
289
290
        if (! $provider->getMetadataModel()) {
291
            return $variables;
292
        }
293
294
        /** @var AbstractPlugin $plugin */
295
        $plugin = $this->getPlugin();
0 ignored issues
show
Unused Code introduced by
$plugin is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
296
297
        /**
298
         * Metadata/EntityDescriptor Model
299
         */
300
        $entityDescriptor = $provider->getMetadataModel();
301
302
        /**
303
         * Add SP URLs
304
         */
305
        if ($provider->getType() === AbstractSettings::SP) {
306
            foreach ($entityDescriptor->getRoleDescriptor() as $roleDescriptor) {
307
                if (! ($roleDescriptor instanceof SPSSODescriptor)) {
308
                    continue;
309
                }
310
311
                if ($endpoint = $this->getFirstEndpoint($roleDescriptor->getSingleLogoutService())) {
312
                    $sloBinding = $endpoint->getBinding();
313
                    $sloResponseLocation = $endpoint->getLocation();
314
                    $variables['singleLogoutServices'][$sloBinding] = $sloResponseLocation;
315
                }
316
317
                /** @var IndexedEndpointType $firstACS */
318
                $firstACS = $this->getFirstEndpoint($roleDescriptor->getAssertionConsumerService());
319
                $acsBinding = $firstACS->getBinding();
320
                $acsLocation = $firstACS->getLocation();
321
                $variables['assertionConsumerServices'][$acsBinding] = $acsLocation;
322
            }
323
        }
324
325
        /**
326
         * Add IDP URLs
327
         */
328
        if ($provider->getType() === AbstractSettings::IDP) {
329
            foreach ($entityDescriptor->getRoleDescriptor() as $roleDescriptor) {
330
                if (! ($roleDescriptor instanceof IDPSSODescriptor)) {
331
                    continue;
332
                }
333
334
                if ($endpoint = $this->getFirstEndpoint($roleDescriptor->getSingleLogoutService())) {
335
                    $sloBinding = $endpoint->getBinding();
336
                    $sloResponseLocation = $endpoint->getLocation();
337
                    $variables['singleLogoutServices'][$sloBinding] = $sloResponseLocation;
338
                }
339
340
                $sso = $this->getFirstEndpoint($roleDescriptor->getSingleSignOnService());
341
                $ssoBinding = $sso->getBinding();
342
                $ssoLocation = $sso->getLocation();
343
                $variables['singleSignOnServices'][$ssoBinding] = $ssoLocation;
344
            }
345
        }
346
347
        return $variables;
348
    }
349
350
    /**
351
     * @param $endpoints
352
     * @return EndpointType|null
353
     */
354
    protected function getFirstEndpoint($endpoints)
355
    {
356
        if (is_null($endpoints) || empty($endpoints)) {
357
            return null;
358
        }
359
360
        return array_shift($endpoints);
361
    }
362
363
364
    /**
365
     * @param $type
366
     * @return string
367
     */
368
    public function getTitle($type)
369
    {
370
        return $type === AbstractSettings::SP ? 'Service Provider (SP)' : 'Identity Provider (IDP)';
371
    }
372
}
373