Compare commits
	
		
			3 Commits
		
	
	
		
			967b4bf4f5
			...
			e2465e2874
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| e2465e2874 | |||
| 8f88cd6d2c | |||
| e66ac2e8bd | 
| @ -74,6 +74,14 @@ function jeanCloudContactFormIntercept (formId, notifier) { | ||||
|         loadingText.classList.add("contact-mailer-sending"); | ||||
|         loadingText.textContent = 'Envoi en cours…' | ||||
|         submitButton.after(loadingText) | ||||
| 
 | ||||
|         /* Add the filling timer in seconds */ | ||||
|         const timerField = document.createElement('input') | ||||
|         timerField.value = Math.round((Date.now() - contactMailerPageLoadedTime) / 1000) | ||||
|         timerField.name = 'timerfield' | ||||
|         timerField.hidden = 'hidden' | ||||
|         formElem.appendChild(timerField) | ||||
| 
 | ||||
|         /* XHR */ | ||||
|         fetch(formElem.action, { | ||||
|             method: formElem.method, | ||||
| @ -98,6 +106,9 @@ function jeanCloudContactFormIntercept (formId, notifier) { | ||||
|             loadingText.parentNode.removeChild(loadingText) | ||||
|             notifier.error('Impossible d’envoyer le formulaire. Vérifiez votre connexion internet ou réessayez plus tard.') | ||||
|         }) | ||||
| 
 | ||||
|         /* Remove timer field after xhr. So we can try again. */ | ||||
|         formElem.removeChild(timerField) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -115,3 +126,5 @@ function jeanCloudContactFormIntercept (formId, notifier) { | ||||
|     // cat style.css | openssl dgst -sha384 -binary | openssl base64 -A
 | ||||
|     document.head.appendChild(link); | ||||
| })() | ||||
| 
 | ||||
| var contactMailerPageLoadedTime = Date.now() | ||||
|  | ||||
							
								
								
									
										43
									
								
								main.py
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								main.py
									
									
									
									
									
								
							| @ -46,7 +46,6 @@ class EnableCors(object): | ||||
|         return _enable_cors | ||||
| 
 | ||||
| app = application = bottle.Bottle(catchall=False) | ||||
| #app.install(EnableCors()) | ||||
| 
 | ||||
| ##################################################### Configuration ############################################ | ||||
| 
 | ||||
| @ -86,7 +85,7 @@ smtp_server_password = get_env('SMTP_SERVER_PASSWORD') | ||||
| smtp_server_sender   = get_env('SMTP_SERVER_SENDER') | ||||
| 
 | ||||
| # Get mongodb connection | ||||
| mongodb_host = get_env('MONGODB_HOST') | ||||
| mongodb_host   = get_env('MONGODB_HOST') | ||||
| mongodb_port   = get_env('MONGODB_PORT', '27017') | ||||
| mongodb_dbname = get_env('MONGODB_DBNAME', 'contact_mailer') | ||||
| 
 | ||||
| @ -134,16 +133,24 @@ def submission (): | ||||
|         response.status = 500 | ||||
|         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'])) | ||||
|         # Did the bot filled the honeypot field? | ||||
|         if 'honeypotfield' in form and form['honeypotfield'] in request.forms and request.forms.get(form['honeypotfield']) != '': | ||||
|     # 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 | ||||
|         print('honeypotfield') | ||||
|         return resp('error', 'We identified you as a bot. If this is an error, try to contact us via another way.') | ||||
|     # Is the js timer enabled? | ||||
|     if 'timerdelay' in form: | ||||
|         # Did it work? | ||||
|         if 'timerfield' not in request.forms or int(request.forms.get('timerfield')) < int(form['timerdelay']): | ||||
|             print('timer : {}/{}'.format(request.forms.get('timerfield'), form['timerdelay'])) | ||||
|             response.status = 400 | ||||
|             return resp('error', 'We identified you as a bot. If this is an error, try to contact us via another way.') | ||||
| 
 | ||||
|     try: | ||||
|         subject_fields = fill_fields(request, get_fields(form['subject'])) | ||||
|         content_fields = fill_fields(request, get_fields(form['content'])) | ||||
|     except MissingParameterException as e: | ||||
|         response.status = 404 | ||||
|         response.status = 400 | ||||
|         return resp('error', str(e)) | ||||
| 
 | ||||
|     subject = re.sub(form_regex, r'{\1}', form['subject']).format(**subject_fields) | ||||
| @ -184,9 +191,13 @@ def fill_fields(request, fields): | ||||
|     """Look for fields in request and fill fields dict with values or let default ones. If the value is required, throw exception.""" | ||||
|     for field in fields: | ||||
|         if field in request.forms: | ||||
|             if request.forms.get(field).strip() == '' and fields[field] is None: # If empty and mandatory | ||||
|                 raise MissingParameterException("Le champs {} doit être rempli".format(field)) | ||||
|             fields[field] = request.forms.getunicode(field) | ||||
|             if fields[field] is None: # if unicode failed | ||||
|                 fields[field] = request.forms.get(field) | ||||
|             if fields[field] is None: # if get failed too | ||||
|                 raise Exception("Error, field '{}' not gettable".format(field)) | ||||
|         elif fields[field] is None: | ||||
|             raise MissingParameterException("Le champs {} est obligatoire".format(field)) | ||||
|     return fields | ||||
| @ -264,10 +275,6 @@ def create_form (): | ||||
|         response.status = 400 | ||||
|         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: | ||||
| @ -284,14 +291,19 @@ def create_form (): | ||||
|     # TODO limit the insertion rate | ||||
|     token = ''.join(random.sample(token_chars, token_len)) | ||||
|     try: | ||||
|         inserted = mongodb_database['forms'].insert_one({ | ||||
|         newEntry = { | ||||
|             'mail': mail, | ||||
|             'content': content, | ||||
|             'subject': subject, | ||||
|             'user_id': user['_id'], | ||||
|             'token': token, | ||||
|             'honeypotfield': honeypotfield, | ||||
|         }) | ||||
|         } | ||||
|         if 'honeypotfield' in request.forms: | ||||
|             newEntry['honeypotfield'] = request.forms.getunicode('honeypotfield') | ||||
|         if 'timerdelay' in request.forms: | ||||
|             newEntry['timerdelay'] = request.forms.getunicode('timerdelay') | ||||
| 
 | ||||
|         inserted = mongodb_database['forms'].insert_one(newEntry) | ||||
|     except pymongo.errors.ServerSelectionTimeoutError as e: | ||||
|         response.status = 500 | ||||
|         return resp('error', 'La base de donnée n’est pas accessible') | ||||
| @ -411,6 +423,7 @@ def delete_user (username): | ||||
| 
 | ||||
| ##################################################### app startup ############################################ | ||||
| if __name__ == '__main__': | ||||
|     app.install(EnableCors()) | ||||
|     bottle.run(app=StripPathMiddleware(app), host=listen_address, port=listen_port, debug=True) | ||||
| else: | ||||
|     prod_app = StripPathMiddleware(app) | ||||
|  | ||||
| @ -7,7 +7,8 @@ | ||||
| <body> | ||||
| <div id="contact-mailer-message"></div> | ||||
| <form action="http://localhost:8080/submit" method="POST" id="contact-mailer-form"> | ||||
|     <input type="hidden" name="token" value="sYMXDz5UKuRF38LbQl20ikrmp7nhHcxTCgGZodqAaBtSvPOV4f" /> | ||||
|     <noscript>Les protections anti-spam, nécéssitent l’utilisation de javascript. Rien d’intrusif normalement.</noscript> | ||||
|     <input type="hidden" name="token" value="PK8gQHDx9VoJ7yuEhbj5iCZkcUOAqTYlRSN14XFtdfr3LBs0zn" /> | ||||
|     <div> | ||||
|       <label for="nom">Votre nom :</label> | ||||
|       <input type="text" name="nom" required="required"/> | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user