def test_get_survey_by_id_fail(self):
     with responses.RequestsMock() as rsps:
         rsps.add(rsps.GET, url_get_survey, status=400)
         with app.app_context():
             with self.assertRaises(ApiError):
                 survey_controller.get_survey(self.app_config["SURVEY_URL"],
                                              self.app_config["BASIC_AUTH"],
                                              survey["id"])
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')
Example #3
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")
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")
Example #5
0
    def get_survey(self, key):
        """
        Gets the survey from redis or the collection-instrument service

        :param key: Key in redis (for this example will be a frontstage:survey:id)
        :return: Result from either the cache or survey service
        """
        redis_key = f"frontstage:survey:{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 survey service",
                        key=redis_key)
            result = get_survey(app.config["SURVEY_URL"],
                                app.config["BASIC_AUTH"], key)
            self.save(redis_key, result, self.SURVEY_CATEGORY_EXPIRY)
            return result

        return json.loads(result.decode("utf-8"))
    def test_get_survey_by_id_success(self):
        with responses.RequestsMock() as rsps:
            rsps.add(rsps.GET,
                     url_get_survey,
                     json=survey,
                     status=200,
                     content_type='application/json')
            with app.app_context():
                get_survey = survey_controller.get_survey(survey['id'])

                self.assertIn(
                    'Bricks', get_survey['shortName'],
                    'Bricks short name is not in the returned survey')
Example #7
0
def send_instruction_get(session):
    email = flask_session['share_survey_recipient_email_address']
    selected_surveys = []
    for survey_id in flask_session['share_survey_surveys_selected']:
        selected_surveys.append(
            survey_controller.get_survey(app.config['SURVEY_URL'],
                                         app.config['BASIC_AUTH'], survey_id))
    selected_business = get_business_by_id(
        [flask_session['share_survey_business_selected']])
    return render_template('surveys/surveys-share/send-instructions.html',
                           email=email,
                           surveys=selected_surveys,
                           form=ConfirmEmailChangeForm(),
                           business_name=selected_business[0]['name'])
    def test_get_survey_by_id_success(self):
        with responses.RequestsMock() as rsps:
            rsps.add(rsps.GET,
                     url_get_survey,
                     json=survey,
                     status=200,
                     content_type="application/json")
            with app.app_context():
                get_survey = survey_controller.get_survey(
                    self.app_config["SURVEY_URL"],
                    self.app_config["BASIC_AUTH"], survey["id"])

                self.assertIn(
                    "Bricks", get_survey["shortName"],
                    "Bricks short name is not in the returned survey")
Example #9
0
def get_surveys_listed_against_party_and_business_id(business_id, party_id):
    """
    returns list of surveys associated with a business id and respondent
    :param business_id: business id
    :param party_id: The respondent's party id
    :return: list of surveys
    :rtype: list
    """
    enrolment_data = get_respondent_enrolments(party_id)
    survey_ids = {
        enrolment['survey_id']
        for enrolment in enrolment_data
        if enrolment['business_id'] == business_id
    }
    surveys = []
    for survey in survey_ids:
        response = survey_controller.get_survey(app.config['SURVEY_URL'],
                                                app.config['BASIC_AUTH'],
                                                survey)
        surveys.append(response)
    return surveys
Example #10
0
def send_instruction_get(session):
    email = flask_session["share_survey_recipient_email_address"]
    share_dict = {}
    for business_id in flask_session["share_survey_data"]:
        selected_business = get_business_by_id(business_id)
        surveys = []
        for survey_id in flask_session["share_survey_data"][business_id]:
            surveys.append(
                survey_controller.get_survey(app.config["SURVEY_URL"],
                                             app.config["BASIC_AUTH"],
                                             survey_id))
        share_dict[selected_business[0]["id"]] = {
            "name": selected_business[0]["name"],
            "surveys": surveys,
        }
    return render_template(
        "surveys/surveys-share/send-instructions.html",
        email=email,
        share_dict=share_dict,
        form=ConfirmEmailChangeForm(),
    )
