source: tools/policy/window.py @ e69367b

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

Better Labels

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