From be24a37f5cd911c4e10e7aa4bcf27ecbe519982f Mon Sep 17 00:00:00 2001 From: Yusur Princeps Date: Thu, 6 Nov 2025 06:36:02 +0100 Subject: [PATCH 1/4] move old migrations away from project root --- migrate_0_4_to_0_5.py => src/old_migrations/migrate_0_4_to_0_5.py | 0 migrate_0_6_to_0_7.py => src/old_migrations/migrate_0_6_to_0_7.py | 0 migrate_0_7_to_0_8.py => src/old_migrations/migrate_0_7_to_0_8.py | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename migrate_0_4_to_0_5.py => src/old_migrations/migrate_0_4_to_0_5.py (100%) rename migrate_0_6_to_0_7.py => src/old_migrations/migrate_0_6_to_0_7.py (100%) rename migrate_0_7_to_0_8.py => src/old_migrations/migrate_0_7_to_0_8.py (100%) diff --git a/migrate_0_4_to_0_5.py b/src/old_migrations/migrate_0_4_to_0_5.py similarity index 100% rename from migrate_0_4_to_0_5.py rename to src/old_migrations/migrate_0_4_to_0_5.py diff --git a/migrate_0_6_to_0_7.py b/src/old_migrations/migrate_0_6_to_0_7.py similarity index 100% rename from migrate_0_6_to_0_7.py rename to src/old_migrations/migrate_0_6_to_0_7.py diff --git a/migrate_0_7_to_0_8.py b/src/old_migrations/migrate_0_7_to_0_8.py similarity index 100% rename from migrate_0_7_to_0_8.py rename to src/old_migrations/migrate_0_7_to_0_8.py From c46dce5e3bef094dc726483232ee02049cf6edd9 Mon Sep 17 00:00:00 2001 From: Yusur Princeps Date: Thu, 6 Nov 2025 07:25:07 +0100 Subject: [PATCH 2/4] add CSRF token --- CHANGELOG.md | 1 + genmig.sh | 6 ++++++ pyproject.toml | 4 +++- src/coriplus/__init__.py | 8 +++++++- src/coriplus/models.py | 3 ++- src/coriplus/templates/about.html | 9 ++++++--- src/coriplus/templates/admin_report_detail.html | 1 + src/coriplus/templates/base.html | 2 +- src/coriplus/templates/change_password.html | 1 + src/coriplus/templates/confirm_delete.html | 9 ++++----- src/coriplus/templates/create.html | 1 + src/coriplus/templates/edit.html | 1 + src/coriplus/templates/edit_profile.html | 1 + src/coriplus/templates/login.html | 1 + src/coriplus/templates/report_message.html | 1 + src/coriplus/templates/report_user.html | 1 + 16 files changed, 38 insertions(+), 12 deletions(-) create mode 100755 genmig.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index ff728bc..24a2232 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ + Codebase refactor (with breaking changes!) + Move ALL config to .env (config.py is NO MORE supported) + Config SITE_NAME replaced with APP_NAME ++ Add CSRF token and flask_WTF ## 0.9.0 diff --git a/genmig.sh b/genmig.sh new file mode 100755 index 0000000..bc624ce --- /dev/null +++ b/genmig.sh @@ -0,0 +1,6 @@ +#!/usr/bin/bash +# GENERATE MIGRATIONS + +source venv/bin/activate && \ +source .env && \ +pw_migrate create --auto --auto-source=coriplus.models --directory=src/migrations --database="$DATABASE_URL" "$@" \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index f4d5b53..72b1800 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,9 @@ dependencies = [ "Python-Dotenv>=1.0.0", "Flask", "Flask-Login", - "Peewee" + "Peewee", + "Flask-WTF", + "peewee-migrate" ] requires-python = ">=3.10" classifiers = [ diff --git a/src/coriplus/__init__.py b/src/coriplus/__init__.py index 4f01715..d829da9 100644 --- a/src/coriplus/__init__.py +++ b/src/coriplus/__init__.py @@ -20,6 +20,7 @@ from flask import ( send_from_directory, __version__ as flask_version) import os, sys from flask_login import LoginManager +from flask_wtf import CSRFProtect import dotenv import logging @@ -44,6 +45,8 @@ app.secret_key = os.environ['SECRET_KEY'] login_manager = LoginManager(app) +CSRFProtect(app) + from .models import * from .utils import * @@ -64,7 +67,10 @@ def before_request(): @app.after_request def after_request(response): - g.db.close() + try: + g.db.close() + except Exception: + logger.error('database closed twice') return response @app.context_processor diff --git a/src/coriplus/models.py b/src/coriplus/models.py index 4cdb2b5..0c9c68e 100644 --- a/src/coriplus/models.py +++ b/src/coriplus/models.py @@ -13,11 +13,12 @@ The tables are: from flask import request from peewee import * +from playhouse.db_url import connect import os # here should go `from .utils import get_current_user`, but it will cause # import errors. It's instead imported at function level. -database = SqliteDatabase('coriplus.sqlite') +database = connect(os.environ['DATABASE_URL']) class BaseModel(Model): class Meta: diff --git a/src/coriplus/templates/about.html b/src/coriplus/templates/about.html index e5691a8..b337caa 100644 --- a/src/coriplus/templates/about.html +++ b/src/coriplus/templates/about.html @@ -3,9 +3,12 @@ {% block body %}

