跳转到主要内容

PRECIS-i18n:国际化用户名和密码

项目描述

PRECIS-i18n:国际化用户名和密码

MIT licensed Build Status codecov.io

如果您希望您的应用程序接受Unicode用户名和密码,您必须小心地验证和比较它们。PRECIS框架使应用程序使用国际化用户名和密码更加安全。PRECIS配置文件将Unicode字符串转换为规范形式,适合比较。

本模块实现了如下所述的PRECIS框架:

  • PRECIS框架:应用程序协议中国际化字符串的准备、实施和比较(《RFC 8264》)
  • 表示用户名和密码的国际化字符串的准备、实施和比较(《RFC 8265》)
  • 表示昵称的国际化字符串的准备、实施和比较(《RFC 8266》)

需要Python 3.5或更高版本。

用法

使用get_profile函数获取配置文件对象,然后使用其enforce方法。该方法返回一个Unicode字符串。

>>> from precis_i18n import get_profile
>>> username = get_profile('UsernameCaseMapped')
>>> username.enforce('Kevin')
'kevin'
>>> username.enforce('\u212Aevin')
'kevin'
>>> username.enforce('\uFF2Bevin')
'kevin'
>>> username.enforce('\U0001F17Aevin')
Traceback (most recent call last):
  ...
UnicodeEncodeError: 'UsernameCaseMapped' codec can't encode character '\U0001f17a' in position 0: DISALLOWED/symbols

或者,您可以使用Python的str.encode API。导入precis_i18n.codec模块以注册PRECIS编解码器名称。现在您可以使用任何Unicode字符串的str.encode方法。结果将是一个UTF-8编码的字节字符串,或者如果字符串不被允许,则返回一个UnicodeEncodeError

>>> import precis_i18n.codec
>>> 'Kevin'.encode('UsernameCasePreserved')
b'Kevin'
>>> '\u212Aevin'.encode('UsernameCasePreserved')
b'Kevin'
>>> '\uFF2Bevin'.encode('UsernameCasePreserved')
b'Kevin'
>>> '\u212Aevin'.encode('UsernameCaseMapped')
b'kevin'
>>> '\uFF2Bevin'.encode('OpaqueString')
b'\xef\xbc\xabevin'
>>> '\U0001F17Aevin'.encode('UsernameCasePreserved')
Traceback (most recent call last):
  ...
UnicodeEncodeError: 'UsernameCasePreserved' codec can't encode character '\U0001f17a' in position 0: DISALLOWED/symbols

其他Unicode版本

《get_profile》函数使用由Python运行时提供的任何版本的unicodedata。Unicode版本通常与Python运行时的主版本相关联。Python 3.7.x使用Unicode 11.0。Python 3.6.x使用Unicode 10.0。

要使用替代的unicodedata实现,请将unicodedata关键字参数传递给get_profile

例如,您可以从PyPI单独安装unicodedata2模块的12.0版本。然后,将其传递给get_profile以检索使用Unicode 12.0的配置文件。

>>> import unicodedata2
>>> from precis_i18n import get_profile
>>> username = get_profile('UsernameCaseMapped', unicodedata=unicodedata2)
>>> username.enforce('Kevin')
'kevin'

支持的配置文件和编解码器

每个PRECIS配置文件都有一个相应的编解码器名称。《CaseMapped》变体将字符串转换为小写以实现不区分大小写的比较。

  • UsernameCasePreserved
  • UsernameCaseMapped
  • OpaqueString
  • NicknameCasePreserved
  • NicknameCaseMapped

《CaseMapped》配置文件根据最新的RFC使用Unicode ToLower。此包的早期版本使用Unicode默认大小写折叠。存在不同大小写转换的CaseMapped变体。这些配置文件名称已弃用

  • UsernameCaseMapped:ToLower
  • UsernameCaseMapped:CaseFold
  • NicknameCaseMapped:ToLower
  • NicknameCaseMapped:CaseFold

PRECIS基本字符串类也作为编解码器提供

  • IdentifierClass
  • FreeFormClass

用户部分和空格分隔的用户名

在此实现中,用户名配置文件不允许空格。用户名配置文件对应于RFC 8265中“用户部分”的定义。如果您想允许应用程序的用户名中包含空格,则必须先拆分字符串。

def enforce_app_username(name):
    profile = precis_i18n.get_profile('UsernameCasePreserved')
    userparts = [profile.enforce(userpart) for userpart in name.split(' ')]
    return ' '.join(userparts)

