Пример #1
0
def _submit_data(user):

    answer_store = get_answer_store(user)

    if answer_store.answers:
        metadata = get_metadata(user)
        collection_metadata = get_collection_metadata(user)
        schema = load_schema_from_metadata(metadata)
        completed_blocks = get_completed_blocks(user)
        routing_path = PathFinder(schema, answer_store, metadata,
                                  completed_blocks).get_full_routing_path()

        message = convert_answers(metadata,
                                  collection_metadata,
                                  schema,
                                  answer_store,
                                  routing_path,
                                  flushed=True)
        encrypted_message = encrypt(message, current_app.eq['key_store'],
                                    KEY_PURPOSE_SUBMISSION)

        sent = current_app.eq['submitter'].send_message(
            encrypted_message, current_app.config['EQ_RABBITMQ_QUEUE_NAME'],
            metadata['tx_id'])

        if not sent:
            raise SubmissionFailedException()

        get_questionnaire_store(user.user_id, user.user_ik).delete()
        return True

    return False
Пример #2
0
def get_block(eq_id, form_type, collection_id, group_id, group_instance,
              block_id):  # pylint: disable=unused-argument,too-many-locals
    current_location = Location(group_id, group_instance, block_id)
    metadata = get_metadata(current_user)
    answer_store = get_answer_store(current_user)
    path_finder = PathFinder(g.schema_json, answer_store, metadata)
    valid_group = group_id in SchemaHelper.get_group_ids(g.schema_json)
    full_routing_path = path_finder.get_routing_path()
    is_valid_location = valid_group and current_location in path_finder.get_routing_path(
        group_id, group_instance)
    latest_location = path_finder.get_latest_location(
        get_completed_blocks(current_user), routing_path=full_routing_path)
    if not is_valid_location:
        return _redirect_to_location(collection_id, eq_id, form_type,
                                     latest_location)

    block = _render_schema(current_location)
    block_type = block['type']
    is_skipping_to_end = block_type in [
        'Summary', 'Confirmation'
    ] and current_location != latest_location
    if is_skipping_to_end:
        return _redirect_to_location(collection_id, eq_id, form_type,
                                     latest_location)

    context = _get_context(block, current_location, answer_store)
    return _build_template(current_location,
                           context,
                           template=block_type,
                           routing_path=full_routing_path)
Пример #3
0
def login():
    """
    Initial url processing - expects a token parameter and then will authenticate this token. Once authenticated
    it will be placed in the users session
    :return: a 302 redirect to the next location for the user
    """
    logger.new()
    # logging in again clears any session state
    if session:
        session.clear()

    logger.debug("attempting token authentication")
    authenticator.jwt_login(request)
    logger.debug("token authenticated - linking to session")

    metadata = get_metadata(current_user)

    eq_id = metadata["eq_id"]
    form_type = metadata["form_type"]

    logger.bind(eq_id=eq_id, form_type=form_type)

    if not eq_id or not form_type:
        logger.error("missing eq id or form type in jwt")
        raise NotFound

    json = get_schema(metadata)

    navigator = PathFinder(json, get_answer_store(current_user), metadata)
    current_location = navigator.get_latest_location(
        get_completed_blocks(current_user))

    return redirect(current_location.url(metadata))
Пример #4
0
def get_summary(eq_id, form_type, period_id, collection_id):
    navigator = g.questionnaire_manager.navigator
    latest_location = navigator.get_latest_location(get_answers(current_user), get_completed_blocks(current_user))
    if latest_location is 'summary':
        return render_page('summary', True)

    return redirect_to_questionnaire_page(eq_id, form_type, period_id, collection_id, latest_location)
Пример #5
0
def _redirect_to_latest_location(collection_id, eq_id, form_type, schema):
    metadata = get_metadata(current_user)
    answer_store = get_answer_store(current_user)
    path_finder = PathFinder(schema, answer_store, metadata)
    routing_path = path_finder.get_routing_path()
    latest_location = path_finder.get_latest_location(
        get_completed_blocks(current_user), routing_path=routing_path)
    return _redirect_to_location(collection_id, eq_id, form_type,
                                 latest_location)
def get_path_finder():
    finder = getattr(g, 'path_finder', None)

    if finder is None:
        metadata = get_metadata(current_user)
        answer_store = get_answer_store(current_user)
        completed_blocks = get_completed_blocks(current_user)
        finder = PathFinder(g.schema, answer_store, metadata, completed_blocks)
        g.path_finder = finder

    return finder
