0795151020bcf3583bf28c1541ac6fbe4285e4a7
[plcapi.git] / PLC / Methods / UpdatePerson.py
1 # $Id$
2 # $URL$
3 from PLC.Faults import *
4 from PLC.Method import Method
5 from PLC.Parameter import Parameter, Mixed
6 from PLC.Persons import Person, Persons
7 from PLC.Auth import Auth
8 from PLC.sendmail import sendmail
9
10 related_fields = Person.related_fields.keys()
11 can_update = lambda (field, value): field in \
12              ['first_name', 'last_name', 'title', 'email',
13               'password', 'phone', 'url', 'bio', 'accepted_aup',
14               'enabled'] + related_fields
15
16 class UpdatePerson(Method):
17     """
18     Updates a person. Only the fields specified in person_fields are
19     updated, all other fields are left untouched.
20
21     Users and techs can only update themselves. PIs can only update
22     themselves and other non-PIs at their sites.
23
24     Returns 1 if successful, faults otherwise.
25     """
26
27     roles = ['admin', 'pi', 'user', 'tech']
28
29     person_fields = dict(filter(can_update, Person.fields.items() + Person.related_fields.items()))
30
31     accepts = [
32         Auth(),
33         Mixed(Person.fields['person_id'],
34               Person.fields['email']),
35         person_fields
36         ]
37
38     returns = Parameter(int, '1 if successful')
39
40     def call(self, auth, person_id_or_email, person_fields):
41         person_fields = dict(filter(can_update, person_fields.items()))
42
43         # Get account information
44         persons = Persons(self.api, [person_id_or_email])
45         if not persons:
46             raise PLCInvalidArgument, "No such account"
47         person = persons[0]
48
49         if person['peer_id'] is not None:
50             raise PLCInvalidArgument, "Not a local account"
51
52         # Authenticated function
53         assert self.caller is not None
54
55         # Check if we can update this account
56         if not self.caller.can_update(person):
57             raise PLCPermissionDenied, "Not allowed to update specified account"
58
59         # Make requested associations
60         for field in related_fields:
61             if field in person_fields:
62                 person.associate(auth, field, person_fields[field])
63                 person_fields.pop(field)
64
65         person.update(person_fields)
66         person.update_last_updated(False)
67         person.sync()
68
69         if 'enabled' in person_fields:
70             To = [("%s %s" % (person['first_name'], person['last_name']), person['email'])]
71             Cc = []
72             if person['enabled']:
73                 Subject = "%s account enabled" % (self.api.config.PLC_NAME)
74                 Body = "Your %s account has been enabled. Please visit %s to access your account." % (self.api.config.PLC_NAME, self.api.config.PLC_WWW_HOST)
75             else:
76                 Subject = "%s account disabled" % (self.api.config.PLC_NAME)
77                 Body = "Your %s account has been disabled. Please contact your PI or PlanetLab support for more information" % (self.api.config.PLC_NAME)
78             sendmail(self.api, To = To, Cc = Cc, Subject = Subject, Body = Body)
79
80
81         # Logging variables
82         self.event_objects = {'Person': [person['person_id']]}
83
84         # Redact password
85         if 'password' in person_fields:
86             person_fields['password'] = "Removed by API"
87         self.message = 'Person %d updated: %s.' % \
88                        (person['person_id'], person_fields.keys())
89         if 'enabled' in person_fields:
90             self.message += ' Person enabled'
91
92         return 1