# IN THE WORK.
#----------------------------------------------------------------------
+from __future__ import print_function
+
from sfa.trust.credential import Credential, append_sub, DEFAULT_CREDENTIAL_LIFETIME
from sfa.util.sfalogging import logger
from sfa.util.sfatime import SFATIME_FORMAT
-from StringIO import StringIO
from xml.dom.minidom import Document, parseString
+from sfa.util.py23 import StringIO
+
HAVELXML = False
try:
from lxml import etree
# or between a subject and a class of targets (all those satisfying a role).
#
# An ABAC credential is like a normal SFA credential in that it has
-# a validated signature block and is checked for expiration.
+# a validated signature block and is checked for expiration.
# It does not, however, have 'privileges'. Rather it contains a 'head' and
# list of 'tails' of elements, each of which represents a principal and
# role.
# A special case of an ABAC credential is a speaks_for credential. Such
-# a credential is simply an ABAC credential in form, but has a single
+# a credential is simply an ABAC credential in form, but has a single
# tail and fixed role 'speaks_for'. In ABAC notation, it asserts
# AGENT.speaks_for(AGENT)<-CLIENT, or "AGENT asserts that CLIENT may speak
# for AGENT". The AGENT in this case is the head and the CLIENT is the
# An ABAC element contains a principal (keyid and optional mnemonic)
# and optional role and linking_role element
class ABACElement:
- def __init__(self, principal_keyid, principal_mnemonic=None, \
- role=None, linking_role=None):
+
+ def __init__(self, principal_keyid, principal_mnemonic=None,
+ role=None, linking_role=None):
self._principal_keyid = principal_keyid
self._principal_mnemonic = principal_mnemonic
self._role = role
self._linking_role = linking_role
def get_principal_keyid(self): return self._principal_keyid
+
def get_principal_mnemonic(self): return self._principal_mnemonic
+
def get_role(self): return self._role
+
def get_linking_role(self): return self._linking_role
def __str__(self):
# Subclass of Credential for handling ABAC credentials
# They have a different cred_type (geni_abac vs. geni_sfa)
# and they have a head and tail and role (as opposed to privileges)
+
+
class ABACCredential(Credential):
ABAC_CREDENTIAL_TYPE = 'geni_abac'
- def __init__(self, create=False, subject=None,
+ def __init__(self, create=False, subject=None,
string=None, filename=None):
- self.head = None # An ABACElemenet
- self.tails = [] # List of ABACElements
- super(ABACCredential, self).__init__(create=create,
- subject=subject,
- string=string,
+ self.head = None # An ABACElemenet
+ self.tails = [] # List of ABACElements
+ super(ABACCredential, self).__init__(create=create,
+ subject=subject,
+ string=string,
filename=filename)
self.cred_type = ABACCredential.ABAC_CREDENTIAL_TYPE
- def get_head(self) :
- if not self.head:
+ def get_head(self):
+ if not self.head:
self.decode()
return self.head
- def get_tails(self) :
+ def get_tails(self):
if len(self.tails) == 0:
self.decode()
return self.tails
rt0_root = rt0s[0]
heads = self._get_abac_elements(rt0_root, 'head')
if len(heads) != 1:
- raise CredentialNotVerifiable("ABAC credential should have exactly 1 head element, had %d" % len(heads))
+ raise CredentialNotVerifiable(
+ "ABAC credential should have exactly 1 head element, had %d" % len(heads))
self.head = heads[0]
self.tails = self._get_abac_elements(rt0_root, 'tail')
for elt in elements:
keyids = elt.getElementsByTagName('keyid')
if len(keyids) != 1:
- raise CredentialNotVerifiable("ABAC credential element '%s' should have exactly 1 keyid, had %d." % (label, len(keyids)))
+ raise CredentialNotVerifiable(
+ "ABAC credential element '%s' should have exactly 1 keyid, had %d." % (label, len(keyids)))
keyid_elt = keyids[0]
keyid = keyid_elt.childNodes[0].nodeValue.strip()
linking_role = None
linking_role_elts = elt.getElementsByTagName('linking_role')
if len(linking_role_elts) > 0:
- linking_role = linking_role_elts[0].childNodes[0].nodeValue.strip()
+ linking_role = linking_role_elts[
+ 0].childNodes[0].nodeValue.strip()
abac_element = ABACElement(keyid, mnemonic, role, linking_role)
abac_elements.append(abac_element)
def dump_string(self, dump_parents=False, show_xml=False):
result = "ABAC Credential\n"
- filename=self.get_filename()
- if filename: result += "Filename %s\n"%filename
+ filename = self.get_filename()
+ if filename:
+ result += "Filename %s\n" % filename
if self.expiration:
- result += "\texpiration: %s \n" % self.expiration.strftime(SFATIME_FORMAT)
+ result += "\texpiration: %s \n" % self.expiration.strftime(
+ SFATIME_FORMAT)
- result += "\tHead: %s\n" % self.get_head()
+ result += "\tHead: %s\n" % self.get_head()
for tail in self.get_tails():
result += "\tTail: %s\n" % tail
if self.get_signature():
result += "\nEnd XML\n"
except:
import traceback
- print "exc. Credential.dump_string / XML"
+ print("exc. Credential.dump_string / XML")
traceback.print_exc()
return result
# sounds like this should be __repr__ instead ??
- # Produce the ABAC assertion. Something like [ABAC cred: Me.role<-You] or similar
+ # Produce the ABAC assertion. Something like [ABAC cred: Me.role<-You] or
+ # similar
def pretty_cred(self):
result = "[ABAC cred: " + str(self.get_head())
for tail in self.get_tails():
def createABACElement(self, doc, tagName, abacObj):
kid = abacObj.get_principal_keyid()
- mnem = abacObj.get_principal_mnemonic() # may be None
- role = abacObj.get_role() # may be None
- link = abacObj.get_linking_role() # may be None
+ mnem = abacObj.get_principal_mnemonic() # may be None
+ role = abacObj.get_role() # may be None
+ link = abacObj.get_linking_role() # may be None
ele = doc.createElement(tagName)
prin = doc.createElement('ABACprincipal')
ele.appendChild(prin)
# WARNING:
# In general, a signed credential obtained externally should
# not be changed else the signature is no longer valid. So, once
- # you have loaded an existing signed credential, do not call encode() or sign() on it.
+ # you have loaded an existing signed credential, do not call encode() or
+ # sign() on it.
def encode(self):
# Create the XML document
# Note that delegation of credentials between the 2 only really works
# cause those schemas are identical.
# Also note these PG schemas talk about PG tickets and CM policies.
- signed_cred.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
- signed_cred.setAttribute("xsi:noNamespaceSchemaLocation", "http://www.geni.net/resources/credential/2/credential.xsd")
- signed_cred.setAttribute("xsi:schemaLocation", "http://www.planet-lab.org/resources/sfa/ext/policy/1 http://www.planet-lab.org/resources/sfa/ext/policy/1/policy.xsd")
+ signed_cred.setAttribute(
+ "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
+ signed_cred.setAttribute("xsi:noNamespaceSchemaLocation",
+ "http://www.geni.net/resources/credential/2/credential.xsd")
+ signed_cred.setAttribute(
+ "xsi:schemaLocation", "http://www.planet-lab.org/resources/sfa/ext/policy/1 http://www.planet-lab.org/resources/sfa/ext/policy/1/policy.xsd")
# PG says for those last 2:
# signed_cred.setAttribute("xsi:noNamespaceSchemaLocation", "http://www.protogeni.net/resources/credential/credential.xsd")
append_sub(doc, cred, "uuid", "")
if not self.expiration:
- self.set_expiration(datetime.datetime.utcnow() + datetime.timedelta(seconds=DEFAULT_CREDENTIAL_LIFETIME))
+ self.set_expiration(datetime.datetime.utcnow(
+ ) + datetime.timedelta(seconds=DEFAULT_CREDENTIAL_LIFETIME))
self.expiration = self.expiration.replace(microsecond=0)
if self.expiration.tzinfo is not None and self.expiration.tzinfo.utcoffset(self.expiration) is not None:
# TZ aware. Make sure it is UTC
self.expiration = self.expiration.astimezone(tz.tzutc())
- append_sub(doc, cred, "expires", self.expiration.strftime(SFATIME_FORMAT)) # RFC3339
+ append_sub(doc, cred, "expires", self.expiration.strftime(
+ SFATIME_FORMAT)) # RFC3339
abac = doc.createElement("abac")
rt0 = doc.createElement("rt0")