Proyectos de Subversion LeadersLinked - Services

Rev

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

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