2 from PLC.Method import Method
3 from PLC.Parameter import Parameter, Mixed
4 from PLC.Filter import Filter
5 from PLC.Auth import Auth
6 from PLC.Persons import Person, Persons
7 from PLC.Sites import Site, Sites
8 from PLC.Slices import Slice, Slices
9 from PLC.Keys import Key, Keys
11 class GetSliceKeys(Method):
13 Returns an array of structs containing public key info for users in
14 the specified slices. If slice_filter is specified and is an array
15 of slice identifiers or slice names, or a struct of slice
16 attributes, only slices matching the filter will be returned. If
17 return_fields is specified, only the specified details will be
20 Users may only query slices of which they are members. PIs may
21 query any of the slices at their sites. Admins and nodes may query
22 any slice. If a slice that cannot be queried is specified in
23 slice_filter, details about that slice will not be returned.
26 roles = ['admin', 'pi', 'user', 'node']
30 Mixed([Mixed(Slice.fields['slice_id'],
31 Slice.fields['name'])],
32 Filter(Slice.fields)),
33 Parameter([str], "List of fields to return", nullok = True)
38 'slice_id': Slice.fields['slice_id'],
39 'name': Slice.fields['name'],
40 'person_id': Person.fields['person_id'],
41 'email': Person.fields['email'],
42 'key': Key.fields['key']
45 def call(self, auth, slice_filter = None, return_fields = None):
46 slice_fields = ['slice_id', 'name']
47 person_fields = ['person_id', 'email']
50 # If we are not admin, make sure to return only viewable
52 if isinstance(self.caller, Person) and \
53 'admin' not in self.caller['roles']:
54 # Get slices that we are able to view
55 valid_slice_ids = self.caller['slice_ids']
56 if 'pi' in self.caller['roles'] and self.caller['site_ids']:
57 sites = Sites(self.api, self.caller['site_ids'])
59 valid_slice_ids += site['slice_ids']
61 if not valid_slice_ids:
64 if slice_filter is None:
65 slice_filter = valid_slice_ids
68 slice_return_fields = filter(lambda field: field in slice_fields, return_fields)
69 person_return_fields = filter(lambda field: field in person_fields, return_fields)
70 key_return_fields = filter(lambda field: field in key_fields, return_fields)
72 slice_return_fields = slice_fields
73 person_return_fields = person_fields
74 key_return_fields = key_fields
76 # Must query at least Slice.slice_id, Slice.person_ids,
77 # and Person.person_id and Person.key_ids so we can join data correctly
78 slice_added_fields = set(['slice_id', 'person_ids']).difference(slice_return_fields)
79 slice_return_fields += slice_added_fields
80 person_added_fields = set(['person_id', 'key_ids']).difference(person_return_fields)
81 person_return_fields += person_added_fields
82 key_added_fields = set(['key_id']).difference(key_return_fields)
83 key_return_fields += key_added_fields
86 all_slices = Slices(self.api, slice_filter, slice_return_fields).dict('slice_id')
87 slice_ids = all_slices.keys()
88 slices = all_slices.values()
90 # Filter out slices that are not viewable
91 if isinstance(self.caller, Person) and \
92 'admin' not in self.caller['roles']:
93 slices = filter(lambda slice: slice['slice_id'] in valid_slice_ids, slices)
98 person_ids.update(slice['person_ids'])
100 all_persons = Persons(self.api, list(person_ids), person_return_fields).dict('person_id')
101 person_ids = all_persons.keys()
102 persons = all_persons.values()
106 for person in persons:
107 key_ids.update(person['key_ids'])
109 all_keys = Keys(self.api, list(key_ids), key_return_fields).dict('key_id')
110 key_ids = all_keys.keys()
111 keys = all_keys.values()
113 # Create slice_keys list
115 slice_fields = list(set(slice_return_fields).difference(slice_added_fields))
116 person_fields = list(set(person_return_fields).difference(person_added_fields))
117 key_fields = list(set(key_return_fields).difference(key_added_fields))
120 slice_key = dict.fromkeys(slice_fields + person_fields + key_fields)
121 if not slice['person_ids']:
123 for person_id in slice['person_ids']:
124 person = all_persons[person_id]
125 if not person['key_ids']:
127 for key_id in person['key_ids']:
128 key = all_keys[key_id]
129 slice_key.update(dict(filter(lambda (k, v): k in slice_fields, slice.items())))
130 slice_key.update(dict(filter(lambda (k, v): k in person_fields, person.items())))
131 slice_key.update(dict(filter(lambda (k, v): k in key_fields, key.items())))
132 slice_keys.append(slice_key.copy())