def ThreadedFunction (from_email="",username="",title="",cgac_code="",userEmail="" ,link="") :
            """
            This inner function sends emails in a new thread as there could be lots of admins

            from_email -- (string) the from email address
            username -- (string) the name of the  user
            title  --   (string) the title of the  user
            agency -- (string) the agency of the  user
            userEmail -- (string) the email of the user
            link  -- (string) the broker email link
            """
            threadedDatabase =  UserHandler()
            try:
                agency_name = self.interfaces.validationDb.getAgencyName(cgac_code)
                agency_name = "Unknown" if agency_name is None else agency_name
                for user in threadedDatabase.getUsersByType("website_admin"):
                    emailTemplate = {'[REG_NAME]': username, '[REG_TITLE]':title, '[REG_AGENCY_NAME]':agency_name,
                                     '[REG_CGAC_CODE]': cgac_code,'[REG_EMAIL]' : userEmail,'[URL]':link}
                    newEmail = sesEmail(user.email, system_email,templateType="account_creation",parameters=emailTemplate,database=threadedDatabase)
                    newEmail.send()
                for user in threadedDatabase.getUsersByType("agency_admin"):
                    if user.cgac_code == cgac_code:
                        emailTemplate = {'[REG_NAME]': username, '[REG_TITLE]': title, '[REG_AGENCY_NAME]': agency_name,
                             '[REG_CGAC_CODE]': cgac_code,'[REG_EMAIL]': userEmail, '[URL]': link}
                        newEmail = sesEmail(user.email, system_email, templateType="account_creation", parameters=emailTemplate,
                                database=threadedDatabase)
                        newEmail.send()

            finally:
                InterfaceHolder.closeOne(threadedDatabase)
Exemple #2
0
    def changeStatus(self, system_email):
        """

        Changes status for specified user.  Associated request body should have keys 'uid' and 'new_status'

        arguments:

        system_email  -- (string) the emaily to send emails from

        return the reponse object with a success message

        """
        requestDict = RequestDictionary(self.request)
        if (not (requestDict.exists("uid")
                 and requestDict.exists("new_status"))):
            # Missing a required field, return 400
            exc = ResponseException(
                "Request body must include uid and new_status",
                StatusCode.CLIENT_ERROR)
            return JsonResponse.error(exc, exc.status)

        # Find user that matches specified uid
        user = self.interfaces.userDb.getUserByUID(
            int(requestDict.getValue("uid")))

        if (user.email == None):
            return JsonResponse.error(
                ResponseException("User does not have a defined email",
                                  StatusCode.INTERNAL_ERROR),
                StatusCode.INTERNAL_ERROR)

        #check if the user is waiting
        if (self.interfaces.userDb.checkStatus(user, "awaiting_approval")):
            if (requestDict.getValue("new_status") == "approved"):
                # Grant agency_user permission to newly approved users
                self.interfaces.userDb.grantPermission(user, "agency_user")
                link = AccountHandler.FRONT_END
                emailTemplate = {'[URL]': link, '[EMAIL]': system_email}
                newEmail = sesEmail(user.email,
                                    system_email,
                                    templateType="account_approved",
                                    parameters=emailTemplate,
                                    database=self.interfaces.userDb)
                newEmail.send()
            elif (requestDict.getValue("new_status") == "denied"):
                emailTemplate = {}
                newEmail = sesEmail(user.email,
                                    system_email,
                                    templateType="account_rejected",
                                    parameters=emailTemplate,
                                    database=self.interfaces.userDb)
                newEmail.send()
        # Change user's status
        self.interfaces.userDb.changeStatus(user,
                                            requestDict.getValue("new_status"))
        return JsonResponse.create(StatusCode.OK,
                                   {"message": "Status change successful"})
