Пример #1
0
	def email_change_request( self, email ):
	# request an email address to be modified. Create a rollback option.
		result = 'cannot_remove'
		emailCurrent = self.enki_user.email
		userId = self.enki_user.key.id()
		if email != '' and enki.libuser.exist_EnkiUser( email ):
			# if the new email matches an existing verified user email, reject it
			if emailCurrent == email:
				result = 'same'
			else:
				result = ERROR_EMAIL_IN_USE # Note: send an email to emailcurrent regardless to prevent email checking (see below)
		else:
			if email == '':
				# if the user erased the email, and they can log in through auth, store "removed" in the email field, so it isn't overwritten by an auth login with a verified email
				if self.enki_user.auth_ids_provider:
					self.enki_user.email = 'removed'
					self.enki_user.put()
					result = 'removed'
				else:
					return result
			else:
				# email the new, unverified address with a link to allow the user to verify the email
				tokenEntity = EnkiModelTokenVerify.get_by_user_id_email_type( userId, email, 'emailchange' )
				if tokenEntity:
					# if a verify token for the same new email address and user already exists, use its token
					token = tokenEntity.token
				else:
					# otherwise create a new token
					token = security.generate_random_string( entropy = 256 )
					emailToken = EnkiModelTokenVerify( token = token, email = email, user_id = userId, type = 'emailchange' )
					emailToken.put()
				link = enki.libutil.get_local_url( 'emailchangeconfirm', { 'verifytoken': token })
				self.send_email( email, MSG.SEND_EMAIL_EMAIL_CHANGE_CONFIRM_SUBJECT(), MSG.SEND_EMAIL_EMAIL_CHANGE_CONFIRM_BODY( link, email ))
				result = 'change'
		if emailCurrent and emailCurrent != 'removed' and result != 'same':
			# email the current, verified address in case they want to undo the change (useful if account has been hacked)
			# skip this step if the current email is empty (case if user logged in with auth id without email with e.g. Steam) or "removed".
			# If the email is already in use, mask the fact to prevent email checking.
			tokenEntity = enki.libuser.get_EmailRollbackToken_by_user_id_email( userId, emailCurrent )
			if tokenEntity:
				# if the old email is already in the archive, use its token
				token = tokenEntity.token
			else:
				# otherwise create a new token
				token = security.generate_random_string( entropy = 256 )
				emailOldToken = EnkiModelTokenEmailRollback( token = token, email = emailCurrent, user_id = userId )
				emailOldToken.put()
			if result == ERROR_EMAIL_IN_USE:
				self.add_debugmessage( '''Comment - whether the email is available or not, the feedback through both the UI AND EMAIL is identical to prevent email checking.''' )
			link = enki.libutil.get_local_url( 'emailrollback', { 'rollbacktoken': token } )
			self.send_email( emailCurrent, MSG.SEND_EMAIL_EMAIL_CHANGE_UNDO_SUBJECT(), MSG.SEND_EMAIL_EMAIL_CHANGE_UNDO_BODY( link, emailCurrent ))
		return result
Пример #2
0
def get_EmailRollbackToken_by_user_id_email(user_id, email):
    entity = EnkiModelTokenEmailRollback.query(
        ndb.AND(EnkiModelTokenEmailRollback.user_id == user_id, EnkiModelTokenEmailRollback.email == email)
    ).get()
    if entity:
        return entity
    else:
        return None
