Completed
Push — master ( 39468f...49d871 )
by Björn
14:59
created
apps/user_ldap/lib/Command/CheckUser.php 1 patch
Indentation   +96 added lines, -96 removed lines patch added patch discarded remove patch
@@ -36,101 +36,101 @@
 block discarded – undo
36 36
 use OCA\User_LDAP\User_Proxy;
37 37
 
38 38
 class CheckUser extends Command {
39
-	/** @var \OCA\User_LDAP\User_Proxy */
40
-	protected $backend;
41
-
42
-	/** @var \OCA\User_LDAP\Helper */
43
-	protected $helper;
44
-
45
-	/** @var \OCA\User_LDAP\User\DeletedUsersIndex */
46
-	protected $dui;
47
-
48
-	/** @var \OCA\User_LDAP\Mapping\UserMapping */
49
-	protected $mapping;
50
-
51
-	/**
52
-	 * @param User_Proxy $uBackend
53
-	 * @param LDAPHelper $helper
54
-	 * @param DeletedUsersIndex $dui
55
-	 * @param UserMapping $mapping
56
-	 */
57
-	public function __construct(User_Proxy $uBackend, LDAPHelper $helper, DeletedUsersIndex $dui, UserMapping $mapping) {
58
-		$this->backend = $uBackend;
59
-		$this->helper = $helper;
60
-		$this->dui = $dui;
61
-		$this->mapping = $mapping;
62
-		parent::__construct();
63
-	}
64
-
65
-	protected function configure() {
66
-		$this
67
-			->setName('ldap:check-user')
68
-			->setDescription('checks whether a user exists on LDAP.')
69
-			->addArgument(
70
-					'ocName',
71
-					InputArgument::REQUIRED,
72
-					'the user name as used in Nextcloud'
73
-				     )
74
-			->addOption(
75
-					'force',
76
-					null,
77
-					InputOption::VALUE_NONE,
78
-					'ignores disabled LDAP configuration'
79
-				     )
80
-		;
81
-	}
82
-
83
-	protected function execute(InputInterface $input, OutputInterface $output) {
84
-		try {
85
-			$uid = $input->getArgument('ocName');
86
-			$this->isAllowed($input->getOption('force'));
87
-			$this->confirmUserIsMapped($uid);
88
-			$exists = $this->backend->userExistsOnLDAP($uid);
89
-			if($exists === true) {
90
-				$output->writeln('The user is still available on LDAP.');
91
-				return;
92
-			}
93
-
94
-			$this->dui->markUser($uid);
95
-			$output->writeln('The user does not exists on LDAP anymore.');
96
-			$output->writeln('Clean up the user\'s remnants by: ./occ user:delete "'
97
-				. $uid . '"');
98
-		} catch (\Exception $e) {
99
-			$output->writeln('<error>' . $e->getMessage(). '</error>');
100
-		}
101
-	}
102
-
103
-	/**
104
-	 * checks whether a user is actually mapped
105
-	 * @param string $ocName the username as used in Nextcloud
106
-	 * @throws \Exception
107
-	 * @return true
108
-	 */
109
-	protected function confirmUserIsMapped($ocName) {
110
-		$dn = $this->mapping->getDNByName($ocName);
111
-		if ($dn === false) {
112
-			throw new \Exception('The given user is not a recognized LDAP user.');
113
-		}
114
-
115
-		return true;
116
-	}
117
-
118
-	/**
119
-	 * checks whether the setup allows reliable checking of LDAP user existence
120
-	 * @throws \Exception
121
-	 * @return true
122
-	 */
123
-	protected function isAllowed($force) {
124
-		if($this->helper->haveDisabledConfigurations() && !$force) {
125
-			throw new \Exception('Cannot check user existence, because '
126
-				. 'disabled LDAP configurations are present.');
127
-		}
128
-
129
-		// we don't check ldapUserCleanupInterval from config.php because this
130
-		// action is triggered manually, while the setting only controls the
131
-		// background job.
132
-
133
-		return true;
134
-	}
39
+    /** @var \OCA\User_LDAP\User_Proxy */
40
+    protected $backend;
41
+
42
+    /** @var \OCA\User_LDAP\Helper */
43
+    protected $helper;
44
+
45
+    /** @var \OCA\User_LDAP\User\DeletedUsersIndex */
46
+    protected $dui;
47
+
48
+    /** @var \OCA\User_LDAP\Mapping\UserMapping */
49
+    protected $mapping;
50
+
51
+    /**
52
+     * @param User_Proxy $uBackend
53
+     * @param LDAPHelper $helper
54
+     * @param DeletedUsersIndex $dui
55
+     * @param UserMapping $mapping
56
+     */
57
+    public function __construct(User_Proxy $uBackend, LDAPHelper $helper, DeletedUsersIndex $dui, UserMapping $mapping) {
58
+        $this->backend = $uBackend;
59
+        $this->helper = $helper;
60
+        $this->dui = $dui;
61
+        $this->mapping = $mapping;
62
+        parent::__construct();
63
+    }
64
+
65
+    protected function configure() {
66
+        $this
67
+            ->setName('ldap:check-user')
68
+            ->setDescription('checks whether a user exists on LDAP.')
69
+            ->addArgument(
70
+                    'ocName',
71
+                    InputArgument::REQUIRED,
72
+                    'the user name as used in Nextcloud'
73
+                        )
74
+            ->addOption(
75
+                    'force',
76
+                    null,
77
+                    InputOption::VALUE_NONE,
78
+                    'ignores disabled LDAP configuration'
79
+                        )
80
+        ;
81
+    }
82
+
83
+    protected function execute(InputInterface $input, OutputInterface $output) {
84
+        try {
85
+            $uid = $input->getArgument('ocName');
86
+            $this->isAllowed($input->getOption('force'));
87
+            $this->confirmUserIsMapped($uid);
88
+            $exists = $this->backend->userExistsOnLDAP($uid);
89
+            if($exists === true) {
90
+                $output->writeln('The user is still available on LDAP.');
91
+                return;
92
+            }
93
+
94
+            $this->dui->markUser($uid);
95
+            $output->writeln('The user does not exists on LDAP anymore.');
96
+            $output->writeln('Clean up the user\'s remnants by: ./occ user:delete "'
97
+                . $uid . '"');
98
+        } catch (\Exception $e) {
99
+            $output->writeln('<error>' . $e->getMessage(). '</error>');
100
+        }
101
+    }
102
+
103
+    /**
104
+     * checks whether a user is actually mapped
105
+     * @param string $ocName the username as used in Nextcloud
106
+     * @throws \Exception
107
+     * @return true
108
+     */
109
+    protected function confirmUserIsMapped($ocName) {
110
+        $dn = $this->mapping->getDNByName($ocName);
111
+        if ($dn === false) {
112
+            throw new \Exception('The given user is not a recognized LDAP user.');
113
+        }
114
+
115
+        return true;
116
+    }
117
+
118
+    /**
119
+     * checks whether the setup allows reliable checking of LDAP user existence
120
+     * @throws \Exception
121
+     * @return true
122
+     */
123
+    protected function isAllowed($force) {
124
+        if($this->helper->haveDisabledConfigurations() && !$force) {
125
+            throw new \Exception('Cannot check user existence, because '
126
+                . 'disabled LDAP configurations are present.');
127
+        }
128
+
129
+        // we don't check ldapUserCleanupInterval from config.php because this
130
+        // action is triggered manually, while the setting only controls the
131
+        // background job.
132
+
133
+        return true;
134
+    }
135 135
 
136 136
 }
Please login to merge, or discard this patch.
apps/user_ldap/lib/LogWrapper.php 1 patch
Indentation   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -28,13 +28,13 @@
 block discarded – undo
28 28
  * @brief wraps around static Nextcloud core methods
29 29
  */
30 30
 class LogWrapper {
31
-	protected $app = 'user_ldap';
31
+    protected $app = 'user_ldap';
32 32
 
33
-	/**
34
-	 * @brief states whether the filesystem was loaded
35
-	 * @return bool
36
-	 */
37
-	public function log($msg, $level) {
38
-		\OCP\Util::writeLog($this->app, $msg, $level);
39
-	}
33
+    /**
34
+     * @brief states whether the filesystem was loaded
35
+     * @return bool
36
+     */
37
+    public function log($msg, $level) {
38
+        \OCP\Util::writeLog($this->app, $msg, $level);
39
+    }
40 40
 }
Please login to merge, or discard this patch.
apps/user_ldap/lib/FilesystemHelper.php 1 patch
Indentation   +14 added lines, -14 removed lines patch added patch discarded remove patch
@@ -29,19 +29,19 @@
 block discarded – undo
29 29
  */
30 30
 class FilesystemHelper {
31 31
 
32
-	/**
33
-	 * @brief states whether the filesystem was loaded
34
-	 * @return bool
35
-	 */
36
-	public function isLoaded() {
37
-		return \OC\Files\Filesystem::$loaded;
38
-	}
32
+    /**
33
+     * @brief states whether the filesystem was loaded
34
+     * @return bool
35
+     */
36
+    public function isLoaded() {
37
+        return \OC\Files\Filesystem::$loaded;
38
+    }
39 39
 
40
-	/**
41
-	 * @brief initializes the filesystem for the given user
42
-	 * @param string $uid the Nextcloud username of the user
43
-	 */
44
-	public function setup($uid) {
45
-		\OC_Util::setupFS($uid);
46
-	}
40
+    /**
41
+     * @brief initializes the filesystem for the given user
42
+     * @param string $uid the Nextcloud username of the user
43
+     */
44
+    public function setup($uid) {
45
+        \OC_Util::setupFS($uid);
46
+    }
47 47
 }
Please login to merge, or discard this patch.
apps/user_ldap/lib/User/OfflineUser.php 1 patch
Indentation   +193 added lines, -193 removed lines patch added patch discarded remove patch
@@ -27,205 +27,205 @@
 block discarded – undo
27 27
 use OCA\User_LDAP\Mapping\UserMapping;
28 28
 
