Example #1
0
 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))
Example #2
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())
Example #3
0
	def post( self ):
		url = settings.URL_PURCHASE_FASTSPRING
		if not settings.SECRET_FASTSPRING or enki.libutil.is_debug( ) or settings.ENKI_EMULATE_STORE:
			url = enki.libutil.get_local_url( 'storeemulatefastspring' )
		if self.is_logged_in():
			purchaser_user_id = self.enki_user.key.id()
			token = security.generate_random_string( entropy = 256 )
			token_purchase = EnkiModelTokenVerify( token = token, user_id = purchaser_user_id, type = 'purchasebyuser' )
			token_purchase.put()
			url = enki.libutil.get_local_url( 'storeemulatefastspring', { 'referrer': token_purchase.token })
		self.redirect( url )
Example #4
0
	def password_change_request( self, email ):
		if enki.libuser.exist_EnkiUser( email ):
		# create an email verify token, send it to the email address
			token = security.generate_random_string( entropy = 256 )
			emailToken = EnkiModelTokenVerify( token = token, email = email, type = 'passwordchange' )
			emailToken.put()
			link = enki.libutil.get_local_url( 'passwordrecoverconfirm', { 'verifytoken': emailToken.token } )
			self.send_email( email, MSG.SEND_EMAIL_PASSWORD_RESET_SUBJECT(), MSG.SEND_EMAIL_PASSWORD_RESET_BODY( link ))
			result = enki.libutil.ENKILIB_OK
		else:
			result = ERROR_EMAIL_NOT_EXIST
		return result
Example #5
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
Example #6
0
 def create_user_from_email_pw(self, email, password):
     result = enki.libutil.ENKILIB_OK
     # create a user with the email provided
     user = self.set_email(email)
     if user:
         # set the user's password
         result = self.set_password(user, password)
         if result == enki.libutil.ENKILIB_OK:
             # cleanup: delete all verify tokens created when registering the email
             EnkiModelTokenVerify.delete_by_email_type(email, 'register')
     else:
         result = self.ERROR_USER_NOT_CREATED
     return result
Example #7
0
    def post(self):
        url = settings.URL_PURCHASE_FASTSPRING

        # ------
        # Requires enkiDL
        if self.request.get('download'):
            ref_url = enki.libutil.get_local_url('store')
            self.session['sessionrefpath'] = ref_url
            url_fetcher = ''
            if settings.URLS_ENKIDL:
                # shuffle then try to download from locations in sequence
                random.shuffle(settings.URLS_ENKIDL)
                for i in range(len(settings.URLS_ENKIDL)):
                    url_enkiDL = settings.URLS_ENKIDL[i]
                    item_to_download = 'product_a'
                    url_fetcher = enki.libenkiDL.URLFetcher()
                    url_fetcher.get_download_URL(url_enkiDL,
                                                 settings.SECRET_ENKIDL,
                                                 item_to_download,
                                                 self.request.remote_addr)
                    if not url_fetcher.error:
                        enki.modelcounter.increment('downloads_product_a')
                        break
                if url_fetcher and url_fetcher.error:
                    self.response.status_int = 500
                    self.add_infomessage(MSG.WARNING(), MSG.DOWNLOAD_ERROR())
                    self.redirect('info')
                    return
                url = url_fetcher.download_url
            else:
                self.add_infomessage(MSG.WARNING(), MSG.DOWNLOAD_ERROR())
                self.redirect('info')
                return
        # -------

        else:
            if not settings.SECRET_FASTSPRING or enki.libutil.is_debug(
            ) or settings.ENKI_EMULATE_STORE:
                url = enki.libutil.get_local_url('storeemulatefastspring')
            else:
                enki.modelcounter.increment('purchases_product_a')
            if self.is_logged_in():
                purchaser_user_id = self.enki_user.key.id()
                token = security.generate_random_string(entropy=256)
                token_purchase = EnkiModelTokenVerify(
                    token=token,
                    user_id=purchaser_user_id,
                    type='purchasebyuser')
                token_purchase.put()
                url += '?referrer=' + token_purchase.token.encode('utf-8')
        self.redirect(url)
Example #8
0
 def post(self):
     url = settings.URL_PURCHASE_FASTSPRING
     if not settings.SECRET_FASTSPRING or enki.libutil.is_debug(
     ) or settings.ENKI_EMULATE_STORE:
         url = enki.libutil.get_local_url('storeemulatefastspring')
     if self.is_logged_in():
         purchaser_user_id = self.enki_user.key.id()
         token = security.generate_random_string(entropy=256)
         token_purchase = EnkiModelTokenVerify(token=token,
                                               user_id=purchaser_user_id,
                                               type='purchasebyuser')
         token_purchase.put()
         url = enki.libutil.get_local_url(
             'storeemulatefastspring', {'referrer': token_purchase.token})
     self.redirect(url)
Example #9
0
	def post_reauthenticated( self, params ):
		register = params.get( 'register' )
		deregister = params.get( 'deregister' )
		if register:  # initiate adding a new authentication method to the account
			for authhandler in settings.HANDLERS:
				if register == authhandler.get_provider_name():
					token = security.generate_random_string( entropy = 256 )
					LoginAddToken = EnkiModelTokenVerify( token = token, user_id = self.user_id, auth_ids_provider = register, type = 'loginaddconfirm_1' )
					LoginAddToken.put()
					self.redirect( authhandler.get_button().href )
					break
		elif deregister:
			self.remove_auth_id( deregister)
			self.add_infomessage( 'success', MSG.SUCCESS(), MSG.AUTH_PROVIDER_REMOVED( deregister ))
			self.redirect( enki.libutil.get_local_url( 'accountconnect' ))
Example #10
0
	def email_set_request( self, email ):
	# request the creation of a new account based on an email address
		result = enki.libuser.validate_email( email )
		if result == enki.libutil.ENKILIB_OK :
			if enki.libuser.exist_EnkiUser( email ):
				result = ERROR_EMAIL_IN_USE
			else:
				# create an email verify token, send it to the email address
				token = security.generate_random_string( entropy = 256 )
				emailToken = EnkiModelTokenVerify( token = token, email = email, type = 'register' )
				emailToken.put()
				link = enki.libutil.get_local_url( 'registerconfirm', { 'verifytoken': emailToken.token })
				self.send_email( email, MSG.SEND_EMAIL_REGISTER_CONFIRM_SUBJECT(), MSG.SEND_EMAIL_REGISTER_CONFIRM_BODY( link ))
				result = enki.libutil.ENKILIB_OK
		return result
