Rev 7359 | 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\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\Mapper\UserMapper;
use LeadersLinked\Authentication\AuthTokenAdapter;
use Laminas\Authentication\AuthenticationService;
use Laminas\Permissions\Acl\Resource\GenericResource;
use LeadersLinked\Model\UserType;
use LeadersLinked\Plugin\CurrentNetworkPlugin;
use LeadersLinked\Model\Network;
use LeadersLinked\Model\User;
use LeadersLinked\Mapper\CompanyUserMapper;
use LeadersLinked\Model\CompanyUser;
use LeadersLinked\Mapper\CompanyMapper;
use LeadersLinked\Mapper\CompanyServiceMapper;
use LeadersLinked\Model\Service;
use LeadersLinked\Library\Functions;
use LeadersLinked\Mapper\DailyPulseMapper;
use LeadersLinked\Model\DailyPulse;
use LeadersLinked\Mapper\OrganizationPositionMapper;
use LeadersLinked\Mapper\KnowledgeAreaCategoryJobDescriptionMapper;
use LeadersLinked\Mapper\MyCoachCategoryJobDescriptionMapper;
use LeadersLinked\Mapper\KnowledgeAreaCategoryUserMapper;
use LeadersLinked\Mapper\MyCoachCategoryUserMapper;
class Module
{
/**
*
* @var boolean
*/
private $isJson;
/**
*
* @var boolean
*/
private $isHtml;
/**
*
* @var Acl
*/
private $acl;
/**
*
* @var AdapterInterface
*/
private $adapter;
/**
*
* @var CurrentUserPlugin
*/
private $currentUserPlugin;
/**
*
* @var CurrentNetworkPlugin
*/
private $currentNetworkPlugin;
/**
*
* @var array
*/
private $routesAuthorized = [];
/**
*
* @var boolean
*/
private $authByHeaders = false;
/**
*
* @var array
*/
private $config;
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();
$this->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)
{
$this->config[$prefix . '.' . $section . '.' . $key] = $value;
}
}
$configListener->setMergedConfig($this->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 = Functions::sanitizeFilterString($headers->get('token')->getFieldValue());
} else {
$device_uuid = '';
}
if($headers->has('secret')) {
$password = Functions::sanitizeFilterString($headers->get('secret')->getFieldValue());
} else {
$password = '';
}
if($headers->has('rand')) {
$rand = Functions::sanitizeFilterString($headers->get('rand')->getFieldValue());
} else {
$rand = 0;
}
if($headers->has('created')) {
$timestamp = Functions::sanitizeFilterString($headers->get('created')->getFieldValue());
} else {
$timestamp = 0;
}
$this->currentNetworkPlugin = new CurrentNetworkPlugin($adapter);
if(!$this->currentNetworkPlugin->hasNetwork()) {
$this->isJson = true;
$response = $event->getResponse();
$this->sendResponse($response, ['success' => false, 'data' => '401 Unauthorized - Private network - not found', 'fatal' => true]);
}
if($this->currentNetworkPlugin->getNetwork()->status == Network::STATUS_INACTIVE) {
$this->isJson = true;
$response = $event->getResponse();
$this->sendResponse($response, ['success' => false, 'data' => '401 Unauthorized - Private network - inactive', 'fatal' => true]);
}
$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]);
}
}
if(empty($_SERVER['REDIRECT_URL'])) {
if(empty($_SERVER['REQUEST_URI'])) {
$routeName = '';
} else {
$routeName = $_SERVER['REQUEST_URI'];
}
} else {
$routeName = $_SERVER['REDIRECT_URL'];
}
$routeName = strtolower(trim($routeName));
if(strlen($routeName) > 0 && substr($routeName, 0, 1) == '/') {
$routeName = substr($routeName, 1);
}
$this->isHtml = $this->isJson ? false : true;
$this->currentUserPlugin = new CurrentUserPlugin($adapter);
if($this->authByHeaders && substr($routeName, 0, 8) == 'services') {
$checkUserForNetwork = false;
} else {
if($this->currentUserPlugin->hasIdentity()) {
$checkUserForNetwork = true;
} else {
$checkUserForNetwork = false;
}
}
if($checkUserForNetwork) {
if(!$routeName || in_array($routeName, ['signout', 'signin', 'home'])) {
$checkUserForNetwork = false;
}
}
if($checkUserForNetwork) {
if($this->currentUserPlugin->getUser()->network_id != $this->currentNetworkPlugin->getNetworkId()) {
$this->isJson = true;
$response = $event->getResponse();
$this->sendResponse($response, ['success' => false, 'data' => '401 Unauthorized - The user is not part of this private network', 'fatal' => true]);
}
}
/*
$application = $event->getApplication();
$templateMapResolver = $application->getServiceManager()->get(
'ViewTemplateMapResolver'
);
$listener = new LayoutListener($templateMapResolver);
$listener->attach($application->getEventManager());*/
$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)
{
$serviceManager = $event->getApplication()->getServiceManager();
$adapter = $serviceManager->get('leaders-linked-db');
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);
}
}
if($this->currentUserPlugin->hasIdentity() && $this->currentUserPlugin->getUser()->is_super_user == User::IS_SUPER_USER_YES) {
$resources = getAclSuperAdmin();
foreach($resources as $resourceName)
{
$this->acl->allow(UserType::ADMIN, $resourceName);
}
}
$allowMyCoach = false;
$allowKnowledgeArea = false;
$allowDailyPulse = false;
$companyMapper = CompanyMapper::getInstance($adapter);
$company = $companyMapper->fetchDefaultForNetworkByNetworkId($this->currentNetworkPlugin->getNetwork()->id);
if($company) {
$companyServiceMapper = CompanyServiceMapper::getInstance($adapter);
$companyService = $companyServiceMapper->fetchOneActiveByCompanyIdAndServiceId($company->id, Service::DAILY_PULSE);
$companyUserMapper = CompanyUserMapper::getInstance($adapter);
$companyUser = $companyUserMapper->fetchOneAcceptedByCompanyIdAndUserId($company->id, $this->currentUserPlugin->getUserId());
if($companyService) {
$dailyPulseMapper = DailyPulseMapper::getInstance($adapter);
$dailyPulse = $dailyPulseMapper->fetchOneByCompanyId($company->id);
if($dailyPulse) {
$privacy = $dailyPulse->privacy;
} else {
$privacy = DailyPulse::PRIVACY_COMPANY;
}
if($privacy == DailyPulse::PRIVACY_PUBLIC) {
$allowDailyPulse = true;
} else {
$allowDailyPulse = !empty($companyUser);
}
}
$job_description_ids = [];
$organizationPositionMapper = OrganizationPositionMapper::getInstance($adapter);
$records = $organizationPositionMapper->fetchAllByCompanyIdAndEmployeeId($company->id, $this->currentUserPlugin->getUserId());
foreach($records as $record)
{
array_push($job_description_ids, $record->job_description_id);
}
$companyService = $companyServiceMapper->fetchOneActiveByCompanyIdAndServiceId($company->id, Service::KNOWLEDGE_AREA);
if($companyService) {
if($job_description_ids) {
$knowledgeAreaCategoryJobDescriptionMapper = KnowledgeAreaCategoryJobDescriptionMapper::getInstance($adapter);
$records = $knowledgeAreaCategoryJobDescriptionMapper->fetchAllByCompanyIdAndJobDescriptionIds($company->id, $job_description_ids);
if(!empty($records)) {
$allowKnowledgeArea = true;
}
}
if($companyUser && !$allowKnowledgeArea) {
$knowledgeAreaCategoryUserMapper = KnowledgeAreaCategoryUserMapper::getInstance($adapter);
$records = $knowledgeAreaCategoryUserMapper->fetchAllByUserId($companyUser->user_id);
if(!empty($records)) {
$allowKnowledgeArea = true;
}
}
}
$companyService = $companyServiceMapper->fetchOneActiveByCompanyIdAndServiceId($company->id, Service::MY_COACH);
if($companyService) {
if($job_description_ids) {
$myCoachCategoryJobDescriptionMapper = MyCoachCategoryJobDescriptionMapper::getInstance($adapter);
$records = $myCoachCategoryJobDescriptionMapper->fetchAllByCompanyIdAndJobDescriptionIds($company->id, $job_description_ids);
if(!empty($records)) {
$allowKnowledgeArea = true;
}
}
if($companyUser && !$allowMyCoach) {
$myCoachCategoryUserMapper = MyCoachCategoryUserMapper::getInstance($adapter);
$records = $myCoachCategoryUserMapper->fetchAllByUserId($companyUser->user_id);
if(!empty($records)) {
$allowMyCoach = true;
}
}
}
} else {
$companyUser = '';
}
$usertype = $this->currentUserPlugin->getUserTypeId();
if($allowDailyPulse) {
$resources = getAclDailyPulse();
foreach($resources as $resourceName)
{
$this->acl->allow($usertype, $resourceName);
}
}
if($allowKnowledgeArea) {
$resources = getAclKnowledgeArea();
foreach($resources as $resourceName)
{
$this->acl->allow($usertype, $resourceName);
}
}
if($allowMyCoach) {
$resources = getAclMyCoach();
foreach($resources as $resourceName)
{
$this->acl->allow($usertype, $resourceName);
}
}
if($this->currentNetworkPlugin->getNetwork()->default == Network::DEFAULT_YES) {
$usertypes = getAclUsertypeDefaultNetwork();
foreach($usertypes as $usertype => $resources)
{
foreach ($resources as $resourceName)
{
$this->acl->allow($usertype, $resourceName);
}
}
} else {
if($this->currentUserPlugin->hasIdentity()) {
if($company) {
if($companyUser) {
$usertype = $this->currentUserPlugin->getUserTypeId();
if($companyUser->creator == CompanyUser::CREATOR_YES) {
$resources = getAclUsertypeOtherNetworkCreator();
foreach($resources as $resourceName)
{
$this->acl->allow($usertype, $resourceName);
}
}
if($companyUser->creator == CompanyUser::CREATOR_NO) {
$resources = getAclUsertypeOtherNetworkNonCreator();
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)
{
/*
$headers = $response->getHeaders();
$headers->clearHeaders();
$headers->addHeaderLine('Content-type', 'application/json; charset=UTF-8');
$response->setStatusCode(200);
$response->setContent(json_encode($data));
$response->send();
/*
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();
} else {
throw new \Exception($data['data']);
}*/
//exit;
}
public function processError(MvcEvent $event)
{
$request = $event->getRequest();
$response = $event->getResponse();
$headers = $response->getHeaders();
$headers->clearHeaders();
$response->setStatusCode(404);
$response->send();
//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);
$this->authPreDispatch($event);
}
public function authPreDispatch(MvcEvent $event)
{
$serviceManager = $event->getApplication()->getServiceManager();
$adapter = $serviceManager->get('leaders-linked-db');
$routeName = $event->getRouteMatch()->getMatchedRouteName();
$requestMethod = isset($_SERVER['REQUEST_METHOD']) ? trim(strtoupper($_SERVER['REQUEST_METHOD'])) : '';
if($requestMethod == 'POST' || $requestMethod == 'PUT' || $requestMethod == 'DELETE') {
if($this->authByHeaders && substr($routeName, 0, 8) == 'services') {
$exclude = true;
} else {
$exclude = false;
$usertypes = getAclUsertype();
foreach($usertypes[UserType::GUEST] as $resourceName)
{
if($routeName == $resourceName) {
$exclude = true;
break;
}
}
}
$exclude = true;
if(!$exclude) {
$httpToken = isset($_SERVER['HTTP_X_CSRF_TOKEN']) ? $_SERVER['HTTP_X_CSRF_TOKEN'] : '';
$sessionToken = isset($_SESSION['token']) ? $_SESSION['token'] : uniqid();
unset($_SESSION['token']);
if ( $httpToken != $sessionToken) {
header("HTTP/1.1 401 Unauthorized");
exit;
}
}
}
if($this->currentUserPlugin->hasIdentity()) {
$user = $this->currentUserPlugin->getUser();
$userTypeId = $user->usertype_id;
} else {
$userTypeId = UserType::GUEST;
}
if($this->acl->isAllowed($userTypeId, $routeName)) {
$user = $this->currentUserPlugin->getUser();
if($user) {
$updateLastActivity = true;
if ('chat' == substr($routeName, 0, 4)) {
$updateLastActivity = false;
}
if ('inmail' == substr($routeName, 0, 6)) {
$updateLastActivity = false;
}
if ('check-session' == $routeName) {
$updateLastActivity = false;
}
if($updateLastActivity) {
$userMapper = UserMapper::getInstance($adapter);
$userMapper->updateLastActivity($user->id);
}
}
} else {
if($this->authByHeaders || $this->isJson) {
$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;
}
$response = $event->getResponse();
$headers = $response->getHeaders();
$headers->clearHeaders();
$response->setStatusCode(401);
$response->send();
exit;
//print_r($this->routesAuthorized);
// echo 'sin permiso'; exit;
/*
$this->currentUserPlugin->clearIdentity();
// if() {
$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();
}*/
}
}
public function authPosDispatch(MvcEvent $event)
{
/// if($this->isHtml) {
/*if(empty($_SERVER['REDIRECT_URL'])) {
if(empty($_SERVER['REQUEST_URI'])) {
$routeName = '';
} else {
$routeName = $_SERVER['REQUEST_URI'];
}
} else {
$routeName = $_SERVER['REDIRECT_URL'];
}
$routeName = strtolower(trim($routeName));
if(strlen($routeName) > 0 && substr($routeName, 0, 1) == '/') {
$routeName = substr($routeName, 1);
}
$exclude = [
'home',
'oauth/facebook',
'oauth/facebook/cancel',
'oauth/facebook/delete',
'oauth/twitter',
'oauth/google',
'oauth/instagram',
'paypal',
'paypal/success',
'paypal/cancel',
'storage',
'storage-network',
'signout'
];
if(!in_array($routeName, $exclude)) {
$event->getViewModel()->setVariables([
]);
}*/
$event->getViewModel()->setTemplate('layout/layout');
/// }
}
}