Repository: identitypython/pysaml2
Issue: [Metadata] Configurable AssertionConsumerService isDefault and index values (IndexedEndpointType)

In my SP metadata I have
`<ns0:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://sp1.test.org:8000/saml2/acs/" index="1"/>`

I'd like instead to have:
`<ns0:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://sp1.test.org:8000/saml2/acs/" index="0" isDefault=True/>`

I tried a little modification in md.AssertionConsumerService (line 520) this way:
````
class AssertionConsumerService(IndexedEndpointType_):
    """The urn:oasis:names:tc:SAML:2.0:metadata:AssertionConsumerService
    element """
    c_tag = 'AssertionConsumerService'
    c_namespace = NAMESPACE
    c_children = IndexedEndpointType_.c_children.copy()
    c_attributes = IndexedEndpointType_.c_attributes.copy()
    c_child_order = IndexedEndpointType_.c_child_order[:]
    c_cardinality = IndexedEndpointType_.c_cardinality.copy()

    def __init__(self, **kwargs):
        super().__init__()
        self.index = 0
        self.is_default = "true"
````

But still cannot set the index value to zero.
More in the deep I also see that...

I've also found in metadata.do_attribute_consuming_service, at line 485, index value as a constant:
````
        ac_serv = md.AttributeConsumingService(
            index="1", service_name=service_name,
            requested_attribute=requested_attributes)
````
`metadata.do_attribute_consuming_service` also take `spsso` object as argument, it have `spsso.assertion_consumer_service[0]` with the followings attributes (see index):
````
{'extension_attributes': {}, 
 'location': 'http://sp1.testunical.it:8000/saml2/acs/', 
 'text': None, 
 'index': '1', 
 'binding': 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
 'encrypted_assertion': None,
 'extension_elements': [],
 'response_location': None,
 'is_default': None}
````
Probably `ac_serv` could use `spsso.assertion_consumer_service[0]`'s index value to get coupled with it, rather then a constant value like "1".

`spsso` originates in `metadata.do_spsso_descriptor` and it seems that the index value is initialized in `metadata.do_endopints`, as following:
````
def do_endpoints(conf, endpoints):
    service = {}

    for endpoint, (eclass, indexed) in endpoints.items():
        try:
            servs = []
            i = 1
````

Setting the initial value of `i` to 0 and changing the constant argument "index" in md.AttributeConsumingService to `0` made finally the index starting from 0...

Bytheway I'd prefer a solution with any modifications in the pySAML2 code.
I patched in my SP implementation the descriptor objects, before the metadata get encoded in the http response, in this way:
````
def metadata(request, config_loader_path=None, valid_for=None):
    """Returns an XML with the SAML 2.0 metadata for this
    SP as configured in the settings.py file.
    """
    conf = get_config(config_loader_path, request)
    metadata = entity_descriptor(conf)

    # this will renumber acs starting from 0 and set index=0 as is_default
    cnt = 0
    for attribute_consuming_service in metadata.spsso_descriptor.attribute_consuming_service:
        attribute_consuming_service.index = str(cnt)
        cnt += 1

    cnt = 0
    for assertion_consumer_service in metadata.spsso_descriptor.assertion_consumer_service:
        assertion_consumer_service.is_default = 'true' if not cnt else '' 
        assertion_consumer_service.index = str(cnt)
        cnt += 1
        
    return HttpResponse(content=text_type(metadata).encode('utf-8'),
                        content_type="text/xml; charset=utf8")
````

My question is, is there any way to do this using specific options in SP_CONF? 
Why ACS start from 1?
Is there an option to configure a ACS binding as the default one (isDefault)?

I read [OASIS Specifications, saml-metadata-2.0-os.pdf - "2.2.3 Complex Type IndexedEndpointType"](https://docs.oasis-open.org/security/saml/v2.0/saml-metadata-2.0-os.pdf) for better view and I understand that pySAML2 behaviour is formally correct. This question is due to the fact the italian SPID federation needs this kind of metadata to permit us to join! 

Thank you

Changed files:
src/saml2/config.py

diff --git a/src/saml2/config.py b/src/saml2/config.py
index 8b865dcb..6687a60f 100644
--- a/src/saml2/config.py
+++ b/src/saml2/config.py
@@ -404,7 +404,12 @@ class Config(object):
         if endps and service in endps:
             for endpspec in endps[service]:
                 try:
-                    endp, bind = endpspec
+                    # endspec sometime is str, sometime is a tuple
+                    if type(endpspec) in (tuple, list):
+                        # slice prevents 3-tuple, eg: sp's assertion_consumer_service
+                        endp, bind = endpspec[0:2]
+                    else:
+                        endp, bind = endpspec
                     if binding is None or bind == binding:
                         spec.append(endp)
                 except ValueError: