<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
   xmlns:policy-arc="http://www.nordugrid.org/schemas/policy-arc"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   targetNamespace="http://www.nordugrid.org/schemas/policy-arc"
   elementFormDefault="qualified"
   attributeFormDefault="unqualified">

 <!--One Policy is composed of a few Rules; 
    one Rule is composed of a tuple <Subjects, Resources, Actions, Conditions>, 
    and each Rule has one Decision: Permit or Deny.
 -->
 <!--The proposed schema is not as complicated as XACML, but not so adapatable and general as XACML.
  
    The elements and attributes in the policy can only be understood by Arc policy evaluation engine;
    Each service or resource can have one or more authorization policy file. 
    If the policy enforcement point only includes one entity on which the policy needs to be enforced,
    the "Resources" element can be omitted. For instance, if we have policy which is attached to each
    file, it is not necessary to specify this file as the Resource element of Policy.
 -->
 <!-- For quick reference here is a tree desribing the interconnection of 
    the main elements. Multiplicity is specified in brackets.
      Policy (1)
        Rule (1-)
          Subjects (1)
            Subject (1-)
              Attribute (1-)
          Resources (0-1)
            Resource (1-)
          Actions (0-1)
            Action (1-)
          Conditions (0-1)
            Condition (1-)
              Attribute (1-)
 -->
 <!-- Human-readable description of element -->
 <xsd:element name="Description" type="xsd:string"/>

 <!-- An authorization policy is a combination of Rules. Their evalutaion results
      are combined according to a specified rule combining algorithm. -->
 <xsd:element name="Policy" type="policy-arc:PolicyType"/>
 <xsd:complexType name="PolicyType">
  <xsd:sequence>
   <xsd:element ref="policy-arc:Description" minOccurs="0"/>
   <xsd:element ref="policy-arc:Rule" minOccurs="1" maxOccurs="unbounded"/>
  </xsd:sequence>
  <xsd:attribute name="Id" type="xsd:anyURI" use="required"/>
  <!-- Combining Algorithm for Rules,  e.g. "DenyOverride" means any "Deny" evaluation 
       resulting from any Rule will override all "Permit" results from the other Rules. -->
  <xsd:attribute name="RuleCombiningAlg" type="xsd:string"/> 
 </xsd:complexType>


 <!--One rule is a unit of decision-making, which means there is an implicit relationship 
  among <Subjects, Resources, Actions, Conditions>. 
  There are some principles about the Rule definition:
   1. Each Rule has a tuple <Subjects, Resources, Actios, Conditions> (actually 
      <Subjects, Resources, Actions, Conditions, Effect>). The policy administrator should 
      define the rules according to the granularity and the exact value of Actions, Resources, 
      Conditions, and Subjects. For example, there is a Rule: 
      <UserA/UserB, FileX, Read/List, 2008-05-01T14:00:00Z~2008-05-01T20:00:00Z, Permit>.
      If the administrator wants to add "Delete" permssion for "UserA/UserB" to "FileX" at Condition 
      "2008-05-01T14:00:00Z~2008-05-01T20:00:00Z" (which means the following constraints:
      <UserA/UserB, FileX, Delete, 2008-05-01T14:00:00Z~2008-05-01T20:00:00Z, Permit>), 
      then the constraint can be merged to the existing rule: 
      <UserA/UserB, FileX, Read/List/Delete, 2008-05-01T14:00:00Z~2008-05-01T20:00:00Z, Permit>; 
      Otherwise, if any of the other element (Subjects, Resources, Conditions, Effect) 
      does not match, a new Rule should be added into this Policy.
   2. Subjects is a must element for each Rule. Each Rule must have one and only one Subjects element.
   3. Each Rule can have zero or one Resources, Actions, Conditions element. 
      If the policy is attached to some specified Resource, then Resources element is not necessary, 
      just like GACL policy which is attached to each file. If there is only one operation applicable to 
      the Resources then Actions element can be omitted, just like gridmap in which the operation is to grant
      all permissions of a specified system to Subject.
      If there is no Conditions constrains, the Conditions element can be omittted.
      Moreover, the absence of one or more elements can make the Rule more general, and then we can need less 
      items of rules. But the price is more coarse granularity. -->
 <xsd:element name="Rule" type="policy-arc:RuleType"/>
 <xsd:complexType name="RuleType">
  <xsd:sequence> 
   <xsd:element ref="policy-arc:Description" minOccurs="0"/>
   <xsd:element ref="policy-arc:Subjects"/>
   <xsd:element ref="policy-arc:Resources" minOccurs="0"/>
   <xsd:element ref="policy-arc:Actions" minOccurs="0"/>
   <xsd:element ref="policy-arc:Conditions" minOccurs="0"/>
  </xsd:sequence>
  <xsd:attribute name="Id" type="xsd:string" use="required"/>
  <xsd:attribute name="Decision" type="policy-arc:DecisionType" use="required"/>
 </xsd:complexType> 


 <!--Some common definitions-->
 
 <!-- Decision to be made by evaluation of Rule. -->
 <xsd:simpleType name="DecisionType">
  <xsd:restriction base="xsd:string">
   <xsd:enumeration value="Permit"/>
   <xsd:enumeration value="Deny"/>
  </xsd:restriction>
 </xsd:simpleType>

 <!--Ref element is used by Subjects, Resources, Actions and Conditions to 
   refer to other set of corresponding elements defined out of scope of 
   refering element.
   -->
 <xsd:element name="Ref" type="policy-arc:RefType"/>
 <xsd:complexType name="RefType">
  <xsd:simpleContent>
   <!--Identifier of refered element-->
   <xsd:extension base="xsd:anyURI">
    <!--Location specifies location (usually local path) of another file 
      containing refered element-->
    <xsd:attribute name="Location" type="xsd:anyURI" use="optional"/>
   </xsd:extension>
  </xsd:simpleContent>
 </xsd:complexType>

 <!---SubjectsRef for specifying a Subjects reference -->
 <xsd:element name="SubjectsRef" type="policy-arc:RefType"/>

 <!--Definition of Subjects-->
 <xsd:element name="Subjects" type="policy-arc:SubjectsType"/>
 <xsd:complexType name="SubjectsType">
  <xsd:choice maxOccurs="unbounded">
   <!--Reference to external Subjects element which is optionally 
     stored in a separate file--> 
   <xsd:element ref="policy-arc:SubjectsRef"/>
   <!--Subject to which rule should be applied -->
   <xsd:element ref="policy-arc:Subject"/>
  </xsd:choice>
  <!-- Data Type of the Subjects, the Type could be specified here,
   which means all of the low-level <Subject/> have the same DataType, 
   otherwise it should be specified in the lower-level node <Subject/>
    However, for these three levels: <Subjects/>, <Subject/>, <Attribute> 
   there should be at least one and only one level which will have "Type" 
   attribute -->
  <xsd:attribute name="Type" type="xsd:anyURI" use="optional"/>
  <!-- Identifier for external reference. Not like the definition in XACML, 
   here the Id attribute is optional. If there is Id defined in policy, there 
   should also be Id or AttributeId defined in request-->
  <xsd:attribute name="Id" type="xsd:anyURI" use="optional"/>
 </xsd:complexType>

 <xsd:element name="Subject" type="policy-arc:SubjectType"/>
 <xsd:complexType name="SubjectType">
  <!--If there are more than one Attribute elements in one Subject, the 
    request should match all of these: 
      <Subject>
       <Attribute Type="X500DN">/O=Grid/OU=KnowARC/CN=ABC</Attribute>
       <Attribute Type="ShibName">urn:mace:shibboleth:examples</Attribute>
      </Subject>
  -->
  <xsd:sequence>
   <xsd:element name="Attribute" maxOccurs="unbounded">
     <xsd:complexType>
      <xsd:simpleContent>
       <xsd:extension base="xsd:string">
       <!-- Data Type of the Attribute, if the DataType of <Attribute/>s 
         under the <Subject/> node are not the same, then Type should be 
         specified here -->
        <xsd:attribute name="Type" type="xsd:anyURI" use="optional"/>
       </xsd:extension>
      </xsd:simpleContent>
     </xsd:complexType>
   </xsd:element>
  </xsd:sequence>
  <!-- Data Type of the Subject, the Type could be specified here,
   which means all of the low-level <Attribute/> have the same DataType, 
   otherwise it should be specified in the lower-level node <Attribute/> -->
  <xsd:attribute name="Type" type="xsd:anyURI" use="optional"/>
 </xsd:complexType>

 <!--Definition of Resources differs from the definition of Subjects.
   Here only two levels are available: <Resources> and <Resource> -->
 <xsd:element name="ResourcesRef" type="policy-arc:RefType"/>
 <xsd:element name="Resources" type="policy-arc:ResourcesType"/>
 <xsd:complexType name="ResourcesType">
  <xsd:choice maxOccurs="unbounded">
   <xsd:element ref="policy-arc:ResourcesRef"/>
   <xsd:element ref="policy-arc:Resource"/>
  </xsd:choice>
  <!-- Data Type of Resources. the Type could be specified here, which 
    means all of the lower-level <Resource/> have the same DataType, 
    otherwise it should be specified in the lower-level node <Resource/>.
     However, for these two levels: <Resources/>, <Resource/>, there should
     be at least one and only one level which will have "Type" attribute -->
  <xsd:attribute name="Type" type="xsd:anyURI" use="optional"/>
  <!-- Identifier for external reference -->
  <xsd:attribute name="Id" type="xsd:anyURI" use="optional"/>
 </xsd:complexType>

 <!--Definition of Resource to which policy applies-->
 <xsd:element name="Resource" type="policy-arc:ResourceType"/>
 <xsd:complexType name="ResourceType">
  <xsd:simpleContent>
   <xsd:extension base="xsd:string">
    <!-- Data Type of Resource  -->
    <xsd:attribute name="Type" type="xsd:anyURI" use="optional"/>
   </xsd:extension>
  </xsd:simpleContent>
 </xsd:complexType>


 <!--Definition of Actions which may be requested. Definition is similiar to 
   <Resources> except no <ActionsRef> is supported here -->
 <xsd:element name="Actions" type="policy-arc:ActionsType"/>
 <xsd:complexType name="ActionsType">
  <xsd:sequence maxOccurs="unbounded">
   <xsd:element ref="policy-arc:Action"/>
  </xsd:sequence>
  <!-- Data Type of Actions.-->
  <xsd:attribute name="Type" type="xsd:anyURI" use="optional"/>
  <!-- Identifier for external reference-->
  <xsd:attribute name="Id" type="xsd:anyURI" use="optional"/>
 </xsd:complexType>

 <xsd:element name="Action" type="policy-arc:ActionType"/>
 <xsd:complexType name="ActionType">
  <xsd:simpleContent>
   <xsd:extension base="xsd:string">
    <xsd:attribute name="Type" type="xsd:anyURI" use="optional"/>
   </xsd:extension>
  </xsd:simpleContent>
 </xsd:complexType>


 <!--Definition of Conditions. 
   The definition of Conditions is complicated, because there can be many 
   types of conditions: Time, Duration, URI, etc.;
   The match-making of Conditions with Request.Contex (See schema definition 
   of Request) is complicated as well, because each type of Condition could 
   require its own match-making algorithm. Simple "string1 == string2" 
   match-making is not adequate in this case. -->
 <!--The relationship between <Attribute>s is "and"; The relationship between 
   <Condition>s is "or" -->
 <xsd:element name="Conditions" type="policy-arc:ConditionsType"/>
 <xsd:element name="ConditionsRef" type="policy-arc:RefType"/>
 <xsd:complexType name="ConditionsType">
  <xsd:choice maxOccurs="unbounded">
   <!--Reference to Conditions could optionally be stored in a separate file.
     It is reasonable when the administrator wants to define some general 
     condition constraints -->
   <xsd:element ref="policy-arc:ConditionsRef"/>
   <xsd:element ref="policy-arc:Condition"/>
  </xsd:choice>
  <!-- Data Type of Conditions.-->
  <xsd:attribute name="Type" type="xsd:anyURI" use="optional"/>
  <!-- Identifier for external reference-->  
  <xsd:attribute name="Id" type="xsd:anyURI" use="optional"/>
 </xsd:complexType>

 <xsd:element name="Condition" type="policy-arc:ConditionType"/>
 <xsd:complexType name="ConditionType">
  <!--If there are more than one <Attribute> elements in one <Condition>, 
    the request should match all of these.-->
  <xsd:sequence>
   <xsd:element name="Attribute" maxOccurs="unbounded">
    <xsd:complexType>
     <xsd:complexContent>
      <xsd:extension base="policy-arc:VariableType">
       <!-- Data Type of the Attribute, if the data Type of <Attribute/>s 
         under the <Condition/> node are different, then Type should be 
	 specified here -->
       <xsd:attribute name="Type" type="xsd:anyURI" use="optional"/>
       <!-- Function name for evaluation, if not exists, "equal" function will be supposed-->
       <xsd:attribute name="Function" type="xsd:string" use="optional"/>
      </xsd:extension>
     </xsd:complexContent>
    </xsd:complexType>
   </xsd:element>
  </xsd:sequence>
 </xsd:complexType>

 <xsd:element name="Variable" type="policy-arc:VariableType" abstract="true"/>
 <xsd:complexType name="VariableType" abstract="true"/>

</xsd:schema>
