Exemple #1
0
def form_create():
    """Creates a new form with a blank schema and uiSchema.
    """
    from ..main import app
    request_body = app.current_request.json_body or {}
    if request_body.get("formId", None):
        # todo: add permissions check -- some forms should not be able to be duplicated.
        formId = request_body.get("formId", None)
        old_form = Form.objects.get({"_id": ObjectId(formId)})
        form = Form(
            name=old_form.name + " Copy - " +
            datetime.datetime.now().isoformat(),
            version=1,
            center="None",
            id=ObjectId(),
            cff_permissions={app.get_current_user_id(): {
                                 "owner": True
                             }},
            schema=old_form.schema,
            uiSchema=old_form.uiSchema,
            formOptions=old_form.formOptions,
            date_modified=datetime.datetime.now().isoformat(),
            date_created=datetime.datetime.now().isoformat())
        form.save()
        return {'res': {'form': serialize_model(form)}}
    else:
        form_name = request_body.get(
            "form_name",
            "Untitled form {}".format(datetime.datetime.now().isoformat()))
        form = Form(
            name=form_name,
            version=1,
            center="None",
            id=ObjectId(),
            cff_permissions={app.get_current_user_id(): {
                                 "owner": True
                             }},
            schema={
                "title": "Form",
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string"
                    }
                }
            },
            uiSchema={"name": {
                "ui:placeholder": "Name"
            }},
            formOptions=FormOptions(confirmationEmailInfo={},
                                    paymentInfo={},
                                    paymentMethods={},
                                    dataOptions={},
                                    defaultFormData={}),
            date_modified=datetime.datetime.now().isoformat(),
            date_created=datetime.datetime.now().isoformat())
        form.save()
        return {'res': {'form': serialize_model(form)}}
Exemple #2
0
def response_edit_common(responseId, response_base_path):
    from ..main import app
    response = Response.objects.get({"_id": ObjectId(responseId)})
    path = app.current_request.json_body.get("path", None)
    value = app.current_request.json_body.get("value", None)
    batch = app.current_request.json_body.get("batch", None)
    if batch is None:
        batch = [{"path": path, "value": value}]
    if response_base_path == "value":
        if all(item["path"].endswith(".checkin") for item in batch):
            app.check_permissions(response.form,
                                  ["Responses_CheckIn", "Responses_Edit"])
        else:
            app.check_permissions(response.form, "Responses_Edit")
    elif response_base_path == "admin_info":
        app.check_permissions(response.form, "Responses_AdminInfo_Edit")
    else:
        raise Exception(
            "response_base_path specified is not valid or you not have permissions to perform the specified action."
        )
    for item in batch:
        update_response_path(response, item["path"], item["value"],
                             response_base_path)
    response.save()
    return {"res": {"success": True, "response": serialize_model(response)}}
Exemple #3
0
def response_payment(responseId):
    from ..main import app
    response = Response.objects.get({"_id": ObjectId(responseId)})
    app.check_permissions(response.form, "Responses_Edit")
    amount = app.current_request.json_body["amount"]
    currency = app.current_request.json_body["currency"]
    date = app.current_request.json_body.get("date", None)
    if date and "$date" in date:
        date = dateutil.parser.parse(date["$date"])
    id = app.current_request.json_body["id"]
    method = app.current_request.json_body["method"]
    send_email = app.current_request.json_body.get("sendEmail", True)
    paid = mark_successful_payment(response.form,
                                   response, {
                                       "type": "manual",
                                       "method": method,
                                       "id": id
                                   },
                                   method,
                                   amount,
                                   currency,
                                   id,
                                   date=date,
                                   send_email=send_email)
    response.save()
    return {
        "res": {
            "success": True,
            "paid": paid,
            "response": serialize_model(response)
        }
    }
