* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://www.seeddms.org Main Site */ /* Middleware for authentication based on session */ class SeedDMS_Auth_Middleware_Session { /* {{{ */ private $container; private $responsefactory; public function __construct($container, $responsefactory) { $this->container = $container; $this->responsefactory = $responsefactory; } /** * Example middleware invokable class * * @param \Psr\Http\Message\ServerRequestInterface $request PSR7 request * @param \Psr\Http\Message\ResponseInterface $response PSR7 response * @param callable $next Next middleware * * @return \Psr\Http\Message\ResponseInterface */ public function __invoke($request, $handler) { // $this->container has the DI $dms = $this->container->get('dms'); $settings = $this->container->get('config'); $logger = $this->container->get('logger'); $userobj = null; if ($this->container->has('userobj')) { $userobj = $this->container->get('userobj'); } if ($userobj) { $response = $handler->handle($request); return $response; } $logger->log("Invoke AuthSessionMiddleware for method " . $request->getMethod() . " on '" . $request->getUri()->getPath() . "'", PEAR_LOG_INFO); require_once("inc/inc.ClassSession.php"); $session = new SeedDMS_Session($dms->getDb()); if (isset($_COOKIE["mydms_session"])) { $dms_session = $_COOKIE["mydms_session"]; $logger->log("Session key: " . $dms_session, PEAR_LOG_DEBUG); if (!$resArr = $session->load($dms_session)) { /* Delete Cookie */ setcookie("mydms_session", $dms_session, time() - 3600, $settings->_httpRoot); $logger->log("Session for id '" . $dms_session . "' has gone", PEAR_LOG_ERR); $response = $this->responsefactory->createResponse(); return $response->withStatus(403); } /* Load user data */ $userobj = $dms->getUser($resArr["userID"]); if (!is_object($userobj)) { /* Delete Cookie */ setcookie("mydms_session", $dms_session, time() - 3600, $settings->_httpRoot); if ($settings->_enableGuestLogin) { if (!($userobj = $dms->getUser($settings->_guestID))) { $response = $this->responsefactory->createResponse(); return $response->withStatus(403); } } else { return $response->withStatus(403); } } if ($userobj->isAdmin()) { if ($resArr["su"]) { if (!($userobj = $dms->getUser($resArr["su"]))) { $response = $this->responsefactory->createResponse(); return $response->withStatus(403); } } } $dms->setUser($userobj); } else { $response = $this->responsefactory->createResponse(); return $response->withStatus(403); } $this->container->set('userobj', $userobj); $response = $handler->handle($request); return $response; } } /* }}} */ /** * Middleware for authentication based on basic authentication * **/ class SeedDMS_Auth_Middleware_Basic { /* {{{ */ private $container; private $responsefactory; public function __construct($container, $responsefactory) { $this->container = $container; $this->responsefactory = $responsefactory; } /** * Basic authentication middleware invokable class * * @param \Psr\Http\Message\ServerRequestInterface $request PSR7 request * @param \Psr\Http\Message\ResponseInterface $response PSR7 response * @param callable $next Next middleware * * @return \Psr\Http\Message\ResponseInterface */ public function __invoke($request, $handler) { $dms = $this->container->get('dms'); $settings = $this->container->get('config'); $logger = $this->container->get('logger'); $userobj = null; if ($this->container->has('userobj')) { $userobj = $this->container->get('userobj'); } if ($userobj) { $response = $handler->handle($request); return $response; } $logger->log("Invoke AuthBasicMiddleware for method " . $request->getMethod() . " on '" . $request->getUri()->getPath() . "'", PEAR_LOG_INFO); $environment = $request->getServerParams(); if(!empty($environment['HTTP_AUTHORIZATION'])) { $tmp = explode(' ', $environment['HTTP_AUTHORIZATION'], 2); switch($tmp[0]) { case 'Basic': $logger->log("Basic authentication with ".$tmp[0]."=".$tmp[1], PEAR_LOG_INFO); $authenticator = $this->container->get('authenticator'); $kk = explode(':', base64_decode($tmp[1])); $userobj = $authenticator->authenticate($kk[0], $kk[1]); if(!$userobj) { $logger->log("Login with basic authentication for '".$kk[0]."' failed", PEAR_LOG_ERR); $response = $this->responsefactory->createResponse(); return $response->withStatus(403); } $dms->setUser($userobj); if($this->container instanceof \Slim\Container) $this->container['userobj'] = $userobj; else $this->container->set('userobj', $userobj); $logger->log("Login with basic authentication as '".$userobj->getLogin()."' successful", PEAR_LOG_INFO); break; } } $this->container->set('userobj', $userobj); if(!$userobj) $logger->log("Not yet authenticated. Pass on to next middleware", PEAR_LOG_INFO); else $logger->log("Authenticated as ".(is_object($userobj) ? $userobj->getLogin() : "annon").". Pass on to next middleware", PEAR_LOG_INFO); /* Always pass on to the next middleware. If that middleware does * authentication, then it should first check if 'userobj' in the container * is already set. The authentication shipped with seeddms restapi does that * and skips its own authentication, if userobj already exists. */ $response = $handler->handle($request); return $response; } } /* }}} */ /** * Middleware for authentication based on token * **/ class SeedDMS_Auth_Middleware_Token { /* {{{ */ private $container; private $responsefactory; public function __construct($container, $responsefactory) { $this->container = $container; $this->responsefactory = $responsefactory; } /** * Basic authentication middleware invokable class * * @param \Psr\Http\Message\ServerRequestInterface $request PSR7 request * @param \Psr\Http\Message\ResponseInterface $response PSR7 response * @param callable $next Next middleware * * @return \Psr\Http\Message\ResponseInterface */ public function __invoke($request, $handler) { $dms = $this->container->get('dms'); $settings = $this->container->get('config'); $logger = $this->container->get('logger'); $userobj = null; if ($this->container->has('userobj')) { $userobj = $this->container->get('userobj'); } if ($userobj) { $response = $handler->handle($request); return $response; } $logger->log("Invoke AuthTokenMiddleware for method " . $request->getMethod() . " on '" . $request->getUri()->getPath() . "'", PEAR_LOG_INFO); $environment = $request->getServerParams(); /* Do not even try to authenticate if HTTP_AUTHORIZATION is empty, contains * a ' ' (in case of Basic authentication), the api key is not set, the api * user is not set. */ if (!empty($environment['HTTP_AUTHORIZATION']) && strstr($environment['HTTP_AUTHORIZATION'], ' ') === false && !empty($settings->_apiKey) && !empty($settings->_apiUserId)) { $logger->log("Authorization key: ".$environment['HTTP_AUTHORIZATION'], PEAR_LOG_DEBUG); if($settings->_apiKey == $environment['HTTP_AUTHORIZATION']) { if(!($userobj = $dms->getUser($settings->_apiUserId))) { $response = $this->responsefactory->createResponse(); $response = $response->withHeader('Content-Type', 'application/json'); $response = $response->withStatus(403); $response->getBody()->write( (string)json_encode( ['success'=>false, 'message'=>'Invalid user associated with api key', 'data'=>''], JSON_UNESCAPED_SLASHES | JSON_PARTIAL_OUTPUT_ON_ERROR ) ); return $response; } } else { $response = $this->responsefactory->createResponse(); $response = $response->withHeader('Content-Type', 'application/json'); $response = $response->withStatus(403); $response->getBody()->write( (string)json_encode( ['success'=>false, 'message'=>'Wrong api key', 'data'=>''], JSON_UNESCAPED_SLASHES | JSON_PARTIAL_OUTPUT_ON_ERROR ) ); return $response; } $logger->log("Login with apikey as '".$userobj->getLogin()."' successful", PEAR_LOG_INFO); } $this->container->set('userobj', $userobj); if(!$userobj) $logger->log("Not yet authenticated. Pass on to next middleware", PEAR_LOG_INFO); else $logger->log("Authenticated as ".(is_object($userobj) ? $userobj->getLogin() : "annon").". Pass on to next middleware", PEAR_LOG_INFO); /* Always pass on to the next middleware. If that middleware does * authentication, then it should first check if 'userobj' in the container * is already set. The authentication shipped with seeddms restapi does that * and skips its own authentication, if userobj already exists. */ $response = $handler->handle($request); return $response; } } /* }}} */