def checkPasswordToken(self,session):
        """

        Checks the password token if its valid

        arguments:

        session -- (Session) object from flask

        return the reponse object with a error code and a message

        """
        requestFields = RequestDictionary(self.request)
        if(not requestFields.exists("token")):
            exc = ResponseException("Request body must include token", StatusCode.CLIENT_ERROR)
            return JsonResponse.error(exc,exc.status)
        token = requestFields.getValue("token")
        success,message,errorCode = sesEmail.checkToken(token,self.interfaces.userDb,"password_reset")
        if(success):
            #mark session that password can be filled out
            LoginSession.resetPassword(session)

            return JsonResponse.create(StatusCode.OK,{"email":message,"errorCode":errorCode,"message":"success"})
        else:
            #failure but alert UI of issue
            return JsonResponse.create(StatusCode.OK,{"errorCode":errorCode,"message":message})
    def checkEmailConfirmationToken(self,session):
        """

        Creates user record and email

        arguments:

        session -- (Session) object from flask

        return the reponse object with a error code and a message

        """
        requestFields = RequestDictionary(self.request)
        if(not requestFields.exists("token")):
            exc = ResponseException("Request body must include token", StatusCode.CLIENT_ERROR)
            return JsonResponse.error(exc,exc.status)
        token = requestFields.getValue("token")
        success,message,errorCode = sesEmail.checkToken(token,self.interfaces.userDb,"validate_email")
        if(success):
            #mark session that email can be filled out
            LoginSession.register(session)

            #remove token so it cant be used again
            # The following line is commented out for issues with registration email links bouncing users back
            # to the original email input page instead of the registration page
            #self.interfaces.userDb.deleteToken(token)

            #set the status only if current status is awaiting confirmation
            user = self.interfaces.userDb.getUserByEmail(message)
            if self.interfaces.userDb.checkStatus(user,"awaiting_confirmation"):
                self.interfaces.userDb.changeStatus(user,"email_confirmed")
            return JsonResponse.create(StatusCode.OK,{"email":message,"errorCode":errorCode,"message":"success"})
        else:
            #failure but alert UI of issue
            return JsonResponse.create(StatusCode.OK,{"errorCode":errorCode,"message":message})
    def checkPasswordToken(self,session):
        """

        Checks the password token if its valid

        arguments:

        session -- (Session) object from flask

        return the reponse object with a error code and a message

        """
        request_fields = RequestDictionary.derive(self.request)
        try:
            if 'token' not in request_fields:
                raise ResponseException(
                    "Request body must include token", StatusCode.CLIENT_ERROR)
        except ResponseException as exc:
            return JsonResponse.error(exc, exc.status)
        token = request_fields['token']
        # Save token to be deleted after reset
        session["token"] = token
        success, message, errorCode = sesEmail.check_token(token, "password_reset")
        if success:
            #mark session that password can be filled out
            LoginSession.reset_password(session)

            return JsonResponse.create(StatusCode.OK,{"email":message,"errorCode":errorCode,"message":"success"})
        else:
            #failure but alert UI of issue
            return JsonResponse.create(StatusCode.OK,{"errorCode":errorCode,"message":message})
def test_max_login_success(monkeypatch):
    ah = accountHandler.AccountHandler(Mock())

    mock_dict = Mock()
    mock_dict.return_value.safeDictionary.side_effect = {'ticket': '', 'service': ''}
    monkeypatch.setattr(accountHandler, 'RequestDictionary', mock_dict)

    max_dict = {'cas:serviceResponse': {}}
    monkeypatch.setattr(accountHandler, 'get_max_dict', Mock(return_value=max_dict))
    config = {'parent_group': 'parent-group'}
    monkeypatch.setattr(accountHandler, 'CONFIG_BROKER', config)
    max_dict = make_max_dict('parent-group,parent-group-CGAC_SYS')
    monkeypatch.setattr(accountHandler, 'get_max_dict', Mock(return_value=max_dict))

    # If it gets to this point, that means the user was in all the right groups aka successful login
    monkeypatch.setattr(ah, 'create_session_and_response',
                        Mock(return_value=JsonResponse.create(StatusCode.OK, {"message": "Login successful"})))
    json_response = ah.max_login(Mock())

    assert "Login successful" == json.loads(json_response.get_data().decode("utf-8"))['message']

    max_dict = make_max_dict('')
    monkeypatch.setattr(accountHandler, 'get_max_dict', Mock(return_value=max_dict))

    # If it gets to this point, that means the user was in all the right groups aka successful login
    monkeypatch.setattr(ah, 'create_session_and_response',
                        Mock(return_value=JsonResponse.create(StatusCode.OK, {"message": "Login successful"})))
    json_response = ah.max_login(Mock())

    assert "Login successful" == json.loads(json_response.get_data().decode("utf-8"))['message']
def find_existing_submissions_in_period(cgac_code, frec_code, reporting_fiscal_year, reporting_fiscal_period,
                                        submission_id=None):
    """ Find all the submissions in the given period for the given CGAC or FREC code

        Args:
            cgac_code: the CGAC code to check against or None if checking a FREC agency
            frec_code: the FREC code to check against or None if checking a CGAC agency
            reporting_fiscal_year: the year to check for
            reporting_fiscal_period: the period in the year to check for
            submission_id: the submission ID to check against (used when checking if this submission is being
                re-certified)

        Returns:
            A JsonResponse containing a success message to indicate there are no existing submissions in the given
            period or the error if there was one
    """
    # We need either a cgac or a frec code for this function
    if not cgac_code and not frec_code:
        return JsonResponse.error(ValueError("CGAC or FR Entity Code required"), StatusCode.CLIENT_ERROR)

    submission_query = get_existing_submission_list(cgac_code, frec_code, reporting_fiscal_year,
                                                    reporting_fiscal_period, submission_id)

    if submission_query.count() > 0:
        data = {
            "message": "A submission with the same period already exists.",
            "submissionId": submission_query[0].submission_id
        }
        return JsonResponse.create(StatusCode.CLIENT_ERROR, data)
    return JsonResponse.create(StatusCode.OK, {"message": "Success"})
Пример #6
0
    def checkPasswordToken(self, session):
        """

        Checks the password token if its valid

        arguments:

        session -- (Session) object from flask

        return the reponse object with a error code and a message

        """
        requestFields = RequestDictionary(self.request)
        if (not requestFields.exists("token")):
            exc = ResponseException("Request body must include token",
                                    StatusCode.CLIENT_ERROR)
            return JsonResponse.error(exc, exc.status)
        token = requestFields.getValue("token")
        success, message, errorCode = sesEmail.checkToken(
            token, self.interfaces.userDb, "password_reset")
        if (success):
            #mark session that password can be filled out
            LoginSession.resetPassword(session)

            return JsonResponse.create(StatusCode.OK, {
                "email": message,
                "errorCode": errorCode,
                "message": "success"
            })
        else:
            #failure but alert UI of issue
            return JsonResponse.create(StatusCode.OK, {
                "errorCode": errorCode,
                "message": message
            })
    def inner(*args, **kwargs):
        if g.user is None:
            return JsonResponse.create(StatusCode.LOGIN_REQUIRED, {'message': "Login Required"})

        if not g.user.website_admin:
            return JsonResponse.create(StatusCode.LOGIN_REQUIRED, {'message': NOT_AUTHORIZED_MSG})

        return func(*args, **kwargs)
