summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2008-10-08 23:31:49 -0400
committerRob Crittenden <rcritten@redhat.com>2008-10-10 03:36:56 -0400
commit83bb41faebc0a61269f2869e9123166254fff5b3 (patch)
treecfb1e62a7e770c35d230ed778b5808a221234fcf
parent672c07566df8d838b46edb6b80ba73ade2a27d55 (diff)
downloadfreeipa-83bb41faebc0a61269f2869e9123166254fff5b3.tar.gz
freeipa-83bb41faebc0a61269f2869e9123166254fff5b3.tar.xz
freeipa-83bb41faebc0a61269f2869e9123166254fff5b3.zip
Mechanism to convert from xmlrpclib.Fault to an IPAError exception
Include slew of new exceptions, not all of which are used yet
-rw-r--r--ipa_server/ipaldap.py17
-rw-r--r--ipa_server/servercore.py3
-rw-r--r--ipalib/errors.py137
-rw-r--r--ipalib/plugins/b_xmlrpc.py3
-rw-r--r--ipalib/plugins/f_user.py48
5 files changed, 173 insertions, 35 deletions
diff --git a/ipa_server/ipaldap.py b/ipa_server/ipaldap.py
index 7ee31465c..a76040213 100644
--- a/ipa_server/ipaldap.py
+++ b/ipa_server/ipaldap.py
@@ -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):
diff --git a/ipa_server/servercore.py b/ipa_server/servercore.py
index a391c5cf9..d842a8c77 100644
--- a/ipa_server/servercore.py
+++ b/ipa_server/servercore.py
@@ -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
diff --git a/ipalib/errors.py b/ipalib/errors.py
index 097747ac7..c00db9dc6 100644
--- a/ipalib/errors.py
+++ b/ipalib/errors.py
@@ -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
diff --git a/ipalib/plugins/b_xmlrpc.py b/ipalib/plugins/b_xmlrpc.py
index feb87556b..442afebfd 100644
--- a/ipalib/plugins/b_xmlrpc.py
+++ b/ipalib/plugins/b_xmlrpc.py
@@ -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)
diff --git a/ipalib/plugins/f_user.py b/ipalib/plugins/f_user.py
index f87ddea1f..8a1c3045d 100644
--- a/ipalib/plugins/f_user.py
+++ b/ipalib/plugins/f_user.py
@@ -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)