def __has_reached_max_unver_testmins(account_id, testmin):
    '''
        @description:
            - returns True if the user enrolled 
            unverified testmin more than the 
            allowed (per day), else False
            - updates array of 
    '''
    testmin = '639%s' % str(testmin[-9:])

    unver_req = Verification.get_code_unverified_requests(account_id)

    if not unver_req:
        # return False and create redis list
        # (for counting and comparison)
        unverified_mob_list = [testmin]
        Verification.set_code_unverified_requests(account_id,
                                                  unverified_mob_list)
        return False

    unver_req = loads(unver_req)

    if unver_req and len(unver_req) >= MAX_CODE_REQUEST and \
        testmin not in unver_req:
        return True

    if testmin not in unver_req:
        unver_req.append(testmin)
        Verification.set_code_unverified_requests(account_id, unver_req)

    return False
 def test_push_email_to_queue(self):
     '''
     test if emails are pushed to the queue in FIFO manner 
     '''
     
     for x in range( 3 ):
         Verification.add_email_to_reg_queue( email='kirby@kirby-agudelo%s.net'%x )
def send_mt_message(account_id, suffix, testmin, mt_message, client_id, secret_key):
    '''
        uses API to send MT message
        to user
    '''
    
    gen_logger = sms_api_logger.GeneralLogger() 
        
    if not mt_message:
        message_id = send_trial_mt(suffix, testmin, 
            SENT_TRIAL_MESSAGE % DEFAULT_MESSAGE,
            client_id, secret_key)
    elif len(mt_message) > MESSAGE_LEN:
        message_id = None
    else:
        message_id = send_trial_mt(suffix,
            testmin, SENT_TRIAL_MESSAGE % mt_message,
            client_id, secret_key)
        
    gen_logger.info('Hitting API to sending MT message', 
        {'account_id': account_id, 'mobile': testmin, 'suffix': suffix, 'message_id': message_id})
            
    Verification.set_message_sent_to_pending(
        testmin[-12:], message_id)
    
    return message_id
def process_testmin_code_verification(suffix, account_id, testmin, code):
    '''
        @description:
            - handles testmin code verificition
    '''

    gen_logger = sms_api_logger.GeneralLogger()

    testmin = '639%s' % str(testmin[-9:])

    correct_code = __get_vercode(account_id, testmin)

    if not __is_code_correct(correct_code, code):
        gen_logger.error(
            'testmin enrollment -- incorrect pincode', {
                'account_id': account_id,
                'mobile': testmin,
                'code': code,
                'suffix': suffix
            })

        raise WrongCodeException(account_id, testmin, code)

    if __is_code_expired (correct_code) and \
        __has_reached_max_code_request(account_id, testmin):

        gen_logger.error(
            'testmin enrollment -- expired pincode, max code requests', {
                'account_id': account_id,
                'mobile': testmin,
                'code': code,
                'suffix': suffix
            })

        raise ExpiredCodeMaxCodeRequestException(account_id, testmin, code)
    if __is_code_expired(correct_code):

        gen_logger.error(
            'testmin enrollment -- expired pincode', {
                'account_id': account_id,
                'mobile': testmin,
                'code': code,
                'suffix': suffix
            })

        raise ExpiredCodeException(account_id, testmin, code)

    __save_testmin(account_id, testmin)
    ContentProviders.update_cached_api_min(suffix, testmin)

    Verification.delete_mobile_code(account_id, testmin)
Beispiel #5
0
def forgot_password_send( email ):
    '''
    @param email: the email of the user to send the password
    executes process for "forgot password" procedure
    
    
    email is sent to email address identified by "email" parameter
    '''
    
    # 1. check if email is invalid or unregistered
    
    
    valid_email_format = email_tool.is_email_format_valid( email )
    if not valid_email_format:
        raise InvalidEmailFormatError()
    
    # check if email is registered 
    account_object = account = Account.get( email=email )
    if account_object is None :
        raise AccountNotExist('account does not exist')
    else :
        if account_object.is_pending() is True :
            raise PendingAccountAlreadyExisting()
        
        
    # verification will now be created
    
    verification_object = Verification.create_new_forgot_password_verification( account_object=account_object )
    
    if verification_object :
        verification_object.add_forgot_password_email_to_queue()
