X-Git-Url: http://git.datanom.net/securemail.git/blobdiff_plain/7ef0042650fe0a5e12373fd6ef438f138afe65b2..5bc1fc471eb0a72f4420b9189c990026e570d52a:/app/backend/user.py diff --git a/app/backend/user.py b/app/backend/user.py new file mode 100644 index 0000000..a4ab2f7 --- /dev/null +++ b/app/backend/user.py @@ -0,0 +1,142 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2018 Michael Rasmussen + +# This file is part of SecureMail. + +# SecureMail is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# SecureMail is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with SecureMail. If not, see . + +import pickle +from db import DBInterface as DBI +from cryptonize import Cryptonize +from nacl.public import PublicKey + +class NoSuchUser(Exception): + pass + +class User: + """ + Class implementing the backend users + """ + def __init__(self, key=None): + if key is not None: + self.load(key) + else: + self.pubkeys = {} + + def store(self, key): + crypto = Cryptonize() + cipher = crypto.symmetric_encrypt(key, pickle.dumps(self)) + DBI.store_user(crypto.generate_hash(key), cipher) + + def load(self, key): + crypto = Cryptonize() + cipher = DBI.load_user(crypto.generate_hash(key)) + if cipher is None: + raise NoSuchUser('{0}: User not found'.format(key)) + plain = crypto.symmetric_decrypt(key, cipher) + try: + obj = pickle.loads(plain) + self.__dict__.update(obj.__dict__) + except pickle.UnpicklingError as e: + raise e + + def add_pubkey(self, email, key): + if email not in self.pubkeys: + self.pubkeys[email] = key.encode() + else: + raise KeyError('{0}: Exists'.format(email)) + + def update_pubkey(self, email, key): + self.pubkeys[email] = key.encode() + + def delete_pubkey(self, email): + if email in self.pubkeys: + del self.pubkeys[email] + + def get_pubkey(self, email): + if email in self.pubkeys: + key = self.pubkeys[email] + key = PublicKey(key) + else: + key = None + + return key + + @property + def name(self): + return self._name + + @name.setter + def name(self, name): + self._name = name + + @property + def email(self): + return self._email + + @email.setter + def email(self, email): + self._email = email + + @property + def pubkeys(self): + return self._pubkeys + + @pubkeys.setter + def pubkeys(self, pubkeys): + if type(pubkeys) is not type({}): + raise ValueError('Not dictionary') + self._pubkeys = pubkeys + +if __name__ == '__main__': + try: + u = User('test') + for attr, value in u.__dict__.items(): + print ('{0}: {1}'.format(attr, value)) + print ('{0} - {1} - {2}'.format(u.name, u.email, u.pubkeys)) + key = '' + for i in range(40): + key += '{0}'.format(i) + u = User() + u.name = 'testname1' + u.email = 'testname1@securemail.icu' + u.pubkeys = {'test': 'some test', 'test1': 'some test 1'} + try: + u.store(key) + except: + u = User(key) + for attr, value in u.__dict__.items(): + print ('{0}: {1}'.format(attr, value)) + print ('{0} - {1} - {2}'.format(u.name, u.email, u.pubkeys)) + c = Cryptonize() + keypair1 = c.get_key_pair() + keypair2 = c.get_key_pair() + try: + u.add_pubkey('test', keypair2[1]) + except KeyError: + u.update_pubkey('test', keypair2[1]) + message = "Kill all humans æøåÅØÆ" + print ("Message to encrypt: {0}".format(message)) + encrypted = c.asymmetric_encrypt(keypair1[0], u.get_pubkey('test'), message) + print ("Message encrypted: {0}".format(encrypted)) + plaintext = c.asymmetric_decrypt(keypair2[0], keypair1[1], encrypted) + print("Message decrypted: {0}".format(plaintext.decode())) + except NoSuchUser: + u = User() + u.name = 'testname' + u.email = 'testname@securemail.icu' + u.store('test') + except Exception as e: + print (e)