Пример #8
0
    def getProtectedFiles(self):
        """ Returns a set of urls to protected files on the help page """
        response = {}
        if self.isLocal:
            response["urls"] = {}
            return JsonResponse.create(StatusCode.CLIENT_ERROR, response)

        response["urls"] = self.s3manager.getFileUrls(bucket_name=CONFIG_BROKER["static_files_bucket"], path=CONFIG_BROKER["help_files_path"])
        return JsonResponse.create(StatusCode.OK, response)
    def inner(*args, **kwargs):
        if g.user is None:
            return JsonResponse.create(StatusCode.LOGIN_REQUIRED,
                                       {'message': "Login Required"})

        if not g.user.website_admin:
            return JsonResponse.create(StatusCode.LOGIN_REQUIRED,
                                       {'message': NOT_AUTHORIZED_MSG})

        return func(*args, **kwargs)
def test_max_login_success_cert_login(monkeypatch):
    ah = account_handler.AccountHandler(Mock())

    mock_dict = Mock()
    mock_dict.return_value.exists.return_value = True
    mock_dict.return_value.safeDictionary.side_effect = {'cert': ''}
    monkeypatch.setattr(account_handler, 'RequestDictionary', mock_dict)

    max_dict = {'cas:serviceResponse': {}}
    monkeypatch.setattr(account_handler, 'get_max_dict',
                        Mock(return_value=max_dict))

    config = {
        'parent_group': 'parent-group',
        'full_url': 'full-url',
        'max_cert_url': 'max-cert-url'
    }
    monkeypatch.setattr(account_handler, 'CONFIG_BROKER', config)

    max_dict = make_max_dict('parent-group,parent-group-CGAC_SYS')
    max_dict['cas:serviceResponse']['cas:authenticationSuccess'][
        'cas:attributes']['maxAttribute:MAX-ID'] = 'S_id'
    monkeypatch.setattr(account_handler, 'get_max_dict',
                        Mock(return_value=max_dict))

    mock_resp = Mock()
    mock_resp.return_value = mock_response(url='ticket=12345')
    monkeypatch.setattr('requests.get', mock_resp)

    # If it gets to this point, that means the user was in all the right groups aka successful login
    monkeypatch.setattr(
        ah, 'create_session_and_response',
        Mock(return_value=JsonResponse.create(
            StatusCode.OK, {"message": "Login successful"})))
    json_response = ah.max_login(Mock())

    assert "Login successful" == json.loads(
        json_response.get_data().decode("utf-8"))['message']

    max_dict = make_max_dict('')
    monkeypatch.setattr(account_handler, 'get_max_dict',
                        Mock(return_value=max_dict))

    # If it gets to this point, that means the user was in all the right groups aka successful login
    monkeypatch.setattr(
        ah, 'create_session_and_response',
        Mock(return_value=JsonResponse.create(
            StatusCode.OK, {"message": "Login successful"})))
    json_response = ah.max_login(Mock())

    assert "Login successful" == json.loads(
        json_response.get_data().decode("utf-8"))['message']
Пример #11
0
def find_existing_submissions_in_period(cgac_code,
                                        frec_code,
                                        reporting_fiscal_year,
                                        reporting_fiscal_period,
                                        submission_id=None):
    """ Find all the submissions in the given period for the given CGAC or FREC code

        Args:
            cgac_code: the CGAC code to check against or None if checking a FREC agency
            frec_code: the FREC code to check against or None if checking a CGAC agency
            reporting_fiscal_year: the year to check for
            reporting_fiscal_period: the period in the year to check for
            submission_id: the submission ID to check against (used when checking if this submission is being
                re-certified)

        Returns:
            A JsonResponse containing a success message to indicate there are no existing submissions in the given
            period or the error if there was one
    """
    # We need either a cgac or a frec code for this function
    if not cgac_code and not frec_code:
        return JsonResponse.error(
            ValueError("CGAC or FR Entity Code required"),
            StatusCode.CLIENT_ERROR)

    sess = GlobalDB.db().session

    submission_query = sess.query(Submission).filter(
        (Submission.cgac_code == cgac_code) if cgac_code else
        (Submission.frec_code == frec_code),
        Submission.reporting_fiscal_year == reporting_fiscal_year,
        Submission.reporting_fiscal_period == reporting_fiscal_period,
        Submission.publish_status_id != PUBLISH_STATUS_DICT['unpublished'])

    # Filter out the submission we are potentially re-certifying if one is provided
    if submission_id:
        submission_query = submission_query.filter(
            Submission.submission_id != submission_id)

    submission_query = submission_query.order_by(desc(Submission.created_at))

    if submission_query.count() > 0:
        data = {
            "message": "A submission with the same period already exists.",
            "submissionId": submission_query[0].submission_id
        }
        return JsonResponse.create(StatusCode.CLIENT_ERROR, data)
    return JsonResponse.create(StatusCode.OK, {"message": "Success"})
    def set_new_password(self, session):
        """ Set a new password for a user, request should have keys "user_email" and "password" """
        sess = GlobalDB.db().session
        request_dict = RequestDictionary.derive(self.request)
        required = ('user_email', 'password')
        try:
            if any(field not in request_dict for field in required):
                # Don't have the keys we need in request
                raise ResponseException(
                    "Set password route requires keys user_email and password",
                    StatusCode.CLIENT_ERROR
                )
            if not self.checkPassword(request_dict['password']):
                raise ResponseException(
                    "Invalid Password", StatusCode.CLIENT_ERROR)
        except ResponseException as exc:
            return JsonResponse.error(exc,exc.status)

        # Get user from email
        user = sess.query(User).filter(
            func.lower(User.email) == func.lower(request_dict["user_email"])
        ).one()
        # Set new password
        set_user_password(user,request_dict["password"],self.bcrypt)
        # Invalidate token
        oldToken = sess.query(EmailToken).filter(EmailToken.token == session["token"]).one()
        sess.delete(oldToken)
        sess.commit()
        session["reset"] = None
        # Return success message
        return JsonResponse.create(StatusCode.OK,{"message":"Password successfully changed"})
    def list_users_with_status(self):
        """ List all users with the specified status.  Associated request body must have key 'status' """
        request_dict = RequestDictionary.derive(self.request)
        try:
            if 'status' not in request_dict:
                # Missing a required field, return 400
                raise ResponseException(
                    "Request body must include status", StatusCode.CLIENT_ERROR)
        except ResponseException as exc:
            return JsonResponse.error(exc, exc.status)

        sess = GlobalDB.db().session

        try:
            users = sess.query(User).filter_by(
                user_status_id=USER_STATUS_DICT[request_dict['status']]
            ).all()
        except ValueError as exc:
            # Client provided a bad status
            return JsonResponse.error(exc, StatusCode.CLIENT_ERROR)
        user_info = []
        for user in users:
            agency_name = sess.query(CGAC.agency_name).\
                filter(CGAC.cgac_code == user.cgac_code).\
                one_or_none()
            this_info = {"name":user.name, "title":user.title, "agency_name":agency_name, "cgac_code":user.cgac_code,
                        "email":user.email, "id":user.user_id }
            user_info.append(this_info)
        return JsonResponse.create(StatusCode.OK,{"users":user_info})
    def list_users(self):
        """ List all users ordered by status. Associated request body must have key 'filter_by' """
        request_dict = RequestDictionary.derive(
            self.request, optional_request=True)
        user_status = request_dict.get('status', 'all')
        sess = GlobalDB.db().session
        try:
            user_query = sess.query(User)
            if user_status != "all":
                user_query = user_query.filter(User.user_status_id == USER_STATUS_DICT[user_status])
            users = user_query.all()
        except ValueError as exc:
            # Client provided a bad status
            return JsonResponse.error(exc, StatusCode.CLIENT_ERROR)
        user_info = []
        for user in users:
            agency_name = sess.query(CGAC.agency_name).\
                filter(CGAC.cgac_code == user.cgac_code).\
                one_or_none()

            thisInfo = {"name":user.name, "title":user.title, "agency_name":agency_name, "cgac_code":user.cgac_code,
                        "email":user.email, "id":user.user_id, "is_active":user.is_active,
                        "permission": PERMISSION_TYPE_DICT_ID.get(user.permission_type_id), "status": user.user_status.name}
            user_info.append(thisInfo)
        return JsonResponse.create(StatusCode.OK,{"users":user_info})
 def list_all_agencies():
     sess = GlobalDB.db().session
     cgacs = sess.query(CGAC).all()
     agency_list = [{'agency_name': cgac.agency_name, 'cgac_code': cgac.cgac_code} for cgac in cgacs]
     frecs = sess.query(FREC).all()
     shared_list = [{'agency_name': frec.agency_name, 'frec_code': frec.frec_code} for frec in frecs]
     return JsonResponse.create(StatusCode.OK, {'agency_list': agency_list, 'shared_agency_list': shared_list})