Example #11
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 = enki.libuser.fetch_keys_RollbackToken( 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 = enki.libdisplayname.fetch_EnkiUserDisplayName_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:
				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 = enki.libdisplayname.get_EnkiUserDisplayName_by_user_id_current( user_to_delete.key.id())
			if display_name:
				if display_name.prefix != enki.libdisplayname.DELETED_PREFIX or display_name.suffix != enki.libdisplayname.DELETED_SUFFIX:
					enki.libdisplayname.set_display_name( user_to_delete.key.id(), enki.libdisplayname.DELETED_PREFIX, enki.libdisplayname.DELETED_SUFFIX )
			# delete user's sent and received messages
			ndb.delete_multi( enki.libmessage.fetch_keys_sent_or_received_message( user_to_delete.key.id()))
			# delete user's posts if required
			if delete_posts:
				enki.libforum.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()
		enki.libuser.revoke_user_authentications( user_to_delete.key.id())
Example #12
0
	def post( self, **kwargs ):
		self.check_CSRF()
		token = kwargs[ 'verifytoken' ]
		tokenEntity = EnkiModelTokenVerify.get_by_token_type( token, 'passwordchange' )
		if tokenEntity:
			email = tokenEntity.email
			user = enki.libuser.get_EnkiUser( email )
			if user:
				password = self.request.get( 'password' )
				result = enki.libuser.set_password( user, password )
				if result == enki.libutil.ENKILIB_OK:
					enki.libuser.delete_verifytoken_by_email( email, 'passwordchange' )
					self.log_in_with_id( user.key.id(), password )
					self.add_infomessage( 'success', MSG.SUCCESS( ), MSG.PASSWORD_SET())
					self.redirect( enki.libutil.get_local_url( 'profile' ) )
					return
				else:
					error_message = ''
					if result == enki.libuser.ERROR_PASSWORD_BLANK :
						error_message = MSG.MISSING_PW()
					elif result == enki.libuser.ERROR_PASSWORD_TOO_SHORT :
						length = len( password )
						error_message = " ".join( [ MSG.PW_TOO_SHORT( length ), MSG.PW_ENSURE_MIN_LENGTH( self.app.config.get( 'enki' ).get( 'user' ).get( 'PASSWORD_LENGTH_MIN' ) ) ] )
					self.render_tmpl( 'passwordrecoverconfirm.html',
					                  error = error_message )
			else:
				self.abort( 401 )
		else:
			self.abort( 404 )
Example #13
0
 def password_change_request(self, email):
     if EnkiModelUser.exist_by_email(email):
         # create an email verify token, send it to the email address
         token = security.generate_random_string(entropy=256)
         emailToken = EnkiModelTokenVerify(token=token,
                                           email=email,
                                           type='passwordchange')
         emailToken.put()
         link = enki.libutil.get_local_url(
             'passwordrecoverconfirm', {'verifytoken': emailToken.token})
         self.send_email(email, MSG.SEND_EMAIL_PASSWORD_RESET_SUBJECT(),
                         MSG.SEND_EMAIL_PASSWORD_RESET_BODY(link))
         result = enki.libutil.ENKILIB_OK
     else:
         result = self.ERROR_EMAIL_NOT_EXIST
     return result
 def get(self, verifytoken):
     tokenEntity = EnkiModelTokenVerify.get_by_token_type(
         xstr(verifytoken), 'emailsubscriptionconfirm')
     if tokenEntity:
         newsletter = tokenEntity.state
         unsubscribe_token = EnkiModelEmailSubscriptions.add_newsletter(
             tokenEntity.email, newsletter)
         self.add_infomessage(MSG.SUCCESS(),
                              MSG.EMAIL_SUBSCRIBED(newsletter))
         # send welcome email with unsubscribe link
         link = enki.libutil.get_local_url('emailunsubscribe', {
             'unsubscribetoken': unsubscribe_token,
             'newsletter': newsletter
         })
         self.send_email(
             tokenEntity.email,
             MSG.SEND_EMAIL_EMAIL_NEWSLETTER_WELCOME_SUBJECT(newsletter),
             MSG.SEND_EMAIL_EMAIL_NEWSLETTER_WELCOME_BODY(newsletter, link))
         self.add_infomessage(
             MSG.INFORMATION(),
             MSG.EMAIL_NEWSLETTER_WELCOME_EMAIL_SENT(newsletter))
         self.redirect(enki.libutil.get_local_url('home'))
         tokenEntity.key.delete()
     else:
         self.add_infomessage(MSG.INFORMATION(),
                              MSG.EMAIL_SUBSCRIPTION_FAILED())
         self.redirect(enki.libutil.get_local_url('emailsubscriptions'))
Example #15
0
	def get( self ):
		token = self.session.get( 'tokenregisterauth' )
		tokenEntity = EnkiModelTokenVerify.get_by_token_type( token, 'register' )
		if tokenEntity:
			provider_name, provider_uid = tokenEntity.auth_ids_provider.partition( ':' )[ ::2 ]
			provider_email = tokenEntity.email
			provider_authhandler = ''
			for handler in settings.HANDLERS:
				if handler.get_provider_name() == provider_name:
					provider_authhandler = handler
			# only display the email/pw login if the user has a password
			email_user_has_pw = enki.libuser.user_has_password_by_email( provider_email )
			# list of email user's auth providers
			authhandlers = []
			user = enki.libuser.get_EnkiUser( provider_email )
			for user_provider_uid in user.auth_ids_provider:
				for handler in settings.HANDLERS:
					if ( handler.get_provider_name() in user_provider_uid ) and ( handler not in authhandlers ):
						authhandlers.append( handler )
						break
			self.render_tmpl( 'registeroauthwithexistingemail.html',
			                  active_menu = 'login',
			                  token = tokenEntity,
							  email = provider_email,
							  email_user_has_pw = email_user_has_pw,
			                  provider_name = provider_name,
			                  provider_uid = str( provider_uid ),
							  provider_authhandler = provider_authhandler,
							  authhandlers = authhandlers,
							  )
		else:
			self.abort( 404 )
Example #16
0
	def post( self, **kwargs ):
		self.check_CSRF(),
		token = kwargs[ 'verifytoken' ]
		tokenEntity = EnkiModelTokenVerify.get_by_token_type( token, 'register' )
		if tokenEntity:
			email = tokenEntity.email
			password = self.request.get( 'password' )
			result = enki.libuser.validate_password( password )
			link = enki.libutil.get_local_url( 'registerconfirm', { 'verifytoken': token } )
			if result == enki.libutil.ENKILIB_OK:
				result = self.create_user_from_email_pw( email, password )
				if result == enki.libutil.ENKILIB_OK:
					self.add_infomessage( 'success', MSG.SUCCESS( ), MSG.ACCOUNT_CREATED())
					self.log_in_with_email( email, password )
					self.redirect_to_relevant_page()
				elif result == enki.handlerbase.ERROR_USER_NOT_CREATED:
					error_message = MSG.FAIL_REGISTRATION()
					self.render_tmpl( 'register.html',
					                  active_menu = 'register',
					                  email = email,
					                  error = error_message )
			else:
				error_message = ''
				if result == enki.libuser.ERROR_PASSWORD_BLANK:
					error_message = MSG.MISSING_PW()
				elif result == enki.libuser.ERROR_PASSWORD_TOO_SHORT :
					length = len( password )
					error_message = " ".join( [ MSG.PW_TOO_SHORT( length ), MSG.PW_ENSURE_MIN_LENGTH( self.app.config.get( 'enki' ).get( 'user' ).get( 'PASSWORD_LENGTH_MIN' ))])
				self.render_tmpl( 'registerconfirm.html',
				                  active_menu = 'register',
				                  email = email,
				                  url = link,
				                  error = error_message )
		else:
			self.abort( 404 )
Example #17
0
def exist_VerifyToken(token, type):
    count = EnkiModelTokenVerify.query(
        ndb.AND(EnkiModelTokenVerify.token == token, EnkiModelTokenVerify.type == type)
    ).count(1)
    if count:
        return True
    else:
        return False
Example #18
0
def fetch_keys_VerifyToken_by_email_type(email, type):
    keys = EnkiModelTokenVerify.query(
        ndb.AND(EnkiModelTokenVerify.email == email, EnkiModelTokenVerify.type == type)
    ).fetch(keys_only=True)
    if keys:
        return keys
    else:
        return None
Example #19
0
def get_VerifyToken_by_token_type(token, type):
    entity = EnkiModelTokenVerify.query(
        ndb.AND(EnkiModelTokenVerify.token == token, EnkiModelTokenVerify.type == type)
    ).get()
    if entity:
        return entity
    else:
        return None
Example #20
0
def get_VerifyToken_by_authid_type(authId, type):
    entity = EnkiModelTokenVerify.query(
        ndb.AND(EnkiModelTokenVerify.auth_ids_provider == authId, EnkiModelTokenVerify.type == type)
    ).get()
    if entity:
        return entity
    else:
        return None
Example #21
0
def fetch_keys_VerifyToken_by_user_id_except_type(user_id, type):
    keys = EnkiModelTokenVerify.query(
        ndb.AND(EnkiModelTokenVerify.user_id == user_id, EnkiModelTokenVerify.type != type)
    ).fetch(keys_only=True)
    if keys:
        return keys
    else:
        return None
Example #22
0
 def email_set_request(self, email):
     # request the creation of a new account based on an email address
     result = enki.libutil.ENKILIB_OK
     if EnkiModelUser.exist_by_email(email):
         result = self.ERROR_EMAIL_IN_USE
     else:
         # create an email verify token, send it to the email address
         token = security.generate_random_string(entropy=256)
         emailToken = EnkiModelTokenVerify(token=token,
                                           email=email,
                                           type='register')
         emailToken.put()
         link = enki.libutil.get_local_url(
             'registerconfirm', {'verifytoken': emailToken.token})
         self.send_email(email, MSG.SEND_EMAIL_REGISTER_CONFIRM_SUBJECT(),
                         MSG.SEND_EMAIL_REGISTER_CONFIRM_BODY(link))
     return result
Example #23
0
def check_and_delete_preventmultipost_token( token ):
	# prevent accidental multiple posting
	result = False
	verify_token = EnkiModelTokenVerify.get_by_token_type( token, 'preventmultipost' )
	if verify_token:
		verify_token.key.delete()
		result = True
	return result
Example #24
0
	def get( self, **kwargs ):
		token = kwargs[ 'verifytoken' ]
		delete_posts = False
		tokenExists = EnkiModelTokenVerify.exist_by_token_type( token, 'accountdelete' )
		if not tokenExists:
			tokenExists = EnkiModelTokenVerify.exist_by_token_type( token, 'accountandpostsdelete' )
			if tokenExists:
				delete_posts = True
		if tokenExists:
			result = self.delete_account( delete_posts, token )
			if delete_posts:
				self.add_infomessage( 'success', MSG.SUCCESS(), MSG.ACCOUNT_AND_POSTS_DELETED())
			else:
				self.add_infomessage( 'success', MSG.SUCCESS(), MSG.ACCOUNT_DELETED())
			self.redirect( enki.libutil.get_local_url())
		else:
			self.abort( 404 )
Example #25
0
	def get( self, **kwargs):
		token = kwargs[ 'verifytoken' ]
		if EnkiModelTokenVerify.exist_by_token_type( token, 'passwordchange' ):
			link = enki.libutil.get_local_url( 'passwordrecoverconfirm', { 'verifytoken': token } )
			self.render_tmpl( 'passwordrecoverconfirm.html',
			                  active_menu = 'profile',
			                  url = link )
		else:
			self.abort( 404 )
Example #26
0
	def get( self, **kwargs ):
		token = kwargs[ 'verifytoken' ]
		tokenEntity = EnkiModelTokenVerify.get_by_token_type( token, 'emailchange' )
		if tokenEntity:
			self.email_change( tokenEntity )
			self.add_infomessage( 'success', MSG.SUCCESS( ), MSG.EMAIL_SET())
			self.redirect( enki.libutil.get_local_url( 'profile' ) )
		else:
			self.abort( 404 )
Example #27
0
	def post_reauthenticated( self, params ):
		choice = params.get( 'choice' )
		if choice != 'cancel':
			tokenEntity = EnkiModelTokenVerify.get_by_user_id_auth_id_type( user_id = self.user_id, auth_id = choice, type = 'loginaddconfirm_3' )
			if tokenEntity:
				self.set_auth_id( tokenEntity.auth_ids_provider, self.user_id )
				self.add_infomessage( 'success', MSG.SUCCESS(), MSG.AUTH_PROVIDER_ADDED( str( tokenEntity.auth_ids_provider )))
			tokenEntity.key.delete()
		self.redirect( enki.libutil.get_local_url( 'accountconnect' ))
Example #28
0
def check_and_delete_preventmultipost_token(token):
    # prevent accidental multiple posting
    result = False
    verify_token = EnkiModelTokenVerify.get_by_token_type(
        token, 'preventmultipost')
    if verify_token:
        verify_token.key.delete()
        result = True
    return result
Example #29
0
 def get(self, **kwargs):
     token = kwargs['verifytoken']
     if EnkiModelTokenVerify.exist_by_token_type(token, 'passwordchange'):
         link = enki.libutil.get_local_url('passwordrecoverconfirm',
                                           {'verifytoken': token})
         self.render_tmpl('passwordrecoverconfirm.html',
                          active_menu='profile',
                          url=link)
     else:
         self.abort(404)
Example #30
0
 def get(self, **kwargs):
     token = kwargs['verifytoken']
     tokenEntity = EnkiModelTokenVerify.get_by_token_type(
         token, 'emailchange')
     if tokenEntity:
         self.email_change(tokenEntity)
         self.add_infomessage('success', MSG.SUCCESS(), MSG.EMAIL_SET())
         self.redirect(enki.libutil.get_local_url('profile'))
     else:
         self.abort(404)
Example #31
0
	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 ))
Example #32
0
	def cleanup_item( self ):
		likelyhood = 10 # occurs with a probability of 1%
		number = random.randint( 1, 1000 )
		if number < likelyhood:
			ndb.delete_multi_async( self.fetch_old_backoff_timers( 3 ))
			ndb.delete_multi_async( self.fetch_old_auth_tokens( 3 ))
			ndb.delete_multi_async( self.fetch_old_sessions( 3 ))
			ndb.delete_multi_async( enki.librestapi.fetch_EnkiModelRestAPIConnectToken_expired())
			ndb.delete_multi_async( enki.librestapi.fetch_EnkiModelRestAPIDataStore_expired())
			ndb.delete_multi_async( EnkiModelTokenVerify.fetch_old_tokens_by_types( 0.007, [ 'loginaddconfirm_1', 'loginaddconfirm_2', 'loginaddconfirm_3' ]))
			enki.librestapi.refresh_EnkiModelRestAPIConnectToken_non_expiring()
Example #33
0
 def post_reauthenticated(self, params):
     register = params.get('register')
     deregister = params.get('deregister')
     if register:  # initiate adding a new authentication method to the account
         for authhandler in settings.HANDLERS:
             if register == authhandler.get_provider_name():
                 token = security.generate_random_string(entropy=256)
                 LoginAddToken = EnkiModelTokenVerify(
                     token=token,
                     user_id=self.user_id,
                     auth_ids_provider=register,
                     type='loginaddconfirm_1')
                 LoginAddToken.put()
                 self.redirect(authhandler.get_button().href)
                 break
     elif deregister:
         self.remove_auth_id(deregister)
         self.add_infomessage('success', MSG.SUCCESS(),
                              MSG.AUTH_PROVIDER_REMOVED(deregister))
         self.redirect(enki.libutil.get_local_url('accountconnect'))