Пример #3
0
 def delete_account(self, delete_posts=False, token=''):
     token_to_save = 'accountdelete'
     if not token:
         # there is no token if the user has no email address: they are deleted immediately. They must be logged in.
         user_to_delete = self.enki_user
     else:
         # a user has followed a accountdelete token link. The user account associated with the token will be deleted
         tokenEntity = EnkiModelTokenVerify.get_by_token(token)
         user_to_delete = EnkiModelUser.get_by_id(tokenEntity.user_id)
         # delete all user related tokens except any verify token related to account deletion that's not yet been used
         if tokenEntity.type == token_to_save:
             token_to_save = 'accountandpostsdelete'
     verify_tokens_to_delete = EnkiModelTokenVerify.fetch_keys_by_user_id_except_type(
         user_to_delete.key.id(), token_to_save)
     if verify_tokens_to_delete:
         ndb.delete_multi(verify_tokens_to_delete)
     email_rollback_tokens_to_delete = EnkiModelTokenEmailRollback.fetch_keys_by_user_id(
         user_to_delete.key.id())
     if email_rollback_tokens_to_delete:
         ndb.delete_multi(email_rollback_tokens_to_delete)
     # Delete the user account and log them out.
     if not HandlerBase.account_is_active(user_to_delete.key.id()):
         # delete user if the account is inactive
         display_names = EnkiModelDisplayName.fetch_keys_by_user_id(
             user_to_delete.key.id())
         if display_names:
             ndb.delete_multi(display_names)
         user_to_delete.key.delete()
     else:
         # anonymise the user
         if user_to_delete.email:
             # delete email subscriptions
             EnkiModelEmailSubscriptions.remove_by_email(
                 user_to_delete.email)
             user_to_delete.email = None
         if user_to_delete.password:
             user_to_delete.password = None
         if user_to_delete.auth_ids_provider:
             user_to_delete.auth_ids_provider = []
         user_to_delete.put()
         # keep all historical display_names. Add a new current display_name '[deleted]' (unless it's already been deleted)
         display_name = EnkiModelDisplayName.get_by_user_id_current(
             user_to_delete.key.id())
         if display_name:
             if display_name.prefix != EnkiModelDisplayName.DELETED_PREFIX or display_name.suffix != EnkiModelDisplayName.DELETED_SUFFIX:
                 EnkiModelDisplayName.set_display_name(
                     user_to_delete.key.id(),
                     EnkiModelDisplayName.DELETED_PREFIX,
                     EnkiModelDisplayName.DELETED_SUFFIX)
         # delete user's sent and received messages
         EnkiModelMessage.delete_user_messages(user_to_delete.key.id())
         # delete user's posts if required
         if delete_posts:
             EnkiModelPost.delete_user_posts(user_to_delete.key.id())
     # log the deleted user out
     if self.enki_user == user_to_delete.key.id():
         self.log_out()
     EnkiModelTokenAuth.revoke_user_authentications(user_to_delete.key.id())
Пример #4
0
def fetch_keys_RollbackToken_by_time(user_id, time_created):
    keys = EnkiModelTokenEmailRollback.query(
        ndb.AND(
            EnkiModelTokenEmailRollback.time_created >= time_created, EnkiModelTokenEmailRollback.user_id == user_id
        )
    ).fetch(keys_only=True)
    if keys:
        return keys
    else:
        return None
Пример #5
0
 def email_rollback(self, token):
     email = token.email
     user_id = token.user_id
     # change the email
     user = self.set_email(email, user_id)
     if user:
         # retrieve all rollback tokens that are more recent, including the current one, and delete them
         tokenDateCreated = token.time_created
         youngerTokens = EnkiModelTokenEmailRollback.fetch_keys_by_user_id_time(
             user_id, tokenDateCreated)
         if youngerTokens:
             ndb.delete_multi(youngerTokens)
         # delete all potential remaining email verify tokens for that user
         userTokens = EnkiModelTokenVerify.fetch_keys_by_user_id_type(
             user_id, 'emailchange')
         if userTokens:
             ndb.delete_multi(userTokens)
