using method get_self_credential to bootstrap SM credential
[sfa.git] / sfa / plc / api.py
index 21e573e..5af31ec 100644 (file)
@@ -17,6 +17,7 @@ from sfa.util.faults import *
 from sfa.util.debug import *
 from sfa.trust.rights import *
 from sfa.trust.credential import *
+from sfa.trust.certificate import *
 from sfa.util.misc import *
 from sfa.util.sfalogging import *
 from sfa.util.genitable import *
@@ -115,10 +116,17 @@ class GeniAPI:
         self.auth = Auth(peer_cert)
         self.interface = interface
         self.key_file = key_file
+        self.key = Keypair(filename=self.key_file)
         self.cert_file = cert_file
+        self.cert = Certificate(filename=self.cert_file)
         self.credential = None
-        self.plshell = self.getPLCShell()
-        self.plshell_version = self.getPLCShellVersion()
+        
+        # Initialize the PLC shell only if SFA wraps a myPLC
+        rspec_type = self.config.get_aggregate_rspec_type()
+        if (rspec_type == 'pl' or rspec_type == 'vini'):
+            self.plshell = self.getPLCShell()
+            self.plshell_version = self.getPLCShellVersion()
+
         self.hrn = self.config.SFA_INTERFACE_HRN
         self.time_format = "%Y-%m-%d %H:%M:%S"
         self.logger=get_sfa_logger()
@@ -128,14 +136,15 @@ class GeniAPI:
                        'AuthMethod': 'password',
                        'AuthString': self.config.SFA_PLC_PASSWORD}
         try:
+            self.plshell_type = 'direct'
             import PLC.Shell
             shell = PLC.Shell.Shell(globals = globals())
             shell.AuthCheck(self.plauth)
             return shell
         except ImportError:
+            self.plshell_type = 'xmlrpc' 
             # connect via xmlrpc
             url = self.config.SFA_PLC_URL
-             
             shell = xmlrpclib.Server(url, verbose = 0, allow_none = True)
             shell.AuthCheck(self.plauth)
             return shell
@@ -161,7 +170,6 @@ class GeniAPI:
         else:
             return self.getCredentialFromRegistry()
     
-
     def getCredentialFromRegistry(self):
         """ 
         Get our credential from a remote registry using a geniclient connection
@@ -172,14 +180,23 @@ class GeniAPI:
         cred_filename = path + os.sep + filename
         try:
             credential = Credential(filename = cred_filename)
-            return credential
+            return credential.save_to_string(save_parents=True)
         except IOError:
             from sfa.server.registry import Registries
             registries = Registries(self)
             registry = registries[self.hrn]
-            self_cred = registry.get_credential(None, type, self.hrn)
-            cred = registry.get_credential(self_cred, type, self.hrn)
-            cred.save_to_file(cred_filename, save_parents=True)
+           cert_string=self.cert.save_to_string(save_parents=True)
+            # get self credential
+            arg_list = [cert_string,type,self.hrn]
+            request_hash=self.key.compute_hash(arg_list)
+            self_cred = registry.get_self_credential(cert_string, type, self.hrn, request_hash)
+            # get credential
+            arg_list = [self_cred,type,self.hrn]
+            request_hash=self.key.compute_hash(arg_list)
+            cred = registry.get_credential(self_cred, type, self.hrn, request_hash)
+            
+            # save cred to file
+            Credential(string=cred).save_to_file(cred_filename, save_parents=True)
             return cred
 
     def getCredentialFromLocalRegistry(self):
@@ -216,7 +233,7 @@ class GeniAPI:
         new_cred.encode()
         new_cred.sign()
 
-        return new_cred
+        return new_cred.save_to_string(save_parents=True)
    
 
     def loadCredential (self):
@@ -309,7 +326,7 @@ class GeniAPI:
             record.update({})
             return
 
-        if (type in ["authority", "sa", "ma"]):
+        if (type in ["authority"]):
             pl_res = self.plshell.GetSites(self.plauth, [pointer])
         elif (type == "slice"):
             pl_res = self.plshell.GetSlices(self.plauth, [pointer])
@@ -361,34 +378,42 @@ class GeniAPI:
         record.update(pl_record)
 
 
-    def lookup_users(self, user_id_list, role="*"):
-        table = GeniTable() 
-        record_list = []
-        for person_id in user_id_list:
-            user_records = table.find({'type': 'user', 'pointer': person_id})
-            for user_record in user_records:
-                self.fill_record_info(user_record)
-                user_roles = user_record.get("roles")
-                if (role=="*") or (role in user_roles):
-                    record_list.append(user_record['hrn'])
-        return record_list
 
     def fill_record_geni_info(self, record):
         geni_info = {}
         type = record['type']
+        table = GeniTable()
         if (type == "slice"):
             person_ids = record.get("person_ids", [])
-            researchers = self.lookup_users(person_ids)
+            persons = table.find({'type': 'user', 'pointer': person_ids})
+            researchers = [person['hrn'] for person in persons]
             geni_info['researcher'] = researchers
 
         elif (type == "authority"):
             person_ids = record.get("person_ids", [])
-            pis = self.lookup_users(person_ids, "pi")
-            operators = self.lookup_users(person_ids, "tech")
-            owners = self.lookup_users(person_ids, "admin")
-            geni_info['pi'] = pis
-            geni_info['operator'] = operators
-            geni_info['owner'] = owners
+            persons = table.find({'type': 'user', 'pointer': person_ids})
+            persons_dict = {}
+            for person in persons:
+                persons_dict[person['pointer']] = person 
+            pl_persons = self.plshell.GetPersons(self.plauth, person_ids, ['person_id', 'roles'])
+            pis, techs, admins = [], [], []
+            for person in pl_persons:
+                pointer = person['person_id']
+                
+                if pointer not in persons_dict:
+                    # this means there is not sfa record for this user
+                    continue    
+                hrn = persons_dict[pointer]['hrn']    
+                if 'pi' in person['roles']:
+                    pis.append(hrn)
+                if 'tech' in person['roles']:
+                    techs.append(hrn)
+                if 'admin' in person['roles']:
+                    admins.append(hrn)
+            
+            geni_info['PI'] = pis
+            geni_info['operator'] = techs
+            geni_info['owner'] = admins
             # xxx TODO: OrganizationName
 
         elif (type == "node"):
@@ -442,13 +467,11 @@ class GeniAPI:
     # add people who are in the new list, but not the oldList
         for personId in newIdList:
             if not (personId in oldIdList):
-                print "adding id", personId, "to", record.get_name()
                 addFunc(self.plauth, personId, containerId)
 
         # remove people who are in the old list, but not the new list
         for personId in oldIdList:
             if not (personId in newIdList):
-                print "removing id", personId, "from", record.get_name()
                 delFunc(self.plauth, personId, containerId)
 
     def update_membership(self, oldRecord, record):