Compare commits

..

11 Commits

7 changed files with 61 additions and 56 deletions

View File

@ -29,12 +29,11 @@ To set up the server, consult some of the comprehensive guides on various hostin
Here is a [good starting point on setting up a server](https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-22-04).
To install Docker and Docker Compose, consult the respective documentation:
- [Install on Ubuntu](https://docs.docker.com/engine/install/ubuntu/) or [Install on Debian](https://docs.docker.com/engine/install/debian/)
- Docker Compose should be installed as part of that.
```
At the time of writing, there has been an upgrade to Docker and Docker Compose, meaning the syntax below might be different between versions.
```
> At the time of writing, there has been an upgrade to Docker and Docker Compose, meaning the syntax below might be different between versions.
Check if Git is installed on your server using the `git --version` command.
If it isn't installed, install it.
@ -72,13 +71,13 @@ Also make sure that the various entries for usernames and passwords match.
There are some values in the following four files you will need to configure to reflect the domain you are installing this app.
```
```sh
# .env
SERVER_NAME= # URL where this will be hosted.
```
```
```sh
# install-script.sh
domains=(example.org www.example.org)
@ -87,7 +86,7 @@ email="" # Adding a valid address is strongly recommended
Substitute the domain name `domain_name` in the two file paths in the following file:
```
```sh
# nginx/ssl.conf
ssl_certificate /etc/letsencrypt/live/domain_name/fullchain.pem;
@ -95,9 +94,9 @@ ssl_certificate_key /etc/letsencrypt/live/domain_name/privkey.pem;
...
```
And **six** locations in the following file, two for the regular version of the domain and two for the www version:
And **six** locations in the following file, two for the regular version of the domain and four for the www version (remember to keep the www. prefix where present):
```
```nginx
# nginx/conf.d/ref-test-app.conf
server {
@ -140,9 +139,9 @@ This will be set up automatically.
However, there is a specific chicken-and-egg problem as the web server, Nginx, won't run without certificates, Certbot, the certificate generator, won't run without the web server.
So to solve this, there is an automation script we can run that will set up a dummy certificate and then issue the appropriate certificates for us.
```
$ chmod +x install-script.sh
$ sudo ./install-script.sh
```sh
chmod +x install-script.sh
sudo ./install-script.sh
```
This will take a long time to run the first time because it will try and generate a fairly sizeable cypher.

View File

@ -6,11 +6,6 @@
- [Docker Compose Reference](https://docs.docker.com/compose/compose-file/compose-file-v3/)
### MongoDB/PyMongo
- [MongoDB Shell Commands](https://docs.mongodb.com/manual/reference/)
- [PyMongo Driver](https://pymongo.readthedocs.io/en/stable/)
## Source Code
- [MongoDB Docker Image entrypoint shell script](https://github.com/docker-library/mongo/blob/master/5.0/docker-entrypoint.sh) (Context: Tried to replicate the command to create a new user in the original entrypoint script in the custom initialisation script in this app.)
@ -23,15 +18,6 @@
- [Tables](https://www.blog.pythonlibrary.org/2017/12/14/flask-101-adding-editing-and-displaying-data/)
- [Tables, but interactive](https://blog.miguelgrinberg.com/post/beautiful-interactive-tables-for-your-flask-templates)
## Stack Exchange/Overflow
### MongoDB
- [Creating MongoDB Database on Container Start](https://stackoverflow.com/questions/42912755/how-to-create-a-db-for-mongodb-container-on-start-up)
- [Passing Environment Variables to Docker Container Entrypoint](https://stackoverflow.com/questions/64606674/how-can-i-pass-environment-variables-to-mongo-docker-entrypoint-initdb-d)
- [Integrating Flask-Login with MongoDB](https://stackoverflow.com/questions/54992412/flask-login-usermixin-class-with-a-mongodb) (**This does not work with the app as is, and is possibly something that needs more research and development in the future**)
- [Setting up a Postfix email notification system](https://medium.com/@vietgoeswest/a-simple-outbound-email-service-for-your-app-in-15-minutes-cc4da70a2af7)
## YouTube Tutorials
### General Flask Introduction
@ -72,7 +58,7 @@ A much simpler and more rudimentary introduction to Flask and MongoDB.
- [Build a User Login System with `flask-login`, `flask-wtforms`, `flask-bootstrap`, and `flask-sqlalchemy`](https://www.youtube.com/watch?v=8aTnmsDMldY)
A much more robust method that uses the various Flask modules to make a more powerful framework.
Uses SQL rather than MongoDB.
Uses SQL.
### Flask techniques
@ -80,4 +66,4 @@ Uses SQL rather than MongoDB.
### Flask handling file uploads
- [Handlin File Uploads](https://blog.miguelgrinberg.com/post/handling-file-uploads-with-flask)
- [Handling File Uploads](https://blog.miguelgrinberg.com/post/handling-file-uploads-with-flask)

View File

@ -10,11 +10,12 @@ services:
volumes:
- ./certbot:/etc/letsencrypt:ro
- ./nginx:/etc/nginx
- ./src/html:/usr/share/nginx/html/
- ./ref-test/app/editor/static:/usr/share/nginx/html/admin/editor/static
- ./ref-test/app/admin/static:/usr/share/nginx/html/admin/static
- ./ref-test/app/quiz/static:/usr/share/nginx/html/quiz/static
- ./ref-test/app/root:/usr/share/nginx/html/root
- ./src/html/robots.txt:/usr/share/nginx/html/robots.txt:ro
- ./ref-test/app/root:/usr/share/nginx/html/root:ro
- ./ref-test/app/admin/static:/usr/share/nginx/html/admin/static:ro
- ./ref-test/app/editor/static:/usr/share/nginx/html/editor/static:ro
- ./ref-test/app/quiz/static:/usr/share/nginx/html/quiz/static:ro
- ./ref-test/app/view/static:/usr/share/nginx/html/view/static:ro
ports:
- 80:80
- 443:443

View File

@ -20,6 +20,11 @@ server {
include /etc/nginx/certbot-challenge.conf;
# Define locations for static files to be served by Nginx
location ^~ /root/ {
include /etc/nginx/mime.types;
alias /usr/share/nginx/html/root/;
}
location ^~ /quiz/static/ {
include /etc/nginx/mime.types;
alias /usr/share/nginx/html/quiz/static/;
@ -32,12 +37,12 @@ server {
location ^~ /admin/editor/static/ {
include /etc/nginx/mime.types;
alias /usr/share/nginx/html/admin/editor/static/;
alias /usr/share/nginx/html/editor/static/;
}
location ^~ /admin/view/static/ {
include /etc/nginx/mime.types;
alias /usr/share/nginx/html/admin/view/static/;
alias /usr/share/nginx/html/view/static/;
}
# Proxy to the main app for all other requests

View File

@ -6,6 +6,7 @@ from .test import Test
from flask_login import current_user
from flask_mail import Message
from smtplib import SMTPException
from datetime import datetime, timedelta
from uuid import uuid4
@ -174,4 +175,7 @@ class Entry(db.Model):
<p>Best wishes, <br/> SKA Refereeing</p>
"""
)
try:
mail.send(email)
except SMTPException as exception:
write('system.log', f'SMTP Error when trying to notify results to {self.get_surname()}, {self.get_first_name()} with error: {exception}')

View File

@ -6,6 +6,7 @@ from flask import flash, jsonify, session
from flask.helpers import url_for
from flask_login import current_user, login_user, logout_user, UserMixin
from flask_mail import Message
from smtplib import SMTPException
from werkzeug.security import check_password_hash, generate_password_hash
import secrets
@ -90,7 +91,10 @@ class User(UserMixin, db.Model):
<p>SKA Refereeing</p>
"""
)
try:
mail.send(email)
except SMTPException as exception:
write('system.log', f'SMTP Error while trying to notify new user account creation to {self.get_username()} with error: {exception}')
return True, f'User {self.get_username()} was created successfully.'
def login(self, remember:bool=False):
@ -109,7 +113,6 @@ class User(UserMixin, db.Model):
self.set_password(new_password)
self.reset_token = secrets.token_urlsafe(16)
self.verification_token = secrets.token_urlsafe(16)
db.session.commit()
email = Message(
subject='RefTest | Password Reset',
recipients=[self.get_email()],
@ -142,11 +145,12 @@ class User(UserMixin, db.Model):
<p>SKA Refereeing</p>
"""
)
try:
mail.send(email)
print('Password', new_password)
print('Reset Token', self.reset_token)
print('Verification Token', self.verification_token)
print('Reset Link', f'{url_for("admin._reset", token=self.reset_token, verification=self.verification_token, _external=True)}')
except SMTPException as exception:
write('system.log', f'SMTP Error while trying to reset password for {self.get_username()} with error: {exception}')
return jsonify({'error': f'SMTP Error: {exception}'}), 500
db.session.commit()
return jsonify({'success': 'Your password reset link has been generated.'}), 200
def clear_reset_tokens(self):
@ -182,7 +186,10 @@ class User(UserMixin, db.Model):
<p>SKA Refereeing</p>
"""
)
try:
mail.send(email)
except SMTPException as exception:
write('system.log', f'SMTP Error when trying to delete account {username} with error: {exception}')
return True, message
def update(self, password:str=None, email:str=None, notify:bool=False):
@ -223,5 +230,8 @@ class User(UserMixin, db.Model):
<p>SKA Refereeing</p>
"""
)
try:
mail.send(message)
except SMTPException as exception:
write('system.log', f'SMTP Error when trying to update account {self.get_username()} with error: {exception}')
return True, f'Account {self.get_username()} has been updated.'

View File

@ -1,13 +1,13 @@
blinker==1.4
cffi==1.15.0
blinker==1.5
cffi==1.15.1
click==8.1.3
cryptography==37.0.2
cryptography==37.0.4
dnspython==2.2.1
dominate==2.6.0
dominate==2.7.0
email-validator==1.2.1
Flask==2.1.2
Flask==2.2.2
Flask-Bootstrap==3.3.7.1
Flask-Login==0.6.1
Flask-Login==0.6.2
Flask-Mail==0.9.1
Flask-SQLAlchemy==2.5.1
Flask-WTF==1.0.1
@ -20,8 +20,8 @@ MarkupSafe==2.1.1
pycparser==2.21
python-dotenv==0.20.0
six==1.16.0
SQLAlchemy==1.4.37
SQLAlchemy-Utils==0.38.2
SQLAlchemy==1.4.40
SQLAlchemy-Utils==0.38.3
visitor==0.1.3
Werkzeug==2.1.2
Werkzeug==2.2.2
WTForms==3.0.1