source: tools/policy/window.py @ b8ccf17

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

Friendlier rendering

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