Completed
Push — master ( 284ca3...2651df )
by Joas
20:49 queued 11s
created
apps/settings/lib/Middleware/SubadminMiddleware.php 1 patch
Indentation   +47 added lines, -47 removed lines patch added patch discarded remove patch
@@ -38,55 +38,55 @@
 block discarded – undo
38 38
  * To bypass use the `@NoSubAdminRequired` annotation
39 39
  */
40 40
 class SubadminMiddleware extends Middleware {
41
-	/** @var bool */
42
-	protected $isSubAdmin;
43
-	/** @var ControllerMethodReflector */
44
-	protected $reflector;
45
-	/** @var IL10N */
46
-	private $l10n;
41
+    /** @var bool */
42
+    protected $isSubAdmin;
43
+    /** @var ControllerMethodReflector */
44
+    protected $reflector;
45
+    /** @var IL10N */
46
+    private $l10n;
47 47
 
48
-	/**
49
-	 * @param ControllerMethodReflector $reflector
50
-	 * @param bool $isSubAdmin
51
-	 * @param IL10N $l10n
52
-	 */
53
-	public function __construct(ControllerMethodReflector $reflector,
54
-								$isSubAdmin,
55
-								IL10N $l10n) {
56
-		$this->reflector = $reflector;
57
-		$this->isSubAdmin = $isSubAdmin;
58
-		$this->l10n = $l10n;
59
-	}
48
+    /**
49
+     * @param ControllerMethodReflector $reflector
50
+     * @param bool $isSubAdmin
51
+     * @param IL10N $l10n
52
+     */
53
+    public function __construct(ControllerMethodReflector $reflector,
54
+                                $isSubAdmin,
55
+                                IL10N $l10n) {
56
+        $this->reflector = $reflector;
57
+        $this->isSubAdmin = $isSubAdmin;
58
+        $this->l10n = $l10n;
59
+    }
60 60
 
61
-	/**
62
-	 * Check if sharing is enabled before the controllers is executed
63
-	 * @param Controller $controller
64
-	 * @param string $methodName
65
-	 * @throws \Exception
66
-	 */
67
-	public function beforeController($controller, $methodName) {
68
-		if (!$this->reflector->hasAnnotation('NoSubAdminRequired')) {
69
-			if (!$this->isSubAdmin) {
70
-				throw new NotAdminException($this->l10n->t('Logged in user must be a subadmin'));
71
-			}
72
-		}
73
-	}
61
+    /**
62
+     * Check if sharing is enabled before the controllers is executed
63
+     * @param Controller $controller
64
+     * @param string $methodName
65
+     * @throws \Exception
66
+     */
67
+    public function beforeController($controller, $methodName) {
68
+        if (!$this->reflector->hasAnnotation('NoSubAdminRequired')) {
69
+            if (!$this->isSubAdmin) {
70
+                throw new NotAdminException($this->l10n->t('Logged in user must be a subadmin'));
71
+            }
72
+        }
73
+    }
74 74
 
75
-	/**
76
-	 * Return 403 page in case of an exception
77
-	 * @param Controller $controller
78
-	 * @param string $methodName
79
-	 * @param \Exception $exception
80
-	 * @return TemplateResponse
81
-	 * @throws \Exception
82
-	 */
83
-	public function afterException($controller, $methodName, \Exception $exception) {
84
-		if ($exception instanceof NotAdminException) {
85
-			$response = new TemplateResponse('core', '403', [], 'guest');
86
-			$response->setStatus(Http::STATUS_FORBIDDEN);
87
-			return $response;
88
-		}
75
+    /**
76
+     * Return 403 page in case of an exception
77
+     * @param Controller $controller
78
+     * @param string $methodName
79
+     * @param \Exception $exception
80
+     * @return TemplateResponse
81
+     * @throws \Exception
82
+     */
83
+    public function afterException($controller, $methodName, \Exception $exception) {
84
+        if ($exception instanceof NotAdminException) {
85
+            $response = new TemplateResponse('core', '403', [], 'guest');
86
+            $response->setStatus(Http::STATUS_FORBIDDEN);
87
+            return $response;
88
+        }
89 89
 
90
-		throw $exception;
91
-	}
90
+        throw $exception;
91
+    }
92 92
 }
Please login to merge, or discard this patch.
apps/settings/lib/Controller/ChangePasswordController.php 1 patch
Indentation   +210 added lines, -210 removed lines patch added patch discarded remove patch
@@ -47,232 +47,232 @@
 block discarded – undo
47 47
 
48 48
 class ChangePasswordController extends Controller {
49 49
 
50
-	/** @var string */
51
-	private $userId;
50
+    /** @var string */
51
+    private $userId;
52 52
 
53
-	/** @var IUserManager */
54
-	private $userManager;
53
+    /** @var IUserManager */
54
+    private $userManager;
55 55
 
56
-	/** @var IL10N */
57
-	private $l;
56
+    /** @var IL10N */
57
+    private $l;
58 58
 
59
-	/** @var IGroupManager */
60
-	private $groupManager;
59
+    /** @var IGroupManager */
60
+    private $groupManager;
61 61
 
62
-	/** @var Session */
63
-	private $userSession;
62
+    /** @var Session */
63
+    private $userSession;
64 64
 
65
-	/** @var IAppManager */
66
-	private $appManager;
65
+    /** @var IAppManager */
66
+    private $appManager;
67 67
 
68
-	public function __construct(string $appName,
69
-								IRequest $request,
70
-								string $userId,
71
-								IUserManager $userManager,
72
-								IUserSession $userSession,
73
-								IGroupManager $groupManager,
74
-								IAppManager $appManager,
75
-								IL10N $l) {
76
-		parent::__construct($appName, $request);
68
+    public function __construct(string $appName,
69
+                                IRequest $request,
70
+                                string $userId,
71
+                                IUserManager $userManager,
72
+                                IUserSession $userSession,
73
+                                IGroupManager $groupManager,
74
+                                IAppManager $appManager,
75
+                                IL10N $l) {
76
+        parent::__construct($appName, $request);
77 77
 
78
-		$this->userId = $userId;
79
-		$this->userManager = $userManager;
80
-		$this->userSession = $userSession;
81
-		$this->groupManager = $groupManager;
82
-		$this->appManager = $appManager;
83
-		$this->l = $l;
84
-	}
78
+        $this->userId = $userId;
79
+        $this->userManager = $userManager;
80
+        $this->userSession = $userSession;
81
+        $this->groupManager = $groupManager;
82
+        $this->appManager = $appManager;
83
+        $this->l = $l;
84
+    }
85 85
 
86
-	/**
87
-	 * @NoAdminRequired
88
-	 * @NoSubAdminRequired
89
-	 * @BruteForceProtection(action=changePersonalPassword)
90
-	 */
91
-	public function changePersonalPassword(string $oldpassword = '', string $newpassword = null): JSONResponse {
92
-		$loginName = $this->userSession->getLoginName();
93
-		/** @var IUser $user */
94
-		$user = $this->userManager->checkPassword($loginName, $oldpassword);
95
-		if ($user === false) {
96
-			$response = new JSONResponse([
97
-				'status' => 'error',
98
-				'data' => [
99
-					'message' => $this->l->t('Wrong password'),
100
-				],
101
-			]);
102
-			$response->throttle();
103
-			return $response;
104
-		}
86
+    /**
87
+     * @NoAdminRequired
88
+     * @NoSubAdminRequired
89
+     * @BruteForceProtection(action=changePersonalPassword)
90
+     */
91
+    public function changePersonalPassword(string $oldpassword = '', string $newpassword = null): JSONResponse {
92
+        $loginName = $this->userSession->getLoginName();
93
+        /** @var IUser $user */
94
+        $user = $this->userManager->checkPassword($loginName, $oldpassword);
95
+        if ($user === false) {
96
+            $response = new JSONResponse([
97
+                'status' => 'error',
98
+                'data' => [
99
+                    'message' => $this->l->t('Wrong password'),
100
+                ],
101
+            ]);
102
+            $response->throttle();
103
+            return $response;
104
+        }
105 105
 
106
-		try {
107
-			if ($newpassword === null || $user->setPassword($newpassword) === false) {
108
-				return new JSONResponse([
109
-					'status' => 'error'
110
-				]);
111
-			}
112
-			// password policy app throws exception
113
-		} catch (HintException $e) {
114
-			return new JSONResponse([
115
-				'status' => 'error',
116
-				'data' => [
117
-					'message' => $e->getHint(),
118
-				],
119
-			]);
120
-		}
106
+        try {
107
+            if ($newpassword === null || $user->setPassword($newpassword) === false) {
108
+                return new JSONResponse([
109
+                    'status' => 'error'
110
+                ]);
111
+            }
112
+            // password policy app throws exception
113
+        } catch (HintException $e) {
114
+            return new JSONResponse([
115
+                'status' => 'error',
116
+                'data' => [
117
+                    'message' => $e->getHint(),
118
+                ],
119
+            ]);
120
+        }
121 121
 
122
-		$this->userSession->updateSessionTokenPassword($newpassword);
122
+        $this->userSession->updateSessionTokenPassword($newpassword);
123 123
 
124
-		return new JSONResponse([
125
-			'status' => 'success',
126
-			'data' => [
127
-				'message' => $this->l->t('Saved'),
128
-			],
129
-		]);
130
-	}
124
+        return new JSONResponse([
125
+            'status' => 'success',
126
+            'data' => [
127
+                'message' => $this->l->t('Saved'),
128
+            ],
129
+        ]);
130
+    }
131 131
 
132
-	/**
133
-	 * @NoAdminRequired
134
-	 * @PasswordConfirmationRequired
135
-	 */
136
-	public function changeUserPassword(string $username = null, string $password = null, string $recoveryPassword = null): JSONResponse {
137
-		if ($username === null) {
138
-			return new JSONResponse([
139
-				'status' => 'error',
140
-				'data' => [
141
-					'message' => $this->l->t('No user supplied'),
142
-				],
143
-			]);
144
-		}
132
+    /**
133
+     * @NoAdminRequired
134
+     * @PasswordConfirmationRequired
135
+     */
136
+    public function changeUserPassword(string $username = null, string $password = null, string $recoveryPassword = null): JSONResponse {
137
+        if ($username === null) {
138
+            return new JSONResponse([
139
+                'status' => 'error',
140
+                'data' => [
141
+                    'message' => $this->l->t('No user supplied'),
142
+                ],
143
+            ]);
144
+        }
145 145
 
146
-		if ($password === null) {
147
-			return new JSONResponse([
148
-				'status' => 'error',
149
-				'data' => [
150
-					'message' => $this->l->t('Unable to change password'),
151
-				],
152
-			]);
153
-		}
146
+        if ($password === null) {
147
+            return new JSONResponse([
148
+                'status' => 'error',
149
+                'data' => [
150
+                    'message' => $this->l->t('Unable to change password'),
151
+                ],
152
+            ]);
153
+        }
154 154
 
155
-		$currentUser = $this->userSession->getUser();
156
-		$targetUser = $this->userManager->get($username);
157
-		if ($currentUser === null || $targetUser === null ||
158
-			!($this->groupManager->isAdmin($this->userId) ||
159
-			 $this->groupManager->getSubAdmin()->isUserAccessible($currentUser, $targetUser))
160
-		) {
161
-			return new JSONResponse([
162
-				'status' => 'error',
163
-				'data' => [
164
-					'message' => $this->l->t('Authentication error'),
165
-				],
166
-			]);
167
-		}
155
+        $currentUser = $this->userSession->getUser();
156
+        $targetUser = $this->userManager->get($username);
157
+        if ($currentUser === null || $targetUser === null ||
158
+            !($this->groupManager->isAdmin($this->userId) ||
159
+             $this->groupManager->getSubAdmin()->isUserAccessible($currentUser, $targetUser))
160
+        ) {
161
+            return new JSONResponse([
162
+                'status' => 'error',
163
+                'data' => [
164
+                    'message' => $this->l->t('Authentication error'),
165
+                ],
166
+            ]);
167
+        }
168 168
 
169
-		if ($this->appManager->isEnabledForUser('encryption')) {
170
-			//handle the recovery case
171
-			$crypt = new \OCA\Encryption\Crypto\Crypt(
172
-				\OC::$server->getLogger(),
173
-				\OC::$server->getUserSession(),
174
-				\OC::$server->getConfig(),
175
-				\OC::$server->getL10N('encryption'));
176
-			$keyStorage = \OC::$server->getEncryptionKeyStorage();
177
-			$util = new \OCA\Encryption\Util(
178
-				new \OC\Files\View(),
179
-				$crypt,
180
-				\OC::$server->getLogger(),
181
-				\OC::$server->getUserSession(),
182
-				\OC::$server->getConfig(),
183
-				\OC::$server->getUserManager());
184
-			$keyManager = new \OCA\Encryption\KeyManager(
185
-				$keyStorage,
186
-				$crypt,
187
-				\OC::$server->getConfig(),
188
-				\OC::$server->getUserSession(),
189
-				new \OCA\Encryption\Session(\OC::$server->getSession()),
190
-				\OC::$server->getLogger(),
191
-				$util);
192
-			$recovery = new \OCA\Encryption\Recovery(
193
-				\OC::$server->getUserSession(),
194
-				$crypt,
195
-				$keyManager,
196
-				\OC::$server->getConfig(),
197
-				\OC::$server->getEncryptionFilesHelper(),
198
-				new \OC\Files\View());
199
-			$recoveryAdminEnabled = $recovery->isRecoveryKeyEnabled();
169
+        if ($this->appManager->isEnabledForUser('encryption')) {
170
+            //handle the recovery case
171
+            $crypt = new \OCA\Encryption\Crypto\Crypt(
172
+                \OC::$server->getLogger(),
173
+                \OC::$server->getUserSession(),
174
+                \OC::$server->getConfig(),
175
+                \OC::$server->getL10N('encryption'));
176
+            $keyStorage = \OC::$server->getEncryptionKeyStorage();
177
+            $util = new \OCA\Encryption\Util(
178
+                new \OC\Files\View(),
179
+                $crypt,
180
+                \OC::$server->getLogger(),
181
+                \OC::$server->getUserSession(),
182
+                \OC::$server->getConfig(),
183
+                \OC::$server->getUserManager());
184
+            $keyManager = new \OCA\Encryption\KeyManager(
185
+                $keyStorage,
186
+                $crypt,
187
+                \OC::$server->getConfig(),
188
+                \OC::$server->getUserSession(),
189
+                new \OCA\Encryption\Session(\OC::$server->getSession()),
190
+                \OC::$server->getLogger(),
191
+                $util);
192
+            $recovery = new \OCA\Encryption\Recovery(
193
+                \OC::$server->getUserSession(),
194
+                $crypt,
195
+                $keyManager,
196
+                \OC::$server->getConfig(),
197
+                \OC::$server->getEncryptionFilesHelper(),
198
+                new \OC\Files\View());
199
+            $recoveryAdminEnabled = $recovery->isRecoveryKeyEnabled();
200 200
 
201
-			$validRecoveryPassword = false;
202
-			$recoveryEnabledForUser = false;
203
-			if ($recoveryAdminEnabled) {
204
-				$validRecoveryPassword = $keyManager->checkRecoveryPassword($recoveryPassword);
205
-				$recoveryEnabledForUser = $recovery->isRecoveryEnabledForUser($username);
206
-			}
201
+            $validRecoveryPassword = false;
202
+            $recoveryEnabledForUser = false;
203
+            if ($recoveryAdminEnabled) {
204
+                $validRecoveryPassword = $keyManager->checkRecoveryPassword($recoveryPassword);
205
+                $recoveryEnabledForUser = $recovery->isRecoveryEnabledForUser($username);
206
+            }
207 207
 
208
-			if ($recoveryEnabledForUser && $recoveryPassword === '') {
209
-				return new JSONResponse([
210
-					'status' => 'error',
211
-					'data' => [
212
-						'message' => $this->l->t('Please provide an admin recovery password; otherwise, all user data will be lost.'),
213
-					]
214
-				]);
215
-			} elseif ($recoveryEnabledForUser && ! $validRecoveryPassword) {
216
-				return new JSONResponse([
217
-					'status' => 'error',
218
-					'data' => [
219
-						'message' => $this->l->t('Wrong admin recovery password. Please check the password and try again.'),
220
-					]
221
-				]);
222
-			} else { // now we know that everything is fine regarding the recovery password, let's try to change the password
223
-				try {
224
-					$result = $targetUser->setPassword($password, $recoveryPassword);
225
-					// password policy app throws exception
226
-				} catch (HintException $e) {
227
-					return new JSONResponse([
228
-						'status' => 'error',
229
-						'data' => [
230
-							'message' => $e->getHint(),
231
-						],
232
-					]);
233
-				}
234
-				if (!$result && $recoveryEnabledForUser) {
235
-					return new JSONResponse([
236
-						'status' => 'error',
237
-						'data' => [
238
-							'message' => $this->l->t('Backend doesn\'t support password change, but the user\'s encryption key was updated.'),
239
-						]
240
-					]);
241
-				} elseif (!$result && !$recoveryEnabledForUser) {
242
-					return new JSONResponse([
243
-						'status' => 'error',
244
-						'data' => [
245
-							'message' => $this->l->t('Unable to change password'),
246
-						]
247
-					]);
248
-				}
249
-			}
250
-		} else {
251
-			try {
252
-				if ($targetUser->setPassword($password) === false) {
253
-					return new JSONResponse([
254
-						'status' => 'error',
255
-						'data' => [
256
-							'message' => $this->l->t('Unable to change password'),
257
-						],
258
-					]);
259
-				}
260
-				// password policy app throws exception
261
-			} catch (HintException $e) {
262
-				return new JSONResponse([
263
-					'status' => 'error',
264
-					'data' => [
265
-						'message' => $e->getHint(),
266
-					],
267
-				]);
268
-			}
269
-		}
208
+            if ($recoveryEnabledForUser && $recoveryPassword === '') {
209
+                return new JSONResponse([
210
+                    'status' => 'error',
211
+                    'data' => [
212
+                        'message' => $this->l->t('Please provide an admin recovery password; otherwise, all user data will be lost.'),
213
+                    ]
214
+                ]);
215
+            } elseif ($recoveryEnabledForUser && ! $validRecoveryPassword) {
216
+                return new JSONResponse([
217
+                    'status' => 'error',
218
+                    'data' => [
219
+                        'message' => $this->l->t('Wrong admin recovery password. Please check the password and try again.'),
220
+                    ]
221
+                ]);
222
+            } else { // now we know that everything is fine regarding the recovery password, let's try to change the password
223
+                try {
224
+                    $result = $targetUser->setPassword($password, $recoveryPassword);
225
+                    // password policy app throws exception
226
+                } catch (HintException $e) {
227
+                    return new JSONResponse([
228
+                        'status' => 'error',
229
+                        'data' => [
230
+                            'message' => $e->getHint(),
231
+                        ],
232
+                    ]);
233
+                }
234
+                if (!$result && $recoveryEnabledForUser) {
235
+                    return new JSONResponse([
236
+                        'status' => 'error',
237
+                        'data' => [
238
+                            'message' => $this->l->t('Backend doesn\'t support password change, but the user\'s encryption key was updated.'),
239
+                        ]
240
+                    ]);
241
+                } elseif (!$result && !$recoveryEnabledForUser) {
242
+                    return new JSONResponse([
243
+                        'status' => 'error',
244
+                        'data' => [
245
+                            'message' => $this->l->t('Unable to change password'),
246
+                        ]
247
+                    ]);
248
+                }
249
+            }
250
+        } else {
251
+            try {
252
+                if ($targetUser->setPassword($password) === false) {
253
+                    return new JSONResponse([
254
+                        'status' => 'error',
255
+                        'data' => [
256
+                            'message' => $this->l->t('Unable to change password'),
257
+                        ],
258
+                    ]);
259
+                }
260
+                // password policy app throws exception
261
+            } catch (HintException $e) {
262
+                return new JSONResponse([
263
+                    'status' => 'error',
264
+                    'data' => [
265
+                        'message' => $e->getHint(),
266
+                    ],
267
+                ]);
268
+            }
269
+        }
270 270
 
271
-		return new JSONResponse([
272
-			'status' => 'success',
273
-			'data' => [
274
-				'username' => $username,
275
-			],
276
-		]);
277
-	}
271
+        return new JSONResponse([
272
+            'status' => 'success',
273
+            'data' => [
274
+                'username' => $username,
275
+            ],
276
+        ]);
277
+    }
278 278
 }
