Completed
Push — master ( ede649...d3e7dd )
by Lukas
16:27
created

AbstractMapping::count()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
nc 1
nop 0
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Aaron Wood <[email protected]>
6
 * @author Arthur Schiwon <[email protected]>
7
 * @author Morris Jobke <[email protected]>
8
 *
9
 * @license AGPL-3.0
10
 *
11
 * This code is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License, version 3,
13
 * as published by the Free Software Foundation.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU Affero General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Affero General Public License, version 3,
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
22
 *
23
 */
24
25
namespace OCA\User_LDAP\Mapping;
26
27
/**
28
* Class AbstractMapping
29
* @package OCA\User_LDAP\Mapping
30
*/
31
abstract class AbstractMapping {
32
	/**
33
	 * @var \OCP\IDBConnection $dbc
34
	 */
35
	protected $dbc;
36
37
	/**
38
	 * returns the DB table name which holds the mappings
39
	 * @return string
40
	 */
41
	abstract protected function getTableName();
42
43
	/**
44
	 * @param \OCP\IDBConnection $dbc
45
	 */
46
	public function __construct(\OCP\IDBConnection $dbc) {
47
		$this->dbc = $dbc;
48
	}
49
50
	/**
51
	 * checks whether a provided string represents an existing table col
52
	 * @param string $col
53
	 * @return bool
54
	 */
55
	public function isColNameValid($col) {
56
		switch($col) {
57
			case 'ldap_dn':
58
			case 'owncloud_name':
59
			case 'directory_uuid':
60
				return true;
61
			default:
62
				return false;
63
		}
64
	}
65
66
	/**
67
	 * Gets the value of one column based on a provided value of another column
68
	 * @param string $fetchCol
69
	 * @param string $compareCol
70
	 * @param string $search
71
	 * @throws \Exception
72
	 * @return string|false
73
	 */
74
	protected function getXbyY($fetchCol, $compareCol, $search) {
75
		if(!$this->isColNameValid($fetchCol)) {
76
			//this is used internally only, but we don't want to risk
77
			//having SQL injection at all.
78
			throw new \Exception('Invalid Column Name');
79
		}
80
		$query = $this->dbc->prepare('
81
			SELECT `' . $fetchCol . '`
82
			FROM `'. $this->getTableName() .'`
83
			WHERE `' . $compareCol . '` = ?
84
		');
85
86
		$res = $query->execute(array($search));
87
		if($res !== false) {
88
			return $query->fetchColumn();
89
		}
90
91
		return false;
92
	}
93
94
	/**
95
	 * Performs a DELETE or UPDATE query to the database.
96
	 * @param \Doctrine\DBAL\Driver\Statement $query
97
	 * @param array $parameters
98
	 * @return bool true if at least one row was modified, false otherwise
99
	 */
100
	protected function modify($query, $parameters) {
101
		$result = $query->execute($parameters);
102
		return ($result === true && $query->rowCount() > 0);
103
	}
104
105
	/**
106
	 * Gets the LDAP DN based on the provided name.
107
	 * Replaces Access::ocname2dn
108
	 * @param string $name
109
	 * @return string|false
110
	 */
111
	public function getDNByName($name) {
112
		return $this->getXbyY('ldap_dn', 'owncloud_name', $name);
113
	}
114
115
	/**
116
	 * Updates the DN based on the given UUID
117
	 * @param string $fdn
118
	 * @param string $uuid
119
	 * @return bool
120
	 */
121 View Code Duplication
	public function setDNbyUUID($fdn, $uuid) {
122
		$query = $this->dbc->prepare('
123
			UPDATE `' . $this->getTableName() . '`
124
			SET `ldap_dn` = ?
125
			WHERE `directory_uuid` = ?
126
		');
127
128
		return $this->modify($query, array($fdn, $uuid));
129
	}
130
131
	/**
132
	 * Updates the UUID based on the given DN
133
	 *
134
	 * required by Migration/UUIDFix
135
	 *
136
	 * @param $uuid
137
	 * @param $fdn
138
	 * @return bool
139
	 */
140 View Code Duplication
	public function setUUIDbyDN($uuid, $fdn) {
141
		$query = $this->dbc->prepare('
142
			UPDATE `' . $this->getTableName() . '`
143
			SET `directory_uuid` = ?
144
			WHERE `ldap_dn` = ?
145
		');
146
147
		return $this->modify($query, [$uuid, $fdn]);
148
	}
149
150
	/**
151
	 * Gets the name based on the provided LDAP DN.
152
	 * @param string $fdn
153
	 * @return string|false
154
	 */
155
	public function getNameByDN($fdn) {
156
		return $this->getXbyY('owncloud_name', 'ldap_dn', $fdn);
157
	}
158
159
	/**
160
	 * Searches mapped names by the giving string in the name column
161
	 * @param string $search
162
	 * @param string $prefixMatch
163
	 * @param string $postfixMatch
164
	 * @return string[]
165
	 */
166
	public function getNamesBySearch($search, $prefixMatch = "", $postfixMatch = "") {
167
		$query = $this->dbc->prepare('
168
			SELECT `owncloud_name`
169
			FROM `'. $this->getTableName() .'`
170
			WHERE `owncloud_name` LIKE ?
171
		');
172
173
		$res = $query->execute(array($prefixMatch.$this->dbc->escapeLikeParameter($search).$postfixMatch));
174
		$names = array();
175
		if($res !== false) {
176
			while($row = $query->fetch()) {
177
				$names[] = $row['owncloud_name'];
178
			}
179
		}
180
		return $names;
181
	}
182
183
	/**
184
	 * Gets the name based on the provided LDAP UUID.
185
	 * @param string $uuid
186
	 * @return string|false
187
	 */
188
	public function getNameByUUID($uuid) {
189
		return $this->getXbyY('owncloud_name', 'directory_uuid', $uuid);
190
	}
191
192
	/**
193
	 * Gets the UUID based on the provided LDAP DN
194
	 * @param string $dn
195
	 * @return false|string
196
	 * @throws \Exception
197
	 */
198
	public function getUUIDByDN($dn) {
199
		return $this->getXbyY('directory_uuid', 'ldap_dn', $dn);
200
	}
201
202
	/**
203
	 * gets a piece of the mapping list
204
	 * @param int $offset
205
	 * @param int $limit
206
	 * @return array
207
	 */
208
	public function getList($offset = null, $limit = null) {
209
		$query = $this->dbc->prepare('
210
			SELECT
211
				`ldap_dn` AS `dn`,
212
				`owncloud_name` AS `name`,
213
				`directory_uuid` AS `uuid`
214
			FROM `' . $this->getTableName() . '`',
215
			$limit,
216
			$offset
217
		);
218
219
		$query->execute();
220
		return $query->fetchAll();
221
	}
222
223
	/**
224
	 * attempts to map the given entry
225
	 * @param string $fdn fully distinguished name (from LDAP)
226
	 * @param string $name
227
	 * @param string $uuid a unique identifier as used in LDAP
228
	 * @return bool
229
	 */
230
	public function map($fdn, $name, $uuid) {
231 View Code Duplication
		if(mb_strlen($fdn) > 255) {
232
			\OC::$server->getLogger()->error(
233
				'Cannot map, because the DN exceeds 255 characters: {dn}',
234
				[
235
					'app' => 'user_ldap',
236
					'dn' => $fdn,
237
				]
238
			);
239
			return false;
240
		}
241
242
		$row = array(
243
			'ldap_dn'        => $fdn,
244
			'owncloud_name'  => $name,
245
			'directory_uuid' => $uuid
246
		);
247
248
		try {
249
			$result = $this->dbc->insertIfNotExist($this->getTableName(), $row);
250
			// insertIfNotExist returns values as int
251
			return (bool)$result;
252
		} catch (\Exception $e) {
253
			return false;
254
		}
255
	}
256
257
	/**
258
	 * removes a mapping based on the owncloud_name of the entry
259
	 * @param string $name
260
	 * @return bool
261
	 */
262 View Code Duplication
	public function unmap($name) {
263
		$query = $this->dbc->prepare('
264
			DELETE FROM `'. $this->getTableName() .'`
265
			WHERE `owncloud_name` = ?');
266
267
		return $this->modify($query, array($name));
268
	}
269
270
	/**
271
	 * Truncate's the mapping table
272
	 * @return bool
273
	 */
274
	public function clear() {
275
		$sql = $this->dbc
276
			->getDatabasePlatform()
277
			->getTruncateTableSQL('`' . $this->getTableName() . '`');
278
		return $this->dbc->prepare($sql)->execute();
279
	}
280
281
	/**
282
	 * returns the number of entries in the mappings table
283
	 *
284
	 * @return int
285
	 */
286
	public function count() {
287
		$qb = $this->dbc->getQueryBuilder();
288
		$query = $qb->select($qb->createFunction('COUNT(`ldap_dn`)'))
289
			->from($this->getTableName());
290
		$res = $query->execute();
291
		$count = $res->fetchColumn();
292
		$res->closeCursor();
293
		return (int)$count;
294
	}
295
}
296