Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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