1<?php 2 3/** 4 * This file is part of the FreeDSx LDAP package. 5 * 6 * (c) Chad Sikorra <Chad.Sikorra@gmail.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace FreeDSx\Ldap\Protocol\Factory; 13 14use FreeDSx\Ldap\Control\Control; 15use FreeDSx\Ldap\Control\ControlBag; 16use FreeDSx\Ldap\Operation\Request\ExtendedRequest; 17use FreeDSx\Ldap\Operation\Request\RequestInterface; 18use FreeDSx\Ldap\Operation\Request\SearchRequest; 19use FreeDSx\Ldap\Operation\Request\UnbindRequest; 20use FreeDSx\Ldap\Protocol\ServerProtocolHandler; 21use FreeDSx\Ldap\Protocol\ServerProtocolHandler\ServerProtocolHandlerInterface; 22use FreeDSx\Ldap\Server\HandlerFactoryInterface; 23use FreeDSx\Ldap\Server\RequestHistory; 24 25/** 26 * Determines the correct handler for the request. 27 * 28 * @author Chad Sikorra <Chad.Sikorra@gmail.com> 29 */ 30class ServerProtocolHandlerFactory 31{ 32 /** 33 * @var HandlerFactoryInterface 34 */ 35 private $handlerFactory; 36 37 /** 38 * @var RequestHistory 39 */ 40 private $requestHistory; 41 42 public function __construct( 43 HandlerFactoryInterface $handlerFactory, 44 RequestHistory $requestHistory 45 ) { 46 $this->handlerFactory = $handlerFactory; 47 $this->requestHistory = $requestHistory; 48 } 49 50 public function get( 51 RequestInterface $request, 52 ControlBag $controls 53 ): ServerProtocolHandlerInterface { 54 if ($request instanceof ExtendedRequest && $request->getName() === ExtendedRequest::OID_WHOAMI) { 55 return new ServerProtocolHandler\ServerWhoAmIHandler(); 56 } elseif ($request instanceof ExtendedRequest && $request->getName() === ExtendedRequest::OID_START_TLS) { 57 return new ServerProtocolHandler\ServerStartTlsHandler(); 58 } elseif ($this->isRootDseSearch($request)) { 59 return $this->getRootDseHandler(); 60 } elseif ($this->isPagingSearch($request, $controls)) { 61 return $this->getPagingHandler(); 62 } elseif ($request instanceof SearchRequest) { 63 return new ServerProtocolHandler\ServerSearchHandler(); 64 } elseif ($request instanceof UnbindRequest) { 65 return new ServerProtocolHandler\ServerUnbindHandler(); 66 } else { 67 return new ServerProtocolHandler\ServerDispatchHandler(); 68 } 69 } 70 71 private function isRootDseSearch(RequestInterface $request): bool 72 { 73 if (!$request instanceof SearchRequest) { 74 return false; 75 } 76 77 return $request->getScope() === SearchRequest::SCOPE_BASE_OBJECT 78 && ((string)$request->getBaseDn() === ''); 79 } 80 81 private function isPagingSearch( 82 RequestInterface $request, 83 ControlBag $controls 84 ): bool { 85 return $request instanceof SearchRequest 86 && $controls->has(Control::OID_PAGING); 87 } 88 89 private function getRootDseHandler(): ServerProtocolHandler\ServerRootDseHandler 90 { 91 $rootDseHandler = $this->handlerFactory->makeRootDseHandler(); 92 93 return new ServerProtocolHandler\ServerRootDseHandler($rootDseHandler); 94 } 95 96 private function getPagingHandler(): ServerProtocolHandlerInterface 97 { 98 $pagingHandler = $this->handlerFactory->makePagingHandler(); 99 100 if (!$pagingHandler) { 101 return new ServerProtocolHandler\ServerPagingUnsupportedHandler(); 102 } 103 104 return new ServerProtocolHandler\ServerPagingHandler( 105 $pagingHandler, 106 $this->requestHistory 107 ); 108 } 109} 110