Skip to content

Commit 1d806d5

Browse files
author
www-data
committed
WIP
1 parent fccdbe1 commit 1d806d5

File tree

8 files changed

+103
-17
lines changed

8 files changed

+103
-17
lines changed

routing/routes/routes.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use SimpleSAML\Module\oidc\Controllers\OAuth2\OAuth2ServerConfigurationController;
2222
use SimpleSAML\Module\oidc\Controllers\UserInfoController;
2323
use SimpleSAML\Module\oidc\Controllers\VerifiableCredentials\CredentialIssuerConfigurationController;
24+
use SimpleSAML\Module\oidc\Controllers\VerifiableCredentials\CredentialIssuerCredentialController;
2425
use SimpleSAML\OpenID\Codebooks\HttpMethodsEnum;
2526
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
2627

@@ -128,6 +129,6 @@
128129
->methods([HttpMethodsEnum::GET->value]);
129130

130131
$routes->add(RoutesEnum::CredentialIssuerCredential->name, RoutesEnum::CredentialIssuerCredential->value)
131-
->controller([CredentialIssuerConfigurationController::class, 'credential'])
132-
->methods([HttpMethodsEnum::GET->value]);
132+
->controller([CredentialIssuerCredentialController::class, 'credential'])
133+
->methods([HttpMethodsEnum::GET->value, HttpMethodsEnum::POST->value]);
133134
};

src/Controllers/Admin/VerifiableCredentailsTestController.php

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,13 @@
1111
use SimpleSAML\Module\oidc\Factories\Entities\AuthCodeEntityFactory;
1212
use SimpleSAML\Module\oidc\Factories\Entities\ClientEntityFactory;
1313
use SimpleSAML\Module\oidc\Factories\TemplateFactory;
14-
use SimpleSAML\Module\oidc\Helpers;
1514
use SimpleSAML\Module\oidc\ModuleConfig;
1615
use SimpleSAML\Module\oidc\Repositories\AuthCodeRepository;
1716
use SimpleSAML\Module\oidc\Repositories\ClientRepository;
1817
use SimpleSAML\Module\oidc\Services\LoggerService;
19-
use SimpleSAML\Module\oidc\Utils\Debug\ArrayLogger;
2018
use SimpleSAML\OpenID\Codebooks\ClaimsEnum;
2119
use SimpleSAML\OpenID\Codebooks\GrantTypesEnum;
22-
use SimpleSAML\OpenID\Federation;
2320
use SimpleSAML\OpenID\VerifiableCredentials;
24-
use Symfony\Component\HttpFoundation\Request;
2521
use Symfony\Component\HttpFoundation\Response;
2622

