Return a boolean of whether the raw password matches the three
    part encoded digest.
    If setter is specified, it'll be called when you need to
    regenerate the password.

def check_password(password, encoded, setter=None, preferred='default'):
    """
    Return a boolean of whether the raw password matches the three
    part encoded digest.
    If setter is specified, it'll be called when you need to
    regenerate the password.
    """
    if password is None:
        return False

    preferred = bCryptPasswordHasher
    hasher = bCryptPasswordHasher

    hasher_changed = hasher.algorithm != preferred.algorithm
    must_update = hasher_changed or preferred.must_update(encoded)
    is_correct = hasher.verify(password, encoded)

    # If the hasher didn't change (we don't protect against enumeration if it
    # does) and the password should get updated, try to close the timing gap
    # between the work factor of the current encoded password and the default
    # work factor.
    if not is_correct and not hasher_changed and must_update:
        hasher.harden_runtime(password, encoded)

    if setter and is_correct and must_update:
        setter(password)
    return is_correct