Completed
Push — master ( 21c128...38f7e0 )
by
unknown
41:49 queued 18:50
created
lib/private/Profile/ProfileManager.php 1 patch
Indentation   +387 added lines, -387 removed lines patch added patch discarded remove patch
@@ -38,391 +38,391 @@
 block discarded – undo
38 38
  * @psalm-import-type CoreProfileFields from ResponseDefinitions
39 39
  */
40 40
 class ProfileManager implements IProfileManager {
41
-	/** @var ILinkAction[] */
42
-	private array $actions = [];
43
-
44
-	/** @var null|ILinkAction[] */
45
-	private ?array $sortedActions = null;
46
-	/** @var CappedMemoryCache<ProfileConfig> */
47
-	private CappedMemoryCache $configCache;
48
-
49
-	private const CORE_APP_ID = 'core';
50
-
51
-	/**
52
-	 * Array of account property actions
53
-	 */
54
-	private const ACCOUNT_PROPERTY_ACTIONS = [
55
-		EmailAction::class,
56
-		PhoneAction::class,
57
-		WebsiteAction::class,
58
-		TwitterAction::class,
59
-		FediverseAction::class,
60
-	];
61
-
62
-	/**
63
-	 * Array of account properties displayed on the profile
64
-	 */
65
-	private const PROFILE_PROPERTIES = [
66
-		IAccountManager::PROPERTY_ADDRESS,
67
-		IAccountManager::PROPERTY_AVATAR,
68
-		IAccountManager::PROPERTY_BIOGRAPHY,
69
-		IAccountManager::PROPERTY_DISPLAYNAME,
70
-		IAccountManager::PROPERTY_HEADLINE,
71
-		IAccountManager::PROPERTY_ORGANISATION,
72
-		IAccountManager::PROPERTY_ROLE,
73
-		IAccountManager::PROPERTY_PRONOUNS,
74
-	];
75
-
76
-	public function __construct(
77
-		private IAccountManager $accountManager,
78
-		private IAppManager $appManager,
79
-		private IConfig $config,
80
-		private ProfileConfigMapper $configMapper,
81
-		private ContainerInterface $container,
82
-		private KnownUserService $knownUserService,
83
-		private IFactory $l10nFactory,
84
-		private LoggerInterface $logger,
85
-		private Coordinator $coordinator,
86
-	) {
87
-		$this->configCache = new CappedMemoryCache();
88
-	}
89
-
90
-	/**
91
-	 * If no user is passed as an argument return whether profile is enabled globally in `config.php`
92
-	 */
93
-	public function isProfileEnabled(?IUser $user = null): bool {
94
-		$profileEnabledGlobally = $this->config->getSystemValueBool('profile.enabled', true);
95
-
96
-		if (empty($user) || !$profileEnabledGlobally) {
97
-			return $profileEnabledGlobally;
98
-		}
99
-
100
-		$account = $this->accountManager->getAccount($user);
101
-		return (bool)filter_var(
102
-			$account->getProperty(IAccountManager::PROPERTY_PROFILE_ENABLED)->getValue(),
103
-			FILTER_VALIDATE_BOOLEAN,
104
-			FILTER_NULL_ON_FAILURE,
105
-		);
106
-	}
107
-
108
-	/**
109
-	 * Register an action for the user
110
-	 */
111
-	private function registerAction(ILinkAction $action, IUser $targetUser, ?IUser $visitingUser): void {
112
-		$action->preload($targetUser);
113
-
114
-		if ($action->getTarget() === null) {
115
-			// Actions without a target are not registered
116
-			return;
117
-		}
118
-
119
-		if ($action->getAppId() !== self::CORE_APP_ID) {
120
-			if (!$this->appManager->isEnabledForUser($action->getAppId(), $targetUser)) {
121
-				$this->logger->notice('App: ' . $action->getAppId() . ' cannot register actions as it is not enabled for the target user: ' . $targetUser->getUID());
122
-				return;
123
-			}
124
-			if (!$this->appManager->isEnabledForUser($action->getAppId(), $visitingUser)) {
125
-				$this->logger->notice('App: ' . $action->getAppId() . ' cannot register actions as it is not enabled for the visiting user: ' . ($visitingUser ? $visitingUser->getUID() : '(user not connected)'));
126
-				return;
127
-			}
128
-		}
129
-
130
-		if (in_array($action->getId(), self::PROFILE_PROPERTIES, true)) {
131
-			$this->logger->error('Cannot register action with ID: ' . $action->getId() . ', as it is used by a core account property.');
132
-			return;
133
-		}
134
-
135
-		if (isset($this->actions[$action->getId()])) {
136
-			$this->logger->error('Cannot register duplicate action: ' . $action->getId());
137
-			return;
138
-		}
139
-
140
-		// Add action to associative array of actions
141
-		$this->actions[$action->getId()] = $action;
142
-	}
143
-
144
-	/**
145
-	 * Return an array of registered profile actions for the user
146
-	 *
147
-	 * @return ILinkAction[]
148
-	 */
149
-	private function getActions(IUser $targetUser, ?IUser $visitingUser): array {
150
-		// If actions are already registered and sorted, return them
151
-		if ($this->sortedActions !== null) {
152
-			return $this->sortedActions;
153
-		}
154
-
155
-		foreach (self::ACCOUNT_PROPERTY_ACTIONS as $actionClass) {
156
-			/** @var ILinkAction $action */
157
-			$action = $this->container->get($actionClass);
158
-			$this->registerAction($action, $targetUser, $visitingUser);
159
-		}
160
-
161
-		$context = $this->coordinator->getRegistrationContext();
162
-
163
-		if ($context !== null) {
164
-			foreach ($context->getProfileLinkActions() as $registration) {
165
-				/** @var ILinkAction $action */
166
-				$action = $this->container->get($registration->getService());
167
-				$this->registerAction($action, $targetUser, $visitingUser);
168
-			}
169
-		}
170
-
171
-		$actionsClone = $this->actions;
172
-		// Sort associative array into indexed array in ascending order of priority
173
-		usort($actionsClone, function (ILinkAction $a, ILinkAction $b) {
174
-			return $a->getPriority() === $b->getPriority() ? 0 : ($a->getPriority() < $b->getPriority() ? -1 : 1);
175
-		});
176
-
177
-		$this->sortedActions = $actionsClone;
178
-		return $this->sortedActions;
179
-	}
180
-
181
-	/**
182
-	 * Return whether the profile parameter of the target user
183
-	 * is visible to the visiting user
184
-	 */
185
-	public function isProfileFieldVisible(string $profileField, IUser $targetUser, ?IUser $visitingUser): bool {
186
-		try {
187
-			$account = $this->accountManager->getAccount($targetUser);
188
-			$scope = $account->getProperty($profileField)->getScope();
189
-		} catch (PropertyDoesNotExistException $e) {
190
-			// Allow the exception as not all profile parameters are account properties
191
-		}
192
-
193
-		$visibility = $this->getProfileConfig($targetUser, $visitingUser)[$profileField]['visibility'];
194
-		// Handle profile visibility and account property scope
195
-
196
-		if ($visibility === self::VISIBILITY_SHOW_USERS_ONLY) {
197
-			if (empty($scope)) {
198
-				return $visitingUser !== null;
199
-			}
200
-
201
-			return match ($scope) {
202
-				IAccountManager::SCOPE_PRIVATE => $visitingUser !== null && $this->knownUserService->isKnownToUser($targetUser->getUID(), $visitingUser->getUID()),
203
-				IAccountManager::SCOPE_LOCAL,
204
-				IAccountManager::SCOPE_FEDERATED,
205
-				IAccountManager::SCOPE_PUBLISHED => $visitingUser !== null,
206
-				default => false,
207
-			};
208
-		}
209
-
210
-		if ($visibility === self::VISIBILITY_SHOW) {
211
-			if (empty($scope)) {
212
-				return true;
213
-			}
214
-
215
-			return match ($scope) {
216
-				IAccountManager::SCOPE_PRIVATE => $visitingUser !== null && $this->knownUserService->isKnownToUser($targetUser->getUID(), $visitingUser->getUID()),
217
-				IAccountManager::SCOPE_LOCAL,
218
-				IAccountManager::SCOPE_FEDERATED,
219
-				IAccountManager::SCOPE_PUBLISHED => true,
220
-				default => false,
221
-			};
222
-		}
223
-
224
-		return false;
225
-	}
226
-
227
-	/**
228
-	 * Return the profile parameters of the target user that are visible to the visiting user
229
-	 * in an associative array
230
-	 * @psalm-return CoreProfileFields
231
-	 */
232
-	public function getProfileFields(IUser $targetUser, ?IUser $visitingUser): array {
233
-		$account = $this->accountManager->getAccount($targetUser);
234
-
235
-		// Initialize associative array of profile parameters
236
-		$profileParameters = [
237
-			'userId' => $account->getUser()->getUID(),
238
-		];
239
-
240
-		// Add account properties
241
-		foreach (self::PROFILE_PROPERTIES as $property) {
242
-			switch ($property) {
243
-				case IAccountManager::PROPERTY_ADDRESS:
244
-				case IAccountManager::PROPERTY_BIOGRAPHY:
245
-				case IAccountManager::PROPERTY_DISPLAYNAME:
246
-				case IAccountManager::PROPERTY_HEADLINE:
247
-				case IAccountManager::PROPERTY_ORGANISATION:
248
-				case IAccountManager::PROPERTY_ROLE:
249
-				case IAccountManager::PROPERTY_PRONOUNS:
250
-					$profileParameters[$property] =
251
-						$this->isProfileFieldVisible($property, $targetUser, $visitingUser)
252
-						// Explicitly set to null when value is empty string
253
-						? ($account->getProperty($property)->getValue() ?: null)
254
-						: null;
255
-					break;
256
-				case IAccountManager::PROPERTY_AVATAR:
257
-					// Add avatar visibility
258
-					$profileParameters['isUserAvatarVisible'] = $this->isProfileFieldVisible($property, $targetUser, $visitingUser);
259
-					break;
260
-			}
261
-		}
262
-
263
-		// Add actions
264
-		$profileParameters['actions'] = array_map(
265
-			function (ILinkAction $action) {
266
-				return [
267
-					'id' => $action->getId(),
268
-					'icon' => $action->getIcon(),
269
-					'title' => $action->getTitle(),
270
-					'target' => $action->getTarget(),
271
-				];
272
-			},
273
-			// This is needed to reindex the array after filtering
274
-			array_values(
275
-				array_filter(
276
-					$this->getActions($targetUser, $visitingUser),
277
-					function (ILinkAction $action) use ($targetUser, $visitingUser) {
278
-						return $this->isProfileFieldVisible($action->getId(), $targetUser, $visitingUser);
279
-					}
280
-				),
281
-			)
282
-		);
283
-
284
-		return $profileParameters;
285
-	}
286
-
287
-	/**
288
-	 * Return the filtered profile config containing only
289
-	 * the properties to be stored on the database
290
-	 */
291
-	private function filterNotStoredProfileConfig(array $profileConfig): array {
292
-		$dbParamConfigProperties = [
293
-			'visibility',
294
-		];
295
-
296
-		foreach ($profileConfig as $paramId => $paramConfig) {
297
-			$profileConfig[$paramId] = array_intersect_key($paramConfig, array_flip($dbParamConfigProperties));
298
-		}
299
-
300
-		return $profileConfig;
301
-	}
302
-
303
-	/**
304
-	 * Return the default profile config
305
-	 */
306
-	private function getDefaultProfileConfig(IUser $targetUser, ?IUser $visitingUser): array {
307
-		// Construct the default config for actions
308
-		$actionsConfig = [];
309
-		foreach ($this->getActions($targetUser, $visitingUser) as $action) {
310
-			$actionsConfig[$action->getId()] = ['visibility' => self::DEFAULT_VISIBILITY];
311
-		}
312
-
313
-		// Construct the default config for account properties
314
-		$propertiesConfig = [];
315
-		foreach (self::DEFAULT_PROPERTY_VISIBILITY as $property => $visibility) {
316
-			$propertiesConfig[$property] = ['visibility' => $visibility];
317
-		}
318
-
319
-		return array_merge($actionsConfig, $propertiesConfig);
320
-	}
321
-
322
-	/**
323
-	 * Return the profile config of the target user,
324
-	 * if a config does not already exist a default config is created and returned
325
-	 */
326
-	public function getProfileConfig(IUser $targetUser, ?IUser $visitingUser): array {
327
-		$defaultProfileConfig = $this->getDefaultProfileConfig($targetUser, $visitingUser);
328
-		try {
329
-			if (($config = $this->configCache[$targetUser->getUID()]) === null) {
330
-				$config = $this->configMapper->get($targetUser->getUID());
331
-				$this->configCache[$targetUser->getUID()] = $config;
332
-			}
333
-			// Merge defaults with the existing config in case the defaults are missing
334
-			$config->setConfigArray(array_merge(
335
-				$defaultProfileConfig,
336
-				$this->filterNotStoredProfileConfig($config->getConfigArray()),
337
-			));
338
-			$this->configMapper->update($config);
339
-			$configArray = $config->getConfigArray();
340
-		} catch (DoesNotExistException $e) {
341
-			// Create a new default config if it does not exist
342
-			$config = new ProfileConfig();
343
-			$config->setUserId($targetUser->getUID());
344
-			$config->setConfigArray($defaultProfileConfig);
345
-			$this->configMapper->insert($config);
346
-			$configArray = $config->getConfigArray();
347
-		}
348
-
349
-		return $configArray;
350
-	}
351
-
352
-	/**
353
-	 * Return the profile config of the target user with additional medatata,
354
-	 * if a config does not already exist a default config is created and returned
355
-	 */
356
-	public function getProfileConfigWithMetadata(IUser $targetUser, ?IUser $visitingUser): array {
357
-		$configArray = $this->getProfileConfig($targetUser, $visitingUser);
358
-
359
-		$actionsMetadata = [];
360
-		foreach ($this->getActions($targetUser, $visitingUser) as $action) {
361
-			$actionsMetadata[$action->getId()] = [
362
-				'appId' => $action->getAppId(),
363
-				'displayId' => $action->getDisplayId(),
364
-			];
365
-		}
366
-
367
-		// Add metadata for account property actions which are always configurable
368
-		foreach (self::ACCOUNT_PROPERTY_ACTIONS as $actionClass) {
369
-			/** @var ILinkAction $action */
370
-			$action = $this->container->get($actionClass);
371
-			if (!isset($actionsMetadata[$action->getId()])) {
372
-				$actionsMetadata[$action->getId()] = [
373
-					'appId' => $action->getAppId(),
374
-					'displayId' => $action->getDisplayId(),
375
-				];
376
-			}
377
-		}
378
-
379
-		$propertiesMetadata = [
380
-			IAccountManager::PROPERTY_ADDRESS => [
381
-				'appId' => self::CORE_APP_ID,
382
-				'displayId' => $this->l10nFactory->get('lib')->t('Address'),
383
-			],
384
-			IAccountManager::PROPERTY_AVATAR => [
385
-				'appId' => self::CORE_APP_ID,
386
-				'displayId' => $this->l10nFactory->get('lib')->t('Profile picture'),
387
-			],
388
-			IAccountManager::PROPERTY_BIOGRAPHY => [
389
-				'appId' => self::CORE_APP_ID,
390
-				'displayId' => $this->l10nFactory->get('lib')->t('About'),
391
-			],
392
-			IAccountManager::PROPERTY_DISPLAYNAME => [
393
-				'appId' => self::CORE_APP_ID,
394
-				'displayId' => $this->l10nFactory->get('lib')->t('Display name'),
395
-			],
396
-			IAccountManager::PROPERTY_HEADLINE => [
397
-				'appId' => self::CORE_APP_ID,
398
-				'displayId' => $this->l10nFactory->get('lib')->t('Headline'),
399
-			],
400
-			IAccountManager::PROPERTY_ORGANISATION => [
401
-				'appId' => self::CORE_APP_ID,
402
-				'displayId' => $this->l10nFactory->get('lib')->t('Organisation'),
403
-			],
404
-			IAccountManager::PROPERTY_ROLE => [
405
-				'appId' => self::CORE_APP_ID,
406
-				'displayId' => $this->l10nFactory->get('lib')->t('Role'),
407
-			],
408
-			IAccountManager::PROPERTY_PRONOUNS => [
409
-				'appId' => self::CORE_APP_ID,
410
-				'displayId' => $this->l10nFactory->get('lib')->t('Pronouns'),
411
-			],
412
-		];
413
-
414
-		$paramMetadata = array_merge($actionsMetadata, $propertiesMetadata);
415
-		$configArray = array_intersect_key($configArray, $paramMetadata);
416
-
417
-		foreach ($configArray as $paramId => $paramConfig) {
418
-			if (isset($paramMetadata[$paramId])) {
419
-				$configArray[$paramId] = array_merge(
420
-					$paramConfig,
421
-					$paramMetadata[$paramId],
422
-				);
423
-			}
424
-		}
425
-
426
-		return $configArray;
427
-	}
41
+    /** @var ILinkAction[] */
42
+    private array $actions = [];
43
+
44
+    /** @var null|ILinkAction[] */
45
+    private ?array $sortedActions = null;
46
+    /** @var CappedMemoryCache<ProfileConfig> */
47
+    private CappedMemoryCache $configCache;
48
+
49
+    private const CORE_APP_ID = 'core';
50
+
51
+    /**
52
+     * Array of account property actions
53
+     */
54
+    private const ACCOUNT_PROPERTY_ACTIONS = [
55
+        EmailAction::class,
56
+        PhoneAction::class,
57
+        WebsiteAction::class,
58
+        TwitterAction::class,
59
+        FediverseAction::class,
60
+    ];
61
+
62
+    /**
63
+     * Array of account properties displayed on the profile
64
+     */
65
+    private const PROFILE_PROPERTIES = [
66
+        IAccountManager::PROPERTY_ADDRESS,
67
+        IAccountManager::PROPERTY_AVATAR,
68
+        IAccountManager::PROPERTY_BIOGRAPHY,
69
+        IAccountManager::PROPERTY_DISPLAYNAME,
70
+        IAccountManager::PROPERTY_HEADLINE,
71
+        IAccountManager::PROPERTY_ORGANISATION,
72
+        IAccountManager::PROPERTY_ROLE,
73
+        IAccountManager::PROPERTY_PRONOUNS,
74
+    ];
75
+
76
+    public function __construct(
77
+        private IAccountManager $accountManager,
78
+        private IAppManager $appManager,
79
+        private IConfig $config,
80
+        private ProfileConfigMapper $configMapper,
81
+        private ContainerInterface $container,
82
+        private KnownUserService $knownUserService,
83
+        private IFactory $l10nFactory,
84
+        private LoggerInterface $logger,
85
+        private Coordinator $coordinator,
86
+    ) {
87
+        $this->configCache = new CappedMemoryCache();
88
+    }
89
+
90
+    /**
91
+     * If no user is passed as an argument return whether profile is enabled globally in `config.php`
92
+     */
93
+    public function isProfileEnabled(?IUser $user = null): bool {
94
+        $profileEnabledGlobally = $this->config->getSystemValueBool('profile.enabled', true);
95
+
96
+        if (empty($user) || !$profileEnabledGlobally) {
97
+            return $profileEnabledGlobally;
98
+        }
99
+
100
+        $account = $this->accountManager->getAccount($user);
101
+        return (bool)filter_var(
102
+            $account->getProperty(IAccountManager::PROPERTY_PROFILE_ENABLED)->getValue(),
103
+            FILTER_VALIDATE_BOOLEAN,
104
+            FILTER_NULL_ON_FAILURE,
105
+        );
106
+    }
107
+
108
+    /**
109
+     * Register an action for the user
110
+     */
111
+    private function registerAction(ILinkAction $action, IUser $targetUser, ?IUser $visitingUser): void {
112
+        $action->preload($targetUser);
113
+
114
+        if ($action->getTarget() === null) {
115
+            // Actions without a target are not registered
116
+            return;
117
+        }
118
+
119
+        if ($action->getAppId() !== self::CORE_APP_ID) {
120
+            if (!$this->appManager->isEnabledForUser($action->getAppId(), $targetUser)) {
121
+                $this->logger->notice('App: ' . $action->getAppId() . ' cannot register actions as it is not enabled for the target user: ' . $targetUser->getUID());
122
+                return;
123
+            }
124
+            if (!$this->appManager->isEnabledForUser($action->getAppId(), $visitingUser)) {
125
+                $this->logger->notice('App: ' . $action->getAppId() . ' cannot register actions as it is not enabled for the visiting user: ' . ($visitingUser ? $visitingUser->getUID() : '(user not connected)'));
126
+                return;
127
+            }
128
+        }
129
+
130
+        if (in_array($action->getId(), self::PROFILE_PROPERTIES, true)) {
131
+            $this->logger->error('Cannot register action with ID: ' . $action->getId() . ', as it is used by a core account property.');
132
+            return;
133
+        }
134
+
135
+        if (isset($this->actions[$action->getId()])) {
136
+            $this->logger->error('Cannot register duplicate action: ' . $action->getId());
137
+            return;
138
+        }
139
+
140
+        // Add action to associative array of actions
141
+        $this->actions[$action->getId()] = $action;
142
+    }
143
+
144
+    /**
145
+     * Return an array of registered profile actions for the user
146
+     *
147
+     * @return ILinkAction[]
148
+     */
149
+    private function getActions(IUser $targetUser, ?IUser $visitingUser): array {
150
+        // If actions are already registered and sorted, return them
151
+        if ($this->sortedActions !== null) {
152
+            return $this->sortedActions;
153
+        }
154
+
155
+        foreach (self::ACCOUNT_PROPERTY_ACTIONS as $actionClass) {
156
+            /** @var ILinkAction $action */
157
+            $action = $this->container->get($actionClass);
158
+            $this->registerAction($action, $targetUser, $visitingUser);
159
+        }
160
+
161
+        $context = $this->coordinator->getRegistrationContext();
162
+
163
+        if ($context !== null) {
164
+            foreach ($context->getProfileLinkActions() as $registration) {
165
+                /** @var ILinkAction $action */
166
+                $action = $this->container->get($registration->getService());
167
+                $this->registerAction($action, $targetUser, $visitingUser);
168
+            }
169
+        }
170
+
171
+        $actionsClone = $this->actions;
172
+        // Sort associative array into indexed array in ascending order of priority
173
+        usort($actionsClone, function (ILinkAction $a, ILinkAction $b) {
174
+            return $a->getPriority() === $b->getPriority() ? 0 : ($a->getPriority() < $b->getPriority() ? -1 : 1);
175
+        });
176
+
177
+        $this->sortedActions = $actionsClone;
178
+        return $this->sortedActions;
179
+    }
180
+
181
+    /**
182
+     * Return whether the profile parameter of the target user
183
+     * is visible to the visiting user
184
+     */
185
+    public function isProfileFieldVisible(string $profileField, IUser $targetUser, ?IUser $visitingUser): bool {
186
+        try {
187
+            $account = $this->accountManager->getAccount($targetUser);
188
+            $scope = $account->getProperty($profileField)->getScope();
189
+        } catch (PropertyDoesNotExistException $e) {
190
+            // Allow the exception as not all profile parameters are account properties
191
+        }
192
+
193
+        $visibility = $this->getProfileConfig($targetUser, $visitingUser)[$profileField]['visibility'];
194
+        // Handle profile visibility and account property scope
195
+
196
+        if ($visibility === self::VISIBILITY_SHOW_USERS_ONLY) {
197
+            if (empty($scope)) {
198
+                return $visitingUser !== null;
199
+            }
200
+
201
+            return match ($scope) {
202
+                IAccountManager::SCOPE_PRIVATE => $visitingUser !== null && $this->knownUserService->isKnownToUser($targetUser->getUID(), $visitingUser->getUID()),
203
+                IAccountManager::SCOPE_LOCAL,
204
+                IAccountManager::SCOPE_FEDERATED,
205
+                IAccountManager::SCOPE_PUBLISHED => $visitingUser !== null,
206
+                default => false,
207
+            };
208
+        }
209
+
210
+        if ($visibility === self::VISIBILITY_SHOW) {
211
+            if (empty($scope)) {
212
+                return true;
213
+            }
214
+
215
+            return match ($scope) {
216
+                IAccountManager::SCOPE_PRIVATE => $visitingUser !== null && $this->knownUserService->isKnownToUser($targetUser->getUID(), $visitingUser->getUID()),
217
+                IAccountManager::SCOPE_LOCAL,
218
+                IAccountManager::SCOPE_FEDERATED,
219
+                IAccountManager::SCOPE_PUBLISHED => true,
220
+                default => false,
221
+            };
222
+        }
223
+
224
+        return false;
225
+    }
226
+
227
+    /**
228
+     * Return the profile parameters of the target user that are visible to the visiting user
229
+     * in an associative array
230
+     * @psalm-return CoreProfileFields
231
+     */
232
+    public function getProfileFields(IUser $targetUser, ?IUser $visitingUser): array {
233
+        $account = $this->accountManager->getAccount($targetUser);
234
+
235
+        // Initialize associative array of profile parameters
236
+        $profileParameters = [
237
+            'userId' => $account->getUser()->getUID(),
238
+        ];
239
+
240
+        // Add account properties
241
+        foreach (self::PROFILE_PROPERTIES as $property) {
242
+            switch ($property) {
243
+                case IAccountManager::PROPERTY_ADDRESS:
244
+                case IAccountManager::PROPERTY_BIOGRAPHY:
245
+                case IAccountManager::PROPERTY_DISPLAYNAME:
246
+                case IAccountManager::PROPERTY_HEADLINE:
247
+                case IAccountManager::PROPERTY_ORGANISATION:
248
+                case IAccountManager::PROPERTY_ROLE:
249
+                case IAccountManager::PROPERTY_PRONOUNS:
250
+                    $profileParameters[$property] =
251
+                        $this->isProfileFieldVisible($property, $targetUser, $visitingUser)
252
+                        // Explicitly set to null when value is empty string
253
+                        ? ($account->getProperty($property)->getValue() ?: null)
254
+                        : null;
255
+                    break;
256
+                case IAccountManager::PROPERTY_AVATAR:
257
+                    // Add avatar visibility
258
+                    $profileParameters['isUserAvatarVisible'] = $this->isProfileFieldVisible($property, $targetUser, $visitingUser);
259
+                    break;
260
+            }
261
+        }
262
+
263
+        // Add actions
264
+        $profileParameters['actions'] = array_map(
265
+            function (ILinkAction $action) {
266
+                return [
267
+                    'id' => $action->getId(),
268
+                    'icon' => $action->getIcon(),
269
+                    'title' => $action->getTitle(),
270
+                    'target' => $action->getTarget(),
271
+                ];
272
+            },
273
+            // This is needed to reindex the array after filtering
274
+            array_values(
275
+                array_filter(
276
+                    $this->getActions($targetUser, $visitingUser),
277
+                    function (ILinkAction $action) use ($targetUser, $visitingUser) {
278
+                        return $this->isProfileFieldVisible($action->getId(), $targetUser, $visitingUser);
279
+                    }
280
+                ),
281
+            )
282
+        );
283
+
284
+        return $profileParameters;
285
+    }
286
+
287
+    /**
288
+     * Return the filtered profile config containing only
289
+     * the properties to be stored on the database
290
+     */
291
+    private function filterNotStoredProfileConfig(array $profileConfig): array {
292
+        $dbParamConfigProperties = [
293
+            'visibility',
294
+        ];
295
+
296
+        foreach ($profileConfig as $paramId => $paramConfig) {
297
+            $profileConfig[$paramId] = array_intersect_key($paramConfig, array_flip($dbParamConfigProperties));
298
+        }
299
+
300
+        return $profileConfig;
301
+    }
302
+
303
+    /**
304
+     * Return the default profile config
305
+     */
306
+    private function getDefaultProfileConfig(IUser $targetUser, ?IUser $visitingUser): array {
307
+        // Construct the default config for actions
308
+        $actionsConfig = [];
309
+        foreach ($this->getActions($targetUser, $visitingUser) as $action) {
310
+            $actionsConfig[$action->getId()] = ['visibility' => self::DEFAULT_VISIBILITY];
311
+        }
312
+
313
+        // Construct the default config for account properties
314
+        $propertiesConfig = [];
315
+        foreach (self::DEFAULT_PROPERTY_VISIBILITY as $property => $visibility) {
316
+            $propertiesConfig[$property] = ['visibility' => $visibility];
317
+        }
318
+
319
+        return array_merge($actionsConfig, $propertiesConfig);
320
+    }
321
+
322
+    /**
323
+     * Return the profile config of the target user,
324
+     * if a config does not already exist a default config is created and returned
325
+     */
326
+    public function getProfileConfig(IUser $targetUser, ?IUser $visitingUser): array {
327
+        $defaultProfileConfig = $this->getDefaultProfileConfig($targetUser, $visitingUser);
328
+        try {
329
+            if (($config = $this->configCache[$targetUser->getUID()]) === null) {
330
+                $config = $this->configMapper->get($targetUser->getUID());
331
+                $this->configCache[$targetUser->getUID()] = $config;
332
+            }
333
+            // Merge defaults with the existing config in case the defaults are missing
334
+            $config->setConfigArray(array_merge(
335
+                $defaultProfileConfig,
336
+                $this->filterNotStoredProfileConfig($config->getConfigArray()),
337
+            ));
338
+            $this->configMapper->update($config);
339
+            $configArray = $config->getConfigArray();
340
+        } catch (DoesNotExistException $e) {
341
+            // Create a new default config if it does not exist
342
+            $config = new ProfileConfig();
343
+            $config->setUserId($targetUser->getUID());
344
+            $config->setConfigArray($defaultProfileConfig);
345
+            $this->configMapper->insert($config);
346
+            $configArray = $config->getConfigArray();
347
+        }
348
+
349
+        return $configArray;
350
+    }
351
+
352
+    /**
353
+     * Return the profile config of the target user with additional medatata,
354
+     * if a config does not already exist a default config is created and returned
355
+     */
356
+    public function getProfileConfigWithMetadata(IUser $targetUser, ?IUser $visitingUser): array {
357
+        $configArray = $this->getProfileConfig($targetUser, $visitingUser);
358
+
359
+        $actionsMetadata = [];
360
+        foreach ($this->getActions($targetUser, $visitingUser) as $action) {
361
+            $actionsMetadata[$action->getId()] = [
362
+                'appId' => $action->getAppId(),
363
+                'displayId' => $action->getDisplayId(),
364
+            ];
365
+        }
366
+
367
+        // Add metadata for account property actions which are always configurable
368
+        foreach (self::ACCOUNT_PROPERTY_ACTIONS as $actionClass) {
369
+            /** @var ILinkAction $action */
370
+            $action = $this->container->get($actionClass);
371
+            if (!isset($actionsMetadata[$action->getId()])) {
372
+                $actionsMetadata[$action->getId()] = [
373
+                    'appId' => $action->getAppId(),
374
+                    'displayId' => $action->getDisplayId(),
375
+                ];
376
+            }
377
+        }
378
+
379
+        $propertiesMetadata = [
380
+            IAccountManager::PROPERTY_ADDRESS => [
381
+                'appId' => self::CORE_APP_ID,
382
+                'displayId' => $this->l10nFactory->get('lib')->t('Address'),
383
+            ],
384
+            IAccountManager::PROPERTY_AVATAR => [
385
+                'appId' => self::CORE_APP_ID,
386
+                'displayId' => $this->l10nFactory->get('lib')->t('Profile picture'),
387
+            ],
388
+            IAccountManager::PROPERTY_BIOGRAPHY => [
389
+                'appId' => self::CORE_APP_ID,
390
+                'displayId' => $this->l10nFactory->get('lib')->t('About'),
391
+            ],
392
+            IAccountManager::PROPERTY_DISPLAYNAME => [
393
+                'appId' => self::CORE_APP_ID,
394
+                'displayId' => $this->l10nFactory->get('lib')->t('Display name'),
395
+            ],
396
+            IAccountManager::PROPERTY_HEADLINE => [
397
+                'appId' => self::CORE_APP_ID,
398
+                'displayId' => $this->l10nFactory->get('lib')->t('Headline'),
399
+            ],
400
+            IAccountManager::PROPERTY_ORGANISATION => [
401
+                'appId' => self::CORE_APP_ID,
402
+                'displayId' => $this->l10nFactory->get('lib')->t('Organisation'),
403
+            ],
404
+            IAccountManager::PROPERTY_ROLE => [
405
+                'appId' => self::CORE_APP_ID,
406
+                'displayId' => $this->l10nFactory->get('lib')->t('Role'),
407
+            ],
408
+            IAccountManager::PROPERTY_PRONOUNS => [
409
+                'appId' => self::CORE_APP_ID,
410
+                'displayId' => $this->l10nFactory->get('lib')->t('Pronouns'),
411
+            ],
412
+        ];
413
+
414
+        $paramMetadata = array_merge($actionsMetadata, $propertiesMetadata);
415
+        $configArray = array_intersect_key($configArray, $paramMetadata);
416
+
417
+        foreach ($configArray as $paramId => $paramConfig) {
418
+            if (isset($paramMetadata[$paramId])) {
419
+                $configArray[$paramId] = array_merge(
420
+                    $paramConfig,
421
+                    $paramMetadata[$paramId],
422
+                );
423
+            }
424
+        }
425
+
426
+        return $configArray;
427
+    }
428 428
 }
