+ self.load_trusted_certs()
+
+ def load_trusted_certs(self):
+ 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()
+
+ # this convenience methods extracts speaking_for_xrn
+ # from the passed options using 'geni_speaking_for'
+ def checkCredentialsSpeaksFor(self, *args, **kwds):
+ if 'options' not in kwds:
+ logger.error(
+ "checkCredentialsSpeaksFor was not passed options=options")
+ return
+ # remove the options arg
+ options = kwds['options']
+ del kwds['options']
+ # compute the speaking_for_xrn arg and pass it to checkCredentials
+ if options is None:
+ speaking_for_xrn = None
+ else:
+ speaking_for_xrn = options.get('geni_speaking_for', None)
+ kwds['speaking_for_xrn'] = speaking_for_xrn
+ return self.checkCredentials(*args, **kwds)
+
+ # do not use mutable as default argument
+ # http://docs.python-guide.org/en/latest/writing/gotchas/#mutable-default-arguments
+ def checkCredentials(self, creds, operation, xrns=None,
+ check_sliver_callback=None,
+ speaking_for_xrn=None):
+ if xrns is None:
+ xrns = []
+ error = (None, None)
+
+ def log_invalid_cred(cred, exception):
+ if isinstance(cred, dict) and 'geni_value' in cred:
+ cred = cred['geni_value']
+ if not isinstance(cred, StringType):
+ logger.info(
+ "{}: cannot validate credential {}"
+ .format(exception, cred))
+ error = ('TypeMismatch',
+ "checkCredentials: expected a string, got {} -- {}"
+ .format(type(cred), cred))
+ else:
+ cred_obj = Credential(string=cred)
+ logger.info("{}: failed to validate credential dump={}"
+ .format(exception,
+ cred_obj.dump_string(dump_parents=True)))
+ error = sys.exc_info()[:2]
+ return error
+
+ # if xrns are specified they cannot be None or empty string
+ if xrns:
+ for xrn in xrns:
+ if not xrn:
+ raise BadArgs("Invalid urn or hrn")
+
+ if not isinstance(xrns, list):
+ xrns = [xrns]
+
+ # slice_xrns = Xrn.filter_type(xrns, 'slice')
+ sliver_xrns = Xrn.filter_type(xrns, 'sliver')
+
+ # we are not able to validate slivers in the traditional way so
+ # we make sure not to include sliver urns/hrns in the core validation
+ # loop
+ hrns = [Xrn(xrn).hrn for xrn in xrns if xrn not in sliver_xrns]
+ valid = []
+ if not isinstance(creds, list):
+ creds = [creds]
+ logger.debug("Auth.checkCredentials with %d creds on hrns=%s" %
+ (len(creds), hrns))
+ # won't work if either creds or hrns is empty - let's make it more
+ # explicit
+ if not creds:
+ raise Forbidden("no credential provided")
+ if not hrns:
+ hrns = [None]
+
+ speaks_for_gid = determine_speaks_for(logger, creds, self.peer_cert,
+ speaking_for_xrn, self.trusted_cert_list)
+
+ if self.peer_cert and \
+ not self.peer_cert.is_pubkey(speaks_for_gid.get_pubkey()):
+ valid = creds
+ else:
+ for cred in creds:
+ for hrn in hrns:
+ try:
+ self.check(cred, operation, hrn)
+ valid.append(cred)
+ except Exception as exc:
+ error = log_invalid_cred(cred, exc)
+
+ # make sure all sliver xrns are validated against the valid credentials
+ if sliver_xrns:
+ if not check_sliver_callback:
+ msg = "sliver verification callback method not found."
+ msg += " Unable to validate sliver xrns: %s" % sliver_xrns
+ raise Forbidden(msg)
+ check_sliver_callback(valid, sliver_xrns)
+
+ if not len(valid):
+ raise Forbidden("Invalid credential %s -- %s" %
+ (error[0], error[1]))
+
+ return valid
+
+ def check(self, credential, operation, hrn=None):