Added more examples for splitted metadata
This commit is contained in:
		
							parent
							
								
									e4c552af01
								
							
						
					
					
						commit
						ccb1f9b005
					
				|  | @ -0,0 +1,82 @@ | ||||||
|  | # Example on Plugin Development | ||||||
|  | 
 | ||||||
|  | ## File Structure | ||||||
|  | ``` | ||||||
|  | - root | ||||||
|  |   - flaschengeist_example | ||||||
|  |     - __init__.py | ||||||
|  |     - plugin.py | ||||||
|  |     [- migrations] | ||||||
|  |   - setup.cfg | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | In a minimal example, you would only need two python source files and | ||||||
|  | your setup configuration. | ||||||
|  | If you also use custom database tables, you would also need a directory | ||||||
|  | containing your _alembic_-migration files. | ||||||
|  | 
 | ||||||
|  | ## Source code | ||||||
|  | Code is seperated in two locations, the meta data of your plugin goes into the `__init__.py` and all logic goes into the `plugin.py`, of cause you could add more files, but make sure to not depend on some external packages in the `__init__.py`. | ||||||
|  | 
 | ||||||
|  | ### Project data / setuptools | ||||||
|  | For **Flaschengeist** to find your plugin, you have to | ||||||
|  | install it corretly, especially the entry points have to be set. | ||||||
|  | ```ini | ||||||
|  | [metadata] | ||||||
|  | license = MIT | ||||||
|  | version = 1.0.0 | ||||||
|  | name = flaschengeist-example | ||||||
|  | description = Example plugin for Flaschengeist | ||||||
|  | # ... | ||||||
|  | 
 | ||||||
|  | [options] | ||||||
|  | packages = | ||||||
|  |     flaschengeist_example | ||||||
|  | install_requires = | ||||||
|  |     flaschengeist == 2.0.* | ||||||
|  | 
 | ||||||
|  | [options.entry_points] | ||||||
|  |     # Path to your meta data instance | ||||||
|  |     flaschengeist.plugins = | ||||||
|  |         example = flaschengeist_example:plugin | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ### Metadata | ||||||
|  | The `__init__.py` contains the plugin meta data. | ||||||
|  | 
 | ||||||
|  | ```python | ||||||
|  | # __init__.py | ||||||
|  | from flaschengeist.plugins import PluginMetadata | ||||||
|  | plugin = PluginMetadata( | ||||||
|  |     id="com.example.plugin", # unique, recommend FQN | ||||||
|  |     name="Example Plugin", # Human readable name | ||||||
|  |     version="1.0.0", # Optional | ||||||
|  |     module="flaschengeist_example.plugin.ExamplePlugin" # module and class of your plugin | ||||||
|  | ) | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | `version` is optional, if not provided the version of your distribution (set in setup.cfg) is used. | ||||||
|  | 
 | ||||||
|  | ### Implementation | ||||||
|  | You plugin implementation goes into the `plugin.py`. | ||||||
|  | Here you define your Plugin class, make sure it inheritates from `flaschengeist.plugins.Plugin` or `flaschengeist.plugins.AuthPlugin` respectivly. | ||||||
|  | 
 | ||||||
|  | It will get initalized with the meta data you defined in the `__init__.py` and the configuration object. | ||||||
|  | 
 | ||||||
|  | ```python | ||||||
|  | from flaschengeist.plugins import Plugin | ||||||
|  | from flask import Blueprint | ||||||
|  | 
 | ||||||
|  | bp = Blueprint(...) | ||||||
|  | 
 | ||||||
|  | class ExamplePlugin(Plugin): | ||||||
|  |     blueprint = bp | ||||||
|  |     ... | ||||||
|  | 
 | ||||||
|  | @bp.route("/example") | ||||||
|  | def get_example(): | ||||||
|  |     ... | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | @ -68,19 +68,6 @@ class PluginMetadata: | ||||||
|     If not provided the version will be set to the |     If not provided the version will be set to the | ||||||
|     distribution version of the package providing the module""" |     distribution version of the package providing the module""" | ||||||
| 
 | 
 | ||||||
|     blueprint: Blueprint = None |  | ||||||
|     """Override with a `flask.blueprint` if the plugin uses custom routes""" |  | ||||||
| 
 |  | ||||||
