diff --git a/inc/inc.ClassAuthenticationMiddleware.php b/inc/inc.ClassAuthenticationMiddleware.php index bd9b1c40d..f406747cf 100644 --- a/inc/inc.ClassAuthenticationMiddleware.php +++ b/inc/inc.ClassAuthenticationMiddleware.php @@ -122,8 +122,11 @@ class SeedDMS_Auth_Middleware_Basic { /* {{{ */ private $container; - public function __construct($container) { + private $responsefactory; + + public function __construct($container, $responsefactory) { $this->container = $container; + $this->responsefactory = $responsefactory; } /** @@ -189,3 +192,95 @@ class SeedDMS_Auth_Middleware_Basic { /* {{{ */ 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; + } +} /* }}} */ +