Please login to merge, or discard this patch.
lib/public/Profile/IProfileManager.php 1 patch
Indentation   +64 added lines, -64 removed lines patch added patch discarded remove patch
@@ -18,75 +18,75 @@
 block discarded – undo
18 18
  * @since 28.0.0
19 19
  */
20 20
 interface IProfileManager {
21
-	/**
22
-	 * Visible to users, guests, and public access
23
-	 *
24
-	 * @since 28.0.0
25
-	 */
26
-	public const VISIBILITY_SHOW = 'show';
21
+    /**
22
+     * Visible to users, guests, and public access
23
+     *
24
+     * @since 28.0.0
25
+     */
26
+    public const VISIBILITY_SHOW = 'show';
27 27
 
28
-	/**
29
-	 * Visible to users and guests
30
-	 *
31
-	 * @since 28.0.0
32
-	 */
33
-	public const VISIBILITY_SHOW_USERS_ONLY = 'show_users_only';
28
+    /**
29
+     * Visible to users and guests
30
+     *
31
+     * @since 28.0.0
32
+     */
33
+    public const VISIBILITY_SHOW_USERS_ONLY = 'show_users_only';
34 34
 
35
-	/**
36
-	 * Visible to nobody
37
-	 *
38
-	 * @since 28.0.0
39
-	 */
40
-	public const VISIBILITY_HIDE = 'hide';
35
+    /**
36
+     * Visible to nobody
37
+     *
38
+     * @since 28.0.0
39
+     */
40
+    public const VISIBILITY_HIDE = 'hide';
41 41
 
42
-	/**
43
-	 * Default account property visibility
44
-	 *
45
-	 * @since 28.0.0
46
-	 */
47
-	public const DEFAULT_PROPERTY_VISIBILITY = [
48
-		IAccountManager::PROPERTY_ADDRESS => self::VISIBILITY_SHOW_USERS_ONLY,
49
-		IAccountManager::PROPERTY_AVATAR => self::VISIBILITY_SHOW,
50
-		IAccountManager::PROPERTY_BIOGRAPHY => self::VISIBILITY_SHOW,
51
-		IAccountManager::PROPERTY_DISPLAYNAME => self::VISIBILITY_SHOW,
52
-		IAccountManager::PROPERTY_HEADLINE => self::VISIBILITY_SHOW,
53
-		IAccountManager::PROPERTY_ORGANISATION => self::VISIBILITY_SHOW,
54
-		IAccountManager::PROPERTY_ROLE => self::VISIBILITY_SHOW,
55
-		IAccountManager::PROPERTY_EMAIL => self::VISIBILITY_SHOW_USERS_ONLY,
56
-		IAccountManager::PROPERTY_PHONE => self::VISIBILITY_SHOW_USERS_ONLY,
57
-		IAccountManager::PROPERTY_TWITTER => self::VISIBILITY_SHOW,
58
-		IAccountManager::PROPERTY_WEBSITE => self::VISIBILITY_SHOW,
59
-		IAccountManager::PROPERTY_PRONOUNS => self::VISIBILITY_SHOW,
60
-	];
42
+    /**
43
+     * Default account property visibility
44
+     *
45
+     * @since 28.0.0
46
+     */
47
+    public const DEFAULT_PROPERTY_VISIBILITY = [
48
+        IAccountManager::PROPERTY_ADDRESS => self::VISIBILITY_SHOW_USERS_ONLY,
49
+        IAccountManager::PROPERTY_AVATAR => self::VISIBILITY_SHOW,
50
+        IAccountManager::PROPERTY_BIOGRAPHY => self::VISIBILITY_SHOW,
51
+        IAccountManager::PROPERTY_DISPLAYNAME => self::VISIBILITY_SHOW,
52
+        IAccountManager::PROPERTY_HEADLINE => self::VISIBILITY_SHOW,
53
+        IAccountManager::PROPERTY_ORGANISATION => self::VISIBILITY_SHOW,
54
+        IAccountManager::PROPERTY_ROLE => self::VISIBILITY_SHOW,
55
+        IAccountManager::PROPERTY_EMAIL => self::VISIBILITY_SHOW_USERS_ONLY,
56
+        IAccountManager::PROPERTY_PHONE => self::VISIBILITY_SHOW_USERS_ONLY,
57
+        IAccountManager::PROPERTY_TWITTER => self::VISIBILITY_SHOW,
58
+        IAccountManager::PROPERTY_WEBSITE => self::VISIBILITY_SHOW,
59
+        IAccountManager::PROPERTY_PRONOUNS => self::VISIBILITY_SHOW,
60
+    ];
61 61
 
62
-	/**
63
-	 * Default visibility
64
-	 *
65
-	 * @since 28.0.0
66
-	 */
67
-	public const DEFAULT_VISIBILITY = self::VISIBILITY_SHOW_USERS_ONLY;
62
+    /**
63
+     * Default visibility
64
+     *
65
+     * @since 28.0.0
66
+     */
67
+    public const DEFAULT_VISIBILITY = self::VISIBILITY_SHOW_USERS_ONLY;
68 68
 
69
-	/**
70
-	 * If no user is passed as an argument return whether profile is enabled globally in `config.php`
71
-	 *
72
-	 * @since 28.0.0
73
-	 */
74
-	public function isProfileEnabled(?IUser $user = null): bool;
69
+    /**
70
+     * If no user is passed as an argument return whether profile is enabled globally in `config.php`
71
+     *
72
+     * @since 28.0.0
73
+     */
74
+    public function isProfileEnabled(?IUser $user = null): bool;
75 75
 
76
-	/**
77
-	 * Return whether the profile parameter of the target user
78
-	 * is visible to the visiting user
79
-	 *
80
-	 * @since 28.0.0
81
-	 */
82
-	public function isProfileFieldVisible(string $profileField, IUser $targetUser, ?IUser $visitingUser): bool;
76
+    /**
77
+     * Return whether the profile parameter of the target user
78
+     * is visible to the visiting user
79
+     *
80
+     * @since 28.0.0
81
+     */
82
+    public function isProfileFieldVisible(string $profileField, IUser $targetUser, ?IUser $visitingUser): bool;
83 83
 
84
-	/**
85
-	 * Return the profile parameters of the target user that are visible to the visiting user
86
-	 * in an associative array
87
-	 *
88
-	 * @psalm-return CoreProfileFields
89
-	 * @since 28.0.0
90
-	 */
91
-	public function getProfileFields(IUser $targetUser, ?IUser $visitingUser): array;
84
+    /**
85
+     * Return the profile parameters of the target user that are visible to the visiting user
86
+     * in an associative array
87
+     *
88
+     * @psalm-return CoreProfileFields
89
+     * @since 28.0.0
90
+     */
91
+    public function getProfileFields(IUser $targetUser, ?IUser $visitingUser): array;
92 92
 }
