5 from sfa.util.faults import *
6 from sfa.util.method import Method
7 from sfa.util.parameter import Parameter, Mixed
8 from sfa.trust.auth import Auth
9 from sfa.util.record import GeniRecord
10 from sfa.util.genitable import GeniTable
11 from sfa.trust.certificate import Keypair, convert_public_key
12 from sfa.trust.gid import *
13 from sfa.util.debug import log
14 from sfa.trust.credential import Credential
18 Update an object in the registry. Currently, this only updates the
19 PLC information associated with the record. The Geni fields (name, type,
22 @param cred credential string specifying rights of the caller
23 @param record a record dictionary to be updated
25 @return 1 if successful, faults otherwise
28 interfaces = ['registry']
31 Parameter(str, "Credential string"),
32 Parameter(dict, "Record dictionary to be updated"),
33 Parameter(str, "Request hash")
36 returns = Parameter(int, "1 if successful")
38 def call(self, cred, record_dict, request_hash, caller_cred=None):
43 self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s"%(self.api.interface, Credential(string=caller_cred).get_gid_caller().get_hrn(), None, self.name))
44 # This cred might be an authority cred, not a user, so we cant use it to
45 # authenticate the caller's request_hash. Let just get the caller's gid
46 # from the cred and authenticate using that
47 client_gid = Credential(string=cred).get_gid_caller()
48 client_gid_str = client_gid.save_to_string(save_parents=True)
49 self.api.auth.authenticateGid(client_gid_str, [cred], request_hash)
50 self.api.auth.check(cred, "update")
51 new_record = GeniRecord(dict = record_dict)
52 type = new_record['type']
53 hrn = new_record['hrn']
54 self.api.auth.verify_object_permission(hrn)
56 # make sure the record exists
57 records = table.findObjects({'type': type, 'hrn': hrn})
59 raise RecordNotFound(hrn)
61 record['last_updated'] = time.gmtime()
63 # Update_membership needs the membership lists in the existing record
64 # filled in, so it can see if members were added or removed
65 self.api.fill_record_info(record)
67 # Use the pointer from the existing record, not the one that the user
68 # gave us. This prevents the user from inserting a forged pointer
69 pointer = record['pointer']
71 # update the PLC information that was specified with the record
73 if (type == "authority"):
74 self.api.plshell.UpdateSite(self.api.plauth, pointer, new_record)
77 pl_record=self.api.geni_fields_to_pl_fields(type, hrn, new_record)
78 if 'name' in pl_record:
80 self.api.plshell.UpdateSlice(self.api.plauth, pointer, pl_record)
83 # SMBAKER: UpdatePerson only allows a limited set of fields to be
84 # updated. Ideally we should have a more generic way of doing
85 # this. I copied the field names from UpdatePerson.py...
87 all_fields = new_record
88 for key in all_fields.keys():
89 if key in ['first_name', 'last_name', 'title', 'email',
90 'password', 'phone', 'url', 'bio', 'accepted_aup',
92 update_fields[key] = all_fields[key]
93 self.api.plshell.UpdatePerson(self.api.plauth, pointer, update_fields)
95 if 'key' in new_record and new_record['key']:
96 # must check this key against the previous one if it exists
97 persons = self.api.plshell.GetPersons(self.api.plauth, [pointer], ['key_ids'])
99 keys = person['key_ids']
100 keys = self.api.plshell.GetKeys(self.api.plauth, person['key_ids'])
102 if isinstance(new_record['key'], list):
103 new_key = new_record['key'][0]
105 new_key = new_record['key']
107 # Delete all stale keys
109 if new_record['key'] != key['key']:
110 self.api.plshell.DeleteKey(self.api.plauth, key['key_id'])
114 self.api.plshell.AddPersonKey(self.api.plauth, pointer, {'key_type': 'ssh', 'key': new_key})
116 # update the openssl key and gid
117 pkey = convert_public_key(new_key)
119 gid_object = self.api.auth.hierarchy.create_gid(hrn, uuid, pkey)
120 gid = gid_object.save_to_string(save_parents=True)
122 record = GeniRecord(dict=record)
126 self.api.plshell.UpdateNode(self.api.plauth, pointer, new_record)
129 raise UnknownGeniType(type)
131 # update membership for researchers, pis, owners, operators
132 self.api.update_membership(record, new_record)