Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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