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