@@ -2471,6 +2471,327 @@ func TestToken(t *testing.T) {
2471
2471
Name : "jane" ,
2472
2472
},
2473
2473
},
2474
+ {
2475
+ name : "claim mappings with expressions and deeply nested claim - success" ,
2476
+ options : Options {
2477
+ JWTAuthenticator : apiserver.JWTAuthenticator {
2478
+ Issuer : apiserver.Issuer {
2479
+ URL : "https://auth.example.com" ,
2480
+ Audiences : []string {"my-client" },
2481
+ },
2482
+ ClaimValidationRules : []apiserver.ClaimValidationRule {
2483
+ {
2484
+ Expression : "claims.turtle.foo.other1.bit1 && !claims.turtle.foo.bar.other1.bit2" ,
2485
+ },
2486
+ },
2487
+ ClaimMappings : apiserver.ClaimMappings {
2488
+ Username : apiserver.PrefixedClaimOrExpression {
2489
+ Expression : "claims.turtle.foo.bar.baz.panda[0]" ,
2490
+ },
2491
+ UID : apiserver.ClaimOrExpression {
2492
+ Expression : "claims.turtle.foo.bar.baz.panda[1]" ,
2493
+ },
2494
+ Groups : apiserver.PrefixedClaimOrExpression {
2495
+ Expression : "claims.turtle.foo.bar.baz.panda" ,
2496
+ },
2497
+ Extra : []apiserver.ExtraMapping {
2498
+ {
2499
+ Key : "bio.snorlax.org/1" ,
2500
+ ValueExpression : "string(claims.turtle.foo.bar.other1.bit2)" ,
2501
+ },
2502
+ {
2503
+ Key : "bio.snorlax.org/2" ,
2504
+ ValueExpression : "string(claims.turtle.foo.bar.baz.other1.bit3)" ,
2505
+ },
2506
+ {
2507
+ Key : "bio.snorlax.org/3" ,
2508
+ ValueExpression : "[string(claims.turtle.foo.bar.baz.other1.bit1)] + ['a', 'b', 'c']" ,
2509
+ },
2510
+ },
2511
+ },
2512
+ UserValidationRules : []apiserver.UserValidationRule {
2513
+ {
2514
+ Expression : `user.username != "bad"` ,
2515
+ },
2516
+ {
2517
+ Expression : `user.uid == "007"` ,
2518
+ },
2519
+ {
2520
+ Expression : `"claus" in user.groups` ,
2521
+ },
2522
+ {
2523
+ Expression : `user.extra["bio.snorlax.org/3"].size() == 4` ,
2524
+ },
2525
+ },
2526
+ },
2527
+ now : func () time.Time { return now },
2528
+ },
2529
+ signingKey : loadRSAPrivKey (t , "testdata/rsa_1.pem" , jose .RS256 ),
2530
+ pubKeys : []* jose.JSONWebKey {
2531
+ loadRSAKey (t , "testdata/rsa_1.pem" , jose .RS256 ),
2532
+ },
2533
+ claims : fmt .Sprintf (`{
2534
+ "iss": "https://auth.example.com",
2535
+ "aud": "my-client",
2536
+ "exp": %d,
2537
+ "turtle": {
2538
+ "foo": {
2539
+ "1": "a",
2540
+ "2": "b",
2541
+ "other1": {
2542
+ "bit1": true,
2543
+ "bit2": false,
2544
+ "bit3": 1
2545
+ },
2546
+ "bar": {
2547
+ "3": "c",
2548
+ "4": "d",
2549
+ "other1": {
2550
+ "bit1": true,
2551
+ "bit2": false,
2552
+ "bit3": 1
2553
+ },
2554
+ "baz": {
2555
+ "5": "e",
2556
+ "6": "f",
2557
+ "panda": [
2558
+ "snorlax",
2559
+ "007",
2560
+ "santa",
2561
+ "claus"
2562
+ ],
2563
+ "other1": {
2564
+ "bit1": true,
2565
+ "bit2": false,
2566
+ "bit3": 1
2567
+ }
2568
+ }
2569
+ }
2570
+ }
2571
+ }
2572
+ }` , valid .Unix ()),
2573
+ want : & user.DefaultInfo {
2574
+ Name : "snorlax" ,
2575
+ UID : "007" ,
2576
+ Groups : []string {"snorlax" , "007" , "santa" , "claus" },
2577
+ Extra : map [string ][]string {
2578
+ "bio.snorlax.org/1" : {"false" },
2579
+ "bio.snorlax.org/2" : {"1" },
2580
+ "bio.snorlax.org/3" : {"true" , "a" , "b" , "c" },
2581
+ },
2582
+ },
2583
+ },
2584
+ {
2585
+ name : "claim mappings with expressions and deeply nested claim - success via optional" ,
2586
+ options : Options {
2587
+ JWTAuthenticator : apiserver.JWTAuthenticator {
2588
+ Issuer : apiserver.Issuer {
2589
+ URL : "https://auth.example.com" ,
2590
+ Audiences : []string {"my-client" },
2591
+ },
2592
+ ClaimValidationRules : []apiserver.ClaimValidationRule {
2593
+ {
2594
+ Expression : "claims.turtle.foo.other1.bit1 && !claims.turtle.foo.bar.other1.bit2" ,
2595
+ },
2596
+ },
2597
+ ClaimMappings : apiserver.ClaimMappings {
2598
+ Username : apiserver.PrefixedClaimOrExpression {
2599
+ Expression : "claims.turtle.foo.bar.baz.panda[0]" ,
2600
+ },
2601
+ UID : apiserver.ClaimOrExpression {
2602
+ Expression : "claims.turtle.foo.bar.baz.panda[1]" ,
2603
+ },
2604
+ Groups : apiserver.PrefixedClaimOrExpression {
2605
+ Expression : "claims.turtle.foo.bar.baz.?a.b.c.d.orValue([ 'claus' ])" , // this passes because of the optional
2606
+ },
2607
+ Extra : []apiserver.ExtraMapping {
2608
+ {
2609
+ Key : "bio.snorlax.org/1" ,
2610
+ ValueExpression : "string(claims.turtle.foo.bar.other1.bit2)" ,
2611
+ },
2612
+ {
2613
+ Key : "bio.snorlax.org/2" ,
2614
+ ValueExpression : "string(claims.turtle.foo.bar.baz.other1.bit3)" ,
2615
+ },
2616
+ {
2617
+ Key : "bio.snorlax.org/3" ,
2618
+ ValueExpression : "[string(claims.turtle.foo.bar.baz.other1.bit1)] + ['a', 'b', 'c']" ,
2619
+ },
2620
+ },
2621
+ },
2622
+ UserValidationRules : []apiserver.UserValidationRule {
2623
+ {
2624
+ Expression : `user.username != "bad"` ,
2625
+ },
2626
+ {
2627
+ Expression : `user.uid == "007"` ,
2628
+ },
2629
+ {
2630
+ Expression : `"claus" in user.groups` ,
2631
+ },
2632
+ {
2633
+ Expression : `user.extra["bio.snorlax.org/3"].size() == 4` ,
2634
+ },
2635
+ },
2636
+ },
2637
+ now : func () time.Time { return now },
2638
+ },
2639
+ signingKey : loadRSAPrivKey (t , "testdata/rsa_1.pem" , jose .RS256 ),
2640
+ pubKeys : []* jose.JSONWebKey {
2641
+ loadRSAKey (t , "testdata/rsa_1.pem" , jose .RS256 ),
2642
+ },
2643
+ claims : fmt .Sprintf (`{
2644
+ "iss": "https://auth.example.com",
2645
+ "aud": "my-client",
2646
+ "exp": %d,
2647
+ "turtle": {
2648
+ "foo": {
2649
+ "1": "a",
2650
+ "2": "b",
2651
+ "other1": {
2652
+ "bit1": true,
2653
+ "bit2": false,
2654
+ "bit3": 1
2655
+ },
2656
+ "bar": {
2657
+ "3": "c",
2658
+ "4": "d",
2659
+ "other1": {
2660
+ "bit1": true,
2661
+ "bit2": false,
2662
+ "bit3": 1
2663
+ },
2664
+ "baz": {
2665
+ "5": "e",
2666
+ "6": "f",
2667
+ "panda": [
2668
+ "snorlax",
2669
+ "007",
2670
+ "santa",
2671
+ "claus"
2672
+ ],
2673
+ "other1": {
2674
+ "bit1": true,
2675
+ "bit2": false,
2676
+ "bit3": 1
2677
+ }
2678
+ }
2679
+ }
2680
+ }
2681
+ }
2682
+ }` , valid .Unix ()),
2683
+ want : & user.DefaultInfo {
2684
+ Name : "snorlax" ,
2685
+ UID : "007" ,
2686
+ Groups : []string {"claus" },
2687
+ Extra : map [string ][]string {
2688
+ "bio.snorlax.org/1" : {"false" },
2689
+ "bio.snorlax.org/2" : {"1" },
2690
+ "bio.snorlax.org/3" : {"true" , "a" , "b" , "c" },
2691
+ },
2692
+ },
2693
+ },
2694
+ {
2695
+ name : "claim mappings with expressions and deeply nested claim - failure without optional" ,
2696
+ options : Options {
2697
+ JWTAuthenticator : apiserver.JWTAuthenticator {
2698
+ Issuer : apiserver.Issuer {
2699
+ URL : "https://auth.example.com" ,
2700
+ Audiences : []string {"my-client" },
2701
+ },
2702
+ ClaimValidationRules : []apiserver.ClaimValidationRule {
2703
+ {
2704
+ Expression : "claims.turtle.foo.other1.bit1 && !claims.turtle.foo.bar.other1.bit2" ,
2705
+ },
2706
+ },
2707
+ ClaimMappings : apiserver.ClaimMappings {
2708
+ Username : apiserver.PrefixedClaimOrExpression {
2709
+ Expression : "claims.turtle.foo.bar.baz.panda[0]" ,
2710
+ },
2711
+ UID : apiserver.ClaimOrExpression {
2712
+ Expression : "claims.turtle.foo.bar.baz.panda[1]" ,
2713
+ },
2714
+ Groups : apiserver.PrefixedClaimOrExpression {
2715
+ Expression : "claims.turtle.foo.bar.baz.a.b.c.d" , // this fails because the key does not exist
2716
+ },
2717
+ Extra : []apiserver.ExtraMapping {
2718
+ {
2719
+ Key : "bio.snorlax.org/1" ,
2720
+ ValueExpression : "string(claims.turtle.foo.bar.other1.bit2)" ,
2721
+ },
2722
+ {
2723
+ Key : "bio.snorlax.org/2" ,
2724
+ ValueExpression : "string(claims.turtle.foo.bar.baz.other1.bit3)" ,
2725
+ },
2726
+ {
2727
+ Key : "bio.snorlax.org/3" ,
2728
+ ValueExpression : "[string(claims.turtle.foo.bar.baz.other1.bit1)] + ['a', 'b', 'c']" ,
2729
+ },
2730
+ },
2731
+ },
2732
+ UserValidationRules : []apiserver.UserValidationRule {
2733
+ {
2734
+ Expression : `user.username != "bad"` ,
2735
+ },
2736
+ {
2737
+ Expression : `user.uid == "007"` ,
2738
+ },
2739
+ {
2740
+ Expression : `"claus" in user.groups` ,
2741
+ },
2742
+ {
2743
+ Expression : `user.extra["bio.snorlax.org/3"].size() == 4` ,
2744
+ },
2745
+ },
2746
+ },
2747
+ now : func () time.Time { return now },
2748
+ },
2749
+ signingKey : loadRSAPrivKey (t , "testdata/rsa_1.pem" , jose .RS256 ),
2750
+ pubKeys : []* jose.JSONWebKey {
2751
+ loadRSAKey (t , "testdata/rsa_1.pem" , jose .RS256 ),
2752
+ },
2753
+ claims : fmt .Sprintf (`{
2754
+ "iss": "https://auth.example.com",
2755
+ "aud": "my-client",
2756
+ "exp": %d,
2757
+ "turtle": {
2758
+ "foo": {
2759
+ "1": "a",
2760
+ "2": "b",
2761
+ "other1": {
2762
+ "bit1": true,
2763
+ "bit2": false,
2764
+ "bit3": 1
2765
+ },
2766
+ "bar": {
2767
+ "3": "c",
2768
+ "4": "d",
2769
+ "other1": {
2770
+ "bit1": true,
2771
+ "bit2": false,
2772
+ "bit3": 1
2773
+ },
2774
+ "baz": {
2775
+ "5": "e",
2776
+ "6": "f",
2777
+ "panda": [
2778
+ "snorlax",
2779
+ "007",
2780
+ "santa",
2781
+ "claus"
2782
+ ],
2783
+ "other1": {
2784
+ "bit1": true,
2785
+ "bit2": false,
2786
+ "bit3": 1
2787
+ }
2788
+ }
2789
+ }
2790
+ }
2791
+ }
2792
+ }` , valid .Unix ()),
2793
+ wantErr : "oidc: error evaluating group claim expression: expression 'claims.turtle.foo.bar.baz.a.b.c.d' resulted in error: no such key: a" ,
2794
+ },
2474
2795
{
2475
2796
name : "groups claim mapping with expression" ,
2476
2797
options : Options {
@@ -3506,8 +3827,12 @@ func TestToken(t *testing.T) {
3506
3827
3507
3828
var successTestCount , failureTestCount int
3508
3829
for _ , test := range tests {
3509
- t .Run (test .name , test .run )
3510
- if test .wantSkip || len (test .wantInitErr ) > 0 || len (test .wantHealthErrPrefix ) > 0 {
3830
+ var called bool
3831
+ t .Run (test .name , func (t * testing.T ) {
3832
+ called = true
3833
+ test .run (t )
3834
+ })
3835
+ if test .wantSkip || len (test .wantInitErr ) > 0 || len (test .wantHealthErrPrefix ) > 0 || ! called {
3511
3836
continue
3512
3837
}
3513
3838
// check metrics for success and failure
0 commit comments