Proyectos de Subversion LeadersLinked - Services

Rev

Rev 1 | Rev 4 | 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
 
3 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
        }
3 efrain 178
 
1 efrain 179
 
180
 
181
        $this->authByHeaders = false;
182
        if($device_uuid && $password && $rand && $timestamp) {
183
            $this->authByHeaders = true;
184
 
185
 
186
            $tokenAuthAdapter = new AuthTokenAdapter($adapter);
187
            $tokenAuthAdapter->setData($device_uuid, $password, $timestamp, $rand);
188
 
189
            $authService = new AuthenticationService();
190
            $result = $authService->authenticate($tokenAuthAdapter);
191
            if($result->getCode() != \Laminas\Authentication\Result::SUCCESS) {
192
                $response = $event->getResponse();
193
 
194
                $this->sendResponse($response, ['success' => false, 'data' => $result->getMessages()[0], 'fatal' => true]);
195
            }
196
 
197
        }
198
 
199
 
200
 
201
        if(empty($_SERVER['REDIRECT_URL'])) {
202
            if(empty($_SERVER['REQUEST_URI'])) {
203
                $routeName = '';
204
 
205
            } else {
206
                $routeName = $_SERVER['REQUEST_URI'];
207
            }
208
 
209
        } else {
210
            $routeName = $_SERVER['REDIRECT_URL'];
211
 
212
        }
213
 
214
 
215
        $routeName = strtolower(trim($routeName));
216
        if(strlen($routeName) > 0 && substr($routeName, 0, 1) == '/') {
217
            $routeName = substr($routeName, 1);
218
        }
219
 
220
        $this->currentUserPlugin = new CurrentUserPlugin($adapter);
221
 
222
 
223
        if($this->authByHeaders && substr($routeName, 0, 8) == 'services') {
224
            $checkUserForNetwork = false;
225
        } else {
226
            if($this->currentUserPlugin->hasIdentity()) {
227
 
228
                $checkUserForNetwork = true;
229
            } else {
230
                $checkUserForNetwork = false;
231
            }
232
        }
233
 
234
        if($checkUserForNetwork) {
235
            if(!$routeName || in_array($routeName, ['signout', 'signin', 'home'])) {
236
                $checkUserForNetwork = false;
237
            }
238
        }
239
 
240
        if($checkUserForNetwork) {
241
 
242
 
243
 
244
            if($this->currentUserPlugin->getUser()->network_id != $this->currentNetworkPlugin->getNetworkId()) {
245
                $response = $event->getResponse();
246
                $this->sendResponse($response, ['success' => false, 'data' => '401 Unauthorized - The user is not part of this private network', 'fatal' => true]);
247
                exit;
248
            }
249
        }
250
 
251
 
252
 
253
        $this->initAcl($event);
254
        $eventManager = $event->getApplication()->getEventManager();
255
        $eventManager->attach(MvcEvent::EVENT_DISPATCH_ERROR, [$this,'onDispatchError'], 0);
256
        $eventManager->attach(MvcEvent::EVENT_RENDER_ERROR, [$this,'onRenderError'], 0);
257
 
258
        $sharedManager = $eventManager->getSharedManager();
259
        $sharedManager->attach(__NAMESPACE__, MvcEvent::EVENT_DISPATCH, [$this, 'authPreDispatch'], 100);
260
        $sharedManager->attach(__NAMESPACE__, MvcEvent::EVENT_DISPATCH, [$this, 'authPosDispatch'], -100);
261
    }
262
 
263
    public function initAcl(MvcEvent $event)
