def add_backoff_timer(self, identifier): if not self.exist_backoff_timer(identifier): entity = EnkiModelBackoffTimer( identifier=identifier, last_failure=datetime.datetime.now(), backoff_duration=datetime.timedelta(milliseconds=15)) entity.put()
def log_in_with_email(self, email, password): # log the user in using their email if EnkiModelBackoffTimer.get(email, True) == 0: user = EnkiModelUser.get_by_email(email) if user and user.password: validPassword = enki.authcryptcontext.pwd_context.verify( password, user.password) if validPassword: self.log_in_session_token_create(user) EnkiModelBackoffTimer.remove(user.email) return True return False
def reauthenticate(self, email, password): # reauthenticate the user if EnkiModelBackoffTimer.get(email, True) == 0: user = EnkiModelUser.get_by_email(email) if user and user.password: validPassword = enki.authcryptcontext.pwd_context.verify( password, user.password) if validPassword and self.is_logged_in( ) and self.user_id == user.key.id(): self.session['reauth_time'] = datetime.datetime.now() EnkiModelBackoffTimer.remove(user.email) return True return False
def log_in_with_id(self, userId, password): # log the user in using their Id enkiKey = ndb.Key(EnkiModelUser, userId) if enkiKey: user = enkiKey.get() if EnkiModelBackoffTimer.get(user.email, True) == 0: validPassword = enki.authcryptcontext.pwd_context.verify( password, user.password) if validPassword: self.log_in_session_token_create(user) EnkiModelBackoffTimer.remove(user.email) return True return False
def cleanup_item(self): number = random.randint(1, 1000) likelihood = 10 # occurs with a probability of 1% if number < likelihood: ndb.delete_multi_async(self.fetch_keys_old_sessions(3)) ndb.delete_multi_async(EnkiModelBackoffTimer.fetch_keys_old(3)) ndb.delete_multi_async(EnkiModelTokenAuth.fetch_keys_expired()) ndb.delete_multi_async( EnkiModelRestAPIConnectToken.fetch_expired()) ndb.delete_multi_async(EnkiModelRestAPIDataStore.fetch_expired()) ndb.delete_multi_async( EnkiModelTokenVerify.fetch_keys_old_tokens_by_types( 0.007, [ 'loginaddconfirm_1', 'loginaddconfirm_2', 'loginaddconfirm_3' ])) EnkiModelRestAPIDataStore.refresh_non_expiring() ndb.delete_multi_async( EnkiModelTokenVerify.fetch_keys_old_tokens_by_types( 1, ['emailsubscriptionconfirm'])) ndb.delete_multi_async(EnkiModelBackoffTimer.fetch_keys_old(1))
def remove_backoff_timer( self, email ): entity = EnkiModelBackoffTimer.query( EnkiModelBackoffTimer.email == email ).get() if entity: entity.key.delete()
def exist_backoff_timer(self, identifier): count = EnkiModelBackoffTimer.query( EnkiModelBackoffTimer.identifier == identifier).count(1) return count > 0
def exist_backoff_timer( self, identifier ): count = EnkiModelBackoffTimer.query( EnkiModelBackoffTimer.identifier == identifier ).count( 1 ) return count > 0
def fetch_old_backoff_timers( self, days_old ): list = EnkiModelBackoffTimer.query( EnkiModelBackoffTimer.last_failure <= (datetime.datetime.now( ) - datetime.timedelta( days = days_old )) ).fetch( keys_only = True ) return list
def remove_backoff_timer( self, identifier ): entity = EnkiModelBackoffTimer.query( EnkiModelBackoffTimer.identifier == identifier ).get() if entity: entity.key.delete()
def get_backofftimer( self, identifier ): entity = EnkiModelBackoffTimer.query( EnkiModelBackoffTimer.identifier == identifier ).get() return entity
def add_backoff_timer( self, email ): if not self.exist_backoff_timer( email ): entity = EnkiModelBackoffTimer( email = email, last_failed_login = datetime.datetime.now(), backoff_duration = datetime.timedelta( milliseconds = 15 )) entity.put()
def add_backoff_timer( self, identifier ): if not self.exist_backoff_timer( identifier ): entity = EnkiModelBackoffTimer( identifier = identifier, last_failure = datetime.datetime.now(), backoff_duration = datetime.timedelta( milliseconds = 15 )) entity.put()
def get_backofftimer( self, email ): entity = EnkiModelBackoffTimer.query( EnkiModelBackoffTimer.email == email ).get() if entity: return entity else: return None
def get_backofftimer(self, identifier): entity = EnkiModelBackoffTimer.query( EnkiModelBackoffTimer.identifier == identifier).get() return entity
def remove_backoff_timer(self, identifier): entity = EnkiModelBackoffTimer.query( EnkiModelBackoffTimer.identifier == identifier).get() if entity: entity.key.delete()
def exist_backoff_timer( self, email ): count = EnkiModelBackoffTimer.query( EnkiModelBackoffTimer.email == email ).count( 1 ) if count: return True else: return False
def post(self): self.check_CSRF() submit_type = self.request.get('submittype') data = self.get_email_subscriptions_data() email = '' error_message = '' if data[0]: # is_logged_in if submit_type == 'subscribe': # delete eventual verification tokens for this email and newsletter tokenEntity = EnkiModelTokenVerify.get_by_email_state_type( self.enki_user.email, settings.email_newsletter_name[0], 'emailsubscriptionconfirm') if tokenEntity: tokenEntity.key.delete() EnkiModelEmailSubscriptions.add_newsletter( self.enki_user.email, settings.email_newsletter_name[0]) self.add_infomessage( MSG.SUCCESS(), MSG.EMAIL_SUBSCRIBED(settings.email_newsletter_name[0])) data[1] = True # has_email_subscriptions elif submit_type == 'unsubscribe': EnkiModelEmailSubscriptions.remove_newsletter_by_email( self.enki_user.email, settings.email_newsletter_name[0]) self.add_infomessage( MSG.SUCCESS(), MSG.EMAIL_UNSUBSCRIBED(settings.email_newsletter_name[0])) data[ 1] = False # has_email_subscriptions - ASSUMPTION: ONLY ONE NEWSLETTER AVAILABLE if submit_type == 'subscribeemail': email_unsafe = self.request.get('email') email, result = self.validate_email(email_unsafe) if result == self.ERROR_EMAIL_FORMAT_INVALID: error_message = MSG.WRONG_EMAIL_FORMAT() elif result == self.ERROR_EMAIL_MISSING: error_message = MSG.MISSING_EMAIL() elif result == enki.libutil.ENKILIB_OK: if EnkiModelBackoffTimer.get(self.request.remote_addr, increment=True, expires=True) == 0: if not EnkiModelEmailSubscriptions.exist_by_email_newsletter( email, settings.email_newsletter_name[0]): # if not already subscribed, create a token and send email with a link to allow the user to confirm their subscription if not EnkiModelTokenVerify.get_by_email_state_type( email, settings.email_newsletter_name[0], 'emailsubscriptionconfirm'): # if a verify token already exists, skip as an email was already sent. token = security.generate_random_string( entropy=256) emailToken = EnkiModelTokenVerify( token=token, email=email, state=settings.email_newsletter_name[0], type='emailsubscriptionconfirm') emailToken.put() link = enki.libutil.get_local_url( 'emailsubscriptionconfirm', {'verifytoken': token}) self.send_email( email, MSG.SEND_EMAIL_EMAIL_SUBSCRIBE_CONFIRM_SUBJECT( ), MSG.SEND_EMAIL_EMAIL_SUBSCRIBE_CONFIRM_BODY( link, settings.email_newsletter_name[0])) self.add_infomessage( MSG.INFORMATION(), MSG.EMAIL_SUBSCRIBE_CONFIRM_EMAIL_SENT( email, settings.email_newsletter_name[0])) self.add_debugmessage( 'Comment - whether the email is sent or not, the feedback through the UI is identical to prevent email checking.' ) email = '' else: backoff_timer = EnkiModelBackoffTimer.get( self.request.remote_addr, expires=True) if backoff_timer != 0: error_message = MSG.TIMEOUT( enki.libutil.format_timedelta(backoff_timer)) if data[0]: # is_logged_in self.redirect(enki.libutil.get_local_url('profile')) else: self.render_tmpl('emailsubscriptions.html', active_menu='profile', data=data, email=email, error=error_message)
def fetch_old_backoff_timers(self, days_old): list = EnkiModelBackoffTimer.query( EnkiModelBackoffTimer.last_failure <= ( datetime.datetime.now() - datetime.timedelta(days=days_old))).fetch(keys_only=True) return list
def post_reauthenticated(self, params): licence_key_preset = params.get('licence_key_preset') licence_key_manual = params.get('licence_key_manual') user_id = self.enki_user.key.id() if EnkiModelBackoffTimer.get(str(user_id), True) == 0: licence_key_preset = licence_key_preset.strip()[:( EnkiModelProductKey.LICENCE_KEY_DASHES_LENGTH + 4 )] if licence_key_preset else '' # 4 allows for some leading and trailing characters licence_key_manual = licence_key_manual.strip()[:( EnkiModelProductKey.LICENCE_KEY_DASHES_LENGTH + 4)] if licence_key_manual else '' licence_key = licence_key_manual is_manual = True if licence_key_preset and not licence_key_manual: licence_key = licence_key_preset is_manual = False if licence_key: if len(licence_key) < EnkiModelProductKey.LICENCE_KEY_LENGTH: self.session['error_library'] = MSG.LICENCE_TOO_SHORT() self.session['error_library_licence'] = licence_key elif len(licence_key) <= ( EnkiModelProductKey.LICENCE_KEY_DASHES_LENGTH): licence_key_reduced = re.sub( r'[^\w]', '', licence_key)[:EnkiModelProductKey.LICENCE_KEY_LENGTH] item = EnkiModelProductKey.get_by_licence_key( licence_key_reduced) if not item: if is_manual: self.session[ 'error_library'] = MSG.LICENCE_INVALID() self.session['error_library_licence'] = licence_key elif item: licence_key_formatted = EnkiModelProductKey.insert_dashes_5_10( licence_key_reduced) if item.activated_by_user == -1: # the licence key is not activated. if EnkiModelProductKey.exist_product_by_activator( user_id, item.product_name): # the user has already activated a key for the same product if is_manual: self.session[ 'error_library'] = MSG.LICENCE_ALREADY_ACTIVATED_GIVE( settings.product_displayname[ item.product_name]) self.session[ 'error_library_licence'] = licence_key_formatted else: # activate the licence item.activated_by_user = user_id item.put() EnkiModelBackoffTimer.remove(str(user_id)) self.add_infomessage( MSG.SUCCESS(), MSG.PRODUCT_LICENCE_ACTIVATED( settings.product_displayname[ item.product_name], licence_key_formatted)) elif item.activated_by_user == user_id: # the user has already activated this specific key if is_manual: self.session[ 'error_library'] = MSG.PRODUCT_ALREADY_ACTIVATED( settings.product_displayname[ item.product_name]) self.session[ 'error_library_licence'] = licence_key_formatted else: self.add_infomessage( MSG.INFORMATION(), MSG.PRODUCT_ALREADY_ACTIVATED( settings.product_displayname[ item.product_name])) else: # another user has activated the key if is_manual: self.session[ 'error_library'] = MSG.LICENCE_ANOTHER_USER_ACTIVATED( settings.product_displayname[ item.product_name], licence_key_formatted) self.session[ 'error_library_licence'] = licence_key_formatted else: self.add_infomessage( MSG.INFORMATION(), MSG.LICENCE_ANOTHER_USER_ACTIVATED( settings.product_displayname[ item.product_name], licence_key_formatted)) else: self.session['error_library'] = MSG.LICENCE_TOO_LONG() self.session['error_library_licence'] = licence_key elif is_manual: self.session['error_library'] = MSG.LICENCE_MISSING() else: backoff_timer = EnkiModelBackoffTimer.get(str(user_id)) if backoff_timer != 0: self.session['error_library'] = MSG.TIMEOUT( enki.libutil.format_timedelta(backoff_timer)) self.render_tmpl('library.html', active_menu='profile', data=self.get_data())