Skip to content
Open
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
233 changes: 232 additions & 1 deletion app/Http/Controllers/OAuth2/OAuth2ProviderController.php

Large diffs are not rendered by default.

172 changes: 172 additions & 0 deletions app/Swagger/OAuth2ProviderControllerSchemas.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
<?php

namespace App\Swagger\schemas;

use OpenApi\Attributes as OA;

#[OA\Schema(
schema: 'OAuth2TokenResponse',
title: 'OAuth2 Token Response',
description: 'Successful token response per RFC 6749 §5.1',
type: 'object',
properties: [
new OA\Property(property: 'access_token', type: 'string', description: 'The access token issued by the authorization server'),
new OA\Property(property: 'token_type', type: 'string', description: 'The type of the token (typically Bearer)', example: 'Bearer'),
new OA\Property(property: 'expires_in', type: 'integer', description: 'Lifetime of the access token in seconds', example: 3600),
new OA\Property(property: 'refresh_token', type: 'string', description: 'Refresh token (only if access_type=offline)', nullable: true),
new OA\Property(property: 'scope', type: 'string', description: 'Space-delimited list of granted scopes'),
new OA\Property(property: 'id_token', type: 'string', description: 'ID token JWT (only for OpenID Connect flows with openid scope)', nullable: true),
]
)]
class OAuth2TokenResponseSchema
{
}

#[OA\Schema(
schema: 'OAuth2ErrorResponse',
title: 'OAuth2 Error Response',
description: 'Error response per RFC 6749 §5.2',
type: 'object',
required: ['error'],
properties: [
new OA\Property(property: 'error', type: 'string', description: 'Error code', example: 'invalid_request'),
new OA\Property(property: 'error_description', type: 'string', description: 'Human-readable error description'),
]
)]
class OAuth2ErrorResponseSchema
{
}

#[OA\Schema(
schema: 'OAuth2IntrospectionResponse',
title: 'OAuth2 Token Introspection Response',
description: 'Token introspection response per RFC 7662',
type: 'object',
properties: [
new OA\Property(property: 'active', type: 'boolean', description: 'Whether the token is active'),
new OA\Property(property: 'access_token', type: 'string', description: 'The access token value'),
new OA\Property(property: 'client_id', type: 'string', description: 'Client identifier'),
new OA\Property(property: 'application_type', type: 'string', description: 'Client application type', enum: ['WEB', 'NATIVE', 'JS']),
new OA\Property(property: 'token_type', type: 'string', description: 'Token type', example: 'Bearer'),
new OA\Property(property: 'scope', type: 'string', description: 'Space-delimited scopes'),
new OA\Property(property: 'audience', type: 'string', description: 'Token audience'),
new OA\Property(property: 'expires_in', type: 'integer', description: 'Remaining lifetime in seconds'),
new OA\Property(property: 'user_id', type: 'integer', description: 'Resource owner user ID', nullable: true),
new OA\Property(property: 'user_identifier', type: 'string', description: 'Resource owner identifier', nullable: true),
new OA\Property(property: 'user_email', type: 'string', description: 'Resource owner email', nullable: true),
new OA\Property(property: 'user_first_name', type: 'string', description: 'Resource owner first name', nullable: true),
new OA\Property(property: 'user_last_name', type: 'string', description: 'Resource owner last name', nullable: true),
new OA\Property(property: 'user_pic', type: 'string', format: 'uri', description: 'Resource owner profile picture URL', nullable: true),
new OA\Property(
property: 'user_groups',
type: 'array',
description: 'Resource owner group memberships',
items: new OA\Items(
type: 'object',
properties: [
new OA\Property(property: 'id', type: 'integer'),
new OA\Property(property: 'title', type: 'string'),
new OA\Property(property: 'description', type: 'string'),
]
),
nullable: true
),
new OA\Property(property: 'user_email_verified', type: 'boolean', description: 'Whether the user email is verified', nullable: true),
new OA\Property(property: 'user_language', type: 'string', description: 'User preferred language', nullable: true),
new OA\Property(property: 'user_country', type: 'string', description: 'User country', nullable: true),
new OA\Property(property: 'allowed_return_uris', type: 'string', description: 'Space-delimited allowed return URIs'),
new OA\Property(property: 'allowed_origins', type: 'string', description: 'Space-delimited allowed origins'),
]
)]
class OAuth2IntrospectionResponseSchema
{
}

#[OA\Schema(
schema: 'JWKSResponse',
title: 'JSON Web Key Set',
description: 'JWK Set document per RFC 7517',
type: 'object',
properties: [
new OA\Property(
property: 'keys',
type: 'array',
description: 'Array of JSON Web Keys',
items: new OA\Items(
type: 'object',
properties: [
new OA\Property(property: 'kty', type: 'string', description: 'Key type', example: 'RSA'),
new OA\Property(property: 'kid', type: 'string', description: 'Key ID'),
new OA\Property(property: 'use', type: 'string', description: 'Key usage', example: 'sig'),
new OA\Property(property: 'alg', type: 'string', description: 'Algorithm', example: 'RS256'),
new OA\Property(property: 'n', type: 'string', description: 'RSA modulus (Base64urlUInt-encoded)'),
new OA\Property(property: 'e', type: 'string', description: 'RSA exponent (Base64urlUInt-encoded)', example: 'AQAB'),
]
)
),
]
)]
class JWKSResponseSchema
{
}

