def download_collection_instrument(collection_instrument_id, case_id,
                                   party_id):
    logger.debug('Attempting to download collection instrument',
                 collection_instrument_id=collection_instrument_id,
                 party_id=party_id)

    url = f"{app.config['COLLECTION_INSTRUMENT_URL']}/collection-instrument-api/1.0.2/download/{collection_instrument_id}"
    response = requests.get(url, auth=app.config['COLLECTION_INSTRUMENT_AUTH'])

    # Post relevant download case event
    category = 'COLLECTION_INSTRUMENT_DOWNLOADED' if response.ok else 'COLLECTION_INSTRUMENT_ERROR'
    case_controller.post_case_event(
        case_id,
        party_id=party_id,
        category=category,
        description=
        f'Instrument {collection_instrument_id} downloaded by {party_id} for case {case_id}'
    )

    try:
        response.raise_for_status()
    except requests.exceptions.HTTPError:
        raise ApiError(logger,
                       response,
                       collection_instrument_id=collection_instrument_id,
                       log_level='warning'
                       if response.status_code == 404 else 'exception',
                       message='Failed to download collection instrument',
                       party_id=party_id)

    logger.debug('Successfully downloaded collection instrument',
                 collection_instrument_id=collection_instrument_id,
                 party_id=party_id)
    return response.content, response.headers.items()
Example #2
0
def ci_post_case_event(case_id, party_id, category):
    # Post relevant upload case event
    case_controller.post_case_event(
        case_id,
        party_id=party_id,
        category=category,
        description=
        f"Survey response for case {case_id} uploaded by {party_id}",
    )
Example #3
0
def register():
    cryptographer = Cryptographer()
    form = EnrolmentCodeForm(request.form)
    if form.enrolment_code.data:
        form.enrolment_code.data = form.enrolment_code.data.strip()

    if request.method == 'POST' and form.validate():
        logger.info('Enrolment code submitted')
        enrolment_code = form.enrolment_code.data.lower()

        # Validate the enrolment code
        try:
            iac = iac_controller.get_iac_from_enrolment(enrolment_code)
            if iac is None:
                template_data = {"error": {"type": "failed"}}
                return render_template(
                    'register/register.enter-enrolment-code.html',
                    form=form,
                    data=template_data), 200
        except ApiError as exc:
            if exc.status_code == 400:
                logger.info('Enrolment code already used')
                template_data = {"error": {"type": "failed"}}
                return render_template(
                    'register/register.enter-enrolment-code.html',
                    form=form,
                    data=template_data), 200
            else:
                logger.error('Failed to submit enrolment code')
                raise exc

        # This is the initial submission of enrolment code so post a case event for authentication attempt
        case_id = iac['caseId']
        case = case_controller.get_case_by_enrolment_code(enrolment_code)
        business_party_id = case['partyId']
        case_controller.post_case_event(
            case_id,
            party_id=business_party_id,
            category='ACCESS_CODE_AUTHENTICATION_ATTEMPT',
            description='Access code authentication attempted')

        encrypted_enrolment_code = cryptographer.encrypt(
            enrolment_code.encode()).decode()
        logger.info('Successful enrolment code submitted')
        return redirect(
            url_for('register_bp.register_confirm_organisation_survey',
                    encrypted_enrolment_code=encrypted_enrolment_code,
                    _external=True,
                    _scheme=os.getenv('SCHEME', 'http')))

    return render_template('register/register.enter-enrolment-code.html',
                           form=form,
                           data={"error": {}})
Example #4
0
def download_collection_instrument(collection_instrument_id, case_id,
                                   party_id):
    """
    Downloads the collection instrument and updates the case with the record that the instrument has been downloaded.

    :param collection_instrument_id: UUID of the collection instrument
    :param case_id: UUID of the case
    :param party_id: UUID of the party
    :return: A tuple containing the collection instrument and the headers
    """
    bound_logger = logger.bind(
        collection_instrument_id=collection_instrument_id,
        party_id=party_id,
        case_id=case_id)
    bound_logger.info("Attempting to download collection instrument")

    url = (
        f"{app.config['COLLECTION_INSTRUMENT_URL']}/collection-instrument-api/1.0.2/download/{collection_instrument_id}"
    )
    response = requests.get(url, auth=app.config["BASIC_AUTH"])

    # Post relevant download case event
    category = "COLLECTION_INSTRUMENT_DOWNLOADED" if response.ok else "COLLECTION_INSTRUMENT_ERROR"
    case_controller.post_case_event(
        case_id,
        party_id=party_id,
        category=category,
        description=
        f"Instrument {collection_instrument_id} downloaded by {party_id} for case {case_id}",
    )

    try:
        response.raise_for_status()
    except requests.exceptions.HTTPError:
        bound_logger.error("Failed to download collection instrument")
        bound_logger.unbind("collection_instrument_id", "party_id", "case_id")
        raise ApiError(logger, response)

    bound_logger.info("Successfully downloaded collection instrument")

    headers = response.headers
    acao = app.config["ACCESS_CONTROL_ALLOW_ORIGIN"]
    bound_logger.debug(f"Setting Access-Control-Allow-Origin header to {acao}")
    headers["Access-Control-Allow-Origin"] = acao
    bound_logger.unbind("collection_instrument_id", "party_id", "case_id")
    return response.content, headers.items()
