[Kimchi-devel] [PATCH] [Wok 3/3] Allow protecting an resource action (POST) when resource (GET) is not protected

Aline Manera alinefm at linux.vnet.ibm.com
Thu Feb 16 17:20:48 UTC 2017


Signed-off-by: Aline Manera <alinefm at linux.vnet.ibm.com>
---
 src/wok/control/base.py     | 13 +++++++----
 src/wok/control/config.py   |  6 ++---
 tests/test_authorization.py | 57 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 69 insertions(+), 7 deletions(-)
 create mode 100644 tests/test_authorization.py

diff --git a/src/wok/control/base.py b/src/wok/control/base.py
index 3070e53..0791062 100644
--- a/src/wok/control/base.py
+++ b/src/wok/control/base.py
@@ -27,7 +27,7 @@ import urllib2
 
 import wok.template
 from wok.asynctask import save_request_log_id
-from wok.auth import USER_GROUPS, USER_NAME, USER_ROLE
+from wok.auth import wokauth, USER_GROUPS, USER_NAME, USER_ROLE
 from wok.control.utils import get_class_name, internal_redirect, model_fn
 from wok.control.utils import parse_request, validate_method
 from wok.control.utils import validate_params
@@ -91,7 +91,7 @@ class Resource(object):
             raise cherrypy.HTTPRedirect(base_uri % tuple(uri_params), code)
 
     def generate_action_handler(self, action_name, action_args=None,
-                                destructive=False):
+                                destructive=False, protected=None):
         def _render_element(self, ident):
             self._redirect(ident)
             uri_params = []
@@ -104,7 +104,8 @@ class Resource(object):
 
         return self._generate_action_handler_base(action_name, _render_element,
                                                   destructive=destructive,
-                                                  action_args=action_args)
+                                                  action_args=action_args,
+                                                  protected=protected)
 
     def generate_action_handler_task(self, action_name, action_args=None):
         def _render_task(self, task):
@@ -115,10 +116,14 @@ class Resource(object):
                                                   action_args=action_args)
 
     def _generate_action_handler_base(self, action_name, render_fn,
-                                      destructive=False, action_args=None):
+                                      destructive=False, action_args=None,
+                                      protected=None):
         def wrapper(*args, **kwargs):
             # status must be always set in order to request be logged.
             # use 500 as fallback for "exception not handled" cases.
+            if protected is not None and protected:
+                wokauth()
+
             details = None
             status = 500
 
diff --git a/src/wok/control/config.py b/src/wok/control/config.py
index 8da2fc0..a18fff0 100644
--- a/src/wok/control/config.py
+++ b/src/wok/control/config.py
@@ -44,7 +44,7 @@ class Config(Resource):
         self.admin_methods = ['POST']
         self.plugins = Plugins(self.model)
         self.log_map = CONFIG_REQUESTS
-        self.reload = self.generate_action_handler('reload')
+        self.reload = self.generate_action_handler('reload', protected=True)
 
     @property
     def data(self):
@@ -64,8 +64,8 @@ class Plugin(Resource):
         self.admin_methods = ['POST']
         self.uri_fmt = "/config/plugins/%s"
         self.log_map = PLUGIN_REQUESTS
-        self.enable = self.generate_action_handler('enable')
-        self.disable = self.generate_action_handler('disable')
+        self.enable = self.generate_action_handler('enable', protected=True)
+        self.disable = self.generate_action_handler('disable', protected=True)
 
     @property
     def data(self):
diff --git a/tests/test_authorization.py b/tests/test_authorization.py
new file mode 100644
index 0000000..7b7bbcc
--- /dev/null
+++ b/tests/test_authorization.py
@@ -0,0 +1,57 @@
+#
+# Project Wok
+#
+# Copyright IBM Corp, 2014-2017
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+
+import unittest
+from functools import partial
+
+from tests.utils import patch_auth
+from tests.utils import request, run_server
+
+test_server = None
+
+
+def setUpModule():
+    global test_server
+
+    patch_auth()
+    test_server = run_server(test_mode=True)
+
+
+def tearDownModule():
+    test_server.stop()
+
+
+class AuthorizationTests(unittest.TestCase):
+    def setUp(self):
+        self.request = partial(request, user='user')
+
+    def test_nonroot_access(self):
+        # Non-root users can not reload wok config
+        resp = self.request('/config', '{}', 'GET')
+        self.assertEquals(200, resp.status)
+        resp = self.request('/config/reload', '{}', 'POST')
+        self.assertEquals(403, resp.status)
+
+        # Non-root users can not enable/disable a plugin
+        resp = self.request('/config/plugins/sample', '{}', 'GET')
+        self.assertEquals(200, resp.status)
+        resp = self.request('/config/plugins/sample/enable', '{}', 'POST')
+        self.assertEquals(403, resp.status)
+        resp = self.request('/config/plugins/sample/disable', '{}', 'POST')
+        self.assertEquals(403, resp.status)
-- 
2.9.3



More information about the Kimchi-devel mailing list