Example #34
0
	def get( self ):
		token = self.session.get( 'tokenregisterauth' )
		tokenEntity = EnkiModelTokenVerify.get_by_token_type( token, 'register' )
		if tokenEntity:
			provider_name, provider_uid = tokenEntity.auth_ids_provider.partition( ':' )[ ::2 ]
			self.render_tmpl( 'registeroauthconfirm.html',
			                  active_menu = 'register',
			                  token = tokenEntity,
			                  provider_name = provider_name,
			                  provider_uid = str( provider_uid ))
		else:
			self.abort( 404 )
Example #35
0
 def get(self, **kwargs):
     token = kwargs['verifytoken']
     delete_posts = False
     tokenExists = EnkiModelTokenVerify.exist_by_token_type(
         token, 'accountdelete')
     if not tokenExists:
         tokenExists = EnkiModelTokenVerify.exist_by_token_type(
             token, 'accountandpostsdelete')
         if tokenExists:
             delete_posts = True
     if tokenExists:
         result = self.delete_account(delete_posts, token)
         if delete_posts:
             self.add_infomessage('success', MSG.SUCCESS(),
                                  MSG.ACCOUNT_AND_POSTS_DELETED())
         else:
             self.add_infomessage('success', MSG.SUCCESS(),
                                  MSG.ACCOUNT_DELETED())
         self.redirect(enki.libutil.get_local_url())
     else:
         self.abort(404)
Example #36
0
def get_VerifyToken_by_user_id_email_type(user_id, email, type):
    entity = EnkiModelTokenVerify.query(
        ndb.AND(
            EnkiModelTokenVerify.user_id == user_id,
            EnkiModelTokenVerify.email == email,
            EnkiModelTokenVerify.type == type,
        )
    ).get()
    if entity:
        return entity
    else:
        return None
Example #37
0
	def get( self, **kwargs ):
		token = kwargs[ 'verifytoken' ]
		tokenEntity = EnkiModelTokenVerify.get_by_token_type( token, 'register' )
		if tokenEntity:
			email = tokenEntity.email
			link = enki.libutil.get_local_url( 'registerconfirm', { 'verifytoken': token } )
			self.render_tmpl( 'registerconfirm.html',
			                  active_menu = 'register',
			                  email = email,
			                  url = link )
		else:
			self.abort( 404 )
Example #38
0
 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))
Example #39
0
	def get_logged_in( self ):
		tokenEntity = EnkiModelTokenVerify.get_by_user_id_type( self.user_id, 'loginaddconfirm_2' )
		if tokenEntity:
			provider_name, provider_uid = tokenEntity.auth_ids_provider.partition( ':' )[ ::2 ]
			tokenEntity.type = 'loginaddconfirm_3'
			tokenEntity.put()
			self.render_tmpl( 'loginaddconfirm.html',
							  active_menu = 'profile',
							  provider_name = provider_name,
							  provider_uid = provider_uid,
							  token = tokenEntity.token )
		else:
			self.redirect( enki.libutil.get_local_url( 'accountconnect' ))
