def validate(username, password):
    if validators.length(username, 2, 20) is not True:
        return "Nazwa użytkownika powinna zawierać pomiędzy 2 a 20 znaków"
    if validators.length(password, 8, 30) is not True:
        return "Hasło musi mieć co najmniej 8 znaków"

    return "ok"
Beispiel #2
0
def snmp_auth(line_count, auth_key, priv_key, priv_type):
    if not (priv_type == 'none' or priv_type == 'aes-128'
            or priv_type == 'des'):
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        print(f'    Error on Row {line_count}. priv_type {priv_type} is not ')
        print(f'    [none|des|aes-128].  Exiting....')
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        exit()
    if not priv_type == 'none':
        if not validators.length(priv_key, min=8):
            print(
                f'\n-----------------------------------------------------------------------------\n'
            )
            print(f'   Error on Row {line_count}. priv_key does not ')
            print(f'   meet the minimum character count of 8.  Exiting....')
            print(
                f'\n-----------------------------------------------------------------------------\n'
            )
            exit()

    if not validators.length(auth_key, min=8):
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        print(f"  Error on Row {line_count}. auth_key does not ")
        print(f"  meet the minimum character count of 8.  Exiting....")
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        exit()
Beispiel #3
0
def valid_inputs(post_data):
    error = {"error": False}

    if len(post_data["post_title"]) == 0:
        error["error"] = True
        error["post_title"] = "Title must not be empty"
    elif validators.length(post_data["post_title"], min=3) != True:
        error["error"] = True
        error["post_title"] = "Title must be three characters long"

    if (
        len(post_data["post_author_link"])
        and validators.url(post_data["post_author_link"], public=True) != True
    ):
        error["error"] = True
        error["post_author_link"] = "Url must be valid"

    if validators.length(post_data["post_secret"], min=6) != True:
        error["error"] = True
        error["post_secret"] = "Secret must be six characters long"

    if validators.length(post_data["post_content"], min=1) != True:
        error["error"] = True
        error["post_content"] = "Content must not be empty"

    return error
def check_env():
    if "HOST_ADDRESS" not in os.environ:
        raise Exception("\"HOST_ADDRESS\" was not found")

    if "FAUXAPI_KEY" not in os.environ:
        raise Exception("\"FAUXAPI_KEY\" was not found")

    if "FAUXAPI_SECRET" not in os.environ:
        raise Exception("\"FAUXAPI_SECRET\" was not found")

    host = os.getenv("HOST_ADDRESS")
    valid_host: bool = False

    if ip_address.ipv4(host):
        valid_host = True

    if ip_address.ipv6(host):
        valid_host = True

    if domain(host):
        valid_host = True

    if not valid_host:
        raise Exception("Please verify \"HOST_ADDRESS\" was entered correctly")

    key = os.getenv("FAUXAPI_KEY")
    if not length(key, min=12, max=40) or not key.startswith("PFFA"):
        raise Exception("Please verify \"FAUXAPI_KEY\" was entered correctly")

    secret = os.getenv("FAUXAPI_SECRET")
    if not length(secret, min=40, max=128):
        raise Exception("Please verify \"FAUXAPI_SECRET\" was entered correctly")
