switch from sa/ma to authority, fix update_membership_list
[sfa.git] / geni / methods / update.py
1 from geni.util.faults import *
2 from geni.util.excep import *
3 from geni.util.method import Method
4 from geni.util.parameter import Parameter, Mixed
5 from geni.util.auth import Auth
6 from geni.util.record import GeniRecord
7 from geni.util.debug import log
8
9 class update(Method):
10     """
11     Update an object in the registry. Currently, this only updates the
12     PLC information associated with the record. The Geni fields (name, type,
13     GID) are fixed.
14     
15     The record is expected to have the pl_info field filled in with the data
16     that should be updated.
17     
18     TODO: The geni_info member of the record should be parsed and the pl_info
19     adjusted as necessary (add/remove users from a slice, etc)
20     
21     @param cred credential string specifying rights of the caller
22     @param record a record dictionary to be updated
23
24     @return 1 if successful, faults otherwise 
25     """
26
27     interfaces = ['registry']
28     
29     accepts = [
30         Parameter(str, "Credential string"),
31         Parameter(dict, "Record dictionary to be updated")
32         ]
33
34     returns = Parameter(int, "1 if successful")
35     
36     def call(self, cred, record_dict):
37         self.api.auth.check(cred, "update")
38         record = GeniRecord(dict = record_dict)
39         type = record.get_type()
40         self.api.auth.verify_object_permission(record.get_name())
41         auth_name = self.api.auth.get_authority(record.get_name())
42         if not auth_name:
43             auth_name = record.get_name()
44         table = self.api.auth.get_auth_table(auth_name)
45
46         # make sure the record exists
47         existing_record_list = table.resolve(type, record.get_name())
48         if not existing_record_list:
49             raise RecordNotFound(record.get_name())
50         existing_record = existing_record_list[0]
51
52         # Update_membership needs the membership lists in the existing record
53         # filled in, so it can see if members were added or removed
54         self.api.fill_record_info(existing_record)
55
56          # Use the pointer from the existing record, not the one that the user
57         # gave us. This prevents the user from inserting a forged pointer
58         pointer = existing_record.get_pointer()
59
60         # update the PLC information that was specified with the record
61
62         if (type == "authority"):
63             self.api.plshell.UpdateSite(self.api.plauth, pointer, record.get_pl_info())
64
65         elif type == "slice":
66             self.api.plshell.UpdateSlice(self.api.plauth, pointer, record.get_pl_info())
67
68         elif type == "user":
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...
72             update_fields = {}
73             all_fields = record.get_pl_info()
74             for key in all_fields.keys():
75                 if key in ['first_name', 'last_name', 'title', 'email',
76                            'password', 'phone', 'url', 'bio', 'accepted_aup',
77                            'enabled']:
78                     update_fields[key] = all_fields[key]
79             self.api.plshell.UpdatePerson(self.api.plauth, pointer, update_fields)
80
81         elif type == "node":
82             self.api.plshell.UpdateNode(self.api.plauth, pointer, record.get_pl_info())
83
84         else:
85             raise UnknownGeniType(type)
86
87         # update membership for researchers, pis, owners, operators
88         self.api.update_membership(existing_record, record)
89
90         return 1