Office staff can modify office staff
[public/pyceo-broken.git] / pylib / csc / apps / urwid / groups.py
1 import urwid, pwd, grp
2 from csc.apps.urwid.widgets import *
3 from csc.apps.urwid.window import *
4 import csc.apps.urwid.search as search
5
6 from csc.adm import accounts, members
7 from csc.common.excep import InvalidArgument
8
9 def menu_items(items):
10     return [ urwid.AttrWrap( ButtonText( cb, data, txt ), 'menu', 'selected') for (txt, cb, data) in items ]
11
12 def change_group_member(data):
13     push_wizard("%s %s Member" % (data["type"], data["name"]), [
14         (ChangeMember, data),
15         EndPage,
16     ])
17
18 def list_group_members(data):
19     mlist = members.list_group( data["group"] ).values()
20     search.member_list( mlist )
21
22 def group_members(data):
23     data, euid = data
24
25     # only syscom may modify non-club groups
26     if data['group'] != 'office':
27         user = pwd.getpwuid(euid).pw_name
28         users = grp.getgrnam('syscom').gr_mem
29         if user not in users:
30             member = members.get(data['group'])
31             if member is None or 'objectClass' not in member \
32                     or 'club' not in member['objectClass']:
33                 return
34
35     add_data = data.copy()
36     add_data['type'] = 'Add'
37     remove_data = data.copy()
38     remove_data['type'] = 'Remove'
39     menu = [
40         ("Add %s member" % data["name"].lower(),
41             change_group_member, add_data),
42         ("Remove %s member" % data["name"].lower(),
43             change_group_member, remove_data),
44         ("List %s members" % data["name"].lower(), list_group_members, data),
45         ("Back", raise_back, None),
46     ]
47
48     listbox = urwid.ListBox( menu_items( menu ) )
49     push_window(listbox, "Manage %s" % data["name"])
50
51 class IntroPage(WizardPanel):
52     def init_widgets(self):
53         self.widgets = [
54             urwid.Text( "Managing Club or Group" ),
55             urwid.Divider(),
56             urwid.Text( "Adding a member to a club will also grant them "
57                         "access to the club's files and allow them to "
58                         "become_club."
59                         "\n\n"
60                         "Do not manage office and syscom related groups using "
61                         "this interface. Instead use the \"Manage Office "
62                         "Staff\" and \"Manage Systems Committee\" entries "
63                         "from the main menu." )
64         ]
65     def focusable(self):
66         return False
67
68 class InfoPage(WizardPanel):
69     def __init__(self, state, euid):
70         state['euid'] = euid
71         WizardPanel.__init__(self, state)
72     def init_widgets(self):
73         self.group = WordEdit("Club or Group: ")
74         self.widgets = [
75             urwid.Text( "Club or Group Information"),
76             urwid.Divider(),
77             self.group,
78         ]
79     def check(self):
80         group = self.group.get_edit_text()
81         # TODO - check that group is valid
82         group_name = group # TODO
83         data = {
84             "name" : group,
85             "group" : group_name,
86             "groups" : [group],
87         }
88         group_members((data, self.state['euid']))
89
90 class ChangeMember(WizardPanel):
91     def __init__(self, state, data):
92         state['data'] = data
93         WizardPanel.__init__(self, state)
94     def init_widgets(self):
95         self.userid = WordEdit("Username: ")
96
97         data = self.state['data']
98         self.widgets = [
99             urwid.Text( "%s %s Member" % (data['type'], data['name']) ),
100             urwid.Divider(),
101             self.userid,
102         ]
103     def check(self):
104         self.state['userid'] = self.userid.get_edit_text()
105         if self.state['userid']:
106             self.state['member'] = members.get(self.userid.get_edit_text())
107         if not self.state['member']:
108             set_status("Member not found")
109             self.focus_widget(self.userid)
110             return True
111         clear_status()
112
113 class EndPage(WizardPanel):
114     def init_widgets(self):
115         self.headtext = urwid.Text("")
116         self.midtext = urwid.Text("")
117         self.widgets = [
118             self.headtext,
119             urwid.Divider(),
120             self.midtext,
121         ]
122     def focusable(self):
123         return False
124     def check(self):
125         pop_window()
126     def activate(self):
127         data = self.state['data']
128         type = data['type'].lower()
129         failed = []
130         for group in data['groups']:
131             try:
132                 members.change_group_member(type, group, self.state['userid'])
133             except:
134                 failed.append(group)
135         if len(failed) == 0:
136             self.headtext.set_text("%s succeeded" % data['type'])
137             self.midtext.set_text("Congratulations, the group modification "
138                 "has succeeded.")
139         else:
140             self.headtext.set_text("%s partially succeeded" % data['type'])
141             self.midtext.set_text("Failed to %s member to %s for the "
142                 "following groups: %s. This may indicate an attempt to add a "
143                 "duplicate group member or to delete a non-present group "
144                 "member." % (data['type'].lower(), data['name'],
145                 ', '.join(failed)))