From: Tony Mack Date: Mon, 10 Sep 2007 21:31:21 +0000 (+0000) Subject: - returns user public key information X-Git-Tag: PLCAPI-4.2-0~82 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=e848d8810d07781418219ec18e5fb8a3e67edeaf;p=plcapi.git - returns user public key information - Initial checkin of new API implementation --- diff --git a/PLC/Methods/GetSliceKeys.py b/PLC/Methods/GetSliceKeys.py new file mode 100644 index 0000000..50298da --- /dev/null +++ b/PLC/Methods/GetSliceKeys.py @@ -0,0 +1,138 @@ +from PLC.Method import Method +from PLC.Parameter import Parameter, Mixed +from PLC.Filter import Filter +from PLC.Auth import Auth +from PLC.Persons import Person, Persons +from PLC.Sites import Site, Sites +from PLC.Slices import Slice, Slices +from PLC.Keys import Key, Keys + + +slice_fields = ['slice_id', 'name'] +person_fields = ['person_id', 'email'] +key_fields = ['key'] + +class GetSliceKeys(Method): + """ + Returns an array of structs containing details about users/public keys + in slices. If slice_filter is specified and is an array of slice + identifiers or slice names, or a struct of slice attributes, only + slices matching the filter will be returned. If return_fields is + specified, only the specified details will be returned. + + Users may only query slices of which they are members. PIs may + query any of the slices at their sites. Admins and nodes may query + any slice. If a slice that cannot be queried is specified in + slice_filter, details about that slice will not be returned. + """ + + roles = ['admin', 'pi', 'user', 'node'] + + accepts = [ + Auth(), + Mixed([Mixed(Slice.fields['slice_id'], + Slice.fields['name'])], + Filter(Slice.fields)), + Parameter([str], "List of fields to return", nullok = True) + ] + + returns = [ + { + 'slice_id': Slice.fields['slice_id'], + 'name': Slice.fields['name'], + 'person_id': Person.fields['person_id'], + 'email': Person.fields['email'], + 'key': Key.fields['key'] + }] + + def call(self, auth, slice_filter = None, return_fields = None): + slice_fields = ['slice_id', 'name'] + person_fields = ['person_id', 'email'] + key_fields = ['key'] + + # If we are not admin, make sure to return only viewable + # slices. + if isinstance(self.caller, Person) and \ + 'admin' not in self.caller['roles']: + # Get slices that we are able to view + valid_slice_ids = self.caller['slice_ids'] + if 'pi' in self.caller['roles'] and self.caller['site_ids']: + sites = Sites(self.api, self.caller['site_ids']) + for site in sites: + valid_slice_ids += site['slice_ids'] + + if not valid_slice_ids: + return [] + + if slice_filter is None: + slice_filter = valid_slice_ids + + if return_fields: + slice_return_fields = filter(lambda field: field in slice_fields, return_fields) + person_return_fields = filter(lambda field: field in person_fields, return_fields) + key_return_fields = filter(lambda field: field in key_fields, return_fields) + else: + slice_return_fields = slice_fields + person_return_fields = person_fields + key_return_fields = key_fields + + # Must query at least Slice.slice_id, Slice.person_ids, + # and Person.person_id and Person.key_ids so we can join data correctly + slice_added_fields = set(['slice_id', 'person_ids']).difference(slice_return_fields) + slice_return_fields += slice_added_fields + person_added_fields = set(['person_id', 'key_ids']).difference(person_return_fields) + person_return_fields += person_added_fields + key_added_fields = set(['key_id']).difference(key_return_fields) + key_return_fields += key_added_fields + + # Get the slices + all_slices = Slices(self.api, slice_filter, slice_return_fields).dict('slice_id') + slice_ids = all_slices.keys() + slices = all_slices.values() + + # Filter out slices that are not viewable + if isinstance(self.caller, Person) and \ + 'admin' not in self.caller['roles']: + slices = filter(lambda slice: slice['slice_id'] in valid_slice_ids, slices) + + # Get the persons + person_ids = set() + for slice in slices: + person_ids.update(slice['person_ids']) + + all_persons = Persons(self.api, list(person_ids), person_return_fields).dict('person_id') + person_ids = all_persons.keys() + persons = all_persons.values() + + # Get the keys + key_ids = set() + for person in persons: + key_ids.update(person['key_ids']) + + all_keys = Keys(self.api, list(key_ids), key_return_fields).dict('key_id') + key_ids = all_keys.keys() + keys = all_keys.values() + + # Create slice_keys list + slice_keys = [] + slice_fields = list(set(slice_return_fields).difference(slice_added_fields)) + person_fields = list(set(person_return_fields).difference(person_added_fields)) + key_fields = list(set(key_return_fields).difference(key_added_fields)) + + for slice in slices: + slice_key = dict.fromkeys(slice_fields + person_fields + key_fields) + if not slice['person_ids']: + continue + for person_id in slice['person_ids']: + person = all_persons[person_id] + if not person['key_ids']: + continue + for key_id in person['key_ids']: + key = all_keys[key_id] + slice_key.update(dict(filter(lambda (k, v): k in slice_fields, slice.items()))) + slice_key.update(dict(filter(lambda (k, v): k in person_fields, person.items()))) + slice_key.update(dict(filter(lambda (k, v): k in key_fields, key.items()))) + slice_keys.append(slice_key.copy()) + + return slice_keys +