Пример #16
0
    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)

        email = requestDict.getValue("email")
        LoginSession.logout(session)
        self.sendResetPasswordEmail(user, system_email, email)

        # Return success message
        return JsonResponse.create(StatusCode.OK,
                                   {"message": "Password reset"})
Пример #17
0
    def checkGeneration(self, submission_id = None, file_type = None):
        """ Return information about file generation jobs

        Returns:
            Response object with keys status, file_type, url, message.  If file_type is D1 or D2, also includes start and end.
        """
        if submission_id is None or file_type is None:
            submission_id, file_type = self.getRequestParamsForGenerate()
        # Check permission to submission
        self.checkSubmissionById(submission_id, file_type)

        uploadJob = self.interfaces.jobDb.getJobBySubmissionFileTypeAndJobType(submission_id, self.fileTypeMap[file_type], "file_upload")
        if file_type in ["D1","D2"]:
            validationJob = self.interfaces.jobDb.getJobBySubmissionFileTypeAndJobType(submission_id, self.fileTypeMap[file_type], "csv_record_validation")
        else:
            validationJob = None
        responseDict = {}
        responseDict["status"] = self.mapGenerateStatus(uploadJob, validationJob)
        responseDict["file_type"] = file_type
        responseDict["message"] = uploadJob.error_message or ""
        if uploadJob.filename is None:
            responseDict["url"] = "#"
        elif CONFIG_BROKER["use_aws"]:
            path, file_name = uploadJob.filename.split("/")
            responseDict["url"] = s3UrlHandler().getSignedUrl(path=path, fileName=file_name, bucketRoute=None, method="GET")
        else:
            responseDict["url"] = uploadJob.filename

        # Pull start and end from jobs table if D1 or D2
        if file_type in ["D1","D2"]:
            responseDict["start"] = uploadJob.start_date.strftime("%m/%d/%Y") if uploadJob.start_date is not None else ""
            responseDict["end"] = uploadJob.end_date.strftime("%m/%d/%Y") if uploadJob.end_date is not None else ""

        return JsonResponse.create(StatusCode.OK,responseDict)
 def list_sub_tier_agencies(sub_tier_agencies):
     """ List all Sub-Tier Agencies user has FABS permissions for
         Args:
         sub_tier_agencies - List of all SubTierAgencies generated by the get_fabs_sub_tier_agencies decorator,
             required to list only sub_tier_agencies that user has FABS permissions for
     """
     return JsonResponse.create(StatusCode.OK, organize_sub_tier_agencies(sub_tier_agencies))
Пример #19
0
    def getCurrentUser(self, session):
        """

        Gets the current user information

        arguments:

        session  -- (Session) object from flask

        return the reponse object with the current user information

        """
        uid = session["name"]
        user = self.interfaces.userDb.getUserByUID(uid)
        permissionList = []
        for permission in self.interfaces.userDb.getPermissionList():
            if (self.interfaces.userDb.hasPermission(user, permission.name)):
                permissionList.append(permission.permission_type_id)
        agency_name = self.interfaces.validationDb.getAgencyName(
            user.cgac_code)
        return JsonResponse.create(
            StatusCode.OK, {
                "user_id": int(uid),
                "name": user.name,
                "agency_name": agency_name,
                "cgac_code": user.cgac_code,
                "title": user.title,
                "permissions": permissionList,
                "skip_guide": user.skip_guide
            })
    def validate_job(self, request):
        """ Gets file for job, validates each row, and sends valid rows to a staging table
        Args:
        request -- HTTP request containing the jobId
        Returns:
        Http response object
        """
        # Create connection to job tracker database
        sess = GlobalDB.db().session

        requestDict = RequestDictionary(request)
        if requestDict.exists('job_id'):
            job_id = requestDict.getValue('job_id')
        else:
            # Request does not have a job ID, can't validate
            validation_error_type = ValidationError.jobError
            raise ResponseException('No job ID specified in request',
                                    StatusCode.CLIENT_ERROR, None,
                                    validation_error_type)

        # Get the job
        job = sess.query(Job).filter_by(job_id=job_id).one_or_none()
        if job is None:
            validation_error_type = ValidationError.jobError
            writeFileError(job_id, None, validation_error_type)
            raise ResponseException(
                'Job ID {} not found in database'.format(job_id),
                StatusCode.CLIENT_ERROR, None, validation_error_type)

        # Make sure job's prerequisites are complete
        if not run_job_checks(job_id):
            validation_error_type = ValidationError.jobError
            writeFileError(job_id, None, validation_error_type)
            raise ResponseException(
                'Prerequisites for Job ID {} are not complete'.format(job_id),
                StatusCode.CLIENT_ERROR, None, validation_error_type)

        # Make sure this is a validation job
        if job.job_type.name in ('csv_record_validation', 'validation'):
            job_type_name = job.job_type.name
        else:
            validation_error_type = ValidationError.jobError
            writeFileError(job_id, None, validation_error_type)
            raise ResponseException(
                'Job ID {} is not a validation job (job type is {})'.format(
                    job_id, job.job_type.name), StatusCode.CLIENT_ERROR, None,
                validation_error_type)

        # set job status to running and do validations
        mark_job_status(job_id, "running")
        if job_type_name == 'csv_record_validation':
            self.runValidation(job)
        elif job_type_name == 'validation':
            self.runCrossValidation(job)
        else:
            raise ResponseException("Bad job type for validator",
                                    StatusCode.INTERNAL_ERROR)

        return JsonResponse.create(StatusCode.OK,
                                   {"message": "Validation complete"})
    def listUsersWithStatus(self):
        """ List all users with the specified status.  Associated request body must have key 'status' """
        requestDict = RequestDictionary(self.request)
        if(not (requestDict.exists("status"))):
            # Missing a required field, return 400
            exc = ResponseException("Request body must include status", StatusCode.CLIENT_ERROR)
            return JsonResponse.error(exc,exc.status)

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

        try:
            if self.interfaces.userDb.hasPermission(current_user, "agency_admin"):
                users = self.interfaces.userDb.getUsersByStatus(requestDict.getValue("status"), current_user.cgac_code)
            else:
                users = self.interfaces.userDb.getUsersByStatus(requestDict.getValue("status"))
        except ValueError as e:
            # Client provided a bad status
            exc = ResponseException(str(e),StatusCode.CLIENT_ERROR,ValueError)
            return JsonResponse.error(exc,exc.status)
        userInfo = []
        for user in users:
            agency_name = self.interfaces.validationDb.getAgencyName(user.cgac_code)
            thisInfo = {"name":user.name, "title":user.title, "agency_name":agency_name, "cgac_code":user.cgac_code,
                        "email":user.email, "id":user.user_id }
            userInfo.append(thisInfo)
        return JsonResponse.create(StatusCode.OK,{"users":userInfo})
    def list_all_agencies():
        """ List all CGAC and FREC Agencies
        """
        sess = GlobalDB.db().session
        agency_list, shared_list = [], []

        # combine CGAC SubTierAgencies and CGACs without SubTierAgencies into the agency_list
        csubs = sess.query(SubTierAgency).filter(
            SubTierAgency.is_frec.is_(False)).distinct(
                SubTierAgency.cgac_id).all()
        all_cgacs = get_cgacs_without_sub_tier_agencies(sess) + [
            st.cgac for st in csubs if st.is_frec is False
        ]
        agency_list = [{
            'agency_name': cst.agency_name,
            'cgac_code': cst.cgac_code
        } for cst in all_cgacs]

        # add distinct FRECs from SubTierAgencies with a True is_frec into the shared_list
        fsubs = sess.query(SubTierAgency).filter(
            SubTierAgency.is_frec.is_(True)).distinct(
                SubTierAgency.frec_id).all()
        shared_list = [{
            'agency_name': fst.frec.agency_name,
            'frec_code': fst.frec.frec_code
        } for fst in fsubs]

        return JsonResponse.create(StatusCode.OK, {
            'agency_list': agency_list,
            'shared_agency_list': shared_list
        })