Exemple #3
0
        def ThreadedFunction(from_email="",
                             username="",
                             title="",
                             cgac_code="",
                             userEmail="",
                             link=""):
            """
            This inner function sends emails in a new thread as there could be lots of admins

            from_email -- (string) the from email address
            username -- (string) the name of the  user
            title  --   (string) the title of the  user
            agency -- (string) the agency of the  user
            userEmail -- (string) the email of the user
            link  -- (string) the broker email link
            """
            threadedDatabase = UserHandler()
            try:
                agency_name = self.interfaces.validationDb.getAgencyName(
                    cgac_code)
                agency_name = "Unknown" if agency_name is None else agency_name
                for user in threadedDatabase.getUsersByType("website_admin"):
                    emailTemplate = {
                        '[REG_NAME]': username,
                        '[REG_TITLE]': title,
                        '[REG_AGENCY_NAME]': agency_name,
                        '[REG_CGAC_CODE]': cgac_code,
                        '[REG_EMAIL]': userEmail,
                        '[URL]': link
                    }
                    newEmail = sesEmail(user.email,
                                        system_email,
                                        templateType="account_creation",
                                        parameters=emailTemplate,
                                        database=threadedDatabase)
                    newEmail.send()
                for user in threadedDatabase.getUsersByType("agency_admin"):
                    if user.cgac_code == cgac_code:
                        emailTemplate = {
                            '[REG_NAME]': username,
                            '[REG_TITLE]': title,
                            '[REG_AGENCY_NAME]': agency_name,
                            '[REG_CGAC_CODE]': cgac_code,
                            '[REG_EMAIL]': userEmail,
                            '[URL]': link
                        }
                        newEmail = sesEmail(user.email,
                                            system_email,
                                            templateType="account_creation",
                                            parameters=emailTemplate,
                                            database=threadedDatabase)
                        newEmail.send()

            finally:
                threadedDatabase.close()
        def ThreadedFunction(from_email="",
                             username="",
                             title="",
                             agency="",
                             userEmail="",
                             link=""):
            """
            This inner function sends emails in a new thread as there could be lots of admins

            from_email -- (string) the from email address
            username -- (string) the name of the  user
            title  --   (string) the title of the  user
            agency -- (string) the agency of the  user
            userEmail -- (string) the email of the user
            link  -- (string) the broker email link
            """
            threadedDatabase = UserHandler()
            try:
                for user in threadedDatabase.getUsersByType("website_admin"):
                    emailTemplate = {
                        '[REG_NAME]': username,
                        '[REG_TITLE]': title,
                        '[REG_AGENCY]': agency,
                        '[REG_EMAIL]': userEmail,
                        '[URL]': link
                    }
                    newEmail = sesEmail(user.email,
                                        system_email,
                                        templateType="account_creation",
                                        parameters=emailTemplate,
                                        database=threadedDatabase)
                    newEmail.send()
            finally:
                InterfaceHolder.closeOne(threadedDatabase)
    def resetPassword(self,system_email,session):
        """

        Remove old password and email user a token to set a new password.  Request should have key "email"

        arguments:

        system_email  -- (string) email used to send messages
        session  -- (Session) object from flask

        """
        requestDict = RequestDictionary(self.request)
        if(not (requestDict.exists("email"))):
            # Don't have the keys we need in request
            exc = ResponseException("Reset password route requires key 'email'",StatusCode.CLIENT_ERROR)
            return JsonResponse.error(exc,exc.status)
        # Get user object
        try:
            user = self.interfaces.userDb.getUserByEmail(requestDict.getValue("email"))
        except Exception as e:
            exc = ResponseException("Unknown Error",StatusCode.CLIENT_ERROR,ValueError)
            return JsonResponse.error(exc,exc.status)

        LoginSession.logout(session)
        self.interfaces.userDb.session.commit()
        email = requestDict.getValue("email")
        # Send email with token
        emailToken = sesEmail.createToken(email,self.interfaces.userDb,"password_reset")
        link= "".join([ AccountHandler.FRONT_END,'#/forgotpassword/',emailToken])
        emailTemplate = { '[URL]':link}
        newEmail = sesEmail(user.email, system_email,templateType="reset_password",parameters=emailTemplate,database=self.interfaces.userDb)
        newEmail.send()
        # Return success message
        return JsonResponse.create(StatusCode.OK,{"message":"Password reset"})
    def createEmailConfirmation(self,system_email,session):
        """

        Creates user record and email

        arguments:

        system_email  -- (string) email used to send messages
        session  -- (Session) object from flask

        """
        requestFields = RequestDictionary(self.request)
        if(not requestFields.exists("email")):
            exc = ResponseException("Request body must include email", StatusCode.CLIENT_ERROR)
            return JsonResponse.error(exc,exc.status)
        email = requestFields.getValue("email")
        if( not re.match("[^@]+@[^@]+\.[^@]+",email)) :
            return JsonResponse.error(ValueError("Invalid Email Format"),StatusCode.CLIENT_ERROR)
        try :
            user = self.interfaces.userDb.getUserByEmail(requestFields.getValue("email"))
        except ResponseException as e:
            self.interfaces.userDb.addUnconfirmedEmail(email)
        else:
            if(not (user.user_status_id == self.interfaces.userDb.getUserStatusId("awaiting_confirmation") or user.user_status_id == self.interfaces.userDb.getUserStatusId("email_confirmed"))):
                exc = ResponseException("User already registered", StatusCode.CLIENT_ERROR)
                return JsonResponse.error(exc,exc.status)
        emailToken = sesEmail.createToken(email,self.interfaces.userDb,"validate_email")
        link= "".join([AccountHandler.FRONT_END,'#/registration/',emailToken])
        emailTemplate = {'[USER]': email, '[URL]':link}
        newEmail = sesEmail(email, system_email,templateType="validate_email",parameters=emailTemplate,database=self.interfaces.userDb)
        newEmail.send()
        return JsonResponse.create(StatusCode.OK,{"message":"Email Sent"})