def do_stuff():
    i = 1
    subs = []
    first = True
    paginationToken = None
    while first or paginationToken:
        first = False
        if paginationToken:
            response = client.list_users(
                UserPoolId=pool,
                AttributesToGet=["email", "email_verified"],
                PaginationToken=paginationToken)
        else:
            response = client.list_users(
                UserPoolId=pool, AttributesToGet=["email", "email_verified"])
        subs += [u["Username"] for u in response["Users"]]
        paginationToken = response.get("PaginationToken", None)
    print(subs)
    response = Response.objects.raw({
        "user": {
            "$exists": 1
        }
    }).project({"user": 1})
    for r in response:
        _, user = r.user.split("cm:cognitoUserPool:")
        if user not in subs:
            print("NO!!! ", user, serialize_model(r))
        # print("OK")
        pass
Exemple #5
0
def response_delete(responseId):
    from ..main import app

    response = Response.objects.get({"_id": ObjectId(responseId)})
    app.check_permissions(response.form, "Responses_Delete")
    response.delete()
    return {"res": {"success": True, "response": serialize_model(response)}}
def group_edit(formId):
    from ..main import app
    form = Form.objects.get({"_id": ObjectId(formId)})
    app.check_permissions(form, 'Forms_Edit')
    groups = app.current_request.json_body["groups"]
    form.formOptions.dataOptions["groups"] = groups
    form.save()
    return {"res": {"success": True, "form": serialize_model(form)}}
Exemple #7
0
def fill_string_from_template(response, templateText):
    flat = flatdict.FlatterDict(response.value)
    for i in flat:
        flat[human_readable_key(i)] = flat.pop(i)
    kwargs = dict(serialize_model(response), response=flat)
    if kwargs.get("modify_link", None):
        kwargs["view_link"] = kwargs["modify_link"] + "&mode=view"
    msgBody = env.from_string(templateText).render(**kwargs)
    return msgBody
Exemple #8
0
def fix_data():
    for response in responses:
        indexes_to_delete = []
        i = 0
        for item in response.payment_trail:
            idx_payment_trail = 0
            idx_payment_status_detail = 0
            if item.method == "paypal_ipn" and item.value["custom"] != str(
                    response.id):
                if item.status != "SUCCESS":
                    indexes_to_delete.append([i])
                    continue
                print("Doing it...")
                idx_payment_trail = i

                # Find the associated payment_status_detail item.
                idx_payment_status_detail = find_index(
                    response.payment_status_detail,
                    lambda x: x.date == item.date)
                if idx_payment_status_detail == -1:
                    idx_payment_status_detail = find_index(
                        response.payment_status_detail, lambda x:
                        (x.date - item.date).total_seconds() < .1)
                    print(item.date, response.payment_status_detail,
                          serialize_model(response))
                assert idx_payment_status_detail != -1
                payment_status_detail_item = response.payment_status_detail[
                    idx_payment_status_detail]
                print("old", len(response.payment_status_detail))
                assert payment_status_detail_item.method == "paypal_ipn"
                assert payment_status_detail_item.amount == str(
                    item.value["mc_gross"])
                assert payment_status_detail_item.id == None or payment_status_detail_item.id == item.value[
                    "txn_id"]

                assert Response.objects.raw({
                    "payment_trail": {
                        "$elemMatch": {
                            "value.txn_id": item.value["txn_id"]
                        }
                    }
                }).count() > 1
                if response.paid == True and response.paymentInfo.get(
                        "total", 0) > 0:
                    assert len(response.payment_trail) > 1
                indexes_to_delete.append(
                    [idx_payment_trail, idx_payment_status_detail])
                print("new", len(response.payment_status_detail))

            i += 1
        print("indexes to delete", indexes_to_delete)
        for item in indexes_to_delete:
            del response.payment_trail[item[0]]
            if len(item) > 1:
                del response.payment_status_detail[item[1]]
        if not TEST:
            response.save()
Exemple #9
0
def response_send_email(responseId):
    from ..main import app

    response = Response.objects.get({"_id": ObjectId(responseId)})
    app.check_permissions(response.form,
                          ["Responses_Edit", "Responses_SendEmail"])
    email_template_id = _parse_email_parameters(app.current_request.json_body)
    send_email_receipt(response, response.form.formOptions, email_template_id)
    response.save()
    return {"res": {"success": True, "response": serialize_model(response)}}