def has_reached_max_wrong_code_tries(account_id, testmin):
    '''
        @description:
            - returns True if user has inputted
            wrong codes more than allowed,
            else False 
            - uses redis incr
    '''

    testmin = '639%s' % str(testmin[-9:])

    code_tries = Verification.incr_code_tries(account_id=account_id,
                                              testmin=testmin)
    # if code_tries and int(code_tries) > MAX_CODE_TRIES:
    gen_logger = sms_api_logger.GeneralLogger()
    gen_logger.info('testmin enrollment -- max pincode retries', {
        'account_id': account_id,
        'mobile': testmin
    })
    # return True
    # return False

    if code_tries:
        return int(code_tries)
    return None
Beispiel #7
0
def is_valid_forget_password_code( code ):
    '''
    checks if code is valid
    @return: Boolean . if code is valid or not (exists in database and is PASSWORD-type verification)
    @raise VerificationExpired: on expired verification 
    
    '''
    
    verification_object = Verification.get_forgot_password_verify_by_code( code=code )
    if verification_object :

        # check if password verification is expired
        
        print 'expiry is', type(verification_object.date_expiry)
        if  verification_object.date_expiry < datetime.now() :
            raise VerificationExpired()
        
        
        return True
    
    
    
    
    else:
        return False
Beispiel #8
0
def change_password_by_code( code, new_password ):
    '''
    resets the password given the verification code
    '''
    
    #check if password is valid
#     if len(new_password) < 8 or len(new_password) > 32 :
#         raise password_tool.InvalidPasswordLength('invalid old password. too short / too long')

    if password_tool.is_valid_password_format( password=new_password ) is not True :
        raise InvalidPasswordFormat('invalid format')


    verification_object = Verification.get_forgot_password_verify_by_code( code=code )
    #print verification_object


    account_object = Account.get( account_id=verification_object.account_id )
    
    if account_object :
        encrypted_new_password = password_tool.encrypt( password=new_password )
        result = account_object.save_new_password( new_password=encrypted_new_password )
        
        if result :
            verification_object.destroy()
            return True


    return False
def set_message_sent_to_success(mobile, message_id):
    
    gen_logger = sms_api_logger.GeneralLogger()    
    try:
        return Verification.set_message_sent_to_success(
            mobile, message_id)
    except Exception, e:
        gen_logger.error('TEST MT sent status to SUCCESS', 
            {'mobile': mobile, 'message_id': message_id})
def __get_vercode(account_id, testmin):
    '''
        @description:
            - returns the verification code
    '''

    testmin = '639%s' % str(testmin[-9:])

    correct_code = Verification.get_mobile_code(account_id=account_id,
                                                testmin=testmin)
    return correct_code
    def create_new_signup_verification(self,
                                       account_id,
                                       email,
                                       code,
                                       resend_code,
                                       expiration_delta=None):
        '''
        writes signup verification to verification table
        
        @param account_id: the account id assigned to the pending user
        @param email: the email used by the registering user
        @param code : String the unique string that will publicly identify the verification
        @param expiration_delta : python timedelta , denotes duration of validity of the verification
        
        
        @author: vincent agudelo
        
        
        '''
        verification_id = None

        new_verification_object = None
        params = {
            'email': email,
            'account_id': account_id,
            'code': code,
            'resend_code': resend_code,
            'category': 'SIGNUP'
        }

        if expiration_delta:
            params['date_expiry'] = (
                datetime.now() +
                expiration_delta).strftime('%Y-%m-%d %H:%M:%S')

        try:

            verification_id = self.__insert_to_database(params)

            new_verification_object = Verification()
            new_verification_object.verification_id = verification_id
            new_verification_object.email = email
            new_verification_object.verification_category = 'SIGNUP'
            new_verification_object.account_id = account_id
            new_verification_object.code = code
            new_verification_object.resend_code = resend_code

        except Exception, e:

            raise VerificationError(
                'could not create verification record: %s' % e)
Beispiel #12
0
def resend_forgot_password_by_code( code ):
    
    verification_object = Verification.get_forgot_password_verify_by_code( code=code )
    
    
    if verification_object :
        
        # step 1 update expiry
        verification_object.update_forgot_password_expiry()
        
        # step 2 add to email queue
        verification_object.add_forgot_password_email_to_queue()
    else :
        raise VerificationError('does not exist')