Exemple #7
0
    def sendResetPasswordEmail(self,
                               user,
                               system_email,
                               email=None,
                               unlock_user=False):
        if email is None:
            email = user.email

        # User must be approved and active to reset password
        if user.user_status_id != self.interfaces.userDb.getUserStatusId(
                "approved"):
            raise ResponseException(
                "User must be approved before resetting password",
                StatusCode.CLIENT_ERROR)
        elif not unlock_user and not user.is_active:
            raise ResponseException("User is locked, cannot reset password",
                                    StatusCode.CLIENT_ERROR)

        # If unlocking a user, wipe out current password
        if unlock_user:
            UserHandler().clearPassword(user)

        self.interfaces.userDb.session.commit()
        # Send email with token
        emailToken = sesEmail.createToken(email, "password_reset")
        link = "".join(
            [AccountHandler.FRONT_END, '#/forgotpassword/', emailToken])
        emailTemplate = {'[URL]': link}
        templateType = "unlock_account" if unlock_user else "reset_password"
        newEmail = sesEmail(user.email,
                            system_email,
                            templateType=templateType,
                            parameters=emailTemplate,
                            database=self.interfaces.userDb)
        newEmail.send()
    def changeStatus(self,system_email):
        """

        Changes status for specified user.  Associated request body should have keys 'uid' and 'new_status'

        arguments:

        system_email  -- (string) the emaily to send emails from

        return the reponse object with a success message

        """
        requestDict = RequestDictionary(self.request)
        if(not (requestDict.exists("uid") and requestDict.exists("new_status"))):
            # Missing a required field, return 400
            exc = ResponseException("Request body must include uid and new_status", StatusCode.CLIENT_ERROR)
            return JsonResponse.error(exc,exc.status)

        # Find user that matches specified uid
        user = self.interfaces.userDb.getUserByUID(int(requestDict.getValue("uid")))

        if(user.email == None):
            return JsonResponse.error(ResponseException("User does not have a defined email",StatusCode.INTERNAL_ERROR),StatusCode.INTERNAL_ERROR)

        #check if the user is waiting
        if(self.interfaces.userDb.checkStatus(user,"awaiting_approval")):
            if(requestDict.getValue("new_status") == "approved"):
                # Grant agency_user permission to newly approved users
                self.interfaces.userDb.grantPermission(user,"agency_user")
                link=  AccountHandler.FRONT_END
                emailTemplate = { '[URL]':link,'[EMAIL]':system_email}
                newEmail = sesEmail(user.email, system_email,templateType="account_approved",parameters=emailTemplate,database=self.interfaces.userDb)
                newEmail.send()
            elif (requestDict.getValue("new_status") == "denied"):
                emailTemplate = {}
                newEmail = sesEmail(user.email, system_email,templateType="account_rejected",parameters=emailTemplate,database=self.interfaces.userDb)
                newEmail.send()
        # Change user's status
        self.interfaces.userDb.changeStatus(user,requestDict.getValue("new_status"))
        return JsonResponse.create(StatusCode.OK,{"message":"Status change successful"})
    def create_email_confirmation(self,system_email):
        """

        Creates user record and email

        arguments:

        system_email  -- (string) email used to send messages

        """
        sess = GlobalDB.db().session
        request_fields = RequestDictionary.derive(self.request)
        try:
            if 'email' not in request_fields:
                raise ResponseException(
                    "Request body must include email", StatusCode.CLIENT_ERROR)
            email = request_fields['email']
            if not re.match("[^@]+@[^@]+\.[^@]+",email):
                raise ValueError("Invalid Email Format")
        except (ResponseException, ValueError) as exc:
            return JsonResponse.error(exc, StatusCode.CLIENT_ERROR)

        try :
            user = sess.query(User).filter(
                func.lower(User.email) == func.lower(request_fields['email'])
            ).one()
        except NoResultFound:
            # Create user with specified email if none is found
            user = User(email=email)
            user.user_status_id = USER_STATUS_DICT["awaiting_confirmation"]
            user.permissions = 0
            sess.add(user)
            sess.commit()
        else:
            try:
                good_statuses = (USER_STATUS_DICT["awaiting_confirmation"],
                                 USER_STATUS_DICT["email_confirmed"])
                if user.user_status_id not in good_statuses:
                    raise ResponseException(
                        "User already registered", StatusCode.CLIENT_ERROR)
            except ResponseException as exc:
                return JsonResponse.error(exc, exc.status)
        email_token = sesEmail.createToken(email, "validate_email")
        link= "".join([AccountHandler.FRONT_END,'#/registration/',email_token])
        email_template = {'[USER]': email, '[URL]':link}
        new_email = sesEmail(email, system_email,templateType="validate_email",parameters=email_template)
        new_email.send()
        return JsonResponse.create(StatusCode.OK,{"message":"Email Sent"})
