Completed
Push — master ( 0a312f...e14633 )
by Thomas
27:43 queued 11:29
created

Principal::findByUri()   B

Complexity

Conditions 5
Paths 7

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 12
nc 7
nop 2
dl 0
loc 18
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Bart Visscher <[email protected]>
4
 * @author Jakob Sack <[email protected]>
5
 * @author Jörn Friedrich Dreyer <[email protected]>
6
 * @author Lukas Reschke <[email protected]>
7
 * @author Morris Jobke <[email protected]>
8
 * @author Thomas Müller <[email protected]>
9
 * @author Thomas Tanghus <[email protected]>
10
 * @author Vincent Petry <[email protected]>
11
 *
12
 * @copyright Copyright (c) 2018, ownCloud GmbH
13
 * @license AGPL-3.0
14
 *
15
 * This code is free software: you can redistribute it and/or modify
16
 * it under the terms of the GNU Affero General Public License, version 3,
17
 * as published by the Free Software Foundation.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
 * GNU Affero General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU Affero General Public License, version 3,
25
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
26
 *
27
 */
28
29
namespace OCA\DAV\Connector\Sabre;
30
31
use OCP\IGroup;
32
use OCP\IGroupManager;
33
use OCP\IUser;
34
use OCP\IUserManager;
35
use Sabre\DAV\Exception;
36
use Sabre\DAV\PropPatch;
37
use Sabre\DAVACL\PrincipalBackend\BackendInterface;
38
use Sabre\HTTP\URLUtil;
39
40
class Principal implements BackendInterface {
41
42
	/** @var IUserManager */
43
	private $userManager;
44
45
	/** @var IGroupManager */
46
	private $groupManager;
47
48
	/** @var string */
49
	private $principalPrefix;
50
51
	/** @var bool */
52
	private $hasGroups;
53
54
	/**
55
	 * @param IUserManager $userManager
56
	 * @param IGroupManager $groupManager
57
	 * @param string $principalPrefix
58
	 */
59
	public function __construct(IUserManager $userManager,
60
								IGroupManager $groupManager,
61
								$principalPrefix = 'principals/users/') {
62
		$this->userManager = $userManager;
63
		$this->groupManager = $groupManager;
64
		$this->principalPrefix = trim($principalPrefix, '/');
65
		$this->hasGroups = ($principalPrefix === 'principals/users/');
66
	}
67
68
	/**
69
	 * Returns a list of principals based on a prefix.
70
	 *
71
	 * This prefix will often contain something like 'principals'. You are only
72
	 * expected to return principals that are in this base path.
73
	 *
74
	 * You are expected to return at least a 'uri' for every user, you can
75
	 * return any additional properties if you wish so. Common properties are:
76
	 *   {DAV:}displayname
77
	 *
78
	 * @param string $prefixPath
79
	 * @return string[]
80
	 */
81
	public function getPrincipalsByPrefix($prefixPath) {
82
		$principals = [];
83
84
		if ($prefixPath === $this->principalPrefix) {
85
			foreach($this->userManager->search('') as $user) {
86
				$principals[] = $this->userToPrincipal($user);
87
			}
88
		}
89
90
		return $principals;
91
	}
92
93
	/**
94
	 * Returns a specific principal, specified by it's path.
95
	 * The returned structure should be the exact same as from
96
	 * getPrincipalsByPrefix.
97
	 *
98
	 * @param string $path
99
	 * @return array
100
	 */
101
	public function getPrincipalByPath($path) {
102
		list($prefix, $name) = URLUtil::splitPath($path);
103
104
		if ($prefix === $this->principalPrefix) {
105
			$user = $this->userManager->get($name);
106
107
			if (!is_null($user)) {
108
				return $this->userToPrincipal($user);
109
			}
110
		}
111
		return null;
112
	}
113
114
	/**
115
	 * Returns the list of members for a group-principal
116
	 *
117
	 * @param string $principal
118
	 * @return string[]
119
	 * @throws Exception
120
	 */
121 View Code Duplication
	public function getGroupMemberSet($principal) {
122
		// TODO: for now the group principal has only one member, the user itself
123
		$principal = $this->getPrincipalByPath($principal);
124
		if (!$principal) {
125
			throw new Exception('Principal not found');
126
		}
127
128
		return [$principal['uri']];
129
	}
130
131
	/**
132
	 * Returns the list of groups a principal is a member of
133
	 *
134
	 * @param string $principal
135
	 * @param bool $needGroups
136
	 * @return array
137
	 * @throws Exception
138
	 */
139
	public function getGroupMembership($principal, $needGroups = false) {
140
		list($prefix, $name) = URLUtil::splitPath($principal);
141
142
		if ($prefix === $this->principalPrefix) {
143
			$user = $this->userManager->get($name);
144
			if (!$user) {
145
				throw new Exception('Principal not found');
146
			}
147
148
			if ($this->hasGroups || $needGroups) {
149
				$groups = $this->groupManager->getUserGroups($user);
150
				$groups = array_map(function($group) {
151
					/** @var IGroup $group */
152
					return 'principals/groups/' . $group->getGID();
153
				}, $groups);
154
155
				return $groups;
156
			}
157
		}
158
		return [];
159
	}
160
161
	/**
162
	 * Updates the list of group members for a group principal.
163
	 *
164
	 * The principals should be passed as a list of uri's.
165
	 *
166
	 * @param string $principal
167
	 * @param string[] $members
168
	 * @throws Exception
169
	 */
170
	public function setGroupMemberSet($principal, array $members) {
171
		throw new Exception('Setting members of the group is not supported yet');
172
	}
173
174
	/**
175
	 * @param string $path
176
	 * @param PropPatch $propPatch
177
	 * @return int
178
	 */
179
	function updatePrincipal($path, PropPatch $propPatch) {
180
		return 0;
181
	}
182
183
	/**
184
	 * @param string $prefixPath
185
	 * @param array $searchProperties
186
	 * @param string $test
187
	 * @return array
188
	 */
189
	function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof') {
190
		return [];
191
	}
192
193
	/**
194
	 * @param string $uri
195
	 * @param string $principalPrefix
196
	 * @return string
197
	 */
198
	function findByUri($uri, $principalPrefix) {
199
		if (substr($uri, 0, 7) === 'mailto:') {
200
			$email = substr($uri, 7);
201
			$users = $this->userManager->getByEmail($email);
202
			if (count($users) === 1) {
203
				return $this->principalPrefix . '/' . $users[0]->getUID();
204
			}
205
		}
206
		if (substr($uri, 0, 10) === 'principal:') {
207
			$principal = substr($uri, 10);
208
			$principal = $this->getPrincipalByPath($principal);
209
			if ($principal !== null) {
210
				return $principal['uri'];
211
			}
212
		}
213
214
		return '';
215
	}
216
217
	/**
218
	 * @param IUser $user
219
	 * @return array
220
	 */
221
	protected function userToPrincipal($user) {
222
		$userId = $user->getUID();
223
		$displayName = $user->getDisplayName();
224
		$principal = [
225
				'uri' => $this->principalPrefix . '/' . $userId,
226
				'{DAV:}displayname' => is_null($displayName) ? $userId : $displayName,
227
		];
228
229
		$email = $user->getEMailAddress();
230
		if (!empty($email)) {
231
			$principal['{http://sabredav.org/ns}email-address'] = $email;
232
		}
233
234
		return $principal;
235
	}
236
237
	public function getPrincipalPrefix() {
238
		return $this->principalPrefix;
239
	}
240
241
}
242