About {{ site_name }}

-

{{ site_name }} {{ version }} – Python {{ python_version }} – - Flask {{ flask_version }}

-

Copyright © 2019 Sakuragasaki46.

+ +

Copyright © 2019, 2025 Sakuragasaki46.

License

Permission is hereby granted, free of charge, to any person obtaining diff --git a/src/coriplus/templates/admin_report_detail.html b/src/coriplus/templates/admin_report_detail.html index d445d64..8f5d2c6 100644 --- a/src/coriplus/templates/admin_report_detail.html +++ b/src/coriplus/templates/admin_report_detail.html @@ -21,6 +21,7 @@ {% include "includes/reported_message.html" %} {% endif %}

+
diff --git a/src/coriplus/templates/base.html b/src/coriplus/templates/base.html index b2f79bc..adba498 100644 --- a/src/coriplus/templates/base.html +++ b/src/coriplus/templates/base.html @@ -34,7 +34,7 @@ {% block body %}{% endblock %} {% endblock %} diff --git a/src/coriplus/templates/edit.html b/src/coriplus/templates/edit.html index 5a8f907..316dc7e 100644 --- a/src/coriplus/templates/edit.html +++ b/src/coriplus/templates/edit.html @@ -1,5 +1,6 @@ {% extends "base.html" %} {% block body %} +

Edit

@@ -15,4 +16,5 @@
+
{% endblock %} diff --git a/src/coriplus/templates/edit_profile.html b/src/coriplus/templates/edit_profile.html index 319a9c2..66ecd28 100644 --- a/src/coriplus/templates/edit_profile.html +++ b/src/coriplus/templates/edit_profile.html @@ -1,6 +1,7 @@ {% extends "base.html" %} {% block body %} +

Edit Profile

@@ -33,4 +34,5 @@
+
{% endblock %} diff --git a/src/coriplus/templates/explore.html b/src/coriplus/templates/explore.html index 65d1846..e86a8f2 100644 --- a/src/coriplus/templates/explore.html +++ b/src/coriplus/templates/explore.html @@ -1,9 +1,10 @@ {% extends "base.html" %} +{% from "macros/message.html" import feed_message with context %} {% block body %}

Explore

{% include "includes/pagination.html" %} diff --git a/src/coriplus/templates/feed.html b/src/coriplus/templates/feed.html index 88b05ac..beb6607 100644 --- a/src/coriplus/templates/feed.html +++ b/src/coriplus/templates/feed.html @@ -1,9 +1,10 @@ {% extends "base.html" %} +{% from "macros/message.html" import feed_message with context %} {% block body %}

Your Timeline

{% include "includes/pagination.html" %} diff --git a/src/coriplus/templates/homepage.html b/src/coriplus/templates/homepage.html index 106bf9a..fdad92f 100644 --- a/src/coriplus/templates/homepage.html +++ b/src/coriplus/templates/homepage.html @@ -1,7 +1,9 @@ {% extends "base.html" %} {% block body %} +

Hello

{{ site_name }} is made by people like you.
Log in or register to see more.

+
{% endblock %} diff --git a/src/coriplus/templates/join.html b/src/coriplus/templates/join.html index 607387f..a45b511 100644 --- a/src/coriplus/templates/join.html +++ b/src/coriplus/templates/join.html @@ -1,5 +1,6 @@ {% extends "base.html" %} {% block body %} +

Join {{ site_name }}

@@ -32,4 +33,5 @@
+
{% endblock %} diff --git a/src/coriplus/templates/login.html b/src/coriplus/templates/login.html index dee8219..21a5e93 100644 --- a/src/coriplus/templates/login.html +++ b/src/coriplus/templates/login.html @@ -1,9 +1,10 @@ {% extends "base.html" %} {% block body %}

Login

- {% if error %}

Error: {{ error }}{% endif %} + {% if error %}

Error: {{ error }}

