Пример #1
0
def list_forms():
    # grab all the forms this user controls
    if current_user.has_feature("dashboard"):
        forms = current_user.forms.order_by(Form.id.desc()).all()
    else:
        forms = []

    return jsonify({"ok": True, "forms": [f.serialize() for f in forms]})
Пример #2
0
    def decorated_view(*args, **kwargs):
        if "form" in kwargs:
            if not kwargs["form"].has_feature(feature):
                return (
                    jsonify({"error": "Feature unavailable for this form's plan."}),
                    402,
                )
        else:
            if not current_user.has_feature(feature):
                return (
                    jsonify({"error": "Feature unavailable for current logged user."}),
                    402,
                )

        return func(*args, **kwargs)
Пример #3
0
def list():
    # grab all the forms this user controls
    if current_user.has_feature('dashboard'):
        forms = current_user.forms.order_by(Form.id.desc()).all()
    else:
        forms = []

    return jsonify({
        'ok': True,
        'user': {
            'features': {f: True for f in current_user.features},
            'email': current_user.email
        },
        'forms': [f.serialize() for f in forms]
    })
Пример #4
0
def list():
    # grab all the forms this user controls
    if current_user.has_feature('dashboard'):
        forms = current_user.forms.order_by(Form.id.desc()).all()
    else:
        forms = []

    return jsonify({
        'ok': True,
        'user': {
            'features': {f: True
                         for f in current_user.features},
            'email': current_user.email
        },
        'forms': [f.serialize() for f in forms]
    })
Пример #5
0
def export_submissions(hashid, format=None):
    if not current_user.has_feature("dashboard"):
        return jsonify({"error": "Please upgrade your account."}), 402

    form = Form.get_with(hashid=hashid)
    if not form.controlled_by(current_user):
        return abort(401)

    submissions, fields = form.submissions_with_fields(with_ids=False)

    if format == "json":
        return Response(
            json.dumps(
                {
                    "host": form.host,
                    "email": form.email,
                    "fields": fields,
                    "submissions": submissions,
                },
                sort_keys=True,
                indent=2,
            ),
            mimetype="application/json",
            headers={
                "Content-Disposition":
                "attachment; filename=form-%s-submissions-%s.json" %
                (hashid, datetime.datetime.now().isoformat().split(".")[0])
            },
        )
    elif format == "csv":
        out = io.BytesIO()

        w = csv.DictWriter(out, fieldnames=fields, encoding="utf-8")
        w.writeheader()
        for sub in submissions:
            w.writerow(sub)

        return Response(
            out.getvalue(),
            mimetype="text/csv",
            headers={
                "Content-Disposition":
                "attachment; filename=form-%s-submissions-%s.csv" %
                (hashid, datetime.datetime.now().isoformat().split(".")[0])
            },
        )
Пример #6
0
def get(hashid):
    if not current_user.has_feature('dashboard'):
        return jsonerror(402, {'error': "Please upgrade your account."})

    form = Form.get_with_hashid(hashid)
    if not form:
        return jsonerror(404, {'error': "Form not found."})

    if not form.controlled_by(current_user):
        return jsonerror(401, {'error': "You do not control this form."})

    submissions, fields = form.submissions_with_fields()

    ret = form.serialize()
    ret['submissions'] = submissions
    ret['fields'] = fields

    return jsonify(ret)
Пример #7
0
def get(hashid):
    if not current_user.has_feature('dashboard'):
        return jsonerror(402, {'error': "Please upgrade your account."})

    form = Form.get_with_hashid(hashid)
    if not form:
        return jsonerror(404, {'error': "Form not found."})

    if not form.controlled_by(current_user):
        return jsonerror(401, {'error': "You do not control this form."})

    submissions, fields = form.submissions_with_fields()

    ret = form.serialize()
    ret['submissions'] = submissions
    ret['fields'] = fields

    return jsonify(ret)
