Пример #1
0
 def test_get_party_by_business_id_fail(self):
     with responses.RequestsMock() as rsps:
         rsps.add(rsps.GET, url_get_business_party, status=400)
         with app.app_context():
             with self.assertRaises(ApiError):
                 party_controller.get_party_by_business_id(
                     business_party['id'])
Пример #2
0
 def test_get_party_by_business_id_fail(self):
     called_url = "http://localhost:8081/party-api/v1/businesses/id/be3483c3-f5c9-4b13-bdd7-244db78ff687?verbose=True"
     with responses.RequestsMock() as rsps:
         rsps.add(rsps.GET, url_get_business_party, status=400)
         with app.app_context():
             with self.assertRaises(ApiError):
                 party_controller.get_party_by_business_id(
                     business_party['id'], self.app_config['PARTY_URL'],
                     self.app_config['BASIC_AUTH'])
             self.assertEqual(len(rsps.calls), 1)
             self.assertEqual(rsps.calls[0].request.url, called_url)
def survey_confirm_organisation(_):
    # Get and decrypt enrolment code
    cryptographer = Cryptographer()
    encrypted_enrolment_code = request.args.get("encrypted_enrolment_code",
                                                None)
    enrolment_code = cryptographer.decrypt(
        encrypted_enrolment_code.encode()).decode()

    # Validate enrolment code before retrieving organisation data
    iac_controller.validate_enrolment_code(enrolment_code)

    logger.info(
        "Attempting to retrieve data for confirm add organisation/survey page",
        enrolment_code=enrolment_code)
    try:
        # Get organisation name
        case = case_controller.get_case_by_enrolment_code(enrolment_code)
        business_party_id = case["caseGroup"]["partyId"]
        business_party = party_controller.get_party_by_business_id(
            business_party_id, app.config["PARTY_URL"],
            app.config["BASIC_AUTH"])

        # Get survey name
        collection_exercise_id = case["caseGroup"]["collectionExerciseId"]
        collection_exercise = collection_exercise_controller.get_collection_exercise(
            collection_exercise_id)
        survey_id = collection_exercise["surveyId"]
        survey_name = survey_controller.get_survey(app.config["SURVEY_URL"],
                                                   app.config["BASIC_AUTH"],
                                                   survey_id).get("longName")
def survey_confirm_organisation(_):
    # Get and decrypt enrolment code
    cryptographer = Cryptographer()
    encrypted_enrolment_code = request.args.get('encrypted_enrolment_code',
                                                None)
    enrolment_code = cryptographer.decrypt(
        encrypted_enrolment_code.encode()).decode()

    # Validate enrolment code before retrieving organisation data
    iac_controller.validate_enrolment_code(enrolment_code)

    logger.info(
        'Attempting to retrieve data for confirm add organisation/survey page')
    try:
        # Get organisation name
        case = case_controller.get_case_by_enrolment_code(enrolment_code)
        business_party_id = case['caseGroup']['partyId']
        business_party = party_controller.get_party_by_business_id(
            business_party_id, app.config['PARTY_URL'],
            app.config['BASIC_AUTH'])

        # Get survey name
        collection_exercise_id = case['caseGroup']['collectionExerciseId']
        collection_exercise = collection_exercise_controller.get_collection_exercise(
            collection_exercise_id)
        survey_id = collection_exercise['surveyId']
        survey_name = survey_controller.get_survey(app.config['SURVEY_URL'],
                                                   app.config['BASIC_AUTH'],
                                                   survey_id).get('longName')
Пример #5
0
    def get_business_party(self, key):
        """
        Gets the business party from redis or the party service

        :param key: Key in redis (for this example will be a frontstage:business-party:id)
        :return: Result from either the cache or party service
        """
        redis_key = f"frontstage:business-party:{key}"
        try:
            result = redis.get(redis_key)
        except RedisError:
            logger.error("Error getting value from cache, please investigate",
                         key=redis_key,
                         exc_info=True)
            result = None

        if not result:
            logger.info("Key not in cache, getting value from party service",
                        key=redis_key)
            result = get_party_by_business_id(key, app.config["PARTY_URL"],
                                              app.config["BASIC_AUTH"])
            self.save(redis_key, result, self.BUSINESS_PARTY_CATEGORY_EXPIRY)
            return result

        return json.loads(result.decode("utf-8"))
