示例#1
0
def get_crypt_handler(name, default=Undef):
    """return handler for specified password hash scheme.

    this method looks up a handler for the specified scheme.
    if the handler is not already loaded,
    it checks if the location is known, and loads it first.

    :arg name: name of handler to return
    :param default: optional default value to return if no handler with specified name is found.

    :raises KeyError: if no handler matching that name is found, and no default specified, a KeyError will be raised.

    :returns: handler attached to name, or default value (if specified).
    """
    global _handlers, _handler_locations

    #check if handler loaded
    handler = _handlers.get(name)
    if handler:
        return handler

    #normalize name (and if changed, check dict again)
    alt = name.replace("-","_").lower()
    if alt != name:
        warn("handler names should be lower-case, and use underscores instead of hyphens: %r => %r" % (name, alt))
        name = alt

        #check if handler loaded
        handler = _handlers.get(name)
        if handler:
            return handler

    #check if lazy load mapping has been specified for this driver
    route = _handler_locations.get(name)
    if route:
        modname, modattr = route

        #try to load the module - any import errors indicate runtime config,
        # either missing packages, or bad path provided to register_crypt_handler_path()
        mod = __import__(modname, None, None, ['dummy'], 0)

        #first check if importing module triggered register_crypt_handler(),
        #(though this is discouraged due to it's magical implicitness)
        handler = _handlers.get(name)
        if handler:
            #XXX: issue deprecation warning here?
            assert is_crypt_handler(handler), "unexpected object: name=%r object=%r" % (name, handler)
            return handler

        #then get real handler & register it
        handler = getattr(mod, modattr)
        register_crypt_handler(handler, name=name)
        return handler

    #fail!
    if default is Undef:
        raise KeyError("no crypt handler found for algorithm: %r" % (name,))
    else:
        return default
示例#2
0
def _resolve(hasher, param="value"):
    """
    internal helper to resolve argument to hasher object
    """
    if is_crypt_handler(hasher):
        return hasher
    elif isinstance(hasher, unicode_or_str):
        return get_crypt_handler(hasher)
    else:
        raise exc.ExpectedTypeError(hasher, unicode_or_str, param)
示例#3
0
def register_crypt_handler(handler, force=False, _attr=None):
    """register password hash handler.

    this method immediately registers a handler with the internal passlib registry,
    so that it will be returned by :func:`get_crypt_handler` when requested.

    :arg handler: the password hash handler to register
    :param force: force override of existing handler (defaults to False)
    :param _attr:
        [internal kwd] if specified, ensures ``handler.name``
        matches this value, or raises :exc:`ValueError`.

    :raises TypeError:
        if the specified object does not appear to be a valid handler.

    :raises ValueError:
        if the specified object's name (or other required attributes)
        contain invalid values.

    :raises KeyError:
        if a (different) handler was already registered with
        the same name, and ``force=True`` was not specified.
    """
    # validate handler
    if not is_crypt_handler(handler):
        raise ExpectedTypeError(handler, "password hash handler", "handler")
    if not handler:
        raise AssertionError("``bool(handler)`` must be True")

    # validate name
    name = handler.name
    _validate_handler_name(name)
    if _attr and _attr != name:
        raise ValueError(
            "handlers must be stored only under their own name (%r != %r)" %
            (_attr, name))

    # check for existing handler
    other = _handlers.get(name)
    if other:
        if other is handler:
            log.debug("same %r handler already registered: %r", name, handler)
            return
        elif force:
            log.warning("overriding previously registered %r handler: %r",
                        name, other)
        else:
            raise KeyError(
                "another %r handler has already been registered: %r" %
                (name, other))

    # register handler
    _handlers[name] = handler
    log.debug("registered %r handler: %r", name, handler)
示例#4
0
文件: registry.py 项目: cutso/passlib
def register_crypt_handler(handler, force=False, _attr=None):
    """register password hash handler.

    this method immediately registers a handler with the internal passlib registry,
    so that it will be returned by :func:`get_crypt_handler` when requested.

    :arg handler: the password hash handler to register
    :param force: force override of existing handler (defaults to False)
    :param _attr:
        [internal kwd] if specified, ensures ``handler.name``
        matches this value, or raises :exc:`ValueError`.

    :raises TypeError:
        if the specified object does not appear to be a valid handler.

    :raises ValueError:
        if the specified object's name (or other required attributes)
        contain invalid values.

    :raises KeyError:
        if a (different) handler was already registered with
        the same name, and ``force=True`` was not specified.
    """
    # validate handler
    if not is_crypt_handler(handler):
        raise ExpectedTypeError(handler, "password hash handler", "handler")
    if not handler:
        raise AssertionError("``bool(handler)`` must be True")

    # validate name
    name = handler.name
    _validate_handler_name(name)
    if _attr and _attr != name:
        raise ValueError("handlers must be stored only under their own name (%r != %r)" %
                         (_attr, name))

    # check for existing handler
    other = _handlers.get(name)
    if other:
        if other is handler:
            log.debug("same %r handler already registered: %r", name, handler)
            return
        elif force:
            log.warning("overriding previously registered %r handler: %r",
                        name, other)
        else:
            raise KeyError("another %r handler has already been registered: %r" %
                           (name, other))

    # register handler
    _handlers[name] = handler
    log.debug("registered %r handler: %r", name, handler)
