Completed
Push — master ( af20f1...8ccb99 )
by Morris
78:09 queued 53:18
created
apps/user_ldap/lib/User/Manager.php 2 patches
Indentation   +194 added lines, -194 removed lines patch added patch discarded remove patch
@@ -45,224 +45,224 @@
 block discarded – undo
45 45
  * cache
46 46
  */
47 47
 class Manager {
48
-	/** @var IUserTools */
49
-	protected $access;
48
+    /** @var IUserTools */
49
+    protected $access;
50 50
 
51
-	/** @var IConfig */
52
-	protected $ocConfig;
51
+    /** @var IConfig */
52
+    protected $ocConfig;
53 53
 
54
-	/** @var IDBConnection */
55
-	protected $db;
54
+    /** @var IDBConnection */
55
+    protected $db;
56 56
 
57
-	/** @var IUserManager */
58
-	protected $userManager;
57
+    /** @var IUserManager */
58
+    protected $userManager;
59 59
 
60
-	/** @var INotificationManager */
61
-	protected $notificationManager;
60
+    /** @var INotificationManager */
61
+    protected $notificationManager;
62 62
 
63
-	/** @var FilesystemHelper */
64
-	protected $ocFilesystem;
63
+    /** @var FilesystemHelper */
64
+    protected $ocFilesystem;
65 65
 
66
-	/** @var LogWrapper */
67
-	protected $ocLog;
66
+    /** @var LogWrapper */
67
+    protected $ocLog;
68 68
 
69
-	/** @var Image */
70
-	protected $image;
69
+    /** @var Image */
70
+    protected $image;
71 71
 
72
-	/** @param \OCP\IAvatarManager */
73
-	protected $avatarManager;
72
+    /** @param \OCP\IAvatarManager */
73
+    protected $avatarManager;
74 74
 
75
-	/**
76
-	 * @var CappedMemoryCache $usersByDN
77
-	 */
78
-	protected $usersByDN;
79
-	/**
80
-	 * @var CappedMemoryCache $usersByUid
81
-	 */
82
-	protected $usersByUid;
75
+    /**
76
+     * @var CappedMemoryCache $usersByDN
77
+     */
78
+    protected $usersByDN;
79
+    /**
80
+     * @var CappedMemoryCache $usersByUid
81
+     */
82
+    protected $usersByUid;
83 83
 
84
-	/**
85
-	 * @param IConfig $ocConfig
86
-	 * @param \OCA\User_LDAP\FilesystemHelper $ocFilesystem object that
87
-	 * gives access to necessary functions from the OC filesystem
88
-	 * @param  \OCA\User_LDAP\LogWrapper $ocLog
89
-	 * @param IAvatarManager $avatarManager
90
-	 * @param Image $image an empty image instance
91
-	 * @param IDBConnection $db
92
-	 * @throws \Exception when the methods mentioned above do not exist
93
-	 */
94
-	public function __construct(IConfig $ocConfig,
95
-								FilesystemHelper $ocFilesystem, LogWrapper $ocLog,
96
-								IAvatarManager $avatarManager, Image $image,
97
-								IDBConnection $db, IUserManager $userManager,
98
-								INotificationManager $notificationManager) {
84
+    /**
85
+     * @param IConfig $ocConfig
86
+     * @param \OCA\User_LDAP\FilesystemHelper $ocFilesystem object that
87
+     * gives access to necessary functions from the OC filesystem
88
+     * @param  \OCA\User_LDAP\LogWrapper $ocLog
89
+     * @param IAvatarManager $avatarManager
90
+     * @param Image $image an empty image instance
91
+     * @param IDBConnection $db
92
+     * @throws \Exception when the methods mentioned above do not exist
93
+     */
94
+    public function __construct(IConfig $ocConfig,
95
+                                FilesystemHelper $ocFilesystem, LogWrapper $ocLog,
96
+                                IAvatarManager $avatarManager, Image $image,
97
+                                IDBConnection $db, IUserManager $userManager,
98
+                                INotificationManager $notificationManager) {
99 99
 
100
-		$this->ocConfig            = $ocConfig;
101
-		$this->ocFilesystem        = $ocFilesystem;
102
-		$this->ocLog               = $ocLog;
103
-		$this->avatarManager       = $avatarManager;
104
-		$this->image               = $image;
105
-		$this->db                  = $db;
106
-		$this->userManager         = $userManager;
107
-		$this->notificationManager = $notificationManager;
108
-		$this->usersByDN           = new CappedMemoryCache();
109
-		$this->usersByUid          = new CappedMemoryCache();
110
-	}
100
+        $this->ocConfig            = $ocConfig;
101
+        $this->ocFilesystem        = $ocFilesystem;
102
+        $this->ocLog               = $ocLog;
103
+        $this->avatarManager       = $avatarManager;
104
+        $this->image               = $image;
105
+        $this->db                  = $db;
106
+        $this->userManager         = $userManager;
107
+        $this->notificationManager = $notificationManager;
108
+        $this->usersByDN           = new CappedMemoryCache();
109
+        $this->usersByUid          = new CappedMemoryCache();
110
+    }
111 111
 
112
-	/**
113
-	 * @brief binds manager to an instance of IUserTools (implemented by
114
-	 * Access). It needs to be assigned first before the manager can be used.
115
-	 * @param IUserTools
116
-	 */
117
-	public function setLdapAccess(IUserTools $access) {
118
-		$this->access = $access;
119
-	}
112
+    /**
113
+     * @brief binds manager to an instance of IUserTools (implemented by
114
+     * Access). It needs to be assigned first before the manager can be used.
115
+     * @param IUserTools
116
+     */
117
+    public function setLdapAccess(IUserTools $access) {
118
+        $this->access = $access;
119
+    }
120 120
 
121
-	/**
122
-	 * @brief creates an instance of User and caches (just runtime) it in the
123
-	 * property array
124
-	 * @param string $dn the DN of the user
125
-	 * @param string $uid the internal (owncloud) username
126
-	 * @return \OCA\User_LDAP\User\User
127
-	 */
128
-	private function createAndCache($dn, $uid) {
129
-		$this->checkAccess();
130
-		$user = new User($uid, $dn, $this->access, $this->ocConfig,
131
-			$this->ocFilesystem, clone $this->image, $this->ocLog,
132
-			$this->avatarManager, $this->userManager, 
133
-			$this->notificationManager);
134
-		$this->usersByDN[$dn]   = $user;
135
-		$this->usersByUid[$uid] = $user;
136
-		return $user;
137
-	}
121
+    /**
122
+     * @brief creates an instance of User and caches (just runtime) it in the
123
+     * property array
124
+     * @param string $dn the DN of the user
125
+     * @param string $uid the internal (owncloud) username
126
+     * @return \OCA\User_LDAP\User\User
127
+     */
128
+    private function createAndCache($dn, $uid) {
129
+        $this->checkAccess();
130
+        $user = new User($uid, $dn, $this->access, $this->ocConfig,
131
+            $this->ocFilesystem, clone $this->image, $this->ocLog,
132
+            $this->avatarManager, $this->userManager, 
133
+            $this->notificationManager);
134
+        $this->usersByDN[$dn]   = $user;
135
+        $this->usersByUid[$uid] = $user;
136
+        return $user;
137
+    }
138 138
 
139
-	/**
140
-	 * removes a user entry from the cache
141
-	 * @param $uid
142
-	 */
143
-	public function invalidate($uid) {
144
-		if(!isset($this->usersByUid[$uid])) {
145
-			return;
146
-		}
147
-		$dn = $this->usersByUid[$uid]->getDN();
148
-		unset($this->usersByUid[$uid]);
149
-		unset($this->usersByDN[$dn]);
150
-	}
139
+    /**
140
+     * removes a user entry from the cache
141
+     * @param $uid
142
+     */
143
+    public function invalidate($uid) {
144
+        if(!isset($this->usersByUid[$uid])) {
145
+            return;
146
+        }
147
+        $dn = $this->usersByUid[$uid]->getDN();
148
+        unset($this->usersByUid[$uid]);
149
+        unset($this->usersByDN[$dn]);
150
+    }
151 151
 
152
-	/**
153
-	 * @brief checks whether the Access instance has been set
154
-	 * @throws \Exception if Access has not been set
155
-	 * @return null
156
-	 */
157
-	private function checkAccess() {
158
-		if(is_null($this->access)) {
159
-			throw new \Exception('LDAP Access instance must be set first');
160
-		}
161
-	}
152
+    /**
153
+     * @brief checks whether the Access instance has been set
154
+     * @throws \Exception if Access has not been set
155
+     * @return null
156
+     */
157
+    private function checkAccess() {
158
+        if(is_null($this->access)) {
159
+            throw new \Exception('LDAP Access instance must be set first');
160
+        }
161
+    }
162 162
 
163
-	/**
164
-	 * returns a list of attributes that will be processed further, e.g. quota,
165
-	 * email, displayname, or others.
166
-	 *
167
-	 * @param bool $minimal - optional, set to true to skip attributes with big
168
-	 * payload
169
-	 * @return string[]
170
-	 */
171
-	public function getAttributes($minimal = false) {
172
-		$attributes = array_merge(Access::UUID_ATTRIBUTES, ['dn', 'uid', 'samaccountname', 'memberof']);
173
-		$possible = array(
174
-			$this->access->getConnection()->ldapExpertUUIDUserAttr,
175
-			$this->access->getConnection()->ldapQuotaAttribute,
176
-			$this->access->getConnection()->ldapEmailAttribute,
177
-			$this->access->getConnection()->ldapUserDisplayName,
178
-			$this->access->getConnection()->ldapUserDisplayName2,
179
-		);
180
-		foreach($possible as $attr) {
181
-			if(!is_null($attr)) {
182
-				$attributes[] = $attr;
183
-			}
184
-		}
163
+    /**
164
+     * returns a list of attributes that will be processed further, e.g. quota,
165
+     * email, displayname, or others.
166
+     *
167
+     * @param bool $minimal - optional, set to true to skip attributes with big
168
+     * payload
169
+     * @return string[]
170
+     */
171
+    public function getAttributes($minimal = false) {
172
+        $attributes = array_merge(Access::UUID_ATTRIBUTES, ['dn', 'uid', 'samaccountname', 'memberof']);
173
+        $possible = array(
174
+            $this->access->getConnection()->ldapExpertUUIDUserAttr,
175
+            $this->access->getConnection()->ldapQuotaAttribute,
176
+            $this->access->getConnection()->ldapEmailAttribute,
177
+            $this->access->getConnection()->ldapUserDisplayName,
178
+            $this->access->getConnection()->ldapUserDisplayName2,
179
+        );
180
+        foreach($possible as $attr) {
181
+            if(!is_null($attr)) {
182
+                $attributes[] = $attr;
183
+            }
184
+        }
185 185
 
186
-		$homeRule = $this->access->getConnection()->homeFolderNamingRule;
187
-		if(strpos($homeRule, 'attr:') === 0) {
188
-			$attributes[] = substr($homeRule, strlen('attr:'));
189
-		}
186
+        $homeRule = $this->access->getConnection()->homeFolderNamingRule;
187
+        if(strpos($homeRule, 'attr:') === 0) {
188
+            $attributes[] = substr($homeRule, strlen('attr:'));
189
+        }
190 190
 
191
-		if(!$minimal) {
192
-			// attributes that are not really important but may come with big
193
-			// payload.
194
-			$attributes = array_merge(
195
-				$attributes,
196
-				$this->access->getConnection()->resolveRule('avatar')
197
-			);
198
-		}
191
+        if(!$minimal) {
192
+            // attributes that are not really important but may come with big
193
+            // payload.
194
+            $attributes = array_merge(
195
+                $attributes,
196
+                $this->access->getConnection()->resolveRule('avatar')
197
+            );
198
+        }
199 199
 
200
-		return $attributes;
201
-	}
200
+        return $attributes;
201
+    }
202 202
 
203
-	/**
204
-	 * Checks whether the specified user is marked as deleted
205
-	 * @param string $id the Nextcloud user name
206
-	 * @return bool
207
-	 */
208
-	public function isDeletedUser($id) {
209
-		$isDeleted = $this->ocConfig->getUserValue(
210
-			$id, 'user_ldap', 'isDeleted', 0);
211
-		return (int)$isDeleted === 1;
212
-	}
203
+    /**
204
+     * Checks whether the specified user is marked as deleted
205
+     * @param string $id the Nextcloud user name
206
+     * @return bool
207
+     */
208
+    public function isDeletedUser($id) {
209
+        $isDeleted = $this->ocConfig->getUserValue(
210
+            $id, 'user_ldap', 'isDeleted', 0);
211
+        return (int)$isDeleted === 1;
212
+    }
213 213
 
214
-	/**
215
-	 * creates and returns an instance of OfflineUser for the specified user
216
-	 * @param string $id
217
-	 * @return \OCA\User_LDAP\User\OfflineUser
218
-	 */
219
-	public function getDeletedUser($id) {
220
-		return new OfflineUser(
221
-			$id,
222
-			$this->ocConfig,
223
-			$this->db,
224
-			$this->access->getUserMapper());
225
-	}
214
+    /**
215
+     * creates and returns an instance of OfflineUser for the specified user
216
+     * @param string $id
217
+     * @return \OCA\User_LDAP\User\OfflineUser
218
+     */
219
+    public function getDeletedUser($id) {
220
+        return new OfflineUser(
221
+            $id,
222
+            $this->ocConfig,
223
+            $this->db,
224
+            $this->access->getUserMapper());
225
+    }
226 226
 
227
-	/**
228
-	 * @brief returns a User object by it's Nextcloud username
229
-	 * @param string $id the DN or username of the user
230
-	 * @return \OCA\User_LDAP\User\User|\OCA\User_LDAP\User\OfflineUser|null
231
-	 */
232
-	protected function createInstancyByUserName($id) {
233
-		//most likely a uid. Check whether it is a deleted user
234
-		if($this->isDeletedUser($id)) {
235
-			return $this->getDeletedUser($id);
236
-		}
237
-		$dn = $this->access->username2dn($id);
238
-		if($dn !== false) {
239
-			return $this->createAndCache($dn, $id);
240
-		}
241
-		return null;
242
-	}
227
+    /**
228
+     * @brief returns a User object by it's Nextcloud username
229
+     * @param string $id the DN or username of the user
230
+     * @return \OCA\User_LDAP\User\User|\OCA\User_LDAP\User\OfflineUser|null
231
+     */
232
+    protected function createInstancyByUserName($id) {
233
+        //most likely a uid. Check whether it is a deleted user
234
+        if($this->isDeletedUser($id)) {
235
+            return $this->getDeletedUser($id);
236
+        }
237
+        $dn = $this->access->username2dn($id);
238
+        if($dn !== false) {
239
+            return $this->createAndCache($dn, $id);
240
+        }
241
+        return null;
242
+    }
243 243
 
244
-	/**
245
-	 * @brief returns a User object by it's DN or Nextcloud username
246
-	 * @param string $id the DN or username of the user
247
-	 * @return \OCA\User_LDAP\User\User|\OCA\User_LDAP\User\OfflineUser|null
248
-	 * @throws \Exception when connection could not be established
249
-	 */
250
-	public function get($id) {
251
-		$this->checkAccess();
252
-		if(isset($this->usersByDN[$id])) {
253
-			return $this->usersByDN[$id];
254
-		} else if(isset($this->usersByUid[$id])) {
255
-			return $this->usersByUid[$id];
256
-		}
244
+    /**
245
+     * @brief returns a User object by it's DN or Nextcloud username
246
+     * @param string $id the DN or username of the user
247
+     * @return \OCA\User_LDAP\User\User|\OCA\User_LDAP\User\OfflineUser|null
248
+     * @throws \Exception when connection could not be established
249
+     */
250
+    public function get($id) {
251
+        $this->checkAccess();
252
+        if(isset($this->usersByDN[$id])) {
253
+            return $this->usersByDN[$id];
254
+        } else if(isset($this->usersByUid[$id])) {
255
+            return $this->usersByUid[$id];
256
+        }
257 257
 
258
-		if($this->access->stringResemblesDN($id) ) {
259
-			$uid = $this->access->dn2username($id);
260
-			if($uid !== false) {
261
-				return $this->createAndCache($id, $uid);
262
-			}
263
-		}
258
+        if($this->access->stringResemblesDN($id) ) {
259
+            $uid = $this->access->dn2username($id);
260
+            if($uid !== false) {
261
+                return $this->createAndCache($id, $uid);
262
+            }
263
+        }
264 264
 
265
-		return $this->createInstancyByUserName($id);
266
-	}
265
+        return $this->createInstancyByUserName($id);
266
+    }
267 267
 
268 268
 }
Please login to merge, or discard this patch.
Spacing   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -141,7 +141,7 @@  discard block
 block discarded – undo
141 141
 	 * @param $uid
142 142
 	 */