264
    {
265
 
266
        $serviceManager = $event->getApplication()->getServiceManager();
267
        $adapter = $serviceManager->get('leaders-linked-db');
268
 
269
 
270
        require_once   (dirname(__DIR__) . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'acl.config.php');
271
 
272
 
273
        $this->acl = new Acl();
274
        $resources = getAclResources();
275
 
276
        foreach($resources as $resourceName)
277
        {
278
            $this->acl->addResource(new GenericResource($resourceName));
279
        }
280
 
281
        $usertypes = getAclUsertype();
282
        foreach($usertypes as $usertype => $resources)
283
        {
284
            $this->acl->addRole(new GenericRole($usertype));
285
            foreach ($resources as $resourceName)
286
            {
287
                $this->acl->allow($usertype, $resourceName);
288
            }
289
        }
290
 
291
 
292
 
293
        if($this->currentUserPlugin->hasIdentity() && $this->currentUserPlugin->getUser()->is_super_user == User::IS_SUPER_USER_YES) {
294
 
295
            $resources =  getAclSuperAdmin();
296
            foreach($resources as $resourceName)
297
            {
298
                $this->acl->allow(UserType::ADMIN, $resourceName);
299
            }
300
        }
301
 
302
 
303
 
304
        $allowMyCoach = false;
305
        $allowKnowledgeArea = false;
306
        $allowDailyPulse = false;
307
 
308
 
309
 
310
        $companyMapper = CompanyMapper::getInstance($adapter);
311
        $company = $companyMapper->fetchDefaultForNetworkByNetworkId($this->currentNetworkPlugin->getNetwork()->id);
312
 
313
 
314
        if($company) {
315
 
316
            $companyServiceMapper = CompanyServiceMapper::getInstance($adapter);
317
            $companyService = $companyServiceMapper->fetchOneActiveByCompanyIdAndServiceId($company->id, Service::DAILY_PULSE);
318
 
319
 
320
            $companyUserMapper = CompanyUserMapper::getInstance($adapter);
321
            $companyUser = $companyUserMapper->fetchOneAcceptedByCompanyIdAndUserId($company->id,  $this->currentUserPlugin->getUserId());
322
 
323
 
324
 
325
 
326
            if($companyService) {
327
 
328
                $dailyPulseMapper = DailyPulseMapper::getInstance($adapter);
329
                $dailyPulse = $dailyPulseMapper->fetchOneByCompanyId($company->id);
330
 
331
                if($dailyPulse) {
332
                    $privacy = $dailyPulse->privacy;
333
 
334
                } else {
335
                    $privacy = DailyPulse::PRIVACY_COMPANY;
336
                }
337
 
338
                if($privacy ==  DailyPulse::PRIVACY_PUBLIC) {
339
                    $allowDailyPulse = true;
340
                } else {
341
                    $allowDailyPulse = !empty($companyUser);
342
                }
343
 
344
 
345
            }
346
 
347
            $job_description_ids = [];
348
 
349
            $organizationPositionMapper = OrganizationPositionMapper::getInstance($adapter);
350
            $records = $organizationPositionMapper->fetchAllByCompanyIdAndEmployeeId($company->id,  $this->currentUserPlugin->getUserId());
351
            foreach($records as $record)
352
            {
353
                array_push($job_description_ids, $record->job_description_id);
354
            }
355
 
356
 
357
            $companyService = $companyServiceMapper->fetchOneActiveByCompanyIdAndServiceId($company->id, Service::KNOWLEDGE_AREA);
358
            if($companyService) {
359
                if($job_description_ids) {
360
 
361
 
362
                    $knowledgeAreaCategoryJobDescriptionMapper = KnowledgeAreaCategoryJobDescriptionMapper::getInstance($adapter);
363
                    $records = $knowledgeAreaCategoryJobDescriptionMapper->fetchAllByCompanyIdAndJobDescriptionIds($company->id, $job_description_ids);
364
 
365
                    if(!empty($records)) {
366
                        $allowKnowledgeArea = true;
367
                    }
368
 
369
                }
370
 
371
                if($companyUser && !$allowKnowledgeArea) {
372
                    $knowledgeAreaCategoryUserMapper = KnowledgeAreaCategoryUserMapper::getInstance($adapter);
373
                    $records = $knowledgeAreaCategoryUserMapper->fetchAllByUserId($companyUser->user_id);
374
                    if(!empty($records)) {
375
                        $allowKnowledgeArea = true;
376
                    }
377
                }
378
            }
379
 
380
            $companyService = $companyServiceMapper->fetchOneActiveByCompanyIdAndServiceId($company->id, Service::MY_COACH);
381
            if($companyService) {
382
 
383
 
384
                if($job_description_ids) {
385
 
386
 
387
                    $myCoachCategoryJobDescriptionMapper = MyCoachCategoryJobDescriptionMapper::getInstance($adapter);
388
                    $records = $myCoachCategoryJobDescriptionMapper->fetchAllByCompanyIdAndJobDescriptionIds($company->id, $job_description_ids);
389
 
390
                    if(!empty($records)) {
391
                        $allowKnowledgeArea = true;
392
                    }
393
 
394
                }
395
 
396
                if($companyUser && !$allowMyCoach) {
397
                    $myCoachCategoryUserMapper = MyCoachCategoryUserMapper::getInstance($adapter);
398
                    $records = $myCoachCategoryUserMapper->fetchAllByUserId($companyUser->user_id);
399
                    if(!empty($records)) {
400
                        $allowMyCoach = true;
401
                    }
402
 
403
 
404
                }
405
            }
406
 
407
        } else {
408
            $companyUser = '';
409
        }
410
 
411
 
412
        $usertype = $this->currentUserPlugin->getUserTypeId();
413
        if($allowDailyPulse) {
414
            $resources = getAclDailyPulse();
415
            foreach($resources as $resourceName)
416
            {
417
                $this->acl->allow($usertype, $resourceName);
418
            }
419
        }
420
 
421
        if($allowKnowledgeArea) {
422
            $resources = getAclKnowledgeArea();
423
            foreach($resources as $resourceName)
424
            {
425
                $this->acl->allow($usertype, $resourceName);
426
            }
427
        }
428
 
429
        if($allowMyCoach) {
430
            $resources = getAclMyCoach();
431
 
432
 
433
 
434
            foreach($resources as $resourceName)
435
            {
436
                $this->acl->allow($usertype, $resourceName);
437
            }
438
 
439
        }
440
 
441
 
442
 
443
        if($this->currentNetworkPlugin->getNetwork()->default == Network::DEFAULT_YES) {
444
 
445
            $usertypes = getAclUsertypeDefaultNetwork();
446
            foreach($usertypes as $usertype => $resources)
447
            {
448
 
449
 
450
 
451
                foreach ($resources as $resourceName)
452
                {
453
                    $this->acl->allow($usertype, $resourceName);
454
                }
455
            }
456
 
457
 
458
        } else {
459
 
460
            if($this->currentUserPlugin->hasIdentity()) {
461
 
462
 
463
                if($company) {
464
 
465
 
466
                    if($companyUser) {
467
                        $usertype = $this->currentUserPlugin->getUserTypeId();
468
 
469
                        if($companyUser->creator == CompanyUser::CREATOR_YES) {
470
 
471
                            $resources =  getAclUsertypeOtherNetworkCreator();
472
                            foreach($resources as $resourceName)
473
                            {
474
                                $this->acl->allow($usertype, $resourceName);
475
                            }
476
 
477
                        }
478
                        if($companyUser->creator == CompanyUser::CREATOR_NO) {
479
                            $resources =  getAclUsertypeOtherNetworkNonCreator();
480
                            foreach($resources as $resourceName)
481
                            {
482
                                $this->acl->allow($usertype, $resourceName);
483
                            }
484
                        }
485
                    }
486
                }
487
            }
488
        }
489
 
490
 
491
        $event->getViewModel()->setVariable('acl', $this->acl);
492
 
493
    }
