@@ -556,3 +556,65 @@ func TestBuildTargetDatalogFacts(t *testing.T) {
556556 })
557557 }
558558}
559+
560+ func TestRegionFactsAndCheck (t * testing.T ) {
561+ pub , priv := makeKeyPair (t )
562+
563+ if facts := RegionFacts ("" ); facts != nil {
564+ t .Errorf ("RegionFacts(\" \" ) = %v, want nil" , facts )
565+ }
566+ if _ , err := RegionCheck (nil ); err == nil {
567+ t .Error ("RegionCheck(nil): expected error, got nil" )
568+ }
569+ if _ , err := RegionCheck ([]string {"MARS" }); err == nil {
570+ t .Error ("RegionCheck(MARS): expected error, got nil" )
571+ }
572+
573+ tests := []struct {
574+ name string
575+ claimed string // minted into the token via RegionFacts
576+ required []string
577+ expectAllow bool
578+ }{
579+ {"finer claim satisfies coarser requirement" , "EU-DE-BY" , []string {"EU" }, true },
580+ {"exact level match" , "EU-DE" , []string {"EU-DE" }, true },
581+ {"any-of requirement" , "NA-US" , []string {"EU" , "NA-US" }, true },
582+ {"lowercase requirement is normalized" , "EU-DE" , []string {"eu" }, true },
583+ {"coarser claim never satisfies finer requirement" , "EU" , []string {"EU-DE" }, false },
584+ {"disjoint region" , "NA-US" , []string {"EU" }, false },
585+ {"unattested token fails closed" , "" , []string {"EU" }, false },
586+ }
587+
588+ for _ , tt := range tests {
589+ t .Run (tt .name , func (t * testing.T ) {
590+ builder := biscuit .NewBuilder (priv )
591+ for _ , fact := range RegionFacts (tt .claimed ) {
592+ if err := builder .AddAuthorityFact (fact ); err != nil {
593+ t .Fatalf ("failed to add region fact: %v" , err )
594+ }
595+ }
596+ tok , err := builder .Build ()
597+ if err != nil {
598+ t .Fatalf ("failed to build token: %v" , err )
599+ }
600+
601+ authorizer , err := tok .Authorizer (pub , biscuit .WithWorldOptions (datalog .WithMaxDuration (5 * time .Second )))
602+ if err != nil {
603+ t .Fatalf ("failed to create authorizer: %v" , err )
604+ }
605+ check , err := RegionCheck (tt .required )
606+ if err != nil {
607+ t .Fatalf ("RegionCheck(%v): %v" , tt .required , err )
608+ }
609+ authorizer .AddCheck (check )
610+ authorizer .AddPolicy (AllowIfTruePolicy )
611+
612+ err = authorizer .Authorize ()
613+ if tt .expectAllow && err != nil {
614+ t .Errorf ("expected authorized, got error: %v" , err )
615+ } else if ! tt .expectAllow && err == nil {
616+ t .Error ("expected denied, but authorization succeeded" )
617+ }
618+ })
619+ }
620+ }
0 commit comments