Пример #23
0
        def validate_threaded():
            """Start the validation process on a new thread."""
            @copy_current_request_context
            def ThreadedFunction(arg):
                """The new thread."""
                threadedManager = ValidationManager(local, error_report_path)
                threadedManager.threadedValidateJob(arg)

            try:
                interfaces = InterfaceHolder()
                jobTracker = interfaces.jobDb
            except ResponseException as e:
                open("errorLog","a").write(str(e) + "\n")
                return JsonResponse.error(e,e.status,table = "cannot connect to job database")
            except Exception as e:
                open("errorLog","a").write(str(e) + "\n")
                exc = ResponseException(str(e),StatusCode.INTERNAL_ERROR,type(e))
                return JsonResponse.error(exc,exc.status,table= "cannot connect to job database")

            jobId = None
            manager = ValidationManager(local, error_report_path)

            try:
                jobId = manager.getJobID(request)
            except ResponseException as e:
                manager.markJob(jobId,jobTracker,"invalid",interfaces.errorDb,manager.filename)
                CloudLogger.logError(str(e),e,traceback.extract_tb(sys.exc_info()[2]))
                return JsonResponse.error(e,e.status,table ="")
            except Exception as e:
                exc = ResponseException(str(e),StatusCode.CLIENT_ERROR,type(e))
                manager.markJob(jobId,jobTracker,"invalid",interfaces.errorDb,manager.filename)
                CloudLogger.logError(str(e),exc,traceback.extract_tb(sys.exc_info()[2]))
                return JsonResponse.error(exc,exc.status,table="")

            try:
                manager.testJobID(jobId,interfaces)
            except ResponseException as e:
                open("errorLog","a").write(str(e) + "\n")
                # Job is not ready to run according to job tracker, do not change status of job in job tracker
                interfaces.errorDb.writeFileError(jobId,manager.filename,ValidationError.jobError)
                return JsonResponse.error(e,e.status,table="")
            except Exception as e:
                open("errorLog","a").write(str(e) + "\n")
                exc = ResponseException(str(e),StatusCode.CLIENT_ERROR,type(e))
                interfaces.errorDb.writeFileError(jobId,manager.filename,ValidationError.jobError)
                return JsonResponse.error(exc,exc.status,table="")

            thread = Thread(target=ThreadedFunction, args= (jobId,))

            try :
                jobTracker.markJobStatus(jobId,"running")
            except Exception as e:
                open("errorLog","a").write(str(e) + "\n")
                exc = ResponseException(str(e),StatusCode.INTERNAL_ERROR,type(e))
                return JsonResponse.error(exc,exc.status,table="could not start job")

            interfaces.close()
            thread.start()

            return JsonResponse.create(StatusCode.OK,{"table":"job"+str(jobId)})
    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)

        email = requestDict.getValue("email")
        LoginSession.logout(session)
        self.sendResetPasswordEmail(user, system_email, email)

        # Return success message
        return JsonResponse.create(StatusCode.OK,{"message":"Password reset"})
    def reset_password(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

        """
        sess = GlobalDB.db().session
        request_dict = RequestDictionary.derive(self.request)
        try:
            if 'email' not in request_dict:
                # Don't have the keys we need in request
                raise ResponseException(
                    "Reset password route requires key 'email'",
                    StatusCode.CLIENT_ERROR
                )
            user = sess.query(User).filter(
                func.lower(User.email) == func.lower(request_dict['email'])
            ).one()
        except Exception as exc:
            return JsonResponse.error(exc, StatusCode.CLIENT_ERROR)

        email = request_dict['email']
        LoginSession.logout(session)
        self.send_reset_password_email(user, system_email, email)

        # Return success message
        return JsonResponse.create(StatusCode.OK,{"message":"Password reset"})
Пример #26
0
 def setSkipGuide(self, session):
     """ Set current user's skip guide parameter """
     uid = session["name"]
     userDb = self.interfaces.userDb
     user = userDb.getUserByUID(uid)
     requestDict = RequestDictionary(self.request)
     if not requestDict.exists("skip_guide"):
         exc = ResponseException("Must include skip_guide parameter",
                                 StatusCode.CLIENT_ERROR)
         return JsonResponse.error(exc, exc.status)
     skipGuide = requestDict.getValue("skip_guide")
     if type(skipGuide) == type(True):
         # param is a bool
         user.skip_guide = skipGuide
     elif type(skipGuide) == type("string"):
         # param is a string, allow "true" or "false"
         if skipGuide.lower() == "true":
             user.skip_guide = True
         elif skipGuide.lower() == "false":
             user.skip_guide = False
         else:
             exc = ResponseException("skip_guide must be true or false",
                                     StatusCode.CLIENT_ERROR)
             return JsonResponse.error(exc, exc.status)
     else:
         exc = ResponseException("skip_guide must be a boolean",
                                 StatusCode.CLIENT_ERROR)
         return JsonResponse.error(exc, exc.status)
     userDb.session.commit()
     return JsonResponse.create(StatusCode.OK, {
         "message": "skip_guide set successfully",
         "skip_guide": skipGuide
     })
Пример #27
0
    def setNewPassword(self, session):
        """ Set a new password for a user, request should have keys "user_email" and "password" """
        requestDict = RequestDictionary(self.request)
        if (not (requestDict.exists("user_email")
                 and requestDict.exists("password"))):
            # Don't have the keys we need in request
            exc = ResponseException(
                "Set password route requires keys user_email and password",
                StatusCode.CLIENT_ERROR)
            return JsonResponse.error(exc, exc.status)

        if (not self.checkPassword(requestDict.getValue("password"))):
            exc = ResponseException("Invalid Password",
                                    StatusCode.CLIENT_ERROR)
            return JsonResponse.error(exc, exc.status)
        # Get user from email
        user = self.interfaces.userDb.getUserByEmail(
            requestDict.getValue("user_email"))
        # Set new password
        self.interfaces.userDb.setPassword(user,
                                           requestDict.getValue("password"),
                                           self.bcrypt)
        # Invalidate token
        self.interfaces.userDb.deleteToken(session["token"])
        session["reset"] = None
        # Return success message
        return JsonResponse.create(
            StatusCode.OK, {"message": "Password successfully changed"})
    def list_agencies(cgac_sub_tiers, frec_sub_tiers):
        """ List all CGAC and FREC Agencies user has DABS permissions for
            Args:
            cgac_sub_tiers - List of all CGAC SubTierAgencies generated by the get_dabs_sub_tier_agencies decorator,
                required to list only sub_tier_agencies that user has DABS permissions for
            frec_sub_tiers - List of all FREC SubTierAgencies generated by the get_dabs_sub_tier_agencies decorator,
                required to list only sub_tier_agencies that user has DABS permissions for
        """
        # combine SubTierAgency CGACs with CGACs without SubTierAgencies into a cgac_list
        all_cgacs = [st.cgac for st in cgac_sub_tiers if st.is_frec is False
                     ] + get_cgacs_without_sub_tier_agencies()
        cgac_list = [{
            'agency_name': cst.agency_name,
            'cgac_code': cst.cgac_code
        } for cst in all_cgacs]

        # convert the list of frec sub_tier_agencies into a list of frec agencies
        frec_list = [{
            'agency_name': fst.frec.agency_name,
            'frec_code': fst.frec.frec_code
        } for fst in frec_sub_tiers]

        return JsonResponse.create(StatusCode.OK, {
            'cgac_agency_list': cgac_list,
            'frec_agency_list': frec_list
        })
 def setSkipGuide(self, session):
     """ Set current user's skip guide parameter """
     uid =  session["name"]
     userDb = self.interfaces.userDb
     user =  userDb.getUserByUID(uid)
     requestDict = RequestDictionary(self.request)
     if not requestDict.exists("skip_guide"):
         exc = ResponseException("Must include skip_guide parameter", StatusCode.CLIENT_ERROR)
         return JsonResponse.error(exc, exc.status)
     skipGuide = requestDict.getValue("skip_guide")
     if type(skipGuide) == type(True):
         # param is a bool
         user.skip_guide = skipGuide
     elif type(skipGuide) == type("string"):
         # param is a string, allow "true" or "false"
         if skipGuide.lower() == "true":
             user.skip_guide = True
         elif skipGuide.lower() == "false":
             user.skip_guide = False
         else:
             exc = ResponseException("skip_guide must be true or false", StatusCode.CLIENT_ERROR)
             return JsonResponse.error(exc, exc.status)
     else:
         exc = ResponseException("skip_guide must be a boolean", StatusCode.CLIENT_ERROR)
         return JsonResponse.error(exc, exc.status)
     userDb.session.commit()
     return JsonResponse.create(StatusCode.OK,{"message":"skip_guide set successfully","skip_guide":skipGuide})
    def set_skip_guide(self):
        """ Set current user's skip guide parameter

            Returns:
                JsonResponse object containing results of setting the skip guide or details of the error that occurred.
                Possible errors include the request not containing a skip_guide parameter or it not being a boolean
                value
        """
        sess = GlobalDB.db().session
        request_dict = RequestDictionary.derive(self.request)
        try:
            if 'skip_guide' not in request_dict:
                raise ResponseException(
                    "Must include skip_guide parameter",
                    StatusCode.CLIENT_ERROR
                )
            skip_guide = str(request_dict['skip_guide']).lower()
            if skip_guide not in ("true", "false"):
                raise ResponseException(
                    "skip_guide must be true or false",
                    StatusCode.CLIENT_ERROR
                )
            g.user.skip_guide = skip_guide == "true"
        except ResponseException as exc:
            return JsonResponse.error(exc, exc.status)
        sess.commit()
        return JsonResponse.create(StatusCode.OK, {"message": "skip_guide set successfully", "skip_guide": skip_guide})
Пример #31
0
 def listUsersWithStatus(self):
     """ List all users with the specified status.  Associated request body must have key 'status' """
     requestDict = RequestDictionary(self.request)
     if (not (requestDict.exists("status"))):
         # Missing a required field, return 400
         exc = ResponseException("Request body must include status",
                                 StatusCode.CLIENT_ERROR)
         return JsonResponse.error(exc, exc.status)
     try:
         users = self.interfaces.userDb.getUsersByStatus(
             requestDict.getValue("status"))
     except ValueError as e:
         # Client provided a bad status
         exc = ResponseException(str(e), StatusCode.CLIENT_ERROR,
                                 ValueError)
         return JsonResponse.error(exc, exc.status)
     userInfo = []
     for user in users:
         thisInfo = {
             "name": user.name,
             "title": user.title,
             "agency": user.agency,
             "email": user.email,
             "id": user.user_id
         }
         userInfo.append(thisInfo)
     return JsonResponse.create(StatusCode.OK, {"users": userInfo})
    def delete_submission(submission):
        """ Deletes all data associated with the specified submission
        NOTE: THERE IS NO WAY TO UNDO THIS """

        if submission.publish_status_id != PUBLISH_STATUS_DICT['unpublished']:
            return JsonResponse.error(ValueError("Submissions that have been certified cannot be deleted"),
                                      StatusCode.CLIENT_ERROR)

        sess = GlobalDB.db().session

        # Check if the submission has any jobs that are currently running, if so, do not allow deletion
        jobs = sess.query(Job).filter(Job.submission_id == submission.submission_id,
                                      Job.job_status_id == JOB_STATUS_DICT['running']).all()

        if jobs:
            return JsonResponse.error(ValueError("Submissions with running jobs cannot be deleted"),
                                      StatusCode.CLIENT_ERROR)

        sess.query(SubmissionSubTierAffiliation).filter(
            SubmissionSubTierAffiliation.submission_id == submission.submission_id).delete(
                synchronize_session=False)
        sess.query(Submission).filter(Submission.submission_id == submission.submission_id).delete(
            synchronize_session=False)
        sess.expire_all()

        return JsonResponse.create(StatusCode.OK, {"message": "Success"})
Пример #33
0
    def getErrorMetrics(self) :
        """ Returns an Http response object containing error information for every validation job in specified submission """
        responseDict = {}
        returnDict = {}
        try:
            safeDictionary = RequestDictionary(self.request)
            submission_id =  safeDictionary.getValue("submission_id")

            # Check if user has permission to specified submission
            self.checkSubmissionPermission(self.jobManager.getSubmissionById(submission_id))

            jobIds = self.jobManager.getJobsBySubmission(submission_id)
            for currentId in jobIds :
                if(self.jobManager.getJobType(currentId) == "csv_record_validation"):
                    fileName = self.jobManager.getFileType(currentId)
                    dataList = self.interfaces.errorDb.getErrorMetricsByJobId(currentId)
                    returnDict[fileName]  = dataList
            return JsonResponse.create(StatusCode.OK,returnDict)
        except ( ValueError , TypeError ) as e:
            return JsonResponse.error(e,StatusCode.CLIENT_ERROR)
        except ResponseException as e:
            return JsonResponse.error(e,e.status)
        except Exception as e:
            # Unexpected exception, this is a 500 server error
            return JsonResponse.error(e,StatusCode.INTERNAL_ERROR)
def list_submission_users(d2_submission):
    """ List user IDs and names that have submissions that the requesting user can see.

        Arguments:
            d2_submission: boolean indicating whether it is a DABS or FABS submission (True if FABS)

        Returns:
            A JsonResponse containing a list of users that have submissions that the requesting user can see
    """

    sess = GlobalDB.db().session
    # subquery to create the EXISTS portion of the query
    exists_query = sess.query(Submission).filter(
        Submission.user_id == User.user_id,
        Submission.d2_submission.is_(d2_submission))

    # if user is not an admin, we have to adjust the exists query to limit submissions
    if not g.user.website_admin:
        # split affiliations into frec and cgac
        cgac_affiliations = [aff for aff in g.user.affiliations if aff.cgac]
        frec_affiliations = [aff for aff in g.user.affiliations if aff.frec]

        # Don't list FABS permissions users if the user only has DABS permissions
        if not d2_submission:
            cgac_affiliations = [
                aff for aff in cgac_affiliations
                if aff.permission_type_id in DABS_PERMISSION_ID_LIST
            ]
            frec_affiliations = [
                aff for aff in frec_affiliations
                if aff.permission_type_id in DABS_PERMISSION_ID_LIST
            ]

        # Make a list of cgac and frec codes
        cgac_list = [aff.cgac.cgac_code for aff in cgac_affiliations]
        frec_list = [aff.frec.frec_code for aff in frec_affiliations]

        # Add filters where applicable
        affiliation_filters = [Submission.user_id == g.user.user_id]
        if cgac_list:
            affiliation_filters.append(Submission.cgac_code.in_(cgac_list))
        if frec_list:
            affiliation_filters.append(Submission.frec_code.in_(frec_list))

        exists_query = exists_query.filter(or_(*affiliation_filters))

    # Add an exists onto the query, couldn't do this earlier because then the filters couldn't get added in the if
    exists_query = exists_query.exists()

    # Get all the relevant users
    user_results = sess.query(User.user_id,
                              User.name).filter(exists_query).order_by(
                                  User.name).all()

    # Create an array containing relevant users in a readable format
    user_list = []
    for user in user_results:
        user_list.append({'user_id': user[0], 'name': user[1]})

    return JsonResponse.create(StatusCode.OK, {"users": user_list})
    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"})
Пример #36
0
 def getErrorReportURLsForSubmission(self):
     """
     Gets the Signed URLs for download based on the submissionId
     """
     try :
         self.s3manager = s3UrlHandler()
         safeDictionary = RequestDictionary(self.request)
         submissionId = safeDictionary.getValue("submission_id")
         responseDict ={}
         for jobId in self.jobManager.getJobsBySubmission(submissionId):
             if(self.jobManager.getJobType(jobId) == "csv_record_validation"):
                 if(not self.isLocal):
                     responseDict["job_"+str(jobId)+"_error_url"] = self.s3manager.getSignedUrl("errors",self.jobManager.getReportPath(jobId),"GET")
                 else:
                     path = os.path.join(self.serverPath, self.jobManager.getReportPath(jobId))
                     responseDict["job_"+str(jobId)+"_error_url"] = path
         if(not self.isLocal):
             crossFileReport = self.s3manager.getSignedUrl("errors",self.jobManager.getCrossFileReportPath(submissionId),"GET")
         else:
             crossFileReport = os.path.join(self.serverPath, self.jobManager.getCrossFileReportPath(submissionId))
         responseDict["cross_file_error_url"] = crossFileReport
         return JsonResponse.create(StatusCode.OK,responseDict)
     except ResponseException as e:
         return JsonResponse.error(e,StatusCode.CLIENT_ERROR)
     except Exception as e:
         # Unexpected exception, this is a 500 server error
         return JsonResponse.error(e,StatusCode.INTERNAL_ERROR)
Пример #37
0
 def uploadFile(self):
     """saves a file and returns the saved path"""
     try:
         if(self.isLocal):
             uploadedFile = request.files['file']
             if(uploadedFile):
                 seconds = int((datetime.utcnow()-datetime(1970,1,1)).total_seconds())
                 filename = "".join([str(seconds),"_", secure_filename(uploadedFile.filename)])
                 path = os.path.join(self.serverPath, filename)
                 uploadedFile.save(path)
                 returnDict = {"path":path}
                 return JsonResponse.create(StatusCode.OK,returnDict)
             else:
                 exc = ResponseException("Failure to read file", StatusCode.CLIENT_ERROR)
                 return JsonResponse.error(exc,exc.status)
         else :
             exc = ResponseException("Route Only Valid For Local Installs", StatusCode.CLIENT_ERROR)
             return JsonResponse.error(exc,exc.status)
     except ( ValueError , TypeError ) as e:
         return JsonResponse.error(e,StatusCode.CLIENT_ERROR)
     except ResponseException as e:
         return JsonResponse.error(e,e.status)
     except Exception as e:
         # Unexpected exception, this is a 500 server error
         return JsonResponse.error(e,StatusCode.INTERNAL_ERROR)
    def email_users(self, system_email):
        """ Send email notification to list of users

            Args:
                system_email: the address of the system to send the email from

            Returns:
                A JsonReponse containing a message that the email sent successfully or the details of the missing
                parameters
        """
        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)

        user_ids = request_dict['users']
        submission_id = request_dict['submission_id']
        # Check if submission id is valid
        _, agency_name = sess.query(Submission.submission_id, CGAC.agency_name).\
            join(CGAC, Submission.cgac_code == CGAC.cgac_code).filter(Submission.submission_id == submission_id).one()
        if not agency_name:
            _, agency_name = sess.query(Submission.submission_id, FREC.agency_name).\
                join(FREC, Submission.frec_code == FREC.frec_code).\
                filter(Submission.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]': g.user.name,
            '[REV_AGENCY]': agency_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,
                                 template_type=template_type,
                                 parameters=email_template)
            new_email.send()

        return JsonResponse.create(StatusCode.OK,
                                   {"message": "Emails successfully sent"})
    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 submit_files():
        file_manager = FileHandler(request, is_local=is_local, server_path=server_path)

        sess = GlobalDB.db().session

        start_date = request.json.get('reporting_period_start_date')
        end_date = request.json.get('reporting_period_end_date')
        is_quarter = request.json.get('is_quarter_format', False)

        if not (start_date is None or end_date is None):
            formatted_start_date, formatted_end_date = FileHandler.check_submission_dates(start_date,
                                                                                          end_date, is_quarter)

            submissions = sess.query(Submission).filter(
                Submission.cgac_code == request.json.get('cgac_code'),
                Submission.frec_code == request.json.get('frec_code'),
                Submission.reporting_start_date == formatted_start_date,
                Submission.reporting_end_date == formatted_end_date,
                Submission.is_quarter_format == request.json.get('is_quarter'),
                Submission.publish_status_id != PUBLISH_STATUS_DICT['unpublished'])

            if 'existing_submission_id' in request.json:
                submissions.filter(Submission.submission_id !=
                                   request.json['existing_submission_id'])

            submissions = submissions.order_by(desc(Submission.created_at))

            if submissions.count() > 0:
                data = {
                        "message": "A submission with the same period already exists.",
                        "submissionId": submissions[0].submission_id
                }
                return JsonResponse.create(StatusCode.CLIENT_ERROR, data)

        return file_manager.submit(create_credentials)
    def set_skip_guide(self):
        """ Set current user's skip guide parameter

            Returns:
                JsonResponse object containing results of setting the skip guide or details of the error that occurred.
                Possible errors include the request not containing a skip_guide parameter or it not being a boolean
                value
        """
        sess = GlobalDB.db().session
        request_dict = RequestDictionary.derive(self.request)
        try:
            if 'skip_guide' not in request_dict:
                raise ResponseException("Must include skip_guide parameter",
                                        StatusCode.CLIENT_ERROR)
            skip_guide = str(request_dict['skip_guide']).lower()
            if skip_guide not in ("true", "false"):
                raise ResponseException("skip_guide must be true or false",
                                        StatusCode.CLIENT_ERROR)
            g.user.skip_guide = skip_guide == "true"
        except ResponseException as exc:
            return JsonResponse.error(exc, exc.status)
        sess.commit()
        return JsonResponse.create(StatusCode.OK, {
            "message": "skip_guide set successfully",
            "skip_guide": skip_guide
        })
    def delete_submission(submission):
        """ Deletes all data associated with the specified submission
        NOTE: THERE IS NO WAY TO UNDO THIS """

        if submission.publish_status_id != PUBLISH_STATUS_DICT['unpublished']:
            return JsonResponse.error(ValueError("Submissions that have been certified cannot be deleted"),
                                      StatusCode.CLIENT_ERROR)

        sess = GlobalDB.db().session

        # Check if the submission has any jobs that are currently running, if so, do not allow deletion
        jobs = sess.query(Job).filter(Job.submission_id == submission.submission_id,
                                      Job.job_status_id == JOB_STATUS_DICT['running']).all()

        if jobs:
            return JsonResponse.error(ValueError("Submissions with running jobs cannot be deleted"),
                                      StatusCode.CLIENT_ERROR)

        sess.query(SubmissionSubTierAffiliation).filter(
            SubmissionSubTierAffiliation.submission_id == submission.submission_id).delete(
                synchronize_session=False)
        sess.query(Submission).filter(Submission.submission_id == submission.submission_id).delete(
            synchronize_session=False)
        sess.expire_all()

        return JsonResponse.create(StatusCode.OK, {"message": "Success"})
    def submit_files():
        file_manager = FileHandler(request, is_local=is_local, server_path=server_path)

        sess = GlobalDB.db().session

        start_date = request.json.get('reporting_period_start_date')
        end_date = request.json.get('reporting_period_end_date')
        is_quarter = request.json.get('is_quarter_format', False)

        if not (start_date is None or end_date is None):
            formatted_start_date, formatted_end_date = FileHandler.check_submission_dates(start_date,
                                                                                          end_date, is_quarter)

            submissions = sess.query(Submission).filter(
                Submission.cgac_code == request.json.get('cgac_code'),
                Submission.frec_code == request.json.get('frec_code'),
                Submission.reporting_start_date == formatted_start_date,
                Submission.reporting_end_date == formatted_end_date,
                Submission.is_quarter_format == request.json.get('is_quarter'),
                Submission.publish_status_id != PUBLISH_STATUS_DICT['unpublished'])

            if 'existing_submission_id' in request.json:
                submissions.filter(Submission.submission_id !=
                                   request.json['existing_submission_id'])

            submissions = submissions.order_by(desc(Submission.created_at))

            if submissions.count() > 0:
                data = {
                        "message": "A submission with the same period already exists.",
                        "submissionId": submissions[0].submission_id
                }
                return JsonResponse.create(StatusCode.CLIENT_ERROR, data)

        return file_manager.submit(create_credentials)
