Passed
Push — master ( f0dd71...c56a27 )
by Christoph
11:49 queued 12s
created
apps/dav/lib/DAV/GroupPrincipalBackend.php 1 patch
Indentation   +290 added lines, -290 removed lines patch added patch discarded remove patch
@@ -37,294 +37,294 @@
 block discarded – undo
37 37
 
38 38
 class GroupPrincipalBackend implements BackendInterface {
39 39
 
40
-	const PRINCIPAL_PREFIX = 'principals/groups';
41
-
42
-	/** @var IGroupManager */
43
-	private $groupManager;
44
-
45
-	/** @var IUserSession */
46
-	private $userSession;
47
-
48
-	/** @var IShareManager */
49
-	private $shareManager;
50
-
51
-	/**
52
-	 * @param IGroupManager $IGroupManager
53
-	 * @param IUserSession $userSession
54
-	 * @param IShareManager $shareManager
55
-	 */
56
-	public function __construct(IGroupManager $IGroupManager,
57
-								IUserSession $userSession,
58
-								IShareManager $shareManager) {
59
-		$this->groupManager = $IGroupManager;
60
-		$this->userSession = $userSession;
61
-		$this->shareManager = $shareManager;
62
-	}
63
-
64
-	/**
65
-	 * Returns a list of principals based on a prefix.
66
-	 *
67
-	 * This prefix will often contain something like 'principals'. You are only
68
-	 * expected to return principals that are in this base path.
69
-	 *
70
-	 * You are expected to return at least a 'uri' for every user, you can
71
-	 * return any additional properties if you wish so. Common properties are:
72
-	 *   {DAV:}displayname
73
-	 *
74
-	 * @param string $prefixPath
75
-	 * @return string[]
76
-	 */
77
-	public function getPrincipalsByPrefix($prefixPath) {
78
-		$principals = [];
79
-
80
-		if ($prefixPath === self::PRINCIPAL_PREFIX) {
81
-			foreach($this->groupManager->search('') as $user) {
82
-				$principals[] = $this->groupToPrincipal($user);
83
-			}
84
-		}
85
-
86
-		return $principals;
87
-	}
88
-
89
-	/**
90
-	 * Returns a specific principal, specified by it's path.
91
-	 * The returned structure should be the exact same as from
92
-	 * getPrincipalsByPrefix.
93
-	 *
94
-	 * @param string $path
95
-	 * @return array
96
-	 */
97
-	public function getPrincipalByPath($path) {
98
-		$elements = explode('/', $path,  3);
99
-		if ($elements[0] !== 'principals') {
100
-			return null;
101
-		}
102
-		if ($elements[1] !== 'groups') {
103
-			return null;
104
-		}
105
-		$name = urldecode($elements[2]);
106
-		$group = $this->groupManager->get($name);
107
-
108
-		if (!is_null($group)) {
109
-			return $this->groupToPrincipal($group);
110
-		}
111
-
112
-		return null;
113
-	}
114
-
115
-	/**
116
-	 * Returns the list of members for a group-principal
117
-	 *
118
-	 * @param string $principal
119
-	 * @return string[]
120
-	 * @throws Exception
121
-	 */
122
-	public function getGroupMemberSet($principal) {
123
-		$elements = explode('/', $principal);
124
-		if ($elements[0] !== 'principals') {
125
-			return [];
126
-		}
127
-		if ($elements[1] !== 'groups') {
128
-			return [];
129
-		}
130
-		$name = $elements[2];
131
-		$group = $this->groupManager->get($name);
132
-
133
-		if (is_null($group)) {
134
-			return [];
135
-		}
136
-
137
-		return array_map(function ($user) {
138
-			return $this->userToPrincipal($user);
139
-		}, $group->getUsers());
140
-	}
141
-
142
-	/**
143
-	 * Returns the list of groups a principal is a member of
144
-	 *
145
-	 * @param string $principal
146
-	 * @return array
147
-	 * @throws Exception
148
-	 */
149
-	public function getGroupMembership($principal) {
150
-		return [];
151
-	}
152
-
153
-	/**
154
-	 * Updates the list of group members for a group principal.
155
-	 *
156
-	 * The principals should be passed as a list of uri's.
157
-	 *
158
-	 * @param string $principal
159
-	 * @param string[] $members
160
-	 * @throws Exception
161
-	 */
162
-	public function setGroupMemberSet($principal, array $members) {
163
-		throw new Exception('Setting members of the group is not supported yet');
164
-	}
165
-
166
-	/**
167
-	 * @param string $path
168
-	 * @param PropPatch $propPatch
169
-	 * @return int
170
-	 */
171
-	function updatePrincipal($path, PropPatch $propPatch) {
172
-		return 0;
173
-	}
174
-
175
-	/**
176
-	 * @param string $prefixPath
177
-	 * @param array $searchProperties
178
-	 * @param string $test
179
-	 * @return array
180
-	 */
181
-	function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof') {
182
-		$results = [];
183
-
184
-		if (\count($searchProperties) === 0) {
185
-			return [];
186
-		}
187
-		if ($prefixPath !== self::PRINCIPAL_PREFIX) {
188
-			return [];
189
-		}
190
-		// If sharing is disabled, return the empty array
191
-		$shareAPIEnabled = $this->shareManager->shareApiEnabled();
192
-		if (!$shareAPIEnabled) {
193
-			return [];
194
-		}
195
-
196
-		// If sharing is restricted to group members only,
197
-		// return only members that have groups in common
198
-		$restrictGroups = false;
199
-		if ($this->shareManager->shareWithGroupMembersOnly()) {
200
-			$user = $this->userSession->getUser();
201
-			if (!$user) {
202
-				return [];
203
-			}
204
-
205
-			$restrictGroups = $this->groupManager->getUserGroupIds($user);
206
-		}
207
-
208
-		foreach ($searchProperties as $prop => $value) {
209
-			switch ($prop) {
210
-				case '{DAV:}displayname':
211
-					$groups = $this->groupManager->search($value);
212
-
213
-					$results[] = array_reduce($groups, function (array $carry, IGroup $group) use ($restrictGroups) {
214
-						$gid = $group->getGID();
215
-						// is sharing restricted to groups only?
216
-						if ($restrictGroups !== false) {
217
-							if (!\in_array($gid, $restrictGroups, true)) {
218
-								return $carry;
219
-							}
220
-						}
221
-
222
-						$carry[] = self::PRINCIPAL_PREFIX . '/' . $gid;
223
-						return $carry;
224
-					}, []);
225
-					break;
226
-
227
-				case '{urn:ietf:params:xml:ns:caldav}calendar-user-address-set':
228
-					// If you add support for more search properties that qualify as a user-address,
229
-					// please also add them to the array below
230
-					$results[] = $this->searchPrincipals(self::PRINCIPAL_PREFIX, [
231
-					], 'anyof');
232
-					break;
233
-
234
-				default:
235
-					$results[] = [];
236
-					break;
237
-			}
238
-		}
239
-
240
-		// results is an array of arrays, so this is not the first search result
241
-		// but the results of the first searchProperty
242
-		if (count($results) === 1) {
243
-			return $results[0];
244
-		}
245
-
246
-		switch ($test) {
247
-			case 'anyof':
248
-				return array_values(array_unique(array_merge(...$results)));
249
-
250
-			case 'allof':
251
-			default:
252
-				return array_values(array_intersect(...$results));
253
-		}
254
-	}
255
-
256
-	/**
257
-	 * @param string $uri
258
-	 * @param string $principalPrefix
259
-	 * @return string
260
-	 */
261
-	function findByUri($uri, $principalPrefix) {
262
-		// If sharing is disabled, return the empty array
263
-		$shareAPIEnabled = $this->shareManager->shareApiEnabled();
264
-		if (!$shareAPIEnabled) {
265
-			return null;
266
-		}
267
-
268
-		// If sharing is restricted to group members only,
269
-		// return only members that have groups in common
270
-		$restrictGroups = false;
271
-		if ($this->shareManager->shareWithGroupMembersOnly()) {
272
-			$user = $this->userSession->getUser();
273
-			if (!$user) {
274
-				return null;
275
-			}
276
-
277
-			$restrictGroups = $this->groupManager->getUserGroupIds($user);
278
-		}
279
-
280
-		if (strpos($uri, 'principal:principals/groups/') === 0) {
281
-			$name = urlencode(substr($uri, 28));
282
-			if ($restrictGroups !== false && !\in_array($name, $restrictGroups, true)) {
283
-				return null;
284
-			}
285
-
286
-			return substr($uri, 10);
287
-		}
288
-
289
-		return null;
290
-	}
291
-
292
-	/**
293
-	 * @param IGroup $group
294
-	 * @return array
295
-	 */
296
-	protected function groupToPrincipal($group) {
297
-		$groupId = $group->getGID();
298
-		// getDisplayName returns UID if none
299
-		$displayName = $group->getDisplayName();
300
-
301
-		return [
302
-			'uri' => 'principals/groups/' . urlencode($groupId),
303
-			'{DAV:}displayname' => $displayName,
304
-			'{urn:ietf:params:xml:ns:caldav}calendar-user-type' => 'GROUP',
305
-		];
306
-	}
307
-
308
-	/**
309
-	 * @param IUser $user
310
-	 * @return array
311
-	 */
312
-	protected function userToPrincipal($user) {
313
-		$userId = $user->getUID();
314
-		// getDisplayName returns UID if none
315
-		$displayName = $user->getDisplayName();
316
-
317
-		$principal = [
318
-			'uri' => 'principals/users/' . $userId,
319
-			'{DAV:}displayname' => $displayName,
320
-			'{urn:ietf:params:xml:ns:caldav}calendar-user-type' => 'INDIVIDUAL',
321
-		];
322
-
323
-		$email = $user->getEMailAddress();
324
-		if (!empty($email)) {
325
-			$principal['{http://sabredav.org/ns}email-address'] = $email;
326
-		}
327
-
328
-		return $principal;
329
-	}
40
+    const PRINCIPAL_PREFIX = 'principals/groups';
41
+
42
+    /** @var IGroupManager */
43
+    private $groupManager;
44
+
45
+    /** @var IUserSession */
46
+    private $userSession;
47
+
48
+    /** @var IShareManager */
49
+    private $shareManager;
50
+
51
+    /**
52
+     * @param IGroupManager $IGroupManager
53
+     * @param IUserSession $userSession
54
+     * @param IShareManager $shareManager
55
+     */
56
+    public function __construct(IGroupManager $IGroupManager,
57
+                                IUserSession $userSession,
58
+                                IShareManager $shareManager) {
59
+        $this->groupManager = $IGroupManager;
60
+        $this->userSession = $userSession;
61
+        $this->shareManager = $shareManager;
62
+    }
63
+
64
+    /**
65
+     * Returns a list of principals based on a prefix.
66
+     *
67
+     * This prefix will often contain something like 'principals'. You are only
68
+     * expected to return principals that are in this base path.
69
+     *
70
+     * You are expected to return at least a 'uri' for every user, you can
71
+     * return any additional properties if you wish so. Common properties are:
72
+     *   {DAV:}displayname
73
+     *
74
+     * @param string $prefixPath
75
+     * @return string[]
76
+     */
77
+    public function getPrincipalsByPrefix($prefixPath) {
78
+        $principals = [];
79
+
80
+        if ($prefixPath === self::PRINCIPAL_PREFIX) {
81
+            foreach($this->groupManager->search('') as $user) {
82
+                $principals[] = $this->groupToPrincipal($user);
83
+            }
84
+        }
85
+
86
+        return $principals;
87
+    }
88
+
89
+    /**
90
+     * Returns a specific principal, specified by it's path.
91
+     * The returned structure should be the exact same as from
92
+     * getPrincipalsByPrefix.
93
+     *
94
+     * @param string $path
95
+     * @return array
96
+     */
97
+    public function getPrincipalByPath($path) {
98
+        $elements = explode('/', $path,  3);
99
+        if ($elements[0] !== 'principals') {
100
+            return null;
101
+        }
102
+        if ($elements[1] !== 'groups') {
103
+            return null;
104
+        }
105
+        $name = urldecode($elements[2]);
106
+        $group = $this->groupManager->get($name);
107
+
108
+        if (!is_null($group)) {
109
+            return $this->groupToPrincipal($group);
110
+        }
111
+
112
+        return null;
113
+    }
114
+
115
+    /**
116
+     * Returns the list of members for a group-principal
117
+     *
118
+     * @param string $principal
119
+     * @return string[]
120
+     * @throws Exception
121
+     */
122
+    public function getGroupMemberSet($principal) {
123
+        $elements = explode('/', $principal);
124
+        if ($elements[0] !== 'principals') {
125
+            return [];
126
+        }
127
+        if ($elements[1] !== 'groups') {
128
+            return [];
129
+        }
130
+        $name = $elements[2];
131
+        $group = $this->groupManager->get($name);
132
+
133
+        if (is_null($group)) {
134
+            return [];
135
+        }
136
+
137
+        return array_map(function ($user) {
138
+            return $this->userToPrincipal($user);
139
+        }, $group->getUsers());
140
+    }
141
+
142
+    /**
143
+     * Returns the list of groups a principal is a member of
144
+     *
145
+     * @param string $principal
146
+     * @return array
147
+     * @throws Exception
148
+     */
149
+    public function getGroupMembership($principal) {
150
+        return [];
151
+    }
152
+
153
+    /**
154
+     * Updates the list of group members for a group principal.
155
+     *
156
+     * The principals should be passed as a list of uri's.
157
+     *
158
+     * @param string $principal
159
+     * @param string[] $members
160
+     * @throws Exception
161
+     */
162
+    public function setGroupMemberSet($principal, array $members) {
163
+        throw new Exception('Setting members of the group is not supported yet');
164
+    }
165
+
166
+    /**
167
+     * @param string $path
168
+     * @param PropPatch $propPatch
169
+     * @return int
170
+     */
171
+    function updatePrincipal($path, PropPatch $propPatch) {
172
+        return 0;
173
+    }
174
+
175
+    /**
176
+     * @param string $prefixPath
177
+     * @param array $searchProperties
178
+     * @param string $test
179
+     * @return array
180
+     */
181
+    function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof') {
182
+        $results = [];
183
+
184
+        if (\count($searchProperties) === 0) {
185
+            return [];
186
+        }
187
+        if ($prefixPath !== self::PRINCIPAL_PREFIX) {
188
+            return [];
189
+        }
190
+        // If sharing is disabled, return the empty array
191
+        $shareAPIEnabled = $this->shareManager->shareApiEnabled();
192
+        if (!$shareAPIEnabled) {
193
+            return [];
194
+        }
195
+
196
+        // If sharing is restricted to group members only,
197
+        // return only members that have groups in common
198
+        $restrictGroups = false;
199
+        if ($this->shareManager->shareWithGroupMembersOnly()) {
200
+            $user = $this->userSession->getUser();
201
+            if (!$user) {
202
+                return [];
203
+            }
204
+
205
+            $restrictGroups = $this->groupManager->getUserGroupIds($user);
206
+        }
207
+
208
+        foreach ($searchProperties as $prop => $value) {
209
+            switch ($prop) {
210
+                case '{DAV:}displayname':
211
+                    $groups = $this->groupManager->search($value);
212
+
213
+                    $results[] = array_reduce($groups, function (array $carry, IGroup $group) use ($restrictGroups) {
214
+                        $gid = $group->getGID();
215
+                        // is sharing restricted to groups only?
216
+                        if ($restrictGroups !== false) {
217
+                            if (!\in_array($gid, $restrictGroups, true)) {
218
+                                return $carry;
219
+                            }
220
+                        }
221
+
222
+                        $carry[] = self::PRINCIPAL_PREFIX . '/' . $gid;
223
+                        return $carry;
224
+                    }, []);
225
+                    break;
226
+
227
+                case '{urn:ietf:params:xml:ns:caldav}calendar-user-address-set':
228
+                    // If you add support for more search properties that qualify as a user-address,
229
+                    // please also add them to the array below
230
+                    $results[] = $this->searchPrincipals(self::PRINCIPAL_PREFIX, [
231
+                    ], 'anyof');
232
+                    break;
233
+
234
+                default:
235
+                    $results[] = [];
236
+                    break;
237
+            }
238
+        }
239
+
240
+        // results is an array of arrays, so this is not the first search result
241
+        // but the results of the first searchProperty
242
+        if (count($results) === 1) {
243
+            return $results[0];
244
+        }
245
+
246
+        switch ($test) {
247
+            case 'anyof':
248
+                return array_values(array_unique(array_merge(...$results)));
249
+
250
+            case 'allof':
251
+            default:
252
+                return array_values(array_intersect(...$results));
253
+        }
254
+    }
255
+
256
+    /**
257
+     * @param string $uri
258
+     * @param string $principalPrefix
259
+     * @return string
260
+     */
261
+    function findByUri($uri, $principalPrefix) {
262
+        // If sharing is disabled, return the empty array
263
+        $shareAPIEnabled = $this->shareManager->shareApiEnabled();
264
+        if (!$shareAPIEnabled) {
265
+            return null;
266
+        }
267
+
268
+        // If sharing is restricted to group members only,
269
+        // return only members that have groups in common
270
+        $restrictGroups = false;
271
+        if ($this->shareManager->shareWithGroupMembersOnly()) {
272
+            $user = $this->userSession->getUser();
273
+            if (!$user) {
274
+                return null;
275
+            }
276
+
277
+            $restrictGroups = $this->groupManager->getUserGroupIds($user);
278
+        }
279
+
280
+        if (strpos($uri, 'principal:principals/groups/') === 0) {
281
+            $name = urlencode(substr($uri, 28));
282
+            if ($restrictGroups !== false && !\in_array($name, $restrictGroups, true)) {
283
+                return null;
284
+            }
285
+
286
+            return substr($uri, 10);
287
+        }
288
+
289
+        return null;
290
+    }
291
+
292
+    /**
293
+     * @param IGroup $group
294
+     * @return array
295
+     */
296
+    protected function groupToPrincipal($group) {
297
+        $groupId = $group->getGID();
298
+        // getDisplayName returns UID if none
299
+        $displayName = $group->getDisplayName();
300
+
301
+        return [
302
+            'uri' => 'principals/groups/' . urlencode($groupId),
303
+            '{DAV:}displayname' => $displayName,
304
+            '{urn:ietf:params:xml:ns:caldav}calendar-user-type' => 'GROUP',
305
+        ];
306
+    }
307
+
308
+    /**
309
+     * @param IUser $user
310
+     * @return array
311
+     */
312
+    protected function userToPrincipal($user) {
313
+        $userId = $user->getUID();
314
+        // getDisplayName returns UID if none
315
+        $displayName = $user->getDisplayName();
316
+
317
+        $principal = [
318
+            'uri' => 'principals/users/' . $userId,
319
+            '{DAV:}displayname' => $displayName,
320
+            '{urn:ietf:params:xml:ns:caldav}calendar-user-type' => 'INDIVIDUAL',
321
+        ];
322
+
323
+        $email = $user->getEMailAddress();
324
+        if (!empty($email)) {
325
+            $principal['{http://sabredav.org/ns}email-address'] = $email;
326
+        }
327
+
328
+        return $principal;
329
+    }
330 330
 }