#[OA\Schema(
schema: 'OpenIDDiscoveryResponse',
title: 'OpenID Connect Discovery Document',
description: 'OpenID Provider Configuration per OpenID Connect Discovery 1.0',
type: 'object',
properties: [
new OA\Property(property: 'issuer', type: 'string', format: 'uri', description: 'Issuer identifier URL'),
new OA\Property(property: 'authorization_endpoint', type: 'string', format: 'uri', description: 'Authorization endpoint URL'),
new OA\Property(property: 'token_endpoint', type: 'string', format: 'uri', description: 'Token endpoint URL'),
new OA\Property(property: 'userinfo_endpoint', type: 'string', format: 'uri', description: 'UserInfo endpoint URL'),
new OA\Property(property: 'revocation_endpoint', type: 'string', format: 'uri', description: 'Token revocation endpoint URL'),
new OA\Property(property: 'introspection_endpoint', type: 'string', format: 'uri', description: 'Token introspection endpoint URL'),
new OA\Property(property: 'jwks_uri', type: 'string', format: 'uri', description: 'JSON Web Key Set URL'),
new OA\Property(
property: 'scopes_supported',
type: 'array',
description: 'Supported OAuth2 scopes',
items: new OA\Items(type: 'string')
),
new OA\Property(
property: 'response_types_supported',
type: 'array',
description: 'Supported response types',
items: new OA\Items(type: 'string')
),
new OA\Property(
property: 'response_modes_supported',
type: 'array',
description: 'Supported response modes',
items: new OA\Items(type: 'string')
),
new OA\Property(
property: 'grant_types_supported',
type: 'array',
description: 'Supported grant types',
items: new OA\Items(type: 'string')
),
new OA\Property(
property: 'subject_types_supported',
type: 'array',
description: 'Supported subject types',
items: new OA\Items(type: 'string')
),
new OA\Property(
property: 'id_token_signing_alg_values_supported',
type: 'array',
description: 'Supported ID token signing algorithms',
items: new OA\Items(type: 'string')
),
new OA\Property(
property: 'code_challenge_methods_supported',
type: 'array',
description: 'Supported PKCE code challenge methods',
items: new OA\Items(type: 'string')
),
]
)]
class OpenIDDiscoveryResponseSchema
{
}
29 changes: 29 additions & 0 deletions app/Swagger/Requests/OAuth2AuthorizationRequestSchema.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace App\Swagger\schemas;

use OpenApi\Attributes as OA;

#[OA\Schema(
schema: 'OAuth2AuthorizationRequest',
title: 'OAuth2 Authorization Request',
description: 'Authorization request parameters per RFC 6749 §4.1.1 and OpenID Connect Core §3.1.2.1',
type: 'object',
required: ['response_type', 'client_id', 'redirect_uri'],
properties: [
new OA\Property(property: 'response_type', type: 'string', description: 'OAuth2 response type', enum: ['code', 'token', 'id_token', 'code token', 'code id_token', 'token id_token', 'code token id_token', 'otp', 'none']),
new OA\Property(property: 'client_id', type: 'string', description: 'OAuth2 client identifier'),
new OA\Property(property: 'redirect_uri', type: 'string', format: 'uri', description: 'Redirect URI'),
new OA\Property(property: 'scope', type: 'string', description: 'Space-delimited scopes'),
new OA\Property(property: 'state', type: 'string', description: 'Opaque state parameter'),
new OA\Property(property: 'nonce', type: 'string', description: 'Nonce for ID token replay protection'),
new OA\Property(property: 'response_mode', type: 'string', description: 'Response mode override', enum: ['query', 'fragment', 'form_post', 'direct']),
new OA\Property(property: 'prompt', type: 'string', description: 'User interaction prompts'),
new OA\Property(property: 'login_hint', type: 'string', description: 'Login identifier hint'),
new OA\Property(property: 'code_challenge', type: 'string', description: 'PKCE code challenge'),
new OA\Property(property: 'code_challenge_method', type: 'string', description: 'PKCE challenge method', enum: ['plain', 'S256']),
]
)]
class OAuth2AuthorizationRequestSchema
{
}
22 changes: 22 additions & 0 deletions app/Swagger/Requests/OAuth2EndSessionRequestSchema.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace App\Swagger\schemas;

use OpenApi\Attributes as OA;