def form_response_summary(formId):
    """Show response agg. summary"""
    from ..main import app
    form = Form.objects.only("formOptions",
                             "cff_permissions").get({"_id": ObjectId(formId)})
    app.check_permissions(form, "Responses_ViewSummary")
    # todo: use aggregation framework here instead.
    responses = Response.objects.raw({"form": form.id, "paid": True})
    responses = serialize_model(responses)
    result = aggregate_data(form.formOptions.dataOptions, responses)
    return {"res": result}
Exemple #11
0
def form_list():
    """Get forms user has access to."""
    from ..main import app
    userId = app.get_current_user_id()
    forms = Form.objects.raw({
        f"cff_permissions.{userId}": {
            "$exists": True
        }
    }).only("name", "cff_permissions", "date_modified", "date_created")
    forms = serialize_model(list(forms))
    return {"res": forms}
Exemple #12
0
def response_view(responseId):
    """View an individual response."""
    from ..main import app
    try:
        response = Response.objects.get({"_id": ObjectId(responseId)})
        if True:
            # if response.user == app.get_current_user_id() or app.check_permissions(response.select_related("form"), ["Responses_View", "Responses_CheckIn"]):
            return {"success": True, "res": serialize_model(response)}
        else:
            raise UnauthorizedError("Unauthorized to access this response.")
    except DoesNotExist:
        raise NotFoundError(f"Response with ID {responseId} not found")
def form_render(formId):
    """Render single form."""
    form = None
    try:
        form = Form.objects.only("name", "schema", "uiSchema", "formOptions",
                                 "cff_permissions").get(
                                     {"_id": ObjectId(formId)})
        # Convert __$ref back to $ref.
        if form.schema:
            form.schema = renameKey(form.schema, "__$ref", "$ref")
    except DoesNotExist:
        raise NotFoundError(f"Form ID not found: {formId}")
    return {"res": serialize_model(form)}
Exemple #14
0
def form_edit(formId):
    from ..main import app
    form = Form.objects.get({"_id": ObjectId(formId)})
    app.check_permissions(form, 'Forms_Edit')
    body = pick(app.current_request.json_body,
                ["schema", "uiSchema", "formOptions", "name"])
    for k, v in body.items():
        setattr(form, k, v)
    # Validate $ref properly.
    if form.schema:
        form.schema = renameKey(form.schema, "$ref", "__$ref")
    form.save()
    form = Form.objects.get({"_id": ObjectId(formId)})
    return {"res": {"success": True, "updated_values": serialize_model(form)}}
Exemple #15
0
def response_view(responseId):
    """View an individual response."""
    from ..main import app

    try:
        response = Response.objects.get({"_id": ObjectId(responseId)})
        if response.user and response.user.id == app.get_current_user_id():
            pass  # user owns this response
        elif response.form.formOptions.responseCanViewByLink:
            pass  # can view response by link
        else:
            app.check_permissions(response.form, ["Responses_View"])
        return {"success": True, "res": serialize_model(response)}
    except DoesNotExist:
        raise NotFoundError(f"Response with ID {responseId} not found")
Exemple #16
0
def form_list():
    """Get forms user has access to."""
    from ..main import app

    userId = app.get_current_user_id()

    # Get all forms for superusers
    query = (
        {} if app.is_superuser() else {f"cff_permissions.{userId}": {"$exists": True}}
    )

    forms = Form.objects.raw(query).only(
        "name", "cff_permissions", "date_modified", "date_created", "tags"
    )
    forms = serialize_model(list(forms))
    return {"res": forms}