29 29
 class OfflineUser {
30
-	/**
31
-	 * @var string $ocName
32
-	 */
33
-	protected $ocName;
34
-	/**
35
-	 * @var string $dn
36
-	 */
37
-	protected $dn;
38
-	/**
39
-	 * @var string $uid the UID as provided by LDAP
40
-	 */
41
-	protected $uid;
42
-	/**
43
-	 * @var string $displayName
44
-	 */
45
-	protected $displayName;
46
-	/**
47
-	 * @var string $homePath
48
-	 */
49
-	protected $homePath;
50
-	/**
51
-	 * @var string $lastLogin the timestamp of the last login
52
-	 */
53
-	protected $lastLogin;
54
-	/**
55
-	 * @var string $email
56
-	 */
57
-	protected $email;
58
-	/**
59
-	 * @var bool $hasActiveShares
60
-	 */
61
-	protected $hasActiveShares;
62
-	/**
63
-	 * @var \OCP\IConfig $config
64
-	 */
65
-	protected $config;
66
-	/**
67
-	 * @var \OCP\IDBConnection $db
68
-	 */
69
-	protected $db;
70
-	/**
71
-	 * @var \OCA\User_LDAP\Mapping\UserMapping
72
-	 */
73
-	protected $mapping;
74
-
75
-	/**
76
-	 * @param string $ocName
77
-	 * @param \OCP\IConfig $config
78
-	 * @param \OCP\IDBConnection $db
79
-	 * @param \OCA\User_LDAP\Mapping\UserMapping $mapping
80
-	 */
81
-	public function __construct($ocName, \OCP\IConfig $config, \OCP\IDBConnection $db, UserMapping $mapping) {
82
-		$this->ocName = $ocName;
83
-		$this->config = $config;
84
-		$this->db = $db;
85
-		$this->mapping = $mapping;
86
-		$this->fetchDetails();
87
-	}
88
-
89
-	/**
90
-	 * remove the Delete-flag from the user.
91
-	 */
92
-	public function unmark() {
93
-		$this->config->setUserValue($this->ocName, 'user_ldap', 'isDeleted', '0');
94
-	}
95
-
96
-	/**
97
-	 * exports the user details in an assoc array
98
-	 * @return array
99
-	 */
100
-	public function export() {
101
-		$data = array();
102
-		$data['ocName'] = $this->getOCName();
103
-		$data['dn'] = $this->getDN();
104
-		$data['uid'] = $this->getUID();
105
-		$data['displayName'] = $this->getDisplayName();
106
-		$data['homePath'] = $this->getHomePath();
107
-		$data['lastLogin'] = $this->getLastLogin();
108
-		$data['email'] = $this->getEmail();
109
-		$data['hasActiveShares'] = $this->getHasActiveShares();
110
-
111
-		return $data;
112
-	}
113
-
114
-	/**
115
-	 * getter for Nextcloud internal name
116
-	 * @return string
117
-	 */
118
-	public function getOCName() {
119
-		return $this->ocName;
120
-	}
121
-
122
-	/**
123
-	 * getter for LDAP uid
124
-	 * @return string
125
-	 */
126
-	public function getUID() {
127
-		return $this->uid;
128
-	}
129
-
130
-	/**
131
-	 * getter for LDAP DN
132
-	 * @return string
133
-	 */
134
-	public function getDN() {
135
-		return $this->dn;
136
-	}
137
-
138
-	/**
139
-	 * getter for display name
140
-	 * @return string
141
-	 */
142
-	public function getDisplayName() {
143
-		return $this->displayName;
144
-	}
145
-
146
-	/**
147
-	 * getter for email
148
-	 * @return string
149
-	 */
150
-	public function getEmail() {
151
-		return $this->email;
152
-	}
153
-
154
-	/**
155
-	 * getter for home directory path
156
-	 * @return string
157
-	 */
158
-	public function getHomePath() {
159
-		return $this->homePath;
160
-	}
161
-
162
-	/**
163
-	 * getter for the last login timestamp
164
-	 * @return int
165
-	 */
166
-	public function getLastLogin() {
167
-		return intval($this->lastLogin);
168
-	}
169
-
170
-	/**
171
-	 * getter for having active shares
172
-	 * @return bool
173
-	 */
174
-	public function getHasActiveShares() {
175
-		return $this->hasActiveShares;
176
-	}
177
-
178
-	/**
179
-	 * reads the user details
180
-	 */
181
-	protected function fetchDetails() {
182
-		$properties = array (
183
-			'displayName' => 'user_ldap',
184
-			'uid'         => 'user_ldap',
185
-			'homePath'    => 'user_ldap',
186
-			'email'       => 'settings',
187
-			'lastLogin'   => 'login'
188
-		);
189
-		foreach($properties as $property => $app) {
190
-			$this->$property = $this->config->getUserValue($this->ocName, $app, $property, '');
191
-		}
192
-
193
-		$dn = $this->mapping->getDNByName($this->ocName);
194
-		$this->dn = ($dn !== false) ? $dn : '';
195
-
196
-		$this->determineShares();
197
-	}
198
-
199
-
200
-	/**
201
-	 * finds out whether the user has active shares. The result is stored in
202
-	 * $this->hasActiveShares
203
-	 */
204
-	protected function determineShares() {
205
-		$query = $this->db->prepare('
30
+    /**
31
+     * @var string $ocName
32
+     */
33
+    protected $ocName;
34
+    /**
35
+     * @var string $dn
36
+     */
37
+    protected $dn;
38
+    /**
39
+     * @var string $uid the UID as provided by LDAP
40
+     */
41
+    protected $uid;
42
+    /**
43
+     * @var string $displayName
44
+     */
45
+    protected $displayName;
46
+    /**
47
+     * @var string $homePath
48
+     */
49
+    protected $homePath;
50
+    /**
51
+     * @var string $lastLogin the timestamp of the last login
52
+     */
53
+    protected $lastLogin;
54
+    /**
55
+     * @var string $email
56
+     */
57
+    protected $email;
58
+    /**
59
+     * @var bool $hasActiveShares
60
+     */
61
+    protected $hasActiveShares;
62
+    /**
63
+     * @var \OCP\IConfig $config
64
+     */
65
+    protected $config;
66
+    /**
67
+     * @var \OCP\IDBConnection $db
68
+     */
69
+    protected $db;
70
+    /**
71
+     * @var \OCA\User_LDAP\Mapping\UserMapping
72
+     */
73
+    protected $mapping;
74
+
75
+    /**
76
+     * @param string $ocName
77
+     * @param \OCP\IConfig $config
78
+     * @param \OCP\IDBConnection $db
79
+     * @param \OCA\User_LDAP\Mapping\UserMapping $mapping
80
+     */
81
+    public function __construct($ocName, \OCP\IConfig $config, \OCP\IDBConnection $db, UserMapping $mapping) {
82
+        $this->ocName = $ocName;
83
+        $this->config = $config;
84
+        $this->db = $db;
85
+        $this->mapping = $mapping;
86
+        $this->fetchDetails();
87
+    }
88
+
89
+    /**
90
+     * remove the Delete-flag from the user.
91
+     */
92
+    public function unmark() {
93
+        $this->config->setUserValue($this->ocName, 'user_ldap', 'isDeleted', '0');
94
+    }
95
+
96
+    /**
97
+     * exports the user details in an assoc array
98
+     * @return array
99
+     */
100
+    public function export() {
101
+        $data = array();
102
+        $data['ocName'] = $this->getOCName();
103
+        $data['dn'] = $this->getDN();
104
+        $data['uid'] = $this->getUID();
105
+        $data['displayName'] = $this->getDisplayName();
106
+        $data['homePath'] = $this->getHomePath();
107
+        $data['lastLogin'] = $this->getLastLogin();
108
+        $data['email'] = $this->getEmail();
109
+        $data['hasActiveShares'] = $this->getHasActiveShares();
110
+
111
+        return $data;
112
+    }
113
+
114
+    /**
115
+     * getter for Nextcloud internal name
116
+     * @return string
117
+     */
118
+    public function getOCName() {
119
+        return $this->ocName;
120
+    }
121
+
122
+    /**
123
+     * getter for LDAP uid
124
+     * @return string
125
+     */
126
+    public function getUID() {
127
+        return $this->uid;
128
+    }
129
+
130
+    /**
131
+     * getter for LDAP DN
132
+     * @return string
133
+     */
134
+    public function getDN() {
135
+        return $this->dn;
136
+    }
137
+
138
+    /**
139
+     * getter for display name
140
+     * @return string
141
+     */
142
+    public function getDisplayName() {
143
+        return $this->displayName;
144
+    }
145
+
146
+    /**
147
+     * getter for email
148
+     * @return string
149
+     */
150
+    public function getEmail() {
151
+        return $this->email;
152
+    }
153
+
154
+    /**
155
+     * getter for home directory path
156
+     * @return string
157
+     */
158
+    public function getHomePath() {
159
+        return $this->homePath;
160
+    }
161
+
162
+    /**
163
+     * getter for the last login timestamp
164
+     * @return int
165
+     */
166
+    public function getLastLogin() {
167
+        return intval($this->lastLogin);
168
+    }
169
+
170
+    /**
171
+     * getter for having active shares
172
+     * @return bool
173
+     */
174
+    public function getHasActiveShares() {
175
+        return $this->hasActiveShares;
176
+    }
177
+
178
+    /**
179
+     * reads the user details
180
+     */
181
+    protected function fetchDetails() {
182
+        $properties = array (
183
+            'displayName' => 'user_ldap',
184
+            'uid'         => 'user_ldap',
185
+            'homePath'    => 'user_ldap',
186
+            'email'       => 'settings',
187
+            'lastLogin'   => 'login'
188
+        );
189
+        foreach($properties as $property => $app) {
190
+            $this->$property = $this->config->getUserValue($this->ocName, $app, $property, '');
191
+        }
192
+
193
+        $dn = $this->mapping->getDNByName($this->ocName);
194
+        $this->dn = ($dn !== false) ? $dn : '';
195
+
196
+        $this->determineShares();
197
+    }
198
+
199
+
200
+    /**
201
+     * finds out whether the user has active shares. The result is stored in
202
+     * $this->hasActiveShares
203
+     */
204
+    protected function determineShares() {
205
+        $query = $this->db->prepare('
206 206
 			SELECT COUNT(`uid_owner`)
207 207
 			FROM `*PREFIX*share`
208 208
 			WHERE `uid_owner` = ?
209 209
 		', 1);
210
-		$query->execute(array($this->ocName));
211
-		$sResult = $query->fetchColumn(0);
212
-		if(intval($sResult) === 1) {
213
-			$this->hasActiveShares = true;
214
-			return;
215
-		}
216
-
217
-		$query = $this->db->prepare('
210
+        $query->execute(array($this->ocName));
211
+        $sResult = $query->fetchColumn(0);
212
+        if(intval($sResult) === 1) {
213
+            $this->hasActiveShares = true;
214
+            return;
215
+        }
216
+
217
+        $query = $this->db->prepare('
218 218
 			SELECT COUNT(`owner`)
219 219
 			FROM `*PREFIX*share_external`
220 220
 			WHERE `owner` = ?
221 221
 		', 1);
222
-		$query->execute(array($this->ocName));
223
-		$sResult = $query->fetchColumn(0);
224
-		if(intval($sResult) === 1) {
225
-			$this->hasActiveShares = true;
226
-			return;
227
-		}
228
-
229
-		$this->hasActiveShares = false;
230
-	}
222
+        $query->execute(array($this->ocName));
223
+        $sResult = $query->fetchColumn(0);
224
+        if(intval($sResult) === 1) {
225
+            $this->hasActiveShares = true;
226
+            return;
227
+        }
228
+
229
+        $this->hasActiveShares = false;
230
+    }
231 231
 }
Please login to merge, or discard this patch.
apps/user_ldap/lib/User/User.php 1 patch
Indentation   +545 added lines, -545 removed lines patch added patch discarded remove patch
@@ -41,550 +41,550 @@
 block discarded – undo
41 41
  * represents an LDAP user, gets and holds user-specific information from LDAP
42 42
  */
43 43
 class User {
44
-	/**
45
-	 * @var IUserTools
46
-	 */
47
-	protected $access;
48
-	/**
49
-	 * @var Connection
50
-	 */
51
-	protected $connection;
52
-	/**
53
-	 * @var IConfig
54
-	 */
55
-	protected $config;
56
-	/**
57
-	 * @var FilesystemHelper
58
-	 */
59
-	protected $fs;
60
-	/**
61
-	 * @var Image
62
-	 */
63
-	protected $image;
64
-	/**
65
-	 * @var LogWrapper
66
-	 */
67
-	protected $log;
68
-	/**
69
-	 * @var IAvatarManager
70
-	 */
71
-	protected $avatarManager;
72
-	/**
73
-	 * @var IUserManager
74
-	 */
75
-	protected $userManager;
76
-	/**
77
-	 * @var string
78
-	 */
79
-	protected $dn;
80
-	/**
81
-	 * @var string
82
-	 */
83
-	protected $uid;
84
-	/**
85
-	 * @var string[]
86
-	 */
87
-	protected $refreshedFeatures = array();
88
-	/**
89
-	 * @var string
90
-	 */
91
-	protected $avatarImage;
92
-
93
-	/**
94
-	 * DB config keys for user preferences
95
-	 */
96
-	const USER_PREFKEY_FIRSTLOGIN  = 'firstLoginAccomplished';
97
-	const USER_PREFKEY_LASTREFRESH = 'lastFeatureRefresh';
98
-
99
-	/**
100
-	 * @brief constructor, make sure the subclasses call this one!
101
-	 * @param string $username the internal username
102
-	 * @param string $dn the LDAP DN
103
-	 * @param IUserTools $access an instance that implements IUserTools for
104
-	 * LDAP interaction
105
-	 * @param IConfig $config
106
-	 * @param FilesystemHelper $fs
107
-	 * @param Image $image any empty instance
108
-	 * @param LogWrapper $log
109
-	 * @param IAvatarManager $avatarManager
110
-	 * @param IUserManager $userManager
111
-	 */
112
-	public function __construct($username, $dn, IUserTools $access,
113
-		IConfig $config, FilesystemHelper $fs, Image $image,
114
-		LogWrapper $log, IAvatarManager $avatarManager, IUserManager $userManager) {
115
-
116
-		if ($username === null) {
117
-			$log->log("uid for '$dn' must not be null!", Util::ERROR);
118
-			throw new \InvalidArgumentException('uid must not be null!');
119
-		} else if ($username === '') {
120
-			$log->log("uid for '$dn' must not be an empty string", Util::ERROR);
121
-			throw new \InvalidArgumentException('uid must not be an empty string!');
122
-		}
123
-
124
-		$this->access        = $access;
125
-		$this->connection    = $access->getConnection();
126
-		$this->config        = $config;
127
-		$this->fs            = $fs;
128
-		$this->dn            = $dn;
129
-		$this->uid           = $username;
130
-		$this->image         = $image;
131
-		$this->log           = $log;
132
-		$this->avatarManager = $avatarManager;
133
-		$this->userManager   = $userManager;
134
-	}
135
-
136
-	/**
137
-	 * @brief updates properties like email, quota or avatar provided by LDAP
138
-	 * @return null
139
-	 */
140
-	public function update() {
141
-		if(is_null($this->dn)) {
142
-			return null;
143
-		}
144
-
145
-		$hasLoggedIn = $this->config->getUserValue($this->uid, 'user_ldap',
146
-				self::USER_PREFKEY_FIRSTLOGIN, 0);
147
-
148
-		if($this->needsRefresh()) {
149
-			$this->updateEmail();
150
-			$this->updateQuota();
151
-			if($hasLoggedIn !== 0) {
152
-				//we do not need to try it, when the user has not been logged in
153
-				//before, because the file system will not be ready.
154
-				$this->updateAvatar();
155
-				//in order to get an avatar as soon as possible, mark the user
156
-				//as refreshed only when updating the avatar did happen
157
-				$this->markRefreshTime();
158
-			}
159
-		}
160
-	}
161
-
162
-	/**
163
-	 * processes results from LDAP for attributes as returned by getAttributesToRead()
164
-	 * @param array $ldapEntry the user entry as retrieved from LDAP
165
-	 */
166
-	public function processAttributes($ldapEntry) {
167
-		$this->markRefreshTime();
168
-		//Quota
169
-		$attr = strtolower($this->connection->ldapQuotaAttribute);
170
-		if(isset($ldapEntry[$attr])) {
171
-			$this->updateQuota($ldapEntry[$attr][0]);
172
-		} else {
173
-			if ($this->connection->ldapQuotaDefault !== '') {
174
-				$this->updateQuota();
175
-			}
176
-		}
177
-		unset($attr);
178
-
179
-		//Email
180
-		$attr = strtolower($this->connection->ldapEmailAttribute);
181
-		if(isset($ldapEntry[$attr])) {
182
-			$this->updateEmail($ldapEntry[$attr][0]);
183
-		}
184
-		unset($attr);
185
-
186
-		//displayName
187
-		$displayName = $displayName2 = '';
188
-		$attr = strtolower($this->connection->ldapUserDisplayName);
189
-		if(isset($ldapEntry[$attr])) {
190
-			$displayName = strval($ldapEntry[$attr][0]);
191
-		}
192
-		$attr = strtolower($this->connection->ldapUserDisplayName2);
193
-		if(isset($ldapEntry[$attr])) {
194
-			$displayName2 = strval($ldapEntry[$attr][0]);
195
-		}
196
-		if ($displayName !== '') {
197
-			$this->composeAndStoreDisplayName($displayName);
198
-			$this->access->cacheUserDisplayName(
199
-				$this->getUsername(),
200
-				$displayName,
201
-				$displayName2
202
-			);
203
-		}
204
-		unset($attr);
205
-
206
-		// LDAP Username, needed for s2s sharing
207
-		if(isset($ldapEntry['uid'])) {
208
-			$this->storeLDAPUserName($ldapEntry['uid'][0]);
209
-		} else if(isset($ldapEntry['samaccountname'])) {
210
-			$this->storeLDAPUserName($ldapEntry['samaccountname'][0]);
211
-		}
212
-
213
-		//homePath
214
-		if(strpos($this->connection->homeFolderNamingRule, 'attr:') === 0) {
215
-			$attr = strtolower(substr($this->connection->homeFolderNamingRule, strlen('attr:')));
216
-			if(isset($ldapEntry[$attr])) {
217
-				$this->access->cacheUserHome(
218
-					$this->getUsername(), $this->getHomePath($ldapEntry[$attr][0]));
219
-			}
220
-		}
221
-
222
-		//memberOf groups
223
-		$cacheKey = 'getMemberOf'.$this->getUsername();
224
-		$groups = false;
225
-		if(isset($ldapEntry['memberof'])) {
226
-			$groups = $ldapEntry['memberof'];
227
-		}
228
-		$this->connection->writeToCache($cacheKey, $groups);
229
-
230
-		//Avatar
231
-		$attrs = array('jpegphoto', 'thumbnailphoto');
232
-		foreach ($attrs as $attr)  {
233
-			if(isset($ldapEntry[$attr])) {
234
-				$this->avatarImage = $ldapEntry[$attr][0];
235
-				// the call to the method that saves the avatar in the file
236
-				// system must be postponed after the login. It is to ensure
237
-				// external mounts are mounted properly (e.g. with login
238
-				// credentials from the session).
239
-				\OCP\Util::connectHook('OC_User', 'post_login', $this, 'updateAvatarPostLogin');
240
-				break;
241
-			}
242
-		}
243
-	}
244
-
245
-	/**
246
-	 * @brief returns the LDAP DN of the user
247
-	 * @return string
248
-	 */
249
-	public function getDN() {
250
-		return $this->dn;
251
-	}
252
-
253
-	/**
254
-	 * @brief returns the Nextcloud internal username of the user
255
-	 * @return string
256
-	 */
257
-	public function getUsername() {
258
-		return $this->uid;
259
-	}
260
-
261
-	/**
262
-	 * returns the home directory of the user if specified by LDAP settings
263
-	 * @param string $valueFromLDAP
264
-	 * @return bool|string
265
-	 * @throws \Exception
266
-	 */
267
-	public function getHomePath($valueFromLDAP = null) {
268
-		$path = strval($valueFromLDAP);
269
-		$attr = null;
270
-
271
-		if (is_null($valueFromLDAP)
272
-		   && strpos($this->access->connection->homeFolderNamingRule, 'attr:') === 0
273
-		   && $this->access->connection->homeFolderNamingRule !== 'attr:')
274
-		{
275
-			$attr = substr($this->access->connection->homeFolderNamingRule, strlen('attr:'));
276
-			$homedir = $this->access->readAttribute(
277
-				$this->access->username2dn($this->getUsername()), $attr);
278
-			if ($homedir && isset($homedir[0])) {
279
-				$path = $homedir[0];
280
-			}
281
-		}
282
-
283
-		if ($path !== '') {
284
-			//if attribute's value is an absolute path take this, otherwise append it to data dir
285
-			//check for / at the beginning or pattern c:\ resp. c:/
286
-			if(   '/' !== $path[0]
287
-			   && !(3 < strlen($path) && ctype_alpha($path[0])
288
-			       && $path[1] === ':' && ('\\' === $path[2] || '/' === $path[2]))
289
-			) {
290
-				$path = $this->config->getSystemValue('datadirectory',
291
-						\OC::$SERVERROOT.'/data' ) . '/' . $path;
292
-			}
293
-			//we need it to store it in the DB as well in case a user gets
294
-			//deleted so we can clean up afterwards
295
-			$this->config->setUserValue(
296
-				$this->getUsername(), 'user_ldap', 'homePath', $path
297
-			);
298
-			return $path;
299
-		}
300
-
301
-		if(    !is_null($attr)
302
-			&& $this->config->getAppValue('user_ldap', 'enforce_home_folder_naming_rule', true)
303
-		) {
304
-			// a naming rule attribute is defined, but it doesn't exist for that LDAP user
305
-			throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: ' . $this->getUsername());
306
-		}
307
-
308
-		//false will apply default behaviour as defined and done by OC_User
309
-		$this->config->setUserValue($this->getUsername(), 'user_ldap', 'homePath', '');
310
-		return false;
311
-	}
312
-
313
-	public function getMemberOfGroups() {
314
-		$cacheKey = 'getMemberOf'.$this->getUsername();
315
-		$memberOfGroups = $this->connection->getFromCache($cacheKey);
316
-		if(!is_null($memberOfGroups)) {
317
-			return $memberOfGroups;
318
-		}
319
-		$groupDNs = $this->access->readAttribute($this->getDN(), 'memberOf');
320
-		$this->connection->writeToCache($cacheKey, $groupDNs);
321
-		return $groupDNs;
322
-	}
323
-
324
-	/**
325
-	 * @brief reads the image from LDAP that shall be used as Avatar
326
-	 * @return string data (provided by LDAP) | false
327
-	 */
328
-	public function getAvatarImage() {
329
-		if(!is_null($this->avatarImage)) {
330
-			return $this->avatarImage;
331
-		}
332
-
333
-		$this->avatarImage = false;
334
-		$attributes = array('jpegPhoto', 'thumbnailPhoto');
335
-		foreach($attributes as $attribute) {
336
-			$result = $this->access->readAttribute($this->dn, $attribute);
337
-			if($result !== false && is_array($result) && isset($result[0])) {
338
-				$this->avatarImage = $result[0];
339
-				break;
340
-			}
341
-		}
342
-
343
-		return $this->avatarImage;
344
-	}
345
-
346
-	/**
347
-	 * @brief marks the user as having logged in at least once
348
-	 * @return null
349
-	 */
350
-	public function markLogin() {
351
-		$this->config->setUserValue(
352
-			$this->uid, 'user_ldap', self::USER_PREFKEY_FIRSTLOGIN, 1);
353
-	}
354
-
355
-	/**
356
-	 * @brief marks the time when user features like email have been updated
357
-	 * @return null
358
-	 */
359
-	public function markRefreshTime() {
360
-		$this->config->setUserValue(
361
-			$this->uid, 'user_ldap', self::USER_PREFKEY_LASTREFRESH, time());
362
-	}
363
-
364
-	/**
365
-	 * @brief checks whether user features needs to be updated again by
366
-	 * comparing the difference of time of the last refresh to now with the
367
-	 * desired interval
368
-	 * @return bool
369
-	 */
370
-	private function needsRefresh() {
371
-		$lastChecked = $this->config->getUserValue($this->uid, 'user_ldap',
372
-			self::USER_PREFKEY_LASTREFRESH, 0);
373
-
374
-		//TODO make interval configurable
375
-		if((time() - intval($lastChecked)) < 86400 ) {
376
-			return false;
377
-		}
378
-		return  true;
379
-	}
380
-
381
-	/**
382
-	 * Stores a key-value pair in relation to this user
383
-	 *
384
-	 * @param string $key
385
-	 * @param string $value
386
-	 */
387
-	private function store($key, $value) {
388
-		$this->config->setUserValue($this->uid, 'user_ldap', $key, $value);
389
-	}
390
-
391
-	/**
392
-	 * Composes the display name and stores it in the database. The final
393
-	 * display name is returned.
394
-	 *
395
-	 * @param string $displayName
396
-	 * @param string $displayName2
397
-	 * @returns string the effective display name
398
-	 */
399
-	public function composeAndStoreDisplayName($displayName, $displayName2 = '') {
400
-		$displayName2 = strval($displayName2);
401
-		if($displayName2 !== '') {
402
-			$displayName .= ' (' . $displayName2 . ')';
403
-		}
404
-		$this->store('displayName', $displayName);
405
-		return $displayName;
406
-	}
407
-
408
-	/**
409
-	 * Stores the LDAP Username in the Database
410
-	 * @param string $userName
411
-	 */
412
-	public function storeLDAPUserName($userName) {
413
-		$this->store('uid', $userName);
414
-	}
415
-
416
-	/**
417
-	 * @brief checks whether an update method specified by feature was run
418
-	 * already. If not, it will marked like this, because it is expected that
419
-	 * the method will be run, when false is returned.
420
-	 * @param string $feature email | quota | avatar (can be extended)
421
-	 * @return bool
422
-	 */
423
-	private function wasRefreshed($feature) {
424
-		if(isset($this->refreshedFeatures[$feature])) {
425
-			return true;
426
-		}
427
-		$this->refreshedFeatures[$feature] = 1;
428
-		return false;
429
-	}
430
-
431
-	/**
432
-	 * fetches the email from LDAP and stores it as Nextcloud user value
433
-	 * @param string $valueFromLDAP if known, to save an LDAP read request
434
-	 * @return null
435
-	 */
436
-	public function updateEmail($valueFromLDAP = null) {
437
-		if($this->wasRefreshed('email')) {
438
-			return;
439
-		}
440
-		$email = strval($valueFromLDAP);
441
-		if(is_null($valueFromLDAP)) {
442
-			$emailAttribute = $this->connection->ldapEmailAttribute;
443
-			if ($emailAttribute !== '') {
444
-				$aEmail = $this->access->readAttribute($this->dn, $emailAttribute);
445
-				if(is_array($aEmail) && (count($aEmail) > 0)) {
446
-					$email = strval($aEmail[0]);
447
-				}
448
-			}
449
-		}
450
-		if ($email !== '') {
451
-			$user = $this->userManager->get($this->uid);
452
-			if (!is_null($user)) {
453
-				$currentEmail = strval($user->getEMailAddress());
454
-				if ($currentEmail !== $email) {
455
-					$user->setEMailAddress($email);
456
-				}
457
-			}
458
-		}
459
-	}
460
-
461
-	/**
462
-	 * Overall process goes as follow:
463
-	 * 1. fetch the quota from LDAP and check if it's parseable with the "verifyQuotaValue" function
464
-	 * 2. if the value can't be fetched, is empty or not parseable, use the default LDAP quota
465
-	 * 3. if the default LDAP quota can't be parsed, use the Nextcloud's default quota (use 'default')
466
-	 * 4. check if the target user exists and set the quota for the user.
467
-	 *
468
-	 * In order to improve performance and prevent an unwanted extra LDAP call, the $valueFromLDAP
469
-	 * parameter can be passed with the value of the attribute. This value will be considered as the
470
-	 * quota for the user coming from the LDAP server (step 1 of the process) It can be useful to
471
-	 * fetch all the user's attributes in one call and use the fetched values in this function.
472
-	 * The expected value for that parameter is a string describing the quota for the user. Valid
473
-	 * values are 'none' (unlimited), 'default' (the Nextcloud's default quota), '1234' (quota in
474
-	 * bytes), '1234 MB' (quota in MB - check the \OC_Helper::computerFileSize method for more info)
475
-	 *
476
-	 * fetches the quota from LDAP and stores it as Nextcloud user value
477
-	 * @param string $valueFromLDAP the quota attribute's value can be passed,
478
-	 * to save the readAttribute request
479
-	 * @return null
480
-	 */
481
-	public function updateQuota($valueFromLDAP = null) {
482
-		if($this->wasRefreshed('quota')) {
483
-			return;
484
-		}
485
-
486
-		$quota = false;
487
-		if(is_null($valueFromLDAP)) {
488
-			$quotaAttribute = $this->connection->ldapQuotaAttribute;
489
-			if ($quotaAttribute !== '') {
490
-				$aQuota = $this->access->readAttribute($this->dn, $quotaAttribute);
491
-				if($aQuota && (count($aQuota) > 0)) {
492
-					if ($this->verifyQuotaValue($aQuota[0])) {
493
-						$quota = $aQuota[0];
494
-					} else {
495
-						$this->log->log('not suitable LDAP quota found for user ' . $this->uid . ': [' . $aQuota[0] . ']', \OCP\Util::WARN);
496
-					}
497
-				}
498
-			}
499
-		} else {
500
-			if ($this->verifyQuotaValue($valueFromLDAP)) {
501
-				$quota = $valueFromLDAP;
502
-			} else {
503
-				$this->log->log('not suitable LDAP quota found for user ' . $this->uid . ': [' . $valueFromLDAP . ']', \OCP\Util::WARN);
504
-			}
505
-		}
506
-
507
-		if ($quota === false) {
508
-			// quota not found using the LDAP attribute (or not parseable). Try the default quota
509
-			$defaultQuota = $this->connection->ldapQuotaDefault;
510
-			if ($this->verifyQuotaValue($defaultQuota)) {
511
-				$quota = $defaultQuota;
512
-			}
513
-		}
514
-
515
-		$targetUser = $this->userManager->get($this->uid);
516
-		if ($targetUser) {
517
-			if($quota !== false) {
518
-				$targetUser->setQuota($quota);
519
-			} else {
520
-				$this->log->log('not suitable default quota found for user ' . $this->uid . ': [' . $defaultQuota . ']', \OCP\Util::WARN);
521
-				$targetUser->setQuota('default');
522
-			}
523
-		} else {
524
-			$this->log->log('trying to set a quota for user ' . $this->uid . ' but the user is missing', \OCP\Util::ERROR);
525
-		}
526
-	}
527
-
528
-	private function verifyQuotaValue($quotaValue) {
529
-		return $quotaValue === 'none' || $quotaValue === 'default' || \OC_Helper::computerFileSize($quotaValue) !== false;
530
-	}
531
-
532
-	/**
533
-	 * called by a post_login hook to save the avatar picture
534
-	 *
535
-	 * @param array $params
536
-	 */
537
-	public function updateAvatarPostLogin($params) {
538
-		if(isset($params['uid']) && $params['uid'] === $this->getUsername()) {
539
-			$this->updateAvatar();
540
-		}
541
-	}
542
-
543
-	/**
544
-	 * @brief attempts to get an image from LDAP and sets it as Nextcloud avatar
545
-	 * @return null
546
-	 */
547
-	public function updateAvatar() {
548
-		if($this->wasRefreshed('avatar')) {
549
-			return;
550
-		}
551
-		$avatarImage = $this->getAvatarImage();
552
-		if($avatarImage === false) {
553
-			//not set, nothing left to do;
554
-			return;
555
-		}
556
-		$this->image->loadFromBase64(base64_encode($avatarImage));
557
-		$this->setOwnCloudAvatar();
558
-	}
559
-
560
-	/**
561
-	 * @brief sets an image as Nextcloud avatar
562
-	 * @return null
563
-	 */
564
-	private function setOwnCloudAvatar() {
565
-		if(!$this->image->valid()) {
566
-			$this->log->log('jpegPhoto data invalid for '.$this->dn, \OCP\Util::ERROR);
567
-			return;
568
-		}
569
-		//make sure it is a square and not bigger than 128x128
570
-		$size = min(array($this->image->width(), $this->image->height(), 128));
571
-		if(!$this->image->centerCrop($size)) {
572
-			$this->log->log('croping image for avatar failed for '.$this->dn, \OCP\Util::ERROR);
573
-			return;
574
-		}
575
-
576
-		if(!$this->fs->isLoaded()) {
577
-			$this->fs->setup($this->uid);
578
-		}
579
-
580
-		try {
581
-			$avatar = $this->avatarManager->getAvatar($this->uid);
582
-			$avatar->set($this->image);
583
-		} catch (\Exception $e) {
584
-			\OC::$server->getLogger()->notice(
585
-				'Could not set avatar for ' . $this->dn	. ', because: ' . $e->getMessage(),
586
-				['app' => 'user_ldap']);
587
-		}
588
-	}
44
+    /**
45
+     * @var IUserTools
46
+     */
47
+    protected $access;
48
+    /**
49
+     * @var Connection
50
+     */
51
+    protected $connection;
52
+    /**
53
+     * @var IConfig
54
+     */
55
+    protected $config;
56
+    /**
57
+     * @var FilesystemHelper
58
+     */
59
+    protected $fs;
60
+    /**
61
+     * @var Image
62
+     */
63
+    protected $image;
64
+    /**
65
+     * @var LogWrapper
66
+     */
67
+    protected $log;
68
+    /**
69
+     * @var IAvatarManager
70
+     */
71
+    protected $avatarManager;
72
+    /**
73
+     * @var IUserManager
74
+     */
75
+    protected $userManager;
76
+    /**
77
+     * @var string
78
+     */
79
+    protected $dn;
80
+    /**
81
+     * @var string
82
+     */
83
+    protected $uid;
84
+    /**
85
+     * @var string[]
86
+     */
87
+    protected $refreshedFeatures = array();
88
+    /**
89
+     * @var string
90
+     */
91
+    protected $avatarImage;
92
+
93
+    /**
94
+     * DB config keys for user preferences
95
+     */
96
+    const USER_PREFKEY_FIRSTLOGIN  = 'firstLoginAccomplished';
97
+    const USER_PREFKEY_LASTREFRESH = 'lastFeatureRefresh';
98
+
99
+    /**
100
+     * @brief constructor, make sure the subclasses call this one!
101
+     * @param string $username the internal username
102
+     * @param string $dn the LDAP DN
103
+     * @param IUserTools $access an instance that implements IUserTools for
104
+     * LDAP interaction
105
+     * @param IConfig $config
106
+     * @param FilesystemHelper $fs
107
+     * @param Image $image any empty instance
108
+     * @param LogWrapper $log
109
+     * @param IAvatarManager $avatarManager
110
+     * @param IUserManager $userManager
111
+     */
112
+    public function __construct($username, $dn, IUserTools $access,
113
+        IConfig $config, FilesystemHelper $fs, Image $image,
114
+        LogWrapper $log, IAvatarManager $avatarManager, IUserManager $userManager) {
115
+
116
+        if ($username === null) {
117
+            $log->log("uid for '$dn' must not be null!", Util::ERROR);
118
+            throw new \InvalidArgumentException('uid must not be null!');
119
+        } else if ($username === '') {
120
+            $log->log("uid for '$dn' must not be an empty string", Util::ERROR);
121
+            throw new \InvalidArgumentException('uid must not be an empty string!');
122
+        }
123
+
124
+        $this->access        = $access;
125
+        $this->connection    = $access->getConnection();
126
+        $this->config        = $config;
127
+        $this->fs            = $fs;
128
+        $this->dn            = $dn;
129
+        $this->uid           = $username;
130
+        $this->image         = $image;
131
+        $this->log           = $log;
132
+        $this->avatarManager = $avatarManager;
133
+        $this->userManager   = $userManager;
134
+    }
135
+
136
+    /**
137
+     * @brief updates properties like email, quota or avatar provided by LDAP
138
+     * @return null
139
+     */
140
+    public function update() {
141
+        if(is_null($this->dn)) {
142
+            return null;
143
+        }
144
+
145
+        $hasLoggedIn = $this->config->getUserValue($this->uid, 'user_ldap',
146
+                self::USER_PREFKEY_FIRSTLOGIN, 0);
147
+
148
+        if($this->needsRefresh()) {
149
+            $this->updateEmail();
150
+            $this->updateQuota();
151
+            if($hasLoggedIn !== 0) {
152
+                //we do not need to try it, when the user has not been logged in
153
+                //before, because the file system will not be ready.
154
+                $this->updateAvatar();
155
+                //in order to get an avatar as soon as possible, mark the user
156
+                //as refreshed only when updating the avatar did happen
157
+                $this->markRefreshTime();
158
+            }
159
+        }
160
+    }
161
+
162
+    /**
163
+     * processes results from LDAP for attributes as returned by getAttributesToRead()
164
+     * @param array $ldapEntry the user entry as retrieved from LDAP
165
+     */
166
+    public function processAttributes($ldapEntry) {
167
+        $this->markRefreshTime();
168
+        //Quota
169
+        $attr = strtolower($this->connection->ldapQuotaAttribute);
170
+        if(isset($ldapEntry[$attr])) {
171
+            $this->updateQuota($ldapEntry[$attr][0]);
172
+        } else {
173
+            if ($this->connection->ldapQuotaDefault !== '') {
174
+                $this->updateQuota();
175
+            }
176
+        }
177
+        unset($attr);
178
+
179
+        //Email
180
+        $attr = strtolower($this->connection->ldapEmailAttribute);
181
+        if(isset($ldapEntry[$attr])) {
182
+            $this->updateEmail($ldapEntry[$attr][0]);
183
+        }
184
+        unset($attr);
185
+
186
+        //displayName
187
+        $displayName = $displayName2 = '';
188
+        $attr = strtolower($this->connection->ldapUserDisplayName);
189
+        if(isset($ldapEntry[$attr])) {
190
+            $displayName = strval($ldapEntry[$attr][0]);
191
+        }
192
+        $attr = strtolower($this->connection->ldapUserDisplayName2);
193
+        if(isset($ldapEntry[$attr])) {
194
+            $displayName2 = strval($ldapEntry[$attr][0]);
195
+        }
196
+        if ($displayName !== '') {
197
+            $this->composeAndStoreDisplayName($displayName);
198
+            $this->access->cacheUserDisplayName(
199
+                $this->getUsername(),
200
+                $displayName,
201
+                $displayName2
202
+            );
203
+        }
204
+        unset($attr);
205
+
206
+        // LDAP Username, needed for s2s sharing
207
+        if(isset($ldapEntry['uid'])) {
208
+            $this->storeLDAPUserName($ldapEntry['uid'][0]);
209
+        } else if(isset($ldapEntry['samaccountname'])) {
210
+            $this->storeLDAPUserName($ldapEntry['samaccountname'][0]);
211
+        }
212
+
213
+        //homePath
214
+        if(strpos($this->connection->homeFolderNamingRule, 'attr:') === 0) {
215
+            $attr = strtolower(substr($this->connection->homeFolderNamingRule, strlen('attr:')));
216
+            if(isset($ldapEntry[$attr])) {
217
+                $this->access->cacheUserHome(
218
+                    $this->getUsername(), $this->getHomePath($ldapEntry[$attr][0]));
219
+            }
220
+        }
221
+
222
+        //memberOf groups
223
+        $cacheKey = 'getMemberOf'.$this->getUsername();
224
+        $groups = false;
225
+        if(isset($ldapEntry['memberof'])) {
226
+            $groups = $ldapEntry['memberof'];
227
+        }
228
+        $this->connection->writeToCache($cacheKey, $groups);
229
+
230
+        //Avatar
231
+        $attrs = array('jpegphoto', 'thumbnailphoto');
232
+        foreach ($attrs as $attr)  {
233
+            if(isset($ldapEntry[$attr])) {
234
+                $this->avatarImage = $ldapEntry[$attr][0];
235
+                // the call to the method that saves the avatar in the file
236
+                // system must be postponed after the login. It is to ensure
237
+                // external mounts are mounted properly (e.g. with login
238
+                // credentials from the session).
239
+                \OCP\Util::connectHook('OC_User', 'post_login', $this, 'updateAvatarPostLogin');
240
+                break;
241
+            }
242
+        }
243
+    }
244
+
245
+    /**
246
+     * @brief returns the LDAP DN of the user
247
+     * @return string
248
+     */
249
+    public function getDN() {
250
+        return $this->dn;
251
+    }
252
+
253
+    /**
254
+     * @brief returns the Nextcloud internal username of the user
255
+     * @return string
256
+     */
257
+    public function getUsername() {
258
+        return $this->uid;
259
+    }
260
+
261
+    /**
262
+     * returns the home directory of the user if specified by LDAP settings
263
+     * @param string $valueFromLDAP
264
+     * @return bool|string
265
+     * @throws \Exception
266
+     */
267
+    public function getHomePath($valueFromLDAP = null) {
268
+        $path = strval($valueFromLDAP);
269
+        $attr = null;
270
+
271
+        if (is_null($valueFromLDAP)
272
+           && strpos($this->access->connection->homeFolderNamingRule, 'attr:') === 0
273
+           && $this->access->connection->homeFolderNamingRule !== 'attr:')
274
+        {
275
+            $attr = substr($this->access->connection->homeFolderNamingRule, strlen('attr:'));
276
+            $homedir = $this->access->readAttribute(
277
+                $this->access->username2dn($this->getUsername()), $attr);
278
+            if ($homedir && isset($homedir[0])) {
279
+                $path = $homedir[0];
280
+            }
281
+        }
282
+
283
+        if ($path !== '') {
284
+            //if attribute's value is an absolute path take this, otherwise append it to data dir
285
+            //check for / at the beginning or pattern c:\ resp. c:/
286
+            if(   '/' !== $path[0]
287
+               && !(3 < strlen($path) && ctype_alpha($path[0])
288
+                   && $path[1] === ':' && ('\\' === $path[2] || '/' === $path[2]))
289
+            ) {
290
+                $path = $this->config->getSystemValue('datadirectory',
291
+                        \OC::$SERVERROOT.'/data' ) . '/' . $path;
292
+            }
293
+            //we need it to store it in the DB as well in case a user gets
294
+            //deleted so we can clean up afterwards
295
+            $this->config->setUserValue(
296
+                $this->getUsername(), 'user_ldap', 'homePath', $path
297
+            );
298
+            return $path;
299
+        }
300
+
301
+        if(    !is_null($attr)
302
+            && $this->config->getAppValue('user_ldap', 'enforce_home_folder_naming_rule', true)
303
+        ) {
304
+            // a naming rule attribute is defined, but it doesn't exist for that LDAP user
305
+            throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: ' . $this->getUsername());
306
+        }
307
+
308
+        //false will apply default behaviour as defined and done by OC_User
309
+        $this->config->setUserValue($this->getUsername(), 'user_ldap', 'homePath', '');
310
+        return false;
311
+    }
312
+
313
+    public function getMemberOfGroups() {
314
+        $cacheKey = 'getMemberOf'.$this->getUsername();
315
+        $memberOfGroups = $this->connection->getFromCache($cacheKey);
316
+        if(!is_null($memberOfGroups)) {
317
+            return $memberOfGroups;
318
+        }
319
+        $groupDNs = $this->access->readAttribute($this->getDN(), 'memberOf');
320
+        $this->connection->writeToCache($cacheKey, $groupDNs);
321
+        return $groupDNs;
322
+    }
323
+
324
+    /**
325
+     * @brief reads the image from LDAP that shall be used as Avatar
326
+     * @return string data (provided by LDAP) | false
327
+     */
328
+    public function getAvatarImage() {
329
+        if(!is_null($this->avatarImage)) {
330
+            return $this->avatarImage;
331
+        }
332
+
333
+        $this->avatarImage = false;
334
+        $attributes = array('jpegPhoto', 'thumbnailPhoto');
335
+        foreach($attributes as $attribute) {
336
+            $result = $this->access->readAttribute($this->dn, $attribute);
337
+            if($result !== false && is_array($result) && isset($result[0])) {
338
+                $this->avatarImage = $result[0];
339
+                break;
340
+            }
341
+        }
342
+
343
+        return $this->avatarImage;
344
+    }
345
+
346
+    /**
347
+     * @brief marks the user as having logged in at least once
348
+     * @return null
349
+     */
350
+    public function markLogin() {
351
+        $this->config->setUserValue(
352
+            $this->uid, 'user_ldap', self::USER_PREFKEY_FIRSTLOGIN, 1);
353
+    }
354
+
355
+    /**
356
+     * @brief marks the time when user features like email have been updated
357
+     * @return null
358
+     */
359
+    public function markRefreshTime() {
360
+        $this->config->setUserValue(
361
+            $this->uid, 'user_ldap', self::USER_PREFKEY_LASTREFRESH, time());
362
+    }
363
+
364
+    /**
365
+     * @brief checks whether user features needs to be updated again by
366
+     * comparing the difference of time of the last refresh to now with the
367
+     * desired interval
368
+     * @return bool
369
+     */
370
+    private function needsRefresh() {
371
+        $lastChecked = $this->config->getUserValue($this->uid, 'user_ldap',
372
+            self::USER_PREFKEY_LASTREFRESH, 0);
373
+
374
+        //TODO make interval configurable
375
+        if((time() - intval($lastChecked)) < 86400 ) {
376
+            return false;
377
+        }
378
+        return  true;
379
+    }
380
+
381
+    /**
382
+     * Stores a key-value pair in relation to this user
383
+     *
384
+     * @param string $key
385
+     * @param string $value
386
+     */
387
+    private function store($key, $value) {
388
+        $this->config->setUserValue($this->uid, 'user_ldap', $key, $value);
389
+    }
390
+
391
+    /**
392
+     * Composes the display name and stores it in the database. The final
393
+     * display name is returned.
394
+     *
395
+     * @param string $displayName
396
+     * @param string $displayName2
397
+     * @returns string the effective display name
398
+     */
399
+    public function composeAndStoreDisplayName($displayName, $displayName2 = '') {
400
+        $displayName2 = strval($displayName2);
401
+        if($displayName2 !== '') {
402
+            $displayName .= ' (' . $displayName2 . ')';
403
+        }
404
+        $this->store('displayName', $displayName);
405
+        return $displayName;
406
+    }
407
+
408
+    /**
409
+     * Stores the LDAP Username in the Database
410
+     * @param string $userName
411
+     */
412
+    public function storeLDAPUserName($userName) {
413
+        $this->store('uid', $userName);
414
+    }
415
+
416
+    /**
417
+     * @brief checks whether an update method specified by feature was run
418
+     * already. If not, it will marked like this, because it is expected that
419
+     * the method will be run, when false is returned.
420
+     * @param string $feature email | quota | avatar (can be extended)
421
+     * @return bool
422
+     */
423
+    private function wasRefreshed($feature) {
424
+        if(isset($this->refreshedFeatures[$feature])) {
425
+            return true;
426
+        }
427
+        $this->refreshedFeatures[$feature] = 1;
428
+        return false;
429
+    }
430
+
431
+    /**
432
+     * fetches the email from LDAP and stores it as Nextcloud user value
433
+     * @param string $valueFromLDAP if known, to save an LDAP read request
434
+     * @return null
435
+     */
436
+    public function updateEmail($valueFromLDAP = null) {
437
+        if($this->wasRefreshed('email')) {
438
+            return;
439
+        }
440
+        $email = strval($valueFromLDAP);
441
+        if(is_null($valueFromLDAP)) {
442
+            $emailAttribute = $this->connection->ldapEmailAttribute;
443
+            if ($emailAttribute !== '') {
444
+                $aEmail = $this->access->readAttribute($this->dn, $emailAttribute);
445
+                if(is_array($aEmail) && (count($aEmail) > 0)) {
446
+                    $email = strval($aEmail[0]);
447
+                }
448
+            }
449
+        }
450
+        if ($email !== '') {
451
+            $user = $this->userManager->get($this->uid);
452
+            if (!is_null($user)) {
453
+                $currentEmail = strval($user->getEMailAddress());
454
+                if ($currentEmail !== $email) {
455
+                    $user->setEMailAddress($email);
456
+                }
457
+            }
458
+        }
459
+    }
460
+
461
+    /**
462
+     * Overall process goes as follow:
463
+     * 1. fetch the quota from LDAP and check if it's parseable with the "verifyQuotaValue" function
464
+     * 2. if the value can't be fetched, is empty or not parseable, use the default LDAP quota
465
+     * 3. if the default LDAP quota can't be parsed, use the Nextcloud's default quota (use 'default')
466
+     * 4. check if the target user exists and set the quota for the user.
467
+     *
468
+     * In order to improve performance and prevent an unwanted extra LDAP call, the $valueFromLDAP
469
+     * parameter can be passed with the value of the attribute. This value will be considered as the
470
+     * quota for the user coming from the LDAP server (step 1 of the process) It can be useful to
471
+     * fetch all the user's attributes in one call and use the fetched values in this function.
472
+     * The expected value for that parameter is a string describing the quota for the user. Valid
473
+     * values are 'none' (unlimited), 'default' (the Nextcloud's default quota), '1234' (quota in
474
+     * bytes), '1234 MB' (quota in MB - check the \OC_Helper::computerFileSize method for more info)
475
+     *
476
+     * fetches the quota from LDAP and stores it as Nextcloud user value
477
+     * @param string $valueFromLDAP the quota attribute's value can be passed,
478
+     * to save the readAttribute request
479
+     * @return null
480
+     */
481
+    public function updateQuota($valueFromLDAP = null) {
482
+        if($this->wasRefreshed('quota')) {
483
+            return;
484
+        }
485
+
486
+        $quota = false;
487
+        if(is_null($valueFromLDAP)) {
488
+            $quotaAttribute = $this->connection->ldapQuotaAttribute;
489
+            if ($quotaAttribute !== '') {
490
+                $aQuota = $this->access->readAttribute($this->dn, $quotaAttribute);
491
+                if($aQuota && (count($aQuota) > 0)) {
492
+                    if ($this->verifyQuotaValue($aQuota[0])) {
493
+                        $quota = $aQuota[0];
494
+                    } else {
495
+                        $this->log->log('not suitable LDAP quota found for user ' . $this->uid . ': [' . $aQuota[0] . ']', \OCP\Util::WARN);
496
+                    }
497
+                }
498
+            }
499
+        } else {
500
+            if ($this->verifyQuotaValue($valueFromLDAP)) {
501
+                $quota = $valueFromLDAP;
502
+            } else {
503
+                $this->log->log('not suitable LDAP quota found for user ' . $this->uid . ': [' . $valueFromLDAP . ']', \OCP\Util::WARN);
504
+            }
505
+        }
506
+
507
+        if ($quota === false) {
508
+            // quota not found using the LDAP attribute (or not parseable). Try the default quota
509
+            $defaultQuota = $this->connection->ldapQuotaDefault;
510
+            if ($this->verifyQuotaValue($defaultQuota)) {
511
+                $quota = $defaultQuota;
512
+            }
513
+        }
514
+
515
+        $targetUser = $this->userManager->get($this->uid);
516
+        if ($targetUser) {
517
+            if($quota !== false) {
518
+                $targetUser->setQuota($quota);
519
+            } else {
520
+                $this->log->log('not suitable default quota found for user ' . $this->uid . ': [' . $defaultQuota . ']', \OCP\Util::WARN);
521
+                $targetUser->setQuota('default');
522
+            }
523
+        } else {
524
+            $this->log->log('trying to set a quota for user ' . $this->uid . ' but the user is missing', \OCP\Util::ERROR);
525
+        }
526
+    }
527
+
528
+    private function verifyQuotaValue($quotaValue) {
529
+        return $quotaValue === 'none' || $quotaValue === 'default' || \OC_Helper::computerFileSize($quotaValue) !== false;
530
+    }
531
+
532
+    /**
533
+     * called by a post_login hook to save the avatar picture
534
+     *
535
+     * @param array $params
536
+     */
537
+    public function updateAvatarPostLogin($params) {
538
+        if(isset($params['uid']) && $params['uid'] === $this->getUsername()) {
539
+            $this->updateAvatar();
540
+        }
541
+    }
542
+
543
+    /**
544
+     * @brief attempts to get an image from LDAP and sets it as Nextcloud avatar
545
+     * @return null
546
+     */
547
+    public function updateAvatar() {
548
+        if($this->wasRefreshed('avatar')) {
549
+            return;
550
+        }
551
+        $avatarImage = $this->getAvatarImage();
552
+        if($avatarImage === false) {
553
+            //not set, nothing left to do;
554
+            return;
555
+        }
556
+        $this->image->loadFromBase64(base64_encode($avatarImage));
557
+        $this->setOwnCloudAvatar();
558
+    }
559
+
560
+    /**
561
+     * @brief sets an image as Nextcloud avatar
562
+     * @return null
563
+     */
564
+    private function setOwnCloudAvatar() {
565
+        if(!$this->image->valid()) {
566
+            $this->log->log('jpegPhoto data invalid for '.$this->dn, \OCP\Util::ERROR);
567
+            return;
568
+        }
569
+        //make sure it is a square and not bigger than 128x128
570
+        $size = min(array($this->image->width(), $this->image->height(), 128));
571
+        if(!$this->image->centerCrop($size)) {
572
+            $this->log->log('croping image for avatar failed for '.$this->dn, \OCP\Util::ERROR);
573
+            return;
574
+        }
575
+
576
+        if(!$this->fs->isLoaded()) {
577
+            $this->fs->setup($this->uid);
578
+        }
579
+
580
+        try {
581
+            $avatar = $this->avatarManager->getAvatar($this->uid);
582
+            $avatar->set($this->image);
583
+        } catch (\Exception $e) {
584
+            \OC::$server->getLogger()->notice(
585
+                'Could not set avatar for ' . $this->dn	. ', because: ' . $e->getMessage(),
586
+                ['app' => 'user_ldap']);
587
+        }
588
+    }
589 589
 
590 590
 }
Please login to merge, or discard this patch.
apps/user_ldap/lib/User/Manager.php 1 patch
Indentation   +195 added lines, -195 removed lines patch added patch discarded remove patch
@@ -42,200 +42,200 @@
 block discarded – undo
42 42
  * cache
43 43
  */
44 44
 class Manager {
45
-	/** @var IUserTools */
46
-	protected $access;
47
-
48
-	/** @var IConfig */
49
-	protected $ocConfig;
50
-
51
-	/** @var IDBConnection */
52
-	protected $db;
53
-
54
-	/** @var FilesystemHelper */
55
-	protected $ocFilesystem;
56
-
57
-	/** @var LogWrapper */
58
-	protected $ocLog;
59
-
60
-	/** @var Image */
61
-	protected $image;
62
-
63
-	/** @param \OCP\IAvatarManager */
64
-	protected $avatarManager;
65
-
66
-	/**
67
-	 * @var CappedMemoryCache $usersByDN
68
-	 */
69
-	protected $usersByDN;
70
-	/**
71
-	 * @var CappedMemoryCache $usersByUid
72
-	 */
73
-	protected $usersByUid;
74
-
75
-	/**
76
-	 * @param IConfig $ocConfig
77
-	 * @param \OCA\User_LDAP\FilesystemHelper $ocFilesystem object that
78
-	 * gives access to necessary functions from the OC filesystem
79
-	 * @param  \OCA\User_LDAP\LogWrapper $ocLog
80
-	 * @param IAvatarManager $avatarManager
81
-	 * @param Image $image an empty image instance
82
-	 * @param IDBConnection $db
83
-	 * @throws \Exception when the methods mentioned above do not exist
84
-	 */
85
-	public function __construct(IConfig $ocConfig,
86
-								FilesystemHelper $ocFilesystem, LogWrapper $ocLog,
87
-								IAvatarManager $avatarManager, Image $image,
88
-								IDBConnection $db, IUserManager $userManager) {
89
-
90
-		$this->ocConfig      = $ocConfig;
91
-		$this->ocFilesystem  = $ocFilesystem;
92
-		$this->ocLog         = $ocLog;
93
-		$this->avatarManager = $avatarManager;
94
-		$this->image         = $image;
95
-		$this->db            = $db;
96
-		$this->userManager   = $userManager;
97
-		$this->usersByDN     = new CappedMemoryCache();
98
-		$this->usersByUid    = new CappedMemoryCache();
99
-	}
100
-
101
-	/**
102
-	 * @brief binds manager to an instance of IUserTools (implemented by
103
-	 * Access). It needs to be assigned first before the manager can be used.
104
-	 * @param IUserTools
105
-	 */
106
-	public function setLdapAccess(IUserTools $access) {
107
-		$this->access = $access;
108
-	}
109
-
110
-	/**
111
-	 * @brief creates an instance of User and caches (just runtime) it in the
112
-	 * property array
113
-	 * @param string $dn the DN of the user
114
-	 * @param string $uid the internal (owncloud) username
115
-	 * @return \OCA\User_LDAP\User\User
116
-	 */
117
-	private function createAndCache($dn, $uid) {
118
-		$this->checkAccess();
119
-		$user = new User($uid, $dn, $this->access, $this->ocConfig,
120
-			$this->ocFilesystem, clone $this->image, $this->ocLog,
121
-			$this->avatarManager, $this->userManager);
122
-		$this->usersByDN[$dn]   = $user;
123
-		$this->usersByUid[$uid] = $user;
124
-		return $user;
125
-	}
126
-
127
-	/**
128
-	 * @brief checks whether the Access instance has been set
129
-	 * @throws \Exception if Access has not been set
130
-	 * @return null
131
-	 */
132
-	private function checkAccess() {
133
-		if(is_null($this->access)) {
134
-			throw new \Exception('LDAP Access instance must be set first');
135
-		}
136
-	}
137
-
138
-	/**
139
-	 * returns a list of attributes that will be processed further, e.g. quota,
140
-	 * email, displayname, or others.
141
-	 * @param bool $minimal - optional, set to true to skip attributes with big
142
-	 * payload
143
-	 * @return string[]
144
-	 */
145
-	public function getAttributes($minimal = false) {
146
-		$attributes = array('dn', 'uid', 'samaccountname', 'memberof');
147
-		$possible = array(
148
-			$this->access->getConnection()->ldapQuotaAttribute,
149
-			$this->access->getConnection()->ldapEmailAttribute,
150
-			$this->access->getConnection()->ldapUserDisplayName,
151
-			$this->access->getConnection()->ldapUserDisplayName2,
152
-		);
153
-		foreach($possible as $attr) {
154
-			if(!is_null($attr)) {
155
-				$attributes[] = $attr;
156
-			}
157
-		}
158
-
159
-		$homeRule = $this->access->getConnection()->homeFolderNamingRule;
160
-		if(strpos($homeRule, 'attr:') === 0) {
161
-			$attributes[] = substr($homeRule, strlen('attr:'));
162
-		}
163
-
164
-		if(!$minimal) {
165
-			// attributes that are not really important but may come with big
166
-			// payload.
167
-			$attributes = array_merge($attributes, array(
168
-				'jpegphoto',
169
-				'thumbnailphoto'
170
-			));
171
-		}
172
-
173
-		return $attributes;
174
-	}
175
-
176
-	/**
177
-	 * Checks whether the specified user is marked as deleted
178
-	 * @param string $id the Nextcloud user name
179
-	 * @return bool
180
-	 */
181
-	public function isDeletedUser($id) {
182
-		$isDeleted = $this->ocConfig->getUserValue(
183
-			$id, 'user_ldap', 'isDeleted', 0);
184
-		return intval($isDeleted) === 1;
185
-	}
186
-
187
-	/**
188
-	 * creates and returns an instance of OfflineUser for the specified user
189
-	 * @param string $id
190
-	 * @return \OCA\User_LDAP\User\OfflineUser
191
-	 */
192
-	public function getDeletedUser($id) {
193
-		return new OfflineUser(
194
-			$id,
195
-			$this->ocConfig,
196
-			$this->db,
197
-			$this->access->getUserMapper());
198
-	}
199
-
200
-	/**
201
-	 * @brief returns a User object by it's Nextcloud username
202
-	 * @param string $id the DN or username of the user
203
-	 * @return \OCA\User_LDAP\User\User|\OCA\User_LDAP\User\OfflineUser|null
204
-	 */
205
-	protected function createInstancyByUserName($id) {
206
-		//most likely a uid. Check whether it is a deleted user
207
-		if($this->isDeletedUser($id)) {
208
-			return $this->getDeletedUser($id);
209
-		}
210
-		$dn = $this->access->username2dn($id);
211
-		if($dn !== false) {
212
-			return $this->createAndCache($dn, $id);
213
-		}
214
-		return null;
215
-	}
216
-
217
-	/**
218
-	 * @brief returns a User object by it's DN or Nextcloud username
219
-	 * @param string $id the DN or username of the user
220
-	 * @return \OCA\User_LDAP\User\User|\OCA\User_LDAP\User\OfflineUser|null
221
-	 * @throws \Exception when connection could not be established
222
-	 */
223
-	public function get($id) {
224
-		$this->checkAccess();
225
-		if(isset($this->usersByDN[$id])) {
226
-			return $this->usersByDN[$id];
227
-		} else if(isset($this->usersByUid[$id])) {
228
-			return $this->usersByUid[$id];
229
-		}
230
-
231
-		if($this->access->stringResemblesDN($id) ) {
232
-			$uid = $this->access->dn2username($id);
233
-			if($uid !== false) {
234
-				return $this->createAndCache($id, $uid);
235
-			}
236
-		}
237
-
238
-		return $this->createInstancyByUserName($id);
239
-	}
45
+    /** @var IUserTools */
46
+    protected $access;
47
+
48
+    /** @var IConfig */
49
+    protected $ocConfig;
50
+
51
+    /** @var IDBConnection */
52
+    protected $db;
53
+
54
+    /** @var FilesystemHelper */
55
+    protected $ocFilesystem;
56
+
57
+    /** @var LogWrapper */
58
+    protected $ocLog;
59
+
60
+    /** @var Image */
61
+    protected $image;
62
+
63
+    /** @param \OCP\IAvatarManager */
64
+    protected $avatarManager;
65
+
66
+    /**
67
+     * @var CappedMemoryCache $usersByDN
68
+     */
69
+    protected $usersByDN;
70
+    /**
71
+     * @var CappedMemoryCache $usersByUid
72
+     */
73
+    protected $usersByUid;
74
+
75
+    /**
76
+     * @param IConfig $ocConfig
77
+     * @param \OCA\User_LDAP\FilesystemHelper $ocFilesystem object that
78
+     * gives access to necessary functions from the OC filesystem
79
+     * @param  \OCA\User_LDAP\LogWrapper $ocLog
80
+     * @param IAvatarManager $avatarManager
81
+     * @param Image $image an empty image instance
82
+     * @param IDBConnection $db
83
+     * @throws \Exception when the methods mentioned above do not exist
84
+     */
85
+    public function __construct(IConfig $ocConfig,
86
+                                FilesystemHelper $ocFilesystem, LogWrapper $ocLog,
87
+                                IAvatarManager $avatarManager, Image $image,
88
+                                IDBConnection $db, IUserManager $userManager) {
89
+
90
+        $this->ocConfig      = $ocConfig;
91
+        $this->ocFilesystem  = $ocFilesystem;
92
+        $this->ocLog         = $ocLog;
93
+        $this->avatarManager = $avatarManager;
94
+        $this->image         = $image;
95
+        $this->db            = $db;
96
+        $this->userManager   = $userManager;
97
+        $this->usersByDN     = new CappedMemoryCache();
98
+        $this->usersByUid    = new CappedMemoryCache();
99
+    }
100
+
101
+    /**
102
+     * @brief binds manager to an instance of IUserTools (implemented by
103
+     * Access). It needs to be assigned first before the manager can be used.
104
+     * @param IUserTools
105
+     */
106
+    public function setLdapAccess(IUserTools $access) {
107
+        $this->access = $access;
108
+    }
109
+
110
+    /**
111
+     * @brief creates an instance of User and caches (just runtime) it in the
112
+     * property array
113
+     * @param string $dn the DN of the user
114
+     * @param string $uid the internal (owncloud) username
115
+     * @return \OCA\User_LDAP\User\User
116
+     */
117
+    private function createAndCache($dn, $uid) {
118
+        $this->checkAccess();
119
+        $user = new User($uid, $dn, $this->access, $this->ocConfig,
120
+            $this->ocFilesystem, clone $this->image, $this->ocLog,
121
+            $this->avatarManager, $this->userManager);
122
+        $this->usersByDN[$dn]   = $user;
123
+        $this->usersByUid[$uid] = $user;
124
+        return $user;
125
+    }
126
+
127
+    /**
128
+     * @brief checks whether the Access instance has been set
129
+     * @throws \Exception if Access has not been set
130
+     * @return null
131
+     */
132
+    private function checkAccess() {
133
+        if(is_null($this->access)) {
134
+            throw new \Exception('LDAP Access instance must be set first');
135
+        }
136
+    }
137
+
138
+    /**
139
+     * returns a list of attributes that will be processed further, e.g. quota,
140
+     * email, displayname, or others.
141
+     * @param bool $minimal - optional, set to true to skip attributes with big
142
+     * payload
143
+     * @return string[]
144
+     */
145
+    public function getAttributes($minimal = false) {
146
+        $attributes = array('dn', 'uid', 'samaccountname', 'memberof');
147
+        $possible = array(
148
+            $this->access->getConnection()->ldapQuotaAttribute,
149
+            $this->access->getConnection()->ldapEmailAttribute,
150
+            $this->access->getConnection()->ldapUserDisplayName,
151
+            $this->access->getConnection()->ldapUserDisplayName2,
152
+        );
153
+        foreach($possible as $attr) {
154
+            if(!is_null($attr)) {
155
+                $attributes[] = $attr;
156
+            }
157
+        }
158
+
159
+        $homeRule = $this->access->getConnection()->homeFolderNamingRule;
160
+        if(strpos($homeRule, 'attr:') === 0) {
161
+            $attributes[] = substr($homeRule, strlen('attr:'));
162
+        }
163
+
164
+        if(!$minimal) {
165
+            // attributes that are not really important but may come with big
166
+            // payload.
167
+            $attributes = array_merge($attributes, array(
168
+                'jpegphoto',
169
+                'thumbnailphoto'
170
+            ));
171
+        }
172
+
173
+        return $attributes;
174
+    }
175
+
176
+    /**
177
+     * Checks whether the specified user is marked as deleted
178
+     * @param string $id the Nextcloud user name
179
+     * @return bool
180
+     */
181
+    public function isDeletedUser($id) {
182
+        $isDeleted = $this->ocConfig->getUserValue(
183
+            $id, 'user_ldap', 'isDeleted', 0);
184
+        return intval($isDeleted) === 1;
185
+    }
186
+
187
+    /**
188
+     * creates and returns an instance of OfflineUser for the specified user
189
+     * @param string $id
190
+     * @return \OCA\User_LDAP\User\OfflineUser
191
+     */
192
+    public function getDeletedUser($id) {
193
+        return new OfflineUser(
194
+            $id,
195
+            $this->ocConfig,
196
+            $this->db,
197
+            $this->access->getUserMapper());
198
+    }
199
+
200
+    /**
201
+     * @brief returns a User object by it's Nextcloud username
202
+     * @param string $id the DN or username of the user
203
+     * @return \OCA\User_LDAP\User\User|\OCA\User_LDAP\User\OfflineUser|null
204
+     */
205
+    protected function createInstancyByUserName($id) {
206
+        //most likely a uid. Check whether it is a deleted user
207
+        if($this->isDeletedUser($id)) {
208
+            return $this->getDeletedUser($id);
209
+        }
210
+        $dn = $this->access->username2dn($id);
211
+        if($dn !== false) {
212
+            return $this->createAndCache($dn, $id);
213
+        }
214
+        return null;
215
+    }
216
+
217
+    /**
218
+     * @brief returns a User object by it's DN or Nextcloud username
219
+     * @param string $id the DN or username of the user
220
+     * @return \OCA\User_LDAP\User\User|\OCA\User_LDAP\User\OfflineUser|null
221
+     * @throws \Exception when connection could not be established
222
+     */
223
+    public function get($id) {
224
+        $this->checkAccess();
225
+        if(isset($this->usersByDN[$id])) {
226
+            return $this->usersByDN[$id];
227
+        } else if(isset($this->usersByUid[$id])) {
228
+            return $this->usersByUid[$id];
229
+        }
230
+
231
+        if($this->access->stringResemblesDN($id) ) {
232
+            $uid = $this->access->dn2username($id);
233
+            if($uid !== false) {
234
+                return $this->createAndCache($id, $uid);
235
+            }
236
+        }
237
+
238
+        return $this->createInstancyByUserName($id);
239
+    }
240 240
 
241 241
 }
Please login to merge, or discard this patch.
apps/user_ldap/lib/User_Proxy.php 1 patch
Indentation   +260 added lines, -260 removed lines patch added patch discarded remove patch
@@ -33,285 +33,285 @@
 block discarded – undo
33 33
 use OCP\IConfig;
34 34
 
35 35
 class User_Proxy extends Proxy implements \OCP\IUserBackend, \OCP\UserInterface, IUserLDAP {
36
-	private $backends = array();
37
-	private $refBackend = null;
36
+    private $backends = array();
37
+    private $refBackend = null;
38 38
 
39
-	/**
40
-	 * Constructor
41
-	 * @param array $serverConfigPrefixes array containing the config Prefixes
42
-	 */
43
-	public function __construct(array $serverConfigPrefixes, ILDAPWrapper $ldap, IConfig $ocConfig) {
44
-		parent::__construct($ldap);
45
-		foreach($serverConfigPrefixes as $configPrefix) {
46
-			$this->backends[$configPrefix] =
47
-				new User_LDAP($this->getAccess($configPrefix), $ocConfig);
48
-			if(is_null($this->refBackend)) {
49
-				$this->refBackend = &$this->backends[$configPrefix];
50
-			}
51
-		}
52
-	}
39
+    /**
40
+     * Constructor
41
+     * @param array $serverConfigPrefixes array containing the config Prefixes
42
+     */
43
+    public function __construct(array $serverConfigPrefixes, ILDAPWrapper $ldap, IConfig $ocConfig) {
44
+        parent::__construct($ldap);
45
+        foreach($serverConfigPrefixes as $configPrefix) {
46
+            $this->backends[$configPrefix] =
47
+                new User_LDAP($this->getAccess($configPrefix), $ocConfig);
48
+            if(is_null($this->refBackend)) {
49
+                $this->refBackend = &$this->backends[$configPrefix];
50
+            }
51
+        }
52
+    }
53 53
 
54
-	/**
55
-	 * Tries the backends one after the other until a positive result is returned from the specified method
56
-	 * @param string $uid the uid connected to the request
57
-	 * @param string $method the method of the user backend that shall be called
58
-	 * @param array $parameters an array of parameters to be passed
59
-	 * @return mixed the result of the method or false
60
-	 */
61
-	protected function walkBackends($uid, $method, $parameters) {
62
-		$cacheKey = $this->getUserCacheKey($uid);
63
-		foreach($this->backends as $configPrefix => $backend) {
64
-			$instance = $backend;
65
-			if(!method_exists($instance, $method)
66
-				&& method_exists($this->getAccess($configPrefix), $method)) {
67
-				$instance = $this->getAccess($configPrefix);
68
-			}
69
-			if($result = call_user_func_array(array($instance, $method), $parameters)) {
70
-				$this->writeToCache($cacheKey, $configPrefix);
71
-				return $result;
72
-			}
73
-		}
74
-		return false;
75
-	}
54
+    /**
55
+     * Tries the backends one after the other until a positive result is returned from the specified method
56
+     * @param string $uid the uid connected to the request
57
+     * @param string $method the method of the user backend that shall be called
58
+     * @param array $parameters an array of parameters to be passed
59
+     * @return mixed the result of the method or false
60
+     */
61
+    protected function walkBackends($uid, $method, $parameters) {
62
+        $cacheKey = $this->getUserCacheKey($uid);
63
+        foreach($this->backends as $configPrefix => $backend) {
64
+            $instance = $backend;
65
+            if(!method_exists($instance, $method)
66
+                && method_exists($this->getAccess($configPrefix), $method)) {
67
+                $instance = $this->getAccess($configPrefix);
68
+            }
69
+            if($result = call_user_func_array(array($instance, $method), $parameters)) {
70
+                $this->writeToCache($cacheKey, $configPrefix);
71
+                return $result;
72
+            }
73
+        }
74
+        return false;
75
+    }
76 76
 
77
-	/**
78
-	 * Asks the backend connected to the server that supposely takes care of the uid from the request.
79
-	 * @param string $uid the uid connected to the request
80
-	 * @param string $method the method of the user backend that shall be called
81
-	 * @param array $parameters an array of parameters to be passed
82
-	 * @param mixed $passOnWhen the result matches this variable
83
-	 * @return mixed the result of the method or false
84
-	 */
85
-	protected function callOnLastSeenOn($uid, $method, $parameters, $passOnWhen) {
86
-		$cacheKey = $this->getUserCacheKey($uid);
87
-		$prefix = $this->getFromCache($cacheKey);
88
-		//in case the uid has been found in the past, try this stored connection first
89
-		if(!is_null($prefix)) {
90
-			if(isset($this->backends[$prefix])) {
91
-				$instance = $this->backends[$prefix];
92
-				if(!method_exists($instance, $method)
93
-					&& method_exists($this->getAccess($prefix), $method)) {
94
-					$instance = $this->getAccess($prefix);
95
-				}
96
-				$result = call_user_func_array(array($instance, $method), $parameters);
97
-				if($result === $passOnWhen) {
98
-					//not found here, reset cache to null if user vanished
99
-					//because sometimes methods return false with a reason
100
-					$userExists = call_user_func_array(
101
-						array($this->backends[$prefix], 'userExists'),
102
-						array($uid)
103
-					);
104
-					if(!$userExists) {
105
-						$this->writeToCache($cacheKey, null);
106
-					}
107
-				}
108
-				return $result;
109
-			}
110
-		}
111
-		return false;
112
-	}
77
+    /**
78
+     * Asks the backend connected to the server that supposely takes care of the uid from the request.
79
+     * @param string $uid the uid connected to the request
80
+     * @param string $method the method of the user backend that shall be called
81
+     * @param array $parameters an array of parameters to be passed
82
+     * @param mixed $passOnWhen the result matches this variable
83
+     * @return mixed the result of the method or false
84
+     */
85
+    protected function callOnLastSeenOn($uid, $method, $parameters, $passOnWhen) {
86
+        $cacheKey = $this->getUserCacheKey($uid);
87
+        $prefix = $this->getFromCache($cacheKey);
88
+        //in case the uid has been found in the past, try this stored connection first
89
+        if(!is_null($prefix)) {
90
+            if(isset($this->backends[$prefix])) {
91
+                $instance = $this->backends[$prefix];
92
+                if(!method_exists($instance, $method)
93
+                    && method_exists($this->getAccess($prefix), $method)) {
94
+                    $instance = $this->getAccess($prefix);
95
+                }
96
+                $result = call_user_func_array(array($instance, $method), $parameters);
97
+                if($result === $passOnWhen) {
98
+                    //not found here, reset cache to null if user vanished
99
+                    //because sometimes methods return false with a reason
100
+                    $userExists = call_user_func_array(
101
+                        array($this->backends[$prefix], 'userExists'),
102
+                        array($uid)
103
+                    );
104
+                    if(!$userExists) {
105
+                        $this->writeToCache($cacheKey, null);
106
+                    }
107
+                }
108
+                return $result;
109
+            }
110
+        }
111
+        return false;
112
+    }
113 113
 
114
-	/**
115
-	 * Check if backend implements actions
116
-	 * @param int $actions bitwise-or'ed actions
117
-	 * @return boolean
118
-	 *
119
-	 * Returns the supported actions as int to be
120
-	 * compared with OC_USER_BACKEND_CREATE_USER etc.
121
-	 */
122
-	public function implementsActions($actions) {
123
-		//it's the same across all our user backends obviously
124
-		return $this->refBackend->implementsActions($actions);
125
-	}
114
+    /**
115
+     * Check if backend implements actions
116
+     * @param int $actions bitwise-or'ed actions
117
+     * @return boolean
118
+     *
119
+     * Returns the supported actions as int to be
120
+     * compared with OC_USER_BACKEND_CREATE_USER etc.
121
+     */
122
+    public function implementsActions($actions) {
123
+        //it's the same across all our user backends obviously
124
+        return $this->refBackend->implementsActions($actions);
125
+    }
126 126
 
127
-	/**
128
-	 * Backend name to be shown in user management
129
-	 * @return string the name of the backend to be shown
130
-	 */
131
-	public function getBackendName() {
132
-		return $this->refBackend->getBackendName();
133
-	}
127
+    /**
128
+     * Backend name to be shown in user management
129
+     * @return string the name of the backend to be shown
130
+     */
131
+    public function getBackendName() {
132
+        return $this->refBackend->getBackendName();
133
+    }
134 134
 
135
-	/**
136
-	 * Get a list of all users
137
-	 *
138
-	 * @param string $search
139
-	 * @param null|int $limit
140
-	 * @param null|int $offset
141
-	 * @return string[] an array of all uids
142
-	 */
143
-	public function getUsers($search = '', $limit = 10, $offset = 0) {
144
-		//we do it just as the /OC_User implementation: do not play around with limit and offset but ask all backends
145
-		$users = array();
146
-		foreach($this->backends as $backend) {
147
-			$backendUsers = $backend->getUsers($search, $limit, $offset);
148
-			if (is_array($backendUsers)) {
149
-				$users = array_merge($users, $backendUsers);
150
-			}
151
-		}
152
-		return $users;
153
-	}
135
+    /**
136
+     * Get a list of all users
137
+     *
138
+     * @param string $search
139
+     * @param null|int $limit
140
+     * @param null|int $offset
141
+     * @return string[] an array of all uids
142
+     */
143
+    public function getUsers($search = '', $limit = 10, $offset = 0) {
144
+        //we do it just as the /OC_User implementation: do not play around with limit and offset but ask all backends
145
+        $users = array();
146
+        foreach($this->backends as $backend) {
147
+            $backendUsers = $backend->getUsers($search, $limit, $offset);
148
+            if (is_array($backendUsers)) {
149
+                $users = array_merge($users, $backendUsers);
150
+            }
151
+        }
152
+        return $users;
153
+    }
154 154
 
155
-	/**
156
-	 * check if a user exists
157
-	 * @param string $uid the username
158
-	 * @return boolean
159
-	 */
160
-	public function userExists($uid) {
161
-		return $this->handleRequest($uid, 'userExists', array($uid));
162
-	}
155
+    /**
156
+     * check if a user exists
157
+     * @param string $uid the username
158
+     * @return boolean
159
+     */
160
+    public function userExists($uid) {
161
+        return $this->handleRequest($uid, 'userExists', array($uid));
162
+    }
163 163
 
164
-	/**
165
-	 * check if a user exists on LDAP
166
-	 * @param string|\OCA\User_LDAP\User\User $user either the Nextcloud user
167
-	 * name or an instance of that user
168
-	 * @return boolean
169
-	 */
170
-	public function userExistsOnLDAP($user) {
171
-		$id = ($user instanceof User) ? $user->getUsername() : $user;
172
-		return $this->handleRequest($id, 'userExistsOnLDAP', array($user));
173
-	}
164
+    /**
165
+     * check if a user exists on LDAP
166
+     * @param string|\OCA\User_LDAP\User\User $user either the Nextcloud user
167
+     * name or an instance of that user
168
+     * @return boolean
169
+     */
170
+    public function userExistsOnLDAP($user) {
171
+        $id = ($user instanceof User) ? $user->getUsername() : $user;
172
+        return $this->handleRequest($id, 'userExistsOnLDAP', array($user));
173
+    }
174 174
 
175
-	/**
176
-	 * Check if the password is correct
177
-	 * @param string $uid The username
178
-	 * @param string $password The password
179
-	 * @return bool
180
-	 *
181
-	 * Check if the password is correct without logging in the user
182
-	 */
183
-	public function checkPassword($uid, $password) {
184
-		return $this->handleRequest($uid, 'checkPassword', array($uid, $password));
185
-	}
175
+    /**
176
+     * Check if the password is correct
177
+     * @param string $uid The username
178
+     * @param string $password The password
179
+     * @return bool
180
+     *
181
+     * Check if the password is correct without logging in the user
182
+     */
183
+    public function checkPassword($uid, $password) {
184
+        return $this->handleRequest($uid, 'checkPassword', array($uid, $password));
185
+    }
186 186
 
187
-	/**
188
-	 * returns the username for the given login name, if available
189
-	 *
190
-	 * @param string $loginName
191
-	 * @return string|false
192
-	 */
193
-	public function loginName2UserName($loginName) {
194
-		$id = 'LOGINNAME,' . $loginName;
195
-		return $this->handleRequest($id, 'loginName2UserName', array($loginName));
196
-	}
187
+    /**
188
+     * returns the username for the given login name, if available
189
+     *
190
+     * @param string $loginName
191
+     * @return string|false
192
+     */
193
+    public function loginName2UserName($loginName) {
194
+        $id = 'LOGINNAME,' . $loginName;
195
+        return $this->handleRequest($id, 'loginName2UserName', array($loginName));
196
+    }
197 197
 	
198
-	/**
199
-	 * returns the username for the given LDAP DN, if available
200
-	 *
201
-	 * @param string $dn
202
-	 * @return string|false with the username
203
-	 */
204
-	public function dn2UserName($dn) {
205
-		$id = 'DN,' . $dn;
206
-		return $this->handleRequest($id, 'dn2UserName', array($dn));
207
-	}
198
+    /**
199
+     * returns the username for the given LDAP DN, if available
200
+     *
201
+     * @param string $dn
202
+     * @return string|false with the username
203
+     */
204
+    public function dn2UserName($dn) {
205
+        $id = 'DN,' . $dn;
206
+        return $this->handleRequest($id, 'dn2UserName', array($dn));
207
+    }
208 208
 
209
-	/**
210
-	 * get the user's home directory
211
-	 * @param string $uid the username
212
-	 * @return boolean
213
-	 */
214
-	public function getHome($uid) {
215
-		return $this->handleRequest($uid, 'getHome', array($uid));
216
-	}
209
+    /**
210
+     * get the user's home directory
211
+     * @param string $uid the username
212
+     * @return boolean
213
+     */
214
+    public function getHome($uid) {
215
+        return $this->handleRequest($uid, 'getHome', array($uid));
216
+    }
217 217
 
218
-	/**
219
-	 * get display name of the user
220
-	 * @param string $uid user ID of the user
221
-	 * @return string display name
222
-	 */
223
-	public function getDisplayName($uid) {
224
-		return $this->handleRequest($uid, 'getDisplayName', array($uid));
225
-	}
218
+    /**
219
+     * get display name of the user
220
+     * @param string $uid user ID of the user
221
+     * @return string display name
222
+     */
223
+    public function getDisplayName($uid) {
224
+        return $this->handleRequest($uid, 'getDisplayName', array($uid));
225
+    }
226 226
 
227
-	/**
228
-	 * checks whether the user is allowed to change his avatar in Nextcloud
229
-	 * @param string $uid the Nextcloud user name
230
-	 * @return boolean either the user can or cannot
231
-	 */
232
-	public function canChangeAvatar($uid) {
233
-		return $this->handleRequest($uid, 'canChangeAvatar', array($uid), true);
234
-	}
227
+    /**
228
+     * checks whether the user is allowed to change his avatar in Nextcloud
229
+     * @param string $uid the Nextcloud user name
230
+     * @return boolean either the user can or cannot
231
+     */
232
+    public function canChangeAvatar($uid) {
233
+        return $this->handleRequest($uid, 'canChangeAvatar', array($uid), true);
234
+    }
235 235
 
236
-	/**
237
-	 * Get a list of all display names and user ids.
238
-	 * @param string $search
239
-	 * @param string|null $limit
240
-	 * @param string|null $offset
241
-	 * @return array an array of all displayNames (value) and the corresponding uids (key)
242
-	 */
243
-	public function getDisplayNames($search = '', $limit = null, $offset = null) {
244
-		//we do it just as the /OC_User implementation: do not play around with limit and offset but ask all backends
245
-		$users = array();
246
-		foreach($this->backends as $backend) {
247
-			$backendUsers = $backend->getDisplayNames($search, $limit, $offset);
248
-			if (is_array($backendUsers)) {
249
-				$users = $users + $backendUsers;
250
-			}
251
-		}
252
-		return $users;
253
-	}
236
+    /**
237
+     * Get a list of all display names and user ids.
238
+     * @param string $search
239
+     * @param string|null $limit
240
+     * @param string|null $offset
241
+     * @return array an array of all displayNames (value) and the corresponding uids (key)
242
+     */
243
+    public function getDisplayNames($search = '', $limit = null, $offset = null) {
244
+        //we do it just as the /OC_User implementation: do not play around with limit and offset but ask all backends
245
+        $users = array();
246
+        foreach($this->backends as $backend) {
247
+            $backendUsers = $backend->getDisplayNames($search, $limit, $offset);
248
+            if (is_array($backendUsers)) {
249
+                $users = $users + $backendUsers;
250
+            }
251
+        }
252
+        return $users;
253
+    }
254 254
 
255
-	/**
256
-	 * delete a user
257
-	 * @param string $uid The username of the user to delete
258
-	 * @return bool
259
-	 *
260
-	 * Deletes a user
261
-	 */
262
-	public function deleteUser($uid) {
263
-		return $this->handleRequest($uid, 'deleteUser', array($uid));
264
-	}
255
+    /**
256
+     * delete a user
257
+     * @param string $uid The username of the user to delete
258
+     * @return bool
259
+     *
260
+     * Deletes a user
261
+     */
262
+    public function deleteUser($uid) {
263
+        return $this->handleRequest($uid, 'deleteUser', array($uid));
264
+    }
265 265
 	
266
-	/**
267
-	 * Set password
268
-	 * @param string $uid The username
269
-	 * @param string $password The new password
270
-	 * @return bool
271
-	 *
272
-	 */
273
-	public function setPassword($uid, $password) {
274
-		return $this->handleRequest($uid, 'setPassword', array($uid, $password));
275
-	}
266
+    /**
267
+     * Set password
268
+     * @param string $uid The username
269
+     * @param string $password The new password
270
+     * @return bool
271
+     *
272
+     */
273
+    public function setPassword($uid, $password) {
274
+        return $this->handleRequest($uid, 'setPassword', array($uid, $password));
275
+    }
276 276
 
277
-	/**
278
-	 * @return bool
279
-	 */
280
-	public function hasUserListings() {
281
-		return $this->refBackend->hasUserListings();
282
-	}
277
+    /**
278
+     * @return bool
279
+     */
280
+    public function hasUserListings() {
281
+        return $this->refBackend->hasUserListings();
282
+    }
283 283
 
284
-	/**
285
-	 * Count the number of users
286
-	 * @return int|bool
287
-	 */
288
-	public function countUsers() {
289
-		$users = false;
290
-		foreach($this->backends as $backend) {
291
-			$backendUsers = $backend->countUsers();
292
-			if ($backendUsers !== false) {
293
-				$users += $backendUsers;
294
-			}
295
-		}
296
-		return $users;
297
-	}
284
+    /**
285
+     * Count the number of users
286
+     * @return int|bool
287
+     */
288
+    public function countUsers() {
289
+        $users = false;
290
+        foreach($this->backends as $backend) {
291
+            $backendUsers = $backend->countUsers();
292
+            if ($backendUsers !== false) {
293
+                $users += $backendUsers;
294
+            }
295
+        }
296
+        return $users;
297
+    }
298 298
 
299
-	/**
300
-	 * Return access for LDAP interaction.
301
-	 * @param string $uid
302
-	 * @return Access instance of Access for LDAP interaction
303
-	 */
304
-	public function getLDAPAccess($uid) {
305
-		return $this->handleRequest($uid, 'getLDAPAccess', array($uid));
306
-	}
299
+    /**
300
+     * Return access for LDAP interaction.
301
+     * @param string $uid
302
+     * @return Access instance of Access for LDAP interaction
303
+     */
304
+    public function getLDAPAccess($uid) {
305
+        return $this->handleRequest($uid, 'getLDAPAccess', array($uid));
306
+    }
307 307
 	
308
-	/**
309
-	 * Return a new LDAP connection for the specified user.
310
-	 * The connection needs to be closed manually.
311
-	 * @param string $uid
312
-	 * @return resource of the LDAP connection
313
-	 */
314
-	public function getNewLDAPConnection($uid) {
315
-		return $this->handleRequest($uid, 'getNewLDAPConnection', array($uid));
316
-	}
308
+    /**
309
+     * Return a new LDAP connection for the specified user.
310
+     * The connection needs to be closed manually.
311
+     * @param string $uid
312
+     * @return resource of the LDAP connection
313
+     */
314
+    public function getNewLDAPConnection($uid) {
315
+        return $this->handleRequest($uid, 'getNewLDAPConnection', array($uid));
316
+    }
317 317
 }
Please login to merge, or discard this patch.
apps/dav/lib/Connector/Sabre/Auth.php 2 patches
Indentation   +192 added lines, -192 removed lines patch added patch discarded remove patch
@@ -48,212 +48,212 @@
 block discarded – undo
48 48
 class Auth extends AbstractBasic {
49 49
 
50 50
 
51
-	const DAV_AUTHENTICATED = 'AUTHENTICATED_TO_DAV_BACKEND';
51
+    const DAV_AUTHENTICATED = 'AUTHENTICATED_TO_DAV_BACKEND';
52 52
 
53
-	/** @var ISession */
54
-	private $session;
55
-	/** @var Session */
56
-	private $userSession;
57
-	/** @var IRequest */
58
-	private $request;
59
-	/** @var string */
60
-	private $currentUser;
61
-	/** @var Manager */
62
-	private $twoFactorManager;
63
-	/** @var Throttler */
64
-	private $throttler;
53
+    /** @var ISession */
54
+    private $session;
55
+    /** @var Session */
56
+    private $userSession;
57
+    /** @var IRequest */
58
+    private $request;
59
+    /** @var string */
60
+    private $currentUser;
61
+    /** @var Manager */
62
+    private $twoFactorManager;
63
+    /** @var Throttler */
64
+    private $throttler;
65 65
 
66
-	/**
67
-	 * @param ISession $session
68
-	 * @param Session $userSession
69
-	 * @param IRequest $request
70
-	 * @param Manager $twoFactorManager
71
-	 * @param Throttler $throttler
72
-	 * @param string $principalPrefix
73
-	 */
74
-	public function __construct(ISession $session,
75
-								Session $userSession,
76
-								IRequest $request,
77
-								Manager $twoFactorManager,
78
-								Throttler $throttler,
79
-								$principalPrefix = 'principals/users/') {
80
-		$this->session = $session;
81
-		$this->userSession = $userSession;
82
-		$this->twoFactorManager = $twoFactorManager;
83
-		$this->request = $request;
84
-		$this->throttler = $throttler;
85
-		$this->principalPrefix = $principalPrefix;
66
+    /**
67
+     * @param ISession $session
68
+     * @param Session $userSession
69
+     * @param IRequest $request
70
+     * @param Manager $twoFactorManager
71
+     * @param Throttler $throttler
72
+     * @param string $principalPrefix
73
+     */
74
+    public function __construct(ISession $session,
75
+                                Session $userSession,
76
+                                IRequest $request,
77
+                                Manager $twoFactorManager,
78
+                                Throttler $throttler,
79
+                                $principalPrefix = 'principals/users/') {
80
+        $this->session = $session;
81
+        $this->userSession = $userSession;
82
+        $this->twoFactorManager = $twoFactorManager;
83
+        $this->request = $request;
84
+        $this->throttler = $throttler;
85
+        $this->principalPrefix = $principalPrefix;
86 86
 
87
-		// setup realm
88
-		$defaults = new \OCP\Defaults();
89
-		$this->realm = $defaults->getName();
90
-	}
87
+        // setup realm
88
+        $defaults = new \OCP\Defaults();
89
+        $this->realm = $defaults->getName();
90
+    }
91 91
 
92
-	/**
93
-	 * Whether the user has initially authenticated via DAV
94
-	 *
95
-	 * This is required for WebDAV clients that resent the cookies even when the
96
-	 * account was changed.
97
-	 *
98
-	 * @see https://github.com/owncloud/core/issues/13245
99
-	 *
100
-	 * @param string $username
101
-	 * @return bool
102
-	 */
103
-	public function isDavAuthenticated($username) {
104
-		return !is_null($this->session->get(self::DAV_AUTHENTICATED)) &&
105
-		$this->session->get(self::DAV_AUTHENTICATED) === $username;
106
-	}
92
+    /**
93
+     * Whether the user has initially authenticated via DAV
94
+     *
95
+     * This is required for WebDAV clients that resent the cookies even when the
96
+     * account was changed.
97
+     *
98
+     * @see https://github.com/owncloud/core/issues/13245
99
+     *
100
+     * @param string $username
101
+     * @return bool
102
+     */
103
+    public function isDavAuthenticated($username) {
104
+        return !is_null($this->session->get(self::DAV_AUTHENTICATED)) &&
105
+        $this->session->get(self::DAV_AUTHENTICATED) === $username;
106
+    }
107 107
 
108
-	/**
109
-	 * Validates a username and password
110
-	 *
111
-	 * This method should return true or false depending on if login
112
-	 * succeeded.
113
-	 *
114
-	 * @param string $username
115
-	 * @param string $password
116
-	 * @return bool
117
-	 * @throws PasswordLoginForbidden
118
-	 */
119
-	protected function validateUserPass($username, $password) {
120
-		if ($this->userSession->isLoggedIn() &&
121
-			$this->isDavAuthenticated($this->userSession->getUser()->getUID())
122
-		) {
123
-			\OC_Util::setupFS($this->userSession->getUser()->getUID());
124
-			$this->session->close();
125
-			return true;
126
-		} else {
127
-			\OC_Util::setupFS(); //login hooks may need early access to the filesystem
128
-			try {
129
-				if ($this->userSession->logClientIn($username, $password, $this->request, $this->throttler)) {
130
-					\OC_Util::setupFS($this->userSession->getUser()->getUID());
131
-					$this->session->set(self::DAV_AUTHENTICATED, $this->userSession->getUser()->getUID());
132
-					$this->session->close();
133
-					return true;
134
-				} else {
135
-					$this->session->close();
136
-					return false;
137
-				}
138
-			} catch (PasswordLoginForbiddenException $ex) {
139
-				$this->session->close();
140
-				throw new PasswordLoginForbidden();
141
-			}
142
-		}
143
-	}
108
+    /**
109
+     * Validates a username and password
110
+     *
111
+     * This method should return true or false depending on if login
112
+     * succeeded.
113
+     *
114
+     * @param string $username
115
+     * @param string $password
116
+     * @return bool
117
+     * @throws PasswordLoginForbidden
118
+     */
119
+    protected function validateUserPass($username, $password) {
120
+        if ($this->userSession->isLoggedIn() &&
121
+            $this->isDavAuthenticated($this->userSession->getUser()->getUID())
122
+        ) {
123
+            \OC_Util::setupFS($this->userSession->getUser()->getUID());
124
+            $this->session->close();
125
+            return true;
126
+        } else {
127
+            \OC_Util::setupFS(); //login hooks may need early access to the filesystem
128
+            try {
129
+                if ($this->userSession->logClientIn($username, $password, $this->request, $this->throttler)) {
130
+                    \OC_Util::setupFS($this->userSession->getUser()->getUID());
131
+                    $this->session->set(self::DAV_AUTHENTICATED, $this->userSession->getUser()->getUID());
132
+                    $this->session->close();
133
+                    return true;
134
+                } else {
135
+                    $this->session->close();
136
+                    return false;
137
+                }
138
+            } catch (PasswordLoginForbiddenException $ex) {
139
+                $this->session->close();
140
+                throw new PasswordLoginForbidden();
141
+            }
142
+        }
143
+    }
144 144
 
145
-	/**
146
-	 * @param RequestInterface $request
147
-	 * @param ResponseInterface $response
148
-	 * @return array
149
-	 * @throws NotAuthenticated
150
-	 * @throws ServiceUnavailable
151
-	 */
152
-	function check(RequestInterface $request, ResponseInterface $response) {
153
-		try {
154
-			$result = $this->auth($request, $response);
155
-			return $result;
156
-		} catch (NotAuthenticated $e) {
157
-			throw $e;
158
-		} catch (Exception $e) {
159
-			$class = get_class($e);
160
-			$msg = $e->getMessage();
161
-			\OC::$server->getLogger()->logException($e);
162
-			throw new ServiceUnavailable("$class: $msg");
163
-		}
164
-	}
145
+    /**
146
+     * @param RequestInterface $request
147
+     * @param ResponseInterface $response
148
+     * @return array
149
+     * @throws NotAuthenticated
150
+     * @throws ServiceUnavailable
151
+     */
152
+    function check(RequestInterface $request, ResponseInterface $response) {
153
+        try {
154
+            $result = $this->auth($request, $response);
155
+            return $result;
156
+        } catch (NotAuthenticated $e) {
157
+            throw $e;
158
+        } catch (Exception $e) {
159
+            $class = get_class($e);
160
+            $msg = $e->getMessage();
161
+            \OC::$server->getLogger()->logException($e);
162
+            throw new ServiceUnavailable("$class: $msg");
163
+        }
164
+    }
165 165
 
166
-	/**
167
-	 * Checks whether a CSRF check is required on the request
168
-	 *
169
-	 * @return bool
170
-	 */
171
-	private function requiresCSRFCheck() {
172
-		// GET requires no check at all
173
-		if($this->request->getMethod() === 'GET') {
174
-			return false;
175
-		}
166
+    /**
167
+     * Checks whether a CSRF check is required on the request
168
+     *
169
+     * @return bool
170
+     */
171
+    private function requiresCSRFCheck() {
172
+        // GET requires no check at all
173
+        if($this->request->getMethod() === 'GET') {
174
+            return false;
175
+        }
176 176
 
177
-		// Official Nextcloud clients require no checks
178
-		if($this->request->isUserAgent([
179
-			IRequest::USER_AGENT_CLIENT_DESKTOP,
180
-			IRequest::USER_AGENT_CLIENT_ANDROID,
181
-			IRequest::USER_AGENT_CLIENT_IOS,
182
-		])) {
183
-			return false;
184
-		}
177
+        // Official Nextcloud clients require no checks
178
+        if($this->request->isUserAgent([
179
+            IRequest::USER_AGENT_CLIENT_DESKTOP,
180
+            IRequest::USER_AGENT_CLIENT_ANDROID,
181
+            IRequest::USER_AGENT_CLIENT_IOS,
182
+        ])) {
183
+            return false;
184
+        }
185 185
 
186
-		// If not logged-in no check is required
187
-		if(!$this->userSession->isLoggedIn()) {
188
-			return false;
189
-		}
186
+        // If not logged-in no check is required
187
+        if(!$this->userSession->isLoggedIn()) {
188
+            return false;
189
+        }
190 190
 
191
-		// POST always requires a check
192
-		if($this->request->getMethod() === 'POST') {
193
-			return true;
194
-		}
191
+        // POST always requires a check
192
+        if($this->request->getMethod() === 'POST') {
193
+            return true;
194
+        }
195 195
 
196
-		// If logged-in AND DAV authenticated no check is required
197
-		if($this->userSession->isLoggedIn() &&
198
-			$this->isDavAuthenticated($this->userSession->getUser()->getUID())) {
199
-			return false;
200
-		}
196
+        // If logged-in AND DAV authenticated no check is required
197
+        if($this->userSession->isLoggedIn() &&
198
+            $this->isDavAuthenticated($this->userSession->getUser()->getUID())) {
199
+            return false;
200
+        }
201 201
 
202
-		return true;
203
-	}
202
+        return true;
203
+    }
204 204
 
205
-	/**
206
-	 * @param RequestInterface $request
207
-	 * @param ResponseInterface $response
208
-	 * @return array
209
-	 * @throws NotAuthenticated
210
-	 */
211
-	private function auth(RequestInterface $request, ResponseInterface $response) {
212
-		$forcedLogout = false;
213
-		if(!$this->request->passesCSRFCheck() &&
214
-			$this->requiresCSRFCheck()) {
215
-			// In case of a fail with POST we need to recheck the credentials
216
-			if($this->request->getMethod() === 'POST') {
217
-				$forcedLogout = true;
218
-			} else {
219
-				$response->setStatus(401);
220
-				throw new \Sabre\DAV\Exception\NotAuthenticated('CSRF check not passed.');
221
-			}
222
-		}
205
+    /**
206
+     * @param RequestInterface $request
207
+     * @param ResponseInterface $response
208
+     * @return array
209
+     * @throws NotAuthenticated
210
+     */
211
+    private function auth(RequestInterface $request, ResponseInterface $response) {
212
+        $forcedLogout = false;
213
+        if(!$this->request->passesCSRFCheck() &&
214
+            $this->requiresCSRFCheck()) {
215
+            // In case of a fail with POST we need to recheck the credentials
216
+            if($this->request->getMethod() === 'POST') {
217
+                $forcedLogout = true;
218
+            } else {
219
+                $response->setStatus(401);
220
+                throw new \Sabre\DAV\Exception\NotAuthenticated('CSRF check not passed.');
221
+            }
222
+        }
223 223
 
224
-		if($forcedLogout) {
225
-			$this->userSession->logout();
226
-		} else {
227
-			if($this->twoFactorManager->needsSecondFactor($this->userSession->getUser())) {
228
-				throw new \Sabre\DAV\Exception\NotAuthenticated('2FA challenge not passed.');
229
-			}
230
-			if (\OC_User::handleApacheAuth() ||
231
-				//Fix for broken webdav clients
232
-				($this->userSession->isLoggedIn() && is_null($this->session->get(self::DAV_AUTHENTICATED))) ||
233
-				//Well behaved clients that only send the cookie are allowed
234
-				($this->userSession->isLoggedIn() && $this->session->get(self::DAV_AUTHENTICATED) === $this->userSession->getUser()->getUID() && $request->getHeader('Authorization') === null)
235
-			) {
236
-				$user = $this->userSession->getUser()->getUID();
237
-				\OC_Util::setupFS($user);
238
-				$this->currentUser = $user;
239
-				$this->session->close();
240
-				return [true, $this->principalPrefix . $user];
241
-			}
242
-		}
224
+        if($forcedLogout) {
225
+            $this->userSession->logout();
226
+        } else {
227
+            if($this->twoFactorManager->needsSecondFactor($this->userSession->getUser())) {
228
+                throw new \Sabre\DAV\Exception\NotAuthenticated('2FA challenge not passed.');
229
+            }
230
+            if (\OC_User::handleApacheAuth() ||
231
+                //Fix for broken webdav clients
232
+                ($this->userSession->isLoggedIn() && is_null($this->session->get(self::DAV_AUTHENTICATED))) ||
233
+                //Well behaved clients that only send the cookie are allowed
234
+                ($this->userSession->isLoggedIn() && $this->session->get(self::DAV_AUTHENTICATED) === $this->userSession->getUser()->getUID() && $request->getHeader('Authorization') === null)
235
+            ) {
236
+                $user = $this->userSession->getUser()->getUID();
237
+                \OC_Util::setupFS($user);
238
+                $this->currentUser = $user;
239
+                $this->session->close();
240
+                return [true, $this->principalPrefix . $user];
241
+            }
242
+        }
243 243
 
244
-		if (!$this->userSession->isLoggedIn() && in_array('XMLHttpRequest', explode(',', $request->getHeader('X-Requested-With')))) {
245
-			// do not re-authenticate over ajax, use dummy auth name to prevent browser popup
246
-			$response->addHeader('WWW-Authenticate','DummyBasic realm="' . $this->realm . '"');
247
-			$response->setStatus(401);
248
-			throw new \Sabre\DAV\Exception\NotAuthenticated('Cannot authenticate over ajax calls');
249
-		}
244
+        if (!$this->userSession->isLoggedIn() && in_array('XMLHttpRequest', explode(',', $request->getHeader('X-Requested-With')))) {
245
+            // do not re-authenticate over ajax, use dummy auth name to prevent browser popup
246
+            $response->addHeader('WWW-Authenticate','DummyBasic realm="' . $this->realm . '"');
247
+            $response->setStatus(401);
248
+            throw new \Sabre\DAV\Exception\NotAuthenticated('Cannot authenticate over ajax calls');
249
+        }
250 250
 
251
-		$data = parent::check($request, $response);
252
-		if($data[0] === true) {
253
-			$startPos = strrpos($data[1], '/') + 1;
254
-			$user = $this->userSession->getUser()->getUID();
255
-			$data[1] = substr_replace($data[1], $user, $startPos);
256
-		}
257
-		return $data;
258
-	}
251
+        $data = parent::check($request, $response);
252
+        if($data[0] === true) {
253
+            $startPos = strrpos($data[1], '/') + 1;
254
+            $user = $this->userSession->getUser()->getUID();
255
+            $data[1] = substr_replace($data[1], $user, $startPos);
256
+        }
257
+        return $data;
258
+    }
259 259
 }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -170,12 +170,12 @@  discard block
 block discarded – undo
170 170
 	 */
171 171
 	private function requiresCSRFCheck() {
172 172
 		// GET requires no check at all
173
-		if($this->request->getMethod() === 'GET') {
173
+		if ($this->request->getMethod() === 'GET') {
174 174
 			return false;
175 175
 		}
176 176
 
177 177
 		// Official Nextcloud clients require no checks
178
-		if($this->request->isUserAgent([
178
+		if ($this->request->isUserAgent([
179 179
 			IRequest::USER_AGENT_CLIENT_DESKTOP,
180 180
 			IRequest::USER_AGENT_CLIENT_ANDROID,
181 181
 			IRequest::USER_AGENT_CLIENT_IOS,
@@ -184,17 +184,17 @@  discard block
 block discarded – undo
184 184
 		}
185 185
 
186 186
 		// If not logged-in no check is required
187
-		if(!$this->userSession->isLoggedIn()) {
187
+		if (!$this->userSession->isLoggedIn()) {
188 188
 			return false;
189 189
 		}
190 190
 
191 191
 		// POST always requires a check
192
-		if($this->request->getMethod() === 'POST') {
192
+		if ($this->request->getMethod() === 'POST') {
193 193
 			return true;
194 194
 		}
195 195
 
196 196
 		// If logged-in AND DAV authenticated no check is required
197
-		if($this->userSession->isLoggedIn() &&
197
+		if ($this->userSession->isLoggedIn() &&
198 198
 			$this->isDavAuthenticated($this->userSession->getUser()->getUID())) {
199 199
 			return false;
200 200
 		}
@@ -210,10 +210,10 @@  discard block
 block discarded – undo
210 210
 	 */
211 211
 	private function auth(RequestInterface $request, ResponseInterface $response) {
212 212
 		$forcedLogout = false;
213
-		if(!$this->request->passesCSRFCheck() &&
213
+		if (!$this->request->passesCSRFCheck() &&
214 214
 			$this->requiresCSRFCheck()) {
215 215
 			// In case of a fail with POST we need to recheck the credentials
216
-			if($this->request->getMethod() === 'POST') {
216
+			if ($this->request->getMethod() === 'POST') {
217 217
 				$forcedLogout = true;
218 218
 			} else {
219 219
 				$response->setStatus(401);
@@ -221,10 +221,10 @@  discard block
 block discarded – undo
221 221
 			}
222 222
 		}
223 223
 
224
-		if($forcedLogout) {
224
+		if ($forcedLogout) {
225 225
 			$this->userSession->logout();
226 226
 		} else {
227
-			if($this->twoFactorManager->needsSecondFactor($this->userSession->getUser())) {
227
+			if ($this->twoFactorManager->needsSecondFactor($this->userSession->getUser())) {
228 228
 				throw new \Sabre\DAV\Exception\NotAuthenticated('2FA challenge not passed.');
229 229
 			}
230 230
 			if (\OC_User::handleApacheAuth() ||
@@ -237,19 +237,19 @@  discard block
 block discarded – undo
237 237
 				\OC_Util::setupFS($user);
238 238
 				$this->currentUser = $user;
239 239
 				$this->session->close();
240
-				return [true, $this->principalPrefix . $user];
240
+				return [true, $this->principalPrefix.$user];
241 241
 			}
242 242
 		}
243 243
 
244 244
 		if (!$this->userSession->isLoggedIn() && in_array('XMLHttpRequest', explode(',', $request->getHeader('X-Requested-With')))) {
245 245
 			// do not re-authenticate over ajax, use dummy auth name to prevent browser popup
246
-			$response->addHeader('WWW-Authenticate','DummyBasic realm="' . $this->realm . '"');
246
+			$response->addHeader('WWW-Authenticate', 'DummyBasic realm="'.$this->realm.'"');
247 247
 			$response->setStatus(401);
248 248
 			throw new \Sabre\DAV\Exception\NotAuthenticated('Cannot authenticate over ajax calls');
249 249
 		}
250 250
 
251 251
 		$data = parent::check($request, $response);
252
-		if($data[0] === true) {
252
+		if ($data[0] === true) {
253 253
 			$startPos = strrpos($data[1], '/') + 1;
254 254
 			$user = $this->userSession->getUser()->getUID();
255 255
 			$data[1] = substr_replace($data[1], $user, $startPos);
Please login to merge, or discard this patch.
apps/dav/lib/Connector/Sabre/ServerFactory.php 1 patch
Indentation   +145 added lines, -145 removed lines patch added patch discarded remove patch
@@ -42,158 +42,158 @@
 block discarded – undo
42 42
 use Sabre\DAV\Auth\Backend\BackendInterface;
43 43
 
44 44
 class ServerFactory {
45
-	/** @var IConfig */
46
-	private $config;
47
-	/** @var ILogger */
48
-	private $logger;
49
-	/** @var IDBConnection */
50
-	private $databaseConnection;
51
-	/** @var IUserSession */
52
-	private $userSession;
53
-	/** @var IMountManager */
54
-	private $mountManager;
55
-	/** @var ITagManager */
56
-	private $tagManager;
57
-	/** @var IRequest */
58
-	private $request;
59
-	/** @var IPreview  */
60
-	private $previewManager;
45
+    /** @var IConfig */
46
+    private $config;
47
+    /** @var ILogger */
48
+    private $logger;
49
+    /** @var IDBConnection */
50
+    private $databaseConnection;
51
+    /** @var IUserSession */
52
+    private $userSession;
53
+    /** @var IMountManager */
54
+    private $mountManager;
55
+    /** @var ITagManager */
56
+    private $tagManager;
57
+    /** @var IRequest */
58
+    private $request;
59
+    /** @var IPreview  */
60
+    private $previewManager;
61 61
 
62
-	/**
63
-	 * @param IConfig $config
64
-	 * @param ILogger $logger
65
-	 * @param IDBConnection $databaseConnection
66
-	 * @param IUserSession $userSession
67
-	 * @param IMountManager $mountManager
68
-	 * @param ITagManager $tagManager
69
-	 * @param IRequest $request
70
-	 * @param IPreview $previewManager
71
-	 */
72
-	public function __construct(
73
-		IConfig $config,
74
-		ILogger $logger,
75
-		IDBConnection $databaseConnection,
76
-		IUserSession $userSession,
77
-		IMountManager $mountManager,
78
-		ITagManager $tagManager,
79
-		IRequest $request,
80
-		IPreview $previewManager
81
-	) {
82
-		$this->config = $config;
83
-		$this->logger = $logger;
84
-		$this->databaseConnection = $databaseConnection;
85
-		$this->userSession = $userSession;
86
-		$this->mountManager = $mountManager;
87
-		$this->tagManager = $tagManager;
88
-		$this->request = $request;
89
-		$this->previewManager = $previewManager;
90
-	}
62
+    /**
63
+     * @param IConfig $config
64
+     * @param ILogger $logger
65
+     * @param IDBConnection $databaseConnection
66
+     * @param IUserSession $userSession
67
+     * @param IMountManager $mountManager
68
+     * @param ITagManager $tagManager
69
+     * @param IRequest $request
70
+     * @param IPreview $previewManager
71
+     */
72
+    public function __construct(
73
+        IConfig $config,
74
+        ILogger $logger,
75
+        IDBConnection $databaseConnection,
76
+        IUserSession $userSession,
77
+        IMountManager $mountManager,
78
+        ITagManager $tagManager,
79
+        IRequest $request,
80
+        IPreview $previewManager
81
+    ) {
82
+        $this->config = $config;
83
+        $this->logger = $logger;
84
+        $this->databaseConnection = $databaseConnection;
85
+        $this->userSession = $userSession;
86
+        $this->mountManager = $mountManager;
87
+        $this->tagManager = $tagManager;
88
+        $this->request = $request;
89
+        $this->previewManager = $previewManager;
90
+    }
91 91
 
92
-	/**
93
-	 * @param string $baseUri
94
-	 * @param string $requestUri
95
-	 * @param BackendInterface $authBackend
96
-	 * @param callable $viewCallBack callback that should return the view for the dav endpoint
97
-	 * @return Server
98
-	 */
99
-	public function createServer($baseUri,
100
-								 $requestUri,
101
-								 BackendInterface $authBackend,
102
-								 callable $viewCallBack) {
103
-		// Fire up server
104
-		$objectTree = new \OCA\DAV\Connector\Sabre\ObjectTree();
105
-		$server = new \OCA\DAV\Connector\Sabre\Server($objectTree);
106
-		// Set URL explicitly due to reverse-proxy situations
107
-		$server->httpRequest->setUrl($requestUri);
108
-		$server->setBaseUri($baseUri);
92
+    /**
93
+     * @param string $baseUri
94
+     * @param string $requestUri
95
+     * @param BackendInterface $authBackend
96
+     * @param callable $viewCallBack callback that should return the view for the dav endpoint
97
+     * @return Server
98
+     */
99
+    public function createServer($baseUri,
100
+                                    $requestUri,
101
+                                    BackendInterface $authBackend,
102
+                                    callable $viewCallBack) {
103
+        // Fire up server
104
+        $objectTree = new \OCA\DAV\Connector\Sabre\ObjectTree();
105
+        $server = new \OCA\DAV\Connector\Sabre\Server($objectTree);
106
+        // Set URL explicitly due to reverse-proxy situations
107
+        $server->httpRequest->setUrl($requestUri);
108
+        $server->setBaseUri($baseUri);
109 109
 
110
-		// Load plugins
111
-		$server->addPlugin(new \OCA\DAV\Connector\Sabre\MaintenancePlugin($this->config));
112
-		$server->addPlugin(new \OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin($this->config));
113
-		$server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend));
114
-		// FIXME: The following line is a workaround for legacy components relying on being able to send a GET to /
115
-		$server->addPlugin(new \OCA\DAV\Connector\Sabre\DummyGetResponsePlugin());
116
-		$server->addPlugin(new \OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin('webdav', $this->logger));
117
-		$server->addPlugin(new \OCA\DAV\Connector\Sabre\LockPlugin());
118
-		// Some WebDAV clients do require Class 2 WebDAV support (locking), since
119
-		// we do not provide locking we emulate it using a fake locking plugin.
120
-		if($this->request->isUserAgent([
121
-				'/WebDAVFS/',
122
-				'/Microsoft Office OneNote 2013/',
123
-				'/Microsoft-WebDAV-MiniRedir/',
124
-		])) {
125
-			$server->addPlugin(new \OCA\DAV\Connector\Sabre\FakeLockerPlugin());
126
-		}
110
+        // Load plugins
111
+        $server->addPlugin(new \OCA\DAV\Connector\Sabre\MaintenancePlugin($this->config));
112
+        $server->addPlugin(new \OCA\DAV\Connector\Sabre\BlockLegacyClientPlugin($this->config));
113
+        $server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend));
114
+        // FIXME: The following line is a workaround for legacy components relying on being able to send a GET to /
115
+        $server->addPlugin(new \OCA\DAV\Connector\Sabre\DummyGetResponsePlugin());
116
+        $server->addPlugin(new \OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin('webdav', $this->logger));
117
+        $server->addPlugin(new \OCA\DAV\Connector\Sabre\LockPlugin());
118
+        // Some WebDAV clients do require Class 2 WebDAV support (locking), since
119
+        // we do not provide locking we emulate it using a fake locking plugin.
120
+        if($this->request->isUserAgent([
121
+                '/WebDAVFS/',
122
+                '/Microsoft Office OneNote 2013/',
123
+                '/Microsoft-WebDAV-MiniRedir/',
124
+        ])) {
125
+            $server->addPlugin(new \OCA\DAV\Connector\Sabre\FakeLockerPlugin());
126
+        }
127 127
 
128
-		if (BrowserErrorPagePlugin::isBrowserRequest($this->request)) {
129
-			$server->addPlugin(new BrowserErrorPagePlugin());
130
-		}
128
+        if (BrowserErrorPagePlugin::isBrowserRequest($this->request)) {
129
+            $server->addPlugin(new BrowserErrorPagePlugin());
130
+        }
131 131
 
132
-		// wait with registering these until auth is handled and the filesystem is setup
133
-		$server->on('beforeMethod', function () use ($server, $objectTree, $viewCallBack) {
134
-			// ensure the skeleton is copied
135
-			$userFolder = \OC::$server->getUserFolder();
132
+        // wait with registering these until auth is handled and the filesystem is setup
133
+        $server->on('beforeMethod', function () use ($server, $objectTree, $viewCallBack) {
134
+            // ensure the skeleton is copied
135
+            $userFolder = \OC::$server->getUserFolder();
136 136
 			
137
-			/** @var \OC\Files\View $view */
138
-			$view = $viewCallBack($server);
139
-			if ($userFolder instanceof Folder && $userFolder->getPath() === $view->getRoot()) {
140
-				$rootInfo = $userFolder;
141
-			} else {
142
-				$rootInfo = $view->getFileInfo('');
143
-			}
137
+            /** @var \OC\Files\View $view */
138
+            $view = $viewCallBack($server);
139
+            if ($userFolder instanceof Folder && $userFolder->getPath() === $view->getRoot()) {
140
+                $rootInfo = $userFolder;
141
+            } else {
142
+                $rootInfo = $view->getFileInfo('');
143
+            }
144 144
 
145
-			// Create Nextcloud Dir
146
-			if ($rootInfo->getType() === 'dir') {
147
-				$root = new \OCA\DAV\Connector\Sabre\Directory($view, $rootInfo, $objectTree);
148
-			} else {
149
-				$root = new \OCA\DAV\Connector\Sabre\File($view, $rootInfo);
150
-			}
151
-			$objectTree->init($root, $view, $this->mountManager);
145
+            // Create Nextcloud Dir
146
+            if ($rootInfo->getType() === 'dir') {
147
+                $root = new \OCA\DAV\Connector\Sabre\Directory($view, $rootInfo, $objectTree);
148
+            } else {
149
+                $root = new \OCA\DAV\Connector\Sabre\File($view, $rootInfo);
150
+            }
151
+            $objectTree->init($root, $view, $this->mountManager);
152 152
 
153
-			$server->addPlugin(
154
-				new \OCA\DAV\Connector\Sabre\FilesPlugin(
155
-					$objectTree,
156
-					$this->config,
157
-					$this->request,
158
-					$this->previewManager,
159
-					false,
160
-					!$this->config->getSystemValue('debug', false)
161
-				)
162
-			);
163
-			$server->addPlugin(new \OCA\DAV\Connector\Sabre\QuotaPlugin($view));
153
+            $server->addPlugin(
154
+                new \OCA\DAV\Connector\Sabre\FilesPlugin(
155
+                    $objectTree,
156
+                    $this->config,
157
+                    $this->request,
158
+                    $this->previewManager,
159
+                    false,
160
+                    !$this->config->getSystemValue('debug', false)
161
+                )
162
+            );
163
+            $server->addPlugin(new \OCA\DAV\Connector\Sabre\QuotaPlugin($view));
164 164
 
165
-			if($this->userSession->isLoggedIn()) {
166
-				$server->addPlugin(new \OCA\DAV\Connector\Sabre\TagsPlugin($objectTree, $this->tagManager));
167
-				$server->addPlugin(new \OCA\DAV\Connector\Sabre\SharesPlugin(
168
-					$objectTree,
169
-					$this->userSession,
170
-					$userFolder,
171
-					\OC::$server->getShareManager()
172
-				));
173
-				$server->addPlugin(new \OCA\DAV\Connector\Sabre\CommentPropertiesPlugin(\OC::$server->getCommentsManager(), $this->userSession));
174
-				$server->addPlugin(new \OCA\DAV\Connector\Sabre\FilesReportPlugin(
175
-					$objectTree,
176
-					$view,
177
-					\OC::$server->getSystemTagManager(),
178
-					\OC::$server->getSystemTagObjectMapper(),
179
-					\OC::$server->getTagManager(),
180
-					$this->userSession,
181
-					\OC::$server->getGroupManager(),
182
-					$userFolder
183
-				));
184
-				// custom properties plugin must be the last one
185
-				$server->addPlugin(
186
-					new \Sabre\DAV\PropertyStorage\Plugin(
187
-						new \OCA\DAV\Connector\Sabre\CustomPropertiesBackend(
188
-							$objectTree,
189
-							$this->databaseConnection,
190
-							$this->userSession->getUser()
191
-						)
192
-					)
193
-				);
194
-			}
195
-			$server->addPlugin(new \OCA\DAV\Connector\Sabre\CopyEtagHeaderPlugin());
196
-		}, 30); // priority 30: after auth (10) and acl(20), before lock(50) and handling the request
197
-		return $server;
198
-	}
165
+            if($this->userSession->isLoggedIn()) {
166
+                $server->addPlugin(new \OCA\DAV\Connector\Sabre\TagsPlugin($objectTree, $this->tagManager));
167
+                $server->addPlugin(new \OCA\DAV\Connector\Sabre\SharesPlugin(
168
+                    $objectTree,
169
+                    $this->userSession,
170
+                    $userFolder,
171
+                    \OC::$server->getShareManager()
172
+                ));
173
+                $server->addPlugin(new \OCA\DAV\Connector\Sabre\CommentPropertiesPlugin(\OC::$server->getCommentsManager(), $this->userSession));
174
+                $server->addPlugin(new \OCA\DAV\Connector\Sabre\FilesReportPlugin(
175
+                    $objectTree,
176
+                    $view,
177
+                    \OC::$server->getSystemTagManager(),
178
+                    \OC::$server->getSystemTagObjectMapper(),
179
+                    \OC::$server->getTagManager(),
180
+                    $this->userSession,
181
+                    \OC::$server->getGroupManager(),
182
+                    $userFolder
183
+                ));
184
+                // custom properties plugin must be the last one
185
+                $server->addPlugin(
186
+                    new \Sabre\DAV\PropertyStorage\Plugin(
187
+                        new \OCA\DAV\Connector\Sabre\CustomPropertiesBackend(
188
+                            $objectTree,
189
+                            $this->databaseConnection,
190
+                            $this->userSession->getUser()
191
+                        )
192
+                    )
193
+                );
194
+            }
195
+            $server->addPlugin(new \OCA\DAV\Connector\Sabre\CopyEtagHeaderPlugin());
196
+        }, 30); // priority 30: after auth (10) and acl(20), before lock(50) and handling the request
197
+        return $server;
198
+    }
199 199
 }
Please login to merge, or discard this patch.