Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
conv.py273 linesDownload Raw Back to utils
1"""2"""3 4# Created on 2014.04.265#6# Author: Giovanni Cannata7#8# Copyright 2014 - 2020 Giovanni Cannata9#10# This file is part of ldap3.11#12# ldap3 is free software: you can redistribute it and/or modify13# it under the terms of the GNU Lesser General Public License as published14# by the Free Software Foundation, either version 3 of the License, or15# (at your option) any later version.16#17# ldap3 is distributed in the hope that it will be useful,18# but WITHOUT ANY WARRANTY; without even the implied warranty of19# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the20# GNU Lesser General Public License for more details.21#22# You should have received a copy of the GNU Lesser General Public License23# along with ldap3 in the COPYING and COPYING.LESSER files.24# If not, see <http://www.gnu.org/licenses/>.25 26from base64 import b64encode, b64decode27import datetime28import re29 30from .. import SEQUENCE_TYPES, STRING_TYPES, NUMERIC_TYPES, get_config_parameter31from ..utils.ciDict import CaseInsensitiveDict32from ..core.exceptions import LDAPDefinitionError33 34 35def to_unicode(obj, encoding=None, from_server=False):36    """Try to convert bytes (and str in python2) to unicode.37     Return object unmodified if python3 string, else raise an exception38    """39    conf_default_client_encoding = get_config_parameter('DEFAULT_CLIENT_ENCODING')40    conf_default_server_encoding = get_config_parameter('DEFAULT_SERVER_ENCODING')41    conf_additional_server_encodings = get_config_parameter('ADDITIONAL_SERVER_ENCODINGS')42    conf_additional_client_encodings = get_config_parameter('ADDITIONAL_CLIENT_ENCODINGS')43    if isinstance(obj, NUMERIC_TYPES):44        obj = str(obj)45 46    if isinstance(obj, (bytes, bytearray)):47        if from_server:  # data from server48            if encoding is None:49                encoding = conf_default_server_encoding50            try:51                return obj.decode(encoding)52            except UnicodeDecodeError:53                for encoding in conf_additional_server_encodings:  # AD could have DN not encoded in utf-8 (even if this is not allowed by RFC4510)54                    try:55                        return obj.decode(encoding)56                    except UnicodeDecodeError:57                        pass58                raise UnicodeError("Unable to convert server data to unicode: %r" % obj)59        else:  # data from client60            if encoding is None:61                encoding = conf_default_client_encoding62            try:63                return obj.decode(encoding)64            except UnicodeDecodeError:65                for encoding in conf_additional_client_encodings:  # tries additional encodings66                    try:67                        return obj.decode(encoding)68                    except UnicodeDecodeError:69                        pass70                raise UnicodeError("Unable to convert client data to unicode: %r" % obj)71 72    if isinstance(obj, STRING_TYPES):  # python3 strings, python 2 unicode73        return obj74 75    raise UnicodeError("Unable to convert type %s to unicode: %r" % (obj.__class__.__name__, obj))76 77 78def to_raw(obj, encoding='utf-8'):79    """Tries to convert to raw bytes from unicode"""80    if isinstance(obj, NUMERIC_TYPES):81        obj = str(obj)82 83    if not (isinstance(obj, bytes)):84        if isinstance(obj, SEQUENCE_TYPES):85            return [to_raw(element) for element in obj]86        elif isinstance(obj, STRING_TYPES):87            return obj.encode(encoding)88    return obj89 90 91def escape_filter_chars(text, encoding=None):92    """ Escape chars mentioned in RFC4515. """93    if encoding is None:94        encoding = get_config_parameter('DEFAULT_ENCODING')95 96    try:97        text = to_unicode(text, encoding)98        escaped = text.replace('\\', '\\5c')99        escaped = escaped.replace('*', '\\2a')100        escaped = escaped.replace('(', '\\28')101        escaped = escaped.replace(')', '\\29')102        escaped = escaped.replace('\x00', '\\00')103    except Exception:  # probably raw bytes values, return escaped bytes value104        escaped = to_unicode(escape_bytes(text))105        # escape all octets greater than 0x7F that are not part of a valid UTF-8106        # escaped = ''.join(c if c <= ord(b'\x7f') else escape_bytes(to_raw(to_unicode(c, encoding))) for c in escaped)107    return escaped108 109 110def unescape_filter_chars(text, encoding=None):111    """ unescape chars mentioned in RFC4515. """112    if encoding is None:113        encoding = get_config_parameter('DEFAULT_ENCODING')114 115    unescaped = to_raw(text, encoding)116    unescaped = unescaped.replace(b'\\5c', b'\\')117    unescaped = unescaped.replace(b'\\5C', b'\\')118    unescaped = unescaped.replace(b'\\2a', b'*')119    unescaped = unescaped.replace(b'\\2A', b'*')120    unescaped = unescaped.replace(b'\\28', b'(')121    unescaped = unescaped.replace(b'\\29', b')')122    unescaped = unescaped.replace(b'\\00', b'\x00')123    return unescaped124 125 126def escape_bytes(bytes_value):127    """ Convert a byte sequence to a properly escaped for LDAP (format BACKSLASH HEX HEX) string"""128    if bytes_value:129        if str is not bytes:  # Python 3130            if isinstance(bytes_value, str):131                bytes_value = bytearray(bytes_value, encoding='utf-8')132            escaped = '\\'.join([('%02x' % int(b)) for b in bytes_value])133        else:  # Python 2134            if isinstance(bytes_value, unicode):135                bytes_value = bytes_value.encode('utf-8')136            escaped = '\\'.join([('%02x' % ord(b)) for b in bytes_value])137    else:138        escaped = ''139 140    return ('\\' + escaped) if escaped else ''141 142 143def prepare_for_stream(value):144    if str is not bytes:  # Python 3145        return value146    else:  # Python 2147        return value.decode()148 149 150def json_encode_b64(obj):151    try:152        return dict(encoding='base64', encoded=b64encode(obj))153    except Exception as e:154        raise LDAPDefinitionError('unable to encode ' + str(obj) + ' - ' + str(e))155 156 157# noinspection PyProtectedMember158def check_json_dict(json_dict):159    # needed for python 2160 161    for k, v in json_dict.items():162        if isinstance(v, dict):163            check_json_dict(v)164        elif isinstance(v, CaseInsensitiveDict):165            check_json_dict(v._store)166        elif isinstance(v, SEQUENCE_TYPES):167            for i, e in enumerate(v):168                if isinstance(e, dict):169                    check_json_dict(e)170                elif isinstance(e, CaseInsensitiveDict):171                    check_json_dict(e._store)172                else:173                    v[i] = format_json(e)174        else:175            json_dict[k] = format_json(v)176 177 178def json_hook(obj):179    if hasattr(obj, 'keys') and len(list(obj.keys())) == 2 and 'encoding' in obj.keys() and 'encoded' in obj.keys():180        return b64decode(obj['encoded'])181 182    return obj183 184 185# noinspection PyProtectedMember186def format_json(obj, iso_format=False):187    if isinstance(obj, CaseInsensitiveDict):188        return obj._store189 190    if isinstance(obj, datetime.datetime):191        return str(obj)192 193    if isinstance(obj, int):194        return obj195 196    if isinstance(obj, datetime.timedelta):197        if iso_format:198            return obj.isoformat()199        return str(obj)200 201    if str is bytes:  # Python 2202        if isinstance(obj, long):  # long exists only in python2203            return obj204 205    try:206        if str is not bytes:  # Python 3207            if isinstance(obj, bytes):208                # return check_escape(str(obj, 'utf-8', errors='strict'))209                return str(obj, 'utf-8', errors='strict')210            raise LDAPDefinitionError('unable to serialize ' + str(obj))211        else:  # Python 2212            if isinstance(obj, unicode):213                return obj214            else:215                # return unicode(check_escape(obj))216                return unicode(obj)217    except (TypeError, UnicodeDecodeError):218        pass219 220    try:221        return json_encode_b64(bytes(obj))222    except Exception:223        pass224 225    raise LDAPDefinitionError('unable to serialize ' + str(obj))226 227 228def is_filter_escaped(text):229    if not type(text) == ((str is not bytes) and str or unicode):  # requires str for Python 3 and unicode for Python 2230        raise ValueError('unicode input expected')231 232    return all(c not in text for c in '()*\0') and not re.search('\\\\([^0-9a-fA-F]|(.[^0-9a-fA-F]))', text)233 234 235def ldap_escape_to_bytes(text):236    bytesequence = bytearray()237    i = 0238    try:239        if isinstance(text, STRING_TYPES):240            while i < len(text):241                if text[i] == '\\':242                    if len(text) > i + 2:243                        try:244                            bytesequence.append(int(text[i+1:i+3], 16))245                            i += 3246                            continue247                        except ValueError:248                            pass249                    bytesequence.append(92)  # "\" ASCII code250                else:251                    raw = to_raw(text[i])252                    for c in raw:253                        bytesequence.append(c)254                i += 1255        elif isinstance(text, (bytes, bytearray)):256            while i < len(text):257                if text[i] == 92:  # "\" ASCII code258                    if len(text) > i + 2:259                        try:260                            bytesequence.append(int(text[i + 1:i + 3], 16))261                            i += 3262                            continue263                        except ValueError:264                            pass265                    bytesequence.append(92)  # "\" ASCII code266                else:267                    bytesequence.append(text[i])268                i += 1269    except Exception:270        raise LDAPDefinitionError('badly formatted LDAP byte escaped sequence')271 272    return bytes(bytesequence)273 
codekingpro/portable-devtools · Team Ai