Changeset 6547 for TI12-security


Ignore:
Timestamp:
10/02/10 13:40:54 (10 years ago)
Author:
pjkersha
Message:

Working ElementTree serialisation/deserialisation for AuthzDecisionQuery?

Location:
TI12-security/trunk/ndg_security_saml/saml
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/ndg_security_saml/saml/common/__init__.py

    r6543 r6547  
    2929__contact__ = "Philip.Kershaw@stfc.ac.uk" 
    3030__revision__ = "$Id: $" 
    31    
     31from saml.common.xml import SAMLConstants, QName 
     32  
     33 
    3234class SAMLObject(object): 
    3335    """Base class for all SAML types""" 
    34     __slots__ = () 
     36    DEFAULT_ELEMENT_LOCAL_NAME = None 
     37    __slots__ = ('__qname',) 
    3538     
     39    def __init__(self, 
     40                 namespaceURI=SAMLConstants.SAML20_NS,  
     41                 elementLocalName=None,  
     42                 namespacePrefix=SAMLConstants.SAML20_PREFIX): 
     43        '''@param namespaceURI: the namespace the element is in 
     44        @param elementLocalName: the local name of the XML element this Object  
     45        represents 
     46        @param namespacePrefix: the prefix for the given namespace 
     47        ''' 
     48        if elementLocalName is None: 
     49            elementLocalName = self.__class__.DEFAULT_ELEMENT_LOCAL_NAME 
     50             
     51        self.__qname = QName(namespaceURI,  
     52                             elementLocalName,  
     53                             namespacePrefix) 
     54     
     55    @property 
     56    def qname(self): 
     57        "Qualified Name for this type" 
     58        return self.__qname 
     59             
    3660    @classmethod 
    3761    def fromXML(cls, xmlObject): 
  • TI12-security/trunk/ndg_security_saml/saml/saml2/core.py

    r6546 r6547  
    8282    ) 
    8383     
    84     def __init__(self): 
     84    def __init__(self, **kw): 
    8585        """Initialise Attribute Class attributes""" 
     86        super(Attribute, self).__init__(**kw) 
     87         
    8688        self.__name = None 
    8789        self.__nameFormat = None 
     
    172174    __slots__ = ('__attributes', '__encryptedAttributes') 
    173175     
    174     def __init__(self): 
     176    def __init__(self, **kw): 
     177        super(AttributeStatement, self).__init__(**kw) 
     178         
    175179        self.__attributes = TypedList(Attribute) 
    176180        self.__encryptedAttributes = TypedList(Attribute) 
     
    345349    # Decision attribute name 
    346350    DECISION_ATTRIB_NAME = "Decision" 
     351     
     352    def __init__(self,  
     353                 normalizeResource=True,  
     354                 safeNormalizationChars='/%', 
     355                 **kw): 
     356        '''Create new authorisation decision statement 
     357        ''' 
     358        super(AuthzDecisionStatement, self).__init__(**kw) 
     359 
     360        # Resource attribute value.  
     361        self.__resource = None 
     362         
     363        # Tuning for normalization of resource URIs in property set method 
     364        self.normalizeResource = normalizeResource 
     365        self.safeNormalizationChars = safeNormalizationChars 
     366 
     367    def _getNormalizeResource(self): 
     368        return self.__normalizeResource 
     369 
     370    def _setNormalizeResource(self, value): 
     371        if not isinstance(value, bool): 
     372            raise TypeError('Expecting bool type for "normalizeResource" ' 
     373                            'attribute; got %r instead' % type(value)) 
     374             
     375        self.__normalizeResource = value 
     376 
     377    normalizeResource = property(_getNormalizeResource,  
     378                                 _setNormalizeResource,  
     379                                 doc="Flag to normalize new resource value " 
     380                                     "assigned to the \"resource\" property.  " 
     381                                     "The setting only applies for URIs " 
     382                                     'beginning with "http://" or "https://"') 
     383 
     384    def _getSafeNormalizationChars(self): 
     385        return self.__safeNormalizationChars 
     386 
     387    def _setSafeNormalizationChars(self, value): 
     388        if not isinstance(value, basestring): 
     389            raise TypeError('Expecting string type for "normalizeResource" ' 
     390                            'attribute; got %r instead' % type(value)) 
     391             
     392        self.__safeNormalizationChars = value 
     393 
     394    safeNormalizationChars = property(_getSafeNormalizationChars,  
     395                                      _setSafeNormalizationChars,  
     396                                      doc="String containing a list of " 
     397                                          "characters that should not be " 
     398                                          "converted when Normalizing the " 
     399                                          "resource URI.  These are passed to " 
     400                                          "urllib.quote when the resource " 
     401                                          "property is set.  The default " 
     402                                          "characters are '/%'") 
    347403 
    348404    def _getResource(self): 
    349         ''' 
    350         Get URI of the resource to which authorization is saught. 
    351          
    352         @return: URI of the resource to which authorization is saught 
     405        '''Gets the Resource attrib value of this query. 
     406 
     407        @return: the Resource attrib value of this query''' 
     408        return self.__resource 
     409     
     410    def _setResource(self, value): 
     411        '''Sets the Resource attrib value of this query normalizing the path 
     412        component, removing spurious port numbers (80 for HTTP and 443 for  
     413        HTTPS) and converting the host component to lower case. 
     414         
     415        @param value: the new Resource attrib value of this query''' 
     416        if not isinstance(value, basestring): 
     417            raise TypeError('Expecting string type for "resource" attribute; ' 
     418                            'got %r instead' % type(value)) 
     419         
     420        if (self.normalizeResource and  
     421            value.startswith('http://') or value.startswith('https://')): 
     422            # Normalise the path, set the host name to lower case and remove  
     423            # port redundant numbers 80 and 443 
     424            splitResult = urlsplit(value) 
     425            uriComponents = list(splitResult) 
     426             
     427            # hostname attribute is lowercase 
     428            uriComponents[1] = splitResult.hostname 
     429             
     430            if splitResult.port is not None: 
     431                isHttpWithStdPort = (splitResult.port == 80 and  
     432                                     splitResult.scheme == 'http') 
     433                 
     434                isHttpsWithStdPort = (splitResult.port == 443 and 
     435                                      splitResult.scheme == 'https') 
     436                 
     437                if not isHttpWithStdPort and not isHttpsWithStdPort: 
     438                    uriComponents[1] += ":%d" % splitResult.port 
     439             
     440            uriComponents[2] = urllib.quote(splitResult.path,  
     441                                            self.safeNormalizationChars) 
     442             
     443            self.__resource = urlunsplit(uriComponents) 
     444        else: 
     445            self.__resource = value 
     446     
     447    resource = property(fget=_getResource, fset=_setResource, 
     448                        doc="Resource for which authorisation was requested") 
     449 
     450    def _getDecision(self): 
     451        ''' 
     452        Gets the decision of the authorization request. 
     453         
     454        @return: the decision of the authorization request 
    353455        ''' 
    354456        raise NotImplementedError() 
    355457 
    356     def _setResource(self, value): 
    357         ''' 
    358         Sets URI of the resource to which authorization is saught. 
    359          
    360         @param value: URI of the resource to which authorization is  
    361         saught 
     458    def _setDecision(self, value): 
     459        ''' 
     460        Sets the decision of the authorization request. 
     461         
     462        @param value: the decision of the authorization request 
    362463        ''' 
    363464        raise NotImplementedError() 
    364  
    365     def _getDecision(self): 
    366         ''' 
    367         Gets the decision of the authorization request. 
    368          
    369         @return: the decision of the authorization request 
    370         ''' 
    371         raise NotImplementedError() 
    372  
    373     def _setDecision(self, value): 
    374         ''' 
    375         Sets the decision of the authorization request. 
    376          
    377         @param value: the decision of the authorization request 
    378         ''' 
    379         raise NotImplementedError() 
    380  
    381     def _getActions(self): 
    382         ''' 
    383         Gets the actions authorized to be performed. 
    384          
    385         @return: the actions authorized to be performed 
    386         ''' 
    387         raise NotImplementedError() 
    388  
    389  
     465     
     466    @property 
     467    def actions(self): 
     468        '''The actions for which authorisation is requested 
     469         
     470        @return: the Actions of this statement''' 
     471        return self.__actions 
     472    
    390473    def _getEvidence(self): 
    391         ''' 
    392         Get the SAML assertion the authority relied on when making the  
    393         authorization decision. 
    394          
    395         @return: the SAML assertion the authority relied on when making the  
    396         authorization decision 
    397         ''' 
    398         raise NotImplementedError() 
     474        '''Gets the Evidence of this statement. 
     475 
     476        @return: the Evidence of this statement''' 
     477        return self.__evidence 
    399478 
    400479    def _setEvidence(self, value): 
    401         ''' 
    402         Sets the SAML assertion the authority relied on when making the  
    403         authorization decision. 
    404          
    405         @param value: the SAML assertion the authority relied on when  
    406         making the authorization decision 
    407         ''' 
    408         raise NotImplementedError() 
     480        '''Sets the Evidence of this query. 
     481        @param newEvidence: the new Evidence of this statement'''   
     482        if not isinstance(value, Evidence): 
     483            raise TypeError('Expecting Evidence type for "evidence" ' 
     484                            'attribute; got %r' % type(value)) 
     485 
     486        self.__evidence = value   
     487 
     488    evidence = property(fget=_getEvidence, fset=_setEvidence,  
     489                        doc="A set of assertions which the Authority may use " 
     490                            "to base its authorisation decision on") 
     491     
     492    def getOrderedChildren(self): 
     493        children = [] 
     494 
     495        superChildren = super(AuthzDecisionStatement, self).getOrderedChildren() 
     496        if superChildren: 
     497            children.extend(superChildren) 
     498 
     499        children.extend(self.__actions) 
     500         
     501        if self.__evidence is not None: 
     502            children.extend(self.__evidence) 
     503 
     504        if len(children) == 0: 
     505            return None 
     506 
     507        return tuple(children) 
    409508         
    410509 
     
    435534    ) 
    436535     
    437     def __init__(self,  
    438                  namespaceURI=SAMLConstants.SAML20_NS,  
    439                  elementLocalName=DEFAULT_ELEMENT_LOCAL_NAME,  
    440                  namespacePrefix=SAMLConstants.SAML20_PREFIX): 
    441         '''@param namespaceURI: the namespace the element is in 
    442         @param elementLocalName: the local name of the XML element this Object  
    443         represents 
    444         @param namespacePrefix: the prefix for the given namespace 
    445         ''' 
    446         self.__qname = QName(namespaceURI,  
    447                              elementLocalName,  
    448                              namespacePrefix) 
     536    def __init__(self, **kw): 
     537        super(Subject, self).__init__(**kw) 
    449538         
    450539        # BaseID child element. 
     
    459548        # Subject Confirmations of the Subject. 
    460549        self.__subjectConfirmations = [] 
    461      
    462     def _get_qname(self): 
    463         return self.__qname 
    464      
    465     qname = property(fget=_get_qname, doc="Qualified Name for Subject") 
    466550     
    467551    def _getBaseID(self):  
     
    15541638 
    15551639    # Name of the Namespace attribute.  
    1556     NAMEPSACE_ATTRIB_NAME = "Namespace" 
     1640    NAMESPACE_ATTRIB_NAME = "Namespace" 
    15571641 
    15581642    # Read/Write/Execute/Delete/Control action namespace.  
     
    16101694    HTTP_POST_ACTION = "POST" 
    16111695     
    1612     def __init__(self, namespaceURI, elementLocalName, namespacePrefix): 
    1613         ''' 
    1614         @param namespaceURI: the namespace the element is in 
    1615         @param elementLocalName: the local name of the XML element this object  
    1616         represents 
    1617         @param namespacePrefix: the prefix for the given namespace''' 
    1618         super(Action, self).__init__(namespaceURI,  
    1619                                      elementLocalName,  
    1620                                      namespacePrefix) 
    1621          
    1622         # URI of the Namespace of this Action 
     1696    def __init__(self, **kw): 
     1697        '''Create an authorization action type 
     1698        ''' 
     1699        super(Action, self).__init__(**kw) 
     1700 
     1701        # URI of the Namespace of this action 
    16231702        self.__namespace = None 
    16241703 
    1625         # Action value 
    1626         self.__action = None 
     1704        #Value value 
     1705        self.__action = None        
    16271706     
    16281707    def _getNamespace(self): 
    16291708        ''' 
    1630         gets the namespace scope of the specified action. 
    1631          
    1632         @return: the namespace scope of the specified action 
    1633         ''' 
    1634         self.__namespace 
     1709        gets the namespace scope of the specifiedvalue. 
     1710         
     1711        @return: the namespace scope of the specifiedvalue 
     1712        ''' 
     1713        return self.__namespace 
    16351714 
    16361715    def _setNamespace(self, value): 
    16371716        ''' 
    1638         Sets the namespace scope of the specified action. 
    1639          
    1640         @param value: the namespace scope of the specified action 
     1717        Sets the namespace scope of the specifiedvalue. 
     1718         
     1719        @param value: the namespace scope of the specifiedvalue 
    16411720        ''' 
    16421721        if not isinstance(value, basestring): 
     
    16451724        self.__namespace = value 
    16461725 
    1647     namespace = property(_getNamespace, _setNamespace,  
    1648                          doc="Action Namespace") 
    1649  
    1650     def _getAction(self): 
     1726    namespace = property(_getNamespace, _setNamespace, doc="Action Namespace") 
     1727 
     1728    def _getValue(self): 
    16511729        ''' 
    16521730        gets the URI of the action to be performed. 
     
    16541732        @return: the URI of the action to be performed 
    16551733        ''' 
    1656         return self.__action 
    1657  
    1658     def _setAction(self, value): 
     1734        return self.__value 
     1735 
     1736    def _setValue(self, value): 
    16591737        ''' 
    16601738        Sets the URI of the action to be performed. 
    16611739         
    1662         @param value: the URI of the action to be performed 
     1740        @param value: the URI of thevalue to be performed 
    16631741        ''' 
    16641742        if not isinstance(value, basestring): 
    16651743            raise TypeError('Expecting string type for "action" ' 
    16661744                            'attribute; got %r' % type(value)) 
    1667         self.__action = value 
    1668  
    1669     action = property(_getAction, _setAction,  
    1670                       doc="Action string") 
     1745        self.__value = value 
     1746 
     1747    value = property(_getValue, _setValue, doc="Action string") 
    16711748         
    16721749 
     
    19582035 
    19592036class AssertionURIRef(Evidentiary): 
     2037    '''SAML 2.0 Core AssertionURIRef''' 
    19602038    __slots__ = ('__assertionURI',) 
    19612039     
    1962     def __init__(self, namespaceURI, elementLocalName, namespacePrefix): 
    1963         ''' 
    1964         @param namespaceURI: the namespace the element is in 
    1965         @param elementLocalName: the local name of the XML element this Object  
    1966         represents 
    1967         @param namespacePrefix: the prefix for the given namespace''' 
    1968         super(AssertionURIRef, self).__init__(namespaceURI,  
    1969                                               elementLocalName,  
    1970                                               namespacePrefix) 
     2040    # Element local name 
     2041    DEFAULT_ELEMENT_LOCAL_NAME = "AssertionURIRef" 
     2042 
     2043    # Default element name 
     2044    DEFAULT_ELEMENT_NAME = QName(SAMLConstants.SAML20_NS,  
     2045                                 DEFAULT_ELEMENT_LOCAL_NAME, 
     2046                                 SAMLConstants.SAML20_PREFIX) 
     2047     
     2048    def __init__(self): 
     2049        '''Create assertion URI reference''' 
     2050        super(AssertionURIRef, self).__init__() 
    19712051         
    19722052        # URI of the Assertion 
     
    21002180                      SAMLConstants.SAML20_PREFIX) 
    21012181 
    2102     __slots__ = ('__evidence',) 
    2103      
    2104     def __init__(self, namespaceURI, elementLocalName, namespacePrefix): 
    2105         ''' 
    2106         @param namespaceURI: the namespace the element is in 
    2107         @param elementLocalName: the local name of the XML element this Object  
    2108         represents 
    2109         @param namespacePrefix: the prefix for the given namespace''' 
    2110         super(Evidence, self).__init__(namespaceURI,  
    2111                                        elementLocalName,  
    2112                                        namespacePrefix) 
     2182    __slots__ = ('__values',) 
     2183     
     2184    def __init__(self, **kw): 
     2185        '''Create an authorization evidence type 
     2186        ''' 
     2187        super(Evidence, self).__init__(**kw) 
     2188 
    21132189        # Assertion of the Evidence.  
    2114         self.__evidence = TypedList(Evidentiary) 
    2115          
    2116     def _getAssertionIDReferences(self): 
     2190        self.__values = TypedList(Evidentiary)  
     2191         
     2192    @property 
     2193    def assertionIDReferences(self): 
    21172194        '''Gets the list of AssertionID references used as evidence. 
    21182195     
    21192196        @return: the list of AssertionID references used as evidence''' 
    2120         return [i for i in self.__evidence  
     2197        return [i for i in self.__values  
    21212198                if (getattr(i, "DEFAULT_ELEMENT_NAME") ==  
    21222199                    AssertionIDRef.DEFAULT_ELEMENT_NAME)] 
    21232200     
    2124     def _getAssertionURIReferences(self): 
     2201    @property 
     2202    def assertionURIReferences(self): 
    21252203        '''Gets the list of AssertionURI references used as evidence. 
    21262204        
    21272205        @return: the list of AssertionURI references used as evidence''' 
    2128         return [i for i in self.__evidence  
     2206        return [i for i in self.__values  
    21292207                if (getattr(i, "DEFAULT_ELEMENT_NAME") ==  
    21302208                    AssertionURIRef.DEFAULT_ELEMENT_NAME)] 
    21312209     
    2132     def _getAssertions(self): 
     2210    @property 
     2211    def assertions(self): 
    21332212        '''Gets the list of Assertions used as evidence. 
    21342213        
    21352214        @return: the list of Assertions used as evidence''' 
    2136         return [i for i in self.__evidence  
     2215        return [i for i in self.__values  
    21372216                if (getattr(i, "DEFAULT_ELEMENT_NAME") ==  
    21382217                    Assertion.DEFAULT_ELEMENT_NAME)] 
    21392218     
    2140     def _getEncryptedAssertions(self): 
     2219    @property 
     2220    def encryptedAssertions(self): 
    21412221        '''Gets the list of EncryptedAssertions used as evidence. 
    21422222        
    21432223        @return: the list of EncryptedAssertions used as evidence''' 
    2144         return [i for i in self.__evidence  
     2224        return [i for i in self.__values  
    21452225                if (getattr(i, "DEFAULT_ELEMENT_NAME") ==  
    2146                     EncryptedAssertion.DEFAULT_ELEMENT_NAME)] 
    2147  
    2148     def _getEvidence(self): 
     2226                    EncryptedAssertion.DEFAULT_ELEMENT_NAME)]    
     2227 
     2228    @property 
     2229    def values(self): 
    21492230        '''Gets the list of all elements used as evidence. 
    21502231        
    21512232        @return: the list of Evidentiary objects used as evidence''' 
    2152         return self.__evidence 
     2233        return self.__values 
    21532234     
    21542235    def getOrderedChildren(self): 
    21552236        children = [] 
    21562237 
    2157         if len(self.evidence) == 0: 
     2238        if len(self.__values) == 0: 
    21582239            return None 
    21592240 
    2160         children.extend(self.evidence) 
     2241        children.extend(self.__values) 
    21612242 
    21622243        return tuple(children) 
     
    21882269       '__resource', 
    21892270       '__evidence', 
    2190        '__actions' 
     2271       '__actions', 
     2272       '__normalizeResource', 
     2273       '__safeNormalizationChars' 
    21912274    ) 
    21922275     
    2193     def __init__(self): 
     2276    def __init__(self,  
     2277                 normalizeResource=True,  
     2278                 safeNormalizationChars='/%', 
     2279                 **kw): 
    21942280        '''Create new authorisation decision query 
    21952281        ''' 
    2196         super(AuthzDecisionQuery, self).__init__() 
     2282        super(AuthzDecisionQuery, self).__init__(**kw) 
    21972283 
    21982284        # Resource attribute value.  
     
    22032289     
    22042290        # Action child elements. 
    2205         self.__actions = TypedList(Action) 
    2206          
     2291        self.__actions = TypedList(Action)    
     2292         
     2293        # Tuning for normalization of resource URIs in property set method 
     2294        self.normalizeResource = normalizeResource 
     2295        self.safeNormalizationChars = safeNormalizationChars 
     2296 
     2297    def _getNormalizeResource(self): 
     2298        return self.__normalizeResource 
     2299 
     2300    def _setNormalizeResource(self, value): 
     2301        if not isinstance(value, bool): 
     2302            raise TypeError('Expecting bool type for "normalizeResource" ' 
     2303                            'attribute; got %r instead' % type(value)) 
     2304             
     2305        self.__normalizeResource = value 
     2306 
     2307    normalizeResource = property(_getNormalizeResource,  
     2308                                 _setNormalizeResource,  
     2309                                 doc="Flag to normalize new resource value " 
     2310                                     "assigned to the \"resource\" property.  " 
     2311                                     "The setting only applies for URIs " 
     2312                                     'beginning with "http://" or "https://"') 
     2313 
     2314    def _getSafeNormalizationChars(self): 
     2315        return self.__safeNormalizationChars 
     2316 
     2317    def _setSafeNormalizationChars(self, value): 
     2318        if not isinstance(value, basestring): 
     2319            raise TypeError('Expecting string type for "normalizeResource" ' 
     2320                            'attribute; got %r instead' % type(value)) 
     2321             
     2322        self.__safeNormalizationChars = value 
     2323 
     2324    safeNormalizationChars = property(_getSafeNormalizationChars,  
     2325                                      _setSafeNormalizationChars,  
     2326                                      doc="String containing a list of " 
     2327                                          "characters that should not be " 
     2328                                          "converted when Normalizing the " 
     2329                                          "resource URI.  These are passed to " 
     2330                                          "urllib.quote when the resource " 
     2331                                          "property is set.  The default " 
     2332                                          "characters are '/%'") 
     2333 
    22072334    def _getResource(self): 
    22082335        '''Gets the Resource attrib value of this query. 
     
    22212348                            'got %r instead' % type(value)) 
    22222349         
    2223         # Normalise the path, set the host name to lower case and remove  
    2224         # port redundant numbers 80 and 443 
    2225         splitResult = urlsplit(value) 
    2226         uriComponents = list(splitResult) 
    2227          
    2228         # hostname attribute is lowercase 
    2229         uriComponents[1] = splitResult.hostname 
    2230          
    2231         isHttpWithStdPort = (splitResult.port == 80 and  
    2232                              splitResult.scheme == 'http') 
    2233          
    2234         isHttpsWithStdPort = (splitResult.port == 443 and 
    2235                               splitResult.scheme == 'https') 
    2236          
    2237         if not isHttpWithStdPort and not isHttpsWithStdPort: 
    2238             uriComponents[1] += ":%d" % splitResult.port 
    2239          
    2240         uriComponents[2] = urllib.quote(splitResult.path) 
    2241          
    2242         self.__resource = urlunsplit(uriComponents) 
     2350        if (self.normalizeResource and  
     2351            value.startswith('http://') or value.startswith('https://')): 
     2352            # Normalise the path, set the host name to lower case and remove  
     2353            # port redundant numbers 80 and 443 
     2354            splitResult = urlsplit(value) 
     2355            uriComponents = list(splitResult) 
     2356             
     2357            # hostname attribute is lowercase 
     2358            uriComponents[1] = splitResult.hostname 
     2359             
     2360            if splitResult.port is not None: 
     2361                isHttpWithStdPort = (splitResult.port == 80 and  
     2362                                     splitResult.scheme == 'http') 
     2363                 
     2364                isHttpsWithStdPort = (splitResult.port == 443 and 
     2365                                      splitResult.scheme == 'https') 
     2366                 
     2367                if not isHttpWithStdPort and not isHttpsWithStdPort: 
     2368                    uriComponents[1] += ":%d" % splitResult.port 
     2369             
     2370            uriComponents[2] = urllib.quote(splitResult.path,  
     2371                                            self.safeNormalizationChars) 
     2372             
     2373            self.__resource = urlunsplit(uriComponents) 
     2374        else: 
     2375            self.__resource = value 
    22432376     
    22442377    resource = property(fget=_getResource, fset=_setResource, 
    22452378                        doc="Resource for which authorisation is requested") 
    22462379     
    2247     def _getActions(self): 
    2248         '''Gets the Actions of this query. 
     2380    @property 
     2381    def actions(self): 
     2382        '''The actions for which authorisation is requested 
    22492383         
    22502384        @return: the Actions of this query''' 
    22512385        return self.__actions 
    2252      
    2253     actions = property(fget=_getActions,  
    2254                        doc="The actions for which authorisation is requested") 
    22552386    
    22562387    def _getEvidence(self): 
     
    22802411            children.extend(superChildren) 
    22812412 
    2282         children.extend(self.actions) 
    2283          
    2284         if evidence is not None: 
    2285             children.extend(evidence) 
     2413        children.extend(self.__actions) 
     2414         
     2415        if self.__evidence is not None: 
     2416            children.extend(self.__evidence) 
    22862417 
    22872418        if len(children) == 0: 
  • TI12-security/trunk/ndg_security_saml/saml/test/test_saml.py

    r6546 r6547  
    2121from xml.etree import ElementTree 
    2222 
    23 from saml.saml2.core import Action 
    2423from saml.saml2.core import (SAMLVersion, Attribute, AttributeStatement,  
    2524                             Assertion, AttributeQuery, Response, Issuer,  
    2625                             Subject, NameID, StatusCode,  
    2726                             StatusMessage, Status, Conditions,  
    28                              XSStringAttributeValue, 
     27                             XSStringAttributeValue, Action, 
    2928                             AuthzDecisionQuery) 
    3029 
    3130from saml.common.xml import SAMLConstants 
    3231from saml.xml.etree import (prettyPrint, AssertionElementTree,  
    33                             AttributeQueryElementTree, ResponseElementTree) 
     32                            AttributeQueryElementTree, ResponseElementTree, 
     33                            AuthzDecisionQueryElementTree) 
    3434 
    3535 
     
    3838    http://www.ci.uchicago.edu/wiki/bin/view/ESGProject/ESGSAMLAttributes#ESG_Attribute_Service 
    3939    """ 
     40    NAMEID_FORMAT = "urn:esg:openid" 
     41    NAMEID_VALUE = "https://openid.localhost/philip.kershaw" 
     42    ISSUER_DN = "/O=NDG/OU=BADC/CN=attributeauthority.badc.rl.ac.uk" 
     43    UNCORRECTED_RESOURCE_URI = "http://LOCALHOST:80/My Secured URI" 
     44    RESOURCE_URI = "http://localhost/My%20Secured%20URI" 
    4045     
    4146    def __init__(self): 
     
    97102        attributeQuery.subject = Subject()   
    98103        attributeQuery.subject.nameID = NameID() 
    99         attributeQuery.subject.nameID.format = "urn:esg:openid" 
     104        attributeQuery.subject.nameID.format = SAMLTestCase.NAMEID_FORMAT 
    100105        attributeQuery.subject.nameID.value = subjectNameID 
    101106                                     
     
    162167             
    163168        return attributes 
    164  
     169     
     170    def buildAuthzDecisionQuery(self,  
     171                                issuer=ISSUER_DN, 
     172                                issuerFormat=Issuer.X509_SUBJECT, 
     173                                subjectNameID=NAMEID_VALUE,  
     174                                subjectNameIdFormat=NAMEID_FORMAT, 
     175                                resource=UNCORRECTED_RESOURCE_URI, 
     176                                actions=((Action.HTTP_GET_ACTION,  
     177                                          Action.GHPP_NS_URI),)): 
     178        """Convenience utility to make an Authorisation decision query""" 
     179        authzDecisionQuery = AuthzDecisionQuery() 
     180 
     181        authzDecisionQuery.version = SAMLVersion(SAMLVersion.VERSION_20) 
     182        authzDecisionQuery.id = str(uuid4()) 
     183        authzDecisionQuery.issueInstant = datetime.utcnow() 
     184         
     185        authzDecisionQuery.issuer = Issuer() 
     186        authzDecisionQuery.issuer.format = issuerFormat 
     187        authzDecisionQuery.issuer.value = issuer 
     188         
     189        authzDecisionQuery.subject = Subject() 
     190        authzDecisionQuery.subject.nameID = NameID() 
     191        authzDecisionQuery.subject.nameID.format = subjectNameIdFormat 
     192        authzDecisionQuery.subject.nameID.value = subjectNameID 
     193         
     194        authzDecisionQuery.resource = resource 
     195         
     196        for action, namespace in actions: 
     197            authzDecisionQuery.actions.append(Action()) 
     198            authzDecisionQuery.actions[-1].value = action 
     199            authzDecisionQuery.actions[-1].namespace = namespace 
     200             
     201        return authzDecisionQuery 
     202             
    165203 
    166204class SAMLTestCase(unittest.TestCase): 
    167205    """Test SAML implementation for use with CMIP5 federation""" 
     206    NAMEID_FORMAT = SAMLUtil.NAMEID_FORMAT 
     207    NAMEID_VALUE = SAMLUtil.NAMEID_VALUE 
     208    ISSUER_DN = SAMLUtil.ISSUER_DN 
     209    UNCORRECTED_RESOURCE_URI = SAMLUtil.UNCORRECTED_RESOURCE_URI 
     210    RESOURCE_URI = SAMLUtil.RESOURCE_URI 
    168211     
    169212    def _createAssertionHelper(self): 
     
    240283        samlUtil.lastName = '' 
    241284        samlUtil.emailAddress = '' 
    242         attributeQuery = samlUtil.buildAttributeQuery( 
    243                         "/O=NDG/OU=BADC/CN=attributeauthority.badc.rl.ac.uk", 
    244                         "https://openid.localhost/philip.kershaw") 
     285        attributeQuery = samlUtil.buildAttributeQuery(SAMLTestCase.ISSUER_DN, 
     286                                                      SAMLTestCase.NAMEID_VALUE) 
    245287         
    246288        elem = AttributeQueryElementTree.toXML(attributeQuery)         
     
    256298        samlUtil.lastName = '' 
    257299        samlUtil.emailAddress = '' 
    258         attributeQuery = samlUtil.buildAttributeQuery( 
    259                         "/O=NDG/OU=BADC/CN=attributeauthority.badc.rl.ac.uk", 
    260                         "https://openid.localhost/philip.kershaw") 
     300        attributeQuery = samlUtil.buildAttributeQuery(SAMLTestCase.ISSUER_DN, 
     301                                                      SAMLTestCase.NAMEID_VALUE) 
    261302         
    262303        elem = AttributeQueryElementTree.toXML(attributeQuery)         
     
    298339        response.issuer.format = Issuer.X509_SUBJECT 
    299340        response.issuer.value = \ 
    300                         "/O=NDG/OU=BADC/CN=attributeauthority.badc.rl.ac.uk" 
     341                        SAMLTestCase.ISSUER_DN 
    301342         
    302343        response.status = Status() 
     
    316357        assertion.subject = Subject()   
    317358        assertion.subject.nameID = NameID() 
    318         assertion.subject.nameID.format = "urn:esg:openid" 
    319         assertion.subject.nameID.value = \ 
    320                         "https://openid.localhost/philip.kershaw"     
     359        assertion.subject.nameID.format = SAMLTestCase.NAMEID_FORMAT 
     360        assertion.subject.nameID.value = SAMLTestCase.NAMEID_VALUE     
    321361             
    322362        assertion.issuer = Issuer() 
    323363        assertion.issuer.format = Issuer.X509_SUBJECT 
    324         assertion.issuer.value = \ 
    325                         "/O=NDG/OU=BADC/CN=attributeauthority.badc.rl.ac.uk" 
     364        assertion.issuer.value = SAMLTestCase.ISSUER_DN 
    326365 
    327366        response.assertions.append(assertion) 
     
    341380    def test06CreateAuthzDecisionQuery(self): 
    342381        authzDecisionQuery = AuthzDecisionQuery() 
     382 
     383        authzDecisionQuery.version = SAMLVersion(SAMLVersion.VERSION_20) 
     384        authzDecisionQuery.id = str(uuid4()) 
     385        authzDecisionQuery.issueInstant = datetime.utcnow() 
     386         
     387        authzDecisionQuery.issuer = Issuer() 
     388        authzDecisionQuery.issuer.format = Issuer.X509_SUBJECT 
     389        authzDecisionQuery.issuer.value = SAMLTestCase.ISSUER_DN 
     390         
     391        authzDecisionQuery.subject = Subject() 
     392        authzDecisionQuery.subject.nameID = NameID() 
     393        authzDecisionQuery.subject.nameID.format = SAMLTestCase.NAMEID_FORMAT 
     394        authzDecisionQuery.subject.nameID.value = SAMLTestCase.NAMEID_VALUE 
     395         
    343396        authzDecisionQuery.resource = "http://LOCALHOST:80/My Secured URI" 
    344397        self.assert_(":80" not in authzDecisionQuery.resource) 
     
    352405        self.assert_("somewhere.ac.uk" in authzDecisionQuery.resource) 
    353406        self.assert_("yes=True" in authzDecisionQuery.resource) 
     407         
     408        authzDecisionQuery.actions.append(Action()) 
     409        authzDecisionQuery.actions[0].value = Action.HTTP_GET_ACTION 
     410        authzDecisionQuery.actions[0].namespace = Action.GHPP_NS_URI 
     411         
     412        self.assert_( 
     413            authzDecisionQuery.actions[0].value == Action.HTTP_GET_ACTION) 
     414        self.assert_( 
     415            authzDecisionQuery.actions[0].namespace == Action.GHPP_NS_URI) 
     416         
     417    def test07SerializeAuthzDecisionQuery(self): 
     418        samlUtil = SAMLUtil() 
     419        authzDecisionQuery = samlUtil.buildAuthzDecisionQuery() 
     420         
     421        # Create ElementTree Assertion Element 
     422        authzDecisionQueryElem = AuthzDecisionQueryElementTree.toXML( 
     423                                                            authzDecisionQuery) 
     424         
     425        self.assert_(iselement(authzDecisionQueryElem)) 
     426         
     427        # Serialise to output  
     428        xmlOutput = prettyPrint(authzDecisionQueryElem)        
     429        self.assert_(len(xmlOutput)) 
     430         
     431        print("\n"+"_"*80) 
     432        print(xmlOutput) 
     433        print("_"*80) 
    354434    
     435    def test08DeserializeAuthzDecisionQuery(self): 
     436        samlUtil = SAMLUtil() 
     437        authzDecisionQuery = samlUtil.buildAuthzDecisionQuery() 
     438         
     439        # Create ElementTree Assertion Element 
     440        authzDecisionQueryElem = AuthzDecisionQueryElementTree.toXML( 
     441                                                            authzDecisionQuery) 
     442         
     443        self.assert_(iselement(authzDecisionQueryElem)) 
     444         
     445        # Serialise to output  
     446        xmlOutput = prettyPrint(authzDecisionQueryElem)        
     447        self.assert_(len(xmlOutput)) 
     448         
     449        authzDecisionQueryStream = StringIO() 
     450        authzDecisionQueryStream.write(xmlOutput) 
     451        authzDecisionQueryStream.seek(0) 
     452 
     453        tree = ElementTree.parse(authzDecisionQueryStream) 
     454        elem2 = tree.getroot() 
     455         
     456        authzDecisionQuery2 = AuthzDecisionQueryElementTree.fromXML(elem2) 
     457        self.assert_(authzDecisionQuery2) 
     458        self.assert_( 
     459        authzDecisionQuery2.subject.nameID.value == SAMLTestCase.NAMEID_VALUE) 
     460        self.assert_( 
     461        authzDecisionQuery2.subject.nameID.format == SAMLTestCase.NAMEID_FORMAT) 
     462        self.assert_( 
     463            authzDecisionQuery2.issuer.value == SAMLTestCase.ISSUER_DN) 
     464        self.assert_( 
     465            authzDecisionQuery2.resource == SAMLTestCase.RESOURCE_URI) 
     466        self.assert_(len(authzDecisionQuery2.actions) == 1) 
     467        self.assert_( 
     468            authzDecisionQuery2.actions[0].value == Action.HTTP_GET_ACTION) 
     469        self.assert_( 
     470            authzDecisionQuery2.actions[0].namespace == Action.GHPP_NS_URI) 
     471        self.assert_(authzDecisionQuery2.evidence is None) 
     472 
     473        
    355474if __name__ == "__main__": 
    356475    unittest.main()         
  • TI12-security/trunk/ndg_security_saml/saml/xml/etree.py

    r6069 r6547  
    4141                             AuthnStatement, AuthzDecisionStatement, Assertion, 
    4242                             Conditions, AttributeValue, AttributeQuery,  
    43                              Subject, NameID, Issuer, Response, Status,  
    44                              StatusCode, StatusMessage, StatusDetail, Advice,  
     43                             AuthzDecisionQuery, Subject, NameID, Issuer,  
     44                             Response, Status, StatusCode, StatusMessage,  
     45                             StatusDetail, Advice, Action, 
    4546                             XSStringAttributeValue)  
    4647                              
     
    923924        """Create an XML representation of the input SAML Name Identifier 
    924925        object 
    925         @type nameID: saml.saml2.core.Subject 
    926         @param nameID: SAML subject 
     926        @type nameID: saml.saml2.core.NameID 
     927        @param nameID: SAML name ID 
    927928        @rtype: ElementTree.Element 
    928929        @return: Name ID as ElementTree XML element""" 
     
    14621463        return response 
    14631464 
     1465 
     1466class ActionElementTree(Action): 
     1467    """Represent a SAML authorization action in XML using ElementTree""" 
     1468     
     1469    @classmethod 
     1470    def toXML(cls, action): 
     1471        """Create an XML representation of the input SAML Name Identifier 
     1472        object 
     1473        @type action: saml.saml2.core.Action 
     1474        @param action: SAML subject 
     1475        @rtype: ElementTree.Element 
     1476        @return: Name ID as ElementTree XML element""" 
     1477         
     1478        if not isinstance(action, Action): 
     1479            raise TypeError("Expecting %r class got %r" % (Action,  
     1480                                                           type(action))) 
     1481             
     1482        if not action.namespace: 
     1483            raise AttributeError("No action namespace set") 
     1484         
     1485        attrib = { 
     1486            cls.NAMESPACE_ATTRIB_NAME: action.namespace 
     1487        } 
     1488        tag = str(QName.fromGeneric(cls.DEFAULT_ELEMENT_NAME)) 
     1489        elem = ElementTree.Element(tag, **attrib) 
     1490         
     1491        ElementTree._namespace_map[action.qname.namespaceURI 
     1492                                   ] = action.qname.prefix 
     1493         
     1494        if not action.value: 
     1495            raise AttributeError("No action name set") 
     1496          
     1497        elem.text = action.value 
     1498 
     1499        return elem 
     1500 
     1501    @classmethod 
     1502    def fromXML(cls, elem): 
     1503        """Parse ElementTree element into a SAML Action object 
     1504         
     1505        @type elem: ElementTree.Element 
     1506        @param elem: Name ID as ElementTree XML element 
     1507        @rtype: saml.saml2.core.Action 
     1508        @return: SAML Name ID 
     1509        """ 
     1510        if not ElementTree.iselement(elem): 
     1511            raise TypeError("Expecting %r input type for parsing; got %r" % 
     1512                            (ElementTree.Element, elem)) 
     1513 
     1514        if QName.getLocalPart(elem.tag) != cls.DEFAULT_ELEMENT_LOCAL_NAME: 
     1515            raise XMLTypeParseError("No \"%s\" element found" % 
     1516                                    cls.DEFAULT_ELEMENT_LOCAL_NAME) 
     1517             
     1518        namespace = elem.attrib.get(cls.NAMESPACE_ATTRIB_NAME) 
     1519        if namespace is None: 
     1520            raise XMLTypeParseError('No "%s" attribute found in "%s" ' 
     1521                                    'element' % 
     1522                                    (cls.NAMESPACE_ATTRIB_NAME, 
     1523                                     cls.DEFAULT_ELEMENT_LOCAL_NAME)) 
     1524        action = Action() 
     1525        action.namespace = namespace 
     1526        action.value = elem.text.strip()  
     1527         
     1528        return action 
     1529     
     1530     
     1531class AuthzDecisionQueryElementTree(AuthzDecisionQuery): 
     1532    """Represent a SAML Attribute Query in XML using ElementTree""" 
     1533         
     1534    @classmethod 
     1535    def toXML(cls, authzDecisionQuery): 
     1536        """Create an XML representation of the input SAML Authorization 
     1537        Decision Query object 
     1538 
     1539        @type authzDecisionQuery: saml.saml2.core.AuthzDecisionQuery 
     1540        @param authzDecisionQuery: SAML Authorization Decision Query 
     1541        @rtype: ElementTree.Element 
     1542        @return: Attribute Query as ElementTree XML element 
     1543        """ 
     1544        if not isinstance(authzDecisionQuery, AuthzDecisionQuery): 
     1545            raise TypeError("Expecting %r class got %r" % (AuthzDecisionQuery,  
     1546                                                    type(authzDecisionQuery))) 
     1547             
     1548        if not authzDecisionQuery.resource: 
     1549            raise AttributeError("No resource has been set for the " 
     1550                                 "AuthzDecisionQuery") 
     1551             
     1552        issueInstant = SAMLDateTime.toString(authzDecisionQuery.issueInstant) 
     1553        attrib = { 
     1554            cls.ID_ATTRIB_NAME: authzDecisionQuery.id, 
     1555            cls.ISSUE_INSTANT_ATTRIB_NAME: issueInstant, 
     1556             
     1557            # Nb. Version is a SAMLVersion instance and requires explicit cast 
     1558            cls.VERSION_ATTRIB_NAME: str(authzDecisionQuery.version), 
     1559             
     1560            cls.RESOURCE_ATTRIB_NAME: authzDecisionQuery.resource 
     1561        } 
     1562         
     1563        tag = str(QName.fromGeneric(cls.DEFAULT_ELEMENT_NAME)) 
     1564        elem = ElementTree.Element(tag, **attrib) 
     1565         
     1566        ElementTree._namespace_map[cls.DEFAULT_ELEMENT_NAME.namespaceURI 
     1567                                   ] = cls.DEFAULT_ELEMENT_NAME.prefix 
     1568         
     1569        issuerElem = IssuerElementTree.toXML(authzDecisionQuery.issuer) 
     1570        elem.append(issuerElem) 
     1571 
     1572        subjectElem = SubjectElementTree.toXML(authzDecisionQuery.subject) 
     1573        elem.append(subjectElem) 
     1574 
     1575        for action in authzDecisionQuery.actions: 
     1576            # Factory enables support for multiple attribute types 
     1577            actionElem = ActionElementTree.toXML(action) 
     1578            elem.append(actionElem) 
     1579         
     1580        if (authzDecisionQuery.evidence and  
     1581            len(authzDecisionQuery.evidence.evidence) > 0): 
     1582            raise NotImplementedError("Conversion of AuthzDecisionQuery " 
     1583                                      "Evidence type to ElementTree Element is " 
     1584                                      "not currently supported") 
     1585             
     1586        return elem 
     1587 
     1588    @classmethod 
     1589    def fromXML(cls, elem): 
     1590        """Parse ElementTree element into a SAML AuthzDecisionQuery object 
     1591         
     1592        @type elem: ElementTree.Element 
     1593        @param elem: XML element containing the AuthzDecisionQuery 
     1594        @rtype: saml.saml2.core.AuthzDecisionQuery 
     1595        @return: AuthzDecisionQuery object 
     1596        """ 
     1597        if not ElementTree.iselement(elem): 
     1598            raise TypeError("Expecting %r input type for parsing; got %r" % 
     1599                            (ElementTree.Element, elem)) 
     1600 
     1601        if QName.getLocalPart(elem.tag) != cls.DEFAULT_ELEMENT_LOCAL_NAME: 
     1602            raise XMLTypeParseError("No \"%s\" element found" % 
     1603                                    cls.DEFAULT_ELEMENT_LOCAL_NAME) 
     1604         
     1605        # Unpack attributes from top-level element 
     1606        attributeValues = [] 
     1607        for attributeName in (cls.VERSION_ATTRIB_NAME, 
     1608                              cls.ISSUE_INSTANT_ATTRIB_NAME, 
     1609                              cls.ID_ATTRIB_NAME, 
     1610                              cls.RESOURCE_ATTRIB_NAME): 
     1611            attributeValue = elem.attrib.get(attributeName) 
     1612            if attributeValue is None: 
     1613                raise XMLTypeParseError('No "%s" attribute found in "%s" ' 
     1614                                 'element' % 
     1615                                 (attributeName, 
     1616                                  cls.DEFAULT_ELEMENT_LOCAL_NAME)) 
     1617                 
     1618            attributeValues.append(attributeValue) 
     1619         
     1620        authzDecisionQuery = AuthzDecisionQuery() 
     1621        authzDecisionQuery.version = SAMLVersion(attributeValues[0]) 
     1622        if authzDecisionQuery.version != SAMLVersion.VERSION_20: 
     1623            raise NotImplementedError("Parsing for %r is implemented for " 
     1624                                      "SAML version %s only; version %s is "  
     1625                                      "not supported" %  
     1626                                      (cls, 
     1627                                       SAMLVersion(SAMLVersion.VERSION_20), 
     1628                                       SAMLVersion(authzDecisionQuery.version))) 
     1629             
     1630        authzDecisionQuery.issueInstant = SAMLDateTime.fromString( 
     1631                                                            attributeValues[1]) 
     1632        authzDecisionQuery.id = attributeValues[2] 
     1633         
     1634        authzDecisionQuery.resource = attributeValues[3] 
     1635         
     1636        for childElem in elem: 
     1637            localName = QName.getLocalPart(childElem.tag) 
     1638            if localName == Issuer.DEFAULT_ELEMENT_LOCAL_NAME: 
     1639                # Parse Issuer 
     1640                authzDecisionQuery.issuer = IssuerElementTree.fromXML(childElem) 
     1641                 
     1642            elif localName == Subject.DEFAULT_ELEMENT_LOCAL_NAME: 
     1643                # Parse Subject 
     1644                authzDecisionQuery.subject = SubjectElementTree.fromXML(childElem) 
     1645             
     1646            elif localName == Action.DEFAULT_ELEMENT_LOCAL_NAME: 
     1647                action = ActionElementTree.fromXML(childElem) 
     1648                authzDecisionQuery.actions.append(action) 
     1649            else: 
     1650                raise XMLTypeParseError("Unrecognised AuthzDecisionQuery child " 
     1651                                        "element \"%s\"" % localName) 
     1652         
     1653        return authzDecisionQuery 
     1654 
Note: See TracChangeset for help on using the changeset viewer.