Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 5951 | Rev 6481 | 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();
390
            foreach($resources as $resourceName)
391
            {
392
                $this->acl->allow($usertype, $resourceName);
393
            }
394
 
395
        }
5951 efrain 396
 
397
 
6388 efrain 398
 
3639 efrain 399
        if($this->currentNetworkPlugin->getNetwork()->default == Network::DEFAULT_YES) {
400
 
401
            $usertypes = getAclUsertypeDefaultNetwork();
402
            foreach($usertypes as $usertype => $resources)
403
            {
5205 efrain 404
 
3639 efrain 405
 
5205 efrain 406
 
3639 efrain 407
                foreach ($resources as $resourceName)
408
                {
409
                    $this->acl->allow($usertype, $resourceName);
410
                }
411
            }
412
 
413
 
414
        } else {
3647 efrain 415
 
3645 efrain 416
            if($this->currentUserPlugin->hasIdentity()) {
3639 efrain 417
 
5205 efrain 418
 
3645 efrain 419
                if($company) {
3639 efrain 420
 
5205 efrain 421
 
3645 efrain 422
                    if($companyUser) {
423
                        $usertype = $this->currentUserPlugin->getUserTypeId();
3639 efrain 424
 
3645 efrain 425
                        if($companyUser->creator == CompanyUser::CREATOR_YES) {
426
 
427
                            $resources =  getAclUsertypeOtherNetworkCreator();
428
                            foreach($resources as $resourceName)
429
                            {
430
                                $this->acl->allow($usertype, $resourceName);
431
                            }
432
 
3639 efrain 433
                        }
3645 efrain 434
                        if($companyUser->creator == CompanyUser::CREATOR_NO) {
435
                            $resources =  getAclUsertypeOtherNetworkNonCreator();
436
                            foreach($resources as $resourceName)
437
                            {
438
                                $this->acl->allow($usertype, $resourceName);
439
                            }
3639 efrain 440
                        }
441
                    }
442
                }
3647 efrain 443
            }
3639 efrain 444
        }
445
 
446
 
1 www 447
        $event->getViewModel()->setVariable('acl', $this->acl);
448
 
449
    }
450
 
451
    public function onDispatchError(MvcEvent $event)
452
    {
453
        $this->processError($event);
454
    }
455
 
456
    public function onRenderError(MvcEvent $event)
457
    {
458
        $this->processError($event);
459
    }
460
 
461
    public function sendResponse(\Laminas\Http\Response $response, $data)
462
    {
463
 
464
 
465
        if($this->isJson) {
466
            $headers = $response->getHeaders();
467
            $headers->clearHeaders();
468
            $headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
469
 
470
            $response->setStatusCode(200);
471
            $response->setContent(json_encode($data));
472
            $response->send();
473
 
474
        } else {
475
            throw new \Exception($data['data']);
476
        }
477
        exit;
478
    }
479
 
480
    public function processError(MvcEvent $event)
481
    {
482
 
483
        $request =  $event->getRequest();
484
        if((method_exists($request, 'isXmlHttpRequest') && $request->isXmlHttpRequest()) || ($this->isJson && !$this->isHtml)) {
485
 
486
            $error = $event->getError();
487
            if (!$error) {
488
                return;
489
            }
490
 
491
            $response = $event->getResponse();
492
 
493
            if('error-exception' == $error) {
494
                $exception = $event->getParam('exception');
495
                error_log($exception->getCode() . ' ' . $exception->getMessage());
496
                error_log($exception->getTraceAsString());
497
 
498
 
499
                $data = [
500
                    'success' => false,
501
                    'data' => 'An error occurred during execution; please try again later.'
502
                ];
503
 
504
            } else if('error-router-no-match' == $error) {
505
                $data = [
506
                    'success' => false,
507
                    'data' => 'Resource not found.'
508
 
509
                ];
510
            } else if(' error-controller-not-found' == $error) {
511
                $data = [
512
                    'success' => false,
513
                    'data' => 'Controller not found.'
514
 
515
                ];
516
            } else {
517
                $data = [
518
                    'success' => false,
519
                    'data' => 'Unknow error.' , 'error' => $error
520
 
521
                ];
522
            }
523
 
524
            $this->sendResponse($response, $data);
525
        }
526
 
527
        $this->initAcl($event);
528
    }
529
 
530
 
531
    public function authPreDispatch(MvcEvent $event)
