• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

FastyBird / simple-auth / 9954267582

16 Jul 2024 09:26AM UTC coverage: 66.994% (+1.3%) from 65.685%
9954267582

push

github

web-flow
Integrate Casbin authorizator (#6)

114 of 161 new or added lines in 9 files covered. (70.81%)

2 existing lines in 2 files now uncovered.

477 of 712 relevant lines covered (66.99%)

4.96 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.63
/src/DI/SimpleAuthExtension.php
1
<?php declare(strict_types = 1);
2

3
/**
4
 * SimpleAuthExtension.php
5
 *
6
 * @license        More in LICENSE.md
7
 * @copyright      https://www.fastybird.com
8
 * @author         Adam Kadlec <adam.kadlec@fastybird.com>
9
 * @package        FastyBird:SimpleAuth!
10
 * @subpackage     DI
11
 * @since          0.1.0
12
 *
13
 * @date           09.07.20
14
 */
15

16
namespace FastyBird\SimpleAuth\DI;
17

18
use Casbin;
19
use CasbinAdapter;
20
use Doctrine\DBAL\Connection;
21
use Doctrine\Persistence;
22
use FastyBird\SimpleAuth;
23
use FastyBird\SimpleAuth\Events;
24
use FastyBird\SimpleAuth\Exceptions;
25
use FastyBird\SimpleAuth\Mapping;
26
use FastyBird\SimpleAuth\Middleware;
27
use FastyBird\SimpleAuth\Security;
28
use FastyBird\SimpleAuth\Subscribers;
29
use Nette;
30
use Nette\Application as NetteApplication;
31
use Nette\DI;
32
use Nette\PhpGenerator;
33
use Nette\Schema;
34
use stdClass;
35
use Symfony\Contracts\EventDispatcher;
36
use function assert;
37
use function is_file;
38
use function is_string;
39
use const DIRECTORY_SEPARATOR;
40

41
/**
42
 * Authentication helpers extension container
43
 *
44
 * @package        FastyBird:SimpleAuth!
45
 * @subpackage     DI
46
 *
47
 * @author         Adam Kadlec <adam.kadlec@fastybird.com>
48
 */
49
class SimpleAuthExtension extends DI\CompilerExtension
50
{
51

52
        public static function register(
53
                Nette\Bootstrap\Configurator $config,
54
                string $extensionName = 'fbSimpleAuth',
55
        ): void
56
        {
57
                $config->onCompile[] = static function (Nette\Bootstrap\Configurator $config, DI\Compiler $compiler) use ($extensionName): void {
33✔
58
                        $compiler->addExtension($extensionName, new self());
8✔
59
                };
33✔
60
        }
61

62
        public function getConfigSchema(): Schema\Schema
63
        {
64
                return Schema\Expect::structure([
8✔
65
                        'token' => Schema\Expect::structure([
8✔
66
                                'issuer' => Schema\Expect::string(),
8✔
67
                                'signature' => Schema\Expect::string('g3xHbkELpMD9LRqW4WmJkHL7kz2bdNYAQJyEuFVzR3k='),
8✔
68
                        ]),
8✔
69
                        'enable' => Schema\Expect::structure([
8✔
70
                                'middleware' => Schema\Expect::bool(false),
8✔
71
                                'doctrine' => Schema\Expect::structure([
8✔
72
                                        'mapping' => Schema\Expect::bool(false),
8✔
73
                                        'models' => Schema\Expect::bool(false),
8✔
74
                                ]),
8✔
75
                                'casbin' => Schema\Expect::structure([
8✔
76
                                        'database' => Schema\Expect::bool(false),
8✔
77
                                ]),
8✔
78
                                'nette' => Schema\Expect::structure([
8✔
79
                                        'application' => Schema\Expect::bool(false),
8✔
80
                                ]),
8✔
81
                        ]),
8✔
82
                        'application' => Schema\Expect::structure([
8✔
83
                                'signInUrl' => Schema\Expect::string(),
8✔
84
                                'homeUrl' => Schema\Expect::string('/'),
8✔
85
                        ]),
8✔
86
                        'services' => Schema\Expect::structure([
8✔
87
                                'identity' => Schema\Expect::bool(false),
8✔
88
                        ]),
8✔
89
                        'casbin' => Schema\Expect::structure([
8✔
90
                                'model' => Schema\Expect::string(
8✔
91
                                        // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
92
                                        __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'resources' . DIRECTORY_SEPARATOR . 'model.conf',
8✔
93
                                ),
8✔
94
                                'policy' => Schema\Expect::string(),
8✔
95
                        ]),
8✔
96
                        'database' => Schema\Expect::anyOf(
8✔
97
                                Schema\Expect::null(),
8✔
98
                                Schema\Expect::structure([
8✔
99
                                        'driver' => Schema\Expect::string('pdo_mysql'),
8✔
100
                                        'host' => Schema\Expect::string('127.0.0.1'),
8✔
101
                                        'port' => Schema\Expect::int(3_306),
8✔
102
                                        'database' => Schema\Expect::string('security'),
8✔
103
                                        'user' => Schema\Expect::string('root'),
8✔
104
                                        'password' => Schema\Expect::string(),
8✔
105
                                ]),
8✔
106
                        ),
8✔
107
                ]);
8✔
108
        }
109

110
        public function loadConfiguration(): void
111
        {
112
                $builder = $this->getContainerBuilder();
8✔
113
                $configuration = $this->getConfig();
8✔
114
                assert($configuration instanceof stdClass);
115

116
                $builder->addDefinition($this->prefix('auth'), new DI\Definitions\ServiceDefinition())
8✔
117
                        ->setType(SimpleAuth\Auth::class);
8✔
118

119
                $builder->addDefinition($this->prefix('configuration'), new DI\Definitions\ServiceDefinition())
8✔
120
                        ->setType(SimpleAuth\Configuration::class)
8✔
121
                        ->setArguments([
8✔
122
                                'tokenIssuer' => $configuration->token->issuer,
8✔
123
                                'tokenSignature' => $configuration->token->signature,
8✔
124
                                'enableMiddleware' => $configuration->enable->middleware,
8✔
125
                                'enableDoctrineMapping' => $configuration->enable->doctrine->mapping,
8✔
126
                                'enableDoctrineModels' => $configuration->enable->doctrine->models,
8✔
127
                                'enableNetteApplication' => $configuration->enable->nette->application,
8✔
128
                                'applicationSignInUrl' => $configuration->application->signInUrl,
8✔
129
                                'applicationHomeUrl' => $configuration->application->homeUrl,
8✔
130
                        ]);
8✔
131

132
                /**
133
                 * Token utilities
134
                 */
135

136
                $builder->addDefinition($this->prefix('token.builder'), new DI\Definitions\ServiceDefinition())
8✔
137
                        ->setType(Security\TokenBuilder::class)
8✔
138
                        ->setArgument('tokenSignature', $configuration->token->signature)
8✔
139
                        ->setArgument('tokenIssuer', $configuration->token->issuer);
8✔
140

141
                $builder->addDefinition($this->prefix('token.reader'), new DI\Definitions\ServiceDefinition())
8✔
142
                        ->setType(Security\TokenReader::class);
8✔
143

144
                $builder->addDefinition($this->prefix('token.validator'), new DI\Definitions\ServiceDefinition())
8✔
145
                        ->setType(Security\TokenValidator::class)
8✔
146
                        ->setArgument('tokenSignature', $configuration->token->signature)
8✔
147
                        ->setArgument('tokenIssuer', $configuration->token->issuer);
8✔
148

149
                /**
150
                 * User security
151
                 */
152

153
                if ($configuration->services->identity) {
8✔
154
                        $builder->addDefinition($this->prefix('security.identityFactory'), new DI\Definitions\ServiceDefinition())
8✔
155
                                ->setType(Security\IdentityFactory::class);
8✔
156
                }
157

158
                $builder->addDefinition($this->prefix('security.userStorage'), new DI\Definitions\ServiceDefinition())
8✔
159
                        ->setType(Security\UserStorage::class);
8✔
160

161
                $builder->addDefinition($this->prefix('security.annotationChecker'), new DI\Definitions\ServiceDefinition())
8✔
162
                        ->setType(Security\AnnotationChecker::class);
8✔
163

164
                /**
165
                 * Web server extension
166
                 */
167

168
                if ($configuration->enable->middleware) {
8✔
169
                        $builder->addDefinition($this->prefix('middleware.access'), new DI\Definitions\ServiceDefinition())
8✔
170
                                ->setType(Middleware\Access::class);
8✔
171

172
                        $builder->addDefinition($this->prefix('middleware.user'), new DI\Definitions\ServiceDefinition())
8✔
173
                                ->setType(Middleware\User::class);
8✔
174
                }
175

176
                /**
177
                 * Doctrine extension
178
                 */
179

180
                if ($configuration->enable->doctrine->mapping) {
8✔
181
                        $builder->addDefinition($this->prefix('doctrine.driver'), new DI\Definitions\ServiceDefinition())
8✔
182
                                ->setType(Mapping\Driver\Owner::class);
8✔
183

184
                        $builder->addDefinition($this->prefix('doctrine.subscriber'), new DI\Definitions\ServiceDefinition())
8✔
185
                                ->setType(Subscribers\User::class);
8✔
186
                }
187

188
                if ($configuration->enable->doctrine->models) {
8✔
189
                        $builder->addDefinition($this->prefix('doctrine.tokensRepository'), new DI\Definitions\ServiceDefinition())
8✔
190
                                ->setType(SimpleAuth\Models\Tokens\Repository::class);
8✔
191

192
                        $builder->addDefinition($this->prefix('doctrine.tokensManager'), new DI\Definitions\ServiceDefinition())
8✔
193
                                ->setType(SimpleAuth\Models\Tokens\Manager::class);
8✔
194
                }
195

196
                $builder->addDefinition($this->prefix('doctrine.policiesRepository'), new DI\Definitions\ServiceDefinition())
8✔
197
                        ->setType(SimpleAuth\Models\Policies\Repository::class);
8✔
198

199
                $builder->addDefinition($this->prefix('doctrine.policiesManager'), new DI\Definitions\ServiceDefinition())
8✔
200
                        ->setType(SimpleAuth\Models\Policies\Manager::class);
8✔
201

202
                /**
203
                 * Nette application extension
204
                 */
205

206
                if ($configuration->enable->nette->application) {
8✔
207
                        $builder->addDefinition($this->prefix('nette.application'), new DI\Definitions\ServiceDefinition())
×
208
                                ->setType(Subscribers\Application::class);
×
209
                }
210
        }
211

212
        /**
213
         * @throws DI\MissingServiceException
214
         * @throws Exceptions\Logical
215
         */
216
        public function beforeCompile(): void
217
        {
218
                parent::beforeCompile();
8✔
219

220
                $builder = $this->getContainerBuilder();
8✔
221
                $configuration = $this->getConfig();
8✔
222
                assert($configuration instanceof stdClass);
223

224
                $userContextServiceName = $builder->getByType(Security\User::class);
8✔
225

226
                $userContext = null;
8✔
227

228
                if ($userContextServiceName !== null) {
8✔
229
                        $userContext = $builder->getDefinition($userContextServiceName);
×
230
                }
231

232
                if ($userContext === null) {
8✔
233
                        $builder->addDefinition($this->prefix('security.user'), new DI\Definitions\ServiceDefinition())
8✔
234
                                ->setType(Security\User::class);
8✔
235
                }
236

237
                /**
238
                 * Doctrine extension
239
                 */
240

241
                if ($configuration->enable->doctrine->models) {
8✔
242
                        $ormAttributeDriverService = $builder->getDefinition('nettrineOrmAttributes.attributeDriver');
8✔
243

244
                        if ($ormAttributeDriverService instanceof DI\Definitions\ServiceDefinition) {
8✔
245
                                $ormAttributeDriverService->addSetup(
8✔
246
                                        'addPaths',
8✔
247
                                        [[__DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'Entities']],
8✔
248
                                );
8✔
249
                        }
250

251
                        $ormAttributeDriverChainService = $builder->getDefinitionByType(
8✔
252
                                Persistence\Mapping\Driver\MappingDriverChain::class,
8✔
253
                        );
8✔
254

255
                        if ($ormAttributeDriverChainService instanceof DI\Definitions\ServiceDefinition) {
8✔
256
                                $ormAttributeDriverChainService->addSetup('addDriver', [
8✔
257
                                        $ormAttributeDriverService,
8✔
258
                                        'FastyBird\SimpleAuth\Entities',
8✔
259
                                ]);
8✔
260
                        }
261
                }
262

263
                /**
264
                 * Nette application extension
265
                 */
266

267
                if ($configuration->enable->nette->application) {
8✔
268
                        if ($builder->getByType(EventDispatcher\EventDispatcherInterface::class) !== null) {
×
269
                                if ($builder->getByType(NetteApplication\Application::class) !== null) {
×
270
                                        $dispatcher = $builder->getDefinition(
×
271
                                                $builder->getByType(EventDispatcher\EventDispatcherInterface::class),
×
272
                                        );
×
273

274
                                        $application = $builder->getDefinition($builder->getByType(NetteApplication\Application::class));
×
275
                                        assert($application instanceof DI\Definitions\ServiceDefinition);
276

277
                                        $application->addSetup('?->onRequest[] = function() {?->dispatch(new ?(...func_get_args()));}', [
×
278
                                                '@self',
×
279
                                                $dispatcher,
×
280
                                                new PhpGenerator\Literal(Events\Request::class),
×
281
                                        ]);
×
282

283
                                        $application->addSetup('?->onResponse[] = function() {?->dispatch(new ?(...func_get_args()));}', [
×
284
                                                '@self',
×
285
                                                $dispatcher,
×
286
                                                new PhpGenerator\Literal(Events\Response::class),
×
287
                                        ]);
×
288
                                }
289
                        }
290
                }
291

292
                /**
293
                 * Casbin
294
                 */
295

296
                if ($configuration->enable->casbin->database) {
8✔
297
                        $connectionServiceName = $builder->getByType(Connection::class);
3✔
298

299
                        if ($connectionServiceName !== null) {
3✔
300
                                $connectionService = $builder->getDefinition($connectionServiceName);
3✔
301

302
                                $adapter = $builder->addDefinition(
3✔
303
                                        $this->prefix('casbin.adapter'),
3✔
304
                                        new DI\Definitions\ServiceDefinition(),
3✔
305
                                )
3✔
306
                                        ->setType(CasbinAdapter\DBAL\Adapter::class)
3✔
307
                                        ->setArguments([
3✔
308
                                                'connection' => $connectionService,
3✔
309
                                        ])
3✔
310
                                        ->addSetup('$policyTableName', ['fb_security_policies']);
3✔
311
                        } else {
NEW
312
                                $adapter = $builder->addDefinition(
×
NEW
313
                                        $this->prefix('casbin.adapter'),
×
NEW
314
                                        new DI\Definitions\ServiceDefinition(),
×
NEW
315
                                )
×
NEW
316
                                        ->setType(CasbinAdapter\DBAL\Adapter::class)
×
NEW
317
                                        ->setArguments([
×
NEW
318
                                                'connection' => [
×
NEW
319
                                                        'driver' => $configuration->database->driver,
×
NEW
320
                                                        'host' => $configuration->database->host,
×
NEW
321
                                                        'port' => $configuration->database->port,
×
NEW
322
                                                        'dbname' => $configuration->database->database,
×
NEW
323
                                                        'user' => $configuration->database->user,
×
NEW
324
                                                        'password' => $configuration->database->password,
×
NEW
325
                                                        'policy_table_name' => 'fb_security_policies',
×
NEW
326
                                                ],
×
NEW
327
                                        ]);
×
328
                        }
329

330
                        $builder->addDefinition($this->prefix('casbin.subscriber'), new DI\Definitions\ServiceDefinition())
3✔
331
                                ->setType(Subscribers\Policy::class);
3✔
332
                } else {
333
                        $policyFile = $configuration->casbin->policy;
5✔
334

335
                        if (!is_string($policyFile) || !is_file($policyFile)) {
5✔
NEW
336
                                throw new Exceptions\Logical('Casbin policy file is not configured');
×
337
                        }
338

339
                        $adapter = $builder->addDefinition($this->prefix('casbin.adapter'), new DI\Definitions\ServiceDefinition())
5✔
340
                                ->setType(Casbin\Persist\Adapters\FileAdapter::class)
5✔
341
                                ->setArguments([
5✔
342
                                        'filePath' => $policyFile,
5✔
343
                                ]);
5✔
344
                }
345

346
                $modelFile = $configuration->casbin->model;
8✔
347

348
                if (!is_string($modelFile) || !is_file($modelFile)) {
8✔
NEW
349
                        throw new Exceptions\Logical('Casbin model file is not configured');
×
350
                }
351

352
                $builder->addDefinition($this->prefix('casbin.enforcer'), new DI\Definitions\ServiceDefinition())
8✔
353
                        ->setType(Casbin\Enforcer::class)
8✔
354
                        ->setArguments([
8✔
355
                                $modelFile,
8✔
356
                                $adapter,
8✔
357
                        ]);
8✔
358
        }
359

360
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc