Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 4778 | Rev 5205 | Ir a la última revisión | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 www 1
<?php
2
declare(strict_types=1);
3
 
4
namespace LeadersLinked;
5
 
6
use Laminas\Db\Adapter\AdapterInterface;
7
use Laminas\Cache\Storage\Adapter\AbstractAdapter as CacheAdapter;
8
use Laminas\ModuleManager\ModuleEvent;
9
use Laminas\ModuleManager\ModuleManager;
10
use Laminas\Mvc\MvcEvent;
11
use Laminas\Config\Reader\Ini;
12
use Laminas\Permissions\Acl\Acl;
13
use Laminas\Permissions\Acl\Role\GenericRole;
14
use LeadersLinked\Plugin\CurrentUserPlugin;
15
use LeadersLinked\Model\Company;
16
use LeadersLinked\Mapper\UserMapper;
17
use LeadersLinked\Authentication\AuthTokenAdapter;
18
use Laminas\Authentication\AuthenticationService;
19
use Laminas\Permissions\Acl\Resource\GenericResource;
20
use LeadersLinked\Model\UserType;
3639 efrain 21
use LeadersLinked\Plugin\CurrentNetworkPlugin;
22
use LeadersLinked\Model\Network;
23
use LeadersLinked\Model\User;
24
use LeadersLinked\Mapper\CompanyUserMapper;
25
use LeadersLinked\Model\CompanyUser;
26
use LeadersLinked\Mapper\CompanyMapper;
1 www 27
 