Пример #6
0
def get_case_data(case_id, party_id, business_party_id, survey_short_name):
    logger.info("Attempting to retrieve detailed case data",
                case_id=case_id,
                party_id=party_id)

    # Check if respondent has permission to see case data
    case = get_case_by_case_id(case_id)
    survey = survey_controller.get_survey_by_short_name(survey_short_name)
    if not party_controller.is_respondent_enrolled(party_id, business_party_id,
                                                   survey):
        raise NoSurveyPermission(party_id, case_id)

    case_data = {
        "collection_exercise":
        collection_exercise_controller.get_collection_exercise(
            case["caseGroup"]["collectionExerciseId"]),
        "collection_instrument":
        collection_instrument_controller.get_collection_instrument(
            case["collectionInstrumentId"],
            app.config["COLLECTION_INSTRUMENT_URL"], app.config["BASIC_AUTH"]),
        "survey":
        survey,
        "business_party":
        party_controller.get_party_by_business_id(business_party_id,
                                                  app.config["PARTY_URL"],
                                                  app.config["BASIC_AUTH"]),
    }
Пример #7
0
def get_case_data(case_id, party_id, business_party_id, survey_short_name):
    logger.info('Attempting to retrieve detailed case data',
                case_id=case_id,
                party_id=party_id)

    # Check if respondent has permission to see case data
    case = get_case_by_case_id(case_id)
    if not party_controller.is_respondent_enrolled(party_id, business_party_id,
                                                   survey_short_name):
        raise NoSurveyPermission(party_id, case_id)

    case_data = {
        "collection_exercise":
        collection_exercise_controller.get_collection_exercise(
            case['caseGroup']['collectionExerciseId']),
        "collection_instrument":
        collection_instrument_controller.get_collection_instrument(
            case['collectionInstrumentId'],
            app.config['COLLECTION_INSTRUMENT_URL'], app.config['BASIC_AUTH']),
        "survey":
        survey_controller.get_survey_by_short_name(survey_short_name),
        "business_party":
        party_controller.get_party_by_business_id(business_party_id,
                                                  app.config['PARTY_URL'],
                                                  app.config['BASIC_AUTH'])
    }

    logger.info('Successfully retrieved all data relating to case',
                case_id=case_id,
                party_id=party_id)
    return case_data
Пример #8
0
def register_confirm_organisation_survey():
    # Get and decrypt enrolment code
    cryptographer = Cryptographer()
    encrypted_enrolment_code = request.args.get("encrypted_enrolment_code")
    try:
        enrolment_code = cryptographer.decrypt(
            encrypted_enrolment_code.encode()).decode()
    except AttributeError:
        logger.error("No enrolment code supplied",
                     exc_info=True,
                     url=request.url)
        raise
    # Validate enrolment code before retrieving organisation data
    iac_controller.validate_enrolment_code(enrolment_code)

    logger.info(
        "Attempting to retrieve data for confirm organisation/survey page",
        enrolment_code=enrolment_code)
    try:
        # Get organisation name
        case = case_controller.get_case_by_enrolment_code(enrolment_code)
        business_party_id = case["caseGroup"]["partyId"]
        business_party = party_controller.get_party_by_business_id(
            business_party_id, app.config["PARTY_URL"],
            app.config["BASIC_AUTH"])

        # Get survey name
        collection_exercise_id = case["caseGroup"]["collectionExerciseId"]
        collection_exercise = collection_exercise_controller.get_collection_exercise(
            collection_exercise_id)
        survey_id = collection_exercise["surveyId"]
        survey_name = survey_controller.get_survey(app.config["SURVEY_URL"],
                                                   app.config["BASIC_AUTH"],
                                                   survey_id).get("longName")
Пример #9
0
    def test_get_party_by_business_id_success_with_collection_exercise_id(
            self):
        with responses.RequestsMock() as rsps:
            url = f"{url_get_business_party}?collection_exercise_id={collection_exercise['id']}&verbose=True"
            rsps.add(rsps.GET, url, json=business_party, status=200)
            with app.app_context():
                business = party_controller.get_party_by_business_id(
                    business_party['id'], collection_exercise['id'])

                self.assertEqual(business['id'], business_party['id'])
                self.assertEqual(business['name'], business_party['name'])
