# -*- coding: utf-8 -*-
"""
    MoinMoin - MoinCrypt Action

    PURPOSE:
        This action is used to display an encrypted page

    MODIFICATION HISTORY:
        @copyright: 2008 by Frank Maloschytzki (Frank.Maloschytzki@gansnett.de)
        @license: GNU GPL, see COPYING for details.
        Version: 0.2

    Part of code is copied from Whois.py  and test.py



"""

from MoinMoin.PageEditor import PageEditor
from MoinMoin.action import ActionBase
from MoinMoin import config
from base64 import b64decode
from Crypto.Cipher import AES


PAGENAME = u'ThisPageDoesNotExistsAndWillNeverBeReally'

CRYPTHEADER = 'Encrypted Page:'




class MoinCrypt(ActionBase):
    """ Show Decrypted page action

    """


    def __init__(self, pagename, request):
        ActionBase.__init__(self, pagename, request)
        self.use_ticket = False
        _ = self._
        self.form_trigger = 'passphrase'
        self.form_trigger_label = _('Crypt / Decrypt')
        self.thispage = PageEditor(request, pagename)


    def expandto16(self, text, fillchar=' '):
        """ Expand length of string to multiple of 16 by adding spaces
            """
        i = len(text) % 16
        if i != 0:
            return text + fillchar*(16-i)
        else:
            return text


    def do_action(self):
        
        _ = self._
        form = self.form
        passphrase = self.expandto16(form.get('pass', [u''])[0])
        text = self.thispage.get_body().encode(config.charset)
        if text.find(CRYPTHEADER) == -1:
            # Encrypt Page
            obj = AES.new(passphrase)
            ctext = obj.encrypt(self.expandto16(text))

            self.thispage.saveText(CRYPTHEADER+ctext.encode("base64"), 0, comment=u"Encrypt")
            self.render_msg(_('Successfully encrypted'))
            return
        else:
            # Page ist encrypted, so decrypt
            text = text[len(CRYPTHEADER):]
            text = b64decode(text)
            
            obj = AES.new(passphrase, AES.MODE_ECB)

            ctext = obj.decrypt(text)
            self.thispage.saveText(unicode(ctext, config.charset), 0, comment=u"Decrypt")
            self.render_msg(_('Successfully decrypted'))
            return


    def get_form_html(self, buttons_html):
        _ = self._
        d = {
            'pagename': self.pagename,
            'pass_label': _("Passphrase"),
            'buttons_html': buttons_html,
        }
        return '''
<table>
               <tr>
               <td class="label"><label>%(pass_label)s</label></td>
               <td class="content">
               <input type="text" name="pass" maxlength="128">
               </td>
               </tr>
               <tr>
               <td></td>
               <td class="buttons">
               %(buttons_html)s
               </td>
               </tr>
</table>
''' % d

    def work(self):
        """ Render action - this is the main function called by action's
            execute() function.

            We usually render a form here, check for posted forms, etc.
        """
        _ = self._
        form = self.form

        if form.has_key(self.form_cancel):
            self.render_cancel()
            return

        # Validate allowance, user rights and other conditions.
        error = None
        if self.is_excluded():
            error = _('Action %(actionname)s is excluded in this wiki!') % {'actionname': self.actionname }
        elif not self.is_allowed():
            error = _('You are not allowed to use action %(actionname)s on thispage!') % {'actionname': self.actionname }
        if error is None:
            self.check_condition()
        if error:
            self.render_msg(error)
        elif form.has_key(self.form_trigger) or form.has_key('pass'): # user hit the trigger button
            if self.ticket_ok():
                self.do_action()
                return
            else:
                self.render_msg(_('Please use the interactive user interface to use action %(actionname)s!') % {'actionname': self.actionname })
            return
        else:
            # Return a new form
            self.render_msg(self.make_form())

def execute(pagename, request):
    """ Do your work
    """
    _ = request.getText

# Don't check if personal wiki

#    if request.user.valid:
#        username = request.user.name
#    else:
#        username = ''
#
#    if not username:
#        return thispage.send_page(
#            msg = _('Please log in first.'))

    
    MoinCrypt(pagename, request).work()
