@@ -47,6 +47,10 @@ def _base64(string):
47
47
return base64 .standard_b64encode (string .encode ()).decode ()
48
48
49
49
50
+ def _urlsafe_unpadded_b64encode (string ):
51
+ return base64 .urlsafe_b64encode (string .encode ()).decode ().rstrip ('=' )
52
+
53
+
50
54
def _format_expiry_datetime (dt ):
51
55
return dt .strftime (EXPIRY_DATETIME_FORMAT )
52
56
@@ -94,12 +98,33 @@ def _raise_exception(st):
94
98
95
99
TEST_OIDC_TOKEN = "test-oidc-token"
96
100
TEST_OIDC_INFO = "{\" name\" : \" test\" }"
97
- TEST_OIDC_BASE = _base64 (TEST_OIDC_TOKEN ) + "." + _base64 (TEST_OIDC_INFO )
98
- TEST_OIDC_LOGIN = TEST_OIDC_BASE + "." + TEST_CLIENT_CERT_BASE64
101
+ TEST_OIDC_BASE = "." .join ([
102
+ _urlsafe_unpadded_b64encode (TEST_OIDC_TOKEN ),
103
+ _urlsafe_unpadded_b64encode (TEST_OIDC_INFO )
104
+ ])
105
+ TEST_OIDC_LOGIN = "." .join ([
106
+ TEST_OIDC_BASE ,
107
+ _urlsafe_unpadded_b64encode (TEST_CLIENT_CERT_BASE64 )
108
+ ])
99
109
TEST_OIDC_TOKEN = "Bearer %s" % TEST_OIDC_LOGIN
100
110
TEST_OIDC_EXP = "{\" name\" : \" test\" ,\" exp\" : 536457600}"
101
- TEST_OIDC_EXP_BASE = _base64 (TEST_OIDC_TOKEN ) + "." + _base64 (TEST_OIDC_EXP )
102
- TEST_OIDC_EXPIRED_LOGIN = TEST_OIDC_EXP_BASE + "." + TEST_CLIENT_CERT_BASE64
111
+ TEST_OIDC_EXP_BASE = _urlsafe_unpadded_b64encode (
112
+ TEST_OIDC_TOKEN ) + "." + _urlsafe_unpadded_b64encode (TEST_OIDC_EXP )
113
+ TEST_OIDC_EXPIRED_LOGIN = "." .join ([
114
+ TEST_OIDC_EXP_BASE ,
115
+ _urlsafe_unpadded_b64encode (TEST_CLIENT_CERT )
116
+ ])
117
+ TEST_OIDC_CONTAINS_RESERVED_CHARACTERS = "." .join ([
118
+ _urlsafe_unpadded_b64encode (TEST_OIDC_TOKEN ),
119
+ _urlsafe_unpadded_b64encode (TEST_OIDC_INFO ).replace ("a" , "+" ),
120
+ _urlsafe_unpadded_b64encode (TEST_CLIENT_CERT )
121
+ ])
122
+ TEST_OIDC_INVALID_PADDING_LENGTH = "." .join ([
123
+ _urlsafe_unpadded_b64encode (TEST_OIDC_TOKEN ),
124
+ "aaaaa" ,
125
+ _urlsafe_unpadded_b64encode (TEST_CLIENT_CERT )
126
+ ])
127
+
103
128
TEST_OIDC_CA = _base64 (TEST_CERTIFICATE_AUTH )
104
129
105
130
@@ -406,6 +431,22 @@ class TestKubeConfigLoader(BaseTestCase):
406
431
"user" : "expired_oidc_nocert"
407
432
}
408
433
},
434
+ {
435
+ "name" : "oidc_contains_reserved_character" ,
436
+ "context" : {
437
+ "cluster" : "default" ,
438
+ "user" : "oidc_contains_reserved_character"
439
+
440
+ }
441
+ },
442
+ {
443
+ "name" : "oidc_invalid_padding_length" ,
444
+ "context" : {
445
+ "cluster" : "default" ,
446
+ "user" : "oidc_invalid_padding_length"
447
+
448
+ }
449
+ },
409
450
{
410
451
"name" : "user_pass" ,
411
452
"context" : {
@@ -592,6 +633,38 @@ class TestKubeConfigLoader(BaseTestCase):
592
633
}
593
634
}
594
635
},
636
+ {
637
+ "name" : "oidc_contains_reserved_character" ,
638
+ "user" : {
639
+ "auth-provider" : {
640
+ "name" : "oidc" ,
641
+ "config" : {
642
+ "client-id" : "tectonic-kubectl" ,
643
+ "client-secret" : "FAKE_SECRET" ,
644
+ "id-token" : TEST_OIDC_CONTAINS_RESERVED_CHARACTERS ,
645
+ "idp-issuer-url" : "https://example.org/identity" ,
646
+ "refresh-token" :
647
+ "lucWJjEhlxZW01cXI3YmVlcYnpxNGhzk"
648
+ }
649
+ }
650
+ }
651
+ },
652
+ {
653
+ "name" : "oidc_invalid_padding_length" ,
654
+ "user" : {
655
+ "auth-provider" : {
656
+ "name" : "oidc" ,
657
+ "config" : {
658
+ "client-id" : "tectonic-kubectl" ,
659
+ "client-secret" : "FAKE_SECRET" ,
660
+ "id-token" : TEST_OIDC_INVALID_PADDING_LENGTH ,
661
+ "idp-issuer-url" : "https://example.org/identity" ,
662
+ "refresh-token" :
663
+ "lucWJjEhlxZW01cXI3YmVlcYnpxNGhzk"
664
+ }
665
+ }
666
+ }
667
+ },
595
668
{
596
669
"name" : "user_pass" ,
597
670
"user" : {
@@ -790,6 +863,26 @@ def test_oidc_with_refresh_nocert(
790
863
self .assertTrue (loader ._load_auth_provider_token ())
791
864
self .assertEqual ("Bearer abc123" , loader .token )
792
865
866
+ def test_oidc_fails_if_contains_reserved_chars (self ):
867
+ loader = KubeConfigLoader (
868
+ config_dict = self .TEST_KUBE_CONFIG ,
869
+ active_context = "oidc_contains_reserved_character" ,
870
+ )
871
+ self .assertEqual (
872
+ loader ._load_oid_token ("oidc_contains_reserved_character" ),
873
+ None ,
874
+ )
875
+
876
+ def test_oidc_fails_if_invalid_padding_length (self ):
877
+ loader = KubeConfigLoader (
878
+ config_dict = self .TEST_KUBE_CONFIG ,
879
+ active_context = "oidc_invalid_padding_length" ,
880
+ )
881
+ self .assertEqual (
882
+ loader ._load_oid_token ("oidc_invalid_padding_length" ),
883
+ None ,
884
+ )
885
+
793
886
def test_user_pass (self ):
794
887
expected = FakeConfig (host = TEST_HOST , token = TEST_BASIC_TOKEN )
795
888
actual = FakeConfig ()
0 commit comments