<?xml version="1.0" encoding="UTF-8"?>
<!--
  _=_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_=
  Repose
  _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
  Copyright (C) 2010 - 2015 Rackspace US, Inc.
  _-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at
  
       http://www.apache.org/licenses/LICENSE-2.0
  
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
  =_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_=_
  -->


<xs:schema xmlns="http://docs.openrepose.org/repose/uri-user/v1.0"
           xmlns:html="http://www.w3.org/1999/xhtml"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:xerces="http://xerces.apache.org"
           xmlns:saxon="http://saxon.sf.net/"
           xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified"
           targetNamespace="http://docs.openrepose.org/repose/uri-user/v1.0">

    <!-- Client User Identity Configuration -->
    <xs:element name="uri-user" type="UriUserConfig"/>

    <xs:complexType name="UriUserConfig">
        <xs:annotation>
            <xs:documentation>
                <html:p>
                    With the URI User Filter, Repose can introspect a requests URI and set the X-PP-User and
                    X-PP-Group headers accordingly. These headers get consumed by the Repose Rate Limiting Filter.
                </html:p>
            </xs:documentation>
        </xs:annotation>

        <xs:all>
            <xs:element name="identification-mappings" type="IdentificationMappingList" minOccurs="1"
                        maxOccurs="1"/>
            <xs:element name="group" type="xs:string" minOccurs="0" maxOccurs="1" default="User_Standard">
                <xs:annotation>
                    <xs:documentation>
                        <html:p>The rate limiting group associated with the extracted identification data.</html:p>
                        <html:p>X-PP-Group will be set to whatever is configured in the group element of the
                            uri-user.cfg.xml file.
                        </html:p>
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="quality" type="doubleBetweenZeroandOne" minOccurs="0" maxOccurs="1"
                        default="0.5">
                <xs:annotation>
                    <xs:documentation>
                        <html:p>Quality assigned to user using the incoming identification data.</html:p>
                        <html:p>
                            Quality factors are defined in the
                            <html:a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.9">HTTP RFC -
                                Section-3.9
                            </html:a>
                            (for usage examples, see<html:a
                                href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html">HTTP RFC - Section
                            14.1</html:a>)
                            as a mechanism for weighting values in multi-value headers.
                            Possible values for quality are 0 to 1.0.
                        </html:p>
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:all>
    </xs:complexType>

    <xs:complexType name="IdentificationMappingList">
        <xs:annotation>
            <xs:documentation>
                <html:p>
                    A list of mapping elements which are regular expressions used to extract the identification
                    information from the request URI. The first regular expression in the list that finds a match
                    in the URI is what is used to extract the data.
                </html:p>
                <html:p>X-PP-User will be set to the identification data retrieved from the first matching regular
                    expression.
                </html:p>
            </xs:documentation>
        </xs:annotation>

        <xs:sequence>
            <xs:element name="mapping" type="IdentificationMapping" minOccurs="1" maxOccurs="unbounded"/>
        </xs:sequence>

        <xs:assert vc:minVersion="1.1"
                   xpathDefaultNamespace="##targetNamespace"
                   test="count(distinct-values(*/@id)) = count(*/@id)"
                   xerces:message="Mappings ids must be unique if specified"
                   saxon:message="Mappings ids must be unique if specified">
        </xs:assert>
    </xs:complexType>

    <xs:complexType name="IdentificationMapping">
        <xs:annotation>
            <xs:documentation>
                <html:p>Describes how to extract identification information from a given URI</html:p>
            </xs:documentation>
        </xs:annotation>

        <xs:attribute name="id" type="xs:string" use="optional">
            <xs:annotation>
                <xs:documentation>
                    <html:p>Unique identifier of the mapping</html:p>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>

        <xs:attribute name="identification-regex" type="xs:string" use="required">
            <xs:annotation>
                <xs:documentation>
                    <html:p>Regex used to extract identification information from a given URI</html:p>
                </xs:documentation>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>

    <xs:simpleType name="doubleBetweenZeroandOne">
        <xs:restriction base="xs:double">
            <xs:minInclusive value="0.0"/>
            <xs:maxInclusive value="1.0"/>
        </xs:restriction>
    </xs:simpleType>
</xs:schema>