+ # If the root node is a signed-credential (it should be), then
+ # get all its attributes and attach those to our signed_cred
+ # node.
+ # Specifically, PG and PLadd attributes for namespaces (which is reasonable),
+ # and we need to include those again here or else their signature
+ # no longer matches on the credential.
+ # We expect three of these, but here we copy them all:
+# signed_cred.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
+# and from PG (PL is equivalent, as shown above):
+# signed_cred.setAttribute("xsi:noNamespaceSchemaLocation", "http://www.protogeni.net/resources/credential/credential.xsd")
+# signed_cred.setAttribute("xsi:schemaLocation", "http://www.protogeni.net/resources/credential/ext/policy/1 http://www.protogeni.net/resources/credential/ext/policy/1/policy.xsd")
+
+ # HOWEVER!
+ # PL now also declares these, with different URLs, so
+ # the code notices those attributes already existed with
+ # different values, and complains.
+ # This happens regularly on delegation now that PG and
+ # PL both declare the namespace with different URLs.
+ # If the content ever differs this is a problem,
+ # but for now it works - different URLs (values in the attributes)
+ # but the same actual schema, so using the PG schema
+ # on delegated-to-PL credentials works fine.
+
+ # Note: you could also not copy attributes
+ # which already exist. It appears that both PG and PL
+ # will actually validate a slicecred with a parent
+ # signed using PG namespaces and a child signed with PL
+ # namespaces over the whole thing. But I don't know
+ # if that is a bug in xmlsec1, an accident since
+ # the contents of the schemas are the same,
+ # or something else, but it seems odd. And this works.
+ parentRoot = sdoc.documentElement
+ if parentRoot.tagName == "signed-credential" and parentRoot.hasAttributes():
+ for attrIx in range(0, parentRoot.attributes.length):
+ attr = parentRoot.attributes.item(attrIx)
+ # returns the old attribute of same name that was
+ # on the credential
+ # Below throws InUse exception if we forgot to clone the attribute first
+ oldAttr = signed_cred.setAttributeNode(attr.cloneNode(True))
+ if oldAttr and oldAttr.value != attr.value:
+ msg = "Delegating cred from owner %s to %s over %s replaced attribute %s value '%s' with '%s'" % (self.parent.gidCaller.get_urn(), self.gidCaller.get_urn(), self.gidObject.get_urn(), oldAttr.name, oldAttr.value, attr.value)
+ logger.warn(msg)
+ #raise CredentialNotVerifiable("Can't encode new valid delegated credential: %s" % msg)
+