Пример #44
0
    def finalize(self):
        """ Set upload job in job tracker database to finished, allowing dependent jobs to be started

        Flask request should include key "upload_id", which holds the job_id for the file_upload job

        Returns:
        A flask response object, if successful just contains key "success" with value True, otherwise value is False
        """
        responseDict = {}
        try:
            inputDictionary = RequestDictionary(self.request)
            jobId = inputDictionary.getValue("upload_id")
            # Compare user ID with user who submitted job, if no match return 400
            job = self.jobManager.getJobById(jobId)
            submission = self.jobManager.getSubmissionForJob(job)
            if(submission.user_id != LoginSession.getName(session)):
                # This user cannot finalize this job
                raise ResponseException("Cannot finalize a job created by a different user", StatusCode.CLIENT_ERROR)
            # Change job status to finished
            if(self.jobManager.checkUploadType(jobId)):
                self.jobManager.changeToFinished(jobId)
                responseDict["success"] = True
                return JsonResponse.create(StatusCode.OK,responseDict)
            else:
                raise ResponseException("Wrong job type for finalize route",StatusCode.CLIENT_ERROR)

        except ( ValueError , TypeError ) as e:
            return JsonResponse.error(e,StatusCode.CLIENT_ERROR)
        except ResponseException as e:
            return JsonResponse.error(e,e.status)
        except Exception as e:
            # Unexpected exception, this is a 500 server error
            return JsonResponse.error(e,StatusCode.INTERNAL_ERROR)
