source: subversion/trunk/plugins/enigma/lib/enigma_ui.php @ 5526

Last change on this file since 5526 was 5526, checked in by alec, 18 months ago
  • Remove wrong check
File size: 15.4 KB
Line 
1<?php
2/*
3 +-------------------------------------------------------------------------+
4 | User Interface for the Enigma Plugin                                    |
5 |                                                                         |
6 | This program is free software; you can redistribute it and/or modify    |
7 | it under the terms of the GNU General Public License version 2          |
8 | as published by the Free Software Foundation.                           |
9 |                                                                         |
10 | This program is distributed in the hope that it will be useful,         |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of          |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           |
13 | GNU General Public License for more details.                            |
14 |                                                                         |
15 | You should have received a copy of the GNU General Public License along |
16 | with this program; if not, write to the Free Software Foundation, Inc., |
17 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.             |
18 |                                                                         |
19 +-------------------------------------------------------------------------+
20 | Author: Aleksander Machniak <alec@alec.pl>                              |
21 +-------------------------------------------------------------------------+
22*/
23
24class enigma_ui
25{
26    private $rc;
27    private $enigma;
28    private $home;
29    private $css_added;
30    private $data;
31
32
33    function __construct($enigma_plugin, $home='')
34    {
35        $this->enigma = $enigma_plugin;
36        $this->rc = $enigma_plugin->rc;
37        // we cannot use $enigma_plugin->home here
38        $this->home = $home;
39    }
40
41    /**
42     * UI initialization and requests handlers.
43     *
44     * @param string Preferences section
45     */
46    function init($section='')
47    {
48        $this->enigma->include_script('enigma.js');
49
50        // Enigma actions
51        if ($this->rc->action == 'plugin.enigma') {
52            $action = get_input_value('_a', RCUBE_INPUT_GPC);
53
54            switch ($action) {
55                case 'keyedit':
56                    $this->key_edit();
57                    break;
58                case 'keyimport':
59                    $this->key_import();
60                    break;
61                case 'keysearch':
62                case 'keylist':
63                    $this->key_list();
64                    break;
65                case 'keyinfo':
66                default:
67                    $this->key_info();
68            }
69        }
70        // Message composing UI
71        else if ($this->rc->action == 'compose') {
72            $this->compose_ui();
73        }
74        // Preferences UI
75        else { // if ($this->rc->action == 'edit-prefs') {
76            if ($section == 'enigmacerts') {
77                $this->rc->output->add_handlers(array(
78                    'keyslist' => array($this, 'tpl_certs_list'),
79                    'keyframe' => array($this, 'tpl_cert_frame'),
80                    'countdisplay' => array($this, 'tpl_certs_rowcount'),
81                    'searchform' => array($this->rc->output, 'search_form'),
82                ));
83                $this->rc->output->set_pagetitle($this->enigma->gettext('enigmacerts'));
84                $this->rc->output->send('enigma.certs'); 
85            }
86            else {
87                $this->rc->output->add_handlers(array(
88                    'keyslist' => array($this, 'tpl_keys_list'),
89                    'keyframe' => array($this, 'tpl_key_frame'),
90                    'countdisplay' => array($this, 'tpl_keys_rowcount'),
91                    'searchform' => array($this->rc->output, 'search_form'),
92                ));
93                $this->rc->output->set_pagetitle($this->enigma->gettext('enigmakeys'));
94                $this->rc->output->send('enigma.keys'); 
95            }
96        }
97    }
98
99   /**
100     * Adds CSS style file to the page header.
101     */
102    function add_css()
103    {
104        if ($this->css_loaded)
105            return;
106
107        $skin = $this->rc->config->get('skin');
108        if (!file_exists($this->home . "/skins/$skin/enigma.css"))
109            $skin = 'default';
110
111        $this->enigma->include_stylesheet("skins/$skin/enigma.css");
112        $this->css_added = true;
113    }
114
115    /**
116     * Template object for key info/edit frame.
117     *
118     * @param array Object attributes
119     *
120     * @return string HTML output
121     */
122    function tpl_key_frame($attrib)
123    {
124        if (!$attrib['id']) {
125            $attrib['id'] = 'rcmkeysframe';
126        }
127
128        $attrib['name'] = $attrib['id'];
129
130        $this->rc->output->set_env('contentframe', $attrib['name']);
131        $this->rc->output->set_env('blankpage', $attrib['src'] ? 
132            $this->rc->output->abs_url($attrib['src']) : 'program/blank.gif');
133
134        return html::tag('iframe', $attrib);
135    }
136
137    /**
138     * Template object for list of keys.
139     *
140     * @param array Object attributes
141     *
142     * @return string HTML content
143     */
144    function tpl_keys_list($attrib)
145    {
146        // add id to message list table if not specified
147        if (!strlen($attrib['id'])) {
148            $attrib['id'] = 'rcmenigmakeyslist';
149        }
150
151        // define list of cols to be displayed
152        $a_show_cols = array('name');
153
154        // create XHTML table
155        $out = rcube_table_output($attrib, array(), $a_show_cols, 'id');
156
157        // set client env
158        $this->rc->output->add_gui_object('keyslist', $attrib['id']);
159        $this->rc->output->include_script('list.js');
160
161        // add some labels to client
162        $this->rc->output->add_label('enigma.keyconfirmdelete');
163
164        return $out;
165    }
166
167    /**
168     * Key listing (and searching) request handler
169     */
170    private function key_list()
171    {
172        $this->enigma->load_engine();
173
174        $pagesize = $this->rc->config->get('pagesize', 100);
175        $page     = max(intval(get_input_value('_p', RCUBE_INPUT_GPC)), 1);
176        $search   = get_input_value('_q', RCUBE_INPUT_GPC);
177
178        // define list of cols to be displayed
179        $a_show_cols = array('name');
180        $result = array();
181
182        // Get the list
183        $list = $this->enigma->engine->list_keys($search);
184
185        if ($list && ($list instanceof enigma_error))
186            $this->rc->output->show_message('enigma.keylisterror', 'error');
187        else if (empty($list))
188            $this->rc->output->show_message('enigma.nokeysfound', 'notice');
189        else {
190            if (is_array($list)) {
191                // Save the size
192                $listsize = count($list);
193
194                // Sort the list by key (user) name
195                usort($list, array('enigma_key', 'cmp'));
196
197                // Slice current page
198                $list = array_slice($list, ($page - 1) * $pagesize, $pagesize);
199
200                $size = count($list);
201
202                // Add rows
203                foreach($list as $idx => $key) {
204                    $this->rc->output->command('enigma_add_list_row',
205                        array('name' => Q($key->name), 'id' => $key->id));
206                }
207            }
208        }
209
210        $this->rc->output->set_env('search_request', $search);
211        $this->rc->output->set_env('pagecount', ceil($listsize/$pagesize));
212        $this->rc->output->set_env('current_page', $page);
213        $this->rc->output->command('set_rowcount',
214            $this->get_rowcount_text($listsize, $size, $page));
215
216        $this->rc->output->send();
217    }
218
219    /**
220     * Template object for list records counter.
221     *
222     * @param array Object attributes
223     *
224     * @return string HTML output
225     */
226    function tpl_keys_rowcount($attrib)
227    {
228        if (!$attrib['id'])
229            $attrib['id'] = 'rcmcountdisplay';
230
231        $this->rc->output->add_gui_object('countdisplay', $attrib['id']);
232
233        return html::span($attrib, $this->get_rowcount_text());
234    }
235
236    /**
237     * Returns text representation of list records counter
238     */
239    private function get_rowcount_text($all=0, $curr_count=0, $page=1)
240    {
241        if (!$curr_count)
242            $out = $this->enigma->gettext('nokeysfound');
243        else {
244            $pagesize = $this->rc->config->get('pagesize', 100);
245            $first = ($page - 1) * $pagesize;
246
247            $out = $this->enigma->gettext(array(
248                'name' => 'keysfromto',
249                'vars' => array(
250                    'from'  => $first + 1,
251                    'to'    => $first + $curr_count,
252                    'count' => $all)
253            ));
254        }
255
256        return $out;
257    }
258
259    /**
260     * Key information page handler
261     */
262    private function key_info()
263    {
264        $id = get_input_value('_id', RCUBE_INPUT_GET);
265
266        $this->enigma->load_engine();
267        $res = $this->enigma->engine->get_key($id);
268
269        if ($res instanceof enigma_key)
270            $this->data = $res;
271        else { // error
272            $this->rc->output->show_message('enigma.keyopenerror', 'error');
273            $this->rc->output->command('parent.enigma_loadframe');
274            $this->rc->output->send('iframe');
275        }
276
277        $this->rc->output->add_handlers(array(
278            'keyname' => array($this, 'tpl_key_name'),
279            'keydata' => array($this, 'tpl_key_data'),
280        ));
281
282        $this->rc->output->set_pagetitle($this->enigma->gettext('keyinfo'));
283        $this->rc->output->send('enigma.keyinfo');
284    }
285
286    /**
287     * Template object for key name
288     */
289    function tpl_key_name($attrib)
290    {
291        return Q($this->data->name);
292    }
293
294    /**
295     * Template object for key information page content
296     */
297    function tpl_key_data($attrib)
298    {
299        $out = '';
300        $table = new html_table(array('cols' => 2)); 
301
302        // Key user ID
303        $table->add('title', $this->enigma->gettext('keyuserid'));
304        $table->add(null, Q($this->data->name));
305        // Key ID
306        $table->add('title', $this->enigma->gettext('keyid'));
307        $table->add(null, $this->data->subkeys[0]->get_short_id());
308        // Key type
309        $keytype = $this->data->get_type();
310        if ($keytype == enigma_key::TYPE_KEYPAIR)
311            $type = $this->enigma->gettext('typekeypair');
312        else if ($keytype == enigma_key::TYPE_PUBLIC)
313            $type = $this->enigma->gettext('typepublickey');
314        $table->add('title', $this->enigma->gettext('keytype'));
315        $table->add(null, $type);
316        // Key fingerprint
317        $table->add('title', $this->enigma->gettext('fingerprint'));
318        $table->add(null, $this->data->subkeys[0]->get_fingerprint());
319
320        $out .= html::tag('fieldset', null,
321            html::tag('legend', null,
322                $this->enigma->gettext('basicinfo')) . $table->show($attrib));
323
324        // Subkeys
325        $table = new html_table(array('cols' => 6)); 
326        // Columns: Type, ID, Algorithm, Size, Created, Expires
327
328        $out .= html::tag('fieldset', null,
329            html::tag('legend', null, 
330                $this->enigma->gettext('subkeys')) . $table->show($attrib));
331
332        // Additional user IDs
333        $table = new html_table(array('cols' => 2));
334        // Columns: User ID, Validity
335
336        $out .= html::tag('fieldset', null,
337            html::tag('legend', null, 
338                $this->enigma->gettext('userids')) . $table->show($attrib));
339
340        return $out;
341    }
342
343    /**
344     * Key import page handler
345     */
346    private function key_import()
347    {
348        // Import process
349        if ($_FILES['_file']['tmp_name'] && is_uploaded_file($_FILES['_file']['tmp_name'])) {
350            $this->enigma->load_engine();
351            $result = $this->enigma->engine->import_key($_FILES['_file']['tmp_name'], true);
352
353            if (is_array($result)) {
354                // reload list if any keys has been added
355                if ($result['imported']) {
356                    $this->rc->output->command('parent.enigma_list', 1);
357                }
358                else
359                    $this->rc->output->command('parent.enigma_loadframe');
360
361                $this->rc->output->show_message('enigma.keysimportsuccess', 'confirmation',
362                    array('new' => $result['imported'], 'old' => $result['unchanged']));
363
364                $this->rc->output->send('iframe');
365            }
366            else
367                $this->rc->output->show_message('enigma.keysimportfailed', 'error');
368        }
369        else if ($err = $_FILES['_file']['error']) {
370            if ($err == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE) {
371                $this->rc->output->show_message('filesizeerror', 'error',
372                    array('size' => show_bytes(parse_bytes(ini_get('upload_max_filesize')))));
373            } else {
374                $this->rc->output->show_message('fileuploaderror', 'error');
375            }
376        }
377
378        $this->rc->output->add_handlers(array(
379            'importform' => array($this, 'tpl_key_import_form'),
380        ));
381
382        $this->rc->output->set_pagetitle($this->enigma->gettext('keyimport'));
383        $this->rc->output->send('enigma.keyimport');
384    }
385
386    /**
387     * Template object for key import (upload) form
388     */
389    function tpl_key_import_form($attrib)
390    {
391        $attrib += array('id' => 'rcmKeyImportForm');
392
393        $upload = new html_inputfield(array('type' => 'file', 'name' => '_file',
394            'id' => 'rcmimportfile', 'size' => 30));
395
396        $form = html::p(null,
397            Q($this->enigma->gettext('keyimporttext'), 'show')
398            . html::br() . html::br() . $upload->show()
399        );
400
401        $this->rc->output->add_label('selectimportfile', 'importwait');
402        $this->rc->output->add_gui_object('importform', $attrib['id']);
403
404        $out = $this->rc->output->form_tag(array(
405            'action' => $this->rc->url(array('action' => 'plugin.enigma', 'a' => 'keyimport')),
406            'method' => 'post',
407            'enctype' => 'multipart/form-data') + $attrib,
408            $form);
409
410        return $out;
411    }
412
413    private function compose_ui()
414    {
415        // Options menu button
416        // @TODO: make this work with non-default skins
417        $this->enigma->add_button(array(
418            'name' => 'enigmamenu',
419            'imagepas' => 'skins/default/enigma.png',
420            'imageact' => 'skins/default/enigma.png',
421            'onclick' => "rcmail_ui.show_popup('enigmamenu', true); return false",
422            'title' => 'securityoptions',
423            'domain' => 'enigma',
424            ), 'toolbar');
425
426        // Options menu contents
427        $this->enigma->add_hook('render_page', array($this, 'compose_menu'));
428    }
429
430    function compose_menu($p)
431    {
432        $menu = new html_table(array('cols' => 2));
433        $chbox = new html_checkbox(array('value' => 1));
434
435        $menu->add(null, html::label(array('for' => 'enigmadefaultopt'),
436            Q($this->enigma->gettext('identdefault'))));
437        $menu->add(null, $chbox->show(1, array('name' => '_enigma_default', 'id' => 'enigmadefaultopt')));
438
439        $menu->add(null, html::label(array('for' => 'enigmasignopt'),
440            Q($this->enigma->gettext('signmsg'))));
441        $menu->add(null, $chbox->show(1, array('name' => '_enigma_sign', 'id' => 'enigmasignopt')));
442
443        $menu->add(null, html::label(array('for' => 'enigmacryptopt'),
444            Q($this->enigma->gettext('encryptmsg'))));
445        $menu->add(null, $chbox->show(1, array('name' => '_enigma_crypt', 'id' => 'enigmacryptopt')));
446
447        $menu = html::div(array('id' => 'enigmamenu', 'class' => 'popupmenu'),
448            $menu->show());
449
450        $p['content'] = preg_replace('/(<form name="form"[^>]+>)/i', '\\1'."\n$menu", $p['content']);
451
452        return $p;
453
454    }
455
456}
Note: See TracBrowser for help on using the repository browser.