Completed
Push — master ( 8ef4fc...ba2e1c )
by Morris
13:20
created

Manager::invalidate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 1
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Arthur Schiwon <[email protected]>
6
 * @author Joas Schilling <[email protected]>
7
 * @author Jörn Friedrich Dreyer <[email protected]>
8
 * @author Morris Jobke <[email protected]>
9
 * @author Thomas Müller <[email protected]>
10
 *
11
 * @license AGPL-3.0
12
 *
13
 * This code is free software: you can redistribute it and/or modify
14
 * it under the terms of the GNU Affero General Public License, version 3,
15
 * as published by the Free Software Foundation.
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, version 3,
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
24
 *
25
 */
26
27
namespace OCA\User_LDAP\User;
28
29
use OC\Cache\CappedMemoryCache;
30
use OCA\User_LDAP\LogWrapper;
31
use OCA\User_LDAP\FilesystemHelper;
32
use OCP\IAvatarManager;
33
use OCP\IConfig;
34
use OCP\IDBConnection;
35
use OCP\Image;
36
use OCP\IUserManager;
37
use OCP\Notification\IManager as INotificationManager;
38
39
/**
40
 * Manager
41
 *
42
 * upon request, returns an LDAP user object either by creating or from run-time
43
 * cache
44
 */
45
class Manager {
46
	/** @var IUserTools */
47
	protected $access;
48
49
	/** @var IConfig */
50
	protected $ocConfig;
51
52
	/** @var IDBConnection */
53
	protected $db;
54
55
	/** @var IUserManager */
56
	protected $userManager;
57
58
	/** @var INotificationManager */
59
	protected $notificationManager;
60
61
	/** @var FilesystemHelper */
62
	protected $ocFilesystem;
63
64
	/** @var LogWrapper */
65
	protected $ocLog;
66
67
	/** @var Image */
68
	protected $image;
69
70
	/** @param \OCP\IAvatarManager */
71
	protected $avatarManager;
72
73
	/**
74
	 * @var CappedMemoryCache $usersByDN
75
	 */
76
	protected $usersByDN;
77
	/**
78
	 * @var CappedMemoryCache $usersByUid
79
	 */
80
	protected $usersByUid;
81
82
	/**
83
	 * @param IConfig $ocConfig
84
	 * @param \OCA\User_LDAP\FilesystemHelper $ocFilesystem object that
85
	 * gives access to necessary functions from the OC filesystem
86
	 * @param  \OCA\User_LDAP\LogWrapper $ocLog
87
	 * @param IAvatarManager $avatarManager
88
	 * @param Image $image an empty image instance
89
	 * @param IDBConnection $db
90
	 * @throws \Exception when the methods mentioned above do not exist
91
	 */
92
	public function __construct(IConfig $ocConfig,
93
								FilesystemHelper $ocFilesystem, LogWrapper $ocLog,
94
								IAvatarManager $avatarManager, Image $image,
95
								IDBConnection $db, IUserManager $userManager,
96
								INotificationManager $notificationManager) {
97
98
		$this->ocConfig            = $ocConfig;
99
		$this->ocFilesystem        = $ocFilesystem;
100
		$this->ocLog               = $ocLog;
101
		$this->avatarManager       = $avatarManager;
102
		$this->image               = $image;
103
		$this->db                  = $db;
104
		$this->userManager         = $userManager;
105
		$this->notificationManager = $notificationManager;
106
		$this->usersByDN           = new CappedMemoryCache();
107
		$this->usersByUid          = new CappedMemoryCache();
108
	}
109
110
	/**
111
	 * @brief binds manager to an instance of IUserTools (implemented by
112
	 * Access). It needs to be assigned first before the manager can be used.
113
	 * @param IUserTools
114
	 */
115
	public function setLdapAccess(IUserTools $access) {
116
		$this->access = $access;
117
	}
118
119
	/**
120
	 * @brief creates an instance of User and caches (just runtime) it in the
121
	 * property array
122
	 * @param string $dn the DN of the user
123
	 * @param string $uid the internal (owncloud) username
124
	 * @return \OCA\User_LDAP\User\User
125
	 */
126
	private function createAndCache($dn, $uid) {
127
		$this->checkAccess();
128
		$user = new User($uid, $dn, $this->access, $this->ocConfig,
129
			$this->ocFilesystem, clone $this->image, $this->ocLog,
130
			$this->avatarManager, $this->userManager, 
131
			$this->notificationManager);
132
		$this->usersByDN[$dn]   = $user;
133
		$this->usersByUid[$uid] = $user;
134
		return $user;
135
	}
136
137
	/**
138
	 * removes a user entry from the cache
139
	 * @param $uid
140
	 */
141
	public function invalidate($uid) {
142
		if(!isset($this->usersByUid[$uid])) {
143
			return;
144
		}
145
		$dn = $this->usersByUid[$uid]->getDN();
146
		unset($this->usersByUid[$uid]);
147
		unset($this->usersByDN[$dn]);
148
	}
149
150
	/**
151
	 * @brief checks whether the Access instance has been set
152
	 * @throws \Exception if Access has not been set
153
	 * @return null
154
	 */
155
	private function checkAccess() {
156
		if(is_null($this->access)) {
157
			throw new \Exception('LDAP Access instance must be set first');
158
		}
159
	}
160
161
	/**
162
	 * returns a list of attributes that will be processed further, e.g. quota,
163
	 * email, displayname, or others.
164
	 * @param bool $minimal - optional, set to true to skip attributes with big
165
	 * payload
166
	 * @return string[]
167
	 */
168
	public function getAttributes($minimal = false) {
169
		$attributes = array('dn', 'uid', 'samaccountname', 'memberof');
170
		$possible = array(
171
			$this->access->getConnection()->ldapQuotaAttribute,
172
			$this->access->getConnection()->ldapEmailAttribute,
173
			$this->access->getConnection()->ldapUserDisplayName,
174
			$this->access->getConnection()->ldapUserDisplayName2,
175
		);
176
		foreach($possible as $attr) {
177
			if(!is_null($attr)) {
178
				$attributes[] = $attr;
179
			}
180
		}
181
182
		$homeRule = $this->access->getConnection()->homeFolderNamingRule;
183
		if(strpos($homeRule, 'attr:') === 0) {
184
			$attributes[] = substr($homeRule, strlen('attr:'));
185
		}
186
187
		if(!$minimal) {
188
			// attributes that are not really important but may come with big
189
			// payload.
190
			$attributes = array_merge($attributes, array(
191
				'jpegphoto',
192
				'thumbnailphoto'
193
			));
194
		}
195
196
		return $attributes;
197
	}
198
199
	/**
200
	 * Checks whether the specified user is marked as deleted
201
	 * @param string $id the Nextcloud user name
202
	 * @return bool
203
	 */
204
	public function isDeletedUser($id) {
205
		$isDeleted = $this->ocConfig->getUserValue(
206
			$id, 'user_ldap', 'isDeleted', 0);
207
		return intval($isDeleted) === 1;
208
	}
209
210
	/**
211
	 * creates and returns an instance of OfflineUser for the specified user
212
	 * @param string $id
213
	 * @return \OCA\User_LDAP\User\OfflineUser
214
	 */
215
	public function getDeletedUser($id) {
216
		return new OfflineUser(
217
			$id,
218
			$this->ocConfig,
219
			$this->db,
220
			$this->access->getUserMapper());
221
	}
222
223
	/**
224
	 * @brief returns a User object by it's Nextcloud username
225
	 * @param string $id the DN or username of the user
226
	 * @return \OCA\User_LDAP\User\User|\OCA\User_LDAP\User\OfflineUser|null
227
	 */
228
	protected function createInstancyByUserName($id) {
229
		//most likely a uid. Check whether it is a deleted user
230
		if($this->isDeletedUser($id)) {
231
			return $this->getDeletedUser($id);
232
		}
233
		$dn = $this->access->username2dn($id);
234
		if($dn !== false) {
235
			return $this->createAndCache($dn, $id);
236
		}
237
		return null;
238
	}
239
240
	/**
241
	 * @brief returns a User object by it's DN or Nextcloud username
242
	 * @param string $id the DN or username of the user
243
	 * @return \OCA\User_LDAP\User\User|\OCA\User_LDAP\User\OfflineUser|null
244
	 * @throws \Exception when connection could not be established
245
	 */
246
	public function get($id) {
247
		$this->checkAccess();
248
		if(isset($this->usersByDN[$id])) {
249
			return $this->usersByDN[$id];
250
		} else if(isset($this->usersByUid[$id])) {
251
			return $this->usersByUid[$id];
252
		}
253
254
		if($this->access->stringResemblesDN($id) ) {
255
			$uid = $this->access->dn2username($id);
256
			if($uid !== false) {
257
				return $this->createAndCache($id, $uid);
258
			}
259
		}
260
261
		return $this->createInstancyByUserName($id);
262
	}
263
264
}
265