1# Copyright 2021 Google LLC 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS-IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14"""Tests for tink.testing.cross_language.util._primitives.""" 15 16import datetime 17from absl.testing import absltest 18 19from tink import jwt 20 21from util import _primitives 22from protos import testing_api_pb2 23 24 25class PrimitivesTest(absltest.TestCase): 26 27 def test_split_merge_timestamp(self): 28 dt = datetime.datetime.fromtimestamp(1234.5678, datetime.timezone.utc) 29 seconds, nanos = _primitives.split_datetime(dt) 30 self.assertEqual(seconds, 1234) 31 self.assertEqual(nanos, 567800000) 32 self.assertEqual(_primitives.to_datetime(seconds, nanos), dt) 33 34 def test_raw_jwt_to_proto_to_verified_jwt(self): 35 raw = jwt.new_raw_jwt( 36 type_header='type_header', 37 issuer='issuer', 38 subject='subject', 39 audiences=['audience1', 'audience2'], 40 jwt_id='jwt_id', 41 not_before=datetime.datetime.fromtimestamp(1234567.89, 42 datetime.timezone.utc), 43 issued_at=datetime.datetime.fromtimestamp(2345678.9, 44 datetime.timezone.utc), 45 expiration=datetime.datetime.fromtimestamp(3456789, 46 datetime.timezone.utc), 47 custom_claims={ 48 'null': None, 49 'string': 'aString', 50 'number': 123.456, 51 'integer': 123, 52 'bool': True, 53 'list': [None, True, 'foo', 42, { 54 'pi': 3.14 55 }], 56 'obj': { 57 'list': [1, 3.14], 58 'null': None, 59 'bool': False 60 } 61 }) 62 proto = _primitives.raw_jwt_to_proto(raw) 63 verified = _primitives.proto_to_verified_jwt(proto) 64 self.assertEqual(verified.type_header(), 'type_header') 65 self.assertEqual(verified.issuer(), 'issuer') 66 self.assertEqual(verified.subject(), 'subject') 67 self.assertEqual(verified.audiences(), ['audience1', 'audience2']) 68 self.assertEqual(verified.jwt_id(), 'jwt_id') 69 self.assertEqual( 70 verified.not_before(), 71 datetime.datetime.fromtimestamp(1234567, datetime.timezone.utc)) 72 self.assertEqual( 73 verified.issued_at(), 74 datetime.datetime.fromtimestamp(2345678, datetime.timezone.utc)) 75 self.assertEqual( 76 verified.expiration(), 77 datetime.datetime.fromtimestamp(3456789, datetime.timezone.utc)) 78 self.assertEqual( 79 verified.custom_claim_names(), 80 {'null', 'string', 'number', 'integer', 'bool', 'list', 'obj'}) 81 self.assertIsNone(verified.custom_claim('null')) 82 self.assertEqual(verified.custom_claim('string'), 'aString') 83 self.assertEqual(verified.custom_claim('number'), 123.456) 84 self.assertEqual(verified.custom_claim('integer'), 123) 85 self.assertEqual(verified.custom_claim('bool'), True) 86 self.assertEqual(verified.custom_claim('list'), 87 [None, True, 'foo', 42, {'pi': 3.14}]) 88 self.assertEqual( 89 verified.custom_claim('obj'), 90 {'list': [1, 3.14], 'null': None, 'bool': False}) 91 92 def test_empty_raw_jwt_to_proto_to_verified_jwt(self): 93 raw = jwt.new_raw_jwt(without_expiration=True) 94 proto = _primitives.raw_jwt_to_proto(raw) 95 verified = _primitives.proto_to_verified_jwt(proto) 96 self.assertFalse(verified.has_type_header()) 97 self.assertFalse(verified.has_issuer()) 98 self.assertFalse(verified.has_subject()) 99 self.assertFalse(verified.has_audiences()) 100 self.assertFalse(verified.has_jwt_id()) 101 self.assertFalse(verified.has_not_before()) 102 self.assertFalse(verified.has_issued_at()) 103 self.assertFalse(verified.has_expiration()) 104 self.assertEmpty(verified.custom_claim_names()) 105 106 def test_jwt_validator_to_proto(self): 107 now = datetime.datetime.fromtimestamp(1234567.125, datetime.timezone.utc) 108 validator = jwt.new_validator( 109 expected_type_header='type_header', 110 expected_issuer='issuer', 111 expected_audience='audience', 112 clock_skew=datetime.timedelta(seconds=123), 113 fixed_now=now) 114 proto = _primitives.jwt_validator_to_proto(validator) 115 expected = testing_api_pb2.JwtValidator() 116 expected.expected_type_header.value = 'type_header' 117 expected.expected_issuer.value = 'issuer' 118 expected.expected_audience.value = 'audience' 119 expected.clock_skew.seconds = 123 120 expected.now.seconds = 1234567 121 expected.now.nanos = 125000000 122 self.assertEqual(proto, expected) 123 124 def test_empty_jwt_validator_to_proto(self): 125 validator = jwt.new_validator() 126 proto = _primitives.jwt_validator_to_proto(validator) 127 expected = testing_api_pb2.JwtValidator() 128 expected.clock_skew.seconds = 0 129 self.assertEqual(proto, expected) 130 131if __name__ == '__main__': 132 absltest.main() 133