def reset_password(self, email, reset_code, new_password):
     """
     Reset password with the reset code
     """
     result = None
     try:
         existed_reset = self._database['resetpassword'].find_one({'email': email,'reset_code':reset_code})
         if existed_reset:
             created_day = existed_reset['created_date']
             delta = datetime.datetime.utcnow() - created_day
             if delta.total_seconds() < RESET_PASSWORD_EXPIRED_TIME:
                 salt = random_string_generator()
                 password_hash = hash_password_salt(new_password, salt)
                 user = self.exist_email(email)
                 username = user['username']
                 result = self._auth_collection.update({'username': username,}, 
                                                                       {'$set':{'salt':salt, 'password': password_hash}},
                                                                       safe=True, 
                                                                       multi=False)                    
             else:
                 result = None
             """mongodb will delete old reset code for us"""
             self._database['resetpassword'].remove({'email': email,})
     except pymongo.errors.AutoReconnect:
         logger.error("Auto reconnect")
     except:
         logger.error("Unexpected Error: " + traceback.format_exc())            
     return result                
 def authenticate_email(self, email, password):
     """
     Authenticate with username and password
     """
     result = False
     user = self.exist_email(email)
     if user:
         salt = user['salt']
         if user['password'] == hash_password_salt(password, salt):
             result = user
     return result
 def authenticate_user(self, username, password):
     """
     Authenticate with username and password
     """
     result = False
     user = self.exist_user(username)
     if user:
         salt = user['salt']
         if user['password'] == hash_password_salt(password, salt):
             result = True
     return result
 def create_user(self, username, password, email, phone=None):
     """
     Create an user in authentication database. Username or email is unique in the collection.
     """
     result = None
     username = username.lower()
     try:
         """salt for password's hash"""
         salt = random_string_generator()
         """password's hash"""
         password_hash = hash_password_salt(password, salt)
         """encrypt email with AES"""
         encryption_iv = Random.new().read(AES.block_size)
         cipher = AES.new(ENCRYPTION_AES_KEY, AES.MODE_CFB, encryption_iv)
         encrypted_email_string = ''.join([encryption_iv,cipher.encrypt(email)])
         encrypted_email_base64 = base64.b64encode(encrypted_email_string)            
         hash_email = hashlib.md5('{}{}'.format(email,SECRET_SALT)).hexdigest()
         """encrypt phone with AES"""
         encrypted_phone_base64 = None
         hash_phone = None
         if phone:
             encryption_iv = Random.new().read(AES.block_size)
             cipher = AES.new(ENCRYPTION_AES_KEY, AES.MODE_CFB, encryption_iv)
             encrypted_phone_string = ''.join([encryption_iv,cipher.encrypt(phone)])
             encrypted_phone_base64 = base64.b64encode(encrypted_phone_string)
             hash_phone = hashlib.md5('{}{}'.format(phone,SECRET_SALT)).hexdigest()
         _newuser = {'username': username, 
                     'password': password_hash,
                     'salt': salt,
                     'email': encrypted_email_base64,
                     'hash_email': hash_email,
                     'phone': encrypted_phone_base64,
                     'hash_phone': hash_phone,
                     'verified': False,
                     }
         result = self._auth_collection.insert(_newuser, safe=True)
     except pymongo.errors.DuplicateKeyError:
         logger.error("Duplicate username or email.")
     except pymongo.errors.AutoReconnect:
         logger.error("Auto reconnect.")
     except:
         logger.error("Unexpected Error.")
         #raise
     """if result:
         if not verification_code:
             verification_code = random_string_generator(12)
         verified = self.create_email_verification_code(verification_code, username)
         if not verified:
             logger.error('Cannot create verification code.')"""        
     return result
 def change_password(self, username, old_password, new_password):
     """
     Change current password to new password
     """
     result = None
     try:
         if self.authenticate_user(username, old_password):
             salt = random_string_generator()
             password_hash = hash_password_salt(new_password, salt)
             result = self._auth_collection.update({'username': username,}, 
                                                                   {'$set':{'salt':salt, 'password': password_hash}},
                                                                   safe=True, 
                                                                   multi=False)
     except pymongo.errors.AutoReconnect:
         logger.error("Auto reconnect")
     except:
         logger.error("Unexpected Error: " + traceback.format_exc())            
     return result