Exemple #10
0
    def emailUsers(self, system_email, session):
        """ Send email notification to list of users """
        requestDict = RequestDictionary(self.request)
        if not (requestDict.exists("users")
                and requestDict.exists("submission_id")
                and requestDict.exists("email_template")):
            exc = ResponseException(
                "Email users route requires users, email_template, and submission_id",
                StatusCode.CLIENT_ERROR)
            return JsonResponse.error(exc, exc.status)

        uid = session["name"]
        current_user = self.interfaces.userDb.getUserByUID(uid)

        user_ids = requestDict.getValue("users")
        submission_id = requestDict.getValue("submission_id")
        # Check if submission id is valid
        self.jobManager.getSubmissionById(submission_id)

        template_type = requestDict.getValue("email_template")
        # Check if email template type is valid
        self.userManager.getEmailTemplate(template_type)

        users = []

        link = "".join(
            [AccountHandler.FRONT_END, '#/reviewData/',
             str(submission_id)])
        emailTemplate = {
            '[REV_USER_NAME]': current_user.name,
            '[REV_URL]': link
        }

        for user_id in user_ids:
            # Check if user id is valid, if so add User object to array
            users.append(self.userManager.getUserByUID(user_id))

        for user in users:
            newEmail = sesEmail(user.email,
                                system_email,
                                templateType=template_type,
                                parameters=emailTemplate,
                                database=UserHandler())
            newEmail.send()

        return JsonResponse.create(StatusCode.OK,
                                   {"message": "Emails successfully sent"})
    def resetPassword(self, system_email, session):
        """

        Remove old password and email user a token to set a new password.  Request should have key "email"

        arguments:

        system_email  -- (string) email used to send messages
        session  -- (Session) object from flask

        """
        requestDict = RequestDictionary(self.request)
        if (not (requestDict.exists("email"))):
            # Don't have the keys we need in request
            exc = ResponseException(
                "Reset password route requires key 'email'",
                StatusCode.CLIENT_ERROR)
            return JsonResponse.error(exc, exc.status)
        # Get user object
        try:
            user = self.interfaces.userDb.getUserByEmail(
                requestDict.getValue("email"))
        except Exception as e:
            exc = ResponseException("Unknown Error", StatusCode.CLIENT_ERROR,
                                    ValueError)
            return JsonResponse.error(exc, exc.status)

        LoginSession.logout(session)
        self.interfaces.userDb.session.commit()
        email = requestDict.getValue("email")
        # Send email with token
        emailToken = sesEmail.createToken(email, self.interfaces.userDb,
                                          "password_reset")
        link = "".join(
            [AccountHandler.FRONT_END, '#/forgotpassword/', emailToken])
        emailTemplate = {'[URL]': link}
        newEmail = sesEmail(user.email,
                            system_email,
                            templateType="reset_password",
                            parameters=emailTemplate,
                            database=self.interfaces.userDb)
        newEmail.send()
        # Return success message
        return JsonResponse.create(StatusCode.OK,
                                   {"message": "Password reset"})
    def createEmailConfirmation(self, system_email, session):
        """

        Creates user record and email

        arguments:

        system_email  -- (string) email used to send messages
        session  -- (Session) object from flask

        """
        requestFields = RequestDictionary(self.request)
        if (not requestFields.exists("email")):
            exc = ResponseException("Request body must include email",
                                    StatusCode.CLIENT_ERROR)
            return JsonResponse.error(exc, exc.status)
        email = requestFields.getValue("email")
        if (not re.match("[^@]+@[^@]+\.[^@]+", email)):
            return JsonResponse.error(ValueError("Invalid Email Format"),
                                      StatusCode.CLIENT_ERROR)
        try:
            user = self.interfaces.userDb.getUserByEmail(
                requestFields.getValue("email"))
        except ResponseException as e:
            self.interfaces.userDb.addUnconfirmedEmail(email)
        else:
            if (not (user.user_status_id == self.interfaces.userDb.
                     getUserStatusId("awaiting_confirmation")
                     or user.user_status_id == self.interfaces.userDb.
                     getUserStatusId("email_confirmed"))):
                exc = ResponseException("User already registered",
                                        StatusCode.CLIENT_ERROR)
                return JsonResponse.error(exc, exc.status)
        emailToken = sesEmail.createToken(email, self.interfaces.userDb,
                                          "validate_email")
        link = "".join(
            [AccountHandler.FRONT_END, '#/registration/', emailToken])
        emailTemplate = {'[USER]': email, '[URL]': link}
        newEmail = sesEmail(email,
                            system_email,
                            templateType="validate_email",
                            parameters=emailTemplate,
                            database=self.interfaces.userDb)
        newEmail.send()
        return JsonResponse.create(StatusCode.OK, {"message": "Email Sent"})
        def ThreadedFunction (from_email="",username="",title="",agency="",userEmail="" ,link="") :
            """
            This inner function sends emails in a new thread as there could be lots of admins

            from_email -- (string) the from email address
            username -- (string) the name of the  user
            title  --   (string) the title of the  user
            agency -- (string) the agency of the  user
            userEmail -- (string) the email of the user
            link  -- (string) the broker email link
            """
            threadedDatabase =  UserHandler()
            try:
                for user in threadedDatabase.getUsersByType("website_admin") :
                    emailTemplate = {'[REG_NAME]': username, '[REG_TITLE]':title, '[REG_AGENCY]':agency,'[REG_EMAIL]' : userEmail,'[URL]':link}
                    newEmail = sesEmail(user.email, system_email,templateType="account_creation",parameters=emailTemplate,database=threadedDatabase)
                    newEmail.send()
            finally:
                InterfaceHolder.closeOne(threadedDatabase)
        def ThreadedFunction (username="", title="", cgac_code="", user_email="" , link="") :
            """
            This inner function sends emails in a new thread as there could be lots of admins

            username -- (string) the name of the  user
            title  --   (string) the title of the  user
            cgac_code -- (string) the agency of the  user
            user_email -- (string) the email of the user
            link  -- (string) the broker email link
            """
            agency_name = sess.query(CGAC.agency_name).\
                filter(CGAC.cgac_code == cgac_code).\
                one_or_none()
            agency_name = "Unknown" if agency_name is None else agency_name
            for user in sess.query(User).filter_by(permission_type_id=PERMISSION_TYPE_DICT['website_admin']):
                email_template = {'[REG_NAME]': username, '[REG_TITLE]':title, '[REG_AGENCY_NAME]':agency_name,
                                 '[REG_CGAC_CODE]': cgac_code,'[REG_EMAIL]' : user_email,'[URL]':link}
                new_email = sesEmail(user.email, system_email,templateType="account_creation",parameters=email_template)
                new_email.send()
    def email_users(self, system_email, session):
        """ Send email notification to list of users """
        sess = GlobalDB.db().session
        request_dict = RequestDictionary.derive(self.request)
        required = ('users', 'submission_id', 'email_template')
        try:
            if any(field not in request_dict for field in required):
                raise ResponseException(
                    "Email users route requires users, email_template, and "
                    "submission_id", StatusCode.CLIENT_ERROR
                )
        except ResponseException as exc:
            return JsonResponse.error(exc, exc.status)

        current_user = sess.query(User).filter(User.user_id == session["name"]).one()

        user_ids = request_dict['users']
        submission_id = request_dict['submission_id']
        # Check if submission id is valid
        sess.query(Submission).filter_by(submission_id=submission_id).one()

        template_type = request_dict['email_template']
        # Check if email template type is valid
        get_email_template(template_type)

        users = []

        link = "".join([AccountHandler.FRONT_END, '#/reviewData/', str(submission_id)])
        email_template = {'[REV_USER_NAME]': current_user.name, '[REV_URL]': link}

        for user_id in user_ids:
            # Check if user id is valid, if so add User object to array
            users.append(sess.query(User).filter(User.user_id == user_id).one())

        for user in users:
            new_email = sesEmail(user.email, system_email, templateType=template_type, parameters=email_template)
            new_email.send()

        return JsonResponse.create(StatusCode.OK, {"message": "Emails successfully sent"})
    def sendResetPasswordEmail(self, user, system_email, email=None, unlock_user=False):
        if email is None:
            email = user.email

        # User must be approved and active to reset password
        if user.user_status_id != self.interfaces.userDb.getUserStatusId("approved"):
            raise ResponseException("User must be approved before resetting password", StatusCode.CLIENT_ERROR)
        elif not unlock_user and not user.is_active:
            raise ResponseException("User is locked, cannot reset password", StatusCode.CLIENT_ERROR)

        # If unlocking a user, wipe out current password
        if unlock_user:
            UserHandler().clearPassword(user)

        self.interfaces.userDb.session.commit()
        # Send email with token
        emailToken = sesEmail.createToken(email, self.interfaces.userDb, "password_reset")
        link = "".join([AccountHandler.FRONT_END, '#/forgotpassword/', emailToken])
        emailTemplate = {'[URL]': link}
        templateType = "unlock_account" if unlock_user else "reset_password"
        newEmail = sesEmail(user.email, system_email, templateType=templateType,
                            parameters=emailTemplate, database=self.interfaces.userDb)
        newEmail.send()
    def send_reset_password_email(self, user, system_email, email=None, unlock_user=False):
        sess = GlobalDB.db().session
        if email is None:
            email = user.email

        # User must be approved and active to reset password
        if user.user_status_id != USER_STATUS_DICT["approved"]:
            raise ResponseException("User must be approved before resetting password", StatusCode.CLIENT_ERROR)
        elif not unlock_user and not user.is_active:
            raise ResponseException("User is locked, cannot reset password", StatusCode.CLIENT_ERROR)

        # If unlocking a user, wipe out current password
        if unlock_user:
            user.salt = None
            user.password_hash = None

        sess.commit()
        # Send email with token
        email_token = sesEmail.createToken(email, "password_reset")
        link = "".join([AccountHandler.FRONT_END, '#/forgotpassword/', email_token])
        email_template = {'[URL]': link}
        template_type = "unlock_account" if unlock_user else "reset_password"
        new_email = sesEmail(user.email, system_email, templateType=template_type, parameters=email_template)
        new_email.send()
