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 flaschengeist import logger
from flaschengeist.config import config
from flaschengeist.controller import userController
from flaschengeist.models import User, Role
from flaschengeist.models.user import _Avatar
@ -18,8 +19,7 @@ from flaschengeist.plugins import AuthPlugin, before_role_updated
class AuthLDAP(AuthPlugin):
def __init__(self, entry_point, config):
super().__init__(entry_point, config)
def load(self):
app.config.update(
LDAP_SERVER=config.get("host", "localhost"),
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})")
self.__modify_role(role, new_name)
def login(self, user, password):
if not user:
def login(self, login_name, password):
if not login_name:
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):
attr = self.__find(userid, mail)
if attr is not None:
user = User(userid=attr["uid"][0])
self.__update(user, attr)
return user
def user_exists(self, userid) -> bool:
attr = self.__find(userid, None)
return attr is not None
def update_user(self, user):
attr = self.__find(user.userid)
self.__update(user, attr)
def create_user(self, user, password):
if self.root_dn is None:
logger.error("root_dn missing in ldap config!")
raise InternalServerError
def can_register(self):
return self.root_dn is not None
def create_user(self, user, password):
try:
ldap_conn = self.ldap.connect(self.root_dn, self.root_secret)
attributes = self.user_attributes.copy()

View File

@ -4,10 +4,10 @@ Extends users plugin with balance functions
"""
from flask import current_app
from werkzeug.local import LocalProxy
from werkzeug.exceptions import NotFound
from flaschengeist import logger
from flaschengeist.config import config
from flaschengeist.plugins import Plugin, plugins_loaded, before_update_user
from flaschengeist.plugins.scheduler import add_scheduled
@ -56,16 +56,13 @@ def service_debit():
class BalancePlugin(Plugin):
permissions = permissions.permissions
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):
super(BalancePlugin, self).__init__(entry_point, config)
def load(self):
from .routes import blueprint
self.blueprint = blueprint
@plugins_loaded

View File

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