Beispiel #5
0
def snmp_auth(row_num, ws, priv_type, priv_key, auth_type, auth_key):
    if not (priv_type == None or priv_type == 'none' or priv_type == 'aes-128'
            or priv_type == 'des'):
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        print(
            f'    Error on Worksheet {ws.title}, Row {row_num}. priv_type {priv_type} is not '
        )
        print(f'    [none|des|aes-128].  Exiting....')
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        exit()
    if not (priv_type == 'none' or priv_type == None):
        if not validators.length(priv_key, min=8, max=32):
            print(
                f'\n-----------------------------------------------------------------------------\n'
            )
            print(
                f'   Error on Worksheet {ws.title}, Row {row_num}. priv_key does not '
            )
            print(
                f'   meet the minimum character count of 8 or the maximum of 32.  Exiting....'
            )
            print(
                f'\n-----------------------------------------------------------------------------\n'
            )
            exit()
    if not (auth_type == 'md5' or auth_type == 'sha1'):
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        print(
            f'    Error on Worksheet {ws.title}, Row {row_num}. priv_type {priv_type} is not '
        )
        print(f'    [md5|sha1].  Exiting....')
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        exit()
    if not validators.length(auth_key, min=8, max=32):
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        print(
            f'   Error on Worksheet {ws.title}, Row {row_num}. auth_key does not '
        )
        print(
            f'   meet the minimum character count of 8 or the maximum of 32.  Exiting....'
        )
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        exit()
def login():
    try:
        if not validators.length(request.get_json()['username'].strip(),
                                 min=2) or not validators.length(
                                     request.get_json()['password'].strip(),
                                     min=2):
            task = {'status': 'username and password should not be null'}
            res2 = json.dumps(task)
            res1 = json.loads(res2)
            response = make_response(res1, 400)
            response.headers.add('Access-Control-Allow-Origin', '*')
            return response
        dic = Dbconnection.DBConnection()
        today = datetime.now()
        key = Fernet.generate_key()
        #apartmentId = session.get('apartmentId')
        myquery = {'username': request.get_json()['username'].strip()}
        mydoc = dic['user'].find(myquery)
        print(mydoc.count())
        if mydoc.count() == 0:
            task = {'status': 'Invalid username and password'}
            res2 = json.dumps(task)
            res1 = json.loads(res2)
            response = make_response(res1, 400)
            response.headers.add('Access-Control-Allow-Origin', '*')
            return response
        task = dumps(mydoc)
        res = json.dumps(task)
        res1 = json.loads(res).strip('[]')
        res2 = eval(res1)
        password = res2.get('password')
        f = Fernet(res2.get('key'))
        if f.decrypt(password) == request.get_json()['password'].strip():
            session['username'] = res2.get('username')
            session['apartmentId'] = res2.get('apartmentId')
            task = {'status': 'Success'}
            res2 = json.dumps(task)
            res1 = json.loads(res2)
            response = make_response(res1, 200)
            response.headers.add('Access-Control-Allow-Origin', '*')
            return response
        else:
            task = {'status': 'Invalid username and password'}
            res2 = json.dumps(task)
            res1 = json.loads(res2)
            response = make_response(res1, 400)
            response.headers.add('Access-Control-Allow-Origin', '*')
            return response
    except BulkWriteError as e:
        task = {'status': 'Someting went wrong in post data %s' % e}
        res2 = json.dumps(task)
        res1 = json.loads(res2)
        response = make_response(res1, 404)
        response.headers.add('Access-Control-Allow-Origin', '*')
        return response
Beispiel #7
0
def validate(username, email, password, conf_pass):
    if validators.length(username, 2, 20) is not True:
        return "Nazwa użytkownika powinna zawierać pomiędzy 2 a 20 znaków"
    if validators.email(email) is not True:
        return "Niepoprawny adres email"
    if validators.length(password, 8, 30) is not True:
        return "Hasło musi mieć co najmniej 8 znaków"
    if password != conf_pass:
        return "Hasła nie są identyczne"

    return "ok"
Beispiel #8
0
def secret(row_num, ws, var, var_value):
    if not validators.length(var_value, min=1, max=32):
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        print(
            f'   Error on Worksheet {ws.title}, Row {row_num}, {var}, {var_value}'
        )
        print(
            f'   The Shared Secret Length must be between 1 and 32 characters.  Exiting....'
        )
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        exit()
    if re.search('[\\\\ #]+', var_value):
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        print(
            f'   Error on Worksheet {ws.title}, Row {row_num}, {var}, {var_value}'
        )
        print(
            f'   The Shared Secret cannot contain backslash, space or hashtag.  Exiting....'
        )
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        exit()
def set_token(auth_token):
    """
    Configure EvalAI Token.
    """
    """
    Invoked by `evalai set_token <your_evalai_auth_token>`.
    """
    if validators.length(auth_token, min=LEN_OF_TOKEN, max=LEN_OF_TOKEN):
        if not os.path.exists(AUTH_TOKEN_DIR):
            os.makedirs(AUTH_TOKEN_DIR)
        with open(AUTH_TOKEN_PATH, "w+") as fw:
            try:
                auth_token = {"token": "{}".format(auth_token)}  # noqa
                auth_token = json.dumps(auth_token)
                fw.write(auth_token)
            except (OSError, IOError) as e:
                echo(e)
            echo(
                style(
                    "Success: Authentication token is successfully set.",
                    bold=True,
                    fg="green",
                ))
    else:
        echo(
            style("Error: Invalid Length. Enter a valid token of length: {}".
                  format(LEN_OF_TOKEN),
                  bold=True,
                  fg="red"))