Пример #7
0
def is_survey_completed(answer_store, metadata):
    path_finder = PathFinder(g.schema_json, answer_store, metadata)
    completed_blocks = get_completed_blocks(current_user)

    for location in path_finder.get_routing_path():
        if location.block_id in ['thank-you', 'summary', 'confirmation']:
            continue

        if location not in completed_blocks:
            return False, location

    return True, None
Пример #8
0
def get_confirmation(eq_id, form_type, collection_id):  # pylint: disable=unused-argument
    answer_store = get_answer_store(current_user)
    path_finder = PathFinder(g.schema_json, answer_store, get_metadata(current_user))

    latest_location = path_finder.get_latest_location(get_completed_blocks(current_user))

    if latest_location.block_id == 'confirmation':
        block = _render_schema(latest_location)
        return _build_template(current_location=latest_location, context={"block": block})

    metadata = get_metadata(current_user)

    return redirect(latest_location.url(metadata))
def dump_submission():
    answer_store = get_answer_store(current_user)
    metadata = get_metadata(current_user)
    session_data = get_session_store().session_data
    schema = load_schema_from_session_data(session_data)
    completed_blocks = get_completed_blocks(current_user)
    routing_path = PathFinder(schema, answer_store, metadata,
                              completed_blocks).get_full_routing_path()
    response = {
        'submission': convert_answers(metadata, schema, answer_store,
                                      routing_path)
    }
    return jsonify(response), 200
Пример #10
0
def _get_front_end_navigation(answer_store,
                              current_location,
                              metadata,
                              schema,
                              routing_path=None):
    completed_blocks = get_completed_blocks(current_user)
    navigation = Navigation(schema, answer_store, metadata, completed_blocks,
                            routing_path, get_completeness(current_user))
    block_json = schema.get_block(current_location.block_id)
    if block_json['type'] != 'Introduction':
        return navigation.build_navigation(current_location.group_id,
                                           current_location.group_instance)

    return None
Пример #11
0
def get_summary(eq_id, form_type, collection_id):  # pylint: disable=unused-argument
    answer_store = get_answer_store(current_user)
    path_finder = PathFinder(g.schema_json, answer_store, get_metadata(current_user))
    latest_location = path_finder.get_latest_location(get_completed_blocks(current_user))
    metadata = get_metadata(current_user)

    if latest_location.block_id is 'summary':
        answers = get_answer_store(current_user)
        schema_context = build_schema_context(metadata, g.schema.aliases, answers)
        rendered_schema_json = renderer.render(g.schema_json, **schema_context)
        summary_context = build_summary_rendering_context(rendered_schema_json, answer_store, metadata)
        return _build_template(current_location=latest_location, context=summary_context)

    return redirect(latest_location.url(metadata))
Пример #12
0
def _get_front_end_navigation(answer_store,
                              current_location,
                              metadata,
                              routing_path=None):
    completed_blocks = get_completed_blocks(current_user)
    navigation = Navigation(g.schema_json, answer_store, metadata,
                            completed_blocks, routing_path)
    block_json = SchemaHelper.get_block_for_location(g.schema_json,
                                                     current_location)
    if block_json is not None and block_json['type'] in (
            'Questionnaire', 'Interstitial', 'Confirmation', 'Summary'):
        return navigation.build_navigation(current_location.group_id,
                                           current_location.group_instance)
    else:
        return None
Пример #13
0
def post_block(eq_id, form_type, collection_id, group_id, group_instance,
               block_id):  # pylint: disable=too-many-locals
    current_location = Location(group_id, group_instance, block_id)
    metadata = get_metadata(current_user)
    answer_store = get_answer_store(current_user)
    path_finder = PathFinder(g.schema_json, answer_store, metadata)

    valid_group = group_id in SchemaHelper.get_group_ids(g.schema_json)
    full_routing_path = path_finder.get_routing_path()
    is_valid_location = valid_group and current_location in path_finder.get_routing_path(
        group_id, group_instance)
    if not is_valid_location:
        latest_location = path_finder.get_latest_location(
            get_completed_blocks(current_user), routing_path=full_routing_path)
        return _redirect_to_location(collection_id, eq_id, form_type,
                                     latest_location)

    error_messages = SchemaHelper.get_messages(g.schema_json)
    block = _render_schema(current_location)
    disable_mandatory = 'action[save_sign_out]' in request.form
    form, _ = post_form_for_location(block,
                                     current_location,
                                     answer_store,
                                     request.form,
                                     error_messages,
                                     disable_mandatory=disable_mandatory)

    if 'action[save_sign_out]' in request.form:
        return _save_sign_out(collection_id, eq_id, form_type,
                              current_location, form)
    elif _is_invalid_form(form):
        context = {'form': form, 'block': block}
        return _build_template(current_location,
                               context,
                               template=block['type'],
                               routing_path=full_routing_path)
    else:
        _update_questionnaire_store(current_location, form)
        next_location = path_finder.get_next_location(
            current_location=current_location)

        if next_location is None and block['type'] in [
                "Summary", "Confirmation"
        ]:
            return submit_answers(eq_id, form_type, collection_id, metadata,
                                  answer_store)

        return redirect(next_location.url(metadata))