532
    {
210 efrain 533
 
534
 
535
 
536
 
1 www 537
        $serviceManager = $event->getApplication()->getServiceManager();
538
        $adapter = $serviceManager->get('leaders-linked-db');
539
 
210 efrain 540
        $routeName = $event->getRouteMatch()->getMatchedRouteName();
541
 
1 www 542
 
210 efrain 543
        $requestMethod = isset($_SERVER['REQUEST_METHOD']) ? trim(strtoupper($_SERVER['REQUEST_METHOD'])) : '';
544
 
545
        if($requestMethod == 'POST' || $requestMethod == 'PUT' || $requestMethod == 'DELETE') {
546
 
1979 efrain 547
 
1323 efrain 548
            if($this->authByHeaders && substr($routeName, 0, 8) == 'services') {
549
                $exclude = true;
550
            } else {
551
                $exclude = false;
552
 
553
                $usertypes = getAclUsertype();
554
 
555
 
556
                foreach($usertypes[UserType::GUEST] as $resourceName)
557
                {
558
                   if($routeName == $resourceName) {
559
                      $exclude = true;
560
                      break;
561
                    }
210 efrain 562
                }
563
            }
4131 efrain 564
 
4808 efrain 565
            $exclude = true;
1979 efrain 566
 
210 efrain 567
            if(!$exclude) {
568
                $httpToken = isset($_SERVER['HTTP_X_CSRF_TOKEN']) ? $_SERVER['HTTP_X_CSRF_TOKEN'] : '';
569
                $sessionToken = isset($_SESSION['token']) ? $_SESSION['token'] : uniqid();
570
 
571
                unset($_SESSION['token']);
572
                if ( $httpToken != $sessionToken) {
573
                    header("HTTP/1.1 401 Unauthorized");
574
                    exit;
575
                }
576
 
577
            }
578
        }
579
 
580
 
581
 
3639 efrain 582
        if($this->currentUserPlugin->hasIdentity())  {
583
            $user = $this->currentUserPlugin->getUser();
1 www 584
            $userTypeId = $user->usertype_id;
585
 
586
 
587
        }  else {
588
 
589
            $userTypeId = UserType::GUEST;
590
        }
591
 
210 efrain 592
 
1 www 593
        if($this->acl->isAllowed($userTypeId, $routeName)) {
3639 efrain 594
            $user = $this->currentUserPlugin->getUser();
210 efrain 595
 
1 www 596
 
597
            if($user) {
3086 efrain 598
 
599
                $updateLastActivity = true;
600
                if ('chat' == substr($routeName, 0, 4)) {
601
                    $updateLastActivity = false;
602
                }
603
                if ('inmail' == substr($routeName, 0, 6)) {
604
                    $updateLastActivity = false;
605
                }
606
                if ('check-session' == $routeName) {
607
                    $updateLastActivity = false;
608
                }
609
 
610
 
611
                if($updateLastActivity) {
612
                    $userMapper = UserMapper::getInstance($adapter);
613
                    $userMapper->updateLastActivity($user->id);
614
                }
1 www 615
            }
616
 
617
        } else {
210 efrain 618
 
1 www 619
            if($this->authByHeaders) {
620
                $response = $event->getResponse();
621
                $headers = $response->getHeaders();
622
                $headers->clearHeaders();
623
                $headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
624
 
625
                $response->setStatusCode(401);
626
                $response->setContent(json_encode(['success' => false, 'data' => 'Unauthorized.', 'fatal' => true]));
627
                $response->send();
628
                exit;
629
 
210 efrain 630
            }
1 www 631
 
632
 
633
            //print_r($this->routesAuthorized);
634
           // echo 'sin permiso'; exit;
635
 
636
 
3639 efrain 637
            $this->currentUserPlugin->clearIdentity();
1 www 638
 
639
 
640
            if($this->isJson) {
641
                $response = $event->getResponse();
642
                $headers = $response->getHeaders();
643
                $headers->clearHeaders();
644
                $headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
645
 
646
                $response->setStatusCode(200);
647
                $response->setContent(json_encode(['success' => false, 'data' => 'Unauthorized.', 'fatal' => true]));
648
                $response->send();
649
            } else {
650
                $url = $event->getRouter()->assemble([], ['name' => 'signout']);
651
 
652
                $response = $event->getResponse();
653
                $headers = $response->getHeaders();
654
                $headers->clearHeaders();
655
                $headers->addHeaderLine('Location', $url);
656
 
657
                $response->setStatusCode(302);
658
                $response->send();
659
            }
660
            exit;
661
        }
662
 
663
 
664
    }
665
 
666
 
667
    public function authPosDispatch(MvcEvent $event)
668
    {
669
 
670
    }
671
 
672
 
673
}