4 from sfa.util.faults import *
5 from sfa.util.method import Method
6 from sfa.util.parameter import Parameter, Mixed
7 from sfa.trust.auth import Auth
8 from sfa.util.record import GeniRecord
9 from sfa.trust.certificate import Keypair, convert_public_key
10 from sfa.trust.gid import *
11 from sfa.util.debug import log
15 Update an object in the registry. Currently, this only updates the
16 PLC information associated with the record. The Geni fields (name, type,
19 @param cred credential string specifying rights of the caller
20 @param record a record dictionary to be updated
22 @return 1 if successful, faults otherwise
25 interfaces = ['registry']
28 Parameter(str, "Credential string"),
29 Parameter(dict, "Record dictionary to be updated")
32 returns = Parameter(int, "1 if successful")
34 def call(self, cred, record_dict):
35 self.api.auth.check(cred, "update")
36 record = GeniRecord(dict = record_dict)
37 type = record.get_type()
38 self.api.auth.verify_object_permission(record.get_name())
39 auth_name = self.api.auth.get_authority(record.get_name())
41 auth_name = record.get_name()
42 table = self.api.auth.get_auth_table(auth_name)
44 # make sure the record exists
45 existing_record_list = table.resolve(type, record.get_name())
46 if not existing_record_list:
47 raise RecordNotFound(record.get_name())
48 existing_record = existing_record_list[0]
50 # Update_membership needs the membership lists in the existing record
51 # filled in, so it can see if members were added or removed
52 self.api.fill_record_info(existing_record)
54 # Use the pointer from the existing record, not the one that the user
55 # gave us. This prevents the user from inserting a forged pointer
56 pointer = existing_record.get_pointer()
58 # update the PLC information that was specified with the record
60 if (type == "authority"):
61 self.api.plshell.UpdateSite(self.api.plauth, pointer, record)
65 pl_record=self.api.geni_fields_to_pl_fields(type, hrn, record)
66 self.api.plshell.UpdateSlice(self.api.plauth, pointer, pl_record)
69 # SMBAKER: UpdatePerson only allows a limited set of fields to be
70 # updated. Ideally we should have a more generic way of doing
71 # this. I copied the field names from UpdatePerson.py...
74 for key in all_fields.keys():
75 if key in ['first_name', 'last_name', 'title', 'email',
76 'password', 'phone', 'url', 'bio', 'accepted_aup',
78 update_fields[key] = all_fields[key]
79 self.api.plshell.UpdatePerson(self.api.plauth, pointer, update_fields)
81 if 'key' in record and record['key']:
82 # must check this key against the previous one if it exists
83 persons = self.api.plshell.GetPersons(self.api.plauth, [pointer], ['key_ids'])
85 keys = person['key_ids']
86 keys = GetKeys(person['key_ids'])
88 # Delete all stale keys
90 if record['key'] != key['key']:
91 self.api.plshell.DeleteKey(self.api.plauth, key['key_id'])
95 self.api.plshell.AddPersonKey(pointer, {'key_type': 'ssh', 'key': record['key']})
97 # find the existing geni record
99 auth_name = self.api.auth.get_authority(hrn)
100 auth_info = self.api.auth.get_auth_info(auth_name)
101 table = self.api.auth.get_auth_table(auth_name)
102 person_records = table.resolve('user', hrn)
103 person_record = person_records[0]
105 # update the openssl key and gid
106 pkey = convert_public_key(record['key'])
108 gid_object = self.api.auth.hierarchy.create_gid(hrn, uuid, pkey)
109 gid = gid_object.save_to_string(save_parents=True)
110 person_record['gid'] = gid
111 person_record.set_gid(gid)
112 table.update(person_record)
115 self.api.plshell.UpdateNode(self.api.plauth, pointer, record)
118 raise UnknownGeniType(type)
120 # update membership for researchers, pis, owners, operators
121 self.api.update_membership(existing_record, record)