Пример #8
0
def export_submissions(hashid, format=None):
    if not current_user.has_feature("dashboard"):
        return jsonify({"error": "Please upgrade your account."}), 402

    form = Form.get_with(hashid=hashid)
    if not form.controlled_by(current_user):
        return abort(401)

    submissions, fields = form.submissions_with_fields(with_ids=False)

    if format == "json":
        return Response(
            json.dumps(
                {
                    "host": form.host,
                    "email": form.email,
                    "fields": fields,
                    "submissions": submissions,
                },
                sort_keys=True,
                indent=2,
            ),
            mimetype="application/json",
            headers={
                "Content-Disposition": "attachment; filename=form-%s-submissions-%s.json"
                % (hashid, datetime.datetime.now().isoformat().split(".")[0])
            },
        )
    elif format == "csv":
        out = io.BytesIO()

        w = csv.DictWriter(out, fieldnames=fields, encoding="utf-8")
        w.writeheader()
        for sub in submissions:
            w.writerow(sub)

        return Response(
            out.getvalue(),
            mimetype="text/csv",
            headers={
                "Content-Disposition": "attachment; filename=form-%s-submissions-%s.csv"
                % (hashid, datetime.datetime.now().isoformat().split(".")[0])
            },
        )
Пример #9
0
    def decorated_view(*args, **kwargs):
        if "form" in kwargs:
            if not kwargs["form"].has_feature(feature):
                return (
                    jsonify(
                        {"error":
                         "Feature unavailable for this form's plan."}),
                    402,
                )
        else:
            if not current_user.has_feature(feature):
                return (
                    jsonify({
                        "error":
                        "Feature unavailable for current logged user."
                    }),
                    402,
                )

        return func(*args, **kwargs)
Пример #10
0
def export_submissions(hashid, format=None):
    if not current_user.has_feature('dashboard'):
        return jsonerror(402, {'error': "Please upgrade your account."})

    form = Form.get_with_hashid(hashid)
    if not form.controlled_by(current_user):
        return abort(401)

    submissions, fields = form.submissions_with_fields()

    if format == 'json':
        return Response(
            json.dumps({
                'host': form.host,
                'email': form.email,
                'fields': fields,
                'submissions': submissions
            }, sort_keys=True, indent=2),
            mimetype='application/json',
            headers={
                'Content-Disposition': 'attachment; filename=form-%s-submissions-%s.json' \
                            % (hashid, datetime.datetime.now().isoformat().split('.')[0])
            }
        )
    elif format == 'csv':
        out = io.BytesIO()

        w = csv.DictWriter(out, fieldnames=['id'] + fields, encoding='utf-8')
        w.writeheader()
        for sub in submissions:
            w.writerow(sub)

        return Response(
            out.getvalue(),
            mimetype='text/csv',
            headers={
                'Content-Disposition': 'attachment; filename=form-%s-submissions-%s.csv' \
                            % (hashid, datetime.datetime.now().isoformat().split('.')[0])
            }
        )
Пример #11
0
def export_submissions(hashid, format=None):
    if not current_user.has_feature('dashboard'):
        return jsonerror(402, {'error': "Please upgrade your account."})

    form = Form.get_with_hashid(hashid)
    if not form.controlled_by(current_user):
        return abort(401)

    submissions, fields = form.submissions_with_fields()

    if format == 'json':
        return Response(
            json.dumps({
                'host': form.host,
                'email': form.email,
                'fields': fields,
                'submissions': submissions
            }, sort_keys=True, indent=2),
            mimetype='application/json',
            headers={
                'Content-Disposition': 'attachment; filename=form-%s-submissions-%s.json' \
                            % (hashid, datetime.datetime.now().isoformat().split('.')[0])
            }
        )
    elif format == 'csv':
        out = io.BytesIO()
        
        w = csv.DictWriter(out, fieldnames=['id'] + fields, encoding='utf-8')
        w.writeheader()
        for sub in submissions:
            w.writerow(sub)

        return Response(
            out.getvalue(),
            mimetype='text/csv',
            headers={
                'Content-Disposition': 'attachment; filename=form-%s-submissions-%s.csv' \
                            % (hashid, datetime.datetime.now().isoformat().split('.')[0])
            }
        )
