Mechanism to convert from xmlrpclib.Fault to an IPAError exception
Include slew of new exceptions, not all of which are used yet
This commit is contained in:
1 parent
672c07566d
commit
83bb41faeb
5 files changed
+173
-35
No files matched your search
@@ -32,7 +32,7 @@ import ldap.sasl
|
||||
from ldap.controls import LDAPControl,DecodeControlTuples,EncodeControlTuples
|
||||
from ldap.ldapobject import SimpleLDAPObject
|
||||
from ipa_server import ipautil
|
||||
|
||||
from ipalib import errors
|
||||
|
||||
# Global variable to define SASL auth
|
||||
sasl_auth = ldap.sasl.sasl({},'GSSAPI')
|
||||
@@ -279,12 +279,12 @@ class IPAdmin(SimpleLDAPObject):
|
||||
res = self.search(*args)
|
||||
objtype, obj = self.result(res)
|
||||
except ldap.NO_SUCH_OBJECT, e:
|
||||
raise e
|
||||
raise errors.NotFound, notfound(args)
|
||||
except ldap.LDAPError, e:
|
||||
raise e
|
||||
raise errors.DatabaseError, e
|
||||
|
||||
if not obj:
|
||||
raise ldap.NO_SUCH_OBJECT
|
||||
raise errors.NotFound, notfound(args)
|
||||
|
||||
elif isinstance(obj,Entry):
|
||||
return obj
|
||||
@@ -308,7 +308,7 @@ class IPAdmin(SimpleLDAPObject):
|
||||
raise e
|
||||
|
||||
if not obj:
|
||||
raise ldap.NO_SUCH_OBJECT
|
||||
raise errors.NotFound, notfound(args)
|
||||
|
||||
entries = []
|
||||
for s in obj:
|
||||
@@ -345,7 +345,7 @@ class IPAdmin(SimpleLDAPObject):
|
||||
raise e
|
||||
|
||||
if not entries:
|
||||
raise ldap.NO_SUCH_OBJECT
|
||||
raise errors.NotFound, notfound(args)
|
||||
|
||||
if partial == 1:
|
||||
counter = -1
|
||||
@@ -408,10 +408,9 @@ class IPAdmin(SimpleLDAPObject):
|
||||
# it indicates the previous attribute was removed by another
|
||||
# update, making the oldentry stale.
|
||||
except ldap.NO_SUCH_ATTRIBUTE:
|
||||
# FIXME: better error
|
||||
raise SyntaxError("mid-air collision")
|
||||
raise ipaldap.MidairCollision
|
||||
except ldap.LDAPError, e:
|
||||
raise e
|
||||
raise ipaldap.DatabaseError, e
|
||||
return True
|
||||
|
||||
def generateModList(self, old_entry, new_entry):
|
||||
|
||||
@@ -22,6 +22,7 @@ import string
|
||||
import re
|
||||
from ipa_server.context import context
|
||||
import ipautil
|
||||
from ipalib import errors
|
||||
|
||||
# temporary
|
||||
import krbV
|
||||
@@ -335,6 +336,6 @@ def get_ipa_config():
|
||||
config = get_sub_entry("cn=etc," + basedn, searchfilter)
|
||||
except ldap.NO_SUCH_OBJECT, e:
|
||||
# FIXME
|
||||
raise e
|
||||
raise errors.NotFound
|
||||
|
||||
return config
|
||||
@@ -240,3 +240,140 @@ class MissingOverrideError(RegistrationError):
|
||||
|
||||
def __str__(self):
|
||||
return self.msg % (self.base.__name__, self.cls.__name__, self.cls)
|
||||
|
||||
class GenericError(IPAError):
|
||||
"""Base class for our custom exceptions"""
|
||||
faultCode = 1000
|
||||
fromFault = False
|
||||
def __str__(self):
|
||||
try:
|
||||
return str(self.args[0]['args'][0])
|
||||
except:
|
||||
try:
|
||||
return str(self.args[0])
|
||||
except:
|
||||
return str(self.__dict__)
|
||||
|
||||
class DatabaseError(GenericError):
|
||||
"""A database error has occurred"""
|
||||
faultCode = 1001
|
||||
|
||||
class MidairCollision(GenericError):
|
||||
"""Change collided with another change"""
|
||||
faultCode = 1002
|
||||
|
||||
class NotFound(GenericError):
|
||||
"""Entry not found"""
|
||||
faultCode = 1003
|
||||
|
||||
class Duplicate(GenericError):
|
||||
"""This entry already exists"""
|
||||
faultCode = 1004
|
||||
|
||||
class MissingDN(GenericError):
|
||||
"""The distinguished name (DN) is missing"""
|
||||
faultCode = 1005
|
||||
|
||||
class EmptyModlist(GenericError):
|
||||
"""No modifications to be performed"""
|
||||
faultCode = 1006
|
||||
|
||||
class InputError(GenericError):
|
||||
"""Error on input"""
|
||||
faultCode = 1007
|
||||
|
||||
class SameGroupError(InputError):
|
||||
"""You can't add a group to itself"""
|
||||
faultCode = 1008
|
||||
|
||||
class AdminsImmutable(InputError):
|
||||
"""The admins group cannot be renamed"""
|
||||
faultCode = 1009
|
||||
|
||||
class UsernameTooLong(InputError):
|
||||
"""The requested username is too long"""
|
||||
faultCode = 1010
|
||||
|
||||
class PrincipalError(GenericError):
|
||||
"""There is a problem with the kerberos principal"""
|
||||
faultCode = 1011
|
||||
|
||||
class MalformedServicePrincipal(PrincipalError):
|
||||
"""The requested service principal is not of the form: service/fully-qualified host name"""
|
||||
faultCode = 1012
|
||||
|
||||
class RealmMismatch(PrincipalError):
|
||||
"""The realm for the principal does not match the realm for this IPA server"""
|
||||
faultCode = 1013
|
||||
|
||||
class PrincipalRequired(PrincipalError):
|
||||
"""You cannot remove IPA server service principals"""
|
||||
faultCode = 1014
|
||||
|
||||
class InactivationError(GenericError):
|
||||
"""This entry cannot be inactivated"""
|
||||
faultCode = 1015
|
||||
|
||||
class ConnectionError(GenericError):
|
||||
"""Connection to database failed"""
|
||||
faultCode = 1016
|
||||
|
||||
class NoCCacheError(GenericError):
|
||||
"""No Kerberos credentials cache is available. Connection cannot be made"""
|
||||
faultCode = 1017
|
||||
|
||||
class GSSAPIError(GenericError):
|
||||
"""GSSAPI Authorization error"""
|
||||
faultCode = 1018
|
||||
|
||||
class ServerUnwilling(GenericError):
|
||||
"""Account inactivated. Server is unwilling to perform"""
|
||||
faultCode = 1018
|
||||
|
||||
class ConfigurationError(GenericError):
|
||||
"""A configuration error occurred"""
|
||||
faultCode = 1019
|
||||
|
||||
class DefaultGroup(ConfigurationError):
|
||||
"""You cannot remove the default users group"""
|
||||
faultCode = 1020
|
||||
|
||||
class FunctionDeprecated(GenericError):
|
||||
"""Raised by a deprecated function"""
|
||||
faultCode = 2000
|
||||
|
||||
def convertFault(fault):
|
||||
"""Convert a fault to the corresponding Exception type, if possible"""
|
||||
code = getattr(fault,'faultCode',None)
|
||||
if code is None:
|
||||
return fault
|
||||
for v in globals().values():
|
||||
if type(v) == type(Exception) and issubclass(v,GenericError) and \
|
||||
code == getattr(v,'faultCode',None):
|
||||
ret = v(fault.faultString)
|
||||
ret.fromFault = True
|
||||
return ret
|
||||
#otherwise...
|
||||
return fault
|
||||
|
||||
def listFaults():
|
||||
"""Return a list of faults
|
||||
|
||||
Returns a list of dictionaries whose keys are:
|
||||
faultCode: the numeric code used in fault conversion
|
||||
name: the name of the exception
|
||||
desc: the description of the exception (docstring)
|
||||
"""
|
||||
ret = []
|
||||
for n,v in globals().items():
|
||||
if type(v) == type(Exception) and issubclass(v,GenericError):
|
||||
code = getattr(v,'faultCode',None)
|
||||
if code is None:
|
||||
continue
|
||||
info = {}
|
||||
info['faultCode'] = code
|
||||
info['name'] = n
|
||||
info['desc'] = getattr(v,'__doc__',None)
|
||||
ret.append(info)
|
||||
ret.sort(lambda a,b: cmp(a['faultCode'],b['faultCode']))
|
||||
return ret
|
||||
@@ -29,6 +29,7 @@ import socket
|
||||
from ipalib.backend import Backend
|
||||
from ipalib.util import xmlrpc_marshal
|
||||
from ipalib import api
|
||||
from ipalib import errors
|
||||
|
||||
class xmlrpc(Backend):
|
||||
"""
|
||||
@@ -51,5 +52,7 @@ class xmlrpc(Backend):
|
||||
except socket.error, e:
|
||||
print e[1]
|
||||
return False
|
||||
except xmlrpclib.Fault, e:
|
||||
raise errors.convertFault(e)
|
||||
|
||||
api.register(xmlrpc)
|
||||
+23
-25
@@ -25,6 +25,7 @@ from ipalib import frontend
|
||||
from ipalib import crud
|
||||
from ipalib.frontend import Param
|
||||
from ipalib import api
|
||||
from ipalib import errors
|
||||
from ipa_server import servercore
|
||||
from ipa_server import ipaldap
|
||||
import ldap
|
||||
@@ -32,7 +33,7 @@ import ldap
|
||||
# Command to get the idea how plugins will interact with api.env
|
||||
class envtest(frontend.Command):
|
||||
'Show current environment.'
|
||||
def run(*args, **kw):
|
||||
def run(self, *args, **kw):
|
||||
print ""
|
||||
print "Environment variables:"
|
||||
for var in api.env:
|
||||
@@ -87,18 +88,12 @@ class user_add(crud.Add):
|
||||
|
||||
user = kw
|
||||
|
||||
if not isinstance(user, dict):
|
||||
# FIXME, need proper error
|
||||
raise SyntaxError
|
||||
|
||||
user['uid'] = args[0]
|
||||
|
||||
if servercore.user_exists(user['uid']):
|
||||
# FIXME, specific error
|
||||
raise SyntaxError("user already exists")
|
||||
raise errors.Duplicate("user already exists")
|
||||
if servercore.uid_too_long(user['uid']):
|
||||
# FIXME, specific error
|
||||
raise SyntaxError("uid is too long")
|
||||
raise errors.UsernameTooLong
|
||||
|
||||
# dn is set here, not by the user
|
||||
try:
|
||||
@@ -139,17 +134,15 @@ class user_add(crud.Add):
|
||||
default_group = servercore.get_entry_by_dn(group_dn, ['dn','gidNumber'])
|
||||
if default_group:
|
||||
user['gidnumber'] = default_group.get('gidnumber')
|
||||
# except ipaerror.exception_for(ipaerror.LDAP_DATABASE_ERROR), e:
|
||||
# raise ipaerror.gen_exception(ipaerror.LDAP_DATABASE_ERROR, message=None, nested_exception=e.detail)
|
||||
# except ipaerror.exception_for(ipaerror.LDAP_NOT_FOUND):
|
||||
# # Fake an LDAP error so we can return something useful to the user
|
||||
# raise ipaerror.gen_exception(ipaerror.LDAP_NOT_FOUND, "The default group for new users, '%s', cannot be found." % config.get('ipadefaultprimarygroup'))
|
||||
except errors.NotFound:
|
||||
# Fake an LDAP error so we can return something useful to the user
|
||||
raise ipalib.NotFound, "The default group for new users, '%s', cannot be found." % config.get('ipadefaultprimarygroup')
|
||||
except Exception, e:
|
||||
# FIXME
|
||||
# catch everything else
|
||||
raise e
|
||||
|
||||
if user.get('krbprincipalname') is None:
|
||||
user['krbprincipalname'] = "%s@%s" % (user.get('uid'), self.realm)
|
||||
user['krbprincipalname'] = "%s@%s" % (user.get('uid'), servercore.realm)
|
||||
|
||||
# FIXME. This is a hack so we can request separate First and Last
|
||||
# name in the GUI.
|
||||
@@ -169,7 +162,7 @@ class user_add(crud.Add):
|
||||
return result
|
||||
def forward(self, *args, **kw):
|
||||
result = super(crud.Add, self).forward(*args, **kw)
|
||||
if result != False:
|
||||
if result:
|
||||
print "User %s added" % args[0]
|
||||
|
||||
api.register(user_add)
|
||||
@@ -190,17 +183,18 @@ class user_del(crud.Del):
|
||||
"""
|
||||
uid = args[0]
|
||||
if uid == "admin":
|
||||
raise ipaerror.gen_exception(ipaerror.INPUT_ADMIN_REQUIRED)
|
||||
# FIXME: do we still want a "special" user?
|
||||
raise SyntaxError("admin required")
|
||||
# raise ipaerror.gen_exception(ipaerror.INPUT_ADMIN_REQUIRED)
|
||||
# logging.info("IPA: delete_user '%s'" % uid)
|
||||
user = servercore.get_user_by_uid(uid, ['dn', 'uid'])
|
||||
if not user:
|
||||
# FIXME, specific error
|
||||
raise SyntaxError("user doesn't exist")
|
||||
raise errors.NotFound
|
||||
|
||||
return servercore.delete_entry(user['dn'])
|
||||
def forward(self, *args, **kw):
|
||||
result = super(crud.Del, self).forward(*args, **kw)
|
||||
if result != False:
|
||||
if result:
|
||||
print "User %s removed" % args[0]
|
||||
api.register(user_del)
|
||||
|
||||
@@ -224,7 +218,7 @@ class user_mod(crud.Mod):
|
||||
return result
|
||||
def forward(self, *args, **kw):
|
||||
result = super(crud.Mod, self).forward(*args, **kw)
|
||||
if result != False:
|
||||
if result:
|
||||
print "User %s modified" % args[0]
|
||||
api.register(user_mod)
|
||||
|
||||
@@ -259,7 +253,11 @@ class user_show(crud.Get):
|
||||
result = servercore.get_user_by_uid(uid, ["*"])
|
||||
return result
|
||||
def forward(self, *args, **kw):
|
||||
result = super(crud.Get, self).forward(*args, **kw)
|
||||
for a in result:
|
||||
print a, ": ", result[a]
|
||||
try:
|
||||
result = super(crud.Get, self).forward(*args, **kw)
|
||||
if not result: return
|
||||
for a in result:
|
||||
print a, ": ", result[a]
|
||||
except errors.NotFound:
|
||||
print "User %s not found" % args[0]
|
||||
api.register(user_show)
|
||||
Reference in new issue
Block a user