|     permissions: list[str] = field(default_factory=list) |  | ||||||
|     """Override to add custom permissions used by the plugin |  | ||||||
|      |  | ||||||
|     A good style is to name the permissions with a prefix related to the plugin name, |  | ||||||
|     to prevent clashes with other plugins. E. g. instead of *delete* use *plugin_delete*. |  | ||||||
|     """ |  | ||||||
| 
 |  | ||||||
|     models = None  # You have to override |  | ||||||
|     """Override with models module""" |  | ||||||
| 
 |  | ||||||
|     migrations_path = None  # Override this with the location of your db migrations directory |     migrations_path = None  # Override this with the location of your db migrations directory | ||||||
|     """Override with path to migration files, if custome db tables are used""" |     """Override with path to migration files, if custome db tables are used""" | ||||||
| 
 | 
 | ||||||
|  | @ -102,7 +89,29 @@ class PluginMetadata: | ||||||
| 
 | 
 | ||||||
| class Plugin(PluginMetadata): | class Plugin(PluginMetadata): | ||||||
|     """Base class for all Plugins |     """Base class for all Plugins | ||||||
|     If your class uses custom models add a static property called ``models``""" | 
 | ||||||
|  |     All plugins must interitate from this class for adding their logic. | ||||||
|  |     This class gets filled with the meta data of the plugin automatically. | ||||||
|  | 
 | ||||||
|  |     Additionally the `flask.Blueprint` can be added for API routes. | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     blueprint: Blueprint = None | ||||||
|  |     """Override with a `flask.blueprint` if the plugin uses custom routes""" | ||||||
|  | 
 | ||||||
|  |     models = None | ||||||
|  |     """Module with all custom sqlalchemy models | ||||||
|  |      | ||||||
|  |     Override this with the module containing all your sqlalchemy models module | ||||||
|  |     to enable the `flaschengeist` tool to generate TS API. | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     permissions: list[str] = [] | ||||||
|  |     """Override to add custom permissions used by the plugin | ||||||
|  |      | ||||||
|  |     A good style is to name the permissions with a prefix related to the plugin name, | ||||||
|  |     to prevent clashes with other plugins. E. g. instead of *delete* use *plugin_delete*. | ||||||
|  |     """ | ||||||
| 
 | 
 | ||||||
|     def __init__(self, metadata: PluginMetadata, config=None): |     def __init__(self, metadata: PluginMetadata, config=None): | ||||||
|         """Constructor called by create_app |         """Constructor called by create_app | ||||||
|  |  | ||||||
|  | @ -1,177 +1,7 @@ | ||||||
| """Authentication plugin, provides basic routes | from flaschengeist.plugins import PluginMetadata | ||||||
| 
 | 
 | ||||||
| Allow management of authentication, login, logout, etc. | plugin = PluginMetadata( | ||||||
| """ |     id = "auth", | ||||||
| from flask import Blueprint, request, jsonify |     name="auth", | ||||||
| from werkzeug.exceptions import Forbidden, BadRequest, Unauthorized |     module=__name__ + ".plugin.AuthPlugin" | ||||||
| 
 | ) | ||||||
| from flaschengeist import logger |  | ||||||
| from flaschengeist.plugins import Plugin |  | ||||||
| from flaschengeist.utils.HTTP import no_content, created |  | ||||||
| from flaschengeist.utils.decorators import login_required |  | ||||||
| from flaschengeist.controller import sessionController, userController |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class AuthRoutePlugin(Plugin): |  | ||||||
|     name = "auth" |  | ||||||
|     blueprint = Blueprint(name, __name__) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @AuthRoutePlugin.blueprint.route("/auth", methods=["POST"]) |  | ||||||
| def login(): |  | ||||||
|     """Login in an user and create a session |  | ||||||
| 
 |  | ||||||
|     Route: ``/auth`` | Method: ``POST`` |  | ||||||
| 
 |  | ||||||
|     POST-data: ``{userid: string, password: string}`` |  | ||||||
| 
 |  | ||||||
|     Returns: |  | ||||||
|         A JSON object with `flaschengeist.models.user.User` and created |  | ||||||
|         `flaschengeist.models.session.Session` or HTTP error |  | ||||||
|     """ |  | ||||||
|     logger.debug("Start log in.") |  | ||||||
|     data = request.get_json() |  | ||||||
|     try: |  | ||||||
|         userid = str(data["userid"]) |  | ||||||
|         password = str(data["password"]) |  | ||||||
|     except (KeyError, ValueError, TypeError): |  | ||||||
|         raise BadRequest("Missing parameter(s)") |  | ||||||
| 
 |  | ||||||
