<?php
// login.php
// Copyright P.Kassel, M.Seliger, G.Trietsch, all Rights Reserved
namespace Docuform\Api\Authentication;use DI\DependencyException;use DI\NotFoundException;use Docuform\Api\Authentication\login\AuthInterface;use Docuform\Api\Authentication\login\AuthNogui;use Docuform\Api\Authentication\login\AuthPassword;use Docuform\Api\Exception\ApiHttpAuthException;use Docuform\Api\HttpRequestHandler;use League\OAuth2\Server\AuthorizationServer;use League\OAuth2\Server\Exception\OAuthServerException;use Psr\Http\Message\ResponseInterface;use Psr\Http\Message\ServerRequestInterface;use Psr\Log\LoggerInterface;use Slim\Interfaces\RouteParserInterface;use SlimSession\Helper;class login extends HttpRequestHandler{public function getAllowedUserTypes($request):array{return[];}public function getRequiredScopes($request):array{return['allOf'=>[],'anyOf'=>[]];}public function handleRequest($request,& $response,$arguments):int{$code=500;$server=$this->getContainer()->get('authserver');if($server!=null){try{$bError=false;$params=array();if($request->getMethod()==='GET'){$queryParams=$request->getQueryParams();if(!empty($queryParams['cmd'])){$params=decryptCommand($queryParams['cmd']);$bError=$params===false;}}elseif($request->getMethod()==='POST'){$params=$_POST;if(!array_keys_exists(array('response_type','client_id','scope','state','authMode'),$params)){$bError=true;}}else{$bError=true;}if(!$bError&&!empty($params['authMode'])){$response=$response->withHeader('X-DF-Authorization',$params['authMode']);if($params['authMode']===AuthMode::password||$params['authMode']===AuthMode::nogui){require 'auth/Auth'.ucfirst($params['authMode']).'.php';$auth=null;if($params['authMode']===AuthMode::password){$auth=new AuthPassword($this->getContainer(),$params);}elseif($params['authMode']===AuthMode::nogui){$auth=new AuthNogui($this->getContainer(),$params);}if($auth){if($request->getMethod()==='GET'){$response=$auth->Authorize($request,$response);$code=$response->getStatusCode();}else{$params=$request->getParsedBody();$result=$auth->ProcessResponse((array)$response,$params);$session=$this->getContainer()->get('session');$session->set('authorization_result',$result);$logger=$this->getContainer()->get('logger');$logger->debug('Login result: '.$result);$qparams=array_intersect_key($params,array('response_type'=>'','client_id'=>'','redirect_uri'=>'','scope'=>'','state'=>''));$routeParser=$this->getContainer()->get(RouteParserInterface::class);$url=$routeParser->urlFor('Authorize',[],$qparams);$response=$response->withStatus(302)->withHeader('Location',$url);$code=302;}}else{$bError=true;}}else{$bError=true;}}else{$bError=true;}if($bError){$redirectUri=!empty($params['redirect_uri'])?$params['redirect_uri']:null;throw new ApiHttpAuthException(400,'invalid_grant','Invalid parameters','',$redirectUri,$this->getLogger(),'Invalid parameters at login');}return $code;}catch(OAuthServerException $exception){$response=$exception->generateHttpResponse($response);$logtext='Code '.$response->getStatusCode().': '.$exception->getErrorType().' ('.$exception->getMessage().')';if(!empty($exception->getHint())){$logtext.=' -> '.$exception->getHint();}$this->getLogger()->error($logtext);return $response->getStatusCode();}}$this->getLogger()->debug("login: Returning ".$code);return $code;}}function decryptCommand($cmd):bool|array{$bOk=false;$params=array();if(!empty($cmd)){$cmd=base64_decode($cmd);if(!empty($cmd)){parse_str($cmd,$params);if(array_keys_exists(array('response_type','client_id','scope','state','redirect_uri','authMode','qh'),$params)){$pos=strpos($cmd,'&qh=');if($pos!==false){$cmd=substr($cmd,0,$pos);$crc32=crc32($cmd);if(password_verify($crc32,$params['qh'])){$bOk=true;}}}}}return $bOk?$params:false;}function array_keys_exists(array $keys,array $array):bool{return(!array_diff_key(array_flip($keys),$array));}