Please login to merge, or discard this patch.
build/integration/features/bootstrap/Provisioning.php 2 patches
Indentation   +1000 added lines, -1000 removed lines patch added patch discarded remove patch
@@ -13,1004 +13,1004 @@
 block discarded – undo
13 13
 require __DIR__ . '/../../vendor/autoload.php';
14 14
 
15 15
 trait Provisioning {
16
-	use BasicStructure;
17
-
18
-	/** @var array */
19
-	private $createdUsers = [];
20
-
21
-	/** @var array */
22
-	private $createdRemoteUsers = [];
23
-
24
-	/** @var array */
25
-	private $createdRemoteGroups = [];
26
-
27
-	/** @var array */
28
-	private $createdGroups = [];
29
-
30
-	/**
31
-	 * @Given /^user "([^"]*)" exists$/
32
-	 * @param string $user
33
-	 */
34
-	public function assureUserExists($user) {
35
-		try {
36
-			$this->userExists($user);
37
-		} catch (\GuzzleHttp\Exception\ClientException $ex) {
38
-			$previous_user = $this->currentUser;
39
-			$this->currentUser = 'admin';
40
-			$this->creatingTheUser($user);
41
-			$this->currentUser = $previous_user;
42
-		}
43
-		$this->userExists($user);
44
-		Assert::assertEquals(200, $this->response->getStatusCode());
45
-	}
46
-
47
-	/**
48
-	 * @Given /^user "([^"]*)" with displayname "((?:[^"]|\\")*)" exists$/
49
-	 * @param string $user
50
-	 */
51
-	public function assureUserWithDisplaynameExists($user, $displayname) {
52
-		try {
53
-			$this->userExists($user);
54
-		} catch (\GuzzleHttp\Exception\ClientException $ex) {
55
-			$previous_user = $this->currentUser;
56
-			$this->currentUser = 'admin';
57
-			$this->creatingTheUser($user, $displayname);
58
-			$this->currentUser = $previous_user;
59
-		}
60
-		$this->userExists($user);
61
-		Assert::assertEquals(200, $this->response->getStatusCode());
62
-	}
63
-
64
-	/**
65
-	 * @Given /^user "([^"]*)" does not exist$/
66
-	 * @param string $user
67
-	 */
68
-	public function userDoesNotExist($user) {
69
-		try {
70
-			$this->userExists($user);
71
-		} catch (\GuzzleHttp\Exception\ClientException $ex) {
72
-			$this->response = $ex->getResponse();
73
-			Assert::assertEquals(404, $ex->getResponse()->getStatusCode());
74
-			return;
75
-		}
76
-		$previous_user = $this->currentUser;
77
-		$this->currentUser = 'admin';
78
-		$this->deletingTheUser($user);
79
-		$this->currentUser = $previous_user;
80
-		try {
81
-			$this->userExists($user);
82
-		} catch (\GuzzleHttp\Exception\ClientException $ex) {
83
-			$this->response = $ex->getResponse();
84
-			Assert::assertEquals(404, $ex->getResponse()->getStatusCode());
85
-		}
86
-	}
87
-
88
-	public function creatingTheUser($user, $displayname = '') {
89
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users";
90
-		$client = new Client();
91
-		$options = [];
92
-		if ($this->currentUser === 'admin') {
93
-			$options['auth'] = $this->adminUser;
94
-		}
95
-
96
-		$options['form_params'] = [
97
-			'userid' => $user,
98
-			'password' => '123456'
99
-		];
100
-		if ($displayname !== '') {
101
-			$options['form_params']['displayName'] = $displayname;
102
-		}
103
-		$options['headers'] = [
104
-			'OCS-APIREQUEST' => 'true',
105
-		];
106
-
107
-		$this->response = $client->post($fullUrl, $options);
108
-		if ($this->currentServer === 'LOCAL') {
109
-			$this->createdUsers[$user] = $user;
110
-		} elseif ($this->currentServer === 'REMOTE') {
111
-			$this->createdRemoteUsers[$user] = $user;
112
-		}
113
-
114
-		//Quick hack to login once with the current user
115
-		$options2 = [
116
-			'auth' => [$user, '123456'],
117
-		];
118
-		$options2['headers'] = [
119
-			'OCS-APIREQUEST' => 'true',
120
-		];
121
-		$url = $fullUrl . '/' . $user;
122
-		$client->get($url, $options2);
123
-	}
124
-
125
-	/**
126
-	 * @Then /^user "([^"]*)" has$/
127
-	 *
128
-	 * @param string $user
129
-	 * @param TableNode|null $settings
130
-	 */
131
-	public function userHasSetting($user, $settings) {
132
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
133
-		$client = new Client();
134
-		$options = [];
135
-		if ($this->currentUser === 'admin') {
136
-			$options['auth'] = $this->adminUser;
137
-		} else {
138
-			$options['auth'] = [$this->currentUser, $this->regularUser];
139
-		}
140
-		$options['headers'] = [
141
-			'OCS-APIREQUEST' => 'true',
142
-		];
143
-
144
-		$response = $client->get($fullUrl, $options);
145
-		foreach ($settings->getRows() as $setting) {
146
-			$value = json_decode(json_encode(simplexml_load_string($response->getBody())->data->{$setting[0]}), 1);
147
-			if (isset($value['element']) && in_array($setting[0], ['additional_mail', 'additional_mailScope'], true)) {
148
-				$expectedValues = explode(';', $setting[1]);
149
-				foreach ($expectedValues as $expected) {
150
-					Assert::assertTrue(in_array($expected, $value['element'], true), 'Data wrong for field: ' . $setting[0]);
151
-				}
152
-			} elseif (isset($value[0])) {
153
-				Assert::assertEqualsCanonicalizing($setting[1], $value[0], 'Data wrong for field: ' . $setting[0]);
154
-			} else {
155
-				Assert::assertEquals('', $setting[1], 'Data wrong for field: ' . $setting[0]);
156
-			}
157
-		}
158
-	}
159
-
160
-	/**
161
-	 * @Then /^user "([^"]*)" has the following profile data$/
162
-	 */
163
-	public function userHasProfileData(string $user, ?TableNode $settings): void {
164
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/profile/$user";
165
-		$client = new Client();
166
-		$options = [];
167
-		if ($this->currentUser === 'admin') {
168
-			$options['auth'] = $this->adminUser;
169
-		} else {
170
-			$options['auth'] = [$this->currentUser, $this->regularUser];
171
-		}
172
-		$options['headers'] = [
173
-			'OCS-APIREQUEST' => 'true',
174
-			'Accept' => 'application/json',
175
-		];
176
-
177
-		$response = $client->get($fullUrl, $options);
178
-		$body = $response->getBody()->getContents();
179
-		$data = json_decode($body, true);
180
-		$data = $data['ocs']['data'];
181
-		foreach ($settings->getRows() as $setting) {
182
-			Assert::assertArrayHasKey($setting[0], $data, 'Profile data field missing: ' . $setting[0]);
183
-			if ($setting[1] === 'NULL') {
184
-				Assert::assertNull($data[$setting[0]], 'Profile data wrong for field: ' . $setting[0]);
185
-			} else {
186
-				Assert::assertEquals($setting[1], $data[$setting[0]], 'Profile data wrong for field: ' . $setting[0]);
187
-			}
188
-		}
189
-	}
190
-
191
-	/**
192
-	 * @Then /^group "([^"]*)" has$/
193
-	 *
194
-	 * @param string $user
195
-	 * @param TableNode|null $settings
196
-	 */
197
-	public function groupHasSetting($group, $settings) {
198
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/groups/details?search=$group";
199
-		$client = new Client();
200
-		$options = [];
201
-		if ($this->currentUser === 'admin') {
202
-			$options['auth'] = $this->adminUser;
203
-		} else {
204
-			$options['auth'] = [$this->currentUser, $this->regularUser];
205
-		}
206
-		$options['headers'] = [
207
-			'OCS-APIREQUEST' => 'true',
208
-		];
209
-
210
-		$response = $client->get($fullUrl, $options);
211
-		$groupDetails = simplexml_load_string($response->getBody())->data[0]->groups[0]->element;
212
-		foreach ($settings->getRows() as $setting) {
213
-			$value = json_decode(json_encode($groupDetails->{$setting[0]}), 1);
214
-			if (isset($value[0])) {
215
-				Assert::assertEqualsCanonicalizing($setting[1], $value[0]);
216
-			} else {
217
-				Assert::assertEquals('', $setting[1]);
218
-			}
219
-		}
220
-	}
221
-
222
-
223
-	/**
224
-	 * @Then /^user "([^"]*)" has editable fields$/
225
-	 *
226
-	 * @param string $user
227
-	 * @param TableNode|null $fields
228
-	 */
229
-	public function userHasEditableFields($user, $fields) {
230
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/user/fields";
231
-		if ($user !== 'self') {
232
-			$fullUrl .= '/' . $user;
233
-		}
234
-		$client = new Client();
235
-		$options = [];
236
-		if ($this->currentUser === 'admin') {
237
-			$options['auth'] = $this->adminUser;
238
-		} else {
239
-			$options['auth'] = [$this->currentUser, $this->regularUser];
240
-		}
241
-		$options['headers'] = [
242
-			'OCS-APIREQUEST' => 'true',
243
-		];
244
-
245
-		$response = $client->get($fullUrl, $options);
246
-		$fieldsArray = json_decode(json_encode(simplexml_load_string($response->getBody())->data->element), 1);
247
-
248
-		$expectedFields = $fields->getRows();
249
-		$expectedFields = $this->simplifyArray($expectedFields);
250
-		Assert::assertEquals($expectedFields, $fieldsArray);
251
-	}
252
-
253
-	/**
254
-	 * @Then /^search users by phone for region "([^"]*)" with$/
255
-	 *
256
-	 * @param string $user
257
-	 * @param TableNode|null $settings
258
-	 */
259
-	public function searchUserByPhone($region, TableNode $searchTable) {
260
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/search/by-phone";
261
-		$client = new Client();
262
-		$options = [];
263
-		$options['auth'] = $this->adminUser;
264
-		$options['headers'] = [
265
-			'OCS-APIREQUEST' => 'true',
266
-		];
267
-
268
-		$search = [];
269
-		foreach ($searchTable->getRows() as $row) {
270
-			if (!isset($search[$row[0]])) {
271
-				$search[$row[0]] = [];
272
-			}
273
-			$search[$row[0]][] = $row[1];
274
-		}
275
-
276
-		$options['form_params'] = [
277
-			'location' => $region,
278
-			'search' => $search,
279
-		];
280
-
281
-		$this->response = $client->post($fullUrl, $options);
282
-	}
283
-
284
-	public function createUser($user) {
285
-		$previous_user = $this->currentUser;
286
-		$this->currentUser = 'admin';
287
-		$this->creatingTheUser($user);
288
-		$this->userExists($user);
289
-		$this->currentUser = $previous_user;
290
-	}
291
-
292
-	public function deleteUser($user) {
293
-		$previous_user = $this->currentUser;
294
-		$this->currentUser = 'admin';
295
-		$this->deletingTheUser($user);
296
-		$this->userDoesNotExist($user);
297
-		$this->currentUser = $previous_user;
298
-	}
299
-
300
-	public function createGroup($group) {
301
-		$previous_user = $this->currentUser;
302
-		$this->currentUser = 'admin';
303
-		$this->creatingTheGroup($group);
304
-		$this->groupExists($group);
305
-		$this->currentUser = $previous_user;
306
-	}
307
-
308
-	public function deleteGroup($group) {
309
-		$previous_user = $this->currentUser;
310
-		$this->currentUser = 'admin';
311
-		$this->deletingTheGroup($group);
312
-		$this->groupDoesNotExist($group);
313
-		$this->currentUser = $previous_user;
314
-	}
315
-
316
-	public function userExists($user) {
317
-		$fullUrl = $this->baseUrl . "v2.php/cloud/users/$user";
318
-		$client = new Client();
319
-		$options = [];
320
-		$options['auth'] = $this->adminUser;
321
-		$options['headers'] = [
322
-			'OCS-APIREQUEST' => 'true'
323
-		];
324
-
325
-		$this->response = $client->get($fullUrl, $options);
326
-	}
327
-
328
-	/**
329
-	 * @Then /^check that user "([^"]*)" belongs to group "([^"]*)"$/
330
-	 * @param string $user
331
-	 * @param string $group
332
-	 */
333
-	public function checkThatUserBelongsToGroup($user, $group) {
334
-		$fullUrl = $this->baseUrl . "v2.php/cloud/users/$user/groups";
335
-		$client = new Client();
336
-		$options = [];
337
-		if ($this->currentUser === 'admin') {
338
-			$options['auth'] = $this->adminUser;
339
-		}
340
-		$options['headers'] = [
341
-			'OCS-APIREQUEST' => 'true',
342
-		];
343
-
344
-		$this->response = $client->get($fullUrl, $options);
345
-		$respondedArray = $this->getArrayOfGroupsResponded($this->response);
346
-		sort($respondedArray);
347
-		Assert::assertContains($group, $respondedArray);
348
-		Assert::assertEquals(200, $this->response->getStatusCode());
349
-	}
350
-
351
-	public function userBelongsToGroup($user, $group) {
352
-		$fullUrl = $this->baseUrl . "v2.php/cloud/users/$user/groups";
353
-		$client = new Client();
354
-		$options = [];
355
-		if ($this->currentUser === 'admin') {
356
-			$options['auth'] = $this->adminUser;
357
-		}
358
-		$options['headers'] = [
359
-			'OCS-APIREQUEST' => 'true',
360
-		];
361
-
362
-		$this->response = $client->get($fullUrl, $options);
363
-		$respondedArray = $this->getArrayOfGroupsResponded($this->response);
364
-
365
-		if (array_key_exists($group, $respondedArray)) {
366
-			return true;
367
-		} else {
368
-			return false;
369
-		}
370
-	}
371
-
372
-	/**
373
-	 * @Given /^user "([^"]*)" belongs to group "([^"]*)"$/
374
-	 * @param string $user
375
-	 * @param string $group
376
-	 */
377
-	public function assureUserBelongsToGroup($user, $group) {
378
-		$previous_user = $this->currentUser;
379
-		$this->currentUser = 'admin';
380
-
381
-		if (!$this->userBelongsToGroup($user, $group)) {
382
-			$this->addingUserToGroup($user, $group);
383
-		}
384
-
385
-		$this->checkThatUserBelongsToGroup($user, $group);
386
-		$this->currentUser = $previous_user;
387
-	}
388
-
389
-	/**
390
-	 * @Given /^user "([^"]*)" does not belong to group "([^"]*)"$/
391
-	 * @param string $user
392
-	 * @param string $group
393
-	 */
394
-	public function userDoesNotBelongToGroup($user, $group) {
395
-		$fullUrl = $this->baseUrl . "v2.php/cloud/users/$user/groups";
396
-		$client = new Client();
397
-		$options = [];
398
-		if ($this->currentUser === 'admin') {
399
-			$options['auth'] = $this->adminUser;
400
-		}
401
-		$options['headers'] = [
402
-			'OCS-APIREQUEST' => 'true',
403
-		];
404
-
405
-		$this->response = $client->get($fullUrl, $options);
406
-		$groups = [$group];
407
-		$respondedArray = $this->getArrayOfGroupsResponded($this->response);
408
-		Assert::assertNotEqualsCanonicalizing($groups, $respondedArray);
409
-		Assert::assertEquals(200, $this->response->getStatusCode());
410
-	}
411
-
412
-	/**
413
-	 * @When /^creating the group "([^"]*)"$/
414
-	 * @param string $group
415
-	 */
416
-	public function creatingTheGroup($group) {
417
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/groups";
418
-		$client = new Client();
419
-		$options = [];
420
-		if ($this->currentUser === 'admin') {
421
-			$options['auth'] = $this->adminUser;
422
-		}
423
-
424
-		$options['form_params'] = [
425
-			'groupid' => $group,
426
-		];
427
-		$options['headers'] = [
428
-			'OCS-APIREQUEST' => 'true',
429
-		];
430
-
431
-		$this->response = $client->post($fullUrl, $options);
432
-		if ($this->currentServer === 'LOCAL') {
433
-			$this->createdGroups[$group] = $group;
434
-		} elseif ($this->currentServer === 'REMOTE') {
435
-			$this->createdRemoteGroups[$group] = $group;
436
-		}
437
-	}
438
-
439
-	/**
440
-	 * @When /^assure user "([^"]*)" is disabled$/
441
-	 */
442
-	public function assureUserIsDisabled($user) {
443
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user/disable";
444
-		$client = new Client();
445
-		$options = [];
446
-		if ($this->currentUser === 'admin') {
447
-			$options['auth'] = $this->adminUser;
448
-		}
449
-		$options['headers'] = [
450
-			'OCS-APIREQUEST' => 'true',
451
-		];
452
-		// TODO: fix hack
453
-		$options['form_params'] = [
454
-			'foo' => 'bar'
455
-		];
456
-
457
-		$this->response = $client->put($fullUrl, $options);
458
-	}
459
-
460
-	/**
461
-	 * @When /^Deleting the user "([^"]*)"$/
462
-	 * @param string $user
463
-	 */
464
-	public function deletingTheUser($user) {
465
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
466
-		$client = new Client();
467
-		$options = [];
468
-		if ($this->currentUser === 'admin') {
469
-			$options['auth'] = $this->adminUser;
470
-		}
471
-		$options['headers'] = [
472
-			'OCS-APIREQUEST' => 'true',
473
-		];
474
-
475
-		$this->response = $client->delete($fullUrl, $options);
476
-	}
477
-
478
-	/**
479
-	 * @When /^Deleting the group "([^"]*)"$/
480
-	 * @param string $group
481
-	 */
482
-	public function deletingTheGroup($group) {
483
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/groups/$group";
484
-		$client = new Client();
485
-		$options = [];
486
-		if ($this->currentUser === 'admin') {
487
-			$options['auth'] = $this->adminUser;
488
-		}
489
-		$options['headers'] = [
490
-			'OCS-APIREQUEST' => 'true',
491
-		];
492
-
493
-		$this->response = $client->delete($fullUrl, $options);
494
-
495
-		if ($this->currentServer === 'LOCAL') {
496
-			unset($this->createdGroups[$group]);
497
-		} elseif ($this->currentServer === 'REMOTE') {
498
-			unset($this->createdRemoteGroups[$group]);
499
-		}
500
-	}
501
-
502
-	/**
503
-	 * @Given /^Add user "([^"]*)" to the group "([^"]*)"$/
504
-	 * @param string $user
505
-	 * @param string $group
506
-	 */
507
-	public function addUserToGroup($user, $group) {
508
-		$this->userExists($user);
509
-		$this->groupExists($group);
510
-		$this->addingUserToGroup($user, $group);
511
-	}
512
-
513
-	/**
514
-	 * @When /^User "([^"]*)" is added to the group "([^"]*)"$/
515
-	 * @param string $user
516
-	 * @param string $group
517
-	 */
518
-	public function addingUserToGroup($user, $group) {
519
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user/groups";
520
-		$client = new Client();
521
-		$options = [];
522
-		if ($this->currentUser === 'admin') {
523
-			$options['auth'] = $this->adminUser;
524
-		}
525
-		$options['headers'] = [
526
-			'OCS-APIREQUEST' => 'true',
527
-		];
528
-
529
-		$options['form_params'] = [
530
-			'groupid' => $group,
531
-		];
532
-
533
-		$this->response = $client->post($fullUrl, $options);
534
-	}
535
-
536
-
537
-	public function groupExists($group) {
538
-		$fullUrl = $this->baseUrl . "v2.php/cloud/groups/$group";
539
-		$client = new Client();
540
-		$options = [];
541
-		$options['auth'] = $this->adminUser;
542
-		$options['headers'] = [
543
-			'OCS-APIREQUEST' => 'true',
544
-		];
545
-
546
-		$this->response = $client->get($fullUrl, $options);
547
-	}
548
-
549
-	/**
550
-	 * @Given /^group "([^"]*)" exists$/
551
-	 * @param string $group
552
-	 */
553
-	public function assureGroupExists($group) {
554
-		try {
555
-			$this->groupExists($group);
556
-		} catch (\GuzzleHttp\Exception\ClientException $ex) {
557
-			$previous_user = $this->currentUser;
558
-			$this->currentUser = 'admin';
559
-			$this->creatingTheGroup($group);
560
-			$this->currentUser = $previous_user;
561
-		}
562
-		$this->groupExists($group);
563
-		Assert::assertEquals(200, $this->response->getStatusCode());
564
-	}
565
-
566
-	/**
567
-	 * @Given /^group "([^"]*)" does not exist$/
568
-	 * @param string $group
569
-	 */
570
-	public function groupDoesNotExist($group) {
571
-		try {
572
-			$this->groupExists($group);
573
-		} catch (\GuzzleHttp\Exception\ClientException $ex) {
574
-			$this->response = $ex->getResponse();
575
-			Assert::assertEquals(404, $ex->getResponse()->getStatusCode());
576
-			return;
577
-		}
578
-		$previous_user = $this->currentUser;
579
-		$this->currentUser = 'admin';
580
-		$this->deletingTheGroup($group);
581
-		$this->currentUser = $previous_user;
582
-		try {
583
-			$this->groupExists($group);
584
-		} catch (\GuzzleHttp\Exception\ClientException $ex) {
585
-			$this->response = $ex->getResponse();
586
-			Assert::assertEquals(404, $ex->getResponse()->getStatusCode());
587
-		}
588
-	}
589
-
590
-	/**
591
-	 * @Given /^user "([^"]*)" is subadmin of group "([^"]*)"$/
592
-	 * @param string $user
593
-	 * @param string $group
594
-	 */
595
-	public function userIsSubadminOfGroup($user, $group) {
596
-		$fullUrl = $this->baseUrl . "v2.php/cloud/groups/$group/subadmins";
597
-		$client = new Client();
598
-		$options = [];
599
-		if ($this->currentUser === 'admin') {
600
-			$options['auth'] = $this->adminUser;
601
-		}
602
-		$options['headers'] = [
603
-			'OCS-APIREQUEST' => 'true',
604
-		];
605
-
606
-		$this->response = $client->get($fullUrl, $options);
607
-		$respondedArray = $this->getArrayOfSubadminsResponded($this->response);
608
-		sort($respondedArray);
609
-		Assert::assertContains($user, $respondedArray);
610
-		Assert::assertEquals(200, $this->response->getStatusCode());
611
-	}
612
-
613
-	/**
614
-	 * @Given /^Assure user "([^"]*)" is subadmin of group "([^"]*)"$/
615
-	 * @param string $user
616
-	 * @param string $group
617
-	 */
618
-	public function assureUserIsSubadminOfGroup($user, $group) {
619
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user/subadmins";
620
-		$client = new Client();
621
-		$options = [];
622
-		if ($this->currentUser === 'admin') {
623
-			$options['auth'] = $this->adminUser;
624
-		}
625
-		$options['form_params'] = [
626
-			'groupid' => $group
627
-		];
628
-		$options['headers'] = [
629
-			'OCS-APIREQUEST' => 'true',
630
-		];
631
-		$this->response = $client->post($fullUrl, $options);
632
-		Assert::assertEquals(200, $this->response->getStatusCode());
633
-	}
634
-
635
-	/**
636
-	 * @Given /^user "([^"]*)" is not a subadmin of group "([^"]*)"$/
637
-	 * @param string $user
638
-	 * @param string $group
639
-	 */
640
-	public function userIsNotSubadminOfGroup($user, $group) {
641
-		$fullUrl = $this->baseUrl . "v2.php/cloud/groups/$group/subadmins";
642
-		$client = new Client();
643
-		$options = [];
644
-		if ($this->currentUser === 'admin') {
645
-			$options['auth'] = $this->adminUser;
646
-		}
647
-		$options['headers'] = [
648
-			'OCS-APIREQUEST' => 'true',
649
-		];
650
-
651
-		$this->response = $client->get($fullUrl, $options);
652
-		$respondedArray = $this->getArrayOfSubadminsResponded($this->response);
653
-		sort($respondedArray);
654
-		Assert::assertNotContains($user, $respondedArray);
655
-		Assert::assertEquals(200, $this->response->getStatusCode());
656
-	}
657
-
658
-	/**
659
-	 * @Then /^users returned are$/
660
-	 * @param TableNode|null $usersList
661
-	 */
662
-	public function theUsersShouldBe($usersList) {
663
-		if ($usersList instanceof TableNode) {
664
-			$users = $usersList->getRows();
665
-			$usersSimplified = $this->simplifyArray($users);
666
-			$respondedArray = $this->getArrayOfUsersResponded($this->response);
667
-			Assert::assertEqualsCanonicalizing($usersSimplified, $respondedArray);
668
-		}
669
-	}
670
-
671
-	/**
672
-	 * @Then /^phone matches returned are$/
673
-	 * @param TableNode|null $usersList
674
-	 */
675
-	public function thePhoneUsersShouldBe($usersList) {
676
-		if ($usersList instanceof TableNode) {
677
-			$users = $usersList->getRowsHash();
678
-			$listCheckedElements = simplexml_load_string($this->response->getBody())->data;
679
-			$respondedArray = json_decode(json_encode($listCheckedElements), true);
680
-			Assert::assertEquals($users, $respondedArray);
681
-		}
682
-	}
683
-
684
-	/**
685
-	 * @Then /^detailed users returned are$/
686
-	 * @param TableNode|null $usersList
687
-	 */
688
-	public function theDetailedUsersShouldBe($usersList) {
689
-		if ($usersList instanceof TableNode) {
690
-			$users = $usersList->getRows();
691
-			$usersSimplified = $this->simplifyArray($users);
692
-			$respondedArray = $this->getArrayOfDetailedUsersResponded($this->response);
693
-			$respondedArray = array_keys($respondedArray);
694
-			Assert::assertEquals($usersSimplified, $respondedArray);
695
-		}
696
-	}
697
-
698
-	/**
699
-	 * @Then /^groups returned are$/
700
-	 * @param TableNode|null $groupsList
701
-	 */
702
-	public function theGroupsShouldBe($groupsList) {
703
-		if ($groupsList instanceof TableNode) {
704
-			$groups = $groupsList->getRows();
705
-			$groupsSimplified = $this->simplifyArray($groups);
706
-			$respondedArray = $this->getArrayOfGroupsResponded($this->response);
707
-			Assert::assertEqualsCanonicalizing($groupsSimplified, $respondedArray);
708
-		}
709
-	}
710
-
711
-	/**
712
-	 * @Then /^subadmin groups returned are$/
713
-	 * @param TableNode|null $groupsList
714
-	 */
715
-	public function theSubadminGroupsShouldBe($groupsList) {
716
-		if ($groupsList instanceof TableNode) {
717
-			$groups = $groupsList->getRows();
718
-			$groupsSimplified = $this->simplifyArray($groups);
719
-			$respondedArray = $this->getArrayOfSubadminsResponded($this->response);
720
-			Assert::assertEqualsCanonicalizing($groupsSimplified, $respondedArray);
721
-		}
722
-	}
723
-
724
-	/**
725
-	 * @Then /^apps returned are$/
726
-	 * @param TableNode|null $appList
727
-	 */
728
-	public function theAppsShouldBe($appList) {
729
-		if ($appList instanceof TableNode) {
730
-			$apps = $appList->getRows();
731
-			$appsSimplified = $this->simplifyArray($apps);
732
-			$respondedArray = $this->getArrayOfAppsResponded($this->response);
733
-			Assert::assertEqualsCanonicalizing($appsSimplified, $respondedArray);
734
-		}
735
-	}
736
-
737
-	/**
738
-	 * @Then /^subadmin users returned are$/
739
-	 * @param TableNode|null $groupsList
740
-	 */
741
-	public function theSubadminUsersShouldBe($groupsList) {
742
-		$this->theSubadminGroupsShouldBe($groupsList);
743
-	}
744
-
745
-	/**
746
-	 * Parses the xml answer to get the array of users returned.
747
-	 *
748
-	 * @param ResponseInterface $resp
749
-	 * @return array
750
-	 */
751
-	public function getArrayOfUsersResponded($resp) {
752
-		$listCheckedElements = simplexml_load_string($resp->getBody())->data[0]->users[0]->element;
753
-		$extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
754
-		return $extractedElementsArray;
755
-	}
756
-
757
-	/**
758
-	 * Parses the xml answer to get the array of detailed users returned.
759
-	 *
760
-	 * @param ResponseInterface $resp
761
-	 * @return array
762
-	 */
763
-	public function getArrayOfDetailedUsersResponded($resp) {
764
-		$listCheckedElements = simplexml_load_string($resp->getBody())->data[0]->users;
765
-		$extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
766
-		return $extractedElementsArray;
767
-	}
768
-
769
-	/**
770
-	 * Parses the xml answer to get the array of groups returned.
771
-	 *
772
-	 * @param ResponseInterface $resp
773
-	 * @return array
774
-	 */
775
-	public function getArrayOfGroupsResponded($resp) {
776
-		$listCheckedElements = simplexml_load_string($resp->getBody())->data[0]->groups[0]->element;
777
-		$extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
778
-		return $extractedElementsArray;
779
-	}
780
-
781
-	/**
782
-	 * Parses the xml answer to get the array of apps returned.
783
-	 *
784
-	 * @param ResponseInterface $resp
785
-	 * @return array
786
-	 */
787
-	public function getArrayOfAppsResponded($resp) {
788
-		$listCheckedElements = simplexml_load_string($resp->getBody())->data[0]->apps[0]->element;
789
-		$extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
790
-		return $extractedElementsArray;
791
-	}
792
-
793
-	/**
794
-	 * Parses the xml answer to get the array of subadmins returned.
795
-	 *
796
-	 * @param ResponseInterface $resp
797
-	 * @return array
798
-	 */
799
-	public function getArrayOfSubadminsResponded($resp) {
800
-		$listCheckedElements = simplexml_load_string($resp->getBody())->data[0]->element;
801
-		$extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
802
-		return $extractedElementsArray;
803
-	}
804
-
805
-
806
-	/**
807
-	 * @Given /^app "([^"]*)" is disabled$/
808
-	 * @param string $app
809
-	 */
810
-	public function appIsDisabled($app) {
811
-		$fullUrl = $this->baseUrl . 'v2.php/cloud/apps?filter=disabled';
812
-		$client = new Client();
813
-		$options = [];
814
-		if ($this->currentUser === 'admin') {
815
-			$options['auth'] = $this->adminUser;
816
-		}
817
-		$options['headers'] = [
818
-			'OCS-APIREQUEST' => 'true',
819
-		];
820
-
821
-		$this->response = $client->get($fullUrl, $options);
822
-		$respondedArray = $this->getArrayOfAppsResponded($this->response);
823
-		Assert::assertContains($app, $respondedArray);
824
-		Assert::assertEquals(200, $this->response->getStatusCode());
825
-	}
826
-
827
-	/**
828
-	 * @Given /^app "([^"]*)" is enabled$/
829
-	 * @param string $app
830
-	 */
831
-	public function appIsEnabled($app) {
832
-		$fullUrl = $this->baseUrl . 'v2.php/cloud/apps?filter=enabled';
833
-		$client = new Client();
834
-		$options = [];
835
-		if ($this->currentUser === 'admin') {
836
-			$options['auth'] = $this->adminUser;
837
-		}
838
-		$options['headers'] = [
839
-			'OCS-APIREQUEST' => 'true',
840
-		];
841
-
842
-		$this->response = $client->get($fullUrl, $options);
843
-		$respondedArray = $this->getArrayOfAppsResponded($this->response);
844
-		Assert::assertContains($app, $respondedArray);
845
-		Assert::assertEquals(200, $this->response->getStatusCode());
846
-	}
847
-
848
-	/**
849
-	 * @Given /^app "([^"]*)" is not enabled$/
850
-	 *
851
-	 * Checks that the app is disabled or not installed.
852
-	 *
853
-	 * @param string $app
854
-	 */
855
-	public function appIsNotEnabled($app) {
856
-		$fullUrl = $this->baseUrl . 'v2.php/cloud/apps?filter=enabled';
857
-		$client = new Client();
858
-		$options = [];
859
-		if ($this->currentUser === 'admin') {
860
-			$options['auth'] = $this->adminUser;
861
-		}
862
-		$options['headers'] = [
863
-			'OCS-APIREQUEST' => 'true',
864
-		];
865
-
866
-		$this->response = $client->get($fullUrl, $options);
867
-		$respondedArray = $this->getArrayOfAppsResponded($this->response);
868
-		Assert::assertNotContains($app, $respondedArray);
869
-		Assert::assertEquals(200, $this->response->getStatusCode());
870
-	}
871
-
872
-	/**
873
-	 * @Then /^user "([^"]*)" is disabled$/
874
-	 * @param string $user
875
-	 */
876
-	public function userIsDisabled($user) {
877
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
878
-		$client = new Client();
879
-		$options = [];
880
-		if ($this->currentUser === 'admin') {
881
-			$options['auth'] = $this->adminUser;
882
-		}
883
-		$options['headers'] = [
884
-			'OCS-APIREQUEST' => 'true',
885
-		];
886
-
887
-		$this->response = $client->get($fullUrl, $options);
888
-		// false in xml is empty
889
-		Assert::assertTrue(empty(simplexml_load_string($this->response->getBody())->data[0]->enabled));
890
-	}
891
-
892
-	/**
893
-	 * @Then /^user "([^"]*)" is enabled$/
894
-	 * @param string $user
895
-	 */
896
-	public function userIsEnabled($user) {
897
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
898
-		$client = new Client();
899
-		$options = [];
900
-		if ($this->currentUser === 'admin') {
901
-			$options['auth'] = $this->adminUser;
902
-		}
903
-		$options['headers'] = [
904
-			'OCS-APIREQUEST' => 'true',
905
-		];
906
-
907
-		$this->response = $client->get($fullUrl, $options);
908
-		// boolean to string is integer
909
-		Assert::assertEquals('1', simplexml_load_string($this->response->getBody())->data[0]->enabled);
910
-	}
911
-
912
-	/**
913
-	 * @Given user :user has a quota of :quota
914
-	 * @param string $user
915
-	 * @param string $quota
916
-	 */
917
-	public function userHasAQuotaOf($user, $quota) {
918
-		$body = new TableNode([
919
-			0 => ['key', 'quota'],
920
-			1 => ['value', $quota],
921
-		]);
922
-
923
-		// method used from BasicStructure trait
924
-		$this->sendingToWith('PUT', '/cloud/users/' . $user, $body);
925
-	}
926
-
927
-	/**
928
-	 * @Given user :user has unlimited quota
929
-	 * @param string $user
930
-	 */
931
-	public function userHasUnlimitedQuota($user) {
932
-		$this->userHasAQuotaOf($user, 'none');
933
-	}
934
-
935
-	/**
936
-	 * Returns home path of the given user
937
-	 *
938
-	 * @param string $user
939
-	 */
940
-	public function getUserHome($user) {
941
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
942
-		$client = new Client();
943
-		$options = [];
944
-		$options['auth'] = $this->adminUser;
945
-		$this->response = $client->get($fullUrl, $options);
946
-		return simplexml_load_string($this->response->getBody())->data[0]->home;
947
-	}
948
-
949
-	/**
950
-	 * @BeforeScenario
951
-	 * @AfterScenario
952
-	 */
953
-	public function cleanupUsers() {
954
-		$previousServer = $this->currentServer;
955
-		$this->usingServer('LOCAL');
956
-		foreach ($this->createdUsers as $user) {
957
-			$this->deleteUser($user);
958
-		}
959
-		$this->usingServer('REMOTE');
960
-		foreach ($this->createdRemoteUsers as $remoteUser) {
961
-			$this->deleteUser($remoteUser);
962
-		}
963
-		$this->usingServer($previousServer);
964
-	}
965
-
966
-	/**
967
-	 * @BeforeScenario
968
-	 * @AfterScenario
969
-	 */
970
-	public function cleanupGroups() {
971
-		$previousServer = $this->currentServer;
972
-		$this->usingServer('LOCAL');
973
-		foreach ($this->createdGroups as $group) {
974
-			$this->deleteGroup($group);
975
-		}
976
-		$this->usingServer('REMOTE');
977
-		foreach ($this->createdRemoteGroups as $remoteGroup) {
978
-			$this->deleteGroup($remoteGroup);
979
-		}
980
-		$this->usingServer($previousServer);
981
-	}
982
-
983
-	/**
984
-	 * @Then /^user "([^"]*)" has not$/
985
-	 */
986
-	public function userHasNotSetting($user, TableNode $settings) {
987
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
988
-		$client = new Client();
989
-		$options = [];
990
-		if ($this->currentUser === 'admin') {
991
-			$options['auth'] = $this->adminUser;
992
-		} else {
993
-			$options['auth'] = [$this->currentUser, $this->regularUser];
994
-		}
995
-		$options['headers'] = [
996
-			'OCS-APIREQUEST' => 'true',
997
-		];
998
-
999
-		$response = $client->get($fullUrl, $options);
1000
-		foreach ($settings->getRows() as $setting) {
1001
-			$value = json_decode(json_encode(simplexml_load_string($response->getBody())->data->{$setting[0]}), 1);
1002
-			if (isset($value[0])) {
1003
-				if (in_array($setting[0], ['additional_mail', 'additional_mailScope'], true)) {
1004
-					$expectedValues = explode(';', $setting[1]);
1005
-					foreach ($expectedValues as $expected) {
1006
-						Assert::assertFalse(in_array($expected, $value, true));
1007
-					}
1008
-				} else {
1009
-					Assert::assertNotEqualsCanonicalizing($setting[1], $value[0]);
1010
-				}
1011
-			} else {
1012
-				Assert::assertNotEquals('', $setting[1]);
1013
-			}
1014
-		}
1015
-	}
16
+    use BasicStructure;
17
+
18
+    /** @var array */
19
+    private $createdUsers = [];
20
+
21
+    /** @var array */
22
+    private $createdRemoteUsers = [];
23
+
24
+    /** @var array */
25
+    private $createdRemoteGroups = [];
26
+
27
+    /** @var array */
28
+    private $createdGroups = [];
29
+
30
+    /**
31
+     * @Given /^user "([^"]*)" exists$/
32
+     * @param string $user
33
+     */
34
+    public function assureUserExists($user) {
35
+        try {
36
+            $this->userExists($user);
37
+        } catch (\GuzzleHttp\Exception\ClientException $ex) {
38
+            $previous_user = $this->currentUser;
39
+            $this->currentUser = 'admin';
40
+            $this->creatingTheUser($user);
41
+            $this->currentUser = $previous_user;
42
+        }
43
+        $this->userExists($user);
44
+        Assert::assertEquals(200, $this->response->getStatusCode());
45
+    }
46
+
47
+    /**
48
+     * @Given /^user "([^"]*)" with displayname "((?:[^"]|\\")*)" exists$/
49
+     * @param string $user
50
+     */
51
+    public function assureUserWithDisplaynameExists($user, $displayname) {
52
+        try {
53
+            $this->userExists($user);
54
+        } catch (\GuzzleHttp\Exception\ClientException $ex) {
55
+            $previous_user = $this->currentUser;
56
+            $this->currentUser = 'admin';
57
+            $this->creatingTheUser($user, $displayname);
58
+            $this->currentUser = $previous_user;
59
+        }
60
+        $this->userExists($user);
61
+        Assert::assertEquals(200, $this->response->getStatusCode());
62
+    }
63
+
64
+    /**
65
+     * @Given /^user "([^"]*)" does not exist$/
66
+     * @param string $user
67
+     */
68
+    public function userDoesNotExist($user) {
69
+        try {
70
+            $this->userExists($user);
71
+        } catch (\GuzzleHttp\Exception\ClientException $ex) {
72
+            $this->response = $ex->getResponse();
73
+            Assert::assertEquals(404, $ex->getResponse()->getStatusCode());
74
+            return;
75
+        }
76
+        $previous_user = $this->currentUser;
77
+        $this->currentUser = 'admin';
78
+        $this->deletingTheUser($user);
79
+        $this->currentUser = $previous_user;
80
+        try {
81
+            $this->userExists($user);
82
+        } catch (\GuzzleHttp\Exception\ClientException $ex) {
83
+            $this->response = $ex->getResponse();
84
+            Assert::assertEquals(404, $ex->getResponse()->getStatusCode());
85
+        }
86
+    }
87
+
88
+    public function creatingTheUser($user, $displayname = '') {
89
+        $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users";
90
+        $client = new Client();
91
+        $options = [];
92
+        if ($this->currentUser === 'admin') {
93
+            $options['auth'] = $this->adminUser;
94
+        }
95
+
96
+        $options['form_params'] = [
97
+            'userid' => $user,
98
+            'password' => '123456'
99
+        ];
100
+        if ($displayname !== '') {
101
+            $options['form_params']['displayName'] = $displayname;
102
+        }
103
+        $options['headers'] = [
104
+            'OCS-APIREQUEST' => 'true',
105
+        ];
106
+
107
+        $this->response = $client->post($fullUrl, $options);
108
+        if ($this->currentServer === 'LOCAL') {
109
+            $this->createdUsers[$user] = $user;
110
+        } elseif ($this->currentServer === 'REMOTE') {
111
+            $this->createdRemoteUsers[$user] = $user;
112
+        }
113
+
114
+        //Quick hack to login once with the current user
115
+        $options2 = [
116
+            'auth' => [$user, '123456'],
117
+        ];
118
+        $options2['headers'] = [
119
+            'OCS-APIREQUEST' => 'true',
120
+        ];
121
+        $url = $fullUrl . '/' . $user;
122
+        $client->get($url, $options2);
123
+    }
124
+
125
+    /**
126
+     * @Then /^user "([^"]*)" has$/
127
+     *
128
+     * @param string $user
129
+     * @param TableNode|null $settings
130
+     */
131
+    public function userHasSetting($user, $settings) {
132
+        $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
133
+        $client = new Client();
134
+        $options = [];
135
+        if ($this->currentUser === 'admin') {
136
+            $options['auth'] = $this->adminUser;
137
+        } else {
138
+            $options['auth'] = [$this->currentUser, $this->regularUser];
139
+        }
140
+        $options['headers'] = [
141
+            'OCS-APIREQUEST' => 'true',
142
+        ];
143
+
144
+        $response = $client->get($fullUrl, $options);
145
+        foreach ($settings->getRows() as $setting) {
146
+            $value = json_decode(json_encode(simplexml_load_string($response->getBody())->data->{$setting[0]}), 1);
147
+            if (isset($value['element']) && in_array($setting[0], ['additional_mail', 'additional_mailScope'], true)) {
148
+                $expectedValues = explode(';', $setting[1]);
149
+                foreach ($expectedValues as $expected) {
150
+                    Assert::assertTrue(in_array($expected, $value['element'], true), 'Data wrong for field: ' . $setting[0]);
151
+                }
152
+            } elseif (isset($value[0])) {
153
+                Assert::assertEqualsCanonicalizing($setting[1], $value[0], 'Data wrong for field: ' . $setting[0]);
154
+            } else {
155
+                Assert::assertEquals('', $setting[1], 'Data wrong for field: ' . $setting[0]);
156
+            }
157
+        }
158
+    }
159
+
160
+    /**
161
+     * @Then /^user "([^"]*)" has the following profile data$/
162
+     */
163
+    public function userHasProfileData(string $user, ?TableNode $settings): void {
164
+        $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/profile/$user";
165
+        $client = new Client();
166
+        $options = [];
167
+        if ($this->currentUser === 'admin') {
168
+            $options['auth'] = $this->adminUser;
169
+        } else {
170
+            $options['auth'] = [$this->currentUser, $this->regularUser];
171
+        }
172
+        $options['headers'] = [
173
+            'OCS-APIREQUEST' => 'true',
174
+            'Accept' => 'application/json',
175
+        ];
176
+
177
+        $response = $client->get($fullUrl, $options);
178
+        $body = $response->getBody()->getContents();
179
+        $data = json_decode($body, true);
180
+        $data = $data['ocs']['data'];
181
+        foreach ($settings->getRows() as $setting) {
182
+            Assert::assertArrayHasKey($setting[0], $data, 'Profile data field missing: ' . $setting[0]);
183
+            if ($setting[1] === 'NULL') {
184
+                Assert::assertNull($data[$setting[0]], 'Profile data wrong for field: ' . $setting[0]);
185
+            } else {
186
+                Assert::assertEquals($setting[1], $data[$setting[0]], 'Profile data wrong for field: ' . $setting[0]);
187
+            }
188
+        }
189
+    }
190
+
191
+    /**
192
+     * @Then /^group "([^"]*)" has$/
193
+     *
194
+     * @param string $user
195
+     * @param TableNode|null $settings
196
+     */
197
+    public function groupHasSetting($group, $settings) {
198
+        $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/groups/details?search=$group";
199
+        $client = new Client();
200
+        $options = [];
201
+        if ($this->currentUser === 'admin') {
202
+            $options['auth'] = $this->adminUser;
203
+        } else {
204
+            $options['auth'] = [$this->currentUser, $this->regularUser];
205
+        }
206
+        $options['headers'] = [
207
+            'OCS-APIREQUEST' => 'true',
208
+        ];
209
+
210
+        $response = $client->get($fullUrl, $options);
211
+        $groupDetails = simplexml_load_string($response->getBody())->data[0]->groups[0]->element;
212
+        foreach ($settings->getRows() as $setting) {
213
+            $value = json_decode(json_encode($groupDetails->{$setting[0]}), 1);
214
+            if (isset($value[0])) {
215
+                Assert::assertEqualsCanonicalizing($setting[1], $value[0]);
216
+            } else {
217
+                Assert::assertEquals('', $setting[1]);
218
+            }
219
+        }
220
+    }
221
+
222
+
223
+    /**
224
+     * @Then /^user "([^"]*)" has editable fields$/
225
+     *
226
+     * @param string $user
227
+     * @param TableNode|null $fields
228
+     */
229
+    public function userHasEditableFields($user, $fields) {
230
+        $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/user/fields";
231
+        if ($user !== 'self') {
232
+            $fullUrl .= '/' . $user;
233
+        }
234
+        $client = new Client();
235
+        $options = [];
236
+        if ($this->currentUser === 'admin') {
237
+            $options['auth'] = $this->adminUser;
238
+        } else {
239
+            $options['auth'] = [$this->currentUser, $this->regularUser];
240
+        }
241
+        $options['headers'] = [
242
+            'OCS-APIREQUEST' => 'true',
243
+        ];
244
+
245
+        $response = $client->get($fullUrl, $options);
246
+        $fieldsArray = json_decode(json_encode(simplexml_load_string($response->getBody())->data->element), 1);
247
+
248
+        $expectedFields = $fields->getRows();
249
+        $expectedFields = $this->simplifyArray($expectedFields);
250
+        Assert::assertEquals($expectedFields, $fieldsArray);
251
+    }
252
+
253
+    /**
254
+     * @Then /^search users by phone for region "([^"]*)" with$/
255
+     *
256
+     * @param string $user
257
+     * @param TableNode|null $settings
258
+     */
259
+    public function searchUserByPhone($region, TableNode $searchTable) {
260
+        $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/search/by-phone";
261
+        $client = new Client();
262
+        $options = [];
263
+        $options['auth'] = $this->adminUser;
264
+        $options['headers'] = [
265
+            'OCS-APIREQUEST' => 'true',
266
+        ];
267
+
268
+        $search = [];
269
+        foreach ($searchTable->getRows() as $row) {
270
+            if (!isset($search[$row[0]])) {
271
+                $search[$row[0]] = [];
272
+            }
273
+            $search[$row[0]][] = $row[1];
274
+        }
275
+
276
+        $options['form_params'] = [
277
+            'location' => $region,
278
+            'search' => $search,
279
+        ];
280
+
281
+        $this->response = $client->post($fullUrl, $options);
282
+    }
283
+
284
+    public function createUser($user) {
285
+        $previous_user = $this->currentUser;
286
+        $this->currentUser = 'admin';
287
+        $this->creatingTheUser($user);
288
+        $this->userExists($user);
289
+        $this->currentUser = $previous_user;
290
+    }
291
+
292
+    public function deleteUser($user) {
293
+        $previous_user = $this->currentUser;
294
+        $this->currentUser = 'admin';
295
+        $this->deletingTheUser($user);
296
+        $this->userDoesNotExist($user);
297
+        $this->currentUser = $previous_user;
298
+    }
299
+
300
+    public function createGroup($group) {
301
+        $previous_user = $this->currentUser;
302
+        $this->currentUser = 'admin';
303
+        $this->creatingTheGroup($group);
304
+        $this->groupExists($group);
305
+        $this->currentUser = $previous_user;
306
+    }
307
+
308
+    public function deleteGroup($group) {
309
+        $previous_user = $this->currentUser;
310
+        $this->currentUser = 'admin';
311
+        $this->deletingTheGroup($group);
312
+        $this->groupDoesNotExist($group);
313
+        $this->currentUser = $previous_user;
314
+    }
315
+
316
+    public function userExists($user) {
317
+        $fullUrl = $this->baseUrl . "v2.php/cloud/users/$user";
318
+        $client = new Client();
319
+        $options = [];
320
+        $options['auth'] = $this->adminUser;
321
+        $options['headers'] = [
322
+            'OCS-APIREQUEST' => 'true'
323
+        ];
324
+
325
+        $this->response = $client->get($fullUrl, $options);
326
+    }
327
+
328
+    /**
329
+     * @Then /^check that user "([^"]*)" belongs to group "([^"]*)"$/
330
+     * @param string $user
331
+     * @param string $group
332
+     */
333
+    public function checkThatUserBelongsToGroup($user, $group) {
334
+        $fullUrl = $this->baseUrl . "v2.php/cloud/users/$user/groups";
335
+        $client = new Client();
336
+        $options = [];
337
+        if ($this->currentUser === 'admin') {
338
+            $options['auth'] = $this->adminUser;
339
+        }
340
+        $options['headers'] = [
341
+            'OCS-APIREQUEST' => 'true',
342
+        ];
343
+
344
+        $this->response = $client->get($fullUrl, $options);
345
+        $respondedArray = $this->getArrayOfGroupsResponded($this->response);
346
+        sort($respondedArray);
347
+        Assert::assertContains($group, $respondedArray);
348
+        Assert::assertEquals(200, $this->response->getStatusCode());
349
+    }
350
+
351
+    public function userBelongsToGroup($user, $group) {
352
+        $fullUrl = $this->baseUrl . "v2.php/cloud/users/$user/groups";
353
+        $client = new Client();
354
+        $options = [];
355
+        if ($this->currentUser === 'admin') {
356
+            $options['auth'] = $this->adminUser;
357
+        }
358
+        $options['headers'] = [
359
+            'OCS-APIREQUEST' => 'true',
360
+        ];
361
+
362
+        $this->response = $client->get($fullUrl, $options);
363
+        $respondedArray = $this->getArrayOfGroupsResponded($this->response);
364
+
365
+        if (array_key_exists($group, $respondedArray)) {
366
+            return true;
367
+        } else {
368
+            return false;
369
+        }
370
+    }
371
+
372
+    /**
373
+     * @Given /^user "([^"]*)" belongs to group "([^"]*)"$/
374
+     * @param string $user
375
+     * @param string $group
376
+     */
377
+    public function assureUserBelongsToGroup($user, $group) {
378
+        $previous_user = $this->currentUser;
379
+        $this->currentUser = 'admin';
380
+
381
+        if (!$this->userBelongsToGroup($user, $group)) {
382
+            $this->addingUserToGroup($user, $group);
383
+        }
384
+
385
+        $this->checkThatUserBelongsToGroup($user, $group);
386
+        $this->currentUser = $previous_user;
387
+    }
388
+
389
+    /**
390
+     * @Given /^user "([^"]*)" does not belong to group "([^"]*)"$/
391
+     * @param string $user
392
+     * @param string $group
393
+     */
394
+    public function userDoesNotBelongToGroup($user, $group) {
395
+        $fullUrl = $this->baseUrl . "v2.php/cloud/users/$user/groups";
396
+        $client = new Client();
397
+        $options = [];
398
+        if ($this->currentUser === 'admin') {
399
+            $options['auth'] = $this->adminUser;
400
+        }
401
+        $options['headers'] = [
402
+            'OCS-APIREQUEST' => 'true',
403
+        ];
404
+
405
+        $this->response = $client->get($fullUrl, $options);
406
+        $groups = [$group];
407
+        $respondedArray = $this->getArrayOfGroupsResponded($this->response);
408
+        Assert::assertNotEqualsCanonicalizing($groups, $respondedArray);
409
+        Assert::assertEquals(200, $this->response->getStatusCode());
410
+    }
411
+
412
+    /**
413
+     * @When /^creating the group "([^"]*)"$/
414
+     * @param string $group
415
+     */
416
+    public function creatingTheGroup($group) {
417
+        $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/groups";
418
+        $client = new Client();
419
+        $options = [];
420
+        if ($this->currentUser === 'admin') {
421
+            $options['auth'] = $this->adminUser;
422
+        }
423
+
424
+        $options['form_params'] = [
425
+            'groupid' => $group,
426
+        ];
427
+        $options['headers'] = [
428
+            'OCS-APIREQUEST' => 'true',
429
+        ];
430
+
431
+        $this->response = $client->post($fullUrl, $options);
432
+        if ($this->currentServer === 'LOCAL') {
433
+            $this->createdGroups[$group] = $group;
434
+        } elseif ($this->currentServer === 'REMOTE') {
435
+            $this->createdRemoteGroups[$group] = $group;
436
+        }
437
+    }
438
+
439
+    /**
440
+     * @When /^assure user "([^"]*)" is disabled$/
441
+     */
442
+    public function assureUserIsDisabled($user) {
443
+        $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user/disable";
444
+        $client = new Client();
445
+        $options = [];
446
+        if ($this->currentUser === 'admin') {
447
+            $options['auth'] = $this->adminUser;
448
+        }
449
+        $options['headers'] = [
450
+            'OCS-APIREQUEST' => 'true',
451
+        ];
452
+        // TODO: fix hack
453
+        $options['form_params'] = [
454
+            'foo' => 'bar'
455
+        ];
456
+
457
+        $this->response = $client->put($fullUrl, $options);
458
+    }
459
+
460
+    /**
461
+     * @When /^Deleting the user "([^"]*)"$/
462
+     * @param string $user
463
+     */
464
+    public function deletingTheUser($user) {
465
+        $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
466
+        $client = new Client();
467
+        $options = [];
468
+        if ($this->currentUser === 'admin') {
469
+            $options['auth'] = $this->adminUser;
470
+        }
471
+        $options['headers'] = [
472
+            'OCS-APIREQUEST' => 'true',
473
+        ];
474
+
475
+        $this->response = $client->delete($fullUrl, $options);
476
+    }
477
+
478
+    /**
479
+     * @When /^Deleting the group "([^"]*)"$/
480
+     * @param string $group
481
+     */
482
+    public function deletingTheGroup($group) {
483
+        $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/groups/$group";
484
+        $client = new Client();
485
+        $options = [];
486
+        if ($this->currentUser === 'admin') {
487
+            $options['auth'] = $this->adminUser;
488
+        }
489
+        $options['headers'] = [
490
+            'OCS-APIREQUEST' => 'true',
491
+        ];
492
+
493
+        $this->response = $client->delete($fullUrl, $options);
494
+
495
+        if ($this->currentServer === 'LOCAL') {
496
+            unset($this->createdGroups[$group]);
497
+        } elseif ($this->currentServer === 'REMOTE') {
498
+            unset($this->createdRemoteGroups[$group]);
499
+        }
500
+    }
501
+
502
+    /**
503
+     * @Given /^Add user "([^"]*)" to the group "([^"]*)"$/
504
+     * @param string $user
505
+     * @param string $group
506
+     */
507
+    public function addUserToGroup($user, $group) {
508
+        $this->userExists($user);
509
+        $this->groupExists($group);
510
+        $this->addingUserToGroup($user, $group);
511
+    }
512
+
513
+    /**
514
+     * @When /^User "([^"]*)" is added to the group "([^"]*)"$/
515
+     * @param string $user
516
+     * @param string $group
517
+     */
518
+    public function addingUserToGroup($user, $group) {
519
+        $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user/groups";
520
+        $client = new Client();
521
+        $options = [];
522
+        if ($this->currentUser === 'admin') {
523
+            $options['auth'] = $this->adminUser;
524
+        }
525
+        $options['headers'] = [
526
+            'OCS-APIREQUEST' => 'true',
527
+        ];
528
+
529
+        $options['form_params'] = [
530
+            'groupid' => $group,
531
+        ];
532
+
533
+        $this->response = $client->post($fullUrl, $options);
534
+    }
535
+
536
+
537
+    public function groupExists($group) {
538
+        $fullUrl = $this->baseUrl . "v2.php/cloud/groups/$group";
539
+        $client = new Client();
540
+        $options = [];
541
+        $options['auth'] = $this->adminUser;
542
+        $options['headers'] = [
543
+            'OCS-APIREQUEST' => 'true',
544
+        ];
545
+
546
+        $this->response = $client->get($fullUrl, $options);
547
+    }
548
+
549
+    /**
550
+     * @Given /^group "([^"]*)" exists$/
551
+     * @param string $group
552
+     */
553
+    public function assureGroupExists($group) {
554
+        try {
555
+            $this->groupExists($group);
556
+        } catch (\GuzzleHttp\Exception\ClientException $ex) {
557
+            $previous_user = $this->currentUser;
558
+            $this->currentUser = 'admin';
559
+            $this->creatingTheGroup($group);
560
+            $this->currentUser = $previous_user;
561
+        }
562
+        $this->groupExists($group);
563
+        Assert::assertEquals(200, $this->response->getStatusCode());
564
+    }
565
+
566
+    /**
567
+     * @Given /^group "([^"]*)" does not exist$/
568
+     * @param string $group
569
+     */
570
+    public function groupDoesNotExist($group) {
571
+        try {
572
+            $this->groupExists($group);
573
+        } catch (\GuzzleHttp\Exception\ClientException $ex) {
574
+            $this->response = $ex->getResponse();
575
+            Assert::assertEquals(404, $ex->getResponse()->getStatusCode());
576
+            return;
577
+        }
578
+        $previous_user = $this->currentUser;
579
+        $this->currentUser = 'admin';
580
+        $this->deletingTheGroup($group);
581
+        $this->currentUser = $previous_user;
582
+        try {
583
+            $this->groupExists($group);
584
+        } catch (\GuzzleHttp\Exception\ClientException $ex) {
585
+            $this->response = $ex->getResponse();
586
+            Assert::assertEquals(404, $ex->getResponse()->getStatusCode());
587
+        }
588
+    }
589
+
590
+    /**
591
+     * @Given /^user "([^"]*)" is subadmin of group "([^"]*)"$/
592
+     * @param string $user
593
+     * @param string $group
594
+     */
595
+    public function userIsSubadminOfGroup($user, $group) {
596
+        $fullUrl = $this->baseUrl . "v2.php/cloud/groups/$group/subadmins";
597
+        $client = new Client();
598
+        $options = [];
599
+        if ($this->currentUser === 'admin') {
600
+            $options['auth'] = $this->adminUser;
601
+        }
602
+        $options['headers'] = [
603
+            'OCS-APIREQUEST' => 'true',
604
+        ];
605
+
606
+        $this->response = $client->get($fullUrl, $options);
607
+        $respondedArray = $this->getArrayOfSubadminsResponded($this->response);
608
+        sort($respondedArray);
609
+        Assert::assertContains($user, $respondedArray);
610
+        Assert::assertEquals(200, $this->response->getStatusCode());
611
+    }
612
+
613
+    /**
614
+     * @Given /^Assure user "([^"]*)" is subadmin of group "([^"]*)"$/
615
+     * @param string $user
616
+     * @param string $group
617
+     */
618
+    public function assureUserIsSubadminOfGroup($user, $group) {
619
+        $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user/subadmins";
620
+        $client = new Client();
621
+        $options = [];
622
+        if ($this->currentUser === 'admin') {
623
+            $options['auth'] = $this->adminUser;
624
+        }
625
+        $options['form_params'] = [
626
+            'groupid' => $group
627
+        ];
628
+        $options['headers'] = [
629
+            'OCS-APIREQUEST' => 'true',
630
+        ];
631
+        $this->response = $client->post($fullUrl, $options);
632
+        Assert::assertEquals(200, $this->response->getStatusCode());
633
+    }
634
+
635
+    /**
636
+     * @Given /^user "([^"]*)" is not a subadmin of group "([^"]*)"$/
637
+     * @param string $user
638
+     * @param string $group
639
+     */
640
+    public function userIsNotSubadminOfGroup($user, $group) {
641
+        $fullUrl = $this->baseUrl . "v2.php/cloud/groups/$group/subadmins";
642
+        $client = new Client();
643
+        $options = [];
644
+        if ($this->currentUser === 'admin') {
645
+            $options['auth'] = $this->adminUser;
646
+        }
647
+        $options['headers'] = [
648
+            'OCS-APIREQUEST' => 'true',
649
+        ];
650
+
651
+        $this->response = $client->get($fullUrl, $options);
652
+        $respondedArray = $this->getArrayOfSubadminsResponded($this->response);
653
+        sort($respondedArray);
654
+        Assert::assertNotContains($user, $respondedArray);
655
+        Assert::assertEquals(200, $this->response->getStatusCode());
656
+    }
657
+
658
+    /**
659
+     * @Then /^users returned are$/
660
+     * @param TableNode|null $usersList
661
+     */
662
+    public function theUsersShouldBe($usersList) {
663
+        if ($usersList instanceof TableNode) {
664
+            $users = $usersList->getRows();
665
+            $usersSimplified = $this->simplifyArray($users);
666
+            $respondedArray = $this->getArrayOfUsersResponded($this->response);
667
+            Assert::assertEqualsCanonicalizing($usersSimplified, $respondedArray);
668
+        }
669
+    }
670
+
671
+    /**
672
+     * @Then /^phone matches returned are$/
673
+     * @param TableNode|null $usersList
674
+     */
675
+    public function thePhoneUsersShouldBe($usersList) {
676
+        if ($usersList instanceof TableNode) {
677
+            $users = $usersList->getRowsHash();
678
+            $listCheckedElements = simplexml_load_string($this->response->getBody())->data;
679
+            $respondedArray = json_decode(json_encode($listCheckedElements), true);
680
+            Assert::assertEquals($users, $respondedArray);
681
+        }
682
+    }
683
+
684
+    /**
685
+     * @Then /^detailed users returned are$/
686
+     * @param TableNode|null $usersList
687
+     */
688
+    public function theDetailedUsersShouldBe($usersList) {
689
+        if ($usersList instanceof TableNode) {
690
+            $users = $usersList->getRows();
691
+            $usersSimplified = $this->simplifyArray($users);
692
+            $respondedArray = $this->getArrayOfDetailedUsersResponded($this->response);
693
+            $respondedArray = array_keys($respondedArray);
694
+            Assert::assertEquals($usersSimplified, $respondedArray);
695
+        }
696
+    }
697
+
698
+    /**
699
+     * @Then /^groups returned are$/
700
+     * @param TableNode|null $groupsList
701
+     */
702
+    public function theGroupsShouldBe($groupsList) {
703
+        if ($groupsList instanceof TableNode) {
704
+            $groups = $groupsList->getRows();
705
+            $groupsSimplified = $this->simplifyArray($groups);
706
+            $respondedArray = $this->getArrayOfGroupsResponded($this->response);
707
+            Assert::assertEqualsCanonicalizing($groupsSimplified, $respondedArray);
708
+        }
709
+    }
710
+
711
+    /**
712
+     * @Then /^subadmin groups returned are$/
713
+     * @param TableNode|null $groupsList
714
+     */
715
+    public function theSubadminGroupsShouldBe($groupsList) {
716
+        if ($groupsList instanceof TableNode) {
717
+            $groups = $groupsList->getRows();
718
+            $groupsSimplified = $this->simplifyArray($groups);
719
+            $respondedArray = $this->getArrayOfSubadminsResponded($this->response);
720
+            Assert::assertEqualsCanonicalizing($groupsSimplified, $respondedArray);
721
+        }
722
+    }
723
+
724
+    /**
725
+     * @Then /^apps returned are$/
726
+     * @param TableNode|null $appList
727
+     */
728
+    public function theAppsShouldBe($appList) {
729
+        if ($appList instanceof TableNode) {
730
+            $apps = $appList->getRows();
731
+            $appsSimplified = $this->simplifyArray($apps);
732
+            $respondedArray = $this->getArrayOfAppsResponded($this->response);
733
+            Assert::assertEqualsCanonicalizing($appsSimplified, $respondedArray);
734
+        }
735
+    }
736
+
737
+    /**
738
+     * @Then /^subadmin users returned are$/
739
+     * @param TableNode|null $groupsList
740
+     */
741
+    public function theSubadminUsersShouldBe($groupsList) {
742
+        $this->theSubadminGroupsShouldBe($groupsList);
743
+    }
744
+
745
+    /**
746
+     * Parses the xml answer to get the array of users returned.
747
+     *
748
+     * @param ResponseInterface $resp
749
+     * @return array
750
+     */
751
+    public function getArrayOfUsersResponded($resp) {
752
+        $listCheckedElements = simplexml_load_string($resp->getBody())->data[0]->users[0]->element;
753
+        $extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
754
+        return $extractedElementsArray;
755
+    }
756
+
757
+    /**
758
+     * Parses the xml answer to get the array of detailed users returned.
759
+     *
760
+     * @param ResponseInterface $resp
761
+     * @return array
762
+     */
763
+    public function getArrayOfDetailedUsersResponded($resp) {
764
+        $listCheckedElements = simplexml_load_string($resp->getBody())->data[0]->users;
765
+        $extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
766
+        return $extractedElementsArray;
767
+    }
768
+
769
+    /**
770
+     * Parses the xml answer to get the array of groups returned.
771
+     *
772
+     * @param ResponseInterface $resp
773
+     * @return array
774
+     */
775
+    public function getArrayOfGroupsResponded($resp) {
776
+        $listCheckedElements = simplexml_load_string($resp->getBody())->data[0]->groups[0]->element;
777
+        $extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
778
+        return $extractedElementsArray;
779
+    }
780
+
781
+    /**
782
+     * Parses the xml answer to get the array of apps returned.
783
+     *
784
+     * @param ResponseInterface $resp
785
+     * @return array
786
+     */
787
+    public function getArrayOfAppsResponded($resp) {
788
+        $listCheckedElements = simplexml_load_string($resp->getBody())->data[0]->apps[0]->element;
789
+        $extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
790
+        return $extractedElementsArray;
791
+    }
792
+
793
+    /**
794
+     * Parses the xml answer to get the array of subadmins returned.
795
+     *
796
+     * @param ResponseInterface $resp
797
+     * @return array
798
+     */
799
+    public function getArrayOfSubadminsResponded($resp) {
800
+        $listCheckedElements = simplexml_load_string($resp->getBody())->data[0]->element;
801
+        $extractedElementsArray = json_decode(json_encode($listCheckedElements), 1);
802
+        return $extractedElementsArray;
803
+    }
804
+
805
+
806
+    /**
807
+     * @Given /^app "([^"]*)" is disabled$/
808
+     * @param string $app
809
+     */
810
+    public function appIsDisabled($app) {
811
+        $fullUrl = $this->baseUrl . 'v2.php/cloud/apps?filter=disabled';
812
+        $client = new Client();
813
+        $options = [];
814
+        if ($this->currentUser === 'admin') {
815
+            $options['auth'] = $this->adminUser;
816
+        }
817
+        $options['headers'] = [
818
+            'OCS-APIREQUEST' => 'true',
819
+        ];
820
+
821
+        $this->response = $client->get($fullUrl, $options);
822
+        $respondedArray = $this->getArrayOfAppsResponded($this->response);
823
+        Assert::assertContains($app, $respondedArray);
824
+        Assert::assertEquals(200, $this->response->getStatusCode());
825
+    }
826
+
827
+    /**
828
+     * @Given /^app "([^"]*)" is enabled$/
829
+     * @param string $app
830
+     */
831
+    public function appIsEnabled($app) {
832
+        $fullUrl = $this->baseUrl . 'v2.php/cloud/apps?filter=enabled';
833
+        $client = new Client();
834
+        $options = [];
835
+        if ($this->currentUser === 'admin') {
836
+            $options['auth'] = $this->adminUser;
837
+        }
838
+        $options['headers'] = [
839
+            'OCS-APIREQUEST' => 'true',
840
+        ];
841
+
842
+        $this->response = $client->get($fullUrl, $options);
843
+        $respondedArray = $this->getArrayOfAppsResponded($this->response);
844
+        Assert::assertContains($app, $respondedArray);
845
+        Assert::assertEquals(200, $this->response->getStatusCode());
846
+    }
847
+
848
+    /**
849
+     * @Given /^app "([^"]*)" is not enabled$/
850
+     *
851
+     * Checks that the app is disabled or not installed.
852
+     *
853
+     * @param string $app
854
+     */
855
+    public function appIsNotEnabled($app) {
856
+        $fullUrl = $this->baseUrl . 'v2.php/cloud/apps?filter=enabled';
857
+        $client = new Client();
858
+        $options = [];
859
+        if ($this->currentUser === 'admin') {
860
+            $options['auth'] = $this->adminUser;
861
+        }
862
+        $options['headers'] = [
863
+            'OCS-APIREQUEST' => 'true',
864
+        ];
865
+
866
+        $this->response = $client->get($fullUrl, $options);
867
+        $respondedArray = $this->getArrayOfAppsResponded($this->response);
868
+        Assert::assertNotContains($app, $respondedArray);
869
+        Assert::assertEquals(200, $this->response->getStatusCode());
870
+    }
871
+
872
+    /**
873
+     * @Then /^user "([^"]*)" is disabled$/
874
+     * @param string $user
875
+     */
876
+    public function userIsDisabled($user) {
877
+        $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
878
+        $client = new Client();
879
+        $options = [];
880
+        if ($this->currentUser === 'admin') {
881
+            $options['auth'] = $this->adminUser;
882
+        }
883
+        $options['headers'] = [
884
+            'OCS-APIREQUEST' => 'true',
885
+        ];
886
+
887
+        $this->response = $client->get($fullUrl, $options);
888
+        // false in xml is empty
889
+        Assert::assertTrue(empty(simplexml_load_string($this->response->getBody())->data[0]->enabled));
890
+    }
891
+
892
+    /**
893
+     * @Then /^user "([^"]*)" is enabled$/
894
+     * @param string $user
895
+     */
896
+    public function userIsEnabled($user) {
897
+        $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
898
+        $client = new Client();
899
+        $options = [];
900
+        if ($this->currentUser === 'admin') {
901
+            $options['auth'] = $this->adminUser;
902
+        }
903
+        $options['headers'] = [
904
+            'OCS-APIREQUEST' => 'true',
905
+        ];
906
+
907
+        $this->response = $client->get($fullUrl, $options);
908
+        // boolean to string is integer
909
+        Assert::assertEquals('1', simplexml_load_string($this->response->getBody())->data[0]->enabled);
910
+    }
911
+
912
+    /**
913
+     * @Given user :user has a quota of :quota
914
+     * @param string $user
915
+     * @param string $quota
916
+     */
917
+    public function userHasAQuotaOf($user, $quota) {
918
+        $body = new TableNode([
919
+            0 => ['key', 'quota'],
920
+            1 => ['value', $quota],
921
+        ]);
922
+
923
+        // method used from BasicStructure trait
924
+        $this->sendingToWith('PUT', '/cloud/users/' . $user, $body);
925
+    }
926
+
927
+    /**
928
+     * @Given user :user has unlimited quota
929
+     * @param string $user
930
+     */
931
+    public function userHasUnlimitedQuota($user) {
932
+        $this->userHasAQuotaOf($user, 'none');
933
+    }
934
+
935
+    /**
936
+     * Returns home path of the given user
937
+     *
938
+     * @param string $user
939
+     */
940
+    public function getUserHome($user) {
941
+        $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
942
+        $client = new Client();
943
+        $options = [];
944
+        $options['auth'] = $this->adminUser;
945
+        $this->response = $client->get($fullUrl, $options);
946
+        return simplexml_load_string($this->response->getBody())->data[0]->home;
947
+    }
948
+
949
+    /**
950
+     * @BeforeScenario
951
+     * @AfterScenario
952
+     */
953
+    public function cleanupUsers() {
954
+        $previousServer = $this->currentServer;
955
+        $this->usingServer('LOCAL');
956
+        foreach ($this->createdUsers as $user) {
957
+            $this->deleteUser($user);
958
+        }
959
+        $this->usingServer('REMOTE');
960
+        foreach ($this->createdRemoteUsers as $remoteUser) {
961
+            $this->deleteUser($remoteUser);
962
+        }
963
+        $this->usingServer($previousServer);
964
+    }
965
+
966
+    /**
967
+     * @BeforeScenario
968
+     * @AfterScenario
969
+     */
970
+    public function cleanupGroups() {
971
+        $previousServer = $this->currentServer;
972
+        $this->usingServer('LOCAL');
973
+        foreach ($this->createdGroups as $group) {
974
+            $this->deleteGroup($group);
975
+        }
976
+        $this->usingServer('REMOTE');
977
+        foreach ($this->createdRemoteGroups as $remoteGroup) {
978
+            $this->deleteGroup($remoteGroup);
979
+        }
980
+        $this->usingServer($previousServer);
981
+    }
982
+
983
+    /**
984
+     * @Then /^user "([^"]*)" has not$/
985
+     */
986
+    public function userHasNotSetting($user, TableNode $settings) {
987
+        $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
988
+        $client = new Client();
989
+        $options = [];
990
+        if ($this->currentUser === 'admin') {
991
+            $options['auth'] = $this->adminUser;
992
+        } else {
993
+            $options['auth'] = [$this->currentUser, $this->regularUser];
994
+        }
995
+        $options['headers'] = [
996
+            'OCS-APIREQUEST' => 'true',
997
+        ];
998
+
999
+        $response = $client->get($fullUrl, $options);
1000
+        foreach ($settings->getRows() as $setting) {
1001
+            $value = json_decode(json_encode(simplexml_load_string($response->getBody())->data->{$setting[0]}), 1);
1002
+            if (isset($value[0])) {
1003
+                if (in_array($setting[0], ['additional_mail', 'additional_mailScope'], true)) {
1004
+                    $expectedValues = explode(';', $setting[1]);
1005
+                    foreach ($expectedValues as $expected) {
1006
+                        Assert::assertFalse(in_array($expected, $value, true));
1007
+                    }
1008
+                } else {
1009
+                    Assert::assertNotEqualsCanonicalizing($setting[1], $value[0]);
1010
+                }
1011
+            } else {
1012
+                Assert::assertNotEquals('', $setting[1]);
1013
+            }
1014
+        }
1015
+    }
1016 1016
 }