|     logger.debug(f"search user {userid} in database") |  | ||||||
|     user = userController.login_user(userid, password) |  | ||||||
|     if not user: |  | ||||||
|         raise Unauthorized |  | ||||||
|     session = sessionController.create(user, user_agent=request.user_agent) |  | ||||||
|     logger.debug(f"token is {session.token}") |  | ||||||
|     logger.info(f"User {userid} logged in.") |  | ||||||
| 
 |  | ||||||
|     # Lets cleanup the DB |  | ||||||
|     sessionController.clear_expired() |  | ||||||
|     return created(session) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @AuthRoutePlugin.blueprint.route("/auth", methods=["GET"]) |  | ||||||
| @login_required() |  | ||||||
| def get_sessions(current_session, **kwargs): |  | ||||||
|     """Get all valid sessions of current user |  | ||||||
| 
 |  | ||||||
|     Route: ``/auth`` | Method: ``GET`` |  | ||||||
| 
 |  | ||||||
|     Returns: |  | ||||||
|         A JSON array of `flaschengeist.models.session.Session` or HTTP error |  | ||||||
|     """ |  | ||||||
|     sessions = sessionController.get_users_sessions(current_session.user_) |  | ||||||
|     return jsonify(sessions) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @AuthRoutePlugin.blueprint.route("/auth/<token>", methods=["DELETE"]) |  | ||||||
| @login_required() |  | ||||||
| def delete_session(token, current_session, **kwargs): |  | ||||||
|     """Delete a session aka "logout" |  | ||||||
| 
 |  | ||||||
|     Route: ``/auth/<token>`` | Method: ``DELETE`` |  | ||||||
| 
 |  | ||||||
|     Returns: |  | ||||||
|             200 Status (empty) or HTTP error |  | ||||||
|     """ |  | ||||||
|     logger.debug("Try to delete access token {{ {} }}".format(token)) |  | ||||||
|     session = sessionController.get_session(token, current_session.user_) |  | ||||||
|     if not session: |  | ||||||
|         logger.debug("Token not found in database!") |  | ||||||
|         # Return 403 error, so that users can not bruteforce tokens |  | ||||||
|         # Valid tokens from other users and invalid tokens now are looking the same |  | ||||||
|         raise Forbidden |  | ||||||
|     sessionController.delete_session(session) |  | ||||||
|     sessionController.clear_expired() |  | ||||||
|     return "" |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @AuthRoutePlugin.blueprint.route("/auth/<token>", methods=["GET"]) |  | ||||||
| @login_required() |  | ||||||
| def get_session(token, current_session, **kwargs): |  | ||||||
|     """Retrieve information about a session |  | ||||||
| 
 |  | ||||||
|     Route: ``/auth/<token>`` | Method: ``GET`` |  | ||||||
| 
 |  | ||||||
|     Attributes: |  | ||||||
|         token: Token identifying session to retrieve |  | ||||||
|         current_session: Session sent with Authorization Header |  | ||||||
| 
 |  | ||||||
|     Returns: |  | ||||||
|         JSON encoded `flaschengeist.models.session.Session` or HTTP error |  | ||||||
|     """ |  | ||||||
|     logger.debug("get token {{ {} }}".format(token)) |  | ||||||
|     session = sessionController.get_session(token, current_session.user_) |  | ||||||
|     if not session: |  | ||||||
|         # Return 403 error, so that users can not bruteforce tokens |  | ||||||
|         # Valid tokens from other users and invalid tokens now are looking the same |  | ||||||
|         raise Forbidden |  | ||||||
|     return jsonify(session) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @AuthRoutePlugin.blueprint.route("/auth/<token>", methods=["PUT"]) |  | ||||||
| @login_required() |  | ||||||
| def set_lifetime(token, current_session, **kwargs): |  | ||||||
|     """Set lifetime of a session |  | ||||||
| 
 |  | ||||||
|     Route: ``/auth/<token>`` | Method: ``PUT`` |  | ||||||
| 
 |  | ||||||
|     POST-data: ``{value: int}`` |  | ||||||
| 
 |  | ||||||
|     Attributes: |  | ||||||
|         token: Token identifying the session |  | ||||||
|         current_session: Session sent with Authorization Header |  | ||||||
| 
 |  | ||||||
|     Returns: |  | ||||||
|         HTTP-204 or HTTP error |  | ||||||
|     """ |  | ||||||
|     session = sessionController.get_session(token, current_session.user_) |  | ||||||
|     if not session: |  | ||||||
|         # Return 403 error, so that users can not bruteforce tokens |  | ||||||
|         # Valid tokens from other users and invalid tokens now are looking the same |  | ||||||
|         raise Forbidden |  | ||||||
|     try: |  | ||||||
|         lifetime = request.get_json()["value"] |  | ||||||
|         logger.debug(f"set lifetime >{lifetime}< to access token >{token}<") |  | ||||||
|         sessionController.set_lifetime(session, lifetime) |  | ||||||
|         return jsonify(sessionController.get_session(token, current_session.user_)) |  | ||||||
|     except (KeyError, TypeError): |  | ||||||
|         raise BadRequest |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @AuthRoutePlugin.blueprint.route("/auth/<token>/user", methods=["GET"]) |  | ||||||
| @login_required() |  | ||||||
| def get_assocd_user(token, current_session, **kwargs): |  | ||||||
|     """Retrieve user owning a session |  | ||||||
| 
 |  | ||||||
|     Route: ``/auth/<token>/user`` | Method: ``GET`` |  | ||||||
| 
 |  | ||||||
|     Attributes: |  | ||||||
|         token: Token identifying the session |  | ||||||
|         current_session: Session sent with Authorization Header |  | ||||||
| 
 |  | ||||||
|     Returns: |  | ||||||
|         JSON encoded `flaschengeist.models.user.User` or HTTP error |  | ||||||
|     """ |  | ||||||
|     logger.debug("get token {{ {} }}".format(token)) |  | ||||||
|     session = sessionController.get_session(token, current_session.user_) |  | ||||||
|     if not session: |  | ||||||
|         # Return 403 error, so that users can not bruteforce tokens |  | ||||||
|         # Valid tokens from other users and invalid tokens now are looking the same |  | ||||||
|         raise Forbidden |  | ||||||
|     return jsonify(session.user_) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| @AuthRoutePlugin.blueprint.route("/auth/reset", methods=["POST"]) |  | ||||||
| def reset_password(): |  | ||||||
|     data = request.get_json() |  | ||||||
|     if "userid" in data: |  | ||||||
|         user = userController.find_user(data["userid"]) |  | ||||||
|         if user: |  | ||||||
|             userController.request_reset(user) |  | ||||||
|     elif "password" in data and "token" in data: |  | ||||||
|         userController.reset_password(data["token"], data["password"]) |  | ||||||
|     else: |  | ||||||
|         raise BadRequest("Missing parameter(s)") |  | ||||||
| 
 |  | ||||||
