* @throws OCSForbiddenException Creating app password is not allowed * * 200: App password returned */ #[NoAdminRequired] #[PasswordConfirmationRequired] #[ApiRoute(verb: 'GET', url: '/getapppassword', root: '/core')] public function getAppPassword(): DataResponse { // We do not allow the creation of new tokens if this is an app password if ($this->session->exists('app_password')) { throw new OCSForbiddenException('You cannot request an new apppassword with an apppassword'); } try { $credentials = $this->credentialStore->getLoginCredentials(); } catch (CredentialsUnavailableException $e) { throw new OCSForbiddenException(); } try { $password = $credentials->getPassword(); } catch (PasswordUnavailableException $e) { $password = null; } $userAgent = $this->request->getHeader('USER_AGENT'); $token = $this->random->generate(72, ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_DIGITS); $generatedToken = $this->tokenProvider->generateToken( $token, $credentials->getUID(), $credentials->getLoginName(), $password, $userAgent, IToken::PERMANENT_TOKEN, IToken::DO_NOT_REMEMBER ); $this->eventDispatcher->dispatchTyped( new AppPasswordCreatedEvent($generatedToken) ); return new DataResponse([ 'apppassword' => $token ]); } /** * Delete app password * * @return DataResponse, array{}> * @throws OCSForbiddenException Deleting app password is not allowed * * 200: App password deleted successfully */ #[NoAdminRequired] #[ApiRoute(verb: 'DELETE', url: '/apppassword', root: '/core')] public function deleteAppPassword(): DataResponse { if (!$this->session->exists('app_password')) { throw new OCSForbiddenException('no app password in use'); } $appPassword = $this->session->get('app_password'); try { $token = $this->tokenProvider->getToken($appPassword); } catch (InvalidTokenException $e) { throw new OCSForbiddenException('could not remove apptoken'); } $this->tokenProvider->invalidateTokenById($token->getUID(), $token->getId()); return new DataResponse(); } /** * Rotate app password * * @return DataResponse * @throws OCSForbiddenException Rotating app password is not allowed * * 200: App password returned */ #[NoAdminRequired] #[ApiRoute(verb: 'POST', url: '/apppassword/rotate', root: '/core')] public function rotateAppPassword(): DataResponse { if (!$this->session->exists('app_password')) { throw new OCSForbiddenException('no app password in use'); } $appPassword = $this->session->get('app_password'); try { $token = $this->tokenProvider->getToken($appPassword); } catch (InvalidTokenException $e) { throw new OCSForbiddenException('could not rotate apptoken'); } $newToken = $this->random->generate(72, ISecureRandom::CHAR_UPPER . ISecureRandom::CHAR_LOWER . ISecureRandom::CHAR_DIGITS); $this->tokenProvider->rotate($token, $appPassword, $newToken); return new DataResponse([ 'apppassword' => $newToken, ]); } /** * Confirm the user password * * @param string $password The password of the user * * @return DataResponse|DataResponse, array{}> * * 200: Password confirmation succeeded * 403: Password confirmation failed */ #[NoAdminRequired] #[BruteForceProtection(action: 'sudo')] #[UseSession] #[ApiRoute(verb: 'PUT', url: '/apppassword/confirm', root: '/core')] 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); } } _storage-squashed'>artonge/feat/implement_custom_updater_for_object_storage-squashed Nextcloud server, a safe home for all your data: https://github.com/nextcloud/serverwww-data
aboutsummaryrefslogtreecommitdiffstats
blob: 35606dc6384b33a8788a4aab455d97b2b33a85e7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<?php

declare(strict_types=1);

/**
 * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */

namespace Tests\Core\Controller;

use OC\Core\Controller\WellKnownController;
use OC\Http\WellKnown\RequestManager;
use OCP\AppFramework\Http\JSONResponse;
use OCP\Http\WellKnown\IResponse;
use OCP\IRequest;
use PHPUnit\Framework\MockObject\MockObject;
use Test\TestCase;

class WellKnownControllerTest extends TestCase {
	/** @var IRequest|MockObject */
	private $request;

	/** @var RequestManager|MockObject */
	private $manager;

	/** @var WellKnownController */
	private $controller;

	protected function setUp(): void {
		parent::setUp();

		$this->request = $this->createMock(IRequest::class);
		$this->manager = $this->createMock(RequestManager::class);

		$this->controller = new WellKnownController(
			$this->request,
			$this->manager,
		);
	}

	public function testHandleNotProcessed(): void {
		$httpResponse = $this->controller->handle('nodeinfo');

		self::assertInstanceOf(JSONResponse::class, $httpResponse);
		self::assertArrayHasKey('X-NEXTCLOUD-WELL-KNOWN', $httpResponse->getHeaders());
	}

	public function testHandle(): void {
		$response = $this->createMock(IResponse::class);
		$jsonResponse = $this->createMock(JSONResponse::class);
		$response->expects(self::once())
			->method('toHttpResponse')
			->willReturn($jsonResponse);
		$this->manager->expects(self::once())
			->method('process')
			->with(
				'nodeinfo',
				$this->request
			)->willReturn($response);
		$jsonResponse->expects(self::once())
			->method('addHeader')
			->willReturnSelf();

		$httpResponse = $this->controller->handle('nodeinfo');

		self::assertInstanceOf(JSONResponse::class, $httpResponse);
	}
}