Merge Master in geni-v3 conflict resolution
[sfa.git] / sfa / trust / credential.py
index 135d817..d9368c4 100644 (file)
@@ -237,7 +237,7 @@ class Credential(object):
     # @param string If string!=None, load the credential from the string
     # @param filename If filename!=None, load the credential from the file
     # FIXME: create and subject are ignored!
-    def __init__(self, create=False, subject=None, string=None, filename=None):
+    def __init__(self, create=False, subject=None, string=None, filename=None, cred=None):
         self.gidCaller = None
         self.gidObject = None
         self.expiration = None
@@ -250,6 +250,19 @@ class Credential(object):
         self.xml = None
         self.refid = None
         self.legacy = None
+        self.type = None
+        self.version = None
+
+        if cred:
+            if isinstance(cred, StringTypes):
+                string = cred
+                self.type = 'geni_sfa'
+                self.version = '1.0'
+            elif isinstance(cred, dict):
+                string = cred['geni_value']
+                self.type = cred['geni_type']
+                self.version = cred['geni_version']
+                
 
         # Check if this is a legacy credential, translate it if so
         if string or filename:
@@ -272,13 +285,14 @@ class Credential(object):
             if os.path.isfile(path + '/' + 'xmlsec1'):
                 self.xmlsec_path = path + '/' + 'xmlsec1'
                 break
-        if not self.xmlsec_path:
-            logger.warn("Could not locate binary for xmlsec1 - SFA will be unable to sign stuff !!")
 
     def get_subject(self):
+        subject = ""
         if not self.gidObject:
             self.decode()
-        return self.gidObject.get_subject()
+        if self.gidObject:
+            subject = self.gidObject.get_printable_subject()
+        return subject
 
     # sounds like this should be __repr__ instead ??
     def get_summary_tostring(self):
@@ -628,11 +642,7 @@ class Credential(object):
     # you have loaded an existing signed credential, do not call encode() or sign() on it.
 
     def sign(self):
-        if not self.issuer_privkey:
-            logger.warn("Cannot sign credential (no private key)")
-            return
-        if not self.issuer_gid:
-            logger.warn("Cannot sign credential (no issuer gid)")
+        if not self.issuer_privkey or not self.issuer_gid:
             return
         doc = parseString(self.get_xml())
         sigs = doc.getElementsByTagName("signatures")[0]
@@ -661,10 +671,8 @@ class Credential(object):
         # Call out to xmlsec1 to sign it
         ref = 'Sig_%s' % self.get_refid()
         filename = self.save_to_random_tmp_file()
-        command='%s --sign --node-id "%s" --privkey-pem %s,%s %s' \
-            % (self.xmlsec_path, ref, self.issuer_privkey, ",".join(gid_files), filename)
-#        print 'command',command
-        signed = os.popen(command).read()
+        signed = os.popen('%s --sign --node-id "%s" --privkey-pem %s,%s %s' \
+                 % (self.xmlsec_path, ref, self.issuer_privkey, ",".join(gid_files), filename)).read()
         os.remove(filename)
 
         for gid_file in gid_files:
@@ -688,6 +696,12 @@ class Credential(object):
     def decode(self):
         if not self.xml:
             return
+
+        doc = None
+        try:
+            doc = parseString(self.xml)
+        except ExpatError,e:
+            raise CredentialNotVerifiable("Malformed credential")
         doc = parseString(self.xml)
         sigs = []
         signed_cred = doc.getElementsByTagName("signed-credential")
@@ -1043,12 +1057,16 @@ class Credential(object):
         print self.dump_string(*args, **kwargs)
 
 
-    def dump_string(self, dump_parents=False, show_xml=False):
+    def dump_string(self, dump_parents=False):
         result=""
         result += "CREDENTIAL %s\n" % self.get_subject()
         filename=self.get_filename()
         if filename: result += "Filename %s\n"%filename
-        result += "      privs: %s\n" % self.get_privileges().save_to_string()
+        privileges = self.get_privileges()
+        if privileges:
+            result += "      privs: %s\n" % privileges.save_to_string()
+        else:
+            result += "      privs: \n" 
         gidCaller = self.get_gid_caller()
         if gidCaller:
             result += "  gidCaller:\n"
@@ -1070,16 +1088,4 @@ class Credential(object):
             result += "\nPARENT"
             result += self.parent.dump_string(True)
 
-        if show_xml:
-            try:
-                tree = etree.parse(StringIO(self.xml))
-                aside = etree.tostring(tree, pretty_print=True)
-                result += "\nXML\n"
-                result += aside
-                result += "\nEnd XML\n"
-            except:
-                import traceback
-                print "exc. Credential.dump_string / XML"
-                traceback.print_exc()
-
         return result