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

- 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 @@
- +
+
+ + +