3 from PLC.Faults import *
4 from PLC.Method import Method
5 from PLC.Parameter import Parameter, Mixed
6 from PLC.Filter import Filter
7 from PLC.Persons import Person, Persons
8 from PLC.Sites import Site, Sites
9 from PLC.Auth import Auth
11 hidden_fields = ['password', 'verification_key', 'verification_expires']
13 class GetPersons(Method):
15 Returns an array of structs containing details about users. If
16 person_filter is specified and is an array of user identifiers or
17 usernames, or a struct of user attributes, only users matching the
18 filter will be returned. If return_fields is specified, only the
19 specified details will be returned.
21 Users and techs may only retrieve details about themselves. PIs
22 may retrieve details about themselves and others at their
23 sites. Admins and nodes may retrieve details about all accounts.
26 roles = ['admin', 'pi', 'user', 'tech', 'node']
30 Mixed([Mixed(Person.fields['person_id'],
31 Person.fields['email'])],
32 Parameter(str,"email"),
33 Parameter(int,"person_id"),
34 Filter(Person.fields)),
35 Parameter([str], "List of fields to return", nullok = True)
38 # Filter out password field
39 return_fields = dict(filter(lambda (field, value): field not in hidden_fields,
40 Person.fields.items()))
41 returns = [return_fields]
43 def call(self, auth, person_filter = None, return_fields = None):
44 # If we are not admin, make sure to only return viewable accounts
45 if isinstance(self.caller, Person) and \
46 'admin' not in self.caller['roles']:
47 # Get accounts that we are able to view
48 valid_person_ids = [self.caller['person_id']]
49 if 'pi' in self.caller['roles'] and self.caller['site_ids']:
50 sites = Sites(self.api, self.caller['site_ids'])
52 valid_person_ids += site['person_ids']
54 if not valid_person_ids:
57 if person_filter is None:
58 person_filter = valid_person_ids
60 # Filter out password field
62 return_fields = filter(lambda field: field not in hidden_fields,
65 return_fields = self.return_fields.keys()
67 # Must query at least person_id, site_ids, and role_ids (see
68 # Person.can_view() and below).
69 if return_fields is not None:
70 added_fields = set(['person_id', 'site_ids', 'role_ids','roles']).difference(return_fields)
71 return_fields += added_fields
75 persons = Persons(self.api, person_filter, return_fields)
77 # Filter out accounts that are not viewable
78 if isinstance(self.caller, Person) and \
79 'admin' not in self.caller['roles']:
80 persons = filter(self.caller.can_view, persons)
82 # Remove added fields if not specified
84 for person in persons:
85 for field in added_fields: