From 8a2b9247e111f95a80f290ed40fdc2d7f3556cd0 Mon Sep 17 00:00:00 2001 From: mcbloch Date: Fri, 20 May 2022 19:04:32 +0200 Subject: [PATCH 1/8] initial work, model works, layout doenst --- app/add_admins.py | 2 +- app/models/user.py | 16 ++++++++++++++-- app/templates/layout.html | 6 ++++++ app/zeus.py | 2 +- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/app/add_admins.py b/app/add_admins.py index b3f8112..e9e2fba 100644 --- a/app/add_admins.py +++ b/app/add_admins.py @@ -10,5 +10,5 @@ def add() -> None: """Add users as admin.""" for username in Configuration.HALDIS_ADMINS: user = User() - user.configure(username, True, 0) + user.configure(username, True, 0, associations=["zeus"]) db.session.add(user) diff --git a/app/models/user.py b/app/models/user.py index 8e78b2f..13634bb 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -1,4 +1,6 @@ "Script for everything User related in the database" +from typing import List + from models import db @@ -8,6 +10,10 @@ class User(db.Model): username = db.Column(db.String(80), unique=True, nullable=False) admin = db.Column(db.Boolean) bias = db.Column(db.Integer) + # Assocation logic + associations = db.Column(db.String(120)) + + # Relations runs = db.relation( "Order", backref="courier", @@ -16,11 +22,17 @@ class User(db.Model): ) orderItems = db.relationship("OrderItem", backref="user", lazy="dynamic") - def configure(self, username: str, admin: bool, bias: int) -> None: - "Configure the User" + def association_list(self) -> List[str]: + return self.associations.split(",") + + def configure(self, username: str, admin: bool, bias: int, associations: List[str] = None) -> None: + """Configure the User""" + if associations is None: + associations = [] self.username = username self.admin = admin self.bias = bias + self.associations = ",".join(associations) # pylint: disable=C0111, R0201 def is_authenticated(self) -> bool: diff --git a/app/templates/layout.html b/app/templates/layout.html index 72b85b7..3ba9722 100644 --- a/app/templates/layout.html +++ b/app/templates/layout.html @@ -14,6 +14,12 @@ {% set navbar = navbar + [('admin.index', 'Admin')] -%} {% endif -%} +{% if not current_user.is_anonymous() -%} + {% for association in current_user.association_list() %} + {% set navbar = navbar + [('general_bp.home', association)] -%} + {% endfor -%} +{% endif -%} + {% set active_page = active_page|default('index') -%} {% block title %} diff --git a/app/zeus.py b/app/zeus.py index ebc16ab..09a4b04 100644 --- a/app/zeus.py +++ b/app/zeus.py @@ -77,7 +77,7 @@ def login_and_redirect_user(user) -> Response: def create_user(username) -> User: "Create a temporary user if it is needed" user = User() - user.configure(username, False, 1) + user.configure(username, False, 1, associations=["zeus"]) db.session.add(user) db.session.commit() return user From c43efa4b10cc2bb5c040d20451292e4ac3c9980a Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Fri, 20 May 2022 21:34:18 +0200 Subject: [PATCH 2/8] Migration --- .../5c8378aa4dff_add_user_associations.py | 28 +++++++++++++++++++ app/models/order.py | 1 + 2 files changed, 29 insertions(+) create mode 100644 app/migrations/versions/5c8378aa4dff_add_user_associations.py diff --git a/app/migrations/versions/5c8378aa4dff_add_user_associations.py b/app/migrations/versions/5c8378aa4dff_add_user_associations.py new file mode 100644 index 0000000..4cc135d --- /dev/null +++ b/app/migrations/versions/5c8378aa4dff_add_user_associations.py @@ -0,0 +1,28 @@ +"""Add user associations + +Revision ID: 5c8378aa4dff +Revises: 55013fe95bea +Create Date: 2022-05-20 21:32:47.786340 + +""" + +# revision identifiers, used by Alembic. +revision = '5c8378aa4dff' +down_revision = '55013fe95bea' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('order', sa.Column('association', sa.String(length=120), nullable=True)) + op.add_column('user', sa.Column('associations', sa.String(length=120), nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('user', 'associations') + op.drop_column('order', 'association') + # ### end Alembic commands ### diff --git a/app/models/order.py b/app/models/order.py index 6e5391c..7729d42 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -27,6 +27,7 @@ class Order(db.Model): stoptime = db.Column(db.DateTime) public = db.Column(db.Boolean, default=True) slug = db.Column(db.String(7), default=generate_slug, unique=True) + association = db.Column(db.String(120)) items = db.relationship("OrderItem", backref="order", lazy="dynamic") From 1c0d78f2eec787a5c70fa14f21644c31fb932fb3 Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Fri, 20 May 2022 22:46:56 +0200 Subject: [PATCH 3/8] Make sure only users with at least one association can create an order --- app/forms.py | 2 ++ .../versions/5c8378aa4dff_add_user_associations.py | 4 ++-- app/models/anonymous_user.py | 4 ++++ app/models/order.py | 2 +- app/models/user.py | 2 +- app/templates/orders.html | 5 +++++ app/views/order.py | 5 ++++- 7 files changed, 19 insertions(+), 5 deletions(-) diff --git a/app/forms.py b/app/forms.py index e259563..f847e96 100644 --- a/app/forms.py +++ b/app/forms.py @@ -24,6 +24,7 @@ class OrderForm(Form): "Starttime", default=datetime.now, format="%d-%m-%Y %H:%M" ) stoptime = DateTimeField("Stoptime", format="%d-%m-%Y %H:%M") + association = SelectField("Association", coerce=str, validators=[validators.required()]) submit_button = SubmitField("Submit") def populate(self) -> None: @@ -38,6 +39,7 @@ class OrderForm(Form): (current_user.id, current_user.username), ] self.location_id.choices = [(l.id, l.name) for l in location_definitions] + self.association.choices = current_user.association_list() if self.stoptime.data is None: self.stoptime.data = datetime.now() + timedelta(hours=1) diff --git a/app/migrations/versions/5c8378aa4dff_add_user_associations.py b/app/migrations/versions/5c8378aa4dff_add_user_associations.py index 4cc135d..24f52c7 100644 --- a/app/migrations/versions/5c8378aa4dff_add_user_associations.py +++ b/app/migrations/versions/5c8378aa4dff_add_user_associations.py @@ -16,8 +16,8 @@ import sqlalchemy as sa def upgrade(): # ### commands auto generated by Alembic - please adjust! ### - op.add_column('order', sa.Column('association', sa.String(length=120), nullable=True)) - op.add_column('user', sa.Column('associations', sa.String(length=120), nullable=True)) + op.add_column('order', sa.Column('association', sa.String(length=120), nullable=False, default="")) + op.add_column('user', sa.Column('associations', sa.String(length=120), nullable=False, default="")) # ### end Alembic commands ### diff --git a/app/models/anonymous_user.py b/app/models/anonymous_user.py index 2ae10f2..8e2532a 100644 --- a/app/models/anonymous_user.py +++ b/app/models/anonymous_user.py @@ -1,10 +1,14 @@ "AnonymouseUser for people who are not logged in the normal way" +from typing import List # pylint: disable=R0201,C0111 class AnonymouseUser: id = None + def association_list(self) -> List[str]: + return [] + def is_active(self) -> bool: return False diff --git a/app/models/order.py b/app/models/order.py index 7729d42..37407dd 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -27,7 +27,7 @@ class Order(db.Model): stoptime = db.Column(db.DateTime) public = db.Column(db.Boolean, default=True) slug = db.Column(db.String(7), default=generate_slug, unique=True) - association = db.Column(db.String(120)) + association = db.Column(db.String(120), nullable=False) items = db.relationship("OrderItem", backref="order", lazy="dynamic") diff --git a/app/models/user.py b/app/models/user.py index 13634bb..964ba42 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -11,7 +11,7 @@ class User(db.Model): admin = db.Column(db.Boolean) bias = db.Column(db.Integer) # Assocation logic - associations = db.Column(db.String(120)) + associations = db.Column(db.String(120), nullable=False) # Relations runs = db.relation( diff --git a/app/templates/orders.html b/app/templates/orders.html index e472461..35fa189 100644 --- a/app/templates/orders.html +++ b/app/templates/orders.html @@ -38,6 +38,11 @@ {{ form.location_id(class='form-control select') }} {{ util.render_form_field_errors(form.location_id) }} +
+ {{ form.association.label(class='control-label') }} + {{ form.association(class='form-control select') }} + {{ util.render_form_field_errors(form.association) }} +
{% if current_user.is_admin() %}
{{ form.starttime.label(class='control-label') }} diff --git a/app/views/order.py b/app/views/order.py index 8023ecf..e779c5a 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -21,7 +21,7 @@ order_bp = Blueprint("order_bp", "order") @order_bp.route("/") def orders(form: OrderForm = None) -> str: """Generate general order view""" - if form is None and not current_user.is_anonymous(): + if form is None and current_user.association_list(): form = OrderForm() location_id = request.args.get("location_id") form.location_id.default = location_id @@ -34,6 +34,9 @@ def orders(form: OrderForm = None) -> str: @login_required def order_create() -> typing.Union[str, Response]: """Generate order create view""" + if not current_user.association_list(): + flash("Not allowed to create an order.", "info") + abort(401) orderForm = OrderForm() orderForm.populate() if orderForm.validate_on_submit(): From a077a8038a1908a57e685a7384264821c5a1cea4 Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Fri, 20 May 2022 23:15:45 +0200 Subject: [PATCH 4/8] Only list orders to users of its association --- app/views/general.py | 8 +++++--- app/views/order.py | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/views/general.py b/app/views/general.py index 42753b6..9946fe6 100644 --- a/app/views/general.py +++ b/app/views/general.py @@ -9,7 +9,7 @@ from flask import Blueprint, Flask, abort from flask import current_app as app from flask import (jsonify, make_response, render_template, request, send_from_directory, url_for) -from flask_login import login_required +from flask_login import current_user, login_required from hlds.definitions import location_definitions from hlds.models import Location from models import Order @@ -31,10 +31,12 @@ def home() -> str: "Generate the home view" prev_day = datetime.now() - timedelta(days=1) recently_closed = get_orders( - (Order.stoptime > prev_day) & (Order.stoptime < datetime.now()) + (Order.stoptime > prev_day) & (Order.stoptime < datetime.now()) & Order.association.in_(current_user.association_list()) ) return render_template( - "home.html", orders=get_orders(), recently_closed=recently_closed + "home.html", orders=get_orders( + ((datetime.now() > Order.starttime) & (Order.stoptime > datetime.now()) | (Order.stoptime == None)) & Order.association.in_(current_user.association_list()) + ), recently_closed=recently_closed ) diff --git a/app/views/order.py b/app/views/order.py index e779c5a..dea851c 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -27,7 +27,7 @@ def orders(form: OrderForm = None) -> str: form.location_id.default = location_id form.process() form.populate() - return render_template("orders.html", orders=get_orders(), form=form) + return render_template("orders.html", orders=get_orders(expression=Order.association.in_(current_user.association_list())), form=form) @order_bp.route("/create", methods=["POST"]) From d6d9d61f27bb1e6a491ccc7a559c2ca617a39be0 Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Fri, 20 May 2022 23:21:11 +0200 Subject: [PATCH 5/8] Remove some unused code --- app/templates/layout.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/templates/layout.html b/app/templates/layout.html index 3ba9722..72b85b7 100644 --- a/app/templates/layout.html +++ b/app/templates/layout.html @@ -14,12 +14,6 @@ {% set navbar = navbar + [('admin.index', 'Admin')] -%} {% endif -%} -{% if not current_user.is_anonymous() -%} - {% for association in current_user.association_list() %} - {% set navbar = navbar + [('general_bp.home', association)] -%} - {% endfor -%} -{% endif -%} - {% set active_page = active_page|default('index') -%} {% block title %} From da1a708e28b7fb5329a88512fd7966a5a86ea52b Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Fri, 20 May 2022 23:29:05 +0200 Subject: [PATCH 6/8] List order association in admin view --- app/admin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/admin.py b/app/admin.py index 24b7d99..1845dee 100644 --- a/app/admin.py +++ b/app/admin.py @@ -28,11 +28,12 @@ class OrderAdminModel(ModelBaseView): "Class for the model of a OrderAdmin" # pylint: disable=too-few-public-methods column_default_sort = ("starttime", True) - column_list = ["starttime", "stoptime", "location_name", "location_id", "courier"] + column_list = ["starttime", "stoptime", "location_name", "location_id", "courier", "association"] column_labels = { "starttime": "Start Time", "stoptime": "Closing Time", "location_id": "HLDS Location ID", + "association": "Association", } form_excluded_columns = ["items", "courier_id"] can_delete = False From 4d9d43b0f010015cf68d7285c7ffa55d20ada1fb Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Tue, 24 May 2022 21:26:51 +0200 Subject: [PATCH 7/8] Don't limit length (and fix migration) --- ...ations.py => f6a6004bf4b9_add_user_associations.py} | 10 +++++----- app/models/order.py | 2 +- app/models/user.py | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) rename app/migrations/versions/{5c8378aa4dff_add_user_associations.py => f6a6004bf4b9_add_user_associations.py} (70%) diff --git a/app/migrations/versions/5c8378aa4dff_add_user_associations.py b/app/migrations/versions/f6a6004bf4b9_add_user_associations.py similarity index 70% rename from app/migrations/versions/5c8378aa4dff_add_user_associations.py rename to app/migrations/versions/f6a6004bf4b9_add_user_associations.py index 24f52c7..e084687 100644 --- a/app/migrations/versions/5c8378aa4dff_add_user_associations.py +++ b/app/migrations/versions/f6a6004bf4b9_add_user_associations.py @@ -1,13 +1,13 @@ """Add user associations -Revision ID: 5c8378aa4dff +Revision ID: f6a6004bf4b9 Revises: 55013fe95bea -Create Date: 2022-05-20 21:32:47.786340 +Create Date: 2022-05-24 21:23:27.770365 """ # revision identifiers, used by Alembic. -revision = '5c8378aa4dff' +revision = 'f6a6004bf4b9' down_revision = '55013fe95bea' from alembic import op @@ -16,8 +16,8 @@ import sqlalchemy as sa def upgrade(): # ### commands auto generated by Alembic - please adjust! ### - op.add_column('order', sa.Column('association', sa.String(length=120), nullable=False, default="")) - op.add_column('user', sa.Column('associations', sa.String(length=120), nullable=False, default="")) + op.add_column('order', sa.Column('association', sa.String(length=120), server_default='', nullable=False)) + op.add_column('user', sa.Column('associations', sa.String(), server_default='', nullable=False)) # ### end Alembic commands ### diff --git a/app/models/order.py b/app/models/order.py index 37407dd..c7b458e 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -27,7 +27,7 @@ class Order(db.Model): stoptime = db.Column(db.DateTime) public = db.Column(db.Boolean, default=True) slug = db.Column(db.String(7), default=generate_slug, unique=True) - association = db.Column(db.String(120), nullable=False) + association = db.Column(db.String(120), nullable=False, server_default="") items = db.relationship("OrderItem", backref="order", lazy="dynamic") diff --git a/app/models/user.py b/app/models/user.py index 964ba42..a45faeb 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -11,7 +11,7 @@ class User(db.Model): admin = db.Column(db.Boolean) bias = db.Column(db.Integer) # Assocation logic - associations = db.Column(db.String(120), nullable=False) + associations = db.Column(db.String(), nullable=False, server_default="") # Relations runs = db.relation( From c04d9bbd447509f451b8c8a475bc3aea6e39b925 Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Wed, 25 May 2022 10:07:30 +0200 Subject: [PATCH 8/8] Fix typing of associations in user model --- app/models/user.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/user.py b/app/models/user.py index a45faeb..6f6a372 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -1,5 +1,5 @@ "Script for everything User related in the database" -from typing import List +from typing import List, Optional from models import db @@ -25,7 +25,7 @@ class User(db.Model): def association_list(self) -> List[str]: return self.associations.split(",") - def configure(self, username: str, admin: bool, bias: int, associations: List[str] = None) -> None: + def configure(self, username: str, admin: bool, bias: int, associations: Optional[List[str]] = None) -> None: """Configure the User""" if associations is None: associations = []