示例#5
0
def get_crypt_handler(name, default=_UNSET):
    """return handler for specified password hash scheme.

    this method looks up a handler for the specified scheme.
    if the handler is not already loaded,
    it checks if the location is known, and loads it first.

    :arg name: name of handler to return
    :param default: optional default value to return if no handler with specified name is found.

    :raises KeyError: if no handler matching that name is found, and no default specified, a KeyError will be raised.

    :returns: handler attached to name, or default value (if specified).
    """
    # catch invalid names before we check _handlers,
    # since it's a module dict, and exposes things like __package__, etc.
    if name.startswith("_"):
        if default is _UNSET:
            raise KeyError("invalid handler name: %r" % (name,))
        else:
            return default

    # check if handler is already loaded
    try:
        return _handlers[name]
    except KeyError:
        pass

    # normalize name (and if changed, check dict again)
    assert isinstance(name, str), "name must be str instance"
    alt = name.replace("-","_").lower()
    if alt != name:
        warn("handler names should be lower-case, and use underscores instead "
             "of hyphens: %r => %r" % (name, alt), PasslibWarning,
             stacklevel=2)
        name = alt

        # try to load using new name
        try:
            return _handlers[name]
        except KeyError:
            pass

    # check if lazy load mapping has been specified for this driver
    path = _locations.get(name)
    if path:
        if ':' in path:
            modname, modattr = path.split(":")
        else:
            modname, modattr = path, name
        ##log.debug("loading %r handler from path: '%s:%s'", name, modname, modattr)

        # try to load the module - any import errors indicate runtime config, usually
        # either missing package, or bad path provided to register_crypt_handler_path()
        mod = __import__(modname, fromlist=[modattr], level=0)

        # first check if importing module triggered register_crypt_handler(),
        # (this is discouraged due to it's magical implicitness)
        handler = _handlers.get(name)
        if handler:
            # XXX: issue deprecation warning here?
            assert is_crypt_handler(handler), "unexpected object: name=%r object=%r" % (name, handler)
            return handler

        # then get real handler & register it
        handler = getattr(mod, modattr)
        register_crypt_handler(handler, _attr=name)
        return handler

    # fail!
    if default is _UNSET:
        raise KeyError("no crypt handler found for algorithm: %r" % (name,))
    else:
        return default
示例#6
0
def get_crypt_handler(name, default=_UNSET):
    """return handler for specified password hash scheme.

    this method looks up a handler for the specified scheme.
    if the handler is not already loaded,
    it checks if the location is known, and loads it first.

    :arg name: name of handler to return
    :param default: optional default value to return if no handler with specified name is found.

    :raises KeyError: if no handler matching that name is found, and no default specified, a KeyError will be raised.

    :returns: handler attached to name, or default value (if specified).
    """
    # catch invalid names before we check _handlers,
    # since it's a module dict, and exposes things like __package__, etc.
    if name.startswith("_"):
        if default is _UNSET:
            raise KeyError("invalid handler name: %r" % (name,))
        else:
            return default

    # check if handler is already loaded
    try:
        return _handlers[name]
    except KeyError:
        pass

    # normalize name (and if changed, check dict again)
    assert isinstance(name, str), "name must be str instance"
    alt = name.replace("-","_").lower()
    if alt != name:
        warn("handler names should be lower-case, and use underscores instead "
             "of hyphens: %r => %r" % (name, alt), PasslibWarning,
             stacklevel=2)
        name = alt

        # try to load using new name
        try:
            return _handlers[name]
        except KeyError:
            pass

    # check if lazy load mapping has been specified for this driver
    path = _locations.get(name)
    if path:
        if ':' in path:
            modname, modattr = path.split(":")
        else:
            modname, modattr = path, name
        ##log.debug("loading %r handler from path: '%s:%s'", name, modname, modattr)

        # try to load the module - any import errors indicate runtime config, usually
        # either missing package, or bad path provided to register_crypt_handler_path()
        mod = __import__(modname, fromlist=[modattr], level=0)

        # first check if importing module triggered register_crypt_handler(),
        # (this is discouraged due to its magical implicitness)
        handler = _handlers.get(name)
        if handler:
            # XXX: issue deprecation warning here?
            assert is_crypt_handler(handler), "unexpected object: name=%r object=%r" % (name, handler)
            return handler

        # then get real handler & register it
        handler = getattr(mod, modattr)
        register_crypt_handler(handler, _attr=name)
        return handler

    # fail!
    if default is _UNSET:
        raise KeyError("no crypt handler found for algorithm: %r" % (name,))
    else:
        return default
