def authenticate(cls, email, password): pool = Pool() Attempt = pool.get('web.user.authenticate.attempt') email = email.lower() count_ip = Attempt.count_ip() if count_ip > config.getint( 'session', 'max_attempt_ip_network', default=300): # Do not add attempt as the goal is to prevent flooding raise RateLimitException() count = Attempt.count(email) if count > config.getint('session', 'max_attempt', default=5): Attempt.add(email) raise RateLimitException() # Prevent brute force attack Transaction().atexit(time.sleep, 2 ** count - 1) users = cls.search([('email', '=', email)]) if users: user, = users valid, new_hash = cls.check_password(password, user.password_hash) if valid: if new_hash: logger.info("Update password hash for %s", user.id) with Transaction().new_transaction() as transaction: with transaction.set_user(0): cls.write([cls(user.id)], { 'password_hash': new_hash, }) Attempt.remove(email) return user Attempt.add(email)
def get_login(cls, login, parameters): ''' Return user id if password matches ''' LoginAttempt = Pool().get('res.user.login.attempt') count_ip = LoginAttempt.count_ip() if count_ip > config.getint( 'session', 'max_attempt_ip_network', default=300): # Do not add attempt as the goal is to prevent flooding raise RateLimitException() count = LoginAttempt.count(login) if count > config.getint('session', 'max_attempt', default=5): LoginAttempt.add(login) raise RateLimitException() Transaction().atexit(time.sleep, random.randint(0, 2 ** count - 1)) for methods in config.get( 'session', 'authentications', default='password').split(','): user_ids = set() for method in methods.split('+'): try: func = getattr(cls, '_login_%s' % method) except AttributeError: logger.info('Missing login method: %s', method) break user_ids.add(func(login, parameters)) if len(user_ids) != 1 or not all(user_ids): break if len(user_ids) == 1 and all(user_ids): LoginAttempt.remove(login) return user_ids.pop() LoginAttempt.add(login)
def get_login(cls, login, parameters): ''' Return user id if password matches ''' pool = Pool() LoginAttempt = pool.get('res.user.login.attempt') UserDevice = pool.get('res.user.device') parameters = parameters.copy() count_ip = LoginAttempt.count_ip() if count_ip > config.getint( 'session', 'max_attempt_ip_network', default=300): # Do not add attempt as the goal is to prevent flooding raise RateLimitException() device_cookie = UserDevice.get_valid_cookie( login, parameters.get('device_cookie')) parameters['device_cookie'] = device_cookie count = LoginAttempt.count(login, device_cookie) if count > config.getint('session', 'max_attempt', default=5): LoginAttempt.add(login, device_cookie) raise RateLimitException() Transaction().atexit(time.sleep, random.randint(0, 2**count - 1)) for methods in config.get('session', 'authentications', default='password').split(','): user_ids = set() for method in methods.split('+'): if user_ids: try: method, options = method.split('?', 1) except ValueError: options = [] else: options = options.split(':') if cls._check_login_options(options, login, parameters): continue try: func = getattr(cls, '_login_%s' % method) except AttributeError: logger.info('Missing login method: %s', method) break user_ids.add(func(login, parameters)) if len(user_ids) != 1 or not all(user_ids): break if len(user_ids) == 1 and all(user_ids): LoginAttempt.remove(login, device_cookie) return user_ids.pop() LoginAttempt.add(login, device_cookie)