PRECIS-i18n:国际化用户名和密码
项目描述
PRECIS-i18n:国际化用户名和密码
如果您希望您的应用程序接受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'
)的昵称,您将收到 UnicodeEncodeErrorDISALLOWED/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 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 7ad0d9e08b806f3a9aba042f0b5b28f081fe6decf1dd95ec8e4dc8c6b302aec2 |
|
MD5 | 1faee59bb311dc7e7ea5c0a1bfb077fe |
|
BLAKE2b-256 | acbc189db10d33239407f753a9551cc3c113e00062be8c85d1f76cebaeb4f292 |