2723
class VerifiableCredentailsTestController
@@ -35,8 +31,6 @@ public function __construct(
3531
protected readonly AuthCodeEntityFactory $authCodeEntityFactory,
3632
protected readonly ClientRepository $clientRepository,
3733
protected readonly ClientEntityFactory $clientEntityFactory,
38-
protected readonly Federation $federation,
39-
protected readonly Helpers $helpers,
4034
protected readonly LoggerService $loggerService,
4135
) {
4236
$this->authorization->requireAdmin(true);
@@ -47,7 +41,7 @@ public function __construct(
4741
* @throws \SimpleSAML\OpenID\Exceptions\InvalidValueException
4842
* @throws \SimpleSAML\OpenID\Exceptions\CredentialOfferException
4943
*/
50-
public function verifiableCredentialIssuance(Request $request): Response
44+
public function verifiableCredentialIssuance(): Response
5145
{
5246
$sampleData = [
5347
'eduPersonPrincipalName' => '[email protected]',
@@ -59,7 +53,7 @@ public function verifiableCredentialIssuance(Request $request): Response
5953
'eduPersonScopedAffiliation' => '[email protected]',
6054
];
6155

62-
$this->loggerService->info('test', $sampleData);;
56+
$this->loggerService->info('test', $sampleData);
6357

6458
// TODO mivanci Wallet (client) credential_offer_endpoint metadata
6559
// https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html#client-metadata

src/Controllers/VerifiableCredentials/CredentialIssuerConfigurationController.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use SimpleSAML\Module\oidc\Utils\Routes;
1919
use SimpleSAML\OpenID\Codebooks\ClaimsEnum;
2020
use SimpleSAML\OpenID\Codebooks\CredentialFormatIdentifiersEnum;
21+
use SimpleSAML\OpenID\Codebooks\CredentialTypesEnum;
2122
use SimpleSAML\OpenID\Codebooks\LanguageTagsEnum;
2223
use Symfony\Component\HttpFoundation\Response;
2324

@@ -253,7 +254,7 @@ public function configuration(): Response
253254
// REQUIRED
254255
ClaimsEnum::CredentialDefinition->value => [
255256
ClaimsEnum::Type->value => [
256-
'VerifiableCredential', // TODO mivanci CredentialTypesEnum
257+
CredentialTypesEnum::VerifiableCredential->value,
257258
'ResearchAndScholarshipCredentialJwtVcJson',
258259
],
259260
],

src/Controllers/VerifiableCredentials/CredentialIssuerCredentialController.php

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,20 @@
44

55
namespace SimpleSAML\Module\oidc\Controllers\VerifiableCredentials;
66

7+
use League\OAuth2\Server\ResourceServer;
8+
use SimpleSAML\Module\oidc\Bridges\PsrHttpBridge;
79
use SimpleSAML\Module\oidc\ModuleConfig;
10+
use SimpleSAML\Module\oidc\Repositories\AccessTokenRepository;
811
use SimpleSAML\Module\oidc\Server\Exceptions\OidcServerException;
12+
use SimpleSAML\Module\oidc\Utils\FingerprintGenerator;
913
use SimpleSAML\Module\oidc\Utils\Routes;
14+
use SimpleSAML\OpenID\Algorithms\SignatureAlgorithmEnum;
15+
use SimpleSAML\OpenID\Codebooks\AtContextsEnum;
16+
use SimpleSAML\OpenID\Codebooks\ClaimsEnum;
17+
use SimpleSAML\OpenID\Codebooks\CredentialTypesEnum;
18+
use SimpleSAML\OpenID\Jwk;
19+
use SimpleSAML\OpenID\VerifiableCredentials;
20+
use Symfony\Component\HttpFoundation\Request;
1021
use Symfony\Component\HttpFoundation\Response;
1122

1223
class CredentialIssuerCredentialController
@@ -15,19 +26,81 @@ class CredentialIssuerCredentialController
1526
* @throws \SimpleSAML\Module\oidc\Server\Exceptions\OidcServerException
1627
*/
1728
public function __construct(
29+
protected readonly ResourceServer $resourceServer,
30+
protected readonly AccessTokenRepository $accessTokenRepository,
1831
protected readonly ModuleConfig $moduleConfig,
1932
protected readonly Routes $routes,
33+
protected readonly PsrHttpBridge $psrHttpBridge,
34+
protected readonly VerifiableCredentials $verifiableCredentials,
35+
protected readonly Jwk $jwk,
2036
) {
2137
if (!$this->moduleConfig->getVerifiableCredentialEnabled()) {
2238
throw OidcServerException::forbidden('Verifiable Credential capabilities not enabled');
2339
}
2440
}
2541

26-
public function credential(): Response
42+
public function credential(Request $request): Response
2743
{
44+
$authorization = $this->resourceServer->validateAuthenticatedRequest(
45+
$this->psrHttpBridge->getPsrHttpFactory()->createRequest($request),
46+
);
47+
48+
// TODO mivanci validate
49+
$accessToken = $this->accessTokenRepository->findById($authorization->getAttribute('oauth_access_token_id'));
50+
if ($accessToken->isRevoked()) {
51+
throw OidcServerException::accessDenied('Access token is revoked.');
52+
}
53+
54+
// TODO mivanci validate requested credential identifier
55+
56+
$jwk = $this->jwk->jwkDecoratorFactory()->fromPkcs1Or8KeyFile(
57+
$this->moduleConfig->getProtocolPrivateKeyPath(),
58+
null,
59+
);
60+
61+
$issuedAt = new \DateTimeImmutable();
62+
63+
$verifiableCredential = $this->verifiableCredentials->jwtVcJsonFactory()->fromData(
64+
$jwk,
65+
SignatureAlgorithmEnum::RS256,
66+
[
67+
ClaimsEnum::Vc->value => [
68+
ClaimsEnum::AtContext->value => [
69+
AtContextsEnum::W3Org2018CredentialsV1->value,
70+
],
71+
ClaimsEnum::Type->value => [
72+
CredentialTypesEnum::VerifiableCredential->value,
73+
'ResearchAndScholarshipCredentialJwtVcJson',
74+
],
75+
ClaimsEnum::Issuer->value => $this->moduleConfig->getIssuer(),
76+
ClaimsEnum::Issuance_Date->value => $issuedAt->format(\DateTimeInterface::RFC3339),
77+
ClaimsEnum::Credential_Subject->value => [
78+
'eduPersonPrincipalName' => '[email protected]',
79+
'eduPersonTargetedID' => 'abc123',
80+
'displayName' => 'Test User',
81+
'givenName' => 'Test',
82+
'sn' => 'User',
83+
'mail' => '[email protected]',
84+
'eduPersonScopedAffiliation' => '[email protected]',
85+
],
86+
],
87+
ClaimsEnum::Iss->value => $this->moduleConfig->getIssuer(),
88+
ClaimsEnum::Iat->value => $issuedAt->getTimestamp(),
89+
ClaimsEnum::Nbf->value => $issuedAt->getTimestamp(),
90+
ClaimsEnum::Sub->value => 'testuid',
91+
],
92+
[
93+
ClaimsEnum::Kid->value => FingerprintGenerator::forFile(
94+
$this->moduleConfig->getProtocolCertPath(),
95+
),
96+
],
97+
);
98+
2899
return $this->routes->newJsonResponse(
29100
[
30-
'credential' => 'credential',
101+
'credentials' => [
102+
'credential' => $verifiableCredential->getToken(),
103+
],
31104
],
32105
);
33106
}

src/Factories/Grant/AuthCodeGrantFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public function build(): AuthCodeGrant
6262
$this->authCodeEntityFactory,
6363
$this->refreshTokenIssuer,
6464
$this->helpers,
65-
$this->loggerService
65+
$this->loggerService,
6666
);
6767
$authCodeGrant->setRefreshTokenTTL($this->moduleConfig->getRefreshTokenDuration());
6868

src/Factories/Grant/PreAuthCodeGrantFactory.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
use SimpleSAML\Module\oidc\Repositories\AccessTokenRepository;
2424
use SimpleSAML\Module\oidc\Repositories\AuthCodeRepository;
2525
use SimpleSAML\Module\oidc\Repositories\RefreshTokenRepository;
26-
use SimpleSAML\Module\oidc\Server\Grants\AuthCodeGrant;
2726
use SimpleSAML\Module\oidc\Server\Grants\PreAuthCodeGrant;
2827
use SimpleSAML\Module\oidc\Server\RequestRules\RequestRulesManager;
2928
use SimpleSAML\Module\oidc\Server\TokenIssuers\RefreshTokenIssuer;
@@ -63,7 +62,7 @@ public function build(): PreAuthCodeGrant
6362
$this->authCodeEntityFactory,
6463
$this->refreshTokenIssuer,
6564
$this->helpers,
66-
$this->loggerService
65+
$this->loggerService,
6766
);
6867
$preAuthCodeGrant->setRefreshTokenTTL($this->moduleConfig->getRefreshTokenDuration());
6968

src/Server/Grants/PreAuthCodeGrant.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ public function respondToAccessTokenRequest(
114114

115115
$this->loggerService->debug(
116116
'Pre-authorized code grant respondToAccessTokenRequest',
117-
$this->requestParamsResolver->getAllFromRequest($request)
117+
$this->requestParamsResolver->getAllFromRequest($request),
118118
);
119119

120120
$preAuthorizedCodeId = $this->requestParamsResolver->getAsStringBasedOnAllowedMethods(

src/Services/Container.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
use SimpleSAML\Module\oidc\Factories\FormFactory;
5252
use SimpleSAML\Module\oidc\Factories\Grant\AuthCodeGrantFactory;
5353
use SimpleSAML\Module\oidc\Factories\Grant\ImplicitGrantFactory;
54+
use SimpleSAML\Module\oidc\Factories\Grant\PreAuthCodeGrantFactory;
5455
use SimpleSAML\Module\oidc\Factories\Grant\RefreshTokenGrantFactory;
5556
use SimpleSAML\Module\oidc\Factories\IdTokenResponseFactory;
5657
use SimpleSAML\Module\oidc\Factories\JwksFactory;
@@ -71,6 +72,7 @@
7172
use SimpleSAML\Module\oidc\Server\AuthorizationServer;
7273
use SimpleSAML\Module\oidc\Server\Grants\AuthCodeGrant;
7374
use SimpleSAML\Module\oidc\Server\Grants\ImplicitGrant;
75+
use SimpleSAML\Module\oidc\Server\Grants\PreAuthCodeGrant;
7476
use SimpleSAML\Module\oidc\Server\Grants\RefreshTokenGrant;
7577
use SimpleSAML\Module\oidc\Server\RequestRules\RequestRulesManager;
7678
use SimpleSAML\Module\oidc\Server\RequestRules\Rules\AcrValuesRule;
@@ -469,6 +471,21 @@ public function __construct()
469471
);
470472
$this->services[RefreshTokenGrant::class] = $refreshTokenGrantFactory->build();
471473

474+
$preAuthCodeGrantFactory = new PreAuthCodeGrantFactory(
475+
$moduleConfig,
476+
$authCodeRepository,
477+
$accessTokenRepository,
478+
$refreshTokenRepository,
479+
$requestRuleManager,
480+
$requestParamsResolver,
481+
$accessTokenEntityFactory,
482+
$authCodeEntityFactory,
483+
$refreshTokenIssuer,
484+
$helpers,
485+
$loggerService,
486+
);
487+
$this->services[PreAuthCodeGrant::class] = $preAuthCodeGrantFactory->build();
488+
472489
$authorizationServerFactory = new AuthorizationServerFactory(
473490
$moduleConfig,
474491
$clientRepository,
@@ -480,6 +497,7 @@ public function __construct()
480497
$this->services[IdTokenResponse::class],
481498
$requestRuleManager,
482499
$privateKey,
500+
$this->services[PreAuthCodeGrant::class],
483501
);
484502
$this->services[AuthorizationServer::class] = $authorizationServerFactory->build();
485503

0 commit comments

Comments
 (0)