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
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)
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)
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)
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
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
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)
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