Please login to merge, or discard this patch.
apps/settings/lib/Controller/PersonalSettingsController.php 1 patch
Indentation   +65 added lines, -65 removed lines patch added patch discarded remove patch
@@ -36,77 +36,77 @@
 block discarded – undo
36 36
 use OCP\Template;
37 37
 
38 38
 class PersonalSettingsController extends Controller {
39
-	use CommonSettingsTrait;
39
+    use CommonSettingsTrait;
40 40
 
41
-	public function __construct(
42
-		$appName,
43
-		IRequest $request,
44
-		INavigationManager $navigationManager,
45
-		ISettingsManager $settingsManager,
46
-		IUserSession $userSession,
47
-		IGroupManager $groupManager,
48
-		ISubAdmin $subAdmin
49
-	) {
50
-		parent::__construct($appName, $request);
51
-		$this->navigationManager = $navigationManager;
52
-		$this->settingsManager = $settingsManager;
53
-		$this->userSession = $userSession;
54
-		$this->subAdmin = $subAdmin;
55
-		$this->groupManager = $groupManager;
56
-	}
41
+    public function __construct(
42
+        $appName,
43
+        IRequest $request,
44
+        INavigationManager $navigationManager,
45
+        ISettingsManager $settingsManager,
46
+        IUserSession $userSession,
47
+        IGroupManager $groupManager,
48
+        ISubAdmin $subAdmin
49
+    ) {
50
+        parent::__construct($appName, $request);
51
+        $this->navigationManager = $navigationManager;
52
+        $this->settingsManager = $settingsManager;
53
+        $this->userSession = $userSession;
54
+        $this->subAdmin = $subAdmin;
55
+        $this->groupManager = $groupManager;
56
+    }
57 57
 
58
-	/**
59
-	 * @param string $section
60
-	 * @return TemplateResponse
61
-	 *
62
-	 * @NoCSRFRequired
63
-	 * @NoAdminRequired
64
-	 * @NoSubAdminRequired
65
-	 */
66
-	public function index($section) {
67
-		return $this->getIndexResponse('personal', $section);
68
-	}
58
+    /**
59
+     * @param string $section
60
+     * @return TemplateResponse
61
+     *
62
+     * @NoCSRFRequired
63
+     * @NoAdminRequired
64
+     * @NoSubAdminRequired
65
+     */
66
+    public function index($section) {
67
+        return $this->getIndexResponse('personal', $section);
68
+    }
69 69
 
70
-	/**
71
-	 * @param string $section
72
-	 * @return array
73
-	 */
74
-	protected function getSettings($section) {
75
-		$settings = $this->settingsManager->getPersonalSettings($section);
76
-		$formatted = $this->formatSettings($settings);
77
-		if ($section === 'additional') {
78
-			$formatted['content'] .= $this->getLegacyForms();
79
-		}
80
-		return $formatted;
81
-	}
70
+    /**
71
+     * @param string $section
72
+     * @return array
73
+     */
74
+    protected function getSettings($section) {
75
+        $settings = $this->settingsManager->getPersonalSettings($section);
76
+        $formatted = $this->formatSettings($settings);
77
+        if ($section === 'additional') {
78
+            $formatted['content'] .= $this->getLegacyForms();
79
+        }
80
+        return $formatted;
81
+    }
82 82
 
83
-	/**
84
-	 * @return bool|string
85
-	 */
86
-	private function getLegacyForms() {
87
-		$forms = \OC_App::getForms('personal');
83
+    /**
84
+     * @return bool|string
85
+     */
86
+    private function getLegacyForms() {
87
+        $forms = \OC_App::getForms('personal');
88 88
 
89
-		$forms = array_map(function ($form) {
90
-			if (preg_match('%(<h2(?P<class>[^>]*)>.*?</h2>)%i', $form, $regs)) {
91
-				$sectionName = str_replace('<h2' . $regs['class'] . '>', '', $regs[0]);
92
-				$sectionName = str_replace('</h2>', '', $sectionName);
93
-				$anchor = strtolower($sectionName);
94
-				$anchor = str_replace(' ', '-', $anchor);
89
+        $forms = array_map(function ($form) {
90
+            if (preg_match('%(<h2(?P<class>[^>]*)>.*?</h2>)%i', $form, $regs)) {
91
+                $sectionName = str_replace('<h2' . $regs['class'] . '>', '', $regs[0]);
92
+                $sectionName = str_replace('</h2>', '', $sectionName);
93
+                $anchor = strtolower($sectionName);
94
+                $anchor = str_replace(' ', '-', $anchor);
95 95
 
96
-				return [
97
-					'anchor' => $anchor,
98
-					'section-name' => $sectionName,
99
-					'form' => $form
100
-				];
101
-			}
102
-			return [
103
-				'form' => $form
104
-			];
105
-		}, $forms);
96
+                return [
97
+                    'anchor' => $anchor,
98
+                    'section-name' => $sectionName,
99
+                    'form' => $form
100
+                ];
101
+            }
102
+            return [
103
+                'form' => $form
104
+            ];
105
+        }, $forms);
106 106
 
107
-		$out = new Template('settings', 'settings/additional');
108
-		$out->assign('forms', $forms);
107
+        $out = new Template('settings', 'settings/additional');
108
+        $out->assign('forms', $forms);
109 109
 
110
-		return $out->fetchPage();
111
-	}
110
+        return $out->fetchPage();
111
+    }
112 112
 }
Please login to merge, or discard this patch.
apps/settings/lib/Controller/UsersController.php 1 patch
Indentation   +465 added lines, -465 removed lines patch added patch discarded remove patch
@@ -57,469 +57,469 @@
 block discarded – undo
