source: TI12-security/trunk/NDGSecurity/python/ndg_security_common/ndg/security/common/authz/pip/esginterface.py @ 6598

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI12-security/trunk/NDGSecurity/python/ndg_security_common/ndg/security/common/authz/pip/esginterface.py@6598
Revision 6598, 6.3 KB checked in by pjkersha, 11 years ago (diff)

Renamed PIP modules to avoid ndg name clash.

Line 
1"""PIP with interface to SAML 2.0 Attribute Authority as used with ESG
2
3NERC DataGrid Project
4"""
5__author__ = "P J Kershaw"
6__date__ = "19/02/10"
7__copyright__ = "(C) 2010 Science and Technology Facilities Council"
8__contact__ = "Philip.Kershaw@stfc.ac.uk"
9__license__ = "BSD - see LICENSE file in top-level directory"
10__contact__ = "Philip.Kershaw@stfc.ac.uk"
11__revision__ = "$Id: $"
12import traceback
13import logging
14log = logging.getLogger(__name__)
15
16from os import path
17from ConfigParser import ConfigParser
18
19from ndg.security.common.utils.configfileparsers import \
20                                            CaseSensitiveConfigParser
21from ndg.security.common.saml_utils.attributeQuery import \
22                                            AttributeQuerySslSOAPBinding
23from ndg.security.common.X509 import X509Cert
24from ndg.security.common.authz import Subject
25from ndg.security.common.authz.pip import (PIPBase, PIPAttributeQuery, 
26                                           PIPAttributeResponse)
27   
28
29class PIP(PIPBase):
30    """Policy Information Point to query ESG Attribute Authority for user
31    attributes
32    """
33         
34    ATTRIBUTE_QUERY_ATTRNAME = 'attributeQuery'
35    LEN_ATTRIBUTE_QUERY_ATTRNAME = len(ATTRIBUTE_QUERY_ATTRNAME)
36   
37    __slots__ = ('__attributeQueryBinding')
38   
39    def __init__(self):
40        '''Initialise settings for connection to an Attribute Authority'''
41        self.__attributeQueryBinding = None       
42
43    @classmethod
44    def fromConfig(cls, cfg, **kw):
45        '''Alternative constructor makes object from config file settings
46        @type cfg: basestring /ConfigParser derived type
47        @param cfg: configuration file path or ConfigParser type object
48        @rtype: ndg.security.common.saml_utils.binding.soap.SOAPBinding
49        @return: new instance of this class
50        '''
51        obj = cls()
52        obj.parseConfig(cfg, **kw)
53       
54        return obj
55
56    def parseConfig(self, cfg, prefix='', section='DEFAULT'):
57        '''Read config settings from a file, config parser object or dict
58        @type cfg: basestring / ConfigParser derived type / dict
59        @param cfg: configuration file path or ConfigParser type object
60        @type prefix: basestring
61        @param prefix: prefix for option names e.g. "attributeQuery."
62        @type section: baestring
63        @param section: configuration file section from which to extract
64        parameters.
65        ''' 
66        if isinstance(cfg, basestring):
67            cfgFilePath = path.expandvars(cfg)
68            _cfg = CaseSensitiveConfigParser()
69            _cfg.read(cfgFilePath)
70            items = _cfg.items(section)
71           
72        elif isinstance(cfg, ConfigParser):
73            items = cfg.items(section)
74         
75        elif isinstance(cfg, dict):
76            items = cfg.items()     
77        else:
78            raise AttributeError('Expecting basestring, ConfigParser or dict '
79                                 'type for "cfg" attribute; got %r type' % 
80                                 type(cfg))
81       
82        prefixLen = len(prefix)
83        for optName, val in items:
84            if prefix:
85                # Filter attributes based on prefix
86                if optName.startswith(prefix):
87                    setattr(self, optName[prefixLen:], val)
88            else:
89                # No prefix set - attempt to set all attributes   
90                setattr(self, optName, val)
91               
92        if not self.__attributeQueryBinding.issuerName:
93            issuerX509Cert = X509Cert.Read(
94                    self.__attributeQueryBinding.sslCtxProxy.sslCertFilePath)
95            self.__attributeQueryBinding.issuerName = str(issuerX509Cert.dn)
96           
97    def __setattr__(self, name, value):
98        """Enable setting of AttributeQuerySslSOAPBinding attributes from
99        names starting with attributeQuery.* / attributeQuery_*.  Addition for
100        setting these values from ini file
101        """
102
103        # Coerce into setting AttributeQuerySslSOAPBinding attributes -
104        # names must start with 'attributeQuery\W' e.g.
105        # attributeQuery.clockSkew or attributeQuery_issuerDN
106        if name.startswith(PIP.ATTRIBUTE_QUERY_ATTRNAME):
107            setattr(self.__attributeQueryBinding, 
108                    name[PIP.LEN_ATTRIBUTE_QUERY_ATTRNAME+1:], 
109                    value)
110        else:
111            super(PIP, self).__setattr__(name, value)   
112
113    @property
114    def attributeQueryBinding(self):
115        """SAML SOAP Attribute Query client binding object"""
116        return self.__attributeQueryBinding
117   
118    def attributeQuery(self, attributeQuery):
119        """Query the Attribute Authority specified in the request to retrieve
120        the attributes if any corresponding to the subject
121       
122        @type attributeResponse: PIPAttributeQuery
123        @param attributeResponse:
124        @rtype: PIPAttributeResponse
125        @return: response containing the attributes retrieved from the
126        Attribute Authority"""
127        if not isinstance(attributeQuery, PIPAttributeQuery):
128            raise TypeError('Expecting %r type for input "attributeQuery"; '
129                            'got %r' % (PIPAttributeQuery, 
130                                        type(attributeQuery)))
131                           
132        attributeAuthorityURI = attributeQuery[
133                                        PIPAttributeQuery.ATTRIBUTEAUTHORITY_NS]
134       
135        log.debug("PIP: received attribute query: %r", attributeQuery)
136         
137        response = self.attributeQueryBinding.send(uri=attributeAuthorityURI)
138       
139        attributeResponse = PIPAttributeResponse()
140        attributeResponse[Subject.ROLES_NS] = []
141       
142        # Unpack assertion attribute values and add to the response object
143        for assertion in response.assertions:
144            for statement in assertion.attributeStatements:
145                for attribute in statement.attributes:
146                    attributeResponse[Subject.ROLES_NS] += [
147                        attributeValue.value
148                        for attributeValue in attribute.attributeValues
149                        if attributeValue.value not in attributeResponse[
150                                                            Subject.ROLES_NS]
151                    ]
152       
153        log.debug("PIP.attributeQuery response: %r", attributeResponse)
154       
155        return attributeResponse
Note: See TracBrowser for help on using the repository browser.