Rev 210 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
<?php
declare(strict_types=1);
namespace LeadersLinked;
use Laminas\Db\Adapter\AdapterInterface;
use Laminas\Cache\Storage\Adapter\AbstractAdapter as CacheAdapter;
use Laminas\ModuleManager\ModuleEvent;
use Laminas\ModuleManager\ModuleManager;
use Laminas\Mvc\MvcEvent;
use Laminas\Config\Reader\Ini;
use Laminas\Permissions\Acl\Acl;
use Laminas\Permissions\Acl\Role\GenericRole;
use LeadersLinked\Plugin\CurrentUserPlugin;
use LeadersLinked\Model\Company;
use LeadersLinked\Mapper\UserMapper;
use LeadersLinked\Authentication\AuthTokenAdapter;
use Laminas\Authentication\AuthenticationService;
use Laminas\Permissions\Acl\Resource\GenericResource;
use LeadersLinked\Model\UserType;
class Module
{
/**
*
* @var boolean
*/
private $isJson;
/**
*
* @var boolean
*/
private $isHtml;
/**
*
* @var Acl
*/
private $acl;
/**
*
* @var Company
*/
private $company;
/**
*
* @var AdapterInterface
*/
private $adapter;
/**
*
* @var CacheAdapter
*/
private $cache;
/**
*
* @var CurrentUserPlugin
*/
private $currentUser;
/**
*
* @var array
*/
private $routesAuthorized = [];
/**
*
* @var boolean
*/
private $authByHeaders = false;
public function init(ModuleManager $moduleManager)
{
$events = $moduleManager->getEventManager();
$events->attach(ModuleEvent::EVENT_MERGE_CONFIG, array($this, 'onMergeConfig'));
}
public function onMergeConfig(ModuleEvent $event)
{
$configListener = $event->getConfigListener();
$config = $configListener->getMergedConfig(false);
$reader = new Ini();
$data = $reader->fromFile('config/leaderslinked.ini');
$prefix = 'leaderslinked';
foreach($data as $section => $pairs)
{
foreach($pairs as $key => $value)
{
$config[$prefix . '.' . $section . '.' . $key] = $value;
}
}
$configListener->setMergedConfig($config);
}
public function getConfig() : array
{
return include __DIR__ . '/../config/module.config.php';
}
public function onBootstrap(MvcEvent $event)
{
$serviceManager = $event->getApplication()->getServiceManager();
$adapter = $serviceManager->get('leaders-linked-db');
// $logger = $serviceManager->get('Zend\Log\Logger');
$session = $serviceManager->get('leaders-linked-session');
$session->start();
$translator = $serviceManager->get('MvcTranslator');
$translator->addTranslationFile(
'phpArray',
__DIR__ . '/i18n/validate.php',
'default'
);
$translator->addTranslationFile(
'phpArray',
__DIR__ . '/i18n/spanish.php',
'default'
);
\Laminas\Validator\AbstractValidator::setDefaultTranslator($translator);
$headers = $event->getRequest()->getHeaders();
if($headers->has('Accept')) {
$accept = $headers->get('Accept');
$prioritized = $accept->getPrioritized();
foreach($prioritized as $key => $value) {
$raw = trim($value->getRaw());
if(!$this->isJson) {
$this->isJson = strpos($raw, 'json');
}
}
} else {
$accept = '';
}
if($headers->has('token')) {
$device_uuid = filter_var($headers->get('token')->getFieldValue(), FILTER_SANITIZE_STRING);
} else {
$device_uuid = '';
}
if($headers->has('secret')) {
$password = filter_var($headers->get('secret')->getFieldValue(), FILTER_SANITIZE_STRING);
} else {
$password = '';
}
if($headers->has('rand')) {
$rand = filter_var($headers->get('rand')->getFieldValue(), FILTER_SANITIZE_NUMBER_INT);
} else {
$rand = 0;
}
if($headers->has('created')) {
$timestamp = filter_var($headers->get('created')->getFieldValue(), FILTER_SANITIZE_STRING);
} else {
$timestamp = 0;
}
$this->authByHeaders = false;
if($device_uuid && $password && $rand && $timestamp) {
$this->authByHeaders = true;
$this->isJson = true;
$tokenAuthAdapter = new AuthTokenAdapter($adapter);
$tokenAuthAdapter->setData($device_uuid, $password, $timestamp, $rand);
$authService = new AuthenticationService();
$result = $authService->authenticate($tokenAuthAdapter);
if($result->getCode() != \Laminas\Authentication\Result::SUCCESS) {
$response = $event->getResponse();
$this->sendResponse($response, ['success' => false, 'data' => $result->getMessages()[0], 'fatal' => true]);
}
}
$this->isHtml = $this->isJson ? false : true;
$this->currentUser = new CurrentUserPlugin($adapter);
$this->initAcl($event);
$eventManager = $event->getApplication()->getEventManager();
$eventManager->attach(MvcEvent::EVENT_DISPATCH_ERROR, [$this,'onDispatchError'], 0);
$eventManager->attach(MvcEvent::EVENT_RENDER_ERROR, [$this,'onRenderError'], 0);
$sharedManager = $eventManager->getSharedManager();
$sharedManager->attach(__NAMESPACE__, MvcEvent::EVENT_DISPATCH, [$this, 'authPreDispatch'], 100);
$sharedManager->attach(__NAMESPACE__, MvcEvent::EVENT_DISPATCH, [$this, 'authPosDispatch'], -100);
}
public function initAcl(MvcEvent $event)
{
require_once (dirname(__DIR__) . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'acl.config.php');
$this->acl = new Acl();
$resources = getAclResources();
foreach($resources as $resourceName)
{
$this->acl->addResource(new GenericResource($resourceName));
}
$usertypes = getAclUsertype();
foreach($usertypes as $usertype => $resources)
{
$this->acl->addRole(new GenericRole($usertype));
foreach ($resources as $resourceName)
{
$this->acl->allow($usertype, $resourceName);
}
}
$event->getViewModel()->setVariable('acl', $this->acl);
}
public function onDispatchError(MvcEvent $event)
{
$this->processError($event);
}
public function onRenderError(MvcEvent $event)
{
$this->processError($event);
}
public function sendResponse(\Laminas\Http\Response $response, $data)
{
if($this->isJson) {
$headers = $response->getHeaders();
$headers->clearHeaders();
$headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
$response->setStatusCode(200);
$response->setContent(json_encode($data));
$response->send();
error_log(print_r($data, true));
} else {
throw new \Exception($data['data']);
}
exit;
}
public function processError(MvcEvent $event)
{
$request = $event->getRequest();
if((method_exists($request, 'isXmlHttpRequest') && $request->isXmlHttpRequest()) || ($this->isJson && !$this->isHtml)) {
$error = $event->getError();
if (!$error) {
return;
}
$response = $event->getResponse();
if('error-exception' == $error) {
$exception = $event->getParam('exception');
error_log($exception->getCode() . ' ' . $exception->getMessage());
error_log($exception->getTraceAsString());
$data = [
'success' => false,
'data' => 'An error occurred during execution; please try again later.'
];
} else if('error-router-no-match' == $error) {
$data = [
'success' => false,
'data' => 'Resource not found.'
];
} else if(' error-controller-not-found' == $error) {
$data = [
'success' => false,
'data' => 'Controller not found.'
];
} else {
$data = [
'success' => false,
'data' => 'Unknow error.' , 'error' => $error
];
}
$this->sendResponse($response, $data);
}
$this->initAcl($event);
}
public function authPreDispatch(MvcEvent $event)
{
$serviceManager = $event->getApplication()->getServiceManager();
$adapter = $serviceManager->get('leaders-linked-db');
if($this->currentUser->hasIdentity()) {
$user = $this->currentUser->getUser();
$userTypeId = $user->usertype_id;
} else {
$userTypeId = UserType::GUEST;
}
$routeName = $event->getRouteMatch()->getMatchedRouteName();
if($this->acl->isAllowed($userTypeId, $routeName)) {
$user = $this->currentUser->getUser();
/*if($user && !in_array($routeName, ['check-session', 'dashboard'])) {
}*/
if($user) {
$userMapper = UserMapper::getInstance($adapter);
$userMapper->updateLastActivity($user->id);
}
} else {
/*
if($this->authByHeaders) {
$response = $event->getResponse();
$headers = $response->getHeaders();
$headers->clearHeaders();
$headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
$response->setStatusCode(401);
$response->setContent(json_encode(['success' => false, 'data' => 'Unauthorized.', 'fatal' => true]));
$response->send();
exit;
}*/
//print_r($this->routesAuthorized);
// echo 'sin permiso'; exit;
$this->currentUser->clearIdentity();
if($this->isJson) {
$response = $event->getResponse();
$headers = $response->getHeaders();
$headers->clearHeaders();
$headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
$response->setStatusCode(200);
$response->setContent(json_encode(['success' => false, 'data' => 'Unauthorized.', 'fatal' => true]));
$response->send();
} else {
$url = $event->getRouter()->assemble([], ['name' => 'signout']);
$response = $event->getResponse();
$headers = $response->getHeaders();
$headers->clearHeaders();
$headers->addHeaderLine('Location', $url);
$response->setStatusCode(302);
$response->send();
}
exit;
}
}
public function authPosDispatch(MvcEvent $event)
{
}
}