Merge branch 'maintenance' into devel

This commit is contained in:
Gina Häußge 2016-10-04 18:37:58 +02:00
commit 1456a3e360
3 changed files with 95 additions and 8 deletions

View file

@ -1367,11 +1367,48 @@ class SettingsPlugin(OctoPrintPlugin):
and iterate yourself over all your settings, using the proper retriever methods on the settings manager
to retrieve the data in the correct format.
The default implementation will also replace any paths that have been restricted by your plugin through
:func:`~octoprint.plugin.SettingsPlugin.get_settings_restricted_paths` with ``None`` values where necessary.
Make sure to do your own restriction if you decide to fully overload this method.
:return: the current settings of the plugin, as a dictionary
"""
from flask.ext.login import current_user
data = self._settings.get_all_data()
if self.config_version_key in data:
del data[self.config_version_key]
restricted_paths = self.get_settings_restricted_paths()
def restrict_path_unless(data, path, condition):
if not path:
return
if condition():
return
node = data
if len(path) > 1:
for entry in path[:-1]:
if not entry in node:
return
node = node[entry]
key = path[-1]
if key in node:
node[key] = None
conditions = dict(user=lambda: current_user is not None and not current_user.is_anonymous(),
admin=lambda: current_user is not None and not current_user.is_anonymous() and current_user.is_admin(),
never=lambda: False)
for level, condition in conditions.items():
paths_for_level = restricted_paths.get(level, [])
for path in paths_for_level:
restrict_path_unless(data, path, condition)
return data
def on_settings_save(self, data):
@ -1434,6 +1471,60 @@ class SettingsPlugin(OctoPrintPlugin):
"""
return dict()
def get_settings_restricted_paths(self):
"""
Retrieves the list of paths in the plugin's settings which be restricted on the REST API.
Override this in your plugin's implementation to restrict whether a path should only be returned to logged in
users & admins, only to admins, or never on the REST API.
Return a ``dict`` with the keys ``admin``, ``user``, ``never`` mapping to a list of paths (as tuples or lists of
the path elements) for which to restrict access via the REST API accordingly. Paths returned for the ``admin``
key will only be available on the REST API when access with admin rights, ``user`` will only be available when accessed
as a logged in user. ``never`` will never be returned on the API.
Example:
.. code-block:: python
def get_settings_defaults(self):
return dict(some=dict(admin_only=dict(path="path", foo="foo"),
user_only=dict(path="path", bar="bar")),
another=dict(admin_only=dict(path="path"),
field="field"),
path=dict(to=dict(never=dict(return="return"))))
def get_settings_restricted_path(self):
return dict(admin=[["some", "admin_only", "path], ["another", "admin_only", "path"],
user=[["some", "user_only", "path"],],
never=[["path", "to", "never", "return"],])
# this will make the plugin return settings on the REST API like this for an anonymous user
#
# dict(some=dict(admin_only=dict(path=None, foo="foo"),
# user_only=dict(path=None, bar="bar")),
# another=dict(admin_only=dict(path=None),
# field="field"),
# path=dict(to=dict(never=dict(return=None))))
#
# like this for a logged in user
#
# dict(some=dict(admin_only=dict(path=None, foo="foo"),
# user_only=dict(path="path", bar="bar")),
# another=dict(admin_only=dict(path=None),
# field="field"),
# path=dict(to=dict(never=dict(return=None))))
#
# and like this for an admin user
#
# dict(some=dict(admin_only=dict(path="path", foo="foo"),
# user_only=dict(path="path", bar="bar")),
# another=dict(admin_only=dict(path="path"),
# field="field"),
# path=dict(to=dict(never=dict(return=None))))
"""
return dict()
def get_settings_preprocessors(self):
"""
Retrieves the plugin's preprocessors to use for preprocessing returned or set values prior to returning/setting

View file

@ -414,13 +414,6 @@ class OctoPrintFlaskResponse(flask.Response):
# add request specific cookie suffix to name
flask.Response.set_cookie(self, key + flask.request.cookie_suffix, *args, **kwargs)
def delete_cookie(self, key, *args, **kwargs):
# restrict cookie path to script root
kwargs["path"] = flask.request.script_root + kwargs.get("path", "/")
# add request specific cookie suffix to name
flask.Response.delete_cookie(self, key + flask.request.cookie_suffix, *args, **kwargs)
#~~ passive login helper
def passive_login():

View file

@ -207,4 +207,7 @@ class PrinterStateConnection(sockjs.tornado.SockJSConnection, octoprint.printer.
try:
self.send({type: payload})
except Exception as e:
self._logger.warn("Could not send message to client %s: %s" % (self._remoteAddress, str(e)))
if self._logger.isEnabledFor(logging.DEBUG):
self._logger.exception("Could not send message to client {}".format(self._remoteAddress))
else:
self._logger.warn("Could not send message to client {}: {}".format(self._remoteAddress, e))