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