1313use SimpleSAML \Module \oidc \Entities \UserEntity ;
1414use SimpleSAML \Module \oidc \Factories \Entities \AuthCodeEntityFactory ;
1515use SimpleSAML \Module \oidc \Factories \Entities \ClientEntityFactory ;
16+ use SimpleSAML \Module \oidc \Factories \Entities \IssuerStateEntityFactory ;
1617use SimpleSAML \Module \oidc \Factories \Entities \UserEntityFactory ;
1718use SimpleSAML \Module \oidc \ModuleConfig ;
1819use SimpleSAML \Module \oidc \Repositories \AuthCodeRepository ;
2122use SimpleSAML \Module \oidc \Services \LoggerService ;
2223use SimpleSAML \OpenID \Codebooks \ClaimsEnum ;
2324use SimpleSAML \OpenID \Codebooks \GrantTypesEnum ;
25+ use SimpleSAML \OpenID \Exceptions \OpenIdException ;
2426use SimpleSAML \OpenID \VerifiableCredentials ;
2527use SimpleSAML \OpenID \VerifiableCredentials \TxCode ;
2628
@@ -38,9 +40,59 @@ public function __construct(
3840 protected readonly UserRepository $ userRepository ,
3941 protected readonly UserEntityFactory $ userEntityFactory ,
4042 protected readonly EmailFactory $ emailFactory ,
43+ protected readonly IssuerStateEntityFactory $ issuerStateEntityFactory ,
4144 ) {
4245 }
4346
47+ /**
48+ * @param string[] $credentialConfigurationIds
49+ * @throws \SimpleSAML\OpenId\Exceptions\OpenIdException
50+ */
51+ public function buildForAuthorization (
52+ array $ credentialConfigurationIds ,
53+ ): string {
54+
55+ $ issuerState = null ;
56+
57+ $ issuerStateGenerationAttempts = 3 ;
58+ while ($ issuerStateGenerationAttempts > 0 ) {
59+ $ newIssuerState = $ this ->issuerStateEntityFactory ->buildNew ();
60+ if ($ this ->authCodeRepository ->findById ($ newIssuerState ->getValue ()) === null ) {
61+ $ issuerState = $ newIssuerState ;
62+ break ;
63+ }
64+ $ issuerStateGenerationAttempts --;
65+ }
66+
67+ if ($ issuerState === null ) {
68+ throw new OpenIdException ('Failed to generate issuer state. ' );
69+ }
70+
71+
72+ $ credentialOffer = $ this ->verifiableCredentials ->credentialOfferFactory ()->from (
73+ parameters: [
74+ ClaimsEnum::CredentialIssuer->value => $ this ->moduleConfig ->getIssuer (),
75+ ClaimsEnum::CredentialConfigurationIds->value => [
76+ ...$ credentialConfigurationIds ,
77+ ],
78+ ClaimsEnum::Grants->value => [
79+ GrantTypesEnum::AuthorizationCode->value => [
80+ ClaimsEnum::IssuerState->value => $ issuerState ->getValue (),
81+ ],
82+ ],
83+ ],
84+ );
85+
86+ $ credentialOfferValue = $ credentialOffer ->jsonSerialize ();
87+ $ parameterName = ParametersEnum::CredentialOfferUri->value ;
88+ if (is_array ($ credentialOfferValue )) {
89+ $ parameterName = ParametersEnum::CredentialOffer->value ;
90+ $ credentialOfferValue = json_encode ($ credentialOfferValue );
91+ }
92+
93+ return "openid-credential-offer://? $ parameterName= $ credentialOfferValue " ;
94+ }
95+
4496 /**
4597 * @param string[] $credentialConfigurationIds
4698 * @throws \SimpleSAML\OpenId\Exceptions\OpenIdException
@@ -119,8 +171,9 @@ public function buildPreAuthorized(
119171 $ authCodeId = null ;
120172 $ authCodeIdGenerationAttempts = 3 ;
121173 while ($ authCodeIdGenerationAttempts > 0 ) {
122- $ authCodeId = $ this ->sspBridge ->utils ()->random ()->generateID ();
123- if ($ this ->authCodeRepository ->findById ($ authCodeId ) === null ) {
174+ $ newAuthCodeId = $ this ->sspBridge ->utils ()->random ()->generateID ();
175+ if ($ this ->authCodeRepository ->findById ($ newAuthCodeId ) === null ) {
176+ $ authCodeId = $ newAuthCodeId ;
124177 break ;
125178 }
126179 $ authCodeIdGenerationAttempts --;
0 commit comments