refactor
This commit is contained in:
parent
be9839936f
commit
2610c48a79
198
main.py
198
main.py
@ -32,66 +32,48 @@ class StripPathMiddleware(object):
|
|||||||
return self.a(e, h)
|
return self.a(e, h)
|
||||||
|
|
||||||
|
|
||||||
app = application = bottle.Bottle()
|
app = application = bottle.Bottle(catchall=False)
|
||||||
|
|
||||||
|
|
||||||
##################################################### Configuration ############################################$
|
##################################################### Configuration ############################################$
|
||||||
|
def get_env(var, default=None):
|
||||||
|
if var in os.environ:
|
||||||
|
return os.environ[var]
|
||||||
|
elif default is not None:
|
||||||
|
return default
|
||||||
|
else:
|
||||||
|
raise MissingParameterException("Environment variable {} is missing".format(var))
|
||||||
|
|
||||||
|
|
||||||
|
# Token generation
|
||||||
|
token_chars = string.ascii_lowercase+string.ascii_uppercase+string.digits
|
||||||
|
token_len = 50
|
||||||
|
|
||||||
|
# form template regex
|
||||||
|
form_regex = '\{\{(\w+)(\|\w+)?\}\}'
|
||||||
|
|
||||||
# Load file from .env file.
|
# Load file from .env file.
|
||||||
load_dotenv(os.path.dirname(__file__) + '.env')
|
load_dotenv(os.path.dirname(__file__) + '.env')
|
||||||
|
|
||||||
token_chars = string.ascii_lowercase+string.ascii_uppercase+string.digits
|
|
||||||
token_len = 50
|
|
||||||
|
|
||||||
|
|
||||||
# Get address and port from env
|
# Get address and port from env
|
||||||
listen_address = os.environ['LISTEN_ADDRESS'] if 'LISTEN_ADDRESS' in os.environ else '0.0.0.0'
|
listen_address = get_env('LISTEN_ADDRESS', '0.0.0.0')
|
||||||
listen_port = os.environ['LISTEN_PORT'] if 'LISTEN_PORT' in os.environ else 8080
|
listen_port = get_env('LISTEN_PORT', 8080)
|
||||||
|
|
||||||
# Get mail related informations from env
|
|
||||||
mail_default_subject = os.environ['MAIL_DEFAULT_SUBJECT'] if 'MAIL_DEFAULT_SUBJECT' in os.environ else 'Nouveau message'
|
|
||||||
mail_subject_prefix = os.environ['MAIL_SUBJECT_PREFIX'] if 'MAIL_SUBJECT_PREFIX' in os.environ else '[Contact]'
|
|
||||||
|
|
||||||
# Redirect info
|
|
||||||
success_redirect_default = os.environ['SUCCESS_REDIRECT_DEFAULT'] if 'SUCCESS_REDIRECT_DEFAULT' in os.environ else '/success'
|
|
||||||
failure_redirect_default = os.environ['FAILURE_REDIRECT_DEFAULT'] if 'FAILURE_REDIRECT_DEFAULT' in os.environ else '/fail'
|
|
||||||
|
|
||||||
# Get SMTP infos from env
|
# Get SMTP infos from env
|
||||||
if 'SMTP_SERVER_ADDRESS' in os.environ:
|
smtp_server_address = get_env('SMTP_SERVER_ADDRESS')
|
||||||
smtp_server_address = os.environ['SMTP_SERVER_ADDRESS']
|
smtp_server_port = get_env('SMTP_SERVER_PORT')
|
||||||
else:
|
smtp_server_username = get_env('SMTP_SERVER_USERNAME')
|
||||||
raise MissingParameterException("Environment variable SMTP_SERVER_ADDRESS is missing")
|
smtp_server_password = get_env('SMTP_SERVER_PASSWORD')
|
||||||
|
smtp_server_sender = get_env('SMTP_SERVER_SENDER')
|
||||||
if 'SMTP_SERVER_PORT' in os.environ:
|
|
||||||
smtp_server_port = os.environ['SMTP_SERVER_PORT']
|
|
||||||
else:
|
|
||||||
raise MissingParameterException("Environment variable SMTP_SERVER_PORT is missing")
|
|
||||||
|
|
||||||
if 'SMTP_SERVER_USERNAME' in os.environ:
|
|
||||||
smtp_server_username = os.environ['SMTP_SERVER_USERNAME']
|
|
||||||
else:
|
|
||||||
raise MissingParameterException("Environment variable SMTP_SERVER_USERNAME is missing")
|
|
||||||
|
|
||||||
if 'SMTP_SERVER_PASSWORD' in os.environ:
|
|
||||||
smtp_server_password = os.environ['SMTP_SERVER_PASSWORD']
|
|
||||||
else:
|
|
||||||
raise MissingParameterException("return Environment variable SMTP_SERVER_PASSWORD is missing")
|
|
||||||
|
|
||||||
if 'SMTP_SERVER_SENDER' in os.environ:
|
|
||||||
smtp_server_sender = os.environ['SMTP_SERVER_SENDER']
|
|
||||||
else:
|
|
||||||
raise MissingParameterException("Environment variable SMTP_SERVER_SENDER is missing")
|
|
||||||
|
|
||||||
# Get mongodb connection
|
# Get mongodb connection
|
||||||
if 'MONGODB_HOST' in os.environ:
|
mongodb_host = get_env('MONGODB_HOST')
|
||||||
mongodb_host = os.environ['MONGODB_HOST']
|
mongodb_port = get_env('MONGODB_PORT', '27017')
|
||||||
else:
|
mongodb_dbname = get_env('MONGODB_DBNAME', 'contact_mailer')
|
||||||
raise MissingParameterException("Environment variable MONGODB_HOST is missing")
|
|
||||||
|
|
||||||
mongodb_port = os.environ['MONGODB_PORT'] if 'MONGODB_PORT' in os.environ else '27017'
|
|
||||||
mongodb_dbname = os.environ['MONGODB_DBNAME'] if 'MONGODB_DBNAME' in os.environ else 'contact_mailer'
|
|
||||||
|
|
||||||
# Security
|
# Security
|
||||||
|
admin_password = get_env('ADMIN_PASSWORD')
|
||||||
|
|
||||||
if 'SMTP_SSL' in os.environ and os.environ['SMTP_SSL'] == 'true':
|
if 'SMTP_SSL' in os.environ and os.environ['SMTP_SSL'] == 'true':
|
||||||
security = 'ssl'
|
security = 'ssl'
|
||||||
elif 'SMTP_STARTTLS' in os.environ and os.onviron['SMTP_STARTTLS'] == 'true':
|
elif 'SMTP_STARTTLS' in os.environ and os.onviron['SMTP_STARTTLS'] == 'true':
|
||||||
@ -99,25 +81,12 @@ elif 'SMTP_STARTTLS' in os.environ and os.onviron['SMTP_STARTTLS'] == 'true':
|
|||||||
else:
|
else:
|
||||||
raise MissingParameterException('No security env var (SMTP_SSL or SMTP_STARTTLS) have been defined. (Expected true or false)')
|
raise MissingParameterException('No security env var (SMTP_SSL or SMTP_STARTTLS) have been defined. (Expected true or false)')
|
||||||
|
|
||||||
if 'ADMIN_PASSWORD' in os.environ:
|
|
||||||
admin_password = os.environ['ADMIN_PASSWORD']
|
|
||||||
else:
|
|
||||||
raise MissingParameterException("Environment variable ADMIN_PASSWORD is missing")
|
|
||||||
|
|
||||||
|
|
||||||
# mongodb initialization
|
# mongodb initialization
|
||||||
mongodb_client = pymongo.MongoClient("mongodb://{}:{}/".format(mongodb_host, mongodb_port))
|
mongodb_client = pymongo.MongoClient("mongodb://{}:{}/".format(mongodb_host, mongodb_port), connect=False, serverSelectionTimeoutMS=10000, connectTimeoutMS=10000)
|
||||||
mongodb_database = mongodb_client[mongodb_dbname]
|
mongodb_database = mongodb_client[mongodb_dbname]
|
||||||
|
|
||||||
# form template regex
|
|
||||||
form_regex = '\{\{(\w+)(\|\w+)?\}\}'
|
|
||||||
|
|
||||||
|
##################################################### main route: mail submission ############################################$
|
||||||
@app.post('/fail')
|
|
||||||
def fail ():
|
|
||||||
a = 2/0
|
|
||||||
print('lol, failed', file=sys.stderr)
|
|
||||||
return 'failed'
|
|
||||||
|
|
||||||
@app.post('/submit')
|
@app.post('/submit')
|
||||||
def submission ():
|
def submission ():
|
||||||
@ -140,6 +109,9 @@ def submission ():
|
|||||||
except IndexError as e:
|
except IndexError as e:
|
||||||
response.status = 400
|
response.status = 400
|
||||||
return 'Le formulaire est introuvable'
|
return 'Le formulaire est introuvable'
|
||||||
|
except pymongo.errors.ServerSelectionTimeoutError as e:
|
||||||
|
response.status = 500
|
||||||
|
return 'La base de donnée n’est pas accessible'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
subject_fields = fill_fields(request, get_fields(form['subject']))
|
subject_fields = fill_fields(request, get_fields(form['subject']))
|
||||||
@ -151,9 +123,13 @@ def submission ():
|
|||||||
subject = re.sub(form_regex, r'{\1}', form['subject']).format(**subject_fields)
|
subject = re.sub(form_regex, r'{\1}', form['subject']).format(**subject_fields)
|
||||||
content = re.sub(form_regex, r'{\1}', form['content']).format(**content_fields)
|
content = re.sub(form_regex, r'{\1}', form['content']).format(**content_fields)
|
||||||
|
|
||||||
if not send_mail(from_address, form['mail'], subject, content):
|
try:
|
||||||
|
if not send_mail(from_address, form['mail'], subject, content):
|
||||||
|
response.status = 500
|
||||||
|
return 'Le mail n’a pas pu être envoyé.'
|
||||||
|
except SMTPDataError as e:
|
||||||
response.status = 500
|
response.status = 500
|
||||||
return 'Le mail n’a pas pu être envoyé.'
|
return 'Le mail a été refusé.'
|
||||||
|
|
||||||
# Redirection
|
# Redirection
|
||||||
#redirect(success_redirect_default)
|
#redirect(success_redirect_default)
|
||||||
@ -220,6 +196,9 @@ def login(request):
|
|||||||
return user
|
return user
|
||||||
except IndexError as e:
|
except IndexError as e:
|
||||||
pass
|
pass
|
||||||
|
except pymongo.errors.ServerSelectionTimeoutError as e:
|
||||||
|
response.status = 500
|
||||||
|
return 'La base de donnée n’est pas accessible'
|
||||||
|
|
||||||
return {'_privilege': 1000} # anonymous
|
return {'_privilege': 1000} # anonymous
|
||||||
|
|
||||||
@ -258,27 +237,37 @@ def create_form ():
|
|||||||
|
|
||||||
# TODO limit the insertion rate
|
# TODO limit the insertion rate
|
||||||
token = ''.join(random.sample(token_chars, token_len))
|
token = ''.join(random.sample(token_chars, token_len))
|
||||||
inserted = mongodb_database['forms'].insert_one({
|
try:
|
||||||
'mail': mail,
|
inserted = mongodb_database['forms'].insert_one({
|
||||||
'content': content,
|
'mail': mail,
|
||||||
'subject': subject,
|
'content': content,
|
||||||
'user_id': user['_id'],
|
'subject': subject,
|
||||||
'token': token,
|
'user_id': user['_id'],
|
||||||
})
|
'token': token,
|
||||||
|
})
|
||||||
|
except pymongo.errors.ServerSelectionTimeoutError as e:
|
||||||
|
response.status = 500
|
||||||
|
return 'La base de donnée n’est pas accessible'
|
||||||
|
|
||||||
return 'Créé : ' + token
|
return 'Créé : ' + token
|
||||||
|
|
||||||
@app.post('/form/list')
|
@app.post('/form/list')
|
||||||
def list_forms ():
|
def list_forms ():
|
||||||
user = login(request)
|
try:
|
||||||
if user['_privilege'] == 0:
|
user = login(request)
|
||||||
filt = {}
|
if user['_privilege'] == 0:
|
||||||
elif user['_privilege'] == 1:
|
filt = {}
|
||||||
filt = {'user_id': user['_id']}
|
elif user['_privilege'] == 1:
|
||||||
else:
|
filt = {'user_id': user['_id']}
|
||||||
response.status = 400
|
else:
|
||||||
return 'Privilèges insufisants'
|
response.status = 400
|
||||||
return bottle.template("list.tpl", data=mongodb_database['forms'].find(filt))
|
return 'Privilèges insufisants'
|
||||||
|
data = mongodb_database['forms'].find(filt)
|
||||||
|
return bottle.template("list.tpl", data=data)
|
||||||
|
except pymongo.errors.ServerSelectionTimeoutError as e:
|
||||||
|
response.status = 500
|
||||||
|
return 'La base de donnée n’est pas accessible'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@app.delete('/form/<token>')
|
@app.delete('/form/<token>')
|
||||||
@ -295,11 +284,18 @@ def delete_form(token):
|
|||||||
except IndexError as e:
|
except IndexError as e:
|
||||||
response.status = 400
|
response.status = 400
|
||||||
return 'Le token n’est pas valide'
|
return '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'
|
||||||
|
|
||||||
if user['_privilege'] == 0 or (form['user_id'] == user['_id']):
|
if user['_privilege'] == 0 or (form['user_id'] == user['_id']):
|
||||||
mongodb_database['forms'].delete_one({
|
try:
|
||||||
'token': token,
|
mongodb_database['forms'].delete_one({
|
||||||
})
|
'token': token,
|
||||||
|
})
|
||||||
|
except pymongo.errors.ServerSelectionTimeoutError as e:
|
||||||
|
response.status = 500
|
||||||
|
return 'La base de donnée n’est pas accessible'
|
||||||
return 'Supprimé ' + token
|
return 'Supprimé ' + token
|
||||||
response.status = 400
|
response.status = 400
|
||||||
return 'Privilèges insufisants'
|
return 'Privilèges insufisants'
|
||||||
@ -313,7 +309,13 @@ def list_users ():
|
|||||||
if user['_privilege'] > 0:
|
if user['_privilege'] > 0:
|
||||||
response.status = 400
|
response.status = 400
|
||||||
return 'Privilèges insufisants'
|
return 'Privilèges insufisants'
|
||||||
return bottle.template("list.tpl", data=mongodb_database['users'].find())
|
try:
|
||||||
|
data = mongodb_database['users'].find()
|
||||||
|
return bottle.template("list.tpl", data=data)
|
||||||
|
except pymongo.errors.ServerSelectionTimeoutError as e:
|
||||||
|
response.status = 500
|
||||||
|
return 'La base de donnée n’est pas accessible'
|
||||||
|
|
||||||
|
|
||||||
@app.put('/user/<username>')
|
@app.put('/user/<username>')
|
||||||
def create_user (username):
|
def create_user (username):
|
||||||
@ -325,11 +327,18 @@ def create_user (username):
|
|||||||
mongodb_database['users'].find({'username': username})[0]
|
mongodb_database['users'].find({'username': username})[0]
|
||||||
return 'L’utilisateur existe déjà'
|
return 'L’utilisateur existe déjà'
|
||||||
except IndexError as e:
|
except IndexError as e:
|
||||||
inserted = mongodb_database['users'].insert_one({
|
try:
|
||||||
'username': username,
|
inserted = mongodb_database['users'].insert_one({
|
||||||
'token': ''.join(random.sample(token_chars, token_len))
|
'username': username,
|
||||||
})
|
'token': ''.join(random.sample(token_chars, token_len))
|
||||||
return 'Créé : ' + username
|
})
|
||||||
|
return 'Créé : ' + username
|
||||||
|
except pymongo.errors.ServerSelectionTimeoutError as e:
|
||||||
|
response.status = 500
|
||||||
|
return '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'
|
||||||
|
|
||||||
|
|
||||||
@app.delete('/user/<username>')
|
@app.delete('/user/<username>')
|
||||||
@ -340,15 +349,20 @@ def delete_user (username):
|
|||||||
return 'Privilèges insufisants'
|
return 'Privilèges insufisants'
|
||||||
try:
|
try:
|
||||||
mongodb_database['users'].find({'username': username})[0]
|
mongodb_database['users'].find({'username': username})[0]
|
||||||
|
mongodb_database['users'].delete_one({
|
||||||
|
'username': username,
|
||||||
|
})
|
||||||
|
return 'Supprimé ' + username
|
||||||
except IndexError as e:
|
except IndexError as e:
|
||||||
response.status = 400
|
response.status = 400
|
||||||
return 'L’utilisateur n’existe pas'
|
return 'L’utilisateur n’existe pas'
|
||||||
mongodb_database['users'].delete_one({
|
except pymongo.errors.ServerSelectionTimeoutError as e:
|
||||||
'username': username,
|
response.status = 500
|
||||||
})
|
return 'La base de donnée n’est pas accessible'
|
||||||
return 'Supprimé ' + username
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##################################################### app startup ############################################$
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
bottle.run(app=StripPathMiddleware(app), host=listen_address, port=listen_port, debug=True)
|
bottle.run(app=StripPathMiddleware(app), host=listen_address, port=listen_port, debug=True)
|
||||||
else:
|
else:
|
||||||
|
Loading…
Reference in New Issue
Block a user