Пример #6
0
 def email_change_request(self, email):
     # request an email address to be modified. Create a rollback option.
     result = 'cannot_remove'
     emailCurrent = self.enki_user.email
     userId = self.enki_user.key.id()
     if email != '' and EnkiModelUser.exist_by_email(email):
         # if the new email matches an existing verified user email, reject it
         if emailCurrent == email:
             result = 'same'
         else:
             result = self.ERROR_EMAIL_IN_USE
             # Note: send an email to emailcurrent regardless to prevent email checking (see below)
     else:
         if email == '':
             # if the user erased the email, and they can log in through auth, store "removed" in the email field, so it isn't overwritten by an auth login with a verified email
             if self.enki_user.auth_ids_provider:
                 self.enki_user.email = 'removed'
                 self.enki_user.put()
                 result = 'removed'
             else:
                 return result
         else:
             # email the new, unverified address with a link to allow the user to verify the email
             tokenEntity = EnkiModelTokenVerify.get_by_user_id_email_type(
                 userId, email, 'emailchange')
             if tokenEntity:
                 # if a verify token for the same new email address and user already exists, use its token
                 token = tokenEntity.token
             else:
                 # otherwise create a new token
                 token = security.generate_random_string(entropy=256)
                 emailToken = EnkiModelTokenVerify(token=token,
                                                   email=email,
                                                   user_id=userId,
                                                   type='emailchange')
                 emailToken.put()
             link = enki.libutil.get_local_url('emailchangeconfirm',
                                               {'verifytoken': token})
             self.send_email(
                 email, MSG.SEND_EMAIL_EMAIL_CHANGE_CONFIRM_SUBJECT(),
                 MSG.SEND_EMAIL_EMAIL_CHANGE_CONFIRM_BODY(link, email))
             result = 'change'
     if emailCurrent and emailCurrent != 'removed' and result != 'same':
         # email the current, verified address in case they want to undo the change (useful if account has been hacked)
         # skip this step if the current email is empty (case if user logged in with auth id without email with e.g. Steam) or "removed".
         # If the email is already in use, mask the fact to prevent email checking.
         tokenEntity = EnkiModelTokenEmailRollback.get_by_user_id_email(
             userId, emailCurrent)
         if tokenEntity:
             # if the old email is already in the archive, use its token
             token = tokenEntity.token
         else:
             # otherwise create a new token
             token = security.generate_random_string(entropy=256)
             emailOldToken = EnkiModelTokenEmailRollback(token=token,
                                                         email=emailCurrent,
                                                         user_id=userId)
             emailOldToken.put()
         if result == self.ERROR_EMAIL_IN_USE:
             self.add_debugmessage(
                 '''Comment - whether the email is available or not, the feedback through both the UI AND EMAIL is identical to prevent email checking.'''
             )
         link = enki.libutil.get_local_url('emailrollback',
                                           {'rollbacktoken': token})
         self.send_email(
             emailCurrent, MSG.SEND_EMAIL_EMAIL_CHANGE_UNDO_SUBJECT(),
             MSG.SEND_EMAIL_EMAIL_CHANGE_UNDO_BODY(link, emailCurrent))
     return result
Пример #7
0
def fetch_keys_RollbackToken(user_id):
    keys = EnkiModelTokenEmailRollback.query(EnkiModelTokenEmailRollback.user_id == user_id).fetch(keys_only=True)
    if keys:
        return keys
    else:
        return None
Пример #8
0
def get_RollbackToken_by_token(token):
    entity = EnkiModelTokenEmailRollback.query(EnkiModelTokenEmailRollback.token == token).get()
    if entity:
        return entity
    else:
        return None
Пример #9
0
def fetch_keys_RollbackToken_by_time( user_id, time_created ):
	keys = EnkiModelTokenEmailRollback.query( ndb.AND( EnkiModelTokenEmailRollback.time_created >= time_created ,
	                                                   EnkiModelTokenEmailRollback.user_id == user_id )).fetch( keys_only = True )
	return keys
Пример #10
0
def fetch_keys_RollbackToken( user_id ):
	keys = EnkiModelTokenEmailRollback.query( EnkiModelTokenEmailRollback.user_id == user_id ).fetch( keys_only = True )
	return keys
Пример #11
0
def get_RollbackToken_by_token( token ):
	entity = EnkiModelTokenEmailRollback.query( EnkiModelTokenEmailRollback.token == token ).get()
	return entity
Пример #12
0
def get_EmailRollbackToken_by_user_id_email( user_id, email ):
	entity = EnkiModelTokenEmailRollback.query( ndb.AND( EnkiModelTokenEmailRollback.user_id == user_id,
	                                                     EnkiModelTokenEmailRollback.email == email )).get()
	return entity