Reviewed-by: Daniel Barboza <danielhb(a)linux.vnet.ibm.com>
Tested-by: Daniel Barboza <danielhb(a)linux.vnet.ibm.com>
On 07/16/2014 06:52 PM, alinefm(a)linux.vnet.ibm.com wrote:
From: Aline Manera <alinefm(a)linux.vnet.ibm.com>
Kimchi will allow one user role per tab but it protects its resources
through API URIs.
That way we need to map API URIs per tab to get the user role.
Do that by adding a new parameter to UrlSubNode() to describe which tab
the URI is used.
And then use that information to get the user role for each request.
Signed-off-by: Aline Manera <alinefm(a)linux.vnet.ibm.com>
---
src/kimchi/auth.py | 14 ++++++--------
src/kimchi/control/debugreports.py | 2 +-
src/kimchi/control/host.py | 2 +-
src/kimchi/control/interfaces.py | 2 +-
src/kimchi/control/networks.py | 2 +-
src/kimchi/control/storagepools.py | 2 +-
src/kimchi/control/storageservers.py | 2 +-
src/kimchi/control/templates.py | 2 +-
src/kimchi/control/utils.py | 4 +++-
src/kimchi/control/vms.py | 2 +-
src/kimchi/server.py | 1 +
11 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/src/kimchi/auth.py b/src/kimchi/auth.py
index bf048b2..404bab3 100644
--- a/src/kimchi/auth.py
+++ b/src/kimchi/auth.py
@@ -37,7 +37,6 @@
USER_NAME = 'username'
USER_GROUPS = 'groups'
-USER_SUDO = 'sudo'
USER_ROLES = 'roles'
REFRESH = 'robot-refresh'
@@ -235,7 +234,6 @@ def login(username, password, **kwargs):
cherrypy.session.regenerate()
cherrypy.session[USER_NAME] = username
cherrypy.session[USER_GROUPS] = user.get_groups()
- cherrypy.session[USER_SUDO] = user.has_sudo()
cherrypy.session[USER_ROLES] = user.get_roles()
cherrypy.session[REFRESH] = time.time()
cherrypy.session.release_lock()
@@ -250,26 +248,26 @@ def logout():
cherrypy.lib.sessions.close()
-def has_permission(admin_methods):
+def has_permission(admin_methods, tab):
cherrypy.session.acquire_lock()
- has_sudo = cherrypy.session.get(USER_SUDO, None)
+ role = cherrypy.session.get(USER_ROLES, {}).get(tab, 'user')
cherrypy.session.release_lock()
return not admin_methods or \
cherrypy.request.method not in admin_methods or \
- (cherrypy.request.method in admin_methods and has_sudo)
+ (cherrypy.request.method in admin_methods and role == "admin")
-def kimchiauth(admin_methods=None):
+def kimchiauth(admin_methods=None, tab=None):
debug("Entering kimchiauth...")
session_missing = cherrypy.session.missing
if check_auth_session():
- if not has_permission(admin_methods):
+ if not has_permission(admin_methods, tab):
raise cherrypy.HTTPError(403)
return
if check_auth_httpba():
- if not has_permission(admin_methods):
+ if not has_permission(admin_methods, tab):
raise cherrypy.HTTPError(403)
return
diff --git a/src/kimchi/control/debugreports.py b/src/kimchi/control/debugreports.py
index d651eb1..f0d5dcf 100644
--- a/src/kimchi/control/debugreports.py
+++ b/src/kimchi/control/debugreports.py
@@ -22,7 +22,7 @@
from kimchi.control.utils import UrlSubNode
-@UrlSubNode("debugreports", True, ['GET', 'PUT',
'POST', 'DELETE'])
+@UrlSubNode('debugreports', True, ['GET', 'PUT', 'POST',
'DELETE'], 'host')
class DebugReports(AsyncCollection):
def __init__(self, model):
super(DebugReports, self).__init__(model)
diff --git a/src/kimchi/control/host.py b/src/kimchi/control/host.py
index 9158565..e1971cc 100644
--- a/src/kimchi/control/host.py
+++ b/src/kimchi/control/host.py
@@ -25,7 +25,7 @@
from kimchi.template import render
-@UrlSubNode("host", True, ['GET', 'PUT', 'POST',
'DELETE'])
+@UrlSubNode('host', True, ['GET', 'PUT', 'POST',
'DELETE'], 'host')
class Host(Resource):
def __init__(self, model, id=None):
super(Host, self).__init__(model, id)
diff --git a/src/kimchi/control/interfaces.py b/src/kimchi/control/interfaces.py
index 6ae688d..4aa77b6 100644
--- a/src/kimchi/control/interfaces.py
+++ b/src/kimchi/control/interfaces.py
@@ -21,7 +21,7 @@
from kimchi.control.utils import UrlSubNode
-@UrlSubNode("interfaces", True, ['GET'])
+@UrlSubNode('interfaces', True, ['GET'], 'network')
class Interfaces(Collection):
def __init__(self, model):
super(Interfaces, self).__init__(model)
diff --git a/src/kimchi/control/networks.py b/src/kimchi/control/networks.py
index 431a01f..6bcc871 100644
--- a/src/kimchi/control/networks.py
+++ b/src/kimchi/control/networks.py
@@ -21,7 +21,7 @@
from kimchi.control.utils import UrlSubNode
-@UrlSubNode("networks", True, ['PUT', 'POST',
'DELETE'])
+@UrlSubNode('networks', True, ['PUT', 'POST', 'DELETE'],
'network')
class Networks(Collection):
def __init__(self, model):
super(Networks, self).__init__(model)
diff --git a/src/kimchi/control/storagepools.py b/src/kimchi/control/storagepools.py
index 2adaa30..8c8b522 100644
--- a/src/kimchi/control/storagepools.py
+++ b/src/kimchi/control/storagepools.py
@@ -28,7 +28,7 @@
from kimchi.control.utils import UrlSubNode
-@UrlSubNode("storagepools", True, ['PUT', 'POST',
'DELETE'])
+@UrlSubNode('storagepools', True, ['PUT', 'POST',
'DELETE'], 'storage')
class StoragePools(Collection):
def __init__(self, model):
super(StoragePools, self).__init__(model)
diff --git a/src/kimchi/control/storageservers.py b/src/kimchi/control/storageservers.py
index 068f9ae..9c7bebc 100644
--- a/src/kimchi/control/storageservers.py
+++ b/src/kimchi/control/storageservers.py
@@ -22,7 +22,7 @@
from kimchi.control.utils import get_class_name, model_fn, UrlSubNode
-@UrlSubNode("storageservers", True, ['GET'])
+@UrlSubNode('storageservers', True, ['GET'], 'storage')
class StorageServers(Collection):
def __init__(self, model):
super(StorageServers, self).__init__(model)
diff --git a/src/kimchi/control/templates.py b/src/kimchi/control/templates.py
index 7a203a5..907929f 100644
--- a/src/kimchi/control/templates.py
+++ b/src/kimchi/control/templates.py
@@ -21,7 +21,7 @@
from kimchi.control.utils import UrlSubNode
-@UrlSubNode("templates", True, ['GET', 'PUT', 'POST',
'DELETE'])
+@UrlSubNode('templates', True, ['GET', 'PUT', 'POST',
'DELETE'], 'templates')
class Templates(Collection):
def __init__(self, model):
super(Templates, self).__init__(model)
diff --git a/src/kimchi/control/utils.py b/src/kimchi/control/utils.py
index 5154910..aa592ef 100644
--- a/src/kimchi/control/utils.py
+++ b/src/kimchi/control/utils.py
@@ -107,18 +107,20 @@ def validate_params(params, instance, action):
class UrlSubNode(object):
- def __init__(self, name, auth=False, admin_methods=None):
+ def __init__(self, name, auth=False, admin_methods=None, tab=None):
"""
admin_methods must be None, or a list containing zero or more of the
string values ['GET', 'POST', 'PUT', 'DELETE']
"""
self.name = name
self.auth = auth
+ self.tab = tab
self.admin_methods = admin_methods
def __call__(self, fun):
fun._url_sub_node_name = {"name": self.name}
fun.url_auth = self.auth
+ fun.tab = self.tab
fun.admin_methods = self.admin_methods
return fun
diff --git a/src/kimchi/control/vms.py b/src/kimchi/control/vms.py
index 508f478..cf427fa 100644
--- a/src/kimchi/control/vms.py
+++ b/src/kimchi/control/vms.py
@@ -22,7 +22,7 @@
from kimchi.control.vm import sub_nodes
-@UrlSubNode("vms", True, ['POST', 'PUT', 'DELETE'])
+@UrlSubNode('vms', True, ['POST', 'PUT', 'DELETE'],
'guests')
class VMs(Collection):
def __init__(self, model):
super(VMs, self).__init__(model)
diff --git a/src/kimchi/server.py b/src/kimchi/server.py
index 7344349..b0e9474 100644
--- a/src/kimchi/server.py
+++ b/src/kimchi/server.py
@@ -130,6 +130,7 @@ def __init__(self, options):
ident = "/%s" % ident
cfg[ident] = {'tools.kimchiauth.on': True}
if node.admin_methods:
+ cfg[ident]['tools.kimchiauth.tab'] = node.tab
cfg[ident][
'tools.kimchiauth.admin_methods'] = node.admin_methods