X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=PLC%2FMethods%2FGetPersons.py;h=461c04b0d58e624e0938b6ae43e86018ae931962;hb=28fd040228e398ae1a3593263fbf46239c8d35a6;hp=3805adc8d4b20caf688653065e6ade599f9aad6e;hpb=40d33ca5c3e174e3ac07e3519c07e43825b4c797;p=plcapi.git diff --git a/PLC/Methods/GetPersons.py b/PLC/Methods/GetPersons.py index 3805adc..461c04b 100644 --- a/PLC/Methods/GetPersons.py +++ b/PLC/Methods/GetPersons.py @@ -1,71 +1,88 @@ -import os - +# $Id$ from PLC.Faults import * from PLC.Method import Method from PLC.Parameter import Parameter, Mixed +from PLC.Filter import Filter from PLC.Persons import Person, Persons -from PLC.Auth import PasswordAuth +from PLC.Sites import Site, Sites +from PLC.Auth import Auth + +hidden_fields = ['password', 'verification_key', 'verification_expires'] class GetPersons(Method): """ - Return an array of dictionaries containing details about the - specified accounts. - - ins may retrieve details about all accounts by not specifying - person_id_or_email_list or by specifying an empty list. Users and - techs may only retrieve details about themselves. PIs may retrieve - details about themselves and others at their sites. - - If return_fields is specified, only the specified fields will be - returned, if set. Otherwise, the default set of fields returned is: + Returns an array of structs containing details about users. If + person_filter is specified and is an array of user identifiers or + usernames, or a struct of user attributes, only users matching the + filter will be returned. If return_fields is specified, only the + specified details will be returned. + Users and techs may only retrieve details about themselves. PIs + may retrieve details about themselves and others at their + sites. Admins and nodes may retrieve details about all accounts. """ - roles = ['admin', 'pi', 'user', 'tech'] + roles = ['admin', 'pi', 'user', 'tech', 'node'] accepts = [ - PasswordAuth(), - [Mixed(Person.fields['person_id'], - Person.fields['email'])], - Parameter([str], 'List of fields to return') + Auth(), + Mixed([Mixed(Person.fields['person_id'], + Person.fields['email'])], + Parameter(str,"email"), + Parameter(int,"person_id"), + Filter(Person.fields)), + Parameter([str], "List of fields to return", nullok = True) ] # Filter out password field - can_return = lambda (field, value): field not in ['password'] - return_fields = dict(filter(can_return, Person.fields.items())) + return_fields = dict(filter(lambda (field, value): field not in hidden_fields, + Person.fields.items())) returns = [return_fields] + + def call(self, auth, person_filter = None, return_fields = None): + # If we are not admin, make sure to only return viewable accounts + if isinstance(self.caller, Person) and \ + 'admin' not in self.caller['roles']: + # Get accounts that we are able to view + valid_person_ids = [self.caller['person_id']] + if 'pi' in self.caller['roles'] and self.caller['site_ids']: + sites = Sites(self.api, self.caller['site_ids']) + for site in sites: + valid_person_ids += site['person_ids'] + + if not valid_person_ids: + return [] - def __init__(self, *args, **kwds): - Method.__init__(self, *args, **kwds) - # Update documentation with list of default fields returned - self.__doc__ += os.linesep.join(self.return_fields.keys()) + if person_filter is None: + person_filter = valid_person_ids - def call(self, auth, person_id_or_email_list = None, return_fields = None): - # Make sure that only valid fields are specified - if return_fields is None: - return_fields = self.return_fields - elif filter(lambda field: field not in self.return_fields, return_fields): - raise PLCInvalidArgument, "Invalid return field specified" + # Filter out password field + if return_fields: + return_fields = filter(lambda field: field not in hidden_fields, + return_fields) + else: + return_fields = self.return_fields.keys() - # Authenticated function - assert self.caller is not None + # Must query at least person_id, site_ids, and role_ids (see + # Person.can_view() and below). + if return_fields is not None: + added_fields = set(['person_id', 'site_ids', 'role_ids']).difference(return_fields) + return_fields += added_fields + else: + added_fields = [] - # Only admins can not specify person_id_or_email_list or - # specify an empty list. - if not person_id_or_email_list and 'admin' not in self.caller['roles']: - raise PLCInvalidArgument, "List of accounts to retrieve not specified" + persons = Persons(self.api, person_filter, return_fields) - # Get account information - persons = Persons(self.api, person_id_or_email_list) + # Filter out accounts that are not viewable + if isinstance(self.caller, Person) and \ + 'admin' not in self.caller['roles']: + persons = filter(self.caller.can_view, persons) - # Filter out accounts that are not viewable and turn into list - persons = filter(self.caller.can_view, persons.values()) + # Remove added fields if not specified + if added_fields: + for person in persons: + for field in added_fields: + if field in person: + del person[field] - # Filter out undesired or None fields (XML-RPC cannot marshal - # None) and turn each person into a real dict. - valid_return_fields_only = lambda (key, value): \ - key in return_fields and value is not None - persons = [dict(filter(valid_return_fields_only, person.items())) \ - for person in persons] - return persons