57 57
 use function in_array;
58 58
 
59 59
 class UsersController extends Controller {
60
-	/** @var IUserManager */
61
-	private $userManager;
62
-	/** @var IGroupManager */
63
-	private $groupManager;
64
-	/** @var IUserSession */
65
-	private $userSession;
66
-	/** @var IConfig */
67
-	private $config;
68
-	/** @var bool */
69
-	private $isAdmin;
70
-	/** @var IL10N */
71
-	private $l10n;
72
-	/** @var IMailer */
73
-	private $mailer;
74
-	/** @var IFactory */
75
-	private $l10nFactory;
76
-	/** @var IAppManager */
77
-	private $appManager;
78
-	/** @var AccountManager */
79
-	private $accountManager;
80
-	/** @var Manager */
81
-	private $keyManager;
82
-	/** @var IJobList */
83
-	private $jobList;
84
-	/** @var IManager */
85
-	private $encryptionManager;
86
-
87
-
88
-	public function __construct(string $appName,
89
-								IRequest $request,
90
-								IUserManager $userManager,
91
-								IGroupManager $groupManager,
92
-								IUserSession $userSession,
93
-								IConfig $config,
94
-								bool $isAdmin,
95
-								IL10N $l10n,
96
-								IMailer $mailer,
97
-								IFactory $l10nFactory,
98
-								IAppManager $appManager,
99
-								AccountManager $accountManager,
100
-								Manager $keyManager,
101
-								IJobList $jobList,
102
-								IManager $encryptionManager) {
103
-		parent::__construct($appName, $request);
104
-		$this->userManager = $userManager;
105
-		$this->groupManager = $groupManager;
106
-		$this->userSession = $userSession;
107
-		$this->config = $config;
108
-		$this->isAdmin = $isAdmin;
109
-		$this->l10n = $l10n;
110
-		$this->mailer = $mailer;
111
-		$this->l10nFactory = $l10nFactory;
112
-		$this->appManager = $appManager;
113
-		$this->accountManager = $accountManager;
114
-		$this->keyManager = $keyManager;
115
-		$this->jobList = $jobList;
116
-		$this->encryptionManager = $encryptionManager;
117
-	}
118
-
119
-
120
-	/**
121
-	 * @NoCSRFRequired
122
-	 * @NoAdminRequired
123
-	 *
124
-	 * Display users list template
125
-	 *
126
-	 * @return TemplateResponse
127
-	 */
128
-	public function usersListByGroup() {
129
-		return $this->usersList();
130
-	}
131
-
132
-	/**
133
-	 * @NoCSRFRequired
134
-	 * @NoAdminRequired
135
-	 *
136
-	 * Display users list template
137
-	 *
138
-	 * @return TemplateResponse
139
-	 */
140
-	public function usersList() {
141
-		$user = $this->userSession->getUser();
142
-		$uid = $user->getUID();
143
-
144
-		\OC::$server->getNavigationManager()->setActiveEntry('core_users');
145
-
146
-		/* SORT OPTION: SORT_USERCOUNT or SORT_GROUPNAME */
147
-		$sortGroupsBy = \OC\Group\MetaData::SORT_USERCOUNT;
148
-		$isLDAPUsed = false;
149
-		if ($this->config->getSystemValue('sort_groups_by_name', false)) {
150
-			$sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
151
-		} else {
152
-			if ($this->appManager->isEnabledForUser('user_ldap')) {
153
-				$isLDAPUsed =
154
-					$this->groupManager->isBackendUsed('\OCA\User_LDAP\Group_Proxy');
155
-				if ($isLDAPUsed) {
156
-					// LDAP user count can be slow, so we sort by group name here
157
-					$sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
158
-				}
159
-			}
160
-		}
161
-
162
-		$canChangePassword = $this->canAdminChangeUserPasswords();
163
-
164
-		/* GROUPS */
165
-		$groupsInfo = new \OC\Group\MetaData(
166
-			$uid,
167
-			$this->isAdmin,
168
-			$this->groupManager,
169
-			$this->userSession
170
-		);
171
-
172
-		$groupsInfo->setSorting($sortGroupsBy);
173
-		list($adminGroup, $groups) = $groupsInfo->get();
174
-
175
-		if (!$isLDAPUsed && $this->appManager->isEnabledForUser('user_ldap')) {
176
-			$isLDAPUsed = (bool)array_reduce($this->userManager->getBackends(), function ($ldapFound, $backend) {
177
-				return $ldapFound || $backend instanceof User_Proxy;
178
-			});
179
-		}
180
-
181
-		$disabledUsers = -1;
182
-		$userCount = 0;
183
-
184
-		if (!$isLDAPUsed) {
185
-			if ($this->isAdmin) {
186
-				$disabledUsers = $this->userManager->countDisabledUsers();
187
-				$userCount = array_reduce($this->userManager->countUsers(), function ($v, $w) {
188
-					return $v + (int)$w;
189
-				}, 0);
190
-			} else {
191
-				// User is subadmin !
192
-				// Map group list to names to retrieve the countDisabledUsersOfGroups
193
-				$userGroups = $this->groupManager->getUserGroups($user);
194
-				$groupsNames = [];
195
-
196
-				foreach ($groups as $key => $group) {
197
-					// $userCount += (int)$group['usercount'];
198
-					array_push($groupsNames, $group['name']);
199
-					// we prevent subadmins from looking up themselves
200
-					// so we lower the count of the groups he belongs to
201
-					if (array_key_exists($group['id'], $userGroups)) {
202
-						$groups[$key]['usercount']--;
203
-						$userCount -= 1; // we also lower from one the total count
204
-					}
205
-				};
206
-				$userCount += $this->userManager->countUsersOfGroups($groupsInfo->getGroups());
207
-				$disabledUsers = $this->userManager->countDisabledUsersOfGroups($groupsNames);
208
-			}
209
-
210
-			$userCount -= $disabledUsers;
211
-		}
212
-
213
-		$disabledUsersGroup = [
214
-			'id' => 'disabled',
215
-			'name' => 'Disabled users',
216
-			'usercount' => $disabledUsers
217
-		];
218
-
219
-		/* QUOTAS PRESETS */
220
-		$quotaPreset = $this->parseQuotaPreset($this->config->getAppValue('files', 'quota_preset', '1 GB, 5 GB, 10 GB'));
221
-		$defaultQuota = $this->config->getAppValue('files', 'default_quota', 'none');
222
-
223
-		\OC::$server->getEventDispatcher()->dispatch('OC\Settings\Users::loadAdditionalScripts');
224
-
225
-		/* LANGUAGES */
226
-		$languages = $this->l10nFactory->getLanguages();
227
-
228
-		/* FINAL DATA */
229
-		$serverData = [];
230
-		// groups
231
-		$serverData['groups'] = array_merge_recursive($adminGroup, [$disabledUsersGroup], $groups);
232
-		// Various data
233
-		$serverData['isAdmin'] = $this->isAdmin;
234
-		$serverData['sortGroups'] = $sortGroupsBy;
235
-		$serverData['quotaPreset'] = $quotaPreset;
236
-		$serverData['userCount'] = $userCount;
237
-		$serverData['languages'] = $languages;
238
-		$serverData['defaultLanguage'] = $this->config->getSystemValue('default_language', 'en');
239
-		$serverData['forceLanguage'] = $this->config->getSystemValue('force_language', false);
240
-		// Settings
241
-		$serverData['defaultQuota'] = $defaultQuota;
242
-		$serverData['canChangePassword'] = $canChangePassword;
243
-		$serverData['newUserGenerateUserID'] = $this->config->getAppValue('core', 'newUser.generateUserID', 'no') === 'yes';
244
-		$serverData['newUserRequireEmail'] = $this->config->getAppValue('core', 'newUser.requireEmail', 'no') === 'yes';
245
-		$serverData['newUserSendEmail'] = $this->config->getAppValue('core', 'newUser.sendEmail', 'yes') === 'yes';
246
-
247
-		return new TemplateResponse('settings', 'settings-vue', ['serverData' => $serverData]);
248
-	}
249
-
250
-	/**
251
-	 * @param string $key
252
-	 * @param string $value
253
-	 *
254
-	 * @return JSONResponse
255
-	 */
256
-	public function setPreference(string $key, string $value): JSONResponse {
257
-		$allowed = ['newUser.sendEmail'];
258
-		if (!in_array($key, $allowed, true)) {
259
-			return new JSONResponse([], Http::STATUS_FORBIDDEN);
260
-		}
261
-
262
-		$this->config->setAppValue('core', $key, $value);
263
-
264
-		return new JSONResponse([]);
265
-	}
266
-
267
-	/**
268
-	 * Parse the app value for quota_present
269
-	 *
270
-	 * @param string $quotaPreset
271
-	 * @return array
272
-	 */
273
-	protected function parseQuotaPreset(string $quotaPreset): array {
274
-		// 1 GB, 5 GB, 10 GB => [1 GB, 5 GB, 10 GB]
275
-		$presets = array_filter(array_map('trim', explode(',', $quotaPreset)));
276
-		// Drop default and none, Make array indexes numerically
277
-		return array_values(array_diff($presets, ['default', 'none']));
278
-	}
279
-
280
-	/**
281
-	 * check if the admin can change the users password
282
-	 *
283
-	 * The admin can change the passwords if:
284
-	 *
285
-	 *   - no encryption module is loaded and encryption is disabled
286
-	 *   - encryption module is loaded but it doesn't require per user keys
287
-	 *
288
-	 * The admin can not change the passwords if:
289
-	 *
290
-	 *   - an encryption module is loaded and it uses per-user keys
291
-	 *   - encryption is enabled but no encryption modules are loaded
292
-	 *
293
-	 * @return bool
294
-	 */
295
-	protected function canAdminChangeUserPasswords() {
296
-		$isEncryptionEnabled = $this->encryptionManager->isEnabled();
297
-		try {
298
-			$noUserSpecificEncryptionKeys =!$this->encryptionManager->getEncryptionModule()->needDetailedAccessList();
299
-			$isEncryptionModuleLoaded = true;
300
-		} catch (ModuleDoesNotExistsException $e) {
301
-			$noUserSpecificEncryptionKeys = true;
302
-			$isEncryptionModuleLoaded = false;
303
-		}
304
-
305
-		$canChangePassword = ($isEncryptionEnabled && $isEncryptionModuleLoaded  && $noUserSpecificEncryptionKeys)
306
-			|| (!$isEncryptionEnabled && !$isEncryptionModuleLoaded)
307
-			|| (!$isEncryptionEnabled && $isEncryptionModuleLoaded && $noUserSpecificEncryptionKeys);
308
-
309
-		return $canChangePassword;
310
-	}
311
-
312
-	/**
313
-	 * @NoAdminRequired
314
-	 * @NoSubAdminRequired
315
-	 * @PasswordConfirmationRequired
316
-	 *
317
-	 * @param string $avatarScope
318
-	 * @param string $displayname
319
-	 * @param string $displaynameScope
320
-	 * @param string $phone
321
-	 * @param string $phoneScope
322
-	 * @param string $email
323
-	 * @param string $emailScope
324
-	 * @param string $website
325
-	 * @param string $websiteScope
326
-	 * @param string $address
327
-	 * @param string $addressScope
328
-	 * @param string $twitter
329
-	 * @param string $twitterScope
330
-	 * @return DataResponse
331
-	 */
332
-	public function setUserSettings($avatarScope,
333
-									$displayname,
334
-									$displaynameScope,
335
-									$phone,
336
-									$phoneScope,
337
-									$email,
338
-									$emailScope,
339
-									$website,
340
-									$websiteScope,
341
-									$address,
342
-									$addressScope,
343
-									$twitter,
344
-									$twitterScope
345
-	) {
346
-		if (!empty($email) && !$this->mailer->validateMailAddress($email)) {
347
-			return new DataResponse(
348
-				[
349
-					'status' => 'error',
350
-					'data' => [
351
-						'message' => $this->l10n->t('Invalid mail address')
352
-					]
353
-				],
354
-				Http::STATUS_UNPROCESSABLE_ENTITY
355
-			);
356
-		}
357
-		$user = $this->userSession->getUser();
358
-		$data = $this->accountManager->getUser($user);
359
-		$data[AccountManager::PROPERTY_AVATAR] = ['scope' => $avatarScope];
360
-		if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
361
-			$data[AccountManager::PROPERTY_DISPLAYNAME] = ['value' => $displayname, 'scope' => $displaynameScope];
362
-			$data[AccountManager::PROPERTY_EMAIL] = ['value' => $email, 'scope' => $emailScope];
363
-		}
364
-		if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
365
-			$federatedFileSharing = new \OCA\FederatedFileSharing\AppInfo\Application();
366
-			$shareProvider = $federatedFileSharing->getFederatedShareProvider();
367
-			if ($shareProvider->isLookupServerUploadEnabled()) {
368
-				$data[AccountManager::PROPERTY_WEBSITE] = ['value' => $website, 'scope' => $websiteScope];
369
-				$data[AccountManager::PROPERTY_ADDRESS] = ['value' => $address, 'scope' => $addressScope];
370
-				$data[AccountManager::PROPERTY_PHONE] = ['value' => $phone, 'scope' => $phoneScope];
371
-				$data[AccountManager::PROPERTY_TWITTER] = ['value' => $twitter, 'scope' => $twitterScope];
372
-			}
373
-		}
374
-		try {
375
-			$this->saveUserSettings($user, $data);
376
-			return new DataResponse(
377
-				[
378
-					'status' => 'success',
379
-					'data' => [
380
-						'userId' => $user->getUID(),
381
-						'avatarScope' => $data[AccountManager::PROPERTY_AVATAR]['scope'],
382
-						'displayname' => $data[AccountManager::PROPERTY_DISPLAYNAME]['value'],
383
-						'displaynameScope' => $data[AccountManager::PROPERTY_DISPLAYNAME]['scope'],
384
-						'email' => $data[AccountManager::PROPERTY_EMAIL]['value'],
385
-						'emailScope' => $data[AccountManager::PROPERTY_EMAIL]['scope'],
386
-						'website' => $data[AccountManager::PROPERTY_WEBSITE]['value'],
387
-						'websiteScope' => $data[AccountManager::PROPERTY_WEBSITE]['scope'],
388
-						'address' => $data[AccountManager::PROPERTY_ADDRESS]['value'],
389
-						'addressScope' => $data[AccountManager::PROPERTY_ADDRESS]['scope'],
390
-						'message' => $this->l10n->t('Settings saved')
391
-					]
392
-				],
393
-				Http::STATUS_OK
394
-			);
395
-		} catch (ForbiddenException $e) {
396
-			return new DataResponse([
397
-				'status' => 'error',
398
-				'data' => [
399
-					'message' => $e->getMessage()
400
-				],
401
-			]);
402
-		}
403
-	}
404
-	/**
405
-	 * update account manager with new user data
406
-	 *
407
-	 * @param IUser $user
408
-	 * @param array $data
409
-	 * @throws ForbiddenException
410
-	 */
411
-	protected function saveUserSettings(IUser $user, array $data) {
412
-		// keep the user back-end up-to-date with the latest display name and email
413
-		// address
414
-		$oldDisplayName = $user->getDisplayName();
415
-		$oldDisplayName = is_null($oldDisplayName) ? '' : $oldDisplayName;
416
-		if (isset($data[AccountManager::PROPERTY_DISPLAYNAME]['value'])
417
-			&& $oldDisplayName !== $data[AccountManager::PROPERTY_DISPLAYNAME]['value']
418
-		) {
419
-			$result = $user->setDisplayName($data[AccountManager::PROPERTY_DISPLAYNAME]['value']);
420
-			if ($result === false) {
421
-				throw new ForbiddenException($this->l10n->t('Unable to change full name'));
422
-			}
423
-		}
424
-		$oldEmailAddress = $user->getEMailAddress();
425
-		$oldEmailAddress = is_null($oldEmailAddress) ? '' : $oldEmailAddress;
426
-		if (isset($data[AccountManager::PROPERTY_EMAIL]['value'])
427
-			&& $oldEmailAddress !== $data[AccountManager::PROPERTY_EMAIL]['value']
428
-		) {
429
-			// this is the only permission a backend provides and is also used
430
-			// for the permission of setting a email address
431
-			if (!$user->canChangeDisplayName()) {
432
-				throw new ForbiddenException($this->l10n->t('Unable to change email address'));
433
-			}
434
-			$user->setEMailAddress($data[AccountManager::PROPERTY_EMAIL]['value']);
435
-		}
436
-		$this->accountManager->updateUser($user, $data);
437
-	}
438
-
439
-	/**
440
-	 * Set the mail address of a user
441
-	 *
442
-	 * @NoAdminRequired
443
-	 * @NoSubAdminRequired
444
-	 * @PasswordConfirmationRequired
445
-	 *
446
-	 * @param string $account
447
-	 * @param bool $onlyVerificationCode only return verification code without updating the data
448
-	 * @return DataResponse
449
-	 */
450
-	public function getVerificationCode(string $account, bool $onlyVerificationCode): DataResponse {
451
-		$user = $this->userSession->getUser();
452
-
453
-		if ($user === null) {
454
-			return new DataResponse([], Http::STATUS_BAD_REQUEST);
455
-		}
456
-
457
-		$accountData = $this->accountManager->getUser($user);
458
-		$cloudId = $user->getCloudId();
459
-		$message = 'Use my Federated Cloud ID to share with me: ' . $cloudId;
460
-		$signature = $this->signMessage($user, $message);
461
-
462
-		$code = $message . ' ' . $signature;
463
-		$codeMd5 = $message . ' ' . md5($signature);
464
-
465
-		switch ($account) {
466
-			case 'verify-twitter':
467
-				$accountData[AccountManager::PROPERTY_TWITTER]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
468
-				$msg = $this->l10n->t('In order to verify your Twitter account, post the following tweet on Twitter (please make sure to post it without any line breaks):');
469
-				$code = $codeMd5;
470
-				$type = AccountManager::PROPERTY_TWITTER;
471
-				$data = $accountData[AccountManager::PROPERTY_TWITTER]['value'];
472
-				$accountData[AccountManager::PROPERTY_TWITTER]['signature'] = $signature;
473
-				break;
474
-			case 'verify-website':
475
-				$accountData[AccountManager::PROPERTY_WEBSITE]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
476
-				$msg = $this->l10n->t('In order to verify your Website, store the following content in your web-root at \'.well-known/CloudIdVerificationCode.txt\' (please make sure that the complete text is in one line):');
477
-				$type = AccountManager::PROPERTY_WEBSITE;
478
-				$data = $accountData[AccountManager::PROPERTY_WEBSITE]['value'];
479
-				$accountData[AccountManager::PROPERTY_WEBSITE]['signature'] = $signature;
480
-				break;
481
-			default:
482
-				return new DataResponse([], Http::STATUS_BAD_REQUEST);
483
-		}
484
-
485
-		if ($onlyVerificationCode === false) {
486
-			$this->accountManager->updateUser($user, $accountData);
487
-
488
-			$this->jobList->add(VerifyUserData::class,
489
-				[
490
-					'verificationCode' => $code,
491
-					'data' => $data,
492
-					'type' => $type,
493
-					'uid' => $user->getUID(),
494
-					'try' => 0,
495
-					'lastRun' => $this->getCurrentTime()
496
-				]
497
-			);
498
-		}
499
-
500
-		return new DataResponse(['msg' => $msg, 'code' => $code]);
501
-	}
502
-
503
-	/**
504
-	 * get current timestamp
505
-	 *
506
-	 * @return int
507
-	 */
508
-	protected function getCurrentTime(): int {
509
-		return time();
510
-	}
511
-
512
-	/**
513
-	 * sign message with users private key
514
-	 *
515
-	 * @param IUser $user
516
-	 * @param string $message
517
-	 *
518
-	 * @return string base64 encoded signature
519
-	 */
520
-	protected function signMessage(IUser $user, string $message): string {
521
-		$privateKey = $this->keyManager->getKey($user)->getPrivate();
522
-		openssl_sign(json_encode($message), $signature, $privateKey, OPENSSL_ALGO_SHA512);
523
-		return base64_encode($signature);
524
-	}
60
+    /** @var IUserManager */
61
+    private $userManager;
62
+    /** @var IGroupManager */
63
+    private $groupManager;
64
+    /** @var IUserSession */
65
+    private $userSession;
66
+    /** @var IConfig */
67
+    private $config;
68
+    /** @var bool */
69
+    private $isAdmin;
70
+    /** @var IL10N */
71
+    private $l10n;
72
+    /** @var IMailer */
73
+    private $mailer;
74
+    /** @var IFactory */
75
+    private $l10nFactory;
76
+    /** @var IAppManager */
77
+    private $appManager;
78
+    /** @var AccountManager */
79
+    private $accountManager;
80
+    /** @var Manager */
81
+    private $keyManager;
82
+    /** @var IJobList */
83
+    private $jobList;
84
+    /** @var IManager */
85
+    private $encryptionManager;
86
+
87
+
88
+    public function __construct(string $appName,
89
+                                IRequest $request,
90
+                                IUserManager $userManager,
91
+                                IGroupManager $groupManager,
92
+                                IUserSession $userSession,
93
+                                IConfig $config,
94
+                                bool $isAdmin,
95
+                                IL10N $l10n,
96
+                                IMailer $mailer,
97
+                                IFactory $l10nFactory,
98
+                                IAppManager $appManager,
99
+                                AccountManager $accountManager,
100
+                                Manager $keyManager,
101
+                                IJobList $jobList,
102
+                                IManager $encryptionManager) {
103
+        parent::__construct($appName, $request);
104
+        $this->userManager = $userManager;
105
+        $this->groupManager = $groupManager;
106
+        $this->userSession = $userSession;
107
+        $this->config = $config;
108
+        $this->isAdmin = $isAdmin;
109
+        $this->l10n = $l10n;
110
+        $this->mailer = $mailer;
111
+        $this->l10nFactory = $l10nFactory;
112
+        $this->appManager = $appManager;
113
+        $this->accountManager = $accountManager;
114
+        $this->keyManager = $keyManager;
115
+        $this->jobList = $jobList;
116
+        $this->encryptionManager = $encryptionManager;
117
+    }
118
+
119
+
120
+    /**
121
+     * @NoCSRFRequired
122
+     * @NoAdminRequired
123
+     *
124
+     * Display users list template
125
+     *
126
+     * @return TemplateResponse
127
+     */
128
+    public function usersListByGroup() {
129
+        return $this->usersList();
130
+    }
131
+
132
+    /**
133
+     * @NoCSRFRequired
134
+     * @NoAdminRequired
135
+     *
136
+     * Display users list template
137
+     *
138
+     * @return TemplateResponse
139
+     */
140
+    public function usersList() {
141
+        $user = $this->userSession->getUser();
142
+        $uid = $user->getUID();
143
+
144
+        \OC::$server->getNavigationManager()->setActiveEntry('core_users');
145
+
146
+        /* SORT OPTION: SORT_USERCOUNT or SORT_GROUPNAME */
147
+        $sortGroupsBy = \OC\Group\MetaData::SORT_USERCOUNT;
148
+        $isLDAPUsed = false;
149
+        if ($this->config->getSystemValue('sort_groups_by_name', false)) {
150
+            $sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
151
+        } else {
152
+            if ($this->appManager->isEnabledForUser('user_ldap')) {
153
+                $isLDAPUsed =
154
+                    $this->groupManager->isBackendUsed('\OCA\User_LDAP\Group_Proxy');
155
+                if ($isLDAPUsed) {
156
+                    // LDAP user count can be slow, so we sort by group name here
157
+                    $sortGroupsBy = \OC\Group\MetaData::SORT_GROUPNAME;
158
+                }
159
+            }
160
+        }
161
+
162
+        $canChangePassword = $this->canAdminChangeUserPasswords();
163
+
164
+        /* GROUPS */
165
+        $groupsInfo = new \OC\Group\MetaData(
166
+            $uid,
167
+            $this->isAdmin,
168
+            $this->groupManager,
169
+            $this->userSession
170
+        );
171
+
172
+        $groupsInfo->setSorting($sortGroupsBy);
173
+        list($adminGroup, $groups) = $groupsInfo->get();
174
+
175
+        if (!$isLDAPUsed && $this->appManager->isEnabledForUser('user_ldap')) {
176
+            $isLDAPUsed = (bool)array_reduce($this->userManager->getBackends(), function ($ldapFound, $backend) {
177
+                return $ldapFound || $backend instanceof User_Proxy;
178
+            });
179
+        }
180
+
181
+        $disabledUsers = -1;
182
+        $userCount = 0;
183
+
184
+        if (!$isLDAPUsed) {
185
+            if ($this->isAdmin) {
186
+                $disabledUsers = $this->userManager->countDisabledUsers();
187
+                $userCount = array_reduce($this->userManager->countUsers(), function ($v, $w) {
188
+                    return $v + (int)$w;
189
+                }, 0);
190
+            } else {
191
+                // User is subadmin !
192
+                // Map group list to names to retrieve the countDisabledUsersOfGroups
193
+                $userGroups = $this->groupManager->getUserGroups($user);
194
+                $groupsNames = [];
195
+
196
+                foreach ($groups as $key => $group) {
197
+                    // $userCount += (int)$group['usercount'];
198
+                    array_push($groupsNames, $group['name']);
199
+                    // we prevent subadmins from looking up themselves
200
+                    // so we lower the count of the groups he belongs to
201
+                    if (array_key_exists($group['id'], $userGroups)) {
202
+                        $groups[$key]['usercount']--;
203
+                        $userCount -= 1; // we also lower from one the total count
204
+                    }
205
+                };
206
+                $userCount += $this->userManager->countUsersOfGroups($groupsInfo->getGroups());
207
+                $disabledUsers = $this->userManager->countDisabledUsersOfGroups($groupsNames);
208
+            }
209
+
210
+            $userCount -= $disabledUsers;
211
+        }
212
+
213
+        $disabledUsersGroup = [
214
+            'id' => 'disabled',
215
+            'name' => 'Disabled users',
216
+            'usercount' => $disabledUsers
217
+        ];
218
+
219
+        /* QUOTAS PRESETS */
220
+        $quotaPreset = $this->parseQuotaPreset($this->config->getAppValue('files', 'quota_preset', '1 GB, 5 GB, 10 GB'));
221
+        $defaultQuota = $this->config->getAppValue('files', 'default_quota', 'none');
222
+
223
+        \OC::$server->getEventDispatcher()->dispatch('OC\Settings\Users::loadAdditionalScripts');
224
+
225
+        /* LANGUAGES */
226
+        $languages = $this->l10nFactory->getLanguages();
227
+
228
+        /* FINAL DATA */
229
+        $serverData = [];
230
+        // groups
231
+        $serverData['groups'] = array_merge_recursive($adminGroup, [$disabledUsersGroup], $groups);
232
+        // Various data
233
+        $serverData['isAdmin'] = $this->isAdmin;
234
+        $serverData['sortGroups'] = $sortGroupsBy;
235
+        $serverData['quotaPreset'] = $quotaPreset;
236
+        $serverData['userCount'] = $userCount;
237
+        $serverData['languages'] = $languages;
238
+        $serverData['defaultLanguage'] = $this->config->getSystemValue('default_language', 'en');
239
+        $serverData['forceLanguage'] = $this->config->getSystemValue('force_language', false);
240
+        // Settings
241
+        $serverData['defaultQuota'] = $defaultQuota;
242
+        $serverData['canChangePassword'] = $canChangePassword;
243
+        $serverData['newUserGenerateUserID'] = $this->config->getAppValue('core', 'newUser.generateUserID', 'no') === 'yes';
244
+        $serverData['newUserRequireEmail'] = $this->config->getAppValue('core', 'newUser.requireEmail', 'no') === 'yes';
245
+        $serverData['newUserSendEmail'] = $this->config->getAppValue('core', 'newUser.sendEmail', 'yes') === 'yes';
246
+
247
+        return new TemplateResponse('settings', 'settings-vue', ['serverData' => $serverData]);
248
+    }
249
+
250
+    /**
251
+     * @param string $key
252
+     * @param string $value
253
+     *
254
+     * @return JSONResponse
255
+     */
256
+    public function setPreference(string $key, string $value): JSONResponse {
257
+        $allowed = ['newUser.sendEmail'];
258
+        if (!in_array($key, $allowed, true)) {
259
+            return new JSONResponse([], Http::STATUS_FORBIDDEN);
260
+        }
261
+
262
+        $this->config->setAppValue('core', $key, $value);
263
+
264
+        return new JSONResponse([]);
265
+    }
266
+
267
+    /**
268
+     * Parse the app value for quota_present
269
+     *
270
+     * @param string $quotaPreset
271
+     * @return array
272
+     */
273
+    protected function parseQuotaPreset(string $quotaPreset): array {
274
+        // 1 GB, 5 GB, 10 GB => [1 GB, 5 GB, 10 GB]
275
+        $presets = array_filter(array_map('trim', explode(',', $quotaPreset)));
276
+        // Drop default and none, Make array indexes numerically
277
+        return array_values(array_diff($presets, ['default', 'none']));
278
+    }
279
+
280
+    /**
281
+     * check if the admin can change the users password
282
+     *
283
+     * The admin can change the passwords if:
284
+     *
285
+     *   - no encryption module is loaded and encryption is disabled
286
+     *   - encryption module is loaded but it doesn't require per user keys
287
+     *
288
+     * The admin can not change the passwords if:
289
+     *
290
+     *   - an encryption module is loaded and it uses per-user keys
291
+     *   - encryption is enabled but no encryption modules are loaded
292
+     *
293
+     * @return bool
294
+     */
295
+    protected function canAdminChangeUserPasswords() {
296
+        $isEncryptionEnabled = $this->encryptionManager->isEnabled();
297
+        try {
298
+            $noUserSpecificEncryptionKeys =!$this->encryptionManager->getEncryptionModule()->needDetailedAccessList();
299
+            $isEncryptionModuleLoaded = true;
300
+        } catch (ModuleDoesNotExistsException $e) {
301
+            $noUserSpecificEncryptionKeys = true;
302
+            $isEncryptionModuleLoaded = false;
303
+        }
304
+
305
+        $canChangePassword = ($isEncryptionEnabled && $isEncryptionModuleLoaded  && $noUserSpecificEncryptionKeys)
306
+            || (!$isEncryptionEnabled && !$isEncryptionModuleLoaded)
307
+            || (!$isEncryptionEnabled && $isEncryptionModuleLoaded && $noUserSpecificEncryptionKeys);
308
+
309
+        return $canChangePassword;
310
+    }
311
+
312
+    /**
313
+     * @NoAdminRequired
314
+     * @NoSubAdminRequired
315
+     * @PasswordConfirmationRequired
316
+     *
317
+     * @param string $avatarScope
318
+     * @param string $displayname
319
+     * @param string $displaynameScope
320
+     * @param string $phone
321
+     * @param string $phoneScope
322
+     * @param string $email
323
+     * @param string $emailScope
324
+     * @param string $website
325
+     * @param string $websiteScope
326
+     * @param string $address
327
+     * @param string $addressScope
328
+     * @param string $twitter
329
+     * @param string $twitterScope
330
+     * @return DataResponse
331
+     */
332
+    public function setUserSettings($avatarScope,
333
+                                    $displayname,
334
+                                    $displaynameScope,
335
+                                    $phone,
336
+                                    $phoneScope,
337
+                                    $email,
338
+                                    $emailScope,
339
+                                    $website,
340
+                                    $websiteScope,
341
+                                    $address,
342
+                                    $addressScope,
343
+                                    $twitter,
344
+                                    $twitterScope
345
+    ) {
346
+        if (!empty($email) && !$this->mailer->validateMailAddress($email)) {
347
+            return new DataResponse(
348
+                [
349
+                    'status' => 'error',
350
+                    'data' => [
351
+                        'message' => $this->l10n->t('Invalid mail address')
352
+                    ]
353
+                ],
354
+                Http::STATUS_UNPROCESSABLE_ENTITY
355
+            );
356
+        }
357
+        $user = $this->userSession->getUser();
358
+        $data = $this->accountManager->getUser($user);
359
+        $data[AccountManager::PROPERTY_AVATAR] = ['scope' => $avatarScope];
360
+        if ($this->config->getSystemValue('allow_user_to_change_display_name', true) !== false) {
361
+            $data[AccountManager::PROPERTY_DISPLAYNAME] = ['value' => $displayname, 'scope' => $displaynameScope];
362
+            $data[AccountManager::PROPERTY_EMAIL] = ['value' => $email, 'scope' => $emailScope];
363
+        }
364
+        if ($this->appManager->isEnabledForUser('federatedfilesharing')) {
365
+            $federatedFileSharing = new \OCA\FederatedFileSharing\AppInfo\Application();
366
+            $shareProvider = $federatedFileSharing->getFederatedShareProvider();
367
+            if ($shareProvider->isLookupServerUploadEnabled()) {
368
+                $data[AccountManager::PROPERTY_WEBSITE] = ['value' => $website, 'scope' => $websiteScope];
369
+                $data[AccountManager::PROPERTY_ADDRESS] = ['value' => $address, 'scope' => $addressScope];
370
+                $data[AccountManager::PROPERTY_PHONE] = ['value' => $phone, 'scope' => $phoneScope];
371
+                $data[AccountManager::PROPERTY_TWITTER] = ['value' => $twitter, 'scope' => $twitterScope];
372
+            }
373
+        }
374
+        try {
375
+            $this->saveUserSettings($user, $data);
376
+            return new DataResponse(
377
+                [
378
+                    'status' => 'success',
379
+                    'data' => [
380
+                        'userId' => $user->getUID(),
381
+                        'avatarScope' => $data[AccountManager::PROPERTY_AVATAR]['scope'],
382
+                        'displayname' => $data[AccountManager::PROPERTY_DISPLAYNAME]['value'],
383
+                        'displaynameScope' => $data[AccountManager::PROPERTY_DISPLAYNAME]['scope'],
384
+                        'email' => $data[AccountManager::PROPERTY_EMAIL]['value'],
385
+                        'emailScope' => $data[AccountManager::PROPERTY_EMAIL]['scope'],
386
+                        'website' => $data[AccountManager::PROPERTY_WEBSITE]['value'],
387
+                        'websiteScope' => $data[AccountManager::PROPERTY_WEBSITE]['scope'],
388
+                        'address' => $data[AccountManager::PROPERTY_ADDRESS]['value'],
389
+                        'addressScope' => $data[AccountManager::PROPERTY_ADDRESS]['scope'],
390
+                        'message' => $this->l10n->t('Settings saved')
391
+                    ]
392
+                ],
393
+                Http::STATUS_OK
394
+            );
395
+        } catch (ForbiddenException $e) {
396
+            return new DataResponse([
397
+                'status' => 'error',
398
+                'data' => [
399
+                    'message' => $e->getMessage()
400
+                ],
401
+            ]);
402
+        }
403
+    }
404
+    /**
405
+     * update account manager with new user data
406
+     *
407
+     * @param IUser $user
408
+     * @param array $data
409
+     * @throws ForbiddenException
410
+     */
411
+    protected function saveUserSettings(IUser $user, array $data) {
412
+        // keep the user back-end up-to-date with the latest display name and email
413
+        // address
414
+        $oldDisplayName = $user->getDisplayName();
415
+        $oldDisplayName = is_null($oldDisplayName) ? '' : $oldDisplayName;
416
+        if (isset($data[AccountManager::PROPERTY_DISPLAYNAME]['value'])
417
+            && $oldDisplayName !== $data[AccountManager::PROPERTY_DISPLAYNAME]['value']
418
+        ) {
419
+            $result = $user->setDisplayName($data[AccountManager::PROPERTY_DISPLAYNAME]['value']);
420
+            if ($result === false) {
421
+                throw new ForbiddenException($this->l10n->t('Unable to change full name'));
422
+            }
423
+        }
424
+        $oldEmailAddress = $user->getEMailAddress();
425
+        $oldEmailAddress = is_null($oldEmailAddress) ? '' : $oldEmailAddress;
426
+        if (isset($data[AccountManager::PROPERTY_EMAIL]['value'])
427
+            && $oldEmailAddress !== $data[AccountManager::PROPERTY_EMAIL]['value']
428
+        ) {
429
+            // this is the only permission a backend provides and is also used
430
+            // for the permission of setting a email address
431
+            if (!$user->canChangeDisplayName()) {
432
+                throw new ForbiddenException($this->l10n->t('Unable to change email address'));
433
+            }
434
+            $user->setEMailAddress($data[AccountManager::PROPERTY_EMAIL]['value']);
435
+        }
436
+        $this->accountManager->updateUser($user, $data);
437
+    }
438
+
439
+    /**
440
+     * Set the mail address of a user
441
+     *
442
+     * @NoAdminRequired
443
+     * @NoSubAdminRequired
444
+     * @PasswordConfirmationRequired
445
+     *
446
+     * @param string $account
447
+     * @param bool $onlyVerificationCode only return verification code without updating the data
448
+     * @return DataResponse
449
+     */
450
+    public function getVerificationCode(string $account, bool $onlyVerificationCode): DataResponse {
451
+        $user = $this->userSession->getUser();
452
+
453
+        if ($user === null) {
454
+            return new DataResponse([], Http::STATUS_BAD_REQUEST);
455
+        }
456
+
457
+        $accountData = $this->accountManager->getUser($user);
458
+        $cloudId = $user->getCloudId();
459
+        $message = 'Use my Federated Cloud ID to share with me: ' . $cloudId;
460
+        $signature = $this->signMessage($user, $message);
461
+
462
+        $code = $message . ' ' . $signature;
463
+        $codeMd5 = $message . ' ' . md5($signature);
464
+
465
+        switch ($account) {
466
+            case 'verify-twitter':
467
+                $accountData[AccountManager::PROPERTY_TWITTER]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
468
+                $msg = $this->l10n->t('In order to verify your Twitter account, post the following tweet on Twitter (please make sure to post it without any line breaks):');
469
+                $code = $codeMd5;
470
+                $type = AccountManager::PROPERTY_TWITTER;
471
+                $data = $accountData[AccountManager::PROPERTY_TWITTER]['value'];
472
+                $accountData[AccountManager::PROPERTY_TWITTER]['signature'] = $signature;
473
+                break;
474
+            case 'verify-website':
475
+                $accountData[AccountManager::PROPERTY_WEBSITE]['verified'] = AccountManager::VERIFICATION_IN_PROGRESS;
476
+                $msg = $this->l10n->t('In order to verify your Website, store the following content in your web-root at \'.well-known/CloudIdVerificationCode.txt\' (please make sure that the complete text is in one line):');
477
+                $type = AccountManager::PROPERTY_WEBSITE;
478
+                $data = $accountData[AccountManager::PROPERTY_WEBSITE]['value'];
479
+                $accountData[AccountManager::PROPERTY_WEBSITE]['signature'] = $signature;
480
+                break;
481
+            default:
482
+                return new DataResponse([], Http::STATUS_BAD_REQUEST);
483
+        }
484
+
485
+        if ($onlyVerificationCode === false) {
486
+            $this->accountManager->updateUser($user, $accountData);
487
+
488
+            $this->jobList->add(VerifyUserData::class,
489
+                [
490
+                    'verificationCode' => $code,
491
+                    'data' => $data,
492
+                    'type' => $type,
493
+                    'uid' => $user->getUID(),
494
+                    'try' => 0,
495
+                    'lastRun' => $this->getCurrentTime()
496
+                ]
497
+            );
498
+        }
499
+
500
+        return new DataResponse(['msg' => $msg, 'code' => $code]);
501
+    }
502
+
503
+    /**
504
+     * get current timestamp
505
+     *
506
+     * @return int
507
+     */
508
+    protected function getCurrentTime(): int {
509
+        return time();
510
+    }
511
+
512
+    /**
513
+     * sign message with users private key
514
+     *
515
+     * @param IUser $user
516
+     * @param string $message
517
+     *
518
+     * @return string base64 encoded signature
519
+     */
520
+    protected function signMessage(IUser $user, string $message): string {
521
+        $privateKey = $this->keyManager->getKey($user)->getPrivate();
522
+        openssl_sign(json_encode($message), $signature, $privateKey, OPENSSL_ALGO_SHA512);
523
+        return base64_encode($signature);
524
+    }
525 525
 }