Please login to merge, or discard this patch.
apps/dav/lib/DAV/Sharing/Plugin.php 1 patch
Indentation   +162 added lines, -162 removed lines patch added patch discarded remove patch
@@ -38,167 +38,167 @@
 block discarded – undo
38 38
 
39 39
 class Plugin extends ServerPlugin {
40 40
 
41
-	const NS_OWNCLOUD = 'http://owncloud.org/ns';
42
-	const NS_NEXTCLOUD = 'http://nextcloud.com/ns';
43
-
44
-	/** @var Auth */
45
-	private $auth;
46
-
47
-	/** @var IRequest */
48
-	private $request;
49
-
50
-	/**
51
-	 * Plugin constructor.
52
-	 *
53
-	 * @param Auth $authBackEnd
54
-	 * @param IRequest $request
55
-	 */
56
-	public function __construct(Auth $authBackEnd, IRequest $request) {
57
-		$this->auth = $authBackEnd;
58
-		$this->request = $request;
59
-	}
60
-
61
-	/**
62
-	 * Reference to SabreDAV server object.
63
-	 *
64
-	 * @var \Sabre\DAV\Server
65
-	 */
66
-	protected $server;
67
-
68
-	/**
69
-	 * This method should return a list of server-features.
70
-	 *
71
-	 * This is for example 'versioning' and is added to the DAV: header
72
-	 * in an OPTIONS response.
73
-	 *
74
-	 * @return string[]
75
-	 */
76
-	function getFeatures() {
77
-		return ['oc-resource-sharing'];
78
-	}
79
-
80
-	/**
81
-	 * Returns a plugin name.
82
-	 *
83
-	 * Using this name other plugins will be able to access other plugins
84
-	 * using Sabre\DAV\Server::getPlugin
85
-	 *
86
-	 * @return string
87
-	 */
88
-	function getPluginName() {
89
-		return 'oc-resource-sharing';
90
-	}
91
-
92
-	/**
93
-	 * This initializes the plugin.
94
-	 *
95
-	 * This function is called by Sabre\DAV\Server, after
96
-	 * addPlugin is called.
97
-	 *
98
-	 * This method should set up the required event subscriptions.
99
-	 *
100
-	 * @param Server $server
101
-	 * @return void
102
-	 */
103
-	function initialize(Server $server) {
104
-		$this->server = $server;
105
-		$this->server->xml->elementMap['{' . Plugin::NS_OWNCLOUD . '}share'] = ShareRequest::class;
106
-		$this->server->xml->elementMap['{' . Plugin::NS_OWNCLOUD . '}invite'] = Invite::class;
107
-
108
-		$this->server->on('method:POST', [$this, 'httpPost']);
109
-		$this->server->on('propFind',    [$this, 'propFind']);
110
-	}
111
-
112
-	/**
113
-	 * We intercept this to handle POST requests on a dav resource.
114
-	 *
115
-	 * @param RequestInterface $request
116
-	 * @param ResponseInterface $response
117
-	 * @return null|false
118
-	 */
119
-	function httpPost(RequestInterface $request, ResponseInterface $response) {
120
-
121
-		$path = $request->getPath();
122
-
123
-		// Only handling xml
124
-		$contentType = $request->getHeader('Content-Type');
125
-		if (strpos($contentType, 'application/xml') === false && strpos($contentType, 'text/xml') === false)
126
-			return;
127
-
128
-		// Making sure the node exists
129
-		try {
130
-			$node = $this->server->tree->getNodeForPath($path);
131
-		} catch (NotFound $e) {
132
-			return;
133
-		}
134
-
135
-		$requestBody = $request->getBodyAsString();
136
-
137
-		// If this request handler could not deal with this POST request, it
138
-		// will return 'null' and other plugins get a chance to handle the
139
-		// request.
140
-		//
141
-		// However, we already requested the full body. This is a problem,
142
-		// because a body can only be read once. This is why we preemptively
143
-		// re-populated the request body with the existing data.
144
-		$request->setBody($requestBody);
145
-
146
-		$message = $this->server->xml->parse($requestBody, $request->getUrl(), $documentType);
147
-
148
-		switch ($documentType) {
149
-
150
-			// Dealing with the 'share' document, which modified invitees on a
151
-			// calendar.
152
-			case '{' . self::NS_OWNCLOUD . '}share' :
153
-
154
-				// We can only deal with IShareableCalendar objects
155
-				if (!$node instanceof IShareable) {
156
-					return;
157
-				}
158
-
159
-				$this->server->transactionType = 'post-oc-resource-share';
160
-
161
-				// Getting ACL info
162
-				$acl = $this->server->getPlugin('acl');
163
-
164
-				// If there's no ACL support, we allow everything
165
-				if ($acl) {
166
-					/** @var \Sabre\DAVACL\Plugin $acl */
167
-					$acl->checkPrivileges($path, '{DAV:}write');
168
-				}
169
-
170
-				$node->updateShares($message->set, $message->remove);
171
-
172
-				$response->setStatus(200);
173
-				// Adding this because sending a response body may cause issues,
174
-				// and I wanted some type of indicator the response was handled.
175
-				$response->setHeader('X-Sabre-Status', 'everything-went-well');
176
-
177
-				// Breaking the event chain
178
-				return false;
179
-		}
180
-	}
181
-
182
-	/**
183
-	 * This event is triggered when properties are requested for a certain
184
-	 * node.
185
-	 *
186
-	 * This allows us to inject any properties early.
187
-	 *
188
-	 * @param PropFind $propFind
189
-	 * @param INode $node
190
-	 * @return void
191
-	 */
192
-	function propFind(PropFind $propFind, INode $node) {
193
-		if ($node instanceof IShareable) {
194
-
195
-			$propFind->handle('{' . Plugin::NS_OWNCLOUD . '}invite', function () use ($node) {
196
-				return new Invite(
197
-					$node->getShares()
198
-				);
199
-			});
200
-
201
-		}
202
-	}
41
+    const NS_OWNCLOUD = 'http://owncloud.org/ns';
42
+    const NS_NEXTCLOUD = 'http://nextcloud.com/ns';
43
+
44
+    /** @var Auth */
45
+    private $auth;
46
+
47
+    /** @var IRequest */
48
+    private $request;
49
+
50
+    /**
51
+     * Plugin constructor.
52
+     *
53
+     * @param Auth $authBackEnd
54
+     * @param IRequest $request
55
+     */
56
+    public function __construct(Auth $authBackEnd, IRequest $request) {
57
+        $this->auth = $authBackEnd;
58
+        $this->request = $request;
59
+    }
60
+
61
+    /**
62
+     * Reference to SabreDAV server object.
63
+     *
64
+     * @var \Sabre\DAV\Server
65
+     */
66
+    protected $server;
67
+
68
+    /**
69
+     * This method should return a list of server-features.
70
+     *
71
+     * This is for example 'versioning' and is added to the DAV: header
72
+     * in an OPTIONS response.
73
+     *
74
+     * @return string[]
75
+     */
76
+    function getFeatures() {
77
+        return ['oc-resource-sharing'];
78
+    }
79
+
80
+    /**
81
+     * Returns a plugin name.
82
+     *
83
+     * Using this name other plugins will be able to access other plugins
84
+     * using Sabre\DAV\Server::getPlugin
85
+     *
86
+     * @return string
87
+     */
88
+    function getPluginName() {
89
+        return 'oc-resource-sharing';
90
+    }
91
+
92
+    /**
93
+     * This initializes the plugin.
94
+     *
95
+     * This function is called by Sabre\DAV\Server, after
96
+     * addPlugin is called.
97
+     *
98
+     * This method should set up the required event subscriptions.
99
+     *
100
+     * @param Server $server
101
+     * @return void
102
+     */
103
+    function initialize(Server $server) {
104
+        $this->server = $server;
105
+        $this->server->xml->elementMap['{' . Plugin::NS_OWNCLOUD . '}share'] = ShareRequest::class;
106
+        $this->server->xml->elementMap['{' . Plugin::NS_OWNCLOUD . '}invite'] = Invite::class;
107
+
108
+        $this->server->on('method:POST', [$this, 'httpPost']);
109
+        $this->server->on('propFind',    [$this, 'propFind']);
110
+    }
111
+
112
+    /**
113
+     * We intercept this to handle POST requests on a dav resource.
114
+     *
115
+     * @param RequestInterface $request
116
+     * @param ResponseInterface $response
117
+     * @return null|false
118
+     */
119
+    function httpPost(RequestInterface $request, ResponseInterface $response) {
120
+
121
+        $path = $request->getPath();
122
+
123
+        // Only handling xml
124
+        $contentType = $request->getHeader('Content-Type');
125
+        if (strpos($contentType, 'application/xml') === false && strpos($contentType, 'text/xml') === false)
126
+            return;
127
+
128
+        // Making sure the node exists
129
+        try {
130
+            $node = $this->server->tree->getNodeForPath($path);
131
+        } catch (NotFound $e) {
132
+            return;
133
+        }
134
+
135
+        $requestBody = $request->getBodyAsString();
136
+
137
+        // If this request handler could not deal with this POST request, it
138
+        // will return 'null' and other plugins get a chance to handle the
139
+        // request.
140
+        //
141
+        // However, we already requested the full body. This is a problem,
142
+        // because a body can only be read once. This is why we preemptively
143
+        // re-populated the request body with the existing data.
144
+        $request->setBody($requestBody);
145
+
146
+        $message = $this->server->xml->parse($requestBody, $request->getUrl(), $documentType);
147
+
148
+        switch ($documentType) {
149
+
150
+            // Dealing with the 'share' document, which modified invitees on a
151
+            // calendar.
152
+            case '{' . self::NS_OWNCLOUD . '}share' :
153
+
154
+                // We can only deal with IShareableCalendar objects
155
+                if (!$node instanceof IShareable) {
156
+                    return;
157
+                }
158
+
159
+                $this->server->transactionType = 'post-oc-resource-share';
160
+
161
+                // Getting ACL info
162
+                $acl = $this->server->getPlugin('acl');
163
+
164
+                // If there's no ACL support, we allow everything
165
+                if ($acl) {
166
+                    /** @var \Sabre\DAVACL\Plugin $acl */
167
+                    $acl->checkPrivileges($path, '{DAV:}write');
168
+                }
169
+
170
+                $node->updateShares($message->set, $message->remove);
171
+
172
+                $response->setStatus(200);
173
+                // Adding this because sending a response body may cause issues,
174
+                // and I wanted some type of indicator the response was handled.
175
+                $response->setHeader('X-Sabre-Status', 'everything-went-well');
176
+
177
+                // Breaking the event chain
178
+                return false;
179
+        }
180
+    }
181
+
182
+    /**
183
+     * This event is triggered when properties are requested for a certain
184
+     * node.
185
+     *
186
+     * This allows us to inject any properties early.
187
+     *
188
+     * @param PropFind $propFind
189
+     * @param INode $node
190
+     * @return void
191
+     */
192
+    function propFind(PropFind $propFind, INode $node) {
193
+        if ($node instanceof IShareable) {
194
+
195
+            $propFind->handle('{' . Plugin::NS_OWNCLOUD . '}invite', function () use ($node) {
196
+                return new Invite(
197
+                    $node->getShares()
198
+                );
199
+            });
200
+
201
+        }
202
+    }
203 203
 
204 204
 }
