AbstractPlugin::getSubNav()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 40
rs 9.28
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
/**
3
 * @copyright  Copyright (c) Flipbox Digital Limited
4
 * @license    https://flipboxfactory.com/software/saml-core/license
5
 * @link       https://www.flipboxfactory.com/software/saml-core/
6
 */
7
8
namespace flipbox\saml\core;
9
10
use craft\base\Plugin;
11
use craft\events\RegisterTemplateRootsEvent;
12
use craft\events\RegisterUrlRulesEvent;
13
use craft\helpers\StringHelper;
14
use flipbox\saml\core\helpers\UrlHelper;
15
use craft\web\twig\variables\CraftVariable;
16
use craft\web\View;
17
use flipbox\craft\psr3\Logger;
18
use flipbox\saml\core\models\AbstractSettings;
19
use flipbox\saml\core\models\SettingsInterface;
20
use flipbox\saml\core\services\AbstractCp;
21
use flipbox\saml\core\services\bindings\Factory;
22
use flipbox\saml\core\services\Cp;
23
use flipbox\saml\core\services\EditProvider;
24
use flipbox\saml\core\services\messages\LogoutRequest;
25
use flipbox\saml\core\services\messages\LogoutResponse;
26
use flipbox\saml\core\services\Metadata;
27
use flipbox\saml\core\services\ProviderIdentityServiceInterface;
28
use flipbox\saml\core\services\ProviderServiceInterface;
29
use SAML2\Compat\AbstractContainer;
30
use yii\base\Event;
31
32
/**
33
 * Class AbstractPlugin
34
 * @package flipbox\saml\core
35
 */