Please login to merge, or discard this patch.
apps/settings/lib/Controller/WebAuthnController.php 1 patch
Indentation   +77 added lines, -77 removed lines patch added patch discarded remove patch
@@ -38,81 +38,81 @@
 block discarded – undo
38 38
 use Webauthn\PublicKeyCredentialCreationOptions;
39 39
 
40 40
 class WebAuthnController extends Controller {
41
-	private const WEBAUTHN_REGISTRATION = 'webauthn_registration';
42
-
43
-	/** @var Manager */
44
-	private $manager;
45
-
46
-	/** @var IUserSession */
47
-	private $userSession;
48
-	/**
49
-	 * @var ISession
50
-	 */
51
-	private $session;
52
-	/**
53
-	 * @var ILogger
54
-	 */
55
-	private $logger;
56
-
57
-	public function __construct(IRequest $request, ILogger $logger, Manager $webAuthnManager, IUserSession $userSession, ISession $session) {
58
-		parent::__construct(Application::APP_ID, $request);
59
-
60
-		$this->manager = $webAuthnManager;
61
-		$this->userSession = $userSession;
62
-		$this->session = $session;
63
-		$this->logger = $logger;
64
-	}
65
-
66
-	/**
67
-	 * @NoAdminRequired
68
-	 * @NoSubAdminRequired
69
-	 * @PasswordConfirmationRequired
70
-	 * @UseSession
71
-	 * @NoCSRFRequired
72
-	 */
73
-	public function startRegistration(): JSONResponse {
74
-		$this->logger->debug('Starting WebAuthn registration');
75
-
76
-		$credentialOptions = $this->manager->startRegistration($this->userSession->getUser(), $this->request->getServerHost());
77
-
78
-		// Set this in the session since we need it on finish
79
-		$this->session->set(self::WEBAUTHN_REGISTRATION, $credentialOptions);
80
-
81
-		return new JSONResponse($credentialOptions);
82
-	}
83
-
84
-	/**
85
-	 * @NoAdminRequired
86
-	 * @NoSubAdminRequired
87
-	 * @PasswordConfirmationRequired
88
-	 * @UseSession
89
-	 */
90
-	public function finishRegistration(string $name, string $data): JSONResponse {
91
-		$this->logger->debug('Finishing WebAuthn registration');
92
-
93
-		if (!$this->session->exists(self::WEBAUTHN_REGISTRATION)) {
94
-			$this->logger->debug('Trying to finish WebAuthn registration without session data');
95
-			return new JSONResponse([], Http::STATUS_BAD_REQUEST);
96
-		}
97
-
98
-		// Obtain the publicKeyCredentialOptions from when we started the registration
99
-		$publicKeyCredentialCreationOptions = PublicKeyCredentialCreationOptions::createFromArray($this->session->get(self::WEBAUTHN_REGISTRATION));
100
-
101
-		$this->session->remove(self::WEBAUTHN_REGISTRATION);
102
-
103
-		return new JSONResponse($this->manager->finishRegister($publicKeyCredentialCreationOptions, $name, $data));
104
-	}
105
-
106
-	/**
107
-	 * @NoAdminRequired
108
-	 * @NoSubAdminRequired
109
-	 * @PasswordConfirmationRequired
110
-	 */
111
-	public function deleteRegistration(int $id): JSONResponse {
112
-		$this->logger->debug('Finishing WebAuthn registration');
113
-
114
-		$this->manager->deleteRegistration($this->userSession->getUser(), $id);
115
-
116
-		return new JSONResponse([]);
117
-	}
41
+    private const WEBAUTHN_REGISTRATION = 'webauthn_registration';
42
+
43
+    /** @var Manager */
44
+    private $manager;
45
+
46
+    /** @var IUserSession */
47
+    private $userSession;
48
+    /**
49
+     * @var ISession
50
+     */
51
+    private $session;
52
+    /**
53
+     * @var ILogger
54
+     */
55
+    private $logger;
56
+
57
+    public function __construct(IRequest $request, ILogger $logger, Manager $webAuthnManager, IUserSession $userSession, ISession $session) {
58
+        parent::__construct(Application::APP_ID, $request);
59
+
60
+        $this->manager = $webAuthnManager;
61
+        $this->userSession = $userSession;
62
+        $this->session = $session;
63
+        $this->logger = $logger;
64
+    }
65
+
66
+    /**
67
+     * @NoAdminRequired
68
+     * @NoSubAdminRequired
69
+     * @PasswordConfirmationRequired
70
+     * @UseSession
71
+     * @NoCSRFRequired
72
+     */
73
+    public function startRegistration(): JSONResponse {
74
+        $this->logger->debug('Starting WebAuthn registration');
75
+
76
+        $credentialOptions = $this->manager->startRegistration($this->userSession->getUser(), $this->request->getServerHost());
77
+
78
+        // Set this in the session since we need it on finish
79
+        $this->session->set(self::WEBAUTHN_REGISTRATION, $credentialOptions);
80
+
81
+        return new JSONResponse($credentialOptions);
82
+    }
83
+
84
+    /**
85
+     * @NoAdminRequired
86
+     * @NoSubAdminRequired
87
+     * @PasswordConfirmationRequired
88
+     * @UseSession
89
+     */
90
+    public function finishRegistration(string $name, string $data): JSONResponse {
91
+        $this->logger->debug('Finishing WebAuthn registration');
92
+
93
+        if (!$this->session->exists(self::WEBAUTHN_REGISTRATION)) {
94
+            $this->logger->debug('Trying to finish WebAuthn registration without session data');
95
+            return new JSONResponse([], Http::STATUS_BAD_REQUEST);
96
+        }
97
+
98
+        // Obtain the publicKeyCredentialOptions from when we started the registration
99
+        $publicKeyCredentialCreationOptions = PublicKeyCredentialCreationOptions::createFromArray($this->session->get(self::WEBAUTHN_REGISTRATION));
100
+
101
+        $this->session->remove(self::WEBAUTHN_REGISTRATION);
102
+
103
+        return new JSONResponse($this->manager->finishRegister($publicKeyCredentialCreationOptions, $name, $data));
104
+    }
105
+
106
+    /**
107
+     * @NoAdminRequired
108
+     * @NoSubAdminRequired
109
+     * @PasswordConfirmationRequired
110
+     */
111
+    public function deleteRegistration(int $id): JSONResponse {
112
+        $this->logger->debug('Finishing WebAuthn registration');
113
+
114
+        $this->manager->deleteRegistration($this->userSession->getUser(), $id);
115
+
116
+        return new JSONResponse([]);
117
+    }
118 118
 }
