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

Aline Manera alinefm at linux.vnet.ibm.com
Thu Oct 30 17:02:20 UTC 2014


On 10/28/2014 11:37 AM, lvroyce0210 at gmail.com wrote:
> 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

As we will use the same API for LDAP and PAM, I suggest change the API 
/host/users to /users and /host/groups to /groups.
Originally, /host/users and /host.groups were created because they are 
related to the host system which is not the case for LDAP config.

>
> 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."),

LDAP

>       "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




More information about the Kimchi-devel mailing list