def get_submission_data(submission, file_type=''):
    """ Get data for the submission specified

        Args:
            submission: submission to retrieve metadata for
            file_type: the type of job to retrieve metadata for

        Returns:
            JsonResponse containing the error information or the object containing metadata for all relevant file types
    """
    sess = GlobalDB.db().session
    file_type = file_type.lower()

    # Make sure the file type provided is valid
    if file_type and file_type not in FILE_TYPE_DICT and file_type != 'cross':
        return JsonResponse.error(ValueError(file_type + ' is not a valid file type'), StatusCode.CLIENT_ERROR)

    # Make sure the file type provided is valid for the submission type
    is_fabs = submission.d2_submission
    if file_type and (is_fabs and file_type != 'fabs') or (not is_fabs and file_type == 'fabs'):
        return JsonResponse.error(ValueError(file_type + ' is not a valid file type for this submission'),
                                  StatusCode.CLIENT_ERROR)

    job_query = sess.query(Job).filter(Job.submission_id == submission.submission_id)
    if not file_type:
        relevant_job_types = (JOB_TYPE_DICT['csv_record_validation'], JOB_TYPE_DICT['validation'])
        job_query = job_query.filter(Job.job_type_id.in_(relevant_job_types))
    elif file_type == 'cross':
        job_query = job_query.filter(Job.job_type_id == JOB_TYPE_DICT['validation'])
    else:
        job_query = job_query.filter(Job.file_type_id == FILE_TYPE_DICT[file_type])

    job_dict = {'jobs': [job_to_dict(job) for job in job_query]}
    return JsonResponse.create(StatusCode.OK, job_dict)
    def listAgencies(self):
        agencies = self.validationManager.getAllAgencies()
        agency_list = []

        for agency in agencies:
            agency_list.append({"agency_name": agency.agency_name, "cgac_code": agency.cgac_code})

        return JsonResponse.create(StatusCode.OK, {"cgac_agency_list": agency_list})
 def listSubmissionsByCurrentUser(self):
     """ List all submission IDs associated with the current user ID """
     userId = LoginSession.getName(flaskSession)
     submissions = self.interfaces.jobDb.getSubmissionsByUserId(userId)
     submissionIdList = []
     for submission in submissions:
         submissionIdList.append(submission.submission_id)
     return JsonResponse.create(StatusCode.OK,{"submission_id_list": submissionIdList})
 def getRss(self):
     response = {}
     if self.isLocal:
         response["rss_url"] = os.path.join(self.serverPath, CONFIG_BROKER["rss_folder"],CONFIG_BROKER["rss_file"])
     else:
         self.s3manager = s3UrlHandler()
         response["rss_url"] = self.s3manager.getSignedUrl(CONFIG_BROKER["rss_folder"],CONFIG_BROKER["rss_file"],"GET")
     return JsonResponse.create(200,response)