Exemple #17
0
def form_render_response(formId):
    from ..main import app

    form = Form.objects.only("formOptions").get({"_id": ObjectId(formId)})
    if (get(form, "formOptions.loginRequired", False) == True and
            app.get_current_user_id() != "cm:cognitoUserPool:anonymousUser"):
        try:
            response = Response.objects.get({
                "form": ObjectId(formId),
                "user": app.get_current_user_id()
            })
            return {"res": serialize_model(response)}
        except DoesNotExist:
            predicateFormId = get(form, "formOptions.predicate.formId")
            if not predicateFormId:
                return {"res": None, "error": "No predicate formId."}
            try:
                predicateForm = Form.objects.only("formOptions").get(
                    {"_id": ObjectId(predicateFormId)})
                if get(predicateForm,
                       "formOptions.successor.formId") != formId:
                    return {
                        "res": None,
                        "error":
                        "Successor formId doesn't match current formId.",
                    }
                response = Response.objects.get({
                    "form":
                    ObjectId(predicateFormId),
                    "paid":
                    True,
                    "user":
                    app.get_current_user_id(),
                })
                value = patch_predicate(
                    response.value,
                    get(form, "formOptions.predicate.patches", []))
                return {
                    "res": {
                        "value": value,
                        "form": predicateFormId
                    },
                    "predicate": True,
                }
            except DoesNotExist:
                return {"res": None}
    return {"res": None}
Exemple #18
0
def response_add_payment(responseId):
    from ..main import app

    response = Response.objects.get({"_id": ObjectId(responseId)})
    app.check_permissions(response.form,
                          ["Responses_Edit", "Responses_AddPayment"])
    amount = app.current_request.json_body["amount"]
    currency = app.current_request.json_body["currency"]
    date = app.current_request.json_body.get("date", None)
    if date and "$date" in date:
        date = dateutil.parser.parse(date["$date"])
    id = app.current_request.json_body["id"]
    method = app.current_request.json_body["method"]
    send_email = app.current_request.json_body.get("sendEmail", True)
    email_template_id = _parse_email_parameters(app.current_request.json_body)
    notes = app.current_request.json_body.get("notes", None)
    if notes == "":
        notes = None
    value = {"type": "manual", "method": method, "id": id}
    if notes is not None:
        value = dict(value, notes=notes)
    paid = mark_successful_payment(
        response.form,
        response,
        value,
        method,
        amount,
        currency,
        id,
        date=date,
        send_email=send_email,
        notes=notes,
        email_template_id=email_template_id,
    )
    response.save()
    return {
        "res": {
            "success": True,
            "paid": paid,
            "response": serialize_model(response)
        }
    }
Exemple #19
0
def form_edit(formId):
    from ..main import app

    form = Form.objects.get({"_id": ObjectId(formId)})
    app.check_permissions(form, "Forms_Edit")
    body = pick(
        app.current_request.json_body,
        ["schema", "uiSchema", "formOptions", "name", "tags"],
    )
    for k, v in body.items():
        setattr(form, k, v)
    # Rename $ref properly.
    if form.schema:
        form.schema = renameKey(form.schema, "$ref", "__$ref")
    if (form.formOptions and form.formOptions.dataOptions
            and "views" in form.formOptions.dataOptions):
        form.formOptions.dataOptions["views"] = replaceKey(
            replaceKey(form.formOptions.dataOptions["views"], "$", "|"), ".",
            "||")
    form.save()
    form = Form.objects.get({"_id": ObjectId(formId)})
    return {"res": {"success": True, "updated_values": serialize_model(form)}}
Exemple #20
0
                    item.value["mc_gross"])

                if payment_status_detail_item.id == None:
                    payment_status_detail_item.id = item.value["txn_id"]
        if not TEST:
            response.save()

        # update_trail
        # payment_trail
        # email_trail
        # payment_status_detail


with open("input-prod.txt", "w+") as file:
    file.writelines([
        json.dumps(serialize_model(response), indent=4, sort_keys=True) + "\n"
        for response in responses
    ])

fix_data()
fix_txn_ids()

with open("output-prod.txt", "w+") as file:
    file.writelines([
        json.dumps(serialize_model(response), indent=4, sort_keys=True) + "\n"
        for response in responses
    ])

if not TEST:
    responses = Response.objects.raw({})
Exemple #21
0
def form_create():
    """Creates a new form with a blank schema and uiSchema.
    """
    from ..main import app

    request_body = app.current_request.json_body or {}

    # todo: multiple orgs?
    try:
        org = Org.objects.get({})
    except DoesNotExist:
        raise UnauthorizedError(
            "Organization does not exist, so forms cannot be created.")
    app.check_permissions(org, ["Orgs_FormsCreate"])

    if request_body.get("formId", None):
        # todo: add permissions check on forms -- some forms should not be able to be duplicated.
        formId = request_body.get("formId", None)
        old_form = Form.objects.get({"_id": ObjectId(formId)})
        form = Form(
            name=old_form.name + " Copy - " +
            datetime.datetime.now().isoformat(),
            version=1,
            center="None",
            id=ObjectId(),
            cff_permissions={app.get_current_user_id(): {
                                 "owner": True
                             }},
            schema=old_form.schema,
            uiSchema=old_form.uiSchema,
            formOptions=old_form.formOptions,
            date_modified=datetime.datetime.now().isoformat(),
            date_created=datetime.datetime.now().isoformat(),
        )
        form.save()
        return {"res": {"form": serialize_model(form)}}
    else:
        form_name = request_body.get(
            "form_name",
            "Untitled form {}".format(datetime.datetime.now().isoformat()))
        form = Form(
            name=form_name,
            version=1,
            center="None",
            id=ObjectId(),
            cff_permissions={app.get_current_user_id(): {
                                 "owner": True
                             }},
            schema={
                "title": "Form",
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string"
                    }
                },
            },
            uiSchema={"name": {
                "ui:placeholder": "Name"
            }},
            formOptions=FormOptions(
                confirmationEmailInfo={},
                paymentInfo={},
                paymentMethods={},
                dataOptions={},
                defaultFormData={},
            ),
            date_modified=datetime.datetime.now().isoformat(),
            date_created=datetime.datetime.now().isoformat(),
        )
        form.save()
        return {"res": {"form": serialize_model(form)}}
Exemple #22
0
def _search(form, query, autocomplete, search_by_id, show_unpaid):
    search_fields = get(form.formOptions.dataOptions, "search.searchFields", ["_id"])
    if search_by_id is not None:
        search_fields = ["_id"]
    result_limit = get(form.formOptions.dataOptions, "search.resultLimit", 10)
    result_fields = get(form.formOptions.dataOptions, "search.resultFields", ["_id"])
    autocomplete_fields = get(
        form.formOptions.dataOptions, "search.autocompleteFields", ["_id"]
    )
    if show_unpaid is not None:
        default_mongo_query = {"paid": False}
    else:
        default_mongo_query = {"paid": True}
    mongo_query = {"$or": []}
    for word in query.split(" "):
        for field in search_fields:
            if field == "_id":
                if len(word) <= 24:
                    try:
                        queryObjectIdStart = ObjectId(
                            word + "0" * (24 - len(word))
                        )  # fill in zeroes to create object id, e.g. 5cba --> 5cba0000000000000000000
                        queryObjectIdEnd = ObjectId(word + "e" * (24 - len(word)))
                        mongo_query["$or"].append(
                            {
                                field: {
                                    "$gte": queryObjectIdStart,
                                    "$lte": queryObjectIdEnd,
                                }
                            }
                        )
                    except bson.errors.InvalidId:
                        pass
            else:
                if field.startswith("value.participants."):
                    _, subfield = field.split("value.participants.")
                    mongo_query["$or"].append(
                        {
                            "value.participants": {
                                "$elemMatch": {
                                    subfield: {"$regex": "^" + word, "$options": "i"}
                                }
                            }
                        }
                    )
                else:
                    mongo_query["$or"].append(
                        {field: {"$regex": "^" + word, "$options": "i"}}
                    )
    mongo_query["form"] = form.id
    if len(mongo_query["$or"]) == 0:
        del mongo_query["$or"]
    # Default query paid = True
    if mongo_query:
        mongo_query = {"$and": [default_mongo_query, mongo_query]}
    else:
        mongo_query = default_mongo_query
    if autocomplete is not None:
        projection = {field: 1 for field in autocomplete_fields}
        result_limit = 5
    else:
        projection = {}
        for field in result_fields:
            projection[field] = 1
    responses = (
        Response.objects.raw(mongo_query).limit(result_limit).project(projection)
    )
    return {"res": [serialize_model(r) for r in responses]}