#[OA\Schema(
schema: 'OAuth2EndSessionRequest',
title: 'OAuth2 End Session Request',
description: 'RP-Initiated Logout request parameters per OpenID Connect Session Management 1.0',
type: 'object',
required: ['client_id'],
properties: [
new OA\Property(property: 'client_id', type: 'string', description: 'OAuth2 client identifier'),
new OA\Property(property: 'id_token_hint', type: 'string', description: 'Previously issued ID token'),
new OA\Property(property: 'post_logout_redirect_uri', type: 'string', format: 'uri', description: 'URI to redirect after logout'),
new OA\Property(property: 'state', type: 'string', description: 'Opaque state parameter'),
]
)]
class OAuth2EndSessionRequestSchema
{
}
21 changes: 21 additions & 0 deletions app/Swagger/Requests/OAuth2TokenIntrospectionRequestSchema.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace App\Swagger\schemas;

use OpenApi\Attributes as OA;

#[OA\Schema(
schema: 'OAuth2TokenIntrospectionRequest',
title: 'OAuth2 Token Introspection Request',
description: 'Token introspection request parameters per RFC 7662 §2.1',
type: 'object',
required: ['token'],
properties: [
new OA\Property(property: 'token', type: 'string', description: 'The token to introspect'),
new OA\Property(property: 'client_id', type: 'string', description: 'Client identifier (if not using HTTP Basic auth)'),
new OA\Property(property: 'client_secret', type: 'string', description: 'Client secret (if not using HTTP Basic auth)'),
]
)]
class OAuth2TokenIntrospectionRequestSchema
{
}
32 changes: 32 additions & 0 deletions app/Swagger/Requests/OAuth2TokenRequestSchema.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace App\Swagger\schemas;

use OpenApi\Attributes as OA;

#[OA\Schema(
schema: 'OAuth2TokenRequest',
title: 'OAuth2 Token Request',
description: 'Token request parameters per RFC 6749 §4.1.3. Fields required vary by grant_type.',
type: 'object',
required: ['grant_type'],
properties: [
new OA\Property(property: 'grant_type', type: 'string', description: 'OAuth2 grant type', enum: ['authorization_code', 'client_credentials', 'password', 'refresh_token', 'passwordless']),
new OA\Property(property: 'code', type: 'string', description: 'Authorization code (authorization_code grant)'),
new OA\Property(property: 'redirect_uri', type: 'string', format: 'uri', description: 'Redirect URI (must match the one used in authorization request)'),
new OA\Property(property: 'client_id', type: 'string', description: 'Client identifier (if not using HTTP Basic auth)'),
new OA\Property(property: 'client_secret', type: 'string', description: 'Client secret (if not using HTTP Basic auth)'),
new OA\Property(property: 'refresh_token', type: 'string', description: 'Refresh token (refresh_token grant)'),
new OA\Property(property: 'scope', type: 'string', description: 'Space-delimited scopes'),
new OA\Property(property: 'username', type: 'string', description: 'Username (password grant)'),
new OA\Property(property: 'password', type: 'string', description: 'Password (password grant)'),
new OA\Property(property: 'audience', type: 'string', description: 'Target audience (client_credentials grant)'),
new OA\Property(property: 'connection', type: 'string', description: 'Connection type (passwordless grant)', enum: ['sms', 'email', 'inline']),
new OA\Property(property: 'send', type: 'string', description: 'Delivery method (passwordless grant)', enum: ['code', 'link']),
new OA\Property(property: 'email', type: 'string', description: 'Email address (passwordless grant)'),
new OA\Property(property: 'phone_number', type: 'string', description: 'Phone number (passwordless grant)'),
]
)]
class OAuth2TokenRequestSchema
{
}
22 changes: 22 additions & 0 deletions app/Swagger/Requests/OAuth2TokenRevocationRequestSchema.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace App\Swagger\schemas;

use OpenApi\Attributes as OA;

#[OA\Schema(
schema: 'OAuth2TokenRevocationRequest',
title: 'OAuth2 Token Revocation Request',
description: 'Token revocation request parameters per RFC 7009 §2.1',
type: 'object',
required: ['token'],
properties: [
new OA\Property(property: 'token', type: 'string', description: 'The token to revoke'),
new OA\Property(property: 'token_type_hint', type: 'string', description: 'Hint about the token type', enum: ['access_token', 'refresh_token']),
new OA\Property(property: 'client_id', type: 'string', description: 'Client identifier (if not using HTTP Basic auth)'),
new OA\Property(property: 'client_secret', type: 'string', description: 'Client secret (if not using HTTP Basic auth)'),
]
)]
class OAuth2TokenRevocationRequestSchema
{
}
21 changes: 21 additions & 0 deletions app/Swagger/Security/OAuth2ProviderControllerSecuritySchema.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace App\Swagger\schemas;

use OpenApi\Attributes as OA;

#[OA\SecurityScheme(
securityScheme: 'OAuth2ProviderSecurity',
type: 'oauth2',
description: 'OAuth2 client credentials authentication for protocol endpoints (token, revoke, introspection)',
flows: [
new OA\Flow(
flow: 'clientCredentials',
tokenUrl: L5_SWAGGER_CONST_TOKEN_URL,
scopes: []
),
]
)]
class OAuth2ProviderControllerSecuritySchema
{
}
Loading