Пример #49
0
 def getRss(self):
     """ Returns a signed URL to the RSS document.  If local returns local path to RSS. """
     response = {}
     if self.isLocal:
         response["rss_url"] = os.path.join(self.serverPath, CONFIG_BROKER["rss_folder"],CONFIG_BROKER["rss_file"])
     else:
         self.s3manager = s3UrlHandler()
         response["rss_url"] = self.s3manager.getSignedUrl(CONFIG_BROKER["rss_folder"],CONFIG_BROKER["rss_file"],"GET")
     return JsonResponse.create(200,response)
 def list_agencies(cgac_sub_tiers, frec_sub_tiers):
     """ Get all agencies the current user has DABS access to.
         Args:
         cgac_sub_tiers - List of all CGAC SubTierAgencies generated by the get_dabs_sub_tier_agencies decorator,
             required to list only sub_tier_agencies that user has DABS permissions for
         frec_sub_tiers - List of all FREC SubTierAgencies generated by the get_dabs_sub_tier_agencies decorator,
             required to list only sub_tier_agencies that user has DABS permissions for
     """
     return JsonResponse.create(StatusCode.OK, get_accessible_agencies(cgac_sub_tiers, frec_sub_tiers))
    def login(self,session):
        """

        Logs a user in if their password matches

        arguments:

        session  -- (Session) object from flask

        return the reponse object

        """
        try:
            safeDictionary = RequestDictionary(self.request)

            username = safeDictionary.getValue('username')

            password = safeDictionary.getValue('password')

            try:
                user  = self.interfaces.userDb.getUserByEmail(username)
            except Exception as e:
                raise ValueError("user name and or password invalid")

            if(not self.interfaces.userDb.checkStatus(user,"approved")):
                raise ValueError("user name and or password invalid")

            # Only check if user is active after they've logged in for the first time
            if user.last_login_date is not None and not self.isUserActive(user):
                raise ValueError("Your account has expired. Please contact an administrator.")

            try:
                if(self.interfaces.userDb.checkPassword(user,password,self.bcrypt)):
                    # We have a valid login
                    LoginSession.login(session,user.user_id)
                    permissionList = []
                    for permission in self.interfaces.userDb.getPermssionList():
                        if(self.interfaces.userDb.hasPermission(user, permission.name)):
                            permissionList.append(permission.permission_type_id)
                    self.interfaces.userDb.updateLastLogin(user)
                    return JsonResponse.create(StatusCode.OK,{"message":"Login successful","user_id": int(user.user_id),"name":user.name,"title":user.title ,"agency":user.agency, "permissions" : permissionList})
                else :
                    raise ValueError("user name and or password invalid")
            except Exception as e:
                    LoginSession.logout(session)
                    raise ValueError("user name and or password invalid")

        except (TypeError, KeyError, NotImplementedError) as e:
            # Return a 400 with appropriate message
            return JsonResponse.error(e,StatusCode.CLIENT_ERROR)
        except ValueError as e:
            # Return a 401 for login denied
            return JsonResponse.error(e,StatusCode.LOGIN_REQUIRED)
        except Exception as e:
            # Return 500
            return JsonResponse.error(e,StatusCode.INTERNAL_ERROR)
        return self.response
 def list_agencies(cgacs, frecs):
     """ List all CGAC and FREC Agencies
         Args:
         cgacs - List of all cgac codes that are valid for the user, generated by get_cgacs decorator,
             required to list only agencies that user can access
         frecs - List of all frec codes that are valid for the user, generated by get_frecs decorator,
             required to list only agencies that user can access
     """
     agency_list = [{'agency_name': cgac.agency_name, 'cgac_code': cgac.cgac_code} for cgac in cgacs]
     shared_list = [{'agency_name': frec.agency_name, 'frec_code': frec.frec_code} for frec in frecs]
     return JsonResponse.create(StatusCode.OK, {'cgac_agency_list': agency_list, 'frec_agency_list': shared_list})