Example #40
0
 def get(self):
     token = self.session.get('tokenregisterauth')
     tokenEntity = EnkiModelTokenVerify.get_by_token_type(token, 'register')
     if tokenEntity:
         provider_name, provider_uid = tokenEntity.auth_ids_provider.partition(
             ':')[::2]
         self.render_tmpl('registeroauthconfirm.html',
                          active_menu='register',
                          token=tokenEntity,
                          provider_name=provider_name,
                          provider_uid=str(provider_uid))
     else:
         self.abort(404)
Example #41
0
 def get(self, **kwargs):
     token = kwargs['verifytoken']
     tokenEntity = EnkiModelTokenVerify.get_by_token_type(token, 'register')
     if tokenEntity:
         email = tokenEntity.email
         link = enki.libutil.get_local_url('registerconfirm',
                                           {'verifytoken': token})
         self.render_tmpl('registerconfirm.html',
                          active_menu='register',
                          email=email,
                          url=link)
     else:
         self.abort(404)
Example #42
0
 def post_reauthenticated(self, params):
     choice = params.get('choice')
     if choice != 'cancel':
         tokenEntity = EnkiModelTokenVerify.get_by_user_id_auth_id_type(
             user_id=self.user_id, auth_id=choice, type='loginaddconfirm_3')
         if tokenEntity:
             self.set_auth_id(tokenEntity.auth_ids_provider, self.user_id)
             self.add_infomessage(
                 'success', MSG.SUCCESS(),
                 MSG.AUTH_PROVIDER_ADDED(str(
                     tokenEntity.auth_ids_provider)))
         tokenEntity.key.delete()
     self.redirect(enki.libutil.get_local_url('accountconnect'))
Example #43
0
 def post(self):
     self.cleanup_item()
     self.log_out()
     self.check_CSRF()
     token = self.session.get('tokenregisterauth')
     tokenEntity = EnkiModelTokenVerify.get_by_token_type(token, 'register')
     if tokenEntity:
         submit_type = self.request.get('submittype')
         # Log in with email and password
         if submit_type == 'login':
             email = tokenEntity.email
             tokenEntity.key.delete()
             password = self.request.get('password')
             if self.log_in_with_email(email, password):
                 self.add_infomessage('success', MSG.SUCCESS(),
                                      MSG.LOGGED_IN())
                 self.redirect_to_relevant_page()
             else:
                 error_message = MSG.WRONG_EMAIL_OR_PW()
                 backoff_timer = self.get_backoff_timer(email)
                 if backoff_timer != 0:
                     error_message = MSG.TIMEOUT(
                         enki.libutil.format_timedelta(backoff_timer))
                 self.render_tmpl('login.html',
                                  active_menu='login',
                                  authhandlers=settings.HANDLERS,
                                  email=email,
                                  error=error_message)
         elif submit_type == 'recoverpass':
             email = tokenEntity.email
             tokenEntity.key.delete()
             self.redirect(
                 enki.libutil.get_local_url('passwordrecover',
                                            {'email': email}))
         # Create a new account using the OAuth provider but without the email
         elif submit_type == 'register':
             email = tokenEntity.email
             tokenEntity.email = ''
             tokenEntity.put()
             self.add_infomessage(
                 'info', MSG.INFORMATION(),
                 MSG.REGISTRATION_INFO_EMAIL_CANNOT_USE(email))
             self.redirect(
                 enki.libutil.get_local_url('registeroauthconfirm'))
         else:
             tokenEntity.key.delete()
             self.add_infomessage('info', MSG.INFORMATION(),
                                  MSG.LOGIN_FAILED())
             self.redirect(enki.libutil.get_local_url('home'))
     else:
         self.abort(404)
Example #44
0
	def provider_authenticated_callback( self, loginInfo ):
		# We expect the fields of the dictionary to be:
		# - 'provider_name' unique 'pretty' provider name (e.g. google, facebook,...)
		# - 'provider_uid' provider specific (a.k.a "locally unique") user Id, i.e unique to the provider (e.g. the google user id number)
		# - 'email'
		# - 'email_verified'
		# We IGNORE: username, gender (facebook), avatar link, etc.

		# get the verified email from the auth provider
		email = None
		if loginInfo[ 'email' ] and loginInfo[ 'email_verified' ] == True:
			email = loginInfo[ 'email' ]
		# get the authId from the auth provider
		authId = loginInfo[ 'provider_name' ] + ':' + loginInfo[ 'provider_uid' ]

		if authId:
		# modify existing or create user
			user = self.get_or_create_user_from_authid( authId, email, allow_create = False )
			if user:
				self.log_in_session_token_create( user )
				self.add_infomessage( 'success', MSG.SUCCESS( ), MSG.LOGGED_IN())
				self.redirect_to_relevant_page()
			else:
				# generate & store a verification token and the auth provider. save the token number in the session.
				register_token =  enki.libuser.get_VerifyToken_by_authid_type( authId, 'register' )
				if register_token:
					# if a token already exists, get the token value and update the email
					token = register_token.token
					register_token.email = email # update in case the user changed their email or modified their email access permission
				else:
					# create a new token
					token = security.generate_random_string( entropy = 256 )
					register_token = EnkiModelTokenVerify( token = token, email = email, auth_ids_provider = authId, type = 'register' )
				register_token.put()
				self.session[ 'tokenregisterauth' ] = token
				self.redirect( enki.libutil.get_local_url( 'registeroauthconfirm' ) )
		else:
			self.redirect_to_relevant_page()
Example #45
0
	def email_change( self, token ):
		email = token.email
		user_id = token.user_id
		# change the email
		user = self.set_email( email, user_id )
		if user:
			# delete all potential remaining email verify tokens for that user
			tokens = EnkiModelTokenVerify.fetch_keys_by_user_id_type( user_id, 'emailchange' )
			if tokens:
				ndb.delete_multi( tokens )
			# note: the old email remains saved in the rollback token db
		else:
			# delete the email verification token
			token.key.delete()
Example #46
0
 def get_logged_in(self):
     tokenEntity = EnkiModelTokenVerify.get_by_user_id_type(
         self.user_id, 'loginaddconfirm_2')
     if tokenEntity:
         provider_name, provider_uid = tokenEntity.auth_ids_provider.partition(
             ':')[::2]
         tokenEntity.type = 'loginaddconfirm_3'
         tokenEntity.put()
         self.render_tmpl('loginaddconfirm.html',
                          active_menu='profile',
                          provider_name=provider_name,
                          provider_uid=provider_uid,
                          token=tokenEntity.token)
     else:
         self.redirect(enki.libutil.get_local_url('accountconnect'))