|     return no_content() |  | ||||||
|  | @ -0,0 +1,176 @@ | ||||||
|  | """Authentication plugin, provides basic routes | ||||||
|  | 
 | ||||||
|  | Allow management of authentication, login, logout, etc. | ||||||
|  | """ | ||||||
|  | from flask import Blueprint, request, jsonify | ||||||
|  | from werkzeug.exceptions import Forbidden, BadRequest, Unauthorized | ||||||
|  | 
 | ||||||
|  | from flaschengeist import logger | ||||||
|  | from flaschengeist.plugins import Plugin | ||||||
|  | from flaschengeist.utils.HTTP import no_content, created | ||||||
|  | from flaschengeist.utils.decorators import login_required | ||||||
|  | from flaschengeist.controller import sessionController, userController | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class AuthRoutePlugin(Plugin): | ||||||
|  |     blueprint = Blueprint("auth", __name__) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @AuthRoutePlugin.blueprint.route("/auth", methods=["POST"]) | ||||||
|  | def login(): | ||||||
|  |     """Login in an user and create a session | ||||||
|  | 
 | ||||||
|  |     Route: ``/auth`` | Method: ``POST`` | ||||||
|  | 
 | ||||||
|  |     POST-data: ``{userid: string, password: string}`` | ||||||
|  | 
 | ||||||
|  |     Returns: | ||||||
|  |         A JSON object with `flaschengeist.models.user.User` and created | ||||||
|  |         `flaschengeist.models.session.Session` or HTTP error | ||||||
|  |     """ | ||||||
|  |     logger.debug("Start log in.") | ||||||
|  |     data = request.get_json() | ||||||
|  |     try: | ||||||
|  |         userid = str(data["userid"]) | ||||||
|  |         password = str(data["password"]) | ||||||
|  |     except (KeyError, ValueError, TypeError): | ||||||
|  |         raise BadRequest("Missing parameter(s)") | ||||||
|  | 
 | ||||||
