Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
attribute.py291 linesDownload Raw Back to abstract
1"""2"""3 4# Created on 2014.01.065#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 os import linesep27 28from .. import MODIFY_ADD, MODIFY_REPLACE, MODIFY_DELETE, SEQUENCE_TYPES29from ..core.exceptions import LDAPCursorError30from ..utils.repr import to_stdout_encoding31from . import STATUS_PENDING_CHANGES, STATUS_VIRTUAL, STATUS_READY_FOR_DELETION, STATUS_READY_FOR_MOVING, STATUS_READY_FOR_RENAMING32from ..utils.log import log, log_enabled, ERROR, BASIC, PROTOCOL, EXTENDED33 34 35# noinspection PyUnresolvedReferences36class Attribute(object):37    """Attribute/values object, it includes the search result (after post_query transformation) of each attribute in an entry38 39    Attribute object is read only40 41    - values: contain the processed attribute values42    - raw_values': contain the unprocessed attribute values43 44 45    """46 47    def __init__(self, attr_def, entry, cursor):48        self.key = attr_def.key49        self.definition = attr_def50        self.values = []51        self.raw_values = []52        self.response = None53        self.entry = entry54        self.cursor = cursor55        other_names = [name for name in attr_def.oid_info.name if self.key.lower() != name.lower()] if attr_def.oid_info else None56        self.other_names = set(other_names) if other_names else None  # self.other_names is None if there are no short names, else is a set of secondary names57 58    def __repr__(self):59        if len(self.values) == 1:60            r = to_stdout_encoding(self.key) + ': ' + to_stdout_encoding(self.values[0])61        elif len(self.values) > 1:62            r = to_stdout_encoding(self.key) + ': ' + to_stdout_encoding(self.values[0])63            filler = ' ' * (len(self.key) + 6)64            for value in self.values[1:]:65                r += linesep + filler + to_stdout_encoding(value)66        else:67            r = to_stdout_encoding(self.key) + ': ' + to_stdout_encoding('<no value>')68 69        return r70 71    def __str__(self):72        if len(self.values) == 1:73            return to_stdout_encoding(self.values[0])74        else:75            return to_stdout_encoding(self.values)76 77    def __len__(self):78        return len(self.values)79 80    def __iter__(self):81        return self.values.__iter__()82 83    def __getitem__(self, item):84        return self.values[item]85 86    def __getstate__(self):87        cpy = dict(self.__dict__)88        cpy['cursor'] = None89        return cpy90 91    def __eq__(self, other):92        try:93            if self.value == other:94                return True95        except Exception:96            return False97 98    def __ne__(self, other):99        return not self == other100 101    @property102    def value(self):103        """104        :return: The single value or a list of values of the attribute.105        """106        if not self.values:107            return None108 109        return self.values[0] if len(self.values) == 1 else self.values110 111 112class OperationalAttribute(Attribute):113    """Operational attribute/values object. Include the search result of an114    operational attribute in an entry115 116    OperationalAttribute object is read only117 118    - values: contains the processed attribute values119    - raw_values: contains the unprocessed attribute values120 121    It may not have an AttrDef122 123    """124 125    def __repr__(self):126        if len(self.values) == 1:127            r = to_stdout_encoding(self.key) + ' [OPERATIONAL]: ' + to_stdout_encoding(self.values[0])128        elif len(self.values) > 1:129            r = to_stdout_encoding(self.key) + ' [OPERATIONAL]: ' + to_stdout_encoding(self.values[0])130            filler = ' ' * (len(self.key) + 6)131            for value in sorted(self.values[1:]):132                r += linesep + filler + to_stdout_encoding(value)133        else:134            r = ''135 136        return r137 138 139class WritableAttribute(Attribute):140    def __repr__(self):141        filler = ' ' * (len(self.key) + 6)142        if len(self.values) == 1:143            r = to_stdout_encoding(self.key) + ': ' + to_stdout_encoding(self.values[0])144        elif len(self.values) > 1:145            r = to_stdout_encoding(self.key) + ': ' + to_stdout_encoding(self.values[0])146            for value in self.values[1:]:147                r += linesep + filler + to_stdout_encoding(value)148        else:149            r = to_stdout_encoding(self.key) + to_stdout_encoding(': <Virtual>')150        if self.definition.name in self.entry._changes:151            r += linesep + filler + 'CHANGES: ' + str(self.entry._changes[self.definition.name])152        return r153 154    def __iadd__(self, other):155        self.add(other)156        return Ellipsis  # hack to avoid calling set() in entry __setattr__157 158    def __isub__(self, other):159        self.delete(other)160        return Ellipsis  # hack to avoid calling set_value in entry __setattr__161 162    def _update_changes(self, changes, remove_old=False):163        # checks for friendly key in AttrDef and uses the real attribute name164        if self.definition and self.definition.name:165            key = self.definition.name166        else:167            key = self.key168 169        if key not in self.entry._changes or remove_old:  # remove old changes (for removing attribute)170            self.entry._changes[key] = []171 172        self.entry._changes[key].append(changes)173        if log_enabled(PROTOCOL):174            log(PROTOCOL, 'updated changes <%r> for <%s> attribute in <%s> entry', changes, self.key, self.entry.entry_dn)175        self.entry._state.set_status(STATUS_PENDING_CHANGES)176 177    def add(self, values):178        if log_enabled(PROTOCOL):179            log(PROTOCOL, 'adding %r to <%s> attribute in <%s> entry', values, self.key, self.entry.entry_dn)180        # new value for attribute to commit with a MODIFY_ADD181        if self.entry._state._initial_status == STATUS_VIRTUAL:182            error_message = 'cannot perform a modify operation in a new entry'183            if log_enabled(ERROR):184                log(ERROR, '%s for <%s>', error_message, self)185            raise LDAPCursorError(error_message)186        if self.entry.entry_status in [STATUS_READY_FOR_DELETION, STATUS_READY_FOR_MOVING, STATUS_READY_FOR_RENAMING]:187            error_message = self.entry.entry_status + ' - cannot add attributes'188            if log_enabled(ERROR):189                log(ERROR, '%s for <%s>', error_message, self)190            raise LDAPCursorError(error_message)191        if values is None:192            error_message = 'value to add cannot be None'193            if log_enabled(ERROR):194                log(ERROR, '%s for <%s>', error_message, self)195            raise LDAPCursorError(error_message)196        if values is not None:197            validated = self.definition.validate(values)  # returns True, False or a value to substitute to the actual values198            if validated is False:199                error_message = 'value \'%s\' non valid for attribute \'%s\'' % (values, self.key)200                if log_enabled(ERROR):201                    log(ERROR, '%s for <%s>', error_message, self)202                raise LDAPCursorError(error_message)203            elif validated is not True:  # a valid LDAP value equivalent to the actual values204                values = validated205        self._update_changes((MODIFY_ADD, values if isinstance(values, SEQUENCE_TYPES) else [values]))206 207    def set(self, values):208        # new value for attribute to commit with a MODIFY_REPLACE, old values are deleted209        if log_enabled(PROTOCOL):210            log(PROTOCOL, 'setting %r to <%s> attribute in <%s> entry', values, self.key, self.entry.entry_dn)211        if self.entry.entry_status in [STATUS_READY_FOR_DELETION, STATUS_READY_FOR_MOVING, STATUS_READY_FOR_RENAMING]:212            error_message = self.entry.entry_status + ' - cannot set attributes'213            if log_enabled(ERROR):214                log(ERROR, '%s for <%s>', error_message, self)215            raise LDAPCursorError(error_message)216        if values is None:217            error_message = 'new value cannot be None'218            if log_enabled(ERROR):219                log(ERROR, '%s for <%s>', error_message, self)220            raise LDAPCursorError(error_message)221        validated = self.definition.validate(values)  # returns True, False or a value to substitute to the actual values222        if validated is False:223            error_message = 'value \'%s\' non valid for attribute \'%s\'' % (values, self.key)224            if log_enabled(ERROR):225                log(ERROR, '%s for <%s>', error_message, self)226            raise LDAPCursorError(error_message)227        elif validated is not True:  # a valid LDAP value equivalent to the actual values228            values = validated229        self._update_changes((MODIFY_REPLACE, values if isinstance(values, SEQUENCE_TYPES) else [values]), remove_old=True)230 231    def delete(self, values):232        # value for attribute to delete in commit with a MODIFY_DELETE233        if log_enabled(PROTOCOL):234            log(PROTOCOL, 'deleting %r from <%s> attribute in <%s> entry', values, self.key, self.entry.entry_dn)235        if self.entry._state._initial_status == STATUS_VIRTUAL:236            error_message = 'cannot delete an attribute value in a new entry'237            if log_enabled(ERROR):238                log(ERROR, '%s for <%s>', error_message, self)239            raise LDAPCursorError(error_message)240        if self.entry.entry_status in [STATUS_READY_FOR_DELETION, STATUS_READY_FOR_MOVING, STATUS_READY_FOR_RENAMING]:241            error_message = self.entry.entry_status + ' - cannot delete attributes'242            if log_enabled(ERROR):243                log(ERROR, '%s for <%s>', error_message, self)244            raise LDAPCursorError(error_message)245        if values is None:246            error_message = 'value to delete cannot be None'247            if log_enabled(ERROR):248                log(ERROR, '%s for <%s>', error_message, self)249            raise LDAPCursorError(error_message)250        if not isinstance(values, SEQUENCE_TYPES):251            values = [values]252        for single_value in values:253            if single_value not in self.values:254                error_message = 'value \'%s\' not present in \'%s\'' % (single_value, ', '.join(self.values))255                if log_enabled(ERROR):256                    log(ERROR, '%s for <%s>', error_message, self)257                raise LDAPCursorError(error_message)258        self._update_changes((MODIFY_DELETE, values))259 260    def remove(self):261        if log_enabled(PROTOCOL):262            log(PROTOCOL, 'removing <%s> attribute in <%s> entry', self.key, self.entry.entry_dn)263        if self.entry._state._initial_status == STATUS_VIRTUAL:264            error_message = 'cannot remove an attribute in a new entry'265            if log_enabled(ERROR):266                log(ERROR, '%s for <%s>', error_message, self)267            raise LDAPCursorError(error_message)268        if self.entry.entry_status in [STATUS_READY_FOR_DELETION, STATUS_READY_FOR_MOVING, STATUS_READY_FOR_RENAMING]:269            error_message = self.entry.entry_status + ' - cannot remove attributes'270            if log_enabled(ERROR):271                log(ERROR, '%s for <%s>', error_message, self)272            raise LDAPCursorError(error_message)273        self._update_changes((MODIFY_REPLACE, []), True)274 275    def discard(self):276        if log_enabled(PROTOCOL):277            log(PROTOCOL, 'discarding <%s> attribute in <%s> entry', self.key, self.entry.entry_dn)278        del self.entry._changes[self.key]279        if not self.entry._changes:280            self.entry._state.set_status(self.entry._state._initial_status)281 282    @property283    def virtual(self):284        return False if len(self.values) else True285 286    @property287    def changes(self):288        if self.key in self.entry._changes:289            return self.entry._changes[self.key]290        return None291 
codekingpro/portable-devtools · Team Ai