28
class Module
29
{
30
 
31
    /**
32
     *
33
     * @var boolean
34
     */
35
    private $isJson;
36
 
37
    /**
38
     *
39
     * @var boolean
40
     */
41
    private $isHtml;
42
 
43
    /**
44
     *
45
     * @var Acl
46
     */
47
    private $acl;
48
 
3639 efrain 49
 
1 www 50
 
51
    /**
52
     *
53
     * @var AdapterInterface
54
     */
55
    private $adapter;
56
 
57
 
58
    /**
59
     *
60
     * @var CacheAdapter
61
     */
62
    private $cache;
63
 
64
    /**
65
     *
66
     * @var CurrentUserPlugin
67
     */
3639 efrain 68
    private $currentUserPlugin;
1 www 69
 
70
 
71
    /**
3639 efrain 72
     *
73
     * @var CurrentNetworkPlugin
74
     */
75
    private $currentNetworkPlugin;
76
 
77
 
78
    /**
1 www 79
     *
80
     * @var array
81
     */
82
    private $routesAuthorized = [];
83
 
84
    /**
85
     *
86
     * @var boolean
87
     */
88
    private $authByHeaders = false;
89
 
90
    public function init(ModuleManager $moduleManager)
91
    {
92
        $events = $moduleManager->getEventManager();
93
        $events->attach(ModuleEvent::EVENT_MERGE_CONFIG, array($this, 'onMergeConfig'));
94
    }
95
 
96
    public function onMergeConfig(ModuleEvent $event)
97
    {
98
        $configListener = $event->getConfigListener();
99
        $config         = $configListener->getMergedConfig(false);
100
 
101
        $reader = new Ini();
102
        $data = $reader->fromFile('config/leaderslinked.ini');
103
 
104
        $prefix = 'leaderslinked';
105
        foreach($data as $section => $pairs)
106
        {
107
            foreach($pairs as $key => $value)
108
            {
109
                $config[$prefix . '.' . $section . '.' . $key] = $value;
110
            }
111
        }
112
        $configListener->setMergedConfig($config);
113
    }
114
 
115
 
116
    public function getConfig() : array
117
    {
118
        return include __DIR__ . '/../config/module.config.php';
119
    }
120
 
121
    public function onBootstrap(MvcEvent $event)
122
    {
123
        $serviceManager = $event->getApplication()->getServiceManager();
124
        $adapter = $serviceManager->get('leaders-linked-db');
125
       // $logger          = $serviceManager->get('Zend\Log\Logger');
126
 
127
 
128
        $session = $serviceManager->get('leaders-linked-session');
129
        $session->start();
130
 
131
 
132
        $translator = $serviceManager->get('MvcTranslator');
133
        $translator->addTranslationFile(
134
            'phpArray',
135
            __DIR__ . '/i18n/validate.php',
136
            'default'
137
            );
138
 
139
        $translator->addTranslationFile(
140
            'phpArray',
141
            __DIR__ . '/i18n/spanish.php',
142
            'default'
143
            );
144
 
145
        \Laminas\Validator\AbstractValidator::setDefaultTranslator($translator);
146
 
147
 
148
        $headers  = $event->getRequest()->getHeaders();
149
        if($headers->has('Accept')) {
150
            $accept = $headers->get('Accept');
151
            $prioritized = $accept->getPrioritized();
152
 
153
            foreach($prioritized as $key => $value) {
154
                $raw = trim($value->getRaw());
155
 
156
                if(!$this->isJson) {
157
                    $this->isJson = strpos($raw, 'json');
158
                }
159
 
160
            }
161
        } else {
162
            $accept = '';
163
        }
164
        if($headers->has('token')) {
165
            $device_uuid = filter_var($headers->get('token')->getFieldValue(), FILTER_SANITIZE_STRING);
166
        } else {
167
            $device_uuid = '';
168
        }
169
        if($headers->has('secret')) {
170
            $password = filter_var($headers->get('secret')->getFieldValue(), FILTER_SANITIZE_STRING);
171
        } else {
172
            $password = '';
173
        }
174
        if($headers->has('rand')) {
175
            $rand = filter_var($headers->get('rand')->getFieldValue(), FILTER_SANITIZE_NUMBER_INT);
176
        } else {
177
            $rand = 0;
178
        }
179
        if($headers->has('created')) {
180
            $timestamp = filter_var($headers->get('created')->getFieldValue(), FILTER_SANITIZE_STRING);
181
        } else {
182
            $timestamp = 0;
183
        }
184
 
185
 
3639 efrain 186
 
187
 
188
        $this->currentNetworkPlugin = new CurrentNetworkPlugin($adapter);
189
        if(!$this->currentNetworkPlugin->hasNetwork()) {
3790 efrain 190
            $this->isJson = true;
191
            $response = $event->getResponse();
192
            $this->sendResponse($response, ['success' => false, 'data' => '401 Unauthorized - Private network - not found', 'fatal' => true]);
3639 efrain 193
        }
194
 
195
        if($this->currentNetworkPlugin->getNetwork()->status == Network::STATUS_INACTIVE) {
3790 efrain 196
            $this->isJson = true;
197
            $response = $event->getResponse();
198
            $this->sendResponse($response, ['success' => false, 'data' => '401 Unauthorized - Private network - inactive', 'fatal' => true]);
199
 
3639 efrain 200
        }
201
 
202
 
1 www 203
        $this->authByHeaders = false;
204
        if($device_uuid && $password && $rand && $timestamp) {
205
            $this->authByHeaders = true;
206
 
207
 
208
            $this->isJson = true;
209
 
210
            $tokenAuthAdapter = new AuthTokenAdapter($adapter);
211
            $tokenAuthAdapter->setData($device_uuid, $password, $timestamp, $rand);
212
 
213
            $authService = new AuthenticationService();
214
            $result = $authService->authenticate($tokenAuthAdapter);
215
            if($result->getCode() != \Laminas\Authentication\Result::SUCCESS) {
216
                $response = $event->getResponse();
217
 
218
                $this->sendResponse($response, ['success' => false, 'data' => $result->getMessages()[0], 'fatal' => true]);
219
            }
210 efrain 220
 
221
 
222
 
223
 
224
 
1 www 225
        }
3639 efrain 226
 
1 www 227
 
3639 efrain 228
 
229
        if(empty($_SERVER['REDIRECT_URL'])) {
230
            if(empty($_SERVER['REQUEST_URI'])) {
231
                $routeName = '';
232
 
233
            } else {
234
                $routeName = $_SERVER['REQUEST_URI'];
235
            }
236
 
237
        } else {
238
            $routeName = $_SERVER['REDIRECT_URL'];
239
 
240
        }
241
 
210 efrain 242
 
3639 efrain 243
        $routeName = strtolower(trim($routeName));
244
        if(strlen($routeName) > 0 && substr($routeName, 0, 1) == '/') {
245
            $routeName = substr($routeName, 1);
246
        }
1 www 247
 
3639 efrain 248
        $this->isHtml = $this->isJson ? false : true;
249
        $this->currentUserPlugin = new CurrentUserPlugin($adapter);
1 www 250
 
210 efrain 251
 
3639 efrain 252
        if($this->authByHeaders && substr($routeName, 0, 8) == 'services') {
253
            $checkUserForNetwork = false;
254
        } else {
255
            if($this->currentUserPlugin->hasIdentity()) {
256
 
257
                $checkUserForNetwork = true;
258
            } else {
259
                $checkUserForNetwork = false;
260
            }
261
        }
262
 
263
        if($checkUserForNetwork) {
264
            if(!$routeName || in_array($routeName, ['signout', 'signin', 'home'])) {
265
                $checkUserForNetwork = false;
266
            }
267
        }
268
 
269
        if($checkUserForNetwork) {
270
 
271
 
272
 
273
            if($this->currentUserPlugin->getUser()->network_id != $this->currentNetworkPlugin->getNetworkId()) {
3790 efrain 274
 
275
                $this->isJson = true;
276
                $response = $event->getResponse();
277
                $this->sendResponse($response, ['success' => false, 'data' => '401 Unauthorized - The user is not part of this private network', 'fatal' => true]);
278
 
3639 efrain 279
            }
280
        }
281
 
282
 
283
 
1 www 284
        $this->initAcl($event);
285
        $eventManager = $event->getApplication()->getEventManager();
286
        $eventManager->attach(MvcEvent::EVENT_DISPATCH_ERROR, [$this,'onDispatchError'], 0);
287
        $eventManager->attach(MvcEvent::EVENT_RENDER_ERROR, [$this,'onRenderError'], 0);
288
 
289
        $sharedManager = $eventManager->getSharedManager();
290
        $sharedManager->attach(__NAMESPACE__, MvcEvent::EVENT_DISPATCH, [$this, 'authPreDispatch'], 100);
291
        $sharedManager->attach(__NAMESPACE__, MvcEvent::EVENT_DISPATCH, [$this, 'authPosDispatch'], -100);
292
    }
293
 
294
    public function initAcl(MvcEvent $event)
295
    {
296
 
3639 efrain 297
        $serviceManager = $event->getApplication()->getServiceManager();
298
        $adapter = $serviceManager->get('leaders-linked-db');
299
 
300
 
1 www 301
        require_once   (dirname(__DIR__) . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'acl.config.php');
302
 
303
 
304
        $this->acl = new Acl();
305
        $resources = getAclResources();
1979 efrain 306
 
1 www 307
        foreach($resources as $resourceName)
308
        {
309
            $this->acl->addResource(new GenericResource($resourceName));
310
        }
311
 
312
        $usertypes = getAclUsertype();
313
        foreach($usertypes as $usertype => $resources)
314
        {
315
            $this->acl->addRole(new GenericRole($usertype));
316
            foreach ($resources as $resourceName)
317
            {
318
                $this->acl->allow($usertype, $resourceName);
319
            }
320
        }
321
 
3639 efrain 322
 
323
 
324
 
325
        if($this->currentUserPlugin->hasIdentity() && $this->currentUserPlugin->getUser()->is_super_user == User::IS_SUPER_USER_YES) {
326
 
327
            $resources =  getAclSuperAdmin();
328
            foreach($resources as $resourceName)
329
            {
330
                $this->acl->allow(UserType::ADMIN, $resourceName);
331
            }
332
        }
333
 
334
 
335
        if($this->currentNetworkPlugin->getNetwork()->default == Network::DEFAULT_YES) {
336
 
337
            $usertypes = getAclUsertypeDefaultNetwork();
338
            foreach($usertypes as $usertype => $resources)
339
            {
340
 
341
                foreach ($resources as $resourceName)
342
                {
343
                    $this->acl->allow($usertype, $resourceName);
344
                }
345
            }
346
 
347
 
348
        } else {
3647 efrain 349
 
3645 efrain 350
            if($this->currentUserPlugin->hasIdentity()) {
3639 efrain 351
 
3645 efrain 352
                $companyMapper = CompanyMapper::getInstance($adapter);
353
                $company = $companyMapper->fetchDefaultForNetworkByNetworkId($this->currentNetworkPlugin->getNetwork()->id);
354
                if($company) {
355
                    $companyUserMapper = CompanyUserMapper::getInstance($adapter);
3647 efrain 356
                    $companyUser = $companyUserMapper->fetchOneByCompanyIdAndUserId($company->id,  $this->currentUserPlugin->getUserId());
3639 efrain 357
 
3645 efrain 358
                    if($companyUser) {
359
                        $usertype = $this->currentUserPlugin->getUserTypeId();
3639 efrain 360
 
3645 efrain 361
                        if($companyUser->creator == CompanyUser::CREATOR_YES) {
362
 
363
                            $resources =  getAclUsertypeOtherNetworkCreator();
364
                            foreach($resources as $resourceName)
365
                            {
366
                                $this->acl->allow($usertype, $resourceName);
367
                            }
368
 
3639 efrain 369
                        }
3645 efrain 370
                        if($companyUser->creator == CompanyUser::CREATOR_NO) {
371
                            $resources =  getAclUsertypeOtherNetworkNonCreator();
372
                            foreach($resources as $resourceName)
373
                            {
374
                                $this->acl->allow($usertype, $resourceName);
375
                            }
3639 efrain 376
                        }
377
                    }
378
                }
3647 efrain 379
            }
3639 efrain 380
        }
381
 
382
 
1 www 383
        $event->getViewModel()->setVariable('acl', $this->acl);
384
 
385
    }
386
 
387
    public function onDispatchError(MvcEvent $event)
388
    {
389
        $this->processError($event);
390
    }
391
 
392
    public function onRenderError(MvcEvent $event)
393
    {
394
        $this->processError($event);
395
    }
396
 
397
    public function sendResponse(\Laminas\Http\Response $response, $data)
398
    {
399
 
400
 
401
        if($this->isJson) {
402
            $headers = $response->getHeaders();
403
            $headers->clearHeaders();
404
            $headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
405
 
406
            $response->setStatusCode(200);
407
            $response->setContent(json_encode($data));
408
            $response->send();
409
 
410
        } else {
411
            throw new \Exception($data['data']);
412
        }
413
        exit;
414
    }
415
 
416
    public function processError(MvcEvent $event)
417
    {
418
 
419
        $request =  $event->getRequest();
420
        if((method_exists($request, 'isXmlHttpRequest') && $request->isXmlHttpRequest()) || ($this->isJson && !$this->isHtml)) {
421
 
422
            $error = $event->getError();
423
            if (!$error) {
424
                return;
425
            }
426
 
427
            $response = $event->getResponse();
428
 
429
            if('error-exception' == $error) {
430
                $exception = $event->getParam('exception');
431
                error_log($exception->getCode() . ' ' . $exception->getMessage());
432
                error_log($exception->getTraceAsString());
433
 
434
 
435
                $data = [
436
                    'success' => false,
437
                    'data' => 'An error occurred during execution; please try again later.'
438
                ];
439
 
440
            } else if('error-router-no-match' == $error) {
441
                $data = [
442
                    'success' => false,
443
                    'data' => 'Resource not found.'
444
 
445
                ];
446
            } else if(' error-controller-not-found' == $error) {
447
                $data = [
448
                    'success' => false,
449
                    'data' => 'Controller not found.'
450
 
451
                ];
452
            } else {
453
                $data = [
454
                    'success' => false,
455
                    'data' => 'Unknow error.' , 'error' => $error
456
 
457
                ];
458
            }
459
 
460
            $this->sendResponse($response, $data);
461
        }
462
 
463
        $this->initAcl($event);
464
    }
465
 
466
 
467
    public function authPreDispatch(MvcEvent $event)
468
    {
210 efrain 469
 
470
 
471
 
472
 
1 www 473
        $serviceManager = $event->getApplication()->getServiceManager();
474
        $adapter = $serviceManager->get('leaders-linked-db');
475
 
210 efrain 476
        $routeName = $event->getRouteMatch()->getMatchedRouteName();
477
 
1 www 478
 
210 efrain 479
        $requestMethod = isset($_SERVER['REQUEST_METHOD']) ? trim(strtoupper($_SERVER['REQUEST_METHOD'])) : '';
480
 
481
        if($requestMethod == 'POST' || $requestMethod == 'PUT' || $requestMethod == 'DELETE') {
482
 
1979 efrain 483
 
1323 efrain 484
            if($this->authByHeaders && substr($routeName, 0, 8) == 'services') {
485
                $exclude = true;
486
            } else {
487
                $exclude = false;
488
 
489
                $usertypes = getAclUsertype();
490
 
491
 
492
                foreach($usertypes[UserType::GUEST] as $resourceName)
493
                {
494
                   if($routeName == $resourceName) {
495
                      $exclude = true;
496
                      break;
497
                    }
210 efrain 498
                }
499
            }
4131 efrain 500
 
4808 efrain 501
            $exclude = true;
1979 efrain 502
 
210 efrain 503
            if(!$exclude) {
504
                $httpToken = isset($_SERVER['HTTP_X_CSRF_TOKEN']) ? $_SERVER['HTTP_X_CSRF_TOKEN'] : '';
505
                $sessionToken = isset($_SESSION['token']) ? $_SESSION['token'] : uniqid();
506
 
507
                unset($_SESSION['token']);
508
                if ( $httpToken != $sessionToken) {
509
                    header("HTTP/1.1 401 Unauthorized");
510
                    exit;
511
                }
512
 
513
            }
514
        }
515
 
516
 
517
 
3639 efrain 518
        if($this->currentUserPlugin->hasIdentity())  {
519
            $user = $this->currentUserPlugin->getUser();
1 www 520
            $userTypeId = $user->usertype_id;
521
 
522
 
523
        }  else {
524
 
525
            $userTypeId = UserType::GUEST;
526
        }
527
 
210 efrain 528
 
1 www 529
        if($this->acl->isAllowed($userTypeId, $routeName)) {
3639 efrain 530
            $user = $this->currentUserPlugin->getUser();
210 efrain 531
 
1 www 532
 
533
            if($user) {
3086 efrain 534
 
535
                $updateLastActivity = true;
536
                if ('chat' == substr($routeName, 0, 4)) {
537
                    $updateLastActivity = false;
538
                }
539
                if ('inmail' == substr($routeName, 0, 6)) {
540
                    $updateLastActivity = false;
541
                }
542
                if ('check-session' == $routeName) {
543
                    $updateLastActivity = false;
544
                }
545
 
546
 
547
                if($updateLastActivity) {
548
                    $userMapper = UserMapper::getInstance($adapter);
549
                    $userMapper->updateLastActivity($user->id);
550
                }
1 www 551
            }
552
 
553
        } else {
210 efrain 554
 
1 www 555
            if($this->authByHeaders) {
556
                $response = $event->getResponse();
557
                $headers = $response->getHeaders();
558
                $headers->clearHeaders();
559
                $headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
560
 
561
                $response->setStatusCode(401);
562
                $response->setContent(json_encode(['success' => false, 'data' => 'Unauthorized.', 'fatal' => true]));
563
                $response->send();
564
                exit;
565
 
210 efrain 566
            }
1 www 567
 
568
 
569
            //print_r($this->routesAuthorized);
570
           // echo 'sin permiso'; exit;
571
 
572
 
3639 efrain 573
            $this->currentUserPlugin->clearIdentity();
1 www 574
 
575
 
576
            if($this->isJson) {
577
                $response = $event->getResponse();
578
                $headers = $response->getHeaders();
579
                $headers->clearHeaders();
580
                $headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
581
 
582
                $response->setStatusCode(200);
583
                $response->setContent(json_encode(['success' => false, 'data' => 'Unauthorized.', 'fatal' => true]));
584
                $response->send();
585
            } else {
586
                $url = $event->getRouter()->assemble([], ['name' => 'signout']);
587
 
588
                $response = $event->getResponse();
589
                $headers = $response->getHeaders();
590
                $headers->clearHeaders();
591
                $headers->addHeaderLine('Location', $url);
592
 
593
                $response->setStatusCode(302);
594
                $response->send();
595
            }
596
            exit;
597
        }
598
 
599
 
600
    }
601
 
602
 
603
    public function authPosDispatch(MvcEvent $event)
604
    {
605
 
606
    }
607
 
608
 
609
}