blob: c8db38706eadf2fd2978f3ea2cc362c9d96ee752 [file] [log] [blame]
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +02001<?php
2
3namespace Adldap\Connections;
4
5use Adldap\Adldap;
6use Adldap\Auth\Guard;
7use Adldap\Query\Cache;
8use InvalidArgumentException;
9use Adldap\Auth\GuardInterface;
10use Adldap\Schemas\ActiveDirectory;
11use Adldap\Schemas\SchemaInterface;
12use Psr\SimpleCache\CacheInterface;
13use Adldap\Models\Factory as ModelFactory;
14use Adldap\Query\Factory as SearchFactory;
15use Adldap\Configuration\DomainConfiguration;
16
17/**
18 * Class Provider.
19 *
20 * Contains the LDAP connection and domain configuration to
21 * instantiate factories for retrieving and creating
22 * LDAP records as well as authentication (binding).
23 */
24class Provider implements ProviderInterface
25{
26 /**
27 * The providers connection.
28 *
29 * @var ConnectionInterface
30 */
31 protected $connection;
32
33 /**
34 * The providers configuration.
35 *
36 * @var DomainConfiguration
37 */
38 protected $configuration;
39
40 /**
41 * The providers schema.
42 *
43 * @var SchemaInterface
44 */
45 protected $schema;
46
47 /**
48 * The providers auth guard instance.
49 *
50 * @var GuardInterface
51 */
52 protected $guard;
53
54 /**
55 * The providers cache instance.
56 *
57 * @var Cache|null
58 */
59 protected $cache;
60
61 /**
62 * {@inheritdoc}
63 */
64 public function __construct($configuration = [], ConnectionInterface $connection = null)
65 {
66 $this->setConfiguration($configuration)
67 ->setConnection($connection);
68 }
69
70 /**
71 * Does nothing. Implemented in order to remain backwards compatible.
72 *
73 * @deprecated since v10.3.0
74 */
75 public function __destruct()
76 {
77 //
78 }
79
80 /**
81 * {@inheritdoc}
82 */
83 public function setConfiguration($configuration = [])
84 {
85 if (is_array($configuration)) {
86 $configuration = new DomainConfiguration($configuration);
87 }
88
89 if ($configuration instanceof DomainConfiguration) {
90 $this->configuration = $configuration;
91
92 $schema = $configuration->get('schema');
93
94 // We will update our schema here when our configuration is set.
95 $this->setSchema(new $schema());
96
97 return $this;
98 }
99
100 $class = DomainConfiguration::class;
101
102 throw new InvalidArgumentException(
103 "Configuration must be array or instance of $class"
104 );
105 }
106
107 /**
108 * {@inheritdoc}
109 */
110 public function setConnection(ConnectionInterface $connection = null)
111 {
112 // We will create a standard connection if one isn't given.
113 $this->connection = $connection ?: new Ldap();
114
115 // Prepare the connection.
116 $this->prepareConnection();
117
118 // Instantiate the LDAP connection.
119 $this->connection->connect(
120 $this->configuration->get('hosts'),
121 $this->configuration->get('port')
122 );
123
124 return $this;
125 }
126
127 /**
128 * {@inheritdoc}
129 */
130 public function setSchema(SchemaInterface $schema = null)
131 {
132 $this->schema = $schema ?: new ActiveDirectory();
133
134 return $this;
135 }
136
137 /**
138 * {@inheritdoc}
139 */
140 public function setGuard(GuardInterface $guard)
141 {
142 $this->guard = $guard;
143
144 return $this;
145 }
146
147 /**
148 * Sets the cache store.
149 *
150 * @param CacheInterface $store
151 *
152 * @return $this
153 */
154 public function setCache(CacheInterface $store)
155 {
156 $this->cache = new Cache($store);
157
158 return $this;
159 }
160
161 /**
162 * {@inheritdoc}
163 */
164 public function getConfiguration()
165 {
166 return $this->configuration;
167 }
168
169 /**
170 * {@inheritdoc}
171 */
172 public function getConnection()
173 {
174 return $this->connection;
175 }
176
177 /**
178 * {@inheritdoc}
179 */
180 public function getSchema()
181 {
182 return $this->schema;
183 }
184
185 /**
186 * {@inheritdoc}
187 */
188 public function getGuard()
189 {
190 if (!$this->guard instanceof GuardInterface) {
191 $this->setGuard($this->getDefaultGuard($this->connection, $this->configuration));
192 }
193
194 return $this->guard;
195 }
196
197 /**
198 * {@inheritdoc}
199 */
200 public function getDefaultGuard(ConnectionInterface $connection, DomainConfiguration $configuration)
201 {
202 $guard = new Guard($connection, $configuration);
203
204 $guard->setDispatcher(Adldap::getEventDispatcher());
205
206 return $guard;
207 }
208
209 /**
210 * {@inheritdoc}
211 */
212 public function make()
213 {
214 return new ModelFactory(
215 $this->search()->newQuery()
216 );
217 }
218
219 /**
220 * {@inheritdoc}
221 */
222 public function search()
223 {
224 $factory = new SearchFactory(
225 $this->connection,
226 $this->schema,
227 $this->configuration->get('base_dn')
228 );
229
230 if ($this->cache) {
231 $factory->setCache($this->cache);
232 }
233
234 return $factory;
235 }
236
237 /**
238 * {@inheritdoc}
239 */
240 public function auth()
241 {
242 return $this->getGuard();
243 }
244
245 /**
246 * {@inheritdoc}
247 */
248 public function connect($username = null, $password = null)
249 {
250 // Get the default guard instance.
251 $guard = $this->getGuard();
252
253 if (is_null($username) && is_null($password)) {
254 // If both the username and password are null, we'll connect to the server
255 // using the configured administrator username and password.
256 $guard->bindAsAdministrator();
257 } else {
258 // Bind to the server with the specified username and password otherwise.
259 $guard->bind($username, $password);
260 }
261
262 return $this;
263 }
264
265 /**
266 * Prepares the connection by setting configured parameters.
267 *
268 * @throws \Adldap\Configuration\ConfigurationException When configuration options requested do not exist
269 *
270 * @return void
271 */
272 protected function prepareConnection()
273 {
274 if ($this->configuration->get('use_ssl')) {
275 $this->connection->ssl();
276 } elseif ($this->configuration->get('use_tls')) {
277 $this->connection->tls();
278 }
279
280 $options = array_replace(
281 $this->configuration->get('custom_options'),
282 [
283 LDAP_OPT_PROTOCOL_VERSION => $this->configuration->get('version'),
284 LDAP_OPT_NETWORK_TIMEOUT => $this->configuration->get('timeout'),
285 LDAP_OPT_REFERRALS => $this->configuration->get('follow_referrals'),
286 ]
287 );
288
289 $this->connection->setOptions($options);
290 }
291}