Example #47
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 = enki.libuser.fetch_keys_RollbackToken_by_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 )
Example #48
0
 def email_change(self, token):
     email = token.email
     user_id = token.user_id
     # change the email
     user = self.set_email(email, user_id)
     if user:
         # delete all potential remaining email verify tokens for that user
         tokens = EnkiModelTokenVerify.fetch_keys_by_user_id_type(
             user_id, 'emailchange')
         if tokens:
             ndb.delete_multi(tokens)
         # note: the old email remains saved in the rollback token db
     else:
         # delete the email verification token
         token.key.delete()
Example #49
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)
Example #50
0
 def cleanup_item(self):
     likelyhood = 10  # occurs with a probability of 1%
     number = random.randint(1, 1000)
     if number < likelyhood:
         ndb.delete_multi_async(self.fetch_old_backoff_timers(3))
         ndb.delete_multi_async(self.fetch_old_auth_tokens(3))
         ndb.delete_multi_async(self.fetch_old_sessions(3))
         ndb.delete_multi_async(
             enki.librestapi.fetch_EnkiModelRestAPIConnectToken_expired())
         ndb.delete_multi_async(
             enki.librestapi.fetch_EnkiModelRestAPIDataStore_expired())
         ndb.delete_multi_async(
             EnkiModelTokenVerify.fetch_old_tokens_by_types(
                 0.007, [
                     'loginaddconfirm_1', 'loginaddconfirm_2',
                     'loginaddconfirm_3'
                 ]))
         enki.librestapi.refresh_EnkiModelRestAPIConnectToken_non_expiring()
Example #51
0
    def post(self):
        secret = xstr(self.request.get('secret'))
        if secret == settings.SECRET_FASTSPRING or enki.libutil.is_debug(
        ) or settings.ENKI_EMULATE_STORE:

            licence_key_bundle = xstr(self.request.get('licence_key'))
            purchase_price = xstr(self.request.get('purchase_price'))
            order_id = xstr(self.request.get('order_id'))
            product_name = xstr(self.request.get('product_name'))
            purchaser_email = xstr(self.request.get('purchaser_email'))
            shop_name = xstr(self.request.get('shop_name'))
            quantity = xint(self.request.get('quantity'))

            if secret == settings.SECRET_FASTSPRING:
                is_test = self.request.get('is_test')
                if is_test.capitalize() == 'True':
                    order_type = 'test'
                else:
                    order_type = 'purchase'
            else:
                order_type = xstr(self.request.get('order_type'))

            purchaser_user_id = None
            token_purchasebyuser = xstr(self.request.get('referrer'))
            if token_purchasebyuser:
                token = EnkiModelTokenVerify.get_by_token_type(
                    token_purchasebyuser, 'purchasebyuser')
                if token:
                    purchaser_user_id = token.user_id
                    token.key.delete()

            licence_keys = licence_key_bundle.replace('-', '').split()
            for licence_key in licence_keys:
                item = EnkiModelProductKey(licence_key=licence_key,
                                           purchase_price=purchase_price,
                                           order_id=order_id,
                                           product_name=product_name,
                                           purchaser_email=purchaser_email,
                                           shop_name=shop_name,
                                           quantity=quantity,
                                           purchaser_user_id=purchaser_user_id,
                                           order_type=order_type)
                item.put()
        return
Example #52
0
	def post( self ):
		self.cleanup_item()
		self.log_out()
		self.check_CSRF()
		token = self.session.get('tokenregisterauth')
		tokenEntity = EnkiModelTokenVerify.get_by_token_type(token, 'register')
		if tokenEntity:
			submit_type = self.request.get( 'submittype' )
			# Log in with email and password
			if submit_type == 'login':
				email = tokenEntity.email
				tokenEntity.key.delete()
				password = self.request.get( 'password' )
				if self.log_in_with_email( email, password ):
					self.add_infomessage( 'success', MSG.SUCCESS(), MSG.LOGGED_IN())
					self.redirect_to_relevant_page()
				else:
					error_message = MSG.WRONG_EMAIL_OR_PW()
					backoff_timer = self.get_backoff_timer( email )
					if backoff_timer != 0:
						error_message = MSG.TIMEOUT( enki.libutil.format_timedelta( backoff_timer ))
					self.render_tmpl( 'login.html',
									  active_menu = 'login',
									  authhandlers = settings.HANDLERS,
									  email = email,
									  error = error_message )
			elif submit_type == 'recoverpass':
				email = tokenEntity.email
				tokenEntity.key.delete()
				self.redirect( enki.libutil.get_local_url( 'passwordrecover', { 'email': email }))
			# Create a new account using the OAuth provider but without the email
			elif submit_type == 'register':
				email = tokenEntity.email
				tokenEntity.email = ''
				tokenEntity.put()
				self.add_infomessage( 'info', MSG.INFORMATION() , MSG.REGISTRATION_INFO_EMAIL_CANNOT_USE( email ))
				self.redirect( enki.libutil.get_local_url( 'registeroauthconfirm' ))
			else:
				tokenEntity.key.delete()
				self.add_infomessage( 'info', MSG.INFORMATION(), MSG.LOGIN_FAILED())
				self.redirect( enki.libutil.get_local_url( 'home' ))
		else:
			self.abort(404)
Example #53
0
 def post(self, **kwargs):
     self.check_CSRF(),
     token = kwargs['verifytoken']
     tokenEntity = EnkiModelTokenVerify.get_by_token_type(token, 'register')
     if tokenEntity:
         email = tokenEntity.email
         password = self.request.get('password')
         result = enki.libuser.validate_password(password)
         link = enki.libutil.get_local_url('registerconfirm',
                                           {'verifytoken': token})
         if result == enki.libutil.ENKILIB_OK:
             result = self.create_user_from_email_pw(email, password)
             if result == enki.libutil.ENKILIB_OK:
                 self.add_infomessage('success', MSG.SUCCESS(),
                                      MSG.ACCOUNT_CREATED())
                 self.log_in_with_email(email, password)
                 self.redirect_to_relevant_page()
             elif result == enki.handlerbase.ERROR_USER_NOT_CREATED:
                 error_message = MSG.FAIL_REGISTRATION()
                 self.render_tmpl('register.html',
                                  active_menu='register',
                                  email=email,
                                  error=error_message)
         else:
             error_message = ''
             if result == enki.libuser.ERROR_PASSWORD_BLANK:
                 error_message = MSG.MISSING_PW()
             elif result == enki.libuser.ERROR_PASSWORD_TOO_SHORT:
                 length = len(password)
                 error_message = " ".join([
                     MSG.PW_TOO_SHORT(length),
                     MSG.PW_ENSURE_MIN_LENGTH(
                         self.app.config.get('enki').get('user').get(
                             'PASSWORD_LENGTH_MIN'))
                 ])
             self.render_tmpl('registerconfirm.html',
                              active_menu='register',
                              email=email,
                              url=link,
                              error=error_message)
     else:
         self.abort(404)