Please login to merge, or discard this patch.
apps/dav/lib/Files/Sharing/PublicLinkCheckPlugin.php 1 patch
Indentation   +26 added lines, -26 removed lines patch added patch discarded remove patch
@@ -33,33 +33,33 @@
 block discarded – undo
33 33
  * Verify that the public link share is valid
34 34
  */
35 35
 class PublicLinkCheckPlugin extends ServerPlugin {
36
-	/**
37
-	 * @var FileInfo
38
-	 */
39
-	private $fileInfo;
36
+    /**
37
+     * @var FileInfo
38
+     */
39
+    private $fileInfo;
40 40
 
41
-	/**
42
-	 * @param FileInfo $fileInfo
43
-	 */
44
-	public function setFileInfo($fileInfo) {
45
-		$this->fileInfo = $fileInfo;
46
-	}
41
+    /**
42
+     * @param FileInfo $fileInfo
43
+     */
44
+    public function setFileInfo($fileInfo) {
45
+        $this->fileInfo = $fileInfo;
46
+    }
47 47
 
48
-	/**
49
-	 * This initializes the plugin.
50
-	 *
51
-	 * @param \Sabre\DAV\Server $server Sabre server
52
-	 *
53
-	 * @return void
54
-	 */
55
-	public function initialize(\Sabre\DAV\Server $server) {
56
-		$server->on('beforeMethod:*', [$this, 'beforeMethod']);
57
-	}
48
+    /**
49
+     * This initializes the plugin.
50
+     *
51
+     * @param \Sabre\DAV\Server $server Sabre server
52
+     *
53
+     * @return void
54
+     */
55
+    public function initialize(\Sabre\DAV\Server $server) {
56
+        $server->on('beforeMethod:*', [$this, 'beforeMethod']);
57
+    }
58 58
 
59
-	public function beforeMethod(RequestInterface $request, ResponseInterface $response) {
60
-		// verify that the owner didn't have his share permissions revoked
61
-		if ($this->fileInfo && !$this->fileInfo->isShareable()) {
62
-			throw new NotFound();
63
-		}
64
-	}
59
+    public function beforeMethod(RequestInterface $request, ResponseInterface $response) {
60
+        // verify that the owner didn't have his share permissions revoked
61
+        if ($this->fileInfo && !$this->fileInfo->isShareable()) {
62
+            throw new NotFound();
63
+        }
64
+    }
65 65
 }
Please login to merge, or discard this patch.
apps/dav/lib/Files/Sharing/FilesDropPlugin.php 1 patch
Indentation   +38 added lines, -38 removed lines patch added patch discarded remove patch
@@ -35,52 +35,52 @@
 block discarded – undo
35 35
  */
36 36
 class FilesDropPlugin extends ServerPlugin {
37 37
 
38
-	/** @var View */
39
-	private $view;
38
+    /** @var View */
39
+    private $view;
40 40
 
41
-	/** @var bool */
42
-	private $enabled = false;
41
+    /** @var bool */
42
+    private $enabled = false;
43 43
 
44
-	/**
45
-	 * @param View $view
46
-	 */
47
-	public function setView($view) {
48
-		$this->view = $view;
49
-	}
44
+    /**
45
+     * @param View $view
46
+     */
47
+    public function setView($view) {
48
+        $this->view = $view;
49
+    }
50 50
 
51
-	public function enable() {
52
-		$this->enabled = true;
53
-	}
51
+    public function enable() {
52
+        $this->enabled = true;
53
+    }
54 54
 
55 55
 
56
-	/**
57
-	 * This initializes the plugin.
58
-	 *
59
-	 * @param \Sabre\DAV\Server $server Sabre server
60
-	 *
61
-	 * @return void
62
-	 * @throws MethodNotAllowed
63
-	 */
64
-	public function initialize(\Sabre\DAV\Server $server) {
65
-		$server->on('beforeMethod:*', [$this, 'beforeMethod'], 999);
66
-		$this->enabled = false;
67
-	}
56
+    /**
57
+     * This initializes the plugin.
58
+     *
59
+     * @param \Sabre\DAV\Server $server Sabre server
60
+     *
61
+     * @return void
62
+     * @throws MethodNotAllowed
63
+     */
64
+    public function initialize(\Sabre\DAV\Server $server) {
65
+        $server->on('beforeMethod:*', [$this, 'beforeMethod'], 999);
66
+        $this->enabled = false;
67
+    }
68 68
 
69
-	public function beforeMethod(RequestInterface $request, ResponseInterface $response) {
69
+    public function beforeMethod(RequestInterface $request, ResponseInterface $response) {
70 70
 
71
-		if (!$this->enabled) {
72
-			return;
73
-		}
71
+        if (!$this->enabled) {
72
+            return;
73
+        }
74 74
 
75
-		if ($request->getMethod() !== 'PUT') {
76
-			throw new MethodNotAllowed('Only PUT is allowed on files drop');
77
-		}
75
+        if ($request->getMethod() !== 'PUT') {
76
+            throw new MethodNotAllowed('Only PUT is allowed on files drop');
77
+        }
78 78
 
79
-		$path = explode('/', $request->getPath());
80
-		$path = array_pop($path);
79
+        $path = explode('/', $request->getPath());
80
+        $path = array_pop($path);
81 81
 
82
-		$newName = \OC_Helper::buildNotExistingFileNameForView('/', $path, $this->view);
83
-		$url = $request->getBaseUrl() . $newName;
84
-		$request->setUrl($url);
85
-	}
82
+        $newName = \OC_Helper::buildNotExistingFileNameForView('/', $path, $this->view);
83
+        $url = $request->getBaseUrl() . $newName;
84
+        $request->setUrl($url);
85
+    }
86 86
 }
