Skip to content

Commit ee98b5a

Browse files
committed
WIP
1 parent 3910e53 commit ee98b5a

File tree

3 files changed

+136
-58
lines changed

3 files changed

+136
-58
lines changed

src/Controllers/Admin/VerifiableCredentailsTestController.php

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ public function __construct(
6363
*/
6464
public function verifiableCredentialIssuance(Request $request): Response
6565
{
66+
$setupErrors = [];
67+
68+
if (!$this->moduleConfig->getVerifiableCredentialEnabled()) {
69+
$setupErrors[] = 'Verifiable Credential functionalities are not enabled.';
70+
}
71+
6672
$selectedAuthSourceId = $this->sessionService->getCurrentSession()->getData('vci', 'auth_source_id');
6773

6874
$authSource = null;
@@ -85,20 +91,46 @@ public function verifiableCredentialIssuance(Request $request): Response
8591
$selectedAuthSourceId = $newAuthSourceId;
8692
}
8793

94+
$authSourceIds = array_filter(
95+
$this->sspBridge->auth()->source()->getSources(),
96+
fn (string $authSourceId): bool => $authSourceId !== 'admin',
97+
);
8898

8999
if (
90100
$authSource instanceof Simple &&
91101
($authSource->isAuthenticated() === false) &&
92-
is_string($selectedAuthSourceId)
102+
is_string($selectedAuthSourceId) &&
103+
in_array($selectedAuthSourceId, $authSourceIds, true)
93104
) {
94105
$authSource->login(['ReturnTo' => $this->routes->urlAdminTestVerifiableCredentialIssuance()]);
95106
}
96107

97-
$authSourceIds = array_filter(
98-
$this->sspBridge->auth()->source()->getSources(),
99-
fn (string $authSourceId): bool => $authSourceId !== 'admin',
108+
$selectedCredentialConfigurationId = $this->sessionService->getCurrentSession()->getData(
109+
'vci',
110+
'credential_configuration_id',
100111
);
101112

113+
if (is_string($newCredentialConfigurationId = $request->get('credentialConfigurationId'))) {
114+
$this->sessionService->getCurrentSession()->setData(
115+
'vci',
116+
'credential_configuration_id',
117+
$newCredentialConfigurationId,
118+
);
119+
$selectedCredentialConfigurationId = $newCredentialConfigurationId;
120+
}
121+
122+
$credentialConfigurationIdsSupported = $this->moduleConfig->getCredentialConfigurationIdsSupported();
123+
124+
if (empty($credentialConfigurationIdsSupported)) {
125+
$setupErrors[] = 'No credential configuration IDs configured.';
126+
}
127+
128+
if (
129+
is_null($selectedCredentialConfigurationId) ||
130+
!in_array($selectedCredentialConfigurationId, $credentialConfigurationIdsSupported, true)
131+
) {
132+
$selectedCredentialConfigurationId = current($credentialConfigurationIdsSupported);
133+
}
102134

103135
$credentialOfferQrUri = null;
104136
$credentialOfferUri = null;
@@ -147,19 +179,23 @@ public function verifiableCredentialIssuance(Request $request): Response
147179
$clientId = '1234567890';
148180
$clientSecret = '1234567890';
149181

150-
if (($client = $this->clientRepository->findById($clientId)) === null) {
151-
$client = $this->clientEntityFactory->fromData(
152-
id: $clientId,
153-
secret: $clientSecret,
154-
name: 'VCI Pre-authorized Code Test Client',
155-
description: 'Test client for VCI Pre-authorized Code',
156-
redirectUri: ['https://example.com/oidc/callback'],
157-
scopes: ['openid', 'ResearchAndScholarshipCredentialJwtVcJson'], // TODO mivanci from config
158-
isEnabled: true,
159-
);
182+
$client = $this->clientEntityFactory->fromData(
183+
id: $clientId,
184+
secret: $clientSecret,
185+
name: 'VCI Pre-authorized Code Test Client',
186+
description: 'Test client for VCI Pre-authorized Code',
187+
redirectUri: ['https://example.com/oidc/callback'],
188+
scopes: ['openid', ...$credentialConfigurationIdsSupported], // Test Client so will have
189+
isEnabled: true,
190+
);
160191

192+
if ($this->clientRepository->findById($clientId) === null) {
161193
$this->clientRepository->add($client);
194+
} else {
195+
$this->clientRepository->update($client);
162196
}
197+
198+
// TODO mivanci Randomly generate auth code.
163199
$authCodeId = '1234567890';
164200

165201
// TODO mivanci Add indication of preauthz code to the auth code table.
@@ -170,7 +206,7 @@ public function verifiableCredentialIssuance(Request $request): Response
170206
client: $client,
171207
scopes: [
172208
new ScopeEntity('openid'),
173-
new ScopeEntity('ResearchAndScholarshipCredentialJwtVcJson'),
209+
new ScopeEntity($selectedCredentialConfigurationId),
174210
],
175211
expiryDateTime: new \DateTimeImmutable('+1 month'),
176212
userIdentifier: $userId,
@@ -185,7 +221,7 @@ public function verifiableCredentialIssuance(Request $request): Response
185221
parameters: [
186222
ClaimsEnum::CredentialIssuer->value => $this->moduleConfig->getIssuer(),
187223
ClaimsEnum::CredentialConfigurationIds->value => [
188-
'ResearchAndScholarshipCredentialJwtVcJson', // TODO mivanci from config
224+
$selectedCredentialConfigurationId,
189225
],
190226
ClaimsEnum::Grants->value => [
191227
GrantTypesEnum::PreAuthorizedCode->value => [
@@ -210,6 +246,7 @@ public function verifiableCredentialIssuance(Request $request): Response
210246

211247
$credentialOfferUri = "openid-credential-offer://?$parameterName=$credentialOfferValue";
212248

249+
// TODO mivanci Local QR code generator
213250
// https://quickchart.io/documentation/qr-codes/
214251
$credentialOfferQrUri = 'https://quickchart.io/qr?size=200&margin=1&text=' . urlencode($credentialOfferUri);
215252
}
@@ -223,11 +260,14 @@ public function verifiableCredentialIssuance(Request $request): Response
223260
return $this->templateFactory->build(
224261
'oidc:tests/verifiable-credential-issuance.twig',
225262
compact(
263+
'setupErrors',
226264
'credentialOfferQrUri',
227265
'credentialOfferUri',
228266
'authSourceIds',
229267
'authSourceActionRoute',
230268
'authSource',
269+
'credentialConfigurationIdsSupported',
270+
'selectedCredentialConfigurationId'
231271
),
232272
RoutesEnum::AdminTestVerifiableCredentialIssuance->value,
233273
);

src/ModuleConfig.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,11 @@ public function getCredentialConfigurationsSupported(): array
794794
return $this->config()->getOptionalArray(self::OPTION_CREDENTIAL_CONFIGURATIONS_SUPPORTED, []) ?? [];
795795
}
796796

797+
public function getCredentialConfigurationIdsSupported(): array
798+
{
799+
return array_keys($this->getCredentialConfigurationsSupported());
800+
}
801+
797802
/**
798803
* Extract and parse the claims path definition from the credential configuration supported.
799804
* Returns an array of valid paths for the claims.

templates/tests/verifiable-credential-issuance.twig

Lines changed: 75 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4,54 +4,87 @@
44

55
{% block oidcContent %}
66

7-
<h4>Pre-Authorized Code</h4>
8-
<p>
9-
{{ 'You can use info below to test Verifiable Credential Issuance.'|trans }}
10-
</p>
11-
12-
{% if not authSource or not authSource.isAuthenticated %}
13-
<form method="post"
14-
action="{{ authSourceActionRoute }}"
15-
class="pure-form pure-form-stacked">
16-
<fieldset>
17-
<label for="authSourceId">{{ 'Auth Source ID'|trans }}</label>
18-
<select name="authSourceId" id="authSourceId">
19-
{% for authSourceId in authSourceIds %}
20-
<option value="{{ authSourceId }}">{{ authSourceId }}</option>
21-
{% endfor %}
22-
</select>
23-
24-
<br>
25-
<button type="submit" class="pure-button ">{{ (actionText|default('Login'))|trans }}</button>
26-
</fieldset>
27-
</form>
28-
{% else %}
7+
{% if setupErrors %}
298
<p>
30-
You are currently authenticated with the following user data:
9+
{{ 'There are some setup errors which you should deal with before proceeding.'|trans }}
3110
<br>
32-
<code class="code-box code-box-content">
33-
{{- authSource.getAttributes|json_encode(constant('JSON_PRETTY_PRINT') b-or constant('JSON_UNESCAPED_SLASHES')) -}}
34-
</code>
11+
{{ setupErrors|join('<br>') }}
3512
</p>
36-
<form method="post"
37-
action="{{ authSourceActionRoute }}"
38-
class="pure-form pure-form-stacked">
39-
<fieldset>
40-
<button type="submit" name="logout" class="pure-button ">{{ (actionText|default('Logout'))|trans }}</button>
41-
</fieldset>
42-
</form>
43-
{% endif %}
13+
{% else %}
4414

15+
<h4>Pre-Authorized Code</h4>
16+
17+
{% if not authSource or not authSource.isAuthenticated %}
18+
19+
<p>
20+
{{ 'To test Verifiable Credential issuance using pre-authorized code, choose authentication source, desired Credential Configuration ID, and click Proceed.'|trans }}
21+
{{ 'Once you log in, you will be presented with a Credential Offer which you can use to test credential issuance.'|trans }}
22+
</p>
23+
24+
<form method="post"
25+
action="{{ authSourceActionRoute }}"
26+
class="pure-form pure-form-stacked">
27+
<fieldset>
28+
<label for="authSourceId">{{ 'Auth Source ID'|trans }}</label>
29+
<select name="authSourceId" id="authSourceId">
30+
{% for authSourceId in authSourceIds %}
31+
<option value="{{ authSourceId }}">{{ authSourceId }}</option>
32+
{% endfor %}
33+
</select>
34+
<span class="pure-form-message">
35+
{% trans %}Authentication source to be used for user login.{% endtrans %}
36+
</span>
37+
38+
<label for="credentialConfigurationId">{{ 'Credential Configuration ID'|trans }}</label>
39+
<select name="credentialConfigurationId" id="credentialConfigurationId">
40+
{% for credentialConfigurationId in credentialConfigurationIdsSupported %}
41+
<option value="{{ credentialConfigurationId }}">{{ credentialConfigurationId }}</option>
42+
{% endfor %}
43+
</select>
44+
<span class="pure-form-message">
45+
{% trans %}Credential Configuration ID to be offered.{% endtrans %}
46+
</span>
47+
48+
<br>
49+
<button type="submit" class="pure-button ">{{ (actionText|default('Proceed'))|trans }}</button>
50+
</fieldset>
51+
</form>
52+
{% else %}
53+
<p>
54+
You are currently authenticated with the following user data:
55+
<br>
56+
<code class="code-box code-box-content">
57+
{{- authSource.getAttributes|json_encode(constant('JSON_PRETTY_PRINT') b-or constant('JSON_UNESCAPED_SLASHES')) -}}
58+
</code>
59+
</p>
60+
61+
{% endif %}
62+
63+
64+
{% if credentialOfferUri and credentialOfferQrUri %}
65+
<p>
66+
Credential Offer:
67+
<code class="code-box code-box-content">
68+
{{- credentialOfferUri -}}
69+
</code>
70+
</p>
71+
<img src="{{ credentialOfferQrUri }}" alt="QR Code" />
72+
{% endif %}
73+
74+
{% if authSource and authSource.isAuthenticated %}
75+
<form method="post"
76+
action="{{ authSourceActionRoute }}"
77+
class="pure-form pure-form-stacked">
78+
<fieldset>
79+
<button type="submit" name="logout" class="pure-button ">
80+
{{ (actionText|default('Clear'))|trans }}
81+
</button>
82+
</fieldset>
83+
</form>
84+
{% endif %}
4585

46-
{% if credentialOfferUri and credentialOfferQrUri %}
47-
<p>
48-
Credential Offer (Pre-Authorized Code)
49-
<code class="code-box code-box-content">
50-
{{- credentialOfferUri -}}
51-
</code>
52-
</p>
53-
<img src="{{ credentialOfferQrUri }}" alt="QR Code" />
5486
{% endif %}
5587

5688

89+
5790
{% endblock oidcContent -%}

0 commit comments

Comments
 (0)