+ self.assert_my_gid()
+ return SfaServerProxy (url, self.private_key_filename(), self.my_gid_filename(),
+ verbose=self.verbose, timeout=self.timeout)
+
+ # now in some cases the self-signed is enough
+ def server_proxy_simple (self, url):
+ self.assert_self_signed_cert()
+ return SfaServerProxy (url, self.private_key_filename(), self.self_signed_cert_filename(),
+ verbose=self.verbose, timeout=self.timeout)
+
+ # this method can optionnally be invoked to ensure proper
+ # installation of the private key that belongs to this user
+ # installs private_key in working dir with expected name -- preserve mode
+ # typically user_private_key would be ~/.ssh/id_rsa
+ # xxx should probably check the 2 files are identical
+ def init_private_key_if_missing (self, user_private_key):
+ private_key_filename=self.private_key_filename()
+ if not os.path.isfile (private_key_filename):
+ key=self.plain_read(user_private_key)
+ self.plain_write(private_key_filename, key)
+ os.chmod(private_key_filename,os.stat(user_private_key).st_mode)
+ self.logger.debug("SfaClientBootstrap: Copied private key from %s into %s"%\
+ (user_private_key,private_key_filename))
+
+ #################### private details
+ # stupid stuff
+ def fullpath (self, file): return os.path.join (self.dir,file)
+
+ # the expected filenames for the various pieces
+ def private_key_filename (self):
+ return self.fullpath ("%s.pkey"%self.hrn)
+ def self_signed_cert_filename (self):
+ return self.fullpath ("%s.sscert"%self.hrn)
+ def my_credential_filename (self):
+ return self.credential_filename (self.hrn, "user")
+ def credential_filename (self, hrn, type):
+ return self.fullpath ("%s.%s.cred"%(hrn,type))
+ def slice_credential_filename (self, hrn):
+ return self.credential_filename(hrn,'slice')
+ def authority_credential_filename (self, hrn):
+ return self.credential_filename(hrn,'authority')
+ def my_gid_filename (self):
+ return self.gid_filename (self.hrn, "user")
+ def gid_filename (self, hrn, type):
+ return self.fullpath ("%s.%s.gid"%(hrn,type))
+
+
+# optimizing dependencies
+# originally we used classes GID or Credential or Certificate
+# like e.g.
+# return Credential(filename=self.my_credential()).save_to_string()
+# but in order to make it simpler to other implementations/languages..
+ def plain_read (self, filename):
+ infile=file(filename,"r")
+ result=infile.read()
+ infile.close()
+ return result
+
+ def plain_write (self, filename, contents):
+ outfile=file(filename,"w")
+ result=outfile.write(contents)
+ outfile.close()
+
+ def assert_filename (self, filename, kind):
+ if not os.path.isfile (filename):
+ raise IOError,"Missing %s file %s"%(kind,filename)
+ return True
+
+ def assert_private_key (self): return self.assert_filename (self.private_key_filename(),"private key")
+ def assert_self_signed_cert (self): return self.assert_filename (self.self_signed_cert_filename(),"self-signed certificate")
+ def assert_my_credential (self): return self.assert_filename (self.my_credential_filename(),"user's credential")
+ def assert_my_gid (self): return self.assert_filename (self.my_gid_filename(),"user's GID")
+
+
+ # decorator to make up the other methods
+ def get_or_produce (filename_method, produce_method):
+ def wrap (f):
+ def wrapped (self, *args, **kw):
+ filename=filename_method (self, *args, **kw)
+ if os.path.isfile ( filename ): return filename
+ try:
+ produce_method (self, filename, *args, **kw)
+ return filename
+ except IOError:
+ raise
+ except :
+ error = sys.exc_info()[:2]
+ message="Could not produce/retrieve %s (%s -- %s)"%\
+ (filename,error[0],error[1])
+ self.logger.log_exc(message)
+ raise Exception, message
+ return wrapped
+ return wrap
+
+ @get_or_produce (self_signed_cert_filename, self_signed_cert_produce)
+ def self_signed_cert (self): pass
+
+ @get_or_produce (my_credential_filename, my_credential_produce)
+ def my_credential (self): pass
+
+ @get_or_produce (my_gid_filename, my_gid_produce)
+ def my_gid (self): pass
+
+ @get_or_produce (credential_filename, credential_produce)
+ def credential (self, hrn, type): pass
+
+ @get_or_produce (slice_credential_filename, slice_credential_produce)
+ def slice_credential (self, hrn): pass
+
+ @get_or_produce (authority_credential_filename, authority_credential_produce)
+ def authority_credential (self, hrn): pass
+
+ @get_or_produce (gid_filename, gid_produce)
+ def gid (self, hrn, type ): pass
+
+
+ # get the credentials as strings, for inserting as API arguments
+ def my_credential_string (self):
+ self.my_credential()
+ return self.plain_read(self.my_credential_filename())
+ def slice_credential_string (self, hrn):
+ self.slice_credential(hrn)
+ return self.plain_read(self.slice_credential_filename(hrn))
+ def authority_credential_string (self, hrn):
+ self.authority_credential(hrn)
+ return self.plain_read(self.authority_credential_filename(hrn))