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.util.genitable import GeniTable
10 from sfa.trust.certificate import Keypair, convert_public_key
11 from sfa.trust.gid import *
12 from sfa.util.debug import log
16 Update an object in the registry. Currently, this only updates the
17 PLC information associated with the record. The Geni fields (name, type,
20 @param cred credential string specifying rights of the caller
21 @param record a record dictionary to be updated
23 @return 1 if successful, faults otherwise
26 interfaces = ['registry']
29 Parameter(str, "Credential string"),
30 Parameter(dict, "Record dictionary to be updated")
33 returns = Parameter(int, "1 if successful")
35 def call(self, cred, record_dict):
36 self.api.auth.check(cred, "update")
37 new_record = GeniRecord(dict = record_dict)
38 type = new_record['type']
39 hrn = new_record['hrn']
40 self.api.auth.verify_object_permission(hrn)
42 # make sure the record exists
43 records = table.find({'type': type, 'hrn': hrn})
45 raise RecordNotFound(hrn)
48 # Update_membership needs the membership lists in the existing record
49 # filled in, so it can see if members were added or removed
50 self.api.fill_record_info(record)
52 # Use the pointer from the existing record, not the one that the user
53 # gave us. This prevents the user from inserting a forged pointer
54 pointer = record['pointer']
56 # update the PLC information that was specified with the record
58 if (type == "authority"):
59 self.api.plshell.UpdateSite(self.api.plauth, pointer, new_record)
62 pl_record=self.api.geni_fields_to_pl_fields(type, hrn, new_record)
63 if 'name' in pl_record:
65 self.api.plshell.UpdateSlice(self.api.plauth, pointer, pl_record)
68 # SMBAKER: UpdatePerson only allows a limited set of fields to be
69 # updated. Ideally we should have a more generic way of doing
70 # this. I copied the field names from UpdatePerson.py...
72 all_fields = new_record
73 for key in all_fields.keys():
74 if key in ['first_name', 'last_name', 'title', 'email',
75 'password', 'phone', 'url', 'bio', 'accepted_aup',
77 update_fields[key] = all_fields[key]
78 self.api.plshell.UpdatePerson(self.api.plauth, pointer, update_fields)
80 if 'key' in new_record and new_record['key']:
81 # must check this key against the previous one if it exists
82 persons = self.api.plshell.GetPersons(self.api.plauth, [pointer], ['key_ids'])
84 keys = person['key_ids']
85 keys = self.api.plshell.GetKeys(self.api.plauth, person['key_ids'])
87 if isinstance(new_record['key'], list):
88 new_key = new_record['key'][0]
90 new_key = new_record['key']
92 # Delete all stale keys
94 if new_record['key'] != key['key']:
95 self.api.plshell.DeleteKey(self.api.plauth, key['key_id'])
99 self.api.plshell.AddPersonKey(self.api.plauth, pointer, {'key_type': 'ssh', 'key': new_key})
101 # update the openssl key and gid
102 pkey = convert_public_key(new_key)
104 gid_object = self.api.auth.hierarchy.create_gid(hrn, uuid, pkey)
105 gid = gid_object.save_to_string(save_parents=True)
107 record = GeniRecord(dict=record)
111 self.api.plshell.UpdateNode(self.api.plauth, pointer, new_record)
114 raise UnknownGeniType(type)
116 # update membership for researchers, pis, owners, operators
117 self.api.update_membership(record, record)