494
 
495
    public function onDispatchError(MvcEvent $event)
496
    {
497
        $this->processError($event);
498
    }
499
 
500
    public function onRenderError(MvcEvent $event)
501
    {
502
        $this->processError($event);
503
    }
504
 
505
    public function sendResponse(\Laminas\Http\Response $response, $data)
506
    {
507
        $headers = $response->getHeaders();
508
        $headers->clearHeaders();
509
        $headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
510
 
511
        $response->setStatusCode(200);
512
        $response->setContent(json_encode($data));
513
        $response->send();
514
        exit;
515
    }
516
 
517
    public function processError(MvcEvent $event)
518
    {
519
        $error = $event->getError();
520
        if (!$error) {
521
            return;
522
        }
523
 
524
        $response = $event->getResponse();
525
        if('error-exception' == $error) {
526
            $exception = $event->getParam('exception');
527
            error_log($exception->getCode() . ' ' . $exception->getMessage());
528
            error_log($exception->getTraceAsString());
529
 
530
            $response = $event->getResponse();
531
            $headers = $response->getHeaders();
532
            $headers->clearHeaders();
533
            $headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
534
 
535
            $response->setStatusCode(500);
536
            $response->setContent(json_encode(['success' => false, 'data' => $exception->getCode() . ' ' . $exception->getMessage(), 'fatal' => true]));
537
            $response->send();
538
 
539
        } else if('error-router-no-match' == $error) {
540
            $response = $event->getResponse();
541
            $headers = $response->getHeaders();
542
            $headers->clearHeaders();
543
            $headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
544
 
545
            $response->setStatusCode(404);
546
            $response->setContent(json_encode(['success' => false, 'data' => 'error-router-no-match', 'fatal' => true]));
547
            $response->send();
548
 
549
 
550
        } else if(' error-controller-not-found' == $error) {
551
            $response = $event->getResponse();
552
            $headers = $response->getHeaders();
553
            $headers->clearHeaders();
554
            $headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
555
 
556
            $response->setStatusCode(404);
557
            $response->setContent(json_encode(['success' => false, 'data' => 'error-controller-not-found', 'fatal' => true]));
558
            $response->send();
559
        } else {
560
 
561
            $response = $event->getResponse();
562
            $headers = $response->getHeaders();
563
            $headers->clearHeaders();
564
            $headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
565
 
566
            $response->setStatusCode(500);
567
            $response->setContent(json_encode(['success' => false, 'data' => $error, 'fatal' => true]));
568
            $response->send();
569
 
570
        }
571
 
572
        exit;
573
 
574
        //$this->initAcl($event);
575
        //$this->authPreDispatch($event);
576
    }
