source: tools/policy/window.py @ 3821a93

gec13
Last change on this file since 3821a93 was 3821a93, checked in by Ted Faber <faber@…>, 12 years ago

List Principals who can perform actions

  • Property mode set to 100644
File size: 9.3 KB
Line 
1#!?usr/local/bin/python
2
3import gtk
4import ConfigParser
5import os.path
6import re
7import Creddy
8
9from policy import policy
10
11from principal_tree import principal_issued_tree, \
12        principal_assigned_tree, principal_attribute_tree, \
13        principal_rules_tree, principal_action_tree, action_principal_tree
14
15from new_credential import add_credential_dialog, add_principal_dialog, \
16        mark_action_dialog
17
18class window(gtk.Window):
19
20    ui_def = '''
21    <ui>
22        <menubar>
23            <menu action="FileMenu">
24                <menuitem name="New" action="FileNew"/>
25                <menuitem name="Load" action="FileLoad"/>
26                <menuitem name="Append" action="FileAppend"/>
27                <menuitem name="Save" action="FileSave"/>
28                <menuitem name="Quit" action="FileQuit"/>
29            </menu>
30            <menu action="EditMenu">
31                <menuitem action="EditAddCred"/>
32                <menuitem action="EditAddPrincipal"/>
33                <menuitem action="EditMarkAction"/>
34            </menu>
35            <menu action="ViewMenu">
36                <menu action="Translation">
37                    <menuitem name="ViewSet" action="ViewSet"/>
38                    <menuitem name="ViewRole description" action="ViewRole"/>
39                    <menuitem name="ViewNames" action="ViewName"/>
40                    <menuitem name="ViewRaw" action="ViewRaw"/>
41                </menu>
42            </menu>
43        </menubar>
44    </ui>
45    '''
46    cfg_path = os.path.join(os.path.expanduser('~'), '.abac_policy_tool.cfg')
47
48    @staticmethod
49    def wrapit(widget):
50        sw = gtk.ScrolledWindow()
51        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
52        sw.add(widget)
53        return sw
54
55    def report_error(self, message):
56        md = gtk.MessageDialog(self, gtk.DIALOG_MODAL, 
57                gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE, 
58                message)
59        md.run()
60        md.destroy()
61
62    def __init__(self, policy):
63        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
64        self.policy = policy
65        self.set_title('ABAC Policy Tool')
66        self.connect('destroy', self.quit)
67        self.connect('show', self.shown)
68        self.connect('configure-event', self.changed)
69        self.pos = (0,0)
70        self.size = (500, 500)
71        self.pages = [ ]
72        self.translated = [ ]
73
74        self.read_config()
75
76        nb = gtk.Notebook()
77        p = action_principal_tree(policy)
78        nb.append_page(self.wrapit(p), gtk.Label("Actions"))
79        self.pages.append(p)
80        self.translated.append(p)
81
82        p = principal_action_tree(policy)
83        nb.append_page(self.wrapit(p), gtk.Label("Actions"))
84        self.pages.append(p)
85        self.translated.append(p)
86
87        p = principal_issued_tree(policy)
88        nb.append_page(self.wrapit(p), gtk.Label("Attributes Directly Issued"))
89        self.pages.append(p)
90
91        p = principal_rules_tree(policy)
92        nb.append_page(self.wrapit(p), gtk.Label("Rules declared"))
93        self.pages.append(p)
94        self.translated.append(p)
95
96        p = principal_assigned_tree(policy)
97        nb.append_page(self.wrapit(p), gtk.Label("Attributes Directly Held"))
98        self.pages.append(p)
99
100        p = principal_attribute_tree(policy)
101        nb.append_page(self.wrapit(p), gtk.Label("All Attributes"))
102        self.pages.append(p)
103        self.translated.append(p)
104
105        ui = gtk.UIManager()
106        ag = gtk.ActionGroup('action')
107        ag.add_actions((
108            ('FileMenu', None, 'File'),
109            ('FileNew', gtk.STOCK_NEW, None, None, None, self.new),
110            ('FileSave', gtk.STOCK_SAVE, None, None, None, self.save),
111            ('FileQuit', gtk.STOCK_QUIT, None, None, None, self.quit),
112            ('EditMenu', None, 'Edit'),
113            ('EditAddCred', None, "Add Credential", None, None, self.add_cred),
114            ('EditAddPrincipal', None, "Add Principal", None, None, 
115                self.add_principal),
116            ('EditMarkAction', None, "Mark Action", None, None, 
117                self.mark_action),
118            ('ViewMenu', None, 'View'),
119            ('Translation', None, 'Translate Credentials'),
120            ))
121        ag.add_actions((
122            ('FileLoad', gtk.STOCK_OPEN, None, None, None, self.load),
123            ), True)
124        ag.add_actions((
125            ('FileAppend', gtk.STOCK_ADD, None, None, None, self.load),
126            ), False)
127        ag.add_radio_actions([
128            ('ViewSet', None, 'Set based descriptions', None, None, 0), 
129            ('ViewRole', None, 'Role based descriptions', None, None, 1), 
130            ('ViewName', None, 'ABAC with symbolic names', None, None, 2), 
131            ('ViewRaw', None, 'Raw ABAC', None, None, 3),], 
132            2, self.translation_change)
133
134        ui.insert_action_group(ag, -1)
135        ui.add_ui_from_string(window.ui_def)
136
137        mb = ui.get_widget('ui/menubar')
138        vb = gtk.VBox()
139        vb.pack_start(mb, False, False, 0)
140        vb.pack_start(nb, True, True, 0)
141
142        self.add(vb)
143        self.show_all()
144   
145    def quit(self, widget=None, data=None):
146        self.save_config()
147        gtk.main_quit()
148
149    def save(self, widget=None, data=None):
150        d = gtk.FileChooserDialog('Save file as', self, 
151                gtk.FILE_CHOOSER_ACTION_SAVE, (
152            gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
153            gtk.STOCK_OK, gtk.RESPONSE_OK))
154        fil = gtk.FileFilter()
155        fil.set_name('Zip files')
156        fil.add_pattern('*.zip')
157        d.set_select_multiple(False)
158        d.set_current_folder('.')
159        d.set_do_overwrite_confirmation(True)
160        d.add_filter(fil)
161        if self.policy.filename is not None:
162            d.set_filename(self.policy.filename)
163        rv = d.run()
164        d.hide()
165        if rv == gtk.RESPONSE_OK:
166            self.policy.write_zip(d.get_filename())
167        d.destroy()
168
169    def new(self, widget=None, data=None):
170        d = gtk.MessageDialog(self, gtk.DIALOG_MODAL, 
171                gtk.MESSAGE_ERROR, gtk.BUTTONS_OK_CANCEL, 
172                "Clear this policy?")
173        rv = d.run()
174        if rv == gtk.RESPONSE_OK:
175            self.policy.clear()
176            for p in self.pages:
177                p.recalc()
178        d.destroy()
179
180    def load(self, widget=None, data=None):
181        d = gtk.FileChooserDialog('Load file', self, 
182                gtk.FILE_CHOOSER_ACTION_OPEN, (
183            gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
184            gtk.STOCK_OK, gtk.RESPONSE_OK))
185        fil = gtk.FileFilter()
186        fil.set_name('Zip files')
187        fil.add_pattern('*.zip')
188        d.set_select_multiple(False)
189        d.set_current_folder('.')
190        d.set_do_overwrite_confirmation(True)
191        d.add_filter(fil)
192        if self.policy.filename is not None:
193            d.set_filename(self.policy.filename)
194        rv = d.run()
195        d.hide()
196        if rv == gtk.RESPONSE_OK:
197            self.policy.read_zip(d.get_filename(), data)
198            for p in self.pages:
199                p.recalc()
200        d.destroy()
201
202    def add_principal(self, widget=None, data=None):
203        while True:
204            d = add_principal_dialog(self)
205            rv = d.run()
206            d.hide()
207            if rv == gtk.RESPONSE_OK:
208                name = d.pname.get_text() 
209                if name not in self.policy.principal_names():
210                    try:
211                        cid = Creddy.ID(name, 5 * 3600 * 24 * 365)
212                    except RuntimeError, e:
213                        self.report_error('Cannot create principal: %s' % e)
214                        continue
215                    self.policy.add_identity(cid)
216                    for p in self.pages:
217                        p.recalc()
218                    d.destroy()
219                    return
220                else:
221                    d.destroy()
222                    self.report_error('Cannot overwrite name: %s' % name)
223            else:
224                d.destroy()
225                return
226
227    def add_cred(self, widget=None, data=None):
228        d = add_credential_dialog(self, self.policy)
229        rv = d.run()
230        d.hide()
231        if rv == gtk.RESPONSE_OK:
232            iname = d.issuer.get_active_text()
233            issuer = self.policy.issuers[self.policy.name_to_keyid(iname)]
234            role = re.sub('\.', '_', d.role.get_text())
235            cred = None
236            try: 
237                cred = Creddy.Attribute(issuer, role, 5 * 365 * 3600 * 24)
238            except RuntimeError, e:
239                print e
240                pass
241
242            if cred is None:
243                self.report_error("Missing or invalid role")
244                d.destroy()
245                return
246
247            mode = d.mechanism.get_active_text()
248            p = d.subject_principal.get_text()
249            p = self.policy.name_to_keyid(p)
250            if p is None:
251                self.report_error("Missing or invalid subject principal")
252                d.destroy()
253                return
254            if mode == 'Direct delegation' or mode == 'Delegation to role':
255                r = d.subject_role.get_text()
256                if r is None or r == '':
257                    self.report_error("Missing or invalid subject role")
258                    d.destroy()
259                    return
260            if mode == 'Delegation to role':
261                l = d.subject_link.get_text()
262                if l is None or l == '':
263                    self.report_error("Missing or invalid subject linking role")
264                    d.destroy()
265                    return
266
267            if mode == 'Direct assignment': cred.principal(p)
268            elif mode == 'Direct delegation': cred.role(p, r)
269            else: cred.linking_role(p, l, r)
270
271            try:
272                cred.bake()
273            except:
274                self.report_error("Could not create credential?!")
275                d.destroy()
276                return
277            self.policy.add_credential(cred)
278            for p in self.pages:
279                p.recalc()
280            d.destroy()
281
282    def mark_action(self, widget=None, data=None):
283        d = mark_action_dialog(self, self.policy)
284        rv = d.run()
285        d.hide()
286        if rv == gtk.RESPONSE_OK:
287            action = d.get_value()
288            if action is not None:
289                self.policy.add_action(action)
290            for p in self.pages:
291                p.recalc()
292        d.destroy()
293
294
295    def shown(self, w):
296        self.move(*self.pos)
297        self.resize(*self.size)
298
299    def changed(self, w, e):
300        self.pos = self.get_position()
301        self.size = self.get_size()
302
303    def translation_change(self, ra, c, user=None):
304        cv = c.get_current_value()
305        if cv == 0: self.policy.translate = 'sets'
306        elif cv == 1: self.policy.translate = 'roles'
307        elif cv == 2: self.policy.translate = 'keyids'
308        elif cv == 3: self.policy.translate = 'none'
309        else: print >>sys.stderr, 'Unknown translation type!?'
310
311        for p in self.translated:
312            p.recalc()
313
314    def get_intpair(self, sect, opt):
315        if not self.cfg.has_section(sect):
316            self.cfg.add_section(sect)
317
318        if self.cfg.has_option(sect, opt):
319            try:
320                return [int(x) for x in self.cfg.get(sect, opt).split(',', 1)]
321            except ValueError:
322                return None
323        else:
324            return None
325
326    def read_config(self):
327        self.cfg = ConfigParser.SafeConfigParser()
328        self.cfg.read(window.cfg_path)
329
330        self.pos = self.get_intpair('geom', 'pos') or ( 0, 0)
331        self.size = self.get_intpair('geom', 'size') or ( 500, 500)
332
333
334    def save_config(self):
335        self.cfg.set('geom', 'pos', '%d,%d' % self.pos)
336        self.cfg.set('geom', 'size', '%d,%d' % self.size)
337        try:
338            f = open(window.cfg_path, 'w')
339            self.cfg.write(f)
340            f.close()
341        except EnvironmentError, e:
342            pass
Note: See TracBrowser for help on using the repository browser.