Please login to merge, or discard this patch.
apps/dav/lib/Server.php 1 patch
Indentation   +256 added lines, -256 removed lines patch added patch discarded remove patch
@@ -72,260 +72,260 @@
 block discarded – undo
72 72
 
73 73
 class Server {
74 74
 
75
-	/** @var IRequest */
76
-	private $request;
77
-
78
-	/** @var  string */
79
-	private $baseUri;
80
-
81
-	/** @var Connector\Sabre\Server  */
82
-	public $server;
83
-
84
-	public function __construct(IRequest $request, $baseUri) {
85
-		$this->request = $request;
86
-		$this->baseUri = $baseUri;
87
-		$logger = \OC::$server->getLogger();
88
-		$dispatcher = \OC::$server->getEventDispatcher();
89
-
90
-		$root = new RootCollection();
91
-		$this->server = new \OCA\DAV\Connector\Sabre\Server(new CachingTree($root));
92
-
93
-		// Add maintenance plugin
94
-		$this->server->addPlugin(new \OCA\DAV\Connector\Sabre\MaintenancePlugin(\OC::$server->getConfig()));
95
-
96
-		// Backends
97
-		$authBackend = new Auth(
98
-			\OC::$server->getSession(),
99
-			\OC::$server->getUserSession(),
100
-			\OC::$server->getRequest(),
101
-			\OC::$server->getTwoFactorAuthManager(),
102
-			\OC::$server->getBruteForceThrottler()
103
-		);
104
-
105
-		// Set URL explicitly due to reverse-proxy situations
106
-		$this->server->httpRequest->setUrl($this->request->getRequestUri());
107
-		$this->server->setBaseUri($this->baseUri);
108
-
109
-		$this->server->addPlugin(new BlockLegacyClientPlugin(\OC::$server->getConfig()));
110
-		$this->server->addPlugin(new AnonymousOptionsPlugin());
111
-		$authPlugin = new Plugin();
112
-		$authPlugin->addBackend(new PublicAuth());
113
-		$this->server->addPlugin($authPlugin);
114
-
115
-		// allow setup of additional auth backends
116
-		$event = new SabrePluginEvent($this->server);
117
-		$dispatcher->dispatch('OCA\DAV\Connector\Sabre::authInit', $event);
118
-
119
-		$bearerAuthBackend = new BearerAuth(
120
-			\OC::$server->getUserSession(),
121
-			\OC::$server->getSession(),
122
-			\OC::$server->getRequest()
123
-		);
124
-		$authPlugin->addBackend($bearerAuthBackend);
125
-		// because we are throwing exceptions this plugin has to be the last one
126
-		$authPlugin->addBackend($authBackend);
127
-
128
-		// debugging
129
-		if(\OC::$server->getConfig()->getSystemValue('debug', false)) {
130
-			$this->server->addPlugin(new \Sabre\DAV\Browser\Plugin());
131
-		} else {
132
-			$this->server->addPlugin(new DummyGetResponsePlugin());
133
-		}
134
-
135
-		$this->server->addPlugin(new \OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin('webdav', $logger));
136
-		$this->server->addPlugin(new \OCA\DAV\Connector\Sabre\LockPlugin());
137
-		$this->server->addPlugin(new \Sabre\DAV\Sync\Plugin());
138
-
139
-		// acl
140
-		$acl = new DavAclPlugin();
141
-		$acl->principalCollectionSet = [
142
-			'principals/users',
143
-			'principals/groups',
144
-			'principals/calendar-resources',
145
-			'principals/calendar-rooms',
146
-		];
147
-		$acl->defaultUsernamePath = 'principals/users';
148
-		$this->server->addPlugin($acl);
149
-
150
-		// calendar plugins
151
-		if ($this->requestIsForSubtree(['calendars', 'public-calendars', 'system-calendars', 'principals'])) {
152
-			$this->server->addPlugin(new \OCA\DAV\CalDAV\Plugin());
153
-			$this->server->addPlugin(new \OCA\DAV\CalDAV\ICSExportPlugin\ICSExportPlugin(\OC::$server->getConfig(), \OC::$server->getLogger()));
154
-			$this->server->addPlugin(new \OCA\DAV\CalDAV\Schedule\Plugin());
155
-			if (\OC::$server->getConfig()->getAppValue('dav', 'sendInvitations', 'yes') === 'yes') {
156
-				$this->server->addPlugin(\OC::$server->query(\OCA\DAV\CalDAV\Schedule\IMipPlugin::class));
157
-			}
158
-
159
-			$this->server->addPlugin(new CalDAV\WebcalCaching\Plugin($request));
160
-			$this->server->addPlugin(new \Sabre\CalDAV\Subscriptions\Plugin());
161
-
162
-			$this->server->addPlugin(new \Sabre\CalDAV\Notifications\Plugin());
163
-			$this->server->addPlugin(new DAV\Sharing\Plugin($authBackend, \OC::$server->getRequest()));
164
-			$this->server->addPlugin(new \OCA\DAV\CalDAV\Publishing\PublishPlugin(
165
-				\OC::$server->getConfig(),
166
-				\OC::$server->getURLGenerator()
167
-			));
168
-		}
169
-
170
-		// addressbook plugins
171
-		if ($this->requestIsForSubtree(['addressbooks', 'principals'])) {
172
-			$this->server->addPlugin(new DAV\Sharing\Plugin($authBackend, \OC::$server->getRequest()));
173
-			$this->server->addPlugin(new \OCA\DAV\CardDAV\Plugin());
174
-			$this->server->addPlugin(new VCFExportPlugin());
175
-			$this->server->addPlugin(new MultiGetExportPlugin());
176
-			$this->server->addPlugin(new HasPhotoPlugin());
177
-			$this->server->addPlugin(new ImageExportPlugin(new PhotoCache(
178
-				\OC::$server->getAppDataDir('dav-photocache'),
179
-				\OC::$server->getLogger())
180
-			));
181
-		}
182
-
183
-		// system tags plugins
184
-		$this->server->addPlugin(new SystemTagPlugin(
185
-			\OC::$server->getSystemTagManager(),
186
-			\OC::$server->getGroupManager(),
187
-			\OC::$server->getUserSession()
188
-		));
189
-
190
-		// comments plugin
191
-		$this->server->addPlugin(new CommentsPlugin(
192
-			\OC::$server->getCommentsManager(),
193
-			\OC::$server->getUserSession()
194
-		));
195
-
196
-		$this->server->addPlugin(new CopyEtagHeaderPlugin());
197
-		$this->server->addPlugin(new ChunkingPlugin());
198
-
199
-		// allow setup of additional plugins
200
-		$dispatcher->dispatch('OCA\DAV\Connector\Sabre::addPlugin', $event);
201
-
202
-		// Some WebDAV clients do require Class 2 WebDAV support (locking), since
203
-		// we do not provide locking we emulate it using a fake locking plugin.
204
-		if($request->isUserAgent([
205
-			'/WebDAVFS/',
206
-			'/OneNote/',
207
-			'/^Microsoft-WebDAV/',// Microsoft-WebDAV-MiniRedir/6.1.7601
208
-		])) {
209
-			$this->server->addPlugin(new FakeLockerPlugin());
210
-		}
211
-
212
-		if (BrowserErrorPagePlugin::isBrowserRequest($request)) {
213
-			$this->server->addPlugin(new BrowserErrorPagePlugin());
214
-		}
215
-
216
-		$lazySearchBackend = new LazySearchBackend();
217
-		$this->server->addPlugin(new SearchPlugin($lazySearchBackend));
218
-
219
-		// wait with registering these until auth is handled and the filesystem is setup
220
-		$this->server->on('beforeMethod:*', function () use ($root, $lazySearchBackend) {
221
-			// custom properties plugin must be the last one
222
-			$userSession = \OC::$server->getUserSession();
223
-			$user = $userSession->getUser();
224
-			if ($user !== null) {
225
-				$view = \OC\Files\Filesystem::getView();
226
-				$this->server->addPlugin(
227
-					new FilesPlugin(
228
-						$this->server->tree,
229
-						\OC::$server->getConfig(),
230
-						$this->request,
231
-						\OC::$server->getPreviewManager(),
232
-						false,
233
-						!\OC::$server->getConfig()->getSystemValue('debug', false)
234
-					)
235
-				);
236
-
237
-				$this->server->addPlugin(
238
-					new \Sabre\DAV\PropertyStorage\Plugin(
239
-						new CustomPropertiesBackend(
240
-							$this->server->tree,
241
-							\OC::$server->getDatabaseConnection(),
242
-							\OC::$server->getUserSession()->getUser()
243
-						)
244
-					)
245
-				);
246
-				if ($view !== null) {
247
-					$this->server->addPlugin(
248
-						new QuotaPlugin($view, false));
249
-				}
250
-				$this->server->addPlugin(
251
-					new TagsPlugin(
252
-						$this->server->tree, \OC::$server->getTagManager()
253
-					)
254
-				);
255
-				// TODO: switch to LazyUserFolder
256
-				$userFolder = \OC::$server->getUserFolder();
257
-				$this->server->addPlugin(new SharesPlugin(
258
-					$this->server->tree,
259
-					$userSession,
260
-					$userFolder,
261
-					\OC::$server->getShareManager()
262
-				));
263
-				$this->server->addPlugin(new CommentPropertiesPlugin(
264
-					\OC::$server->getCommentsManager(),
265
-					$userSession
266
-				));
267
-				$this->server->addPlugin(new \OCA\DAV\CalDAV\Search\SearchPlugin());
268
-				if ($view !== null) {
269
-					$this->server->addPlugin(new FilesReportPlugin(
270
-						$this->server->tree,
271
-						$view,
272
-						\OC::$server->getSystemTagManager(),
273
-						\OC::$server->getSystemTagObjectMapper(),
274
-						\OC::$server->getTagManager(),
275
-						$userSession,
276
-						\OC::$server->getGroupManager(),
277
-						$userFolder,
278
-						\OC::$server->getAppManager()
279
-					));
280
-					$lazySearchBackend->setBackend(new \OCA\DAV\Files\FileSearchBackend(
281
-						$this->server->tree,
282
-						$user,
283
-						\OC::$server->getRootFolder(),
284
-						\OC::$server->getShareManager(),
285
-						$view
286
-					));
287
-				}
288
-				$this->server->addPlugin(new \OCA\DAV\CalDAV\BirthdayCalendar\EnablePlugin(
289
-					\OC::$server->getConfig(),
290
-					\OC::$server->query(BirthdayService::class)
291
-				));
292
-				$this->server->addPlugin(new AppleProvisioningPlugin(
293
-					\OC::$server->getUserSession(),
294
-					\OC::$server->getURLGenerator(),
295
-					\OC::$server->getThemingDefaults(),
296
-					\OC::$server->getRequest(),
297
-					\OC::$server->getL10N('dav'),
298
-					function () {
299
-						return UUIDUtil::getUUID();
300
-					}
301
-				));
302
-			}
303
-
304
-			// register plugins from apps
305
-			$pluginManager = new PluginManager(
306
-				\OC::$server,
307
-				\OC::$server->getAppManager()
308
-			);
309
-			foreach ($pluginManager->getAppPlugins() as $appPlugin) {
310
-				$this->server->addPlugin($appPlugin);
311
-			}
312
-			foreach ($pluginManager->getAppCollections() as $appCollection) {
313
-				$root->addChild($appCollection);
314
-			}
315
-		});
316
-	}
317
-
318
-	public function exec() {
319
-		$this->server->exec();
320
-	}
321
-
322
-	private function requestIsForSubtree(array $subTrees): bool {
323
-		foreach ($subTrees as $subTree) {
324
-			$subTree = trim($subTree, ' /');
325
-			if (strpos($this->server->getRequestUri(), $subTree.'/') === 0) {
326
-				return true;
327
-			}
328
-		}
329
-		return false;
330
-	}
75
+    /** @var IRequest */
76
+    private $request;
77
+
78
+    /** @var  string */
79
+    private $baseUri;
80
+
81
+    /** @var Connector\Sabre\Server  */
82
+    public $server;
83
+
84
+    public function __construct(IRequest $request, $baseUri) {
85
+        $this->request = $request;
86
+        $this->baseUri = $baseUri;
87
+        $logger = \OC::$server->getLogger();
88
+        $dispatcher = \OC::$server->getEventDispatcher();
89
+
90
+        $root = new RootCollection();
91
+        $this->server = new \OCA\DAV\Connector\Sabre\Server(new CachingTree($root));
92
+
93
+        // Add maintenance plugin
94
+        $this->server->addPlugin(new \OCA\DAV\Connector\Sabre\MaintenancePlugin(\OC::$server->getConfig()));
95
+
96
+        // Backends
97
+        $authBackend = new Auth(
98
+            \OC::$server->getSession(),
99
+            \OC::$server->getUserSession(),
100
+            \OC::$server->getRequest(),
101
+            \OC::$server->getTwoFactorAuthManager(),
102
+            \OC::$server->getBruteForceThrottler()
103
+        );
104
+
105
+        // Set URL explicitly due to reverse-proxy situations
106
+        $this->server->httpRequest->setUrl($this->request->getRequestUri());
107
+        $this->server->setBaseUri($this->baseUri);
108
+
109
+        $this->server->addPlugin(new BlockLegacyClientPlugin(\OC::$server->getConfig()));
110
+        $this->server->addPlugin(new AnonymousOptionsPlugin());
111
+        $authPlugin = new Plugin();
112
+        $authPlugin->addBackend(new PublicAuth());
113
+        $this->server->addPlugin($authPlugin);
114
+
115
+        // allow setup of additional auth backends
116
+        $event = new SabrePluginEvent($this->server);
117
+        $dispatcher->dispatch('OCA\DAV\Connector\Sabre::authInit', $event);
118
+
119
+        $bearerAuthBackend = new BearerAuth(
120
+            \OC::$server->getUserSession(),
121
+            \OC::$server->getSession(),
122
+            \OC::$server->getRequest()
123
+        );
124
+        $authPlugin->addBackend($bearerAuthBackend);
125
+        // because we are throwing exceptions this plugin has to be the last one
126
+        $authPlugin->addBackend($authBackend);
127
+
128
+        // debugging
129
+        if(\OC::$server->getConfig()->getSystemValue('debug', false)) {
130
+            $this->server->addPlugin(new \Sabre\DAV\Browser\Plugin());
131
+        } else {
132
+            $this->server->addPlugin(new DummyGetResponsePlugin());
133
+        }
134
+
135
+        $this->server->addPlugin(new \OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin('webdav', $logger));
136
+        $this->server->addPlugin(new \OCA\DAV\Connector\Sabre\LockPlugin());
137
+        $this->server->addPlugin(new \Sabre\DAV\Sync\Plugin());
138
+
139
+        // acl
140
+        $acl = new DavAclPlugin();
141
+        $acl->principalCollectionSet = [
142
+            'principals/users',
143
+            'principals/groups',
144
+            'principals/calendar-resources',
145
+            'principals/calendar-rooms',
146
+        ];
147
+        $acl->defaultUsernamePath = 'principals/users';
148
+        $this->server->addPlugin($acl);
149
+
150
+        // calendar plugins
151
+        if ($this->requestIsForSubtree(['calendars', 'public-calendars', 'system-calendars', 'principals'])) {
152
+            $this->server->addPlugin(new \OCA\DAV\CalDAV\Plugin());
153
+            $this->server->addPlugin(new \OCA\DAV\CalDAV\ICSExportPlugin\ICSExportPlugin(\OC::$server->getConfig(), \OC::$server->getLogger()));
154
+            $this->server->addPlugin(new \OCA\DAV\CalDAV\Schedule\Plugin());
155
+            if (\OC::$server->getConfig()->getAppValue('dav', 'sendInvitations', 'yes') === 'yes') {
156
+                $this->server->addPlugin(\OC::$server->query(\OCA\DAV\CalDAV\Schedule\IMipPlugin::class));
157
+            }
158
+
159
+            $this->server->addPlugin(new CalDAV\WebcalCaching\Plugin($request));
160
+            $this->server->addPlugin(new \Sabre\CalDAV\Subscriptions\Plugin());
161
+
162
+            $this->server->addPlugin(new \Sabre\CalDAV\Notifications\Plugin());
163
+            $this->server->addPlugin(new DAV\Sharing\Plugin($authBackend, \OC::$server->getRequest()));
164
+            $this->server->addPlugin(new \OCA\DAV\CalDAV\Publishing\PublishPlugin(
165
+                \OC::$server->getConfig(),
166
+                \OC::$server->getURLGenerator()
167
+            ));
168
+        }
169
+
170
+        // addressbook plugins
171
+        if ($this->requestIsForSubtree(['addressbooks', 'principals'])) {
172
+            $this->server->addPlugin(new DAV\Sharing\Plugin($authBackend, \OC::$server->getRequest()));
173
+            $this->server->addPlugin(new \OCA\DAV\CardDAV\Plugin());
174
+            $this->server->addPlugin(new VCFExportPlugin());
175
+            $this->server->addPlugin(new MultiGetExportPlugin());
176
+            $this->server->addPlugin(new HasPhotoPlugin());
177
+            $this->server->addPlugin(new ImageExportPlugin(new PhotoCache(
178
+                \OC::$server->getAppDataDir('dav-photocache'),
179
+                \OC::$server->getLogger())
180
+            ));
181
+        }
182
+
183
+        // system tags plugins
184
+        $this->server->addPlugin(new SystemTagPlugin(
185
+            \OC::$server->getSystemTagManager(),
186
+            \OC::$server->getGroupManager(),
187
+            \OC::$server->getUserSession()
188
+        ));
189
+
190
+        // comments plugin
191
+        $this->server->addPlugin(new CommentsPlugin(
192
+            \OC::$server->getCommentsManager(),
193
+            \OC::$server->getUserSession()
194
+        ));
195
+
196
+        $this->server->addPlugin(new CopyEtagHeaderPlugin());
197
+        $this->server->addPlugin(new ChunkingPlugin());
198
+
199
+        // allow setup of additional plugins
200
+        $dispatcher->dispatch('OCA\DAV\Connector\Sabre::addPlugin', $event);
201
+
202
+        // Some WebDAV clients do require Class 2 WebDAV support (locking), since
203
+        // we do not provide locking we emulate it using a fake locking plugin.
204
+        if($request->isUserAgent([
205
+            '/WebDAVFS/',
206
+            '/OneNote/',
207
+            '/^Microsoft-WebDAV/',// Microsoft-WebDAV-MiniRedir/6.1.7601
208
+        ])) {
209
+            $this->server->addPlugin(new FakeLockerPlugin());
210
+        }
211
+
212
+        if (BrowserErrorPagePlugin::isBrowserRequest($request)) {
213
+            $this->server->addPlugin(new BrowserErrorPagePlugin());
214
+        }
215
+
216
+        $lazySearchBackend = new LazySearchBackend();
217
+        $this->server->addPlugin(new SearchPlugin($lazySearchBackend));
218
+
219
+        // wait with registering these until auth is handled and the filesystem is setup
220
+        $this->server->on('beforeMethod:*', function () use ($root, $lazySearchBackend) {
221
+            // custom properties plugin must be the last one
222
+            $userSession = \OC::$server->getUserSession();
223
+            $user = $userSession->getUser();
224
+            if ($user !== null) {
225
+                $view = \OC\Files\Filesystem::getView();
226
+                $this->server->addPlugin(
227
+                    new FilesPlugin(
228
+                        $this->server->tree,
229
+                        \OC::$server->getConfig(),
230
+                        $this->request,
231
+                        \OC::$server->getPreviewManager(),
232
+                        false,
233
+                        !\OC::$server->getConfig()->getSystemValue('debug', false)
234
+                    )
235
+                );
236
+
237
+                $this->server->addPlugin(
238
+                    new \Sabre\DAV\PropertyStorage\Plugin(
239
+                        new CustomPropertiesBackend(
240
+                            $this->server->tree,
241
+                            \OC::$server->getDatabaseConnection(),
242
+                            \OC::$server->getUserSession()->getUser()
243
+                        )
244
+                    )
245
+                );
246
+                if ($view !== null) {
247
+                    $this->server->addPlugin(
248
+                        new QuotaPlugin($view, false));
249
+                }
250
+                $this->server->addPlugin(
251
+                    new TagsPlugin(
252
+                        $this->server->tree, \OC::$server->getTagManager()
253
+                    )
254
+                );
255
+                // TODO: switch to LazyUserFolder
256
+                $userFolder = \OC::$server->getUserFolder();
257
+                $this->server->addPlugin(new SharesPlugin(
258
+                    $this->server->tree,
259
+                    $userSession,
260
+                    $userFolder,
261
+                    \OC::$server->getShareManager()
262
+                ));
263
+                $this->server->addPlugin(new CommentPropertiesPlugin(
264
+                    \OC::$server->getCommentsManager(),
265
+                    $userSession
266
+                ));
267
+                $this->server->addPlugin(new \OCA\DAV\CalDAV\Search\SearchPlugin());
268
+                if ($view !== null) {
269
+                    $this->server->addPlugin(new FilesReportPlugin(
270
+                        $this->server->tree,
271
+                        $view,
272
+                        \OC::$server->getSystemTagManager(),
273
+                        \OC::$server->getSystemTagObjectMapper(),
274
+                        \OC::$server->getTagManager(),
275
+                        $userSession,
276
+                        \OC::$server->getGroupManager(),
277
+                        $userFolder,
278
+                        \OC::$server->getAppManager()
279
+                    ));
280
+                    $lazySearchBackend->setBackend(new \OCA\DAV\Files\FileSearchBackend(
281
+                        $this->server->tree,
282
+                        $user,
283
+                        \OC::$server->getRootFolder(),
284
+                        \OC::$server->getShareManager(),
285
+                        $view
286
+                    ));
287
+                }
288
+                $this->server->addPlugin(new \OCA\DAV\CalDAV\BirthdayCalendar\EnablePlugin(
289
+                    \OC::$server->getConfig(),
290
+                    \OC::$server->query(BirthdayService::class)
291
+                ));
292
+                $this->server->addPlugin(new AppleProvisioningPlugin(
293
+                    \OC::$server->getUserSession(),
294
+                    \OC::$server->getURLGenerator(),
295
+                    \OC::$server->getThemingDefaults(),
296
+                    \OC::$server->getRequest(),
297
+                    \OC::$server->getL10N('dav'),
298
+                    function () {
299
+                        return UUIDUtil::getUUID();
300
+                    }
301
+                ));
302
+            }
303
+
304
+            // register plugins from apps
305
+            $pluginManager = new PluginManager(
306
+                \OC::$server,
307
+                \OC::$server->getAppManager()
308
+            );
309
+            foreach ($pluginManager->getAppPlugins() as $appPlugin) {
310
+                $this->server->addPlugin($appPlugin);
311
+            }
312
+            foreach ($pluginManager->getAppCollections() as $appCollection) {
313
+                $root->addChild($appCollection);
314
+            }
315
+        });
316
+    }
317
+
318
+    public function exec() {
319
+        $this->server->exec();
320
+    }
321
+
322
+    private function requestIsForSubtree(array $subTrees): bool {
323
+        foreach ($subTrees as $subTree) {
324
+            $subTree = trim($subTree, ' /');
325
+            if (strpos($this->server->getRequestUri(), $subTree.'/') === 0) {
326
+                return true;
327
+            }
328
+        }
329
+        return false;
330
+    }
331 331
 }
