feature(keyringctl): rework str simplification for printable uids
This commit is contained in:
parent
2030de06a0
commit
bce5bc550e
@ -5,9 +5,7 @@ from collections.abc import Iterable
|
|||||||
from itertools import chain
|
from itertools import chain
|
||||||
from logging import debug
|
from logging import debug
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from re import escape
|
|
||||||
from re import match
|
from re import match
|
||||||
from re import sub
|
|
||||||
from shutil import copytree
|
from shutil import copytree
|
||||||
from tempfile import NamedTemporaryFile
|
from tempfile import NamedTemporaryFile
|
||||||
from tempfile import mkdtemp
|
from tempfile import mkdtemp
|
||||||
@ -33,6 +31,7 @@ from .types import Username
|
|||||||
from .util import filter_fingerprints_by_trust
|
from .util import filter_fingerprints_by_trust
|
||||||
from .util import get_cert_paths
|
from .util import get_cert_paths
|
||||||
from .util import get_fingerprint_from_partial
|
from .util import get_fingerprint_from_partial
|
||||||
|
from .util import simplify_ascii
|
||||||
from .util import transform_fd_to_tmpfile
|
from .util import transform_fd_to_tmpfile
|
||||||
|
|
||||||
|
|
||||||
@ -161,7 +160,7 @@ def convert_certificate( # noqa: ignore=C901
|
|||||||
elif packet.name.endswith("--UserID"):
|
elif packet.name.endswith("--UserID"):
|
||||||
current_packet_mode = "uid"
|
current_packet_mode = "uid"
|
||||||
current_packet_fingerprint = None
|
current_packet_fingerprint = None
|
||||||
current_packet_uid = simplify_user_id(Uid(packet_dump_field(packet, "Value")))
|
current_packet_uid = Uid(simplify_ascii(packet_dump_field(packet, "Value")))
|
||||||
|
|
||||||
uids[current_packet_uid] = packet
|
uids[current_packet_uid] = packet
|
||||||
elif packet.name.endswith("--PublicSubkey"):
|
elif packet.name.endswith("--PublicSubkey"):
|
||||||
@ -493,24 +492,6 @@ def persist_uid_revocations(
|
|||||||
packet_join(packets=[revocation], output=output_file, force=True)
|
packet_join(packets=[revocation], output=output_file, force=True)
|
||||||
|
|
||||||
|
|
||||||
def simplify_user_id(user_id: Uid) -> Uid:
|
|
||||||
"""Simplify the User ID string to contain more filesystem friendly characters
|
|
||||||
|
|
||||||
Parameters
|
|
||||||
----------
|
|
||||||
user_id: A User ID string (e.g. 'Foobar McFooface <foobar@foo.face>')
|
|
||||||
|
|
||||||
Returns
|
|
||||||
-------
|
|
||||||
The simplified representation of user_id
|
|
||||||
"""
|
|
||||||
|
|
||||||
user_id_str: str = user_id.replace("@", "_at_")
|
|
||||||
user_id_str = sub("[<>]", "", user_id_str)
|
|
||||||
user_id_str = sub("[" + escape(r" !@#$%^&*()_-+=[]{}\|;:,.<>/?") + "]", "_", user_id_str)
|
|
||||||
return Uid(user_id_str)
|
|
||||||
|
|
||||||
|
|
||||||
def derive_username_from_fingerprint(keyring_dir: Path, certificate_fingerprint: Fingerprint) -> Optional[Username]:
|
def derive_username_from_fingerprint(keyring_dir: Path, certificate_fingerprint: Fingerprint) -> Optional[Username]:
|
||||||
"""Attempt to derive the username of a public key fingerprint from a keyring directory
|
"""Attempt to derive the username of a public key fingerprint from a keyring directory
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
from collections.abc import Iterable
|
from collections.abc import Iterable
|
||||||
from collections.abc import Iterator
|
from collections.abc import Iterator
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
@ -7,7 +6,11 @@ from os import chdir
|
|||||||
from os import environ
|
from os import environ
|
||||||
from os import getcwd
|
from os import getcwd
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from re import escape
|
||||||
from re import split
|
from re import split
|
||||||
|
from re import sub
|
||||||
|
from string import ascii_letters
|
||||||
|
from string import digits
|
||||||
from subprocess import STDOUT
|
from subprocess import STDOUT
|
||||||
from subprocess import CalledProcessError
|
from subprocess import CalledProcessError
|
||||||
from subprocess import check_output
|
from subprocess import check_output
|
||||||
@ -263,3 +266,51 @@ def filter_fingerprints_by_trust(trusts: Dict[Fingerprint, Trust], trust: Trust)
|
|||||||
filter(lambda item: trust == item[1], trusts.items()),
|
filter(lambda item: trust == item[1], trusts.items()),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
simple_printable: str = ascii_letters + digits + "_-.+@"
|
||||||
|
ascii_mapping: Dict[str, str] = {
|
||||||
|
"àáâãäæąăǎа": "a",
|
||||||
|
"ćçĉċč": "c",
|
||||||
|
"ďđ": "d",
|
||||||
|
"éèêëęēĕėěɇ": "e",
|
||||||
|
"ĝğġģ": "g",
|
||||||
|
"ĥħȟ": "h",
|
||||||
|
"ìíîïĩīĭįıij": "i",
|
||||||
|
"ĵɉ": "j",
|
||||||
|
"ķ": "k",
|
||||||
|
"ł": "l",
|
||||||
|
"ńņň": "n",
|
||||||
|
"òóôõöøŏőðȍǿ": "o",
|
||||||
|
"śș": "s",
|
||||||
|
"ß": "ss",
|
||||||
|
"ț": "t",
|
||||||
|
"úûüȗűȕù": "u",
|
||||||
|
"ýÿ": "y",
|
||||||
|
"źż": "z",
|
||||||
|
}
|
||||||
|
ascii_mapping_lookup: Dict[str, str] = {}
|
||||||
|
for key, value in ascii_mapping.items():
|
||||||
|
for c in key:
|
||||||
|
if c in ascii_mapping_lookup:
|
||||||
|
raise Exception(f"duplicate ascii mapping: {c}")
|
||||||
|
ascii_mapping_lookup[c] = value
|
||||||
|
ascii_mapping_lookup[c.upper()] = value.upper()
|
||||||
|
|
||||||
|
|
||||||
|
def simplify_ascii(_str: str) -> str:
|
||||||
|
"""Simplify a string to contain more filesystem and printable friendly characters
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
_str: A string to simplify (e.g. 'Foobar McFooface <foobar@foo.face>')
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
The simplified representation of _str
|
||||||
|
"""
|
||||||
|
_str = _str.strip("<")
|
||||||
|
_str = _str.strip(">")
|
||||||
|
_str = "".join([ascii_mapping_lookup.get(char) or char for char in _str])
|
||||||
|
_str = sub("[^" + escape(simple_printable) + "]", "_", _str)
|
||||||
|
return _str
|
||||||
|
@ -10,7 +10,6 @@ from typing import Set
|
|||||||
from libkeyringctl.keyring import export
|
from libkeyringctl.keyring import export
|
||||||
from libkeyringctl.keyring import get_fingerprints_from_paths
|
from libkeyringctl.keyring import get_fingerprints_from_paths
|
||||||
from libkeyringctl.keyring import is_pgp_fingerprint
|
from libkeyringctl.keyring import is_pgp_fingerprint
|
||||||
from libkeyringctl.keyring import simplify_user_id
|
|
||||||
from libkeyringctl.keyring import transform_fingerprint_to_keyring_path
|
from libkeyringctl.keyring import transform_fingerprint_to_keyring_path
|
||||||
from libkeyringctl.keyring import transform_username_to_keyring_path
|
from libkeyringctl.keyring import transform_username_to_keyring_path
|
||||||
from libkeyringctl.sequoia import packet_dump_field
|
from libkeyringctl.sequoia import packet_dump_field
|
||||||
@ -20,6 +19,7 @@ from libkeyringctl.types import PacketKind
|
|||||||
from libkeyringctl.types import Uid
|
from libkeyringctl.types import Uid
|
||||||
from libkeyringctl.util import get_cert_paths
|
from libkeyringctl.util import get_cert_paths
|
||||||
from libkeyringctl.util import get_fingerprint_from_partial
|
from libkeyringctl.util import get_fingerprint_from_partial
|
||||||
|
from libkeyringctl.util import simplify_ascii
|
||||||
from libkeyringctl.util import system
|
from libkeyringctl.util import system
|
||||||
|
|
||||||
|
|
||||||
@ -161,7 +161,7 @@ def verify_integrity(certificate: Path, all_fingerprints: Set[Fingerprint]) -> N
|
|||||||
kind = kinds[0]
|
kind = kinds[0]
|
||||||
if kind != "User":
|
if kind != "User":
|
||||||
raise Exception(f"Unexpected packet in file {str(uid_path)}: {kind}")
|
raise Exception(f"Unexpected packet in file {str(uid_path)}: {kind}")
|
||||||
uid_value = simplify_user_id(Uid(packet_dump_field(packet=uid_path, field="Value")))
|
uid_value = Uid(simplify_ascii(packet_dump_field(packet=uid_path, field="Value")))
|
||||||
if uid_value != uid.name:
|
if uid_value != uid.name:
|
||||||
raise Exception(f"Unexpected uid in file {str(uid_path)}: {uid_value}")
|
raise Exception(f"Unexpected uid in file {str(uid_path)}: {uid_value}")
|
||||||
elif not uid_path.is_dir():
|
elif not uid_path.is_dir():
|
||||||
|
@ -25,7 +25,6 @@ from pytest import fixture
|
|||||||
from libkeyringctl.keyring import convert_certificate
|
from libkeyringctl.keyring import convert_certificate
|
||||||
from libkeyringctl.keyring import export
|
from libkeyringctl.keyring import export
|
||||||
from libkeyringctl.keyring import get_fingerprints_from_keyring_files
|
from libkeyringctl.keyring import get_fingerprints_from_keyring_files
|
||||||
from libkeyringctl.keyring import simplify_user_id
|
|
||||||
from libkeyringctl.sequoia import certify
|
from libkeyringctl.sequoia import certify
|
||||||
from libkeyringctl.sequoia import key_extract_certificate
|
from libkeyringctl.sequoia import key_extract_certificate
|
||||||
from libkeyringctl.sequoia import key_generate
|
from libkeyringctl.sequoia import key_generate
|
||||||
@ -35,6 +34,7 @@ from libkeyringctl.types import Fingerprint
|
|||||||
from libkeyringctl.types import Uid
|
from libkeyringctl.types import Uid
|
||||||
from libkeyringctl.types import Username
|
from libkeyringctl.types import Username
|
||||||
from libkeyringctl.util import cwd
|
from libkeyringctl.util import cwd
|
||||||
|
from libkeyringctl.util import simplify_ascii
|
||||||
from libkeyringctl.util import system
|
from libkeyringctl.util import system
|
||||||
|
|
||||||
test_keys: Dict[Username, List[Path]] = defaultdict(list)
|
test_keys: Dict[Username, List[Path]] = defaultdict(list)
|
||||||
@ -133,7 +133,7 @@ def create_uid_certification(
|
|||||||
certificate: Path = test_certificates[certified][0]
|
certificate: Path = test_certificates[certified][0]
|
||||||
fingerprint: Fingerprint = Fingerprint(test_keyring_certificates[certified][0].name)
|
fingerprint: Fingerprint = Fingerprint(test_keyring_certificates[certified][0].name)
|
||||||
issuer_fingerprint: Fingerprint = Fingerprint(test_keyring_certificates[issuer][0].name)
|
issuer_fingerprint: Fingerprint = Fingerprint(test_keyring_certificates[issuer][0].name)
|
||||||
simplified_uid = simplify_user_id(uid)
|
simplified_uid = Uid(simplify_ascii(uid))
|
||||||
|
|
||||||
output: Path = (
|
output: Path = (
|
||||||
working_dir
|
working_dir
|
||||||
|
Loading…
Reference in New Issue
Block a user