aboutsummaryrefslogtreecommitdiffstats
path: root/apps/oauth2/lib/Db/Client.php
blob: 78f3d966928d6e1aa9efc7c9470a595c4a1047a0 (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
<?php
/**
 * @copyright Copyright (c) 2017 Lukas Reschke <lukas@statuscode.ch>
 *
 * @author Lukas Reschke <lukas@statuscode.ch>
 *
 * @license GNU AGPL version 3 or any later version
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 */
namespace OCA\OAuth2\Db;

use OCP\AppFramework\Db\Entity;

/**
 * @method string getClientIdentifier()
 * @method void setClientIdentifier(string $identifier)
 * @method string getSecret()
 * @method void setSecret(string $secret)
 * @method string getRedirectUri()
 * @method void setRedirectUri(string $redirectUri)
 * @method string getName()
 * @method void setName(string $name)
 */
class Client extends Entity {
	/** @var string */
	protected $name;
	/** @var string */
	protected $redirectUri;
	/** @var string */
	protected $clientIdentifier;
	/** @var string */
	protected $secret;

	public function __construct() {
		$this->addType('id', 'int');
		$this->addType('name', 'string');
		$this->addType('redirectUri', 'string');
		$this->addType('clientIdentifier', 'string');
		$this->addType('secret', 'string');
	}
}
s="nx">OC\Authentication\Token\IToken; use OC\User\Session; use OCP\AppFramework\Http; use OCP\AppFramework\Http\Attribute\ApiRoute; use OCP\AppFramework\Http\Attribute\BruteForceProtection; use OCP\AppFramework\Http\Attribute\NoAdminRequired; use OCP\AppFramework\Http\Attribute\PasswordConfirmationRequired; use OCP\AppFramework\Http\Attribute\UseSession; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCS\OCSForbiddenException; use OCP\Authentication\Exceptions\CredentialsUnavailableException; use OCP\Authentication\Exceptions\InvalidTokenException; use OCP\Authentication\Exceptions\PasswordUnavailableException; 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 { public function __construct( string $appName, IRequest $request, private ISession $session, private ISecureRandom $random, private IProvider $tokenProvider, private IStore $credentialStore, private IEventDispatcher $eventDispatcher, private Session $userSession, private IUserManager $userManager, private IThrottler $throttler, ) { parent::__construct($appName, $request); } /** * Create app password * * @return DataResponse<Http::STATUS_OK, array{apppassword: string}, array{}> * @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<Http::STATUS_OK, list<empty>, 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<Http::STATUS_OK, array{apppassword: string}, array{}> * @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<Http::STATUS_OK, array{lastLogin: int}, array{}>|DataResponse<Http::STATUS_FORBIDDEN, list<empty>, 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); } }