From f03314efac0e45cb3f59c6a2d9a687347f8e3ab5 Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Thu, 15 Oct 2020 14:44:58 +0200 Subject: [PATCH] Split installation and app creation. Added Readme --- flaschengeist/app.py | 24 +++++--- flaschengeist/modules/__init__.py | 12 ++++ flaschengeist/modules/auth/__init__.py | 3 +- flaschengeist/modules/roles/__init__.py | 3 +- flaschengeist/modules/schedule/__init__.py | 3 +- flaschengeist/modules/users/__init__.py | 5 +- flaschengeist/readme.md | 68 ++++++++++++++++++++++ run_flaschengeist | 7 +-- 8 files changed, 108 insertions(+), 17 deletions(-) diff --git a/flaschengeist/app.py b/flaschengeist/app.py index d1cb5d7..c96c817 100644 --- a/flaschengeist/app.py +++ b/flaschengeist/app.py @@ -1,5 +1,5 @@ import pkg_resources -from flask import Flask +from flask import Flask, current_app from flask_cors import CORS from datetime import datetime from flask.json import JSONEncoder, jsonify @@ -48,14 +48,24 @@ def __load_plugins(app): app.config['FG_PLUGINS'] = {} for entry_point in pkg_resources.iter_entry_points('flaschengeist.plugin'): logger.debug("Found plugin: >{}<".format(entry_point.name)) + plugin = None if config.get(entry_point.name, 'enabled', fallback=False): - blueprint, permissions = entry_point.load()() - app.config["FG_PLUGINS"][entry_point.name] = True - app.register_blueprint(blueprint) - roleController.create_permissions(permissions.values()) + plugin = entry_point.load()() + app.register_blueprint(plugin.blueprint) logger.info("Loaded plugin >{}<".format(entry_point.name)) - else: - app.config["FG_PLUGINS"][entry_point.name] = False + app.config["FG_PLUGINS"][entry_point.name] = plugin + + +def install_all(): + from flaschengeist.system.database import db + from flaschengeist.system.models import user, event, accessToken + db.create_all() + db.session.commit() + for name, plugin in current_app.config["FG_PLUGINS"].items(): + logger.info("Install plugin {}".format(name)) + plugin.install() + if plugin.permissions: + roleController.create_permissions(plugin.permissions.values()) def create_app(): diff --git a/flaschengeist/modules/__init__.py b/flaschengeist/modules/__init__.py index 0cdd4bb..d33f1cd 100644 --- a/flaschengeist/modules/__init__.py +++ b/flaschengeist/modules/__init__.py @@ -1,3 +1,15 @@ +class Plugin: + def __init__(self, blueprint, permissions = {}): + self.blueprint = blueprint + self.permissions = permissions + + def install(self): + """ Installation routine + Is always called with Flask application context + """ + pass + + class Auth: def configure(self, config): pass diff --git a/flaschengeist/modules/auth/__init__.py b/flaschengeist/modules/auth/__init__.py index be0b688..ef93e97 100644 --- a/flaschengeist/modules/auth/__init__.py +++ b/flaschengeist/modules/auth/__init__.py @@ -9,6 +9,7 @@ from werkzeug.exceptions import Forbidden, BadRequest, Unauthorized from werkzeug.local import LocalProxy from flaschengeist import logger +from flaschengeist.modules import Plugin from flaschengeist.system.decorator import login_required from flaschengeist.system.controller import accessTokenController, userController @@ -18,7 +19,7 @@ auth_bp = Blueprint('auth', __name__) def register(): - return auth_bp, {} + return Plugin(auth_bp) ################################################# # Routes # diff --git a/flaschengeist/modules/roles/__init__.py b/flaschengeist/modules/roles/__init__.py index a011f7e..b29363f 100644 --- a/flaschengeist/modules/roles/__init__.py +++ b/flaschengeist/modules/roles/__init__.py @@ -1,6 +1,7 @@ from flask import Blueprint, request, jsonify from werkzeug.exceptions import NotFound, BadRequest, Forbidden +from flaschengeist.modules import Plugin from flaschengeist.system.decorator import login_required from flaschengeist.system.controller import roleController @@ -9,7 +10,7 @@ permissions = {} def register(): - return roles_bp, permissions + return Plugin(roles_bp, permissions) ###################################################### # Routes # diff --git a/flaschengeist/modules/schedule/__init__.py b/flaschengeist/modules/schedule/__init__.py index 4c8a72b..62bf9cd 100644 --- a/flaschengeist/modules/schedule/__init__.py +++ b/flaschengeist/modules/schedule/__init__.py @@ -3,6 +3,7 @@ from flask import Blueprint, request, jsonify from werkzeug.exceptions import BadRequest, NotFound from datetime import datetime, timedelta +from flaschengeist.modules import Plugin from flaschengeist.system.controller import eventController from flaschengeist.system.database import db from flaschengeist.system.decorator import login_required @@ -13,7 +14,7 @@ permissions = {} def register(): - return schedule_bp, permissions + return Plugin(schedule_bp, permissions) #################################################################################### diff --git a/flaschengeist/modules/users/__init__.py b/flaschengeist/modules/users/__init__.py index c1ac277..d440750 100644 --- a/flaschengeist/modules/users/__init__.py +++ b/flaschengeist/modules/users/__init__.py @@ -2,15 +2,16 @@ from flask import Blueprint, request, jsonify from werkzeug.exceptions import NotFound, BadRequest, Forbidden from flaschengeist import logger +from flaschengeist.modules import Plugin from flaschengeist.system.decorator import login_required from flaschengeist.system.controller import userController users_bp = Blueprint("users", __name__) - permissions = {'EDIT_USER': 'edit_user'} + def register(): - return users_bp, permissions + return Plugin(users_bp, permissions) ################################################# # Routes # diff --git a/flaschengeist/readme.md b/flaschengeist/readme.md index 901d488..395a49b 100644 --- a/flaschengeist/readme.md +++ b/flaschengeist/readme.md @@ -27,3 +27,71 @@ or with ldap support or with debug messages: run_flaschengeist --debug + +## Plugin Development +### File Structure + flaschengeist-example-plugin + |> __init__.py + |> model.py + |> setup.py + +### Files +#### \_\_init\_\_.py + from flask import Blueprint + from flaschengeist.modules import Plugin + + + example_bp = Blueprint("example", __name__, url_prefix="/example") + permissions = {"EXAMPLE_HELLO": "example_hello"} + + + def register(): + # If no model is needed: + # return Plugin(schedule_bp, permissions) + # else if model is used: + class ExamplePlugin(Plugin): + def install(self): + from flaschengeist.system.database import db + import .model + db.create_all() + db.session.commit() + + return ExamplePlugin(schedule_bp, permissions) + + + + @schedule_bp.route("/hello", methods=['GET']) + @login_required(roles=['example_hello']) + def __hello(id, **kwargs): + return "Hello" + +#### model.py +Optional, only needed if you need your own models (database) + + from flaschengeist.system.database import db + + model_name = __name__ + + + class ExampleModel(db.Model): + """Example Model""" + __tablename__ = 'example' + id = db.Column(db.Integer, primary_key=True) + description = db.Column(db.String(240)) + +#### setup.py + from setuptools import setup, find_packages + + setup( + name="flaschengeist-example-plugin", + version="0.0.0-dev", + packages=find_packages(), + install_requires=[ + "flaschengeist >= 2", + ], + entry_points={ + "flaschengeist.plugin": [ + "example = flaschengeist-example-plugin:register" "roles = flaschengeist.modules.roles:register", + ] + }, + ) diff --git a/run_flaschengeist b/run_flaschengeist index b48c5c8..d69c3f5 100644 --- a/run_flaschengeist +++ b/run_flaschengeist @@ -1,5 +1,5 @@ #!/usr/bin/python3 -from flaschengeist.app import create_app +from flaschengeist.app import create_app, install_all import bjoern import argparse @@ -15,10 +15,7 @@ if __name__ == '__main__': app = create_app() if args.install: with app.app_context(): - from flaschengeist.system.models import * - from flaschengeist.system.database import db - db.create_all() - db.session.commit() + install_all() else: if args.debug: app.run(args.host, args.port, debug=True)