From 9a17595158060676479c7809b0bd0b6b83a1fa2b Mon Sep 17 00:00:00 2001 From: Kinjal Mehta Date: Mon, 10 Aug 2015 14:52:16 +0530 Subject: [PATCH 1/2] [REF] auth_crypt: move files in models directory --- addons/auth_crypt/__init__.py | 4 ++-- addons/auth_crypt/models/__init__.py | 3 +++ addons/auth_crypt/{auth_crypt.py => models/res_users.py} | 0 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 addons/auth_crypt/models/__init__.py rename addons/auth_crypt/{auth_crypt.py => models/res_users.py} (100%) diff --git a/addons/auth_crypt/__init__.py b/addons/auth_crypt/__init__.py index 11f3889e8a8..c7b5ac7e1f2 100644 --- a/addons/auth_crypt/__init__.py +++ b/addons/auth_crypt/__init__.py @@ -1,3 +1,3 @@ -# Part of Odoo. See LICENSE file for full copyright and licensing details. +# -*- coding: utf-8 -*- -import auth_crypt +import models diff --git a/addons/auth_crypt/models/__init__.py b/addons/auth_crypt/models/__init__.py new file mode 100644 index 00000000000..ab149929a18 --- /dev/null +++ b/addons/auth_crypt/models/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +import res_users diff --git a/addons/auth_crypt/auth_crypt.py b/addons/auth_crypt/models/res_users.py similarity index 100% rename from addons/auth_crypt/auth_crypt.py rename to addons/auth_crypt/models/res_users.py From 4915cd52e7095c6bc959336909d6e83266baee70 Mon Sep 17 00:00:00 2001 From: Kinjal Mehta Date: Mon, 10 Aug 2015 15:33:20 +0530 Subject: [PATCH 2/2] [MIG] auth_crypt: migrate into new api --- addons/auth_crypt/__init__.py | 2 +- addons/auth_crypt/__openerp__.py | 7 +-- addons/auth_crypt/models/res_users.py | 85 ++++++++++++++------------- 3 files changed, 47 insertions(+), 47 deletions(-) diff --git a/addons/auth_crypt/__init__.py b/addons/auth_crypt/__init__.py index c7b5ac7e1f2..48f417bbd93 100644 --- a/addons/auth_crypt/__init__.py +++ b/addons/auth_crypt/__init__.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- - +# Part of Odoo. See LICENSE file for full copyright and licensing details. import models diff --git a/addons/auth_crypt/__openerp__.py b/addons/auth_crypt/__openerp__.py index 3f28640ba19..9236fc18f1d 100644 --- a/addons/auth_crypt/__openerp__.py +++ b/addons/auth_crypt/__openerp__.py @@ -1,10 +1,11 @@ -# -*- encoding: utf-8 -*- +# -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. + { 'name': 'Password Encryption', 'version': '2.0', 'author': ['Odoo SA', 'FS3'], - 'maintainer': 'OpenERP SA', + 'maintainer': 'Odoo SA', 'category': 'Tools', 'description': """ Encrypted passwords @@ -34,7 +35,5 @@ necessarily have to be enabled). """, 'depends': ['base'], - 'data': [], 'auto_install': True, - 'installable': True, } diff --git a/addons/auth_crypt/models/res_users.py b/addons/auth_crypt/models/res_users.py index 7c9d0c5fa2c..708998acbde 100644 --- a/addons/auth_crypt/models/res_users.py +++ b/addons/auth_crypt/models/res_users.py @@ -1,11 +1,12 @@ -import logging +# -*- coding: utf-8 -*- +import logging from passlib.context import CryptContext -import openerp -from openerp.osv import fields, osv +import odoo +from odoo import api, fields, models -from openerp.addons.base.res import res_users +from odoo.addons.base.res import res_users res_users.USER_PRIVATE_FIELDS.append('password_crypt') _logger = logging.getLogger(__name__) @@ -21,72 +22,72 @@ default_crypt_context = CryptContext( deprecated=['md5_crypt'], ) -class res_users(osv.osv): + +class ResUsers(models.Model): _inherit = "res.users" - def init(self, cr): + def init(self): _logger.info("Hashing passwords, may be slow for databases with many users...") - cr.execute("SELECT id, password FROM res_users" + self.env.cr.execute("SELECT id, password FROM res_users" " WHERE password IS NOT NULL" " AND password != ''") - for uid, pwd in cr.fetchall(): - self._set_password(cr, openerp.SUPERUSER_ID, uid, pwd) + for uid, pwd in self.env.cr.fetchall(): + self.sudo().browse(uid)._set_password(pwd) - def set_pw(self, cr, uid, id, name, value, args, context): - if value: - self._set_password(cr, uid, id, value, context=context) - self.invalidate_cache(cr, uid, context=context) + password = fields.Char(compute='_compute_password', inverse='_inverse_password', invisible=True, store=True) + password_crypt = fields.Char(string='Encrypted Password', invisible=True, copy=False) - def get_pw( self, cr, uid, ids, name, args, context ): - cr.execute('select id, password from res_users where id in %s', (tuple(map(int, ids)),)) - return dict(cr.fetchall()) + def _compute_password(self): + self.env.cr.execute('SELECT id, password FROM res_users WHERE id IN %s', [tuple(self.ids)]) + password_dict = dict(self.env.cr.fetchall()) + for user in self: + user.password = password_dict[user.id] - _columns = { - 'password': fields.function(get_pw, fnct_inv=set_pw, type='char', string='Password', invisible=True, store=True), - 'password_crypt': fields.char(string='Encrypted Password', invisible=True, copy=False), - } + def _inverse_password(self): + for user in self: + user._set_password(user.password) + self.invalidate_cache() - def check_credentials(self, cr, uid, password): + @api.model + def check_credentials(self, password): # convert to base_crypt if needed - cr.execute('SELECT password, password_crypt FROM res_users WHERE id=%s AND active', (uid,)) + self.env.cr.execute('SELECT password, password_crypt FROM res_users WHERE id=%s AND active', (self.env.uid,)) encrypted = None - if cr.rowcount: - stored, encrypted = cr.fetchone() + user = self.env.user + if self.env.cr.rowcount: + stored, encrypted = self.env.cr.fetchone() if stored and not encrypted: - self._set_password(cr, uid, uid, stored) - self.invalidate_cache(cr, uid) + user._set_password(stored) + self.invalidate_cache() try: - return super(res_users, self).check_credentials(cr, uid, password) - except openerp.exceptions.AccessDenied: + return super(ResUsers, self).check_credentials(password) + except odoo.exceptions.AccessDenied: if encrypted: - valid_pass, replacement = self._crypt_context(cr, uid, uid)\ + valid_pass, replacement = user._crypt_context()\ .verify_and_update(password, encrypted) if replacement is not None: - self._set_encrypted_password(cr, uid, uid, replacement) + user._set_encrypted_password(replacement) if valid_pass: return - raise - def _set_password(self, cr, uid, id, password, context=None): + def _set_password(self, password): + self.ensure_one() """ Encrypts then stores the provided plaintext password for the user - ``id`` + ``self`` """ - encrypted = self._crypt_context(cr, uid, id, context=context).encrypt(password) - self._set_encrypted_password(cr, uid, id, encrypted, context=context) + encrypted = self._crypt_context().encrypt(password) + self._set_encrypted_password(encrypted) - def _set_encrypted_password(self, cr, uid, id, encrypted, context=None): + def _set_encrypted_password(self, encrypted): """ Store the provided encrypted password to the database, and clears any plaintext password - - :param uid: id of the current user - :param id: id of the user on which the password should be set """ - cr.execute( + self.env.cr.execute( "UPDATE res_users SET password='', password_crypt=%s WHERE id=%s", - (encrypted, id)) + (encrypted, self.id)) - def _crypt_context(self, cr, uid, id, context=None): + def _crypt_context(self): """ Passlib CryptContext instance used to encrypt and verify passwords. Can be overridden if technical, legal or political matters require different kdfs than the provided default.