请注意,以这种方式构建的用户名可以在单独的用户部分中包含双向文本。

错误信息

如果字符串不被允许,PRECIS配置文件将引发UnicodeEncodeError异常。`reason`字段指定了错误类型。

原因 说明
DISALLOWED/arabic_indic 阿拉伯-印度数字不能与扩展阿拉伯-印度数字混合。(上下文)
DISALLOWED/bidi_rule 由于“Bidi”规则,右到左的字符串不能包含左到右的字符。(上下文)
DISALLOWED/controls 不允许控制字符。
DISALLOWED/empty 应用配置文件后,结果不能为空。
DISALLOWED/exceptions 不允许异常字符。
DISALLOWED/extended_arabic_indic 扩展阿拉伯-印度数字不能与阿拉伯-印度数字混合。(上下文)
DISALLOWED/greek_keraia 希腊keraia必须后跟希腊字符。(上下文)
DISALLOWED/has_compat 不允许兼容字符。
DISALLOWED/hebrew_punctuation 希伯来标点符号geresh或gershayim必须由希伯来字符先导。(上下文)
DISALLOWED/katakana_middle_dot katakana 中间点必须与平假名、片假名或汉字字符一起出现。(上下文)
DISALLOWED/middle_dot 中间点必须被字母 'l' 包围。(上下文)
DISALLOWED/not_idempotent 重新应用配置文件后,结果不稳定。
DISALLOWED/old_hangul_jamo 不允许结合韩文Jamo。
DISALLOWED/other 不允许其他字符。
DISALLOWED/other_letter_digits 不允许非传统字母或数字。
DISALLOWED/precis_ignorable_properties 不允许默认可忽略或非字符。
DISALLOWED/punctuation 不允许非ASCII标点字符。
DISALLOWED/spaces 不允许空格字符。
DISALLOWED/symbols 不允许非ASCII符号字符。
DISALLOWED/unassigned 不允许未分配的Unicode字符。
DISALLOWED/zero_width_joiner 零宽连接符必须紧接在结合virama之后。(上下文)
DISALLOWED/zero_width_nonjoiner 零宽非连接符必须紧接在结合virama之后,或出现在它打破正式草书脚本中的草书连接处。(上下文)

昵称配置文件和空白

当 PRECIS 使用 Nickname 配置处理字符串时,其中一个强制执行步骤会静默地删除前导和尾随空白。从版本 1.1 开始,这个库在 Nickname 配置中使用了更 严格的 空白 定义。

  • 1.1 及以后版本仅包括 Unicode 类别 Zs。如果您尝试强制执行包含空白字符(如 '\n')的昵称,您将收到 UnicodeEncodeError DISALLOWED/controls
  • 1.0.5 及更早版本在删除昵称的前导/尾随空白时包括控制字符,如 '\n''\t''\r'。结果将这些遗留的空白字符视为与 Zs 相同并删除它们。
  • 在所有版本中,内部 空白(非前导或尾随)仅与 Unicode 类别 Zs 匹配。

空白修剪仅针对昵称配置。以下是一个当前行为的示例

>>> from precis_i18n import get_profile
>>> nickname = get_profile('NicknameCaseMapped')
>>> nickname.enforce('Kevin\n')
Traceback (most recent call last):
  ...
UnicodeEncodeError: 'NicknameCaseMapped' codec can't encode character '\x0a' in position 5: DISALLOWED/controls

在版本 1.0.5 及更早版本中,NicknameCaseMapped 配置将 "Kevin\n" 强制为 "kevin"

Unicode 版本更新程序

当 Unicode 发布新版本时,采取以下步骤更新内部表并通过单元测试

  • 在支持新 Unicode 版本的 Python 版本下运行测试,使用 python -m unittest discover 并检查 test_derived_props 测试由于缺少文件而失败。
  • 通过运行 PYTHONPATH=. python test/test_derived_props.py > derived-props-VERSION.txt 生成新的 derived-props 文件。使用 Unicode 版本重命名文件,并重新运行测试。单元测试将进一步检查新文件中的派生属性是否与先前值冲突。
  • 通过运行 PYTHONPATH=. python tools/check_codepoints.py 检查用于上下文规则的内部表的更改。如有必要,更新 precis_i18n/unicode.py 中的相应表。

项目详情


下载文件

下载您平台上的文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。

源分布

precis_i18n-1.1.0.tar.gz (69.5 kB 查看哈希值)

上传

构建分布

precis_i18n-1.1.0-py3-none-any.whl (27.6 kB 查看哈希值)

上传 Python 3

支持者