From 93a73a0ad81093d5a96bb7c58b3fd6bdbfd75278 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Mon, 1 Apr 2013 14:24:47 +0200 Subject: [PATCH] Added roles (user and admin) and according requirements --- octoprint/server.py | 30 ++++++++++++++++++++++++++++-- octoprint/users.py | 5 ++++- requirements.txt | 3 ++- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/octoprint/server.py b/octoprint/server.py index c900f1f..9f33c21 100644 --- a/octoprint/server.py +++ b/octoprint/server.py @@ -2,10 +2,11 @@ __author__ = "Gina Häußge " __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html' -from flask import Flask, request, render_template, jsonify, send_from_directory, abort, url_for from werkzeug.utils import secure_filename import tornadio2 -from flask.ext.login import LoginManager, login_user, logout_user, login_required, current_user, AnonymousUser +from flask import Flask, request, render_template, jsonify, send_from_directory, url_for, current_app, session +from flask.ext.login import LoginManager, login_user, logout_user, login_required, current_user +from flask.ext.principal import Principal, Permission, RoleNeed, Identity, identity_changed, AnonymousIdentity, identity_loaded, UserNeed import os import threading @@ -29,6 +30,10 @@ printer = None gcodeManager = None userManager = None +principals = Principal(app) +admin_permission = Permission(RoleNeed("admin")) +user_permission = Permission(RoleNeed("user")) + #~~ Printer state class PrinterStateConnection(tornadio2.SocketConnection): @@ -403,6 +408,7 @@ def getSettings(): @app.route(BASEURL + "settings", methods=["POST"]) @login_required +@admin_permission.require() def setSettings(): if "application/json" in request.headers["Content-Type"]: data = request.json @@ -449,6 +455,7 @@ def setSettings(): @app.route(BASEURL + "system", methods=["POST"]) @login_required +@admin_permission.require() def performSystemAction(): logger = logging.getLogger(__name__) if request.values.has_key("action"): @@ -484,6 +491,7 @@ def login(): if user is not None: if user.check_password(users.UserManager.createPasswordHash(password)): login_user(user, remember=remember) + identity_changed.send(current_app._get_current_object(), identity=Identity(user.get_id())) return jsonify({"name": user.get_name(), "user": user.is_user(), "admin": user.is_admin()}) return app.make_response(("User unknown or password incorrect", 401, [])) elif "passive" in request.values.keys(): @@ -496,9 +504,27 @@ def login(): @app.route(BASEURL + "logout", methods=["POST"]) @login_required def logout(): + # Remove session keys set by Flask-Principal + for key in ('identity.name', 'identity.auth_type'): + del session[key] + identity_changed.send(current_app._get_current_object(), identity=AnonymousIdentity()) + logout_user() + return jsonify(SUCCESS) +@identity_loaded.connect_via(app) +def on_identity_loaded(sender, identity): + user = load_user(identity.name) + if user is None: + return + + identity.provides.add(UserNeed(user.get_name())) + if user.is_user(): + identity.provides.add(RoleNeed("user")) + if user.is_admin(): + identity.provides.add(RoleNeed("admin")) + def load_user(id): if userManager is not None: return userManager.findUser(id) diff --git a/octoprint/users.py b/octoprint/users.py index f8268f1..2b9de83 100644 --- a/octoprint/users.py +++ b/octoprint/users.py @@ -50,7 +50,10 @@ class FilebasedUserManager(UserManager): self._load() def _load(self): - self._users = {"admin": User("admin", "7557160613d5258f883014a7c3c0428de53040fc152b1791f1cc04a62b428c0c2a9c46ed330cdce9689353ab7a5352ba2b2ceb459b96e9c8ed7d0cb0b2c0c076", True, UserManager.valid_roles)} + self._users = { + "admin": User("admin", "7557160613d5258f883014a7c3c0428de53040fc152b1791f1cc04a62b428c0c2a9c46ed330cdce9689353ab7a5352ba2b2ceb459b96e9c8ed7d0cb0b2c0c076", True, ["user", "admin"]), + "user": User("user", "ced28770ae4457f420e322a5c7b8abc5f31432aef2552871909d6f4f372d1e0d6e0e7be14114656971eeba88e6462d5ea596b656d521c847047a496fecc431a5", True, ["user"]) + } if os.path.exists(self._userfile) and os.path.isfile(self._userfile): with open(self._userfile, "r") as f: data = yaml.safe_load(f) diff --git a/requirements.txt b/requirements.txt index 4114ee7..e1a1510 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,4 +4,5 @@ pyserial>=2.6 tornado>=2.4.1 tornadio2>=0.0.4 PyYAML>=3.10 -Flask-Login>=0.1.3 \ No newline at end of file +Flask-Login>=0.1.3 +Flask-Principal>=0.3.4 \ No newline at end of file