OAuth metadata endpoints.
This commit is contained in:
parent
e5a947e973
commit
b2f8347526
4 changed files with 99 additions and 2 deletions
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
use Index\Db\DbConnection;
|
||||||
|
use Index\Db\Migration\DbMigration;
|
||||||
|
|
||||||
|
final class AddIndexOnRestrictedFieldForScopes_20250226_173829 implements DbMigration {
|
||||||
|
public function migrate(DbConnection $conn): void {
|
||||||
|
$conn->execute(<<<SQL
|
||||||
|
ALTER TABLE msz_scopes
|
||||||
|
ADD INDEX scopes_restricted_index (scope_restricted);
|
||||||
|
SQL);
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,29 @@ class ScopesData {
|
||||||
$this->cache = new DbStatementCache($dbConn);
|
$this->cache = new DbStatementCache($dbConn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getScopes(
|
||||||
|
?bool $restricted = null,
|
||||||
|
?bool $deprecated = null
|
||||||
|
): iterable {
|
||||||
|
$args = 0;
|
||||||
|
$query = <<<SQL
|
||||||
|
SELECT scope_id, scope_string, scope_restricted, scope_summary,
|
||||||
|
UNIX_TIMESTAMP(scope_created), UNIX_TIMESTAMP(scope_deprecated)
|
||||||
|
FROM msz_scopes
|
||||||
|
SQL;
|
||||||
|
if($restricted !== null) {
|
||||||
|
++$args;
|
||||||
|
$query .= sprintf(' WHERE scope_restricted %s 0', $restricted ? '<>' : '=');
|
||||||
|
}
|
||||||
|
if($deprecated !== null)
|
||||||
|
$query .= sprintf(' %s scope_deprecated %s NULL', ++$args > 1 ? 'AND' : 'WHERE', $deprecated ? 'IS NOT' : 'IS');
|
||||||
|
|
||||||
|
$stmt = $this->cache->get($query);
|
||||||
|
$stmt->execute();
|
||||||
|
|
||||||
|
return $stmt->getResultIterator(ScopeInfo::fromResult(...));
|
||||||
|
}
|
||||||
|
|
||||||
public function getScopeInfo(string $value, ScopeInfoGetField $field): ScopeInfo {
|
public function getScopeInfo(string $value, ScopeInfoGetField $field): ScopeInfo {
|
||||||
$stmt = $this->cache->get(sprintf(
|
$stmt = $this->cache->get(sprintf(
|
||||||
<<<SQL
|
<<<SQL
|
||||||
|
|
|
@ -2,15 +2,21 @@
|
||||||
namespace Misuzu\OAuth2;
|
namespace Misuzu\OAuth2;
|
||||||
|
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
|
use Index\XArray;
|
||||||
use Index\Http\{FormHttpContent,HttpResponseBuilder,HttpRequest};
|
use Index\Http\{FormHttpContent,HttpResponseBuilder,HttpRequest};
|
||||||
use Index\Http\Routing\{HttpGet,HttpOptions,HttpPost,RouteHandler,RouteHandlerCommon};
|
use Index\Http\Routing\{HttpGet,HttpOptions,HttpPost,RouteHandler,RouteHandlerCommon};
|
||||||
use Index\Urls\{UrlFormat,UrlSource,UrlSourceCommon};
|
use Index\Urls\{UrlFormat,UrlRegistry,UrlSource,UrlSourceCommon};
|
||||||
|
use Misuzu\SiteInfo;
|
||||||
|
use Misuzu\Apps\AppsContext;
|
||||||
|
|
||||||
final class OAuth2ApiRoutes implements RouteHandler, UrlSource {
|
final class OAuth2ApiRoutes implements RouteHandler, UrlSource {
|
||||||
use RouteHandlerCommon, UrlSourceCommon;
|
use RouteHandlerCommon, UrlSourceCommon;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private OAuth2Context $oauth2Ctx,
|
private OAuth2Context $oauth2Ctx,
|
||||||
|
private AppsContext $appsCtx,
|
||||||
|
private UrlRegistry $urls,
|
||||||
|
private SiteInfo $siteInfo,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,6 +44,62 @@ final class OAuth2ApiRoutes implements RouteHandler, UrlSource {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[HttpOptions('/.well-known/oauth-protected-resource')]
|
||||||
|
#[HttpGet('/.well-known/oauth-protected-resource')]
|
||||||
|
public function getWellKnownProtectedResource(HttpResponseBuilder $response, HttpRequest $request): array|int {
|
||||||
|
$response->setHeader('Access-Control-Allow-Origin', '*');
|
||||||
|
if($request->method === 'OPTIONS')
|
||||||
|
return 204;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'resource' => $this->siteInfo->url,
|
||||||
|
'authorization_servers' => [$this->siteInfo->url],
|
||||||
|
'scopes_supported' => [],
|
||||||
|
'bearer_methods_supported' => ['header'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
#[HttpOptions('/.well-known/oauth-authorization-server')]
|
||||||
|
#[HttpGet('/.well-known/oauth-authorization-server')]
|
||||||
|
public function getWellKnownAuthorizationServer(HttpResponseBuilder $response, HttpRequest $request): array|int {
|
||||||
|
$response->setHeader('Access-Control-Allow-Origin', '*');
|
||||||
|
if($request->method === 'OPTIONS')
|
||||||
|
return 204;
|
||||||
|
|
||||||
|
return [
|
||||||
|
'issuer' => $this->siteInfo->url,
|
||||||
|
'authorization_endpoint' => sprintf('%s%s', $this->siteInfo->url, $this->urls->format('oauth2-authorise')),
|
||||||
|
'token_endpoint' => sprintf('%s%s', $this->siteInfo->url, $this->urls->format('oauth2-token')),
|
||||||
|
'jwks_uri' => sprintf('%s%s', $this->siteInfo->url, $this->urls->format('openid-jwks')),
|
||||||
|
'protected_resources' => [$this->siteInfo->url],
|
||||||
|
'scopes_supported' => XArray::select(
|
||||||
|
$this->appsCtx->scopes->getScopes(
|
||||||
|
restricted: false,
|
||||||
|
deprecated: false,
|
||||||
|
),
|
||||||
|
fn($scopeInfo) => $scopeInfo->string
|
||||||
|
),
|
||||||
|
'response_types_supported' => ['code', 'code id_token'],
|
||||||
|
'response_modes_supported' => ['query'],
|
||||||
|
'grant_types_supported' => [
|
||||||
|
'authorization_code',
|
||||||
|
'client_credentials',
|
||||||
|
'refresh_token',
|
||||||
|
'urn:ietf:params:oauth:grant-type:device_code',
|
||||||
|
],
|
||||||
|
'token_endpoint_auth_methods_supported' => [
|
||||||
|
'none',
|
||||||
|
'client_secret_basic',
|
||||||
|
'client_secret_post',
|
||||||
|
],
|
||||||
|
//'revocation_endpoint' => 'TODO: implement this',
|
||||||
|
//'revocation_endpoint_auth_methods_supported' => ['client_secret_basic'],
|
||||||
|
//'introspection_endpoint ' => 'TODO: implement this',
|
||||||
|
//'introspection_endpoint_auth_methods_supported' => ['Bearer'],
|
||||||
|
'code_challenge_methods_supported' => ['plain', 'S256'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array{
|
* @return array{
|
||||||
* device_code: string,
|
* device_code: string,
|
||||||
|
|
|
@ -23,7 +23,7 @@ class OpenIDRoutes implements RouteHandler, UrlSource {
|
||||||
private ProfileContext $profileCtx,
|
private ProfileContext $profileCtx,
|
||||||
private SiteInfo $siteInfo,
|
private SiteInfo $siteInfo,
|
||||||
private AuthInfo $authInfo,
|
private AuthInfo $authInfo,
|
||||||
private UrlRegistry $urls
|
private UrlRegistry $urls,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
#[HttpOptions('/.well-known/openid-configuration')]
|
#[HttpOptions('/.well-known/openid-configuration')]
|
||||||
|
|
Loading…
Add table
Reference in a new issue