From 31779451464bd2c8bb06c0fe755ce5efbffdb047 Mon Sep 17 00:00:00 2001 From: yuri Date: Tue, 5 Jan 2016 11:49:14 +0200 Subject: [PATCH] portal auth --- application/Espo/Core/Application.php | 13 +-- application/Espo/Core/ApplicationPortal.php | 8 -- application/Espo/Core/Container.php | 5 +- application/Espo/Core/EntryPointManager.php | 9 ++ application/Espo/Core/EntryPoints/Base.php | 2 + application/Espo/Core/Utils/Auth.php | 75 ++++++++++++++- application/Espo/Core/Utils/AuthPortal.php | 95 ------------------- .../Resources/metadata/app/aclPortal.json | 7 +- 8 files changed, 93 insertions(+), 121 deletions(-) delete mode 100644 application/Espo/Core/Utils/AuthPortal.php diff --git a/application/Espo/Core/Application.php b/application/Espo/Core/Application.php index b18d795644..e73b069791 100644 --- a/application/Espo/Core/Application.php +++ b/application/Espo/Core/Application.php @@ -71,12 +71,9 @@ class Application return $this->metadata; } - protected function getAuth() + protected function createAuth() { - if (empty($this->auth)) { - $this->auth = new \Espo\Core\Utils\Auth($this->container); - } - return $this->auth; + return new \Espo\Core\Utils\Auth($this->container); } public function getContainer() @@ -111,7 +108,7 @@ class Application $entryPointManager = new \Espo\Core\EntryPointManager($container); try { - $auth = $this->getAuth(); + $auth = new \Espo\Core\Utils\Auth($this->container, $entryPointManager->checkAllowPortal($entryPoint)); $apiAuth = new \Espo\Core\Utils\Api\Auth($auth, $entryPointManager->checkAuthRequired($entryPoint), true); $slim->add($apiAuth); @@ -127,7 +124,7 @@ class Application public function runCron() { - $auth = $this->getAuth(); + $auth = $this->createAuth(); $auth->useNoAuth(true); $cronManager = new \Espo\Core\CronManager($this->container); @@ -168,7 +165,7 @@ class Application $slim = $this->getSlim(); try { - $auth = $this->getAuth(); + $auth = $this->createAuth(); } catch (\Exception $e) { $container->get('output')->processError($e->getMessage(), $e->getCode()); } diff --git a/application/Espo/Core/ApplicationPortal.php b/application/Espo/Core/ApplicationPortal.php index 35bd6328d4..97cb2120a3 100644 --- a/application/Espo/Core/ApplicationPortal.php +++ b/application/Espo/Core/ApplicationPortal.php @@ -62,14 +62,6 @@ class ApplicationPortal extends Application $this->initAutoloads(); } - protected function getAuth() - { - if (empty($this->auth)) { - $this->auth = new \Espo\Core\Utils\AuthPortal($this->getContainer()); - } - return $this->auth; - } - protected function getPortal() { return $this->portal; diff --git a/application/Espo/Core/Container.php b/application/Espo/Core/Container.php index c22e0957a9..31895283dd 100644 --- a/application/Espo/Core/Container.php +++ b/application/Espo/Core/Container.php @@ -47,7 +47,10 @@ class Container if (empty($this->data[$name])) { $this->load($name); } - return $this->data[$name]; + if (isset($this->data[$name])) { + return $this->data[$name]; + } + return null; } protected function set($name, $obj) diff --git a/application/Espo/Core/EntryPointManager.php b/application/Espo/Core/EntryPointManager.php index 050da070ca..9a23604fa8 100644 --- a/application/Espo/Core/EntryPointManager.php +++ b/application/Espo/Core/EntryPointManager.php @@ -81,6 +81,15 @@ class EntryPointManager return $className::$authRequired; } + public function checkAllowPortal($name) + { + $className = $this->getClassName($name); + if (!$className) { + throw new NotFound(); + } + return $className::$allowPortal; + } + public function run($name) { $className = $this->getClassName($name); diff --git a/application/Espo/Core/EntryPoints/Base.php b/application/Espo/Core/EntryPoints/Base.php index a3002cbc72..1c473a444f 100644 --- a/application/Espo/Core/EntryPoints/Base.php +++ b/application/Espo/Core/EntryPoints/Base.php @@ -39,6 +39,8 @@ abstract class Base public static $authRequired = true; + public static $allowPortal = true; + protected function getContainer() { return $this->container; diff --git a/application/Espo/Core/Utils/Auth.php b/application/Espo/Core/Utils/Auth.php index be1918876d..f6db73b0ca 100644 --- a/application/Espo/Core/Utils/Auth.php +++ b/application/Espo/Core/Utils/Auth.php @@ -32,16 +32,30 @@ namespace Espo\Core\Utils; use \Espo\Core\Exceptions\Error; use \Espo\Core\Exceptions\Forbidden; +use \Espo\Entities\Portal; + class Auth { protected $container; protected $authentication; - public function __construct(\Espo\Core\Container $container) + protected $allowAnyAccess; + + const ACCESS_CRM_ONLY = 0; + + const ACCESS_PORTAL_ONLY = 1; + + const ACCESS_ANY = 3; + + private $portal; + + public function __construct(\Espo\Core\Container $container, $allowAnyAccess = false) { $this->container = $container; + $this->allowAnyAccess = $allowAnyAccess; + $authenticationMethod = $this->getConfig()->get('authenticationMethod', 'Espo'); $authenticationClassName = "\\Espo\\Core\\Utils\\Authentication\\" . $authenticationMethod; $this->authentication = new $authenticationClassName($this->getConfig(), $this->getEntityManager(), $this); @@ -54,6 +68,27 @@ class Auth return $this->container; } + protected function setPortal(Portal $portal) + { + $this->portal = $portal; + } + + protected function isPortal() + { + if ($this->portal) { + return true; + } + return !!$this->getContainer()->get('portal'); + } + + protected function getPortal() + { + if ($this->portal) { + return $this->portal; + } + return $this->getContainer()->get('portal'); + } + protected function getConfig() { return $this->getContainer()->get('config'); @@ -79,11 +114,31 @@ class Auth $this->getContainer()->setUser($user); } - public function login($username, $password) { $authToken = $this->getEntityManager()->getRepository('AuthToken')->where(array('token' => $password))->findOne(); + if ($authToken) { + if (!$this->allowAnyAccess) { + if ($this->isPortal() && $authToken->get('portalId') !== $this->getPortal()->id) { + $GLOBALS['log']->debug("AUTH: Trying to login to portal with a token not related to portal."); + return false; + } + if (!$this->isPortal() && $authToken->get('portalId')) { + $GLOBALS['log']->debug("AUTH: Trying to login to crm with a token related to portal."); + return false; + } + } + if ($this->allowAnyAccess) { + if ($authToken->get('portalId') && !$this->isPortal()) { + $portal = $this->getEntityManager()->getEntity('Portal', $authToken->get('portalId')); + if ($portal) { + $this->setPortal($portal); + } + } + } + } + $user = $this->authentication->login($username, $password, $authToken); if ($user) { @@ -91,10 +146,21 @@ class Auth $GLOBALS['log']->debug("AUTH: Trying to login as user '".$user->get('userName')."' which is not active."); return false; } - if (!$user->isAdmin() && $user->get('isPortalUser')) { + + if (!$user->isAdmin() && !$this->isPortal() && $user->get('isPortalUser')) { $GLOBALS['log']->debug("AUTH: Trying to login to crm as a portal user '".$user->get('userName')."'."); return false; } + + if (!$user->isAdmin() && $this->isPortal() && !$user->get('isPortalUser')) { + $GLOBALS['log']->debug("AUTH: Trying to login to portal as user '".$user->get('userName')."' which is not portal user."); + return false; + } + + if ($this->isPortal()) { + $user->set('portalId', $this->getPortal()->id); + } + $this->getEntityManager()->setUser($user); $this->getContainer()->setUser($user); @@ -106,6 +172,9 @@ class Auth $authToken->set('hash', $user->get('password')); $authToken->set('ipAddress', $_SERVER['REMOTE_ADDR']); $authToken->set('userId', $user->id); + if ($this->isPortal()) { + $authToken->set('portalId', $this->getPortal()->id); + } } $authToken->set('lastAccess', date('Y-m-d H:i:s')); diff --git a/application/Espo/Core/Utils/AuthPortal.php b/application/Espo/Core/Utils/AuthPortal.php deleted file mode 100644 index 4cccbe5703..0000000000 --- a/application/Espo/Core/Utils/AuthPortal.php +++ /dev/null @@ -1,95 +0,0 @@ -getContainer()->get('portal'); - } - - public function login($username, $password) - { - $authToken = $this->getEntityManager()->getRepository('AuthToken')->where(array('token' => $password))->findOne(); - - if ($authToken) { - if ($authToken->get('portalId') !== $this->getPortal()->id) { - $GLOBALS['log']->debug("AUTH: Trying to login to portal with a token not related to portal."); - return false; - } - } - - $user = $this->authentication->login($username, $password, $authToken); - - if ($user) { - if (!$user->isActive()) { - $GLOBALS['log']->debug("AUTH: Trying to login to portal as user '".$user->get('userName')."' which is not active."); - return false; - } - if (!$user->isAdmin() && !$this->getEntityManager()->getRepository('Portal')->isRelated($this->getPortal(), 'users', $user)) { - $GLOBALS['log']->debug("AUTH: Trying to login to portal as user '".$user->get('userName')."' which is not related to portal."); - return false; - } - - if (!$user->isAdmin() && !$user->get('isPortalUser')) { - $GLOBALS['log']->debug("AUTH: Trying to login to portal as user '".$user->get('userName')."' which is not portal user."); - return false; - } - - $user->set('portalId', $this->getPortal()->id); - $this->getEntityManager()->setUser($user); - $this->getContainer()->setUser($user); - - if ($this->request->headers->get('HTTP_ESPO_AUTHORIZATION')) { - if (!$authToken) { - $authToken = $this->getEntityManager()->getEntity('AuthToken'); - $token = $this->createToken($user); - $authToken->set('token', $token); - $authToken->set('hash', $user->get('password')); - $authToken->set('ipAddress', $_SERVER['REMOTE_ADDR']); - $authToken->set('userId', $user->id); - $authToken->set('portalId', $this->getPortal()->id); - } - $authToken->set('lastAccess', date('Y-m-d H:i:s')); - - $this->getEntityManager()->saveEntity($authToken); - $user->set('token', $authToken->get('token')); - } - - return true; - } - } - -} - diff --git a/application/Espo/Resources/metadata/app/aclPortal.json b/application/Espo/Resources/metadata/app/aclPortal.json index dc6c83c599..6b1f463692 100644 --- a/application/Espo/Resources/metadata/app/aclPortal.json +++ b/application/Espo/Resources/metadata/app/aclPortal.json @@ -49,11 +49,6 @@ }, "scopeLevelTypesDefaults": { "boolean": false, - "record": { - "read": "no", - "stream": "no", - "edit": "no", - "delete": "no" - } + "record": false } }