-
Notifications
You must be signed in to change notification settings - Fork 344
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rework Authentication into separate services
This is a from-scratch rewrite, moving a bit closer to Single Responsibility Principle. We split handling of credentials-in-config and always-open authentication systems. In the future, we will be able implement more methods this way. This was motivated by session code being called in constructor, which would break in CLI with Tracy strict mode. For now, we are just porting the Authentication helper and controller. Additionally: - Session verification now also checks if the credentials in the config did not change. - Requests from loopback IP address now give full access to all operations, not just update. - IPv6 loopback address is recognized as well. - Requests forwarded by proxies are filtered out since local reverse proxies might come from loopback as well. One thing I do not like that any request with credentials will automatically persist the login to session but removing that feature can be done later.
- Loading branch information
Showing
11 changed files
with
299 additions
and
107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?php | ||
|
||
// SPDX-FileCopyrightText: 2024 Jan Tojnar <jtojnar@gmail.com> | ||
// SPDX-License-Identifier: GPL-3.0-or-later | ||
|
||
declare(strict_types=1); | ||
|
||
namespace helpers\Authentication; | ||
|
||
use helpers\Configuration; | ||
use Psr\Container\ContainerInterface; | ||
|
||
/** | ||
* Factory that creates `AuthenticationService` based on the configuration. | ||
*/ | ||
final class AuthenticationFactory { | ||
private Configuration $configuration; | ||
private ContainerInterface $container; | ||
|
||
public function __construct(Configuration $configuration, ContainerInterface $container) { | ||
$this->configuration = $configuration; | ||
$this->container = $container; | ||
} | ||
|
||
public function create(): AuthenticationService { | ||
if (!$this->useCredentials() || $this->isCli() || $this->isLocalIp()) { | ||
return $this->container->get(Services\Trust::class); | ||
} | ||
|
||
return $this->container->get(Services\RequestOrSession::class); | ||
} | ||
|
||
private function isCli(): bool { | ||
return PHP_SAPI === 'cli'; | ||
} | ||
|
||
private function isLocalIp(): bool { | ||
// We cannot trust these IP addresses but we know they are likely not local. | ||
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) || isset($_SERVER['HTTP_FORWARDED'])) { | ||
return false; | ||
} | ||
|
||
return $_SERVER['REMOTE_ADDR'] === '::1' || $_SERVER['REMOTE_ADDR'] === '127.0.0.1'; | ||
} | ||
|
||
private function useCredentials(): bool { | ||
return strlen($this->configuration->username) > 0 && strlen($this->configuration->password) > 0; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php | ||
|
||
// SPDX-FileCopyrightText: 2024 Jan Tojnar <jtojnar@gmail.com> | ||
// SPDX-License-Identifier: GPL-3.0-or-later | ||
|
||
declare(strict_types=1); | ||
|
||
namespace helpers\Authentication; | ||
|
||
/** | ||
* Must be implemented by any authentication service. | ||
*/ | ||
interface AuthenticationService { | ||
/** | ||
* Checks whether user is authorized to read (logged in/public mode). | ||
*/ | ||
public function canRead(): bool; | ||
|
||
/** | ||
* Checks whether user is authorized to update sources (logged in/public update mode). | ||
*/ | ||
public function canUpdate(): bool; | ||
|
||
/** | ||
* Checks whether user is authorized to perform a privileged action | ||
* or access privileged information. | ||
*/ | ||
public function isPrivileged(): bool; | ||
|
||
/** | ||
* Give up authorization. | ||
*/ | ||
public function destroy(): void; | ||
} |
Oops, something went wrong.