Please login to merge, or discard this patch.
Spacing   +36 added lines, -36 removed lines patch added patch discarded remove patch
@@ -10,7 +10,7 @@  discard block
 block discarded – undo
10 10
 use GuzzleHttp\Message\ResponseInterface;
11 11
 use PHPUnit\Framework\Assert;
12 12
 
13
-require __DIR__ . '/../../vendor/autoload.php';
13
+require __DIR__.'/../../vendor/autoload.php';
14 14
 
15 15
 trait Provisioning {
16 16
 	use BasicStructure;
@@ -86,7 +86,7 @@  discard block
 block discarded – undo
86 86
 	}
87 87
 
88 88
 	public function creatingTheUser($user, $displayname = '') {
89
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users";
89
+		$fullUrl = $this->baseUrl."v{$this->apiVersion}.php/cloud/users";
90 90
 		$client = new Client();
91 91
 		$options = [];
92 92
 		if ($this->currentUser === 'admin') {
@@ -118,7 +118,7 @@  discard block
 block discarded – undo
118 118
 		$options2['headers'] = [
119 119
 			'OCS-APIREQUEST' => 'true',
120 120
 		];
121
-		$url = $fullUrl . '/' . $user;
121
+		$url = $fullUrl.'/'.$user;
122 122
 		$client->get($url, $options2);
123 123
 	}
124 124
 
@@ -129,7 +129,7 @@  discard block
 block discarded – undo
129 129
 	 * @param TableNode|null $settings
130 130
 	 */
131 131
 	public function userHasSetting($user, $settings) {
132
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
132
+		$fullUrl = $this->baseUrl."v{$this->apiVersion}.php/cloud/users/$user";
133 133
 		$client = new Client();
134 134
 		$options = [];
135 135
 		if ($this->currentUser === 'admin') {
@@ -147,12 +147,12 @@  discard block
 block discarded – undo
147 147
 			if (isset($value['element']) && in_array($setting[0], ['additional_mail', 'additional_mailScope'], true)) {
148 148
 				$expectedValues = explode(';', $setting[1]);
149 149
 				foreach ($expectedValues as $expected) {
150
-					Assert::assertTrue(in_array($expected, $value['element'], true), 'Data wrong for field: ' . $setting[0]);
150
+					Assert::assertTrue(in_array($expected, $value['element'], true), 'Data wrong for field: '.$setting[0]);
151 151
 				}
152 152
 			} elseif (isset($value[0])) {
153
-				Assert::assertEqualsCanonicalizing($setting[1], $value[0], 'Data wrong for field: ' . $setting[0]);
153
+				Assert::assertEqualsCanonicalizing($setting[1], $value[0], 'Data wrong for field: '.$setting[0]);
154 154
 			} else {
155
-				Assert::assertEquals('', $setting[1], 'Data wrong for field: ' . $setting[0]);
155
+				Assert::assertEquals('', $setting[1], 'Data wrong for field: '.$setting[0]);
156 156
 			}
157 157
 		}
158 158
 	}
@@ -161,7 +161,7 @@  discard block
 block discarded – undo
161 161
 	 * @Then /^user "([^"]*)" has the following profile data$/