Пример #10
0
 def test_get_party_by_business_id_success_with_collection_exercise_id(
         self):
     """Tests the function is successful when we supply the optional collection_excercise_id"""
     with responses.RequestsMock() as rsps:
         url = f"{url_get_business_party}?collection_exercise_id={collection_exercise['id']}&verbose=True"
         rsps.add(rsps.GET, url, json=business_party, status=200)
         with app.app_context():
             business = party_controller.get_party_by_business_id(
                 business_party['id'], self.app_config['PARTY_URL'],
                 self.app_config['BASIC_AUTH'], collection_exercise['id'])
             self.assertEqual(business['id'], business_party['id'])
             self.assertEqual(business['name'], business_party['name'])
Пример #11
0
    def test_get_party_by_business_id_success_without_collection_exercise_id(
            self):
        """Tests the function is successful when we only supply the mandatory party_id"""
        with responses.RequestsMock() as rsps:
            rsps.add(rsps.GET,
                     url_get_business_party,
                     json=business_party,
                     status=200)
            with app.app_context():
                business = party_controller.get_party_by_business_id(
                    business_party['id'], self.app_config['PARTY_URL'],
                    self.app_config['BASIC_AUTH'])

                self.assertEqual(business['id'], business_party['id'])
                self.assertEqual(business['name'], business_party['name'])
Пример #12
0
def add_survey_submit(session):
    party_id = session.get_party_id()

    cryptographer = Cryptographer()
    encrypted_enrolment_code = request.args.get("encrypted_enrolment_code")
    enrolment_code = cryptographer.decrypt(
        encrypted_enrolment_code.encode()).decode()
    logger.info("Assigning new survey to a user",
                party_id=party_id,
                enrolment_code=enrolment_code)

    try:
        # Verify enrolment code is active
        iac = iac_controller.get_iac_from_enrolment(enrolment_code)
        if iac is None:
            # Showing the client an error screen if the enrolment code is either not found or inactive isn't great
            # but it's better then what used to happen, which was raise TypeError and show them the generic exception
            # page.  This lets us more easily debug the issue.  Ideally we'd redirect the user to the surveys_list
            # page with a 'Something went wrong when signing you up for the survey, try again or call us' error.
            logger.error("IAC code not found or inactive",
                         enrolment_code=enrolment_code)
            abort(400)

        # Add enrolment for user in party
        case_id = iac["caseId"]
        case = case_controller.get_case_by_enrolment_code(enrolment_code)
        business_party_id = case["partyId"]
        collection_exercise_id = case["caseGroup"]["collectionExerciseId"]
        # Get survey ID from collection Exercise
        added_survey_id = collection_exercise_controller.get_collection_exercise(
            case["caseGroup"]["collectionExerciseId"]).get("surveyId")

        info = party_controller.get_party_by_business_id(
            business_party_id, app.config["PARTY_URL"],
            app.config["BASIC_AUTH"], collection_exercise_id)

        already_enrolled = None
        if is_respondent_and_business_enrolled(info["associations"],
                                               case["caseGroup"]["surveyId"],
                                               party_id):
            logger.info(
                "User tried to enrol onto a survey they are already enrolled on",
                case_id=case_id,
                party_id=party_id,
                enrolment_code=enrolment_code,
            )
            already_enrolled = True
        else:
Пример #13
0
    def test_get_party_by_business_id_success_with_collection_exercise_id_non_verbose(
            self):
        """Tests the function calls the expected url when we turn verbose off"""
        called_url = (
            "http://localhost:8081/party-api/v1/businesses/id/be3483c3-f5c9-4b13-bdd7-244db78ff687"
            "?collection_exercise_id=8d990a74-5f07-4765-ac66-df7e1a96505b")

        with responses.RequestsMock() as rsps:
            url = f"{url_get_business_party}?collection_exercise_id={collection_exercise['id']}"
            rsps.add(rsps.GET, url, json=business_party, status=200)
            with app.app_context():
                business = party_controller.get_party_by_business_id(
                    business_party['id'],
                    self.app_config['PARTY_URL'],
                    self.app_config['BASIC_AUTH'],
                    collection_exercise['id'],
                    verbose=False)
                self.assertEqual(business['id'], business_party['id'])
                self.assertEqual(business['name'], business_party['name'])
                self.assertEqual(len(rsps.calls), 1)
                self.assertEqual(rsps.calls[0].request.url, called_url)