def get_surveys_listed_against_party_and_business_id(business_id: str,
                                                     party_id: str) -> list:
    """
    returns list of surveys associated with a business id and respondent
    :param business_id: business id
    :param party_id: The respondent's party id
    :return: list of surveys
    """
    respondent = get_respondent_party_by_id(party_id)
    enrolment_data = get_respondent_enrolments(respondent)
    survey_ids = {
        enrolment["survey_id"]
        for enrolment in enrolment_data
        if enrolment["business_id"] == business_id
    }
    surveys = []
    for survey in survey_ids:
        response = survey_controller.get_survey(app.config["SURVEY_URL"],
                                                app.config["BASIC_AUTH"],
                                                survey)
        surveys.append(response)
    return surveys
Example #12
0
def view_conversation(session, thread_id):
    """Endpoint to view conversations by thread_id"""
    party_id = session.get_party_id()
    logger.info("Getting conversation", thread_id=thread_id, party_id=party_id)
    conversation = get_conversation(thread_id)
    # secure message will send category in case the conversation is technical or miscellaneous
    is_survey_category = (
        False if "category" in conversation
        and conversation["category"] in ["TECHNICAL", "MISC"] else True)
    # sets appropriate message category
    category = "SURVEY" if is_survey_category else conversation["category"]
    logger.info("Successfully retrieved conversation",
                thread_id=thread_id,
                party_id=party_id)
    try:
        refined_conversation = [
            refine(message) for message in reversed(conversation["messages"])
        ]
    except KeyError:
        logger.error("Message is missing important data",
                     thread_id=thread_id,
                     party_id=party_id)
        raise

    if refined_conversation[-1]["unread"]:
        remove_unread_label(refined_conversation[-1]["message_id"])

    form = SecureMessagingForm(request.form)
    form.subject.data = refined_conversation[0].get("subject")

    if not conversation["is_closed"]:
        if form.validate_on_submit():
            logger.info("Sending message",
                        thread_id=thread_id,
                        party_id=party_id)
            msg_to = get_msg_to(refined_conversation)
            if is_survey_category:
                send_message(
                    _get_message_json(form,
                                      refined_conversation[0],
                                      msg_to=msg_to,
                                      msg_from=party_id))
            else:
                send_message(
                    _get_non_survey_message_json(form,
                                                 refined_conversation[0],
                                                 msg_to=msg_to,
                                                 msg_from=party_id,
                                                 category=category))
            logger.info("Successfully sent message",
                        thread_id=thread_id,
                        party_id=party_id)
            thread_url = url_for("secure_message_bp.view_conversation",
                                 thread_id=thread_id) + "#latest-message"
            flash(
                Markup(f"Message sent. <a href={thread_url}>View Message</a>"))
            return redirect(
                url_for("secure_message_bp.view_conversation_list"))

    unread_message_count = {
        "unread_message_count": get_message_count_from_api(session)
    }
    survey_name = None
    business_name = None
    if is_survey_category:
        try:
            survey_name = get_survey(
                app.config["SURVEY_URL"], app.config["BASIC_AUTH"],
                refined_conversation[-1]["survey_id"]).get("longName")
        except ApiError as exc:
            logger.info("Failed to get survey name, setting to None",
                        status_code=exc.status_code)
        try:
            business_name = conversation["messages"][-1]["@business_details"][
                "name"]
        except (KeyError, TypeError):
            logger.info("Failed to get business name, setting to None")

    return render_template(
        "secure-messages/conversation-view.html",
        form=form,
        conversation=refined_conversation,
        conversation_data=conversation,
        unread_message_count=unread_message_count,
        survey_name=survey_name,
        business_name=business_name,
        category=category,
    )
Example #13
0
def get_survey(cache_data, survey_id, survey_url, survey_auth):
    cache_data['surveys'][survey_id] = survey_controller.get_survey(
        survey_url, survey_auth, survey_id)
