def account_deletion_request(self, delete_posts=False): token_type = 'accountdelete' if delete_posts: token_type = 'accountandpostsdelete' # if the user has an email, create an email verify token, send it to the email address tokenEntity = EnkiModelTokenVerify.get_by_user_id_email_type( self.enki_user.key.id(), self.enki_user.email, token_type) 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) delete_account_token = EnkiModelTokenVerify( token=token, user_id=self.enki_user.key.id(), email=self.enki_user.email, type=token_type) delete_account_token.put() link = enki.libutil.get_local_url( 'accountdeleteconfirm', {'verifytoken': delete_account_token.token}) delete_posts_message = '' if delete_posts: self.send_email(self.enki_user.email, MSG.SEND_EMAIL_ACCOUT_POSTS_DELETE_SUBJECT(), MSG.SEND_EMAIL_ACCOUT_POSTS_DELETE_BODY(link)) else: self.send_email(self.enki_user.email, MSG.SEND_EMAIL_ACCOUT_DELETE_SUBJECT(), MSG.SEND_EMAIL_ACCOUT_DELETE_BODY(link))
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
def account_deletion_request( self, delete_posts = False ): token_type = 'accountdelete' if delete_posts: token_type = 'accountandpostsdelete' # if the user has an email, create an email verify token, send it to the email address tokenEntity = EnkiModelTokenVerify.get_by_user_id_email_type( self.enki_user.key.id( ), self.enki_user.email, token_type ) 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 ) delete_account_token = EnkiModelTokenVerify( token = token, user_id = self.enki_user.key.id(), email = self.enki_user.email, type = token_type ) delete_account_token.put() link = enki.libutil.get_local_url( 'accountdeleteconfirm', { 'verifytoken': delete_account_token.token } ) delete_posts_message = '' if delete_posts: self.send_email( self.enki_user.email, MSG.SEND_EMAIL_ACCOUT_POSTS_DELETE_SUBJECT(), MSG.SEND_EMAIL_ACCOUT_POSTS_DELETE_BODY( link )) else: self.send_email( self.enki_user.email, MSG.SEND_EMAIL_ACCOUT_DELETE_SUBJECT(), MSG.SEND_EMAIL_ACCOUT_DELETE_BODY( link ))
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