odoo的密码机制

有时我们知道数据库中的密码,但是却不知道加密之前的密码,一个一个试又浪费时间,如何通过脚本批量测试? 以下从设置密码开始逐步分析:

设置密码:

调用的是 base模块中res_users文件中的 

_set_password函数,通过sha512算法加密,如下所示:
DEFAULT_CRYPT_CONTEXT = passlib.context.CryptContext(
    # kdf which can be verified by the context. The default encryption kdf is
    # the first of the list
    ['pbkdf2_sha512', 'plaintext'],
    # deprecated algorithms are still verified as usual, but ``needs_update``
    # will indicate that the stored hash should be replaced by a more recent
    # algorithm. Passlib 1.6 supports an `auto` value which deprecates any
    # algorithm but the default, but Ubuntu LTS only provides 1.5 so far.
    deprecated=['plaintext'],
)

对于同一个密码,该算法每次加密出来的结果都不一致。

登录机制:

最终调用的也是 base模块中 res_users文件中的_check_credentials方法:

    def _check_credentials(self, password):
        assert password
        self.env.cr.execute(
            "SELECT COALESCE(password, '') FROM res_users WHERE id=%s",
            [self.env.user.id]
        )
        [hashed] = self.env.cr.fetchone()
        valid, replacement = self._crypt_context()\
            .verify_and_update(password, hashed)
        if replacement is not None:
            self._set_encrypted_password(self.env.user.id, replacement)
        if not valid:
            raise AccessDenied()

该方法会查出当前用户名的在数据库中加密之后的密码,然后再调用 passlib模块中的方法验证密码,使用的对象和设置密码的对象是同一个对象,self._crypt_context().verify_and_update(password, hashed)。

self._crypt_contect()就是上述中的DEFAULT_CRYPT_CONTEXT对象。

综上所述:

如果出现密码忘记的情况,可以将数据库中的hash值取出来,循环调用 verify_and_update方法验证多个可能的密码

创建验证密码的脚本:


from passlib.context import CryptContext
DEFAULT_CRYPT_CONTEXT = CryptContext(
    # kdf which can be verified by the context. The default encryption kdf is
    # the first of the list
    ['pbkdf2_sha512', 'plaintext'],
    # deprecated algorithms are still verified as usual, but ``needs_update``
    # will indicate that the stored hash should be replaced by a more recent
    # algorithm. Passlib 1.6 supports an `auto` value which deprecates any
    # algorithm but the default, but Ubuntu LTS only provides 1.5 so far.
    deprecated=['plaintext'],
)
k='''
$pbkdf2-sha512$25000$HsNYi/Heu7e21hqjNMa4Vw$LqnIuUp18/uz/Vxa1Fp/nLItrJle/14ZYUizvK5npMe1X8.QEyEp/ovq6dlX3aKwz9nHMAB07B6sVz4G9U934Q
$pbkdf2-sha512$25000$915rLSXkHGPs/d/7v/e.Vw$zlPOYR8JACpkDla4.M4BmIsViDUXrHEIn9nlK/ew9jGlJzLUTYVmZ3xtgPP5mJyWYQP2o/AwcALOWaA89Ws1zw
'''

password_list = k.split('\n')
for password in password_list:
    print(DEFAULT_CRYPT_CONTEXT.verify_and_update('xxx',password),password)

打印结果:

odoo的密码机制_第1张图片

其中 password_list 为 数据库中取出来的密码加密列表

如果 打印结果为 true则表示 数据库中的加密是由 密码 xxx加密而来

你可能感兴趣的:(odoo小知识点,python,postgresql)