Пример #12
0
def add_email():
    address = request.get_json()["address"].lower().strip()
    g.log = g.log.bind(address=address, account=current_user.email)

    emails = [email.address for email in current_user.emails]
    if address in emails:
        return (
            jsonify({
                "ok": True,
                "message": "{} already added to account.".format(address),
                "noop": True,
            }),
            200,
        )

    if (not current_user.has_feature("unlimited_addresses")
            and current_user.emails.count() >=
            settings.LINKED_EMAIL_ADDRESSES_LIMIT):
        g.log.info("reached limit of linked addresses.")
        return (
            jsonify({
                "ok":
                False,
                "error":
                ("You've reached the limit of email addresses for this "
                 "account, please upgrade your account or delete one of "
                 "your addresses before adding a new one."),
                "noop":
                True,
            }),
            403,
        )

    try:
        g.log.info("Adding new email address to account.")
        sent = Email.send_confirmation(address, current_user.id)
        if sent:
            newEmail = Email(address=address,
                             owner_id=current_user.id,
                             verified=False)
            DB.session.add(newEmail)
            DB.session.commit()
            return (
                jsonify({
                    "ok":
                    True,
                    "message": ("We've sent a message with a "
                                "verification link to {}.").format(address),
                    "noop":
                    False,
                }),
                202,
            )
        else:
            return (
                jsonify({
                    "ok":
                    False,
                    "error":
                    "We couldn't sent you the verification email at {}. "
                    "Please try again later.".format(address),
                }),
                500,
            )

    except ValueError:
        return (
            jsonify({
                "ok":
                False,
                "error":
                "{} is not a valid email address.".format(address),
            }),
            400,
        )
Пример #13
0
def add_email():
    address = request.get_json()["address"].lower().strip()
    g.log = g.log.bind(address=address, account=current_user.email)

    emails = [email.address for email in current_user.emails]
    if address in emails:
        return (
            jsonify(
                {
                    "ok": True,
                    "message": "{} already added to account.".format(address),
                    "noop": True,
                }
            ),
            200,
        )

    if (
        not current_user.has_feature("unlimited_addresses")
        and current_user.emails.count() >= settings.LINKED_EMAIL_ADDRESSES_LIMIT
    ):
        g.log.info("reached limit of linked addresses.")
        return (
            jsonify(
                {
                    "ok": False,
                    "error": (
                        "You've reached the limit of email addresses for this "
                        "account, please upgrade your account or delete one of "
                        "your addresses before adding a new one."
                    ),
                    "noop": True,
                }
            ),
            403,
        )

    try:
        g.log.info("Adding new email address to account.")
        sent = Email.send_confirmation(address, current_user.id)
        if sent:
            newEmail = Email(address=address, owner_id=current_user.id, verified=False)
            DB.session.add(newEmail)
            DB.session.commit()
            return (
                jsonify(
                    {
                        "ok": True,
                        "message": (
                            "We've sent a message with a " "verification link to {}."
                        ).format(address),
                        "noop": False,
                    }
                ),
                202,
            )
        else:
            return (
                jsonify(
                    {
                        "ok": False,
                        "error": "We couldn't sent you the verification email at {}. "
                        "Please try again later.".format(address),
                    }
                ),
                500,
            )

    except ValueError:
        return (
            jsonify(
                {
                    "ok": False,
                    "error": "{} is not a valid email address.".format(address),
                }
            ),
            400,
        )