|  |     logger.debug(f"search user {userid} in database") | ||||||
|  |     user = userController.login_user(userid, password) | ||||||
|  |     if not user: | ||||||
|  |         raise Unauthorized | ||||||
|  |     session = sessionController.create(user, user_agent=request.user_agent) | ||||||
|  |     logger.debug(f"token is {session.token}") | ||||||
|  |     logger.info(f"User {userid} logged in.") | ||||||
|  | 
 | ||||||
|  |     # Lets cleanup the DB | ||||||
|  |     sessionController.clear_expired() | ||||||
|  |     return created(session) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @AuthRoutePlugin.blueprint.route("/auth", methods=["GET"]) | ||||||
|  | @login_required() | ||||||
|  | def get_sessions(current_session, **kwargs): | ||||||
|  |     """Get all valid sessions of current user | ||||||
|  | 
 | ||||||
|  |     Route: ``/auth`` | Method: ``GET`` | ||||||
|  | 
 | ||||||
|  |     Returns: | ||||||
|  |         A JSON array of `flaschengeist.models.session.Session` or HTTP error | ||||||
|  |     """ | ||||||
|  |     sessions = sessionController.get_users_sessions(current_session.user_) | ||||||
|  |     return jsonify(sessions) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @AuthRoutePlugin.blueprint.route("/auth/<token>", methods=["DELETE"]) | ||||||
|  | @login_required() | ||||||
|  | def delete_session(token, current_session, **kwargs): | ||||||
|  |     """Delete a session aka "logout" | ||||||
|  | 
 | ||||||
|  |     Route: ``/auth/<token>`` | Method: ``DELETE`` | ||||||
|  | 
 | ||||||
|  |     Returns: | ||||||
|  |             200 Status (empty) or HTTP error | ||||||
|  |     """ | ||||||
|  |     logger.debug("Try to delete access token {{ {} }}".format(token)) | ||||||
|  |     session = sessionController.get_session(token, current_session.user_) | ||||||
|  |     if not session: | ||||||
|  |         logger.debug("Token not found in database!") | ||||||
|  |         # Return 403 error, so that users can not bruteforce tokens | ||||||
|  |         # Valid tokens from other users and invalid tokens now are looking the same | ||||||
|  |         raise Forbidden | ||||||
|  |     sessionController.delete_session(session) | ||||||
|  |     sessionController.clear_expired() | ||||||
|  |     return "" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @AuthRoutePlugin.blueprint.route("/auth/<token>", methods=["GET"]) | ||||||
|  | @login_required() | ||||||
|  | def get_session(token, current_session, **kwargs): | ||||||
|  |     """Retrieve information about a session | ||||||
|  | 
 | ||||||
|  |     Route: ``/auth/<token>`` | Method: ``GET`` | ||||||
|  | 
 | ||||||
|  |     Attributes: | ||||||
|  |         token: Token identifying session to retrieve | ||||||
|  |         current_session: Session sent with Authorization Header | ||||||
|  | 
 | ||||||
|  |     Returns: | ||||||
|  |         JSON encoded `flaschengeist.models.session.Session` or HTTP error | ||||||
|  |     """ | ||||||
|  |     logger.debug("get token {{ {} }}".format(token)) | ||||||
|  |     session = sessionController.get_session(token, current_session.user_) | ||||||
|  |     if not session: | ||||||
|  |         # Return 403 error, so that users can not bruteforce tokens | ||||||
|  |         # Valid tokens from other users and invalid tokens now are looking the same | ||||||
|  |         raise Forbidden | ||||||
|  |     return jsonify(session) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @AuthRoutePlugin.blueprint.route("/auth/<token>", methods=["PUT"]) | ||||||
|  | @login_required() | ||||||
|  | def set_lifetime(token, current_session, **kwargs): | ||||||
|  |     """Set lifetime of a session | ||||||
|  | 
 | ||||||
|  |     Route: ``/auth/<token>`` | Method: ``PUT`` | ||||||
|  | 
 | ||||||
|  |     POST-data: ``{value: int}`` | ||||||
|  | 
 | ||||||
|  |     Attributes: | ||||||
|  |         token: Token identifying the session | ||||||
|  |         current_session: Session sent with Authorization Header | ||||||
|  | 
 | ||||||
|  |     Returns: | ||||||
|  |         HTTP-204 or HTTP error | ||||||
|  |     """ | ||||||
|  |     session = sessionController.get_session(token, current_session.user_) | ||||||
|  |     if not session: | ||||||
|  |         # Return 403 error, so that users can not bruteforce tokens | ||||||
|  |         # Valid tokens from other users and invalid tokens now are looking the same | ||||||
|  |         raise Forbidden | ||||||
|  |     try: | ||||||
|  |         lifetime = request.get_json()["value"] | ||||||
|  |         logger.debug(f"set lifetime >{lifetime}< to access token >{token}<") | ||||||
|  |         sessionController.set_lifetime(session, lifetime) | ||||||
|  |         return jsonify(sessionController.get_session(token, current_session.user_)) | ||||||
|  |     except (KeyError, TypeError): | ||||||
|  |         raise BadRequest | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @AuthRoutePlugin.blueprint.route("/auth/<token>/user", methods=["GET"]) | ||||||
|  | @login_required() | ||||||
|  | def get_assocd_user(token, current_session, **kwargs): | ||||||
|  |     """Retrieve user owning a session | ||||||
|  | 
 | ||||||
|  |     Route: ``/auth/<token>/user`` | Method: ``GET`` | ||||||
|  | 
 | ||||||
|  |     Attributes: | ||||||
|  |         token: Token identifying the session | ||||||
|  |         current_session: Session sent with Authorization Header | ||||||
|  | 
 | ||||||
|  |     Returns: | ||||||
|  |         JSON encoded `flaschengeist.models.user.User` or HTTP error | ||||||
|  |     """ | ||||||
|  |     logger.debug("get token {{ {} }}".format(token)) | ||||||
|  |     session = sessionController.get_session(token, current_session.user_) | ||||||
|  |     if not session: | ||||||
|  |         # Return 403 error, so that users can not bruteforce tokens | ||||||
|  |         # Valid tokens from other users and invalid tokens now are looking the same | ||||||
|  |         raise Forbidden | ||||||
|  |     return jsonify(session.user_) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @AuthRoutePlugin.blueprint.route("/auth/reset", methods=["POST"]) | ||||||
|  | def reset_password(): | ||||||
|  |     data = request.get_json() | ||||||
|  |     if "userid" in data: | ||||||
|  |         user = userController.find_user(data["userid"]) | ||||||
|  |         if user: | ||||||
|  |             userController.request_reset(user) | ||||||
|  |     elif "password" in data and "token" in data: | ||||||
|  |         userController.reset_password(data["token"], data["password"]) | ||||||
|  |     else: | ||||||
|  |         raise BadRequest("Missing parameter(s)") | ||||||
|  | 
 | ||||||
|  |     return no_content() | ||||||
|  | @ -1,10 +1,7 @@ | ||||||
| from flaschengeist.plugins import PluginMetadata | from flaschengeist.plugins import PluginMetadata | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def loader(): | plugin = PluginMetadata( | ||||||
|     from .plugin import AuthLDAP |     id="auth_ldap", | ||||||
| 
 |      | ||||||
|     return AuthLDAP | ) | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| Plugin = PluginMetadata(id="auth_ldap", name="auth_ldap", plugin=loader) |  | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue