Ignore:
Timestamp:
14/04/10 16:39:48 (10 years ago)
Author:
pjkersha
Message:

Moving matching and rule evaluation code out of the PDP class and into the relevant classes they pertain to e.g. target matching moved to Target class match method and so on.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/NDG_XACML/ndg/xacml/core/target.py

    r6770 r6806  
    1616__contact__ = "Philip.Kershaw@stfc.ac.uk" 
    1717__revision__ = "$Id: $" 
     18import logging 
     19log = logging.getLogger(__name__) 
     20 
    1821from ndg.xacml.core import XacmlCoreBase 
    1922from ndg.xacml.core.action import Action 
     
    2427 
    2528class Target(XacmlCoreBase): 
     29    """XACML Target element""" 
    2630    ELEMENT_LOCAL_NAME = "Target" 
    2731    SUBJECTS_ELEMENT_LOCAL_NAME = "Subjects" 
     
    2933    RESOURCES_ELEMENT_LOCAL_NAME = "Resources" 
    3034    ENVIRONMENTS_ELEMENT_LOCAL_NAME = "Environments" 
    31      
     35    CHILD_ATTRS = ('subjects', 'resources', 'actions', 'environments') 
     36    
    3237    __slots__ = ('__subjects', '__resources', '__actions', '__environments') 
    3338     
    3439    def __init__(self): 
     40        """Initial attributes""" 
    3541        self.__subjects = TypedList(Subject) 
    3642        self.__resources = TypedList(Resource) 
     
    5359    def environments(self): 
    5460        return self.__environments 
    55      
    56      
    57 class _Target(XacmlCoreBase): 
    58     """Define access behaviour for a resource match a given URI pattern""" 
    59     URI_PATTERN_LOCALNAME = "URIPattern" 
    60     ATTRIBUTES_LOCALNAME = "Attributes" 
    61     ATTRIBUTE_AUTHORITY_LOCALNAME = "AttributeAuthority" 
    62      
    63     __slots__ = ( 
    64         '__uriPattern', 
    65         '__attributes', 
    66         '__regEx'        
    67     ) 
    68        
    69     def __init__(self): 
    70         super(Target, self).__init__() 
    71         self.__uriPattern = None 
    72         self.__attributes = [] 
    73         self.__regEx = None 
    74          
    75     def getUriPattern(self): 
    76         return self.__uriPattern 
    77  
    78     def setUriPattern(self, value): 
    79         if not isinstance(value, basestring): 
    80             raise TypeError('Expecting string type for "uriPattern" ' 
    81                             'attribute; got %r' % type(value)) 
    82         self.__uriPattern = value 
    83  
    84     uriPattern = property(getUriPattern,  
    85                           setUriPattern,  
    86                           doc="URI Pattern to match this target") 
    87  
    88     def getAttributes(self): 
    89         return self.__attributes 
    90  
    91     def setAttributes(self, value): 
    92         if (not isinstance(value, TypedList) and  
    93             not issubclass(value.elementType, Attribute.__class__)): 
    94             raise TypeError('Expecting TypedList(Attribute) for "attributes" ' 
    95                             'attribute; got %r' % type(value)) 
    96         self.__attributes = value 
    97  
    98     attributes = property(getAttributes,  
    99                           setAttributes,   
    100                           doc="Attributes restricting access to this target") 
    101  
    102     def getRegEx(self): 
    103         return self.__regEx 
    104  
    105     def setRegEx(self, value): 
    106         self.__regEx = value 
    107  
    108     regEx = property(getRegEx, setRegEx, doc="RegEx's Docstring") 
    109          
    110     def parse(self, root): 
    111          
    112         self.xmlns = QName.getNs(root.tag) 
    113         version1_0attributeAuthorityURI = None 
    114          
    115         for elem in root: 
    116             localName = QName.getLocalPart(elem.tag) 
    117             if localName == Target.URI_PATTERN_LOCALNAME: 
    118                 self.uriPattern = elem.text.strip() 
    119                 self.regEx = re.compile(self.uriPattern) 
     61             
     62    def match(self, request): 
     63        """Generic method to match a <Target> element to the request context 
     64         
     65        @param target: XACML target element 
     66        @type target: ndg.xacml.core.target.Target 
     67        @param request: XACML request context 
     68        @type request: ndg.xacml.core.context.request.Request 
     69        @return: True if request context matches the given target,  
     70        False otherwise 
     71        @rtype: bool 
     72        """ 
     73         
     74        # From section 5.5 of the XACML 2.0 Core Spec: 
     75        # 
     76        # For the parent of the <Target> element to be applicable to the  
     77        # decision request, there MUST be at least one positive match between  
     78        # each section of the <Target> element and the corresponding section of  
     79        # the <xacml-context:Request> element. 
     80        #  
     81        # Also, 7.6: 
     82        # 
     83        # The target value SHALL be "Match" if the subjects, resources, actions  
     84        # and environments specified in the target all match values in the  
     85        # request context.  
     86        statusValues = [False]*len(self.__class__.CHILD_ATTRS)  
     87         
     88        # Iterate for target subjects, resources, actions and environments  
     89        # elements 
     90        for i, attrName in enumerate(self.__class__.CHILD_ATTRS): 
     91            # If any one of the <Target> children is missing then it counts as 
     92            # a match e.g. for <Subjects> child element - Section 5.5: 
     93            # 
     94            # <Subjects> [Optional] Matching specification for the subject  
     95            # attributes in the context. If this element is missing, 
     96            # then the target SHALL match all subjects. 
     97            targetElem = getattr(self, attrName) 
     98            if len(targetElem) == 0: 
     99                statusValues[i] = True 
     100                continue 
     101             
     102            # Iterate over each for example, subject in the list of subjects: 
     103            # <Target> 
     104            #     <Subjects> 
     105            #          <Subject> 
     106            #              ... 
     107            #          </Subject> 
     108            #          <Subject> 
     109            #              ... 
     110            #          </Subject> 
     111            #     ... 
     112            # or resource in the list of resources and so on 
     113            for targetSubElem in targetElem: 
    120114                 
    121             elif localName == Target.ATTRIBUTES_LOCALNAME: 
    122                 for attrElem in elem: 
    123                     if self.xmlns == Target.VERSION_1_1_XMLNS: 
    124                         self.attributes.append(Attribute.Parse(attrElem)) 
    125                     else: 
    126                         attribute = Attribute() 
    127                         attribute.name = attrElem.text.strip() 
    128                         self.attributes.append(attribute) 
    129                      
    130             elif localName == Target.ATTRIBUTE_AUTHORITY_LOCALNAME: 
    131                 # Expecting first element to contain the URI 
    132                 warnings.warn( 
    133                         Target.ATTRIBUTE_AUTHORITY_LOCALNAME_DEPRECATED_MSG, 
    134                         PendingDeprecationWarning) 
     115                # For the given subject/resource/action/environment check for a 
     116                # match with the equivalent in the request 
     117                requestElem = getattr(request, attrName)  
     118                for requestSubElem in requestElem: 
     119                    if self._matchChild(targetSubElem, requestSubElem): 
     120                        # Within the list of e.g. subjects if one subject  
     121                        # matches then this counts as a subject match overall  
     122                        # for this target 
     123                        statusValues[i] = True 
     124  
     125        # Target matches if all the children (i.e. subjects, resources, actions 
     126        # and environment sections) have at least one match.  Otherwise it  
     127        # doesn't count as a match 
     128        return all(statusValues) 
     129     
     130    def _matchChild(self, targetChild, requestChild): 
     131        """Match a request child element (a <Subject>, <Resource>, <Action> or  
     132        <Environment>) with the corresponding target's <Subject>, <Resource>,  
     133        <Action> or <Environment>. 
     134         
     135        @param targetChild: Target Subject, Resource, Action or Environment 
     136        object 
     137        @type targetChild: ndg.xacml.core.TargetChildBase 
     138        @param requestChild: Request Subject, Resource, Action or Environment 
     139        object 
     140        @type requestChild: ndg.xacml.core.context.RequestChildBase 
     141        @return: True if request context matches something in the target 
     142        @rtype: bool 
     143        @raise UnsupportedElementError: AttributeSelector processing is not  
     144        currently supported.  If an AttributeSelector is found in the policy, 
     145        this exception will be raised. 
     146        @raise UnsupportedStdFunctionError: policy references a function type  
     147        which is in the XACML spec. but is not supported by this implementation 
     148        @raise UnsupportedFunctionError: policy references a function type which 
     149        is not supported by this implementation 
     150        """ 
     151        if targetChild is None: 
     152            # Default if target child is not set is to match all children 
     153            return True 
     154         
     155        matchStatusValues = [True]*len(targetChild.matches) 
     156         
     157        # Section 7.6 
     158        # 
     159        # A subject, resource, action or environment SHALL match a value in the 
     160        # request context if the value of all its <SubjectMatch>,  
     161        # <ResourceMatch>, <ActionMatch> or <EnvironmentMatch> elements,  
     162        # respectively, are "True". 
     163        # 
     164        # e.g. for <SubjectMatch>es in <Subject> ... 
     165        for childMatch, matchStatus in zip(targetChild.matches,  
     166                                           matchStatusValues): 
     167             
     168            matchStatusValues[i] = childMatch.evaluate(requestChild) 
     169             
     170        # Any match => overall match       
     171        return any(matchStatusValues) 
     172     
    135173                 
    136                 version1_0attributeAuthorityURI = elem[-1].text.strip() 
    137             else: 
    138                 raise TargetParseError("Invalid Target attribute: %s" %  
    139                                        localName) 
    140                  
    141         if self.xmlns == Target.VERSION_1_0_XMLNS: 
    142             msg = ("Setting all attributes with Attribute Authority " 
    143                    "URI set read using Version 1.0 schema.  This will " 
    144                    "be deprecated in future releases") 
    145              
    146             warnings.warn(msg, PendingDeprecationWarning) 
    147             log.warning(msg) 
    148              
    149             if version1_0attributeAuthorityURI is None: 
    150                 raise TargetParseError("Assuming version 1.0 schema " 
    151                                        "for Attribute Authority URI setting " 
    152                                        "but no URI has been set") 
    153                  
    154             for attribute in self.attributes: 
    155                 attribute.attributeAuthorityURI = \ 
    156                     version1_0attributeAuthorityURI 
    157      
    158     @classmethod 
    159     def Parse(cls, root): 
    160         resource = cls() 
    161         resource.parse(root) 
    162         return resource 
    163      
    164     def __str__(self): 
    165         return str(self.uriPattern) 
    166  
     174    def attributeDesignatorMatchFuncFactory(self, 
     175                                            matchFunc, 
     176                                            matchAttributeValue,  
     177                                            attributeDesignator): 
     178        """Define a match function to match a given request attribute against  
     179        the input attribute value and AttributeDesignator defined in a policy  
     180        target 
     181        """             
     182        attributeId = attributeDesignator.attributeId 
     183        dataType = attributeDesignator.dataType 
     184         
     185        # Issuer is an optional match - see core spec. 7.2.4 
     186        issuer = attributeDesignator.issuer 
     187        if issuer is not None: 
     188            # Issuer found - set lambda to match this against the  
     189            # issuer setting in the request 
     190            _issuerMatch = lambda requestChildIssuer: ( 
     191                                                issuer == requestChildIssuer) 
     192        else: 
     193            # No issuer set - lambda returns True regardless 
     194            _issuerMatch = lambda requestChildIssuer: True 
     195         
     196         
     197        _attributeMatch = lambda attribute: ( 
     198            any([matchFunc.evaluate(matchAttributeValue, attrVal)  
     199                 for attrVal in attribute.attributeValues]) and 
     200            attribute.attributeId == attributeId and 
     201            attribute.dataType == dataType and 
     202            _issuerMatch(attribute.issuer) 
     203        ) 
     204         
     205        return _attributeMatch 
Note: See TracChangeset for help on using the changeset viewer.