import logging import random from ast import literal_eval from collections import defaultdict from dateutil.relativedelta import relativedelta from datetime import datetime, timedelta from odoo import api, fields, models, _ from odoo.exceptions import UserError from odoo.osv import expression from odoo.tools.misc import ustr from odoo.addons.base.models.ir_mail_server import MailDeliveryException from odoo.addons.auth_signup.models.res_partner import SignupError, now _logger = logging.getLogger(__name__) class ResUsers(models.Model): _inherit = 'res.users' def random_token(self): # the token has an entropy of about 120 bits (6 bits/char * 20 chars) chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' return ''.join(random.SystemRandom().choice(chars) for _ in range(20)) @api.model def signup(self, values, token=None): """ signup a user, to either: - create a new user (no token), or - create a user for a partner (with token, but no user for partner), or - change the password of a user (with token, and existing user). :param values: a dictionary with field values that are written on user :param token: signup token (optional) :return: (dbname, login, password) for the signed up user """ #recherche si un contact existe avec l'adresse email saisie #on ignore les majsucule : operateur ilike partner_email=self.env['res.partner'].sudo().search([('email','ilike',values.get('login'))],limit=1) #_logger.error("partner_email:"+str(partner_email.email)) #si le contact existe déjà on vérifie s'il existe déjà un compte utilisateur if partner_email: user_email=self.env['res.users'].sudo().search([('partner_id','=',int(partner_email.id))],limit=1) #si un compte utilisateur existe déjà avec l'adresse email,on ne crer pas le compte mais on fait la connexion if user_email: return (self.env.cr.dbname, values.get('login'), values.get('password')) #si pas de compte utilisateur on crée un token pour le contact trouvé else: partner_email.signup_type='signup' partner_email.signup_token=self.random_token() partner_email.signup_expiration=datetime.today()+timedelta(days=1) token=partner_email.signup_token if token: # signup with a token: find the corresponding partner id partner = self.env['res.partner']._signup_retrieve_partner(token, check_validity=True, raise_exception=True) # invalidate signup token partner.write({'signup_token': False, 'signup_type': False, 'signup_expiration': False}) partner_user = partner.user_ids and partner.user_ids[0] or False # avoid overwriting existing (presumably correct) values with geolocation data if partner.country_id or partner.zip or partner.city: values.pop('city', None) values.pop('country_id', None) if partner.lang: values.pop('lang', None) if partner_user: _logger.error("user exists, modify it according to values"+str(partner.email)) # user exists, modify it according to values values.pop('login', None) values.pop('name', None) partner_user.write(values) if not partner_user.login_date: partner_user._notify_inviter() return (self.env.cr.dbname, partner_user.login, values.get('password')) else: _logger.error("user does not exist: sign up invited user") # user does not exist: sign up invited user values.update({ 'name': partner.name, 'partner_id': partner.id, 'email': values.get('email') or values.get('login'), }) if partner.company_id: values['company_id'] = partner.company_id.id values['company_ids'] = [(6, 0, [partner.company_id.id])] partner_user = self._signup_create_user(values) partner_user._notify_inviter() else: # no token, sign up an external user values['email'] = values.get('email') or values.get('login') self._signup_create_user(values) return (self.env.cr.dbname, values.get('login'), values.get('password'))