Please login to merge, or discard this patch.
apps/settings/lib/Controller/HelpController.php 1 patch
Indentation   +51 added lines, -51 removed lines patch added patch discarded remove patch
@@ -37,62 +37,62 @@
 block discarded – undo
37 37
 
38 38
 class HelpController extends Controller {
39 39
 
40
-	/** @var INavigationManager */
41
-	private $navigationManager;
42
-	/** @var IUserSession */
43
-	private $urlGenerator;
44
-	/** @var IGroupManager */
45
-	private $groupManager;
40
+    /** @var INavigationManager */
41
+    private $navigationManager;
42
+    /** @var IUserSession */
43
+    private $urlGenerator;
44
+    /** @var IGroupManager */
45
+    private $groupManager;
46 46
 
47
-	/** @var string */
48
-	private $userId;
47
+    /** @var string */
48
+    private $userId;
49 49
 
50
-	public function __construct(
51
-		string $appName,
52
-		IRequest $request,
53
-		INavigationManager $navigationManager,
54
-		IURLGenerator $urlGenerator,
55
-		?string $userId,
56
-		IGroupManager $groupManager
57
-	) {
58
-		parent::__construct($appName, $request);
59
-		$this->navigationManager = $navigationManager;
60
-		$this->urlGenerator = $urlGenerator;
61
-		$this->userId = $userId;
62
-		$this->groupManager = $groupManager;
63
-	}
50
+    public function __construct(
51
+        string $appName,
52
+        IRequest $request,
53
+        INavigationManager $navigationManager,
54
+        IURLGenerator $urlGenerator,
55
+        ?string $userId,
56
+        IGroupManager $groupManager
57
+    ) {
58
+        parent::__construct($appName, $request);
59
+        $this->navigationManager = $navigationManager;
60
+        $this->urlGenerator = $urlGenerator;
61
+        $this->userId = $userId;
62
+        $this->groupManager = $groupManager;
63
+    }
64 64
 
65
-	/**
66
-	 * @return TemplateResponse
67
-	 *
68
-	 * @NoCSRFRequired
69
-	 * @NoAdminRequired
70
-	 * @NoSubAdminRequired
71
-	 */
72
-	public function help(string $mode = 'user'): TemplateResponse {
73
-		$this->navigationManager->setActiveEntry('help');
65
+    /**
66
+     * @return TemplateResponse
67
+     *
68
+     * @NoCSRFRequired
69
+     * @NoAdminRequired
70
+     * @NoSubAdminRequired
71
+     */
72
+    public function help(string $mode = 'user'): TemplateResponse {
73
+        $this->navigationManager->setActiveEntry('help');
74 74
 
75
-		if (!isset($mode) || $mode !== 'admin') {
76
-			$mode = 'user';
77
-		}
75
+        if (!isset($mode) || $mode !== 'admin') {
76
+            $mode = 'user';
77
+        }
78 78
 
79
-		$documentationUrl = $this->urlGenerator->getAbsoluteURL(
80
-			$this->urlGenerator->linkTo('core', 'doc/' . $mode . '/index.html')
81
-		);
79
+        $documentationUrl = $this->urlGenerator->getAbsoluteURL(
80
+            $this->urlGenerator->linkTo('core', 'doc/' . $mode . '/index.html')
81
+        );
82 82
 
83
-		$urlUserDocs = $this->urlGenerator->linkToRoute('settings.Help.help', ['mode' => 'user']);
84
-		$urlAdminDocs = $this->urlGenerator->linkToRoute('settings.Help.help', ['mode' => 'admin']);
83
+        $urlUserDocs = $this->urlGenerator->linkToRoute('settings.Help.help', ['mode' => 'user']);
84
+        $urlAdminDocs = $this->urlGenerator->linkToRoute('settings.Help.help', ['mode' => 'admin']);
85 85
 
86
-		$response = new TemplateResponse('settings', 'help', [
87
-			'admin' => $this->groupManager->isAdmin($this->userId),
88
-			'url' => $documentationUrl,
89
-			'urlUserDocs' => $urlUserDocs,
90
-			'urlAdminDocs' => $urlAdminDocs,
91
-			'mode' => $mode,
92
-		]);
93
-		$policy = new ContentSecurityPolicy();
94
-		$policy->addAllowedFrameDomain('\'self\'');
95
-		$response->setContentSecurityPolicy($policy);
96
-		return $response;
97
-	}
86
+        $response = new TemplateResponse('settings', 'help', [
87
+            'admin' => $this->groupManager->isAdmin($this->userId),
88
+            'url' => $documentationUrl,
89
+            'urlUserDocs' => $urlUserDocs,
90
+            'urlAdminDocs' => $urlAdminDocs,
91
+            'mode' => $mode,
92
+        ]);
93
+        $policy = new ContentSecurityPolicy();
94
+        $policy->addAllowedFrameDomain('\'self\'');
95
+        $response->setContentSecurityPolicy($policy);
96
+        return $response;
97
+    }
98 98
 }