162 162
 	 */
163 163
 	public function userHasProfileData(string $user, ?TableNode $settings): void {
164
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/profile/$user";
164
+		$fullUrl = $this->baseUrl."v{$this->apiVersion}.php/profile/$user";
165 165
 		$client = new Client();
166 166
 		$options = [];
167 167
 		if ($this->currentUser === 'admin') {
@@ -179,11 +179,11 @@  discard block
 block discarded – undo
179 179
 		$data = json_decode($body, true);
180 180
 		$data = $data['ocs']['data'];
181 181
 		foreach ($settings->getRows() as $setting) {
182
-			Assert::assertArrayHasKey($setting[0], $data, 'Profile data field missing: ' . $setting[0]);
182
+			Assert::assertArrayHasKey($setting[0], $data, 'Profile data field missing: '.$setting[0]);
183 183
 			if ($setting[1] === 'NULL') {
184
-				Assert::assertNull($data[$setting[0]], 'Profile data wrong for field: ' . $setting[0]);
184
+				Assert::assertNull($data[$setting[0]], 'Profile data wrong for field: '.$setting[0]);
185 185
 			} else {
186
-				Assert::assertEquals($setting[1], $data[$setting[0]], 'Profile data wrong for field: ' . $setting[0]);
186
+				Assert::assertEquals($setting[1], $data[$setting[0]], 'Profile data wrong for field: '.$setting[0]);
187 187
 			}
188 188
 		}
189 189
 	}
@@ -195,7 +195,7 @@  discard block
 block discarded – undo
195 195
 	 * @param TableNode|null $settings
196 196
 	 */
197 197
 	public function groupHasSetting($group, $settings) {
198
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/groups/details?search=$group";
198
+		$fullUrl = $this->baseUrl."v{$this->apiVersion}.php/cloud/groups/details?search=$group";
199 199
 		$client = new Client();
200 200
 		$options = [];
201 201
 		if ($this->currentUser === 'admin') {
@@ -227,9 +227,9 @@  discard block
 block discarded – undo
227 227
 	 * @param TableNode|null $fields
228 228
 	 */
229 229
 	public function userHasEditableFields($user, $fields) {
230
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/user/fields";
230
+		$fullUrl = $this->baseUrl."v{$this->apiVersion}.php/cloud/user/fields";
231 231
 		if ($user !== 'self') {
232
-			$fullUrl .= '/' . $user;
232
+			$fullUrl .= '/'.$user;
233 233
 		}
234 234
 		$client = new Client();
235 235
 		$options = [];
@@ -257,7 +257,7 @@  discard block
 block discarded – undo
257 257
 	 * @param TableNode|null $settings
258 258
 	 */
259 259
 	public function searchUserByPhone($region, TableNode $searchTable) {
260
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/search/by-phone";
260
+		$fullUrl = $this->baseUrl."v{$this->apiVersion}.php/cloud/users/search/by-phone";
261 261
 		$client = new Client();
262 262
 		$options = [];
263 263
 		$options['auth'] = $this->adminUser;
@@ -314,7 +314,7 @@  discard block
 block discarded – undo
314 314
 	}
315 315
 
316 316
 	public function userExists($user) {
317
-		$fullUrl = $this->baseUrl . "v2.php/cloud/users/$user";
317
+		$fullUrl = $this->baseUrl."v2.php/cloud/users/$user";
318 318
 		$client = new Client();
319 319
 		$options = [];
320 320
 		$options['auth'] = $this->adminUser;
@@ -331,7 +331,7 @@  discard block
 block discarded – undo
331 331
 	 * @param string $group
332 332
 	 */
333 333
 	public function checkThatUserBelongsToGroup($user, $group) {
334
-		$fullUrl = $this->baseUrl . "v2.php/cloud/users/$user/groups";
334
+		$fullUrl = $this->baseUrl."v2.php/cloud/users/$user/groups";
335 335
 		$client = new Client();
336 336
 		$options = [];
337 337
 		if ($this->currentUser === 'admin') {
@@ -349,7 +349,7 @@  discard block
 block discarded – undo
349 349
 	}
350 350
 
351 351
 	public function userBelongsToGroup($user, $group) {
352
-		$fullUrl = $this->baseUrl . "v2.php/cloud/users/$user/groups";
352
+		$fullUrl = $this->baseUrl."v2.php/cloud/users/$user/groups";
353 353
 		$client = new Client();
354 354
 		$options = [];
355 355
 		if ($this->currentUser === 'admin') {
@@ -392,7 +392,7 @@  discard block
 block discarded – undo
392 392
 	 * @param string $group
393 393
 	 */
394 394
 	public function userDoesNotBelongToGroup($user, $group) {
395
-		$fullUrl = $this->baseUrl . "v2.php/cloud/users/$user/groups";
395
+		$fullUrl = $this->baseUrl."v2.php/cloud/users/$user/groups";
396 396
 		$client = new Client();
397 397
 		$options = [];
398 398
 		if ($this->currentUser === 'admin') {
@@ -414,7 +414,7 @@  discard block
 block discarded – undo
414 414
 	 * @param string $group
415 415
 	 */
416 416
 	public function creatingTheGroup($group) {
417
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/groups";
417
+		$fullUrl = $this->baseUrl."v{$this->apiVersion}.php/cloud/groups";
418 418
 		$client = new Client();
419 419
 		$options = [];
420 420
 		if ($this->currentUser === 'admin') {
@@ -440,7 +440,7 @@  discard block
 block discarded – undo
440 440
 	 * @When /^assure user "([^"]*)" is disabled$/
441 441
 	 */
442 442
 	public function assureUserIsDisabled($user) {
443
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user/disable";
443
+		$fullUrl = $this->baseUrl."v{$this->apiVersion}.php/cloud/users/$user/disable";
444 444
 		$client = new Client();
445 445
 		$options = [];
446 446
 		if ($this->currentUser === 'admin') {
@@ -462,7 +462,7 @@  discard block
 block discarded – undo
462 462
 	 * @param string $user
463 463
 	 */
464 464
 	public function deletingTheUser($user) {
465
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
465
+		$fullUrl = $this->baseUrl."v{$this->apiVersion}.php/cloud/users/$user";
466 466
 		$client = new Client();
467 467
 		$options = [];
468 468
 		if ($this->currentUser === 'admin') {
@@ -480,7 +480,7 @@  discard block
 block discarded – undo
480 480
 	 * @param string $group
481 481
 	 */
482 482
 	public function deletingTheGroup($group) {
483
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/groups/$group";
483
+		$fullUrl = $this->baseUrl."v{$this->apiVersion}.php/cloud/groups/$group";
484 484
 		$client = new Client();
485 485
 		$options = [];
486 486
 		if ($this->currentUser === 'admin') {
@@ -516,7 +516,7 @@  discard block
 block discarded – undo
516 516
 	 * @param string $group
517 517
 	 */
518 518
 	public function addingUserToGroup($user, $group) {
519
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user/groups";
519
+		$fullUrl = $this->baseUrl."v{$this->apiVersion}.php/cloud/users/$user/groups";
520 520
 		$client = new Client();
521 521
 		$options = [];
522 522
 		if ($this->currentUser === 'admin') {
@@ -535,7 +535,7 @@  discard block
 block discarded – undo
535 535
 
536 536
 
537 537
 	public function groupExists($group) {
538
-		$fullUrl = $this->baseUrl . "v2.php/cloud/groups/$group";
538
+		$fullUrl = $this->baseUrl."v2.php/cloud/groups/$group";
539 539
 		$client = new Client();
540 540
 		$options = [];
541 541
 		$options['auth'] = $this->adminUser;
@@ -593,7 +593,7 @@  discard block
 block discarded – undo
593 593
 	 * @param string $group
594 594
 	 */
595 595
 	public function userIsSubadminOfGroup($user, $group) {
596
-		$fullUrl = $this->baseUrl . "v2.php/cloud/groups/$group/subadmins";
596
+		$fullUrl = $this->baseUrl."v2.php/cloud/groups/$group/subadmins";
597 597
 		$client = new Client();
598 598
 		$options = [];
599 599
 		if ($this->currentUser === 'admin') {
@@ -616,7 +616,7 @@  discard block
 block discarded – undo
616 616
 	 * @param string $group
617 617
 	 */
618 618
 	public function assureUserIsSubadminOfGroup($user, $group) {
619
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user/subadmins";
619
+		$fullUrl = $this->baseUrl."v{$this->apiVersion}.php/cloud/users/$user/subadmins";
620 620
 		$client = new Client();
621 621
 		$options = [];
622 622
 		if ($this->currentUser === 'admin') {
@@ -638,7 +638,7 @@  discard block
 block discarded – undo
638 638
 	 * @param string $group
639 639
 	 */
640 640
 	public function userIsNotSubadminOfGroup($user, $group) {
641
-		$fullUrl = $this->baseUrl . "v2.php/cloud/groups/$group/subadmins";
641
+		$fullUrl = $this->baseUrl."v2.php/cloud/groups/$group/subadmins";
642 642
 		$client = new Client();
643 643
 		$options = [];
644 644
 		if ($this->currentUser === 'admin') {
@@ -808,7 +808,7 @@  discard block
 block discarded – undo
808 808
 	 * @param string $app
809 809
 	 */
810 810
 	public function appIsDisabled($app) {
811
-		$fullUrl = $this->baseUrl . 'v2.php/cloud/apps?filter=disabled';
811
+		$fullUrl = $this->baseUrl.'v2.php/cloud/apps?filter=disabled';
812 812
 		$client = new Client();
813 813
 		$options = [];
814 814
 		if ($this->currentUser === 'admin') {
@@ -829,7 +829,7 @@  discard block
 block discarded – undo
829 829
 	 * @param string $app
830 830
 	 */
831 831
 	public function appIsEnabled($app) {
832
-		$fullUrl = $this->baseUrl . 'v2.php/cloud/apps?filter=enabled';
832
+		$fullUrl = $this->baseUrl.'v2.php/cloud/apps?filter=enabled';
833 833
 		$client = new Client();
834 834
 		$options = [];
835 835
 		if ($this->currentUser === 'admin') {
@@ -853,7 +853,7 @@  discard block
 block discarded – undo
853 853
 	 * @param string $app
854 854
 	 */
855 855
 	public function appIsNotEnabled($app) {
856
-		$fullUrl = $this->baseUrl . 'v2.php/cloud/apps?filter=enabled';
856
+		$fullUrl = $this->baseUrl.'v2.php/cloud/apps?filter=enabled';
857 857
 		$client = new Client();
858 858
 		$options = [];
859 859
 		if ($this->currentUser === 'admin') {
@@ -874,7 +874,7 @@  discard block
 block discarded – undo
874 874
 	 * @param string $user
875 875
 	 */
876 876
 	public function userIsDisabled($user) {
877
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
877
+		$fullUrl = $this->baseUrl."v{$this->apiVersion}.php/cloud/users/$user";
878 878
 		$client = new Client();
879 879
 		$options = [];
880 880
 		if ($this->currentUser === 'admin') {
@@ -894,7 +894,7 @@  discard block
 block discarded – undo
894 894
 	 * @param string $user
895 895
 	 */
896 896
 	public function userIsEnabled($user) {
897
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
897
+		$fullUrl = $this->baseUrl."v{$this->apiVersion}.php/cloud/users/$user";
898 898
 		$client = new Client();
899 899
 		$options = [];
900 900
 		if ($this->currentUser === 'admin') {
@@ -921,7 +921,7 @@  discard block
 block discarded – undo
921 921
 		]);
922 922
 
923 923
 		// method used from BasicStructure trait
924
-		$this->sendingToWith('PUT', '/cloud/users/' . $user, $body);
924
+		$this->sendingToWith('PUT', '/cloud/users/'.$user, $body);
925 925
 	}
926 926
 
927 927
 	/**
@@ -938,7 +938,7 @@  discard block
 block discarded – undo
938 938
 	 * @param string $user
939 939
 	 */
940 940
 	public function getUserHome($user) {
941
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
941
+		$fullUrl = $this->baseUrl."v{$this->apiVersion}.php/cloud/users/$user";
942 942
 		$client = new Client();
943 943
 		$options = [];
944 944
 		$options['auth'] = $this->adminUser;
@@ -984,7 +984,7 @@  discard block
 block discarded – undo
984 984
 	 * @Then /^user "([^"]*)" has not$/
985 985
 	 */
986 986
 	public function userHasNotSetting($user, TableNode $settings) {
987
-		$fullUrl = $this->baseUrl . "v{$this->apiVersion}.php/cloud/users/$user";
987
+		$fullUrl = $this->baseUrl."v{$this->apiVersion}.php/cloud/users/$user";
988 988
 		$client = new Client();
989 989
 		$options = [];
990 990
 		if ($this->currentUser === 'admin') {
Please login to merge, or discard this patch.
core/Controller/ProfileApiController.php 1 patch
Indentation   +107 added lines, -107 removed lines patch added patch discarded remove patch
@@ -35,111 +35,111 @@
 block discarded – undo
35 35
  * @psalm-import-type CoreProfileData from ResponseDefinitions
36 36
  */
37 37
 class ProfileApiController extends OCSController {
38
-	public function __construct(
39
-		IRequest $request,
40
-		private IConfig $config,
41
-		private ITimeFactory $timeFactory,
42
-		private ProfileConfigMapper $configMapper,
43
-		private ProfileManager $profileManager,
44
-		private IUserManager $userManager,
45
-		private IUserSession $userSession,
46
-		private IManager $shareManager,
47
-	) {
48
-		parent::__construct('core', $request);
49
-	}
50
-
51
-	/**
52
-	 * @NoSubAdminRequired
53
-	 *
54
-	 * Update the visibility of a parameter
55
-	 *
56
-	 * @param string $targetUserId ID of the user
57
-	 * @param string $paramId ID of the parameter
58
-	 * @param string $visibility New visibility
59
-	 * @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
60
-	 * @throws OCSBadRequestException Updating visibility is not possible
61
-	 * @throws OCSForbiddenException Not allowed to edit other users visibility
62
-	 * @throws OCSNotFoundException Account not found
63
-	 *
64
-	 * 200: Visibility updated successfully
65
-	 */
66
-	#[NoAdminRequired]
67
-	#[PasswordConfirmationRequired]
68
-	#[UserRateLimit(limit: 40, period: 600)]
69
-	#[ApiRoute(verb: 'PUT', url: '/{targetUserId}', root: '/profile')]
70
-	public function setVisibility(string $targetUserId, string $paramId, string $visibility): DataResponse {
71
-		$requestingUser = $this->userSession->getUser();
72
-		if ($requestingUser->getUID() !== $targetUserId) {
73
-			throw new OCSForbiddenException('People can only edit their own visibility settings');
74
-		}
75
-
76
-		$targetUser = $this->userManager->get($targetUserId);
77
-		if (!$targetUser instanceof IUser) {
78
-			throw new OCSNotFoundException('Account does not exist');
79
-		}
80
-
81
-		// Ensure that a profile config is created in the database
82
-		$this->profileManager->getProfileConfig($targetUser, $targetUser);
83
-		$config = $this->configMapper->get($targetUserId);
84
-
85
-		if (!in_array($paramId, array_keys($config->getVisibilityMap()), true)) {
86
-			throw new OCSBadRequestException('Account does not have a profile parameter with ID: ' . $paramId);
87
-		}
88
-
89
-		$config->setVisibility($paramId, $visibility);
90
-		$this->configMapper->update($config);
91
-
92
-		return new DataResponse();
93
-	}
94
-
95
-	/**
96
-	 * Get profile fields for another user
97
-	 *
98
-	 * @param string $targetUserId ID of the user
99
-	 * @return DataResponse<Http::STATUS_OK, CoreProfileData, array{}>|DataResponse<Http::STATUS_BAD_REQUEST|Http::STATUS_NOT_FOUND, null, array{}>
100
-	 *
101
-	 * 200: Profile data returned successfully
102
-	 * 400: Profile is disabled
103
-	 * 404: Account not found or disabled
104
-	 */
105
-	#[NoAdminRequired]
106
-	#[ApiRoute(verb: 'GET', url: '/{targetUserId}', root: '/profile')]
107
-	#[BruteForceProtection(action: 'user')]
108
-	#[UserRateLimit(limit: 30, period: 120)]
109
-	public function getProfileFields(string $targetUserId): DataResponse {
110
-		$targetUser = $this->userManager->get($targetUserId);
111
-		if (!$targetUser instanceof IUser) {
112
-			$response = new DataResponse(null, Http::STATUS_NOT_FOUND);
113
-			$response->throttle();
114
-			return $response;
115
-		}
116
-		if (!$targetUser->isEnabled()) {
117
-			return new DataResponse(null, Http::STATUS_NOT_FOUND);
118
-		}
119
-
120
-		if (!$this->profileManager->isProfileEnabled($targetUser)) {
121
-			return new DataResponse(null, Http::STATUS_BAD_REQUEST);
122
-		}
123
-
124
-		$requestingUser = $this->userSession->getUser();
125
-		if ($targetUser !== $requestingUser) {
126
-			if (!$this->shareManager->currentUserCanEnumerateTargetUser($requestingUser, $targetUser)) {
127
-				return new DataResponse(null, Http::STATUS_NOT_FOUND);
128
-			}
129
-		}
130
-
131
-		$profileFields = $this->profileManager->getProfileFields($targetUser, $requestingUser);
132
-
133
-		// Extend the profile information with timezone of the user
134
-		$timezoneStringTarget = $this->config->getUserValue($targetUser->getUID(), 'core', 'timezone') ?: $this->config->getSystemValueString('default_timezone', 'UTC');
135
-		try {
136
-			$timezoneTarget = new \DateTimeZone($timezoneStringTarget);
137
-		} catch (\Throwable) {
138
-			$timezoneTarget = new \DateTimeZone('UTC');
139
-		}
140
-		$profileFields['timezone'] = $timezoneTarget->getName(); // E.g. Europe/Berlin
141
-		$profileFields['timezoneOffset'] = $timezoneTarget->getOffset($this->timeFactory->now()); // In seconds E.g. 7200
142
-
143
-		return new DataResponse($profileFields);
144
-	}
38
+    public function __construct(
39
+        IRequest $request,
40
+        private IConfig $config,
41
+        private ITimeFactory $timeFactory,
42
+        private ProfileConfigMapper $configMapper,
43
+        private ProfileManager $profileManager,
44
+        private IUserManager $userManager,
45
+        private IUserSession $userSession,
46
+        private IManager $shareManager,
47
+    ) {
48
+        parent::__construct('core', $request);
49
+    }
50
+
51
+    /**
52
+     * @NoSubAdminRequired
53
+     *
54
+     * Update the visibility of a parameter
55
+     *
56
+     * @param string $targetUserId ID of the user
57
+     * @param string $paramId ID of the parameter
58
+     * @param string $visibility New visibility
59
+     * @return DataResponse<Http::STATUS_OK, list<empty>, array{}>
60
+     * @throws OCSBadRequestException Updating visibility is not possible
61
+     * @throws OCSForbiddenException Not allowed to edit other users visibility
62
+     * @throws OCSNotFoundException Account not found
63
+     *
64
+     * 200: Visibility updated successfully
65
+     */
66
+    #[NoAdminRequired]
67
+    #[PasswordConfirmationRequired]
68
+    #[UserRateLimit(limit: 40, period: 600)]
69
+    #[ApiRoute(verb: 'PUT', url: '/{targetUserId}', root: '/profile')]
70
+    public function setVisibility(string $targetUserId, string $paramId, string $visibility): DataResponse {
71
+        $requestingUser = $this->userSession->getUser();
72
+        if ($requestingUser->getUID() !== $targetUserId) {
73
+            throw new OCSForbiddenException('People can only edit their own visibility settings');
74
+        }
75
+
76
+        $targetUser = $this->userManager->get($targetUserId);
77
+        if (!$targetUser instanceof IUser) {
78
+            throw new OCSNotFoundException('Account does not exist');
79
+        }
80
+
81
+        // Ensure that a profile config is created in the database
82
+        $this->profileManager->getProfileConfig($targetUser, $targetUser);
83
+        $config = $this->configMapper->get($targetUserId);
84
+
85
+        if (!in_array($paramId, array_keys($config->getVisibilityMap()), true)) {
86
+            throw new OCSBadRequestException('Account does not have a profile parameter with ID: ' . $paramId);
87
+        }
88
+
89
+        $config->setVisibility($paramId, $visibility);
90
+        $this->configMapper->update($config);
91
+
92
+        return new DataResponse();
93
+    }
94
+
95
+    /**
96
+     * Get profile fields for another user
97
+     *
98
+     * @param string $targetUserId ID of the user
99
+     * @return DataResponse<Http::STATUS_OK, CoreProfileData, array{}>|DataResponse<Http::STATUS_BAD_REQUEST|Http::STATUS_NOT_FOUND, null, array{}>
100
+     *
101
+     * 200: Profile data returned successfully
102
+     * 400: Profile is disabled
103
+     * 404: Account not found or disabled
104
+     */
105
+    #[NoAdminRequired]
106
+    #[ApiRoute(verb: 'GET', url: '/{targetUserId}', root: '/profile')]
107
+    #[BruteForceProtection(action: 'user')]
108
+    #[UserRateLimit(limit: 30, period: 120)]
109
+    public function getProfileFields(string $targetUserId): DataResponse {
110
+        $targetUser = $this->userManager->get($targetUserId);
111
+        if (!$targetUser instanceof IUser) {
112
+            $response = new DataResponse(null, Http::STATUS_NOT_FOUND);
113
+            $response->throttle();
114
+            return $response;
115
+        }
116
+        if (!$targetUser->isEnabled()) {
117
+            return new DataResponse(null, Http::STATUS_NOT_FOUND);
118
+        }
119
+
120
+        if (!$this->profileManager->isProfileEnabled($targetUser)) {
121
+            return new DataResponse(null, Http::STATUS_BAD_REQUEST);
122
+        }
123
+
124
+        $requestingUser = $this->userSession->getUser();
125
+        if ($targetUser !== $requestingUser) {
126
+            if (!$this->shareManager->currentUserCanEnumerateTargetUser($requestingUser, $targetUser)) {
127
+                return new DataResponse(null, Http::STATUS_NOT_FOUND);
128
+            }
129
+        }
130
+
131
+        $profileFields = $this->profileManager->getProfileFields($targetUser, $requestingUser);
132
+
133
+        // Extend the profile information with timezone of the user
134
+        $timezoneStringTarget = $this->config->getUserValue($targetUser->getUID(), 'core', 'timezone') ?: $this->config->getSystemValueString('default_timezone', 'UTC');
135
+        try {
136
+            $timezoneTarget = new \DateTimeZone($timezoneStringTarget);
137
+        } catch (\Throwable) {
138
+            $timezoneTarget = new \DateTimeZone('UTC');
139
+        }
140
+        $profileFields['timezone'] = $timezoneTarget->getName(); // E.g. Europe/Berlin
141
+        $profileFields['timezoneOffset'] = $timezoneTarget->getOffset($this->timeFactory->now()); // In seconds E.g. 7200
142
+
143
+        return new DataResponse($profileFields);
144
+    }
145 145
 }
Please login to merge, or discard this patch.