Exemple #18
0
    def register(self, system_email, session):
        """

        Save user's information into user database.  Associated request body should have keys 'email', 'name', 'cgac_code', and 'title'

        arguments:

        system_email  -- (string) email used to send messages
        session  -- (Session) object from flask


        Returns message that registration is successful or error message that fields are not valid

        """
        def ThreadedFunction(from_email="",
                             username="",
                             title="",
                             cgac_code="",
                             userEmail="",
                             link=""):
            """
            This inner function sends emails in a new thread as there could be lots of admins

            from_email -- (string) the from email address
            username -- (string) the name of the  user
            title  --   (string) the title of the  user
            agency -- (string) the agency of the  user
            userEmail -- (string) the email of the user
            link  -- (string) the broker email link
            """
            threadedDatabase = UserHandler()
            try:
                agency_name = self.interfaces.validationDb.getAgencyName(
                    cgac_code)
                agency_name = "Unknown" if agency_name is None else agency_name
                for user in threadedDatabase.getUsersByType("website_admin"):
                    emailTemplate = {
                        '[REG_NAME]': username,
                        '[REG_TITLE]': title,
                        '[REG_AGENCY_NAME]': agency_name,
                        '[REG_CGAC_CODE]': cgac_code,
                        '[REG_EMAIL]': userEmail,
                        '[URL]': link
                    }
                    newEmail = sesEmail(user.email,
                                        system_email,
                                        templateType="account_creation",
                                        parameters=emailTemplate,
                                        database=threadedDatabase)
                    newEmail.send()
                for user in threadedDatabase.getUsersByType("agency_admin"):
                    if user.cgac_code == cgac_code:
                        emailTemplate = {
                            '[REG_NAME]': username,
                            '[REG_TITLE]': title,
                            '[REG_AGENCY_NAME]': agency_name,
                            '[REG_CGAC_CODE]': cgac_code,
                            '[REG_EMAIL]': userEmail,
                            '[URL]': link
                        }
                        newEmail = sesEmail(user.email,
                                            system_email,
                                            templateType="account_creation",
                                            parameters=emailTemplate,
                                            database=threadedDatabase)
                        newEmail.send()

            finally:
                threadedDatabase.close()

        requestFields = RequestDictionary(self.request)
        if (not (requestFields.exists("email") and requestFields.exists("name")
                 and requestFields.exists("cgac_code")
                 and requestFields.exists("title")
                 and requestFields.exists("password"))):
            # Missing a required field, return 400
            exc = ResponseException(
                "Request body must include email, name, cgac_code, title, and password",
                StatusCode.CLIENT_ERROR)
            return JsonResponse.error(exc, exc.status)

        if (not self.checkPassword(requestFields.getValue("password"))):
            exc = ResponseException("Invalid Password",
                                    StatusCode.CLIENT_ERROR)
            return JsonResponse.error(exc, exc.status)
        # Find user that matches specified email
        user = self.interfaces.userDb.getUserByEmail(
            requestFields.getValue("email"))
        # Check that user's status is before submission of registration
        if not (self.interfaces.userDb.checkStatus(user,
                                                   "awaiting_confirmation") or
                self.interfaces.userDb.checkStatus(user, "email_confirmed")):
            # Do not allow duplicate registrations
            exc = ResponseException("User already registered",
                                    StatusCode.CLIENT_ERROR)
            return JsonResponse.error(exc, exc.status)
        # Add user info to database
        self.interfaces.userDb.addUserInfo(user,
                                           requestFields.getValue("name"),
                                           requestFields.getValue("cgac_code"),
                                           requestFields.getValue("title"))
        self.interfaces.userDb.setPassword(user,
                                           requestFields.getValue("password"),
                                           self.bcrypt)

        userLink = "".join(
            [AccountHandler.FRONT_END, '#/login?redirect=/admin'])
        # Send email to approver list
        emailThread = Thread(target=ThreadedFunction,
                             kwargs=dict(from_email=system_email,
                                         username=user.name,
                                         title=user.title,
                                         cgac_code=user.cgac_code,
                                         userEmail=user.email,
                                         link=userLink))
        emailThread.start()

        #email user
        link = AccountHandler.FRONT_END
        emailTemplate = {'[EMAIL]': system_email}
        newEmail = sesEmail(user.email,
                            system_email,
                            templateType="account_creation_user",
                            parameters=emailTemplate,
                            database=self.interfaces.userDb)
        newEmail.send()

        # Logout and delete token
        LoginSession.logout(session)
        self.interfaces.userDb.deleteToken(session["token"])
        # Mark user as awaiting approval
        self.interfaces.userDb.changeStatus(user, "awaiting_approval")
        return JsonResponse.create(StatusCode.OK,
                                   {"message": "Registration successful"})
    def register(self,system_email,session):
        """

        Save user's information into user database.  Associated request body should have keys 'email', 'name', 'agency', and 'title'

        arguments:

        system_email  -- (string) email used to send messages
        session  -- (Session) object from flask


        Returns message that registration is successful or error message that fields are not valid

        """
        def ThreadedFunction (from_email="",username="",title="",agency="",userEmail="" ,link="") :
            """
            This inner function sends emails in a new thread as there could be lots of admins

            from_email -- (string) the from email address
            username -- (string) the name of the  user
            title  --   (string) the title of the  user
            agency -- (string) the agency of the  user
            userEmail -- (string) the email of the user
            link  -- (string) the broker email link
            """
            threadedDatabase =  UserHandler()
            try:
                for user in threadedDatabase.getUsersByType("website_admin") :
                    emailTemplate = {'[REG_NAME]': username, '[REG_TITLE]':title, '[REG_AGENCY]':agency,'[REG_EMAIL]' : userEmail,'[URL]':link}
                    newEmail = sesEmail(user.email, system_email,templateType="account_creation",parameters=emailTemplate,database=threadedDatabase)
                    newEmail.send()
            finally:
                InterfaceHolder.closeOne(threadedDatabase)

        requestFields = RequestDictionary(self.request)
        if(not (requestFields.exists("email") and requestFields.exists("name") and requestFields.exists("agency") and requestFields.exists("title") and requestFields.exists("password"))):
            # Missing a required field, return 400
            exc = ResponseException("Request body must include email, name, agency, title, and password", StatusCode.CLIENT_ERROR)
            return JsonResponse.error(exc,exc.status)

        if(not self.checkPassword(requestFields.getValue("password"))):
            exc = ResponseException("Invalid Password", StatusCode.CLIENT_ERROR)
            return JsonResponse.error(exc,exc.status)
        # Find user that matches specified email
        user = self.interfaces.userDb.getUserByEmail(requestFields.getValue("email"))
        # Check that user's status is before submission of registration
        if not (self.interfaces.userDb.checkStatus(user,"awaiting_confirmation") or self.interfaces.userDb.checkStatus(user,"email_confirmed")):
            # Do not allow duplicate registrations
            exc = ResponseException("User already registered",StatusCode.CLIENT_ERROR)
            return JsonResponse.error(exc,exc.status)
        # Add user info to database
        self.interfaces.userDb.addUserInfo(user,requestFields.getValue("name"),requestFields.getValue("agency"),requestFields.getValue("title"))
        self.interfaces.userDb.setPassword(user,requestFields.getValue("password"),self.bcrypt)

        userLink= "".join([AccountHandler.FRONT_END, '#/login?redirect=/admin'])
        # Send email to approver list
        emailThread = Thread(target=ThreadedFunction, kwargs=dict(from_email=system_email,username=user.name,title=user.title,agency=user.agency,userEmail=user.email,link=userLink))
        emailThread.start()

        #email user
        link= AccountHandler.FRONT_END
        emailTemplate = {'[EMAIL]' : system_email}
        newEmail = sesEmail(user.email, system_email,templateType="account_creation_user",parameters=emailTemplate,database=self.interfaces.userDb)
        newEmail.send()

        LoginSession.logout(session)
        # Mark user as awaiting approval
        self.interfaces.userDb.changeStatus(user,"awaiting_approval")
        return JsonResponse.create(StatusCode.OK,{"message":"Registration successful"})
    def update_user(self, system_email):
        """
        Update editable fields for specified user. Editable fields for a user:
        * is_active
        * user_status_id

        Args:
            system_email: address the email is sent from

        Request body should contain the following keys:
            * uid (integer)
            * status (string)
            * is_active (boolean)

        Returns: JSON response object with either an exception or success message

        """
        sess = GlobalDB.db().session
        request_dict = RequestDictionary.derive(self.request)

        try:
            editable_fields = ('status', 'permissions', 'is_active')
            has_editable = any(key in request_dict for key in editable_fields)
            if 'uid' not in request_dict or not has_editable:
                # missing required fields, return 400
                raise ResponseException(
                    "Request body must include uid and at least one of the "
                    "following: status, permissions, is_active",
                    StatusCode.CLIENT_ERROR
                )
            # Find user that matches specified uid
            user = sess.query(User).filter_by(
                user_id=int(request_dict['uid'])).one_or_none()
            if user is None:
                raise ResponseException(
                    "No users with that uid", StatusCode.CLIENT_ERROR)
        except ResponseException as exc:
            return JsonResponse.error(exc, exc.status)

        if 'status' in request_dict:
            #check if the user is waiting
            if user.user_status_id == USER_STATUS_DICT["awaiting_approval"]:
                if request_dict['status'] == 'approved':
                    # Grant agency_user permission to newly approved users
                    user.permission_type_id = PERMISSION_TYPE_DICT['reader']
                    sess.merge(user)
                    sess.commit()

                    link = AccountHandler.FRONT_END
                    email_template = {'[URL]':link,'[EMAIL]':system_email}
                    new_email = sesEmail(user.email, system_email,templateType="account_approved",parameters=email_template)
                    new_email.send()
                elif request_dict['status'] == 'denied':
                    email_template = {}
                    new_email = sesEmail(user.email, system_email,templateType="account_rejected",parameters=email_template)
                    new_email.send()
            # Change user's status
            try:
                user.user_status_id = USER_STATUS_DICT[request_dict['status']]
            except ValueError as e:
                # In this case having a bad status name is a client error
                raise ResponseException(str(e), StatusCode.CLIENT_ERROR, ValueError)
            sess.commit()

        # Activate/deactivate user
        if 'is_active' in request_dict:
            is_active = bool(request_dict['is_active'])
            user.is_active = is_active
            sess.commit()

        return JsonResponse.create(StatusCode.OK, {"message": "User successfully updated"})
    def register(self,system_email,session):
        """

        Save user's information into user database.  Associated request body should have keys 'email', 'name', 'cgac_code', and 'title'

        arguments:

        system_email  -- (string) email used to send messages
        session  -- (Session) object from flask


        Returns message that registration is successful or error message that fields are not valid

        """
        def ThreadedFunction (username="", title="", cgac_code="", user_email="" , link="") :
            """
            This inner function sends emails in a new thread as there could be lots of admins

            username -- (string) the name of the  user
            title  --   (string) the title of the  user
            cgac_code -- (string) the agency of the  user
            user_email -- (string) the email of the user
            link  -- (string) the broker email link
            """
            agency_name = sess.query(CGAC.agency_name).\
                filter(CGAC.cgac_code == cgac_code).\
                one_or_none()
            agency_name = "Unknown" if agency_name is None else agency_name
            for user in sess.query(User).filter_by(permission_type_id=PERMISSION_TYPE_DICT['website_admin']):
                email_template = {'[REG_NAME]': username, '[REG_TITLE]':title, '[REG_AGENCY_NAME]':agency_name,
                                 '[REG_CGAC_CODE]': cgac_code,'[REG_EMAIL]' : user_email,'[URL]':link}
                new_email = sesEmail(user.email, system_email,templateType="account_creation",parameters=email_template)
                new_email.send()

        sess = GlobalDB.db().session
        request_fields = RequestDictionary.derive(self.request)
        try:
            required = ('email', 'name', 'cgac_code', 'title', 'password')
            if any(field not in request_fields for field in required):
                # Missing a required field, return 400
                raise ResponseException(
                    "Request body must include email, name, cgac_code, "
                    "title, and password", StatusCode.CLIENT_ERROR
                )
            if not self.checkPassword(request_fields["password"]):
                raise ResponseException(
                    "Invalid Password", StatusCode.CLIENT_ERROR)
            # Find user that matches specified email
            user = sess.query(User).filter(
                func.lower(User.email) == func.lower(request_fields['email'])
            ).one_or_none()
            if user is None:
                raise ResponseException(
                    "No users with that email", StatusCode.CLIENT_ERROR)
            # Check that user's status is before submission of registration
            bad_statuses = (USER_STATUS_DICT["awaiting_confirmation"], USER_STATUS_DICT["email_confirmed"])
            if user.user_status_id not in bad_statuses:
                # Do not allow duplicate registrations
                raise ResponseException(
                    "User already registered", StatusCode.CLIENT_ERROR)
            # Add user info to database
            user.name = request_fields['name']
            user.cgac_code = request_fields['cgac_code']
            user.title = request_fields['title']
            sess.commit()
            set_user_password(user, request_fields['password'], self.bcrypt)
        except ResponseException as exc:
            return JsonResponse.error(exc, exc.status)

        user_link= "".join([AccountHandler.FRONT_END, '#/login?redirect=/admin'])
        # Send email to approver list
        email_thread = Thread(target=ThreadedFunction, kwargs=dict(username=user.name,title=user.title,cgac_code=user.cgac_code,user_email=user.email,link=user_link))
        email_thread.start()

        #email user
        email_template = {'[EMAIL]' : system_email}
        new_email = sesEmail(user.email, system_email,templateType="account_creation_user",parameters=email_template)
        new_email.send()

        # Logout and delete token
        LoginSession.logout(session)
        oldToken = sess.query(EmailToken).filter(EmailToken.token == session["token"]).one()
        sess.delete(oldToken)
        # Mark user as awaiting approval
        user.user_status_id = USER_STATUS_DICT["awaiting_approval"]
        sess.commit()
        return JsonResponse.create(StatusCode.OK,{"message":"Registration successful"})
    def updateUser(self, system_email):
        """
        Update editable fields for specified user. Editable fields for a user:
        * is_active
        * user_status_id
        * permissions

        Args:
            None: Request body should contain the following keys:
                * uid (integer)
                * status (string)
                * permissions (comma separated string)
                * is_active (boolean)

        Returns: JSON response object with either an exception or success message

        """
        requestDict = RequestDictionary(self.request)

        # throw an exception if nothing is provided in the request
        if not requestDict.exists("uid") or not (requestDict.exists("status") or requestDict.exists("permissions") or
                    requestDict.exists("is_active")):
            # missing required fields, return 400
            exc = ResponseException("Request body must include uid and at least one of the following: status, permissions, is_active",
                                    StatusCode.CLIENT_ERROR)
            return JsonResponse.error(exc, exc.status)

        # Find user that matches specified uid
        user = self.interfaces.userDb.getUserByUID(int(requestDict.getValue("uid")))

        if requestDict.exists("status"):
            #check if the user is waiting
            if(self.interfaces.userDb.checkStatus(user,"awaiting_approval")):
                if(requestDict.getValue("status") == "approved"):
                    # Grant agency_user permission to newly approved users
                    self.interfaces.userDb.grantPermission(user,"agency_user")
                    link=  AccountHandler.FRONT_END
                    emailTemplate = { '[URL]':link,'[EMAIL]':system_email}
                    newEmail = sesEmail(user.email, system_email,templateType="account_approved",parameters=emailTemplate,database=self.interfaces.userDb)
                    newEmail.send()
                elif (requestDict.getValue("status") == "denied"):
                    emailTemplate = {}
                    newEmail = sesEmail(user.email, system_email,templateType="account_rejected",parameters=emailTemplate,database=self.interfaces.userDb)
                    newEmail.send()
            # Change user's status
            self.interfaces.userDb.changeStatus(user,requestDict.getValue("status"))

        if requestDict.exists("permissions"):
            permissions_list = requestDict.getValue("permissions").split(',')

            # Remove all existing permissions for user
            user_permissions = self.interfaces.userDb.getUserPermissions(user)
            for permission in user_permissions:
                self.interfaces.userDb.removePermission(user, permission)

            # Grant specified permissions
            for permission in permissions_list:
                self.interfaces.userDb.grantPermission(user, permission)

        # Activate/deactivate user
        if requestDict.exists("is_active"):
            is_active = bool(requestDict.getValue("is_active"))
            if not self.isUserActive(user) and is_active:
                # Reset password count to 0
                self.resetPasswordCount(user)
                # Reset last login date so the account isn't expired
                self.interfaces.userDb.updateLastLogin(user, unlock_user=True)
                self.sendResetPasswordEmail(user, system_email, unlock_user=True)
            self.interfaces.userDb.setUserActive(user, is_active)

        return JsonResponse.create(StatusCode.OK, {"message": "User successfully updated"})
