Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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