def find_existing_submissions_in_period(cgac_code, frec_code, reporting_fiscal_year, reporting_fiscal_period,
                                        submission_id=None):
    """ Find all the submissions in the given period for the given CGAC or FREC code

        Args:
            cgac_code: the CGAC code to check against or None if checking a FREC agency
            frec_code: the FREC code to check against or None if checking a CGAC agency
            reporting_fiscal_year: the year to check for
            reporting_fiscal_period: the period in the year to check for
            submission_id: the submission ID to check against (used when checking if this submission is being
                re-certified)

        Returns:
            A JsonResponse containing a success message to indicate there are no existing submissions in the given
            period or the error if there was one
    """
    # We need either a cgac or a frec code for this function
    if not cgac_code and not frec_code:
        return JsonResponse.error(ValueError("CGAC or FR Entity Code required"), StatusCode.CLIENT_ERROR)

    sess = GlobalDB.db().session

    submission_query = sess.query(Submission).filter(
        (Submission.cgac_code == cgac_code) if cgac_code else (Submission.frec_code == frec_code),
        Submission.reporting_fiscal_year == reporting_fiscal_year,
        Submission.reporting_fiscal_period == reporting_fiscal_period,
        Submission.publish_status_id != PUBLISH_STATUS_DICT['unpublished'])

    # Filter out the submission we are potentially re-certifying if one is provided
    if submission_id:
        submission_query = submission_query.filter(Submission.submission_id != submission_id)

    submission_query = submission_query.order_by(desc(Submission.created_at))

    if submission_query.count() > 0:
        data = {
            "message": "A submission with the same period already exists.",
            "submissionId": submission_query[0].submission_id
        }
        return JsonResponse.create(StatusCode.CLIENT_ERROR, data)
    return JsonResponse.create(StatusCode.OK, {"message": "Success"})
def find_existing_submissions_in_period(sess, cgac_code, frec_code, reporting_fiscal_year,
                                        reporting_fiscal_period, submission_id=None):
    submission_query = sess.query(Submission).filter(
        (Submission.cgac_code == cgac_code) if cgac_code else (Submission.frec_code == frec_code),
        Submission.reporting_fiscal_year == reporting_fiscal_year,
        Submission.reporting_fiscal_period == reporting_fiscal_period,
        Submission.publish_status_id != PUBLISH_STATUS_DICT['unpublished'])

    if submission_id:
        submission_query = submission_query.filter(
            Submission.submission_id != submission_id)

    submission_query = submission_query.order_by(desc(Submission.created_at))

    if submission_query.count() > 0:
        data = {
            "message": "A submission with the same period already exists.",
            "submissionId": submission_query[0].submission_id
        }
        return JsonResponse.create(StatusCode.CLIENT_ERROR, data)
    return JsonResponse.create(StatusCode.OK, {"message": "Success"})
def check_detached_generation(job_id):
    """ Return information about detached file generation jobs

        Args:
            job_id: ID of the detached generation job

        Returns:
            Response object with keys job_id, status, file_type, url, message, start, and end.
    """
    response_dict = generation_helper.check_file_generation(job_id)

    return JsonResponse.create(StatusCode.OK, response_dict)