Added registration feature

This commit is contained in:
Ferdinand Thiessen 2020-10-31 00:02:02 +01:00
parent 5da5fcde8f
commit de5a2e1c65
5 changed files with 73 additions and 10 deletions

View File

@ -32,6 +32,15 @@ enabled = true
## ADMIN_DN: ## ADMIN_DN:
## ADMIN_SECRET: ## ADMIN_SECRET:
#[users]
# allways enabled
#
## allowed values: false, "managed", "public"
## false: Disable registration
## "managed": only users with matching permission are allowed to register new users
## "public": Also unautheticated users can register an account
# registration = False
############################ ############################
# Configuration of plugins # # Configuration of plugins #
############################ ############################

View File

@ -68,3 +68,17 @@ def delete(user):
current_app.config["FG_AUTH_BACKEND"].delete_user(user) current_app.config["FG_AUTH_BACKEND"].delete_user(user)
db.session.delete(user) db.session.delete(user)
db.session.commit() db.session.commit()
def register(data):
for required in ["firstname", "lastname", "mail"]:
if required not in data:
raise BadRequest("Missing required parameters")
allowed_keys = User().serialize().keys()
user = User(**{key: value for key, value in data.items() if key in allowed_keys})
current_app.config["FG_AUTH_BACKEND"].create_user(user, data["password"])
db.session.add(user)
db.session.commit()
return user

View File

@ -1,4 +1,5 @@
import pkg_resources import pkg_resources
from werkzeug.exceptions import MethodNotAllowed
from flaschengeist.hook import HookCall from flaschengeist.hook import HookCall
@ -31,11 +32,10 @@ class AuthPlugin(Plugin):
Returns: Returns:
Must return False if not found or invalid credentials, True if success Must return False if not found or invalid credentials, True if success
""" """
raise NotImplementedError raise NotImplemented
def update_user(self, user): def update_user(self, user):
"""If backend is using external data, then update this user instance with external data """If backend is using external data, then update this user instance with external data
)
Args: Args:
user: User object user: User object
""" """
@ -55,6 +55,16 @@ class AuthPlugin(Plugin):
""" """
raise NotImplemented raise NotImplemented
def create_user(self, user, password):
"""If backend is using (writeable) external data, then create a new user on the external database.
Args:
user: User object
password: string
"""
raise MethodNotAllowed
def delete_user(self, user): def delete_user(self, user):
"""If backend is using (writeable) external data, then delete the user from external database. """If backend is using (writeable) external data, then delete the user from external database.
@ -62,4 +72,4 @@ class AuthPlugin(Plugin):
user: User object user: User object
""" """
pass raise MethodNotAllowed

View File

@ -24,6 +24,15 @@ class AuthPlain(AuthPlugin):
if new_password: if new_password:
user.set_attribute("password", AuthPlain._hash_password(new_password)) user.set_attribute("password", AuthPlain._hash_password(new_password))
def create_user(self, user, password):
if not user.userid:
raise BadRequest("userid is missing for new user")
hashed = AuthPlain._hash_password(password)
user.set_attribute("password", hashed)
def delete_user(self, user):
pass
@staticmethod @staticmethod
def _hash_password(password): def _hash_password(password):
salt = hashlib.sha256(os.urandom(60)).hexdigest().encode("ascii") salt = hashlib.sha256(os.urandom(60)).hexdigest().encode("ascii")

View File

@ -2,19 +2,20 @@
Provides routes used to manage users Provides routes used to manage users
""" """
from flaschengeist.config import config
from flask import Blueprint, request, jsonify from flask import Blueprint, request, jsonify
from werkzeug.exceptions import NotFound, BadRequest, Forbidden from werkzeug.exceptions import BadRequest, Forbidden, MethodNotAllowed
from flaschengeist import logger from flaschengeist import logger
from flaschengeist.plugins import Plugin from flaschengeist.plugins import Plugin
from flaschengeist.decorator import login_required from flaschengeist.decorator import login_required, extract_session
from flaschengeist.controller import userController from flaschengeist.controller import userController
users_bp = Blueprint("users", __name__) users_bp = Blueprint("users", __name__)
_permission_edit = "users_edit_other" _permission_edit = "users_edit_other"
_permission_set_roles = "users_set_roles" _permission_set_roles = "users_set_roles"
_permission_delete = "users_delete_other" _permission_delete = "users_delete_other"
_permission_register = "users_register"
class UsersPlugin(Plugin): class UsersPlugin(Plugin):
@ -23,9 +24,29 @@ class UsersPlugin(Plugin):
@users_bp.route("/users", methods=["POST"]) @users_bp.route("/users", methods=["POST"])
def __registration(self): def register():
"""Register a new user
Route: ``/users`` | Method: ``POST``
POST-data: Same as `flaschengeist.models.user.User` + ``password?: string``
Returns:
JSON encoded `flaschengeist.models.user.User` or HTTP error
"""
registration = config["users"].get("registration", False)
if not registration or registration not in ["managed", "public"]:
logger.debug("Config for Registration is set to >{}<".format(registration))
raise MethodNotAllowed
if registration == "managed":
extract_session(_permission_register)
data = request.get_json()
if not data:
raise BadRequest
logger.debug("Register new User...") logger.debug("Register new User...")
return jsonify({"ok": "ok... well not implemented"})
return jsonify(userController.register(data))
@users_bp.route("/users", methods=["GET"]) @users_bp.route("/users", methods=["GET"])