X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sfa%2Fmethods%2Fregister.py;h=294b71237a981e195aa70009d5c69bfd23e2804d;hb=af331734b08993f76d3734e1965dc2e54fadebbc;hp=00ec075774b9f7231b9cad7b8dd6fc0bb50d56ba;hpb=8b29a3f5915b7131010a11d52cdf83395d5c0f09;p=sfa.git diff --git a/sfa/methods/register.py b/sfa/methods/register.py index 00ec0757..294b7123 100644 --- a/sfa/methods/register.py +++ b/sfa/methods/register.py @@ -9,10 +9,11 @@ from sfa.util.misc import * from sfa.util.method import Method from sfa.util.parameter import Parameter, Mixed from sfa.util.record import GeniRecord +from sfa.util.genitable import GeniTable from sfa.util.debug import log - from sfa.trust.auth import Auth from sfa.trust.gid import create_uuid +from sfa.trust.credential import Credential class register(Method): """ @@ -30,100 +31,131 @@ class register(Method): accepts = [ Parameter(str, "Credential string"), - Parameter(dict, "Record dictionary containing record fields") + Parameter(dict, "Record dictionary containing record fields"), + Mixed(Parameter(str, "Request hash"), + Parameter(None, "Request hash not specified")) ] returns = Parameter(int, "String representation of gid object") - def call(self, cred, record_dict): + def call(self, cred, record_dict, request_hash=None, origin_hrn=None): + # This cred will be an authority cred, not a user, so we cant use it to + # authenticate the caller's request_hash. Let just get the caller's gid + # from the cred and authenticate using that + client_gid = Credential(string=cred).get_gid_caller() + client_gid_str = client_gid.save_to_string(save_parents=True) + self.api.auth.authenticateGid(client_gid_str, [cred], request_hash) self.api.auth.check(cred, "register") + if origin_hrn==None: + origin_hrn=Credential(string=cred).get_gid_caller().get_hrn() + + #log the call + self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s"%(self.api.interface, origin_hrn, None, self.name)) record = GeniRecord(dict = record_dict) - type = record.get_type() - name = record.get_name() - self.api.auth.verify_object_permission(name) - auth_name = self.api.auth.get_authority(name) - auth_info = self.api.auth.get_auth_info(auth_name) - table = self.api.auth.get_auth_table(auth_name) - + record['authority'] = get_authority(record['hrn']) + type = record['type'] + hrn = record['hrn'] + self.api.auth.verify_object_permission(hrn) + auth_info = self.api.auth.get_auth_info(record['authority']) + pub_key = None # make sure record has a gid if 'gid' not in record: uuid = create_uuid() pkey = Keypair(create=True) if 'key' in record and record['key']: - pkey = convert_public_key(record['key']) + if isinstance(record['key'], list): + pub_key = record['key'][0] + else: + pub_key = record['key'] + pkey = convert_public_key(pub_key) - gid_object = self.api.auth.hierarchy.create_gid(name, uuid, pkey) + gid_object = self.api.auth.hierarchy.create_gid(hrn, uuid, pkey) gid = gid_object.save_to_string(save_parents=True) record['gid'] = gid record.set_gid(gid) # check if record already exists - existing_records = table.resolve(type, name) + table = GeniTable() + existing_records = table.find({'type': type, 'hrn': hrn}) if existing_records: - raise ExistingRecord(name) - - if type in ["authority", "sa", "ma"]: + raise ExistingRecord(hrn) + + if type in ["authority"]: # update the tree - if not self.api.auth.hierarchy.auth_exists(name): - self.api.auth.hierarchy.create_auth(name) + if not self.api.auth.hierarchy.auth_exists(hrn): + self.api.auth.hierarchy.create_auth(hrn) # authorities are special since they are managed by the registry # rather than by the caller. We create our own GID for the # authority rather than relying on the caller to supply one. # get the GID from the newly created authority - child_auth_info = self.api.auth.get_auth_info(name) gid = auth_info.get_gid_object() record.set_gid(gid.save_to_string(save_parents=True)) - # if registering a sa, see if a ma already exists - # if registering a ma, see if a sa already exists - if type in ["authority", "sa", "ma"]: - other_rec = table.resolve("authority", record.get_name()) - - if other_rec: - print >> log, "linking ma and sa to the same plc site" - pointer = other_rec[0].get_pointer() - else: - pl_record = self.api.geni_fields_to_pl_fields(type, name, record) - print >> log, "adding site with fields", pl_record + pl_record = self.api.geni_fields_to_pl_fields(type, hrn, record) + sites = self.api.plshell.GetSites(self.api.plauth, [pl_record['login_base']]) + if not sites: pointer = self.api.plshell.AddSite(self.api.plauth, pl_record) + else: + pointer = sites[0]['site_id'] record.set_pointer(pointer) + record['pointer'] = pointer elif (type == "slice"): - pl_record = self.api.geni_fields_to_pl_fields(type, name, record) - pointer = self.api.plshell.AddSlice(self.api.plauth, pl_record) + acceptable_fields=['url', 'instantiation', 'name', 'description'] + pl_record = self.api.geni_fields_to_pl_fields(type, hrn, record) + for key in pl_record.keys(): + if key not in acceptable_fields: + pl_record.pop(key) + slices = self.api.plshell.GetSlices(self.api.plauth, [pl_record['name']]) + if not slices: + pointer = self.api.plshell.AddSlice(self.api.plauth, pl_record) + else: + pointer = slices[0]['slice_id'] record.set_pointer(pointer) + record['pointer'] = pointer - elif (type == "user"): - pointer = self.api.plshell.AddPerson(self.api.plauth, dict(record)) + elif (type == "user"): + persons = self.api.plshell.GetPersons(self.api.plauth, [record['email']]) + if not persons: + pointer = self.api.plshell.AddPerson(self.api.plauth, dict(record)) + else: + raise ExistingRecord(record['email']) + if 'enabled' in record and record['enabled']: self.api.plshell.UpdatePerson(self.api.plauth, pointer, {'enabled': record['enabled']}) - login_base = get_leaf(auth_info.hrn) - self.api.plshell.AddPersonToSite(self.api.plauth, pointer, login_base) + # add this persons to the site only if he is being added for the first + # time by sfa and doesont already exist in plc + if not persons or not persons[0]['site_ids']: + login_base = get_leaf(record['authority']) + self.api.plshell.AddPersonToSite(self.api.plauth, pointer, login_base) + # What roles should this user have? self.api.plshell.AddRoleToPerson(self.api.plauth, 'user', pointer) record.set_pointer(pointer) - - # Add the user's key - if record['key']: - self.api.plshell.AddPersonKey(self.api.plauth, pointer, {'key_type' : 'ssh', 'key' : record['key']}) + record['pointer'] = pointer + # Add the user's key + if pub_key: + self.api.plshell.AddPersonKey(self.api.plauth, pointer, {'key_type' : 'ssh', 'key' : pub_key}) elif (type == "node"): - pl_record = self.api.geni_fields_to_pl_fields(type, name, record) - login_base = hrn_to_pl_login_base(auth_name) - pointer = self.api.plshell.AddNode(self.api.plauth, login_base, pl_record) + pl_record = self.api.geni_fields_to_pl_fields(type, hrn, record) + login_base = hrn_to_pl_login_base(record['authority']) + nodes = self.api.plshell.GetNodes(self.api.plauth, [pl_record['hostname']]) + if not nodes: + pointer = self.api.plshell.AddNode(self.api.plauth, login_base, pl_record) + else: + pointer = nodes[0]['node_id'] + record['pointer'] = pointer record.set_pointer(pointer) else: raise UnknownGeniType(type) - # SFA upcalls may exist in PLCAPI and they could have already added the - # record for us. Lets check if the record already exists - existing_records = table.resolve(type, name) - if not existing_records: - table.insert(record) + record_id = table.insert(record) + record['record_id'] = record_id # update membership for researchers, pis, owners, operators self.api.update_membership(None, record)