Completed
Push — master ( 0256f6...5411d6 )
by Morris
22:12 queued 06:46
created

LDAPProvider::unflagRecord()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 *
4
 * @copyright Copyright (c) 2016, Roger Szabo ([email protected])
5
 *
6
 * @author Roger Szabo <[email protected]>
7
 * @author Vinicius Brand <[email protected]>
8
 * @author Daniel Tygel <[email protected]>
9
 *
10
 * @license GNU AGPL version 3 or any later version
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License as
14
 * published by the Free Software Foundation, either version 3 of the
15
 * License, or (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24
 *
25
 */
26
27
namespace OCA\User_LDAP;
28
29
30
use OCP\LDAP\ILDAPProvider;
31
use OCP\LDAP\IDeletionFlagSupport;
32
use OCP\IServerContainer;
33
use OCA\User_LDAP\User\DeletedUsersIndex;
34
35
/**
36
 * LDAP provider for pulic access to the LDAP backend.
37
 */
38
class LDAPProvider implements ILDAPProvider, IDeletionFlagSupport {
39
40
	private $userBackend;
41
	private $groupBackend;
42
	private $logger;
43
	private $helper;
44
	private $deletedUsersIndex;
45
	
46
	/**
47
	 * Create new LDAPProvider
48
	 * @param \OCP\IServerContainer $serverContainer
49
	 * @param Helper $helper
50
	 * @param DeletedUsersIndex $deletedUsersIndex
51
	 * @throws \Exception if user_ldap app was not enabled
52
	 */
53
	public function __construct(IServerContainer $serverContainer, Helper $helper, DeletedUsersIndex $deletedUsersIndex) {
54
		$this->logger = $serverContainer->getLogger();
55
		$this->helper = $helper;
56
		$this->deletedUsersIndex = $deletedUsersIndex;
57
		$userBackendFound = false;
58
		$groupBackendFound = false;
59 View Code Duplication
		foreach ($serverContainer->getUserManager()->getBackends() as $backend){
60
			$this->logger->debug('instance '.get_class($backend).' user backend.', ['app' => 'user_ldap']);
61
			if ($backend instanceof IUserLDAP) {
62
				$this->userBackend = $backend;
63
				$userBackendFound = true;
64
				break;
65
			}
66
        }
67 View Code Duplication
		foreach ($serverContainer->getGroupManager()->getBackends() as $backend){
68
			$this->logger->debug('instance '.get_class($backend).' group backend.', ['app' => 'user_ldap']);
69
			if ($backend instanceof IGroupLDAP) {
70
				$this->groupBackend = $backend;
71
				$groupBackendFound = true;
72
				break;
73
			}
74
		}
75
76
        if (!$userBackendFound or !$groupBackendFound) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
77
			throw new \Exception('To use the LDAPProvider, user_ldap app must be enabled');
78
		}
79
	}
80
	
81
	/**
82
	 * Translate an user id to LDAP DN
83
	 * @param string $uid user id
84
	 * @return string with the LDAP DN
85
	 * @throws \Exception if translation was unsuccessful
86
	 */
87
	public function getUserDN($uid) {
88
		if(!$this->userBackend->userExists($uid)){
89
			throw new \Exception('User id not found in LDAP');
90
		}
91
		$result = $this->userBackend->getLDAPAccess($uid)->username2dn($uid);
92
		if(!$result){
0 ignored issues
show
Bug Best Practice introduced by
The expression $result of type string|false is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
93
			throw new \Exception('Translation to LDAP DN unsuccessful');
94
		}
95
		return $result;
96
	}
97
98
	/**
99
	 * Translate a group id to LDAP DN.
100
	 * @param string $gid group id
101
	 * @return string
102
	 * @throws \Exception
103
	 */
104
	public function getGroupDN($gid) {
105
		if(!$this->groupBackend->groupExists($gid)){
106
			throw new \Exception('Group id not found in LDAP');
107
		}
108
		$result = $this->groupBackend->getLDAPAccess($gid)->groupname2dn($gid);
109
		if(!$result){
0 ignored issues
show
Bug Best Practice introduced by
The expression $result of type string|false is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
110
			throw new \Exception('Translation to LDAP DN unsuccessful');
111
		}
112
		return $result;	
113
	}
114
115
	/**
116
	 * Translate a LDAP DN to an internal user name. If there is no mapping between 
117
	 * the DN and the user name, a new one will be created.
118
	 * @param string $dn LDAP DN
119
	 * @return string with the internal user name
120
	 * @throws \Exception if translation was unsuccessful
121
	 */
122
	public function getUserName($dn) {
123
		$result = $this->userBackend->dn2UserName($dn);
124
		if(!$result){
0 ignored issues
show
Bug Best Practice introduced by
The expression $result of type string|false is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
125
			throw new \Exception('Translation to internal user name unsuccessful');
126
		}
127
		return $result;
128
	}
129
	
130
	/**
131
	 * Convert a stored DN so it can be used as base parameter for LDAP queries.
132
	 * @param string $dn the DN in question
133
	 * @return string
134
	 */
135
	public function DNasBaseParameter($dn) {
136
		return $this->helper->DNasBaseParameter($dn);
137
	}
138
	
139
	/**
140
	 * Sanitize a DN received from the LDAP server.
141
	 * @param array $dn the DN in question
142
	 * @return array the sanitized DN
143
	 */
144
	public function sanitizeDN($dn) {
145
		return $this->helper->sanitizeDN($dn);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->helper->sanitizeDN($dn); of type array|string adds the type string to the return on line 145 which is incompatible with the return type declared by the interface OCP\LDAP\ILDAPProvider::sanitizeDN of type array.
Loading history...
146
	}
147
	
148
	/**
149
	 * Return a new LDAP connection resource for the specified user. 
150
	 * The connection must be closed manually.
151
	 * @param string $uid user id
152
	 * @return resource of the LDAP connection
153
	 * @throws \Exception if user id was not found in LDAP
154
	 */
155
	public function getLDAPConnection($uid) {
156
		if(!$this->userBackend->userExists($uid)){
157
			throw new \Exception('User id not found in LDAP');
158
		}
159
		return $this->userBackend->getNewLDAPConnection($uid);
160
	}
161
162
	/**
163
	 * Return a new LDAP connection resource for the specified user.
164
	 * The connection must be closed manually.
165
	 * @param string $gid group id
166
	 * @return resource of the LDAP connection
167
	 * @throws \Exception if group id was not found in LDAP
168
	 */
169
	public function getGroupLDAPConnection($gid) {
170
		if(!$this->groupBackend->groupExists($gid)){
171
			throw new \Exception('Group id not found in LDAP');
172
		}
173
		return $this->groupBackend->getNewLDAPConnection($gid);
174
	}
175
	
176
	/**
177
	 * Get the LDAP base for users.
178
	 * @param string $uid user id
179
	 * @return string the base for users
180
	 * @throws \Exception if user id was not found in LDAP
181
	 */
182
	public function getLDAPBaseUsers($uid) {
183
		if(!$this->userBackend->userExists($uid)){
184
			throw new \Exception('User id not found in LDAP');
185
		}	
186
		return $this->userBackend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_base_users'];
187
	}
188
	
189
	/**
190
	 * Get the LDAP base for groups.
191
	 * @param string $uid user id
192
	 * @return string the base for groups
193
	 * @throws \Exception if user id was not found in LDAP
194
	 */
195
	public function getLDAPBaseGroups($uid) {
196
		if(!$this->userBackend->userExists($uid)){
197
			throw new \Exception('User id not found in LDAP');
198
		}
199
		return $this->userBackend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_base_groups'];
200
	}
201
	
202
	/**
203
	 * Clear the cache if a cache is used, otherwise do nothing.
204
	 * @param string $uid user id
205
	 * @throws \Exception if user id was not found in LDAP
206
	 */
207
	public function clearCache($uid) {
208
		if(!$this->userBackend->userExists($uid)){
209
			throw new \Exception('User id not found in LDAP');
210
		}
211
		$this->userBackend->getLDAPAccess($uid)->getConnection()->clearCache();
212
	}
213
214
	/**
215
	 * Clear the cache if a cache is used, otherwise do nothing.
216
	 * Acts on the LDAP connection of a group
217
	 * @param string $gid group id
218
	 * @throws \Exception if user id was not found in LDAP
219
	 */
220
	public function clearGroupCache($gid) {
221
		if(!$this->groupBackend->groupExists($gid)){
222
			throw new \Exception('Group id not found in LDAP');
223
		}
224
		$this->groupBackend->getLDAPAccess($gid)->getConnection()->clearCache();
225
	}
226
	
227
	/**
228
	 * Check whether a LDAP DN exists
229
	 * @param string $dn LDAP DN
230
	 * @return bool whether the DN exists
231
	 */
232
	public function dnExists($dn) {
233
		$result = $this->userBackend->dn2UserName($dn);
234
		return !$result ? false : true;
235
	}
236
	
237
	/**
238
	 * Flag record for deletion.
239
	 * @param string $uid user id
240
	 */
241
	public function flagRecord($uid) {
242
		$this->deletedUsersIndex->markUser($uid);
243
	}
244
	
245
	/**
246
	 * Unflag record for deletion.
247
	 * @param string $uid user id
248
	 */
249
	public function unflagRecord($uid) {
250
		//do nothing
251
	}
252
253
	/**
254
	 * Get the LDAP attribute name for the user's display name
255
	 * @param string $uid user id
256
	 * @return string the display name field
257
	 * @throws \Exception if user id was not found in LDAP
258
	 */
259
	public function getLDAPDisplayNameField($uid) {
260
		if(!$this->userBackend->userExists($uid)){
261
			throw new \Exception('User id not found in LDAP');
262
		}
263
		return $this->userBackend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_display_name'];
264
	}
265
266
	/**
267
	 * Get the LDAP attribute name for the email
268
	 * @param string $uid user id
269
	 * @return string the email field
270
	 * @throws \Exception if user id was not found in LDAP
271
	 */
272
	public function getLDAPEmailField($uid) {
273
		if(!$this->userBackend->userExists($uid)){
274
			throw new \Exception('User id not found in LDAP');
275
		}
276
		return $this->userBackend->getLDAPAccess($uid)->getConnection()->getConfiguration()['ldap_email_attr'];
277
	}
278
279
	/**
280
	 * Get the LDAP type of association between users and groups
281
	 * @param string $gid group id
282
	 * @return string the configuration, one of: 'memberUid', 'uniqueMember', 'member', 'gidNumber'
283
	 * @throws \Exception if group id was not found in LDAP
284
	 */
285
	public function getLDAPGroupMemberAssoc($gid) {
286
		if(!$this->groupBackend->groupExists($gid)){
287
			throw new \Exception('Group id not found in LDAP');
288
		}
289
		return $this->groupBackend->getLDAPAccess($gid)->getConnection()->getConfiguration()['ldap_group_member_assoc_attribute'];
290
	}
291
292
}
293