143 143
 	public function invalidate($uid) {
144
-		if(!isset($this->usersByUid[$uid])) {
144
+		if (!isset($this->usersByUid[$uid])) {
145 145
 			return;
146 146
 		}
147 147
 		$dn = $this->usersByUid[$uid]->getDN();
@@ -155,7 +155,7 @@  discard block
 block discarded – undo
155 155
 	 * @return null
156 156
 	 */
157 157
 	private function checkAccess() {
158
-		if(is_null($this->access)) {
158
+		if (is_null($this->access)) {
159 159
 			throw new \Exception('LDAP Access instance must be set first');
160 160
 		}
161 161
 	}
@@ -177,18 +177,18 @@  discard block
 block discarded – undo
177 177
 			$this->access->getConnection()->ldapUserDisplayName,
178 178
 			$this->access->getConnection()->ldapUserDisplayName2,
179 179
 		);
180
-		foreach($possible as $attr) {
181
-			if(!is_null($attr)) {
180
+		foreach ($possible as $attr) {
181
+			if (!is_null($attr)) {
182 182
 				$attributes[] = $attr;
183 183
 			}
184 184
 		}
185 185
 
186 186
 		$homeRule = $this->access->getConnection()->homeFolderNamingRule;
187
-		if(strpos($homeRule, 'attr:') === 0) {
187
+		if (strpos($homeRule, 'attr:') === 0) {
188 188
 			$attributes[] = substr($homeRule, strlen('attr:'));
189 189
 		}
190 190
 
191
-		if(!$minimal) {
191
+		if (!$minimal) {
192 192
 			// attributes that are not really important but may come with big
193 193
 			// payload.
194 194
 			$attributes = array_merge(
@@ -208,7 +208,7 @@  discard block
 block discarded – undo
208 208
 	public function isDeletedUser($id) {
209 209
 		$isDeleted = $this->ocConfig->getUserValue(
210 210
 			$id, 'user_ldap', 'isDeleted', 0);
211
-		return (int)$isDeleted === 1;
211
+		return (int) $isDeleted === 1;
212 212
 	}
213 213
 
214 214
 	/**
@@ -231,11 +231,11 @@  discard block
 block discarded – undo
231 231
 	 */
232 232
 	protected function createInstancyByUserName($id) {
233 233
 		//most likely a uid. Check whether it is a deleted user
234
-		if($this->isDeletedUser($id)) {
234
+		if ($this->isDeletedUser($id)) {
235 235
 			return $this->getDeletedUser($id);
236 236
 		}
237 237
 		$dn = $this->access->username2dn($id);
238
-		if($dn !== false) {
238
+		if ($dn !== false) {
239 239
 			return $this->createAndCache($dn, $id);
240 240
 		}
241 241
 		return null;
@@ -249,15 +249,15 @@  discard block
 block discarded – undo
249 249
 	 */
250 250
 	public function get($id) {
251 251
 		$this->checkAccess();
252
-		if(isset($this->usersByDN[$id])) {
252
+		if (isset($this->usersByDN[$id])) {
253 253
 			return $this->usersByDN[$id];
254
-		} else if(isset($this->usersByUid[$id])) {
254
+		} else if (isset($this->usersByUid[$id])) {
255 255
 			return $this->usersByUid[$id];
256 256
 		}
257 257
 
258
-		if($this->access->stringResemblesDN($id) ) {
258
+		if ($this->access->stringResemblesDN($id)) {
259 259
 			$uid = $this->access->dn2username($id);
260
-			if($uid !== false) {
260
+			if ($uid !== false) {
261 261
 				return $this->createAndCache($id, $uid);
262 262
 			}
263 263
 		}
Please login to merge, or discard this patch.
apps/user_ldap/lib/User/User.php 2 patches
Indentation   +648 added lines, -648 removed lines patch added patch discarded remove patch
@@ -47,658 +47,658 @@
 block discarded – undo
47 47
  * represents an LDAP user, gets and holds user-specific information from LDAP
48 48
  */
49 49
 class User {
50
-	/**
51
-	 * @var IUserTools
52
-	 */
53
-	protected $access;
54
-	/**
55
-	 * @var Connection
56
-	 */
57
-	protected $connection;
58
-	/**
59
-	 * @var IConfig
60
-	 */
61
-	protected $config;
62
-	/**
63
-	 * @var FilesystemHelper
64
-	 */
65
-	protected $fs;
66
-	/**
67
-	 * @var Image
68
-	 */
69
-	protected $image;
70
-	/**
71
-	 * @var LogWrapper
72
-	 */
73
-	protected $log;
74
-	/**
75
-	 * @var IAvatarManager
76
-	 */
77
-	protected $avatarManager;
78
-	/**
79
-	 * @var IUserManager
80
-	 */
81
-	protected $userManager;
82
-	/**
83
-	 * @var INotificationManager
84
-	 */
85
-	protected $notificationManager;
86
-	/**
87
-	 * @var string
88
-	 */
89
-	protected $dn;
90
-	/**
91
-	 * @var string
92
-	 */
93
-	protected $uid;
94
-	/**
95
-	 * @var string[]
96
-	 */
97
-	protected $refreshedFeatures = array();
98
-	/**
99
-	 * @var string
100
-	 */
101
-	protected $avatarImage;
102
-
103
-	/**
104
-	 * DB config keys for user preferences
105
-	 */
106
-	const USER_PREFKEY_FIRSTLOGIN  = 'firstLoginAccomplished';
107
-	const USER_PREFKEY_LASTREFRESH = 'lastFeatureRefresh';
108
-
109
-	/**
110
-	 * @brief constructor, make sure the subclasses call this one!
111
-	 * @param string $username the internal username
112
-	 * @param string $dn the LDAP DN
113
-	 * @param IUserTools $access an instance that implements IUserTools for
114
-	 * LDAP interaction
115
-	 * @param IConfig $config
116
-	 * @param FilesystemHelper $fs
117
-	 * @param Image $image any empty instance
118
-	 * @param LogWrapper $log
119
-	 * @param IAvatarManager $avatarManager
120
-	 * @param IUserManager $userManager
121
-	 * @param INotificationManager $notificationManager
122
-	 */
123
-	public function __construct($username, $dn, IUserTools $access,
124
-		IConfig $config, FilesystemHelper $fs, Image $image,
125
-		LogWrapper $log, IAvatarManager $avatarManager, IUserManager $userManager,
126
-		INotificationManager $notificationManager) {
50
+    /**
51
+     * @var IUserTools
52
+     */
53
+    protected $access;
54
+    /**
55
+     * @var Connection
56
+     */
57
+    protected $connection;
58
+    /**
59
+     * @var IConfig
60
+     */
61
+    protected $config;
62
+    /**
63
+     * @var FilesystemHelper
64
+     */
65
+    protected $fs;
66
+    /**
67
+     * @var Image
68
+     */
69
+    protected $image;
70
+    /**
71
+     * @var LogWrapper
72
+     */
73
+    protected $log;
74
+    /**
75
+     * @var IAvatarManager
76
+     */
77
+    protected $avatarManager;
78
+    /**
79
+     * @var IUserManager
80
+     */
81
+    protected $userManager;
82
+    /**
83
+     * @var INotificationManager
84
+     */
85
+    protected $notificationManager;
86
+    /**
87
+     * @var string
88
+     */
89
+    protected $dn;
90
+    /**
91
+     * @var string
92
+     */
93
+    protected $uid;
94
+    /**
95
+     * @var string[]
96
+     */
97
+    protected $refreshedFeatures = array();
98
+    /**
99
+     * @var string
100
+     */
101
+    protected $avatarImage;
102
+
103
+    /**
104
+     * DB config keys for user preferences
105
+     */
106
+    const USER_PREFKEY_FIRSTLOGIN  = 'firstLoginAccomplished';
107
+    const USER_PREFKEY_LASTREFRESH = 'lastFeatureRefresh';
108
+
109
+    /**
110
+     * @brief constructor, make sure the subclasses call this one!
111
+     * @param string $username the internal username
112
+     * @param string $dn the LDAP DN
113
+     * @param IUserTools $access an instance that implements IUserTools for
114
+     * LDAP interaction
115
+     * @param IConfig $config
116
+     * @param FilesystemHelper $fs
117
+     * @param Image $image any empty instance
118
+     * @param LogWrapper $log
119
+     * @param IAvatarManager $avatarManager
120
+     * @param IUserManager $userManager
121
+     * @param INotificationManager $notificationManager
122
+     */
123
+    public function __construct($username, $dn, IUserTools $access,
124
+        IConfig $config, FilesystemHelper $fs, Image $image,
125
+        LogWrapper $log, IAvatarManager $avatarManager, IUserManager $userManager,
126
+        INotificationManager $notificationManager) {
127 127
 	
128
-		if ($username === null) {
129
-			$log->log("uid for '$dn' must not be null!", ILogger::ERROR);
130
-			throw new \InvalidArgumentException('uid must not be null!');
131
-		} else if ($username === '') {
132
-			$log->log("uid for '$dn' must not be an empty string", ILogger::ERROR);
133
-			throw new \InvalidArgumentException('uid must not be an empty string!');
134
-		}
135
-
136
-		$this->access              = $access;
137
-		$this->connection          = $access->getConnection();
138
-		$this->config              = $config;
139
-		$this->fs                  = $fs;
140
-		$this->dn                  = $dn;
141
-		$this->uid                 = $username;
142
-		$this->image               = $image;
143
-		$this->log                 = $log;
144
-		$this->avatarManager       = $avatarManager;
145
-		$this->userManager         = $userManager;
146
-		$this->notificationManager = $notificationManager;
147
-
148
-		\OCP\Util::connectHook('OC_User', 'post_login', $this, 'handlePasswordExpiry');
149
-	}
150
-
151
-	/**
152
-	 * @brief updates properties like email, quota or avatar provided by LDAP
153
-	 * @return null
154
-	 */
155
-	public function update() {
156
-		if(is_null($this->dn)) {
157
-			return null;
158
-		}
159
-
160
-		$hasLoggedIn = $this->config->getUserValue($this->uid, 'user_ldap',
161
-				self::USER_PREFKEY_FIRSTLOGIN, 0);
162
-
163
-		if($this->needsRefresh()) {
164
-			$this->updateEmail();
165
-			$this->updateQuota();
166
-			if($hasLoggedIn !== 0) {
167
-				//we do not need to try it, when the user has not been logged in
168
-				//before, because the file system will not be ready.
169
-				$this->updateAvatar();
170
-				//in order to get an avatar as soon as possible, mark the user
171
-				//as refreshed only when updating the avatar did happen
172
-				$this->markRefreshTime();
173
-			}
174
-		}
175
-	}
176
-
177
-	/**
178
-	 * processes results from LDAP for attributes as returned by getAttributesToRead()
179
-	 * @param array $ldapEntry the user entry as retrieved from LDAP
180
-	 */
181
-	public function processAttributes($ldapEntry) {
182
-		$this->markRefreshTime();
183
-		//Quota
184
-		$attr = strtolower($this->connection->ldapQuotaAttribute);
185
-		if(isset($ldapEntry[$attr])) {
186
-			$this->updateQuota($ldapEntry[$attr][0]);
187
-		} else {
188
-			if ($this->connection->ldapQuotaDefault !== '') {
189
-				$this->updateQuota();
190
-			}
191
-		}
192
-		unset($attr);
193
-
194
-		//displayName
195
-		$displayName = $displayName2 = '';
196
-		$attr = strtolower($this->connection->ldapUserDisplayName);
197
-		if(isset($ldapEntry[$attr])) {
198
-			$displayName = (string)$ldapEntry[$attr][0];
199
-		}
200
-		$attr = strtolower($this->connection->ldapUserDisplayName2);
201
-		if(isset($ldapEntry[$attr])) {
202
-			$displayName2 = (string)$ldapEntry[$attr][0];
203
-		}
204
-		if ($displayName !== '') {
205
-			$this->composeAndStoreDisplayName($displayName);
206
-			$this->access->cacheUserDisplayName(
207
-				$this->getUsername(),
208
-				$displayName,
209
-				$displayName2
210
-			);
211
-		}
212
-		unset($attr);
213
-
214
-		//Email
215
-		//email must be stored after displayname, because it would cause a user
216
-		//change event that will trigger fetching the display name again
217
-		$attr = strtolower($this->connection->ldapEmailAttribute);
218
-		if(isset($ldapEntry[$attr])) {
219
-			$this->updateEmail($ldapEntry[$attr][0]);
220
-		}
221
-		unset($attr);
222
-
223
-		// LDAP Username, needed for s2s sharing
224
-		if(isset($ldapEntry['uid'])) {
225
-			$this->storeLDAPUserName($ldapEntry['uid'][0]);
226
-		} else if(isset($ldapEntry['samaccountname'])) {
227
-			$this->storeLDAPUserName($ldapEntry['samaccountname'][0]);
228
-		}
229
-
230
-		//homePath
231
-		if(strpos($this->connection->homeFolderNamingRule, 'attr:') === 0) {
232
-			$attr = strtolower(substr($this->connection->homeFolderNamingRule, strlen('attr:')));
233
-			if(isset($ldapEntry[$attr])) {
234
-				$this->access->cacheUserHome(
235
-					$this->getUsername(), $this->getHomePath($ldapEntry[$attr][0]));
236
-			}
237
-		}
238
-
239
-		//memberOf groups
240
-		$cacheKey = 'getMemberOf'.$this->getUsername();
241
-		$groups = false;
242
-		if(isset($ldapEntry['memberof'])) {
243
-			$groups = $ldapEntry['memberof'];
244
-		}
245
-		$this->connection->writeToCache($cacheKey, $groups);
246
-
247
-		//Avatar
248
-		/** @var Connection $connection */
249
-		$connection = $this->access->getConnection();
250
-		$attributes = $connection->resolveRule('avatar');
251
-		foreach ($attributes as $attribute)  {
252
-			if(isset($ldapEntry[$attribute])) {
253
-				$this->avatarImage = $ldapEntry[$attribute][0];
254
-				// the call to the method that saves the avatar in the file
255
-				// system must be postponed after the login. It is to ensure
256
-				// external mounts are mounted properly (e.g. with login
257
-				// credentials from the session).
258
-				\OCP\Util::connectHook('OC_User', 'post_login', $this, 'updateAvatarPostLogin');
259
-				break;
260
-			}
261
-		}
262
-	}
263
-
264
-	/**
265
-	 * @brief returns the LDAP DN of the user
266
-	 * @return string
267
-	 */
268
-	public function getDN() {
269
-		return $this->dn;
270
-	}
271
-
272
-	/**
273
-	 * @brief returns the Nextcloud internal username of the user
274
-	 * @return string
275
-	 */
276
-	public function getUsername() {
277
-		return $this->uid;
278
-	}
279
-
280
-	/**
281
-	 * returns the home directory of the user if specified by LDAP settings
282
-	 * @param string $valueFromLDAP
283
-	 * @return bool|string
284
-	 * @throws \Exception
285
-	 */
286
-	public function getHomePath($valueFromLDAP = null) {
287
-		$path = (string)$valueFromLDAP;
288
-		$attr = null;
289
-
290
-		if (is_null($valueFromLDAP)
291
-		   && strpos($this->access->connection->homeFolderNamingRule, 'attr:') === 0
292
-		   && $this->access->connection->homeFolderNamingRule !== 'attr:')
293
-		{
294
-			$attr = substr($this->access->connection->homeFolderNamingRule, strlen('attr:'));
295
-			$homedir = $this->access->readAttribute(
296
-				$this->access->username2dn($this->getUsername()), $attr);
297
-			if ($homedir && isset($homedir[0])) {
298
-				$path = $homedir[0];
299
-			}
300
-		}
301
-
302
-		if ($path !== '') {
303
-			//if attribute's value is an absolute path take this, otherwise append it to data dir
304
-			//check for / at the beginning or pattern c:\ resp. c:/
305
-			if(   '/' !== $path[0]
306
-			   && !(3 < strlen($path) && ctype_alpha($path[0])
307
-			       && $path[1] === ':' && ('\\' === $path[2] || '/' === $path[2]))
308
-			) {
309
-				$path = $this->config->getSystemValue('datadirectory',
310
-						\OC::$SERVERROOT.'/data' ) . '/' . $path;
311
-			}
312
-			//we need it to store it in the DB as well in case a user gets
313
-			//deleted so we can clean up afterwards
314
-			$this->config->setUserValue(
315
-				$this->getUsername(), 'user_ldap', 'homePath', $path
316
-			);
317
-			return $path;
318
-		}
319
-
320
-		if(    !is_null($attr)
321
-			&& $this->config->getAppValue('user_ldap', 'enforce_home_folder_naming_rule', true)
322
-		) {
323
-			// a naming rule attribute is defined, but it doesn't exist for that LDAP user
324
-			throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: ' . $this->getUsername());
325
-		}
326
-
327
-		//false will apply default behaviour as defined and done by OC_User
328
-		$this->config->setUserValue($this->getUsername(), 'user_ldap', 'homePath', '');
329
-		return false;
330
-	}
331
-
332
-	public function getMemberOfGroups() {
333
-		$cacheKey = 'getMemberOf'.$this->getUsername();
334
-		$memberOfGroups = $this->connection->getFromCache($cacheKey);
335
-		if(!is_null($memberOfGroups)) {
336
-			return $memberOfGroups;
337
-		}
338
-		$groupDNs = $this->access->readAttribute($this->getDN(), 'memberOf');
339
-		$this->connection->writeToCache($cacheKey, $groupDNs);
340
-		return $groupDNs;
341
-	}
342
-
343
-	/**
344
-	 * @brief reads the image from LDAP that shall be used as Avatar
345
-	 * @return string data (provided by LDAP) | false
346
-	 */
347
-	public function getAvatarImage() {
348
-		if(!is_null($this->avatarImage)) {
349
-			return $this->avatarImage;
350
-		}
351
-
352
-		$this->avatarImage = false;
353
-		/** @var Connection $connection */
354
-		$connection = $this->access->getConnection();
355
-		$attributes = $connection->resolveRule('avatar');
356
-		foreach($attributes as $attribute) {
357
-			$result = $this->access->readAttribute($this->dn, $attribute);
358
-			if($result !== false && is_array($result) && isset($result[0])) {
359
-				$this->avatarImage = $result[0];
360
-				break;
361
-			}
362
-		}
363
-
364
-		return $this->avatarImage;
365
-	}
366
-
367
-	/**
368
-	 * @brief marks the user as having logged in at least once
369
-	 * @return null
370
-	 */
371
-	public function markLogin() {
372
-		$this->config->setUserValue(
373
-			$this->uid, 'user_ldap', self::USER_PREFKEY_FIRSTLOGIN, 1);
374
-	}
375
-
376
-	/**
377
-	 * @brief marks the time when user features like email have been updated
378
-	 * @return null
379
-	 */
380
-	public function markRefreshTime() {
381
-		$this->config->setUserValue(
382
-			$this->uid, 'user_ldap', self::USER_PREFKEY_LASTREFRESH, time());
383
-	}
384
-
385
-	/**
386
-	 * @brief checks whether user features needs to be updated again by
387
-	 * comparing the difference of time of the last refresh to now with the
388
-	 * desired interval
389
-	 * @return bool
390
-	 */
391
-	private function needsRefresh() {
392
-		$lastChecked = $this->config->getUserValue($this->uid, 'user_ldap',
393
-			self::USER_PREFKEY_LASTREFRESH, 0);
394
-
395
-		if((time() - (int)$lastChecked) < (int)$this->config->getAppValue('user_ldap', 'updateAttributesInterval', 86400)) {
396
-			return false;
397
-		}
398
-		return  true;
399
-	}
400
-
401
-	/**
402
-	 * Stores a key-value pair in relation to this user
403
-	 *
404
-	 * @param string $key
405
-	 * @param string $value
406
-	 */
407
-	private function store($key, $value) {
408
-		$this->config->setUserValue($this->uid, 'user_ldap', $key, $value);
409
-	}
410
-
411
-	/**
412
-	 * Composes the display name and stores it in the database. The final
413
-	 * display name is returned.
414
-	 *
415
-	 * @param string $displayName
416
-	 * @param string $displayName2
417
-	 * @returns string the effective display name
418
-	 */
419
-	public function composeAndStoreDisplayName($displayName, $displayName2 = '') {
420
-		$displayName2 = (string)$displayName2;
421
-		if($displayName2 !== '') {
422
-			$displayName .= ' (' . $displayName2 . ')';
423
-		}
424
-		$this->store('displayName', $displayName);
425
-		return $displayName;
426
-	}
427
-
428
-	/**
429
-	 * Stores the LDAP Username in the Database
430
-	 * @param string $userName
431
-	 */
432
-	public function storeLDAPUserName($userName) {
433
-		$this->store('uid', $userName);
434
-	}
435
-
436
-	/**
437
-	 * @brief checks whether an update method specified by feature was run
438
-	 * already. If not, it will marked like this, because it is expected that
439
-	 * the method will be run, when false is returned.
440
-	 * @param string $feature email | quota | avatar (can be extended)
441
-	 * @return bool
442
-	 */
443
-	private function wasRefreshed($feature) {
444
-		if(isset($this->refreshedFeatures[$feature])) {
445
-			return true;
446
-		}
447
-		$this->refreshedFeatures[$feature] = 1;
448
-		return false;
449
-	}
450
-
451
-	/**
452
-	 * fetches the email from LDAP and stores it as Nextcloud user value
453
-	 * @param string $valueFromLDAP if known, to save an LDAP read request
454
-	 * @return null
455
-	 */
456
-	public function updateEmail($valueFromLDAP = null) {
457
-		if($this->wasRefreshed('email')) {
458
-			return;
459
-		}
460
-		$email = (string)$valueFromLDAP;
461
-		if(is_null($valueFromLDAP)) {
462
-			$emailAttribute = $this->connection->ldapEmailAttribute;
463
-			if ($emailAttribute !== '') {
464
-				$aEmail = $this->access->readAttribute($this->dn, $emailAttribute);
465
-				if(is_array($aEmail) && (count($aEmail) > 0)) {
466
-					$email = (string)$aEmail[0];
467
-				}
468
-			}
469
-		}
470
-		if ($email !== '') {
471
-			$user = $this->userManager->get($this->uid);
472
-			if (!is_null($user)) {
473
-				$currentEmail = (string)$user->getEMailAddress();
474
-				if ($currentEmail !== $email) {
475
-					$user->setEMailAddress($email);
476
-				}
477
-			}
478
-		}
479
-	}
480
-
481
-	/**
482
-	 * Overall process goes as follow:
483
-	 * 1. fetch the quota from LDAP and check if it's parseable with the "verifyQuotaValue" function
484
-	 * 2. if the value can't be fetched, is empty or not parseable, use the default LDAP quota
485
-	 * 3. if the default LDAP quota can't be parsed, use the Nextcloud's default quota (use 'default')
486
-	 * 4. check if the target user exists and set the quota for the user.
487
-	 *
488
-	 * In order to improve performance and prevent an unwanted extra LDAP call, the $valueFromLDAP
489
-	 * parameter can be passed with the value of the attribute. This value will be considered as the
490
-	 * quota for the user coming from the LDAP server (step 1 of the process) It can be useful to
491
-	 * fetch all the user's attributes in one call and use the fetched values in this function.
492
-	 * The expected value for that parameter is a string describing the quota for the user. Valid
493
-	 * values are 'none' (unlimited), 'default' (the Nextcloud's default quota), '1234' (quota in
494
-	 * bytes), '1234 MB' (quota in MB - check the \OC_Helper::computerFileSize method for more info)
495
-	 *
496
-	 * fetches the quota from LDAP and stores it as Nextcloud user value
497
-	 * @param string $valueFromLDAP the quota attribute's value can be passed,
498
-	 * to save the readAttribute request
499
-	 * @return null
500
-	 */
501
-	public function updateQuota($valueFromLDAP = null) {
502
-		if($this->wasRefreshed('quota')) {
503
-			return;
504
-		}
505
-
506
-		$quotaAttribute = $this->connection->ldapQuotaAttribute;
507
-		$defaultQuota = $this->connection->ldapQuotaDefault;
508
-		if($quotaAttribute === '' && $defaultQuota === '') {
509
-			return;
510
-		}
511
-
512
-		$quota = false;
513
-		if(is_null($valueFromLDAP) && $quotaAttribute !== '') {
514
-			$aQuota = $this->access->readAttribute($this->dn, $quotaAttribute);
515
-			if($aQuota && (count($aQuota) > 0) && $this->verifyQuotaValue($aQuota[0])) {
516
-				$quota = $aQuota[0];
517
-			} else if(is_array($aQuota) && isset($aQuota[0])) {
518
-				$this->log->log('no suitable LDAP quota found for user ' . $this->uid . ': [' . $aQuota[0] . ']', ILogger::DEBUG);
519
-			}
520
-		} else if ($this->verifyQuotaValue($valueFromLDAP)) {
521
-			$quota = $valueFromLDAP;
522
-		} else {
523
-			$this->log->log('no suitable LDAP quota found for user ' . $this->uid . ': [' . $valueFromLDAP . ']', ILogger::DEBUG);
524
-		}
525
-
526
-		if ($quota === false && $this->verifyQuotaValue($defaultQuota)) {
527
-			// quota not found using the LDAP attribute (or not parseable). Try the default quota
528
-			$quota = $defaultQuota;
529
-		} else if($quota === false) {
530
-			$this->log->log('no suitable default quota found for user ' . $this->uid . ': [' . $defaultQuota . ']', ILogger::DEBUG);
531
-			return;
532
-		}
533
-
534
-		$targetUser = $this->userManager->get($this->uid);
535
-		if ($targetUser instanceof IUser) {
536
-			$targetUser->setQuota($quota);
537
-		} else {
538
-			$this->log->log('trying to set a quota for user ' . $this->uid . ' but the user is missing', ILogger::INFO);
539
-		}
540
-	}
541
-
542
-	private function verifyQuotaValue($quotaValue) {
543
-		return $quotaValue === 'none' || $quotaValue === 'default' || \OC_Helper::computerFileSize($quotaValue) !== false;
544
-	}
545
-
546
-	/**
547
-	 * called by a post_login hook to save the avatar picture
548
-	 *
549
-	 * @param array $params
550
-	 */
551
-	public function updateAvatarPostLogin($params) {
552
-		if(isset($params['uid']) && $params['uid'] === $this->getUsername()) {
553
-			$this->updateAvatar();
554
-		}
555
-	}
556
-
557
-	/**
558
-	 * @brief attempts to get an image from LDAP and sets it as Nextcloud avatar
559
-	 * @return bool
560
-	 */
561
-	public function updateAvatar($force = false) {
562
-		if(!$force && $this->wasRefreshed('avatar')) {
563
-			return false;
564
-		}
565
-		$avatarImage = $this->getAvatarImage();
566
-		if($avatarImage === false) {
567
-			//not set, nothing left to do;
568
-			return false;
569
-		}
570
-		if(!$this->image->loadFromBase64(base64_encode($avatarImage))) {
571
-			return false;
572
-		}
573
-		return $this->setOwnCloudAvatar();
574
-	}
575
-
576
-	/**
577
-	 * @brief sets an image as Nextcloud avatar
578
-	 * @return bool
579
-	 */
580
-	private function setOwnCloudAvatar() {
581
-		if(!$this->image->valid()) {
582
-			$this->log->log('avatar image data from LDAP invalid for '.$this->dn, ILogger::ERROR);
583
-			return false;
584
-		}
585
-		//make sure it is a square and not bigger than 128x128
586
-		$size = min(array($this->image->width(), $this->image->height(), 128));
587
-		if(!$this->image->centerCrop($size)) {
588
-			$this->log->log('croping image for avatar failed for '.$this->dn, ILogger::ERROR);
589
-			return false;
590
-		}
591
-
592
-		if(!$this->fs->isLoaded()) {
593
-			$this->fs->setup($this->uid);
594
-		}
595
-
596
-		try {
597
-			$avatar = $this->avatarManager->getAvatar($this->uid);
598
-			$avatar->set($this->image);
599
-			return true;
600
-		} catch (\Exception $e) {
601
-			\OC::$server->getLogger()->logException($e, [
602
-				'message' => 'Could not set avatar for ' . $this->dn,
603
-				'level' => ILogger::INFO,
604
-				'app' => 'user_ldap',
605
-			]);
606
-		}
607
-		return false;
608
-	}
609
-
610
-	/**
611
-	 * called by a post_login hook to handle password expiry
612
-	 *
613
-	 * @param array $params
614
-	 */
615
-	public function handlePasswordExpiry($params) {
616
-		$ppolicyDN = $this->connection->ldapDefaultPPolicyDN;
617
-		if (empty($ppolicyDN) || ((int)$this->connection->turnOnPasswordChange !== 1)) {
618
-			return;//password expiry handling disabled
619
-		}
620
-		$uid = $params['uid'];
621
-		if(isset($uid) && $uid === $this->getUsername()) {
622
-			//retrieve relevant user attributes
623
-			$result = $this->access->search('objectclass=*', array($this->dn), ['pwdpolicysubentry', 'pwdgraceusetime', 'pwdreset', 'pwdchangedtime']);
128
+        if ($username === null) {
129
+            $log->log("uid for '$dn' must not be null!", ILogger::ERROR);
130
+            throw new \InvalidArgumentException('uid must not be null!');
131
+        } else if ($username === '') {
132
+            $log->log("uid for '$dn' must not be an empty string", ILogger::ERROR);
133
+            throw new \InvalidArgumentException('uid must not be an empty string!');
134
+        }
135
+
136
+        $this->access              = $access;
137
+        $this->connection          = $access->getConnection();
138
+        $this->config              = $config;
139
+        $this->fs                  = $fs;
140
+        $this->dn                  = $dn;
141
+        $this->uid                 = $username;
142
+        $this->image               = $image;
143
+        $this->log                 = $log;
144
+        $this->avatarManager       = $avatarManager;
145
+        $this->userManager         = $userManager;
146
+        $this->notificationManager = $notificationManager;
147
+
148
+        \OCP\Util::connectHook('OC_User', 'post_login', $this, 'handlePasswordExpiry');
149
+    }
150
+
151
+    /**
152
+     * @brief updates properties like email, quota or avatar provided by LDAP
153
+     * @return null
154
+     */
155
+    public function update() {
156
+        if(is_null($this->dn)) {
157
+            return null;
158
+        }
159
+
160
+        $hasLoggedIn = $this->config->getUserValue($this->uid, 'user_ldap',
161
+                self::USER_PREFKEY_FIRSTLOGIN, 0);
162
+
163
+        if($this->needsRefresh()) {
164
+            $this->updateEmail();
165
+            $this->updateQuota();
166
+            if($hasLoggedIn !== 0) {
167
+                //we do not need to try it, when the user has not been logged in
168
+                //before, because the file system will not be ready.
169
+                $this->updateAvatar();
170
+                //in order to get an avatar as soon as possible, mark the user
171
+                //as refreshed only when updating the avatar did happen
172
+                $this->markRefreshTime();
173
+            }
174
+        }
175
+    }
176
+
177
+    /**
178
+     * processes results from LDAP for attributes as returned by getAttributesToRead()
179
+     * @param array $ldapEntry the user entry as retrieved from LDAP
180
+     */
181
+    public function processAttributes($ldapEntry) {
182
+        $this->markRefreshTime();
183
+        //Quota
184
+        $attr = strtolower($this->connection->ldapQuotaAttribute);
185
+        if(isset($ldapEntry[$attr])) {
186
+            $this->updateQuota($ldapEntry[$attr][0]);
187
+        } else {
188
+            if ($this->connection->ldapQuotaDefault !== '') {
189
+                $this->updateQuota();
190
+            }
191
+        }
192
+        unset($attr);
193
+
194
+        //displayName
195
+        $displayName = $displayName2 = '';
196
+        $attr = strtolower($this->connection->ldapUserDisplayName);
197
+        if(isset($ldapEntry[$attr])) {
198
+            $displayName = (string)$ldapEntry[$attr][0];
199
+        }
200
+        $attr = strtolower($this->connection->ldapUserDisplayName2);
201
+        if(isset($ldapEntry[$attr])) {
202
+            $displayName2 = (string)$ldapEntry[$attr][0];
203
+        }
204
+        if ($displayName !== '') {
205
+            $this->composeAndStoreDisplayName($displayName);
206
+            $this->access->cacheUserDisplayName(
207
+                $this->getUsername(),
208
+                $displayName,
209
+                $displayName2
210
+            );
211
+        }
212
+        unset($attr);
213
+
214
+        //Email
215
+        //email must be stored after displayname, because it would cause a user
216
+        //change event that will trigger fetching the display name again
217
+        $attr = strtolower($this->connection->ldapEmailAttribute);
218
+        if(isset($ldapEntry[$attr])) {
219
+            $this->updateEmail($ldapEntry[$attr][0]);
220
+        }
221
+        unset($attr);
222
+
223
+        // LDAP Username, needed for s2s sharing
224
+        if(isset($ldapEntry['uid'])) {
225
+            $this->storeLDAPUserName($ldapEntry['uid'][0]);
226
+        } else if(isset($ldapEntry['samaccountname'])) {
227
+            $this->storeLDAPUserName($ldapEntry['samaccountname'][0]);
228
+        }
229
+
230
+        //homePath
231
+        if(strpos($this->connection->homeFolderNamingRule, 'attr:') === 0) {
232
+            $attr = strtolower(substr($this->connection->homeFolderNamingRule, strlen('attr:')));
233
+            if(isset($ldapEntry[$attr])) {
234
+                $this->access->cacheUserHome(
235
+                    $this->getUsername(), $this->getHomePath($ldapEntry[$attr][0]));
236
+            }
237
+        }
238
+
239
+        //memberOf groups
240
+        $cacheKey = 'getMemberOf'.$this->getUsername();
241
+        $groups = false;
242
+        if(isset($ldapEntry['memberof'])) {
243
+            $groups = $ldapEntry['memberof'];
244
+        }
245
+        $this->connection->writeToCache($cacheKey, $groups);
246
+
247
+        //Avatar
248
+        /** @var Connection $connection */
249
+        $connection = $this->access->getConnection();
250
+        $attributes = $connection->resolveRule('avatar');
251
+        foreach ($attributes as $attribute)  {
252
+            if(isset($ldapEntry[$attribute])) {
253
+                $this->avatarImage = $ldapEntry[$attribute][0];
254
+                // the call to the method that saves the avatar in the file
255
+                // system must be postponed after the login. It is to ensure
256
+                // external mounts are mounted properly (e.g. with login
257
+                // credentials from the session).
258
+                \OCP\Util::connectHook('OC_User', 'post_login', $this, 'updateAvatarPostLogin');
259
+                break;
260
+            }
261
+        }
262
+    }
263
+
264
+    /**
265
+     * @brief returns the LDAP DN of the user
266
+     * @return string
267
+     */
268
+    public function getDN() {
269
+        return $this->dn;
270
+    }
271
+
272
+    /**
273
+     * @brief returns the Nextcloud internal username of the user
274
+     * @return string
275
+     */
276
+    public function getUsername() {
277
+        return $this->uid;
278
+    }
279
+
280
+    /**
281
+     * returns the home directory of the user if specified by LDAP settings
282
+     * @param string $valueFromLDAP
283
+     * @return bool|string
284
+     * @throws \Exception
285
+     */
286
+    public function getHomePath($valueFromLDAP = null) {
287
+        $path = (string)$valueFromLDAP;
288
+        $attr = null;
289
+
290
+        if (is_null($valueFromLDAP)
291
+           && strpos($this->access->connection->homeFolderNamingRule, 'attr:') === 0
292
+           && $this->access->connection->homeFolderNamingRule !== 'attr:')
293
+        {
294
+            $attr = substr($this->access->connection->homeFolderNamingRule, strlen('attr:'));
295
+            $homedir = $this->access->readAttribute(
296
+                $this->access->username2dn($this->getUsername()), $attr);
297
+            if ($homedir && isset($homedir[0])) {
298
+                $path = $homedir[0];
299
+            }
300
+        }
301
+
302
+        if ($path !== '') {
303
+            //if attribute's value is an absolute path take this, otherwise append it to data dir
304
+            //check for / at the beginning or pattern c:\ resp. c:/
305
+            if(   '/' !== $path[0]
306
+               && !(3 < strlen($path) && ctype_alpha($path[0])
307
+                   && $path[1] === ':' && ('\\' === $path[2] || '/' === $path[2]))
308
+            ) {
309
+                $path = $this->config->getSystemValue('datadirectory',
310
+                        \OC::$SERVERROOT.'/data' ) . '/' . $path;
311
+            }
312
+            //we need it to store it in the DB as well in case a user gets
313
+            //deleted so we can clean up afterwards
314
+            $this->config->setUserValue(
315
+                $this->getUsername(), 'user_ldap', 'homePath', $path
316
+            );
317
+            return $path;
318
+        }
319
+
320
+        if(    !is_null($attr)
321
+            && $this->config->getAppValue('user_ldap', 'enforce_home_folder_naming_rule', true)
322
+        ) {
323
+            // a naming rule attribute is defined, but it doesn't exist for that LDAP user
324
+            throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: ' . $this->getUsername());
325
+        }
326
+
327
+        //false will apply default behaviour as defined and done by OC_User
328
+        $this->config->setUserValue($this->getUsername(), 'user_ldap', 'homePath', '');
329
+        return false;
330
+    }
331
+
332
+    public function getMemberOfGroups() {
333
+        $cacheKey = 'getMemberOf'.$this->getUsername();
334
+        $memberOfGroups = $this->connection->getFromCache($cacheKey);
335
+        if(!is_null($memberOfGroups)) {
336
+            return $memberOfGroups;
337
+        }
338
+        $groupDNs = $this->access->readAttribute($this->getDN(), 'memberOf');
339
+        $this->connection->writeToCache($cacheKey, $groupDNs);
340
+        return $groupDNs;
341
+    }
342
+
343
+    /**
344
+     * @brief reads the image from LDAP that shall be used as Avatar
345
+     * @return string data (provided by LDAP) | false
346
+     */
347
+    public function getAvatarImage() {
348
+        if(!is_null($this->avatarImage)) {
349
+            return $this->avatarImage;
350
+        }
351
+
352
+        $this->avatarImage = false;
353
+        /** @var Connection $connection */
354
+        $connection = $this->access->getConnection();
355
+        $attributes = $connection->resolveRule('avatar');
356
+        foreach($attributes as $attribute) {
357
+            $result = $this->access->readAttribute($this->dn, $attribute);
358
+            if($result !== false && is_array($result) && isset($result[0])) {
359
+                $this->avatarImage = $result[0];
360
+                break;
361
+            }
362
+        }
363
+
364
+        return $this->avatarImage;
365
+    }
366
+
367
+    /**
368
+     * @brief marks the user as having logged in at least once
369
+     * @return null
370
+     */
371
+    public function markLogin() {
372
+        $this->config->setUserValue(
373
+            $this->uid, 'user_ldap', self::USER_PREFKEY_FIRSTLOGIN, 1);
374
+    }
375
+
376
+    /**
377
+     * @brief marks the time when user features like email have been updated
378
+     * @return null
379
+     */
380
+    public function markRefreshTime() {
381
+        $this->config->setUserValue(
382
+            $this->uid, 'user_ldap', self::USER_PREFKEY_LASTREFRESH, time());
383
+    }
384
+
385
+    /**
386
+     * @brief checks whether user features needs to be updated again by
387
+     * comparing the difference of time of the last refresh to now with the
388
+     * desired interval
389
+     * @return bool
390
+     */
391
+    private function needsRefresh() {
392
+        $lastChecked = $this->config->getUserValue($this->uid, 'user_ldap',
393
+            self::USER_PREFKEY_LASTREFRESH, 0);
394
+
395
+        if((time() - (int)$lastChecked) < (int)$this->config->getAppValue('user_ldap', 'updateAttributesInterval', 86400)) {
396
+            return false;
397
+        }
398
+        return  true;
399
+    }
400
+
401
+    /**
402
+     * Stores a key-value pair in relation to this user
403
+     *
404
+     * @param string $key
405
+     * @param string $value
406
+     */
407
+    private function store($key, $value) {
408
+        $this->config->setUserValue($this->uid, 'user_ldap', $key, $value);
409
+    }
410
+
411
+    /**
412
+     * Composes the display name and stores it in the database. The final
413
+     * display name is returned.
414
+     *
415
+     * @param string $displayName
416
+     * @param string $displayName2
417
+     * @returns string the effective display name
418
+     */
419
+    public function composeAndStoreDisplayName($displayName, $displayName2 = '') {
420
+        $displayName2 = (string)$displayName2;
421
+        if($displayName2 !== '') {
422
+            $displayName .= ' (' . $displayName2 . ')';
423
+        }
424
+        $this->store('displayName', $displayName);
425
+        return $displayName;
426
+    }
427
+
428
+    /**
429
+     * Stores the LDAP Username in the Database
430
+     * @param string $userName
431
+     */
432
+    public function storeLDAPUserName($userName) {
433
+        $this->store('uid', $userName);
434
+    }
435
+
436
+    /**
437
+     * @brief checks whether an update method specified by feature was run
438
+     * already. If not, it will marked like this, because it is expected that
439
+     * the method will be run, when false is returned.
440
+     * @param string $feature email | quota | avatar (can be extended)
441
+     * @return bool
442
+     */
443
+    private function wasRefreshed($feature) {
444
+        if(isset($this->refreshedFeatures[$feature])) {
445
+            return true;
446
+        }
447
+        $this->refreshedFeatures[$feature] = 1;
448
+        return false;
449
+    }
450
+
451
+    /**
452
+     * fetches the email from LDAP and stores it as Nextcloud user value
453
+     * @param string $valueFromLDAP if known, to save an LDAP read request
454
+     * @return null
455
+     */
456
+    public function updateEmail($valueFromLDAP = null) {
457
+        if($this->wasRefreshed('email')) {
458
+            return;
459
+        }
460
+        $email = (string)$valueFromLDAP;
461
+        if(is_null($valueFromLDAP)) {
462
+            $emailAttribute = $this->connection->ldapEmailAttribute;
463
+            if ($emailAttribute !== '') {
464
+                $aEmail = $this->access->readAttribute($this->dn, $emailAttribute);
465
+                if(is_array($aEmail) && (count($aEmail) > 0)) {
466
+                    $email = (string)$aEmail[0];
467
+                }
468
+            }
469
+        }
470
+        if ($email !== '') {
471
+            $user = $this->userManager->get($this->uid);
472
+            if (!is_null($user)) {
473
+                $currentEmail = (string)$user->getEMailAddress();
474
+                if ($currentEmail !== $email) {
475
+                    $user->setEMailAddress($email);
476
+                }
477
+            }
478
+        }
479
+    }
480
+
481
+    /**
482
+     * Overall process goes as follow:
483
+     * 1. fetch the quota from LDAP and check if it's parseable with the "verifyQuotaValue" function
484
+     * 2. if the value can't be fetched, is empty or not parseable, use the default LDAP quota
485
+     * 3. if the default LDAP quota can't be parsed, use the Nextcloud's default quota (use 'default')
486
+     * 4. check if the target user exists and set the quota for the user.
487
+     *
488
+     * In order to improve performance and prevent an unwanted extra LDAP call, the $valueFromLDAP
489
+     * parameter can be passed with the value of the attribute. This value will be considered as the
490
+     * quota for the user coming from the LDAP server (step 1 of the process) It can be useful to
491
+     * fetch all the user's attributes in one call and use the fetched values in this function.
492
+     * The expected value for that parameter is a string describing the quota for the user. Valid
493
+     * values are 'none' (unlimited), 'default' (the Nextcloud's default quota), '1234' (quota in
494
+     * bytes), '1234 MB' (quota in MB - check the \OC_Helper::computerFileSize method for more info)
495
+     *
496
+     * fetches the quota from LDAP and stores it as Nextcloud user value
497
+     * @param string $valueFromLDAP the quota attribute's value can be passed,
498
+     * to save the readAttribute request
499
+     * @return null
500
+     */
501
+    public function updateQuota($valueFromLDAP = null) {
502
+        if($this->wasRefreshed('quota')) {
503
+            return;
504
+        }
505
+
506
+        $quotaAttribute = $this->connection->ldapQuotaAttribute;
507
+        $defaultQuota = $this->connection->ldapQuotaDefault;
508
+        if($quotaAttribute === '' && $defaultQuota === '') {
509
+            return;
510
+        }
511
+
512
+        $quota = false;
513
+        if(is_null($valueFromLDAP) && $quotaAttribute !== '') {
514
+            $aQuota = $this->access->readAttribute($this->dn, $quotaAttribute);
515
+            if($aQuota && (count($aQuota) > 0) && $this->verifyQuotaValue($aQuota[0])) {
516
+                $quota = $aQuota[0];
517
+            } else if(is_array($aQuota) && isset($aQuota[0])) {
518
+                $this->log->log('no suitable LDAP quota found for user ' . $this->uid . ': [' . $aQuota[0] . ']', ILogger::DEBUG);
519
+            }
520
+        } else if ($this->verifyQuotaValue($valueFromLDAP)) {
521
+            $quota = $valueFromLDAP;
522
+        } else {
523
+            $this->log->log('no suitable LDAP quota found for user ' . $this->uid . ': [' . $valueFromLDAP . ']', ILogger::DEBUG);
524
+        }
525
+
526
+        if ($quota === false && $this->verifyQuotaValue($defaultQuota)) {
527
+            // quota not found using the LDAP attribute (or not parseable). Try the default quota
528
+            $quota = $defaultQuota;
529
+        } else if($quota === false) {
530
+            $this->log->log('no suitable default quota found for user ' . $this->uid . ': [' . $defaultQuota . ']', ILogger::DEBUG);
531
+            return;
532
+        }
533
+
534
+        $targetUser = $this->userManager->get($this->uid);
535
+        if ($targetUser instanceof IUser) {
536
+            $targetUser->setQuota($quota);
537
+        } else {
538
+            $this->log->log('trying to set a quota for user ' . $this->uid . ' but the user is missing', ILogger::INFO);
539
+        }
540
+    }
541
+
542
+    private function verifyQuotaValue($quotaValue) {
543
+        return $quotaValue === 'none' || $quotaValue === 'default' || \OC_Helper::computerFileSize($quotaValue) !== false;
544
+    }
545
+
546
+    /**
547
+     * called by a post_login hook to save the avatar picture
548
+     *
549
+     * @param array $params
550
+     */
551
+    public function updateAvatarPostLogin($params) {
552
+        if(isset($params['uid']) && $params['uid'] === $this->getUsername()) {
553
+            $this->updateAvatar();
554
+        }
555
+    }
556
+
557
+    /**
558
+     * @brief attempts to get an image from LDAP and sets it as Nextcloud avatar
559
+     * @return bool
560
+     */
561
+    public function updateAvatar($force = false) {
562
+        if(!$force && $this->wasRefreshed('avatar')) {
563
+            return false;
564
+        }
565
+        $avatarImage = $this->getAvatarImage();
566
+        if($avatarImage === false) {
567
+            //not set, nothing left to do;
568
+            return false;
569
+        }
570
+        if(!$this->image->loadFromBase64(base64_encode($avatarImage))) {
571
+            return false;
572
+        }
573
+        return $this->setOwnCloudAvatar();
574
+    }
575
+
576
+    /**
577
+     * @brief sets an image as Nextcloud avatar
578
+     * @return bool
579
+     */
580
+    private function setOwnCloudAvatar() {
581
+        if(!$this->image->valid()) {
582
+            $this->log->log('avatar image data from LDAP invalid for '.$this->dn, ILogger::ERROR);
583
+            return false;
584
+        }
585
+        //make sure it is a square and not bigger than 128x128
586
+        $size = min(array($this->image->width(), $this->image->height(), 128));
587
+        if(!$this->image->centerCrop($size)) {
588
+            $this->log->log('croping image for avatar failed for '.$this->dn, ILogger::ERROR);
589
+            return false;
590
+        }
591
+
592
+        if(!$this->fs->isLoaded()) {
593
+            $this->fs->setup($this->uid);
594
+        }
595
+
596
+        try {
597
+            $avatar = $this->avatarManager->getAvatar($this->uid);
598
+            $avatar->set($this->image);
599
+            return true;
600
+        } catch (\Exception $e) {
601
+            \OC::$server->getLogger()->logException($e, [
602
+                'message' => 'Could not set avatar for ' . $this->dn,
603
+                'level' => ILogger::INFO,
604
+                'app' => 'user_ldap',
605
+            ]);
606
+        }
607
+        return false;
608
+    }
609
+
610
+    /**
611
+     * called by a post_login hook to handle password expiry
612
+     *
613
+     * @param array $params
614
+     */
615
+    public function handlePasswordExpiry($params) {
616
+        $ppolicyDN = $this->connection->ldapDefaultPPolicyDN;
617
+        if (empty($ppolicyDN) || ((int)$this->connection->turnOnPasswordChange !== 1)) {
618
+            return;//password expiry handling disabled
619
+        }
620
+        $uid = $params['uid'];
621
+        if(isset($uid) && $uid === $this->getUsername()) {
622
+            //retrieve relevant user attributes
623
+            $result = $this->access->search('objectclass=*', array($this->dn), ['pwdpolicysubentry', 'pwdgraceusetime', 'pwdreset', 'pwdchangedtime']);
624 624
 			
625
-			if(array_key_exists('pwdpolicysubentry', $result[0])) {
626
-				$pwdPolicySubentry = $result[0]['pwdpolicysubentry'];
627
-				if($pwdPolicySubentry && (count($pwdPolicySubentry) > 0)){
628
-					$ppolicyDN = $pwdPolicySubentry[0];//custom ppolicy DN
629
-				}
630
-			}
625
+            if(array_key_exists('pwdpolicysubentry', $result[0])) {
626
+                $pwdPolicySubentry = $result[0]['pwdpolicysubentry'];
627
+                if($pwdPolicySubentry && (count($pwdPolicySubentry) > 0)){
628
+                    $ppolicyDN = $pwdPolicySubentry[0];//custom ppolicy DN
629
+                }
630
+            }
631 631
 			
632
-			$pwdGraceUseTime = array_key_exists('pwdgraceusetime', $result[0]) ? $result[0]['pwdgraceusetime'] : null;
633
-			$pwdReset = array_key_exists('pwdreset', $result[0]) ? $result[0]['pwdreset'] : null;
634
-			$pwdChangedTime = array_key_exists('pwdchangedtime', $result[0]) ? $result[0]['pwdchangedtime'] : null;
632
+            $pwdGraceUseTime = array_key_exists('pwdgraceusetime', $result[0]) ? $result[0]['pwdgraceusetime'] : null;
633
+            $pwdReset = array_key_exists('pwdreset', $result[0]) ? $result[0]['pwdreset'] : null;
634
+            $pwdChangedTime = array_key_exists('pwdchangedtime', $result[0]) ? $result[0]['pwdchangedtime'] : null;
635 635
 			
636
-			//retrieve relevant password policy attributes
637
-			$cacheKey = 'ppolicyAttributes' . $ppolicyDN;
638
-			$result = $this->connection->getFromCache($cacheKey);
639
-			if(is_null($result)) {
640
-				$result = $this->access->search('objectclass=*', array($ppolicyDN), ['pwdgraceauthnlimit', 'pwdmaxage', 'pwdexpirewarning']);
641
-				$this->connection->writeToCache($cacheKey, $result);
642
-			}
636
+            //retrieve relevant password policy attributes
637
+            $cacheKey = 'ppolicyAttributes' . $ppolicyDN;
638
+            $result = $this->connection->getFromCache($cacheKey);
639
+            if(is_null($result)) {
640
+                $result = $this->access->search('objectclass=*', array($ppolicyDN), ['pwdgraceauthnlimit', 'pwdmaxage', 'pwdexpirewarning']);
641
+                $this->connection->writeToCache($cacheKey, $result);
642
+            }
643 643
 			
644
-			$pwdGraceAuthNLimit = array_key_exists('pwdgraceauthnlimit', $result[0]) ? $result[0]['pwdgraceauthnlimit'] : null;
645
-			$pwdMaxAge = array_key_exists('pwdmaxage', $result[0]) ? $result[0]['pwdmaxage'] : null;
646
-			$pwdExpireWarning = array_key_exists('pwdexpirewarning', $result[0]) ? $result[0]['pwdexpirewarning'] : null;
644
+            $pwdGraceAuthNLimit = array_key_exists('pwdgraceauthnlimit', $result[0]) ? $result[0]['pwdgraceauthnlimit'] : null;
645
+            $pwdMaxAge = array_key_exists('pwdmaxage', $result[0]) ? $result[0]['pwdmaxage'] : null;
646
+            $pwdExpireWarning = array_key_exists('pwdexpirewarning', $result[0]) ? $result[0]['pwdexpirewarning'] : null;
647 647
 			
648
-			//handle grace login
649
-			$pwdGraceUseTimeCount = count($pwdGraceUseTime);
650
-			if($pwdGraceUseTime && $pwdGraceUseTimeCount > 0) { //was this a grace login?
651
-				if($pwdGraceAuthNLimit 
652
-					&& (count($pwdGraceAuthNLimit) > 0)
653
-					&&($pwdGraceUseTimeCount < (int)$pwdGraceAuthNLimit[0])) { //at least one more grace login available?
654
-					$this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
655
-					header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
656
-					'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
657
-				} else { //no more grace login available
658
-					header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
659
-					'user_ldap.renewPassword.showLoginFormInvalidPassword', array('user' => $uid)));
660
-				}
661
-				exit();
662
-			}
663
-			//handle pwdReset attribute
664
-			if($pwdReset && (count($pwdReset) > 0) && $pwdReset[0] === 'TRUE') { //user must change his password
665
-				$this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
666
-				header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
667
-				'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
668
-				exit();
669
-			}
670
-			//handle password expiry warning
671
-			if($pwdChangedTime && (count($pwdChangedTime) > 0)) {
672
-				if($pwdMaxAge && (count($pwdMaxAge) > 0)
673
-					&& $pwdExpireWarning && (count($pwdExpireWarning) > 0)) {
674
-					$pwdMaxAgeInt = (int)$pwdMaxAge[0];
675
-					$pwdExpireWarningInt = (int)$pwdExpireWarning[0];
676
-					if($pwdMaxAgeInt > 0 && $pwdExpireWarningInt > 0){
677
-						$pwdChangedTimeDt = \DateTime::createFromFormat('YmdHisZ', $pwdChangedTime[0]);
678
-						$pwdChangedTimeDt->add(new \DateInterval('PT'.$pwdMaxAgeInt.'S'));
679
-						$currentDateTime = new \DateTime();
680
-						$secondsToExpiry = $pwdChangedTimeDt->getTimestamp() - $currentDateTime->getTimestamp();
681
-						if($secondsToExpiry <= $pwdExpireWarningInt) {
682
-							//remove last password expiry warning if any
683
-							$notification = $this->notificationManager->createNotification();
684
-							$notification->setApp('user_ldap')
685
-								->setUser($uid)
686
-								->setObject('pwd_exp_warn', $uid)
687
-							;
688
-							$this->notificationManager->markProcessed($notification);
689
-							//create new password expiry warning
690
-							$notification = $this->notificationManager->createNotification();
691
-							$notification->setApp('user_ldap')
692
-								->setUser($uid)
693
-								->setDateTime($currentDateTime)
694
-								->setObject('pwd_exp_warn', $uid) 
695
-								->setSubject('pwd_exp_warn_days', [(int) ceil($secondsToExpiry / 60 / 60 / 24)])
696
-							;
697
-							$this->notificationManager->notify($notification);
698
-						}
699
-					}
700
-				}
701
-			}
702
-		}
703
-	}
648
+            //handle grace login
649
+            $pwdGraceUseTimeCount = count($pwdGraceUseTime);
650
+            if($pwdGraceUseTime && $pwdGraceUseTimeCount > 0) { //was this a grace login?
651
+                if($pwdGraceAuthNLimit 
652
+                    && (count($pwdGraceAuthNLimit) > 0)
653
+                    &&($pwdGraceUseTimeCount < (int)$pwdGraceAuthNLimit[0])) { //at least one more grace login available?
654
+                    $this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
655
+                    header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
656
+                    'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
657
+                } else { //no more grace login available
658
+                    header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
659
+                    'user_ldap.renewPassword.showLoginFormInvalidPassword', array('user' => $uid)));
660
+                }
661
+                exit();
662
+            }
663
+            //handle pwdReset attribute
664
+            if($pwdReset && (count($pwdReset) > 0) && $pwdReset[0] === 'TRUE') { //user must change his password
665
+                $this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
666
+                header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
667
+                'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
668
+                exit();
669
+            }
670
+            //handle password expiry warning
671
+            if($pwdChangedTime && (count($pwdChangedTime) > 0)) {
672
+                if($pwdMaxAge && (count($pwdMaxAge) > 0)
673
+                    && $pwdExpireWarning && (count($pwdExpireWarning) > 0)) {
674
+                    $pwdMaxAgeInt = (int)$pwdMaxAge[0];
675
+                    $pwdExpireWarningInt = (int)$pwdExpireWarning[0];
676
+                    if($pwdMaxAgeInt > 0 && $pwdExpireWarningInt > 0){
677
+                        $pwdChangedTimeDt = \DateTime::createFromFormat('YmdHisZ', $pwdChangedTime[0]);
678
+                        $pwdChangedTimeDt->add(new \DateInterval('PT'.$pwdMaxAgeInt.'S'));
679
+                        $currentDateTime = new \DateTime();
680
+                        $secondsToExpiry = $pwdChangedTimeDt->getTimestamp() - $currentDateTime->getTimestamp();
681
+                        if($secondsToExpiry <= $pwdExpireWarningInt) {
682
+                            //remove last password expiry warning if any
683
+                            $notification = $this->notificationManager->createNotification();
684
+                            $notification->setApp('user_ldap')
685
+                                ->setUser($uid)
686
+                                ->setObject('pwd_exp_warn', $uid)
687
+                            ;
688
+                            $this->notificationManager->markProcessed($notification);
689
+                            //create new password expiry warning
690
+                            $notification = $this->notificationManager->createNotification();
691
+                            $notification->setApp('user_ldap')
692
+                                ->setUser($uid)
693
+                                ->setDateTime($currentDateTime)
694
+                                ->setObject('pwd_exp_warn', $uid) 
695
+                                ->setSubject('pwd_exp_warn_days', [(int) ceil($secondsToExpiry / 60 / 60 / 24)])
696
+                            ;
697
+                            $this->notificationManager->notify($notification);
698
+                        }
699
+                    }
700
+                }
701
+            }
702
+        }
703
+    }
704 704
 }
Please login to merge, or discard this patch.
Spacing   +72 added lines, -72 removed lines patch added patch discarded remove patch
@@ -153,17 +153,17 @@  discard block
 block discarded – undo
153 153
 	 * @return null
154 154
 	 */
155 155
 	public function update() {
156
-		if(is_null($this->dn)) {
156
+		if (is_null($this->dn)) {
157 157
 			return null;
158 158
 		}
159 159
 
160 160
 		$hasLoggedIn = $this->config->getUserValue($this->uid, 'user_ldap',
161 161
 				self::USER_PREFKEY_FIRSTLOGIN, 0);
162 162
 
163
-		if($this->needsRefresh()) {
163
+		if ($this->needsRefresh()) {
164 164
 			$this->updateEmail();
165 165
 			$this->updateQuota();
166
-			if($hasLoggedIn !== 0) {
166
+			if ($hasLoggedIn !== 0) {
167 167
 				//we do not need to try it, when the user has not been logged in
168 168
 				//before, because the file system will not be ready.
169 169
 				$this->updateAvatar();
@@ -182,7 +182,7 @@  discard block
 block discarded – undo
182 182
 		$this->markRefreshTime();
183 183
 		//Quota
184 184
 		$attr = strtolower($this->connection->ldapQuotaAttribute);
185
-		if(isset($ldapEntry[$attr])) {
185
+		if (isset($ldapEntry[$attr])) {
186 186
 			$this->updateQuota($ldapEntry[$attr][0]);
187 187
 		} else {
188 188
 			if ($this->connection->ldapQuotaDefault !== '') {
@@ -194,12 +194,12 @@  discard block
 block discarded – undo
194 194
 		//displayName
195 195
 		$displayName = $displayName2 = '';
196 196
 		$attr = strtolower($this->connection->ldapUserDisplayName);
197
-		if(isset($ldapEntry[$attr])) {
198
-			$displayName = (string)$ldapEntry[$attr][0];
197
+		if (isset($ldapEntry[$attr])) {
198
+			$displayName = (string) $ldapEntry[$attr][0];
199 199
 		}
200 200
 		$attr = strtolower($this->connection->ldapUserDisplayName2);
201
-		if(isset($ldapEntry[$attr])) {
202
-			$displayName2 = (string)$ldapEntry[$attr][0];
201
+		if (isset($ldapEntry[$attr])) {
202
+			$displayName2 = (string) $ldapEntry[$attr][0];
203 203
 		}
204 204
 		if ($displayName !== '') {
205 205
 			$this->composeAndStoreDisplayName($displayName);
@@ -215,22 +215,22 @@  discard block
 block discarded – undo
215 215
 		//email must be stored after displayname, because it would cause a user
216 216
 		//change event that will trigger fetching the display name again
217 217
 		$attr = strtolower($this->connection->ldapEmailAttribute);
218
-		if(isset($ldapEntry[$attr])) {
218
+		if (isset($ldapEntry[$attr])) {
219 219
 			$this->updateEmail($ldapEntry[$attr][0]);
220 220
 		}
221 221
 		unset($attr);
222 222
 
223 223
 		// LDAP Username, needed for s2s sharing
224
-		if(isset($ldapEntry['uid'])) {
224
+		if (isset($ldapEntry['uid'])) {
225 225
 			$this->storeLDAPUserName($ldapEntry['uid'][0]);
226
-		} else if(isset($ldapEntry['samaccountname'])) {
226
+		} else if (isset($ldapEntry['samaccountname'])) {
227 227
 			$this->storeLDAPUserName($ldapEntry['samaccountname'][0]);
228 228
 		}
229 229
 
230 230
 		//homePath
231
-		if(strpos($this->connection->homeFolderNamingRule, 'attr:') === 0) {
231
+		if (strpos($this->connection->homeFolderNamingRule, 'attr:') === 0) {
232 232
 			$attr = strtolower(substr($this->connection->homeFolderNamingRule, strlen('attr:')));
233
-			if(isset($ldapEntry[$attr])) {
233
+			if (isset($ldapEntry[$attr])) {
234 234
 				$this->access->cacheUserHome(
235 235
 					$this->getUsername(), $this->getHomePath($ldapEntry[$attr][0]));
236 236
 			}
@@ -239,7 +239,7 @@  discard block
 block discarded – undo
239 239
 		//memberOf groups
240 240
 		$cacheKey = 'getMemberOf'.$this->getUsername();
241 241
 		$groups = false;
242
-		if(isset($ldapEntry['memberof'])) {
242
+		if (isset($ldapEntry['memberof'])) {
243 243
 			$groups = $ldapEntry['memberof'];
244 244
 		}
245 245
 		$this->connection->writeToCache($cacheKey, $groups);
@@ -248,8 +248,8 @@  discard block
 block discarded – undo
248 248
 		/** @var Connection $connection */
249 249
 		$connection = $this->access->getConnection();
250 250
 		$attributes = $connection->resolveRule('avatar');
251
-		foreach ($attributes as $attribute)  {
252
-			if(isset($ldapEntry[$attribute])) {
251
+		foreach ($attributes as $attribute) {
252
+			if (isset($ldapEntry[$attribute])) {
253 253
 				$this->avatarImage = $ldapEntry[$attribute][0];
254 254
 				// the call to the method that saves the avatar in the file
255 255
 				// system must be postponed after the login. It is to ensure
@@ -284,7 +284,7 @@  discard block
 block discarded – undo
284 284
 	 * @throws \Exception
285 285
 	 */
286 286
 	public function getHomePath($valueFromLDAP = null) {
287
-		$path = (string)$valueFromLDAP;
287
+		$path = (string) $valueFromLDAP;
288 288
 		$attr = null;
289 289
 
290 290
 		if (is_null($valueFromLDAP)
@@ -302,12 +302,12 @@  discard block
 block discarded – undo
302 302
 		if ($path !== '') {
303 303
 			//if attribute's value is an absolute path take this, otherwise append it to data dir
304 304
 			//check for / at the beginning or pattern c:\ resp. c:/
305
-			if(   '/' !== $path[0]
305
+			if ('/' !== $path[0]
306 306
 			   && !(3 < strlen($path) && ctype_alpha($path[0])
307 307
 			       && $path[1] === ':' && ('\\' === $path[2] || '/' === $path[2]))
308 308
 			) {
309 309
 				$path = $this->config->getSystemValue('datadirectory',
310
-						\OC::$SERVERROOT.'/data' ) . '/' . $path;
310
+						\OC::$SERVERROOT.'/data').'/'.$path;
311 311
 			}
312 312
 			//we need it to store it in the DB as well in case a user gets
313 313
 			//deleted so we can clean up afterwards
@@ -317,11 +317,11 @@  discard block
 block discarded – undo
317 317
 			return $path;
318 318
 		}
319 319
 
320
-		if(    !is_null($attr)
320
+		if (!is_null($attr)
321 321
 			&& $this->config->getAppValue('user_ldap', 'enforce_home_folder_naming_rule', true)
322 322
 		) {
323 323
 			// a naming rule attribute is defined, but it doesn't exist for that LDAP user
324
-			throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: ' . $this->getUsername());
324
+			throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: '.$this->getUsername());
325 325
 		}
326 326
 
327 327
 		//false will apply default behaviour as defined and done by OC_User
@@ -332,7 +332,7 @@  discard block
 block discarded – undo
332 332
 	public function getMemberOfGroups() {
333 333
 		$cacheKey = 'getMemberOf'.$this->getUsername();
334 334
 		$memberOfGroups = $this->connection->getFromCache($cacheKey);
335
-		if(!is_null($memberOfGroups)) {
335
+		if (!is_null($memberOfGroups)) {
336 336
 			return $memberOfGroups;
337 337
 		}
338 338
 		$groupDNs = $this->access->readAttribute($this->getDN(), 'memberOf');
@@ -345,7 +345,7 @@  discard block
 block discarded – undo
345 345
 	 * @return string data (provided by LDAP) | false
346 346
 	 */
347 347
 	public function getAvatarImage() {
348
-		if(!is_null($this->avatarImage)) {
348
+		if (!is_null($this->avatarImage)) {
349 349
 			return $this->avatarImage;
350 350
 		}
351 351
 
@@ -353,9 +353,9 @@  discard block
 block discarded – undo
353 353
 		/** @var Connection $connection */
354 354
 		$connection = $this->access->getConnection();
355 355
 		$attributes = $connection->resolveRule('avatar');
356
-		foreach($attributes as $attribute) {
356
+		foreach ($attributes as $attribute) {
357 357
 			$result = $this->access->readAttribute($this->dn, $attribute);
358
-			if($result !== false && is_array($result) && isset($result[0])) {
358
+			if ($result !== false && is_array($result) && isset($result[0])) {
359 359
 				$this->avatarImage = $result[0];
360 360
 				break;
361 361
 			}
@@ -392,7 +392,7 @@  discard block
 block discarded – undo
392 392
 		$lastChecked = $this->config->getUserValue($this->uid, 'user_ldap',
393 393
 			self::USER_PREFKEY_LASTREFRESH, 0);
394 394
 
395
-		if((time() - (int)$lastChecked) < (int)$this->config->getAppValue('user_ldap', 'updateAttributesInterval', 86400)) {
395
+		if ((time() - (int) $lastChecked) < (int) $this->config->getAppValue('user_ldap', 'updateAttributesInterval', 86400)) {
396 396
 			return false;
397 397
 		}
398 398
 		return  true;
@@ -417,9 +417,9 @@  discard block
 block discarded – undo
417 417
 	 * @returns string the effective display name
418 418
 	 */
419 419
 	public function composeAndStoreDisplayName($displayName, $displayName2 = '') {
420
-		$displayName2 = (string)$displayName2;
421
-		if($displayName2 !== '') {
422
-			$displayName .= ' (' . $displayName2 . ')';
420
+		$displayName2 = (string) $displayName2;
421
+		if ($displayName2 !== '') {
422
+			$displayName .= ' ('.$displayName2.')';
423 423
 		}
424 424
 		$this->store('displayName', $displayName);
425 425
 		return $displayName;
@@ -441,7 +441,7 @@  discard block
 block discarded – undo
441 441
 	 * @return bool
442 442
 	 */
443 443
 	private function wasRefreshed($feature) {
444
-		if(isset($this->refreshedFeatures[$feature])) {
444
+		if (isset($this->refreshedFeatures[$feature])) {
445 445
 			return true;
446 446
 		}
447 447
 		$this->refreshedFeatures[$feature] = 1;
@@ -454,23 +454,23 @@  discard block
 block discarded – undo
454 454
 	 * @return null
455 455
 	 */
456 456
 	public function updateEmail($valueFromLDAP = null) {
457
-		if($this->wasRefreshed('email')) {
457
+		if ($this->wasRefreshed('email')) {
458 458
 			return;
459 459
 		}
460
-		$email = (string)$valueFromLDAP;
461
-		if(is_null($valueFromLDAP)) {
460
+		$email = (string) $valueFromLDAP;
461
+		if (is_null($valueFromLDAP)) {
462 462
 			$emailAttribute = $this->connection->ldapEmailAttribute;
463 463
 			if ($emailAttribute !== '') {
464 464
 				$aEmail = $this->access->readAttribute($this->dn, $emailAttribute);
465
-				if(is_array($aEmail) && (count($aEmail) > 0)) {
466
-					$email = (string)$aEmail[0];
465
+				if (is_array($aEmail) && (count($aEmail) > 0)) {
466
+					$email = (string) $aEmail[0];
467 467
 				}
468 468
 			}
469 469
 		}
470 470
 		if ($email !== '') {
471 471
 			$user = $this->userManager->get($this->uid);
472 472
 			if (!is_null($user)) {
473
-				$currentEmail = (string)$user->getEMailAddress();
473
+				$currentEmail = (string) $user->getEMailAddress();
474 474
 				if ($currentEmail !== $email) {
475 475
 					$user->setEMailAddress($email);
476 476
 				}
@@ -499,35 +499,35 @@  discard block
 block discarded – undo
499 499
 	 * @return null
500 500
 	 */
501 501
 	public function updateQuota($valueFromLDAP = null) {
502
-		if($this->wasRefreshed('quota')) {
502
+		if ($this->wasRefreshed('quota')) {
503 503
 			return;
504 504
 		}
505 505
 
506 506
 		$quotaAttribute = $this->connection->ldapQuotaAttribute;
507 507
 		$defaultQuota = $this->connection->ldapQuotaDefault;
508
-		if($quotaAttribute === '' && $defaultQuota === '') {
508
+		if ($quotaAttribute === '' && $defaultQuota === '') {
509 509
 			return;
510 510
 		}
511 511
 
512 512
 		$quota = false;
513
-		if(is_null($valueFromLDAP) && $quotaAttribute !== '') {
513
+		if (is_null($valueFromLDAP) && $quotaAttribute !== '') {
514 514
 			$aQuota = $this->access->readAttribute($this->dn, $quotaAttribute);
515
-			if($aQuota && (count($aQuota) > 0) && $this->verifyQuotaValue($aQuota[0])) {
515
+			if ($aQuota && (count($aQuota) > 0) && $this->verifyQuotaValue($aQuota[0])) {
516 516
 				$quota = $aQuota[0];
517
-			} else if(is_array($aQuota) && isset($aQuota[0])) {
518
-				$this->log->log('no suitable LDAP quota found for user ' . $this->uid . ': [' . $aQuota[0] . ']', ILogger::DEBUG);
517
+			} else if (is_array($aQuota) && isset($aQuota[0])) {
518
+				$this->log->log('no suitable LDAP quota found for user '.$this->uid.': ['.$aQuota[0].']', ILogger::DEBUG);
519 519
 			}
520 520
 		} else if ($this->verifyQuotaValue($valueFromLDAP)) {
521 521
 			$quota = $valueFromLDAP;
522 522
 		} else {
523
-			$this->log->log('no suitable LDAP quota found for user ' . $this->uid . ': [' . $valueFromLDAP . ']', ILogger::DEBUG);
523
+			$this->log->log('no suitable LDAP quota found for user '.$this->uid.': ['.$valueFromLDAP.']', ILogger::DEBUG);
524 524
 		}
525 525
 
526 526
 		if ($quota === false && $this->verifyQuotaValue($defaultQuota)) {
527 527
 			// quota not found using the LDAP attribute (or not parseable). Try the default quota
528 528
 			$quota = $defaultQuota;
529
-		} else if($quota === false) {
530
-			$this->log->log('no suitable default quota found for user ' . $this->uid . ': [' . $defaultQuota . ']', ILogger::DEBUG);
529
+		} else if ($quota === false) {
530
+			$this->log->log('no suitable default quota found for user '.$this->uid.': ['.$defaultQuota.']', ILogger::DEBUG);
531 531
 			return;
532 532
 		}
533 533
 
@@ -535,7 +535,7 @@  discard block
 block discarded – undo
535 535
 		if ($targetUser instanceof IUser) {
536 536
 			$targetUser->setQuota($quota);
537 537
 		} else {
538
-			$this->log->log('trying to set a quota for user ' . $this->uid . ' but the user is missing', ILogger::INFO);
538
+			$this->log->log('trying to set a quota for user '.$this->uid.' but the user is missing', ILogger::INFO);
539 539
 		}
540 540
 	}
541 541
 
@@ -549,7 +549,7 @@  discard block
 block discarded – undo
549 549
 	 * @param array $params
550 550
 	 */
551 551
 	public function updateAvatarPostLogin($params) {
552
-		if(isset($params['uid']) && $params['uid'] === $this->getUsername()) {
552
+		if (isset($params['uid']) && $params['uid'] === $this->getUsername()) {
553 553
 			$this->updateAvatar();
554 554
 		}
555 555
 	}
@@ -559,15 +559,15 @@  discard block
 block discarded – undo
559 559
 	 * @return bool
560 560
 	 */
561 561
 	public function updateAvatar($force = false) {
562
-		if(!$force && $this->wasRefreshed('avatar')) {
562
+		if (!$force && $this->wasRefreshed('avatar')) {
563 563
 			return false;
564 564
 		}
565 565
 		$avatarImage = $this->getAvatarImage();
566
-		if($avatarImage === false) {
566
+		if ($avatarImage === false) {
567 567
 			//not set, nothing left to do;
568 568
 			return false;
569 569
 		}
570
-		if(!$this->image->loadFromBase64(base64_encode($avatarImage))) {
570
+		if (!$this->image->loadFromBase64(base64_encode($avatarImage))) {
571 571
 			return false;
572 572
 		}
573 573
 		return $this->setOwnCloudAvatar();
@@ -578,18 +578,18 @@  discard block
 block discarded – undo
578 578
 	 * @return bool
579 579
 	 */
580 580
 	private function setOwnCloudAvatar() {
581
-		if(!$this->image->valid()) {
581
+		if (!$this->image->valid()) {
582 582
 			$this->log->log('avatar image data from LDAP invalid for '.$this->dn, ILogger::ERROR);
583 583
 			return false;
584 584
 		}
585 585
 		//make sure it is a square and not bigger than 128x128
586 586
 		$size = min(array($this->image->width(), $this->image->height(), 128));
587
-		if(!$this->image->centerCrop($size)) {
587
+		if (!$this->image->centerCrop($size)) {
588 588
 			$this->log->log('croping image for avatar failed for '.$this->dn, ILogger::ERROR);
589 589
 			return false;
590 590
 		}
591 591
 
592
-		if(!$this->fs->isLoaded()) {
592
+		if (!$this->fs->isLoaded()) {
593 593
 			$this->fs->setup($this->uid);
594 594
 		}
595 595
 
@@ -599,7 +599,7 @@  discard block
 block discarded – undo
599 599
 			return true;
600 600
 		} catch (\Exception $e) {
601 601
 			\OC::$server->getLogger()->logException($e, [
602
-				'message' => 'Could not set avatar for ' . $this->dn,
602
+				'message' => 'Could not set avatar for '.$this->dn,
603 603
 				'level' => ILogger::INFO,
604 604
 				'app' => 'user_ldap',
605 605
 			]);
@@ -614,18 +614,18 @@  discard block
 block discarded – undo
614 614
 	 */
615 615
 	public function handlePasswordExpiry($params) {
616 616
 		$ppolicyDN = $this->connection->ldapDefaultPPolicyDN;
617
-		if (empty($ppolicyDN) || ((int)$this->connection->turnOnPasswordChange !== 1)) {
618
-			return;//password expiry handling disabled
617
+		if (empty($ppolicyDN) || ((int) $this->connection->turnOnPasswordChange !== 1)) {
618
+			return; //password expiry handling disabled
619 619
 		}
620 620
 		$uid = $params['uid'];
621
-		if(isset($uid) && $uid === $this->getUsername()) {
621
+		if (isset($uid) && $uid === $this->getUsername()) {
622 622
 			//retrieve relevant user attributes
623 623
 			$result = $this->access->search('objectclass=*', array($this->dn), ['pwdpolicysubentry', 'pwdgraceusetime', 'pwdreset', 'pwdchangedtime']);
624 624
 			
625
-			if(array_key_exists('pwdpolicysubentry', $result[0])) {
625
+			if (array_key_exists('pwdpolicysubentry', $result[0])) {
626 626
 				$pwdPolicySubentry = $result[0]['pwdpolicysubentry'];
627
-				if($pwdPolicySubentry && (count($pwdPolicySubentry) > 0)){
628
-					$ppolicyDN = $pwdPolicySubentry[0];//custom ppolicy DN
627
+				if ($pwdPolicySubentry && (count($pwdPolicySubentry) > 0)) {
628
+					$ppolicyDN = $pwdPolicySubentry[0]; //custom ppolicy DN
629 629
 				}
630 630
 			}
631 631
 			
@@ -634,9 +634,9 @@  discard block
 block discarded – undo
634 634
 			$pwdChangedTime = array_key_exists('pwdchangedtime', $result[0]) ? $result[0]['pwdchangedtime'] : null;
635 635
 			
636 636
 			//retrieve relevant password policy attributes
637
-			$cacheKey = 'ppolicyAttributes' . $ppolicyDN;
637
+			$cacheKey = 'ppolicyAttributes'.$ppolicyDN;
638 638
 			$result = $this->connection->getFromCache($cacheKey);
639
-			if(is_null($result)) {
639
+			if (is_null($result)) {
640 640
 				$result = $this->access->search('objectclass=*', array($ppolicyDN), ['pwdgraceauthnlimit', 'pwdmaxage', 'pwdexpirewarning']);
641 641
 				$this->connection->writeToCache($cacheKey, $result);
642 642
 			}
@@ -647,10 +647,10 @@  discard block
 block discarded – undo
647 647
 			
648 648
 			//handle grace login
649 649
 			$pwdGraceUseTimeCount = count($pwdGraceUseTime);
650
-			if($pwdGraceUseTime && $pwdGraceUseTimeCount > 0) { //was this a grace login?
651
-				if($pwdGraceAuthNLimit 
650
+			if ($pwdGraceUseTime && $pwdGraceUseTimeCount > 0) { //was this a grace login?
651
+				if ($pwdGraceAuthNLimit 
652 652
 					&& (count($pwdGraceAuthNLimit) > 0)
653
-					&&($pwdGraceUseTimeCount < (int)$pwdGraceAuthNLimit[0])) { //at least one more grace login available?
653
+					&&($pwdGraceUseTimeCount < (int) $pwdGraceAuthNLimit[0])) { //at least one more grace login available?
654 654
 					$this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
655 655
 					header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
656 656
 					'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
@@ -661,24 +661,24 @@  discard block
 block discarded – undo
661 661
 				exit();
662 662
 			}
663 663
 			//handle pwdReset attribute
664
-			if($pwdReset && (count($pwdReset) > 0) && $pwdReset[0] === 'TRUE') { //user must change his password
664
+			if ($pwdReset && (count($pwdReset) > 0) && $pwdReset[0] === 'TRUE') { //user must change his password
665 665
 				$this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
666 666
 				header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
667 667
 				'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
668 668
 				exit();
669 669
 			}
670 670
 			//handle password expiry warning
671
-			if($pwdChangedTime && (count($pwdChangedTime) > 0)) {
672
-				if($pwdMaxAge && (count($pwdMaxAge) > 0)
671
+			if ($pwdChangedTime && (count($pwdChangedTime) > 0)) {
672
+				if ($pwdMaxAge && (count($pwdMaxAge) > 0)
673 673
 					&& $pwdExpireWarning && (count($pwdExpireWarning) > 0)) {
674
-					$pwdMaxAgeInt = (int)$pwdMaxAge[0];
675
-					$pwdExpireWarningInt = (int)$pwdExpireWarning[0];
676
-					if($pwdMaxAgeInt > 0 && $pwdExpireWarningInt > 0){
674
+					$pwdMaxAgeInt = (int) $pwdMaxAge[0];
675
+					$pwdExpireWarningInt = (int) $pwdExpireWarning[0];
676
+					if ($pwdMaxAgeInt > 0 && $pwdExpireWarningInt > 0) {
677 677
 						$pwdChangedTimeDt = \DateTime::createFromFormat('YmdHisZ', $pwdChangedTime[0]);
678 678
 						$pwdChangedTimeDt->add(new \DateInterval('PT'.$pwdMaxAgeInt.'S'));
679 679
 						$currentDateTime = new \DateTime();
680 680
 						$secondsToExpiry = $pwdChangedTimeDt->getTimestamp() - $currentDateTime->getTimestamp();
681
-						if($secondsToExpiry <= $pwdExpireWarningInt) {
681
+						if ($secondsToExpiry <= $pwdExpireWarningInt) {
682 682
 							//remove last password expiry warning if any
683 683
 							$notification = $this->notificationManager->createNotification();
684 684
 							$notification->setApp('user_ldap')
Please login to merge, or discard this patch.
apps/user_ldap/lib/Connection.php 1 patch
Indentation   +623 added lines, -623 removed lines patch added patch discarded remove patch
@@ -63,628 +63,628 @@
 block discarded – undo
63 63
  * @property string ldapEmailAttribute
64 64
  */
65 65
 class Connection extends LDAPUtility {
66
-	private $ldapConnectionRes = null;
67
-	private $configPrefix;
68
-	private $configID;
69
-	private $configured = false;
70
-	private $hasPagedResultSupport = true;
71
-	//whether connection should be kept on __destruct
72
-	private $dontDestruct = false;
73
-
74
-	/**
75
-	 * @var bool runtime flag that indicates whether supported primary groups are available
76
-	 */
77
-	public $hasPrimaryGroups = true;
78
-
79
-	/**
80
-	 * @var bool runtime flag that indicates whether supported POSIX gidNumber are available
81
-	 */
82
-	public $hasGidNumber = true;
83
-
84
-	//cache handler
85
-	protected $cache;
86
-
87
-	/** @var Configuration settings handler **/
88
-	protected $configuration;
89
-
90
-	protected $doNotValidate = false;
91
-
92
-	protected $ignoreValidation = false;
93
-
94
-	protected $bindResult = [];
95
-
96
-	/**
97
-	 * Constructor
98
-	 * @param ILDAPWrapper $ldap
99
-	 * @param string $configPrefix a string with the prefix for the configkey column (appconfig table)
100
-	 * @param string|null $configID a string with the value for the appid column (appconfig table) or null for on-the-fly connections
101
-	 */
102
-	public function __construct(ILDAPWrapper $ldap, $configPrefix = '', $configID = 'user_ldap') {
103
-		parent::__construct($ldap);
104
-		$this->configPrefix = $configPrefix;
105
-		$this->configID = $configID;
106
-		$this->configuration = new Configuration($configPrefix,
107
-												 !is_null($configID));
108
-		$memcache = \OC::$server->getMemCacheFactory();
109
-		if($memcache->isAvailable()) {
110
-			$this->cache = $memcache->createDistributed();
111
-		}
112
-		$helper = new Helper(\OC::$server->getConfig());
113
-		$this->doNotValidate = !in_array($this->configPrefix,
114
-			$helper->getServerConfigurationPrefixes());
115
-		$this->hasPagedResultSupport =
116
-			(int)$this->configuration->ldapPagingSize !== 0
117
-			|| $this->ldap->hasPagedResultSupport();
118
-	}
119
-
120
-	public function __destruct() {
121
-		if(!$this->dontDestruct && $this->ldap->isResource($this->ldapConnectionRes)) {
122
-			@$this->ldap->unbind($this->ldapConnectionRes);
123
-			$this->bindResult = [];
124
-		}
125
-	}
126
-
127
-	/**
128
-	 * defines behaviour when the instance is cloned
129
-	 */
130
-	public function __clone() {
131
-		$this->configuration = new Configuration($this->configPrefix,
132
-												 !is_null($this->configID));
133
-		if(count($this->bindResult) !== 0 && $this->bindResult['result'] === true) {
134
-			$this->bindResult = [];
135
-		}
136
-		$this->ldapConnectionRes = null;
137
-		$this->dontDestruct = true;
138
-	}
139
-
140
-	/**
141
-	 * @param string $name
142
-	 * @return bool|mixed
143
-	 */
144
-	public function __get($name) {
145
-		if(!$this->configured) {
146
-			$this->readConfiguration();
147
-		}
148
-
149
-		if($name === 'hasPagedResultSupport') {
150
-			return $this->hasPagedResultSupport;
151
-		}
152
-
153
-		return $this->configuration->$name;
154
-	}
155
-
156
-	/**
157
-	 * @param string $name
158
-	 * @param mixed $value
159
-	 */
160
-	public function __set($name, $value) {
161
-		$this->doNotValidate = false;
162
-		$before = $this->configuration->$name;
163
-		$this->configuration->$name = $value;
164
-		$after = $this->configuration->$name;
165
-		if($before !== $after) {
166
-			if ($this->configID !== '' && $this->configID !== null) {
167
-				$this->configuration->saveConfiguration();
168
-			}
169
-			$this->validateConfiguration();
170
-		}
171
-	}
172
-
173
-	/**
174
-	 * @param string $rule
175
-	 * @return array
176
-	 * @throws \RuntimeException
177
-	 */
178
-	public function resolveRule($rule) {
179
-		return $this->configuration->resolveRule($rule);
180
-	}
181
-
182
-	/**
183
-	 * sets whether the result of the configuration validation shall
184
-	 * be ignored when establishing the connection. Used by the Wizard
185
-	 * in early configuration state.
186
-	 * @param bool $state
187
-	 */
188
-	public function setIgnoreValidation($state) {
189
-		$this->ignoreValidation = (bool)$state;
190
-	}
191
-
192
-	/**
193
-	 * initializes the LDAP backend
194
-	 * @param bool $force read the config settings no matter what
195
-	 */
196
-	public function init($force = false) {
197
-		$this->readConfiguration($force);
198
-		$this->establishConnection();
199
-	}
200
-
201
-	/**
202
-	 * Returns the LDAP handler
203
-	 */
204
-	public function getConnectionResource() {
205
-		if(!$this->ldapConnectionRes) {
206
-			$this->init();
207
-		} else if(!$this->ldap->isResource($this->ldapConnectionRes)) {
208
-			$this->ldapConnectionRes = null;
209
-			$this->establishConnection();
210
-		}
211
-		if(is_null($this->ldapConnectionRes)) {
212
-			\OCP\Util::writeLog('user_ldap', 'No LDAP Connection to server ' . $this->configuration->ldapHost, ILogger::ERROR);
213
-			throw new ServerNotAvailableException('Connection to LDAP server could not be established');
214
-		}
215
-		return $this->ldapConnectionRes;
216
-	}
217
-
218
-	/**
219
-	 * resets the connection resource
220
-	 */
221
-	public function resetConnectionResource() {
222
-		if(!is_null($this->ldapConnectionRes)) {
223
-			@$this->ldap->unbind($this->ldapConnectionRes);
224
-			$this->ldapConnectionRes = null;
225
-			$this->bindResult = [];
226
-		}
227
-	}
228
-
229
-	/**
230
-	 * @param string|null $key
231
-	 * @return string
232
-	 */
233
-	private function getCacheKey($key) {
234
-		$prefix = 'LDAP-'.$this->configID.'-'.$this->configPrefix.'-';
235
-		if(is_null($key)) {
236
-			return $prefix;
237
-		}
238
-		return $prefix.hash('sha256', $key);
239
-	}
240
-
241
-	/**
242
-	 * @param string $key
243
-	 * @return mixed|null
244
-	 */
245
-	public function getFromCache($key) {
246
-		if(!$this->configured) {
247
-			$this->readConfiguration();
248
-		}
249
-		if(is_null($this->cache) || !$this->configuration->ldapCacheTTL) {
250
-			return null;
251
-		}
252
-		$key = $this->getCacheKey($key);
253
-
254
-		return json_decode(base64_decode($this->cache->get($key)), true);
255
-	}
256
-
257
-	/**
258
-	 * @param string $key
259
-	 * @param mixed $value
260
-	 *
261
-	 * @return string
262
-	 */
263
-	public function writeToCache($key, $value) {
264
-		if(!$this->configured) {
265
-			$this->readConfiguration();
266
-		}
267
-		if(is_null($this->cache)
268
-			|| !$this->configuration->ldapCacheTTL
269
-			|| !$this->configuration->ldapConfigurationActive) {
270
-			return null;
271
-		}
272
-		$key   = $this->getCacheKey($key);
273
-		$value = base64_encode(json_encode($value));
274
-		$this->cache->set($key, $value, $this->configuration->ldapCacheTTL);
275
-	}
276
-
277
-	public function clearCache() {
278
-		if(!is_null($this->cache)) {
279
-			$this->cache->clear($this->getCacheKey(null));
280
-		}
281
-	}
282
-
283
-	/**
284
-	 * Caches the general LDAP configuration.
285
-	 * @param bool $force optional. true, if the re-read should be forced. defaults
286
-	 * to false.
287
-	 * @return null
288
-	 */
289
-	private function readConfiguration($force = false) {
290
-		if((!$this->configured || $force) && !is_null($this->configID)) {
291
-			$this->configuration->readConfiguration();
292
-			$this->configured = $this->validateConfiguration();
293
-		}
294
-	}
295
-
296
-	/**
297
-	 * set LDAP configuration with values delivered by an array, not read from configuration
298
-	 * @param array $config array that holds the config parameters in an associated array
299
-	 * @param array &$setParameters optional; array where the set fields will be given to
300
-	 * @return boolean true if config validates, false otherwise. Check with $setParameters for detailed success on single parameters
301
-	 */
302
-	public function setConfiguration($config, &$setParameters = null) {
303
-		if(is_null($setParameters)) {
304
-			$setParameters = array();
305
-		}
306
-		$this->doNotValidate = false;
307
-		$this->configuration->setConfiguration($config, $setParameters);
308
-		if(count($setParameters) > 0) {
309
-			$this->configured = $this->validateConfiguration();
310
-		}
311
-
312
-
313
-		return $this->configured;
314
-	}
315
-
316
-	/**
317
-	 * saves the current Configuration in the database and empties the
318
-	 * cache
319
-	 * @return null
320
-	 */
321
-	public function saveConfiguration() {
322
-		$this->configuration->saveConfiguration();
323
-		$this->clearCache();
324
-	}
325
-
326
-	/**
327
-	 * get the current LDAP configuration
328
-	 * @return array
329
-	 */
330
-	public function getConfiguration() {
331
-		$this->readConfiguration();
332
-		$config = $this->configuration->getConfiguration();
333
-		$cta = $this->configuration->getConfigTranslationArray();
334
-		$result = array();
335
-		foreach($cta as $dbkey => $configkey) {
336
-			switch($configkey) {
337
-				case 'homeFolderNamingRule':
338
-					if(strpos($config[$configkey], 'attr:') === 0) {
339
-						$result[$dbkey] = substr($config[$configkey], 5);
340
-					} else {
341
-						$result[$dbkey] = '';
342
-					}
343
-					break;
344
-				case 'ldapBase':
345
-				case 'ldapBaseUsers':
346
-				case 'ldapBaseGroups':
347
-				case 'ldapAttributesForUserSearch':
348
-				case 'ldapAttributesForGroupSearch':
349
-					if(is_array($config[$configkey])) {
350
-						$result[$dbkey] = implode("\n", $config[$configkey]);
351
-						break;
352
-					} //else follows default
353
-				default:
354
-					$result[$dbkey] = $config[$configkey];
355
-			}
356
-		}
357
-		return $result;
358
-	}
359
-
360
-	private function doSoftValidation() {
361
-		//if User or Group Base are not set, take over Base DN setting
362
-		foreach(array('ldapBaseUsers', 'ldapBaseGroups') as $keyBase) {
363
-			$val = $this->configuration->$keyBase;
364
-			if(empty($val)) {
365
-				$this->configuration->$keyBase = $this->configuration->ldapBase;
366
-			}
367
-		}
368
-
369
-		foreach(array('ldapExpertUUIDUserAttr'  => 'ldapUuidUserAttribute',
370
-					  'ldapExpertUUIDGroupAttr' => 'ldapUuidGroupAttribute')
371
-				as $expertSetting => $effectiveSetting) {
372
-			$uuidOverride = $this->configuration->$expertSetting;
373
-			if(!empty($uuidOverride)) {
374
-				$this->configuration->$effectiveSetting = $uuidOverride;
375
-			} else {
376
-				$uuidAttributes = Access::UUID_ATTRIBUTES;
377
-				array_unshift($uuidAttributes, 'auto');
378
-				if(!in_array($this->configuration->$effectiveSetting,
379
-							$uuidAttributes)
380
-					&& (!is_null($this->configID))) {
381
-					$this->configuration->$effectiveSetting = 'auto';
382
-					$this->configuration->saveConfiguration();
383
-					\OCP\Util::writeLog('user_ldap',
384
-										'Illegal value for the '.
385
-										$effectiveSetting.', '.'reset to '.
386
-										'autodetect.', ILogger::INFO);
387
-				}
388
-
389
-			}
390
-		}
391
-
392
-		$backupPort = (int)$this->configuration->ldapBackupPort;
393
-		if ($backupPort <= 0) {
394
-			$this->configuration->backupPort = $this->configuration->ldapPort;
395
-		}
396
-
397
-		//make sure empty search attributes are saved as simple, empty array
398
-		$saKeys = array('ldapAttributesForUserSearch',
399
-						'ldapAttributesForGroupSearch');
400
-		foreach($saKeys as $key) {
401
-			$val = $this->configuration->$key;
402
-			if(is_array($val) && count($val) === 1 && empty($val[0])) {
403
-				$this->configuration->$key = array();
404
-			}
405
-		}
406
-
407
-		if((stripos($this->configuration->ldapHost, 'ldaps://') === 0)
408
-			&& $this->configuration->ldapTLS) {
409
-			$this->configuration->ldapTLS = false;
410
-			\OCP\Util::writeLog(
411
-				'user_ldap',
412
-				'LDAPS (already using secure connection) and TLS do not work together. Switched off TLS.',
413
-				ILogger::INFO
414
-			);
415
-		}
416
-	}
417
-
418
-	/**
419
-	 * @return bool
420
-	 */
421
-	private function doCriticalValidation() {
422
-		$configurationOK = true;
423
-		$errorStr = 'Configuration Error (prefix '.
424
-			(string)$this->configPrefix .'): ';
425
-
426
-		//options that shall not be empty
427
-		$options = array('ldapHost', 'ldapPort', 'ldapUserDisplayName',
428
-						 'ldapGroupDisplayName', 'ldapLoginFilter');
429
-		foreach($options as $key) {
430
-			$val = $this->configuration->$key;
431
-			if(empty($val)) {
432
-				switch($key) {
433
-					case 'ldapHost':
434
-						$subj = 'LDAP Host';
435
-						break;
436
-					case 'ldapPort':
437
-						$subj = 'LDAP Port';
438
-						break;
439
-					case 'ldapUserDisplayName':
440
-						$subj = 'LDAP User Display Name';
441
-						break;
442
-					case 'ldapGroupDisplayName':
443
-						$subj = 'LDAP Group Display Name';
444
-						break;
445
-					case 'ldapLoginFilter':
446
-						$subj = 'LDAP Login Filter';
447
-						break;
448
-					default:
449
-						$subj = $key;
450
-						break;
451
-				}
452
-				$configurationOK = false;
453
-				\OCP\Util::writeLog(
454
-					'user_ldap',
455
-					$errorStr.'No '.$subj.' given!',
456
-					ILogger::WARN
457
-				);
458
-			}
459
-		}
460
-
461
-		//combinations
462
-		$agent = $this->configuration->ldapAgentName;
463
-		$pwd = $this->configuration->ldapAgentPassword;
464
-		if (
465
-			($agent === ''  && $pwd !== '')
466
-			|| ($agent !== '' && $pwd === '')
467
-		) {
468
-			\OCP\Util::writeLog(
469
-				'user_ldap',
470
-				$errorStr.'either no password is given for the user ' .
471
-					'agent or a password is given, but not an LDAP agent.',
472
-				ILogger::WARN);
473
-			$configurationOK = false;
474
-		}
475
-
476
-		$base = $this->configuration->ldapBase;
477
-		$baseUsers = $this->configuration->ldapBaseUsers;
478
-		$baseGroups = $this->configuration->ldapBaseGroups;
479
-
480
-		if(empty($base) && empty($baseUsers) && empty($baseGroups)) {
481
-			\OCP\Util::writeLog(
482
-				'user_ldap',
483
-				$errorStr.'Not a single Base DN given.',
484
-				ILogger::WARN
485
-			);
486
-			$configurationOK = false;
487
-		}
488
-
489
-		if(mb_strpos($this->configuration->ldapLoginFilter, '%uid', 0, 'UTF-8')
490
-		   === false) {
491
-			\OCP\Util::writeLog(
492
-				'user_ldap',
493
-				$errorStr.'login filter does not contain %uid place holder.',
494
-				ILogger::WARN
495
-			);
496
-			$configurationOK = false;
497
-		}
498
-
499
-		return $configurationOK;
500
-	}
501
-
502
-	/**
503
-	 * Validates the user specified configuration
504
-	 * @return bool true if configuration seems OK, false otherwise
505
-	 */
506
-	private function validateConfiguration() {
507
-
508
-		if($this->doNotValidate) {
509
-			//don't do a validation if it is a new configuration with pure
510
-			//default values. Will be allowed on changes via __set or
511
-			//setConfiguration
512
-			return false;
513
-		}
514
-
515
-		// first step: "soft" checks: settings that are not really
516
-		// necessary, but advisable. If left empty, give an info message
517
-		$this->doSoftValidation();
518
-
519
-		//second step: critical checks. If left empty or filled wrong, mark as
520
-		//not configured and give a warning.
521
-		return $this->doCriticalValidation();
522
-	}
523
-
524
-
525
-	/**
526
-	 * Connects and Binds to LDAP
527
-	 *
528
-	 * @throws ServerNotAvailableException
529
-	 */
530
-	private function establishConnection() {
531
-		if(!$this->configuration->ldapConfigurationActive) {
532
-			return null;
533
-		}
534
-		static $phpLDAPinstalled = true;
535
-		if(!$phpLDAPinstalled) {
536
-			return false;
537
-		}
538
-		if(!$this->ignoreValidation && !$this->configured) {
539
-			\OCP\Util::writeLog(
540
-				'user_ldap',
541
-				'Configuration is invalid, cannot connect',
542
-				ILogger::WARN
543
-			);
544
-			return false;
545
-		}
546
-		if(!$this->ldapConnectionRes) {
547
-			if(!$this->ldap->areLDAPFunctionsAvailable()) {
548
-				$phpLDAPinstalled = false;
549
-				\OCP\Util::writeLog(
550
-					'user_ldap',
551
-					'function ldap_connect is not available. Make sure that the PHP ldap module is installed.',
552
-					ILogger::ERROR
553
-				);
554
-
555
-				return false;
556
-			}
557
-			if($this->configuration->turnOffCertCheck) {
558
-				if(putenv('LDAPTLS_REQCERT=never')) {
559
-					\OCP\Util::writeLog('user_ldap',
560
-						'Turned off SSL certificate validation successfully.',
561
-						ILogger::DEBUG);
562
-				} else {
563
-					\OCP\Util::writeLog(
564
-						'user_ldap',
565
-						'Could not turn off SSL certificate validation.',
566
-						ILogger::WARN
567
-					);
568
-				}
569
-			}
570
-
571
-			$isOverrideMainServer = ($this->configuration->ldapOverrideMainServer
572
-				|| $this->getFromCache('overrideMainServer'));
573
-			$isBackupHost = (trim($this->configuration->ldapBackupHost) !== "");
574
-			$bindStatus = false;
575
-			try {
576
-				if (!$isOverrideMainServer) {
577
-					$this->doConnect($this->configuration->ldapHost,
578
-						$this->configuration->ldapPort);
579
-				}
580
-				return $this->bind();
581
-			} catch (ServerNotAvailableException $e) {
582
-				if(!$isBackupHost) {
583
-					throw $e;
584
-				}
585
-			}
586
-
587
-			//if LDAP server is not reachable, try the Backup (Replica!) Server
588
-			if($isBackupHost || $isOverrideMainServer) {
589
-				$this->doConnect($this->configuration->ldapBackupHost,
590
-								 $this->configuration->ldapBackupPort);
591
-				$this->bindResult = [];
592
-				$bindStatus = $this->bind();
593
-				$error = $this->ldap->isResource($this->ldapConnectionRes) ?
594
-					$this->ldap->errno($this->ldapConnectionRes) : -1;
595
-				if($bindStatus && $error === 0 && !$this->getFromCache('overrideMainServer')) {
596
-					//when bind to backup server succeeded and failed to main server,
597
-					//skip contacting him until next cache refresh
598
-					$this->writeToCache('overrideMainServer', true);
599
-				}
600
-			}
601
-
602
-			return $bindStatus;
603
-		}
604
-		return null;
605
-	}
606
-
607
-	/**
608
-	 * @param string $host
609
-	 * @param string $port
610
-	 * @return bool
611
-	 * @throws \OC\ServerNotAvailableException
612
-	 */
613
-	private function doConnect($host, $port) {
614
-		if ($host === '') {
615
-			return false;
616
-		}
617
-
618
-		$this->ldapConnectionRes = $this->ldap->connect($host, $port);
619
-
620
-		if(!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
621
-			throw new ServerNotAvailableException('Could not set required LDAP Protocol version.');
622
-		}
623
-
624
-		if(!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) {
625
-			throw new ServerNotAvailableException('Could not disable LDAP referrals.');
626
-		}
627
-
628
-		if($this->configuration->ldapTLS) {
629
-			if(!$this->ldap->startTls($this->ldapConnectionRes)) {
630
-				throw new ServerNotAvailableException('Start TLS failed, when connecting to LDAP host ' . $host . '.');
631
-			}
632
-		}
633
-
634
-		return true;
635
-	}
636
-
637
-	/**
638
-	 * Binds to LDAP
639
-	 */
640
-	public function bind() {
641
-		if(!$this->configuration->ldapConfigurationActive) {
642
-			return false;
643
-		}
644
-		$cr = $this->ldapConnectionRes;
645
-		if(!$this->ldap->isResource($cr)) {
646
-			$cr = $this->getConnectionResource();
647
-		}
648
-
649
-		if(
650
-			count($this->bindResult) !== 0
651
-			&& $this->bindResult['dn'] === $this->configuration->ldapAgentName
652
-			&& \OC::$server->getHasher()->verify(
653
-				$this->configPrefix . $this->configuration->ldapAgentPassword,
654
-				$this->bindResult['hash']
655
-			)
656
-		) {
657
-			// don't attempt to bind again with the same data as before
658
-			// bind might have been invoked via getConnectionResource(),
659
-			// but we need results specifically for e.g. user login
660
-			return $this->bindResult['result'];
661
-		}
662
-
663
-		$ldapLogin = @$this->ldap->bind($cr,
664
-										$this->configuration->ldapAgentName,
665
-										$this->configuration->ldapAgentPassword);
666
-
667
-		$this->bindResult = [
668
-			'dn' => $this->configuration->ldapAgentName,
669
-			'hash' => \OC::$server->getHasher()->hash($this->configPrefix . $this->configuration->ldapAgentPassword),
670
-			'result' => $ldapLogin,
671
-		];
672
-
673
-		if(!$ldapLogin) {
674
-			$errno = $this->ldap->errno($cr);
675
-
676
-			\OCP\Util::writeLog('user_ldap',
677
-				'Bind failed: ' . $errno . ': ' . $this->ldap->error($cr),
678
-				ILogger::WARN);
679
-
680
-			// Set to failure mode, if LDAP error code is not LDAP_SUCCESS or LDAP_INVALID_CREDENTIALS
681
-			if($errno !== 0x00 && $errno !== 0x31) {
682
-				$this->ldapConnectionRes = null;
683
-			}
684
-
685
-			return false;
686
-		}
687
-		return true;
688
-	}
66
+    private $ldapConnectionRes = null;
67
+    private $configPrefix;
68
+    private $configID;
69
+    private $configured = false;
70
+    private $hasPagedResultSupport = true;
71
+    //whether connection should be kept on __destruct
72
+    private $dontDestruct = false;
73
+
74
+    /**
75
+     * @var bool runtime flag that indicates whether supported primary groups are available
76
+     */
77
+    public $hasPrimaryGroups = true;
78
+
79
+    /**
80
+     * @var bool runtime flag that indicates whether supported POSIX gidNumber are available
81
+     */
82
+    public $hasGidNumber = true;
83
+
84
+    //cache handler
85
+    protected $cache;
86
+
87
+    /** @var Configuration settings handler **/
88
+    protected $configuration;
89
+
90
+    protected $doNotValidate = false;
91
+
92
+    protected $ignoreValidation = false;
93
+
94
+    protected $bindResult = [];
95
+
96
+    /**
97
+     * Constructor
98
+     * @param ILDAPWrapper $ldap
99
+     * @param string $configPrefix a string with the prefix for the configkey column (appconfig table)
100
+     * @param string|null $configID a string with the value for the appid column (appconfig table) or null for on-the-fly connections
101
+     */
102
+    public function __construct(ILDAPWrapper $ldap, $configPrefix = '', $configID = 'user_ldap') {
103
+        parent::__construct($ldap);
104
+        $this->configPrefix = $configPrefix;
105
+        $this->configID = $configID;
106
+        $this->configuration = new Configuration($configPrefix,
107
+                                                    !is_null($configID));
108
+        $memcache = \OC::$server->getMemCacheFactory();
109
+        if($memcache->isAvailable()) {
110
+            $this->cache = $memcache->createDistributed();
111
+        }
112
+        $helper = new Helper(\OC::$server->getConfig());
113
+        $this->doNotValidate = !in_array($this->configPrefix,
114
+            $helper->getServerConfigurationPrefixes());
115
+        $this->hasPagedResultSupport =
116
+            (int)$this->configuration->ldapPagingSize !== 0
117
+            || $this->ldap->hasPagedResultSupport();
118
+    }
119
+
120
+    public function __destruct() {
121
+        if(!$this->dontDestruct && $this->ldap->isResource($this->ldapConnectionRes)) {
122
+            @$this->ldap->unbind($this->ldapConnectionRes);
123
+            $this->bindResult = [];
124
+        }
125
+    }
126
+
127
+    /**
128
+     * defines behaviour when the instance is cloned
129
+     */
130
+    public function __clone() {
131
+        $this->configuration = new Configuration($this->configPrefix,
132
+                                                    !is_null($this->configID));
133
+        if(count($this->bindResult) !== 0 && $this->bindResult['result'] === true) {
134
+            $this->bindResult = [];
135
+        }
136
+        $this->ldapConnectionRes = null;
137
+        $this->dontDestruct = true;
138
+    }
139
+
140
+    /**
141
+     * @param string $name
142
+     * @return bool|mixed
143
+     */
144
+    public function __get($name) {
145
+        if(!$this->configured) {
146
+            $this->readConfiguration();
147
+        }
148
+
149
+        if($name === 'hasPagedResultSupport') {
150
+            return $this->hasPagedResultSupport;
151
+        }
152
+
153
+        return $this->configuration->$name;
154
+    }
155
+
156
+    /**
157
+     * @param string $name
158
+     * @param mixed $value
159
+     */
160
+    public function __set($name, $value) {
161
+        $this->doNotValidate = false;
162
+        $before = $this->configuration->$name;
163
+        $this->configuration->$name = $value;
164
+        $after = $this->configuration->$name;
165
+        if($before !== $after) {
166
+            if ($this->configID !== '' && $this->configID !== null) {
167
+                $this->configuration->saveConfiguration();
168
+            }
169
+            $this->validateConfiguration();
170
+        }
171
+    }
172
+
173
+    /**
174
+     * @param string $rule
175
+     * @return array
176
+     * @throws \RuntimeException
177
+     */
178
+    public function resolveRule($rule) {
179
+        return $this->configuration->resolveRule($rule);
180
+    }
181
+
182
+    /**
183
+     * sets whether the result of the configuration validation shall
184
+     * be ignored when establishing the connection. Used by the Wizard
185
+     * in early configuration state.
186
+     * @param bool $state
187
+     */
188
+    public function setIgnoreValidation($state) {
189
+        $this->ignoreValidation = (bool)$state;
190
+    }
191
+
192
+    /**
193
+     * initializes the LDAP backend
194
+     * @param bool $force read the config settings no matter what
195
+     */
196
+    public function init($force = false) {
197
+        $this->readConfiguration($force);
198
+        $this->establishConnection();
199
+    }
200
+
201
+    /**
202
+     * Returns the LDAP handler
203
+     */
204
+    public function getConnectionResource() {
205
+        if(!$this->ldapConnectionRes) {
206
+            $this->init();
207
+        } else if(!$this->ldap->isResource($this->ldapConnectionRes)) {
208
+            $this->ldapConnectionRes = null;
209
+            $this->establishConnection();
210
+        }
211
+        if(is_null($this->ldapConnectionRes)) {
212
+            \OCP\Util::writeLog('user_ldap', 'No LDAP Connection to server ' . $this->configuration->ldapHost, ILogger::ERROR);
213
+            throw new ServerNotAvailableException('Connection to LDAP server could not be established');
214
+        }
215
+        return $this->ldapConnectionRes;
216
+    }
217
+
218
+    /**
219
+     * resets the connection resource
220
+     */
221
+    public function resetConnectionResource() {
222
+        if(!is_null($this->ldapConnectionRes)) {
223
+            @$this->ldap->unbind($this->ldapConnectionRes);
224
+            $this->ldapConnectionRes = null;
225
+            $this->bindResult = [];
226
+        }
227
+    }
228
+
229
+    /**
230
+     * @param string|null $key
231
+     * @return string
232
+     */
233
+    private function getCacheKey($key) {
234
+        $prefix = 'LDAP-'.$this->configID.'-'.$this->configPrefix.'-';
235
+        if(is_null($key)) {
236
+            return $prefix;
237
+        }
238
+        return $prefix.hash('sha256', $key);
239
+    }
240
+
241
+    /**
242
+     * @param string $key
243
+     * @return mixed|null
244
+     */
245
+    public function getFromCache($key) {
246
+        if(!$this->configured) {
247
+            $this->readConfiguration();
248
+        }
249
+        if(is_null($this->cache) || !$this->configuration->ldapCacheTTL) {
250
+            return null;
251
+        }
252
+        $key = $this->getCacheKey($key);
253
+
254
+        return json_decode(base64_decode($this->cache->get($key)), true);
255
+    }
256
+
257
+    /**
258
+     * @param string $key
259
+     * @param mixed $value
260
+     *
261
+     * @return string
262
+     */
263
+    public function writeToCache($key, $value) {
264
+        if(!$this->configured) {
265
+            $this->readConfiguration();
266
+        }
267
+        if(is_null($this->cache)
268
+            || !$this->configuration->ldapCacheTTL
269
+            || !$this->configuration->ldapConfigurationActive) {
270
+            return null;
271
+        }
272
+        $key   = $this->getCacheKey($key);
273
+        $value = base64_encode(json_encode($value));
274
+        $this->cache->set($key, $value, $this->configuration->ldapCacheTTL);
275
+    }
276
+
277
+    public function clearCache() {
278
+        if(!is_null($this->cache)) {
279
+            $this->cache->clear($this->getCacheKey(null));
280
+        }
281
+    }
282
+
283
+    /**
284
+     * Caches the general LDAP configuration.
285
+     * @param bool $force optional. true, if the re-read should be forced. defaults
286
+     * to false.
287
+     * @return null
288
+     */
289
+    private function readConfiguration($force = false) {
290
+        if((!$this->configured || $force) && !is_null($this->configID)) {
291
+            $this->configuration->readConfiguration();
292
+            $this->configured = $this->validateConfiguration();
293
+        }
294
+    }
295
+
296
+    /**
297
+     * set LDAP configuration with values delivered by an array, not read from configuration
298
+     * @param array $config array that holds the config parameters in an associated array
299
+     * @param array &$setParameters optional; array where the set fields will be given to
300
+     * @return boolean true if config validates, false otherwise. Check with $setParameters for detailed success on single parameters
301
+     */
302
+    public function setConfiguration($config, &$setParameters = null) {
303
+        if(is_null($setParameters)) {
304
+            $setParameters = array();
305
+        }
306
+        $this->doNotValidate = false;
307
+        $this->configuration->setConfiguration($config, $setParameters);
308
+        if(count($setParameters) > 0) {
309
+            $this->configured = $this->validateConfiguration();
310
+        }
311
+
312
+
313
+        return $this->configured;
314
+    }
315
+
316
+    /**
317
+     * saves the current Configuration in the database and empties the
318
+     * cache
319
+     * @return null
320
+     */
321
+    public function saveConfiguration() {
322
+        $this->configuration->saveConfiguration();
323
+        $this->clearCache();
324
+    }
325
+
326
+    /**
327
+     * get the current LDAP configuration
328
+     * @return array
329
+     */
330
+    public function getConfiguration() {
331
+        $this->readConfiguration();
332
+        $config = $this->configuration->getConfiguration();
333
+        $cta = $this->configuration->getConfigTranslationArray();
334
+        $result = array();
335
+        foreach($cta as $dbkey => $configkey) {
336
+            switch($configkey) {
337
+                case 'homeFolderNamingRule':
338
+                    if(strpos($config[$configkey], 'attr:') === 0) {
339
+                        $result[$dbkey] = substr($config[$configkey], 5);
340
+                    } else {
341
+                        $result[$dbkey] = '';
342
+                    }
343
+                    break;
344
+                case 'ldapBase':
345
+                case 'ldapBaseUsers':
346
+                case 'ldapBaseGroups':
347
+                case 'ldapAttributesForUserSearch':
348
+                case 'ldapAttributesForGroupSearch':
349
+                    if(is_array($config[$configkey])) {
350
+                        $result[$dbkey] = implode("\n", $config[$configkey]);
351
+                        break;
352
+                    } //else follows default
353
+                default:
354
+                    $result[$dbkey] = $config[$configkey];
355
+            }
356
+        }
357
+        return $result;
358
+    }
359
+
360
+    private function doSoftValidation() {
361
+        //if User or Group Base are not set, take over Base DN setting
362
+        foreach(array('ldapBaseUsers', 'ldapBaseGroups') as $keyBase) {
363
+            $val = $this->configuration->$keyBase;
364
+            if(empty($val)) {
365
+                $this->configuration->$keyBase = $this->configuration->ldapBase;
366
+            }
367
+        }
368
+
369
+        foreach(array('ldapExpertUUIDUserAttr'  => 'ldapUuidUserAttribute',
370
+                        'ldapExpertUUIDGroupAttr' => 'ldapUuidGroupAttribute')
371
+                as $expertSetting => $effectiveSetting) {
372
+            $uuidOverride = $this->configuration->$expertSetting;
373
+            if(!empty($uuidOverride)) {
374
+                $this->configuration->$effectiveSetting = $uuidOverride;
375
+            } else {
376
+                $uuidAttributes = Access::UUID_ATTRIBUTES;
377
+                array_unshift($uuidAttributes, 'auto');
378
+                if(!in_array($this->configuration->$effectiveSetting,
379
+                            $uuidAttributes)
380
+                    && (!is_null($this->configID))) {
381
+                    $this->configuration->$effectiveSetting = 'auto';
382
+                    $this->configuration->saveConfiguration();
383
+                    \OCP\Util::writeLog('user_ldap',
384
+                                        'Illegal value for the '.
385
+                                        $effectiveSetting.', '.'reset to '.
386
+                                        'autodetect.', ILogger::INFO);
387
+                }
388
+
389
+            }
390
+        }
391
+
392
+        $backupPort = (int)$this->configuration->ldapBackupPort;
393
+        if ($backupPort <= 0) {
394
+            $this->configuration->backupPort = $this->configuration->ldapPort;
395
+        }
396
+
397
+        //make sure empty search attributes are saved as simple, empty array
398
+        $saKeys = array('ldapAttributesForUserSearch',
399
+                        'ldapAttributesForGroupSearch');
400
+        foreach($saKeys as $key) {
401
+            $val = $this->configuration->$key;
402
+            if(is_array($val) && count($val) === 1 && empty($val[0])) {
403
+                $this->configuration->$key = array();
404
+            }
405
+        }
406
+
407
+        if((stripos($this->configuration->ldapHost, 'ldaps://') === 0)
408
+            && $this->configuration->ldapTLS) {
409
+            $this->configuration->ldapTLS = false;
410
+            \OCP\Util::writeLog(
411
+                'user_ldap',
412
+                'LDAPS (already using secure connection) and TLS do not work together. Switched off TLS.',
413
+                ILogger::INFO
414
+            );
415
+        }
416
+    }
417
+
418
+    /**
419
+     * @return bool
420
+     */
421
+    private function doCriticalValidation() {
422
+        $configurationOK = true;
423
+        $errorStr = 'Configuration Error (prefix '.
424
+            (string)$this->configPrefix .'): ';
425
+
426
+        //options that shall not be empty
427
+        $options = array('ldapHost', 'ldapPort', 'ldapUserDisplayName',
428
+                            'ldapGroupDisplayName', 'ldapLoginFilter');
429
+        foreach($options as $key) {
430
+            $val = $this->configuration->$key;
431
+            if(empty($val)) {
432
+                switch($key) {
433
+                    case 'ldapHost':
434
+                        $subj = 'LDAP Host';
435
+                        break;
436
+                    case 'ldapPort':
437
+                        $subj = 'LDAP Port';
438
+                        break;
439
+                    case 'ldapUserDisplayName':
440
+                        $subj = 'LDAP User Display Name';
441
+                        break;
442
+                    case 'ldapGroupDisplayName':
443
+                        $subj = 'LDAP Group Display Name';
444
+                        break;
445
+                    case 'ldapLoginFilter':
446
+                        $subj = 'LDAP Login Filter';
447
+                        break;
448
+                    default:
449
+                        $subj = $key;
450
+                        break;
451
+                }
452
+                $configurationOK = false;
453
+                \OCP\Util::writeLog(
454
+                    'user_ldap',
455
+                    $errorStr.'No '.$subj.' given!',
456
+                    ILogger::WARN
457
+                );
458
+            }
459
+        }
460
+
461
+        //combinations
462
+        $agent = $this->configuration->ldapAgentName;
463
+        $pwd = $this->configuration->ldapAgentPassword;
464
+        if (
465
+            ($agent === ''  && $pwd !== '')
466
+            || ($agent !== '' && $pwd === '')
467
+        ) {
468
+            \OCP\Util::writeLog(
469
+                'user_ldap',
470
+                $errorStr.'either no password is given for the user ' .
471
+                    'agent or a password is given, but not an LDAP agent.',
472
+                ILogger::WARN);
473
+            $configurationOK = false;
474
+        }
475
+
476
+        $base = $this->configuration->ldapBase;
477
+        $baseUsers = $this->configuration->ldapBaseUsers;
478
+        $baseGroups = $this->configuration->ldapBaseGroups;
479
+
480
+        if(empty($base) && empty($baseUsers) && empty($baseGroups)) {
481
+            \OCP\Util::writeLog(
482
+                'user_ldap',
483
+                $errorStr.'Not a single Base DN given.',
484
+                ILogger::WARN
485
+            );
486
+            $configurationOK = false;
487
+        }
488
+
489
+        if(mb_strpos($this->configuration->ldapLoginFilter, '%uid', 0, 'UTF-8')
490
+            === false) {
491
+            \OCP\Util::writeLog(
492
+                'user_ldap',
493
+                $errorStr.'login filter does not contain %uid place holder.',
494
+                ILogger::WARN
495
+            );
496
+            $configurationOK = false;
497
+        }
498
+
499
+        return $configurationOK;
500
+    }
501
+
502
+    /**
503
+     * Validates the user specified configuration
504
+     * @return bool true if configuration seems OK, false otherwise
505
+     */
506
+    private function validateConfiguration() {
507
+
508
+        if($this->doNotValidate) {
509
+            //don't do a validation if it is a new configuration with pure
510
+            //default values. Will be allowed on changes via __set or
511
+            //setConfiguration
512
+            return false;
513
+        }
514
+
515
+        // first step: "soft" checks: settings that are not really
516
+        // necessary, but advisable. If left empty, give an info message
517
+        $this->doSoftValidation();
518
+
519
+        //second step: critical checks. If left empty or filled wrong, mark as
520
+        //not configured and give a warning.
521
+        return $this->doCriticalValidation();
522
+    }
523
+
524
+
525
+    /**
526
+     * Connects and Binds to LDAP
527
+     *
528
+     * @throws ServerNotAvailableException
529
+     */
530
+    private function establishConnection() {
531
+        if(!$this->configuration->ldapConfigurationActive) {
532
+            return null;
533
+        }
534
+        static $phpLDAPinstalled = true;
535
+        if(!$phpLDAPinstalled) {
536
+            return false;
537
+        }
538
+        if(!$this->ignoreValidation && !$this->configured) {
539
+            \OCP\Util::writeLog(
540
+                'user_ldap',
541
+                'Configuration is invalid, cannot connect',
542
+                ILogger::WARN
543
+            );
544
+            return false;
545
+        }
546
+        if(!$this->ldapConnectionRes) {
547
+            if(!$this->ldap->areLDAPFunctionsAvailable()) {
548
+                $phpLDAPinstalled = false;
549
+                \OCP\Util::writeLog(
550
+                    'user_ldap',
551
+                    'function ldap_connect is not available. Make sure that the PHP ldap module is installed.',
552
+                    ILogger::ERROR
553
+                );
554
+
555
+                return false;
556
+            }
557
+            if($this->configuration->turnOffCertCheck) {
558
+                if(putenv('LDAPTLS_REQCERT=never')) {
559
+                    \OCP\Util::writeLog('user_ldap',
560
+                        'Turned off SSL certificate validation successfully.',
561
+                        ILogger::DEBUG);
562
+                } else {
563
+                    \OCP\Util::writeLog(
564
+                        'user_ldap',
565
+                        'Could not turn off SSL certificate validation.',
566
+                        ILogger::WARN
567
+                    );
568
+                }
569
+            }
570
+
571
+            $isOverrideMainServer = ($this->configuration->ldapOverrideMainServer
572
+                || $this->getFromCache('overrideMainServer'));
573
+            $isBackupHost = (trim($this->configuration->ldapBackupHost) !== "");
574
+            $bindStatus = false;
575
+            try {
576
+                if (!$isOverrideMainServer) {
577
+                    $this->doConnect($this->configuration->ldapHost,
578
+                        $this->configuration->ldapPort);
579
+                }
580
+                return $this->bind();
581
+            } catch (ServerNotAvailableException $e) {
582
+                if(!$isBackupHost) {
583
+                    throw $e;
584
+                }
585
+            }
586
+
587
+            //if LDAP server is not reachable, try the Backup (Replica!) Server
588
+            if($isBackupHost || $isOverrideMainServer) {
589
+                $this->doConnect($this->configuration->ldapBackupHost,
590
+                                    $this->configuration->ldapBackupPort);
591
+                $this->bindResult = [];
592
+                $bindStatus = $this->bind();
593
+                $error = $this->ldap->isResource($this->ldapConnectionRes) ?
594
+                    $this->ldap->errno($this->ldapConnectionRes) : -1;
595
+                if($bindStatus && $error === 0 && !$this->getFromCache('overrideMainServer')) {
596
+                    //when bind to backup server succeeded and failed to main server,
597
+                    //skip contacting him until next cache refresh
598
+                    $this->writeToCache('overrideMainServer', true);
599
+                }
600
+            }
601
+
602
+            return $bindStatus;
603
+        }
604
+        return null;
605
+    }
606
+
607
+    /**
608
+     * @param string $host
609
+     * @param string $port
610
+     * @return bool
611
+     * @throws \OC\ServerNotAvailableException
612
+     */
613
+    private function doConnect($host, $port) {
614
+        if ($host === '') {
615
+            return false;
616
+        }
617
+
618
+        $this->ldapConnectionRes = $this->ldap->connect($host, $port);
619
+
620
+        if(!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
621
+            throw new ServerNotAvailableException('Could not set required LDAP Protocol version.');
622
+        }
623
+
624
+        if(!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) {
625
+            throw new ServerNotAvailableException('Could not disable LDAP referrals.');
626
+        }
627
+
628
+        if($this->configuration->ldapTLS) {
629
+            if(!$this->ldap->startTls($this->ldapConnectionRes)) {
630
+                throw new ServerNotAvailableException('Start TLS failed, when connecting to LDAP host ' . $host . '.');
631
+            }
632
+        }
633
+
634
+        return true;
635
+    }
636
+
637
+    /**
638
+     * Binds to LDAP
639
+     */
640
+    public function bind() {
641
+        if(!$this->configuration->ldapConfigurationActive) {
642
+            return false;
643
+        }
644
+        $cr = $this->ldapConnectionRes;
645
+        if(!$this->ldap->isResource($cr)) {
646
+            $cr = $this->getConnectionResource();
647
+        }
648
+
649
+        if(
650
+            count($this->bindResult) !== 0
651
+            && $this->bindResult['dn'] === $this->configuration->ldapAgentName
652
+            && \OC::$server->getHasher()->verify(
653
+                $this->configPrefix . $this->configuration->ldapAgentPassword,
654
+                $this->bindResult['hash']
655
+            )
656
+        ) {
657
+            // don't attempt to bind again with the same data as before
658
+            // bind might have been invoked via getConnectionResource(),
659
+            // but we need results specifically for e.g. user login
660
+            return $this->bindResult['result'];
661
+        }
662
+
663
+        $ldapLogin = @$this->ldap->bind($cr,
664
+                                        $this->configuration->ldapAgentName,
665
+                                        $this->configuration->ldapAgentPassword);
666
+
667
+        $this->bindResult = [
668
+            'dn' => $this->configuration->ldapAgentName,
669
+            'hash' => \OC::$server->getHasher()->hash($this->configPrefix . $this->configuration->ldapAgentPassword),
670
+            'result' => $ldapLogin,
671
+        ];
672
+
673
+        if(!$ldapLogin) {
674
+            $errno = $this->ldap->errno($cr);
675
+
676
+            \OCP\Util::writeLog('user_ldap',
677
+                'Bind failed: ' . $errno . ': ' . $this->ldap->error($cr),
678
+                ILogger::WARN);
679
+
680
+            // Set to failure mode, if LDAP error code is not LDAP_SUCCESS or LDAP_INVALID_CREDENTIALS
681
+            if($errno !== 0x00 && $errno !== 0x31) {
682
+                $this->ldapConnectionRes = null;
683
+            }
684
+
685
+            return false;
686
+        }
687
+        return true;
688
+    }
689 689
 
690 690
 }
Please login to merge, or discard this patch.
apps/user_ldap/lib/Configuration.php 2 patches
Indentation   +509 added lines, -509 removed lines patch added patch discarded remove patch
@@ -38,542 +38,542 @@
 block discarded – undo
38 38
  * @property string ldapUserAvatarRule
39 39
  */
40 40
 class Configuration {
41
-	const AVATAR_PREFIX_DEFAULT = 'default';
42
-	const AVATAR_PREFIX_NONE = 'none';
43
-	const AVATAR_PREFIX_DATA_ATTRIBUTE = 'data:';
41
+    const AVATAR_PREFIX_DEFAULT = 'default';
42
+    const AVATAR_PREFIX_NONE = 'none';
43
+    const AVATAR_PREFIX_DATA_ATTRIBUTE = 'data:';
44 44
 
45
-	protected $configPrefix = null;
46
-	protected $configRead = false;
47
-	/**
48
-	 * @var string[] pre-filled with one reference key so that at least one entry is written on save request and
49
-	 *               the config ID is registered
50
-	 */
51
-	protected $unsavedChanges = ['ldapConfigurationActive' => 'ldapConfigurationActive'];
45
+    protected $configPrefix = null;
46
+    protected $configRead = false;
47
+    /**
48
+     * @var string[] pre-filled with one reference key so that at least one entry is written on save request and
49
+     *               the config ID is registered
50
+     */
51
+    protected $unsavedChanges = ['ldapConfigurationActive' => 'ldapConfigurationActive'];
52 52
 
53
-	//settings
54
-	protected $config = array(
55
-		'ldapHost' => null,
56
-		'ldapPort' => null,
57
-		'ldapBackupHost' => null,
58
-		'ldapBackupPort' => null,
59
-		'ldapBase' => null,
60
-		'ldapBaseUsers' => null,
61
-		'ldapBaseGroups' => null,
62
-		'ldapAgentName' => null,
63
-		'ldapAgentPassword' => null,
64
-		'ldapTLS' => null,
65
-		'turnOffCertCheck' => null,
66
-		'ldapIgnoreNamingRules' => null,
67
-		'ldapUserDisplayName' => null,
68
-		'ldapUserDisplayName2' => null,
69
-		'ldapUserAvatarRule' => null,
70
-		'ldapGidNumber' => null,
71
-		'ldapUserFilterObjectclass' => null,
72
-		'ldapUserFilterGroups' => null,
73
-		'ldapUserFilter' => null,
74
-		'ldapUserFilterMode' => null,
75
-		'ldapGroupFilter' => null,
76
-		'ldapGroupFilterMode' => null,
77
-		'ldapGroupFilterObjectclass' => null,
78
-		'ldapGroupFilterGroups' => null,
79
-		'ldapGroupDisplayName' => null,
80
-		'ldapGroupMemberAssocAttr' => null,
81
-		'ldapLoginFilter' => null,
82
-		'ldapLoginFilterMode' => null,
83
-		'ldapLoginFilterEmail' => null,
84
-		'ldapLoginFilterUsername' => null,
85
-		'ldapLoginFilterAttributes' => null,
86
-		'ldapQuotaAttribute' => null,
87
-		'ldapQuotaDefault' => null,
88
-		'ldapEmailAttribute' => null,
89
-		'ldapCacheTTL' => null,
90
-		'ldapUuidUserAttribute' => 'auto',
91
-		'ldapUuidGroupAttribute' => 'auto',
92
-		'ldapOverrideMainServer' => false,
93
-		'ldapConfigurationActive' => false,
94
-		'ldapAttributesForUserSearch' => null,
95
-		'ldapAttributesForGroupSearch' => null,
96
-		'ldapExperiencedAdmin' => false,
97
-		'homeFolderNamingRule' => null,
98
-		'hasPagedResultSupport' => false,
99
-		'hasMemberOfFilterSupport' => false,
100
-		'useMemberOfToDetectMembership' => true,
101
-		'ldapExpertUsernameAttr' => null,
102
-		'ldapExpertUUIDUserAttr' => null,
103
-		'ldapExpertUUIDGroupAttr' => null,
104
-		'lastJpegPhotoLookup' => null,
105
-		'ldapNestedGroups' => false,
106
-		'ldapPagingSize' => null,
107
-		'turnOnPasswordChange' => false,
108
-		'ldapDynamicGroupMemberURL' => null,
109
-		'ldapDefaultPPolicyDN' => null,
110
-	);
53
+    //settings
54
+    protected $config = array(
55
+        'ldapHost' => null,
56
+        'ldapPort' => null,
57
+        'ldapBackupHost' => null,
58
+        'ldapBackupPort' => null,
59
+        'ldapBase' => null,
60
+        'ldapBaseUsers' => null,
61
+        'ldapBaseGroups' => null,
62
+        'ldapAgentName' => null,
63
+        'ldapAgentPassword' => null,
64
+        'ldapTLS' => null,
65
+        'turnOffCertCheck' => null,
66
+        'ldapIgnoreNamingRules' => null,
67
+        'ldapUserDisplayName' => null,
68
+        'ldapUserDisplayName2' => null,
69
+        'ldapUserAvatarRule' => null,
70
+        'ldapGidNumber' => null,
71
+        'ldapUserFilterObjectclass' => null,
72
+        'ldapUserFilterGroups' => null,
73
+        'ldapUserFilter' => null,
74
+        'ldapUserFilterMode' => null,
75
+        'ldapGroupFilter' => null,
76
+        'ldapGroupFilterMode' => null,
77
+        'ldapGroupFilterObjectclass' => null,
78
+        'ldapGroupFilterGroups' => null,
79
+        'ldapGroupDisplayName' => null,
80
+        'ldapGroupMemberAssocAttr' => null,
81
+        'ldapLoginFilter' => null,
82
+        'ldapLoginFilterMode' => null,
83
+        'ldapLoginFilterEmail' => null,
84
+        'ldapLoginFilterUsername' => null,
85
+        'ldapLoginFilterAttributes' => null,
86
+        'ldapQuotaAttribute' => null,
87
+        'ldapQuotaDefault' => null,
88
+        'ldapEmailAttribute' => null,
89
+        'ldapCacheTTL' => null,
90
+        'ldapUuidUserAttribute' => 'auto',
91
+        'ldapUuidGroupAttribute' => 'auto',
92
+        'ldapOverrideMainServer' => false,
93
+        'ldapConfigurationActive' => false,
94
+        'ldapAttributesForUserSearch' => null,
95
+        'ldapAttributesForGroupSearch' => null,
96
+        'ldapExperiencedAdmin' => false,
97
+        'homeFolderNamingRule' => null,
98
+        'hasPagedResultSupport' => false,
99
+        'hasMemberOfFilterSupport' => false,
100
+        'useMemberOfToDetectMembership' => true,
101
+        'ldapExpertUsernameAttr' => null,
102
+        'ldapExpertUUIDUserAttr' => null,
103
+        'ldapExpertUUIDGroupAttr' => null,
104
+        'lastJpegPhotoLookup' => null,
105
+        'ldapNestedGroups' => false,
106
+        'ldapPagingSize' => null,
107
+        'turnOnPasswordChange' => false,
108
+        'ldapDynamicGroupMemberURL' => null,
109
+        'ldapDefaultPPolicyDN' => null,
110
+    );
111 111
 
112
-	/**
113
-	 * @param string $configPrefix
114
-	 * @param bool $autoRead
115
-	 */
116
-	public function __construct($configPrefix, $autoRead = true) {
117
-		$this->configPrefix = $configPrefix;
118
-		if($autoRead) {
119
-			$this->readConfiguration();
120
-		}
121
-	}
112
+    /**
113
+     * @param string $configPrefix
114
+     * @param bool $autoRead
115
+     */
116
+    public function __construct($configPrefix, $autoRead = true) {
117
+        $this->configPrefix = $configPrefix;
118
+        if($autoRead) {
119
+            $this->readConfiguration();
120
+        }
121
+    }
122 122
 
123
-	/**
124
-	 * @param string $name
125
-	 * @return mixed|null
126
-	 */
127
-	public function __get($name) {
128
-		if(isset($this->config[$name])) {
129
-			return $this->config[$name];
130
-		}
131
-		return null;
132
-	}
123
+    /**
124
+     * @param string $name
125
+     * @return mixed|null
126
+     */
127
+    public function __get($name) {
128
+        if(isset($this->config[$name])) {
129
+            return $this->config[$name];
130
+        }
131
+        return null;
132
+    }
133 133
 
134
-	/**
135
-	 * @param string $name
136
-	 * @param mixed $value
137
-	 */
138
-	public function __set($name, $value) {
139
-		$this->setConfiguration(array($name => $value));
140
-	}
134
+    /**
135
+     * @param string $name
136
+     * @param mixed $value
137
+     */
138
+    public function __set($name, $value) {
139
+        $this->setConfiguration(array($name => $value));
140
+    }
141 141
 
142
-	/**
143
-	 * @return array
144
-	 */
145
-	public function getConfiguration() {
146
-		return $this->config;
147
-	}
142
+    /**
143
+     * @return array
144
+     */
145
+    public function getConfiguration() {
146
+        return $this->config;
147
+    }
148 148
 
149
-	/**
150
-	 * set LDAP configuration with values delivered by an array, not read
151
-	 * from configuration. It does not save the configuration! To do so, you
152
-	 * must call saveConfiguration afterwards.
153
-	 * @param array $config array that holds the config parameters in an associated
154
-	 * array
155
-	 * @param array &$applied optional; array where the set fields will be given to
156
-	 * @return false|null
157
-	 */
158
-	public function setConfiguration($config, &$applied = null) {
159
-		if(!is_array($config)) {
160
-			return false;
161
-		}
149
+    /**
150
+     * set LDAP configuration with values delivered by an array, not read
151
+     * from configuration. It does not save the configuration! To do so, you
152
+     * must call saveConfiguration afterwards.
153
+     * @param array $config array that holds the config parameters in an associated
154
+     * array
155
+     * @param array &$applied optional; array where the set fields will be given to
156
+     * @return false|null
157
+     */
158
+    public function setConfiguration($config, &$applied = null) {
159
+        if(!is_array($config)) {
160
+            return false;
161
+        }
162 162
 
163
-		$cta = $this->getConfigTranslationArray();
164
-		foreach($config as $inputKey => $val) {
165
-			if(strpos($inputKey, '_') !== false && array_key_exists($inputKey, $cta)) {
166
-				$key = $cta[$inputKey];
167
-			} elseif(array_key_exists($inputKey, $this->config)) {
168
-				$key = $inputKey;
169
-			} else {
170
-				continue;
171
-			}
163
+        $cta = $this->getConfigTranslationArray();
164
+        foreach($config as $inputKey => $val) {
165
+            if(strpos($inputKey, '_') !== false && array_key_exists($inputKey, $cta)) {
166
+                $key = $cta[$inputKey];
167
+            } elseif(array_key_exists($inputKey, $this->config)) {
168
+                $key = $inputKey;
169
+            } else {
170
+                continue;
171
+            }
172 172
 
173
-			$setMethod = 'setValue';
174
-			switch($key) {
175
-				case 'ldapAgentPassword':
176
-					$setMethod = 'setRawValue';
177
-					break;
178
-				case 'homeFolderNamingRule':
179
-					$trimmedVal = trim($val);
180
-					if ($trimmedVal !== '' && strpos($val, 'attr:') === false) {
181
-						$val = 'attr:'.$trimmedVal;
182
-					}
183
-					break;
184
-				case 'ldapBase':
185
-				case 'ldapBaseUsers':
186
-				case 'ldapBaseGroups':
187
-				case 'ldapAttributesForUserSearch':
188
-				case 'ldapAttributesForGroupSearch':
189
-				case 'ldapUserFilterObjectclass':
190
-				case 'ldapUserFilterGroups':
191
-				case 'ldapGroupFilterObjectclass':
192
-				case 'ldapGroupFilterGroups':
193
-				case 'ldapLoginFilterAttributes':
194
-					$setMethod = 'setMultiLine';
195
-					break;
196
-			}
197
-			$this->$setMethod($key, $val);
198
-			if(is_array($applied)) {
199
-				$applied[] = $inputKey;
200
-				// storing key as index avoids duplication, and as value for simplicity
201
-			}
202
-			$this->unsavedChanges[$key] = $key;
203
-		}
204
-		return null;
205
-	}
173
+            $setMethod = 'setValue';
174
+            switch($key) {
175
+                case 'ldapAgentPassword':
176
+                    $setMethod = 'setRawValue';
177
+                    break;
178
+                case 'homeFolderNamingRule':
179
+                    $trimmedVal = trim($val);
180
+                    if ($trimmedVal !== '' && strpos($val, 'attr:') === false) {
181
+                        $val = 'attr:'.$trimmedVal;
182
+                    }
183
+                    break;
184
+                case 'ldapBase':
185
+                case 'ldapBaseUsers':
186
+                case 'ldapBaseGroups':
187
+                case 'ldapAttributesForUserSearch':
188
+                case 'ldapAttributesForGroupSearch':
189
+                case 'ldapUserFilterObjectclass':
190
+                case 'ldapUserFilterGroups':
191
+                case 'ldapGroupFilterObjectclass':
192
+                case 'ldapGroupFilterGroups':
193
+                case 'ldapLoginFilterAttributes':
194
+                    $setMethod = 'setMultiLine';
195
+                    break;
196
+            }
197
+            $this->$setMethod($key, $val);
198
+            if(is_array($applied)) {
199
+                $applied[] = $inputKey;
200
+                // storing key as index avoids duplication, and as value for simplicity
201
+            }
202
+            $this->unsavedChanges[$key] = $key;
203
+        }
204
+        return null;
205
+    }
206 206
 
207
-	public function readConfiguration() {
208
-		if(!$this->configRead && !is_null($this->configPrefix)) {
209
-			$cta = array_flip($this->getConfigTranslationArray());
210
-			foreach($this->config as $key => $val) {
211
-				if(!isset($cta[$key])) {
212
-					//some are determined
213
-					continue;
214
-				}
215
-				$dbKey = $cta[$key];
216
-				switch($key) {
217
-					case 'ldapBase':
218
-					case 'ldapBaseUsers':
219
-					case 'ldapBaseGroups':
220
-					case 'ldapAttributesForUserSearch':
221
-					case 'ldapAttributesForGroupSearch':
222
-					case 'ldapUserFilterObjectclass':
223
-					case 'ldapUserFilterGroups':
224
-					case 'ldapGroupFilterObjectclass':
225
-					case 'ldapGroupFilterGroups':
226
-					case 'ldapLoginFilterAttributes':
227
-						$readMethod = 'getMultiLine';
228
-						break;
229
-					case 'ldapIgnoreNamingRules':
230
-						$readMethod = 'getSystemValue';
231
-						$dbKey = $key;
232
-						break;
233
-					case 'ldapAgentPassword':
234
-						$readMethod = 'getPwd';
235
-						break;
236
-					case 'ldapUserDisplayName2':
237
-					case 'ldapGroupDisplayName':
238
-						$readMethod = 'getLcValue';
239
-						break;
240
-					case 'ldapUserDisplayName':
241
-					default:
242
-						// user display name does not lower case because
243
-						// we rely on an upper case N as indicator whether to
244
-						// auto-detect it or not. FIXME
245
-						$readMethod = 'getValue';
246
-						break;
247
-				}
248
-				$this->config[$key] = $this->$readMethod($dbKey);
249
-			}
250
-			$this->configRead = true;
251
-		}
252
-	}
207
+    public function readConfiguration() {
208
+        if(!$this->configRead && !is_null($this->configPrefix)) {
209
+            $cta = array_flip($this->getConfigTranslationArray());
210
+            foreach($this->config as $key => $val) {
211
+                if(!isset($cta[$key])) {
212
+                    //some are determined
213
+                    continue;
214
+                }
215
+                $dbKey = $cta[$key];
216
+                switch($key) {
217
+                    case 'ldapBase':
218
+                    case 'ldapBaseUsers':
219
+                    case 'ldapBaseGroups':
220
+                    case 'ldapAttributesForUserSearch':
221
+                    case 'ldapAttributesForGroupSearch':
222
+                    case 'ldapUserFilterObjectclass':
223
+                    case 'ldapUserFilterGroups':
224
+                    case 'ldapGroupFilterObjectclass':
225
+                    case 'ldapGroupFilterGroups':
226
+                    case 'ldapLoginFilterAttributes':
227
+                        $readMethod = 'getMultiLine';
228
+                        break;
229
+                    case 'ldapIgnoreNamingRules':
230
+                        $readMethod = 'getSystemValue';
231
+                        $dbKey = $key;
232
+                        break;
233
+                    case 'ldapAgentPassword':
234
+                        $readMethod = 'getPwd';
235
+                        break;
236
+                    case 'ldapUserDisplayName2':
237
+                    case 'ldapGroupDisplayName':
238
+                        $readMethod = 'getLcValue';
239
+                        break;
240
+                    case 'ldapUserDisplayName':
241
+                    default:
242
+                        // user display name does not lower case because
243
+                        // we rely on an upper case N as indicator whether to
244
+                        // auto-detect it or not. FIXME
245
+                        $readMethod = 'getValue';
246
+                        break;
247
+                }
248
+                $this->config[$key] = $this->$readMethod($dbKey);
249
+            }
250
+            $this->configRead = true;
251
+        }
252
+    }
253 253
 
254
-	/**
255
-	 * saves the current config changes in the database
256
-	 */
257
-	public function saveConfiguration() {
258
-		$cta = array_flip($this->getConfigTranslationArray());
259
-		foreach($this->unsavedChanges as $key) {
260
-			$value = $this->config[$key];
261
-			switch ($key) {
262
-				case 'ldapAgentPassword':
263
-					$value = base64_encode($value);
264
-					break;
265
-				case 'ldapBase':
266
-				case 'ldapBaseUsers':
267
-				case 'ldapBaseGroups':
268
-				case 'ldapAttributesForUserSearch':
269
-				case 'ldapAttributesForGroupSearch':
270
-				case 'ldapUserFilterObjectclass':
271
-				case 'ldapUserFilterGroups':
272
-				case 'ldapGroupFilterObjectclass':
273
-				case 'ldapGroupFilterGroups':
274
-				case 'ldapLoginFilterAttributes':
275
-					if(is_array($value)) {
276
-						$value = implode("\n", $value);
277
-					}
278
-					break;
279
-				//following options are not stored but detected, skip them
280
-				case 'ldapIgnoreNamingRules':
281
-				case 'hasPagedResultSupport':
282
-				case 'ldapUuidUserAttribute':
283
-				case 'ldapUuidGroupAttribute':
284
-					continue 2;
285
-			}
286
-			if(is_null($value)) {
287
-				$value = '';
288
-			}
289
-			$this->saveValue($cta[$key], $value);
290
-		}
291
-		$this->saveValue('_lastChange', time());
292
-		$this->unsavedChanges = [];
293
-	}
254
+    /**
255
+     * saves the current config changes in the database
256
+     */
257
+    public function saveConfiguration() {
258
+        $cta = array_flip($this->getConfigTranslationArray());
259
+        foreach($this->unsavedChanges as $key) {
260
+            $value = $this->config[$key];
261
+            switch ($key) {
262
+                case 'ldapAgentPassword':
263
+                    $value = base64_encode($value);
264
+                    break;
265
+                case 'ldapBase':
266
+                case 'ldapBaseUsers':
267
+                case 'ldapBaseGroups':
268
+                case 'ldapAttributesForUserSearch':
269
+                case 'ldapAttributesForGroupSearch':
270
+                case 'ldapUserFilterObjectclass':
271
+                case 'ldapUserFilterGroups':
272
+                case 'ldapGroupFilterObjectclass':
273
+                case 'ldapGroupFilterGroups':
274
+                case 'ldapLoginFilterAttributes':
275
+                    if(is_array($value)) {
276
+                        $value = implode("\n", $value);
277
+                    }
278
+                    break;
279
+                //following options are not stored but detected, skip them
280
+                case 'ldapIgnoreNamingRules':
281
+                case 'hasPagedResultSupport':
282
+                case 'ldapUuidUserAttribute':
283
+                case 'ldapUuidGroupAttribute':
284
+                    continue 2;
285
+            }
286
+            if(is_null($value)) {
287
+                $value = '';
288
+            }
289
+            $this->saveValue($cta[$key], $value);
290
+        }
291
+        $this->saveValue('_lastChange', time());
292
+        $this->unsavedChanges = [];
293
+    }
294 294
 
295
-	/**
296
-	 * @param string $varName
297
-	 * @return array|string
298
-	 */
299
-	protected function getMultiLine($varName) {
300
-		$value = $this->getValue($varName);
301
-		if(empty($value)) {
302
-			$value = '';
303
-		} else {
304
-			$value = preg_split('/\r\n|\r|\n/', $value);
305
-		}
295
+    /**
296
+     * @param string $varName
297
+     * @return array|string
298
+     */
299
+    protected function getMultiLine($varName) {
300
+        $value = $this->getValue($varName);
301
+        if(empty($value)) {
302
+            $value = '';
303
+        } else {
304
+            $value = preg_split('/\r\n|\r|\n/', $value);
305
+        }
306 306
 
307
-		return $value;
308
-	}
307
+        return $value;
308
+    }
309 309
 
310
-	/**
311
-	 * Sets multi-line values as arrays
312
-	 * 
313
-	 * @param string $varName name of config-key
314
-	 * @param array|string $value to set
315
-	 */
316
-	protected function setMultiLine($varName, $value) {
317
-		if(empty($value)) {
318
-			$value = '';
319
-		} else if (!is_array($value)) {
320
-			$value = preg_split('/\r\n|\r|\n|;/', $value);
321
-			if($value === false) {
322
-				$value = '';
323
-			}
324
-		}
310
+    /**
311
+     * Sets multi-line values as arrays
312
+     * 
313
+     * @param string $varName name of config-key
314
+     * @param array|string $value to set
315
+     */
316
+    protected function setMultiLine($varName, $value) {
317
+        if(empty($value)) {
318
+            $value = '';
319
+        } else if (!is_array($value)) {
320
+            $value = preg_split('/\r\n|\r|\n|;/', $value);
321
+            if($value === false) {
322
+                $value = '';
323
+            }
324
+        }
325 325
 
326
-		if(!is_array($value)) {
327
-			$finalValue = trim($value);
328
-		} else {
329
-			$finalValue = [];
330
-			foreach($value as $key => $val) {
331
-				if(is_string($val)) {
332
-					$val = trim($val);
333
-					if ($val !== '') {
334
-						//accidental line breaks are not wanted and can cause
335
-						// odd behaviour. Thus, away with them.
336
-						$finalValue[] = $val;
337
-					}
338
-				} else {
339
-					$finalValue[] = $val;
340
-				}
341
-			}
342
-		}
326
+        if(!is_array($value)) {
327
+            $finalValue = trim($value);
328
+        } else {
329
+            $finalValue = [];
330
+            foreach($value as $key => $val) {
331
+                if(is_string($val)) {
332
+                    $val = trim($val);
333
+                    if ($val !== '') {
334
+                        //accidental line breaks are not wanted and can cause
335
+                        // odd behaviour. Thus, away with them.
336
+                        $finalValue[] = $val;
337
+                    }
338
+                } else {
339
+                    $finalValue[] = $val;
340
+                }
341
+            }
342
+        }
343 343
 
344
-		$this->setRawValue($varName, $finalValue);
345
-	}
344
+        $this->setRawValue($varName, $finalValue);
345
+    }
346 346
 
347
-	/**
348
-	 * @param string $varName
349
-	 * @return string
350
-	 */
351
-	protected function getPwd($varName) {
352
-		return base64_decode($this->getValue($varName));
353
-	}
347
+    /**
348
+     * @param string $varName
349
+     * @return string
350
+     */
351
+    protected function getPwd($varName) {
352
+        return base64_decode($this->getValue($varName));
353
+    }
354 354
 
355
-	/**
356
-	 * @param string $varName
357
-	 * @return string
358
-	 */
359
-	protected function getLcValue($varName) {
360
-		return mb_strtolower($this->getValue($varName), 'UTF-8');
361
-	}
355
+    /**
356
+     * @param string $varName
357
+     * @return string
358
+     */
359
+    protected function getLcValue($varName) {
360
+        return mb_strtolower($this->getValue($varName), 'UTF-8');
361
+    }
362 362
 
363
-	/**
364
-	 * @param string $varName
365
-	 * @return string
366
-	 */
367
-	protected function getSystemValue($varName) {
368
-		//FIXME: if another system value is added, softcode the default value
369
-		return \OC::$server->getConfig()->getSystemValue($varName, false);
370
-	}
363
+    /**
364
+     * @param string $varName
365
+     * @return string
366
+     */
367
+    protected function getSystemValue($varName) {
368
+        //FIXME: if another system value is added, softcode the default value
369
+        return \OC::$server->getConfig()->getSystemValue($varName, false);
370
+    }
371 371
 
372
-	/**
373
-	 * @param string $varName
374
-	 * @return string
375
-	 */
376
-	protected function getValue($varName) {
377
-		static $defaults;
378
-		if(is_null($defaults)) {
379
-			$defaults = $this->getDefaults();
380
-		}
381
-		return \OC::$server->getConfig()->getAppValue('user_ldap',
382
-										$this->configPrefix.$varName,
383
-										$defaults[$varName]);
384
-	}
372
+    /**
373
+     * @param string $varName
374
+     * @return string
375
+     */
376
+    protected function getValue($varName) {
377
+        static $defaults;
378
+        if(is_null($defaults)) {
379
+            $defaults = $this->getDefaults();
380
+        }
381
+        return \OC::$server->getConfig()->getAppValue('user_ldap',
382
+                                        $this->configPrefix.$varName,
383
+                                        $defaults[$varName]);
384
+    }
385 385
 
386
-	/**
387
-	 * Sets a scalar value.
388
-	 * 
389
-	 * @param string $varName name of config key
390
-	 * @param mixed $value to set
391
-	 */
392
-	protected function setValue($varName, $value) {
393
-		if(is_string($value)) {
394
-			$value = trim($value);
395
-		}
396
-		$this->config[$varName] = $value;
397
-	}
386
+    /**
387
+     * Sets a scalar value.
388
+     * 
389
+     * @param string $varName name of config key
390
+     * @param mixed $value to set
391
+     */
392
+    protected function setValue($varName, $value) {
393
+        if(is_string($value)) {
394
+            $value = trim($value);
395
+        }
396
+        $this->config[$varName] = $value;
397
+    }
398 398
 
399
-	/**
400
-	 * Sets a scalar value without trimming.
401
-	 *
402
-	 * @param string $varName name of config key
403
-	 * @param mixed $value to set
404
-	 */
405
-	protected function setRawValue($varName, $value) {
406
-		$this->config[$varName] = $value;
407
-	}
399
+    /**
400
+     * Sets a scalar value without trimming.
401
+     *
402
+     * @param string $varName name of config key
403
+     * @param mixed $value to set
404
+     */
405
+    protected function setRawValue($varName, $value) {
406
+        $this->config[$varName] = $value;
407
+    }
408 408
 
409
-	/**
410
-	 * @param string $varName
411
-	 * @param string $value
412
-	 * @return bool
413
-	 */
414
-	protected function saveValue($varName, $value) {
415
-		\OC::$server->getConfig()->setAppValue(
416
-			'user_ldap',
417
-			$this->configPrefix.$varName,
418
-			$value
419
-		);
420
-		return true;
421
-	}
409
+    /**
410
+     * @param string $varName
411
+     * @param string $value
412
+     * @return bool
413
+     */
414
+    protected function saveValue($varName, $value) {
415
+        \OC::$server->getConfig()->setAppValue(
416
+            'user_ldap',
417
+            $this->configPrefix.$varName,
418
+            $value
419
+        );
420
+        return true;
421
+    }
422 422
 
423
-	/**
424
-	 * @return array an associative array with the default values. Keys are correspond
425
-	 * to config-value entries in the database table
426
-	 */
427
-	public function getDefaults() {
428
-		return array(
429
-			'ldap_host'                         => '',
430
-			'ldap_port'                         => '',
431
-			'ldap_backup_host'                  => '',
432
-			'ldap_backup_port'                  => '',
433
-			'ldap_override_main_server'         => '',
434
-			'ldap_dn'                           => '',
435
-			'ldap_agent_password'               => '',
436
-			'ldap_base'                         => '',
437
-			'ldap_base_users'                   => '',
438
-			'ldap_base_groups'                  => '',
439
-			'ldap_userlist_filter'              => '',
440
-			'ldap_user_filter_mode'             => 0,
441
-			'ldap_userfilter_objectclass'       => '',
442
-			'ldap_userfilter_groups'            => '',
443
-			'ldap_login_filter'                 => '',
444
-			'ldap_login_filter_mode'            => 0,
445
-			'ldap_loginfilter_email'            => 0,
446
-			'ldap_loginfilter_username'         => 1,
447
-			'ldap_loginfilter_attributes'       => '',
448
-			'ldap_group_filter'                 => '',
449
-			'ldap_group_filter_mode'            => 0,
450
-			'ldap_groupfilter_objectclass'      => '',
451
-			'ldap_groupfilter_groups'           => '',
452
-			'ldap_gid_number'                   => 'gidNumber',
453
-			'ldap_display_name'                 => 'displayName',
454
-			'ldap_user_display_name_2'			=> '',
455
-			'ldap_group_display_name'           => 'cn',
456
-			'ldap_tls'                          => 0,
457
-			'ldap_quota_def'                    => '',
458
-			'ldap_quota_attr'                   => '',
459
-			'ldap_email_attr'                   => '',
460
-			'ldap_group_member_assoc_attribute' => 'uniqueMember',
461
-			'ldap_cache_ttl'                    => 600,
462
-			'ldap_uuid_user_attribute'          => 'auto',
463
-			'ldap_uuid_group_attribute'         => 'auto',
464
-			'home_folder_naming_rule'           => '',
465
-			'ldap_turn_off_cert_check'          => 0,
466
-			'ldap_configuration_active'         => 0,
467
-			'ldap_attributes_for_user_search'   => '',
468
-			'ldap_attributes_for_group_search'  => '',
469
-			'ldap_expert_username_attr'         => '',
470
-			'ldap_expert_uuid_user_attr'        => '',
471
-			'ldap_expert_uuid_group_attr'       => '',
472
-			'has_memberof_filter_support'       => 0,
473
-			'use_memberof_to_detect_membership' => 1,
474
-			'last_jpegPhoto_lookup'             => 0,
475
-			'ldap_nested_groups'                => 0,
476
-			'ldap_paging_size'                  => 500,
477
-			'ldap_turn_on_pwd_change'           => 0,
478
-			'ldap_experienced_admin'            => 0,
479
-			'ldap_dynamic_group_member_url'     => '',
480
-			'ldap_default_ppolicy_dn'           => '',
481
-			'ldap_user_avatar_rule'             => 'default',
482
-		);
483
-	}
423
+    /**
424
+     * @return array an associative array with the default values. Keys are correspond
425
+     * to config-value entries in the database table
426
+     */
427
+    public function getDefaults() {
428
+        return array(
429
+            'ldap_host'                         => '',
430
+            'ldap_port'                         => '',
431
+            'ldap_backup_host'                  => '',
432
+            'ldap_backup_port'                  => '',
433
+            'ldap_override_main_server'         => '',
434
+            'ldap_dn'                           => '',
435
+            'ldap_agent_password'               => '',
436
+            'ldap_base'                         => '',
437
+            'ldap_base_users'                   => '',
438
+            'ldap_base_groups'                  => '',
439
+            'ldap_userlist_filter'              => '',
440
+            'ldap_user_filter_mode'             => 0,
441
+            'ldap_userfilter_objectclass'       => '',
442
+            'ldap_userfilter_groups'            => '',
443
+            'ldap_login_filter'                 => '',
444
+            'ldap_login_filter_mode'            => 0,
445
+            'ldap_loginfilter_email'            => 0,
446
+            'ldap_loginfilter_username'         => 1,
447
+            'ldap_loginfilter_attributes'       => '',
448
+            'ldap_group_filter'                 => '',
449
+            'ldap_group_filter_mode'            => 0,
450
+            'ldap_groupfilter_objectclass'      => '',
451
+            'ldap_groupfilter_groups'           => '',
452
+            'ldap_gid_number'                   => 'gidNumber',
453
+            'ldap_display_name'                 => 'displayName',
454
+            'ldap_user_display_name_2'			=> '',
455
+            'ldap_group_display_name'           => 'cn',
456
+            'ldap_tls'                          => 0,
457
+            'ldap_quota_def'                    => '',
458
+            'ldap_quota_attr'                   => '',
459
+            'ldap_email_attr'                   => '',
460
+            'ldap_group_member_assoc_attribute' => 'uniqueMember',
461
+            'ldap_cache_ttl'                    => 600,
462
+            'ldap_uuid_user_attribute'          => 'auto',
463
+            'ldap_uuid_group_attribute'         => 'auto',
464
+            'home_folder_naming_rule'           => '',
465
+            'ldap_turn_off_cert_check'          => 0,
466
+            'ldap_configuration_active'         => 0,
467
+            'ldap_attributes_for_user_search'   => '',
468
+            'ldap_attributes_for_group_search'  => '',
469
+            'ldap_expert_username_attr'         => '',
470
+            'ldap_expert_uuid_user_attr'        => '',
471
+            'ldap_expert_uuid_group_attr'       => '',
472
+            'has_memberof_filter_support'       => 0,
473
+            'use_memberof_to_detect_membership' => 1,
474
+            'last_jpegPhoto_lookup'             => 0,
475
+            'ldap_nested_groups'                => 0,
476
+            'ldap_paging_size'                  => 500,
477
+            'ldap_turn_on_pwd_change'           => 0,
478
+            'ldap_experienced_admin'            => 0,
479
+            'ldap_dynamic_group_member_url'     => '',
480
+            'ldap_default_ppolicy_dn'           => '',
481
+            'ldap_user_avatar_rule'             => 'default',
482
+        );
483
+    }
484 484
 
485
-	/**
486
-	 * @return array that maps internal variable names to database fields
487
-	 */
488
-	public function getConfigTranslationArray() {
489
-		//TODO: merge them into one representation
490
-		static $array = array(
491
-			'ldap_host'                         => 'ldapHost',
492
-			'ldap_port'                         => 'ldapPort',
493
-			'ldap_backup_host'                  => 'ldapBackupHost',
494
-			'ldap_backup_port'                  => 'ldapBackupPort',
495
-			'ldap_override_main_server'         => 'ldapOverrideMainServer',
496
-			'ldap_dn'                           => 'ldapAgentName',
497
-			'ldap_agent_password'               => 'ldapAgentPassword',
498
-			'ldap_base'                         => 'ldapBase',
499
-			'ldap_base_users'                   => 'ldapBaseUsers',
500
-			'ldap_base_groups'                  => 'ldapBaseGroups',
501
-			'ldap_userfilter_objectclass'       => 'ldapUserFilterObjectclass',
502
-			'ldap_userfilter_groups'            => 'ldapUserFilterGroups',
503
-			'ldap_userlist_filter'              => 'ldapUserFilter',
504
-			'ldap_user_filter_mode'             => 'ldapUserFilterMode',
505
-			'ldap_user_avatar_rule'             => 'ldapUserAvatarRule',
506
-			'ldap_login_filter'                 => 'ldapLoginFilter',
507
-			'ldap_login_filter_mode'            => 'ldapLoginFilterMode',
508
-			'ldap_loginfilter_email'            => 'ldapLoginFilterEmail',
509
-			'ldap_loginfilter_username'         => 'ldapLoginFilterUsername',
510
-			'ldap_loginfilter_attributes'       => 'ldapLoginFilterAttributes',
511
-			'ldap_group_filter'                 => 'ldapGroupFilter',
512
-			'ldap_group_filter_mode'            => 'ldapGroupFilterMode',
513
-			'ldap_groupfilter_objectclass'      => 'ldapGroupFilterObjectclass',
514
-			'ldap_groupfilter_groups'           => 'ldapGroupFilterGroups',
515
-			'ldap_gid_number'                   => 'ldapGidNumber',
516
-			'ldap_display_name'                 => 'ldapUserDisplayName',
517
-			'ldap_user_display_name_2'			=> 'ldapUserDisplayName2',
518
-			'ldap_group_display_name'           => 'ldapGroupDisplayName',
519
-			'ldap_tls'                          => 'ldapTLS',
520
-			'ldap_quota_def'                    => 'ldapQuotaDefault',
521
-			'ldap_quota_attr'                   => 'ldapQuotaAttribute',
522
-			'ldap_email_attr'                   => 'ldapEmailAttribute',
523
-			'ldap_group_member_assoc_attribute' => 'ldapGroupMemberAssocAttr',
524
-			'ldap_cache_ttl'                    => 'ldapCacheTTL',
525
-			'home_folder_naming_rule'           => 'homeFolderNamingRule',
526
-			'ldap_turn_off_cert_check'          => 'turnOffCertCheck',
527
-			'ldap_configuration_active'         => 'ldapConfigurationActive',
528
-			'ldap_attributes_for_user_search'   => 'ldapAttributesForUserSearch',
529
-			'ldap_attributes_for_group_search'  => 'ldapAttributesForGroupSearch',
530
-			'ldap_expert_username_attr'         => 'ldapExpertUsernameAttr',
531
-			'ldap_expert_uuid_user_attr'        => 'ldapExpertUUIDUserAttr',
532
-			'ldap_expert_uuid_group_attr'       => 'ldapExpertUUIDGroupAttr',
533
-			'has_memberof_filter_support'       => 'hasMemberOfFilterSupport',
534
-			'use_memberof_to_detect_membership' => 'useMemberOfToDetectMembership',
535
-			'last_jpegPhoto_lookup'             => 'lastJpegPhotoLookup',
536
-			'ldap_nested_groups'                => 'ldapNestedGroups',
537
-			'ldap_paging_size'                  => 'ldapPagingSize',
538
-			'ldap_turn_on_pwd_change'           => 'turnOnPasswordChange',
539
-			'ldap_experienced_admin'            => 'ldapExperiencedAdmin',
540
-			'ldap_dynamic_group_member_url'     => 'ldapDynamicGroupMemberURL',
541
-			'ldap_default_ppolicy_dn'           => 'ldapDefaultPPolicyDN',
542
-			'ldapIgnoreNamingRules'             => 'ldapIgnoreNamingRules',	// sysconfig
543
-		);
544
-		return $array;
545
-	}
485
+    /**
486
+     * @return array that maps internal variable names to database fields
487
+     */
488
+    public function getConfigTranslationArray() {
489
+        //TODO: merge them into one representation
490
+        static $array = array(
491
+            'ldap_host'                         => 'ldapHost',
492
+            'ldap_port'                         => 'ldapPort',
493
+            'ldap_backup_host'                  => 'ldapBackupHost',
494
+            'ldap_backup_port'                  => 'ldapBackupPort',
495
+            'ldap_override_main_server'         => 'ldapOverrideMainServer',
496
+            'ldap_dn'                           => 'ldapAgentName',
497
+            'ldap_agent_password'               => 'ldapAgentPassword',
498
+            'ldap_base'                         => 'ldapBase',
499
+            'ldap_base_users'                   => 'ldapBaseUsers',
500
+            'ldap_base_groups'                  => 'ldapBaseGroups',
501
+            'ldap_userfilter_objectclass'       => 'ldapUserFilterObjectclass',
502
+            'ldap_userfilter_groups'            => 'ldapUserFilterGroups',
503
+            'ldap_userlist_filter'              => 'ldapUserFilter',
504
+            'ldap_user_filter_mode'             => 'ldapUserFilterMode',
505
+            'ldap_user_avatar_rule'             => 'ldapUserAvatarRule',
506
+            'ldap_login_filter'                 => 'ldapLoginFilter',
507
+            'ldap_login_filter_mode'            => 'ldapLoginFilterMode',
508
+            'ldap_loginfilter_email'            => 'ldapLoginFilterEmail',
509
+            'ldap_loginfilter_username'         => 'ldapLoginFilterUsername',
510
+            'ldap_loginfilter_attributes'       => 'ldapLoginFilterAttributes',
511
+            'ldap_group_filter'                 => 'ldapGroupFilter',
512
+            'ldap_group_filter_mode'            => 'ldapGroupFilterMode',
513
+            'ldap_groupfilter_objectclass'      => 'ldapGroupFilterObjectclass',
514
+            'ldap_groupfilter_groups'           => 'ldapGroupFilterGroups',
515
+            'ldap_gid_number'                   => 'ldapGidNumber',
516
+            'ldap_display_name'                 => 'ldapUserDisplayName',
517
+            'ldap_user_display_name_2'			=> 'ldapUserDisplayName2',
518
+            'ldap_group_display_name'           => 'ldapGroupDisplayName',
519
+            'ldap_tls'                          => 'ldapTLS',
520
+            'ldap_quota_def'                    => 'ldapQuotaDefault',
521
+            'ldap_quota_attr'                   => 'ldapQuotaAttribute',
522
+            'ldap_email_attr'                   => 'ldapEmailAttribute',
523
+            'ldap_group_member_assoc_attribute' => 'ldapGroupMemberAssocAttr',
524
+            'ldap_cache_ttl'                    => 'ldapCacheTTL',
525
+            'home_folder_naming_rule'           => 'homeFolderNamingRule',
526
+            'ldap_turn_off_cert_check'          => 'turnOffCertCheck',
527
+            'ldap_configuration_active'         => 'ldapConfigurationActive',
528
+            'ldap_attributes_for_user_search'   => 'ldapAttributesForUserSearch',
529
+            'ldap_attributes_for_group_search'  => 'ldapAttributesForGroupSearch',
530
+            'ldap_expert_username_attr'         => 'ldapExpertUsernameAttr',
531
+            'ldap_expert_uuid_user_attr'        => 'ldapExpertUUIDUserAttr',
532
+            'ldap_expert_uuid_group_attr'       => 'ldapExpertUUIDGroupAttr',
533
+            'has_memberof_filter_support'       => 'hasMemberOfFilterSupport',
534
+            'use_memberof_to_detect_membership' => 'useMemberOfToDetectMembership',
535
+            'last_jpegPhoto_lookup'             => 'lastJpegPhotoLookup',
536
+            'ldap_nested_groups'                => 'ldapNestedGroups',
537
+            'ldap_paging_size'                  => 'ldapPagingSize',
538
+            'ldap_turn_on_pwd_change'           => 'turnOnPasswordChange',
539
+            'ldap_experienced_admin'            => 'ldapExperiencedAdmin',
540
+            'ldap_dynamic_group_member_url'     => 'ldapDynamicGroupMemberURL',
541
+            'ldap_default_ppolicy_dn'           => 'ldapDefaultPPolicyDN',
542
+            'ldapIgnoreNamingRules'             => 'ldapIgnoreNamingRules',	// sysconfig
543
+        );
544
+        return $array;
545
+    }
546 546
 
547
-	/**
548
-	 * @param string $rule
549
-	 * @return array
550
-	 * @throws \RuntimeException
551
-	 */
552
-	public function resolveRule($rule) {
553
-		if($rule === 'avatar') {
554
-			return $this->getAvatarAttributes();
555
-		}
556
-		throw new \RuntimeException('Invalid rule');
557
-	}
547
+    /**
548
+     * @param string $rule
549
+     * @return array
550
+     * @throws \RuntimeException
551
+     */
552
+    public function resolveRule($rule) {
553
+        if($rule === 'avatar') {
554
+            return $this->getAvatarAttributes();
555
+        }
556
+        throw new \RuntimeException('Invalid rule');
557
+    }
558 558
 
559
-	public function getAvatarAttributes() {
560
-		$value = $this->ldapUserAvatarRule ?: self::AVATAR_PREFIX_DEFAULT;
561
-		$defaultAttributes = ['jpegphoto', 'thumbnailphoto'];
559
+    public function getAvatarAttributes() {
560
+        $value = $this->ldapUserAvatarRule ?: self::AVATAR_PREFIX_DEFAULT;
561
+        $defaultAttributes = ['jpegphoto', 'thumbnailphoto'];
562 562
 
563
-		if($value === self::AVATAR_PREFIX_NONE) {
564
-			return [];
565
-		}
566
-		if(strpos($value, self::AVATAR_PREFIX_DATA_ATTRIBUTE) === 0) {
567
-			$attribute = trim(substr($value, strlen(self::AVATAR_PREFIX_DATA_ATTRIBUTE)));
568
-			if($attribute === '') {
569
-				return $defaultAttributes;
570
-			}
571
-			return [strtolower($attribute)];
572
-		}
573
-		if($value !== self::AVATAR_PREFIX_DEFAULT) {
574
-			\OC::$server->getLogger()->warning('Invalid config value to ldapUserAvatarRule; falling back to default.');
575
-		}
576
-		return $defaultAttributes;
577
-	}
563
+        if($value === self::AVATAR_PREFIX_NONE) {
564
+            return [];
565
+        }
566
+        if(strpos($value, self::AVATAR_PREFIX_DATA_ATTRIBUTE) === 0) {
567
+            $attribute = trim(substr($value, strlen(self::AVATAR_PREFIX_DATA_ATTRIBUTE)));
568
+            if($attribute === '') {
569
+                return $defaultAttributes;
570
+            }
571
+            return [strtolower($attribute)];
572
+        }
573
+        if($value !== self::AVATAR_PREFIX_DEFAULT) {
574
+            \OC::$server->getLogger()->warning('Invalid config value to ldapUserAvatarRule; falling back to default.');
575
+        }
576
+        return $defaultAttributes;
577
+    }
578 578
 
579 579
 }
Please login to merge, or discard this patch.
Spacing   +29 added lines, -29 removed lines patch added patch discarded remove patch
@@ -115,7 +115,7 @@  discard block
 block discarded – undo
115 115
 	 */
116 116
 	public function __construct($configPrefix, $autoRead = true) {
117 117
 		$this->configPrefix = $configPrefix;
118
-		if($autoRead) {
118
+		if ($autoRead) {
119 119
 			$this->readConfiguration();
120 120
 		}
121 121
 	}
@@ -125,7 +125,7 @@  discard block
 block discarded – undo
125 125
 	 * @return mixed|null
126 126
 	 */
127 127
 	public function __get($name) {
128
-		if(isset($this->config[$name])) {
128
+		if (isset($this->config[$name])) {
129 129
 			return $this->config[$name];
130 130
 		}
131 131
 		return null;
@@ -156,22 +156,22 @@  discard block
 block discarded – undo
156 156
 	 * @return false|null
157 157
 	 */
158 158
 	public function setConfiguration($config, &$applied = null) {
159
-		if(!is_array($config)) {
159
+		if (!is_array($config)) {
160 160
 			return false;
161 161
 		}
162 162
 
163 163
 		$cta = $this->getConfigTranslationArray();
164
-		foreach($config as $inputKey => $val) {
165
-			if(strpos($inputKey, '_') !== false && array_key_exists($inputKey, $cta)) {
164
+		foreach ($config as $inputKey => $val) {
165
+			if (strpos($inputKey, '_') !== false && array_key_exists($inputKey, $cta)) {
166 166
 				$key = $cta[$inputKey];
167
-			} elseif(array_key_exists($inputKey, $this->config)) {
167
+			} elseif (array_key_exists($inputKey, $this->config)) {
168 168
 				$key = $inputKey;
169 169
 			} else {
170 170
 				continue;
171 171
 			}
172 172
 
173 173
 			$setMethod = 'setValue';
174
-			switch($key) {
174
+			switch ($key) {
175 175
 				case 'ldapAgentPassword':
176 176
 					$setMethod = 'setRawValue';
177 177
 					break;
@@ -195,7 +195,7 @@  discard block
 block discarded – undo
195 195
 					break;
196 196
 			}
197 197
 			$this->$setMethod($key, $val);
198
-			if(is_array($applied)) {
198
+			if (is_array($applied)) {
199 199
 				$applied[] = $inputKey;
200 200
 				// storing key as index avoids duplication, and as value for simplicity
201 201
 			}
@@ -205,15 +205,15 @@  discard block
 block discarded – undo
205 205
 	}
206 206
 
207 207
 	public function readConfiguration() {
208
-		if(!$this->configRead && !is_null($this->configPrefix)) {
208
+		if (!$this->configRead && !is_null($this->configPrefix)) {
209 209
 			$cta = array_flip($this->getConfigTranslationArray());
210
-			foreach($this->config as $key => $val) {
211
-				if(!isset($cta[$key])) {
210
+			foreach ($this->config as $key => $val) {
211
+				if (!isset($cta[$key])) {
212 212
 					//some are determined
213 213
 					continue;
214 214
 				}
215 215
 				$dbKey = $cta[$key];
216
-				switch($key) {
216
+				switch ($key) {
217 217
 					case 'ldapBase':
218 218
 					case 'ldapBaseUsers':
219 219
 					case 'ldapBaseGroups':
@@ -256,7 +256,7 @@  discard block
 block discarded – undo
256 256
 	 */
257 257
 	public function saveConfiguration() {
258 258
 		$cta = array_flip($this->getConfigTranslationArray());
259
-		foreach($this->unsavedChanges as $key) {
259
+		foreach ($this->unsavedChanges as $key) {
260 260
 			$value = $this->config[$key];
261 261
 			switch ($key) {
262 262
 				case 'ldapAgentPassword':
@@ -272,7 +272,7 @@  discard block
 block discarded – undo
272 272
 				case 'ldapGroupFilterObjectclass':
273 273
 				case 'ldapGroupFilterGroups':
274 274
 				case 'ldapLoginFilterAttributes':
275
-					if(is_array($value)) {
275
+					if (is_array($value)) {
276 276
 						$value = implode("\n", $value);
277 277
 					}
278 278
 					break;
@@ -283,7 +283,7 @@  discard block
 block discarded – undo
283 283
 				case 'ldapUuidGroupAttribute':
284 284
 					continue 2;
285 285
 			}
286
-			if(is_null($value)) {
286
+			if (is_null($value)) {
287 287
 				$value = '';
288 288
 			}
289 289
 			$this->saveValue($cta[$key], $value);
@@ -298,7 +298,7 @@  discard block
 block discarded – undo
298 298
 	 */
299 299
 	protected function getMultiLine($varName) {
300 300
 		$value = $this->getValue($varName);
301
-		if(empty($value)) {
301
+		if (empty($value)) {
302 302
 			$value = '';
303 303
 		} else {
304 304
 			$value = preg_split('/\r\n|\r|\n/', $value);
@@ -314,21 +314,21 @@  discard block
 block discarded – undo
314 314
 	 * @param array|string $value to set
315 315
 	 */
316 316
 	protected function setMultiLine($varName, $value) {
317
-		if(empty($value)) {
317
+		if (empty($value)) {
318 318
 			$value = '';
319 319
 		} else if (!is_array($value)) {
320 320
 			$value = preg_split('/\r\n|\r|\n|;/', $value);
321
-			if($value === false) {
321
+			if ($value === false) {
322 322
 				$value = '';
323 323
 			}
324 324
 		}
325 325
 
326
-		if(!is_array($value)) {
326
+		if (!is_array($value)) {
327 327
 			$finalValue = trim($value);
328 328
 		} else {
329 329
 			$finalValue = [];
330
-			foreach($value as $key => $val) {
331
-				if(is_string($val)) {
330
+			foreach ($value as $key => $val) {
331
+				if (is_string($val)) {
332 332
 					$val = trim($val);
333 333
 					if ($val !== '') {
334 334
 						//accidental line breaks are not wanted and can cause
@@ -375,7 +375,7 @@  discard block
 block discarded – undo
375 375
 	 */
376 376
 	protected function getValue($varName) {
377 377
 		static $defaults;
378
-		if(is_null($defaults)) {
378
+		if (is_null($defaults)) {
379 379
 			$defaults = $this->getDefaults();
380 380
 		}
381 381
 		return \OC::$server->getConfig()->getAppValue('user_ldap',
@@ -390,7 +390,7 @@  discard block
 block discarded – undo
390 390
 	 * @param mixed $value to set
391 391
 	 */
392 392
 	protected function setValue($varName, $value) {
393
-		if(is_string($value)) {
393
+		if (is_string($value)) {
394 394
 			$value = trim($value);
395 395
 		}
396 396
 		$this->config[$varName] = $value;
@@ -539,7 +539,7 @@  discard block
 block discarded – undo
539 539
 			'ldap_experienced_admin'            => 'ldapExperiencedAdmin',
540 540
 			'ldap_dynamic_group_member_url'     => 'ldapDynamicGroupMemberURL',
541 541
 			'ldap_default_ppolicy_dn'           => 'ldapDefaultPPolicyDN',
542
-			'ldapIgnoreNamingRules'             => 'ldapIgnoreNamingRules',	// sysconfig
542
+			'ldapIgnoreNamingRules'             => 'ldapIgnoreNamingRules', // sysconfig
543 543
 		);
544 544
 		return $array;
545 545
 	}
@@ -550,7 +550,7 @@  discard block
 block discarded – undo
550 550
 	 * @throws \RuntimeException
551 551
 	 */
552 552
 	public function resolveRule($rule) {
553
-		if($rule === 'avatar') {
553
+		if ($rule === 'avatar') {
554 554
 			return $this->getAvatarAttributes();
555 555
 		}
556 556
 		throw new \RuntimeException('Invalid rule');
@@ -560,17 +560,17 @@  discard block
 block discarded – undo
560 560
 		$value = $this->ldapUserAvatarRule ?: self::AVATAR_PREFIX_DEFAULT;
561 561
 		$defaultAttributes = ['jpegphoto', 'thumbnailphoto'];
562 562
 
563
-		if($value === self::AVATAR_PREFIX_NONE) {
563
+		if ($value === self::AVATAR_PREFIX_NONE) {
564 564
 			return [];
565 565
 		}
566
-		if(strpos($value, self::AVATAR_PREFIX_DATA_ATTRIBUTE) === 0) {
566
+		if (strpos($value, self::AVATAR_PREFIX_DATA_ATTRIBUTE) === 0) {
567 567
 			$attribute = trim(substr($value, strlen(self::AVATAR_PREFIX_DATA_ATTRIBUTE)));
568
-			if($attribute === '') {
568
+			if ($attribute === '') {
569 569
 				return $defaultAttributes;
570 570
 			}
571 571
 			return [strtolower($attribute)];
572 572
 		}
573
-		if($value !== self::AVATAR_PREFIX_DEFAULT) {
573
+		if ($value !== self::AVATAR_PREFIX_DEFAULT) {
574 574
 			\OC::$server->getLogger()->warning('Invalid config value to ldapUserAvatarRule; falling back to default.');
575 575
 		}
576 576
 		return $defaultAttributes;
Please login to merge, or discard this patch.
apps/user_ldap/lib/User_LDAP.php 2 patches
Indentation   +574 added lines, -574 removed lines patch added patch discarded remove patch
@@ -52,582 +52,582 @@
 block discarded – undo
52 52
 use OCP\Util;
53 53
 
54 54
 class User_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserInterface, IUserLDAP {
55
-	/** @var \OCP\IConfig */
56
-	protected $ocConfig;
57
-
58
-	/** @var INotificationManager */
59
-	protected $notificationManager;
60
-
61
-	/** @var string */
62
-	protected $currentUserInDeletionProcess;
63
-
64
-	/** @var UserPluginManager */
65
-	protected $userPluginManager;
66
-
67
-	/**
68
-	 * @param Access $access
69
-	 * @param \OCP\IConfig $ocConfig
70
-	 * @param \OCP\Notification\IManager $notificationManager
71
-	 * @param IUserSession $userSession
72
-	 */
73
-	public function __construct(Access $access, IConfig $ocConfig, INotificationManager $notificationManager, IUserSession $userSession, UserPluginManager $userPluginManager) {
74
-		parent::__construct($access);
75
-		$this->ocConfig = $ocConfig;
76
-		$this->notificationManager = $notificationManager;
77
-		$this->userPluginManager = $userPluginManager;
78
-		$this->registerHooks($userSession);
79
-	}
80
-
81
-	protected function registerHooks(IUserSession $userSession) {
82
-		$userSession->listen('\OC\User', 'preDelete', [$this, 'preDeleteUser']);
83
-		$userSession->listen('\OC\User', 'postDelete', [$this, 'postDeleteUser']);
84
-	}
85
-
86
-	public function preDeleteUser(IUser $user) {
87
-		$this->currentUserInDeletionProcess = $user->getUID();
88
-	}
89
-
90
-	public function postDeleteUser() {
91
-		$this->currentUserInDeletionProcess = null;
92
-	}
93
-
94
-	/**
95
-	 * checks whether the user is allowed to change his avatar in Nextcloud
96
-	 *
97
-	 * @param string $uid the Nextcloud user name
98
-	 * @return boolean either the user can or cannot
99
-	 * @throws \Exception
100
-	 */
101
-	public function canChangeAvatar($uid) {
102
-		if ($this->userPluginManager->implementsActions(Backend::PROVIDE_AVATAR)) {
103
-			return $this->userPluginManager->canChangeAvatar($uid);
104
-		}
105
-
106
-		if(!$this->implementsActions(Backend::PROVIDE_AVATAR)) {
107
-			return true;
108
-		}
109
-
110
-		$user = $this->access->userManager->get($uid);
111
-		if(!$user instanceof User) {
112
-			return false;
113
-		}
114
-		$imageData = $user->getAvatarImage();
115
-		if($imageData === false) {
116
-			return true;
117
-		}
118
-		return !$user->updateAvatar(true);
119
-	}
120
-
121
-	/**
122
-	 * returns the username for the given login name, if available
123
-	 *
124
-	 * @param string $loginName
125
-	 * @return string|false
126
-	 */
127
-	public function loginName2UserName($loginName) {
128
-		$cacheKey = 'loginName2UserName-'.$loginName;
129
-		$username = $this->access->connection->getFromCache($cacheKey);
130
-		if(!is_null($username)) {
131
-			return $username;
132
-		}
133
-
134
-		try {
135
-			$ldapRecord = $this->getLDAPUserByLoginName($loginName);
136
-			$user = $this->access->userManager->get($ldapRecord['dn'][0]);
137
-			if($user instanceof OfflineUser) {
138
-				// this path is not really possible, however get() is documented
139
-				// to return User or OfflineUser so we are very defensive here.
140
-				$this->access->connection->writeToCache($cacheKey, false);
141
-				return false;
142
-			}
143
-			$username = $user->getUsername();
144
-			$this->access->connection->writeToCache($cacheKey, $username);
145
-			return $username;
146
-		} catch (NotOnLDAP $e) {
147
-			$this->access->connection->writeToCache($cacheKey, false);
148
-			return false;
149
-		}
150
-	}
55
+    /** @var \OCP\IConfig */
56
+    protected $ocConfig;
57
+
58
+    /** @var INotificationManager */
59
+    protected $notificationManager;
60
+
61
+    /** @var string */
62
+    protected $currentUserInDeletionProcess;
63
+
64
+    /** @var UserPluginManager */
65
+    protected $userPluginManager;
66
+
67
+    /**
68
+     * @param Access $access
69
+     * @param \OCP\IConfig $ocConfig
70
+     * @param \OCP\Notification\IManager $notificationManager
71
+     * @param IUserSession $userSession
72
+     */
73
+    public function __construct(Access $access, IConfig $ocConfig, INotificationManager $notificationManager, IUserSession $userSession, UserPluginManager $userPluginManager) {
74
+        parent::__construct($access);
75
+        $this->ocConfig = $ocConfig;
76
+        $this->notificationManager = $notificationManager;
77
+        $this->userPluginManager = $userPluginManager;
78
+        $this->registerHooks($userSession);
79
+    }
80
+
81
+    protected function registerHooks(IUserSession $userSession) {
82
+        $userSession->listen('\OC\User', 'preDelete', [$this, 'preDeleteUser']);
83
+        $userSession->listen('\OC\User', 'postDelete', [$this, 'postDeleteUser']);
84
+    }
85
+
86
+    public function preDeleteUser(IUser $user) {
87
+        $this->currentUserInDeletionProcess = $user->getUID();
88
+    }
89
+
90
+    public function postDeleteUser() {
91
+        $this->currentUserInDeletionProcess = null;
92
+    }
93
+
94
+    /**
95
+     * checks whether the user is allowed to change his avatar in Nextcloud
96
+     *
97
+     * @param string $uid the Nextcloud user name
98
+     * @return boolean either the user can or cannot
99
+     * @throws \Exception
100
+     */
101
+    public function canChangeAvatar($uid) {
102
+        if ($this->userPluginManager->implementsActions(Backend::PROVIDE_AVATAR)) {
103
+            return $this->userPluginManager->canChangeAvatar($uid);
104
+        }
105
+
106
+        if(!$this->implementsActions(Backend::PROVIDE_AVATAR)) {
107
+            return true;
108
+        }
109
+
110
+        $user = $this->access->userManager->get($uid);
111
+        if(!$user instanceof User) {
112
+            return false;
113
+        }
114
+        $imageData = $user->getAvatarImage();
115
+        if($imageData === false) {
116
+            return true;
117
+        }
118
+        return !$user->updateAvatar(true);
119
+    }
120
+
121
+    /**
122
+     * returns the username for the given login name, if available
123
+     *
124
+     * @param string $loginName
125
+     * @return string|false
126
+     */
127
+    public function loginName2UserName($loginName) {
128
+        $cacheKey = 'loginName2UserName-'.$loginName;
129
+        $username = $this->access->connection->getFromCache($cacheKey);
130
+        if(!is_null($username)) {
131
+            return $username;
132
+        }
133
+
134
+        try {
135
+            $ldapRecord = $this->getLDAPUserByLoginName($loginName);
136
+            $user = $this->access->userManager->get($ldapRecord['dn'][0]);
137
+            if($user instanceof OfflineUser) {
138
+                // this path is not really possible, however get() is documented
139
+                // to return User or OfflineUser so we are very defensive here.
140
+                $this->access->connection->writeToCache($cacheKey, false);
141
+                return false;
142
+            }
143
+            $username = $user->getUsername();
144
+            $this->access->connection->writeToCache($cacheKey, $username);
145
+            return $username;
146
+        } catch (NotOnLDAP $e) {
147
+            $this->access->connection->writeToCache($cacheKey, false);
148
+            return false;
149
+        }
150
+    }
151 151
 	
152
-	/**
153
-	 * returns the username for the given LDAP DN, if available
154
-	 *
155
-	 * @param string $dn
156
-	 * @return string|false with the username
157
-	 */
158
-	public function dn2UserName($dn) {
159
-		return $this->access->dn2username($dn);
160
-	}
161
-
162
-	/**
163
-	 * returns an LDAP record based on a given login name
164
-	 *
165
-	 * @param string $loginName
166
-	 * @return array
167
-	 * @throws NotOnLDAP
168
-	 */
169
-	public function getLDAPUserByLoginName($loginName) {
170
-		//find out dn of the user name
171
-		$attrs = $this->access->userManager->getAttributes();
172
-		$users = $this->access->fetchUsersByLoginName($loginName, $attrs);
173
-		if(count($users) < 1) {
174
-			throw new NotOnLDAP('No user available for the given login name on ' .
175
-				$this->access->connection->ldapHost . ':' . $this->access->connection->ldapPort);
176
-		}
177
-		return $users[0];
178
-	}
179
-
180
-	/**
181
-	 * Check if the password is correct without logging in the user
182
-	 *
183
-	 * @param string $uid The username
184
-	 * @param string $password The password
185
-	 * @return false|string
186
-	 */
187
-	public function checkPassword($uid, $password) {
188
-		try {
189
-			$ldapRecord = $this->getLDAPUserByLoginName($uid);
190
-		} catch(NotOnLDAP $e) {
191
-			if($this->ocConfig->getSystemValue('loglevel', ILogger::WARN) === ILogger::DEBUG) {
192
-				\OC::$server->getLogger()->logException($e, ['app' => 'user_ldap']);
193
-			}
194
-			return false;
195
-		}
196
-		$dn = $ldapRecord['dn'][0];
197
-		$user = $this->access->userManager->get($dn);
198
-
199
-		if(!$user instanceof User) {
200
-			Util::writeLog('user_ldap',
201
-				'LDAP Login: Could not get user object for DN ' . $dn .
202
-				'. Maybe the LDAP entry has no set display name attribute?',
203
-				ILogger::WARN);
204
-			return false;
205
-		}
206
-		if($user->getUsername() !== false) {
207
-			//are the credentials OK?
208
-			if(!$this->access->areCredentialsValid($dn, $password)) {
209
-				return false;
210
-			}
211
-
212
-			$this->access->cacheUserExists($user->getUsername());
213
-			$user->processAttributes($ldapRecord);
214
-			$user->markLogin();
215
-
216
-			return $user->getUsername();
217
-		}
218
-
219
-		return false;
220
-	}
221
-
222
-	/**
223
-	 * Set password
224
-	 * @param string $uid The username
225
-	 * @param string $password The new password
226
-	 * @return bool
227
-	 */
228
-	public function setPassword($uid, $password) {
229
-		if ($this->userPluginManager->implementsActions(Backend::SET_PASSWORD)) {
230
-			return $this->userPluginManager->setPassword($uid, $password);
231
-		}
232
-
233
-		$user = $this->access->userManager->get($uid);
234
-
235
-		if(!$user instanceof User) {
236
-			throw new \Exception('LDAP setPassword: Could not get user object for uid ' . $uid .
237
-				'. Maybe the LDAP entry has no set display name attribute?');
238
-		}
239
-		if($user->getUsername() !== false && $this->access->setPassword($user->getDN(), $password)) {
240
-			$ldapDefaultPPolicyDN = $this->access->connection->ldapDefaultPPolicyDN;
241
-			$turnOnPasswordChange = $this->access->connection->turnOnPasswordChange;
242
-			if (!empty($ldapDefaultPPolicyDN) && ((int)$turnOnPasswordChange === 1)) {
243
-				//remove last password expiry warning if any
244
-				$notification = $this->notificationManager->createNotification();
245
-				$notification->setApp('user_ldap')
246
-					->setUser($uid)
247
-					->setObject('pwd_exp_warn', $uid)
248
-				;
249
-				$this->notificationManager->markProcessed($notification);
250
-			}
251
-			return true;
252
-		}
253
-
254
-		return false;
255
-	}
256
-
257
-	/**
258
-	 * Get a list of all users
259
-	 *
260
-	 * @param string $search
261
-	 * @param integer $limit
262
-	 * @param integer $offset
263
-	 * @return string[] an array of all uids
264
-	 */
265
-	public function getUsers($search = '', $limit = 10, $offset = 0) {
266
-		$search = $this->access->escapeFilterPart($search, true);
267
-		$cachekey = 'getUsers-'.$search.'-'.$limit.'-'.$offset;
268
-
269
-		//check if users are cached, if so return
270
-		$ldap_users = $this->access->connection->getFromCache($cachekey);
271
-		if(!is_null($ldap_users)) {
272
-			return $ldap_users;
273
-		}
274
-
275
-		// if we'd pass -1 to LDAP search, we'd end up in a Protocol
276
-		// error. With a limit of 0, we get 0 results. So we pass null.
277
-		if($limit <= 0) {
278
-			$limit = null;
279
-		}
280
-		$filter = $this->access->combineFilterWithAnd(array(
281
-			$this->access->connection->ldapUserFilter,
282
-			$this->access->connection->ldapUserDisplayName . '=*',
283
-			$this->access->getFilterPartForUserSearch($search)
284
-		));
285
-
286
-		Util::writeLog('user_ldap',
287
-			'getUsers: Options: search '.$search.' limit '.$limit.' offset '.$offset.' Filter: '.$filter,
288
-			ILogger::DEBUG);
289
-		//do the search and translate results to Nextcloud names
290
-		$ldap_users = $this->access->fetchListOfUsers(
291
-			$filter,
292
-			$this->access->userManager->getAttributes(true),
293
-			$limit, $offset);
294
-		$ldap_users = $this->access->nextcloudUserNames($ldap_users);
295
-		Util::writeLog('user_ldap', 'getUsers: '.count($ldap_users). ' Users found', ILogger::DEBUG);
296
-
297
-		$this->access->connection->writeToCache($cachekey, $ldap_users);
298
-		return $ldap_users;
299
-	}
300
-
301
-	/**
302
-	 * checks whether a user is still available on LDAP
303
-	 *
304
-	 * @param string|\OCA\User_LDAP\User\User $user either the Nextcloud user
305
-	 * name or an instance of that user
306
-	 * @return bool
307
-	 * @throws \Exception
308
-	 * @throws \OC\ServerNotAvailableException
309
-	 */
310
-	public function userExistsOnLDAP($user) {
311
-		if(is_string($user)) {
312
-			$user = $this->access->userManager->get($user);
313
-		}
314
-		if(is_null($user)) {
315
-			return false;
316
-		}
317
-
318
-		$dn = $user->getDN();
319
-		//check if user really still exists by reading its entry
320
-		if(!is_array($this->access->readAttribute($dn, '', $this->access->connection->ldapUserFilter))) {
321
-			$lcr = $this->access->connection->getConnectionResource();
322
-			if(is_null($lcr)) {
323
-				throw new \Exception('No LDAP Connection to server ' . $this->access->connection->ldapHost);
324
-			}
325
-
326
-			try {
327
-				$uuid = $this->access->getUserMapper()->getUUIDByDN($dn);
328
-				if (!$uuid) {
329
-					return false;
330
-				}
331
-				$newDn = $this->access->getUserDnByUuid($uuid);
332
-				//check if renamed user is still valid by reapplying the ldap filter
333
-				if (!is_array($this->access->readAttribute($newDn, '', $this->access->connection->ldapUserFilter))) {
334
-					return false;
335
-				}
336
-				$this->access->getUserMapper()->setDNbyUUID($newDn, $uuid);
337
-				return true;
338
-			} catch (ServerNotAvailableException $e) {
339
-				throw $e;
340
-			} catch (\Exception $e) {
341
-				return false;
342
-			}
343
-		}
344
-
345
-		if($user instanceof OfflineUser) {
346
-			$user->unmark();
347
-		}
348
-
349
-		return true;
350
-	}
351
-
352
-	/**
353
-	 * check if a user exists
354
-	 * @param string $uid the username
355
-	 * @return boolean
356
-	 * @throws \Exception when connection could not be established
357
-	 */
358
-	public function userExists($uid) {
359
-		$userExists = $this->access->connection->getFromCache('userExists'.$uid);
360
-		if(!is_null($userExists)) {
361
-			return (bool)$userExists;
362
-		}
363
-		//getting dn, if false the user does not exist. If dn, he may be mapped only, requires more checking.
364
-		$user = $this->access->userManager->get($uid);
365
-
366
-		if(is_null($user)) {
367
-			Util::writeLog('user_ldap', 'No DN found for '.$uid.' on '.
368
-				$this->access->connection->ldapHost, ILogger::DEBUG);
369
-			$this->access->connection->writeToCache('userExists'.$uid, false);
370
-			return false;
371
-		} else if($user instanceof OfflineUser) {
372
-			//express check for users marked as deleted. Returning true is
373
-			//necessary for cleanup
374
-			return true;
375
-		}
376
-
377
-		$result = $this->userExistsOnLDAP($user);
378
-		$this->access->connection->writeToCache('userExists'.$uid, $result);
379
-		if($result === true) {
380
-			$user->update();
381
-		}
382
-		return $result;
383
-	}
384
-
385
-	/**
386
-	* returns whether a user was deleted in LDAP
387
-	*
388
-	* @param string $uid The username of the user to delete
389
-	* @return bool
390
-	*/
391
-	public function deleteUser($uid) {
392
-		if ($this->userPluginManager->canDeleteUser()) {
393
-			return $this->userPluginManager->deleteUser($uid);
394
-		}
395
-
396
-		$marked = $this->ocConfig->getUserValue($uid, 'user_ldap', 'isDeleted', 0);
397
-		if((int)$marked === 0) {
398
-			\OC::$server->getLogger()->notice(
399
-				'User '.$uid . ' is not marked as deleted, not cleaning up.',
400
-				array('app' => 'user_ldap'));
401
-			return false;
402
-		}
403
-		\OC::$server->getLogger()->info('Cleaning up after user ' . $uid,
404
-			array('app' => 'user_ldap'));
405
-
406
-		$this->access->getUserMapper()->unmap($uid); // we don't emit unassign signals here, since it is implicit to delete signals fired from core
407
-		$this->access->userManager->invalidate($uid);
408
-		return true;
409
-	}
410
-
411
-	/**
412
-	 * get the user's home directory
413
-	 *
414
-	 * @param string $uid the username
415
-	 * @return bool|string
416
-	 * @throws NoUserException
417
-	 * @throws \Exception
418
-	 */
419
-	public function getHome($uid) {
420
-		// user Exists check required as it is not done in user proxy!
421
-		if(!$this->userExists($uid)) {
422
-			return false;
423
-		}
424
-
425
-		if ($this->userPluginManager->implementsActions(Backend::GET_HOME)) {
426
-			return $this->userPluginManager->getHome($uid);
427
-		}
428
-
429
-		$cacheKey = 'getHome'.$uid;
430
-		$path = $this->access->connection->getFromCache($cacheKey);
431
-		if(!is_null($path)) {
432
-			return $path;
433
-		}
434
-
435
-		// early return path if it is a deleted user
436
-		$user = $this->access->userManager->get($uid);
437
-		if($user instanceof OfflineUser) {
438
-			if($this->currentUserInDeletionProcess !== null
439
-				&& $this->currentUserInDeletionProcess === $user->getOCName()
440
-			) {
441
-				return $user->getHomePath();
442
-			} else {
443
-				throw new NoUserException($uid . ' is not a valid user anymore');
444
-			}
445
-		} else if ($user === null) {
446
-			throw new NoUserException($uid . ' is not a valid user anymore');
447
-		}
448
-
449
-		$path = $user->getHomePath();
450
-		$this->access->cacheUserHome($uid, $path);
451
-
452
-		return $path;
453
-	}
454
-
455
-	/**
456
-	 * get display name of the user
457
-	 * @param string $uid user ID of the user
458
-	 * @return string|false display name
459
-	 */
460
-	public function getDisplayName($uid) {
461
-		if ($this->userPluginManager->implementsActions(Backend::GET_DISPLAYNAME)) {
462
-			return $this->userPluginManager->getDisplayName($uid);
463
-		}
464
-
465
-		if(!$this->userExists($uid)) {
466
-			return false;
467
-		}
468
-
469
-		$cacheKey = 'getDisplayName'.$uid;
470
-		if(!is_null($displayName = $this->access->connection->getFromCache($cacheKey))) {
471
-			return $displayName;
472
-		}
473
-
474
-		//Check whether the display name is configured to have a 2nd feature
475
-		$additionalAttribute = $this->access->connection->ldapUserDisplayName2;
476
-		$displayName2 = '';
477
-		if ($additionalAttribute !== '') {
478
-			$displayName2 = $this->access->readAttribute(
479
-				$this->access->username2dn($uid),
480
-				$additionalAttribute);
481
-		}
482
-
483
-		$displayName = $this->access->readAttribute(
484
-			$this->access->username2dn($uid),
485
-			$this->access->connection->ldapUserDisplayName);
486
-
487
-		if($displayName && (count($displayName) > 0)) {
488
-			$displayName = $displayName[0];
489
-
490
-			if (is_array($displayName2)){
491
-				$displayName2 = count($displayName2) > 0 ? $displayName2[0] : '';
492
-			}
493
-
494
-			$user = $this->access->userManager->get($uid);
495
-			if ($user instanceof User) {
496
-				$displayName = $user->composeAndStoreDisplayName($displayName, $displayName2);
497
-				$this->access->connection->writeToCache($cacheKey, $displayName);
498
-			}
499
-			if ($user instanceof OfflineUser) {
500
-				/** @var OfflineUser $user*/
501
-				$displayName = $user->getDisplayName();
502
-			}
503
-			return $displayName;
504
-		}
505
-
506
-		return null;
507
-	}
508
-
509
-	/**
510
-	 * set display name of the user
511
-	 * @param string $uid user ID of the user
512
-	 * @param string $displayName new display name of the user
513
-	 * @return string|false display name
514
-	 */
515
-	public function setDisplayName($uid, $displayName) {
516
-		if ($this->userPluginManager->implementsActions(Backend::SET_DISPLAYNAME)) {
517
-			return $this->userPluginManager->setDisplayName($uid, $displayName);
518
-		}
519
-		return false;
520
-	}
521
-
522
-	/**
523
-	 * Get a list of all display names
524
-	 *
525
-	 * @param string $search
526
-	 * @param string|null $limit
527
-	 * @param string|null $offset
528
-	 * @return array an array of all displayNames (value) and the corresponding uids (key)
529
-	 */
530
-	public function getDisplayNames($search = '', $limit = null, $offset = null) {
531
-		$cacheKey = 'getDisplayNames-'.$search.'-'.$limit.'-'.$offset;
532
-		if(!is_null($displayNames = $this->access->connection->getFromCache($cacheKey))) {
533
-			return $displayNames;
534
-		}
535
-
536
-		$displayNames = array();
537
-		$users = $this->getUsers($search, $limit, $offset);
538
-		foreach ($users as $user) {
539
-			$displayNames[$user] = $this->getDisplayName($user);
540
-		}
541
-		$this->access->connection->writeToCache($cacheKey, $displayNames);
542
-		return $displayNames;
543
-	}
544
-
545
-	/**
546
-	* Check if backend implements actions
547
-	* @param int $actions bitwise-or'ed actions
548
-	* @return boolean
549
-	*
550
-	* Returns the supported actions as int to be
551
-	* compared with \OC\User\Backend::CREATE_USER etc.
552
-	*/
553
-	public function implementsActions($actions) {
554
-		return (bool)((Backend::CHECK_PASSWORD
555
-			| Backend::GET_HOME
556
-			| Backend::GET_DISPLAYNAME
557
-			| (($this->access->connection->ldapUserAvatarRule !== 'none') ? Backend::PROVIDE_AVATAR : 0)
558
-			| Backend::COUNT_USERS
559
-			| (((int)$this->access->connection->turnOnPasswordChange === 1)? Backend::SET_PASSWORD :0)
560
-			| $this->userPluginManager->getImplementedActions())
561
-			& $actions);
562
-	}
563
-
564
-	/**
565
-	 * @return bool
566
-	 */
567
-	public function hasUserListings() {
568
-		return true;
569
-	}
570
-
571
-	/**
572
-	 * counts the users in LDAP
573
-	 *
574
-	 * @return int|bool
575
-	 */
576
-	public function countUsers() {
577
-		if ($this->userPluginManager->implementsActions(Backend::COUNT_USERS)) {
578
-			return $this->userPluginManager->countUsers();
579
-		}
580
-
581
-		$filter = $this->access->getFilterForUserCount();
582
-		$cacheKey = 'countUsers-'.$filter;
583
-		if(!is_null($entries = $this->access->connection->getFromCache($cacheKey))) {
584
-			return $entries;
585
-		}
586
-		$entries = $this->access->countUsers($filter);
587
-		$this->access->connection->writeToCache($cacheKey, $entries);
588
-		return $entries;
589
-	}
590
-
591
-	/**
592
-	 * Backend name to be shown in user management
593
-	 * @return string the name of the backend to be shown
594
-	 */
595
-	public function getBackendName(){
596
-		return 'LDAP';
597
-	}
152
+    /**
153
+     * returns the username for the given LDAP DN, if available
154
+     *
155
+     * @param string $dn
156
+     * @return string|false with the username
157
+     */
158
+    public function dn2UserName($dn) {
159
+        return $this->access->dn2username($dn);
160
+    }
161
+
162
+    /**
163
+     * returns an LDAP record based on a given login name
164
+     *
165
+     * @param string $loginName
166
+     * @return array
167
+     * @throws NotOnLDAP
168
+     */
169
+    public function getLDAPUserByLoginName($loginName) {
170
+        //find out dn of the user name
171
+        $attrs = $this->access->userManager->getAttributes();
172
+        $users = $this->access->fetchUsersByLoginName($loginName, $attrs);
173
+        if(count($users) < 1) {
174
+            throw new NotOnLDAP('No user available for the given login name on ' .
175
+                $this->access->connection->ldapHost . ':' . $this->access->connection->ldapPort);
176
+        }
177
+        return $users[0];
178
+    }
179
+
180
+    /**
181
+     * Check if the password is correct without logging in the user
182
+     *
183
+     * @param string $uid The username
184
+     * @param string $password The password
185
+     * @return false|string
186
+     */
187
+    public function checkPassword($uid, $password) {
188
+        try {
189
+            $ldapRecord = $this->getLDAPUserByLoginName($uid);
190
+        } catch(NotOnLDAP $e) {
191
+            if($this->ocConfig->getSystemValue('loglevel', ILogger::WARN) === ILogger::DEBUG) {
192
+                \OC::$server->getLogger()->logException($e, ['app' => 'user_ldap']);
193
+            }
194
+            return false;
195
+        }
196
+        $dn = $ldapRecord['dn'][0];
197
+        $user = $this->access->userManager->get($dn);
198
+
199
+        if(!$user instanceof User) {
200
+            Util::writeLog('user_ldap',
201
+                'LDAP Login: Could not get user object for DN ' . $dn .
202
+                '. Maybe the LDAP entry has no set display name attribute?',
203
+                ILogger::WARN);
204
+            return false;
205
+        }
206
+        if($user->getUsername() !== false) {
207
+            //are the credentials OK?
208
+            if(!$this->access->areCredentialsValid($dn, $password)) {
209
+                return false;
210
+            }
211
+
212
+            $this->access->cacheUserExists($user->getUsername());
213
+            $user->processAttributes($ldapRecord);
214
+            $user->markLogin();
215
+
216
+            return $user->getUsername();
217
+        }
218
+
219
+        return false;
220
+    }
221
+
222
+    /**
223
+     * Set password
224
+     * @param string $uid The username
225
+     * @param string $password The new password
226
+     * @return bool
227
+     */
228
+    public function setPassword($uid, $password) {
229
+        if ($this->userPluginManager->implementsActions(Backend::SET_PASSWORD)) {
230
+            return $this->userPluginManager->setPassword($uid, $password);
231
+        }
232
+
233
+        $user = $this->access->userManager->get($uid);
234
+
235
+        if(!$user instanceof User) {
236
+            throw new \Exception('LDAP setPassword: Could not get user object for uid ' . $uid .
237
+                '. Maybe the LDAP entry has no set display name attribute?');
238
+        }
239
+        if($user->getUsername() !== false && $this->access->setPassword($user->getDN(), $password)) {
240
+            $ldapDefaultPPolicyDN = $this->access->connection->ldapDefaultPPolicyDN;
241
+            $turnOnPasswordChange = $this->access->connection->turnOnPasswordChange;
242
+            if (!empty($ldapDefaultPPolicyDN) && ((int)$turnOnPasswordChange === 1)) {
243
+                //remove last password expiry warning if any
244
+                $notification = $this->notificationManager->createNotification();
245
+                $notification->setApp('user_ldap')
246
+                    ->setUser($uid)
247
+                    ->setObject('pwd_exp_warn', $uid)
248
+                ;
249
+                $this->notificationManager->markProcessed($notification);
250
+            }
251
+            return true;
252
+        }
253
+
254
+        return false;
255
+    }
256
+
257
+    /**
258
+     * Get a list of all users
259
+     *
260
+     * @param string $search
261
+     * @param integer $limit
262
+     * @param integer $offset
263
+     * @return string[] an array of all uids
264
+     */
265
+    public function getUsers($search = '', $limit = 10, $offset = 0) {
266
+        $search = $this->access->escapeFilterPart($search, true);
267
+        $cachekey = 'getUsers-'.$search.'-'.$limit.'-'.$offset;
268
+
269
+        //check if users are cached, if so return
270
+        $ldap_users = $this->access->connection->getFromCache($cachekey);
271
+        if(!is_null($ldap_users)) {
272
+            return $ldap_users;
273
+        }
274
+
275
+        // if we'd pass -1 to LDAP search, we'd end up in a Protocol
276
+        // error. With a limit of 0, we get 0 results. So we pass null.
277
+        if($limit <= 0) {
278
+            $limit = null;
279
+        }
280
+        $filter = $this->access->combineFilterWithAnd(array(
281
+            $this->access->connection->ldapUserFilter,
282
+            $this->access->connection->ldapUserDisplayName . '=*',
283
+            $this->access->getFilterPartForUserSearch($search)
284
+        ));
285
+
286
+        Util::writeLog('user_ldap',
287
+            'getUsers: Options: search '.$search.' limit '.$limit.' offset '.$offset.' Filter: '.$filter,
288
+            ILogger::DEBUG);
289
+        //do the search and translate results to Nextcloud names
290
+        $ldap_users = $this->access->fetchListOfUsers(
291
+            $filter,
292
+            $this->access->userManager->getAttributes(true),
293
+            $limit, $offset);
294
+        $ldap_users = $this->access->nextcloudUserNames($ldap_users);
295
+        Util::writeLog('user_ldap', 'getUsers: '.count($ldap_users). ' Users found', ILogger::DEBUG);
296
+
297
+        $this->access->connection->writeToCache($cachekey, $ldap_users);
298
+        return $ldap_users;
299
+    }
300
+
301
+    /**
302
+     * checks whether a user is still available on LDAP
303
+     *
304
+     * @param string|\OCA\User_LDAP\User\User $user either the Nextcloud user
305
+     * name or an instance of that user
306
+     * @return bool
307
+     * @throws \Exception
308
+     * @throws \OC\ServerNotAvailableException
309
+     */
310
+    public function userExistsOnLDAP($user) {
311
+        if(is_string($user)) {
312
+            $user = $this->access->userManager->get($user);
313
+        }
314
+        if(is_null($user)) {
315
+            return false;
316
+        }
317
+
318
+        $dn = $user->getDN();
319
+        //check if user really still exists by reading its entry
320
+        if(!is_array($this->access->readAttribute($dn, '', $this->access->connection->ldapUserFilter))) {
321
+            $lcr = $this->access->connection->getConnectionResource();
322
+            if(is_null($lcr)) {
323
+                throw new \Exception('No LDAP Connection to server ' . $this->access->connection->ldapHost);
324
+            }
325
+
326
+            try {
327
+                $uuid = $this->access->getUserMapper()->getUUIDByDN($dn);
328
+                if (!$uuid) {
329
+                    return false;
330
+                }
331
+                $newDn = $this->access->getUserDnByUuid($uuid);
332
+                //check if renamed user is still valid by reapplying the ldap filter
333
+                if (!is_array($this->access->readAttribute($newDn, '', $this->access->connection->ldapUserFilter))) {
334
+                    return false;
335
+                }
336
+                $this->access->getUserMapper()->setDNbyUUID($newDn, $uuid);
337
+                return true;
338
+            } catch (ServerNotAvailableException $e) {
339
+                throw $e;
340
+            } catch (\Exception $e) {
341
+                return false;
342
+            }
343
+        }
344
+
345
+        if($user instanceof OfflineUser) {
346
+            $user->unmark();
347
+        }
348
+
349
+        return true;
350
+    }
351
+
352
+    /**
353
+     * check if a user exists
354
+     * @param string $uid the username
355
+     * @return boolean
356
+     * @throws \Exception when connection could not be established
357
+     */
358
+    public function userExists($uid) {
359
+        $userExists = $this->access->connection->getFromCache('userExists'.$uid);
360
+        if(!is_null($userExists)) {
361
+            return (bool)$userExists;
362
+        }
363
+        //getting dn, if false the user does not exist. If dn, he may be mapped only, requires more checking.
364
+        $user = $this->access->userManager->get($uid);
365
+
366
+        if(is_null($user)) {
367
+            Util::writeLog('user_ldap', 'No DN found for '.$uid.' on '.
368
+                $this->access->connection->ldapHost, ILogger::DEBUG);
369
+            $this->access->connection->writeToCache('userExists'.$uid, false);
370
+            return false;
371
+        } else if($user instanceof OfflineUser) {
372
+            //express check for users marked as deleted. Returning true is
373
+            //necessary for cleanup
374
+            return true;
375
+        }
376
+
377
+        $result = $this->userExistsOnLDAP($user);
378
+        $this->access->connection->writeToCache('userExists'.$uid, $result);
379
+        if($result === true) {
380
+            $user->update();
381
+        }
382
+        return $result;
383
+    }
384
+
385
+    /**
386
+     * returns whether a user was deleted in LDAP
387
+     *
388
+     * @param string $uid The username of the user to delete
389
+     * @return bool
390
+     */
391
+    public function deleteUser($uid) {
392
+        if ($this->userPluginManager->canDeleteUser()) {
393
+            return $this->userPluginManager->deleteUser($uid);
394
+        }
395
+
396
+        $marked = $this->ocConfig->getUserValue($uid, 'user_ldap', 'isDeleted', 0);
397
+        if((int)$marked === 0) {
398
+            \OC::$server->getLogger()->notice(
399
+                'User '.$uid . ' is not marked as deleted, not cleaning up.',
400
+                array('app' => 'user_ldap'));
401
+            return false;
402
+        }
403
+        \OC::$server->getLogger()->info('Cleaning up after user ' . $uid,
404
+            array('app' => 'user_ldap'));
405
+
406
+        $this->access->getUserMapper()->unmap($uid); // we don't emit unassign signals here, since it is implicit to delete signals fired from core
407
+        $this->access->userManager->invalidate($uid);
408
+        return true;
409
+    }
410
+
411
+    /**
412
+     * get the user's home directory
413
+     *
414
+     * @param string $uid the username
415
+     * @return bool|string
416
+     * @throws NoUserException
417
+     * @throws \Exception
418
+     */
419
+    public function getHome($uid) {
420
+        // user Exists check required as it is not done in user proxy!
421
+        if(!$this->userExists($uid)) {
422
+            return false;
423
+        }
424
+
425
+        if ($this->userPluginManager->implementsActions(Backend::GET_HOME)) {
426
+            return $this->userPluginManager->getHome($uid);
427
+        }
428
+
429
+        $cacheKey = 'getHome'.$uid;
430
+        $path = $this->access->connection->getFromCache($cacheKey);
431
+        if(!is_null($path)) {
432
+            return $path;
433
+        }
434
+
435
+        // early return path if it is a deleted user
436
+        $user = $this->access->userManager->get($uid);
437
+        if($user instanceof OfflineUser) {
438
+            if($this->currentUserInDeletionProcess !== null
439
+                && $this->currentUserInDeletionProcess === $user->getOCName()
440
+            ) {
441
+                return $user->getHomePath();
442
+            } else {
443
+                throw new NoUserException($uid . ' is not a valid user anymore');
444
+            }
445
+        } else if ($user === null) {
446
+            throw new NoUserException($uid . ' is not a valid user anymore');
447
+        }
448
+
449
+        $path = $user->getHomePath();
450
+        $this->access->cacheUserHome($uid, $path);
451
+
452
+        return $path;
453
+    }
454
+
455
+    /**
456
+     * get display name of the user
457
+     * @param string $uid user ID of the user
458
+     * @return string|false display name
459
+     */
460
+    public function getDisplayName($uid) {
461
+        if ($this->userPluginManager->implementsActions(Backend::GET_DISPLAYNAME)) {
462
+            return $this->userPluginManager->getDisplayName($uid);
463
+        }
464
+
465
+        if(!$this->userExists($uid)) {
466
+            return false;
467
+        }
468
+
469
+        $cacheKey = 'getDisplayName'.$uid;
470
+        if(!is_null($displayName = $this->access->connection->getFromCache($cacheKey))) {
471
+            return $displayName;
472
+        }
473
+
474
+        //Check whether the display name is configured to have a 2nd feature
475
+        $additionalAttribute = $this->access->connection->ldapUserDisplayName2;
476
+        $displayName2 = '';
477
+        if ($additionalAttribute !== '') {
478
+            $displayName2 = $this->access->readAttribute(
479
+                $this->access->username2dn($uid),
480
+                $additionalAttribute);
481
+        }
482
+
483
+        $displayName = $this->access->readAttribute(
484
+            $this->access->username2dn($uid),
485
+            $this->access->connection->ldapUserDisplayName);
486
+
487
+        if($displayName && (count($displayName) > 0)) {
488
+            $displayName = $displayName[0];
489
+
490
+            if (is_array($displayName2)){
491
+                $displayName2 = count($displayName2) > 0 ? $displayName2[0] : '';
492
+            }
493
+
494
+            $user = $this->access->userManager->get($uid);
495
+            if ($user instanceof User) {
496
+                $displayName = $user->composeAndStoreDisplayName($displayName, $displayName2);
497
+                $this->access->connection->writeToCache($cacheKey, $displayName);
498
+            }
499
+            if ($user instanceof OfflineUser) {
500
+                /** @var OfflineUser $user*/
501
+                $displayName = $user->getDisplayName();
502
+            }
503
+            return $displayName;
504
+        }
505
+
506
+        return null;
507
+    }
508
+
509
+    /**
510
+     * set display name of the user
511
+     * @param string $uid user ID of the user
512
+     * @param string $displayName new display name of the user
513
+     * @return string|false display name
514
+     */
515
+    public function setDisplayName($uid, $displayName) {
516
+        if ($this->userPluginManager->implementsActions(Backend::SET_DISPLAYNAME)) {
517
+            return $this->userPluginManager->setDisplayName($uid, $displayName);
518
+        }
519
+        return false;
520
+    }
521
+
522
+    /**
523
+     * Get a list of all display names
524
+     *
525
+     * @param string $search
526
+     * @param string|null $limit
527
+     * @param string|null $offset
528
+     * @return array an array of all displayNames (value) and the corresponding uids (key)
529
+     */
530
+    public function getDisplayNames($search = '', $limit = null, $offset = null) {
531
+        $cacheKey = 'getDisplayNames-'.$search.'-'.$limit.'-'.$offset;
532
+        if(!is_null($displayNames = $this->access->connection->getFromCache($cacheKey))) {
533
+            return $displayNames;
534
+        }
535
+
536
+        $displayNames = array();
537
+        $users = $this->getUsers($search, $limit, $offset);
538
+        foreach ($users as $user) {
539
+            $displayNames[$user] = $this->getDisplayName($user);
540
+        }
541
+        $this->access->connection->writeToCache($cacheKey, $displayNames);
542
+        return $displayNames;
543
+    }
544
+
545
+    /**
546
+     * Check if backend implements actions
547
+     * @param int $actions bitwise-or'ed actions
548
+     * @return boolean
549
+     *
550
+     * Returns the supported actions as int to be
551
+     * compared with \OC\User\Backend::CREATE_USER etc.
552
+     */
553
+    public function implementsActions($actions) {
554
+        return (bool)((Backend::CHECK_PASSWORD
555
+            | Backend::GET_HOME
556
+            | Backend::GET_DISPLAYNAME
557
+            | (($this->access->connection->ldapUserAvatarRule !== 'none') ? Backend::PROVIDE_AVATAR : 0)
558
+            | Backend::COUNT_USERS
559
+            | (((int)$this->access->connection->turnOnPasswordChange === 1)? Backend::SET_PASSWORD :0)
560
+            | $this->userPluginManager->getImplementedActions())
561
+            & $actions);
562
+    }
563
+
564
+    /**
565
+     * @return bool
566
+     */
567
+    public function hasUserListings() {
568
+        return true;
569
+    }
570
+
571
+    /**
572
+     * counts the users in LDAP
573
+     *
574
+     * @return int|bool
575
+     */
576
+    public function countUsers() {
577
+        if ($this->userPluginManager->implementsActions(Backend::COUNT_USERS)) {
578
+            return $this->userPluginManager->countUsers();
579
+        }
580
+
581
+        $filter = $this->access->getFilterForUserCount();
582
+        $cacheKey = 'countUsers-'.$filter;
583
+        if(!is_null($entries = $this->access->connection->getFromCache($cacheKey))) {
584
+            return $entries;
585
+        }
586
+        $entries = $this->access->countUsers($filter);
587
+        $this->access->connection->writeToCache($cacheKey, $entries);
588
+        return $entries;
589
+    }
590
+
591
+    /**
592
+     * Backend name to be shown in user management
593
+     * @return string the name of the backend to be shown
594
+     */
595
+    public function getBackendName(){
596
+        return 'LDAP';
597
+    }
598 598
 	
599
-	/**
600
-	 * Return access for LDAP interaction.
601
-	 * @param string $uid
602
-	 * @return Access instance of Access for LDAP interaction
603
-	 */
604
-	public function getLDAPAccess($uid) {
605
-		return $this->access;
606
-	}
599
+    /**
600
+     * Return access for LDAP interaction.
601
+     * @param string $uid
602
+     * @return Access instance of Access for LDAP interaction
603
+     */
604
+    public function getLDAPAccess($uid) {
605
+        return $this->access;
606
+    }
607 607
 	
608
-	/**
609
-	 * Return LDAP connection resource from a cloned connection.
610
-	 * The cloned connection needs to be closed manually.
611
-	 * of the current access.
612
-	 * @param string $uid
613
-	 * @return resource of the LDAP connection
614
-	 */
615
-	public function getNewLDAPConnection($uid) {
616
-		$connection = clone $this->access->getConnection();
617
-		return $connection->getConnectionResource();
618
-	}
619
-
620
-	/**
621
-	 * create new user
622
-	 * @param string $username username of the new user
623
-	 * @param string $password password of the new user
624
-	 * @return bool was the user created?
625
-	 */
626
-	public function createUser($username, $password) {
627
-		if ($this->userPluginManager->implementsActions(Backend::CREATE_USER)) {
628
-			return $this->userPluginManager->createUser($username, $password);
629
-		}
630
-		return false;
631
-	}
608
+    /**
609
+     * Return LDAP connection resource from a cloned connection.
610
+     * The cloned connection needs to be closed manually.
611
+     * of the current access.
612
+     * @param string $uid
613
+     * @return resource of the LDAP connection
614
+     */
615
+    public function getNewLDAPConnection($uid) {
616
+        $connection = clone $this->access->getConnection();
617
+        return $connection->getConnectionResource();
618
+    }
619
+
620
+    /**
621
+     * create new user
622
+     * @param string $username username of the new user
623
+     * @param string $password password of the new user
624
+     * @return bool was the user created?
625
+     */
626
+    public function createUser($username, $password) {
627
+        if ($this->userPluginManager->implementsActions(Backend::CREATE_USER)) {
628
+            return $this->userPluginManager->createUser($username, $password);
629
+        }
630
+        return false;
631
+    }
632 632
 
633 633
 }
Please login to merge, or discard this patch.
Spacing   +51 added lines, -51 removed lines patch added patch discarded remove patch
@@ -103,16 +103,16 @@  discard block
 block discarded – undo
103 103
 			return $this->userPluginManager->canChangeAvatar($uid);
104 104
 		}
105 105
 
106
-		if(!$this->implementsActions(Backend::PROVIDE_AVATAR)) {
106
+		if (!$this->implementsActions(Backend::PROVIDE_AVATAR)) {
107 107
 			return true;
108 108
 		}
109 109
 
110 110
 		$user = $this->access->userManager->get($uid);
111
-		if(!$user instanceof User) {
111
+		if (!$user instanceof User) {
112 112
 			return false;
113 113
 		}
114 114
 		$imageData = $user->getAvatarImage();
115
-		if($imageData === false) {
115
+		if ($imageData === false) {
116 116
 			return true;
117 117
 		}
118 118
 		return !$user->updateAvatar(true);
@@ -127,14 +127,14 @@  discard block
 block discarded – undo
127 127
 	public function loginName2UserName($loginName) {
128 128
 		$cacheKey = 'loginName2UserName-'.$loginName;
129 129
 		$username = $this->access->connection->getFromCache($cacheKey);
130
-		if(!is_null($username)) {
130
+		if (!is_null($username)) {
131 131
 			return $username;
132 132
 		}
133 133
 
134 134
 		try {
135 135
 			$ldapRecord = $this->getLDAPUserByLoginName($loginName);
136 136
 			$user = $this->access->userManager->get($ldapRecord['dn'][0]);
137
-			if($user instanceof OfflineUser) {
137
+			if ($user instanceof OfflineUser) {
138 138
 				// this path is not really possible, however get() is documented
139 139
 				// to return User or OfflineUser so we are very defensive here.
140 140
 				$this->access->connection->writeToCache($cacheKey, false);
@@ -170,9 +170,9 @@  discard block
 block discarded – undo
170 170
 		//find out dn of the user name
171 171
 		$attrs = $this->access->userManager->getAttributes();
172 172
 		$users = $this->access->fetchUsersByLoginName($loginName, $attrs);
173
-		if(count($users) < 1) {
174
-			throw new NotOnLDAP('No user available for the given login name on ' .
175
-				$this->access->connection->ldapHost . ':' . $this->access->connection->ldapPort);
173
+		if (count($users) < 1) {
174
+			throw new NotOnLDAP('No user available for the given login name on '.
175
+				$this->access->connection->ldapHost.':'.$this->access->connection->ldapPort);
176 176
 		}
177 177
 		return $users[0];
178 178
 	}
@@ -187,8 +187,8 @@  discard block
 block discarded – undo
187 187
 	public function checkPassword($uid, $password) {
188 188
 		try {
189 189
 			$ldapRecord = $this->getLDAPUserByLoginName($uid);
190
-		} catch(NotOnLDAP $e) {
191
-			if($this->ocConfig->getSystemValue('loglevel', ILogger::WARN) === ILogger::DEBUG) {
190
+		} catch (NotOnLDAP $e) {
191
+			if ($this->ocConfig->getSystemValue('loglevel', ILogger::WARN) === ILogger::DEBUG) {
192 192
 				\OC::$server->getLogger()->logException($e, ['app' => 'user_ldap']);
193 193
 			}
194 194
 			return false;
@@ -196,16 +196,16 @@  discard block
 block discarded – undo
196 196
 		$dn = $ldapRecord['dn'][0];
197 197
 		$user = $this->access->userManager->get($dn);
198 198
 
199
-		if(!$user instanceof User) {
199
+		if (!$user instanceof User) {
200 200
 			Util::writeLog('user_ldap',
201
-				'LDAP Login: Could not get user object for DN ' . $dn .
201
+				'LDAP Login: Could not get user object for DN '.$dn.
202 202
 				'. Maybe the LDAP entry has no set display name attribute?',
203 203
 				ILogger::WARN);
204 204
 			return false;
205 205
 		}
206
-		if($user->getUsername() !== false) {
206
+		if ($user->getUsername() !== false) {
207 207
 			//are the credentials OK?
208
-			if(!$this->access->areCredentialsValid($dn, $password)) {
208
+			if (!$this->access->areCredentialsValid($dn, $password)) {
209 209
 				return false;
210 210
 			}
211 211
 
@@ -232,14 +232,14 @@  discard block
 block discarded – undo
232 232
 
233 233
 		$user = $this->access->userManager->get($uid);
234 234
 
235
-		if(!$user instanceof User) {
236
-			throw new \Exception('LDAP setPassword: Could not get user object for uid ' . $uid .
235
+		if (!$user instanceof User) {
236
+			throw new \Exception('LDAP setPassword: Could not get user object for uid '.$uid.
237 237
 				'. Maybe the LDAP entry has no set display name attribute?');
238 238
 		}
239
-		if($user->getUsername() !== false && $this->access->setPassword($user->getDN(), $password)) {
239
+		if ($user->getUsername() !== false && $this->access->setPassword($user->getDN(), $password)) {
240 240
 			$ldapDefaultPPolicyDN = $this->access->connection->ldapDefaultPPolicyDN;
241 241
 			$turnOnPasswordChange = $this->access->connection->turnOnPasswordChange;
242
-			if (!empty($ldapDefaultPPolicyDN) && ((int)$turnOnPasswordChange === 1)) {
242
+			if (!empty($ldapDefaultPPolicyDN) && ((int) $turnOnPasswordChange === 1)) {
243 243
 				//remove last password expiry warning if any
244 244
 				$notification = $this->notificationManager->createNotification();
245 245
 				$notification->setApp('user_ldap')
@@ -268,18 +268,18 @@  discard block
 block discarded – undo
268 268
 
269 269
 		//check if users are cached, if so return
270 270
 		$ldap_users = $this->access->connection->getFromCache($cachekey);
271
-		if(!is_null($ldap_users)) {
271
+		if (!is_null($ldap_users)) {
272 272
 			return $ldap_users;
273 273
 		}
274 274
 
275 275
 		// if we'd pass -1 to LDAP search, we'd end up in a Protocol
276 276
 		// error. With a limit of 0, we get 0 results. So we pass null.
277
-		if($limit <= 0) {
277
+		if ($limit <= 0) {
278 278
 			$limit = null;
279 279
 		}
280 280
 		$filter = $this->access->combineFilterWithAnd(array(
281 281
 			$this->access->connection->ldapUserFilter,
282
-			$this->access->connection->ldapUserDisplayName . '=*',
282
+			$this->access->connection->ldapUserDisplayName.'=*',
283 283
 			$this->access->getFilterPartForUserSearch($search)
284 284
 		));
285 285
 
@@ -292,7 +292,7 @@  discard block
 block discarded – undo
292 292
 			$this->access->userManager->getAttributes(true),
293 293
 			$limit, $offset);
294 294
 		$ldap_users = $this->access->nextcloudUserNames($ldap_users);
295
-		Util::writeLog('user_ldap', 'getUsers: '.count($ldap_users). ' Users found', ILogger::DEBUG);
295
+		Util::writeLog('user_ldap', 'getUsers: '.count($ldap_users).' Users found', ILogger::DEBUG);
296 296
 
297 297
 		$this->access->connection->writeToCache($cachekey, $ldap_users);
298 298
 		return $ldap_users;
@@ -308,19 +308,19 @@  discard block
 block discarded – undo
308 308
 	 * @throws \OC\ServerNotAvailableException
309 309
 	 */
310 310
 	public function userExistsOnLDAP($user) {
311
-		if(is_string($user)) {
311
+		if (is_string($user)) {
312 312
 			$user = $this->access->userManager->get($user);
313 313
 		}
314
-		if(is_null($user)) {
314
+		if (is_null($user)) {
315 315
 			return false;
316 316
 		}
317 317
 
318 318
 		$dn = $user->getDN();
319 319
 		//check if user really still exists by reading its entry
320
-		if(!is_array($this->access->readAttribute($dn, '', $this->access->connection->ldapUserFilter))) {
320
+		if (!is_array($this->access->readAttribute($dn, '', $this->access->connection->ldapUserFilter))) {
321 321
 			$lcr = $this->access->connection->getConnectionResource();
322
-			if(is_null($lcr)) {
323
-				throw new \Exception('No LDAP Connection to server ' . $this->access->connection->ldapHost);
322
+			if (is_null($lcr)) {
323
+				throw new \Exception('No LDAP Connection to server '.$this->access->connection->ldapHost);
324 324
 			}
325 325
 
326 326
 			try {
@@ -342,7 +342,7 @@  discard block
 block discarded – undo
342 342
 			}
343 343
 		}
344 344
 
345
-		if($user instanceof OfflineUser) {
345
+		if ($user instanceof OfflineUser) {
346 346
 			$user->unmark();
347 347
 		}
348 348
 
@@ -357,18 +357,18 @@  discard block
 block discarded – undo
357 357
 	 */
358 358
 	public function userExists($uid) {
359 359
 		$userExists = $this->access->connection->getFromCache('userExists'.$uid);
360
-		if(!is_null($userExists)) {
361
-			return (bool)$userExists;
360
+		if (!is_null($userExists)) {
361
+			return (bool) $userExists;
362 362
 		}
363 363
 		//getting dn, if false the user does not exist. If dn, he may be mapped only, requires more checking.
364 364
 		$user = $this->access->userManager->get($uid);
365 365
 
366
-		if(is_null($user)) {
366
+		if (is_null($user)) {
367 367
 			Util::writeLog('user_ldap', 'No DN found for '.$uid.' on '.
368 368
 				$this->access->connection->ldapHost, ILogger::DEBUG);
369 369
 			$this->access->connection->writeToCache('userExists'.$uid, false);
370 370
 			return false;
371
-		} else if($user instanceof OfflineUser) {
371
+		} else if ($user instanceof OfflineUser) {
372 372
 			//express check for users marked as deleted. Returning true is
373 373
 			//necessary for cleanup
374 374
 			return true;
@@ -376,7 +376,7 @@  discard block
 block discarded – undo
376 376
 
377 377
 		$result = $this->userExistsOnLDAP($user);
378 378
 		$this->access->connection->writeToCache('userExists'.$uid, $result);
379
-		if($result === true) {
379
+		if ($result === true) {
380 380
 			$user->update();
381 381
 		}
382 382
 		return $result;
@@ -394,13 +394,13 @@  discard block
 block discarded – undo
394 394
 		}
395 395
 
396 396
 		$marked = $this->ocConfig->getUserValue($uid, 'user_ldap', 'isDeleted', 0);
397
-		if((int)$marked === 0) {
397
+		if ((int) $marked === 0) {
398 398
 			\OC::$server->getLogger()->notice(
399
-				'User '.$uid . ' is not marked as deleted, not cleaning up.',
399
+				'User '.$uid.' is not marked as deleted, not cleaning up.',
400 400
 				array('app' => 'user_ldap'));
401 401
 			return false;
402 402
 		}
403
-		\OC::$server->getLogger()->info('Cleaning up after user ' . $uid,
403
+		\OC::$server->getLogger()->info('Cleaning up after user '.$uid,
404 404
 			array('app' => 'user_ldap'));
405 405
 
406 406
 		$this->access->getUserMapper()->unmap($uid); // we don't emit unassign signals here, since it is implicit to delete signals fired from core
@@ -418,7 +418,7 @@  discard block
 block discarded – undo
418 418
 	 */
419 419
 	public function getHome($uid) {
420 420
 		// user Exists check required as it is not done in user proxy!
421
-		if(!$this->userExists($uid)) {
421
+		if (!$this->userExists($uid)) {
422 422
 			return false;
423 423
 		}
424 424
 
@@ -428,22 +428,22 @@  discard block
 block discarded – undo
428 428
 
429 429
 		$cacheKey = 'getHome'.$uid;
430 430
 		$path = $this->access->connection->getFromCache($cacheKey);
431
-		if(!is_null($path)) {
431
+		if (!is_null($path)) {
432 432
 			return $path;
433 433
 		}
434 434
 
435 435
 		// early return path if it is a deleted user
436 436
 		$user = $this->access->userManager->get($uid);
437
-		if($user instanceof OfflineUser) {
438
-			if($this->currentUserInDeletionProcess !== null
437
+		if ($user instanceof OfflineUser) {
438
+			if ($this->currentUserInDeletionProcess !== null
439 439
 				&& $this->currentUserInDeletionProcess === $user->getOCName()
440 440
 			) {
441 441
 				return $user->getHomePath();
442 442
 			} else {
443
-				throw new NoUserException($uid . ' is not a valid user anymore');
443
+				throw new NoUserException($uid.' is not a valid user anymore');
444 444
 			}
445 445
 		} else if ($user === null) {
446
-			throw new NoUserException($uid . ' is not a valid user anymore');
446
+			throw new NoUserException($uid.' is not a valid user anymore');
447 447
 		}
448 448
 
449 449
 		$path = $user->getHomePath();
@@ -462,12 +462,12 @@  discard block
 block discarded – undo
462 462
 			return $this->userPluginManager->getDisplayName($uid);
463 463
 		}
464 464
 
465
-		if(!$this->userExists($uid)) {
465
+		if (!$this->userExists($uid)) {
466 466
 			return false;
467 467
 		}
468 468
 
469 469
 		$cacheKey = 'getDisplayName'.$uid;
470
-		if(!is_null($displayName = $this->access->connection->getFromCache($cacheKey))) {
470
+		if (!is_null($displayName = $this->access->connection->getFromCache($cacheKey))) {
471 471
 			return $displayName;
472 472
 		}
473 473
 
@@ -484,10 +484,10 @@  discard block
 block discarded – undo
484 484
 			$this->access->username2dn($uid),
485 485
 			$this->access->connection->ldapUserDisplayName);
486 486
 
487
-		if($displayName && (count($displayName) > 0)) {
487
+		if ($displayName && (count($displayName) > 0)) {
488 488
 			$displayName = $displayName[0];
489 489
 
490
-			if (is_array($displayName2)){
490
+			if (is_array($displayName2)) {
491 491
 				$displayName2 = count($displayName2) > 0 ? $displayName2[0] : '';
492 492
 			}
493 493
 
@@ -529,7 +529,7 @@  discard block
 block discarded – undo
529 529
 	 */
530 530
 	public function getDisplayNames($search = '', $limit = null, $offset = null) {
531 531
 		$cacheKey = 'getDisplayNames-'.$search.'-'.$limit.'-'.$offset;
532
-		if(!is_null($displayNames = $this->access->connection->getFromCache($cacheKey))) {
532
+		if (!is_null($displayNames = $this->access->connection->getFromCache($cacheKey))) {
533 533
 			return $displayNames;
534 534
 		}
535 535
 
@@ -551,12 +551,12 @@  discard block
 block discarded – undo
551 551
 	* compared with \OC\User\Backend::CREATE_USER etc.
552 552
 	*/
553 553
 	public function implementsActions($actions) {
554
-		return (bool)((Backend::CHECK_PASSWORD
554
+		return (bool) ((Backend::CHECK_PASSWORD
555 555
 			| Backend::GET_HOME
556 556
 			| Backend::GET_DISPLAYNAME
557 557
 			| (($this->access->connection->ldapUserAvatarRule !== 'none') ? Backend::PROVIDE_AVATAR : 0)
558 558
 			| Backend::COUNT_USERS
559
-			| (((int)$this->access->connection->turnOnPasswordChange === 1)? Backend::SET_PASSWORD :0)
559
+			| (((int) $this->access->connection->turnOnPasswordChange === 1) ? Backend::SET_PASSWORD : 0)
560 560
 			| $this->userPluginManager->getImplementedActions())
561 561
 			& $actions);
562 562
 	}
@@ -580,7 +580,7 @@  discard block
 block discarded – undo
580 580
 
581 581
 		$filter = $this->access->getFilterForUserCount();
582 582
 		$cacheKey = 'countUsers-'.$filter;
583
-		if(!is_null($entries = $this->access->connection->getFromCache($cacheKey))) {
583
+		if (!is_null($entries = $this->access->connection->getFromCache($cacheKey))) {
584 584
 			return $entries;
585 585
 		}
586 586
 		$entries = $this->access->countUsers($filter);
@@ -592,7 +592,7 @@  discard block
 block discarded – undo
592 592
 	 * Backend name to be shown in user management
593 593
 	 * @return string the name of the backend to be shown
594 594
 	 */
595
-	public function getBackendName(){
595
+	public function getBackendName() {
596 596
 		return 'LDAP';
597 597
 	}
598 598
 	
Please login to merge, or discard this patch.