diff --git a/src/octoprint/plugins/corewizard/__init__.py b/src/octoprint/plugins/corewizard/__init__.py index e9cc114b..37d734a9 100644 --- a/src/octoprint/plugins/corewizard/__init__.py +++ b/src/octoprint/plugins/corewizard/__init__.py @@ -68,7 +68,7 @@ class CoreWizardPlugin(octoprint.plugin.AssetPlugin, #~~ ACL subwizard def _is_acl_wizard_required(self): - return self._user_manager is not None and not self._user_manager.hasBeenCustomized() + return self._user_manager.enabled and not self._user_manager.hasBeenCustomized() def _get_acl_wizard_details(self): return dict() @@ -93,7 +93,8 @@ class CoreWizardPlugin(octoprint.plugin.AssetPlugin, "pass2" in data.keys() and data["pass1"] == data["pass2"]: # configure access control self._settings.global_set_boolean(["accessControl", "enabled"], True) - octoprint.server.userManager.addUser(data["user"], data["pass1"], True, ["user", "admin"], overwrite=True) + self._user_manager.enable() + self._user_manager.addUser(data["user"], data["pass1"], True, ["user", "admin"], overwrite=True) elif "ac" in data.keys() and not data["ac"] in valid_boolean_trues: # disable access control self._settings.global_set_boolean(["accessControl", "enabled"], False) @@ -101,6 +102,7 @@ class CoreWizardPlugin(octoprint.plugin.AssetPlugin, octoprint.server.loginManager.anonymous_user = octoprint.users.DummyUser octoprint.server.principals.identity_loaders.appendleft(octoprint.users.dummy_identity_loader) + self._user_manager.disable() self._settings.save() return NO_CONTENT diff --git a/src/octoprint/server/__init__.py b/src/octoprint/server/__init__.py index 93dd7181..92df48c9 100644 --- a/src/octoprint/server/__init__.py +++ b/src/octoprint/server/__init__.py @@ -101,7 +101,7 @@ def load_user(id): else: sessionid = None - if userManager is not None: + if userManager.enabled: if sessionid: return userManager.findUser(userid=id, session=sessionid) else: @@ -198,13 +198,15 @@ class Server(): preemptiveCache = PreemptiveCache(os.path.join(self._settings.getBaseFolder("data"), "preemptive_cache_config.yaml")) # setup access control - if self._settings.getBoolean(["accessControl", "enabled"]): - userManagerName = self._settings.get(["accessControl", "userManager"]) - try: - clazz = octoprint.util.get_class(userManagerName) - userManager = clazz() - except AttributeError, e: - self._logger.exception("Could not instantiate user manager %s, will run with accessControl disabled!" % userManagerName) + userManagerName = self._settings.get(["accessControl", "userManager"]) + try: + clazz = octoprint.util.get_class(userManagerName) + userManager = clazz() + except AttributeError, e: + self._logger.exception("Could not instantiate user manager {}, falling back to FilebasedUserManager!".format(userManagerName)) + userManager = octoprint.users.FilebasedUserManager() + finally: + userManager.enabled = self._settings.getBoolean(["accessControl", "enabled"]) def octoprint_plugin_inject_factory(name, implementation): if not isinstance(implementation, octoprint.plugin.OctoPrintPlugin): @@ -317,7 +319,7 @@ class Server(): loginManager = LoginManager() loginManager.session_protection = "strong" loginManager.user_callback = load_user - if userManager is None: + if not userManager.enabled: loginManager.anonymous_user = users.DummyUser principals.identity_loaders.appendleft(users.dummy_identity_loader) loginManager.init_app(app) @@ -545,7 +547,7 @@ class Server(): if "l10n" in request.values: return Locale.negotiate([request.values["l10n"]], LANGUAGES) - if hasattr(g, "identity") and g.identity and userManager is not None: + if hasattr(g, "identity") and g.identity and userManager.enabled: userid = g.identity.id try: user_language = userManager.getUserSetting(userid, ("interface", "language")) diff --git a/src/octoprint/server/api/__init__.py b/src/octoprint/server/api/__init__.py index 4b106cdd..55be59c4 100644 --- a/src/octoprint/server/api/__init__.py +++ b/src/octoprint/server/api/__init__.py @@ -188,7 +188,7 @@ def login(): if hasattr(request, "json") and request.json: data = request.json - if octoprint.server.userManager is not None and "user" in data and "pass" in data: + if octoprint.server.userManager.enabled and "user" in data and "pass" in data: username = data["user"] password = data["pass"] @@ -203,7 +203,7 @@ def login(): user = octoprint.server.userManager.findUser(username) if user is not None: if octoprint.server.userManager.checkPassword(username, password): - if octoprint.server.userManager is not None: + if octoprint.server.userManager.enabled: user = octoprint.server.userManager.login_user(user) session["usersession.id"] = user.get_session() g.user = user diff --git a/src/octoprint/server/api/users.py b/src/octoprint/server/api/users.py index 19472d95..c423bcf8 100644 --- a/src/octoprint/server/api/users.py +++ b/src/octoprint/server/api/users.py @@ -23,7 +23,7 @@ from octoprint.server.util.flask import restricted_access @restricted_access @admin_permission.require(403) def getUsers(): - if userManager is None: + if not userManager.enabled: return jsonify(SUCCESS) return jsonify({"users": userManager.getAllUsers()}) @@ -33,7 +33,7 @@ def getUsers(): @restricted_access @admin_permission.require(403) def addUser(): - if userManager is None: + if not userManager.enabled: return jsonify(SUCCESS) if not "application/json" in request.headers["Content-Type"]: @@ -62,7 +62,7 @@ def addUser(): @api.route("/users/", methods=["GET"]) @restricted_access def getUser(username): - if userManager is None: + if not userManager.enabled: return jsonify(SUCCESS) if current_user is not None and not current_user.is_anonymous() and (current_user.get_name() == username or current_user.is_admin()): @@ -79,7 +79,7 @@ def getUser(username): @restricted_access @admin_permission.require(403) def updateUser(username): - if userManager is None: + if not userManager.enabled: return jsonify(SUCCESS) user = userManager.findUser(username) @@ -110,7 +110,7 @@ def updateUser(username): @restricted_access @admin_permission.require(http_exception=403) def removeUser(username): - if userManager is None: + if not userManager.enabled: return jsonify(SUCCESS) try: @@ -123,7 +123,7 @@ def removeUser(username): @api.route("/users//password", methods=["PUT"]) @restricted_access def changePasswordForUser(username): - if userManager is None: + if not userManager.enabled: return jsonify(SUCCESS) if current_user is not None and not current_user.is_anonymous() and (current_user.get_name() == username or current_user.is_admin()): @@ -151,7 +151,7 @@ def changePasswordForUser(username): @api.route("/users//settings", methods=["GET"]) @restricted_access def getSettingsForUser(username): - if userManager is None: + if not userManager.enabled: return jsonify(SUCCESS) if current_user is None or current_user.is_anonymous() or (current_user.get_name() != username and not current_user.is_admin()): @@ -165,7 +165,7 @@ def getSettingsForUser(username): @api.route("/users//settings", methods=["PATCH"]) @restricted_access def changeSettingsForUser(username): - if userManager is None: + if not userManager.enabled: return jsonify(SUCCESS) if current_user is None or current_user.is_anonymous() or (current_user.get_name() != username and not current_user.is_admin()): @@ -185,7 +185,7 @@ def changeSettingsForUser(username): @api.route("/users//apikey", methods=["DELETE"]) @restricted_access def deleteApikeyForUser(username): - if userManager is None: + if not userManager.enabled: return jsonify(SUCCESS) if current_user is not None and not current_user.is_anonymous() and (current_user.get_name() == username or current_user.is_admin()): @@ -201,7 +201,7 @@ def deleteApikeyForUser(username): @api.route("/users//apikey", methods=["POST"]) @restricted_access def generateApikeyForUser(username): - if userManager is None: + if not userManager.enabled: return jsonify(SUCCESS) if current_user is not None and not current_user.is_anonymous() and (current_user.get_name() == username or current_user.is_admin()): diff --git a/src/octoprint/server/util/__init__.py b/src/octoprint/server/util/__init__.py index 78425af8..36f7bc87 100644 --- a/src/octoprint/server/util/__init__.py +++ b/src/octoprint/server/util/__init__.py @@ -120,7 +120,7 @@ def get_user_for_apikey(apikey): if apikey == settings().get(["api", "key"]) or octoprint.server.appSessionManager.validate(apikey): # master key or an app session key was used return ApiUser() - elif octoprint.server.userManager is not None: + elif octoprint.server.userManager.enabled: # user key might have been used return octoprint.server.userManager.findUser(apikey=apikey) return None diff --git a/src/octoprint/server/util/flask.py b/src/octoprint/server/util/flask.py index 57a53cf7..b443dfc5 100644 --- a/src/octoprint/server/util/flask.py +++ b/src/octoprint/server/util/flask.py @@ -222,7 +222,7 @@ def fix_webassets_filtertool(): #~~ passive login helper def passive_login(): - if octoprint.server.userManager is not None: + if octoprint.server.userManager.enabled: user = octoprint.server.userManager.login_user(flask.ext.login.current_user) else: user = flask.ext.login.current_user @@ -700,7 +700,7 @@ def restricted_access(func): @functools.wraps(func) def decorated_view(*args, **kwargs): # if OctoPrint hasn't been set up yet, abort - if settings().getBoolean(["server", "firstRun"]) and (octoprint.server.userManager is None or not octoprint.server.userManager.hasBeenCustomized()): + if settings().getBoolean(["server", "firstRun"]) and settings().getBoolean(["accessControl", "enabled"]) and (octoprint.server.userManager is None or not octoprint.server.userManager.hasBeenCustomized()): return flask.make_response("OctoPrint isn't setup yet", 403) apikey = octoprint.server.util.get_api_key(flask.request) diff --git a/src/octoprint/server/views.py b/src/octoprint/server/views.py index 693f24bb..4072e9cc 100644 --- a/src/octoprint/server/views.py +++ b/src/octoprint/server/views.py @@ -213,7 +213,7 @@ def index(): else: wizard = wizard_active(_templates) - enable_accesscontrol = userManager is not None + enable_accesscontrol = userManager.enabled render_kwargs.update(dict( webcamStream=settings().get(["webcam", "stream"]), enableTemperatureGraph=settings().get(["feature", "temperatureGraph"]), @@ -267,7 +267,7 @@ def _get_render_kwargs(templates, plugin_names, plugin_vars, now): def _process_templates(): - enable_accesscontrol = userManager is not None + enable_accesscontrol = userManager.enabled first_run = settings().getBoolean(["server", "firstRun"]) enable_gcodeviewer = settings().getBoolean(["gcodeViewer", "enabled"]) enable_timelapse = (settings().get(["webcam", "snapshot"]) and settings().get(["webcam", "ffmpeg"])) diff --git a/src/octoprint/static/js/app/dataupdater.js b/src/octoprint/static/js/app/dataupdater.js index be295a56..ec915b59 100644 --- a/src/octoprint/static/js/app/dataupdater.js +++ b/src/octoprint/static/js/app/dataupdater.js @@ -6,9 +6,6 @@ function DataUpdater(allViewModels) { self._pluginHash = undefined; self._configHash = undefined; - self.reloadOverlay = $("#reloadui_overlay"); - $("#reloadui_overlay_reload").click(function() { location.reload(); }); - self.connect = function() { OctoPrint.socket.connect({debug: !!SOCKJS_DEBUG}); }; @@ -94,7 +91,7 @@ function DataUpdater(allViewModels) { var pluginsChanged = oldPluginHash != undefined && oldPluginHash != self._pluginHash; var configChanged = oldConfigHash != undefined && oldConfigHash != self._configHash; if (versionChanged || pluginsChanged || configChanged) { - self.reloadOverlay.show(); + showReloadOverlay(); } }; diff --git a/src/octoprint/static/js/app/helpers.js b/src/octoprint/static/js/app/helpers.js index 8a67a576..930eccdd 100644 --- a/src/octoprint/static/js/app/helpers.js +++ b/src/octoprint/static/js/app/helpers.js @@ -553,6 +553,10 @@ function showConfirmationDialog(msg, onacknowledge, options) { return modal; } +function showReloadOverlay() { + $("#reloadui_overlay").show(); +} + function commentableLinesToArray(lines) { return splitTextToArray(lines, "\n", true, function(item) {return !_.startsWith(item, "#")}); } diff --git a/src/octoprint/static/js/app/main.js b/src/octoprint/static/js/app/main.js index 841a017a..e7e2ae43 100644 --- a/src/octoprint/static/js/app/main.js +++ b/src/octoprint/static/js/app/main.js @@ -512,6 +512,9 @@ $(function() { e.preventDefault(); }); + // reload overlay + $("#reloadui_overlay_reload").click(function() { location.reload(); }); + //~~ Starting up the app callViewModels(allViewModels, "onStartup"); diff --git a/src/octoprint/users.py b/src/octoprint/users.py index 45c90e32..065aaff2 100644 --- a/src/octoprint/users.py +++ b/src/octoprint/users.py @@ -26,6 +26,21 @@ class UserManager(object): self._logger = logging.getLogger(__name__) self._session_users_by_session = dict() self._session_users_by_userid = dict() + self._enabled = True + + @property + def enabled(self): + return self._enabled + + @enabled.setter + def enabled(self, value): + self._enabled = value + + def enable(self): + self._enabled = True + + def disable(self): + self._enabled = False def login_user(self, user): self._cleanup_sessions()