@@ -10,6 +10,10 @@ import {
1010 printServerSummary ,
1111 runInteractiveMode
1212} from './runner' ;
13+ import {
14+ printAuthorizationServerSummary ,
15+ runAuthorizationServerConformanceTest
16+ } from './runner/authorization-server' ;
1317import {
1418 listScenarios ,
1519 listClientScenarios ,
@@ -24,11 +28,17 @@ import {
2428 listScenariosForSpec ,
2529 listClientScenariosForSpec ,
2630 getScenarioSpecVersions ,
31+ listClientScenariosForAuthorizationServer ,
32+ listClientScenariosForAuthorizationServerForSpec ,
2733 resolveSpecVersion
2834} from './scenarios' ;
2935import type { SpecVersion } from './scenarios' ;
3036import { ConformanceCheck } from './types' ;
31- import { ClientOptionsSchema , ServerOptionsSchema } from './schemas' ;
37+ import {
38+ AuthorizationServerOptionsSchema ,
39+ ClientOptionsSchema ,
40+ ServerOptionsSchema
41+ } from './schemas' ;
3242import {
3343 loadExpectedFailures ,
3444 evaluateBaseline ,
@@ -44,12 +54,19 @@ import packageJson from '../package.json';
4454function filterScenariosBySpecVersion (
4555 allScenarios : string [ ] ,
4656 version : SpecVersion ,
47- command : 'client' | 'server'
57+ command : 'client' | 'server' | 'authorization'
4858) : string [ ] {
49- const versionScenarios =
50- command === 'client'
51- ? listScenariosForSpec ( version )
52- : listClientScenariosForSpec ( version ) ;
59+ let versionScenarios : string [ ] ;
60+ if ( command === 'client' ) {
61+ versionScenarios = listScenariosForSpec ( version ) ;
62+ } else if ( command === 'server' ) {
63+ versionScenarios = listClientScenariosForSpec ( version ) ;
64+ } else if ( command === 'authorization' ) {
65+ versionScenarios =
66+ listClientScenariosForAuthorizationServerForSpec ( version ) ;
67+ } else {
68+ versionScenarios = [ ] ;
69+ }
5370 const allowed = new Set ( versionScenarios ) ;
5471 return allScenarios . filter ( ( s ) => allowed . has ( s ) ) ;
5572}
@@ -437,6 +454,87 @@ program
437454 }
438455 } ) ;
439456
457+ // Authorization command - tests an authorization server implementation
458+ program
459+ . command ( 'authorization' )
460+ . description (
461+ 'Run conformance tests against an authorization server implementation'
462+ )
463+ . requiredOption ( '--url <url>' , 'URL of the authorization server issuer' )
464+ . option ( '-o, --output-dir <path>' , 'Save results to this directory' )
465+ . option (
466+ '--spec-version <version>' ,
467+ 'Filter scenarios by spec version (cumulative for date versions)'
468+ )
469+ . action ( async ( options ) => {
470+ try {
471+ // Validate options with Zod
472+ const validated = AuthorizationServerOptionsSchema . parse ( options ) ;
473+ const outputDir = options . outputDir ;
474+ const specVersionFilter = options . specVersion
475+ ? resolveSpecVersion ( options . specVersion )
476+ : undefined ;
477+
478+ let scenarios : string [ ] ;
479+ scenarios = listClientScenariosForAuthorizationServer ( ) ;
480+ if ( specVersionFilter ) {
481+ scenarios = filterScenariosBySpecVersion (
482+ scenarios ,
483+ specVersionFilter ,
484+ 'authorization'
485+ ) ;
486+ }
487+ console . log (
488+ `Running test (${ scenarios . length } scenarios) against ${ validated . url } \n`
489+ ) ;
490+
491+ const allResults : { scenario : string ; checks: ConformanceCheck [ ] } [ ] = [ ] ;
492+ for ( const scenarioName of scenarios ) {
493+ console . log ( `\n=== Running scenario: ${ scenarioName } ===` ) ;
494+ try {
495+ const result = await runAuthorizationServerConformanceTest (
496+ validated . url ,
497+ scenarioName ,
498+ outputDir
499+ ) ;
500+ allResults . push ( { scenario : scenarioName , checks : result . checks } ) ;
501+ } catch ( error ) {
502+ console . error ( `Failed to run scenario ${ scenarioName } :` , error ) ;
503+ allResults . push ( {
504+ scenario : scenarioName ,
505+ checks : [
506+ {
507+ id : scenarioName ,
508+ name : scenarioName ,
509+ description : 'Failed to run scenario' ,
510+ status : 'FAILURE' ,
511+ timestamp : new Date ( ) . toISOString ( ) ,
512+ errorMessage :
513+ error instanceof Error ? error . message : String ( error )
514+ }
515+ ]
516+ } ) ;
517+ }
518+ }
519+ const { totalFailed } = printAuthorizationServerSummary ( allResults ) ;
520+ process . exit ( totalFailed > 0 ? 1 : 0 ) ;
521+ } catch ( error ) {
522+ if ( error instanceof ZodError ) {
523+ console . error ( 'Validation error:' ) ;
524+ error . issues . forEach ( ( err ) => {
525+ console . error ( ` ${ err . path . join ( '.' ) } : ${ err . message } ` ) ;
526+ } ) ;
527+ console . error ( '\nAvailable authorization server scenarios:' ) ;
528+ listClientScenariosForAuthorizationServer ( ) . forEach ( ( s ) =>
529+ console . error ( ` - ${ s } ` )
530+ ) ;
531+ process . exit ( 1 ) ;
532+ }
533+ console . error ( 'Authorization server test error:' , error ) ;
534+ process . exit ( 1 ) ;
535+ }
536+ } ) ;
537+
440538// Tier check command
441539program . addCommand ( createTierCheckCommand ( ) ) ;
442540
@@ -446,6 +544,7 @@ program
446544 . description ( 'List available test scenarios' )
447545 . option ( '--client' , 'List client scenarios' )
448546 . option ( '--server' , 'List server scenarios' )
547+ . option ( '--authorization' , 'List authorization server scenarios' )
449548 . option (
450549 '--spec-version <version>' ,
451550 'Filter scenarios by spec version (cumulative for date versions)'
@@ -455,7 +554,10 @@ program
455554 ? resolveSpecVersion ( options . specVersion )
456555 : undefined ;
457556
458- if ( options . server || ( ! options . client && ! options . server ) ) {
557+ if (
558+ options . server ||
559+ ( ! options . client && ! options . server && ! options . authorization )
560+ ) {
459561 console . log ( 'Server scenarios (test against a server):' ) ;
460562 let serverScenarios = listClientScenarios ( ) ;
461563 if ( specVersionFilter ) {
@@ -471,7 +573,10 @@ program
471573 } ) ;
472574 }
473575
474- if ( options . client || ( ! options . client && ! options . server ) ) {
576+ if (
577+ options . client ||
578+ ( ! options . client && ! options . server && ! options . authorization )
579+ ) {
475580 if ( options . server || ( ! options . client && ! options . server ) ) {
476581 console . log ( '' ) ;
477582 }
@@ -489,6 +594,31 @@ program
489594 console . log ( ` - ${ s } ${ v ? ` [${ v } ]` : '' } ` ) ;
490595 } ) ;
491596 }
597+
598+ if (
599+ options . authorization ||
600+ ( ! options . authorization && ! options . server && ! options . client )
601+ ) {
602+ if ( ! ( options . authorization && ! options . server && ! options . client ) ) {
603+ console . log ( '' ) ;
604+ }
605+ console . log (
606+ 'Authorization server scenarios (test against an authorization server):'
607+ ) ;
608+ let authorizationServerScenarios =
609+ listClientScenariosForAuthorizationServer ( ) ;
610+ if ( specVersionFilter ) {
611+ authorizationServerScenarios = filterScenariosBySpecVersion (
612+ authorizationServerScenarios ,
613+ specVersionFilter ,
614+ 'authorization'
615+ ) ;
616+ }
617+ authorizationServerScenarios . forEach ( ( s ) => {
618+ const v = getScenarioSpecVersions ( s ) ;
619+ console . log ( ` - ${ s } ${ v ? ` [${ v } ]` : '' } ` ) ;
620+ } ) ;
621+ }
492622 } ) ;
493623
494624program . parse ( ) ;
0 commit comments