source: TI12-security/trunk/python/ndg.security.common/ndg/security/common/utils/classfactory.py @ 5330

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/python/ndg.security.common/ndg/security/common/utils/classfactory.py@5330
Revision 5330, 4.6 KB checked in by pjkersha, 11 years ago (diff)

Completed AuthorizationMiddleware? unit tests ndg.security.test.unit.wsgi.authz:

  • Test 8, 'test08AccessDeniedForAdminQueryArg' tries out the use case for a URI which can display additional content for users with admin privileges. The caller needs to be able to display the correct content according to whether the user has admin rights or not:
    1. the caller invokes /securedURI?admin=1
    2. if the user has admin, rights the PDP will grant access and the PEP will deliver this URI.
    3. if the user doesn't have admin rights, a special overloaded PEP result handler class detects that access was denied for the admin URI and redirects the user to a modified URI subtracting the admin flag. The application code can then deliver the appropriate content minus admin privileges.
Line 
1"""
2Generic parsers to use when reading in configuration data
3- methods available to deal with both XML and INI (flat text key/val) formats
4"""
5__author__ = "C Byrom - Tessella"
6__date__ = "28/08/08"
7__copyright__ = "(C) 2009 Science and Technology Facilities Council"
8__license__ = "BSD - see LICENSE file in top-level directory"
9__contact__ = "Philip.Kershaw@stfc.ac.uk"
10__revision__ = '$Id$'
11
12import logging, os, sys
13log = logging.getLogger(__name__)
14
15class ClassFactoryError(Exception):
16    """Exception handling for NDG classfactory module."""
17    def __init__(self, msg):
18        log.error(msg)
19        Exception.__init__(self, msg)
20
21def importClass(moduleName, className=None, objectType=None):
22    '''Import a class from a string module name and class name.
23   
24    @param moduleName: Name of module containing the class
25    @type moduleName: str
26    @param className: Name of the class to import.  If none is given, the
27    class name will be assumed to be the last component of modulePath
28    @type className: str
29    @rtype: class object
30    @return: imported class'''
31   
32    if className is None:
33        _moduleName, className = moduleName.rsplit('.', 1)
34    else:
35        _moduleName = moduleName
36           
37    module = __import__(_moduleName)
38    components = _moduleName.split('.')
39    for component in components[1:]:
40        module = getattr(module, component)
41
42    importedClass = getattr(module, className)
43
44    # Check class inherits from a base class
45    if objectType and not issubclass(importedClass, objectType):
46        raise TypeError("Specified class %s must be derived from %s; got %s" %
47                        (className, objectType, importedClass))
48   
49    log.info('Imported "%s" class from module, "%s"', className, moduleName)
50    return importedClass
51   
52
53def instantiateClass(moduleName, className, moduleFilePath=None, 
54                     objectType=None, classArgs=(), classProperties={}):
55    '''
56    Create and return an instance of the specified class
57    @param moduleName: Name of module containing the class
58    @type moduleName: str
59    @param className: Name of the class to instantiate.  May be None in
60    which case, the class name is parsed from the moduleName last element
61    @type className: str
62    @keyword moduleFilePath: Path to the module - if unset, assume module on
63    system path already
64    @type moduleFilePath: str
65    @keyword classProperties: dict of properties to use when instantiating the
66    class
67    @type classProperties: dict
68    @keyword objectType: expected type for the object to instantiate - to
69    enforce use of specific interfaces
70    @type objectType: object
71    @return: object - instance of the class specified
72    '''
73
74    log.debug("Instantiating class '%s'" % className)
75   
76    # ensure that classproperties is a dict - NB, it may be passed in as a null
77    # value which can override the default val
78    if not classProperties:
79        classProperties = {}
80
81    # variable to store original state of the system path
82    sysPathBak = None
83    try:
84        try:
85            # Module file path may be None if the new module to be loaded
86            # can be found in the existing system path           
87            if moduleFilePath:
88                if not os.path.exists(moduleFilePath):
89                    raise IOError("Module file path '%s' doesn't exist" % 
90                                  moduleFilePath)
91                         
92                # Temporarily extend system path ready for import
93                sysPathBak = sys.path
94                         
95                sys.path.append(moduleFilePath)
96
97           
98            # Import module name specified in properties file
99            importedClass = importClass(moduleName, 
100                                        className=className,
101                                        objectType=objectType)
102        finally:
103            # revert back to original sys path, if necessary
104            # NB, python requires the use of a try/finally OR a try/except
105            # block - not both combined
106            if sysPathBak:
107                sys.path = sysPathBak
108                           
109    except Exception, e:
110        log.error('%s module import raised %s type exception: %s' % 
111                  (moduleName, e.__class__, e))
112        raise 
113
114    # Instantiate class
115    try:
116        if classArgs:
117            object = importedClass(*classArgs, **classProperties)
118        else:
119            object = importedClass(**classProperties)
120           
121        return object
122
123    except Exception, e:
124        log.error("Instantiating class, %s: %s" % (importedClass.__name__, e))
125        raise
126           
127                 
Note: See TracBrowser for help on using the repository browser.