aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorprovokateurin <kate@provokateurin.de>2024-02-20 09:32:33 +0100
committerprovokateurin <kate@provokateurin.de>2024-02-20 14:28:00 +0100
commit6243a9471d6db3a5d8f13395a89575d4038e266e (patch)
tree5fb04f81ac740911f4007afbaf4cd78545647f7b /core
parentd95e500e45a3c41af92482e04d16c54c2581e467 (diff)
downloadnextcloud-server-6243a9471d6db3a5d8f13395a89575d4038e266e.tar.gz
nextcloud-server-6243a9471d6db3a5d8f13395a89575d4038e266e.zip
feat(core): Add OCS endpoint for confirming the user password
Signed-off-by: provokateurin <kate@provokateurin.de>
Diffstat (limited to 'core')
-rw-r--r--core/Controller/AppPasswordController.php36
-rw-r--r--core/openapi.json107
-rw-r--r--core/routes.php1
3 files changed, 144 insertions, 0 deletions
diff --git a/core/Controller/AppPasswordController.php b/core/Controller/AppPasswordController.php
index a4b7791997a..2575729fe85 100644
--- a/core/Controller/AppPasswordController.php
+++ b/core/Controller/AppPasswordController.php
@@ -31,7 +31,9 @@ namespace OC\Core\Controller;
use OC\Authentication\Events\AppPasswordCreatedEvent;
use OC\Authentication\Token\IProvider;
use OC\Authentication\Token\IToken;
+use OC\User\Session;
use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\Attribute\UseSession;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCS\OCSForbiddenException;
use OCP\Authentication\Exceptions\CredentialsUnavailableException;
@@ -41,6 +43,8 @@ use OCP\Authentication\LoginCredentials\IStore;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IRequest;
use OCP\ISession;
+use OCP\IUserManager;
+use OCP\Security\Bruteforce\IThrottler;
use OCP\Security\ISecureRandom;
class AppPasswordController extends \OCP\AppFramework\OCSController {
@@ -52,6 +56,9 @@ class AppPasswordController extends \OCP\AppFramework\OCSController {
private IProvider $tokenProvider,
private IStore $credentialStore,
private IEventDispatcher $eventDispatcher,
+ private Session $userSession,
+ private IUserManager $userManager,
+ private IThrottler $throttler,
) {
parent::__construct($appName, $request);
}
@@ -165,4 +172,33 @@ class AppPasswordController extends \OCP\AppFramework\OCSController {
'apppassword' => $newToken,
]);
}
+
+ /**
+ * Confirm the user password
+ *
+ * @NoAdminRequired
+ * @BruteForceProtection(action=sudo)
+ *
+ * @param string $password The password of the user
+ *
+ * @return DataResponse<Http::STATUS_OK, array{lastLogin: int}, array{}>|DataResponse<Http::STATUS_FORBIDDEN, array<empty>, array{}>
+ *
+ * 200: Password confirmation succeeded
+ * 403: Password confirmation failed
+ */
+ #[UseSession]
+ public function confirmUserPassword(string $password): DataResponse {
+ $loginName = $this->userSession->getLoginName();
+ $loginResult = $this->userManager->checkPassword($loginName, $password);
+ if ($loginResult === false) {
+ $response = new DataResponse([], Http::STATUS_FORBIDDEN);
+ $response->throttle(['loginName' => $loginName]);
+ return $response;
+ }
+
+ $confirmTimestamp = time();
+ $this->session->set('last-password-confirm', $confirmTimestamp);
+ $this->throttler->resetDelay($this->request->getRemoteAddress(), 'sudo', ['loginName' => $loginName]);
+ return new DataResponse(['lastLogin' => $confirmTimestamp], Http::STATUS_OK);
+ }
}
diff --git a/core/openapi.json b/core/openapi.json
index 9bfee0d40b9..5a33f547a92 100644
--- a/core/openapi.json
+++ b/core/openapi.json
@@ -2475,6 +2475,113 @@
}
}
},
+ "/ocs/v2.php/core/apppassword/confirm": {
+ "put": {
+ "operationId": "app_password-confirm-user-password",
+ "summary": "Confirm the user password",
+ "tags": [
+ "app_password"
+ ],
+ "security": [
+ {
+ "bearer_auth": []
+ },
+ {
+ "basic_auth": []
+ }
+ ],
+ "parameters": [
+ {
+ "name": "password",
+ "in": "query",
+ "description": "The password of the user",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "OCS-APIRequest",
+ "in": "header",
+ "description": "Required to be true for the API request to pass",
+ "required": true,
+ "schema": {
+ "type": "boolean",
+ "default": true
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Password confirmation succeeded",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "ocs"
+ ],
+ "properties": {
+ "ocs": {
+ "type": "object",
+ "required": [
+ "meta",
+ "data"
+ ],
+ "properties": {
+ "meta": {
+ "$ref": "#/components/schemas/OCSMeta"
+ },
+ "data": {
+ "type": "object",
+ "required": [
+ "lastLogin"
+ ],
+ "properties": {
+ "lastLogin": {
+ "type": "integer",
+ "format": "int64"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Password confirmation failed",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "required": [
+ "ocs"
+ ],
+ "properties": {
+ "ocs": {
+ "type": "object",
+ "required": [
+ "meta",
+ "data"
+ ],
+ "properties": {
+ "meta": {
+ "$ref": "#/components/schemas/OCSMeta"
+ },
+ "data": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"/ocs/v2.php/hovercard/v1/{userId}": {
"get": {
"operationId": "hover_card-get-user",
diff --git a/core/routes.php b/core/routes.php
index fe1fe6fcd75..9f8bc5c2c1e 100644
--- a/core/routes.php
+++ b/core/routes.php
@@ -123,6 +123,7 @@ $application->registerRoutes($this, [
['root' => '/core', 'name' => 'AppPassword#getAppPassword', 'url' => '/getapppassword', 'verb' => 'GET'],
['root' => '/core', 'name' => 'AppPassword#rotateAppPassword', 'url' => '/apppassword/rotate', 'verb' => 'POST'],
['root' => '/core', 'name' => 'AppPassword#deleteAppPassword', 'url' => '/apppassword', 'verb' => 'DELETE'],
+ ['root' => '/core', 'name' => 'AppPassword#confirmUserPassword', 'url' => '/apppassword/confirm', 'verb' => 'PUT'],
['root' => '/hovercard', 'name' => 'HoverCard#getUser', 'url' => '/v1/{userId}', 'verb' => 'GET'],