示例#7
0
def register_crypt_handler(handler, force=False, name=None):
    """register password hash handler.

    this method immediately registers a handler with the internal passlib registry,
    so that it will be returned by :func:`get_crypt_handler` when requested.

    :arg handler: the password hash handler to register
    :param force: force override of existing handler (defaults to False)
    :param name:
        [internal kwd] if specified, ensures ``handler.name``
        matches this value, or raises :exc:`ValueError`.

    :raises TypeError:
        if the specified object does not appear to be a valid handler.

    :raises ValueError:
        if the specified object's name (or other required attributes)
        contain invalid values.

    :raises KeyError:
        if a (different) handler was already registered with
        the same name, and ``force=True`` was not specified.
    """
    global _handlers, _name_re

    #validate handler
    if not is_crypt_handler(handler):
        raise TypeError("object does not appear to be a crypt handler: %r" % (handler,))
    assert handler, "crypt handlers must be boolean True: %r" % (handler,)

    #if name specified, make sure it matched
    #(this is mainly used as a check to help __setattr__)
    if name:
        if name != handler.name:
            raise ValueError("handlers must be stored only under their own name")
    else:
        name = handler.name

    #validate name
    if not name:
        raise ValueError("name is null: %r" % (name,))
    if name.lower() != name:
        raise ValueError("name must be lower-case: %r" % (name,))
    if not _name_re.match(name):
        raise ValueError("invalid characters in name (must be 3+ characters, begin with a-z, and contain only underscore, a-z, 0-9): %r" % (name,))
    if '__' in name:
        raise ValueError("name may not contain double-underscores: %r" % (name,))
    if name in _forbidden_names:
        raise ValueError("that name is not allowed: %r" % (name,))

    #check for existing handler
    other = _handlers.get(name)
    if other:
        if other is handler:
            return #already registered
        if force:
            log.warning("overriding previous handler registered to name %r: %r", name, other)
        else:
            raise KeyError("a handler has already registered for the name %r: %r (use force=True to override)" % (name, other))

    #register handler in dict
    _handlers[name] = handler
    log.info("registered crypt handler %r: %r", name, handler)
示例#8
0
    def _from_dict(self, kwds):
        "configure policy from constructor keywords"
        #
        #init cache & options
        #
        context_options = {}
        options = self._options = {None:{"context":context_options}}
        self._cache = {}

        #
        #normalize & sort keywords
        #
        for cat, name, opt, value in parse_policy_items(kwds):
            copts = options.get(cat)
            if copts is None:
                copts = options[cat] = {}
            config = copts.get(name)
            if config is None:
                copts[name] = {opt:value}
            else:
                config[opt] = value

        #
        #parse list of schemes, and resolve to handlers.
        #
        schemes = context_options.get("schemes") or []
        handlers = self._handlers = []
        handler_names = set()
        for scheme in schemes:
            #resolve & validate handler
            if is_crypt_handler(scheme):
                handler = scheme
            else:
                handler = get_crypt_handler(scheme)
            name = handler.name
            if not name:
                raise TypeError("handler lacks name: %r" % (handler,))

            #check name hasn't been re-used
            if name in handler_names:
                #XXX: should this just be a warning ?
                raise KeyError("multiple handlers with same name: %r" % (name,))

            #add to handler list
            handlers.append(handler)
            handler_names.add(name)

        #
        #build _deprecated & _default maps
        #
        dmap = self._deprecated = {}
        fmap = self._default = {}
        mvmap = self._min_verify_time = {}
        for cat, config in options.iteritems():
            kwds = config.pop("context", None)
            if not kwds:
                continue

            #list of deprecated schemes
            deps = kwds.get("deprecated") or []
            if deps:
                if handlers:
                    for scheme in deps:
                        if scheme not in handler_names:
                            raise KeyError("known scheme in deprecated list: %r" % (scheme,))
                dmap[cat] = frozenset(deps)

            #default scheme
            fb = kwds.get("default")
            if fb:
                if handlers:
                    if hasattr(fb, "name"):
                        fb = fb.name
                    if fb not in handler_names:
                        raise KeyError("unknown scheme set as default: %r" % (fb,))
                    fmap[cat] = self.get_handler(fb, required=True)
                else:
                    fmap[cat] = fb

            #min verify time
            value = kwds.get("min_verify_time")
            if value:
                mvmap[cat] = value