示例#1
0
	def get_or_create_user_from_authid( self, auth_id, email = None, allow_create = True ):
		user = None
		user_with_same_auth_id = enki.libuser.get_EnkiUser_by_auth_id( auth_id )
		if user_with_same_auth_id:
			# if a user with the same auth id already exists but has a blank email: add the email to the account.
			# note: if the account has an email or they've removed their email, we don't overwrite it.
			if email and user_with_same_auth_id.email == None:
				user = self.set_email( email, user_with_same_auth_id.key.id())
			else:
				user = user_with_same_auth_id
		if not user and allow_create:
			# create a new user
			user = EnkiModelUser( email = email, auth_ids_provider = [ auth_id ])
			user.put()
		return user
示例#2
0
	def set_email( self, email, user_id = None ):
	# set or change a user's email address
		user_key = enki.libuser.get_key_EnkiUser( email )
		if email and (not user_key or user_key.id() == user_id):
		# if the email doesn't exist in the db or already belongs to the user:
			if user_id == None:
				# create a new user
				user = EnkiModelUser( email = email )
			else:
				# update existing user
				user = ndb.Key( EnkiModelUser, user_id ).get()
				user.email = email
			user.put()
			return user
		else:
			return None
示例#3
0
 def set_email(self, email, user_id=None):
     # set or change a user's email address
     user_key = enki.libuser.get_key_EnkiUser(email)
     if email and (not user_key or user_key.id() == user_id):
         # if the email doesn't exist in the db or already belongs to the user:
         if user_id == None:
             # create a new user
             user = EnkiModelUser(email=email)
         else:
             # update existing user
             user = ndb.Key(EnkiModelUser, user_id).get()
             user.email = email
         user.put()
         return user
     else:
         return None
示例#4
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())
示例#5
0
 def get_or_create_user_from_authid(self,
                                    auth_id,
                                    email=None,
                                    allow_create=True):
     user = None
     user_with_same_auth_id = EnkiModelUser.get_by_auth_id(auth_id)
     if user_with_same_auth_id:
         # if a user with the same auth id already exists but has a blank email: add the email to the account.
         # note: if the account has an email or they've removed their email, we don't overwrite it.
         if email and user_with_same_auth_id.email == None:
             user = self.set_email(email, user_with_same_auth_id.key.id())
         else:
             user = user_with_same_auth_id
     if not user and allow_create:
         # create a new user
         user = EnkiModelUser(email=email, auth_ids_provider=[auth_id])
         user.put()
     return user
示例#6
0
 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
示例#7
0
	def get_data( self, handler ):
		useridnumber = handler.request.route_kwargs.get( 'useridnumber' )
		data = {}
		data[ 'posts' ] = ''
		data[ 'is_author' ] = False
		if handler.ensure_is_logged_in():
			if useridnumber.isdigit() and EnkiModelUser.get_by_id( int( useridnumber ) ):
				posts = EnkiModelPost.get_author_posts( useridnumber )
				if posts:
					data[ 'posts' ] = posts
					data[ 'is_author' ] = True if handler.user_id == posts.author_data.user_id else False
		return data
示例#8
0
 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
示例#9
0
 def set_auth_id(self, auth_id, user_id):
     # add a new auth Id to an existing account
     user_has_same_auth_id = EnkiModelUser.exist_by_auth_id(auth_id)
     if not user_has_same_auth_id:
         user = ndb.Key(EnkiModelUser, user_id).get()
         if user:
             # add the auth_id to the account
             user.auth_ids_provider.append(auth_id)
             user.put()
             return user
         else:
             return None
     else:
         return None
示例#10
0
	def get_or_create_user_from_authid( self, authId, email = None, allow_create = False ):
		user = None
		user_with_same_auth_id = EnkiModelUser.query( EnkiModelUser.auth_ids_provider == authId ).get()
		if user_with_same_auth_id:
			# if a user with the same auth id already exists but has a blank email: add the email to the account.
			# note: if the account has an email, we don't overwrite it.
			if email and user_with_same_auth_id.email == None:
				user = self.set_email( email, user_with_same_auth_id.key.id())
			else:
				user = user_with_same_auth_id
		elif email:
			# no user with the same auth id, but there is a user with the same email: add the auth id to the account
			user_with_same_email = EnkiModelUser.query( EnkiModelUser.email == email ).get()
			if user_with_same_email:
				colon = authId.find( ':' )
				provider_name = str( authId[ :colon ])
				provider_uid = str( authId[ colon+1: ])
				self.send_email( email, MSG.SEND_EMAIL_AUTH_NEW_SUBJECT(), MSG.SEND_EMAIL_AUTH_NEW_BODY( enki.libutil.get_local_url( 'profile' ), provider_name, provider_uid ) )
				user = self.set_authid( authId, user_with_same_email.key.id())
		if not user and allow_create:
			# create a new user
			user = EnkiModelUser( email = email, auth_ids_provider = [ authId ])
			user.put()
		return user
示例#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())
示例#12
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
示例#13
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
示例#14
0
文件: libuser.py 项目: charlf/enkiWS
def get_EnkiUser(email):
    entity = EnkiModelUser.query(EnkiModelUser.email == email).get()
    if entity:
        return entity
    else:
        return None
示例#15
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()
示例#16
0
def get_EnkiUser( email ):
	entity = EnkiModelUser.query( EnkiModelUser.email == email ).get()
	return entity
示例#17
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
示例#18
0
def get_key_EnkiUser( email ):
	key = EnkiModelUser.query( EnkiModelUser.email == email ).get( keys_only = True )
	return key
示例#19
0
def exist_EnkiUser( email ):
	count = EnkiModelUser.query( EnkiModelUser.email == email ).count( 1 )
	return count > 0
示例#20
0
文件: libuser.py 项目: charlf/enkiWS
def exist_EnkiUser(email):
    count = EnkiModelUser.query(EnkiModelUser.email == email).count(1)
    if count:
        return True
    else:
        return False
示例#21
0
文件: libuser.py 项目: charlf/enkiWS
def get_key_EnkiUser(email):
    key = EnkiModelUser.query(EnkiModelUser.email == email).get(keys_only=True)
    if key:
        return key
    else:
        return None
示例#22
0
def get_EnkiUser_by_auth_id( auth_id ):
	entity = EnkiModelUser.query( EnkiModelUser.auth_ids_provider == auth_id ).get()
	return entity
示例#23
0
def exist_Auth_Id( auth_id ):
	count = EnkiModelUser.query( EnkiModelUser.auth_ids_provider == auth_id ).count( 1 )
	return count > 0