def length(field_name, text, min_length=None, max_length=None):

    if min_length:
        message = (f'env.{field_name}: Text "{text}" is too short. '
                   f'min length: {min_length}')

        if vals.length(text, min=min_length) is not True:
            raise ValidatorError(message)

    if max_length:
        message = (f'env.{field_name}: Text "{text}" is too long. '
                   f'max length: {max_length}')

        if vals.length(text, max=max_length) is not True:
            raise ValidatorError(message)

    return True
def validate_video(video: Union[dict, None], key: str):
    if not video.get('url') or not url(video['url']):
        raise MissingCredentialsError(
            f"Wrong video url in {key}' intro section")
    if not video.get('description') or not length(
            video['description'], min=5, max=100):
        raise MissingCredentialsError(
            f"Wrong video description in {key}' intro section")
Beispiel #12
0
def verify_username(username):
    """Verifies if valid username."""
    try:
        # Windows Active Directory Logon Name rules
        # https://technet.microsoft.com/en-us/library/bb726984.aspx
        validators.length(username, min=1, max=104)
        invalid_chars = list('/\\[]":;|<>+=,?*@')
        if any(c in invalid_chars for c in username):
            raise serializers.ValidationError(
                {'target': [
                    'Username cannot contain the following characters: %s' % (
                        ''.join(invalid_chars))
                ]}
            )
    except validators.ValidationFailure:
        raise serializers.ValidationError(
            {'target': ['Username is not valid.']})
Beispiel #13
0
 def validate(self, value, context=None):
     try:
         if (
             value
             and validators.length(value, max=self.max_length) is not True
         ):
             raise ValidationError(message=self.message)
     except (TypeError, AssertionError):
         raise ValidationError(message=self.message)
def validate_input(value, type):
    """ 
        Check if input is valid using Validators
        If valid, return True
        Else, return error message

    """
    if validators.length(value, min=1) != "":  # For all values
        return True
    else:
        return "Kindly input a correct value!"
Beispiel #15
0
 def validate_value(self, value, args):
     ret = validators.length(unicode(value), args.get('min', 0), args.get('max', sys.maxunicode))
     if not ret:
         return ret
     ret = re.search(r'[a-z]', value) is not None
     if not ret:
         return ret
     ret = re.search(r'[A-Z]', value) is not None
     if not ret:
         return ret
     return re.search(r'[0-9]', value) is not None
Beispiel #16
0
def encryption_key(line_count, encryption_key):
    if not validators.length(encryption_key, min=16, max=32):
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        print(
            f'   Error on Row {line_count}, The Encryption Key Length must be')
        print(f'   between 16 and 32 characters.  Exiting....')
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        exit()
Beispiel #17
0
def hostname(line_count, name):
    pattern = re.compile('^[a-zA-Z0-9\\-]+$')
    if not re.search(pattern, name) and validators.length(name, min=1, max=63):
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        print(f'   Error on Row {line_count}. {name} is not a valid Hostname.')
        print(f'   Be sure you are not using the FQDN.  Exiting....')
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        exit()
Beispiel #18
0
def encryption_key(row_num, ws, var, var_value):
    if not validators.length(str(var_value), min=16, max=32):
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        print(
            f'   Error on Worksheet {ws.title}, Row {row_num} {var}. The Encryption Key'
        )
        print(f'   Length must be between 16 and 32 characters.  Exiting....')
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        exit()
Beispiel #19
0
def team_profile_new():
    user = model.Session.get_identity()
    name = request.forms.get('name')

    if not validators.length(name, min=1):
        # TODO: Blow up
        pass

    team = model.Team(name, None)
    team.members.append(user)

    db.session.add(team)
    db.session.commit()

    redirect('/team/%s?just_created=true' % team.team_id)
Beispiel #20
0
def hostname(row_num, ws, var, var_value):
    if not (re.search('^[a-zA-Z0-9\\-]+$', var_value)
            and validators.length(var_value, min=1, max=63)):
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        print(
            f'   Error on Worksheet {ws.title}, Row {row_num} {var}, {var_value} '
        )
        print(
            f'   is not a valid Hostname.  Be sure you are not using the FQDN.  Exiting....'
        )
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        exit()
Beispiel #21
0
def addMember():
    #with con:
    with lite.connect('Students') as con:
        username = request.args['username']
        email = request.args['email']
        usernametry = validators.length(username, min=5, max=80)
        emailtry = validators.email(email)
        if (usernametry == True and emailtry == True):
            cur = con.cursor()
            cur.execute("INSERT INTO students (username, email) VALUES (?, ?)",
                        (username, email))
            con.commit()
        else:
            abort(422)
    #cur = con.cursor()
    #cur.execute("INSERT INTO students (username, email) VALUES(usernameinput, emailinput)")

    return "user"
