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 logging import debug
|
||||
from pathlib import Path
|
||||
from re import escape
|
||||
from re import match
|
||||
from re import sub
|
||||
from shutil import copytree
|
||||
from tempfile import NamedTemporaryFile
|
||||
from tempfile import mkdtemp
|
||||
@ -33,6 +31,7 @@ from .types import Username
|
||||
from .util import filter_fingerprints_by_trust
|
||||
from .util import get_cert_paths
|
||||
from .util import get_fingerprint_from_partial
|
||||
from .util import simplify_ascii
|
||||
from .util import transform_fd_to_tmpfile
|
||||
|
||||
|
||||
@ -161,7 +160,7 @@ def convert_certificate( # noqa: ignore=C901
|
||||
elif packet.name.endswith("--UserID"):
|
||||
current_packet_mode = "uid"
|
||||
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
|
||||
elif packet.name.endswith("--PublicSubkey"):
|
||||
@ -493,24 +492,6 @@ def persist_uid_revocations(
|
||||
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]:
|
||||
"""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
|
||||
|
||||
from collections.abc import Iterable
|
||||
from collections.abc import Iterator
|
||||
from contextlib import contextmanager
|
||||
@ -7,7 +6,11 @@ from os import chdir
|
||||
from os import environ
|
||||
from os import getcwd
|
||||
from pathlib import Path
|
||||
from re import escape
|
||||
from re import split
|
||||
from re import sub
|
||||
from string import ascii_letters
|
||||
from string import digits
|
||||
from subprocess import STDOUT
|
||||
from subprocess import CalledProcessError
|
||||
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()),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
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 get_fingerprints_from_paths
|
||||
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_username_to_keyring_path
|
||||
from libkeyringctl.sequoia import packet_dump_field
|
||||
@ -20,6 +19,7 @@ from libkeyringctl.types import PacketKind
|
||||
from libkeyringctl.types import Uid
|
||||
from libkeyringctl.util import get_cert_paths
|
||||
from libkeyringctl.util import get_fingerprint_from_partial
|
||||
from libkeyringctl.util import simplify_ascii
|
||||
from libkeyringctl.util import system
|
||||
|
||||
|
||||
@ -161,7 +161,7 @@ def verify_integrity(certificate: Path, all_fingerprints: Set[Fingerprint]) -> N
|
||||
kind = kinds[0]
|
||||
if kind != "User":
|
||||
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:
|
||||
raise Exception(f"Unexpected uid in file {str(uid_path)}: {uid_value}")
|
||||
elif not uid_path.is_dir():
|
||||
|
@ -25,7 +25,6 @@ from pytest import fixture
|
||||
from libkeyringctl.keyring import convert_certificate
|
||||
from libkeyringctl.keyring import export
|
||||
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 key_extract_certificate
|
||||
from libkeyringctl.sequoia import key_generate
|
||||
@ -35,6 +34,7 @@ from libkeyringctl.types import Fingerprint
|
||||
from libkeyringctl.types import Uid
|
||||
from libkeyringctl.types import Username
|
||||
from libkeyringctl.util import cwd
|
||||
from libkeyringctl.util import simplify_ascii
|
||||
from libkeyringctl.util import system
|
||||
|
||||
test_keys: Dict[Username, List[Path]] = defaultdict(list)
|
||||
@ -133,7 +133,7 @@ def create_uid_certification(
|
||||
certificate: Path = test_certificates[certified][0]
|
||||
fingerprint: Fingerprint = Fingerprint(test_keyring_certificates[certified][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 = (
|
||||
working_dir
|
||||
|
Loading…
Reference in New Issue
Block a user