def form_response_list(formId):
    """Show all responses for a particular form.
    Example
    /responses?query=test
    /responses?query=test&autocomplete=1
    /responses?query=5cdf&autocomplete=1&search_by_id=1
    """
    from ..main import app
    form = Form.objects.only("formOptions",
                             "cff_permissions").get({"_id": ObjectId(formId)})
    # todo: use search framework, don't return all!
    query = app.current_request.query_params and app.current_request.query_params.get(
        "query", None)
    autocomplete = app.current_request.query_params and app.current_request.query_params.get(
        "autocomplete", None)
    search_by_id = app.current_request.query_params and app.current_request.query_params.get(
        "search_by_id", None)
    show_unpaid = app.current_request.query_params and app.current_request.query_params.get(
        "show_unpaid", None)
    if query:
        # autocomplete, participant name, assign bibs functionality
        app.check_permissions(form, ["Responses_View", "Responses_CheckIn"])
        search_fields = get(form.formOptions.dataOptions,
                            "search.searchFields", ["_id"])
        if search_by_id is not None:
            search_fields = ["_id"]
        result_limit = get(form.formOptions.dataOptions, "search.resultLimit",
                           10)
        result_fields = get(form.formOptions.dataOptions,
                            "search.resultFields", ["_id"])
        autocomplete_fields = get(form.formOptions.dataOptions,
                                  "search.autocompleteFields", ["_id"])
        if show_unpaid is not None:
            default_mongo_query = {"paid": False}
        else:
            default_mongo_query = {"paid": True}
        mongo_query = {"$or": []}
        for word in query.split(" "):
            for field in search_fields:
                if field == "_id":
                    if len(word) <= 24:
                        try:
                            queryObjectIdStart = ObjectId(
                                word + "0" * (24 - len(word))
                            )  # fill in zeroes to create object id, e.g. 5cba --> 5cba0000000000000000000
                            queryObjectIdEnd = ObjectId(word + "e" *
                                                        (24 - len(word)))
                            mongo_query["$or"].append({
                                field: {
                                    "$gte": queryObjectIdStart,
                                    "$lte": queryObjectIdEnd
                                }
                            })
                        except bson.errors.InvalidId:
                            pass
                else:
                    if field.startswith("value.participants."):
                        _, subfield = field.split("value.participants.")
                        mongo_query["$or"].append({
                            "value.participants": {
                                "$elemMatch": {
                                    subfield: {
                                        "$regex": '^' + word,
                                        "$options": "i"
                                    }
                                }
                            }
                        })
                    else:
                        mongo_query["$or"].append(
                            {field: {
                                "$regex": '^' + word,
                                "$options": "i"
                            }})
        mongo_query["form"] = form.id
        if len(mongo_query["$or"]) == 0:
            del mongo_query["$or"]
        # Default query paid = True
        if mongo_query:
            mongo_query = {"$and": [default_mongo_query, mongo_query]}
        else:
            mongo_query = default_mongo_query
        if autocomplete is not None:
            projection = {field: 1 for field in autocomplete_fields}
            result_limit = 5
        else:
            projection = {}
            for field in result_fields:
                projection[field] = 1
        responses = Response.objects.raw(mongo_query).limit(
            result_limit).project(projection)
    else:
        app.check_permissions(form, ["Responses_View"])
        responses = Response.objects.all()._collection.find(
            {"form": form.id}, {
                "value": 1,
                "_id": 1,
                "amount_paid": 1,
                "user": 1,
                "form": 1,
                "paymentInfo": 1,
                "date_created": 1,
                "date_modified": 1,
                "paid": 1,
                "counter": 1
            })
        return {"res": [r for r in json.loads(dumps(responses))]}
    return {"res": [serialize_model(r) for r in responses]}