Please login to merge, or discard this patch.
apps/dav/lib/Command/SyncBirthdayCalendar.php 1 patch
Indentation   +82 added lines, -82 removed lines patch added patch discarded remove patch
@@ -38,86 +38,86 @@
 block discarded – undo
38 38
 
39 39
 class SyncBirthdayCalendar extends Command {
40 40
 
41
-	/** @var BirthdayService */
42
-	private $birthdayService;
43
-
44
-	/** @var IConfig */
45
-	private $config;
46
-
47
-	/** @var IUserManager */
48
-	private $userManager;
49
-
50
-	/**
51
-	 * @param IUserManager $userManager
52
-	 * @param IConfig $config
53
-	 * @param BirthdayService $birthdayService
54
-	 */
55
-	function __construct(IUserManager $userManager, IConfig $config,
56
-						 BirthdayService $birthdayService) {
57
-		parent::__construct();
58
-		$this->birthdayService = $birthdayService;
59
-		$this->config = $config;
60
-		$this->userManager = $userManager;
61
-	}
62
-
63
-	protected function configure() {
64
-		$this
65
-			->setName('dav:sync-birthday-calendar')
66
-			->setDescription('Synchronizes the birthday calendar')
67
-			->addArgument('user',
68
-				InputArgument::OPTIONAL,
69
-				'User for whom the birthday calendar will be synchronized');
70
-	}
71
-
72
-	/**
73
-	 * @param InputInterface $input
74
-	 * @param OutputInterface $output
75
-	 */
76
-	protected function execute(InputInterface $input, OutputInterface $output) {
77
-		$this->verifyEnabled();
78
-
79
-		$user = $input->getArgument('user');
80
-		if (!is_null($user)) {
81
-			if (!$this->userManager->userExists($user)) {
82
-				throw new \InvalidArgumentException("User <$user> in unknown.");
83
-			}
84
-
85
-			// re-enable the birthday calendar in case it's called directly with a user name
86
-			$isEnabled = $this->config->getUserValue($user, 'dav', 'generateBirthdayCalendar', 'yes');
87
-			if ($isEnabled !== 'yes') {
88
-				$this->config->setUserValue($user, 'dav', 'generateBirthdayCalendar', 'yes');
89
-				$output->writeln("Re-enabling birthday calendar for $user");
90
-			}
91
-
92
-			$output->writeln("Start birthday calendar sync for $user");
93
-			$this->birthdayService->syncUser($user);
94
-			return;
95
-		}
96
-		$output->writeln("Start birthday calendar sync for all users ...");
97
-		$p = new ProgressBar($output);
98
-		$p->start();
99
-		$this->userManager->callForSeenUsers(function ($user) use ($p) {
100
-			$p->advance();
101
-
102
-			$userId = $user->getUID();
103
-			$isEnabled = $this->config->getUserValue($userId, 'dav', 'generateBirthdayCalendar', 'yes');
104
-			if ($isEnabled !== 'yes') {
105
-				return;
106
-			}
107
-
108
-			/** @var IUser $user */
109
-			$this->birthdayService->syncUser($user->getUID());
110
-		});
111
-
112
-		$p->finish();
113
-		$output->writeln('');
114
-	}
115
-
116
-	protected function verifyEnabled() {
117
-		$isEnabled = $this->config->getAppValue('dav', 'generateBirthdayCalendar', 'yes');
118
-
119
-		if ($isEnabled !== 'yes') {
120
-			throw new \InvalidArgumentException('Birthday calendars are disabled');
121
-		}
122
-	}
41
+    /** @var BirthdayService */
42
+    private $birthdayService;
43
+
44
+    /** @var IConfig */
45
+    private $config;
46
+
47
+    /** @var IUserManager */
48
+    private $userManager;
49
+
50
+    /**
51
+     * @param IUserManager $userManager
52
+     * @param IConfig $config
53
+     * @param BirthdayService $birthdayService
54
+     */
55
+    function __construct(IUserManager $userManager, IConfig $config,
56
+                            BirthdayService $birthdayService) {
57
+        parent::__construct();
58
+        $this->birthdayService = $birthdayService;
59
+        $this->config = $config;
60
+        $this->userManager = $userManager;
61
+    }
62
+
63
+    protected function configure() {
64
+        $this
65
+            ->setName('dav:sync-birthday-calendar')
66
+            ->setDescription('Synchronizes the birthday calendar')
67
+            ->addArgument('user',
68
+                InputArgument::OPTIONAL,
69
+                'User for whom the birthday calendar will be synchronized');
70
+    }
71
+
72
+    /**
73
+     * @param InputInterface $input
74
+     * @param OutputInterface $output
75
+     */
76
+    protected function execute(InputInterface $input, OutputInterface $output) {
77
+        $this->verifyEnabled();
78
+
79
+        $user = $input->getArgument('user');
80
+        if (!is_null($user)) {
81
+            if (!$this->userManager->userExists($user)) {
82
+                throw new \InvalidArgumentException("User <$user> in unknown.");
83
+            }
84
+
85
+            // re-enable the birthday calendar in case it's called directly with a user name
86
+            $isEnabled = $this->config->getUserValue($user, 'dav', 'generateBirthdayCalendar', 'yes');
87
+            if ($isEnabled !== 'yes') {
88
+                $this->config->setUserValue($user, 'dav', 'generateBirthdayCalendar', 'yes');
89
+                $output->writeln("Re-enabling birthday calendar for $user");
90
+            }
91
+
92
+            $output->writeln("Start birthday calendar sync for $user");
93
+            $this->birthdayService->syncUser($user);
94
+            return;
95
+        }
96
+        $output->writeln("Start birthday calendar sync for all users ...");
97
+        $p = new ProgressBar($output);
98
+        $p->start();
99
+        $this->userManager->callForSeenUsers(function ($user) use ($p) {
100
+            $p->advance();
101
+
102
+            $userId = $user->getUID();
103
+            $isEnabled = $this->config->getUserValue($userId, 'dav', 'generateBirthdayCalendar', 'yes');
104
+            if ($isEnabled !== 'yes') {
105
+                return;
106
+            }
107
+
108
+            /** @var IUser $user */
109
+            $this->birthdayService->syncUser($user->getUID());
110
+        });
111
+
112
+        $p->finish();
113
+        $output->writeln('');
114
+    }
115
+
116
+    protected function verifyEnabled() {
117
+        $isEnabled = $this->config->getAppValue('dav', 'generateBirthdayCalendar', 'yes');
118
+
119
+        if ($isEnabled !== 'yes') {
120
+            throw new \InvalidArgumentException('Birthday calendars are disabled');
121
+        }
122
+    }
123 123
 }