{% endif %} +
- +
Username or email:
@@ -19,4 +20,5 @@
+
{% endblock %} diff --git a/src/coriplus/templates/macros/message.html b/src/coriplus/templates/macros/message.html new file mode 100644 index 0000000..b4ef93a --- /dev/null +++ b/src/coriplus/templates/macros/message.html @@ -0,0 +1,35 @@ +{% macro feed_message(message) %} +
  • +

    {{ message.text|enrich }}

    +{% if message.uploads %} +
    + +
    +{% endif %} + + +
  • +{% endmacro %} \ No newline at end of file diff --git a/src/coriplus/templates/notifications.html b/src/coriplus/templates/notifications.html index 04b61d1..33ee7bb 100644 --- a/src/coriplus/templates/notifications.html +++ b/src/coriplus/templates/notifications.html @@ -3,7 +3,7 @@

    Notifications

      {% for notification in notification_list %} -
    • {% include "includes/notification.html" %}
    • +
    • {% include "includes/notification.html" %}
    • {% endfor %}
    {% include "includes/pagination.html" %} diff --git a/src/coriplus/templates/privacy.html b/src/coriplus/templates/privacy.html index a7b8570..df4248a 100644 --- a/src/coriplus/templates/privacy.html +++ b/src/coriplus/templates/privacy.html @@ -1,47 +1,54 @@ {% extends "base.html" %} {% block body %} -

    Privacy Policy

    +
    +

    Privacy Policy

    -

    At {{ site_name }}, accessible from {{ request.host }}, one of our main priorities is the privacy of our visitors. This Privacy Policy document contains types of information that is collected and recorded by {{ site_name }} and how we use it.

    +

    At {{ site_name }}, accessible from {{ request.host }}, one of our main priorities is the privacy of our visitors. This Privacy Policy document contains types of information that is collected and recorded by {{ site_name }} and how we use it.

    -

    If you have additional questions or require more information about our Privacy Policy, do not hesitate to contact us through email at sakuragasaki46@gmail.com

    +

    If you have additional questions or require more information about our Privacy Policy, do not hesitate to contact us through email at sakuragasaki46@gmail.com

    -

    Log Files

    +

    Log Files

    -

    {{ site_name }} follows a standard procedure of using log files. These files log visitors when they visit websites. All hosting companies do this and a part of hosting services' analytics. The information collected by log files include internet protocol (IP) addresses, browser type, Internet Service Provider (ISP), date and time stamp, referring/exit pages, and possibly the number of clicks. These are not linked to any information that is personally identifiable. The purpose of the information is for analyzing trends, administering the site, tracking users' movement on the website, and gathering demographic information.

    +

    {{ site_name }} follows a standard procedure of using log files. These files log visitors when they visit websites. All hosting companies do this and a part of hosting services' analytics. The information collected by log files include internet protocol (IP) addresses, browser type, Internet Service Provider (ISP), date and time stamp, referring/exit pages, and possibly the number of clicks. These are not linked to any information that is personally identifiable. The purpose of the information is for analyzing trends, administering the site, tracking users' movement on the website, and gathering demographic information.

    -

    Cookies and Web Beacons

    +

    Cookies and Web Beacons

    -

    Like any other website, {{ site_name }} uses 'cookies'. These cookies are used to store information including visitors' preferences, and the pages on the website that the visitor accessed or visited. The information is used to optimize the users' experience by customizing our web page content based on visitors' browser type and/or other information.

    +

    Like any other website, {{ site_name }} uses 'cookies'. These cookies are used to store information including visitors' preferences, and the pages on the website that the visitor accessed or visited. The information is used to optimize the users' experience by customizing our web page content based on visitors' browser type and/or other information.

    +

    You can choose to disable cookies through your individual browser options. This, however, can and will hurt Your usage of {{ site_name }}

    + +

    Privacy Policies

    +

    You may consult this list to find the Privacy Policy for each of the advertising partners of {{ site_name }}. Our Privacy Policy was created with the help of the Privacy Policy Generator and the Generate Privacy Policy Generator.

    -

    Privacy Policies

    +

    Third-party ad servers or ad networks uses technologies like cookies, JavaScript, or Web Beacons that are used in their respective advertisements and links that appear on {{ site_name }}, which are sent directly to users' browser. They automatically receive your IP address when this occurs. These technologies are used to measure the effectiveness of their advertising campaigns and/or to personalize the advertising content that you see on websites that you visit.

    -

    You may consult this list to find the Privacy Policy for each of the advertising partners of {{ site_name }}. Our Privacy Policy was created with the help of the Privacy Policy Generator and the Generate Privacy Policy Generator.

    +

    Note that {{ site_name }} has no access to or control over these cookies that are used by third-party advertisers.

    -

    Third-party ad servers or ad networks uses technologies like cookies, JavaScript, or Web Beacons that are used in their respective advertisements and links that appear on {{ site_name }}, which are sent directly to users' browser. They automatically receive your IP address when this occurs. These technologies are used to measure the effectiveness of their advertising campaigns and/or to personalize the advertising content that you see on websites that you visit.

    +

    Third Party Privacy Policies

    -

    Note that {{ site_name }} has no access to or control over these cookies that are used by third-party advertisers.

    +

    {{ site_name }}'s Privacy Policy does not apply to other advertisers or websites. Thus, we are advising you to consult the respective Privacy Policies of these third-party ad servers for more detailed information. It may include their practices and instructions about how to opt-out of certain options. You may find a complete list of these Privacy Policies and their links here: Privacy Policy Links.

    -

    Third Party Privacy Policies

    +

    Legal Basis

    -

    {{ site_name }}'s Privacy Policy does not apply to other advertisers or websites. Thus, we are advising you to consult the respective Privacy Policies of these third-party ad servers for more detailed information. It may include their practices and instructions about how to opt-out of certain options. You may find a complete list of these Privacy Policies and their links here: Privacy Policy Links.

    +

    Legal Basis for treatment is Legitimate Interest, except:

    +
      +
    • Transactional information, such as username, email and essential cookies, are treated according to Providing a Service.
    • +
    -

    You can choose to disable cookies through your individual browser options. To know more detailed information about cookie management with specific web browsers, it can be found at the browsers' respective websites. What Are Cookies?

    +

    Children's Information

    -

    Children's Information

    +

    Another part of our priority is adding protection for children while using the internet. We encourage parents and guardians to observe, participate in, monitor, guide and/or exercise total control on their online activity.

    -

    Another part of our priority is adding protection for children while using the internet. We encourage parents and guardians to observe, participate in, and/or monitor and guide their online activity.

    +

    {{ site_name }} does not knowingly collect any Personal Identifiable Information from children under the age of 13. If you think that your child provided this kind of information on our website, we strongly encourage you to contact us immediately and we will do our best efforts to promptly remove such information from our records.

    -

    {{ site_name }} does not knowingly collect any Personal Identifiable Information from children under the age of 13. If you think that your child provided this kind of information on our website, we strongly encourage you to contact us immediately and we will do our best efforts to promptly remove such information from our records.

    +

    Online Privacy Policy Only

    -

    Online Privacy Policy Only

    +

    This Privacy Policy applies only to our online activities and is valid for visitors to our website with regards to the information that they shared and/or collect in {{ site_name }}. This policy is not applicable to any information collected via channels other than this website.

    -

    This Privacy Policy applies only to our online activities and is valid for visitors to our website with regards to the information that they shared and/or collect in {{ site_name }}. This policy is not applicable to any information collected offline or via channels other than this website.

    +

    Consent

    -

    Consent

    - -

    By using our website, you hereby consent to our Privacy Policy and agree to its Terms and Conditions.

    +

    By using our website, you hereby consent irrevocably to our Privacy Policy and agree to its Terms and Conditions.

    +
    {% endblock %} diff --git a/src/coriplus/templates/terms.html b/src/coriplus/templates/terms.html index 203e44e..ab8ca7f 100644 --- a/src/coriplus/templates/terms.html +++ b/src/coriplus/templates/terms.html @@ -1,7 +1,9 @@ {% extends "base.html" %} {% block body %} +

    Terms of Service

    - +

    [decline to state]

    +
    {% endblock %} diff --git a/src/coriplus/templates/user_detail.html b/src/coriplus/templates/user_detail.html index 9b5e7a5..6324f1e 100644 --- a/src/coriplus/templates/user_detail.html +++ b/src/coriplus/templates/user_detail.html @@ -1,15 +1,18 @@ {% extends "base.html" %} +{% from "macros/message.html" import feed_message with context %} {% block body %} {% include "includes/infobox_profile.html" %}

    Messages from {{ user.username }}

    {% if not current_user.is_anonymous %} {% if user.username != current_user.username %} {% if current_user|is_following(user) %} -
    + +
    {% else %} -
    + +
    {% endif %} @@ -20,7 +23,7 @@ {% endif %}
      {% for message in message_list %} -
    • {% include "includes/message.html" %}
    • + {{ feed_message(message) }} {% endfor %}
    {% include "includes/pagination.html" %} diff --git a/src/coriplus/utils.py b/src/coriplus/utils.py index 5259b80..7a98d5b 100644 --- a/src/coriplus/utils.py +++ b/src/coriplus/utils.py @@ -218,12 +218,6 @@ def create_mentions(cur_user, text, privacy): pass # New in 0.9 -def inline_svg(name, width=None): - try: - with open('icons/' + name + '-24px.svg') as f: - data = f.read() - if isinstance(width, int): - data = re.sub(r'( (?:height|width)=")\d+(")', lambda x:x.group(1) + str(width) + x.group(2), data) - return Markup(data) - except OSError: - return '' +# changed in 0.10 +def inline_svg(name): + return Markup('{}').format(name)