Exemple #23
0
    def updateUser(self, system_email):
        """
        Update editable fields for specified user. Editable fields for a user:
        * is_active
        * user_status_id
        * permissions

        Args:
            None: Request body should contain the following keys:
                * uid (integer)
                * status (string)
                * permissions (comma separated string)
                * is_active (boolean)

        Returns: JSON response object with either an exception or success message

        """
        requestDict = RequestDictionary(self.request)

        # throw an exception if nothing is provided in the request
        if not requestDict.exists("uid") or not (
                requestDict.exists("status")
                or requestDict.exists("permissions")
                or requestDict.exists("is_active")):
            # missing required fields, return 400
            exc = ResponseException(
                "Request body must include uid and at least one of the following: status, permissions, is_active",
                StatusCode.CLIENT_ERROR)
            return JsonResponse.error(exc, exc.status)

        # Find user that matches specified uid
        user = self.interfaces.userDb.getUserByUID(
            int(requestDict.getValue("uid")))

        if requestDict.exists("status"):
            #check if the user is waiting
            if (self.interfaces.userDb.checkStatus(user, "awaiting_approval")):
                if (requestDict.getValue("status") == "approved"):
                    # Grant agency_user permission to newly approved users
                    self.interfaces.userDb.grantPermission(user, "agency_user")
                    link = AccountHandler.FRONT_END
                    emailTemplate = {'[URL]': link, '[EMAIL]': system_email}
                    newEmail = sesEmail(user.email,
                                        system_email,
                                        templateType="account_approved",
                                        parameters=emailTemplate,
                                        database=self.interfaces.userDb)
                    newEmail.send()
                elif (requestDict.getValue("status") == "denied"):
                    emailTemplate = {}
                    newEmail = sesEmail(user.email,
                                        system_email,
                                        templateType="account_rejected",
                                        parameters=emailTemplate,
                                        database=self.interfaces.userDb)
                    newEmail.send()
            # Change user's status
            self.interfaces.userDb.changeStatus(user,
                                                requestDict.getValue("status"))

        if requestDict.exists("permissions"):
            permissions_list = requestDict.getValue("permissions").split(',')

            # Remove all existing permissions for user
            user_permissions = self.interfaces.userDb.getUserPermissions(user)
            for permission in user_permissions:
                self.interfaces.userDb.removePermission(user, permission)

            # Grant specified permissions
            for permission in permissions_list:
                self.interfaces.userDb.grantPermission(user, permission)

        # Activate/deactivate user
        if requestDict.exists("is_active"):
            is_active = bool(requestDict.getValue("is_active"))
            if not self.isUserActive(user) and is_active:
                # Reset password count to 0
                self.resetPasswordCount(user)
                # Reset last login date so the account isn't expired
                self.interfaces.userDb.updateLastLogin(user, unlock_user=True)
                self.sendResetPasswordEmail(user,
                                            system_email,
                                            unlock_user=True)
            self.interfaces.userDb.setUserActive(user, is_active)

        return JsonResponse.create(StatusCode.OK,
                                   {"message": "User successfully updated"})