diff --git a/server/application.py b/server/application.py index d1eae870..6f5fea24 100644 --- a/server/application.py +++ b/server/application.py @@ -28,6 +28,7 @@ Configuration.SERVER_TYPE = "ce" Configuration.USER_SELF_REGISTRATION = False + application = create_app( [ "DOCS_URL", @@ -37,6 +38,7 @@ "GLOBAL_ADMIN", "GLOBAL_READ", "GLOBAL_WRITE", + "ENABLE_SUPERADMIN_ASSIGNMENT", ] ) register_stats(application) diff --git a/server/mergin/auth/controller.py b/server/mergin/auth/controller.py index cd686203..bccb98ba 100644 --- a/server/mergin/auth/controller.py +++ b/server/mergin/auth/controller.py @@ -408,11 +408,17 @@ def update_user(username): # pylint: disable=W0613,W0612 form = UserForm.from_json(request.json) if not form.validate_on_submit(): return jsonify(form.errors), 400 + if request.json.get("is_admin") is not None and not current_app.config.get( + "ENABLE_SUPERADMIN_ASSIGNMENT" + ): + abort(400, "Unable to assign super admin role") user = User.query.filter_by(username=username).first_or_404("User not found") form.update_obj(user) + # remove inactive since flag for ban or re-activation user.inactive_since = None + db.session.add(user) db.session.commit() return jsonify(UserSchema().dump(user)) diff --git a/server/mergin/config.py b/server/mergin/config.py index fedeb31d..87a6c777 100644 --- a/server/mergin/config.py +++ b/server/mergin/config.py @@ -102,3 +102,7 @@ class Configuration(object): USER_SELF_REGISTRATION = config("USER_SELF_REGISTRATION", default=False, cast=bool) # build hash number BUILD_HASH = config("BUILD_HASH", default="") + # Allow changing access to admin panel + ENABLE_SUPERADMIN_ASSIGNMENT = config( + "ENABLE_SUPERADMIN_ASSIGNMENT", default=True, cast=bool + ) diff --git a/server/mergin/tests/test_auth.py b/server/mergin/tests/test_auth.py index 79317cf3..43d61d7d 100644 --- a/server/mergin/tests/test_auth.py +++ b/server/mergin/tests/test_auth.py @@ -412,6 +412,25 @@ def test_api_user_profile(client): def test_update_user(client): login_as_admin(client) user = User.query.filter_by(username="mergin").first() + data = {"active": True, "is_admin": True} + resp = client.patch( + url_for("/.mergin_auth_controller_update_user", username=user.username), + data=json.dumps(data), + headers=json_headers, + ) + assert resp.status_code == 200 + assert user.active + assert user.is_admin + + client.application.config["ENABLE_SUPERADMIN_ASSIGNMENT"] = False + data = {"active": False, "is_admin": False} + resp = client.patch( + url_for("/.mergin_auth_controller_update_user", username=user.username), + data=json.dumps(data), + headers=json_headers, + ) + assert resp.status_code == 400 + assert user.active data = {"active": False} resp = client.patch( url_for("/.mergin_auth_controller_update_user", username=user.username), @@ -421,6 +440,7 @@ def test_update_user(client): assert resp.status_code == 200 assert not user.active + client.application.config["ENABLE_SUPERADMIN_ASSIGNMENT"] = True user.is_admin = False db.session.add(user) db.session.commit() diff --git a/web-app/packages/admin-lib/src/modules/admin/views/AccountDetailView.vue b/web-app/packages/admin-lib/src/modules/admin/views/AccountDetailView.vue index c38f229e..e733c5c0 100644 --- a/web-app/packages/admin-lib/src/modules/admin/views/AccountDetailView.vue +++ b/web-app/packages/admin-lib/src/modules/admin/views/AccountDetailView.vue @@ -82,7 +82,9 @@ >