[Kimchi-devel] [PATCHv2 5/7] Split users and groups for permission query

lvroyce0210 at gmail.com lvroyce0210 at gmail.com
Tue Oct 28 13:37:43 UTC 2014


From: Royce Lv <lvroyce at linux.vnet.ibm.com>

Put ldap validation in a single function to resue in authorization.
Tested:
1. LDAP:
    GET /host/users?_user_id=a_valid_user_id
    GET /host/users?_user_id=invalid_user_id
    GET /host/groups
2. PAM:
    GET /host/users
    GET /host/groups

Signed-off-by: Royce Lv <lvroyce at linux.vnet.ibm.com>
---
 src/kimchi/control/host.py |  7 +++++
 src/kimchi/i18n.py         |  1 +
 src/kimchi/model/host.py   | 67 ++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/src/kimchi/control/host.py b/src/kimchi/control/host.py
index 7bcae72..20d4c2f 100644
--- a/src/kimchi/control/host.py
+++ b/src/kimchi/control/host.py
@@ -20,6 +20,7 @@
 import cherrypy
 
 from kimchi.control.base import Collection, Resource, SimpleCollection
+from kimchi.control.utils import get_class_name, model_fn
 from kimchi.control.utils import UrlSubNode, validate_method
 from kimchi.exception import OperationFailed, NotFoundError
 from kimchi.template import render
@@ -178,6 +179,12 @@ class Users(SimpleCollection):
         super(Users, self).__init__(model)
         self.role_key = 'guests'
 
+    def get(self, filter_params):
+        res_list = []
+        get_list = getattr(self.model, model_fn(self, 'get_list'))
+        res_list = get_list(*self.model_args, **filter_params)
+        return render(get_class_name(self), res_list)
+
 
 class Groups(SimpleCollection):
     def __init__(self, model):
diff --git a/src/kimchi/i18n.py b/src/kimchi/i18n.py
index 75fb076..27c0f44 100644
--- a/src/kimchi/i18n.py
+++ b/src/kimchi/i18n.py
@@ -39,6 +39,7 @@ messages = {
     "KCHAUTH0001E": _("Authentication failed for user '%(username)s'. [Error code: %(code)s]"),
     "KCHAUTH0002E": _("You are not authorized to access Kimchi"),
     "KCHAUTH0003E": _("Specify %(item)s to login into Kimchi"),
+    "KCHAUTH0004E": _("User %(user_id)s not found with given ldap settings."),
 
     "KCHDEVS0001E": _('Unknown "_cap" specified'),
     "KCHDEVS0002E": _('"_passthrough" should be "true" or "false"'),
diff --git a/src/kimchi/model/host.py b/src/kimchi/model/host.py
index 5d31809..a2f0941 100644
--- a/src/kimchi/model/host.py
+++ b/src/kimchi/model/host.py
@@ -18,6 +18,7 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
 
 import grp
+import ldap
 import libvirt
 import os
 import time
@@ -32,6 +33,7 @@ from kimchi import disks
 from kimchi import netinfo
 from kimchi import xmlutils
 from kimchi.basemodel import Singleton
+from kimchi.config import config
 from kimchi.model import hostdev
 from kimchi.exception import InvalidOperation, InvalidParameter
 from kimchi.exception import NotFoundError, OperationFailed
@@ -459,17 +461,78 @@ class RepositoryModel(object):
 
 
 class UsersModel(object):
+    def __init__(self, **args):
+        auth_type = config.get("authentication", "method")
+        for klass in UsersModel.__subclasses__():
+            if auth_type == klass.auth_type:
+                self.user = klass(**args)
+
+    def get_list(self, **args):
+        return self.user._get_list(**args)
+
+
+class PAMUsersModel(UsersModel):
+    auth_type = 'pam'
     def __init__(self, **kargs):
         pass
 
-    def get_list(self):
+    def _get_list(self):
         return [user.pw_name for user in pwd.getpwall()
                 if user.pw_shell.rsplit("/")[-1] not in ["nologin", "false"]]
 
 
+class LDAPUsersModel(UsersModel):
+    auth_type = 'ldap'
+    def __init__(self, **kargs):
+        pass
+
+    def _get_list(self, _user_id=''):
+        return self._get_user(_user_id)
+
+    def _get_user(self, _user_id):
+        ldap_server = config.get("authentication", "ldap_server").strip('"')
+        ldap_search_base = config.get(
+            "authentication", "ldap_search_base").strip('"')
+        ldap_search_filter = config.get(
+            "authentication", "ldap_search_filter",
+            vars={"username": _user_id.encode("utf-8")}).strip('"')
+
+        connect = ldap.open(ldap_server)
+        try:
+            result = connect.search_s(
+                ldap_search_base, ldap.SCOPE_SUBTREE, ldap_search_filter)
+            if len(result) == 0:
+                raise NotFoundError("KCHAUTH0004E", {'user_id': _user_id})
+            return result[0][1]
+        except ldap.NO_SUCH_OBJECT:
+            raise NotFoundError("KCHAUTH0004E", {'user_id': _user_id})
+
+
 class GroupsModel(object):
+    def __init__(self, **args):
+        auth_type = config.get("authentication", "method")
+        for klass in GroupsModel.__subclasses__():
+            if auth_type == klass.auth_type:
+                self.grp = klass(**args)
+
+
+    def get_list(self, **args):
+        if hasattr(self.grp, '_get_list'):
+            return self.grp._get_list(**args)
+        else:
+            return list()
+
+
+class PAMGroupsModel(GroupsModel):
+    auth_type = 'pam'
     def __init__(self, **kargs):
         pass
 
-    def get_list(self):
+    def _get_list(self):
         return [group.gr_name for group in grp.getgrall()]
+
+
+class LDAPGroupsModel(GroupsModel):
+    auth_type = 'ldap'
+    def __init__(self, **kargs):
+        pass
-- 
1.8.3.2




More information about the Kimchi-devel mailing list