def add_survey_submit(session):
    party_id = session['party_id']
    logger.info('Assigning new survey to a user', party_id=party_id)

    cryptographer = Cryptographer()
    encrypted_enrolment_code = request.args.get('encrypted_enrolment_code')
    enrolment_code = cryptographer.decrypt(
        encrypted_enrolment_code.encode()).decode()

    try:
        # Verify enrolment code is active
        iac = iac_controller.get_iac_from_enrolment(enrolment_code)

        # 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']
        case_controller.post_case_event(
            case_id,
            party_id=business_party_id,
            category='ACCESS_CODE_AUTHENTICATION_ATTEMPT',
            description='Access code authentication attempted')

        party_controller.add_survey(party_id, enrolment_code)

        # Get survey ID from collection Exercise
        added_survey_id = collection_exercise_controller.get_collection_exercise(
            case['caseGroup']['collectionExerciseId']).get('surveyId')

    except ApiError as exc:
        logger.error('Failed to assign user to a survey',
                     party_id=party_id,
                     status_code=exc.status_code)
        raise

    logger.info(
        'Successfully retrieved data for confirm add organisation/survey page',
        case_id=case_id,
        party_id=party_id)
    return redirect(
        url_for('surveys_bp.get_survey_list',
                _anchor=(business_party_id, added_survey_id),
                _external=True,
                business_party_id=business_party_id,
                survey_id=added_survey_id,
                tag='todo'))
def upload_collection_instrument(upload_file, case_id, party_id):
    logger.debug('Attempting to upload collection instrument',
                 case_id=case_id,
                 party_id=party_id)

    url = f"{app.config['COLLECTION_INSTRUMENT_URL']}/survey_response-api/v1/survey_responses/{case_id}"
    response = requests.post(url,
                             auth=app.config['COLLECTION_INSTRUMENT_AUTH'],
                             files=upload_file)

    # Post relevant upload case event
    category = 'SUCCESSFUL_RESPONSE_UPLOAD' if response.ok else 'UNSUCCESSFUL_RESPONSE_UPLOAD'
    case_controller.post_case_event(
        case_id,
        party_id=party_id,
        category=category,
        description=f'Survey response for case {case_id} uploaded by {party_id}'
    )

    if response.status_code == 400:
        raise CiUploadError(logger,
                            response,
                            case_id=case_id,
                            error_message=response.text,
                            party_id=party_id)

    try:
        response.raise_for_status()
    except requests.exceptions.HTTPError:
        raise ApiError(logger,
                       response,
                       case_id=case_id,
                       log_level='warning'
                       if response.status_code == 404 else 'exception',
                       message='Failed to upload collection instrument',
                       party_id=party_id)

    logger.debug('Successfully uploaded collection instrument',
                 case_id=case_id,
                 party_id=party_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)
            already_enrolled = True
        else:
            case_controller.post_case_event(
                case_id,
                party_id=business_party_id,
                category='ACCESS_CODE_AUTHENTICATION_ATTEMPT',
                description='Access code authentication attempted')

            party_controller.add_survey(party_id, enrolment_code)

    except ApiError as exc:
        logger.error('Failed to assign user to a survey',
                     party_id=party_id,
                     status_code=exc.status_code)
        raise

    logger.info(
        'Successfully retrieved data for confirm add organisation/survey page',
        case_id=case_id,
        party_id=party_id)
def register():
    cryptographer = Cryptographer()
    form = EnrolmentCodeForm(request.form)
    if form.enrolment_code.data:
        form.enrolment_code.data = form.enrolment_code.data.strip()

    if request.method == "POST" and form.validate():
        enrolment_code = form.enrolment_code.data.lower()
        logger.info(
            "Enrolment code submitted when attempting to create account",
            enrolment_code=enrolment_code)

        # Validate the enrolment code
        try:
            iac = iac_controller.get_iac_from_enrolment(enrolment_code)
            if iac is None:
                logger.info(
                    "Enrolment code not found when attempting to create account",
                    enrolment_code=enrolment_code)
                template_data = {"error": {"type": "failed"}}
                return (
                    render_template(
                        "register/register.enter-enrolment-code.html",
                        form=form,
                        data=template_data),
                    200,
                )
            if not iac["active"]:
                logger.info(
                    "Enrolment code not active when attempting to create account",
                    enrolment_code=enrolment_code)
                template_data = {"error": {"type": "failed"}}
                return render_template(
                    "register/register.enter-enrolment-code.html",
                    form=form,
                    data=template_data)
        except ApiError as exc:
            if exc.status_code == 400:
                logger.info(
                    "Enrolment code already used when attempting to create account",
                    enrolment_code=enrolment_code)
                template_data = {"error": {"type": "failed"}}
                return (
                    render_template(
                        "register/register.enter-enrolment-code.html",
                        form=form,
                        data=template_data),
                    200,
                )
            else:
                logger.error(
                    "Failed to submit enrolment code when attempting to create account",
                    enrolment_code=enrolment_code)
                raise exc

        # This is the initial submission of enrolment code so post a case event for authentication attempt
        case_id = iac["caseId"]
        case = case_controller.get_case_by_enrolment_code(enrolment_code)
        business_party_id = case["partyId"]
        case_controller.post_case_event(
            case_id,
            party_id=business_party_id,
            category="ACCESS_CODE_AUTHENTICATION_ATTEMPT",
            description="Access code authentication attempted",
        )

        encrypted_enrolment_code = cryptographer.encrypt(
            enrolment_code.encode()).decode()
        logger.info(
            "Successful enrolment code submitted when attempting to create account",
            enrolment_code=enrolment_code)
        return redirect(
            url_for(
                "register_bp.register_confirm_organisation_survey",
                encrypted_enrolment_code=encrypted_enrolment_code,
                _external=True,
                _scheme=os.getenv("SCHEME", "http"),
            ))

    return render_template("register/register.enter-enrolment-code.html",
                           form=form,
                           data={"error": {}})