Пример #14
0
def upload_survey(session):
    party_id = session.get_party_id()
    case_id = request.args["case_id"]
    business_party_id = request.args["business_party_id"]
    survey_short_name = request.args["survey_short_name"]
    logger.info("Attempting to upload collection instrument",
                case_id=case_id,
                party_id=party_id)

    if request.content_length > app.config["MAX_UPLOAD_LENGTH"]:
        return redirect(
            url_for(
                "surveys_bp.upload_failed",
                _external=True,
                case_id=case_id,
                business_party_id=business_party_id,
                survey_short_name=survey_short_name,
                error_info="size",
            ))

    # Check if respondent has permission to upload for this case
    survey = survey_controller.get_survey_by_short_name(survey_short_name)
    if not party_controller.is_respondent_enrolled(party_id, business_party_id,
                                                   survey):
        raise NoSurveyPermission(party_id, case_id)

    case = case_controller.get_case_by_case_id(case_id)

    case_group = case.get("caseGroup")
    collection_exercise_id = case_group.get("collectionExerciseId")
    business_party = party_controller.get_party_by_business_id(
        case_group["partyId"],
        app.config["PARTY_URL"],
        app.config["BASIC_AUTH"],
        collection_exercise_id=collection_exercise_id,
        verbose=True,
    )

    # Get the uploaded file
    upload_file = request.files["file"]

    try:
        # Upload the file to the collection instrument service
        collection_instrument_controller.upload_collection_instrument(
            upload_file, case, business_party, party_id, survey)
    except CiUploadError as ex:
        error_type = determine_error_type(ex)
        if not error_type:
            logger.error(
                "Unexpected error message returned from collection instrument service",
                error_message=ex.error_message,
                party_id=party_id,
                case_id=case_id,
            )
            error_type = "unexpected"
        return redirect(
            url_for(
                "surveys_bp.upload_failed",
                _external=True,
                case_id=case_id,
                business_party_id=business_party_id,
                survey_short_name=survey_short_name,
                error_info=error_type,
            ))

    logger.info("Successfully uploaded collection instrument",
                party_id=party_id,
                case_id=case_id)
    unread_message_count = {
        "unread_message_count":
        conversation_controller.try_message_count_from_session(session)
    }
    return render_template(
        "surveys/surveys-upload-success.html",
        upload_filename=upload_file.filename,
        unread_message_count=unread_message_count,
    )
Пример #15
0
class EqPayload(object):
    def create_payload(self, case, collection_exercise, party_id: str,
                       business_party_id: str, survey, version: str) -> dict:
        """
        Creates the payload needed to communicate with EQ, built from the Case, Collection Exercise, Party,
        Survey and Collection Instrument services
        :param case: A dict containing information about the case
        :param collection_exercise: A dict containing information about the collection exercise
        :param party_id: The uuid of the respondent
        :param business_party_id: The uuid of the reporting unit
        :param survey: A dict containing information about the survey
        :param version: EQ version
        :returns: Payload for EQ
        """

        tx_id = str(uuid.uuid4())
        logger.info("Creating payload for JWT",
                    case_id=case["id"],
                    tx_id=tx_id)

        # Collection Instrument
        ci_id = case["collectionInstrumentId"]
        ci = collection_instrument_controller.get_collection_instrument(
            ci_id, current_app.config["COLLECTION_INSTRUMENT_URL"],
            current_app.config["BASIC_AUTH"])
        if ci["type"] != "EQ":
            raise InvalidEqPayLoad(
                f"Collection instrument {ci_id} type is not EQ")

        classifiers = ci["classifiers"]
        if not classifiers or not classifiers.get(
                "eq_id") or not classifiers.get("form_type"):
            raise InvalidEqPayLoad(
                f"Collection instrument {ci_id} classifiers are incorrect or missing"
            )

        eq_id = ci["classifiers"]["eq_id"]
        form_type = ci["classifiers"]["form_type"]

        # Collection Exercise
        collection_exercise_id = collection_exercise["id"]
        collex_event_dates = self._get_collex_event_dates(
            collection_exercise_id)

        # Party
        party = party_controller.get_party_by_business_id(
            business_party_id,
            current_app.config["PARTY_URL"],
            current_app.config["BASIC_AUTH"],
            collection_exercise_id=collection_exercise_id,
        )

        account_service_url = current_app.config["ACCOUNT_SERVICE_URL"]
        account_service_log_out_url = current_app.config[
            "ACCOUNT_SERVICE_LOG_OUT_URL"]
        iat = time.time()
        exp = time.time() + (5 * 60)

        payload = {
            "jti":
            str(uuid.uuid4()),
            "tx_id":
            tx_id,
            "user_id":
            party_id,
            "iat":
            int(iat),
            "exp":
            int(exp),
            "eq_id":
            eq_id,
            "period_str":
            collection_exercise["userDescription"],
            "period_id":
            collection_exercise["exerciseRef"],
            "form_type":
            form_type,
            "collection_exercise_sid":
            collection_exercise["id"],
            "ru_ref":
            party["sampleUnitRef"] + party["checkletter"],
            "ru_name":
            party["name"],
            "survey_id":
            survey["surveyRef"],
            "case_id":
            case["id"],
            "case_ref":
            case["caseRef"],
            "account_service_url":
            account_service_url,
            "account_service_log_out_url":
            account_service_log_out_url,
            "trad_as":
            f"{party['tradstyle1']} {party['tradstyle2']} {party['tradstyle3']}",
        }

        # Add any non null event dates that exist for this collection exercise
        payload.update([(key, value)
                        for key, value in collex_event_dates.items()
                        if value is not None])

        # Add response_id for v3
        if version == "v3":
            payload.update({
                "response_id":
                f"{party['sampleUnitRef'] + party['checkletter']}"
                f"{collection_exercise['id']}{eq_id}{form_type}"
            })

        logger.debug(payload)

        return payload