Example #54
0
	def post( self ):
		secret = xstr( self.request.get( 'secret' ))
		if secret == settings.SECRET_FASTSPRING or enki.libutil.is_debug( ) or settings.ENKI_EMULATE_STORE:

			licence_key_bundle = xstr( self.request.get( 'licence_key' ))
			purchase_price = xstr( self.request.get( 'purchase_price' ))
			order_id = xstr(self.request.get( 'order_id' ))
			product_name = xstr( self.request.get( 'product_name' ))
			purchaser_email = xstr( self.request.get( 'purchaser_email' ))
			shop_name = xstr( self.request.get( 'shop_name' ))
			quantity = xint( self.request.get( 'quantity' ))

			purchaser_user_id = None
			token_purchasebyuser = xstr( self.request.get( 'referrer' ))
			if token_purchasebyuser:
				token = EnkiModelTokenVerify.get_by_token_type( token_purchasebyuser, 'purchasebyuser' )
				if token:
					purchaser_user_id = token.user_id
					token.key.delete()

			is_test = self.request.get( 'is_test' )
			if is_test:
				order_type = 'test'
				if enki.libutil.is_debug() or settings.ENKI_EMULATE_STORE:
					order_type = 'emulated'

			licence_keys = licence_key_bundle.replace( '-', '' ).split()
			for licence_key in licence_keys:
				item = EnkiModelProductKey( licence_key = licence_key,
				                            purchase_price = purchase_price,
				                            order_id = order_id,
				                            product_name = product_name,
				                            purchaser_email = purchaser_email,
				                            shop_name = shop_name,
				                            quantity = quantity,
				                            purchaser_user_id = purchaser_user_id,
				                            order_type = order_type )
				item.put()
		return
Example #55
0
 def post(self, **kwargs):
     self.check_CSRF()
     token = kwargs['verifytoken']
     tokenEntity = EnkiModelTokenVerify.get_by_token_type(
         token, 'passwordchange')
     if tokenEntity:
         email = tokenEntity.email
         user = enki.libuser.get_EnkiUser(email)
         if user:
             password = self.request.get('password')
             result = enki.libuser.set_password(user, password)
             if result == enki.libutil.ENKILIB_OK:
                 enki.libuser.delete_verifytoken_by_email(
                     email, 'passwordchange')
                 self.log_in_with_id(user.key.id(), password)
                 self.add_infomessage('success', MSG.SUCCESS(),
                                      MSG.PASSWORD_SET())
                 self.redirect(enki.libutil.get_local_url('profile'))
                 return
             else:
                 error_message = ''
                 if result == enki.libuser.ERROR_PASSWORD_BLANK:
                     error_message = MSG.MISSING_PW()
                 elif result == enki.libuser.ERROR_PASSWORD_TOO_SHORT:
                     length = len(password)
                     error_message = " ".join([
                         MSG.PW_TOO_SHORT(length),
                         MSG.PW_ENSURE_MIN_LENGTH(
                             self.app.config.get('enki').get('user').get(
                                 'PASSWORD_LENGTH_MIN'))
                     ])
                 self.render_tmpl('passwordrecoverconfirm.html',
                                  error=error_message)
         else:
             self.abort(401)
     else:
         self.abort(404)
Example #56
0
 def get(self):
     token = self.session.get('tokenregisterauth')
     tokenEntity = EnkiModelTokenVerify.get_by_token_type(token, 'register')
     if tokenEntity:
         provider_name, provider_uid = tokenEntity.auth_ids_provider.partition(
             ':')[::2]
         provider_email = tokenEntity.email
         provider_authhandler = ''
         for handler in settings.HANDLERS:
             if handler.get_provider_name() == provider_name:
                 provider_authhandler = handler
         # only display the email/pw login if the user has a password
         email_user_has_pw = enki.libuser.user_has_password_by_email(
             provider_email)
         # list of email user's auth providers
         authhandlers = []
         user = enki.libuser.get_EnkiUser(provider_email)
         for user_provider_uid in user.auth_ids_provider:
             for handler in settings.HANDLERS:
                 if (handler.get_provider_name()
                         in user_provider_uid) and (handler
                                                    not in authhandlers):
                     authhandlers.append(handler)
                     break
         self.render_tmpl(
             'registeroauthwithexistingemail.html',
             active_menu='login',
             token=tokenEntity,
             email=provider_email,
             email_user_has_pw=email_user_has_pw,
             provider_name=provider_name,
             provider_uid=str(provider_uid),
             provider_authhandler=provider_authhandler,
             authhandlers=authhandlers,
         )
     else:
         self.abort(404)
Example #57
0
def delete_verifytoken_by_email( email, type ):
	# delete all verify tokens for a given email and type (cleanup)
	entities = EnkiModelTokenVerify.fetch_keys_by_email_type( email, type )
	if entities:
		ndb.delete_multi( entities )