Please login to merge, or discard this patch.
apps/dav/lib/Command/SyncSystemAddressBook.php 1 patch
Indentation   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -31,36 +31,36 @@
 block discarded – undo
31 31
 
32 32
 class SyncSystemAddressBook extends Command {
33 33
 
34
-	/** @var SyncService */
35
-	private $syncService;
34
+    /** @var SyncService */
35
+    private $syncService;
36 36
 
37
-	/**
38
-	 * @param SyncService $syncService
39
-	 */
40
-	function __construct(SyncService $syncService) {
41
-		parent::__construct();
42
-		$this->syncService = $syncService;
43
-	}
37
+    /**
38
+     * @param SyncService $syncService
39
+     */
40
+    function __construct(SyncService $syncService) {
41
+        parent::__construct();
42
+        $this->syncService = $syncService;
43
+    }
44 44
 
45
-	protected function configure() {
46
-		$this
47
-			->setName('dav:sync-system-addressbook')
48
-			->setDescription('Synchronizes users to the system addressbook');
49
-	}
45
+    protected function configure() {
46
+        $this
47
+            ->setName('dav:sync-system-addressbook')
48
+            ->setDescription('Synchronizes users to the system addressbook');
49
+    }
50 50
 
51
-	/**
52
-	 * @param InputInterface $input
53
-	 * @param OutputInterface $output
54
-	 */
55
-	protected function execute(InputInterface $input, OutputInterface $output) {
56
-		$output->writeln('Syncing users ...');
57
-		$progress = new ProgressBar($output);
58
-		$progress->start();
59
-		$this->syncService->syncInstance(function () use ($progress) {
60
-			$progress->advance();
61
-		});
51
+    /**
52
+     * @param InputInterface $input
53
+     * @param OutputInterface $output
54
+     */
55
+    protected function execute(InputInterface $input, OutputInterface $output) {
56
+        $output->writeln('Syncing users ...');
57
+        $progress = new ProgressBar($output);
58
+        $progress->start();
59
+        $this->syncService->syncInstance(function () use ($progress) {
60
+            $progress->advance();
61
+        });
62 62
 
63
-		$progress->finish();
64
-		$output->writeln('');
65
-	}
63
+        $progress->finish();
64
+        $output->writeln('');
65
+    }
66 66
 }
Please login to merge, or discard this patch.
apps/dav/lib/Traits/PrincipalProxyTrait.php 1 patch
Indentation   +187 added lines, -187 removed lines patch added patch discarded remove patch
@@ -35,191 +35,191 @@
 block discarded – undo
35 35
  */