Please login to merge, or discard this patch.
apps/settings/lib/Controller/AuthSettingsController.php 1 patch
Indentation   +244 added lines, -244 removed lines patch added patch discarded remove patch
@@ -55,248 +55,248 @@
 block discarded – undo
55 55
 
56 56
 class AuthSettingsController extends Controller {
57 57
 
58
-	/** @var IProvider */
59
-	private $tokenProvider;
60
-
61
-	/** @var ISession */
62
-	private $session;
63
-
64
-	/** IUserSession */
65
-	private $userSession;
66
-
67
-	/** @var string */
68
-	private $uid;
69
-
70
-	/** @var ISecureRandom */
71
-	private $random;
72
-
73
-	/** @var IManager */
74
-	private $activityManager;
75
-
76
-	/** @var RemoteWipe */
77
-	private $remoteWipe;
78
-
79
-	/** @var ILogger */
80
-	private $logger;
81
-
82
-	/**
83
-	 * @param string $appName
84
-	 * @param IRequest $request
85
-	 * @param IProvider $tokenProvider
86
-	 * @param ISession $session
87
-	 * @param ISecureRandom $random
88
-	 * @param string|null $userId
89
-	 * @param IUserSession $userSession
90
-	 * @param IManager $activityManager
91
-	 * @param RemoteWipe $remoteWipe
92
-	 * @param ILogger $logger
93
-	 */
94
-	public function __construct(string $appName,
95
-								IRequest $request,
96
-								IProvider $tokenProvider,
97
-								ISession $session,
98
-								ISecureRandom $random,
99
-								?string $userId,
100
-								IUserSession $userSession,
101
-								IManager $activityManager,
102
-								RemoteWipe $remoteWipe,
103
-								ILogger $logger) {
104
-		parent::__construct($appName, $request);
105
-		$this->tokenProvider = $tokenProvider;
106
-		$this->uid = $userId;
107
-		$this->userSession = $userSession;
108
-		$this->session = $session;
109
-		$this->random = $random;
110
-		$this->activityManager = $activityManager;
111
-		$this->remoteWipe = $remoteWipe;
112
-		$this->logger = $logger;
113
-	}
114
-
115
-	/**
116
-	 * @NoAdminRequired
117
-	 * @NoSubAdminRequired
118
-	 * @PasswordConfirmationRequired
119
-	 *
120
-	 * @param string $name
121
-	 * @return JSONResponse
122
-	 */
123
-	public function create($name) {
124
-		try {
125
-			$sessionId = $this->session->getId();
126
-		} catch (SessionNotAvailableException $ex) {
127
-			return $this->getServiceNotAvailableResponse();
128
-		}
129
-		if ($this->userSession->getImpersonatingUserID() !== null) {
130
-			return $this->getServiceNotAvailableResponse();
131
-		}
132
-
133
-		try {
134
-			$sessionToken = $this->tokenProvider->getToken($sessionId);
135
-			$loginName = $sessionToken->getLoginName();
136
-			try {
137
-				$password = $this->tokenProvider->getPassword($sessionToken, $sessionId);
138
-			} catch (PasswordlessTokenException $ex) {
139
-				$password = null;
140
-			}
141
-		} catch (InvalidTokenException $ex) {
142
-			return $this->getServiceNotAvailableResponse();
143
-		}
144
-
145
-		$token = $this->generateRandomDeviceToken();
146
-		$deviceToken = $this->tokenProvider->generateToken($token, $this->uid, $loginName, $password, $name, IToken::PERMANENT_TOKEN);
147
-		$tokenData = $deviceToken->jsonSerialize();
148
-		$tokenData['canDelete'] = true;
149
-		$tokenData['canRename'] = true;
150
-
151
-		$this->publishActivity(Provider::APP_TOKEN_CREATED, $deviceToken->getId(), ['name' => $deviceToken->getName()]);
152
-
153
-		return new JSONResponse([
154
-			'token' => $token,
155
-			'loginName' => $loginName,
156
-			'deviceToken' => $tokenData,
157
-		]);
158
-	}
159
-
160
-	/**
161
-	 * @return JSONResponse
162
-	 */
163
-	private function getServiceNotAvailableResponse() {
164
-		$resp = new JSONResponse();
165
-		$resp->setStatus(Http::STATUS_SERVICE_UNAVAILABLE);
166
-		return $resp;
167
-	}
168
-
169
-	/**
170
-	 * Return a 25 digit device password
171
-	 *
172
-	 * Example: AbCdE-fGhJk-MnPqR-sTwXy-23456
173
-	 *
174
-	 * @return string
175
-	 */
176
-	private function generateRandomDeviceToken() {
177
-		$groups = [];
178
-		for ($i = 0; $i < 5; $i++) {
179
-			$groups[] = $this->random->generate(5, ISecureRandom::CHAR_HUMAN_READABLE);
180
-		}
181
-		return implode('-', $groups);
182
-	}
183
-
184
-	/**
185
-	 * @NoAdminRequired
186
-	 * @NoSubAdminRequired
187
-	 *
188
-	 * @param int $id
189
-	 * @return array|JSONResponse
190
-	 */
191
-	public function destroy($id) {
192
-		try {
193
-			$token = $this->findTokenByIdAndUser($id);
194
-		} catch (WipeTokenException $e) {
195
-			//continue as we can destroy tokens in wipe
196
-			$token = $e->getToken();
197
-		} catch (InvalidTokenException $e) {
198
-			return new JSONResponse([], Http::STATUS_NOT_FOUND);
199
-		}
200
-
201
-		$this->tokenProvider->invalidateTokenById($this->uid, $token->getId());
202
-		$this->publishActivity(Provider::APP_TOKEN_DELETED, $token->getId(), ['name' => $token->getName()]);
203
-		return [];
204
-	}
205
-
206
-	/**
207
-	 * @NoAdminRequired
208
-	 * @NoSubAdminRequired
209
-	 *
210
-	 * @param int $id
211
-	 * @param array $scope
212
-	 * @param string $name
213
-	 * @return array|JSONResponse
214
-	 */
215
-	public function update($id, array $scope, string $name) {
216
-		try {
217
-			$token = $this->findTokenByIdAndUser($id);
218
-		} catch (InvalidTokenException $e) {
219
-			return new JSONResponse([], Http::STATUS_NOT_FOUND);
220
-		}
221
-
222
-		$currentName = $token->getName();
223
-
224
-		if ($scope !== $token->getScopeAsArray()) {
225
-			$token->setScope(['filesystem' => $scope['filesystem']]);
226
-			$this->publishActivity($scope['filesystem'] ? Provider::APP_TOKEN_FILESYSTEM_GRANTED : Provider::APP_TOKEN_FILESYSTEM_REVOKED, $token->getId(), ['name' => $currentName]);
227
-		}
228
-
229
-		if ($token instanceof INamedToken && $name !== $currentName) {
230
-			$token->setName($name);
231
-			$this->publishActivity(Provider::APP_TOKEN_RENAMED, $token->getId(), ['name' => $currentName, 'newName' => $name]);
232
-		}
233
-
234
-		$this->tokenProvider->updateToken($token);
235
-		return [];
236
-	}
237
-
238
-	/**
239
-	 * @param string $subject
240
-	 * @param int $id
241
-	 * @param array $parameters
242
-	 */
243
-	private function publishActivity(string $subject, int $id, array $parameters = []): void {
244
-		$event = $this->activityManager->generateEvent();
245
-		$event->setApp('settings')
246
-			->setType('security')
247
-			->setAffectedUser($this->uid)
248
-			->setAuthor($this->uid)
249
-			->setSubject($subject, $parameters)
250
-			->setObject('app_token', $id, 'App Password');
251
-
252
-		try {
253
-			$this->activityManager->publish($event);
254
-		} catch (BadMethodCallException $e) {
255
-			$this->logger->warning('could not publish activity');
256
-			$this->logger->logException($e);
257
-		}
258
-	}
259
-
260
-	/**
261
-	 * Find a token by given id and check if uid for current session belongs to this token
262
-	 *
263
-	 * @param int $id
264
-	 * @return IToken
265
-	 * @throws InvalidTokenException
266
-	 */
267
-	private function findTokenByIdAndUser(int $id): IToken {
268
-		try {
269
-			$token = $this->tokenProvider->getTokenById($id);
270
-		} catch (ExpiredTokenException $e) {
271
-			$token = $e->getToken();
272
-		}
273
-		if ($token->getUID() !== $this->uid) {
274
-			throw new InvalidTokenException('This token does not belong to you!');
275
-		}
276
-		return $token;
277
-	}
278
-
279
-	/**
280
-	 * @NoAdminRequired
281
-	 * @NoSubAdminRequired
282
-	 * @PasswordConfirmationRequired
283
-	 *
284
-	 * @param int $id
285
-	 * @return JSONResponse
286
-	 * @throws InvalidTokenException
287
-	 * @throws \OC\Authentication\Exceptions\ExpiredTokenException
288
-	 */
289
-	public function wipe(int $id): JSONResponse {
290
-		try {
291
-			$token = $this->findTokenByIdAndUser($id);
292
-		} catch (InvalidTokenException $e) {
293
-			return new JSONResponse([], Http::STATUS_NOT_FOUND);
294
-		}
295
-
296
-		if (!$this->remoteWipe->markTokenForWipe($token)) {
297
-			return new JSONResponse([], Http::STATUS_BAD_REQUEST);
298
-		}
299
-
300
-		return new JSONResponse([]);
301
-	}
58
+    /** @var IProvider */
59
+    private $tokenProvider;
60
+
61
+    /** @var ISession */
62
+    private $session;
63
+
64
+    /** IUserSession */
65
+    private $userSession;
66
+
67
+    /** @var string */
68
+    private $uid;
69
+
70
+    /** @var ISecureRandom */
71
+    private $random;
72
+
73
+    /** @var IManager */
74
+    private $activityManager;
75
+
76
+    /** @var RemoteWipe */
77
+    private $remoteWipe;
78
+
79
+    /** @var ILogger */
80
+    private $logger;
81
+
82
+    /**
83
+     * @param string $appName
84
+     * @param IRequest $request
85
+     * @param IProvider $tokenProvider
86
+     * @param ISession $session
87
+     * @param ISecureRandom $random
88
+     * @param string|null $userId
89
+     * @param IUserSession $userSession
90
+     * @param IManager $activityManager
91
+     * @param RemoteWipe $remoteWipe
92
+     * @param ILogger $logger
93
+     */
94
+    public function __construct(string $appName,
95
+                                IRequest $request,
96
+                                IProvider $tokenProvider,
97
+                                ISession $session,
98
+                                ISecureRandom $random,
99
+                                ?string $userId,
100
+                                IUserSession $userSession,
101
+                                IManager $activityManager,
102
+                                RemoteWipe $remoteWipe,
103
+                                ILogger $logger) {
104
+        parent::__construct($appName, $request);
105
+        $this->tokenProvider = $tokenProvider;
106
+        $this->uid = $userId;
107
+        $this->userSession = $userSession;
108
+        $this->session = $session;
109
+        $this->random = $random;
110
+        $this->activityManager = $activityManager;
111
+        $this->remoteWipe = $remoteWipe;
112
+        $this->logger = $logger;
113
+    }
114
+
115
+    /**
116
+     * @NoAdminRequired
117
+     * @NoSubAdminRequired
118
+     * @PasswordConfirmationRequired
119
+     *
120
+     * @param string $name
121
+     * @return JSONResponse
122
+     */
123
+    public function create($name) {
124
+        try {
125
+            $sessionId = $this->session->getId();
126
+        } catch (SessionNotAvailableException $ex) {
127
+            return $this->getServiceNotAvailableResponse();
128
+        }
129
+        if ($this->userSession->getImpersonatingUserID() !== null) {
130
+            return $this->getServiceNotAvailableResponse();
131
+        }
132
+
133
+        try {
134
+            $sessionToken = $this->tokenProvider->getToken($sessionId);
135
+            $loginName = $sessionToken->getLoginName();
136
+            try {
137
+                $password = $this->tokenProvider->getPassword($sessionToken, $sessionId);
138
+            } catch (PasswordlessTokenException $ex) {
139
+                $password = null;
140
+            }
141
+        } catch (InvalidTokenException $ex) {
142
+            return $this->getServiceNotAvailableResponse();
143
+        }
144
+
145
+        $token = $this->generateRandomDeviceToken();
146
+        $deviceToken = $this->tokenProvider->generateToken($token, $this->uid, $loginName, $password, $name, IToken::PERMANENT_TOKEN);
147
+        $tokenData = $deviceToken->jsonSerialize();
148
+        $tokenData['canDelete'] = true;
149
+        $tokenData['canRename'] = true;
150
+
151
+        $this->publishActivity(Provider::APP_TOKEN_CREATED, $deviceToken->getId(), ['name' => $deviceToken->getName()]);
152
+
153
+        return new JSONResponse([
154
+            'token' => $token,
155
+            'loginName' => $loginName,
156
+            'deviceToken' => $tokenData,
157
+        ]);
158
+    }
159
+
160
+    /**
161
+     * @return JSONResponse
162
+     */
163
+    private function getServiceNotAvailableResponse() {
164
+        $resp = new JSONResponse();
165
+        $resp->setStatus(Http::STATUS_SERVICE_UNAVAILABLE);
166
+        return $resp;
167
+    }
168
+
169
+    /**
170
+     * Return a 25 digit device password
171
+     *
172
+     * Example: AbCdE-fGhJk-MnPqR-sTwXy-23456
173
+     *
174
+     * @return string
175
+     */
176
+    private function generateRandomDeviceToken() {
177
+        $groups = [];
178
+        for ($i = 0; $i < 5; $i++) {
179
+            $groups[] = $this->random->generate(5, ISecureRandom::CHAR_HUMAN_READABLE);
180
+        }
181
+        return implode('-', $groups);
182
+    }
183
+
184
+    /**
185
+     * @NoAdminRequired
186
+     * @NoSubAdminRequired
187
+     *
188
+     * @param int $id
189
+     * @return array|JSONResponse
190
+     */
191
+    public function destroy($id) {
192
+        try {
193
+            $token = $this->findTokenByIdAndUser($id);
194
+        } catch (WipeTokenException $e) {
195
+            //continue as we can destroy tokens in wipe
196
+            $token = $e->getToken();
197
+        } catch (InvalidTokenException $e) {
198
+            return new JSONResponse([], Http::STATUS_NOT_FOUND);
199
+        }
200
+
201
+        $this->tokenProvider->invalidateTokenById($this->uid, $token->getId());
202
+        $this->publishActivity(Provider::APP_TOKEN_DELETED, $token->getId(), ['name' => $token->getName()]);
203
+        return [];
204
+    }
205
+
206
+    /**
207
+     * @NoAdminRequired
208
+     * @NoSubAdminRequired
209
+     *
210
+     * @param int $id
211
+     * @param array $scope
212
+     * @param string $name
213
+     * @return array|JSONResponse
214
+     */
215
+    public function update($id, array $scope, string $name) {
216
+        try {
217
+            $token = $this->findTokenByIdAndUser($id);
218
+        } catch (InvalidTokenException $e) {
219
+            return new JSONResponse([], Http::STATUS_NOT_FOUND);
220
+        }
221
+
222
+        $currentName = $token->getName();
223
+
224
+        if ($scope !== $token->getScopeAsArray()) {
225
+            $token->setScope(['filesystem' => $scope['filesystem']]);
226
+            $this->publishActivity($scope['filesystem'] ? Provider::APP_TOKEN_FILESYSTEM_GRANTED : Provider::APP_TOKEN_FILESYSTEM_REVOKED, $token->getId(), ['name' => $currentName]);
227
+        }
228
+
229
+        if ($token instanceof INamedToken && $name !== $currentName) {
230
+            $token->setName($name);
231
+            $this->publishActivity(Provider::APP_TOKEN_RENAMED, $token->getId(), ['name' => $currentName, 'newName' => $name]);
232
+        }
233
+
234
+        $this->tokenProvider->updateToken($token);
235
+        return [];
236
+    }
237
+
238
+    /**
239
+     * @param string $subject
240
+     * @param int $id
241
+     * @param array $parameters
242
+     */
243
+    private function publishActivity(string $subject, int $id, array $parameters = []): void {
244
+        $event = $this->activityManager->generateEvent();
245
+        $event->setApp('settings')
246
+            ->setType('security')
247
+            ->setAffectedUser($this->uid)
248
+            ->setAuthor($this->uid)
249
+            ->setSubject($subject, $parameters)
250
+            ->setObject('app_token', $id, 'App Password');
251
+
252
+        try {
253
+            $this->activityManager->publish($event);
254
+        } catch (BadMethodCallException $e) {
255
+            $this->logger->warning('could not publish activity');
256
+            $this->logger->logException($e);
257
+        }
258
+    }
259
+
260
+    /**
261
+     * Find a token by given id and check if uid for current session belongs to this token
262
+     *
263
+     * @param int $id
264
+     * @return IToken
265
+     * @throws InvalidTokenException
266
+     */
267
+    private function findTokenByIdAndUser(int $id): IToken {
268
+        try {
269
+            $token = $this->tokenProvider->getTokenById($id);
270
+        } catch (ExpiredTokenException $e) {
271
+            $token = $e->getToken();
272
+        }
273
+        if ($token->getUID() !== $this->uid) {
274
+            throw new InvalidTokenException('This token does not belong to you!');
275
+        }
276
+        return $token;
277
+    }
278
+
279
+    /**
280
+     * @NoAdminRequired
281
+     * @NoSubAdminRequired
282
+     * @PasswordConfirmationRequired
283
+     *
284
+     * @param int $id
285
+     * @return JSONResponse
286
+     * @throws InvalidTokenException
287
+     * @throws \OC\Authentication\Exceptions\ExpiredTokenException
288
+     */
289
+    public function wipe(int $id): JSONResponse {
290
+        try {
291
+            $token = $this->findTokenByIdAndUser($id);
292
+        } catch (InvalidTokenException $e) {
293
+            return new JSONResponse([], Http::STATUS_NOT_FOUND);
294
+        }
295
+
296
+        if (!$this->remoteWipe->markTokenForWipe($token)) {
297
+            return new JSONResponse([], Http::STATUS_BAD_REQUEST);
298
+        }
299
+
300
+        return new JSONResponse([]);
301
+    }
302 302
 }