577
 
578
 
579
    public function authPreDispatch(MvcEvent $event)
580
    {
581
 
582
 
583
 
584
 
585
        $serviceManager = $event->getApplication()->getServiceManager();
586
        $adapter = $serviceManager->get('leaders-linked-db');
587
 
588
        $routeName = $event->getRouteMatch()->getMatchedRouteName();
589
 
590
 
591
        $requestMethod = isset($_SERVER['REQUEST_METHOD']) ? trim(strtoupper($_SERVER['REQUEST_METHOD'])) : '';
592
 
593
        if($requestMethod == 'POST' || $requestMethod == 'PUT' || $requestMethod == 'DELETE') {
594
 
595
 
596
            if($this->authByHeaders && substr($routeName, 0, 8) == 'services') {
597
                $exclude = true;
598
            } else {
599
                $exclude = false;
600
 
601
                $usertypes = getAclUsertype();
602
 
603
 
604
                foreach($usertypes[UserType::GUEST] as $resourceName)
605
                {
606
                   if($routeName == $resourceName) {
607
                      $exclude = true;
608
                      break;
609
                    }
610
                }
611
            }
612
 
613
            $exclude = true;
614
 
615
            if(!$exclude) {
616
                $httpToken = isset($_SERVER['HTTP_X_CSRF_TOKEN']) ? $_SERVER['HTTP_X_CSRF_TOKEN'] : '';
617
                $sessionToken = isset($_SESSION['token']) ? $_SESSION['token'] : uniqid();
618
 
619
                unset($_SESSION['token']);
620
                if ( $httpToken != $sessionToken) {
621
                    $response = $event->getResponse();
622
                    $headers = $response->getHeaders();
623
                    $headers->clearHeaders();
624
                    $headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
625
 
626
                    $response->setStatusCode(401);
627
                    $response->setContent(json_encode(['success' => false, 'data' => 'Unauthorized.', 'fatal' => true]));
628
                    $response->send();
629
                    exit;
630
                }
631
 
632
            }
633
        }
634
 
635
 
636
 
637
        if($this->currentUserPlugin->hasIdentity())  {
638
            $user = $this->currentUserPlugin->getUser();
639
            $userTypeId = $user->usertype_id;
640
 
641
 
642
        }  else {
643
 
644
            $userTypeId = UserType::GUEST;
645
        }
646
 
647
 
648
        if($this->acl->isAllowed($userTypeId, $routeName)) {
649
            $user = $this->currentUserPlugin->getUser();
650
 
651
 
652
            if($user) {
653
 
654
                $updateLastActivity = true;
655
                if ('chat' == substr($routeName, 0, 4)) {
656
                    $updateLastActivity = false;
657
                }
658
                if ('inmail' == substr($routeName, 0, 6)) {
659
                    $updateLastActivity = false;
660
                }
661
                if ('check-session' == $routeName) {
662
                    $updateLastActivity = false;
663
                }
664
 
665
 
666
                if($updateLastActivity) {
667
                    $userMapper = UserMapper::getInstance($adapter);
668
                    $userMapper->updateLastActivity($user->id);
669
                }
670
            }
671
 
672
 
673
 
674
        } else {
675
            $response = $event->getResponse();
676
            $headers = $response->getHeaders();
677
            $headers->clearHeaders();
678
            $headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
679
 
680
            $response->setStatusCode(401);
681
            $response->setContent(json_encode(['success' => false, 'data' => 'Unauthorized.', 'fatal' => true]));
682
            $response->send();
683
            exit;
684
 
685
 
686
 
687
        }
688
 
689
 
690
    }
691
 
692
 
693
    public function authPosDispatch(MvcEvent $event)
694
    {
695
 
696
    }
697
 
698
 
699
 
700
 
701
}