36 36
 trait PrincipalProxyTrait {
37 37
 
38
-	/**
39
-	 * Returns the list of members for a group-principal
40
-	 *
41
-	 * @param string $principal
42
-	 * @return string[]
43
-	 * @throws Exception
44
-	 */
45
-	public function getGroupMemberSet($principal) {
46
-		$members = [];
47
-
48
-		if ($this->isProxyPrincipal($principal)) {
49
-			$realPrincipal = $this->getPrincipalUriFromProxyPrincipal($principal);
50
-			$principalArray = $this->getPrincipalByPath($realPrincipal);
51
-			if (!$principalArray) {
52
-				throw new Exception('Principal not found');
53
-			}
54
-
55
-			$proxies = $this->proxyMapper->getProxiesOf($principalArray['uri']);
56
-			foreach ($proxies as $proxy) {
57
-				if ($this->isReadProxyPrincipal($principal) && $proxy->getPermissions() === ProxyMapper::PERMISSION_READ) {
58
-					$members[] = $proxy->getProxyId();
59
-				}
60
-
61
-				if ($this->isWriteProxyPrincipal($principal) && $proxy->getPermissions() === (ProxyMapper::PERMISSION_READ | ProxyMapper::PERMISSION_WRITE)) {
62
-					$members[] = $proxy->getProxyId();
63
-				}
64
-			}
65
-		}
66
-
67
-		return $members;
68
-	}
69
-
70
-	/**
71
-	 * Returns the list of groups a principal is a member of
72
-	 *
73
-	 * @param string $principal
74
-	 * @param bool $needGroups
75
-	 * @return array
76
-	 * @throws Exception
77
-	 */
78
-	public function getGroupMembership($principal, $needGroups = false) {
79
-		list($prefix, $name) = \Sabre\Uri\split($principal);
80
-
81
-		if ($prefix !== $this->principalPrefix) {
82
-			return [];
83
-		}
84
-
85
-		$principalArray = $this->getPrincipalByPath($principal);
86
-		if (!$principalArray) {
87
-			throw new Exception('Principal not found');
88
-		}
89
-
90
-		$groups = [];
91
-		$proxies = $this->proxyMapper->getProxiesFor($principal);
92
-		foreach ($proxies as $proxy) {
93
-			if ($proxy->getPermissions() === ProxyMapper::PERMISSION_READ) {
94
-				$groups[] = $proxy->getOwnerId() . '/calendar-proxy-read';
95
-			}
96
-
97
-			if ($proxy->getPermissions() === (ProxyMapper::PERMISSION_READ | ProxyMapper::PERMISSION_WRITE)) {
98
-				$groups[] = $proxy->getOwnerId() . '/calendar-proxy-write';
99
-			}
100
-		}
101
-
102
-		return $groups;
103
-	}
104
-
105
-	/**
106
-	 * Updates the list of group members for a group principal.
107
-	 *
108
-	 * The principals should be passed as a list of uri's.
109
-	 *
110
-	 * @param string $principal
111
-	 * @param string[] $members
112
-	 * @throws Exception
113
-	 */
114
-	public function setGroupMemberSet($principal, array $members) {
115
-		list($principalUri, $target) = \Sabre\Uri\split($principal);
116
-
117
-		if ($target !== 'calendar-proxy-write' && $target !== 'calendar-proxy-read') {
118
-			throw new Exception('Setting members of the group is not supported yet');
119
-		}
120
-
121
-		$masterPrincipalArray = $this->getPrincipalByPath($principalUri);
122
-		if (!$masterPrincipalArray) {
123
-			throw new Exception('Principal not found');
124
-		}
125
-
126
-		$permission = ProxyMapper::PERMISSION_READ;
127
-		if ($target === 'calendar-proxy-write') {
128
-			$permission |= ProxyMapper::PERMISSION_WRITE;
129
-		}
130
-
131
-		list($prefix, $owner) = \Sabre\Uri\split($principalUri);
132
-		$proxies = $this->proxyMapper->getProxiesOf($principalUri);
133
-
134
-		foreach ($members as $member) {
135
-			list($prefix, $name) = \Sabre\Uri\split($member);
136
-
137
-			if ($prefix !== $this->principalPrefix) {
138
-				throw new Exception('Invalid member group prefix: ' . $prefix);
139
-			}
140
-
141
-			$principalArray = $this->getPrincipalByPath($member);
142
-			if (!$principalArray) {
143
-				throw new Exception('Principal not found');
144
-			}
145
-
146
-			$found = false;
147
-			foreach ($proxies as $proxy) {
148
-				if ($proxy->getProxyId() === $member) {
149
-					$found = true;
150
-					$proxy->setPermissions($proxy->getPermissions() | $permission);
151
-					$this->proxyMapper->update($proxy);
152
-
153
-					$proxies = array_filter($proxies, function (Proxy $p) use ($proxy) {
154
-						return $p->getId() !== $proxy->getId();
155
-					});
156
-					break;
157
-				}
158
-			}
159
-
160
-			if ($found === false) {
161
-				$proxy = new Proxy();
162
-				$proxy->setOwnerId($principalUri);
163
-				$proxy->setProxyId($member);
164
-				$proxy->setPermissions($permission);
165
-				$this->proxyMapper->insert($proxy);
166
-			}
167
-		}
168
-
169
-		// Delete all remaining proxies
170
-		foreach ($proxies as $proxy) {
171
-			// Write and Read Proxies have individual requests,
172
-			// so only delete proxies of this permission
173
-			if ($proxy->getPermissions() === $permission) {
174
-				$this->proxyMapper->delete($proxy);
175
-			}
176
-		}
177
-	}
178
-
179
-	/**
180
-	 * @param string $principalUri
181
-	 * @return bool
182
-	 */
183
-	private function isProxyPrincipal(string $principalUri):bool {
184
-		list($realPrincipalUri, $proxy) = \Sabre\Uri\split($principalUri);
185
-		list($prefix, $userId) = \Sabre\Uri\split($realPrincipalUri);
186
-
187
-		if (!isset($prefix) || !isset($userId)) {
188
-			return false;
189
-		}
190
-		if ($prefix !== $this->principalPrefix) {
191
-			return false;
192
-		}
193
-
194
-		return $proxy === 'calendar-proxy-read'
195
-			|| $proxy === 'calendar-proxy-write';
196
-
197
-	}
198
-
199
-	/**
200
-	 * @param string $principalUri
201
-	 * @return bool
202
-	 */
203
-	private function isReadProxyPrincipal(string $principalUri):bool {
204
-		list(, $proxy) = \Sabre\Uri\split($principalUri);
205
-		return $proxy === 'calendar-proxy-read';
206
-	}
207
-
208
-	/**
209
-	 * @param string $principalUri
210
-	 * @return bool
211
-	 */
212
-	private function isWriteProxyPrincipal(string $principalUri):bool {
213
-		list(, $proxy) = \Sabre\Uri\split($principalUri);
214
-		return $proxy === 'calendar-proxy-write';
215
-	}
216
-
217
-	/**
218
-	 * @param string $principalUri
219
-	 * @return string
220
-	 */
221
-	private function getPrincipalUriFromProxyPrincipal(string $principalUri):string {
222
-		list($realPrincipalUri, ) = \Sabre\Uri\split($principalUri);
223
-		return $realPrincipalUri;
224
-	}
38
+    /**
39
+     * Returns the list of members for a group-principal
40
+     *
41
+     * @param string $principal
42
+     * @return string[]
43
+     * @throws Exception
44
+     */
45
+    public function getGroupMemberSet($principal) {
46
+        $members = [];
47
+
48
+        if ($this->isProxyPrincipal($principal)) {
49
+            $realPrincipal = $this->getPrincipalUriFromProxyPrincipal($principal);
50
+            $principalArray = $this->getPrincipalByPath($realPrincipal);
51
+            if (!$principalArray) {
52
+                throw new Exception('Principal not found');
53
+            }
54
+
55
+            $proxies = $this->proxyMapper->getProxiesOf($principalArray['uri']);
56
+            foreach ($proxies as $proxy) {
57
+                if ($this->isReadProxyPrincipal($principal) && $proxy->getPermissions() === ProxyMapper::PERMISSION_READ) {
58
+                    $members[] = $proxy->getProxyId();
59
+                }
60
+
61
+                if ($this->isWriteProxyPrincipal($principal) && $proxy->getPermissions() === (ProxyMapper::PERMISSION_READ | ProxyMapper::PERMISSION_WRITE)) {
62
+                    $members[] = $proxy->getProxyId();
63
+                }
64
+            }
65
+        }
66
+
67
+        return $members;
68
+    }
69
+
70
+    /**
71
+     * Returns the list of groups a principal is a member of
72
+     *
73
+     * @param string $principal
74
+     * @param bool $needGroups
75
+     * @return array
76
+     * @throws Exception
77
+     */
78
+    public function getGroupMembership($principal, $needGroups = false) {
79
+        list($prefix, $name) = \Sabre\Uri\split($principal);
80
+
81
+        if ($prefix !== $this->principalPrefix) {
82
+            return [];
83
+        }
84
+
85
+        $principalArray = $this->getPrincipalByPath($principal);
86
+        if (!$principalArray) {
87
+            throw new Exception('Principal not found');
88
+        }
89
+
90
+        $groups = [];
91
+        $proxies = $this->proxyMapper->getProxiesFor($principal);
92
+        foreach ($proxies as $proxy) {
93
+            if ($proxy->getPermissions() === ProxyMapper::PERMISSION_READ) {
94
+                $groups[] = $proxy->getOwnerId() . '/calendar-proxy-read';
95
+            }
96
+
97
+            if ($proxy->getPermissions() === (ProxyMapper::PERMISSION_READ | ProxyMapper::PERMISSION_WRITE)) {
98
+                $groups[] = $proxy->getOwnerId() . '/calendar-proxy-write';
99
+            }
100
+        }
101
+
102
+        return $groups;
103
+    }
104
+
105
+    /**
106
+     * Updates the list of group members for a group principal.
107
+     *
108
+     * The principals should be passed as a list of uri's.
109
+     *
110
+     * @param string $principal
111
+     * @param string[] $members
112
+     * @throws Exception
113
+     */
114
+    public function setGroupMemberSet($principal, array $members) {
115
+        list($principalUri, $target) = \Sabre\Uri\split($principal);
116
+
117
+        if ($target !== 'calendar-proxy-write' && $target !== 'calendar-proxy-read') {
118
+            throw new Exception('Setting members of the group is not supported yet');
119
+        }
120
+
121
+        $masterPrincipalArray = $this->getPrincipalByPath($principalUri);
122
+        if (!$masterPrincipalArray) {
123
+            throw new Exception('Principal not found');
124
+        }
125
+
126
+        $permission = ProxyMapper::PERMISSION_READ;
127
+        if ($target === 'calendar-proxy-write') {
128
+            $permission |= ProxyMapper::PERMISSION_WRITE;
129
+        }
130
+
131
+        list($prefix, $owner) = \Sabre\Uri\split($principalUri);
132
+        $proxies = $this->proxyMapper->getProxiesOf($principalUri);
133
+
134
+        foreach ($members as $member) {
135
+            list($prefix, $name) = \Sabre\Uri\split($member);
136
+
137
+            if ($prefix !== $this->principalPrefix) {
138
+                throw new Exception('Invalid member group prefix: ' . $prefix);
139
+            }
140
+
141
+            $principalArray = $this->getPrincipalByPath($member);
142
+            if (!$principalArray) {
143
+                throw new Exception('Principal not found');
144
+            }
145
+
146
+            $found = false;
147
+            foreach ($proxies as $proxy) {
148
+                if ($proxy->getProxyId() === $member) {
149
+                    $found = true;
150
+                    $proxy->setPermissions($proxy->getPermissions() | $permission);
151
+                    $this->proxyMapper->update($proxy);
152
+
153
+                    $proxies = array_filter($proxies, function (Proxy $p) use ($proxy) {
154
+                        return $p->getId() !== $proxy->getId();
155
+                    });
156
+                    break;
157
+                }
158
+            }
159
+
160
+            if ($found === false) {
161
+                $proxy = new Proxy();
162
+                $proxy->setOwnerId($principalUri);
163
+                $proxy->setProxyId($member);
164
+                $proxy->setPermissions($permission);
165
+                $this->proxyMapper->insert($proxy);
166
+            }
167
+        }
168
+
169
+        // Delete all remaining proxies
170
+        foreach ($proxies as $proxy) {
171
+            // Write and Read Proxies have individual requests,
172
+            // so only delete proxies of this permission
173
+            if ($proxy->getPermissions() === $permission) {
174
+                $this->proxyMapper->delete($proxy);
175
+            }
176
+        }
177
+    }
178
+
179
+    /**
180
+     * @param string $principalUri
181
+     * @return bool
182
+     */
183
+    private function isProxyPrincipal(string $principalUri):bool {
184
+        list($realPrincipalUri, $proxy) = \Sabre\Uri\split($principalUri);
185
+        list($prefix, $userId) = \Sabre\Uri\split($realPrincipalUri);
186
+
187
+        if (!isset($prefix) || !isset($userId)) {
188
+            return false;
189
+        }
190
+        if ($prefix !== $this->principalPrefix) {
191
+            return false;
192
+        }
193
+
194
+        return $proxy === 'calendar-proxy-read'
195
+            || $proxy === 'calendar-proxy-write';
196
+
197
+    }
198
+
199
+    /**
200
+     * @param string $principalUri
201
+     * @return bool
202
+     */
203
+    private function isReadProxyPrincipal(string $principalUri):bool {
204
+        list(, $proxy) = \Sabre\Uri\split($principalUri);
205
+        return $proxy === 'calendar-proxy-read';
206
+    }
207
+
208
+    /**
209
+     * @param string $principalUri
210
+     * @return bool
211
+     */
212
+    private function isWriteProxyPrincipal(string $principalUri):bool {
213
+        list(, $proxy) = \Sabre\Uri\split($principalUri);
214
+        return $proxy === 'calendar-proxy-write';
215
+    }
216
+
217
+    /**
218
+     * @param string $principalUri
219
+     * @return string
220
+     */
221
+    private function getPrincipalUriFromProxyPrincipal(string $principalUri):string {
222
+        list($realPrincipalUri, ) = \Sabre\Uri\split($principalUri);
223
+        return $realPrincipalUri;
224
+    }
225 225
 }