def __has_reached_max_code_request(account_id, testmin):
    '''
        @description:
            - returns True if user requested 
            code for than the allowed times,
            else False
    '''

    testmin = '639%s' % str(testmin[-9:])

    request_count = Verification.incr_code_request_count(account_id=account_id,
                                                         testmin=testmin)

    if request_count and int(request_count) > (MAX_CODE_REQUEST):
        return True
    return False
    def create_new_change_email_verification(self, account_object, new_email,
                                             code, expiration_delta,
                                             resend_code):

        verification_object = None

        params = {
            'email':
            new_email,
            'account_id':
            account_object.account_id,
            'code':
            code,
            'resend_code':
            resend_code,
            'category':
            self.valid_categories['change_email'],
            'date_expiry':
            (datetime.now() + expiration_delta).strftime('%Y-%m-%d %H:%M:%S')
        }

        try:

            verification_id = self.__insert_to_database(params)

            if verification_id:

                verification_object = Verification()

                verification_object.verification_id = verification_id
                verification_object.email = params['email']
                verification_object.verification_category = params['category']
                verification_object.account_id = params['account_id']
                verification_object.code = params['code']
                verification_object.resend_code = params['resend_code']

        except Exception, e:

            raise VerificationError(
                'could not create verification record: %s' % e)
def __save_code(account_id, code=None, testmin=None, ver_id=None):
    '''
        saves the code generated
        in the Verification table
    '''
    if testmin:
        testmin = '639%s' % str(testmin[-9:])

    gen_logger = sms_api_logger.GeneralLogger()

    try:
        ver_obj = Verification.get_mobile_code(account_id=account_id,
                                               testmin=testmin)

        if ver_obj or ver_id:
            if not ver_id:
                ver_id = ver_obj['id']

            if code:
                Verification.update_mobile_code(account_id=account_id,
                                                code=code,
                                                mobile=testmin,
                                                ver_id=ver_id)
            else:
                Verification.update_mobile_code(account_id=account_id,
                                                mobile=testmin,
                                                ver_id=ver_id)

            gen_logger.info('testmin enrollment -- updating pincode',
                            {'account_id': account_id})

            return ver_obj['id'] if not ver_id else ver_id
        else:

            gen_logger.info('testmin enrollment -- saving pincode', {
                'account_id': account_id,
                'pincode': code
            })

            return Verification.save_mobile_code(account_id=account_id,
                                                 code=code,
                                                 mobile=testmin)

    except DuplicateVerificationCodeException, e:
        gen_logger.info('testmin enrollment -- pincode not unique', {
            'account_id': account_id,
            'error': str(e)
        })
        save_code(account_id, code, testmin)
    def get_verification(self,
                         verification_id=None,
                         code=None,
                         email=None,
                         mobile=None,
                         category=None,
                         account_id=None,
                         resend_code=None):
        '''
        retrieves verification information based on information in given object
        
        '''
        verification_object = None

        criteria = {}

        if verification_id:
            criteria['id'] = verification_id

        if code:
            criteria['code'] = code

        if account_id:
            criteria['account_id'] = account_id

        if category:
            criteria['category'] = category

        if mobile:
            criteria['mobile'] = mobile

        if email:
            criteria['email'] = email

        if resend_code:
            criteria['resend_code'] = resend_code

        if criteria:
            table_cols = [
                'id', 'email', 'account_id', 'code', 'mobile', 'category',
                'date_expiry', 'send_status', 'resend_code'
            ]

            try:
                result = self.dbconn.execute_select(table_name='verification',
                                                    conditions=criteria,
                                                    operator='AND',
                                                    table_cols=table_cols,
                                                    fetchall=False)

            except Exception, e:
                raise VerificationError('unable to retrieve verification: %s' %
                                        e)

            if result:

                verification_object = Verification()

                verification_object.verification_id = result['id']
                verification_object.email = result['email']
                verification_object.account_id = result['account_id']
                verification_object.code = result['code']
                verification_object.resend_code = result['resend_code']

                verification_object.mobile = result['mobile']
                verification_object.verification_category = result['category']

                # magically retured as datetime object
                verification_object.date_expiry = result['date_expiry']
 def test_valid_code(self):
     
     
     invalid_long_code = 'c70a4ef428ca65ee0d8b23fd3a33bf1b'
     Verification.get( code=invalid_long_code )
def get_message_sent_status(mobile, message_id):
    return Verification.get_message_sent_status(
        mobile, message_id)
def get_min(account_id, ver_id):
    min = Verification.get_min(account_id, ver_id)
    if min and 'mobile' in min:
        return min['mobile']