36
abstract class AbstractPlugin extends Plugin
37
{
38
39
    const SAML_CORE_HANDLE = 'saml-core';
40
41
    /**
42
     * @var bool
43
     */
44
    public $hasCpSettings = true;
45
46
    /**
47
     * @var bool
48
     */
49
    public $hasCpSection = true;
50
51
    abstract public function loadSaml2Container(): AbstractContainer;
52
53
    /**
54
     * @return string
55
     */
56
    abstract public function getProviderRecordClass();
57
58
    /**
59
     * @return string
60
     */
61
    abstract public function getProviderIdentityRecordClass();
62
63
    public function init()
64
    {
65
        parent::init();
66
67
        $this->initCore();
68
    }
69
70
    /**
71
     *
72
     */
73
    public function initCore()
74
    {
75
        \Craft::setAlias('@flipbox/saml/core/web/assets', __DIR__ . '/web/assets');
76
        $this->registerTemplates();
77
78
        $this->setComponents([
79
            'cp' => Cp::class,
80
            'psr3logger' => [
81
                'class' => Logger::class,
82
            ],
83
            'metadata' => Metadata::class,
84
            'logoutRequest' => LogoutRequest::class,
85
            'logoutResponse' => LogoutResponse::class,
86
            'editProvider' => [
87
                'class' => EditProvider::class,
88
                'plugin' => $this,
89
            ],
90
        ]);
91
92
        /**
93
         * Set saml plugin to the craft variable
94
         */
95
        Event::on(
96
            CraftVariable::class,
97
            CraftVariable::EVENT_INIT,
98
            function (Event $event) {
99
                /** @var CraftVariable $variable */
100
                $variable = $event->sender;
101
                $variable->set($this->getPluginVariableHandle(), self::getInstance());
102
                $variable->set('samlCp', $this->getCp());
103
            }
104
        );
105
106
        Event::on(
107
            View::class,
108
            View::EVENT_REGISTER_CP_TEMPLATE_ROOTS,
109
            function (RegisterTemplateRootsEvent $e) {
110
                if (is_dir($baseDir = (dirname(__FILE__) . DIRECTORY_SEPARATOR . 'templates'))) {
111
                    $e->roots[static::SAML_CORE_HANDLE] = $baseDir;
112
                }
113
            }
114
        );
115
    }
116
117
    /**
118
     * @inheritdoc
119
     */
120
    public function getSettingsResponse()
121
    {
122
123
        \Craft::$app->getResponse()->redirect(
124
            UrlHelper::cpUrl(static::getInstance()->getHandle() . '/settings')
125
        );
126
127
        \Craft::$app->end();
128
    }
129
130
    /**
131
     * @return array
132
     */
133
    private function getSubNav()
134
    {
135
        return [
136
            'saml.setup' => [
137
                'url' => $this->getHandle() . '/',
138
                'label' => \Craft::t(
139
                    $this->getHandle(),
140
                    'Setup'
141
                ),
142
            ],
143
            'saml.myProvider' => [
144
                'url' => $this->getHandle() . '/metadata/my-provider',
145
                'label' => \Craft::t(
146
                    $this->getHandle(),
147
                    'My Provider'
148
                ),
149
            ],
150
            'saml.providers' => [
151
                'url' => $this->getHandle() . '/metadata',
152
                'label' => \Craft::t(
153
                    $this->getHandle(),
154
                    'Provider List'
155
                ),
156
            ],
157
            'saml.keychain' => [
158
                'url' => $this->getHandle() . '/keychain',
159
                'label' => \Craft::t(
160
                    $this->getHandle(),
161
                    'Keychain'
162
                ),
163
            ],
164
            'saml.settings' => [
165
                'url' => $this->getHandle() . '/settings',
166
                'label' => \Craft::t(
167
                    $this->getHandle(),
168
                    'Settings'
169
                ),
170
            ],
171
        ];
172
    }
173
174
    /**
175
     * @inheritdoc
176
     */
177
    public function getCpNavItem()
178
    {
179
        return array_merge(parent::getCpNavItem(), [
180
            'subnav' => $this->getSubNav(),
181
        ]);
182
    }
183
184
    /**
185
     * @return string
186
     */
187
    public function getPluginVariableHandle()
188
    {
189
        return StringHelper::camelCase($this->handle);
190
    }
191
192
    /**
193
     * Registering the core templates for SP and IDP to use.
194
     */
195
    protected function registerTemplates()
196
    {
197
        Event::on(
198
            View::class,
199
            View::EVENT_REGISTER_CP_TEMPLATE_ROOTS,
200
            function (RegisterTemplateRootsEvent $e) {
201
                if (is_dir($baseDir = $this->getTemplateRoot())) {
202
                    $e->roots[$this->getTemplateRootKey()] = $baseDir;
203
                }
204
            }
205
        );
206
    }
207
208
    /**
209
     * @return string
210
     */
211
    public function getMyType()
212
    {
213
        return $this->getSettings()->getMyType();
214
    }
215
216
    /**
217
     * @return string
218
     */
219
    public function getRemoteType()
220
    {
221
        $type = SettingsInterface::SP;
222
        if ($this->getMyType() === SettingsInterface::SP) {
223
            $type = SettingsInterface::IDP;
224
        }
225
226
        return $type;
227
    }
228
229
    /**
230
     * @return string
231
     */
232
    public function getTemplateRoot()
233
    {
234
        return dirname(__FILE__) . DIRECTORY_SEPARATOR . 'templates';
235
    }
236
237
    /**
238
     * @return string
239
     */
240
    public function getTemplateRootKey()
241
    {
242
        return $this->getHandle() . '-' . 'core';
243
    }
244
    /**
245
     * EVENTs
246
     */
247
248
    /**
249
     * @param RegisterUrlRulesEvent $event
250
     */
251
    public static function onRegisterCpUrlRules(RegisterUrlRulesEvent $event)
252
    {
253
        $handle = static::getInstance()->getHandle();
254
        $event->rules = array_merge(
255
            $event->rules,
256
            [
257
                $handle . '/' => $handle . '/cp/view/general/setup',
258
                $handle . '/settings' => $handle . '/cp/view/general/settings',
259
260
                /**
261
                 * Keychain
262
                 */
263
                $handle . '/keychain' => $handle . '/cp/view/keychain/index',
264
                $handle . '/keychain/new' => $handle . '/cp/view/keychain/edit',
265
                $handle . '/keychain/new-openssl' => $handle . '/cp/view/keychain/edit/openssl',
266
                $handle . '/keychain/<keypairId:\d+>' => $handle . '/cp/view/keychain/edit',
267
268
                /**
269
                 * Metadata
270
                 */
271
                $handle . '/metadata' => $handle . '/cp/view/metadata/default',
272
                $handle . '/metadata/new' => $handle . '/cp/view/metadata/edit',
273
                $handle . '/metadata/new-idp' => $handle . '/cp/view/metadata/edit/new-idp',
274
                $handle . '/metadata/new-sp' => $handle . '/cp/view/metadata/edit/new-sp',
275
                $handle . '/metadata/my-provider' => $handle . '/cp/view/metadata/edit/my-provider',
276
                $handle . '/metadata/<providerId:\d+>' => $handle . '/cp/view/metadata/edit',
277
            ]
278
        );
279
    }
280
281
    /**
282
     * @param RegisterUrlRulesEvent $event
283
     */
284
    public static function onRegisterSiteUrlRules(RegisterUrlRulesEvent $event)
285
    {
286
        $handle = static::getInstance()->getHandle();
287
        $event->rules = array_merge(
288
            $event->rules,
289
            [
290
                /**
291
                 * LOGIN
292
                 */
293
                sprintf(
294
                    'POST,GET %s',
295
                    UrlHelper::buildEndpointPath(
296
                        static::getInstance()->getSettings(),
297
                        UrlHelper::LOGIN_ENDPOINT
298
                    )
299
                ) => $handle . '/login',
300
                sprintf(
301
                    'POST,GET %s/<uid:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}>',
302
                    UrlHelper::buildEndpointPath(
303
                        static::getInstance()->getSettings(),
304
                        UrlHelper::LOGIN_ENDPOINT
305
                    )
306
                ) => $handle . '/login',
307
                sprintf(
308
                    'POST,GET %s',
309
                    UrlHelper::buildEndpointPath(
310
                        static::getInstance()->getSettings(),
311
                        UrlHelper::LOGIN_REQUEST_ENDPOINT
312
                    )
313
                ) => $handle . '/login/request',
314
                sprintf(
315
                    'POST,GET %s'.
316
                    '/<externalUid:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}>',
317
                    UrlHelper::buildEndpointPath(
318
                        static::getInstance()->getSettings(),
319
                        UrlHelper::LOGIN_REQUEST_ENDPOINT
320
                    )
321
                ) => $handle . '/login/request',
322
                sprintf(
323
                    'POST,GET %s'.
324
                    '/<externalUid:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}>' .
325
                    '/<internalUid:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}>',
326
                    UrlHelper::buildEndpointPath(
327
                        static::getInstance()->getSettings(),
328
                        UrlHelper::LOGIN_REQUEST_ENDPOINT
329
                    )
330
                ) => $handle . '/login/request',
331
                /**
332
                 * LOGOUT
333
                 */
334
                sprintf(
335
                    'POST,GET %s/<uid:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}>',
336
                    UrlHelper::buildEndpointPath(
337
                        static::getInstance()->getSettings(),
338
                        UrlHelper::LOGOUT_ENDPOINT
339
                    )
340
                ) => $handle . '/logout',
341
                sprintf(
342
                    'POST,GET %s',
343
                    UrlHelper::buildEndpointPath(
344
                        static::getInstance()->getSettings(),
345
                        UrlHelper::LOGOUT_ENDPOINT
346
                    )
347
                ) => $handle . '/logout',
348
                sprintf(
349
                    'POST,GET %s',
350
                    UrlHelper::buildEndpointPath(
351
                        static::getInstance()->getSettings(),
352
                        UrlHelper::LOGOUT_REQUEST_ENDPOINT
353
                    )
354
                ) => $handle . '/logout/request',
355
                sprintf(
356
                    'POST,GET %s/<uid:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}>',
357
                    UrlHelper::buildEndpointPath(
358
                        static::getInstance()->getSettings(),
359
                        UrlHelper::LOGOUT_REQUEST_ENDPOINT
360
                    )
361
                ) => $handle . '/logout/request',
362
363
            ]
364
        );
365
    }
366
367
    /**
368
     * @return AbstractSettings
369
     */
370
    public function getSettings()
371
    {
372
        return parent::getSettings();
0 ignored issues
show
Bug Compatibility introduced by
The expression parent::getSettings(); of type craft\base\Model|boolean|null adds the type boolean to the return on line 372 which is incompatible with the return type declared by the interface craft\base\PluginInterface::getSettings of type craft\base\Model|null.
Loading history...
373
    }
374
375
    /**
376
     * Components
377
     */
378
379
    /**
380
     * @noinspection PhpDocMissingThrowsInspection
381
     * @returns AbstractCp
382
     */
383
    public function getCp()
384
    {
385
386
        /** @noinspection PhpUnhandledExceptionInspection */
387
        /** @noinspection PhpIncompatibleReturnTypeInspection */
388
        return $this->get('cp');
389
    }
390
391
    /**
392
     * @returns EditProvider
393
     */
394
    public function getEditProvider()
395
    {
396
397
        /** @noinspection PhpUnhandledExceptionInspection */
398
        return $this->get('editProvider');
399
    }
400
401
    /**
402
     * @returns ProviderServiceInterface
403
     */
404
    public function getProvider()
405
    {
406
407
        /** @noinspection PhpUnhandledExceptionInspection */
408
        return $this->get('provider');
409
    }
410
411
    /**
412
     * @returns ProviderIdentityServiceInterface
413
     */
414
    public function getProviderIdentity()
415
    {
416
        return $this->get('providerIdentity');
417
    }
418
419
    /**
420
     * @noinspection PhpDocMissingThrowsInspection
421
     * @return Metadata
422
     */
423
    public function getMetadata()
424
    {
425
        /** @noinspection PhpUnhandledExceptionInspection */
426
        /** @noinspection PhpIncompatibleReturnTypeInspection */
427
        return $this->get('metadata');
428
    }
429
430
    /**
431
     * @noinspection PhpDocMissingThrowsInspection
432
     * @return LogoutRequest
433
     * @throws \yii\base\InvalidConfigException
434
     */
435
    public function getLogoutRequest()
436
    {
437
        /** @noinspection PhpUnhandledExceptionInspection */
438
        /** @noinspection PhpIncompatibleReturnTypeInspection */
439
        return $this->get('logoutRequest');
440
    }
441
442
    /**
443
     * @noinspection PhpDocMissingThrowsInspection
444
     * @return LogoutResponse
445
     * @throws \yii\base\InvalidConfigException
446
     */
447
    public function getLogoutResponse()
448
    {
449
        /** @noinspection PhpUnhandledExceptionInspection */
450
        /** @noinspection PhpIncompatibleReturnTypeInspection */
451
        return $this->get('logoutResponse');
452
    }
453
454
    /**
455
     * Bindings
456
     */
457
458
    /**
459
     * @return Factory
460
     * @throws \yii\base\InvalidConfigException
461
     */
462
    public function getBindingFactory()
463
    {
464
        /** @noinspection PhpUnhandledExceptionInspection */
465
        /** @noinspection PhpIncompatibleReturnTypeInspection */
466
        return $this->get('bindingFactory');
467
    }
468
469
    /**
470
     * @return Logger
471
     * @throws \yii\base\InvalidConfigException
472
     */
473
    public function getPsr3Logger()
474
    {
475
        /** @noinspection PhpUnhandledExceptionInspection */
476
        /** @noinspection PhpIncompatibleReturnTypeInspection */
477
        return $this->get('psr3logger');
478
    }
479
480
481
    /**
482
     * Log Functions
483
     */
484
485
    /**
486
     * @param $message
487
     */
488
    public static function error($message)
489
    {
490
        \Craft::error($message, static::getInstance()->getHandle());
491
    }
492
493
    /**
494
     * @param $message
495
     */
496
    public static function warning($message)
497
    {
498
        \Craft::warning($message, static::getInstance()->getHandle());
499
    }
500
501
    /**
502
     * @param $message
503
     */
504
    public static function info($message)
505
    {
506
        \Craft::info($message, static::getInstance()->getHandle());
507
    }
508
509
    /**
510
     * @param $message
511
     */
512
    public static function debug($message)
513
    {
514
        \Craft::debug($message, static::getInstance()->getHandle());
515
    }
516
}
517