Пример #14
0
def create():
    # check that this request came from user dashboard to prevent XSS and CSRF
    referrer = referrer_to_baseurl(request.referrer)
    service = referrer_to_baseurl(settings.SERVICE_URL)
    if referrer != service:
        return jsonerror(400, {'error': 'Improper request.'})

    if not current_user.has_feature('dashboard'):
        g.log.info('Failed to create form from dashboard. Forbidden.')
        return jsonerror(402, {'error': "Please upgrade your account."})

    email = request.get_json().get('email')
    url = request.get_json().get('url')
    sitewide = request.get_json().get('sitewide')

    g.log = g.log.bind(email=email, url=url, sitewide=sitewide)

    if not IS_VALID_EMAIL(email):
        g.log.info('Failed to create form from dashboard. Invalid address.')
        return jsonerror(400,
                         {'error': "The provided email address is not valid."})

    g.log.info('Creating a new form from the dashboard.')

    email = email.lower().strip()  # case-insensitive
    form = Form(email, owner=current_user)
    if url:
        url = 'http://' + url if not url.startswith('http') else url
        form.host = referrer_to_path(url)

        # sitewide forms, verified with a file at the root of the target domain
        if sitewide:
            if sitewide_file_check(url, email):
                form.host = remove_www(
                    referrer_to_path(urljoin(url, '/'))[:-1])
                form.sitewide = True
            else:
                return jsonerror(
                    403,
                    {'error': u"Couldn't verify the file at {}.".format(url)})

    DB.session.add(form)
    DB.session.commit()

    if form.host:
        # when the email and url are provided, we can automatically confirm the form
        # but only if the email is registered for this account
        for email in current_user.emails:
            if email.address == form.email:
                g.log.info('No need for email confirmation.')
                form.confirmed = True
                DB.session.add(form)
                DB.session.commit()
                break
        else:
            # in case the email isn't registered for this user
            # we automatically send the email confirmation
            form.send_confirmation()

    return jsonify({
        'ok': True,
        'hashid': form.hashid,
        'submission_url': settings.API_ROOT + '/' + form.hashid,
        'confirmed': form.confirmed
    })
Пример #15
0
def create():
    # check that this request came from user dashboard to prevent XSS and CSRF
    referrer = referrer_to_baseurl(request.referrer)
    service = referrer_to_baseurl(settings.SERVICE_URL)
    if referrer != service:
        return jsonerror(400, {'error': 'Improper request.'})

    if not current_user.has_feature('dashboard'):
        g.log.info('Failed to create form from dashboard. Forbidden.')
        return jsonerror(402, {'error': "Please upgrade your account."})

    email = request.get_json().get('email')
    url = request.get_json().get('url')
    sitewide = request.get_json().get('sitewide')

    g.log = g.log.bind(email=email, url=url, sitewide=sitewide)

    if not IS_VALID_EMAIL(email):
        g.log.info('Failed to create form from dashboard. Invalid address.')
        return jsonerror(400, {'error': "The provided email address is not valid."})

    g.log.info('Creating a new form from the dashboard.')

    email = email.lower().strip() # case-insensitive
    form = Form(email, owner=current_user)
    if url:
        url = 'http://' + url if not url.startswith('http') else url
        form.host = referrer_to_path(url)

        # sitewide forms, verified with a file at the root of the target domain
        if sitewide:
            if sitewide_file_check(url, email):
                form.host = remove_www(referrer_to_path(urljoin(url, '/'))[:-1])
                form.sitewide = True
            else:
                return jsonerror(403, {
                    'error': u"Couldn't verify the file at {}.".format(url)
                })

    DB.session.add(form)
    DB.session.commit()

    if form.host:
        # when the email and url are provided, we can automatically confirm the form
        # but only if the email is registered for this account
        for email in current_user.emails:
            if email.address == form.email:
                g.log.info('No need for email confirmation.')
                form.confirmed = True
                DB.session.add(form)
                DB.session.commit()
                break
        else:
            # in case the email isn't registered for this user
            # we automatically send the email confirmation
            form.send_confirmation()

    return jsonify({
        'ok': True,
        'hashid': form.hashid,
        'submission_url': settings.API_ROOT + '/' + form.hashid,
        'confirmed': form.confirmed
    })