[Kimchi-devel] [PATCHv2 2/7] Split PAM and LDAP authentication

Royce Lv lvroyce at linux.vnet.ibm.com
Thu Nov 6 06:13:48 UTC 2014


On 2014年10月31日 00:50, Aline Manera wrote:
>
> On 10/28/2014 11:37 AM, lvroyce0210 at gmail.com wrote:
>> From: Royce Lv <lvroyce at linux.vnet.ibm.com>
>>
>> Split PAM authentication implementation and abstract a common class.
>>
>> Signed-off-by: Royce Lv <lvroyce at linux.vnet.ibm.com>
>> ---
>> src/kimchi/auth.py | 113 
>> ++++++++++++++++++++++++++++++++++-------------------
>> 1 file changed, 73 insertions(+), 40 deletions(-)
>>
>> diff --git a/src/kimchi/auth.py b/src/kimchi/auth.py
>> index c8801a5..ad3f3ac 100644
>> --- a/src/kimchi/auth.py
>> +++ b/src/kimchi/auth.py
>> @@ -31,6 +31,7 @@ import urllib2
>>
>>
>> from kimchi import template
>> +from kimchi.config import config
>> from kimchi.exception import InvalidOperation, OperationFailed
>> from kimchi.utils import get_all_tabs, run_command
>>
>> @@ -39,6 +40,7 @@ USER_NAME = 'username'
>> USER_GROUPS = 'groups'
>> USER_ROLES = 'roles'
>> REFRESH = 'robot-refresh'
>> +AUTH = 'auth_method'
>>
>> tabs = get_all_tabs()
>>
>> @@ -59,6 +61,22 @@ def debug(msg):
>>
>>
>> class User(object):
>> + @classmethod
>> + def create(cls, auth_args):
>
> "create" seems we will create an user which it is not true.
> Change it to "get"
ACK
>
>> + auth_type = auth_args.pop('auth_type')
>> + for klass in cls.__subclasses__():
>> + if auth_type == klass.auth_type:
>> + try:
>> + if not klass.authenticate(**auth_args):
>> + debug("cannot verify user with the given password")
>> + return None
>> + except OperationFailed:
>> + raise
>> + return klass(auth_args['username'])
>> +
>> +
>> +class PAMUser(User):
>> + auth_type = "pam"
>>
>> def __init__(self, username):
>> self.user = {}
>> @@ -124,40 +142,54 @@ class User(object):
>> def get_user(self):
>> return self.user
>>
>> + @staticmethod
>> + def authenticate(username, password, service="passwd"):
>> + '''Returns True if authenticate is OK via PAM.'''
>> + def _pam_conv(auth, query_list, userData=None):
>> + resp = []
>> + for i in range(len(query_list)):
>> + query, qtype = query_list[i]
>> + if qtype == PAM.PAM_PROMPT_ECHO_ON:
>> + resp.append((username, 0))
>> + elif qtype == PAM.PAM_PROMPT_ECHO_OFF:
>> + resp.append((password, 0))
>> + elif qtype == PAM.PAM_PROMPT_ERROR_MSG:
>> + cherrypy.log.error_log.error(
>> + "PAM authenticate prompt error: %s" % query)
>> + resp.append(('', 0))
>> + elif qtype == PAM.PAM_PROMPT_TEXT_INFO:
>> + resp.append(('', 0))
>> + else:
>> + return None
>> + return resp
>> +
>> + auth = PAM.pam()
>> + auth.start(service)
>> + auth.set_item(PAM.PAM_USER, username)
>> + auth.set_item(PAM.PAM_CONV, _pam_conv)
>> + try:
>> + auth.authenticate()
>> + except PAM.error, (resp, code):
>> + msg_args = {'username': username, 'code': code}
>> + raise OperationFailed("KCHAUTH0001E", msg_args)
>>
>> -def authenticate(username, password, service="passwd"):
>> - '''Returns True if authenticate is OK via PAM.'''
>> - def _pam_conv(auth, query_list, userData=None):
>> - resp = []
>> - for i in range(len(query_list)):
>> - query, qtype = query_list[i]
>> - if qtype == PAM.PAM_PROMPT_ECHO_ON:
>> - resp.append((username, 0))
>> - elif qtype == PAM.PAM_PROMPT_ECHO_OFF:
>> - resp.append((password, 0))
>> - elif qtype == PAM.PAM_PROMPT_ERROR_MSG:
>> - cherrypy.log.error_log.error("PAM authenticate prompt error "
>> - "message: %s" % query)
>> - resp.append(('', 0))
>> - elif qtype == PAM.PAM_PROMPT_TEXT_INFO:
>> - resp.append(('', 0))
>> - else:
>> - return None
>> - return resp
>> -
>> - auth = PAM.pam()
>> - auth.start(service)
>> - auth.set_item(PAM.PAM_USER, username)
>> - auth.set_item(PAM.PAM_CONV, _pam_conv)
>> -
>> - try:
>> - auth.authenticate()
>> - except PAM.error:
>> - raise
>> -
>> - return True
>> + return True
>>
>>
>> +class LDAPUser(User):
>> + auth_type = "ldap"
>> + def __init__(self, username):
>> + self.user = {}
>> + self.user[USER_NAME] = username
>> + self.user[USER_GROUPS] = None
>> + # FIXME: user roles will be changed according roles assignment after
>> + # objstore is integrated
>> + self.user[USER_ROLES] = dict.fromkeys(tabs, 'user')
>> +
>> + @staticmethod
>> + def authenticate(username, password):
>> + return False
>> +
>> def from_browser():
>> # Enable Basic Authentication for REST tools.
>> # Ajax request sent from jQuery in browser will have "X-Requested-With"
>> @@ -216,21 +248,22 @@ def check_auth_httpba():
>>
>>
>> def login(username, password, **kwargs):
>> - try:
>> - if not authenticate(username, password):
>> - debug("User cannot be verified with the supplied password")
>> - return None
>> - except PAM.error, (resp, code):
>> - msg_args = {'username': username, 'code': code}
>> - raise OperationFailed("KCHAUTH0001E", msg_args)
>> -
>> - user = User(username)
>> + auth_args = {'auth_type': config.get("authentication", "method"),
>> + 'username': username,
>> + 'password': password}
>> +
>> + user = User.create(auth_args)
>> + if not user:
>> + debug("User cannot be verified with the supplied password")
>> + return None
>> +
>> debug("User verified, establishing session")
>> cherrypy.session.acquire_lock()
>> cherrypy.session.regenerate()
>> cherrypy.session[USER_NAME] = username
>> cherrypy.session[USER_GROUPS] = user.get_groups()
>> cherrypy.session[USER_ROLES] = user.get_roles()
>> + cherrypy.session[AUTH] = config.get("authentication", "method")
>> cherrypy.session[REFRESH] = time.time()
>> cherrypy.session.release_lock()
>> return user.get_user()
>
> _______________________________________________
> Kimchi-devel mailing list
> Kimchi-devel at ovirt.org
> http://lists.ovirt.org/mailman/listinfo/kimchi-devel
>




More information about the Kimchi-devel mailing list