Beispiel #20
0
def register_user(first_name,
                  last_name,
                  email,
                  company_name,
                  address,
                  password,
                  password_again=''):

    # a collector of INLINE errors used for display
    errors = {}

    # for inline error empty input field

    if not email:
        errors['invalid_email'] = SPIELS['gerror']
    if not password:
        errors['invalid_password'] = SPIELS['gerror']
    if not password_again:
        errors['passwords_dont_match'] = SPIELS['gerror']

    l = sms_api_logger.GeneralLogger()
    l.info('start registration sequence', {'email': email})
    #check password
    if 'invalid_password' not in errors and password_tool.is_new_password_valid(
            password) is False:
        l.error('invalid password format')
        errors['invalid_password'] = SPIELS['ierror3']
        # raise password_tool.InvalidPasswordFormat( 'invalid password format' )

    if 'passwords_dont_match' not in errors and password_again:
        # this checking is only used because this function
        # might still be used by others without this param

        if password != password_again:
            l.error('password do not match')
            errors['passwords_dont_match'] = SPIELS['ierror2']

    # check email address if in valid format
    if 'invalid_email' not in errors and not reg_email_tool.is_email_format_valid(
            email):
        l.error('invalid email format')
        errors['invalid_email'] = SPIELS['ierror1']
        # raise reg_email_tool.InvalidEmailFormatError( )

    # this serves as input checking.
    # if error dict has content, display inline error
    # messages to user

    if errors:
        return errors

    encrypted_password = password_tool.encrypt(password)

    result = False

    new_user_account = Account()

    new_user_account.first_name = first_name
    new_user_account.last_name = last_name
    new_user_account.email = email

    new_user_account.company = company_name
    new_user_account.address = address
    new_user_account.password = encrypted_password

    # if duplicate email exists in database
    # check if that is pending or active
    # raise respective error

    try:
        pending_created = new_user_account.create_pending_account()

        if pending_created:
            l.info('pending user created', {
                'email': email,
                'account id': new_user_account.account_id
            })
            try:

                verifi_object = Verification.create_new_signup_verification(
                    new_user_account.account_id, new_user_account.email)

                if verifi_object:
                    l.info('sending verification to email queue', {
                        'code': verifi_object.code,
                        'email': verifi_object.email
                    })

                    verifi_object.add_email_to_reg_queue()

            except Exception, e:
                l.error('could not save pending user', e)
                # most likely the verification was not save
                # delete pending user and ask user to create again
                new_user_account.delete_if_pending()
                raise AccountSaveException(
                    'unable to save verification object: %s. pending user id=%s deleted'
                    % (e, new_user_account.account_id))

            result = True

    except DuplicateEmailException, e:

        # the same email exists in database
        # no more INSERT will execute from here
        #
        # check what user that is
        suspected_account = Account.get_raw_info(email=email)

        if suspected_account.is_active():
            #print 'suspected account is currently active'
            l.error('trying to register email of current active account')
            raise ActiveAccountAlreadyExisting(
                '%s is an active account; id=%s' %
                (email, suspected_account.account_id))
        elif suspected_account.is_pending():
            l.info('trying to register email of pending account', email)
            #get verification object
            verifi = Verification.get(email=email,
                                      account_id=suspected_account.account_id)

            #print 'suspected account is currently pending'
            raise PendingAccountAlreadyExisting(verifi)
                if verifi_type == 'SIGNUP':
                    subject = 'Verify email address to start using Chikka API'
                elif verifi_type == 'CHANGEEMAIL':
                    subject = 'Verify email address to start using Chikka API'
                elif verifi_type == 'PASSWORD':
                    subject = 'You requested for password reset '

                key = 'emailcontent:%s' % verifi_id
                l.debug('retrieving email contents from cache', {'key', key})
                email_content = redisconn.get(key)

                if not email_content:
                    # in case content was eraseed
                    l.debug('missing email content, rebuilding',
                            {'type': verifi_type})
                    verification_object = Verification.get(
                        verification_id=verifi_id)
                    if verifi_type == 'SIGNUP':
                        email_content = verification_object.generate_signup_email_content(
                        )
                    elif verifi_type == 'CHANGEEMAIL':
                        email_content = verification_object.generate_change_email_verify_content(
                        )
                    elif verifi_type == 'PASSWORD':
                        email_content = verification_object.generate_forget_password_content(
                        )

                html_content = email_content.replace("\n", '<br>')

                #--- mailer configs
                mail_from = values['mailer']['mail_from_address']
                mailer_host = values['mailer']['host']