Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 1323 | Rev 3086 | 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;
21
 
22
class Module
23
{
24
 
25
    /**
26
     *
27
     * @var boolean
28
     */
29
    private $isJson;
30
 
31
    /**
32
     *
33
     * @var boolean
34
     */
35
    private $isHtml;
36
 
37
    /**
38
     *
39
     * @var Acl
40
     */
41
    private $acl;
42
 
43
    /**
44
     *
45
     * @var Company
46
     */
47
    private $company;
48
 
49
    /**
50
     *
51
     * @var AdapterInterface
52
     */
53
    private $adapter;
54
 
55
 
56
    /**
57
     *
58
     * @var CacheAdapter
59
     */
60
    private $cache;
61
 
62
    /**
63
     *
64
     * @var CurrentUserPlugin
65
     */
66
    private $currentUser;
67
 
68
 
69
    /**
70
     *
71
     * @var array
72
     */
73
    private $routesAuthorized = [];
74
 
75
    /**
76
     *
77
     * @var boolean
78
     */
79
    private $authByHeaders = false;
80
 
81
    public function init(ModuleManager $moduleManager)
82
    {
83
        $events = $moduleManager->getEventManager();
84
        $events->attach(ModuleEvent::EVENT_MERGE_CONFIG, array($this, 'onMergeConfig'));
85
    }
86
 
87
    public function onMergeConfig(ModuleEvent $event)
88
    {
89
        $configListener = $event->getConfigListener();
90
        $config         = $configListener->getMergedConfig(false);
91
 
92
        $reader = new Ini();
93
        $data = $reader->fromFile('config/leaderslinked.ini');
94
 
95
        $prefix = 'leaderslinked';
96
        foreach($data as $section => $pairs)
97
        {
98
            foreach($pairs as $key => $value)
99
            {
100
                $config[$prefix . '.' . $section . '.' . $key] = $value;
101
            }
102
        }
103
        $configListener->setMergedConfig($config);
104
    }
105
 
106
 
107
    public function getConfig() : array
108
    {
109
        return include __DIR__ . '/../config/module.config.php';
110
    }
111
 
112
    public function onBootstrap(MvcEvent $event)
113
    {
114
        $serviceManager = $event->getApplication()->getServiceManager();
115
        $adapter = $serviceManager->get('leaders-linked-db');
116
       // $logger          = $serviceManager->get('Zend\Log\Logger');
117
 
118
 
119
        $session = $serviceManager->get('leaders-linked-session');
120
        $session->start();
121
 
122
 
123
        $translator = $serviceManager->get('MvcTranslator');
124
        $translator->addTranslationFile(
125
            'phpArray',
126
            __DIR__ . '/i18n/validate.php',
127
            'default'
128
            );
129
 
130
        $translator->addTranslationFile(
131
            'phpArray',
132
            __DIR__ . '/i18n/spanish.php',
133
            'default'
134
            );
135
 
136
        \Laminas\Validator\AbstractValidator::setDefaultTranslator($translator);
137
 
138
 
139
        $headers  = $event->getRequest()->getHeaders();
140
        if($headers->has('Accept')) {
141
            $accept = $headers->get('Accept');
142
            $prioritized = $accept->getPrioritized();
143
 
144
            foreach($prioritized as $key => $value) {
145
                $raw = trim($value->getRaw());
146
 
147
                if(!$this->isJson) {
148
                    $this->isJson = strpos($raw, 'json');
149
                }
150
 
151
            }
152
        } else {
153
            $accept = '';
154
        }
155
        if($headers->has('token')) {
156
            $device_uuid = filter_var($headers->get('token')->getFieldValue(), FILTER_SANITIZE_STRING);
157
        } else {
158
            $device_uuid = '';
159
        }
160
        if($headers->has('secret')) {
161
            $password = filter_var($headers->get('secret')->getFieldValue(), FILTER_SANITIZE_STRING);
162
        } else {
163
            $password = '';
164
        }
165
        if($headers->has('rand')) {
166
            $rand = filter_var($headers->get('rand')->getFieldValue(), FILTER_SANITIZE_NUMBER_INT);
167
        } else {
168
            $rand = 0;
169
        }
170
        if($headers->has('created')) {
171
            $timestamp = filter_var($headers->get('created')->getFieldValue(), FILTER_SANITIZE_STRING);
172
        } else {
173
            $timestamp = 0;
174
        }
175
 
176
 
177
        $this->authByHeaders = false;
178
        if($device_uuid && $password && $rand && $timestamp) {
179
            $this->authByHeaders = true;
180
 
181
 
182
            $this->isJson = true;
183
 
184
            $tokenAuthAdapter = new AuthTokenAdapter($adapter);
185
            $tokenAuthAdapter->setData($device_uuid, $password, $timestamp, $rand);
186
 
187
            $authService = new AuthenticationService();
188
            $result = $authService->authenticate($tokenAuthAdapter);
189
            if($result->getCode() != \Laminas\Authentication\Result::SUCCESS) {
190
                $response = $event->getResponse();
191
 
192
                $this->sendResponse($response, ['success' => false, 'data' => $result->getMessages()[0], 'fatal' => true]);
193
            }
210 efrain 194
 
195
 
196
 
197
 
198
 
1 www 199
        }
200
 
210 efrain 201
 
1 www 202
 
203
 
210 efrain 204
 
1 www 205
        $this->isHtml = $this->isJson ? false : true;
206
        $this->currentUser = new CurrentUserPlugin($adapter);
207
        $this->initAcl($event);
208
        $eventManager = $event->getApplication()->getEventManager();
209
        $eventManager->attach(MvcEvent::EVENT_DISPATCH_ERROR, [$this,'onDispatchError'], 0);
210
        $eventManager->attach(MvcEvent::EVENT_RENDER_ERROR, [$this,'onRenderError'], 0);
211
 
212
        $sharedManager = $eventManager->getSharedManager();
213
        $sharedManager->attach(__NAMESPACE__, MvcEvent::EVENT_DISPATCH, [$this, 'authPreDispatch'], 100);
214
        $sharedManager->attach(__NAMESPACE__, MvcEvent::EVENT_DISPATCH, [$this, 'authPosDispatch'], -100);
215
    }
216
 
217
    public function initAcl(MvcEvent $event)
218
    {
219
 
220
        require_once   (dirname(__DIR__) . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'acl.config.php');
221
 
222
 
223
        $this->acl = new Acl();
224
        $resources = getAclResources();
1979 efrain 225
 
1 www 226
        foreach($resources as $resourceName)
227
        {
228
            $this->acl->addResource(new GenericResource($resourceName));
229
        }
230
 
231
        $usertypes = getAclUsertype();
232
        foreach($usertypes as $usertype => $resources)
233
        {
234
            $this->acl->addRole(new GenericRole($usertype));
235
            foreach ($resources as $resourceName)
236
            {
237
                $this->acl->allow($usertype, $resourceName);
238
            }
239
        }
240
 
241
        $event->getViewModel()->setVariable('acl', $this->acl);
242
 
243
    }
244
 
245
    public function onDispatchError(MvcEvent $event)
246
    {
247
        $this->processError($event);
248
    }
249
 
250
    public function onRenderError(MvcEvent $event)
251
    {
252
        $this->processError($event);
253
    }
254
 
255
    public function sendResponse(\Laminas\Http\Response $response, $data)
256
    {
257
 
258
 
259
        if($this->isJson) {
260
            $headers = $response->getHeaders();
261
            $headers->clearHeaders();
262
            $headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
263
 
264
            $response->setStatusCode(200);
265
            $response->setContent(json_encode($data));
266
            $response->send();
267
 
268
 
269
            error_log(print_r($data, true));
270
 
271
        } else {
272
            throw new \Exception($data['data']);
273
        }
274
        exit;
275
    }
276
 
277
    public function processError(MvcEvent $event)
278
    {
279
 
280
        $request =  $event->getRequest();
281
        if((method_exists($request, 'isXmlHttpRequest') && $request->isXmlHttpRequest()) || ($this->isJson && !$this->isHtml)) {
282
 
283
            $error = $event->getError();
284
            if (!$error) {
285
                return;
286
            }
287
 
288
            $response = $event->getResponse();
289
 
290
            if('error-exception' == $error) {
291
                $exception = $event->getParam('exception');
292
                error_log($exception->getCode() . ' ' . $exception->getMessage());
293
                error_log($exception->getTraceAsString());
294
 
295
 
296
                $data = [
297
                    'success' => false,
298
                    'data' => 'An error occurred during execution; please try again later.'
299
                ];
300
 
301
            } else if('error-router-no-match' == $error) {
302
                $data = [
303
                    'success' => false,
304
                    'data' => 'Resource not found.'
305
 
306
                ];
307
            } else if(' error-controller-not-found' == $error) {
308
                $data = [
309
                    'success' => false,
310
                    'data' => 'Controller not found.'
311
 
312
                ];
313
            } else {
314
                $data = [
315
                    'success' => false,
316
                    'data' => 'Unknow error.' , 'error' => $error
317
 
318
                ];
319
            }
320
 
321
            $this->sendResponse($response, $data);
322
        }
323
 
324
        $this->initAcl($event);
325
    }
326
 
327
 
328
    public function authPreDispatch(MvcEvent $event)
329
    {
210 efrain 330
 
331
 
332
 
333
 
1 www 334
        $serviceManager = $event->getApplication()->getServiceManager();
335
        $adapter = $serviceManager->get('leaders-linked-db');
336
 
210 efrain 337
        $routeName = $event->getRouteMatch()->getMatchedRouteName();
338
 
1 www 339
 
210 efrain 340
        $requestMethod = isset($_SERVER['REQUEST_METHOD']) ? trim(strtoupper($_SERVER['REQUEST_METHOD'])) : '';
341
 
342
        if($requestMethod == 'POST' || $requestMethod == 'PUT' || $requestMethod == 'DELETE') {
343
 
1979 efrain 344
 
1323 efrain 345
            if($this->authByHeaders && substr($routeName, 0, 8) == 'services') {
346
                $exclude = true;
347
            } else {
348
                $exclude = false;
349
 
350
                $usertypes = getAclUsertype();
351
 
352
 
353
                foreach($usertypes[UserType::GUEST] as $resourceName)
354
                {
355
                   if($routeName == $resourceName) {
356
                      $exclude = true;
357
                      break;
358
                    }
210 efrain 359
                }
360
            }
1979 efrain 361
 
210 efrain 362
            if(!$exclude) {
363
                $httpToken = isset($_SERVER['HTTP_X_CSRF_TOKEN']) ? $_SERVER['HTTP_X_CSRF_TOKEN'] : '';
364
                $sessionToken = isset($_SESSION['token']) ? $_SESSION['token'] : uniqid();
365
 
366
                unset($_SESSION['token']);
367
                if ( $httpToken != $sessionToken) {
368
                    header("HTTP/1.1 401 Unauthorized");
369
                    exit;
370
                }
371
 
372
            }
373
        }
374
 
375
 
376
 
1 www 377
        if($this->currentUser->hasIdentity())  {
378
            $user = $this->currentUser->getUser();
379
            $userTypeId = $user->usertype_id;
380
 
381
 
382
        }  else {
383
 
384
            $userTypeId = UserType::GUEST;
385
        }
386
 
210 efrain 387
 
1 www 388
        if($this->acl->isAllowed($userTypeId, $routeName)) {
389
            $user = $this->currentUser->getUser();
210 efrain 390
 
1 www 391
 
392
            if($user) {
393
                $userMapper = UserMapper::getInstance($adapter);
394
                $userMapper->updateLastActivity($user->id);
395
            }
396
 
397
        } else {
210 efrain 398
 
1 www 399
            if($this->authByHeaders) {
400
                $response = $event->getResponse();
401
                $headers = $response->getHeaders();
402
                $headers->clearHeaders();
403
                $headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
404
 
405
                $response->setStatusCode(401);
406
                $response->setContent(json_encode(['success' => false, 'data' => 'Unauthorized.', 'fatal' => true]));
407
                $response->send();
408
                exit;
409
 
210 efrain 410
            }
1 www 411
 
412
 
413
            //print_r($this->routesAuthorized);
414
           // echo 'sin permiso'; exit;
415
 
416
 
417
            $this->currentUser->clearIdentity();
418
 
419
 
420
            if($this->isJson) {
421
                $response = $event->getResponse();
422
                $headers = $response->getHeaders();
423
                $headers->clearHeaders();
424
                $headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
425
 
426
                $response->setStatusCode(200);
427
                $response->setContent(json_encode(['success' => false, 'data' => 'Unauthorized.', 'fatal' => true]));
428
                $response->send();
429
            } else {
430
                $url = $event->getRouter()->assemble([], ['name' => 'signout']);
431
 
432
                $response = $event->getResponse();
433
                $headers = $response->getHeaders();
434
                $headers->clearHeaders();
435
                $headers->addHeaderLine('Location', $url);
436
 
437
                $response->setStatusCode(302);
438
                $response->send();
439
            }
440
            exit;
441
        }
442
 
443
 
444
    }
445
 
446
 
447
    public function authPosDispatch(MvcEvent $event)
448
    {
449
 
450
    }
451
 
452
 
453
}