Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 39b91fd6 authored by Fahim Salam Chowdhury's avatar Fahim Salam Chowdhury 👽
Browse files

fix: validate requested userId with SsoService user

parent 1d08d0fe
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -10,14 +10,14 @@
    <description><![CDATA[in /e/OS cloud, nextcloud accounts are linked to mail accounts. This app ensures both are coordinated: it sets the e-mail address, quota and storage of the user upon creation.
    It also completes the account deletion by cleaning other parts of the /e/OS cloud setup to ensure no more data is retained when a user requests an account deletion.
    This app uses the UserDeletedEvent to invoke scripts in the docker-welcome container of /e/OS cloud setup]]></description>
    <version>10.0.0</version>
    <version>10.0.1</version>
    <licence>agpl</licence>
    <author mail="dev@murena.com" homepage="https://murena.com/">Murena SAS</author>
    <namespace>EcloudAccounts</namespace>
    <category>tools</category>
    <bugs>https://gitlab.e.foundation/e/management/issues</bugs>
    <dependencies>
        <nextcloud min-version="29" max-version="29"/>
        <nextcloud min-version="28" max-version="29"/>
    </dependencies>
	<settings>
		<personal>OCA\EcloudAccounts\Settings\DeleteShopAccountSetting</personal>
+33 −3
Original line number Diff line number Diff line
@@ -20,10 +20,14 @@ class SSOService {
	private array $ssoConfig = [];
	private string $adminAccessToken;
	private string $currentUserId;
	private string $currentUserName;
	private ICrypto $crypto;
	private IFactory $l10nFactory;
	private IUserManager $userManager;

	private string $mainDomain;
	private string $legacyDomain;

	private const ADMIN_TOKEN_ENDPOINT = '/auth/realms/master/protocol/openid-connect/token';
	private const USERS_ENDPOINT = '/users';
	private const CREDENTIALS_ENDPOINT = '/users/{USER_ID}/credentials';
@@ -48,6 +52,9 @@ class SSOService {
		$this->logger = $logger;
		$this->l10nFactory = $l10nFactory;
		$this->userManager = $userManager;

		$this->mainDomain = $this->config->getSystemValue("main_domain");
		$this->legacyDomain = $this->config->getSystemValue("legacy_domain");
	}

	public function shouldSync2FA() : bool {
@@ -55,9 +62,10 @@ class SSOService {
	}

	public function migrateCredential(string $username, string $secret) : void {
		if(empty($this->currentUserId)) {
		if($this->isNotCurrentUser($username)) {
			$this->getUserId($username);
		}

		$this->deleteCredentials($username);

		$decryptedSecret = $this->crypto->decrypt($secret);
@@ -74,9 +82,10 @@ class SSOService {
	}

	public function deleteCredentials(string $username) : void {
		if(empty($this->currentUserId)) {
		if($this->isNotCurrentUser($username)) {
			$this->getUserId($username);
		}

		$credentialIds = $this->getCredentialIds();

		foreach ($credentialIds as $credentialId) {
@@ -89,7 +98,7 @@ class SSOService {
	}

	public function logout(string $username) : void {
		if(empty($this->currentUserId)) {
		if($this->isNotCurrentUser($username)) {
			$this->getUserId($username);
		}

@@ -166,6 +175,11 @@ class SSOService {
			throw new SSOAdminAPIException('Error: no user found for search with url: ' . $url);
		}
		$this->currentUserId = $users[0]['id'];
		$this->currentUserName = $this->sanitizeUserName($users[0]['username']);
		$username = $this->sanitizeUserName($username);
		if ($username !== $this->currentUserName) {
			throw new SSOAdminAPIException('Error: retrieved wrong user info (' . $this->currentUserName . ') from SSO service for ' . $username);
		}
	}

	private function getAdminAccessToken() : void {
@@ -235,4 +249,20 @@ class SSOService {
		$answer = json_decode($answer, true);
		return $answer;
	}

	private function sanitizeUserName(string $username): string {
		$username = strtolower($username);

		if (str_contains($username, "@" . $this->mainDomain) || str_contains($username, "@" . $this->legacyDomain)) {
			list($name, $domain) = explode("@", $username);
			$username = $name;
		}

		return $username;
	}

	private function isNotCurrentUser(string $username): bool {
		$username = $this->sanitizeUserName($username);
		return !(!empty($this->currentUserId) && !empty($this->currentUserName) && $username === $this->currentUserName);
	}
}