class EqPayload(object):
    def create_payload(self, case, party_id, business_party_id, survey):
        """
        Creates the payload needed to communicate with EQ, built from the Case, Collection Exercise, Party,
        Survey and Collection Instrument services
        :case_id: The unique UUID references of a case
        :return Payload for EQ
        """

        tx_id = str(uuid.uuid4())
        logger.info('Creating payload for JWT',
                    case_id=case['id'],
                    tx_id=tx_id)

        # Collection Instrument
        ci_id = case['collectionInstrumentId']
        ci = collection_instrument_controller.get_collection_instrument(
            ci_id, current_app.config['COLLECTION_INSTRUMENT_URL'],
            current_app.config['BASIC_AUTH'])
        if ci['type'] != 'EQ':
            raise InvalidEqPayLoad(
                f'Collection instrument {ci_id} type is not EQ')

        classifiers = ci['classifiers']
        if not classifiers or not classifiers.get(
                'eq_id') or not classifiers.get('form_type'):
            raise InvalidEqPayLoad(
                f'Collection instrument {ci_id} classifiers are incorrect or missing'
            )

        eq_id = ci['classifiers']['eq_id']
        form_type = ci['classifiers']['form_type']

        # Collection Exercise
        collex_id = case["caseGroup"]["collectionExerciseId"]
        collex = collection_exercise_controller.get_collection_exercise(
            collex_id)
        collex_event_dates = self._get_collex_event_dates(collex_id)

        # Party
        party = party_controller.get_party_by_business_id(
            business_party_id,
            current_app.config['PARTY_URL'],
            current_app.config['BASIC_AUTH'],
            collection_exercise_id=collex_id)

        account_service_url = current_app.config['ACCOUNT_SERVICE_URL']
        account_service_log_out_url = current_app.config[
            'ACCOUNT_SERVICE_LOG_OUT_URL']
        iat = time.time()
        exp = time.time() + (5 * 60)

        payload = {
            'jti':
            str(uuid.uuid4()),
            'tx_id':
            tx_id,
            'user_id':
            party_id,
            'iat':
            int(iat),
            'exp':
            int(exp),
            'eq_id':
            eq_id,
            'period_str':
            collex['userDescription'],
            'period_id':
            collex['exerciseRef'],
            'form_type':
            form_type,
            'collection_exercise_sid':
            collex['id'],
            'ru_ref':
            party['sampleUnitRef'] + party['checkletter'],
            'ru_name':
            party['name'],
            'survey_id':
            survey['surveyRef'],
            'case_id':
            case['id'],
            'case_ref':
            case['caseRef'],
            'account_service_url':
            account_service_url,
            'account_service_log_out_url':
            account_service_log_out_url,
            'trad_as':
            f"{party['tradstyle1']} {party['tradstyle2']} {party['tradstyle3']}"
        }

        # Add any non null event dates that exist for this collection exercise
        payload.update([(key, value)
                        for key, value in collex_event_dates.items()
                        if value is not None])

        logger.debug(payload)

        return payload