Example #14
0
def get_survey_list_details_for_party(party_id, tag, business_party_id,
                                      survey_id):

    for enrolment in get_respondent_enrolments(party_id):
        business_party = get_party_by_business_id(enrolment['business_id'])
        survey = survey_controller.get_survey(enrolment['survey_id'])

        live_collection_exercises = collection_exercise_controller.get_live_collection_exercises_for_survey(
            survey['id'])
        collection_exercises_by_id = dict(
            (ce['id'], ce) for ce in live_collection_exercises)

        cases = case_controller.get_cases_for_list_type_by_party_id(
            business_party['id'], tag)
        enrolled_cases = [
            case for case in cases if case['caseGroup']['collectionExerciseId']
            in collection_exercises_by_id.keys()
        ]

        for case in enrolled_cases:
            collection_instrument = collection_instrument_controller.get_collection_instrument(
                case['collectionInstrumentId'])
            collection_exercise = collection_exercises_by_id[
                case['caseGroup']['collectionExerciseId']]
            added_survey = True if business_party_id == business_party[
                'id'] and survey_id == survey['id'] else None
            display_access_button = display_button(
                case['caseGroup']['caseGroupStatus'],
                collection_instrument['type'])

            yield {
                'case_id':
                case['id'],
                'status':
                case_controller.calculate_case_status(
                    case['caseGroup']['caseGroupStatus'],
                    collection_instrument['type']),
                'collection_instrument_type':
                collection_instrument['type'],
                'survey_id':
                survey['id'],
                'survey_long_name':
                survey['longName'],
                'survey_short_name':
                survey['shortName'],
                'survey_ref':
                survey['surveyRef'],
                'business_party_id':
                business_party['id'],
                'business_name':
                business_party['name'],
                'trading_as':
                business_party['trading_as'],
                'business_ref':
                business_party['sampleUnitRef'],
                'period':
                collection_exercise['userDescription'],
                'submit_by':
                collection_exercise['events']['return_by']['date'],
                'collection_exercise_ref':
                collection_exercise['exerciseRef'],
                'added_survey':
                added_survey,
                'display_button':
                display_access_button
            }


def display_button(status, ci_type):
    return not (ci_type == 'EQ' and status in CLOSED_STATE)


def is_respondent_enrolled(party_id,
                           business_party_id,
                           survey_short_name,
                           return_survey=False):
    survey = survey_controller.get_survey_by_short_name(survey_short_name)
    for enrolment in get_respondent_enrolments(party_id):
        if enrolment['business_id'] == business_party_id and enrolment[
                'survey_id'] == survey['id']:
            if return_survey:
                return {'survey': survey}
            return True


def notify_party_and_respondent_account_locked(respondent_id,
                                               email_address,
                                               status=None):
    logger.debug(
        'Notifying respondent and party service that account is locked')
    url = f'{app.config["PARTY_URL"]}/party-api/v1/respondents/edit-account-status/{respondent_id}'

    data = {
        'respondent_id': respondent_id,
        'email_address': email_address,
        'status_change': status
    }

    response = requests.put(url, json=data, auth=app.config['PARTY_AUTH'])

    try:
        response.raise_for_status()
    except requests.exceptions.HTTPError:
        logger.error('Failed to notify party',
                     respondent_id=respondent_id,
                     status=status)
        raise ApiError(logger, response)

    logger.info('Successfully notified party and respondent',
                respondent_id=respondent_id,
                status=status)
def get_share_survey_summary(token):
    """
    Endpoint to verify token and retrieve the summary page
    :param token: share survey token
    :type token: str
    """
    logger.info("Getting share survey summary", token=token)
    try:
        response = party_controller.verify_pending_survey_token(token)
        pending_share_surveys = response.json()
        share_dict = {}
        distinct_businesses = set()
        batch_number = pending_share_surveys[0]["batch_no"]
        originator_party = party_controller.get_respondent_party_by_id(
            pending_share_surveys[0]["shared_by"])
        shared_by = originator_party["emailAddress"]
        for pending_share_survey in pending_share_surveys:
            distinct_businesses.add(pending_share_survey["business_id"])
        for business_id in distinct_businesses:
            business_surveys = []
            for pending_share_survey in pending_share_surveys:
                if pending_share_survey["business_id"] == business_id:
                    business_surveys.append(
                        survey_controller.get_survey(
                            app.config["SURVEY_URL"], app.config["BASIC_AUTH"],
                            pending_share_survey["survey_id"]))
            selected_business = get_business_by_id(business_id)
            share_dict[selected_business[0]["id"]] = {
                "name": selected_business[0]["name"],
                "trading_as": selected_business[0]["trading_as"],
                "surveys": business_surveys,
            }
        return render_template("surveys/surveys-share/summary.html",
                               share_dict=share_dict,
                               batch_no=batch_number,
                               shared_by=shared_by)

    except ApiError as exc:
        # Handle api errors
        if exc.status_code == 409:
            logger.info(
                "Expired share survey email verification token",
                token=token,
                api_url=exc.url,
                api_status_code=exc.status_code,
            )
            return render_template("surveys/surveys-link-expired.html",
                                   is_transfer=False)
        elif exc.status_code == 404:
            logger.warning(
                "Unrecognised share survey email verification token",
                token=token,
                api_url=exc.url,
                api_status_code=exc.status_code,
            )
            return render_template("surveys/surveys-link-not-valid.html",
                                   is_transfer=False)
        else:
            logger.info("Failed to verify share survey email",
                        token=token,
                        api_url=exc.url,
                        api_status_code=exc.status_code)
            raise exc