Пример #14
0
def login():
    """
    Initial url processing - expects a token parameter and then will authenticate this token. Once authenticated
    it will be placed in the users session
    :return: a 302 redirect to the next location for the user
    """
    decrypted_token = decrypt_token(request.args.get('token'))
    metadata = parse_metadata(decrypted_token)
    eq_id = metadata["eq_id"]
    form_type = metadata["form_type"]
    tx_id = metadata["tx_id"]
    ru_ref = metadata["ru_ref"]
    logger.bind(eq_id=eq_id, form_type=form_type, tx_id=tx_id, ru_ref=ru_ref)
    logger.info("decrypted token and parsed metadata")

    if not eq_id or not form_type:
        logger.error("missing eq id or form type in jwt")
        raise NotFound

    # logging in again clears any session state
    if session:
        session.clear()

    jti_claim = metadata.get('jti')
    if jti_claim is None:
        logger.debug('jti claim not provided')
    else:
        try:
            jti_claim_storage = JtiClaimStorage(current_app.eq['database'])
            jti_claim_storage.use_jti_claim(jti_claim)
        except JtiTokenUsed as e:
            raise Unauthorized from e

    store_session(metadata)

    json = load_schema_from_metadata(metadata)

    navigator = PathFinder(json, get_answer_store(current_user), metadata)
    current_location = navigator.get_latest_location(get_completed_blocks(current_user))

    return redirect(current_location.url(metadata))
Пример #15
0
def _build_template(current_location, context=None, template=None):
    metadata = get_metadata(current_user)
    metadata_context = build_metadata_context(metadata)

    answer_store = get_answer_store(current_user)
    completed_blocks = get_completed_blocks(current_user)

    navigation = Navigation(g.schema_json, answer_store, metadata, completed_blocks)
    front_end_navigation = navigation.build_navigation(current_location.group_id, current_location.group_instance)

    path_finder = PathFinder(g.schema_json, answer_store, metadata)
    previous_location = path_finder.get_previous_location(current_location)

    previous_url = None

    is_first_block_for_group = SchemaHelper.is_first_block_id_for_group(g.schema_json, current_location.group_id, current_location.block_id)

    if previous_location is not None and not is_first_block_for_group and not current_location.block_id == 'thank-you':
        previous_url = previous_location.url(metadata)

    return _render_template(context, current_location.block_id, front_end_navigation, metadata_context, current_location, previous_url, template)
Пример #16
0
def login():
    """
    Initial url processing - expects a token parameter and then will authenticate this token. Once authenticated
    it will be placed in the users session
    :return: a 302 redirect to the next location for the user
    """

    # logging in again clears any session state
    if session:
        session.clear()

    authenticator = Authenticator()
    logger.debug("Attempting token authentication")

    authenticator.jwt_login(request)
    logger.debug("Token authenticated - linking to session")

    metadata = get_metadata(current_user)

    eq_id = metadata["eq_id"]
    collection_id = metadata["collection_exercise_sid"]
    form_type = metadata["form_type"]
    period_id = metadata["period_id"]

    logger.debug("Requested questionnaire %s for form type %s", eq_id, form_type)
    if not eq_id or not form_type:
        logger.error("Missing EQ id %s or form type %s in JWT", eq_id, form_type)
        raise NotFound

    json, schema = get_schema()
    questionnaire_manager = QuestionnaireManager(schema, json=json)

    navigator = questionnaire_manager.navigator
    current_location = navigator.get_latest_location(get_answers(current_user), get_completed_blocks(current_user))

    return redirect('/questionnaire/' + eq_id + '/' + form_type + '/' + period_id + '/' + collection_id + '/' + current_location)