Please login to merge, or discard this patch.
lib/private/AppFramework/Utility/ControllerMethodReflector.php 1 patch
Indentation   +99 added lines, -99 removed lines patch added patch discarded remove patch
@@ -39,103 +39,103 @@
 block discarded – undo
39 39
  * Reads and parses annotations from doc comments
40 40
  */
41 41
 class ControllerMethodReflector implements IControllerMethodReflector {
42
-	public $annotations = [];
43
-	private $types = [];
44
-	private $parameters = [];
45
-
46
-	/**
47
-	 * @param object $object an object or classname
48
-	 * @param string $method the method which we want to inspect
49
-	 */
50
-	public function reflect($object, string $method) {
51
-		$reflection = new \ReflectionMethod($object, $method);
52
-		$docs = $reflection->getDocComment();
53
-
54
-		if ($docs !== false) {
55
-			// extract everything prefixed by @ and first letter uppercase
56
-			preg_match_all('/^\h+\*\h+@(?P<annotation>[A-Z]\w+)((?P<parameter>.*))?$/m', $docs, $matches);
57
-			foreach ($matches['annotation'] as $key => $annontation) {
58
-				$annontation = strtolower($annontation);
59
-				$annotationValue = $matches['parameter'][$key];
60
-				if (isset($annotationValue[0]) && $annotationValue[0] === '(' && $annotationValue[\strlen($annotationValue) - 1] === ')') {
61
-					$cutString = substr($annotationValue, 1, -1);
62
-					$cutString = str_replace(' ', '', $cutString);
63
-					$splittedArray = explode(',', $cutString);
64
-					foreach ($splittedArray as $annotationValues) {
65
-						list($key, $value) = explode('=', $annotationValues);
66
-						$this->annotations[$annontation][$key] = $value;
67
-					}
68
-					continue;
69
-				}
70
-
71
-				$this->annotations[$annontation] = [$annotationValue];
72
-			}
73
-
74
-			// extract type parameter information
75
-			preg_match_all('/@param\h+(?P<type>\w+)\h+\$(?P<var>\w+)/', $docs, $matches);
76
-			$this->types = array_combine($matches['var'], $matches['type']);
77
-		}
78
-
79
-		foreach ($reflection->getParameters() as $param) {
80
-			// extract type information from PHP 7 scalar types and prefer them over phpdoc annotations
81
-			$type = $param->getType();
82
-			if ($type instanceof \ReflectionNamedType) {
83
-				$this->types[$param->getName()] = $type->getName();
84
-			}
85
-
86
-			$default = null;
87
-			if ($param->isOptional()) {
88
-				$default = $param->getDefaultValue();
89
-			}
90
-			$this->parameters[$param->name] = $default;
91
-		}
92
-	}
93
-
94
-	/**
95
-	 * Inspects the PHPDoc parameters for types
96
-	 * @param string $parameter the parameter whose type comments should be
97
-	 * parsed
98
-	 * @return string|null type in the type parameters (@param int $something)
99
-	 * would return int or null if not existing
100
-	 */
101
-	public function getType(string $parameter) {
102
-		if (array_key_exists($parameter, $this->types)) {
103
-			return $this->types[$parameter];
104
-		}
105
-
106
-		return null;
107
-	}
108
-
109
-	/**
110
-	 * @return array the arguments of the method with key => default value
111
-	 */
112
-	public function getParameters(): array {
113
-		return $this->parameters;
114
-	}
115
-
116
-	/**
117
-	 * Check if a method contains an annotation
118
-	 * @param string $name the name of the annotation
119
-	 * @return bool true if the annotation is found
120
-	 */
121
-	public function hasAnnotation(string $name): bool {
122
-		$name = strtolower($name);
123
-		return array_key_exists($name, $this->annotations);
124
-	}
125
-
126
-	/**
127
-	 * Get optional annotation parameter by key
128
-	 *
129
-	 * @param string $name the name of the annotation
130
-	 * @param string $key the string of the annotation
131
-	 * @return string
132
-	 */
133
-	public function getAnnotationParameter(string $name, string $key): string {
134
-		$name = strtolower($name);
135
-		if (isset($this->annotations[$name][$key])) {
136
-			return $this->annotations[$name][$key];
137
-		}
138
-
139
-		return '';
140
-	}
42
+    public $annotations = [];
43
+    private $types = [];
44
+    private $parameters = [];
45
+
46
+    /**
47
+     * @param object $object an object or classname
48
+     * @param string $method the method which we want to inspect
49
+     */
50
+    public function reflect($object, string $method) {
51
+        $reflection = new \ReflectionMethod($object, $method);
52
+        $docs = $reflection->getDocComment();
53
+
54
+        if ($docs !== false) {
55
+            // extract everything prefixed by @ and first letter uppercase
56
+            preg_match_all('/^\h+\*\h+@(?P<annotation>[A-Z]\w+)((?P<parameter>.*))?$/m', $docs, $matches);
57
+            foreach ($matches['annotation'] as $key => $annontation) {
58
+                $annontation = strtolower($annontation);
59
+                $annotationValue = $matches['parameter'][$key];
60
+                if (isset($annotationValue[0]) && $annotationValue[0] === '(' && $annotationValue[\strlen($annotationValue) - 1] === ')') {
61
+                    $cutString = substr($annotationValue, 1, -1);
62
+                    $cutString = str_replace(' ', '', $cutString);
63
+                    $splittedArray = explode(',', $cutString);
64
+                    foreach ($splittedArray as $annotationValues) {
65
+                        list($key, $value) = explode('=', $annotationValues);
66
+                        $this->annotations[$annontation][$key] = $value;
67
+                    }
68
+                    continue;
69
+                }
70
+
71
+                $this->annotations[$annontation] = [$annotationValue];
72
+            }
73
+
74
+            // extract type parameter information
75
+            preg_match_all('/@param\h+(?P<type>\w+)\h+\$(?P<var>\w+)/', $docs, $matches);
76
+            $this->types = array_combine($matches['var'], $matches['type']);
77
+        }
78
+
79
+        foreach ($reflection->getParameters() as $param) {
80
+            // extract type information from PHP 7 scalar types and prefer them over phpdoc annotations
81
+            $type = $param->getType();
82
+            if ($type instanceof \ReflectionNamedType) {
83
+                $this->types[$param->getName()] = $type->getName();
84
+            }
85
+
86
+            $default = null;
87
+            if ($param->isOptional()) {
88
+                $default = $param->getDefaultValue();
89
+            }
90
+            $this->parameters[$param->name] = $default;
91
+        }
92
+    }
93
+
94
+    /**
95
+     * Inspects the PHPDoc parameters for types
96
+     * @param string $parameter the parameter whose type comments should be
97
+     * parsed
98
+     * @return string|null type in the type parameters (@param int $something)
99
+     * would return int or null if not existing
100
+     */
101
+    public function getType(string $parameter) {
102
+        if (array_key_exists($parameter, $this->types)) {
103
+            return $this->types[$parameter];
104
+        }
105
+
106
+        return null;
107
+    }
108
+
109
+    /**
110
+     * @return array the arguments of the method with key => default value
111
+     */
112
+    public function getParameters(): array {
113
+        return $this->parameters;
114
+    }
115
+
116
+    /**
117
+     * Check if a method contains an annotation
118
+     * @param string $name the name of the annotation
119
+     * @return bool true if the annotation is found
120
+     */
121
+    public function hasAnnotation(string $name): bool {
122
+        $name = strtolower($name);
123
+        return array_key_exists($name, $this->annotations);
124
+    }
125
+
126
+    /**
127
+     * Get optional annotation parameter by key
128
+     *
129
+     * @param string $name the name of the annotation
130
+     * @param string $key the string of the annotation
131
+     * @return string
132
+     */
133
+    public function getAnnotationParameter(string $name, string $key): string {
134
+        $name = strtolower($name);
135
+        if (isset($this->annotations[$name][$key])) {
136
+            return $this->annotations[$name][$key];
137
+        }
138
+
139
+        return '';
140
+    }
141 141
 }
Please login to merge, or discard this patch.