Example #16
0
    def create_pubsub_payload(self, case, md5sum, size_bytes, file_name,
                              tx_id: str) -> dict:
        log.info("Creating pubsub payload", case_id=case["id"])

        case_group = case.get("caseGroup")
        if not case_group:
            raise SurveyResponseError("Case group not found")

        collection_exercise_id = case_group.get("collectionExerciseId")
        collection_exercise = get_collection_exercise(collection_exercise_id)
        if not collection_exercise:
            raise SurveyResponseError("Collection exercise not found")

        exercise_ref = collection_exercise.get("exerciseRef")
        survey_id = collection_exercise.get("surveyId")
        survey = get_survey(current_app.config["SURVEY_URL"],
                            current_app.config["BASIC_AUTH"], survey_id)
        survey_ref = survey.get("surveyRef")
        if not survey_ref:
            raise SurveyResponseError("Survey ref not found")

        ru = case_group.get("sampleUnitRef")
        exercise_ref = self._format_exercise_ref(exercise_ref)

        payload = {
            "filename": file_name,
            "tx_id": tx_id,
            "survey_id": survey_ref,
            "period": exercise_ref,
            "ru_ref": ru,
            "md5sum": md5sum,
            "sizeBytes": size_bytes,
 def test_get_survey_by_id_fail(self):
     with responses.RequestsMock() as rsps:
         rsps.add(rsps.GET, url_get_survey, status=400)
         with app.app_context():
             with self.assertRaises(ApiError):
                 survey_controller.get_survey(survey['id'])
def view_conversation(session, thread_id):
    """Endpoint to view conversations by thread_id"""
    party_id = session.get_party_id()
    logger.info("Getting conversation", thread_id=thread_id, party_id=party_id)
    conversation = get_conversation(thread_id)
    logger.info('Successfully retrieved conversation',
                thread_id=thread_id,
                party_id=party_id)
    try:
        refined_conversation = [
            refine(message) for message in reversed(conversation['messages'])
        ]
    except KeyError:
        logger.error('Message is missing important data',
                     thread_id=thread_id,
                     party_id=party_id)
        raise

    if refined_conversation[-1]['unread']:
        remove_unread_label(refined_conversation[-1]['message_id'])

    form = SecureMessagingForm(request.form)
    form.subject.data = refined_conversation[0].get('subject')

    if not conversation['is_closed']:
        if form.validate_on_submit():
            logger.info("Sending message",
                        thread_id=thread_id,
                        party_id=party_id)
            msg_to = get_msg_to(refined_conversation)
            send_message(
                _get_message_json(form,
                                  refined_conversation[0],
                                  msg_to=msg_to,
                                  msg_from=party_id))
            logger.info("Successfully sent message",
                        thread_id=thread_id,
                        party_id=party_id)
            thread_url = url_for("secure_message_bp.view_conversation",
                                 thread_id=thread_id) + "#latest-message"
            flash(
                Markup(f'Message sent. <a href={thread_url}>View Message</a>'))
            return redirect(
                url_for('secure_message_bp.view_conversation_list'))

    unread_message_count = {
        'unread_message_count': get_message_count_from_api(session)
    }
    survey_name = None
    try:
        survey_name = get_survey(
            app.config['SURVEY_URL'], app.config['BASIC_AUTH'],
            refined_conversation[-1]['survey_id']).get('longName')
    except ApiError as exc:
        logger.info('Failed to get survey name, setting to None',
                    status_code=exc.status_code)

    business_name = None
    try:
        business_name = conversation['messages'][-1]['@business_details'][
            'name']
    except KeyError:
        logger.info('Failed to get business name, setting to None')

    return render_template('secure-messages/conversation-view.html',
                           form=form,
                           conversation=refined_conversation,
                           conversation_data=conversation,
                           unread_message_count=unread_message_count,
                           survey_name=survey_name,
                           business_name=business_name)