Example #58
0
    def provider_authenticated_callback(self, loginInfo):
        # We expect the fields of the dictionary to be:
        # - 'provider_name' unique 'pretty' provider name (e.g. google, facebook,...)
        # - 'provider_uid' provider specific (a.k.a "locally unique") user Id, i.e unique to the provider (e.g. the google user id number)
        # - 'email'
        # - 'email_verified'
        # We IGNORE: username, gender (facebook), avatar link, etc.

        # get the verified email from the auth provider
        email = None
        if loginInfo['email'] and loginInfo['email_verified'] == True:
            email = loginInfo['email']
        # get the authId from the auth provider
        auth_id = loginInfo['provider_name'] + ':' + loginInfo['provider_uid']

        if auth_id:
            # Modify existing or create user
            # check if it's an add login method request
            LoginAddToken = EnkiModelTokenVerify.get_by_user_id_state_type(
                self.user_id, loginInfo['provider_name'], 'loginaddconfirm_1')
            if LoginAddToken:
                # Add a login method
                if not EnkiModelUser.exist_by_auth_id(auth_id):
                    # store the new auth prov + id in the session
                    LoginAddToken.state = auth_id
                    LoginAddToken.type = 'loginaddconfirm_2'
                    LoginAddToken.put()
                    self.redirect(
                        enki.libutil.get_local_url('loginaddconfirm'))
                else:
                    self.add_infomessage(
                        MSG.INFORMATION(),
                        MSG.AUTH_PROVIDER_CANNOT_BE_ADDED(str(auth_id)))
                    self.redirect(enki.libutil.get_local_url('accountconnect'))
                return
            else:
                user = self.get_user_from_authid(auth_id, email)
                if user:
                    # Existing authentication method / user
                    if self.is_logged_in() and self.user_id == user.key.id():
                        # Refresh the reauthenticated status
                        self.session['reauth_time'] = datetime.datetime.now()
                        self.add_infomessage(MSG.SUCCESS(),
                                             MSG.REAUTHENTICATED())
                        self.redirect_to_relevant_page()
                        return
                    # Login
                    self.log_in_session_token_create(user)
                    self.add_infomessage(MSG.SUCCESS(), MSG.LOGGED_IN())
                    self.redirect_to_relevant_page()
                else:
                    # New authentication method
                    register_token = EnkiModelTokenVerify.get_by_state_type(
                        auth_id, 'register')
                    if register_token:
                        # If a token already exists, get the token value and update the email
                        token = register_token.token
                        register_token.email = email  # update in case the user changed their email or modified their email access permission
                    else:
                        # Create a new token
                        token = security.generate_random_string(entropy=256)
                        register_token = EnkiModelTokenVerify(token=token,
                                                              email=email,
                                                              state=auth_id,
                                                              type='register')
                    register_token.put()
                    self.session['tokenregisterauth'] = token
                    if EnkiModelUser.exist_by_email(email):
                        self.redirect(
                            enki.libutil.get_local_url(
                                'registeroauthwithexistingemail'))
                    else:
                        self.redirect(
                            enki.libutil.get_local_url('registeroauthconfirm'))
        else:
            self.redirect_to_relevant_page()
Example #59
0
    def post(self):
        if not settings.SECRET_FASTSPRING or enki.libutil.is_debug(
        ) or settings.ENKI_EMULATE_STORE:
            self.check_CSRF()

            product = xstr(self.request.get('product'))
            quantity = xint(self.request.get('quantity'))
            purchase_price = xstr(self.request.get('purchase_price'))
            purchaser_email = xstr(self.request.get('purchaser_email'))
            licence_keys = 'not generated'
            user_id = ''
            emulator_order_id = 'EMULATED_' + webapp2_extras.security.generate_random_string(
                length=10, pool=webapp2_extras.security.DIGITS)

            url = enki.libutil.get_local_url('genlicencefastspring')
            form_fields = {
                'secret': 'pretendsecret',
                'quantity': str(quantity)
            }
            form_data = urllib.urlencode(form_fields)
            result = urlfetch.fetch(url=url,
                                    payload=form_data,
                                    method=urlfetch.POST)
            if result.status_code == 200:
                licence_keys = result.content.replace('-', '')

            referrer = xstr(self.request.get('referrer'))
            token = EnkiModelTokenVerify.get_by_token_type(
                referrer, 'purchasebyuser')
            if token:
                user_id = token.user_id
            licence_key_display = []
            for item in licence_keys.split():
                item_dash = enki.libstore.insert_dashes_5_10(item)
                licence_key_display.append(item_dash)
            self.add_infomessage(
                'info', MSG.INFORMATION(),
                '<h3>FastSpring Store Emulator - Step 1</h3>' +
                '<h4>Emulated purchase details</h4>' + '<ul>' +
                '<li>&lt;EnkiModelProductKey&gt; #{FastSpring variable} = <em>&lt;emulated value&gt;</em></li>'
                + '<li>product_name #{orderItem.productName} = <em>' +
                product + '</em></li>' + '<li>order_id #{order.id} = <em>' +
                emulator_order_id + '</em></li>' +
                '<li>quantity #{orderItem.quantity} = <em>' + xstr(quantity) +
                '</em></li>' +
                '<li>purchase_price #{orderItem.totalUSD} = <em>' +
                purchase_price + '</em></li>' +
                '<li>purchaser_email #{order.customer.email} = <em>' +
                purchaser_email + '</em></li>' +
                '<li>shop_name = <em>Emulator_FastSpring</em></li>' +
                '<li>licence_key #{orderItem.fulfillment.licence.licences.list} = <br><em><b>'
                + '<br>'.join(licence_key_display) + '</b></em></li>' + '</ul>'
                '<h4>Internal data - generated if the purchaser was logged in when they bought the product</h4>'
                + '<ul>' +
                '<li>EnkiModelTokenVerify.user_id = purchaser user_id = <em>' +
                (xstr(user_id) if user_id else 'None') + '</em></li>' +
                '<li>EnkiModelTokenVerify.type purchasebyuser referrer #{order.referrer} = <em>'
                + (xstr(referrer) if referrer else 'None') + '</em></li>' +
                '</ul>')

            url = enki.libutil.get_local_url('ordercompletefastspring')
            form_fields = {
                'licence_key': licence_keys,
                'purchase_price': purchase_price,
                'order_id': emulator_order_id,
                'product_name': product,
                'purchaser_email': purchaser_email,
                'shop_name': 'Emulator_FastSpring',
                'quantity': quantity,
                'referrer': referrer,
                'is_test': True
            }

            form_data = urllib.urlencode(form_fields)
            result = urlfetch.fetch(url=url,
                                    payload=form_data,
                                    method=urlfetch.POST)
            if result.status_code == 200:
                message_view_library = ''
                if self.is_logged_in():
                    message_view_library = '<p><a href="/profile" class="alert-link">View and activate licence keys</a>.</p>'
                self.add_infomessage(
                    'info', MSG.INFORMATION(),
                    '<h3>FastSpring Store Emulator - Step 2</h3><p>Purchase records created<p>'
                    + message_view_library)
            else:
                self.add_infomessage(
                    'warning', MSG.WARNING(),
                    '<h3>FastSpring Store Emulator - Step 2 FAILED: Purchase records not created</h3>'
                )

            self.redirect_to_relevant_page()
Example #60
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