示例#1
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
示例#2
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
示例#3
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()
示例#4
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