diff --git a/octoprint/server.py b/octoprint/server.py index 8d2287d..8fcd8fa 100644 --- a/octoprint/server.py +++ b/octoprint/server.py @@ -14,6 +14,7 @@ import os import threading import logging, logging.config import subprocess +import netaddr from octoprint.printer import Printer, getConnectionOptions from octoprint.settings import settings, valid_boolean_trues @@ -64,8 +65,7 @@ class PrinterStateConnection(tornadio2.SocketConnection): self._eventManager = eventManager def on_open(self, info): - self._logger.info("New connection from client") - # Use of global here is smelly + self._logger.info("New connection from client: %s" % info.ip) self._printer.registerCallback(self) self._gcodeManager.registerCallback(self) @@ -74,7 +74,6 @@ class PrinterStateConnection(tornadio2.SocketConnection): def on_close(self): self._logger.info("Closed client connection") - # Use of global here is smelly self._printer.unregisterCallback(self) self._gcodeManager.unregisterCallback(self) @@ -857,6 +856,22 @@ def login(): if user is not None and not user.is_anonymous(): identity_changed.send(current_app._get_current_object(), identity=Identity(user.get_id())) return jsonify(user.asDict()) + elif settings().getBoolean(["accessControl", "autologinLocal"]) \ + and settings().get(["accessControl", "autologinAs"]) is not None \ + and settings().get(["accessControl", "localNetwork"]) is not None: + autologinAs = settings().get(["accessControl", "autologinAs"]) + localNetwork = settings().get(["accessControl", "localNetwork"]) + try: + remoteAddr = util.getRemoteAddress(request) + if netaddr.IPAddress(remoteAddr) in netaddr.IPNetwork(localNetwork): + user = userManager.findUser(autologinAs) + if user is not None: + login_user(user) + identity_changed.send(current_app._get_current_object(), identity=Identity(user.get_id())) + return jsonify(user.asDict()) + except: + logger = logging.getLogger(__name__) + logger.exception("Could not autologin user %s for network %s" % (autologinAs, localNetwork)) return jsonify(SUCCESS) @app.route(BASEURL + "logout", methods=["POST"]) diff --git a/octoprint/settings.py b/octoprint/settings.py index cdc7cc4..4ffd461 100644 --- a/octoprint/settings.py +++ b/octoprint/settings.py @@ -88,7 +88,10 @@ default_settings = { "accessControl": { "enabled": True, "userManager": "octoprint.users.FilebasedUserManager", - "userfile": None + "userfile": None, + "autologinLocal": False, + "localNetwork": "127.0.0.1", + "autologinAs": None }, "events": { "systemCommandTrigger": { diff --git a/octoprint/util/__init__.py b/octoprint/util/__init__.py index 77b046f..23d8a23 100644 --- a/octoprint/util/__init__.py +++ b/octoprint/util/__init__.py @@ -104,3 +104,9 @@ def getFreeBytes(path): st = os.statvfs(path) return st.f_bavail * st.f_frsize + +def getRemoteAddress(request): + forwardedFor = request.headers.get("X-Forwarded-For", None) + if forwardedFor is not None: + return forwardedFor.split(",")[0] + return request.remote_addr diff --git a/requirements-bbb.txt b/requirements-bbb.txt index 6bf2a2d..5558398 100644 --- a/requirements-bbb.txt +++ b/requirements-bbb.txt @@ -5,3 +5,4 @@ tornadio2==0.0.4 PyYAML==3.10 Flask-Login==0.2.2 Flask-Principal==0.3.5 +netaddr>=0.7.10 diff --git a/requirements.txt b/requirements.txt index 7c644b5..23fd4b6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,4 @@ Flask-Login==0.2.2 Flask-Principal==0.3.5 numpy>=1.6.2 pyserial>=2.6 +netaddr>=0.7.10