Added registration feature
This commit is contained in:
		
							parent
							
								
									5da5fcde8f
								
							
						
					
					
						commit
						de5a2e1c65
					
				| 
						 | 
				
			
			@ -32,6 +32,15 @@ enabled = true
 | 
			
		|||
## ADMIN_DN:
 | 
			
		||||
## 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 #
 | 
			
		||||
############################
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -68,3 +68,17 @@ def delete(user):
 | 
			
		|||
    current_app.config["FG_AUTH_BACKEND"].delete_user(user)
 | 
			
		||||
    db.session.delete(user)
 | 
			
		||||
    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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,5 @@
 | 
			
		|||
import pkg_resources
 | 
			
		||||
from werkzeug.exceptions import MethodNotAllowed
 | 
			
		||||
 | 
			
		||||
from flaschengeist.hook import HookCall
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -31,13 +32,12 @@ class AuthPlugin(Plugin):
 | 
			
		|||
        Returns:
 | 
			
		||||
            Must return False if not found or invalid credentials, True if success
 | 
			
		||||
        """
 | 
			
		||||
        raise NotImplementedError
 | 
			
		||||
        raise NotImplemented
 | 
			
		||||
 | 
			
		||||
    def update_user(self, user):
 | 
			
		||||
        """If backend is using external data, then update this user instance with external data
 | 
			
		||||
        )
 | 
			
		||||
                Args:
 | 
			
		||||
                    user: User object
 | 
			
		||||
        Args:
 | 
			
		||||
            user: User object
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -55,6 +55,16 @@ class AuthPlugin(Plugin):
 | 
			
		|||
        """
 | 
			
		||||
        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):
 | 
			
		||||
        """If backend is using (writeable) external data, then delete the user from external database.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -62,4 +72,4 @@ class AuthPlugin(Plugin):
 | 
			
		|||
            user: User object
 | 
			
		||||
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
        raise MethodNotAllowed
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,6 +24,15 @@ class AuthPlain(AuthPlugin):
 | 
			
		|||
        if 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
 | 
			
		||||
    def _hash_password(password):
 | 
			
		||||
        salt = hashlib.sha256(os.urandom(60)).hexdigest().encode("ascii")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,19 +2,20 @@
 | 
			
		|||
 | 
			
		||||
Provides routes used to manage users
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
from flaschengeist.config import config
 | 
			
		||||
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.plugins import Plugin
 | 
			
		||||
from flaschengeist.decorator import login_required
 | 
			
		||||
from flaschengeist.decorator import login_required, extract_session
 | 
			
		||||
from flaschengeist.controller import userController
 | 
			
		||||
 | 
			
		||||
users_bp = Blueprint("users", __name__)
 | 
			
		||||
_permission_edit = "users_edit_other"
 | 
			
		||||
_permission_set_roles = "users_set_roles"
 | 
			
		||||
_permission_delete = "users_delete_other"
 | 
			
		||||
_permission_register = "users_register"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UsersPlugin(Plugin):
 | 
			
		||||
| 
						 | 
				
			
			@ -23,9 +24,29 @@ class UsersPlugin(Plugin):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
@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...")
 | 
			
		||||
    return jsonify({"ok": "ok... well not implemented"})
 | 
			
		||||
 | 
			
		||||
    return jsonify(userController.register(data))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@users_bp.route("/users", methods=["GET"])
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue