From c7df4ad6dc2a21f8884b5205ff76789b62f74248 Mon Sep 17 00:00:00 2001 From: PV Tejas Date: Tue, 11 Jul 2023 13:14:11 +0000 Subject: [PATCH 01/10] Add CONTRIBUTING --- CONTRIBUTING.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..86f3608 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,3 @@ +Merge requests and issues are welcome. + +Merge requests must be targeted at issues, with each merge request including a line (or multiple) "Closes #" in it. If a merge request doesn't close an issue, consider raising an issue before submitting the MR. From f52d98333ef3b7d5448f271d165bf4ca6cdee0bc Mon Sep 17 00:00:00 2001 From: Punnamaraju Vinayaka Tejas Date: Wed, 12 Jul 2023 12:47:01 +0530 Subject: [PATCH 02/10] Configured to run behind reverse proxy, using Gunicorn --- README.md | 4 ++-- flaskr/__init__.py | 5 +++++ requirements.txt | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c8e668f..7ea53b3 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ ## Development From the root directory, run `pip install -r requirements.txt` to install the package (and all dependencies) in editable mode. -Use `flask --app flaskr run` to run app. The package will be updated as you edit files. +Use `gunicorn -w 2 'flaskr:create_app()'` to run app. Increase the number of workers using the `-w` argument if desired. The package will be updated as you edit files. ## Production Run `python -m build --wheel` to generate the wheel, and install the wheel (found in `dist/`) in the production environment. -Use `flask --app flaskr run` to run app. To update package, you will need to install a new wheel. +Use `gunicorn -w 2 'flaskr:create_app()'` to run app. Increase the number of workers using the `-w` argument if desired. To update package, you will need to install a new wheel. ## Initializing database The first time you install the app in each environment, you need to initialize database using `flask --app flaskr init-db`. This only needs to be run once per environment, and **will delete existing database if run again**. diff --git a/flaskr/__init__.py b/flaskr/__init__.py index bf080a1..ed7d989 100644 --- a/flaskr/__init__.py +++ b/flaskr/__init__.py @@ -1,5 +1,6 @@ import os from flask import Flask +from werkzeug.middleware.proxy_fix import ProxyFix def create_app(test_config=None): # create and configure the app @@ -9,6 +10,10 @@ def create_app(test_config=None): DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'), ) + app.wsgi_app = ProxyFix( + app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_prefix=1 + ) + if test_config is None: # load the instance config, if it exists, when not testing app.config.from_pyfile('config.py', silent=True) diff --git a/requirements.txt b/requirements.txt index bd6b9c1..3f319fd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,7 +8,8 @@ dnspython==2.3.0 email-validator==2.0.0.post2 exceptiongroup==1.1.1 Flask==2.3.2 --e git+https://gitlab.com/pvtejas/based4tech.git@3518f50f67c913274f78e2c4b91fe9b7e052ac0d#egg=flaskr +-e git+https://gitlab.com/pvtejas/based4tech.git@4be89bd767a7c5a84ab62fbf4ad924ae1af077f1#egg=flaskr +gunicorn==20.1.0 h11==0.14.0 httpcore==0.17.0 httptools==0.5.0 From de094d4bed20ffa2396e20217546fadf155a72c6 Mon Sep 17 00:00:00 2001 From: Punnamaraju Vinayaka Tejas Date: Wed, 12 Jul 2023 12:51:39 +0530 Subject: [PATCH 03/10] Closes #2 and #3 --- README.md | 11 +++++++++-- flaskr/__init__.py | 1 + flaskr/auth.py | 4 +++- flaskr/templates/base.html | 3 --- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 7ea53b3..e734e45 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,14 @@ Use `gunicorn -w 2 'flaskr:create_app()'` to run app. Increase the number of wor ## Initializing database The first time you install the app in each environment, you need to initialize database using `flask --app flaskr init-db`. This only needs to be run once per environment, and **will delete existing database if run again**. -## Secret key +## Config file + +The config file is located at `/var/flaskr-instance/config.py` + +### Secret Key Every website with login needs a secret key to hash passwords with. -`/var/flaskr-instance/config.py` must contain a line `SECRET_KEY = '`, which must be randomly generated. +The config file must contain a line `SECRET_KEY = '`, which must be randomly generated. Suggested way of generating the key is `python -c 'import secrets; print(secrets.token_hex())'`, which returns a hexadecimal string with length 64. You may choose to randomly generate a key using a different method, but ensure that it is resistant to brute-force attacks. + +### Registration +Since this blog is meant to be updated by a limited number of people, registration is forbidden (403) by default. In addition, registration (/auth/register) and login (/auth/login) URLs are not hyperlinked anywhere. Registration can be opened by including `REGISTER = True`, or closed by including `REGISTER = False`, in the config file. \ No newline at end of file diff --git a/flaskr/__init__.py b/flaskr/__init__.py index ed7d989..d3f29f9 100644 --- a/flaskr/__init__.py +++ b/flaskr/__init__.py @@ -8,6 +8,7 @@ def create_app(test_config=None): app.config.from_mapping( SECRET_KEY='dev', DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'), + REGISTER=False ) app.wsgi_app = ProxyFix( diff --git a/flaskr/auth.py b/flaskr/auth.py index e41998c..f76418e 100644 --- a/flaskr/auth.py +++ b/flaskr/auth.py @@ -1,7 +1,7 @@ import functools from flask import ( - Blueprint, flash, g, redirect, render_template, request, session, url_for + Blueprint, flash, g, redirect, render_template, request, session, url_for, current_app, abort ) from werkzeug.security import check_password_hash, generate_password_hash @@ -11,6 +11,8 @@ bp = Blueprint('auth', __name__, url_prefix='/auth') @bp.route('/register', methods=('GET', 'POST')) def register(): + if not current_app.config['REGISTER']: + abort(403) if request.method == 'POST': username = request.form['username'] password = request.form['password'] diff --git a/flaskr/templates/base.html b/flaskr/templates/base.html index a2c26cd..89fd567 100644 --- a/flaskr/templates/base.html +++ b/flaskr/templates/base.html @@ -8,9 +8,6 @@ {% if g.user %}
  • {{ g.user['username'] }}
  • Log Out - {% else %} -
  • Register -
  • Log In {% endif %} From bda624e4dc1cf97ba2b5b3fcb66a5b28398307bc Mon Sep 17 00:00:00 2001 From: Punnamaraju Vinayaka Tejas Date: Wed, 12 Jul 2023 15:37:40 +0530 Subject: [PATCH 04/10] Closes #6 --- README.md | 8 +++++++- flaskr/__init__.py | 6 +++++- flaskr/templates/base.html | 4 ++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e734e45..8e141c3 100644 --- a/README.md +++ b/README.md @@ -20,4 +20,10 @@ The config file must contain a line `SECRET_KEY = '`, which must be Suggested way of generating the key is `python -c 'import secrets; print(secrets.token_hex())'`, which returns a hexadecimal string with length 64. You may choose to randomly generate a key using a different method, but ensure that it is resistant to brute-force attacks. ### Registration -Since this blog is meant to be updated by a limited number of people, registration is forbidden (403) by default. In addition, registration (/auth/register) and login (/auth/login) URLs are not hyperlinked anywhere. Registration can be opened by including `REGISTER = True`, or closed by including `REGISTER = False`, in the config file. \ No newline at end of file +Since this blog is meant to be updated by a limited number of people, registration is forbidden (403) by default. In addition, registration (/auth/register) and login (/auth/login) URLs are not hyperlinked anywhere. Registration can be opened by including `REGISTER = True`, or closed by including `REGISTER = False`, in the config file. + +### Name +The default app name is "Flaskr", and it is visible on the header bar as well as the page title. Including a line `NAME = ''` in the config file replaces "Flaskr" with "". + +### Static folder +The default static folder is the one included in the repository. You can use a separate static folder to use your own assets by including a line `STATIC_FOLDER = ''` in the config file. diff --git a/flaskr/__init__.py b/flaskr/__init__.py index d3f29f9..7f5869b 100644 --- a/flaskr/__init__.py +++ b/flaskr/__init__.py @@ -8,9 +8,13 @@ def create_app(test_config=None): app.config.from_mapping( SECRET_KEY='dev', DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'), - REGISTER=False + REGISTER=False, + NAME='Flaskr' ) + if app.config.get('STATIC_FOLDER') is not None: + app.static_folder = app.config.get('STATIC_FOLDER') + app.wsgi_app = ProxyFix( app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_prefix=1 ) diff --git a/flaskr/templates/base.html b/flaskr/templates/base.html index 89fd567..0944d7d 100644 --- a/flaskr/templates/base.html +++ b/flaskr/templates/base.html @@ -1,9 +1,9 @@ -{% block title %}{% endblock %} - Flaskr +{% block title %}{% endblock %} - {{ config['NAME'] }} +
    +
    +
    {% block header %}{% endblock %} From 00f7c1de33f47e70db4ff43c138ba85f07027c3d Mon Sep 17 00:00:00 2001 From: Punnamaraju Vinayaka Tejas Date: Fri, 28 Jul 2023 19:47:32 +0530 Subject: [PATCH 10/10] Closes #1 --- flaskr/blog.py | 11 +++++++++++ flaskr/templates/blog/index.html | 7 +++---- flaskr/templates/blog/post.html | 20 ++++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 flaskr/templates/blog/post.html diff --git a/flaskr/blog.py b/flaskr/blog.py index cfa78d8..ec37df5 100644 --- a/flaskr/blog.py +++ b/flaskr/blog.py @@ -66,6 +66,13 @@ def get_post(id, check_author=True): return post +@bp.route('/') +def post(id): + post = get_post(id, check_author=False) + post = dict(post) + post['body'] = markdown.markdown(post['body']) + return render_template('blog/post.html', post=post) + @bp.route('//update', methods=('GET', 'POST')) @login_required def update(id): @@ -101,3 +108,7 @@ def delete(id): db.execute('DELETE FROM post WHERE id = ?',(id,)) db.commit() return redirect(url_for('blog.index')) + +@bp.route('/temp') +def temp(): + return render_template('temp.html') diff --git a/flaskr/templates/blog/index.html b/flaskr/templates/blog/index.html index ffd9fbc..d5a9167 100644 --- a/flaskr/templates/blog/index.html +++ b/flaskr/templates/blog/index.html @@ -12,14 +12,13 @@
    -

    {{ post['title'] }}

    +

    {{ post['title'] }}

    by {{ post['username'] }} on {{ post['created'].strftime('%Y-%m-%d') }}
    {% if g.user['id'] == post['author_id'] %} - Edit - {% endif %} + Edit + {% endif %}
    -

    {{ post['body']|safe }}

    {% if not loop.last %}
    diff --git a/flaskr/templates/blog/post.html b/flaskr/templates/blog/post.html new file mode 100644 index 0000000..701a37f --- /dev/null +++ b/flaskr/templates/blog/post.html @@ -0,0 +1,20 @@ +{% extends 'base.html' %} + +{% block header %} +

    {% block title %}{{ post['title']}}{% endblock %}

    +{% endblock %} + +{% block content %} +
    +
    +
    +

    {{ post['title'] }}

    +
    by {{ post['username'] }} on {{ post['created'].strftime('%Y-%m-%d') }}
    +
    + {% if g.user['id'] == post['author_id'] %} + Edit + {% endif %} +
    +

    {{ post['body']|safe }}

    +
    +{% endblock %}