@@ -36,11 +36,12 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
3636
3737 try
3838 {
39+ var registration = await _service . GetClientRegistrationByProviderNameAsync ( provider , stoppingToken ) ;
3940 var configuration = await _service . GetServerConfigurationByProviderNameAsync ( provider , stoppingToken ) ;
4041
41- if ( await AuthenticateUserInteractivelyAsync ( configuration , stoppingToken ) )
42+ if ( await AuthenticateUserInteractivelyAsync ( registration , configuration , stoppingToken ) )
4243 {
43- var flow = await GetSelectedFlowAsync ( configuration , stoppingToken ) ;
44+ var flow = await GetSelectedFlowAsync ( registration , configuration , stoppingToken ) ;
4445
4546 AnsiConsole . MarkupLine ( "[cyan]Launching the system browser.[/]" ) ;
4647
@@ -144,7 +145,7 @@ await _service.AuthenticateInteractivelyAsync(new()
144145
145146 else
146147 {
147- var type = await GetSelectedGrantTypeAsync ( configuration , stoppingToken ) ;
148+ var type = await GetSelectedGrantTypeAsync ( registration , configuration , stoppingToken ) ;
148149 if ( type is GrantTypes . DeviceCode )
149150 {
150151 // Ask OpenIddict to send a device authorization request and write
@@ -439,34 +440,48 @@ async Task<string> PromptAsync() => AnsiConsole.Prompt(new SelectionPrompt<OpenI
439440 }
440441
441442 Task < ( string ? GrantType , string ? ResponseType ) > GetSelectedFlowAsync (
443+ OpenIddictClientRegistration registration ,
442444 OpenIddictConfiguration configuration , CancellationToken cancellationToken )
443445 {
444- static ( string ? GrantType , string ? ResponseType ) Prompt ( OpenIddictConfiguration configuration )
446+ static ( string ? GrantType , string ? ResponseType ) Prompt (
447+ OpenIddictClientRegistration registration , OpenIddictConfiguration configuration )
445448 {
446449 List < ( ( string ? GrantType , string ? ResponseType ) , string DisplayName ) > choices = [ ] ;
447450
448- var types = configuration . ResponseTypesSupported . Select ( type =>
451+ var types = configuration . ResponseTypesSupported . Select ( static type =>
449452 new HashSet < string > ( type . Split ( Separators . Space , StringSplitOptions . RemoveEmptyEntries ) ) ) ;
450453
451454 if ( configuration . GrantTypesSupported . Contains ( GrantTypes . AuthorizationCode ) &&
452- types . Any ( type => type . Count is 1 && type . Contains ( ResponseTypes . Code ) ) )
455+ ( registration . GrantTypes . Count is 0 || registration . GrantTypes . Contains ( GrantTypes . AuthorizationCode ) ) &&
456+ types . Any ( static type => type . Count is 1 && type . Contains ( ResponseTypes . Code ) ) &&
457+ ( registration . ResponseTypes . Count is 0 || registration . ResponseTypes
458+ . Select ( static type => new HashSet < string > ( type . Split ( Separators . Space , StringSplitOptions . RemoveEmptyEntries ) ) )
459+ . Any ( static type => type . Count is 1 && type . Contains ( ResponseTypes . Code ) ) ) )
453460 {
454461 choices . Add ( ( (
455462 GrantType : GrantTypes . AuthorizationCode ,
456463 ResponseType : ResponseTypes . Code ) , "Authorization code flow" ) ) ;
457464 }
458465
459- if ( configuration . GrantTypesSupported . Contains ( GrantTypes . Implicit ) )
466+ if ( configuration . GrantTypesSupported . Contains ( GrantTypes . Implicit ) &&
467+ ( registration . GrantTypes . Count is 0 || registration . GrantTypes . Contains ( GrantTypes . Implicit ) ) )
460468 {
461- if ( types . Any ( type => type . Count is 1 && type . Contains ( ResponseTypes . IdToken ) ) )
469+ if ( types . Any ( static type => type . Count is 1 && type . Contains ( ResponseTypes . IdToken ) ) &&
470+ ( registration . ResponseTypes . Count is 0 || registration . ResponseTypes
471+ . Select ( static type => new HashSet < string > ( type . Split ( Separators . Space , StringSplitOptions . RemoveEmptyEntries ) ) )
472+ . Any ( static type => type . Count is 1 && type . Contains ( ResponseTypes . IdToken ) ) ) )
462473 {
463474 choices . Add ( ( (
464475 GrantType : GrantTypes . Implicit ,
465476 ResponseType : ResponseTypes . IdToken ) , "Implicit flow (id_token)" ) ) ;
466477 }
467478
468- if ( types . Any ( type => type . Count is 2 && type . Contains ( ResponseTypes . IdToken ) &&
469- type . Contains ( ResponseTypes . Token ) ) )
479+ if ( types . Any ( static type => type . Count is 2 && type . Contains ( ResponseTypes . IdToken ) &&
480+ type . Contains ( ResponseTypes . Token ) ) &&
481+ ( registration . ResponseTypes . Count is 0 || registration . ResponseTypes
482+ . Select ( static type => new HashSet < string > ( type . Split ( Separators . Space , StringSplitOptions . RemoveEmptyEntries ) ) )
483+ . Any ( static type => type . Count is 2 && type . Contains ( ResponseTypes . IdToken ) &&
484+ type . Contains ( ResponseTypes . Token ) ) ) )
470485 {
471486 choices . Add ( ( (
472487 GrantType : GrantTypes . Implicit ,
@@ -475,36 +490,54 @@ async Task<string> PromptAsync() => AnsiConsole.Prompt(new SelectionPrompt<OpenI
475490 }
476491
477492 if ( configuration . GrantTypesSupported . Contains ( GrantTypes . AuthorizationCode ) &&
478- configuration . GrantTypesSupported . Contains ( GrantTypes . Implicit ) )
493+ configuration . GrantTypesSupported . Contains ( GrantTypes . Implicit ) &&
494+ ( registration . GrantTypes . Count is 0 || ( registration . GrantTypes . Contains ( GrantTypes . AuthorizationCode ) &&
495+ registration . GrantTypes . Contains ( GrantTypes . Implicit ) ) ) )
479496 {
480- if ( types . Any ( type => type . Count is 2 && type . Contains ( ResponseTypes . Code ) &&
481- type . Contains ( ResponseTypes . IdToken ) ) )
497+ if ( types . Any ( static type => type . Count is 2 && type . Contains ( ResponseTypes . Code ) &&
498+ type . Contains ( ResponseTypes . IdToken ) ) &&
499+ ( registration . ResponseTypes . Count is 0 || registration . ResponseTypes
500+ . Select ( static type => new HashSet < string > ( type . Split ( Separators . Space , StringSplitOptions . RemoveEmptyEntries ) ) )
501+ . Any ( static type => type . Count is 2 && type . Contains ( ResponseTypes . Code ) &&
502+ type . Contains ( ResponseTypes . IdToken ) ) ) )
482503 {
483504 choices . Add ( ( (
484505 GrantType : GrantTypes . AuthorizationCode ,
485506 ResponseType : ResponseTypes . Code + ' ' + ResponseTypes . IdToken ) , "Hybrid flow (code + id_token)" ) ) ;
486507 }
487508
488- if ( types . Any ( type => type . Count is 3 && type . Contains ( ResponseTypes . Code ) &&
509+ if ( types . Any ( static type => type . Count is 3 && type . Contains ( ResponseTypes . Code ) &&
489510 type . Contains ( ResponseTypes . IdToken ) &&
490- type . Contains ( ResponseTypes . Token ) ) )
511+ type . Contains ( ResponseTypes . Token ) ) &&
512+ ( registration . ResponseTypes . Count is 0 || registration . ResponseTypes
513+ . Select ( static type => new HashSet < string > ( type . Split ( Separators . Space , StringSplitOptions . RemoveEmptyEntries ) ) )
514+ . Any ( static type => type . Count is 3 && type . Contains ( ResponseTypes . Code ) &&
515+ type . Contains ( ResponseTypes . IdToken ) &&
516+ type . Contains ( ResponseTypes . Token ) ) ) )
491517 {
492518 choices . Add ( ( (
493519 GrantType : GrantTypes . AuthorizationCode ,
494520 ResponseType : ResponseTypes . Code + ' ' + ResponseTypes . IdToken + ' ' + ResponseTypes . Token ) ,
495521 "Hybrid flow (code + id_token + token)" ) ) ;
496522 }
497523
498- if ( types . Any ( type => type . Count is 2 && type . Contains ( ResponseTypes . Code ) &&
499- type . Contains ( ResponseTypes . Token ) ) )
524+ if ( types . Any ( static type => type . Count is 2 && type . Contains ( ResponseTypes . Code ) &&
525+ type . Contains ( ResponseTypes . Token ) ) &&
526+ ( registration . ResponseTypes . Count is 0 || registration . ResponseTypes
527+ . Select ( static type => new HashSet < string > ( type . Split ( Separators . Space , StringSplitOptions . RemoveEmptyEntries ) ) )
528+ . Any ( static type => type . Count is 2 && type . Contains ( ResponseTypes . Code ) &&
529+ type . Contains ( ResponseTypes . Token ) ) ) )
500530 {
501531 choices . Add ( ( (
502532 GrantType : GrantTypes . AuthorizationCode ,
503533 ResponseType : ResponseTypes . Code + ' ' + ResponseTypes . Token ) , "Hybrid flow (code + token)" ) ) ;
504534 }
505535 }
506536
507- if ( types . Any ( type => type . Count is 1 && type . Contains ( ResponseTypes . None ) ) )
537+ if ( types . Any ( static type => type . Count is 1 && type . Contains ( ResponseTypes . None ) ) &&
538+ ( registration . ResponseTypes . Count is 0 || registration . ResponseTypes
539+ . Select ( static type => new HashSet < string > ( type . Split ( Separators . Space , StringSplitOptions . RemoveEmptyEntries ) ) )
540+ . Any ( static type => type . Count is 1 && type . Contains ( ResponseTypes . None ) ) ) )
508541 {
509542 choices . Add ( ( (
510543 GrantType : null ,
@@ -524,36 +557,42 @@ async Task<string> PromptAsync() => AnsiConsole.Prompt(new SelectionPrompt<OpenI
524557 . UseConverter ( choice => choice . DisplayName ) ) . Item1 ;
525558 }
526559
527- return WaitAsync ( Task . Run ( ( ) => Prompt ( configuration ) , cancellationToken ) , cancellationToken ) ;
560+ return WaitAsync ( Task . Run ( ( ) => Prompt ( registration , configuration ) , cancellationToken ) , cancellationToken ) ;
528561 }
529562
530- Task < string > GetSelectedGrantTypeAsync ( OpenIddictConfiguration configuration , CancellationToken cancellationToken )
563+ Task < string > GetSelectedGrantTypeAsync (
564+ OpenIddictClientRegistration registration ,
565+ OpenIddictConfiguration configuration , CancellationToken cancellationToken )
531566 {
532- static string Prompt ( OpenIddictConfiguration configuration )
567+ static string Prompt ( OpenIddictClientRegistration registration , OpenIddictConfiguration configuration )
533568 {
534569 List < ( string GrantType , string DisplayName ) > choices = [ ] ;
535570
536571 if ( configuration . GrantTypesSupported . Contains ( GrantTypes . DeviceCode ) &&
537572 configuration . DeviceAuthorizationEndpoint is not null &&
538- configuration . TokenEndpoint is not null )
573+ configuration . TokenEndpoint is not null &&
574+ ( registration . GrantTypes . Count is 0 || registration . GrantTypes . Contains ( GrantTypes . DeviceCode ) ) )
539575 {
540576 choices . Add ( ( GrantTypes . DeviceCode , "Device authorization code grant" ) ) ;
541577 }
542578
543579 if ( configuration . GrantTypesSupported . Contains ( GrantTypes . Password ) &&
544- configuration . TokenEndpoint is not null )
580+ configuration . TokenEndpoint is not null &&
581+ ( registration . GrantTypes . Count is 0 || registration . GrantTypes . Contains ( GrantTypes . Password ) ) )
545582 {
546583 choices . Add ( ( GrantTypes . Password , "Resource owner password credentials grant" ) ) ;
547584 }
548585
549586 if ( configuration . GrantTypesSupported . Contains ( GrantTypes . TokenExchange ) &&
550- configuration . TokenEndpoint is not null )
587+ configuration . TokenEndpoint is not null &&
588+ ( registration . GrantTypes . Count is 0 || registration . GrantTypes . Contains ( GrantTypes . TokenExchange ) ) )
551589 {
552590 choices . Add ( ( GrantTypes . TokenExchange , "Token exchange" ) ) ;
553591 }
554592
555593 if ( configuration . GrantTypesSupported . Contains ( GrantTypes . ClientCredentials ) &&
556- configuration . TokenEndpoint is not null )
594+ configuration . TokenEndpoint is not null &&
595+ ( registration . GrantTypes . Count is 0 || registration . GrantTypes . Contains ( GrantTypes . ClientCredentials ) ) )
557596 {
558597 choices . Add ( ( GrantTypes . ClientCredentials , "Client credentials grant (application authentication only)" ) ) ;
559598 }
@@ -569,10 +608,11 @@ configuration.DeviceAuthorizationEndpoint is not null &&
569608 . UseConverter ( choice => choice . DisplayName ) ) . GrantType ;
570609 }
571610
572- return WaitAsync ( Task . Run ( ( ) => Prompt ( configuration ) , cancellationToken ) , cancellationToken ) ;
611+ return WaitAsync ( Task . Run ( ( ) => Prompt ( registration , configuration ) , cancellationToken ) , cancellationToken ) ;
573612 }
574613
575614 Task < bool > AuthenticateUserInteractivelyAsync (
615+ OpenIddictClientRegistration registration ,
576616 OpenIddictConfiguration configuration , CancellationToken cancellationToken )
577617 {
578618 static bool Prompt ( ) => AnsiConsole . Prompt ( new ConfirmationPrompt (
@@ -583,10 +623,34 @@ static bool Prompt() => AnsiConsole.Prompt(new ConfirmationPrompt(
583623 ShowDefaultValue = true
584624 } ) ;
585625
586- if ( configuration . GrantTypesSupported . Contains ( GrantTypes . AuthorizationCode ) ||
587- configuration . GrantTypesSupported . Contains ( GrantTypes . Implicit ) )
626+ if ( configuration . GrantTypesSupported . Contains ( GrantTypes . AuthorizationCode ) &&
627+ ( registration . GrantTypes . Count is 0 || registration . GrantTypes . Contains ( GrantTypes . AuthorizationCode ) ) )
628+ {
629+ if ( configuration . GrantTypesSupported . Any ( static type => type is not (
630+ GrantTypes . AuthorizationCode or GrantTypes . Implicit or GrantTypes . RefreshToken ) ) &&
631+ ( registration . GrantTypes . Count is 0 ||
632+ registration . GrantTypes . Any ( static type => type is not (
633+ GrantTypes . AuthorizationCode or GrantTypes . Implicit or GrantTypes . RefreshToken ) ) ) )
634+ {
635+ return WaitAsync ( Task . Run ( Prompt , cancellationToken ) , cancellationToken ) ;
636+ }
637+
638+ return Task . FromResult ( true ) ;
639+ }
640+
641+ if ( configuration . GrantTypesSupported . Contains ( GrantTypes . Implicit ) &&
642+ ( registration . GrantTypes . Count is 0 || registration . GrantTypes . Contains ( GrantTypes . Implicit ) ) )
588643 {
589- return WaitAsync ( Task . Run ( Prompt , cancellationToken ) , cancellationToken ) ;
644+ if ( configuration . GrantTypesSupported . Any ( static type => type is not (
645+ GrantTypes . AuthorizationCode or GrantTypes . Implicit or GrantTypes . RefreshToken ) ) &&
646+ ( registration . GrantTypes . Count is 0 ||
647+ registration . GrantTypes . Any ( static type => type is not (
648+ GrantTypes . AuthorizationCode or GrantTypes . Implicit or GrantTypes . RefreshToken ) ) ) )
649+ {
650+ return WaitAsync ( Task . Run ( Prompt , cancellationToken ) , cancellationToken ) ;
651+ }
652+
653+ return Task . FromResult ( true ) ;
590654 }
591655
592656 return Task . FromResult ( false ) ;
0 commit comments