diff --git a/api/.htaccess b/api/v1/.htaccess similarity index 100% rename from api/.htaccess rename to api/v1/.htaccess diff --git a/api/index.php b/api/v1/index.php similarity index 60% rename from api/index.php rename to api/v1/index.php index b5a893c088..bb4870ec9b 100644 --- a/api/index.php +++ b/api/v1/index.php @@ -1,11 +1,7 @@ run(); - -?> \ No newline at end of file diff --git a/application/Espo/Core/Application.php b/application/Espo/Core/Application.php index 4691e48c9c..9a11884f2e 100644 --- a/application/Espo/Core/Application.php +++ b/application/Espo/Core/Application.php @@ -10,6 +10,8 @@ class Application private $container; private $slim; + + private $auth; /** * Constructor @@ -23,23 +25,32 @@ class Application set_error_handler(array($this->getLog(), 'catchError'), E_ALL); set_exception_handler(array($this->getLog(), 'catchException')); - date_default_timezone_set('UTC'); - - $this->slim = $this->container->get('slim'); - $this->metadata = $this->container->get('metadata'); - - $this->initMetadata(); + date_default_timezone_set('UTC'); } public function getSlim() { + if (empty($this->slim)) { + $this->slim = $this->container->get('slim'); + } return $this->slim; } public function getMetadata() { + if (empty($this->metadata)) { + $this->metadata = $this->container->get('metadata'); + } return $this->metadata; } + + protected function getAuth() + { + if (empty($this->auth)) { + $this->auth = new \Espo\Core\Utils\Auth($this->container); + } + return $this->auth; + } public function getContainer() { @@ -57,22 +68,44 @@ class Application $this->initRoutes(); $this->getSlim()->run(); } - - - protected function initMetadata() - { - $isNotCached = !$this->getMetadata()->isCached(); - - $this->getMetadata()->init($isNotCached); - } - + + public function runEntryPoint($entryPoint) + { + if (empty($entryPoint)) { + throw new \Error(); + } + + $slim = $this->getSlim(); + $container = $this->getContainer(); + + $slim->get('/', function() {}); + + $entryPointManager = new \Espo\Core\EntryPointManager($container); + + $auth = $this->getAuth(); + $apiAuth = new \Espo\Core\Utils\Api\Auth($auth, $entryPointManager->checkAuthRequired($entryPoint), true); + $slim->add($apiAuth); + + $slim->hook('slim.before.dispatch', function () use ($entryPoint, $entryPointManager, $container) { + try { + $entryPointManager->run($entryPoint); + } catch (\Exception $e) { + $container->get('output')->processError($e->getMessage(), $e->getCode()); + } + }); + + $slim->run(); + } + protected function routeHooks() { $container = $this->getContainer(); $slim = $this->getSlim(); - - $auth = new \Espo\Core\Utils\Api\Auth($container->get('entityManager'), $container); - $this->getSlim()->add($auth); + + $auth = $this->getAuth(); + + $apiAuth = new \Espo\Core\Utils\Api\Auth($auth); + $this->getSlim()->add($apiAuth); $this->getSlim()->hook('slim.before.dispatch', function () use ($slim, $container) { @@ -119,7 +152,6 @@ class Application } catch (\Exception $e) { $container->get('output')->processError($e->getMessage(), $e->getCode()); } - }); $this->getSlim()->hook('slim.after.router', function () use (&$slim) { @@ -150,6 +182,5 @@ class Application } } } - } diff --git a/application/Espo/Core/Container.php b/application/Espo/Core/Container.php index 44e73bac53..a139fa2eab 100644 --- a/application/Espo/Core/Container.php +++ b/application/Espo/Core/Container.php @@ -87,13 +87,6 @@ class Container ); } - private function loadEntryPointManager() - { - return new \Espo\Core\EntryPointManager( - $this - ); - } - private function loadLog() { return new \Espo\Core\Utils\Log( diff --git a/application/Espo/Core/EntryPointManager.php b/application/Espo/Core/EntryPointManager.php index 776f9923d6..56964fb643 100644 --- a/application/Espo/Core/EntryPointManager.php +++ b/application/Espo/Core/EntryPointManager.php @@ -9,6 +9,7 @@ use \Espo\Core\Exceptions\NotFound, class EntryPointManager { private $container; + private $fileManager; protected $data = null; @@ -33,26 +34,33 @@ class EntryPointManager private $customPaths = array( 'corePath' => 'application/Espo/Custom/EntryPoints', 'modulePath' => 'application/Espo/Custom/Modules/{*}/EntryPoints', - ); - + ); public function __construct(\Espo\Core\Container $container) { $this->container = $container; - $this->fileManager = $this->getContainer()->get('fileManager'); + $this->fileManager = $container->get('fileManager'); } protected function getContainer() { return $this->container; - } + } protected function getFileManager() { return $this->fileManager; } + public function checkAuthRequired($name) + { + $className = $this->get($name); + if ($className === false) { + throw new NotFound(); + } + return $className::$authRequired; + } public function run($name) { @@ -60,14 +68,12 @@ class EntryPointManager if ($className === false) { throw new NotFound(); } - $entryPoint = new $className($this->container); $entryPoint->run(); } - - public function get($name = '') + protected function get($name = '') { if (!isset($this->data)) { $this->init(); @@ -86,12 +92,11 @@ class EntryPointManager } - public function getAll() + protected function getAll() { return $this->get(); } - protected function init() { if (file_exists($this->cacheFile) && $this->getContainer()->get('config')->get('useCache')) { @@ -142,12 +147,7 @@ class EntryPointManager } return $entryPoints; - } + } +} - - - - - -} \ No newline at end of file diff --git a/application/Espo/Core/EntryPoints/Base.php b/application/Espo/Core/EntryPoints/Base.php index cac1414282..ad36526b36 100644 --- a/application/Espo/Core/EntryPoints/Base.php +++ b/application/Espo/Core/EntryPoints/Base.php @@ -10,7 +10,7 @@ abstract class Base { private $container; - protected $authRequired = true; + public static $authRequired = true; protected function getContainer() { @@ -29,12 +29,12 @@ abstract class Base protected function getEntityManager() { - $this->getContainer()->get('entityManager'); + return $this->getContainer()->get('entityManager'); } protected function getServiceFactory() { - $this->getContainer()->get('serviceFactory'); + return $this->getContainer()->get('serviceFactory'); } protected function getConfig() @@ -45,22 +45,11 @@ abstract class Base protected function getMetadata() { return $this->getContainer()->get('metadata'); - } - - protected function checkAccess() - { - if ($this->authRequired) { - return $this->getUser()->isFetched(); - } - return false; - } + } public function __construct(Container $container) { $this->container = $container; - if (!$this->checkAccess()) { - throw new Forbidden(); - } } abstract public function run(); diff --git a/application/Espo/Core/Utils/Api/Auth.php b/application/Espo/Core/Utils/Api/Auth.php index 2ae9889c64..962d73639b 100644 --- a/application/Espo/Core/Utils/Api/Auth.php +++ b/application/Espo/Core/Utils/Api/Auth.php @@ -6,34 +6,41 @@ use \Espo\Core\Utils\Api\Slim; class Auth extends \Slim\Middleware { - private $entityManager; + protected $auth; - private $container; + protected $authRequired = null; + + protected $showDialog = false; - public function __construct(\Espo\Core\ORM\EntityManager $entityManager, \Espo\Core\Container $container) + public function __construct(\Espo\Core\Utils\Auth $auth, $authRequired = null, $showDialog = false) { - $this->entityManager = $entityManager; - $this->container = $container; - } + $this->auth = $auth; + $this->authRequired = $authRequired; + $this->showDialog = $showDialog; + } function call() { - $req = $this->app->request(); - $res = $this->app->response(); + $req = $this->app->request(); $uri = $req->getResourceUri(); $httpMethod = $req->getMethod(); - /** - * Check if user credentials are required for current route - */ - $routes = $this->app->router()->getMatchedRoutes($httpMethod, $uri); + if (is_null($this->authRequired)) { + $routes = $this->app->router()->getMatchedRoutes($httpMethod, $uri); - if (!empty($routes[0])) { - $routeConditions = $routes[0]->getConditions(); - if (isset($routeConditions['auth']) && $routeConditions['auth'] === false) { - $this->container->setUser($this->entityManager->getEntity('User')); - $this->next->call(); + if (!empty($routes[0])) { + $routeConditions = $routes[0]->getConditions(); + if (isset($routeConditions['auth']) && $routeConditions['auth'] === false) { + $this->auth->useNoAuth(); + $this->next->call(); + return; + } + } + } else { + if (!$this->authRequired) { + $this->auth->useNoAuth(); + $this->next->call(); return; } } @@ -41,39 +48,34 @@ class Auth extends \Slim\Middleware $authKey = $req->headers('PHP_AUTH_USER'); $authSec = $req->headers('PHP_AUTH_PW'); - $GLOBALS['log']->add('DEBUG', 'AUTH: Try to authenticate'); - if ($authKey && $authSec) { $isAuthenticated = false; $username = $authKey; $password = $authSec; - - $user = $this->entityManager->getRepository('User')->findOne(array( - 'whereClause' => array( - 'userName' => $username, - 'password' => md5($password) - ), - )); - - - if ($user instanceof \Espo\Entities\User) { - $this->entityManager->setUser($user); - $this->container->setUser($user); - $isAuthenticated = true; - } - - $GLOBALS['log']->add('DEBUG', 'AUTH: Result of authenticate =['.$isAuthenticated.']'); + + $isAuthenticated = $this->auth->login($username, $password); if ($isAuthenticated) { $this->next->call(); } else { - $res->header('WWW-Authenticate'); - $res->status(401); + $this->processUnauthorized(); } } else { - $res->header('WWW-Authenticate'); - $res->status(401); + $this->processUnauthorized(); } } + + protected function processUnauthorized() + { + $res = $this->app->response(); + + if ($this->showDialog) { + $res->header('WWW-Authenticate', sprintf('Basic realm="%s"', '')); + } else { + $res->header('WWW-Authenticate'); + } + $res->status(401); + } } + diff --git a/application/Espo/Core/Utils/Api/Output.php b/application/Espo/Core/Utils/Api/Output.php index 367cca8499..34409bf501 100644 --- a/application/Espo/Core/Utils/Api/Output.php +++ b/application/Espo/Core/Utils/Api/Output.php @@ -31,7 +31,6 @@ class Output ob_clean(); echo $data; - //$this->getSlim()->stop(); } public function processError($message = 'Error', $code = 500) @@ -56,7 +55,7 @@ class Output { $GLOBALS['log']->add('INFO', 'Display Error: '.$text.', Code: '.$statusCode.' URL: '.$_SERVER['REQUEST_URI']); - if ( !empty( $this->slim) ) { + if (!empty( $this->slim)) { $this->getSlim()->response()->status($statusCode); $this->getSlim()->response()->header('X-Status-Reason', $text); $this->getSlim()->stop(); @@ -69,4 +68,3 @@ class Output } -?> diff --git a/application/Espo/Core/Utils/Auth.php b/application/Espo/Core/Utils/Auth.php new file mode 100644 index 0000000000..fea1700005 --- /dev/null +++ b/application/Espo/Core/Utils/Auth.php @@ -0,0 +1,41 @@ +container = $container; + } + + public function useNoAuth() + { + $entityManager = $this->container->get('entityManager'); + $this->container->setUser($entityManager->getEntity('User')); + } + + public function login($username, $password) + { + $GLOBALS['log']->add('DEBUG', 'AUTH: Try to authenticate'); + + $entityManager = $this->container->get('entityManager'); + + $user = $entityManager->getRepository('User')->findOne(array( + 'whereClause' => array( + 'userName' => $username, + 'password' => md5($password) + ), + )); + + if ($user instanceof \Espo\Entities\User) { + $entityManager->setUser($user); + $this->container->setUser($user); + $GLOBALS['log']->add('DEBUG', 'AUTH: Result of authenticate =[' . $isAuthenticated . ']'); + return true; + } + } +} + diff --git a/application/Espo/Core/Utils/Metadata.php b/application/Espo/Core/Utils/Metadata.php index ade46c2ccb..0c3349dd84 100644 --- a/application/Espo/Core/Utils/Metadata.php +++ b/application/Espo/Core/Utils/Metadata.php @@ -26,6 +26,8 @@ class Metadata $this->fileManager = $fileManager; $this->converter = new \Espo\Core\Utils\Database\Converter($this, $this->fileManager); + + $this->init(!$this->isCached()); } protected function getConfig() diff --git a/application/Espo/EntryPoints/Download.php b/application/Espo/EntryPoints/Download.php index 24dfd8f690..a52996d83f 100644 --- a/application/Espo/EntryPoints/Download.php +++ b/application/Espo/EntryPoints/Download.php @@ -8,10 +8,11 @@ use \Espo\Core\Exceptions\BadRequest; class Download extends \Espo\Core\EntryPoints\Base { - protected $authRequired = true; + public static $authRequired = true; public function run() { + $id = $_GET['id']; if (empty($id)) { throw new BadRequest(); @@ -19,21 +20,22 @@ class Download extends \Espo\Core\EntryPoints\Base $attachment = $this->getEntityManager()->getEntity('Attachment', $id); - if ($attachment) { + if (!$attachment) { throw new NotFound(); - } + } - if ($enity->get('parentId') && $enity->get('parentType')) { - $parent = $this->getEntityManager()->getEntity($enity->get('parentType'), $enity->get('parentId')); + if ($attachment->get('parentId') && $attachment->get('parentType')) { + $parent = $this->getEntityManager()->getEntity($attachment->get('parentType'), $attachment->get('parentId')); if (!$this->getAcl()->check($parent)) { throw new Forbidden(); } } $fileName = "data/upload/{$attachment->id}"; - if (!file_exists($fileName)) { + + if (!file_exists($fileName)) { throw new NotFound(); - } + } header('Content-Description: File Transfer'); if ($attachment->get('type')) { diff --git a/bootstrap.php b/bootstrap.php index d675c6b70a..098a2477c9 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -1,50 +1,7 @@ setMetadataDriverImpl(new JsonDriver(array(__DIR__."/data/cache/doctrine/metadata"))); -//END: JSON Driver for Doctrine -*/ - -// database configuration parameters -/*$conn = array( - 'driver' => 'pdo_sqlite', - 'path' => __DIR__ . '/db.sqlite', -); */ - -/*$conn = array( - 'driver' => 'pdo_mysql', - 'user' => 'root', - 'password' => '', - 'dbname' => 'jet_doctrine_last', -); */ - - -/*$conn = array( - 'driver' => 'pdo_mysql', - //'driver' => 'mysqli', - 'host' => 'localhost', - 'dbname' => 'jetcrm', - 'user' => 'root', - 'password' => '' -); - -// obtaining the entity manager -//$entityManager = \Doctrine\ORM\EntityManager::create($conn, $config); -$em = \Doctrine\ORM\EntityManager::create($conn, $config); -*/ - - -?> \ No newline at end of file diff --git a/index.php b/index.php new file mode 100644 index 0000000000..df5bd1c02a --- /dev/null +++ b/index.php @@ -0,0 +1,11 @@ +runEntryPoint($_GET['entryPoint']); +} +