diff --git a/services/presence/psutils.py b/services/presence/psutils.py index 65a94d35..06b8a831 100644 --- a/services/presence/psutils.py +++ b/services/presence/psutils.py @@ -1,4 +1,5 @@ # Copyright (C) 2007, Red Hat, Inc. +# Copyright (C) 2007 Collabora Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -15,13 +16,69 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import logging +from string import ascii_letters, digits import dbus import gobject +from sugar import util + _logger = logging.getLogger('s-p-s.psutils') +_ASCII_ALNUM = ascii_letters + digits + + +def pubkey_to_keyid(key): + """Return the key ID for the given public key. This is currently its SHA-1 + in hex. + + :Parameters: + `key` : str + The public key as a Base64 string + :Returns: + The key ID as a string of hex digits + """ + return util.printable_hash(util._sha_data(key)) + + +def escape_identifier(identifier): + """Escape the given string to be a valid D-Bus object path or service + name component, using a reversible encoding to ensure uniqueness. + + The reversible encoding is as follows: + + * The empty string becomes '_' + * Otherwise, each non-alphanumeric character is replaced by '_' plus + two lower-case hex digits; the same replacement is carried out on + the first character, if it's a digit + """ + # '' -> '_' + if not identifier: + return '_' + + # A bit of a fast path for strings which are already OK. + # We deliberately omit '_' because, for reversibility, that must also + # be escaped. + if (identifier.strip(_ASCII_ALNUM) == '' and + identifier[0] in ascii_letters): + return identifier + + # The first character may not be a digit + if identifier[0] not in ascii_letters: + ret = ['_%02x' % ord(identifier[0])] + else: + ret = [identifier[0]] + + # Subsequent characters may be digits or ASCII letters + for c in identifier[1:]: + if c in _ASCII_ALNUM: + ret.append(c) + else: + ret.append('_%02x' % ord(c)) + + return ''.join(ret) + NM_SERVICE = 'org.freedesktop.NetworkManager' NM_IFACE = 'org.freedesktop.NetworkManager' diff --git a/services/presence/test_psutils.py b/services/presence/test_psutils.py new file mode 100644 index 00000000..deaf1039 --- /dev/null +++ b/services/presence/test_psutils.py @@ -0,0 +1,8 @@ +from psutils import escape_identifier + +assert escape_identifier('') == '_' +assert escape_identifier('_') == '_5f' +assert escape_identifier('1') == '_31' +assert escape_identifier('a1') == 'a1' +assert escape_identifier('1a') == '_31a' +assert escape_identifier("0123abc_xyz\x01\xff") == '_30123abc_5fxyz_01_ff'