diff --git a/list.tpl b/list.tpl
deleted file mode 100644
index 4c03bc4..0000000
--- a/list.tpl
+++ /dev/null
@@ -1,6 +0,0 @@
-
Liste
-
-% for item in data:
- - {{item}}
-% end
-
diff --git a/main.py b/main.py
index 4dede47..e5626cf 100755
--- a/main.py
+++ b/main.py
@@ -11,7 +11,6 @@ import pymongo # database
from dotenv import load_dotenv
import random, string # for tokens
import html # for sanitization
-import datetime # to name unsent mails
from bson.json_util import dumps
@@ -114,7 +113,7 @@ def submission ():
token = request.forms.getunicode('token')
else:
response.status = 400
- return 'Le jeton d’autentification est requis'
+ return resp('error', 'Le jeton d’autentification est requis')
# Getting mail address
if 'mail' in request.forms:
@@ -128,19 +127,22 @@ def submission ():
form = mongodb_database['forms'].find({'token': token})[0]
except IndexError as e:
response.status = 400
- return 'Le formulaire demandé est introuvable, merci de vérifier que le token utilisé est le bon'
+ return resp('error', 'Le formulaire demandé est introuvable, merci de vérifier que le token utilisé est le bon')
except pymongo.errors.ServerSelectionTimeoutError as e:
response.status = 500
- return 'La base de donnée n’est pas accessible.'
+ return resp('error', 'La base de donnée n’est pas accessible.')
try:
subject_fields = fill_fields(request, get_fields(form['subject']))
content_fields = fill_fields(request, get_fields(form['content']))
- print(subject_fields)
- print(content_fields)
+ # Did the bot filled the honeypot field?
+ if 'honeypotfield' in form and form['honeypotfield'] in request.forms and request.forms.get(form['honeypotfield']) != '':
+ response.status = 400
+ return resp('error', 'We identified you as a bot. If this is an error, try to contact us via another way.')
+
except MissingParameterException as e:
response.status = 404
- return str(e)
+ return resp('error', str(e))
subject = re.sub(form_regex, r'{\1}', form['subject']).format(**subject_fields)
content = re.sub(form_regex, r'{\1}', form['content']).format(**content_fields)
@@ -148,33 +150,26 @@ def submission ():
try:
if not send_mail(from_address, form['mail'], subject, content):
response.status = 500
- return 'Le mail n’a pas pu être envoyé.'
+ return resp('error', 'Le mail n’a pas pu être envoyé.')
except smtplib.SMTPDataError as e:
- save_mail (token, form['mail'], from_address, subject, content)
response.status = 500
- error = 'Le mail a été refusé. Votre message a été enregistré, il sera remis manuellement à son destinataire.'
+ error = 'Le mail a été refusé. Merci de réessayer plus tard.'
except smtplib.SMTPRecipientsRefused as e:
- save_mail (token, form['mail'], from_address, subject, content)
response.status = 500
- error = 'Impossible de trouver le destinataire du mail. Votre message a été enregistré, il sera remis manuellement à son destinataire.'
+ error = 'Impossible de trouver le destinataire du mail. Merci de réessayer plus tard'
except Exception as e:
- save_mail (token, form['mail'], from_address, subject, content)
raise
# Redirection
#bottle.redirect(success_redirect_default)
origin = request.headers.get('origin')
- return 'Mail envoyé !
' + ('Retour au formulaire de contact
'.format(origin) if origin else '')
+ return resp('success', 'Mail envoyé !')
##################################################### Helpers ############################################
-def save_mail (token, to, from_address, subject, content):
- with open('unsent/unsent_{}_{}_{}.txt'.format(str(datetime.datetime.now()), token, to), 'w') as f:
- f.write("Unsent mail\nSubject: {}\nFrom: {}Content:\n{}".format(
- subject,
- from_address,
- content
- ))
+
+def resp (status, msg, data='{}'):
+ return '{{"status": "{}", "msg": "{}", "data": {}}}'.format(status, msg, data)
def get_fields (string):
""" Parse the string looking for template elements and create an array with template to fill and their default values. None if mandatory. """
@@ -255,26 +250,31 @@ def create_form ():
subject = mail_default_subject
else:
response.status = 400
- return 'Le champs « sujet » est requis'
+ return resp('error', 'Le champs « sujet » est requis')
# Getting mail content
if 'content' in request.forms:
content = request.forms.getunicode('content')
else:
response.status = 400
- return 'Le champs « contenu » est requis'
+ return resp('error', 'Le champs « contenu » est requis')
+
+ if 'honeypotfield' in request.forms:
+ honeypotfield = request.forms.getunicode('honeypotfield')
+ else:
+ honeypotfield = None
# Getting from address
if 'mail' in request.forms:
mail = request.forms.getunicode('mail')
else:
response.status = 400
- return 'Le champs « adresse » est requis'
+ return resp('error', 'Le champs « adresse » est requis')
user = login(request)
if user['_privilege'] > 1:
response.status = 400
- return 'Privilèges insufisants'
+ return resp('error', 'Privilèges insufisants')
# TODO limit the insertion rate
token = ''.join(random.sample(token_chars, token_len))
@@ -285,12 +285,13 @@ def create_form ():
'subject': subject,
'user_id': user['_id'],
'token': token,
+ 'honeypotfield': honeypotfield,
})
except pymongo.errors.ServerSelectionTimeoutError as e:
response.status = 500
- return 'La base de donnée n’est pas accessible'
+ return resp('error', 'La base de donnée n’est pas accessible')
- return 'Créé : ' + token
+ return resp('success', 'Créé : ' + token)
@app.post('/form/list')
def list_forms ():
@@ -302,12 +303,12 @@ def list_forms ():
filt = {'user_id': user['_id']}
else:
response.status = 400
- return 'Privilèges insufisants'
+ return resp('error', 'Privilèges insufisants')
data = mongodb_database['forms'].find(filt)
- return dumps(list(data))
+ return resp('success','', dumps(list(data)))
except pymongo.errors.ServerSelectionTimeoutError as e:
response.status = 500
- return 'La base de donnée n’est pas accessible'
+ return resp('error','La base de donnée n’est pas accessible')
@@ -317,17 +318,17 @@ def delete_form(token):
user = login(request)
if user['_privilege'] > 1:
response.status = 400
- return 'Privilèges insufisants'
+ return resp('error', 'Privilèges insufisants')
# Actually delete
try:
form = mongodb_database['forms'].find({'token':token })[0]
except IndexError as e:
response.status = 400
- return 'Le token n’est pas valide'
+ return resp('error', 'Le token n’est pas valide')
except pymongo.errors.ServerSelectionTimeoutError as e:
response.status = 500
- return 'La base de donnée n’est pas accessible'
+ return resp('error', 'La base de donnée n’est pas accessible')
if user['_privilege'] == 0 or (form['user_id'] == user['_id']):
try:
@@ -336,10 +337,10 @@ def delete_form(token):
})
except pymongo.errors.ServerSelectionTimeoutError as e:
response.status = 500
- return 'La base de donnée n’est pas accessible'
- return 'Supprimé ' + token
+ return resp('error', 'La base de donnée n’est pas accessible')
+ return resp('success', 'Supprimé ' + token)
response.status = 400
- return 'Privilèges insufisants'
+ return resp('error', 'Privilèges insufisants')
##################################################### Users ############################################
@@ -349,13 +350,13 @@ def list_users ():
user = login(request)
if user['_privilege'] > 0:
response.status = 400
- return 'Privilèges insufisants'
+ return resp('error', 'Privilèges insufisants')
try:
data = mongodb_database['users'].find()
- return dumps(list(data))
+ return resp('success', '', dumps(list(data)))
except pymongo.errors.ServerSelectionTimeoutError as e:
response.status = 500
- return 'La base de donnée n’est pas accessible'
+ return resp('error', 'La base de donnée n’est pas accessible')
@app.route('/user/', method=['OPTIONS', 'PUT'])
@@ -363,23 +364,23 @@ def create_user (username):
user = login(request)
if user['_privilege'] > 0:
response.status = 400
- return 'Privilèges insufisants'
+ return resp('error', 'Privilèges insufisants')
try:
mongodb_database['users'].find({'username': username})[0]
- return 'L’utilisateur existe déjà'
+ return resp('error', 'L’utilisateur existe déjà')
except IndexError as e:
try:
inserted = mongodb_database['users'].insert_one({
'username': username,
'token': ''.join(random.sample(token_chars, token_len))
})
- return 'Créé : ' + username
+ return resp('success', 'Créé : ' + username)
except pymongo.errors.ServerSelectionTimeoutError as e:
response.status = 500
- return 'La base de donnée n’est pas accessible'
+ return resp('error', 'La base de donnée n’est pas accessible')
except pymongo.errors.ServerSelectionTimeoutError as e:
response.status = 500
- return 'La base de donnée n’est pas accessible'
+ return resp('error','La base de donnée n’est pas accessible')
@app.delete('/user/')
@@ -387,19 +388,19 @@ def delete_user (username):
user = login(request)
if user['_privilege'] > 0:
response.status = 400
- return 'Privilèges insufisants'
+ return resp('error', 'Privilèges insufisants')
try:
mongodb_database['users'].find({'username': username})[0]
mongodb_database['users'].delete_one({
'username': username,
})
- return 'Supprimé ' + username
+ return resp('success', 'Supprimé ' + username)
except IndexError as e:
response.status = 400
- return 'L’utilisateur n’existe pas'
+ return resp('error', 'L’utilisateur n’existe pas')
except pymongo.errors.ServerSelectionTimeoutError as e:
response.status = 500
- return 'La base de donnée n’est pas accessible'
+ return resp('error', 'La base de donnée n’est pas accessible')
diff --git a/test.html b/test.html
index 445e98a..52c83be 100644
--- a/test.html
+++ b/test.html
@@ -7,11 +7,15 @@