feature/migrations, closes #19 #20

Merged
crimsen merged 28 commits from feature/migrations into develop 2023-03-02 05:37:11 +00:00
4 changed files with 57 additions and 68 deletions
Showing only changes of commit 9f729bda6c - Show all commits

View File

@ -11,6 +11,7 @@ from werkzeug.exceptions import BadRequest, InternalServerError, NotFound
from werkzeug.datastructures import FileStorage from werkzeug.datastructures import FileStorage
from flaschengeist import logger from flaschengeist import logger
from flaschengeist.config import config
from flaschengeist.controller import userController from flaschengeist.controller import userController
from flaschengeist.models import User, Role from flaschengeist.models import User, Role
from flaschengeist.models.user import _Avatar from flaschengeist.models.user import _Avatar
@ -18,8 +19,7 @@ from flaschengeist.plugins import AuthPlugin, before_role_updated
class AuthLDAP(AuthPlugin): class AuthLDAP(AuthPlugin):
def __init__(self, entry_point, config): def load(self):
super().__init__(entry_point, config)
app.config.update( app.config.update(
LDAP_SERVER=config.get("host", "localhost"), LDAP_SERVER=config.get("host", "localhost"),
LDAP_PORT=config.get("port", 389), LDAP_PORT=config.get("port", 389),
@ -54,27 +54,23 @@ class AuthLDAP(AuthPlugin):
logger.debug(f"LDAP: before_role_updated called with ({role}, {new_name})") logger.debug(f"LDAP: before_role_updated called with ({role}, {new_name})")
self.__modify_role(role, new_name) self.__modify_role(role, new_name)
def login(self, user, password): def login(self, login_name, password):
if not user: if not login_name:
return False return False
return self.ldap.authenticate(user.userid, password, "uid", self.base_dn) return self.ldap.authenticate(login_name, password, "uid", self.base_dn)
def find_user(self, userid, mail=None): def user_exists(self, userid) -> bool:
attr = self.__find(userid, mail) attr = self.__find(userid, None)
if attr is not None: return attr is not None
user = User(userid=attr["uid"][0])
self.__update(user, attr)
return user
def update_user(self, user): def update_user(self, user):
attr = self.__find(user.userid) attr = self.__find(user.userid)
self.__update(user, attr) self.__update(user, attr)
def create_user(self, user, password): def can_register(self):
if self.root_dn is None: return self.root_dn is not None
logger.error("root_dn missing in ldap config!")
raise InternalServerError
def create_user(self, user, password):
try: try:
ldap_conn = self.ldap.connect(self.root_dn, self.root_secret) ldap_conn = self.ldap.connect(self.root_dn, self.root_secret)
attributes = self.user_attributes.copy() attributes = self.user_attributes.copy()

View File

@ -4,10 +4,10 @@ Extends users plugin with balance functions
""" """
from flask import current_app from flask import current_app
from werkzeug.local import LocalProxy
from werkzeug.exceptions import NotFound from werkzeug.exceptions import NotFound
from flaschengeist import logger from flaschengeist import logger
from flaschengeist.config import config
from flaschengeist.plugins import Plugin, plugins_loaded, before_update_user from flaschengeist.plugins import Plugin, plugins_loaded, before_update_user
from flaschengeist.plugins.scheduler import add_scheduled from flaschengeist.plugins.scheduler import add_scheduled
@ -56,16 +56,13 @@ def service_debit():
class BalancePlugin(Plugin): class BalancePlugin(Plugin):
permissions = permissions.permissions
models = models models = models
migrations = True
plugin: "BalancePlugin" = LocalProxy(lambda: current_app.config["FG_PLUGINS"][BalancePlugin.name]) def install(self):
self.install_permissions(permissions.permissions)
def __init__(self, entry_point, config): def load(self):
super(BalancePlugin, self).__init__(entry_point, config)
from .routes import blueprint from .routes import blueprint
self.blueprint = blueprint self.blueprint = blueprint
@plugins_loaded @plugins_loaded

View File

@ -1,39 +1,32 @@
"""Pricelist plugin""" """Pricelist plugin"""
from flask import Blueprint, jsonify, request
import pathlib
from flask import Blueprint, jsonify, request, current_app
from werkzeug.local import LocalProxy
from werkzeug.exceptions import BadRequest, Forbidden, NotFound, Unauthorized from werkzeug.exceptions import BadRequest, Forbidden, NotFound, Unauthorized
from flaschengeist import logger from flaschengeist import logger
from flaschengeist.controller import userController from flaschengeist.controller import userController
from flaschengeist.controller.imageController import send_image, send_thumbnail from flaschengeist.controller.imageController import send_image, send_thumbnail
from flaschengeist.plugins import Plugin from flaschengeist.plugins import Plugin
from flaschengeist.utils.decorators import login_required, extract_session, headers from flaschengeist.utils.decorators import login_required, extract_session
from flaschengeist.utils.HTTP import no_content from flaschengeist.utils.HTTP import no_content
from . import models from . import models
from . import pricelist_controller, permissions from . import pricelist_controller, permissions
class PriceListPlugin(Plugin):
models = models
blueprint = Blueprint("pricelist", __name__, url_prefix="/pricelist") blueprint = Blueprint("pricelist", __name__, url_prefix="/pricelist")
def install(self):
self.install_permissions(permissions.permissions)
class PriceListPlugin(Plugin): def load(self):
permissions = permissions.permissions
plugin = LocalProxy(lambda: current_app.config["FG_PLUGINS"][PriceListPlugin.name])
models = models
def __init__(self, entry_point, config=None):
super().__init__(entry_point, config)
self.blueprint = blueprint
self.migrations_path = (pathlib.Path(__file__).parent / "migrations").resolve()
config = {"discount": 0} config = {"discount": 0}
config.update(config) config.update(config)
@blueprint.route("/drink-types", methods=["GET"]) @PriceListPlugin.blueprint.route("/drink-types", methods=["GET"])
@blueprint.route("/drink-types/<int:identifier>", methods=["GET"]) @PriceListPlugin.blueprint.route("/drink-types/<int:identifier>", methods=["GET"])
def get_drink_types(identifier=None): def get_drink_types(identifier=None):
"""Get DrinkType(s) """Get DrinkType(s)
@ -53,7 +46,7 @@ def get_drink_types(identifier=None):
return jsonify(result) return jsonify(result)
@blueprint.route("/drink-types", methods=["POST"]) @PriceListPlugin.blueprint.route("/drink-types", methods=["POST"])
@login_required(permission=permissions.CREATE_TYPE) @login_required(permission=permissions.CREATE_TYPE)
def new_drink_type(current_session): def new_drink_type(current_session):
"""Create new DrinkType """Create new DrinkType
@ -75,7 +68,7 @@ def new_drink_type(current_session):
return jsonify(drink_type) return jsonify(drink_type)
@blueprint.route("/drink-types/<int:identifier>", methods=["PUT"]) @PriceListPlugin.blueprint.route("/drink-types/<int:identifier>", methods=["PUT"])
@login_required(permission=permissions.EDIT_TYPE) @login_required(permission=permissions.EDIT_TYPE)
def update_drink_type(identifier, current_session): def update_drink_type(identifier, current_session):
"""Modify DrinkType """Modify DrinkType
@ -98,7 +91,7 @@ def update_drink_type(identifier, current_session):
return jsonify(drink_type) return jsonify(drink_type)
@blueprint.route("/drink-types/<int:identifier>", methods=["DELETE"]) @PriceListPlugin.blueprint.route("/drink-types/<int:identifier>", methods=["DELETE"])
@login_required(permission=permissions.DELETE_TYPE) @login_required(permission=permissions.DELETE_TYPE)
def delete_drink_type(identifier, current_session): def delete_drink_type(identifier, current_session):
"""Delete DrinkType """Delete DrinkType
@ -116,8 +109,8 @@ def delete_drink_type(identifier, current_session):
return no_content() return no_content()
@blueprint.route("/tags", methods=["GET"]) @PriceListPlugin.blueprint.route("/tags", methods=["GET"])
@blueprint.route("/tags/<int:identifier>", methods=["GET"]) @PriceListPlugin.blueprint.route("/tags/<int:identifier>", methods=["GET"])
def get_tags(identifier=None): def get_tags(identifier=None):
"""Get Tag(s) """Get Tag(s)
@ -137,7 +130,7 @@ def get_tags(identifier=None):
return jsonify(result) return jsonify(result)
@blueprint.route("/tags", methods=["POST"]) @PriceListPlugin.blueprint.route("/tags", methods=["POST"])
@login_required(permission=permissions.CREATE_TAG) @login_required(permission=permissions.CREATE_TAG)
def new_tag(current_session): def new_tag(current_session):
"""Create Tag """Create Tag
@ -157,7 +150,7 @@ def new_tag(current_session):
return jsonify(drink_type) return jsonify(drink_type)
@blueprint.route("/tags/<int:identifier>", methods=["PUT"]) @PriceListPlugin.blueprint.route("/tags/<int:identifier>", methods=["PUT"])
@login_required(permission=permissions.EDIT_TAG) @login_required(permission=permissions.EDIT_TAG)
def update_tag(identifier, current_session): def update_tag(identifier, current_session):
"""Modify Tag """Modify Tag
@ -178,7 +171,7 @@ def update_tag(identifier, current_session):
return jsonify(tag) return jsonify(tag)
@blueprint.route("/tags/<int:identifier>", methods=["DELETE"]) @PriceListPlugin.blueprint.route("/tags/<int:identifier>", methods=["DELETE"])
@login_required(permission=permissions.DELETE_TAG) @login_required(permission=permissions.DELETE_TAG)
def delete_tag(identifier, current_session): def delete_tag(identifier, current_session):
"""Delete Tag """Delete Tag
@ -196,8 +189,8 @@ def delete_tag(identifier, current_session):
return no_content() return no_content()
@blueprint.route("/drinks", methods=["GET"]) @PriceListPlugin.blueprint.route("/drinks", methods=["GET"])
@blueprint.route("/drinks/<int:identifier>", methods=["GET"]) @PriceListPlugin.blueprint.route("/drinks/<int:identifier>", methods=["GET"])
def get_drinks(identifier=None): def get_drinks(identifier=None):
"""Get Drink(s) """Get Drink(s)
@ -253,7 +246,7 @@ def get_drinks(identifier=None):
return jsonify({"drinks": drinks, "count": count}) return jsonify({"drinks": drinks, "count": count})
@blueprint.route("/list", methods=["GET"]) @PriceListPlugin.blueprint.route("/list", methods=["GET"])
def get_pricelist(): def get_pricelist():
"""Get Priclist """Get Priclist
Route: ``/pricelist/list`` | Method: ``GET`` Route: ``/pricelist/list`` | Method: ``GET``
@ -302,7 +295,7 @@ def get_pricelist():
return jsonify({"pricelist": pricelist, "count": count}) return jsonify({"pricelist": pricelist, "count": count})
@blueprint.route("/drinks/search/<string:name>", methods=["GET"]) @PriceListPlugin.blueprint.route("/drinks/search/<string:name>", methods=["GET"])
def search_drinks(name): def search_drinks(name):
"""Search Drink """Search Drink
@ -323,7 +316,7 @@ def search_drinks(name):
return jsonify(pricelist_controller.get_drinks(name, public=public)) return jsonify(pricelist_controller.get_drinks(name, public=public))
@blueprint.route("/drinks", methods=["POST"]) @PriceListPlugin.blueprint.route("/drinks", methods=["POST"])
@login_required(permission=permissions.CREATE) @login_required(permission=permissions.CREATE)
def create_drink(current_session): def create_drink(current_session):
"""Create Drink """Create Drink
@ -375,7 +368,7 @@ def create_drink(current_session):
return jsonify(pricelist_controller.set_drink(data)) return jsonify(pricelist_controller.set_drink(data))
@blueprint.route("/drinks/<int:identifier>", methods=["PUT"]) @PriceListPlugin.blueprint.route("/drinks/<int:identifier>", methods=["PUT"])
@login_required(permission=permissions.EDIT) @login_required(permission=permissions.EDIT)
def update_drink(identifier, current_session): def update_drink(identifier, current_session):
"""Modify Drink """Modify Drink
@ -429,7 +422,7 @@ def update_drink(identifier, current_session):
return jsonify(pricelist_controller.update_drink(identifier, data)) return jsonify(pricelist_controller.update_drink(identifier, data))
@blueprint.route("/drinks/<int:identifier>", methods=["DELETE"]) @PriceListPlugin.blueprint.route("/drinks/<int:identifier>", methods=["DELETE"])
@login_required(permission=permissions.DELETE) @login_required(permission=permissions.DELETE)
def delete_drink(identifier, current_session): def delete_drink(identifier, current_session):
"""Delete Drink """Delete Drink
@ -447,7 +440,7 @@ def delete_drink(identifier, current_session):
return no_content() return no_content()
@blueprint.route("/prices/<int:identifier>", methods=["DELETE"]) @PriceListPlugin.blueprint.route("/prices/<int:identifier>", methods=["DELETE"])
@login_required(permission=permissions.DELETE_PRICE) @login_required(permission=permissions.DELETE_PRICE)
def delete_price(identifier, current_session): def delete_price(identifier, current_session):
"""Delete Price """Delete Price
@ -465,7 +458,7 @@ def delete_price(identifier, current_session):
return no_content() return no_content()
@blueprint.route("/volumes/<int:identifier>", methods=["DELETE"]) @PriceListPlugin.blueprint.route("/volumes/<int:identifier>", methods=["DELETE"])
@login_required(permission=permissions.DELETE_VOLUME) @login_required(permission=permissions.DELETE_VOLUME)
def delete_volume(identifier, current_session): def delete_volume(identifier, current_session):
"""Delete DrinkPriceVolume """Delete DrinkPriceVolume
@ -483,7 +476,7 @@ def delete_volume(identifier, current_session):
return no_content() return no_content()
@blueprint.route("/ingredients/extraIngredients", methods=["GET"]) @PriceListPlugin.blueprint.route("/ingredients/extraIngredients", methods=["GET"])
@login_required() @login_required()
def get_extra_ingredients(current_session): def get_extra_ingredients(current_session):
"""Get ExtraIngredients """Get ExtraIngredients
@ -499,7 +492,7 @@ def get_extra_ingredients(current_session):
return jsonify(pricelist_controller.get_extra_ingredients()) return jsonify(pricelist_controller.get_extra_ingredients())
@blueprint.route("/ingredients/<int:identifier>", methods=["DELETE"]) @PriceListPlugin.blueprint.route("/ingredients/<int:identifier>", methods=["DELETE"])
@login_required(permission=permissions.DELETE_INGREDIENTS_DRINK) @login_required(permission=permissions.DELETE_INGREDIENTS_DRINK)
def delete_ingredient(identifier, current_session): def delete_ingredient(identifier, current_session):
"""Delete Ingredient """Delete Ingredient
@ -517,7 +510,7 @@ def delete_ingredient(identifier, current_session):
return no_content() return no_content()
@blueprint.route("/ingredients/extraIngredients", methods=["POST"]) @PriceListPlugin.blueprint.route("/ingredients/extraIngredients", methods=["POST"])
@login_required(permission=permissions.EDIT_INGREDIENTS) @login_required(permission=permissions.EDIT_INGREDIENTS)
def set_extra_ingredient(current_session): def set_extra_ingredient(current_session):
"""Create ExtraIngredient """Create ExtraIngredient
@ -536,7 +529,7 @@ def set_extra_ingredient(current_session):
return jsonify(pricelist_controller.set_extra_ingredient(data)) return jsonify(pricelist_controller.set_extra_ingredient(data))
@blueprint.route("/ingredients/extraIngredients/<int:identifier>", methods=["PUT"]) @PriceListPlugin.blueprint.route("/ingredients/extraIngredients/<int:identifier>", methods=["PUT"])
@login_required(permission=permissions.EDIT_INGREDIENTS) @login_required(permission=permissions.EDIT_INGREDIENTS)
def update_extra_ingredient(identifier, current_session): def update_extra_ingredient(identifier, current_session):
"""Modify ExtraIngredient """Modify ExtraIngredient
@ -556,7 +549,7 @@ def update_extra_ingredient(identifier, current_session):
return jsonify(pricelist_controller.update_extra_ingredient(identifier, data)) return jsonify(pricelist_controller.update_extra_ingredient(identifier, data))
@blueprint.route("/ingredients/extraIngredients/<int:identifier>", methods=["DELETE"]) @PriceListPlugin.blueprint.route("/ingredients/extraIngredients/<int:identifier>", methods=["DELETE"])
@login_required(permission=permissions.DELETE_INGREDIENTS) @login_required(permission=permissions.DELETE_INGREDIENTS)
def delete_extra_ingredient(identifier, current_session): def delete_extra_ingredient(identifier, current_session):
"""Delete ExtraIngredient """Delete ExtraIngredient
@ -574,7 +567,7 @@ def delete_extra_ingredient(identifier, current_session):
return no_content() return no_content()
@blueprint.route("/settings/min_prices", methods=["GET"]) @PriceListPlugin.blueprint.route("/settings/min_prices", methods=["GET"])
@login_required() @login_required()
def get_pricelist_settings_min_prices(current_session): def get_pricelist_settings_min_prices(current_session):
"""Get MinPrices """Get MinPrices
@ -595,7 +588,7 @@ def get_pricelist_settings_min_prices(current_session):
return jsonify(min_prices) return jsonify(min_prices)
@blueprint.route("/settings/min_prices", methods=["POST"]) @PriceListPlugin.blueprint.route("/settings/min_prices", methods=["POST"])
@login_required(permission=permissions.EDIT_MIN_PRICES) @login_required(permission=permissions.EDIT_MIN_PRICES)
def post_pricelist_settings_min_prices(current_session): def post_pricelist_settings_min_prices(current_session):
"""Create MinPrices """Create MinPrices
@ -618,7 +611,7 @@ def post_pricelist_settings_min_prices(current_session):
return no_content() return no_content()
@blueprint.route("/users/<userid>/pricecalc_columns", methods=["GET", "PUT"]) @PriceListPlugin.blueprint.route("/users/<userid>/pricecalc_columns", methods=["GET", "PUT"])
@login_required() @login_required()
def get_columns(userid, current_session): def get_columns(userid, current_session):
"""Get pricecalc_columns of an user """Get pricecalc_columns of an user
@ -650,7 +643,7 @@ def get_columns(userid, current_session):
return no_content() return no_content()
@blueprint.route("/users/<userid>/pricecalc_columns_order", methods=["GET", "PUT"]) @PriceListPlugin.blueprint.route("/users/<userid>/pricecalc_columns_order", methods=["GET", "PUT"])
@login_required() @login_required()
def get_columns_order(userid, current_session): def get_columns_order(userid, current_session):
"""Get pricecalc_columns_order of an user """Get pricecalc_columns_order of an user
@ -681,7 +674,7 @@ def get_columns_order(userid, current_session):
return no_content() return no_content()
@blueprint.route("/users/<userid>/pricelist", methods=["GET", "PUT"]) @PriceListPlugin.blueprint.route("/users/<userid>/pricelist", methods=["GET", "PUT"])
@login_required() @login_required()
def get_priclist_setting(userid, current_session): def get_priclist_setting(userid, current_session):
"""Get pricelistsetting of an user """Get pricelistsetting of an user
@ -714,7 +707,7 @@ def get_priclist_setting(userid, current_session):
return no_content() return no_content()
@blueprint.route("/drinks/<int:identifier>/picture", methods=["POST", "DELETE"]) @PriceListPlugin.blueprint.route("/drinks/<int:identifier>/picture", methods=["POST", "DELETE"])
@login_required(permission=permissions.EDIT) @login_required(permission=permissions.EDIT)
def set_picture(identifier, current_session): def set_picture(identifier, current_session):
"""Get, Create, Delete Drink Picture """Get, Create, Delete Drink Picture
@ -741,7 +734,7 @@ def set_picture(identifier, current_session):
raise BadRequest raise BadRequest
@blueprint.route("/drinks/<int:identifier>/picture", methods=["GET"]) @PriceListPlugin.blueprint.route("/drinks/<int:identifier>/picture", methods=["GET"])
# @headers({"Cache-Control": "private, must-revalidate"}) # @headers({"Cache-Control": "private, must-revalidate"})
def _get_picture(identifier): def _get_picture(identifier):
"""Get Picture """Get Picture

View File

@ -1,8 +1,11 @@
from __future__ import annotations # TODO: Remove if python requirement is >= 3.12 (? PEP 563 is defered)
from typing import Optional
from flaschengeist.database import db from flaschengeist.database import db
from flaschengeist.database.types import ModelSerializeMixin, Serial from flaschengeist.database.types import ModelSerializeMixin, Serial
from flaschengeist.models import Image from flaschengeist.models import Image
from typing import Optional
drink_tag_association = db.Table( drink_tag_association = db.Table(
"drink_x_tag", "drink_x_tag",