Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Most of the time, oAuth2 client capacities on third party websites are available

# Setup

This project uses `league/oauth2-server`, `defuse/php-encryption` and `hassankhan/config` packages; `symfony/yaml` is provided by Galette.
This project uses `league/oauth2-server` and `defuse/php-encryption` packages; `symfony/yaml` is provided by Galette.

To automatically download these packages:
```
Expand Down
46 changes: 13 additions & 33 deletions _dependencies.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,13 @@ function (ContainerInterface $container) {
'lifetime' => (int)$container->get(Preferences::class)->getConfigValue('pref_session_timeout')
]);

$galette_sid = session_id();
//close Galette session; OAuth one has its own cookie, so its identifier can be renewed on login
session_write_close();
session_id('galette-oauth-' . $galette_sid);
$sid = $_COOKIE[$session_name] ?? '';
if (!is_string($sid) || !preg_match('/^[a-zA-Z0-9,-]{22,256}$/', $sid)) {
$sid = session_create_id('galette-oauth-');
}
session_id($sid);
$session->start();

$container->get(Messages::class)->__construct($_SESSION);
Expand All @@ -57,50 +61,26 @@ function (ContainerInterface $container) {

$container->set(
Config::class,
static function (ContainerInterface $container) {
$conf = new GaletteOAuth2\Tools\Config(OAUTH2_CONFIGPATH . '/config.yml');

do {
$key = $conf->key();
$current = $conf->current();
if (isset($current['options'])) {
Analog::log(
'"options" is deprecated, please use "authorize" instead for ' . $key,
Analog::WARNING
);

if (!isset($current['authorize'])) {
$conf->set($key . '.authorize', $current['options']);
}
$conf->remove($key . '.options');
}
} while ($conf->next());

return $conf;
},
static fn() => Config::fromFile(OAUTH2_CONFIGPATH . '/config.yml')
);

$container->set(
AuthorizationServer::class,
function (ContainerInterface $container) {
// Setup the authorization server
$server = new AuthorizationServer(
// instance of ClientRepositoryInterface
new ClientRepository($container),
// instance of AccessTokenRepositoryInterface
new AccessTokenRepository(),
// instance of ScopeRepositoryInterface
new ScopeRepository(),
$container->get(ClientRepository::class),
$container->get(AccessTokenRepository::class),
$container->get(ScopeRepository::class),
// path to private key
'file://' . OAUTH2_CONFIGPATH . '/private.key',
// encryption key
EncryptionKey::load($container->get(Config::class), OAUTH2_CONFIGPATH),
);

$refreshTokenRepository = new RefreshTokenRepository();
$refreshTokenRepository = $container->get(RefreshTokenRepository::class);
$grant = new AuthCodeGrant(
new AuthCodeRepository(),
// instance of RefreshTokenRepositoryInterface
$container->get(AuthCodeRepository::class),
$refreshTokenRepository,
new DateInterval('PT10M'),
);
Expand Down Expand Up @@ -133,7 +113,7 @@ static function (ContainerInterface $container) {
$publicKeyPath = 'file://' . OAUTH2_CONFIGPATH . '/public.key';

return new ResourceServer(
new AccessTokenRepository(),
$container->get(AccessTokenRepository::class),
$publicKeyPath,
);
},
Expand Down
1 change: 0 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"require": {
"php": ">=8.3",
"league/oauth2-server": "^9.4",
"hassankhan/config": "^3.2",
"defuse/php-encryption": "^2.4",
"psr/http-message": "^2.0",
"league/uri": "^7.8",
Expand Down
64 changes: 1 addition & 63 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

86 changes: 44 additions & 42 deletions lib/GaletteOAuth2/Authorization/UserHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
namespace GaletteOAuth2\Authorization;

use Analog\Analog;
use DI\Container;
use DI\Attribute\Inject;
use Galette\Core\Db;
use Galette\Core\History;
use Galette\Core\Login;
Expand All @@ -20,6 +20,7 @@
use Galette\Entity\Social;
use GaletteOAuth2\Tools\Config;
use GaletteOAuth2\Tools\Debug;
use RKA\Session;
use Slim\Flash\Messages;

/**
Expand All @@ -34,28 +35,37 @@ final class UserHelper
public const AUTH_UPTODATE = 'uptodate';
public const AUTH_ACTIVE = 'active';

public static function login(Container $container, string $nick, string $password): int|false
{
$preferences = $container->get(Preferences::class);
/** @var Login $login */
$login = $container->get(Login::class);
$history = $container->get(History::class);
$session = $container->get('oauth_session');
$flash = $container->get(Messages::class);
public function __construct(
private readonly Db $zdb,
private readonly Login $login,
private readonly History $history,
private readonly Preferences $preferences,
private readonly Messages $flash,
#[Inject('oauth_session')]
private readonly Session $session
) {
}

/**
* Log in a member
*
* @return int|false Member ID, false on failure
*/
public function login(string $nick, string $password): int|false
{
if (trim($nick) === '' || trim($password) === '') {
return false;
}

if ($nick === $preferences->pref_admin_login) {
if ($nick === $this->preferences->pref_admin_login) {
$pw_superadmin = password_verify(
$password,
$preferences->pref_admin_pass,
$this->preferences->pref_admin_pass,
);

if (!$pw_superadmin) {
$pw_superadmin = (
md5($password) === $preferences->pref_admin_pass
md5($password) === $this->preferences->pref_admin_pass
);
}

Expand All @@ -64,65 +74,57 @@ public static function login(Container $container, string $nick, string $passwor
'OAuth login attempt from superadmin account',
Analog::WARNING
);
$flash->addMessage(
$this->flash->addMessage(
'error_detected',
_T('Cannot OAuth login from superadmin account!', 'oauth2')
);
return false;
}
} else {
$login->logIn($nick, $password);
$this->login->logIn($nick, $password);
}

if ($login->isLogged()) {
$session->login = $login;
$history->add(_T('Login'));
if ($this->login->isLogged()) {
$this->session->login = $this->login;
$this->history->add(_T('Login'));

return $login->id;
return $this->login->id;
}
$history->add(_T('Authentication failed'), $nick);
$this->history->add(_T('Authentication failed'), $nick);

$flash->addMessage(
$this->flash->addMessage(
'error_detected',
_T('Check your login / email or password.', 'oauth2')
);

return false;
}

public static function logout(Container $container): void
/**
* Log out current member
*/
public function logout(): void
{
/** @var Login $login */
$login = $container->get(Login::class);
$history = $container->get(History::class);
$session = $container->get('oauth_session');

$login->logout();
$session->login = $login;
$history->add(_T('Logout'));
$this->login->logout();
$this->session->login = $this->login;
$this->history->add(_T('Logout'));
}

/**
* Get user data
*
* @param Container $container Container instance
* @param int $id User ID
* @param string $acl Requested authorization
* @param string[] $scopes Scopes
* @param bool $legacy Legacy mode for data
* @param int $id User ID
* @param string $acl Requested authorization
* @param string[] $scopes Scopes
* @param bool $legacy Legacy mode for data
*
* @return array<string, mixed>
* @throws UserAuthorizationException
* @throws \DI\DependencyException
* @throws \DI\NotFoundException
* @throws \Throwable
*/
public static function getUserData(Container $container, int $id, string $acl, array $scopes, bool $legacy = false): array
public function getUserData(int $id, string $acl, array $scopes, bool $legacy = false): array
{
/** @var Db $zdb */
$zdb = $container->get(Db::class);

$member = new Adherent($zdb);
$member = new Adherent($this->zdb);
if (!$member->load($id)) {
throw new UserAuthorizationException(_T('User not found.', 'oauth2'));
}
Expand Down Expand Up @@ -347,7 +349,7 @@ public static function getAuthorization(Config $config, string $client_id): stri
$acl = self::AUTH_TEAMONLY;
$conf_acls = $config->get($client_id . '.authorize');

if ($conf_acls === '') {
if ($conf_acls === null) {
//not set: use default
return $acl;
}
Expand Down
Loading
Loading