adding support for geni_speaking_for option
[sfa.git] / sfa / trust / auth.py
index 2f2afb0..48ad5b2 100644 (file)
@@ -34,10 +34,18 @@ class Auth:
         self.trusted_cert_list = TrustedRoots(self.config.get_trustedroots_dir()).get_list()
         self.trusted_cert_file_list = TrustedRoots(self.config.get_trustedroots_dir()).get_file_list()
 
-        
-        
-    def checkCredentials(self, creds, operation, hrn = None):
+       
+    def checkCredentials(self, creds, operation, hrn = None, speaking_for_hrn = None):
+
+        def log_invalid_cred(cred):
+            cred_obj=Credential(string=cred)
+            logger.debug("failed to validate credential - dump=%s"%cred_obj.dump_string(dump_parents=True))
+            error = sys.exc_info()[:2]
+            return error
+
         valid = []
+        speaks_for_cred = None
+
         if not isinstance(creds, list):
             creds = [creds]
         logger.debug("Auth.checkCredentials with %d creds"%len(creds))
@@ -46,14 +54,25 @@ class Auth:
                 self.check(cred, operation, hrn)
                 valid.append(cred)
             except:
-                cred_obj=Credential(string=cred)
-                logger.debug("failed to validate credential - dump=%s"%cred_obj.dump_string(dump_parents=True))
-                error = sys.exc_info()[:2]
+                # check if credential is a 'speaks for  credential'
+                if speaking_for_hrn:
+                    try:
+                        self.check(cred, operation, speaking_for_hrn)
+                        speaks_for_cred = cred
+                        valid.append(cred)    
+                    except:
+                        error = log_invalid_cred(cred)
+                else:
+                    error = log_invalid_cred(cred)
                 continue
             
         if not len(valid):
             raise InsufficientRights('Access denied: %s -- %s' % (error[0],error[1]))
         
+        if speaking_for_hrn and not speaks_for_cred:
+            raise InsufficientRights('Access denied: "geni_speaking_for" option specified but no valid speaks for credential found: %s -- %s' % (error[0],error[1]))
+            
+        
         return valid
         
         
@@ -239,7 +258,7 @@ class Auth:
         Given a user credential and a record, determine what set of rights the
         user should have to that record.
         
-        This is intended to replace determine_rights() and
+        This is intended to replace determine_user_rights() and
         verify_cancreate_credential()
         """
 
@@ -248,10 +267,12 @@ class Auth:
 
         logger.debug("entering determine_user_rights with record %s and caller_hrn %s"%(reg_record, caller_hrn))
 
-        if type=='slice':
+        if type == 'slice':
+            # researchers in the slice are in the DB as-is
             researcher_hrns = [ user.hrn for user in reg_record.reg_researchers ]
-            # xxx need a means to compute pi_hrns from the registry db
-            pi_hrns = reg_record.get('PI',[])
+            # locating PIs attached to that slice
+            slice_pis=reg_record.get_pis()
+            pi_hrns = [ user.hrn for user in slice_pis ]
             if (caller_hrn in researcher_hrns + pi_hrns):
                 rl.add('refresh')
                 rl.add('embed')
@@ -261,8 +282,6 @@ class Auth:
 
         elif type == 'authority':
             pi_hrns = [ user.hrn for user in reg_record.reg_pis ]
-            # xxx need a means to compute operator_hrns from the registry db
-            operator_hrns = reg_record.get('operator',[])
             if (caller_hrn == self.config.SFA_INTERFACE_HRN):
                 rl.add('authority')
                 rl.add('sa')
@@ -270,9 +289,13 @@ class Auth:
             if (caller_hrn in pi_hrns):
                 rl.add('authority')
                 rl.add('sa')
-            if (caller_hrn in operator_hrns):
-                rl.add('authority')
-                rl.add('ma')
+            # NOTE: for the PL implementation, this 'operators' list 
+            # amounted to users with 'tech' role in that site 
+            # it seems like this is not needed any longer, so for now I just drop that
+            # operator_hrns = reg_record.get('operator',[])
+            # if (caller_hrn in operator_hrns):
+            #    rl.add('authority')
+            #    rl.add('ma')
 
         elif type == 'user':
             rl.add('refresh')