Beispiel #22
0
def add_comment():
    content = request.form['inputvalue']
    author = session['login']
    post_id = request.form['post_id']
    if validators.length(content, min=2, max=75):
        cur = mysql.connection.cursor()
        cur.execute("SELECT id FROM wpisy WHERE id=%s", (post_id,))
        check = cur.fetchone()
        if check:
            actualtime = getActualTime()
            cur.execute("INSERT INTO komentarze (tresc, autor, data, post_id) VALUES (%s,%s,%s,%s)", (content, author, actualtime, post_id,))
            mysql.connection.commit()
            cur.execute("SELECT id FROM komentarze WHERE autor=%s ORDER BY id DESC LIMIT 1", (author,))
            comment_id = cur.fetchone()
            comment_id = comment_id['id']
            return jsonify({'autor': author, 'tresc': content, 'komid': comment_id})
        return jsonify({'information': 'Wystąpił błąd'}), 409
    return jsonify({'information': 'Wystąpił błąd, minimalna długość komentarza to 2 znaki, a maksymalna 75 znaków'}), 406
def do_user_edit(username):
    profile = db.session.query(model.Person)\
        .filter_by(multipass_username=username).one()

    name = request.forms.get('name')
    bio = request.forms.get('bio')
    github_username = request.forms.get('github_username')
    website = request.forms.get('website')
    profile_pic = request.files.get('profile_pic')

    if profile_pic:
        if profile_pic.filename and profile_pic.file:
            try:
                (pic, thumb) = helpers.util.upload_profile_pic(profile_pic)
            except IOError as err:
                return "{}".format(err)
            asset = model.Asset(profile_pic.filename,
                                "png",
                                pic,
                                thumbnail=thumb)
            profile.profile_pic = asset
            db.session.add(asset)

    if not validators.length(name, min=1):
        # TODO: Abort nicely
        abort(404, 'Bad person')

    if website and not website.startswith(
            'http://') and not website.startswith('https://'):
        website = 'http://' + website

    if website and not validators.url(website):
        # TODO: blow up
        pass

    profile.name = name
    profile.bio = bio
    profile.github_username = github_username
    profile.website = website
    db.session.add(profile)
    db.session.commit()

    redirect('/user/%s' % username)
Beispiel #24
0
    def setUp(self):
        self.tlc = Specification(str, validation=validators.length(3))
        self.small = Specification(int,
                                   validation=validators.bounds(minimum=0,
                                                                maximum=8))

        self.atom_type = TypeDefinition(str)
        self.restriction_str = TypeDefinition(self.tlc)
        self.restriction_int = TypeDefinition(self.small)

        self.list_type = TypeDefinition([int])
        self.restriction_list = TypeDefinition([self.tlc])

        self.map_type = TypeDefinition({int: str})
        self.restriction_map_key = TypeDefinition({self.tlc: int})
        self.restriction_map_val = TypeDefinition({int: self.tlc})

        self.tuple_type = TypeDefinition((int, str, float))
        self.mixed_type = TypeDefinition([{(int, int): str}])
Beispiel #25
0
def name_rule(row_num, ws, var, var_value):
    if not (re.search(r'^[a-zA-Z0-9_-]+$', var_value)
            and validators.length(str(var_value), min=0, max=63)):
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        print(
            f'   Error on Worksheet {ws.title}, Row {row_num} {var}, {var_value}. '
        )
        print(
            f'   {var} is an invalid Value... It failed one of the complexity tests:'
        )
        print(f'    - Min Length 0')
        print(f'    - Max Length 63')
        print(f'    - Regex [a-zA-Z0-9_-]+')
        print(f'    Exiting....')
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        exit()
Beispiel #26
0
def description(row_num, ws, var, var_value):
    if not (re.search(r'^[a-zA-Z0-9\\!#$%()*,-./:;@ _{|}~?&+]+$', var_value)
            and validators.length(str(var_value), min=0, max=128)):
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        print(
            f'   Error on Worksheet {ws.title}, Row {row_num} {var}, {var_value}. '
        )
        print(
            f'   The description is an invalid Value... It failed one of the complexity tests:'
        )
        print(f'    - Min Length 0')
        print(f'    - Max Length 128')
        print('    - Regex [a-zA-Z0-9\\!#$%()*,-./:;@ _{|}~?&+]+')
        print(f'    Exiting....')
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        exit()
Beispiel #27
0
def do_edit_team(id):
    (team, user) = query_team(id, edit=True)

    name = request.forms.get('name')
    website = request.forms.get('website')
    profile_pic = request.files.get('profile_pic')

    if profile_pic:
        if profile_pic.filename and profile_pic.file:
            try:
                (pic, thumb) = helpers.util.upload_profile_pic(profile_pic)
            except IOError as err:
                return "{}".format(err)

            asset = model.Asset(profile_pic.filename,
                                "png",
                                pic,
                                thumbnail=thumb)
            team.profile_pic = asset
            db.session.add(asset)

    if not validators.length(name, min=1):
        # TODO: Blow up
        pass

    if website and not website.startswith(
            'http://') and not website.startswith('https://'):
        website = 'http://' + website

    if website and not validators.url(website):
        # TODO: blow up
        pass

    team.name = name
    team.website = website
    db.session.add(team)
    db.session.commit()

    redirect('/team/%s' % id)
