Skip to content

Commit 5e33ee7

Browse files
committed
Pick out the unique keys out of list of keys.
1 parent 9d90e4b commit 5e33ee7

File tree

3 files changed

+109
-36
lines changed

3 files changed

+109
-36
lines changed

src/cryptojwt/jwk/hmac.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@ def __eq__(self, other):
135135
if set(self.__dict__.keys()) != set(other.__dict__.keys()):
136136
return False
137137

138+
if self.key != other.key:
139+
return False
140+
138141
for key in self.public_members:
139142
if getattr(other, key) != getattr(self, key):
140143
return False

src/cryptojwt/key_bundle.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,18 @@ def copy(self):
605605
def __iter__(self):
606606
return self._keys.__iter__()
607607

608+
def difference(self, kb):
609+
"""
610+
Return a set of keys that appears in this key bundle but not in the other.
611+
612+
:param kb: A KeyBundle instance
613+
:return: A list of keys
614+
"""
615+
if not isinstance(kb, KeyBundle):
616+
return ValueError('Not a KeyBundle instance')
617+
618+
return [k for k in self._keys if k not in kb]
619+
608620

609621
def keybundle_from_local_file(filename, typ, usage):
610622
"""
@@ -931,3 +943,20 @@ def key_rollover(kb):
931943

932944
update_key_bundle(kb, diff)
933945
return kb
946+
947+
948+
def unique_keys(keys):
949+
"""
950+
From a list of given keys, return the unique keys.
951+
952+
:param keys: List of keys
953+
:return: List of unique keys
954+
"""
955+
956+
unique = []
957+
958+
for k in keys:
959+
if k not in unique:
960+
unique.append(k)
961+
962+
return unique

tests/test_03_key_bundle.py

Lines changed: 77 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
# pylint: disable=missing-docstring,no-self-use
22
import json
33
import os
4-
import pytest
54
import shutil
65
import time
76

7+
import pytest
88
from cryptography.hazmat.primitives.asymmetric import rsa
99

1010
from cryptojwt.jwk.ec import new_ec_key
11-
11+
from cryptojwt.jwk.hmac import SYMKey
12+
from cryptojwt.jwk.rsa import RSAKey
1213
from cryptojwt.jwk.rsa import import_rsa_key_from_cert_file
1314
from cryptojwt.jwk.rsa import new_rsa_key
14-
from cryptojwt.jwk.rsa import RSAKey
15-
from cryptojwt.jwk.hmac import SYMKey
16-
17-
from cryptojwt.key_bundle import build_key_bundle, update_key_bundle, \
18-
key_rollover
15+
from cryptojwt.key_bundle import KeyBundle
16+
from cryptojwt.key_bundle import build_key_bundle
1917
from cryptojwt.key_bundle import dump_jwks
2018
from cryptojwt.key_bundle import key_diff
21-
from cryptojwt.key_bundle import rsa_init
19+
from cryptojwt.key_bundle import key_rollover
2220
from cryptojwt.key_bundle import keybundle_from_local_file
23-
from cryptojwt.key_bundle import KeyBundle
21+
from cryptojwt.key_bundle import rsa_init
22+
from cryptojwt.key_bundle import unique_keys
23+
from cryptojwt.key_bundle import update_key_bundle
2424

2525
__author__ = 'Roland Hedberg'
2626

@@ -116,13 +116,16 @@ def full_path(local_file):
116116
"x5c": [
117117
"MIIC4jCCAcqgAwIBAgIQQNXrmzhLN4VGlUXDYCRT3zANBgkqhkiG9w0BAQsFADAtMSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb"
118118
"250cm9sLndpbmRvd3MubmV0MB4XDTE0MTAyODAwMDAwMFoXDTE2MTAyNzAwMDAwMFowLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZX"
119-
"NzY29udHJvbC53aW5kb3dzLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALyKs/uPhEf7zVizjfcr/ISGFe9+yUO"
119+
"NzY29udHJvbC53aW5kb3dzLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALyKs"
120+
"/uPhEf7zVizjfcr/ISGFe9+yUO"
120121
"qwpel38zgutvLHmFD39E2hpPdQhcXn4c4dt1fU5KvkbcDdVbP8+e4TvNpJMy"
121122
"/nEB2V92zCQ/hhBjilwhF1ETe1TMmVjALs0KFvbxW"
122123
"9ZN3EdUVvxFvz/gvG29nQhl4QWKj3x8opr89lmq14Z7T0mzOV8kub+cgsOU"
123124
"/1bsKqrIqN1fMKKFhjKaetctdjYTfGzVQ0AJAzzbtg"
124-
"0/Q1wdYNAnhSDafygEv6kNiquk0r0RyasUUevEXs2LY3vSgKsKseI8ZZlQEMtE9/k/iAG7JNcEbVg53YTurNTrPnXJOU88mf3TToX"
125-
"14HpYsS1ECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAfolx45w0i8CdAUjjeAaYdhG9+NDHxop0UvNOqlGqYJexqPLuvX8iyUaYxNG"
125+
"0/Q1wdYNAnhSDafygEv6kNiquk0r0RyasUUevEXs2LY3vSgKsKseI8ZZlQEMtE9/k"
126+
"/iAG7JNcEbVg53YTurNTrPnXJOU88mf3TToX"
127+
"14HpYsS1ECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAfolx45w0i8CdAUjjeAaYdhG9"
128+
"+NDHxop0UvNOqlGqYJexqPLuvX8iyUaYxNG"
126129
"zZxFgGI3GpKfmQP2JQWQ1E5JtY/n8iNLOKRMwqkuxSCKJxZJq4Sl/m"
127130
"/Yv7TS1P5LNgAj8QLCypxsWrTAmq2HSpkeSk4JBtsYxX6uh"
128131
"bGM/K1sEktKybVTHu22/7TmRqWTmOUy9wQvMjJb2IXdMGLG3hVntN"
@@ -175,7 +178,8 @@ def full_path(local_file):
175178
"x5c": [
176179
"MIICWzCCAcSgAwIBAgIJAL3MzqqEFMYjMA0GCSqGSIb3DQEBBQUAMCkxJzAlBgNVBAMTHkxpdmUgSUQgU1RTIFNpZ25pbmcgUHVib"
177180
"GljIEtleTAeFw0xMzExMTExOTA1MDJaFw0xOTExMTAxOTA1MDJaMCkxJzAlBgNVBAMTHkxpdmUgSUQgU1RTIFNpZ25pbmcgUHVibG"
178-
"ljIEtleTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAx7HNcD9ZxTFRaAgZ7+gdYLkgQua3zvQseqBJIt8Uq3MimInMZoE9QGQ"
181+
"ljIEtleTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAx7HNcD9ZxTFRaAgZ7"
182+
"+gdYLkgQua3zvQseqBJIt8Uq3MimInMZoE9QGQ"
179183
"eSML7qZPlowb5BUakdLI70ayM4vN36++0ht8+oCHhl8YjGFQkU"
180184
"+Iv2yahWHEP+1EK6eOEYu6INQP9Lk0HMk3QViLwshwb+KXVD02j"
181185
"dmX2HNdYJdPyc0cCAwEAAaOBijCBhzAdBgNVHQ4EFgQULR0aj9AtiNMgqIY8ZyXZGsHcJ5gwWQYDVR0jBFIwUIAULR0aj9AtiNMgq"
@@ -261,14 +265,14 @@ def test_unknown_source():
261265

262266
def test_ignore_unknown_types():
263267
kb = KeyBundle({
264-
"kid": "q-H9y8iuh3BIKZBbK6S0mH_isBlJsk"
265-
"-u6VtZ5rAdBo5fCjjy3LnkrsoK_QWrlKB08j_PcvwpAMfTEDHw5spepw",
266-
"use": "sig",
267-
"alg": "EdDSA",
268-
"kty": "OKP",
269-
"crv": "Ed25519",
270-
"x": "FnbcUAXZ4ySvrmdXK1MrDuiqlqTXvGdAaE4RWZjmFIQ"
271-
})
268+
"kid": "q-H9y8iuh3BIKZBbK6S0mH_isBlJsk"
269+
"-u6VtZ5rAdBo5fCjjy3LnkrsoK_QWrlKB08j_PcvwpAMfTEDHw5spepw",
270+
"use": "sig",
271+
"alg": "EdDSA",
272+
"kty": "OKP",
273+
"crv": "Ed25519",
274+
"x": "FnbcUAXZ4ySvrmdXK1MrDuiqlqTXvGdAaE4RWZjmFIQ"
275+
})
272276

273277
assert len(kb) == 0
274278

@@ -529,13 +533,15 @@ def test_loads_1():
529533
'kty': 'RSA',
530534
'use': 'sig',
531535
'e': 'AQAB',
532-
"n": 'wf-wiusGhA-gleZYQAOPQlNUIucPiqXdPVyieDqQbXXOPBe3nuggtVzeq7pVFH1dZz4dY2Q2LA5DaegvP8kRvoSB_87ds3dy3Rfym_GUSc5B0l1TgEobcyaep8jguRoHto6GWHfCfKqoUYZq4N8vh4LLMQwLR6zi6Jtu82nB5k8',
536+
"n":
537+
'wf-wiusGhA-gleZYQAOPQlNUIucPiqXdPVyieDqQbXXOPBe3nuggtVzeq7pVFH1dZz4dY2Q2LA5DaegvP8kRvoSB_87ds3dy3Rfym_GUSc5B0l1TgEobcyaep8jguRoHto6GWHfCfKqoUYZq4N8vh4LLMQwLR6zi6Jtu82nB5k8',
533538
'kid': "1"
534539
}, {
535540
'kty': 'RSA',
536541
'use': 'enc',
537542
'e': 'AQAB',
538-
"n": 'wf-wiusGhA-gleZYQAOPQlNUIucPiqXdPVyieDqQbXXOPBe3nuggtVzeq7pVFH1dZz4dY2Q2LA5DaegvP8kRvoSB_87ds3dy3Rfym_GUSc5B0l1TgEobcyaep8jguRoHto6GWHfCfKqoUYZq4N8vh4LLMQwLR6zi6Jtu82nB5k8',
543+
"n":
544+
'wf-wiusGhA-gleZYQAOPQlNUIucPiqXdPVyieDqQbXXOPBe3nuggtVzeq7pVFH1dZz4dY2Q2LA5DaegvP8kRvoSB_87ds3dy3Rfym_GUSc5B0l1TgEobcyaep8jguRoHto6GWHfCfKqoUYZq4N8vh4LLMQwLR6zi6Jtu82nB5k8',
539545
'kid': "2"
540546
}
541547
]
@@ -567,7 +573,8 @@ def test_dump_jwk():
567573

568574
JWKS_DICT = {"keys": [
569575
{
570-
"n": u"zkpUgEgXICI54blf6iWiD2RbMDCOO1jV0VSff1MFFnujM4othfMsad7H1kRo50YM5S_X9TdvrpdOfpz5aBaKFhT6Ziv0nhtcekq1eRl8mjBlvGKCE5XGk-0LFSDwvqgkJoFYInq7bu0a4JEzKs5AyJY75YlGh879k1Uu2Sv3ZZOunfV1O1Orta-NvS-aG_jN5cstVbCGWE20H0vFVrJKNx0Zf-u-aA-syM4uX7wdWgQ-owoEMHge0GmGgzso2lwOYf_4znanLwEuO3p5aabEaFoKNR4K6GjQcjBcYmDEE4CtfRU9AEmhcD1kleiTB9TjPWkgDmT9MXsGxBHf3AKT5w",
576+
"n":
577+
u"zkpUgEgXICI54blf6iWiD2RbMDCOO1jV0VSff1MFFnujM4othfMsad7H1kRo50YM5S_X9TdvrpdOfpz5aBaKFhT6Ziv0nhtcekq1eRl8mjBlvGKCE5XGk-0LFSDwvqgkJoFYInq7bu0a4JEzKs5AyJY75YlGh879k1Uu2Sv3ZZOunfV1O1Orta-NvS-aG_jN5cstVbCGWE20H0vFVrJKNx0Zf-u-aA-syM4uX7wdWgQ-owoEMHge0GmGgzso2lwOYf_4znanLwEuO3p5aabEaFoKNR4K6GjQcjBcYmDEE4CtfRU9AEmhcD1kleiTB9TjPWkgDmT9MXsGxBHf3AKT5w",
571578
"e": u"AQAB",
572579
"kty": "RSA",
573580
"kid": "5-VBFv40P8D4I-7SFz7hMugTbPs",
@@ -626,43 +633,38 @@ def test_jwks_url():
626633
KEYSPEC = [
627634
{"type": "RSA", "use": ["sig"]},
628635
{"type": "EC", "crv": "P-256", "use": ["sig"]}
629-
]
630-
636+
]
631637

632638
KEYSPEC_2 = [
633639
{"type": "RSA", "use": ["sig"]},
634640
{"type": "EC", "crv": "P-256", "use": ["sig"]},
635641
{"type": "EC", "crv": "P-384", "use": ["sig"]}
636-
]
637-
642+
]
638643

639644
KEYSPEC_3 = [
640645
{"type": "RSA", "use": ["sig"]},
641646
{"type": "EC", "crv": "P-256", "use": ["sig"]},
642647
{"type": "EC", "crv": "P-384", "use": ["sig"]},
643648
{"type": "EC", "crv": "P-521", "use": ["sig"]}
644-
]
645-
649+
]
646650

647651
KEYSPEC_4 = [
648652
{"type": "RSA", "use": ["sig"]},
649653
{"type": "RSA", "use": ["sig"]},
650654
{"type": "EC", "crv": "P-256", "use": ["sig"]},
651655
{"type": "EC", "crv": "P-384", "use": ["sig"]}
652-
]
653-
656+
]
654657

655658
KEYSPEC_5 = [
656659
{"type": "EC", "crv": "P-256", "use": ["sig"]},
657660
{"type": "EC", "crv": "P-384", "use": ["sig"]}
658-
]
659-
661+
]
660662

661663
KEYSPEC_6 = [
662-
{"type": "oct", "bytes": "24", "use": ["enc"], 'kid':'code'},
664+
{"type": "oct", "bytes": "24", "use": ["enc"], 'kid': 'code'},
663665
{"type": "oct", "bytes": "24", "use": ["enc"], 'kid': 'token'},
664666
{"type": "oct", "bytes": "24", "use": ["enc"], 'kid': 'refresh_token'}
665-
]
667+
]
666668

667669

668670
def test_key_diff_none():
@@ -782,3 +784,42 @@ def test_build_key_bundle_sym():
782784
assert len(_kb.get('RSA')) == 0
783785
assert len(_kb.get('EC')) == 0
784786
assert len(_kb.get('OCT')) == 3
787+
788+
789+
def test_key_bundle_difference_none():
790+
_kb0 = build_key_bundle(key_conf=KEYSPEC_6)
791+
_kb1 = KeyBundle()
792+
_kb1.extend(_kb0.keys())
793+
794+
assert _kb0.difference(_kb1) == []
795+
796+
797+
def test_key_bundle_difference():
798+
_kb0 = build_key_bundle(key_conf=KEYSPEC_6)
799+
_kb1 = build_key_bundle(key_conf=KEYSPEC_2)
800+
801+
assert _kb0.difference(_kb1) == _kb0.keys()
802+
assert _kb1.difference(_kb0) == _kb1.keys()
803+
804+
805+
def test_unique_keys_1():
806+
_kb0 = build_key_bundle(key_conf=KEYSPEC_6)
807+
_kb1 = build_key_bundle(key_conf=KEYSPEC_6)
808+
809+
keys = _kb0.keys()
810+
keys.extend(_kb1.keys())
811+
812+
# All of them
813+
assert len(unique_keys(keys)) == 6
814+
815+
816+
def test_unique_keys_2():
817+
_kb0 = build_key_bundle(key_conf=KEYSPEC_6)
818+
_kb1 = KeyBundle()
819+
_kb1.extend(_kb0.keys())
820+
821+
keys = _kb0.keys()
822+
keys.extend(_kb1.keys())
823+
824+
# 3 of 6
825+
assert len(unique_keys(keys)) == 3

0 commit comments

Comments
 (0)