[PLUGIN][OAuth2] Fix some static issues
This commit is contained in:
parent
4dd976eb22
commit
81f6d496c6
|
@ -78,7 +78,8 @@ class Authorize extends Controller
|
||||||
public function __construct(private int $id)
|
public function __construct(private int $id)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
public function getIdentifier()
|
|
||||||
|
public function getIdentifier(): int
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,8 @@ use App\Core\DB\DB;
|
||||||
use function App\Core\I18n\_m;
|
use function App\Core\I18n\_m;
|
||||||
use App\Core\Log;
|
use App\Core\Log;
|
||||||
use App\Util\Exception\ClientException;
|
use App\Util\Exception\ClientException;
|
||||||
|
use App\Util\Exception\ServerException;
|
||||||
|
use Exception;
|
||||||
use Plugin\OAuth2\Entity;
|
use Plugin\OAuth2\Entity;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
@ -50,6 +52,11 @@ use Symfony\Component\HttpFoundation\Request;
|
||||||
*/
|
*/
|
||||||
class Client extends Controller
|
class Client extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @throws ClientException
|
||||||
|
* @throws Exception
|
||||||
|
* @throws ServerException
|
||||||
|
*/
|
||||||
public function onPost(Request $request): JsonResponse
|
public function onPost(Request $request): JsonResponse
|
||||||
{
|
{
|
||||||
Log::debug('OAuth2 Apps: Received a POST request.');
|
Log::debug('OAuth2 Apps: Received a POST request.');
|
||||||
|
@ -60,8 +67,9 @@ class Client extends Controller
|
||||||
throw new ClientException(_m('Invalid request'), code: 400);
|
throw new ClientException(_m('Invalid request'), code: 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
$identifier = hash('sha256', random_bytes(16)); // TODO maybe use password_hash and verify
|
$identifier = hash('md5', random_bytes(16));
|
||||||
$secret = hash('sha256', random_bytes(64));
|
// Random string Length should be between 43 and 128, thus 57
|
||||||
|
$secret = hash('sha256', random_bytes(57));
|
||||||
|
|
||||||
// TODO more validation
|
// TODO more validation
|
||||||
$client = Entity\Client::create([
|
$client = Entity\Client::create([
|
||||||
|
|
|
@ -34,6 +34,7 @@ namespace Plugin\OAuth2\Entity;
|
||||||
use DateTimeInterface;
|
use DateTimeInterface;
|
||||||
use League\OAuth2\Server\CryptKey;
|
use League\OAuth2\Server\CryptKey;
|
||||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||||
|
use Plugin\OAuth2\Util\Token;
|
||||||
|
|
||||||
class AccessToken extends Token implements AccessTokenEntityInterface
|
class AccessToken extends Token implements AccessTokenEntityInterface
|
||||||
{
|
{
|
||||||
|
@ -47,20 +48,14 @@ class AccessToken extends Token implements AccessTokenEntityInterface
|
||||||
private bool $revoked;
|
private bool $revoked;
|
||||||
private DateTimeInterface $created;
|
private DateTimeInterface $created;
|
||||||
|
|
||||||
public function setId(string $id): self
|
|
||||||
{
|
|
||||||
$this->id = mb_substr($id, 0, 64);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getId(): string
|
public function getId(): string
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setExpiry(DateTimeInterface $expiry): self
|
public function setId(string $id): self
|
||||||
{
|
{
|
||||||
$this->expiry = $expiry;
|
$this->id = mb_substr($id, 0, 64);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,9 +64,9 @@ class AccessToken extends Token implements AccessTokenEntityInterface
|
||||||
return $this->expiry;
|
return $this->expiry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setUserId(?int $user_id): self
|
public function setExpiry(DateTimeInterface $expiry): self
|
||||||
{
|
{
|
||||||
$this->user_id = $user_id;
|
$this->expiry = $expiry;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,9 +75,9 @@ class AccessToken extends Token implements AccessTokenEntityInterface
|
||||||
return $this->user_id;
|
return $this->user_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setClientId(string $client_id): self
|
public function setUserId(?int $user_id): self
|
||||||
{
|
{
|
||||||
$this->client_id = mb_substr($client_id, 0, 64);
|
$this->user_id = $user_id;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,9 +86,9 @@ class AccessToken extends Token implements AccessTokenEntityInterface
|
||||||
return $this->client_id;
|
return $this->client_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setTokenScopes(string $token_scopes): self
|
public function setClientId(string $client_id): self
|
||||||
{
|
{
|
||||||
$this->token_scopes = $token_scopes;
|
$this->client_id = mb_substr($client_id, 0, 64);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,9 +97,9 @@ class AccessToken extends Token implements AccessTokenEntityInterface
|
||||||
return $this->token_scopes;
|
return $this->token_scopes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setRevoked(bool $revoked): self
|
public function setTokenScopes(string $token_scopes): self
|
||||||
{
|
{
|
||||||
$this->revoked = $revoked;
|
$this->token_scopes = $token_scopes;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,9 +108,9 @@ class AccessToken extends Token implements AccessTokenEntityInterface
|
||||||
return $this->revoked;
|
return $this->revoked;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setCreated(DateTimeInterface $created): self
|
public function setRevoked(bool $revoked): self
|
||||||
{
|
{
|
||||||
$this->created = $created;
|
$this->revoked = $revoked;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,13 +119,19 @@ class AccessToken extends Token implements AccessTokenEntityInterface
|
||||||
return $this->created;
|
return $this->created;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setCreated(DateTimeInterface $created): self
|
||||||
|
{
|
||||||
|
$this->created = $created;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
// @codeCoverageIgnoreEnd
|
// @codeCoverageIgnoreEnd
|
||||||
// }}} Autocode
|
// }}} Autocode
|
||||||
|
|
||||||
public CryptKey $private_key;
|
public CryptKey $private_key;
|
||||||
public function setPrivateKey(CryptKey $private_key)
|
public function setPrivateKey(CryptKey $privateKey)
|
||||||
{
|
{
|
||||||
$this->private_key = $private_key;
|
$this->private_key = $privateKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __toString()
|
public function __toString()
|
||||||
|
|
|
@ -34,6 +34,7 @@ namespace Plugin\OAuth2\Entity;
|
||||||
use DateTimeInterface;
|
use DateTimeInterface;
|
||||||
use League\OAuth2\Server\Entities\AuthCodeEntityInterface;
|
use League\OAuth2\Server\Entities\AuthCodeEntityInterface;
|
||||||
use Plugin\OAuth2\Repository;
|
use Plugin\OAuth2\Repository;
|
||||||
|
use Plugin\OAuth2\Util\Token;
|
||||||
|
|
||||||
class AuthCode extends Token implements AuthCodeEntityInterface
|
class AuthCode extends Token implements AuthCodeEntityInterface
|
||||||
{
|
{
|
||||||
|
@ -47,20 +48,14 @@ class AuthCode extends Token implements AuthCodeEntityInterface
|
||||||
private bool $revoked;
|
private bool $revoked;
|
||||||
private DateTimeInterface $created;
|
private DateTimeInterface $created;
|
||||||
|
|
||||||
public function setId(string $id): self
|
|
||||||
{
|
|
||||||
$this->id = mb_substr($id, 0, 64);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getId(): string
|
public function getId(): string
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setExpiry(DateTimeInterface $expiry): self
|
public function setId(string $id): self
|
||||||
{
|
{
|
||||||
$this->expiry = $expiry;
|
$this->id = mb_substr($id, 0, 64);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,9 +64,9 @@ class AuthCode extends Token implements AuthCodeEntityInterface
|
||||||
return $this->expiry;
|
return $this->expiry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setUserId(?int $user_id): self
|
public function setExpiry(DateTimeInterface $expiry): self
|
||||||
{
|
{
|
||||||
$this->user_id = $user_id;
|
$this->expiry = $expiry;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,20 +75,9 @@ class AuthCode extends Token implements AuthCodeEntityInterface
|
||||||
return $this->user_id;
|
return $this->user_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setClientId(string $client_id): self
|
public function setUserId(?int $user_id): self
|
||||||
{
|
{
|
||||||
$this->client_id = mb_substr($client_id, 0, 64);
|
$this->user_id = $user_id;
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getClientId(): string
|
|
||||||
{
|
|
||||||
return $this->client_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setTokenScopes(string $token_scopes): self
|
|
||||||
{
|
|
||||||
$this->token_scopes = $token_scopes;
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,9 +86,9 @@ class AuthCode extends Token implements AuthCodeEntityInterface
|
||||||
return $this->token_scopes;
|
return $this->token_scopes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setRevoked(bool $revoked): self
|
public function setTokenScopes(string $token_scopes): self
|
||||||
{
|
{
|
||||||
$this->revoked = $revoked;
|
$this->token_scopes = $token_scopes;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,9 +97,9 @@ class AuthCode extends Token implements AuthCodeEntityInterface
|
||||||
return $this->revoked;
|
return $this->revoked;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setCreated(DateTimeInterface $created): self
|
public function setRevoked(bool $revoked): self
|
||||||
{
|
{
|
||||||
$this->created = $created;
|
$this->revoked = $revoked;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,25 +108,38 @@ class AuthCode extends Token implements AuthCodeEntityInterface
|
||||||
return $this->created;
|
return $this->created;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setCreated(DateTimeInterface $created): self
|
||||||
|
{
|
||||||
|
$this->created = $created;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
// @codeCoverageIgnoreEnd
|
// @codeCoverageIgnoreEnd
|
||||||
// }}} Autocode
|
// }}} Autocode
|
||||||
|
|
||||||
/**
|
public function getClientId(): string
|
||||||
* @return null|string
|
|
||||||
*/
|
|
||||||
public function getRedirectUri()
|
|
||||||
{
|
{
|
||||||
return (new Repository\Client)->getClientEntity($this->getClientId())->getRedirectUri();
|
return $this->client_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setClientId(string $client_id): self
|
||||||
* @param string $uri
|
{
|
||||||
*/
|
$this->client_id = mb_substr($client_id, 0, 64);
|
||||||
public function setRedirectUri($uri)
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRedirectUri(): ?string
|
||||||
{
|
{
|
||||||
/** @var Client $client */
|
/** @var Client $client */
|
||||||
$client = (new Repository\Client)->getClientEntity($this->getClientId());
|
$client = (new Repository\Client)->getClientEntity($this->getClientId());
|
||||||
$client->setRedirectUris($uri);
|
return $client->getRedirectUris();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setRedirectUri($uri): Client
|
||||||
|
{
|
||||||
|
/** @var Client $client */
|
||||||
|
$client = (new Repository\Client)->getClientEntity($this->getClientId());
|
||||||
|
return $client->setRedirectUris($uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function schemaDef(): array
|
public static function schemaDef(): array
|
||||||
|
|
|
@ -52,20 +52,14 @@ class Client extends Entity implements ClientEntityInterface
|
||||||
private DateTimeInterface $created;
|
private DateTimeInterface $created;
|
||||||
private DateTimeInterface $modified;
|
private DateTimeInterface $modified;
|
||||||
|
|
||||||
public function setId(string $id): self
|
|
||||||
{
|
|
||||||
$this->id = mb_substr($id, 0, 64);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getId(): string
|
public function getId(): string
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setSecret(string $secret): self
|
public function setId(string $id): self
|
||||||
{
|
{
|
||||||
$this->secret = mb_substr($secret, 0, 64);
|
$this->id = mb_substr($id, 0, 64);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,9 +68,9 @@ class Client extends Entity implements ClientEntityInterface
|
||||||
return $this->secret;
|
return $this->secret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setActive(bool $active): self
|
public function setSecret(string $secret): self
|
||||||
{
|
{
|
||||||
$this->active = $active;
|
$this->secret = mb_substr($secret, 0, 64);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,9 +79,9 @@ class Client extends Entity implements ClientEntityInterface
|
||||||
return $this->active;
|
return $this->active;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setPlainPcke(bool $plain_pcke): self
|
public function setActive(bool $active): self
|
||||||
{
|
{
|
||||||
$this->plain_pcke = $plain_pcke;
|
$this->active = $active;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,9 +90,9 @@ class Client extends Entity implements ClientEntityInterface
|
||||||
return $this->plain_pcke;
|
return $this->plain_pcke;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setIsConfidential(bool $is_confidential): self
|
public function setPlainPcke(bool $plain_pcke): self
|
||||||
{
|
{
|
||||||
$this->is_confidential = $is_confidential;
|
$this->plain_pcke = $plain_pcke;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,9 +101,9 @@ class Client extends Entity implements ClientEntityInterface
|
||||||
return $this->is_confidential;
|
return $this->is_confidential;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setRedirectUris(string $redirect_uris): self
|
public function setIsConfidential(bool $is_confidential): self
|
||||||
{
|
{
|
||||||
$this->redirect_uris = $redirect_uris;
|
$this->is_confidential = $is_confidential;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,9 +112,9 @@ class Client extends Entity implements ClientEntityInterface
|
||||||
return $this->redirect_uris;
|
return $this->redirect_uris;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setGrants(string $grants): self
|
public function setRedirectUris(string $redirect_uris): self
|
||||||
{
|
{
|
||||||
$this->grants = $grants;
|
$this->redirect_uris = $redirect_uris;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,9 +123,9 @@ class Client extends Entity implements ClientEntityInterface
|
||||||
return $this->grants;
|
return $this->grants;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setScopes(string $scopes): self
|
public function setGrants(string $grants): self
|
||||||
{
|
{
|
||||||
$this->scopes = $scopes;
|
$this->grants = $grants;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,6 +134,12 @@ class Client extends Entity implements ClientEntityInterface
|
||||||
return $this->scopes;
|
return $this->scopes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setScopes(string $scopes): self
|
||||||
|
{
|
||||||
|
$this->scopes = $scopes;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function setClientName(string $client_name): self
|
public function setClientName(string $client_name): self
|
||||||
{
|
{
|
||||||
$this->client_name = mb_substr($client_name, 0, 191);
|
$this->client_name = mb_substr($client_name, 0, 191);
|
||||||
|
@ -151,20 +151,14 @@ class Client extends Entity implements ClientEntityInterface
|
||||||
return $this->client_name;
|
return $this->client_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setWebsite(?string $website): self
|
|
||||||
{
|
|
||||||
$this->website = $website;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getWebsite(): ?string
|
public function getWebsite(): ?string
|
||||||
{
|
{
|
||||||
return $this->website;
|
return $this->website;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setCreated(DateTimeInterface $created): self
|
public function setWebsite(?string $website): self
|
||||||
{
|
{
|
||||||
$this->created = $created;
|
$this->website = $website;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,9 +167,9 @@ class Client extends Entity implements ClientEntityInterface
|
||||||
return $this->created;
|
return $this->created;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setModified(DateTimeInterface $modified): self
|
public function setCreated(DateTimeInterface $created): self
|
||||||
{
|
{
|
||||||
$this->modified = $modified;
|
$this->created = $created;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,6 +178,11 @@ class Client extends Entity implements ClientEntityInterface
|
||||||
return $this->modified;
|
return $this->modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setModified(DateTimeInterface $modified): self
|
||||||
|
{
|
||||||
|
$this->modified = $modified;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
// @codeCoverageIgnoreEnd
|
// @codeCoverageIgnoreEnd
|
||||||
// }}} Autocode
|
// }}} Autocode
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,11 @@ declare(strict_types = 1);
|
||||||
namespace Plugin\OAuth2\Entity;
|
namespace Plugin\OAuth2\Entity;
|
||||||
|
|
||||||
use App\Core\Entity;
|
use App\Core\Entity;
|
||||||
|
use DateTimeImmutable;
|
||||||
use DateTimeInterface;
|
use DateTimeInterface;
|
||||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||||
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
|
use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
|
||||||
|
use Plugin\OAuth2\Repository;
|
||||||
|
|
||||||
class RefreshToken extends Entity implements RefreshTokenEntityInterface
|
class RefreshToken extends Entity implements RefreshTokenEntityInterface
|
||||||
{
|
{
|
||||||
|
@ -46,20 +48,14 @@ class RefreshToken extends Entity implements RefreshTokenEntityInterface
|
||||||
private bool $revoked;
|
private bool $revoked;
|
||||||
private DateTimeInterface $created;
|
private DateTimeInterface $created;
|
||||||
|
|
||||||
public function setId(string $id): self
|
|
||||||
{
|
|
||||||
$this->id = mb_substr($id, 0, 64);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getId(): string
|
public function getId(): string
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setExpiry(DateTimeInterface $expiry): self
|
public function setId(string $id): self
|
||||||
{
|
{
|
||||||
$this->expiry = $expiry;
|
$this->id = mb_substr($id, 0, 64);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,9 +64,9 @@ class RefreshToken extends Entity implements RefreshTokenEntityInterface
|
||||||
return $this->expiry;
|
return $this->expiry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setAccessTokenId(?string $access_token_id): self
|
public function setExpiry(DateTimeInterface $expiry): self
|
||||||
{
|
{
|
||||||
$this->access_token_id = \is_null($access_token_id) ? null : mb_substr($access_token_id, 0, 64);
|
$this->expiry = $expiry;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,9 +75,9 @@ class RefreshToken extends Entity implements RefreshTokenEntityInterface
|
||||||
return $this->access_token_id;
|
return $this->access_token_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setRevoked(bool $revoked): self
|
public function setAccessTokenId(?string $access_token_id): self
|
||||||
{
|
{
|
||||||
$this->revoked = $revoked;
|
$this->access_token_id = \is_null($access_token_id) ? null : mb_substr($access_token_id, 0, 64);
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,9 +86,9 @@ class RefreshToken extends Entity implements RefreshTokenEntityInterface
|
||||||
return $this->revoked;
|
return $this->revoked;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setCreated(DateTimeInterface $created): self
|
public function setRevoked(bool $revoked): self
|
||||||
{
|
{
|
||||||
$this->created = $created;
|
$this->revoked = $revoked;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,45 +97,21 @@ class RefreshToken extends Entity implements RefreshTokenEntityInterface
|
||||||
return $this->created;
|
return $this->created;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setCreated(DateTimeInterface $created): self
|
||||||
|
{
|
||||||
|
$this->created = $created;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
// @codeCoverageIgnoreEnd
|
// @codeCoverageIgnoreEnd
|
||||||
// }}} Autocode
|
// }}} Autocode
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the token's identifier.
|
* Get the access token that the refresh token was originally associated with.
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function getIdentifier()
|
public function getAccessToken(): AccessTokenEntityInterface
|
||||||
{
|
{
|
||||||
return $this->getId();
|
return (new Repository\AccessToken())->getAccessTokenEntity($this->getAccessTokenId());
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the token's identifier.
|
|
||||||
*/
|
|
||||||
public function setIdentifier($identifier)
|
|
||||||
{
|
|
||||||
$this->setId($identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the token's expiry date time.
|
|
||||||
*
|
|
||||||
* @return DateTimeImmutable
|
|
||||||
*/
|
|
||||||
public function getExpiryDateTime()
|
|
||||||
{
|
|
||||||
return $this->getExpiry();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the date time when the token expires.
|
|
||||||
*
|
|
||||||
* @param DateTimeImmutable $dateTime
|
|
||||||
*/
|
|
||||||
public function setExpiryDateTime(\DateTimeImmutable $dateTime)
|
|
||||||
{
|
|
||||||
$this->setExpiry($dateTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -150,14 +122,27 @@ class RefreshToken extends Entity implements RefreshTokenEntityInterface
|
||||||
$this->setAccessTokenId($accessToken->getIdentifier());
|
$this->setAccessTokenId($accessToken->getIdentifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function setIdentifier($identifier): self
|
||||||
* Get the access token that the refresh token was originally associated with.
|
|
||||||
*
|
|
||||||
* @return AccessTokenEntityInterface
|
|
||||||
*/
|
|
||||||
public function getAccessToken()
|
|
||||||
{
|
{
|
||||||
return (new Repository\AccessToken)->getAccessTokenEntity($this->getAccessTokenId());
|
return $this->setId($identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getIdentifier(): string
|
||||||
|
{
|
||||||
|
return $this->getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the date time when the token expires.
|
||||||
|
*/
|
||||||
|
public function setExpiryDateTime(DateTimeImmutable $dateTime)
|
||||||
|
{
|
||||||
|
$this->setExpiry($dateTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getExpiryDateTime(): DateTimeImmutable
|
||||||
|
{
|
||||||
|
return DateTimeImmutable::createFromInterface($this->getExpiry());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function schemaDef(): array
|
public static function schemaDef(): array
|
||||||
|
|
|
@ -39,6 +39,7 @@ use App\Core\Router\RouteLoader;
|
||||||
use App\Core\Router\Router;
|
use App\Core\Router\Router;
|
||||||
use App\Util\Common;
|
use App\Util\Common;
|
||||||
use DateInterval;
|
use DateInterval;
|
||||||
|
use Exception;
|
||||||
use League\OAuth2\Server\AuthorizationServer;
|
use League\OAuth2\Server\AuthorizationServer;
|
||||||
use League\OAuth2\Server\CryptKey;
|
use League\OAuth2\Server\CryptKey;
|
||||||
use League\OAuth2\Server\Grant\AuthCodeGrant;
|
use League\OAuth2\Server\Grant\AuthCodeGrant;
|
||||||
|
@ -54,16 +55,19 @@ use XML_XRD_Element_Link;
|
||||||
*/
|
*/
|
||||||
class OAuth2 extends Plugin
|
class OAuth2 extends Plugin
|
||||||
{
|
{
|
||||||
public const OAUTH_REQUEST_TOKEN_REL = 'http://apinamespace.org/oauth/request_token';
|
public const OAUTH_REQUEST_TOKEN_REL = 'http://apinamespace.org/oauth/request_token';
|
||||||
public const OAUTH_ACCESS_TOKEN_REL = 'http://apinamespace.org/oauth/access_token';
|
public const OAUTH_ACCESS_TOKEN_REL = 'http://apinamespace.org/oauth/access_token';
|
||||||
public const OAUTH_AUTHORIZE_REL = 'http://apinamespace.org/oauth/authorize';
|
public const OAUTH_AUTHORIZE_REL = 'http://apinamespace.org/oauth/authorize';
|
||||||
|
public static ?AuthorizationServer $authorization_server = null;
|
||||||
|
|
||||||
public function version(): string
|
public function version(): string
|
||||||
{
|
{
|
||||||
return '3.0.0';
|
return '3.0.0';
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ?AuthorizationServer $authorization_server = null;
|
/**
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
public function onInitializePlugin()
|
public function onInitializePlugin()
|
||||||
{
|
{
|
||||||
self::$authorization_server = new AuthorizationServer(
|
self::$authorization_server = new AuthorizationServer(
|
||||||
|
@ -102,9 +106,9 @@ class OAuth2 extends Plugin
|
||||||
|
|
||||||
public function onEndHostMetaLinks(array &$links): bool
|
public function onEndHostMetaLinks(array &$links): bool
|
||||||
{
|
{
|
||||||
$links[] = new XML_XRD_Element_link(self::OAUTH_REQUEST_TOKEN_REL, Router::url('oauth2_client', type: Router::ABSOLUTE_URL));
|
$links[] = new XML_XRD_Element_Link(self::OAUTH_REQUEST_TOKEN_REL, Router::url('oauth2_client', type: Router::ABSOLUTE_URL));
|
||||||
$links[] = new XML_XRD_Element_link(self::OAUTH_AUTHORIZE_REL, Router::url('oauth2_authorize', type: Router::ABSOLUTE_URL));
|
$links[] = new XML_XRD_Element_Link(self::OAUTH_AUTHORIZE_REL, Router::url('oauth2_authorize', type: Router::ABSOLUTE_URL));
|
||||||
$links[] = new XML_XRD_Element_link(self::OAUTH_ACCESS_TOKEN_REL, Router::url('oauth2_token', type: Router::ABSOLUTE_URL));
|
$links[] = new XML_XRD_Element_Link(self::OAUTH_ACCESS_TOKEN_REL, Router::url('oauth2_token', type: Router::ABSOLUTE_URL));
|
||||||
return Event::next;
|
return Event::next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,10 @@ use Plugin\OAuth2\Entity;
|
||||||
|
|
||||||
class AccessToken implements AccessTokenRepositoryInterface
|
class AccessToken implements AccessTokenRepositoryInterface
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @throws \App\Util\Exception\DuplicateFoundException
|
||||||
|
* @throws \App\Util\Exception\NotFoundException
|
||||||
|
*/
|
||||||
public function getAccessTokenEntity(string $identifier): Entity\AccessToken
|
public function getAccessTokenEntity(string $identifier): Entity\AccessToken
|
||||||
{
|
{
|
||||||
return DB::findOneBy(Entity\AccessToken::class, ['id' => $identifier]);
|
return DB::findOneBy(Entity\AccessToken::class, ['id' => $identifier]);
|
||||||
|
@ -56,12 +60,12 @@ class AccessToken implements AccessTokenRepositoryInterface
|
||||||
// Some logic here to revoke the access token
|
// Some logic here to revoke the access token
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isAccessTokenRevoked($tokenId)
|
public function isAccessTokenRevoked($tokenId): bool
|
||||||
{
|
{
|
||||||
return false; // Access token hasn't been revoked
|
return false; // Access token hasn't been revoked
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getNewToken(ClientEntityInterface $clientEntity, array $scopes, $userIdentifier = null)
|
public function getNewToken(ClientEntityInterface $clientEntity, array $scopes, $userIdentifier = null): Entity\AccessToken
|
||||||
{
|
{
|
||||||
$accessToken = new Entity\AccessToken();
|
$accessToken = new Entity\AccessToken();
|
||||||
$accessToken->setClient($clientEntity);
|
$accessToken->setClient($clientEntity);
|
||||||
|
|
|
@ -50,12 +50,12 @@ class AuthCode implements AuthCodeRepositoryInterface
|
||||||
// Some logic to revoke the auth code in a database
|
// Some logic to revoke the auth code in a database
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isAuthCodeRevoked($codeId)
|
public function isAuthCodeRevoked($codeId): bool
|
||||||
{
|
{
|
||||||
return false; // The auth code has not been revoked
|
return false; // The auth code has not been revoked
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getNewAuthCode()
|
public function getNewAuthCode(): Entity\AuthCode
|
||||||
{
|
{
|
||||||
return new Entity\AuthCode();
|
return new Entity\AuthCode();
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,12 +40,12 @@ use Plugin\OAuth2\Entity;
|
||||||
|
|
||||||
class Client implements ClientRepositoryInterface
|
class Client implements ClientRepositoryInterface
|
||||||
{
|
{
|
||||||
public function getClientEntity($clientIdentifier)
|
/**
|
||||||
{
|
* @param string $clientIdentifier
|
||||||
return DB::findOneBy(Entity\Client::class, ['id' => $clientIdentifier]);
|
* @param null|string $clientSecret
|
||||||
}
|
* @param null|string $grantType
|
||||||
|
*/
|
||||||
public function validateClient($clientIdentifier, $clientSecret, $grantType)
|
public function validateClient($clientIdentifier, $clientSecret, $grantType): bool
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
/** @var Entity\Client $client */
|
/** @var Entity\Client $client */
|
||||||
|
@ -58,4 +58,13 @@ class Client implements ClientRepositoryInterface
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws \App\Util\Exception\DuplicateFoundException
|
||||||
|
* @throws NotFoundException
|
||||||
|
*/
|
||||||
|
public function getClientEntity($clientIdentifier)
|
||||||
|
{
|
||||||
|
return DB::findOneBy(Entity\Client::class, ['id' => $clientIdentifier]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,9 +40,9 @@ use Plugin\OAuth2\Entity;
|
||||||
|
|
||||||
class RefreshToken implements RefreshTokenRepositoryInterface
|
class RefreshToken implements RefreshTokenRepositoryInterface
|
||||||
{
|
{
|
||||||
public function persistNewRefreshToken(RefreshtokenEntityInterface $refreshtokenEntity)
|
public function persistNewRefreshToken(RefreshtokenEntityInterface $refreshTokenEntity)
|
||||||
{
|
{
|
||||||
DB::persist($refreshtokenEntity);
|
DB::persist($refreshTokenEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function revokeRefreshToken($tokenId)
|
public function revokeRefreshToken($tokenId)
|
||||||
|
@ -50,12 +50,12 @@ class RefreshToken implements RefreshTokenRepositoryInterface
|
||||||
// Some logic to revoke the auth token in a database
|
// Some logic to revoke the auth token in a database
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isRefreshtokenRevoked($tokenId)
|
public function isRefreshtokenRevoked($tokenId): bool
|
||||||
{
|
{
|
||||||
return false; // The auth token has not been revoked
|
return false; // The auth token has not been revoked
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getNewRefreshToken()
|
public function getNewRefreshToken(): Entity\RefreshToken
|
||||||
{
|
{
|
||||||
return new Entity\RefreshToken();
|
return new Entity\RefreshToken();
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,9 +40,9 @@ use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
|
||||||
class Scope implements ScopeRepositoryInterface
|
class Scope implements ScopeRepositoryInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @return ?ScopeEntityInterface
|
* @param string $identifier
|
||||||
*/
|
*/
|
||||||
public function getScopeEntityByIdentifier($scopeIdentifier)
|
public function getScopeEntityByIdentifier($identifier): ?ScopeEntityInterface
|
||||||
{
|
{
|
||||||
$scopes = [
|
$scopes = [
|
||||||
'basic' => [
|
'basic' => [
|
||||||
|
@ -62,19 +62,21 @@ class Scope implements ScopeRepositoryInterface
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
if (\array_key_exists($scopeIdentifier, $scopes) === false) {
|
if (\array_key_exists($identifier, $scopes) === false) {
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new class($scopeIdentifier) implements ScopeEntityInterface {
|
return new class($identifier) implements ScopeEntityInterface {
|
||||||
public function __construct(private string $identifier)
|
public function __construct(private string $identifier)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
public function getIdentifier()
|
|
||||||
|
public function getIdentifier(): string
|
||||||
{
|
{
|
||||||
return $this->identifier;
|
return $this->identifier;
|
||||||
}
|
}
|
||||||
public function jsonSerialize(): mixed
|
|
||||||
|
public function jsonSerialize(): string
|
||||||
{
|
{
|
||||||
return $this->getIdentifier();
|
return $this->getIdentifier();
|
||||||
}
|
}
|
||||||
|
@ -86,7 +88,7 @@ class Scope implements ScopeRepositoryInterface
|
||||||
$grantType,
|
$grantType,
|
||||||
ClientEntityInterface $clientEntity,
|
ClientEntityInterface $clientEntity,
|
||||||
$userIdentifier = null,
|
$userIdentifier = null,
|
||||||
) {
|
): array {
|
||||||
return $scopes;
|
return $scopes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,18 +33,19 @@ declare(strict_types = 1);
|
||||||
namespace Plugin\OAuth2\Util;
|
namespace Plugin\OAuth2\Util;
|
||||||
|
|
||||||
use App\Entity\Actor;
|
use App\Entity\Actor;
|
||||||
|
use App\Util\Exception\BugFoundException;
|
||||||
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
|
||||||
use League\OAuth2\Server\ResponseTypes\BearerTokenResponse;
|
use League\OAuth2\Server\ResponseTypes\BearerTokenResponse;
|
||||||
|
|
||||||
class ExpandedBearerTokenResponse extends BearerTokenResponse
|
class ExpandedBearerTokenResponse extends BearerTokenResponse
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @throws BugFoundException
|
||||||
*/
|
*/
|
||||||
protected function getExtraParams(AccessTokenEntityInterface $access_token)
|
protected function getExtraParams(AccessTokenEntityInterface $accessToken): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'me' => Actor::getById($access_token->getUserIdentifier())->getUri(),
|
'me' => Actor::getById($accessToken->getUserIdentifier())->getUri(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,9 +29,10 @@ declare(strict_types = 1);
|
||||||
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
* @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Plugin\OAuth2\Entity;
|
namespace Plugin\OAuth2\Util;
|
||||||
|
|
||||||
use App\Core\Entity;
|
use App\Core\Entity;
|
||||||
|
use DateTimeImmutable;
|
||||||
use Functional as F;
|
use Functional as F;
|
||||||
use League\OAuth2\Server\Entities\ClientEntityInterface;
|
use League\OAuth2\Server\Entities\ClientEntityInterface;
|
||||||
use League\OAuth2\Server\Entities\ScopeEntityInterface;
|
use League\OAuth2\Server\Entities\ScopeEntityInterface;
|
||||||
|
@ -40,7 +41,7 @@ use Plugin\OAuth2\Repository;
|
||||||
|
|
||||||
abstract class Token extends Entity implements TokenInterface
|
abstract class Token extends Entity implements TokenInterface
|
||||||
{
|
{
|
||||||
public function getIdentifier()
|
public function getIdentifier(): string
|
||||||
{
|
{
|
||||||
return $this->getId();
|
return $this->getId();
|
||||||
}
|
}
|
||||||
|
@ -52,20 +53,16 @@ abstract class Token extends Entity implements TokenInterface
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the token's expiry date time.
|
* Get the token's expiry date time.
|
||||||
*
|
|
||||||
* @return DateTimeImmutable
|
|
||||||
*/
|
*/
|
||||||
public function getExpiryDateTime()
|
public function getExpiryDateTime(): DateTimeImmutable
|
||||||
{
|
{
|
||||||
return $this->getExpiry();
|
return $this->getExpiry();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the date time when the token expires.
|
* Set the date time when the token expires.
|
||||||
*
|
|
||||||
* @param DateTimeImmutable $dateTime
|
|
||||||
*/
|
*/
|
||||||
public function setExpiryDateTime(\DateTimeImmutable $dateTime)
|
public function setExpiryDateTime(DateTimeImmutable $dateTime)
|
||||||
{
|
{
|
||||||
$this->setExpiry($dateTime);
|
$this->setExpiry($dateTime);
|
||||||
}
|
}
|
||||||
|
@ -82,20 +79,16 @@ abstract class Token extends Entity implements TokenInterface
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the token user's identifier.
|
* Get the token user's identifier.
|
||||||
*
|
|
||||||
* @return null|int|string
|
|
||||||
*/
|
*/
|
||||||
public function getUserIdentifier()
|
public function getUserIdentifier(): int|string|null
|
||||||
{
|
{
|
||||||
return $this->getUserId();
|
return $this->getUserId();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the client that the token was issued to.
|
* Get the client that the token was issued to.
|
||||||
*
|
|
||||||
* @return ClientEntityInterface
|
|
||||||
*/
|
*/
|
||||||
public function getClient()
|
public function getClient(): ClientEntityInterface
|
||||||
{
|
{
|
||||||
return (new Repository\Client)->getClientEntity($this->getClientId());
|
return (new Repository\Client)->getClientEntity($this->getClientId());
|
||||||
}
|
}
|
||||||
|
@ -122,7 +115,7 @@ abstract class Token extends Entity implements TokenInterface
|
||||||
*
|
*
|
||||||
* @return ScopeEntityInterface[]
|
* @return ScopeEntityInterface[]
|
||||||
*/
|
*/
|
||||||
public function getScopes()
|
public function getScopes(): array
|
||||||
{
|
{
|
||||||
return F\map(
|
return F\map(
|
||||||
explode(' ', $this->getTokenScopes()),
|
explode(' ', $this->getTokenScopes()),
|
||||||
|
@ -135,13 +128,13 @@ abstract class Token extends Entity implements TokenInterface
|
||||||
return [
|
return [
|
||||||
'name' => $table_name,
|
'name' => $table_name,
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'id' => ['type' => 'char', 'length' => 64, 'not null' => true, 'description' => 'identifier for this token'],
|
'id' => ['type' => 'char', 'length' => 64, 'not null' => true, 'description' => 'identifier for this token'],
|
||||||
'expiry' => ['type' => 'datetime', 'not null' => true, 'description' => 'when this token expires'],
|
'expiry' => ['type' => 'datetime', 'not null' => true, 'description' => 'when this token expires'],
|
||||||
'user_id' => ['type' => 'int', 'foreign key' => true, 'description' => 'Actor foreign key'],
|
'user_id' => ['type' => 'int', 'foreign key' => true, 'description' => 'Actor foreign key'],
|
||||||
'client_id' => ['type' => 'char', 'length' => 64, 'not null' => true, 'foreign key' => true, 'description' => 'OAuth client foreign key'],
|
'client_id' => ['type' => 'char', 'length' => 64, 'not null' => true, 'foreign key' => true, 'description' => 'OAuth client foreign key'],
|
||||||
'token_scopes' => ['type' => 'text', 'not null' => true, 'description' => 'Space separated scopes'],
|
'token_scopes' => ['type' => 'text', 'not null' => true, 'description' => 'Space separated scopes'],
|
||||||
'revoked' => ['type' => 'bool', 'not null' => true, 'foreign key' => true, 'description' => 'Whether this token is revoked'],
|
'revoked' => ['type' => 'bool', 'not null' => true, 'foreign key' => true, 'description' => 'Whether this token is revoked'],
|
||||||
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
'created' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was created'],
|
||||||
],
|
],
|
||||||
'primary key' => ['id'],
|
'primary key' => ['id'],
|
||||||
];
|
];
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"require": {
|
"require": {
|
||||||
"league/oauth2-server": "*",
|
"league/oauth2-server": "*",
|
||||||
"nyholm/psr7": "*"
|
"nyholm/psr7": "*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user