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\Server\RequestHandler;
13
14use FreeDSx\Ldap\Entry\Entries;
15use FreeDSx\Ldap\Exception\BindException;
16use FreeDSx\Ldap\Exception\OperationException;
17use FreeDSx\Ldap\LdapClient;
18use FreeDSx\Ldap\Operation\LdapResult;
19use FreeDSx\Ldap\Operation\Request\AddRequest;
20use FreeDSx\Ldap\Operation\Request\CompareRequest;
21use FreeDSx\Ldap\Operation\Request\DeleteRequest;
22use FreeDSx\Ldap\Operation\Request\ExtendedRequest;
23use FreeDSx\Ldap\Operation\Request\ModifyDnRequest;
24use FreeDSx\Ldap\Operation\Request\ModifyRequest;
25use FreeDSx\Ldap\Operation\Request\SearchRequest;
26use FreeDSx\Ldap\Operation\ResultCode;
27use FreeDSx\Ldap\Server\RequestContext;
28
29/**
30 * Proxies requests to an LDAP server and returns the response. You should extend this to add your own constructor and
31 * set the LDAP client options variable.
32 *
33 * @author Chad Sikorra <Chad.Sikorra@gmail.com>
34 */
35class ProxyRequestHandler implements RequestHandlerInterface
36{
37    /**
38     * @var LdapClient|null
39     */
40    protected $ldap;
41
42    /**
43     * @var array
44     */
45    protected $options = [];
46
47    /**
48     * @inheritDoc
49     */
50    public function bind(string $username, string $password): bool
51    {
52        try {
53            return (bool) $this->ldap()->bind($username, $password);
54        } catch (BindException $e) {
55            throw new OperationException($e->getMessage(), $e->getCode());
56        }
57    }
58
59    /**
60     * @inheritDoc
61     */
62    public function modify(RequestContext $context, ModifyRequest $modify): void
63    {
64        $this->ldap()->sendAndReceive($modify, ...$context->controls()->toArray());
65    }
66
67    /**
68     * @inheritDoc
69     */
70    public function modifyDn(RequestContext $context, ModifyDnRequest $modifyDn): void
71    {
72        $this->ldap()->sendAndReceive($modifyDn, ...$context->controls()->toArray());
73    }
74
75    /**
76     * @inheritDoc
77     */
78    public function delete(RequestContext $context, DeleteRequest $delete): void
79    {
80        $this->ldap()->sendAndReceive($delete, ...$context->controls()->toArray());
81    }
82
83    /**
84     * @inheritDoc
85     */
86    public function add(RequestContext $context, AddRequest $add): void
87    {
88        $this->ldap()->sendAndReceive($add, ...$context->controls()->toArray());
89    }
90
91    /**
92     * @inheritDoc
93     */
94    public function search(RequestContext $context, SearchRequest $search): Entries
95    {
96        return $this->ldap()->search($search, ...$context->controls()->toArray());
97    }
98
99    /**
100     * @inheritDoc
101     */
102    public function compare(RequestContext $context, CompareRequest $compare): bool
103    {
104        $response = $this->ldap()->sendAndReceive($compare, ...$context->controls()->toArray())->getResponse();
105        if (!$response instanceof LdapResult) {
106            throw new OperationException('The result was malformed.', ResultCode::PROTOCOL_ERROR);
107        }
108
109        return $response->getResultCode() === ResultCode::COMPARE_TRUE;
110    }
111
112    /**
113     * @inheritDoc
114     */
115    public function extended(RequestContext $context, ExtendedRequest $extended): void
116    {
117        $this->ldap()->send($extended, ...$context->controls()->toArray());
118    }
119
120    /**
121     * @param LdapClient $client
122     */
123    public function setLdapClient(LdapClient $client): void
124    {
125        $this->ldap = $client;
126    }
127
128    /**
129     * @return LdapClient
130     */
131    protected function ldap(): LdapClient
132    {
133        if ($this->ldap === null) {
134            $this->ldap = new LdapClient($this->options);
135        }
136
137        return $this->ldap;
138    }
139}
140