Please login to merge, or discard this patch.
apps/dav/lib/Provisioning/Apple/AppleProvisioningPlugin.php 1 patch
Indentation   +135 added lines, -135 removed lines patch added patch discarded remove patch
@@ -36,164 +36,164 @@  discard block
 block discarded – undo
36 36
 
37 37
 class AppleProvisioningPlugin extends ServerPlugin {
38 38
 
39
-	/**
40
-	 * @var Server
41
-	 */
42
-	protected $server;
39
+    /**
40
+     * @var Server
41
+     */
42
+    protected $server;
43 43
 
44
-	/**
45
-	 * @var IURLGenerator
46
-	 */
47
-	protected $urlGenerator;
44
+    /**
45
+     * @var IURLGenerator
46
+     */
47
+    protected $urlGenerator;
48 48
 
49
-	/**
50
-	 * @var IUserSession
51
-	 */
52
-	protected $userSession;
49
+    /**
50
+     * @var IUserSession
51
+     */
52
+    protected $userSession;
53 53
 
54
-	/**
55
-	 * @var \OC_Defaults
56
-	 */
57
-	protected $themingDefaults;
54
+    /**
55
+     * @var \OC_Defaults
56
+     */
57
+    protected $themingDefaults;
58 58
 
59
-	/**
60
-	 * @var IRequest
61
-	 */
62
-	protected $request;
59
+    /**
60
+     * @var IRequest
61
+     */
62
+    protected $request;
63 63
 
64
-	/**
65
-	 * @var IL10N
66
-	 */
67
-	protected $l10n;
64
+    /**
65
+     * @var IL10N
66
+     */
67
+    protected $l10n;
68 68
 
69
-	/**
70
-	 * @var \closure
71
-	 */
72
-	protected $uuidClosure;
69
+    /**
70
+     * @var \closure
71
+     */
72
+    protected $uuidClosure;
73 73
 
74
-	/**
75
-	 * AppleProvisioningPlugin constructor.
76
-	 *
77
-	 * @param IUserSession $userSession
78
-	 * @param IURLGenerator $urlGenerator
79
-	 * @param \OC_Defaults $themingDefaults
80
-	 * @param IRequest $request
81
-	 * @param IL10N $l10n
82
-	 * @param \closure $uuidClosure
83
-	 */
84
-	public function __construct(IUserSession $userSession, IURLGenerator $urlGenerator,
85
-								\OC_Defaults $themingDefaults, IRequest $request,
86
-								IL10N $l10n, \closure $uuidClosure) {
87
-		$this->userSession = $userSession;
88
-		$this->urlGenerator = $urlGenerator;
89
-		$this->themingDefaults = $themingDefaults;
90
-		$this->request = $request;
91
-		$this->l10n = $l10n;
92
-		$this->uuidClosure = $uuidClosure;
93
-	}
74
+    /**
75
+     * AppleProvisioningPlugin constructor.
76
+     *
77
+     * @param IUserSession $userSession
78
+     * @param IURLGenerator $urlGenerator
79
+     * @param \OC_Defaults $themingDefaults
80
+     * @param IRequest $request
81
+     * @param IL10N $l10n
82
+     * @param \closure $uuidClosure
83
+     */
84
+    public function __construct(IUserSession $userSession, IURLGenerator $urlGenerator,
85
+                                \OC_Defaults $themingDefaults, IRequest $request,
86
+                                IL10N $l10n, \closure $uuidClosure) {
87
+        $this->userSession = $userSession;
88
+        $this->urlGenerator = $urlGenerator;
89
+        $this->themingDefaults = $themingDefaults;
90
+        $this->request = $request;
91
+        $this->l10n = $l10n;
92
+        $this->uuidClosure = $uuidClosure;
93
+    }
94 94
 
95
-	/**
96
-	 * @param Server $server
97
-	 */
98
-	public function initialize(Server $server) {
99
-		$this->server = $server;
100
-		$this->server->on('method:GET', [$this, 'httpGet'], 90);
101
-	}
95
+    /**
96
+     * @param Server $server
97
+     */
98
+    public function initialize(Server $server) {
99
+        $this->server = $server;
100
+        $this->server->on('method:GET', [$this, 'httpGet'], 90);
101
+    }
102 102
 
103
-	/**
104
-	 * @param RequestInterface $request
105
-	 * @param ResponseInterface $response
106
-	 * @return boolean
107
-	 */
108
-	public function httpGet(RequestInterface $request, ResponseInterface $response):bool {
109
-		if ($request->getPath() !== 'provisioning/' . AppleProvisioningNode::FILENAME) {
110
-			return true;
111
-		}
103
+    /**
104
+     * @param RequestInterface $request
105
+     * @param ResponseInterface $response
106
+     * @return boolean
107
+     */
108
+    public function httpGet(RequestInterface $request, ResponseInterface $response):bool {
109
+        if ($request->getPath() !== 'provisioning/' . AppleProvisioningNode::FILENAME) {
110
+            return true;
111
+        }
112 112
 
113
-		$user = $this->userSession->getUser();
114
-		if (!$user) {
115
-			return true;
116
-		}
113
+        $user = $this->userSession->getUser();
114
+        if (!$user) {
115
+            return true;
116
+        }
117 117
 
118
-		$serverProtocol = $this->request->getServerProtocol();
119
-		$useSSL = ($serverProtocol === 'https');
118
+        $serverProtocol = $this->request->getServerProtocol();
119
+        $useSSL = ($serverProtocol === 'https');
120 120
 
121
-		if (!$useSSL) {
122
-			$response->setStatus(200);
123
-			$response->setHeader('Content-Type', 'text/plain; charset=utf-8');
124
-			$response->setBody($this->l10n->t('Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS.', [$this->themingDefaults->getName()]));
121
+        if (!$useSSL) {
122
+            $response->setStatus(200);
123
+            $response->setHeader('Content-Type', 'text/plain; charset=utf-8');
124
+            $response->setBody($this->l10n->t('Your %s needs to be configured to use HTTPS in order to use CalDAV and CardDAV with iOS/macOS.', [$this->themingDefaults->getName()]));
125 125
 
126
-			return false;
127
-		}
126
+            return false;
127
+        }
128 128
 
129
-		$absoluteURL = $this->urlGenerator->getBaseUrl();
130
-		$parsedUrl = parse_url($absoluteURL);
131
-		if (isset($parsedUrl['port'])) {
132
-			$serverPort = (int) $parsedUrl['port'];
133
-		} else {
134
-			$serverPort = 443;
135
-		}
136
-		$server_url = $parsedUrl['host'];
129
+        $absoluteURL = $this->urlGenerator->getBaseUrl();
130
+        $parsedUrl = parse_url($absoluteURL);
131
+        if (isset($parsedUrl['port'])) {
132
+            $serverPort = (int) $parsedUrl['port'];
133
+        } else {
134
+            $serverPort = 443;
135
+        }
136
+        $server_url = $parsedUrl['host'];
137 137
 
138
-		$description = $this->themingDefaults->getName();
139
-		$userId = $user->getUID();
138
+        $description = $this->themingDefaults->getName();
139
+        $userId = $user->getUID();
140 140
 
141
-		$reverseDomain = implode('.', array_reverse(explode('.', $parsedUrl['host'])));
141
+        $reverseDomain = implode('.', array_reverse(explode('.', $parsedUrl['host'])));
142 142
 
143
-		$caldavUUID = call_user_func($this->uuidClosure);
144
-		$carddavUUID = call_user_func($this->uuidClosure);
145
-		$profileUUID = call_user_func($this->uuidClosure);
143
+        $caldavUUID = call_user_func($this->uuidClosure);
144
+        $carddavUUID = call_user_func($this->uuidClosure);
145
+        $profileUUID = call_user_func($this->uuidClosure);
146 146
 
147
-		$caldavIdentifier = $reverseDomain . '.' . $caldavUUID;
148
-		$carddavIdentifier = $reverseDomain . '.' . $carddavUUID;
149
-		$profileIdentifier = $reverseDomain . '.' . $profileUUID;
147
+        $caldavIdentifier = $reverseDomain . '.' . $caldavUUID;
148
+        $carddavIdentifier = $reverseDomain . '.' . $carddavUUID;
149
+        $profileIdentifier = $reverseDomain . '.' . $profileUUID;
150 150
 
151
-		$caldavDescription = $this->l10n->t('Configures a CalDAV account');
152
-		$caldavDisplayname = $description . ' CalDAV';
153
-		$carddavDescription = $this->l10n->t('Configures a CardDAV account');
154
-		$carddavDisplayname = $description . ' CardDAV';
151
+        $caldavDescription = $this->l10n->t('Configures a CalDAV account');
152
+        $caldavDisplayname = $description . ' CalDAV';
153
+        $carddavDescription = $this->l10n->t('Configures a CardDAV account');
154
+        $carddavDisplayname = $description . ' CardDAV';
155 155
 
156
-		$filename = $userId . '-' . AppleProvisioningNode::FILENAME;
156
+        $filename = $userId . '-' . AppleProvisioningNode::FILENAME;
157 157
 
158
-		$xmlSkeleton = $this->getTemplate();
159
-		$body = vsprintf($xmlSkeleton, array_map(function ($v) {
160
-				return \htmlspecialchars($v, ENT_XML1, 'UTF-8');
161
-			}, [
162
-				$description,
163
-				$server_url,
164
-				$userId,
165
-				$serverPort,
166
-				$caldavDescription,
167
-				$caldavDisplayname,
168
-				$caldavIdentifier,
169
-				$caldavUUID,
170
-				$description,
171
-				$server_url,
172
-				$userId,
173
-				$serverPort,
174
-				$carddavDescription,
175
-				$carddavDisplayname,
176
-				$carddavIdentifier,
177
-				$carddavUUID,
178
-				$description,
179
-				$profileIdentifier,
180
-				$profileUUID
181
-			]
182
-		));
158
+        $xmlSkeleton = $this->getTemplate();
159
+        $body = vsprintf($xmlSkeleton, array_map(function ($v) {
160
+                return \htmlspecialchars($v, ENT_XML1, 'UTF-8');
161
+            }, [
162
+                $description,
163
+                $server_url,
164
+                $userId,
165
+                $serverPort,
166
+                $caldavDescription,
167
+                $caldavDisplayname,
168
+                $caldavIdentifier,
169
+                $caldavUUID,
170
+                $description,
171
+                $server_url,
172
+                $userId,
173
+                $serverPort,
174
+                $carddavDescription,
175
+                $carddavDisplayname,
176
+                $carddavIdentifier,
177
+                $carddavUUID,
178
+                $description,
179
+                $profileIdentifier,
180
+                $profileUUID
181
+            ]
182
+        ));
183 183
 
184
-		$response->setStatus(200);
185
-		$response->setHeader('Content-Disposition', 'attachment; filename="' . $filename . '"');
186
-		$response->setHeader('Content-Type', 'application/xml; charset=utf-8');
187
-		$response->setBody($body);
184
+        $response->setStatus(200);
185
+        $response->setHeader('Content-Disposition', 'attachment; filename="' . $filename . '"');
186
+        $response->setHeader('Content-Type', 'application/xml; charset=utf-8');
187
+        $response->setBody($body);
188 188
 
189
-		return false;
190
-	}
189
+        return false;
190
+    }
191 191
 
192
-	/**
193
-	 * @return string
194
-	 */
195
-	private function getTemplate():string {
196
-		return <<<EOF
192
+    /**
193
+     * @return string
194
+     */
195
+    private function getTemplate():string {
196
+        return <<<EOF
197 197
 <?xml version="1.0" encoding="UTF-8"?>
198 198
 <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
199 199
 <plist version="1.0">
@@ -265,5 +265,5 @@  discard block
 block discarded – undo
265 265
 </plist>
266 266
 
267 267
 EOF;
268
-	}
268
+    }
269 269
 }
Please login to merge, or discard this patch.