Beispiel #28
0
def updateMember():
    with lite.connect('Students') as con:
        userid = request.args['userid']
        email = request.args['email']
        username = request.args['username']
        usernametry = validators.length(username, min=5, max=80)
        emailtry = validators.email(email)
        if (usernametry == True and emailtry == True):
            cur = con.cursor()
            if (username == ""):
                cur.execute("UPDATE students SET email=(?) WHERE userid=(?)",
                            (email, userid))
                con.commit()
            if (email == ""):
                cur.execute(
                    "UPDATE students SET username=(?) WHERE userid=(?)",
                    (username, userid))
                con.commit()
        else:
            abort(422)

    return "Success"
Beispiel #29
0
def snmp_string(line_count, snmp_name):
    if not (validators.length(snmp_name, min=1, max=32)
            and re.fullmatch('^([a-zA-Z0-9\\-\\_\\.]+)$', snmp_name)):
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        print(
            f'   Error on Row {line_count}. Community {snmp_name} is not valid.'
        )
        print(
            f'   The community/username policy name can be a maximum of 32 characters in length.'
        )
        print(
            f'   The name can contain only letters, numbers and the special characters of'
        )
        print(
            f'   underscore (_), hyphen (-), or period (.). The name cannot contain'
        )
        print(f'   the @ symbol.  Exiting....')
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        exit()
Beispiel #30
0
def secret(line_count, secret):
    if not validators.length(secret, min=1, max=32):
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        print(
            f'   Error on Row {line_count}, The Shared Secret Length must be')
        print(f'   between 1 and 32 characters.  Exiting....')
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        exit()
    if re.search('[\\\\ #]+', secret):
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        print(
            f'  The Shared Secret cannot contain backslash, space or hashtag.  Exiting....'
        )
        print(
            f'\n-----------------------------------------------------------------------------\n'
        )
        exit()
Beispiel #31
0
def test_returns_true_on_valid_length(value, min, max):
    assert validators.length(value, min=min, max=max)
Beispiel #32
0
def test_returns_failed_validation_on_invalid_range(value, min, max):
    assert isinstance(
        validators.length(value, min=min, max=max),
        validators.ValidationFailure
    )
Beispiel #33
0
def test_raises_assertion_error_for_invalid_args(value, min, max):
    with pytest.raises(AssertionError):
        assert validators.length(value, min=min, max=max)
