205 lines
6.4 KiB
Python
205 lines
6.4 KiB
Python
from urllib.parse import urljoin
|
|
|
|
from flask import request, jsonify, g
|
|
from flask_login import current_user, login_required
|
|
|
|
from formspree import settings
|
|
from formspree.stuff import DB
|
|
from formspree.utils import jsonerror, IS_VALID_EMAIL
|
|
from .helpers import referrer_to_path, sitewide_file_check, remove_www, \
|
|
referrer_to_baseurl
|
|
from .models import Form, Submission
|
|
|
|
|
|
@login_required
|
|
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]
|
|
})
|
|
|
|
|
|
@login_required
|
|
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
|
|
})
|
|
|
|
|
|
@login_required
|
|
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."})
|
|
|
|
for cont in form.controllers:
|
|
if cont.id == current_user.id: break
|
|
else:
|
|
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)
|
|
|
|
|
|
@login_required
|
|
def update(hashid):
|
|
# 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.'})
|
|
|
|
form = Form.get_with_hashid(hashid)
|
|
if not form:
|
|
return jsonerror(400, {'error': 'Not a valid form.'})
|
|
|
|
if form.owner_id != current_user.id and form not in current_user.forms:
|
|
return jsonerror(401, {'error': 'Wrong user.'})
|
|
|
|
patch = request.get_json()
|
|
|
|
for attr in ['disable_storage', 'disabled', 'disable_email', 'captcha_disabled']:
|
|
if attr in patch:
|
|
setattr(form, attr, patch[attr])
|
|
|
|
DB.session.add(form)
|
|
DB.session.commit()
|
|
return jsonify({'ok': True})
|
|
|
|
|
|
@login_required
|
|
def delete(hashid):
|
|
# 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.'})
|
|
|
|
form = Form.get_with_hashid(hashid)
|
|
if not form:
|
|
return jsonerror(400, {'error': 'Not a valid form.'})
|
|
|
|
if form.owner_id != current_user.id and form not in current_user.forms:
|
|
return jsonerror(401, {'error': 'Wrong user.'})
|
|
|
|
for submission in form.submissions:
|
|
DB.session.delete(submission)
|
|
DB.session.delete(form)
|
|
DB.session.commit()
|
|
|
|
return jsonify({'ok': True})
|
|
|
|
|
|
@login_required
|
|
def submission_delete(hashid, submissionid):
|
|
# 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.'})
|
|
|
|
form = Form.get_with_hashid(hashid)
|
|
if not form:
|
|
return jsonerror(400, {'error': 'Not a valid form.'})
|
|
|
|
if form.owner_id != current_user.id and form not in current_user.forms:
|
|
return jsonerror(401, {'error': 'Wrong user.'})
|
|
|
|
submission = Submission.query.get(submissionid)
|
|
if not submission:
|
|
return jsonerror(401, 'Not a valid submission.')
|
|
|
|
DB.session.delete(submission)
|
|
form.counter -= 1
|
|
DB.session.add(form)
|
|
DB.session.commit()
|
|
return jsonify({'ok': True})
|
|
|
|
|
|
@login_required
|
|
def sitewide_check():
|
|
email = request.get_json().get('email')
|
|
url = request.get_json().get('url')
|
|
|
|
if sitewide_file_check(url, email):
|
|
return jsonify({'ok': True})
|
|
else:
|
|
return jsonify({'ok': False})
|