Passed
Push — master ( 24690a...b9026a )
by Christoph
20:57 queued 17s
created
apps/dav/lib/CardDAV/SystemAddressbook.php 1 patch
Indentation   +234 added lines, -234 removed lines patch added patch discarded remove patch
@@ -49,261 +49,261 @@
 block discarded – undo
49 49
 use function array_unique;
50 50
 
51 51
 class SystemAddressbook extends AddressBook {
52
-	public const URI_SHARED = 'z-server-generated--system';
53
-	/** @var IConfig */
54
-	private $config;
55
-	private IUserSession $userSession;
56
-	private ?TrustedServers $trustedServers;
57
-	private ?IRequest $request;
58
-	private ?IGroupManager $groupManager;
52
+    public const URI_SHARED = 'z-server-generated--system';
53
+    /** @var IConfig */
54
+    private $config;
55
+    private IUserSession $userSession;
56
+    private ?TrustedServers $trustedServers;
57
+    private ?IRequest $request;
58
+    private ?IGroupManager $groupManager;
59 59
 
60
-	public function __construct(BackendInterface $carddavBackend,
61
-		array $addressBookInfo,
62
-		IL10N $l10n,
63
-		IConfig $config,
64
-		IUserSession $userSession,
65
-		?IRequest $request = null,
66
-		?TrustedServers $trustedServers = null,
67
-		?IGroupManager $groupManager) {
68
-		parent::__construct($carddavBackend, $addressBookInfo, $l10n);
69
-		$this->config = $config;
70
-		$this->userSession = $userSession;
71
-		$this->request = $request;
72
-		$this->trustedServers = $trustedServers;
73
-		$this->groupManager = $groupManager;
60
+    public function __construct(BackendInterface $carddavBackend,
61
+        array $addressBookInfo,
62
+        IL10N $l10n,
63
+        IConfig $config,
64
+        IUserSession $userSession,
65
+        ?IRequest $request = null,
66
+        ?TrustedServers $trustedServers = null,
67
+        ?IGroupManager $groupManager) {
68
+        parent::__construct($carddavBackend, $addressBookInfo, $l10n);
69
+        $this->config = $config;
70
+        $this->userSession = $userSession;
71
+        $this->request = $request;
72
+        $this->trustedServers = $trustedServers;
73
+        $this->groupManager = $groupManager;
74 74
 
75
-		$this->addressBookInfo['{DAV:}displayname'] = $l10n->t('Accounts');
76
-		$this->addressBookInfo['{' . Plugin::NS_CARDDAV . '}addressbook-description'] = $l10n->t('System address book which holds all accounts');
77
-	}
75
+        $this->addressBookInfo['{DAV:}displayname'] = $l10n->t('Accounts');
76
+        $this->addressBookInfo['{' . Plugin::NS_CARDDAV . '}addressbook-description'] = $l10n->t('System address book which holds all accounts');
77
+    }
78 78
 
79
-	/**
80
-	 * No checkbox checked -> Show only the same user
81
-	 * 'Allow username autocompletion in share dialog' -> show everyone
82
-	 * 'Allow username autocompletion in share dialog' + 'Allow username autocompletion to users within the same groups' -> show only users in intersecting groups
83
-	 * 'Allow username autocompletion in share dialog' + 'Allow username autocompletion to users based on phone number integration' -> show only the same user
84
-	 * 'Allow username autocompletion in share dialog' + 'Allow username autocompletion to users within the same groups' + 'Allow username autocompletion to users based on phone number integration' -> show only users in intersecting groups
85
-	 */
86
-	public function getChildren() {
87
-		$shareEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
88
-		$shareEnumerationGroup = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
89
-		$shareEnumerationPhone = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes';
90
-		$user = $this->userSession->getUser();
91
-		if (!$user) {
92
-			// Should never happen because we don't allow anonymous access
93
-			return [];
94
-		}
95
-		if (!$shareEnumeration || !$shareEnumerationGroup && $shareEnumerationPhone) {
96
-			$name = SyncService::getCardUri($user);
97
-			try {
98
-				return [parent::getChild($name)];
99
-			} catch (NotFound $e) {
100
-				return [];
101
-			}
102
-		}
103
-		if ($shareEnumerationGroup) {
104
-			if ($this->groupManager === null) {
105
-				// Group manager is not available, so we can't determine which data is safe
106
-				return [];
107
-			}
108
-			$groups = $this->groupManager->getUserGroups($user);
109
-			$names = [];
110
-			foreach ($groups as $group) {
111
-				$users = $group->getUsers();
112
-				foreach ($users as $groupUser) {
113
-					if ($groupUser->getBackendClassName() === 'Guests') {
114
-						continue;
115
-					}
116
-					$names[] = SyncService::getCardUri($groupUser);
117
-				}
118
-			}
119
-			return parent::getMultipleChildren(array_unique($names));
120
-		}
79
+    /**
80
+     * No checkbox checked -> Show only the same user
81
+     * 'Allow username autocompletion in share dialog' -> show everyone
82
+     * 'Allow username autocompletion in share dialog' + 'Allow username autocompletion to users within the same groups' -> show only users in intersecting groups
83
+     * 'Allow username autocompletion in share dialog' + 'Allow username autocompletion to users based on phone number integration' -> show only the same user
84
+     * 'Allow username autocompletion in share dialog' + 'Allow username autocompletion to users within the same groups' + 'Allow username autocompletion to users based on phone number integration' -> show only users in intersecting groups
85
+     */
86
+    public function getChildren() {
87
+        $shareEnumeration = $this->config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes';
88
+        $shareEnumerationGroup = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes';
89
+        $shareEnumerationPhone = $this->config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes';
90
+        $user = $this->userSession->getUser();
91
+        if (!$user) {
92
+            // Should never happen because we don't allow anonymous access
93
+            return [];
94
+        }
95
+        if (!$shareEnumeration || !$shareEnumerationGroup && $shareEnumerationPhone) {
96
+            $name = SyncService::getCardUri($user);
97
+            try {
98
+                return [parent::getChild($name)];
99
+            } catch (NotFound $e) {
100
+                return [];
101
+            }
102
+        }
103
+        if ($shareEnumerationGroup) {
104
+            if ($this->groupManager === null) {
105
+                // Group manager is not available, so we can't determine which data is safe
106
+                return [];
107
+            }
108
+            $groups = $this->groupManager->getUserGroups($user);
109
+            $names = [];
110
+            foreach ($groups as $group) {
111
+                $users = $group->getUsers();
112
+                foreach ($users as $groupUser) {
113
+                    if ($groupUser->getBackendClassName() === 'Guests') {
114
+                        continue;
115
+                    }
116
+                    $names[] = SyncService::getCardUri($groupUser);
117
+                }
118
+            }
119
+            return parent::getMultipleChildren(array_unique($names));
120
+        }
121 121
 
122
-		$children = parent::getChildren();
123
-		return array_filter($children, function (Card $child) {
124
-			// check only for URIs that begin with Guests:
125
-			return strpos($child->getName(), 'Guests:') !== 0;
126
-		});
127
-	}
122
+        $children = parent::getChildren();
123
+        return array_filter($children, function (Card $child) {
124
+            // check only for URIs that begin with Guests:
125
+            return strpos($child->getName(), 'Guests:') !== 0;
126
+        });
127
+    }
128 128
 
129
-	/**
130
-	 * @param array $paths
131
-	 * @return Card[]
132
-	 * @throws NotFound
133
-	 */
134
-	public function getMultipleChildren($paths): array {
135
-		if (!$this->isFederation()) {
136
-			return parent::getMultipleChildren($paths);
137
-		}
129
+    /**
130
+     * @param array $paths
131
+     * @return Card[]
132
+     * @throws NotFound
133
+     */
134
+    public function getMultipleChildren($paths): array {
135
+        if (!$this->isFederation()) {
136
+            return parent::getMultipleChildren($paths);
137
+        }
138 138
 
139
-		$objs = $this->carddavBackend->getMultipleCards($this->addressBookInfo['id'], $paths);
140
-		$children = [];
141
-		/** @var array $obj */
142
-		foreach ($objs as $obj) {
143
-			if (empty($obj)) {
144
-				continue;
145
-			}
146
-			$carddata = $this->extractCarddata($obj);
147
-			if (empty($carddata)) {
148
-				continue;
149
-			} else {
150
-				$obj['carddata'] = $carddata;
151
-			}
152
-			$children[] = new Card($this->carddavBackend, $this->addressBookInfo, $obj);
153
-		}
154
-		return $children;
155
-	}
139
+        $objs = $this->carddavBackend->getMultipleCards($this->addressBookInfo['id'], $paths);
140
+        $children = [];
141
+        /** @var array $obj */
142
+        foreach ($objs as $obj) {
143
+            if (empty($obj)) {
144
+                continue;
145
+            }
146
+            $carddata = $this->extractCarddata($obj);
147
+            if (empty($carddata)) {
148
+                continue;
149
+            } else {
150
+                $obj['carddata'] = $carddata;
151
+            }
152
+            $children[] = new Card($this->carddavBackend, $this->addressBookInfo, $obj);
153
+        }
154
+        return $children;
155
+    }
156 156
 
157
-	/**
158
-	 * @param string $name
159
-	 * @return Card
160
-	 * @throws NotFound
161
-	 * @throws Forbidden
162
-	 */
163
-	public function getChild($name): Card {
164
-		if (!$this->isFederation()) {
165
-			return parent::getChild($name);
166
-		}
157
+    /**
158
+     * @param string $name
159
+     * @return Card
160
+     * @throws NotFound
161
+     * @throws Forbidden
162
+     */
163
+    public function getChild($name): Card {
164
+        if (!$this->isFederation()) {
165
+            return parent::getChild($name);
166
+        }
167 167
 
168
-		$obj = $this->carddavBackend->getCard($this->addressBookInfo['id'], $name);
169
-		if (!$obj) {
170
-			throw new NotFound('Card not found');
171
-		}
172
-		$carddata = $this->extractCarddata($obj);
173
-		if (empty($carddata)) {
174
-			throw new Forbidden();
175
-		} else {
176
-			$obj['carddata'] = $carddata;
177
-		}
178
-		return new Card($this->carddavBackend, $this->addressBookInfo, $obj);
179
-	}
168
+        $obj = $this->carddavBackend->getCard($this->addressBookInfo['id'], $name);
169
+        if (!$obj) {
170
+            throw new NotFound('Card not found');
171
+        }
172
+        $carddata = $this->extractCarddata($obj);
173
+        if (empty($carddata)) {
174
+            throw new Forbidden();
175
+        } else {
176
+            $obj['carddata'] = $carddata;
177
+        }
178
+        return new Card($this->carddavBackend, $this->addressBookInfo, $obj);
179
+    }
180 180
 
181
-	/**
182
-	 * @throws UnsupportedLimitOnInitialSyncException
183
-	 */
184
-	public function getChanges($syncToken, $syncLevel, $limit = null) {
185
-		if (!$syncToken && $limit) {
186
-			throw new UnsupportedLimitOnInitialSyncException();
187
-		}
181
+    /**
182
+     * @throws UnsupportedLimitOnInitialSyncException
183
+     */
184
+    public function getChanges($syncToken, $syncLevel, $limit = null) {
185
+        if (!$syncToken && $limit) {
186
+            throw new UnsupportedLimitOnInitialSyncException();
187
+        }
188 188
 
189
-		if (!$this->carddavBackend instanceof SyncSupport) {
190
-			return null;
191
-		}
189
+        if (!$this->carddavBackend instanceof SyncSupport) {
190
+            return null;
191
+        }
192 192
 
193
-		if (!$this->isFederation()) {
194
-			return parent::getChanges($syncToken, $syncLevel, $limit);
195
-		}
193
+        if (!$this->isFederation()) {
194
+            return parent::getChanges($syncToken, $syncLevel, $limit);
195
+        }
196 196
 
197
-		$changed = $this->carddavBackend->getChangesForAddressBook(
198
-			$this->addressBookInfo['id'],
199
-			$syncToken,
200
-			$syncLevel,
201
-			$limit
202
-		);
197
+        $changed = $this->carddavBackend->getChangesForAddressBook(
198
+            $this->addressBookInfo['id'],
199
+            $syncToken,
200
+            $syncLevel,
201
+            $limit
202
+        );
203 203
 
204
-		if (empty($changed)) {
205
-			return $changed;
206
-		}
204
+        if (empty($changed)) {
205
+            return $changed;
206
+        }
207 207
 
208
-		$added = $modified = $deleted = [];
209
-		foreach ($changed['added'] as $uri) {
210
-			try {
211
-				$this->getChild($uri);
212
-				$added[] = $uri;
213
-			} catch (NotFound | Forbidden $e) {
214
-				$deleted[] = $uri;
215
-			}
216
-		}
217
-		foreach ($changed['modified'] as $uri) {
218
-			try {
219
-				$this->getChild($uri);
220
-				$modified[] = $uri;
221
-			} catch (NotFound | Forbidden $e) {
222
-				$deleted[] = $uri;
223
-			}
224
-		}
225
-		$changed['added'] = $added;
226
-		$changed['modified'] = $modified;
227
-		$changed['deleted'] = $deleted;
228
-		return $changed;
229
-	}
208
+        $added = $modified = $deleted = [];
209
+        foreach ($changed['added'] as $uri) {
210
+            try {
211
+                $this->getChild($uri);
212
+                $added[] = $uri;
213
+            } catch (NotFound | Forbidden $e) {
214
+                $deleted[] = $uri;
215
+            }
216
+        }
217
+        foreach ($changed['modified'] as $uri) {
218
+            try {
219
+                $this->getChild($uri);
220
+                $modified[] = $uri;
221
+            } catch (NotFound | Forbidden $e) {
222
+                $deleted[] = $uri;
223
+            }
224
+        }
225
+        $changed['added'] = $added;
226
+        $changed['modified'] = $modified;
227
+        $changed['deleted'] = $deleted;
228
+        return $changed;
229
+    }
230 230
 
231
-	private function isFederation(): bool {
232
-		if ($this->trustedServers === null || $this->request === null) {
233
-			return false;
234
-		}
231
+    private function isFederation(): bool {
232
+        if ($this->trustedServers === null || $this->request === null) {
233
+            return false;
234
+        }
235 235
 
236
-		/** @psalm-suppress NoInterfaceProperties */
237
-		if ($this->request->server['PHP_AUTH_USER'] !== 'system') {
238
-			return false;
239
-		}
236
+        /** @psalm-suppress NoInterfaceProperties */
237
+        if ($this->request->server['PHP_AUTH_USER'] !== 'system') {
238
+            return false;
239
+        }
240 240
 
241
-		/** @psalm-suppress NoInterfaceProperties */
242
-		$sharedSecret = $this->request->server['PHP_AUTH_PW'];
243
-		if ($sharedSecret === null) {
244
-			return false;
245
-		}
241
+        /** @psalm-suppress NoInterfaceProperties */
242
+        $sharedSecret = $this->request->server['PHP_AUTH_PW'];
243
+        if ($sharedSecret === null) {
244
+            return false;
245
+        }
246 246
 
247
-		$servers = $this->trustedServers->getServers();
248
-		$trusted = array_filter($servers, function ($trustedServer) use ($sharedSecret) {
249
-			return $trustedServer['shared_secret'] === $sharedSecret;
250
-		});
251
-		// Authentication is fine, but it's not for a federated share
252
-		if (empty($trusted)) {
253
-			return false;
254
-		}
247
+        $servers = $this->trustedServers->getServers();
248
+        $trusted = array_filter($servers, function ($trustedServer) use ($sharedSecret) {
249
+            return $trustedServer['shared_secret'] === $sharedSecret;
250
+        });
251
+        // Authentication is fine, but it's not for a federated share
252
+        if (empty($trusted)) {
253
+            return false;
254
+        }
255 255
 
256
-		return true;
257
-	}
256
+        return true;
257
+    }
258 258
 
259
-	/**
260
-	 * If the validation doesn't work the card is "not found" so we
261
-	 * return empty carddata even if the carddata might exist in the local backend.
262
-	 * This can happen when a user sets the required properties
263
-	 * FN, N to a local scope only but the request is from
264
-	 * a federated share.
265
-	 *
266
-	 * @see https://github.com/nextcloud/server/issues/38042
267
-	 *
268
-	 * @param array $obj
269
-	 * @return string|null
270
-	 */
271
-	private function extractCarddata(array $obj): ?string {
272
-		$obj['acl'] = $this->getChildACL();
273
-		$cardData = $obj['carddata'];
274
-		/** @var VCard $vCard */
275
-		$vCard = Reader::read($cardData);
276
-		foreach ($vCard->children() as $child) {
277
-			$scope = $child->offsetGet('X-NC-SCOPE');
278
-			if ($scope !== null && $scope->getValue() === IAccountManager::SCOPE_LOCAL) {
279
-				$vCard->remove($child);
280
-			}
281
-		}
282
-		$messages = $vCard->validate();
283
-		if (!empty($messages)) {
284
-			return null;
285
-		}
259
+    /**
260
+     * If the validation doesn't work the card is "not found" so we
261
+     * return empty carddata even if the carddata might exist in the local backend.
262
+     * This can happen when a user sets the required properties
263
+     * FN, N to a local scope only but the request is from
264
+     * a federated share.
265
+     *
266
+     * @see https://github.com/nextcloud/server/issues/38042
267
+     *
268
+     * @param array $obj
269
+     * @return string|null
270
+     */
271
+    private function extractCarddata(array $obj): ?string {
272
+        $obj['acl'] = $this->getChildACL();
273
+        $cardData = $obj['carddata'];
274
+        /** @var VCard $vCard */
275
+        $vCard = Reader::read($cardData);
276
+        foreach ($vCard->children() as $child) {
277
+            $scope = $child->offsetGet('X-NC-SCOPE');
278
+            if ($scope !== null && $scope->getValue() === IAccountManager::SCOPE_LOCAL) {
279
+                $vCard->remove($child);
280
+            }
281
+        }
282
+        $messages = $vCard->validate();
283
+        if (!empty($messages)) {
284
+            return null;
285
+        }
286 286
 
287
-		return $vCard->serialize();
288
-	}
287
+        return $vCard->serialize();
288
+    }
289 289
 
290
-	/**
291
-	 * @return mixed
292
-	 * @throws Forbidden
293
-	 */
294
-	public function delete() {
295
-		if ($this->isFederation()) {
296
-			parent::delete();
297
-		}
298
-		throw new Forbidden();
299
-	}
290
+    /**
291
+     * @return mixed
292
+     * @throws Forbidden
293
+     */
294
+    public function delete() {
295
+        if ($this->isFederation()) {
296
+            parent::delete();
297
+        }
298
+        throw new Forbidden();
299
+    }
300 300
 
301
-	public function getACL() {
302
-		return array_filter(parent::getACL(), function($acl) {
303
-			if (in_array($acl['privilege'], ['{DAV:}write', '{DAV:}all'], true)) {
304
-				return false;
305
-			}
306
-			return true;
307
-		});
308
-	}
301
+    public function getACL() {
302
+        return array_filter(parent::getACL(), function($acl) {
303
+            if (in_array($acl['privilege'], ['{DAV:}write', '{DAV:}all'], true)) {
304
+                return false;
305
+            }
306
+            return true;
307
+        });
308
+    }
309 309
 }
Please login to merge, or discard this patch.