Source code for ez_message

# encoding=utf-8 ==============================================================#
#                                  ez_message                                  #
#==============================================================================#

#============#
#  Includes  #
#============#
from datetime import datetime
from Crypto.Hash import SHA # Shorter IDs than with 256
import ez_crypto as ec
import ez_database as ed

#==============================================================================#
#                                class Message                                 #
#==============================================================================#

[docs]class Message(object): """ This is the object that will be permanently saved in the database. It generates a unique ID based on sender, recipient and exact datetime. Unencrypted is recipient, year-month, injection vector and crypt_mode. Crypted is the message as cipher(AES) and key as ciphered_key(RSA). """ crypto_content = ['cipher', 'ciphered_key', 'iv', 'crypt_mode', 'ciphered_mac'] components = ['time', 'recipient', 'UID'] + crypto_content def __init__(self, sender='', recipient='', content='', dtime=None, _dict=None): if dtime == None: dtime=datetime.now() if _dict: for component in Message.components: setattr(self, component, _dict[component]) else: # todo: (bcn 2014-07-06) Isoformat is at least localization independent # but timezone information is still missing ! self.time = str(dtime.year) + '-' + str(dtime.month) exact_time = dtime.isoformat(' ') self.recipient = recipient self.UID = SHA.new(sender + recipient + exact_time).hexdigest() package = {'etime' : exact_time, 'sender' : sender, 'recipient' : recipient, 'content' : content} crypt_dict = ec.eZ_CryptoScheme(**package).encrypt_sign() for crypto_component in Message.crypto_content: setattr(self, crypto_component, crypt_dict[crypto_component]) def __str__(self): """ Full representation including local database information """ lst = [str(k) + ' : ' + str(getattr(self, k)) for k in Message.components] return '-'*80 + '\n' + '\n'.join(lst)
[docs] def clear_text(self): """ Return the decrypted text, given the private key is found on disk """ crypt_dict = {x : getattr(self, x) for x in Message.crypto_content} crypt_dict.update({'recipient' : self.recipient}) clear_dict = ec.eZ_CryptoScheme(**crypt_dict).decrypt_verify() if clear_dict['authorized']: sig_symb = '✓' else: sig_symb = '✗' lst = [clear_dict['sender'], "@", clear_dict['etime'], ":\n", clear_dict['content'], "\n:HMAC:", "[", sig_symb, "]"] return ' '.join(lst) #==============================================================================# # class MessageDatabase # #==============================================================================#
[docs]class MessageDatabase(ed.Database): """ The MessageDatabase class gives access to the saved, encrypted messages in the SQL database """ def __init__(self, **kwargs): """ Opens a local sqlite database in the default location default_db, which is saved to and loaded from disk automatically. To create a merely temporary database in memory use 'sqlite:///:memory:' """ ed.Database.__init__(self, 'Messages', Message, **kwargs)
message_database = MessageDatabase()