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]})
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)
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] })
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]) }, )
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)
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)
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]) } )
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, )
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, )
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 })
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 })