Beispiel #34
0
def arg_validator(arg, vlist=None):
    """
    检查数据,可对同一个数据进行多种检查

    arg : 字符串,要验证的参数
    vlist :  列表,验证列表,每个元素包含两项.
            第一个项是检查类型(字符串),第二项是可选参数字典,类似:
            [
                ("检查类型",{"可选参数1":参数值,"可选参数2":参数值...}),
                ("检查类型",{"可选参数1":参数值,"可选参数2":参数值...}),
            ...
            ]
    返回: 双元组,第一项为True 或 False,第二项为验证失败的类型(第一项为True的话第二项就留空)

    注意:
    vlist 列表的第一项可以是字符串 "required",用于表示是必填项:
        如果第一项不是,而且要验证的 arg 为空,会直接返回 True,不是的继续验证。
        如果第一项是,就完全按照 vlist[1:] 的要求验证
    vlist 的元素如果是验证整数/小数/email等不需要附加参数的可以直接传入验证类型字符串即可

    用例(使用args_validator函数的,看这里vdict每个键值对的形式):
    vdict = {
            "token": ["required", "uuid"],
            "username": ["required", ("length", {"min": 4, "max": 30}), "safe_str"],
            "password": ["required", ("length", {"min": 4, "max": 20}), "safe_str"],
            "captcha": ["required", ("length", {"min": 4, "max": 8}), "safe_str"],
        }
    form = args_validator(self.request.arguments, vdict)

    """
    if not any((isinstance(vlist, list), isinstance(vlist, tuple))):
        einfo = "不支持的数据类型!应使用列表或元组,但输入的是{}".format(type(vlist))
        raise ValueError(einfo)

    if vlist[0] == "required":
        # 第一项不是 required 的,把第一项的 "required" 去掉
        vlist = vlist[1:]
    else:
        # 第一项不是 required 的,如果 arg 是空的,直接返回 True,不是的继续验证
        if not arg:
            return True, None

    # 待返回的验证结果
    verification = None
    failed_type = None        # 验证失败的类型

    # 开始检查,有一个不通过就返回 False
    for i in vlist:
        local_verification = None
        if isinstance(i, str):  # 如果是字符串的话就改为元组
            i = (i, {})

        if len(i) == 1:         # 只有一个元素的,添加一个空字典
            i = (i[0], {})

        vtype = i[0]        # 检查类型是第一项
        vdict = i[1]        # 检查类型所需的可选参数字典

        # 在 validators 之外添加的
        # 没有空白
        if vtype == "no_space":
            if not re.search(r"\s", arg):
                local_verification = True
        # 安全字符串,只包含 0-9a-zA-Z-空格和下划线
        elif vtype == "safe_str":
            if re.match(r"^[0-9a-zA-Z-_ ]+$", arg, flags=re.U):
                local_verification = True

        # 是否包含
        elif vtype == "in":
            # 迭代 vdict 的键值(所以键名无所谓)
            for v in vdict.values():
                if arg not in v:
                    local_verification = False
                    break
        elif vtype == "not_in":
            # 迭代 vdict 的键值(所以键名无所谓)
            for v in vdict.values():
                if arg in v:
                    local_verification = False
                    break

        # 字符串形式的数字
        elif vtype == "str_number":
            if re.match(r"[+-]?\d+$", arg, flags=re.U) or \
                    re.match(r"[+-]?\d+\.\d+$", arg, flags=re.U):
                local_verification = True
        elif vtype == "str_int":
            if re.match(r"[+-]?\d+$", arg, flags=re.U):
                local_verification = True
        elif vtype == "str_float":
            if re.match(r"[+-]?\d+\.\d+$", arg, flags=re.U):
                local_verification = True

        # 数字
        elif vtype == "number":     # 整数或浮点数都可以
            local_verification = isinstance(arg, int) or isinstance(arg, float)
        elif vtype == "int":
            local_verification = isinstance(arg, int)
        elif vtype == "float":
            local_verification = isinstance(arg, float)

        # 直接调用 validators的
        elif vtype == "length":
            local_verification = validators.length(arg, **vdict)
        elif vtype == "url":
            local_verification = validators.url(arg, **vdict)
        elif vtype == "email":
            local_verification = validators.email(arg, **vdict)
        elif vtype == "ip":       # ipv4 或 ipv6都可以
            local_verification = any((validators.ipv4(arg, **vdict),
                                      validators.ipv6(arg, **vdict)))
        elif vtype == "between":
            local_verification = validators.between(arg, **vdict)
        elif vtype == "uuid":
            local_verification = validators.uuid(arg, **vdict)
        elif vtype == "ipv4":
            local_verification = validators.ipv4(arg, **vdict)
        elif vtype == "ipv6":
            local_verification = validators.ipv6(arg, **vdict)
        elif vtype == "mac_address":
            local_verification = validators.mac_address(arg, **vdict)
        elif vtype == "iban":
            local_verification = validators.iban(arg, **vdict)
        elif vtype == "slug":
            local_verification = validators.slug(arg, **vdict)
        elif vtype == "truthy":
            local_verification = validators.truthy(arg, **vdict)

        # 对于验证不为真或没有验证的
        # 不为真的时候返回的是: ValidationFailure(......)
        if not local_verification:
            verification = False
            failed_type = vtype
            break                           # 有一条不为 True, 直接返回 False
        else:
            verification = True
    # 处理返回值
    if verification not in(False, True):
        verification = False
    if not verification:
        return verification, failed_type
    else:
        return True, None