├── .gitignore ├── disappeer ├── __init__.py ├── __main__.py ├── components │ ├── __init__.py │ └── notifications.py ├── console │ ├── __init__.py │ ├── consolecontroller.py │ ├── consoleframe.py │ └── tests │ │ ├── __init__.py │ │ └── test_consolecontroller.py ├── constants │ ├── __init__.py │ ├── constants.py │ ├── styling.py │ └── tests │ │ ├── __init__.py │ │ └── test_constants.py ├── executor │ ├── __init__.py │ ├── commandclient.py │ ├── commands │ │ ├── __init__.py │ │ ├── abstractcommand.py │ │ ├── checksanitycommand.py │ │ ├── newcontactrequestclientresponsecommand.py │ │ ├── newcontactresponseclientresponsecommand.py │ │ ├── newcontactresponsecommand.py │ │ ├── receivednewmessagecommand.py │ │ ├── sendnewmessageclientresponsecommand.py │ │ ├── sendnewmessagecommand.py │ │ └── tests │ │ │ ├── __init__.py │ │ │ ├── test_abstractcommand.py │ │ │ ├── test_checksanitycommand.py │ │ │ ├── test_newcontactrequestclientresponsecommand.py │ │ │ ├── test_newcontactresponseclientresponsecommand.py │ │ │ ├── test_newcontactresponsecommand.py │ │ │ ├── test_receivednewmessagecommand.py │ │ │ ├── test_sendnewmessageclientresponsecommand.py │ │ │ └── test_sendnewmessagecommand.py │ ├── controllermediator.py │ ├── invoker.py │ ├── receiverfactory.py │ ├── receivers │ │ ├── __init__.py │ │ ├── abstractreceiver.py │ │ ├── checksanityreceiver.py │ │ ├── newcontactrequestclientresponsereceiver.py │ │ ├── newcontactresponseclientresponsereceiver.py │ │ ├── newcontactresponsereceiver.py │ │ ├── receivednewmessagereceiver.py │ │ ├── sendnewmessageclientresponsereceiver.py │ │ ├── sendnewmessagereceiver.py │ │ └── tests │ │ │ ├── __init__.py │ │ │ ├── test_abstractreceiver.py │ │ │ ├── test_checksanityreceiver.py │ │ │ ├── test_newcontactrequestclientresponsereceiver.py │ │ │ ├── test_newcontactresponseclientresponsereceiver.py │ │ │ ├── test_newcontactresponsereceiver.py │ │ │ ├── test_receivednewmessagereceiver.py │ │ │ ├── test_sendnewmessageclientresponsereceiver.py │ │ │ └── test_sendnewmessagereceiver.py │ └── tests │ │ ├── __init__.py │ │ ├── test_commandclient.py │ │ ├── test_controllermediator.py │ │ ├── test_invoker.py │ │ └── test_receiverfactory.py ├── gpg │ ├── __init__.py │ ├── agents │ │ ├── __init__.py │ │ ├── decrypter.py │ │ ├── detachedverifier.py │ │ ├── encrypter.py │ │ ├── gpgagent.py │ │ ├── gpgclient.py │ │ ├── keycreator.py │ │ ├── keydeleter.py │ │ ├── keyring.py │ │ ├── signer.py │ │ └── verifier.py │ ├── gpgcontroller.py │ ├── gpgframe.py │ ├── helpers │ │ ├── __init__.py │ │ ├── gpgpubkeyvalidator.py │ │ ├── hostkeyobservable.py │ │ ├── keyfinder.py │ │ ├── keylistformatter.py │ │ ├── keylistobservable.py │ │ ├── passphrasevalidator.py │ │ ├── tempdetachedverifier.py │ │ └── tempkeyring.py │ └── tests │ │ ├── __init__.py │ │ ├── agents │ │ ├── __init__.py │ │ ├── test_decrypter.py │ │ ├── test_detachedverifier.py │ │ ├── test_encrypter.py │ │ ├── test_gpgagent.py │ │ ├── test_gpgclient.py │ │ ├── test_keycreator.py │ │ ├── test_keydeleter.py │ │ ├── test_keyring.py │ │ ├── test_signer.py │ │ └── test_verifier.py │ │ ├── gpgcontroller │ │ ├── __init__.py │ │ ├── gpgcontrollersetupclass.py │ │ ├── test_gpgcontroller.py │ │ └── test_gpgcontrollereventmethods.py │ │ └── helpers │ │ ├── __init__.py │ │ ├── test_gpgpubkeyvalidator.py │ │ ├── test_hostkeyobservable.py │ │ ├── test_keyfinder.py │ │ ├── test_keylistformatter.py │ │ ├── test_keylistobservable.py │ │ ├── test_passphrasevalidator.py │ │ ├── test_tempdetachedverifier.py │ │ └── test_tempkeyring.py ├── images │ ├── Farm-Fresh_lightning_go.png │ ├── Farm-Fresh_update.png │ ├── __init__.py │ ├── bullet_green_small.gif │ ├── crypto_key.png │ ├── delete_icon.png │ ├── logo_64x64.gif │ ├── logo_icon.png │ ├── logo_icon_huge.png │ ├── logo_icon_large.png │ ├── logo_icon_small.png │ ├── no_image.gif │ ├── open_icon.png │ ├── play_icon.png │ ├── run_icon.png │ ├── save_icon.png │ ├── send_icon.png │ ├── send_icon_1.png │ ├── small_gnupg_full_logo.png │ └── tor_icon_small.gif ├── messages │ ├── __init__.py │ ├── messagescontroller.py │ ├── messagesframe.py │ └── tests │ │ ├── __init__.py │ │ └── test_messagescontroller.py ├── metainfo.py ├── models │ ├── __init__.py │ ├── db │ │ ├── __init__.py │ │ ├── bases │ │ │ ├── __init__.py │ │ │ ├── abstractdbtable.py │ │ │ ├── basemessagestable.py │ │ │ └── tests │ │ │ │ ├── __init__.py │ │ │ │ ├── test_abstractdbtable.py │ │ │ │ └── test_basemessagestable.py │ │ ├── databasefacade.py │ │ ├── dbcontactrequesttable.py │ │ ├── dbexecutor.py │ │ ├── dbpeercontactstable.py │ │ ├── dbpendingcontactresponsetable.py │ │ ├── dbreceivedmessagestable.py │ │ ├── dbsentmessagestable.py │ │ ├── dbserversynctable.py │ │ └── tests │ │ │ ├── __init__.py │ │ │ ├── test_databasefacade.py │ │ │ ├── test_dbcontactrequestable.py │ │ │ ├── test_dbexecutor.py │ │ │ ├── test_dbpeercontactstable.py │ │ │ ├── test_dbpendingcontactresponsetable.py │ │ │ ├── test_dbreceivedmessagestable.py │ │ │ ├── test_dbsentmessagestable.py │ │ │ ├── test_dbserversynctable.py │ │ │ └── testdatabasesmain.sqlite │ ├── gpgdatacontext.py │ ├── tests │ │ ├── __init__.py │ │ ├── test_gpgdatacontext.py │ │ └── test_tordatacontext.py │ └── tordatacontext.py ├── net │ ├── __init__.py │ ├── bases │ │ ├── __init__.py │ │ ├── abstractclient.py │ │ ├── abstractserverfactory.py │ │ ├── baseprotocol.py │ │ ├── clientcontroller.py │ │ ├── clientfactory.py │ │ ├── packet.py │ │ ├── servercontroller.py │ │ ├── tests │ │ │ ├── __init__.py │ │ │ ├── test_abstractclient.py │ │ │ ├── test_abstractserverfactory.py │ │ │ ├── test_baseprotocol.py │ │ │ ├── test_clientcontroller.py │ │ │ ├── test_clientfactory.py │ │ │ ├── test_packet.py │ │ │ ├── test_servercontroller.py │ │ │ └── test_threadmanagers.py │ │ └── threadmanagers.py │ ├── contact │ │ ├── __init__.py │ │ ├── contactprotocol.py │ │ ├── contactrequestclient.py │ │ ├── contactrequestfactory.py │ │ ├── contactrequestserver.py │ │ ├── contactrequestvalidator.py │ │ └── tests │ │ │ ├── __init__.py │ │ │ ├── test_contactprotocol.py │ │ │ ├── test_contactrequestclient.py │ │ │ ├── test_contactrequestfactory.py │ │ │ ├── test_contactrequestserver.py │ │ │ └── test_contactrequestvalidator.py │ ├── contactresponse │ │ ├── __init__.py │ │ ├── contactresponseclient.py │ │ ├── contactresponsefactory.py │ │ ├── contactresponseserver.py │ │ ├── contactresponsevalidator.py │ │ └── tests │ │ │ ├── __init__.py │ │ │ ├── test_contactresponseclient.py │ │ │ ├── test_contactresponsefactory.py │ │ │ ├── test_contactresponseserver.py │ │ │ └── test_contactresponsevalidator.py │ ├── message │ │ ├── __init__.py │ │ ├── messageclient.py │ │ ├── messagefactory.py │ │ ├── messageserver.py │ │ ├── messagevalidator.py │ │ └── tests │ │ │ ├── __init__.py │ │ │ ├── test_messageclient.py │ │ │ ├── test_messagefactory.py │ │ │ ├── test_messageserver.py │ │ │ └── test_messagevalidator.py │ ├── networkservers.py │ └── tests │ │ ├── __init__.py │ │ └── test_networkservers.py ├── popups │ ├── __init__.py │ ├── aboutbox │ │ ├── __init__.py │ │ ├── aboutboxcontroller.py │ │ └── aboutboxview.py │ ├── alertbox │ │ ├── __init__.py │ │ ├── alertboxcontroller.py │ │ └── alertboxview.py │ ├── bases │ │ ├── __init__.py │ │ └── basepopupcontroller.py │ ├── blinkalert │ │ ├── __init__.py │ │ ├── blinkalertcontroller.py │ │ └── blinkalertview.py │ ├── contactrequest │ │ ├── __init__.py │ │ ├── contactrequestcontroller.py │ │ └── contactrequestview.py │ ├── deletekey │ │ ├── __init__.py │ │ ├── deletekeycontroller.py │ │ └── deletekeyview.py │ ├── displaymessage │ │ ├── __init__.py │ │ ├── displaymessagecontroller.py │ │ └── displaymessageview.py │ ├── displaysentrequest │ │ ├── __init__.py │ │ ├── displaysentrequestcontroller.py │ │ └── displaysentrequestview.py │ ├── getpassphrase │ │ ├── __init__.py │ │ ├── getpassphrasecontroller.py │ │ └── getpassphraseview.py │ ├── getsessionpassphrase │ │ ├── __init__.py │ │ ├── getsessionpassphrasecontroller.py │ │ └── getsessionpassphraseview.py │ ├── keyinfo │ │ ├── __init__.py │ │ ├── keyinfocontroller.py │ │ └── keyinfoview.py │ ├── newkey │ │ ├── __init__.py │ │ ├── newkeycontroller.py │ │ └── newkeyview.py │ ├── peerconnect │ │ ├── __init__.py │ │ ├── peerconnectcontroller.py │ │ └── peerconnectview.py │ ├── peercontact │ │ ├── __init__.py │ │ ├── peercontactcontroller.py │ │ └── peercontactview.py │ ├── popuplauncher.py │ ├── sendmessage │ │ ├── __init__.py │ │ ├── sendmessagecontroller.py │ │ └── sendmessageview.py │ └── tests │ │ ├── __init__.py │ │ ├── aboutbox │ │ ├── __init__.py │ │ └── test_aboutboxcontroller.py │ │ ├── alertbox │ │ ├── __init__.py │ │ └── test_alertboxcontroller.py │ │ ├── bases │ │ ├── __init__.py │ │ └── test_basepopupcontroller.py │ │ ├── blinkalert │ │ ├── __init__.py │ │ └── test_blinkalertcontroller.py │ │ ├── contactrequest │ │ ├── __init__.py │ │ └── test_contactrequestcontroller.py │ │ ├── deletekey │ │ ├── __init__.py │ │ └── test_deletekeycontroller.py │ │ ├── displaymessage │ │ ├── __init__.py │ │ └── test_displaymessagecontroller.py │ │ ├── displaysentrequest │ │ ├── __init__.py │ │ └── test_displaysentrequestcontroller.py │ │ ├── getpassphrase │ │ ├── __init__.py │ │ └── test_getpassphrasecontroller.py │ │ ├── getsessionpassphrase │ │ ├── __init__.py │ │ └── test_getsessionpassphrasecontroller.py │ │ ├── keyinfo │ │ ├── __init__.py │ │ └── test_keyinfocontroller.py │ │ ├── newkey │ │ ├── __init__.py │ │ └── test_newkeycontroller.py │ │ ├── peerconnect │ │ ├── __init__.py │ │ └── test_peerconnectcontroller.py │ │ ├── peercontact │ │ ├── __init__.py │ │ └── test_peercontactcontroller.py │ │ ├── sendmessage │ │ ├── __init__.py │ │ └── test_sendmessagecontroller.py │ │ └── test_popuplauncher.py ├── requests │ ├── __init__.py │ ├── requestscontroller.py │ ├── requestsframe.py │ └── tests │ │ ├── __init__.py │ │ └── test_requestscontroller.py ├── root │ ├── __init__.py │ ├── leftpanel.py │ ├── rightpanel.py │ ├── rootcontroller.py │ ├── rootparameters.py │ ├── rootview.py │ └── tests │ │ ├── __init__.py │ │ ├── rootsetupclass.py │ │ ├── test_rootcontroller.py │ │ ├── test_rootcontrollercontactmethods.py │ │ └── test_rootparameters.py ├── settings.py ├── tests │ ├── __init__.py │ ├── data │ │ ├── altkeys │ │ │ ├── pubring.kbx │ │ │ └── trustdb.gpg │ │ ├── dirmaker │ │ │ ├── data │ │ │ │ └── 55A45A99FE45E540 │ │ │ │ │ └── databases │ │ │ │ │ ├── 55A45A99FE45E540.sqlite │ │ │ │ │ └── server_sync.sqlite │ │ │ └── keys │ │ │ │ └── default │ │ │ │ ├── .#lk0x00007fee80501220.niemand.local.74548 │ │ │ │ ├── .gpg-v21-migrated │ │ │ │ ├── private-keys-v1.d │ │ │ │ ├── 291A515859B553CEFEEE91B95443F1B172CE206A.key │ │ │ │ └── 8DC8015AE89B9D4E6B02FAB83FEE523483A6DB84.key │ │ │ │ ├── pubring.gpg │ │ │ │ ├── pubring.gpg~ │ │ │ │ ├── random_seed │ │ │ │ ├── secring.gpg │ │ │ │ └── trustdb.gpg │ │ ├── keys │ │ │ ├── .gpg-v21-migrated │ │ │ ├── private-keys-v1.d │ │ │ │ ├── 0BD83B491C590E2CF9710E75DFB474977AA80CB4.key │ │ │ │ └── 543A3A58E42A4026115A3FF05BE57748DF264557.key │ │ │ ├── pubring.gpg │ │ │ ├── pubring.gpg~ │ │ │ ├── random_seed │ │ │ ├── secring.gpg │ │ │ └── trustdb.gpg │ │ ├── msg_ctrlr_keys │ │ │ └── pubring.kbx │ │ ├── root_data_dir_test │ │ │ ├── data │ │ │ │ └── No Private Key in Ring │ │ │ │ │ └── databases │ │ │ │ │ ├── No Private Key in Ring.sqlite │ │ │ │ │ └── server_sync.sqlite │ │ │ ├── host_gpg_pubkey.gpg │ │ │ ├── keys │ │ │ │ ├── pubring.kbx │ │ │ │ └── trustdb.gpg │ │ │ └── log │ │ │ │ └── app.log │ │ ├── testdb.sqlite │ │ └── tor_data │ │ │ └── ServiceName │ ├── test_appmodule.py │ ├── test_metainfo.py │ └── test_settings.py ├── tornet │ ├── __init__.py │ ├── tests │ │ ├── __init__.py │ │ └── test_tornetcontroller.py │ ├── tornetcontroller.py │ └── tornetframe.py ├── torproxy │ ├── __init__.py │ ├── tests │ │ ├── __init__.py │ │ ├── test_torproxycontroller.py │ │ └── test_torproxyservice.py │ ├── torproxycontroller.py │ └── torproxyservice.py └── utilities │ ├── __init__.py │ ├── dirmaker.py │ ├── helpers.py │ ├── logger.py │ ├── observable.py │ ├── queueconsumer.py │ └── tests │ ├── __init__.py │ ├── test_dirmaker.py │ ├── test_helpers.py │ ├── test_observable.py │ └── test_queueconsumer.py ├── license ├── readme.md ├── requirements.txt └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | .idea/ 3 | .DS_Store 4 | scratch/ 5 | .coverage 6 | reports/ 7 | __pycache__/ 8 | *.egg-info/ 9 | 10 | 11 | -------------------------------------------------------------------------------- /disappeer/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/__init__.py -------------------------------------------------------------------------------- /disappeer/__main__.py: -------------------------------------------------------------------------------- 1 | """ 2 | disappeer.py 3 | 4 | Main app run module for the disappeer app. 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import tkinter 11 | from disappeer.constants import constants 12 | from disappeer.utilities import logger 13 | from disappeer.root import rootcontroller 14 | import sys 15 | from disappeer.utilities import dirmaker 16 | from disappeer.root import rootview 17 | from disappeer import settings 18 | from disappeer.models import gpgdatacontext 19 | from disappeer.models.db import databasefacade 20 | from disappeer.models import tordatacontext 21 | 22 | 23 | class App: 24 | def __init__(self): 25 | self.title = constants.title 26 | self.root = tkinter.Tk() 27 | 28 | self.dir_maker = dirmaker.DirMaker(settings.root_data_dir) 29 | self.config_logger() 30 | self.config_logo() 31 | self.gpg_datacontext = gpgdatacontext.GPGDataContext(settings.default_key_dir) 32 | self.database_facade = databasefacade.DatabaseFacade(self.gpg_datacontext.get_host_key_observer(), self.dir_maker.get_user_database_dir) 33 | self.tor_datacontext = tordatacontext.TorDataContext(self.dir_maker.get_user_tor_keys_dir) 34 | self.root_view = rootview.RootView(self.root) 35 | self.controller = rootcontroller.RootController(self.root, self.root_view, self.gpg_datacontext, self.database_facade, self.tor_datacontext) 36 | self.config_exit_protocol() 37 | 38 | def config_exit_protocol(self): 39 | self.root.protocol("WM_DELETE_WINDOW", self.controller.exit) 40 | 41 | def config_logger(self): 42 | log_file = settings.default_log_dir + 'app.log' 43 | self.log = logger.AppLogger(self.title, file=log_file).create() 44 | sys.excepthook = self.log.handle_uncaught_system_exception 45 | self.root.report_callback_exception = self.log.handle_uncaught_tkinter_exception 46 | 47 | def config_logo(self): 48 | if constants.display_images: 49 | # This works to add icon to all windows 50 | from disappeer.utilities import helpers 51 | image_path = helpers.get_images_dir_path() 52 | img = tkinter.PhotoImage(file=image_path + 'logo_icon.png') 53 | self.root.tk.call('wm', 'iconphoto', self.root._w, '-default', img) 54 | 55 | def run(self): 56 | try: 57 | self.root.mainloop() 58 | except KeyboardInterrupt: 59 | self.log.info("Keyboard interrupt called. Shutting down.") 60 | sys.exit() 61 | 62 | 63 | def main(): 64 | app = App() 65 | app.run() 66 | 67 | 68 | if __name__ == '__main__': 69 | main() 70 | -------------------------------------------------------------------------------- /disappeer/components/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/components/__init__.py -------------------------------------------------------------------------------- /disappeer/components/notifications.py: -------------------------------------------------------------------------------- 1 | """ 2 | notifications.py 3 | 4 | A notifications box component, subclass of tkinter LabelFrame. 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import tkinter 11 | from disappeer.constants import styling 12 | 13 | 14 | class NotificationsBox(tkinter.LabelFrame): 15 | """ 16 | A tkinter labelframe containing a textbox with styled print and append methods. 17 | """ 18 | 19 | def __init__(self, parent, title="Notifications"): 20 | tkinter.LabelFrame.__init__(self, parent, text=title, **styling.label_frame_args) 21 | self.rowconfigure(0, weight=1) 22 | self.columnconfigure(0, weight=1) 23 | self.config_textbox() 24 | 25 | def config_textbox(self): 26 | self.text_box = tkinter.Text(self, **styling.debug_text_area) 27 | self.text_box.grid(row=0, column=0, sticky=styling.sticky_all) 28 | 29 | def print_msg(self, msg, level='Debug'): 30 | """ 31 | Clear debug text box and insert msg. 32 | """ 33 | self.config_level(level) 34 | self.text_box.delete('1.0', 'end') 35 | self.text_box.insert('1.0', msg + "\n") 36 | 37 | def append_msg(self, msg, level='Debug'): 38 | """ 39 | Append msg to end of debug text box. Scroll to end of textbox. 40 | """ 41 | self.config_level(level) 42 | self.text_box.insert('end', msg + "\n") 43 | self.text_box.see('end') 44 | 45 | def get_text_area(self): 46 | """ 47 | :return: all current contents of text area 48 | """ 49 | result = self.text_box.get('1.0', 'end') 50 | return result 51 | 52 | def config_level(self, level): 53 | """ 54 | configure the text box to print a different color 55 | :param level: level determines color 56 | """ 57 | if level == 'Debug': 58 | self.text_box.configure(foreground='green') 59 | elif level == 'Info': 60 | self.text_box.configure(foreground='blue') 61 | else: 62 | self.text_box.configure(foreground='red') -------------------------------------------------------------------------------- /disappeer/console/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/console/__init__.py -------------------------------------------------------------------------------- /disappeer/console/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/console/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/constants/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/constants/__init__.py -------------------------------------------------------------------------------- /disappeer/constants/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/constants/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/executor/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/executor/__init__.py -------------------------------------------------------------------------------- /disappeer/executor/commands/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/executor/commands/__init__.py -------------------------------------------------------------------------------- /disappeer/executor/commands/abstractcommand.py: -------------------------------------------------------------------------------- 1 | """ 2 | abstractcommand.py 3 | 4 | Module for the AbstractCommand abstract base class for command objects 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import abc 11 | from disappeer.utilities.logger import log 12 | 13 | 14 | class AbstractCommand(metaclass=abc.ABCMeta): 15 | 16 | def __init__(self, receiver, **kwargs): 17 | self.receiver = receiver 18 | self.kwargs = kwargs 19 | self.validate() 20 | 21 | @property 22 | @abc.abstractproperty 23 | def name(self): 24 | raise NotImplementedError 25 | 26 | @property 27 | @abc.abstractproperty 28 | def valid_kwarg_keys(self): 29 | raise NotImplementedError 30 | 31 | @abc.abstractmethod 32 | def execute(self): 33 | raise NotImplementedError 34 | 35 | def validate(self): 36 | if not isinstance(self.valid_kwarg_keys, set): 37 | raise ValueError 38 | elif self.valid_kwarg_keys != self.kwargs.keys(): 39 | log.error("Key Error:\nValid kwarg keys: {}.\nGiven kwarg keys: {}".format(self.valid_kwarg_keys, self.kwargs.keys())) 40 | raise KeyError 41 | self.update_attrs_with_kwargs() 42 | 43 | def update_attrs_with_kwargs(self): 44 | self.__dict__.update((k, v) for k, v in self.kwargs.items()) 45 | 46 | 47 | -------------------------------------------------------------------------------- /disappeer/executor/commands/checksanitycommand.py: -------------------------------------------------------------------------------- 1 | """ 2 | checksanitycommand.py 3 | 4 | Module for command pattern CheckSanityCommand class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | 11 | from disappeer.constants import constants 12 | from disappeer.executor.commands import abstractcommand 13 | 14 | command_list = constants.command_list 15 | 16 | 17 | class CheckSanity(abstractcommand.AbstractCommand): 18 | 19 | def __init__(self, receiver, **kwargs): 20 | super().__init__(receiver, **kwargs) 21 | self.message = kwargs['message'] 22 | 23 | @property 24 | def name(self): 25 | return command_list.Check_Sanity 26 | 27 | @property 28 | def valid_kwarg_keys(self): 29 | return {'message'} 30 | 31 | def execute(self): 32 | self.receiver.log_message(self.message) 33 | -------------------------------------------------------------------------------- /disappeer/executor/commands/newcontactrequestclientresponsecommand.py: -------------------------------------------------------------------------------- 1 | """ 2 | newcontactrequestclientresponsecommand.py 3 | 4 | Module for the NewContactRequestClientResponseCommand class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.constants import constants 11 | from disappeer.executor.commands import abstractcommand 12 | 13 | command_list = constants.command_list 14 | 15 | 16 | class NewContactRequestClientResponseCommand(abstractcommand.AbstractCommand): 17 | 18 | def __init__(self, receiver, **kwargs): 19 | super().__init__(receiver, **kwargs) 20 | 21 | @property 22 | def name(self): 23 | return command_list.New_Contact_Req_Client_Res 24 | 25 | @property 26 | def valid_kwarg_keys(self): 27 | return {'payload'} 28 | 29 | def execute(self): 30 | self.receiver.execute(self.payload) 31 | -------------------------------------------------------------------------------- /disappeer/executor/commands/newcontactresponseclientresponsecommand.py: -------------------------------------------------------------------------------- 1 | """ 2 | newcontactresponseclientrescommand.py 3 | 4 | Module for command pattern concrete command newcontactresponseclientrescommand 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.constants import constants 11 | from disappeer.executor.commands import abstractcommand 12 | 13 | command_list = constants.command_list 14 | 15 | 16 | class NewContactResponseClientResponseCommand(abstractcommand.AbstractCommand): 17 | 18 | def __init__(self, receiver, **kwargs): 19 | super().__init__(receiver, **kwargs) 20 | 21 | @property 22 | def name(self): 23 | return command_list.New_Contact_Res_Client_Res 24 | 25 | @property 26 | def valid_kwarg_keys(self): 27 | return {'payload'} 28 | 29 | def execute(self): 30 | self.receiver.execute(self.payload) 31 | -------------------------------------------------------------------------------- /disappeer/executor/commands/newcontactresponsecommand.py: -------------------------------------------------------------------------------- 1 | """ 2 | newcontactresponsecommand.py 3 | 4 | Module for NewContactResponseCommand class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | 11 | from disappeer.constants import constants 12 | from disappeer.executor.commands import abstractcommand 13 | 14 | command_list = constants.command_list 15 | 16 | 17 | class NewContactResponseCommand(abstractcommand.AbstractCommand): 18 | 19 | def __init__(self, receiver, **kwargs): 20 | super().__init__(receiver, **kwargs) 21 | 22 | @property 23 | def name(self): 24 | return command_list.New_Contact_Res 25 | 26 | @property 27 | def valid_kwarg_keys(self): 28 | return {'payload'} 29 | 30 | def execute(self): 31 | self.receiver.execute(self.payload) 32 | 33 | -------------------------------------------------------------------------------- /disappeer/executor/commands/receivednewmessagecommand.py: -------------------------------------------------------------------------------- 1 | """ 2 | receivednewmessagecommand.py 3 | 4 | Module for ReceivedNewMessageCommand class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | 11 | from disappeer.constants import constants 12 | from disappeer.executor.commands import abstractcommand 13 | 14 | command_list = constants.command_list 15 | 16 | 17 | class ReceivedNewMessageCommand(abstractcommand.AbstractCommand): 18 | 19 | def __init__(self, receiver, **kwargs): 20 | super().__init__(receiver, **kwargs) 21 | 22 | @property 23 | def name(self): 24 | return command_list.Received_New_Message 25 | 26 | @property 27 | def valid_kwarg_keys(self): 28 | return {'payload'} 29 | 30 | def execute(self): 31 | self.receiver.execute(self.payload) 32 | -------------------------------------------------------------------------------- /disappeer/executor/commands/sendnewmessageclientresponsecommand.py: -------------------------------------------------------------------------------- 1 | """ 2 | sendnewmessageclientresponsecommand.py 3 | 4 | Module for SendNewMessageClientResponseCommand class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | 11 | from disappeer.constants import constants 12 | from disappeer.executor.commands import abstractcommand 13 | command_list = constants.command_list 14 | 15 | 16 | class SendNewMessageClientResponseCommand(abstractcommand.AbstractCommand): 17 | 18 | def __init__(self, receiver, **kwargs): 19 | super().__init__(receiver, **kwargs) 20 | 21 | @property 22 | def name(self): 23 | return command_list.Send_New_Message_Client_Res 24 | 25 | @property 26 | def valid_kwarg_keys(self): 27 | return {'payload'} 28 | 29 | def execute(self): 30 | self.receiver.execute(self.payload) 31 | 32 | -------------------------------------------------------------------------------- /disappeer/executor/commands/sendnewmessagecommand.py: -------------------------------------------------------------------------------- 1 | """ 2 | sendnewmessagecommand.py 3 | 4 | Module for SendNewMessageCommand class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.constants import constants 11 | from disappeer.executor.commands import abstractcommand 12 | 13 | command_list = constants.command_list 14 | 15 | 16 | class SendNewMessageCommand(abstractcommand.AbstractCommand): 17 | 18 | def __init__(self, receiver, **kwargs): 19 | super().__init__(receiver, **kwargs) 20 | 21 | @property 22 | def name(self): 23 | return command_list.Send_New_Message 24 | 25 | @property 26 | def valid_kwarg_keys(self): 27 | return {'payload'} 28 | 29 | def execute(self): 30 | self.receiver.execute(self.payload) 31 | 32 | -------------------------------------------------------------------------------- /disappeer/executor/commands/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/executor/commands/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/executor/commands/tests/test_checksanitycommand.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_checksanitycommand.py 3 | 4 | Test suite for command module check sanity command 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import MagicMock 12 | 13 | from disappeer.constants import constants 14 | from disappeer.executor import commands 15 | from disappeer.executor.commands import abstractcommand 16 | from disappeer.executor.commands import checksanitycommand 17 | from disappeer.executor.receivers import checksanityreceiver 18 | 19 | 20 | class TestImports(unittest.TestCase): 21 | 22 | def test_abstractcommand(self): 23 | self.assertEqual(abstractcommand, commands.abstractcommand) 24 | 25 | def test_constants(self): 26 | self.assertEqual(constants, checksanitycommand.constants) 27 | 28 | 29 | class TestCheckSanityCommand(unittest.TestCase): 30 | 31 | def setUp(self): 32 | self.receiver = MagicMock(spec=checksanityreceiver.CheckSanityReceiver) 33 | self.message = 'hello' 34 | self.kwargs = dict(message=self.message) 35 | self.x = checksanitycommand.CheckSanity(self.receiver, **self.kwargs) 36 | 37 | def test_instance(self): 38 | self.assertIsInstance(self.x, checksanitycommand.CheckSanity) 39 | self.assertIsInstance(self.x, abstractcommand.AbstractCommand) 40 | 41 | def test_name_attr(self): 42 | self.assertEqual(self.x.name, constants.command_list.Check_Sanity) 43 | 44 | def test_receiver_attr(self): 45 | self.assertEqual(self.x.receiver, self.receiver) 46 | 47 | def test_valid_kwarg_keys_set(self): 48 | target = {'message'} 49 | self.assertEqual(target, self.x.valid_kwarg_keys) 50 | 51 | def test_message_attr_set(self): 52 | self.assertEqual(self.x.message, self.message) 53 | 54 | def test_execute_calls_log_message_on_receiver(self): 55 | msg = 'hello' 56 | self.x.execute() 57 | self.receiver.log_message.assert_called_with(self.x.message) 58 | -------------------------------------------------------------------------------- /disappeer/executor/commands/tests/test_newcontactrequestclientresponsecommand.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_newcontactrequestclientresponsecommand.py 3 | 4 | Test suite for the newcontactrequestclientresponsecommand module and class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import MagicMock 12 | 13 | from disappeer.constants import constants 14 | from disappeer.executor.commands import abstractcommand 15 | from disappeer.executor.commands import newcontactrequestclientresponsecommand as command 16 | 17 | 18 | class TestNewContactResponseClientResponseCommand(unittest.TestCase): 19 | 20 | def setUp(self): 21 | self.receiver = MagicMock() 22 | self.payload = dict() 23 | self.kwargs = dict(payload=self.payload) 24 | self.x = command.NewContactRequestClientResponseCommand(self.receiver, **self.kwargs) 25 | 26 | def test_instance(self): 27 | self.assertIsInstance(self.x, command.NewContactRequestClientResponseCommand) 28 | self.assertIsInstance(self.x, abstractcommand.AbstractCommand) 29 | 30 | def test_name_attr(self): 31 | self.assertEqual(self.x.name, constants.command_list.New_Contact_Req_Client_Res) 32 | 33 | def test_receiver_attr(self): 34 | self.assertEqual(self.x.receiver, self.receiver) 35 | 36 | def test_valid_kwarg_keys_set(self): 37 | target = {'payload'} 38 | self.assertEqual(target, self.x.valid_kwarg_keys) 39 | 40 | def test_execute_calls_execute_on_receiver_with_payload_attr_as_arg(self): 41 | target = self.x.receiver = MagicMock() 42 | self.x.execute() 43 | target.execute.assert_called_with(self.x.payload) -------------------------------------------------------------------------------- /disappeer/executor/commands/tests/test_newcontactresponseclientresponsecommand.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_newcontactresponseclientrescommand.py 3 | 4 | Module for command pattern newcontactresponseclientrescommand 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import MagicMock 12 | 13 | from disappeer.constants import constants 14 | from disappeer.executor.commands import abstractcommand 15 | from disappeer.executor.commands import newcontactresponseclientresponsecommand as command 16 | from disappeer.executor.receivers import newcontactresponseclientresponsereceiver as receiver 17 | 18 | 19 | class TestNewContactResponseClientResponseCommand(unittest.TestCase): 20 | 21 | def setUp(self): 22 | self.receiver = MagicMock(spec=receiver.NewContactResponseClientResponseReceiver) 23 | self.payload = dict() 24 | self.kwargs = dict(payload=self.payload) 25 | self.x = command.NewContactResponseClientResponseCommand(self.receiver, **self.kwargs) 26 | 27 | def test_instance(self): 28 | self.assertIsInstance(self.x, command.NewContactResponseClientResponseCommand) 29 | self.assertIsInstance(self.x, abstractcommand.AbstractCommand) 30 | 31 | def test_name_attr(self): 32 | self.assertEqual(self.x.name, constants.command_list.New_Contact_Res_Client_Res) 33 | 34 | def test_receiver_attr(self): 35 | self.assertEqual(self.x.receiver, self.receiver) 36 | 37 | def test_valid_kwarg_keys_set(self): 38 | target = {'payload'} 39 | self.assertEqual(target, self.x.valid_kwarg_keys) 40 | 41 | def test_execute_calls_execute_on_receiver_with_payload_attr_as_arg(self): 42 | target = self.x.receiver = MagicMock() 43 | self.x.execute() 44 | target.execute.assert_called_with(self.x.payload) 45 | -------------------------------------------------------------------------------- /disappeer/executor/commands/tests/test_newcontactresponsecommand.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_newcontactresponsecommand.py 3 | 4 | Test suite for NewContactResponseCommand object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import MagicMock 12 | 13 | from disappeer.constants import constants 14 | from disappeer.executor.commands import abstractcommand 15 | from disappeer.executor.commands import newcontactresponsecommand as command 16 | 17 | 18 | class TestNewContactResponseCommand(unittest.TestCase): 19 | 20 | def setUp(self): 21 | self.receiver = MagicMock() 22 | self.payload = dict() 23 | self.kwargs = dict(payload=self.payload) 24 | self.x = command.NewContactResponseCommand(self.receiver, **self.kwargs) 25 | 26 | def test_instance(self): 27 | self.assertIsInstance(self.x, command.NewContactResponseCommand) 28 | self.assertIsInstance(self.x, abstractcommand.AbstractCommand) 29 | 30 | def test_name_attr(self): 31 | self.assertEqual(self.x.name, constants.command_list.New_Contact_Res) 32 | 33 | def test_receiver_attr(self): 34 | self.assertEqual(self.x.receiver, self.receiver) 35 | 36 | def test_valid_kwarg_keys_set(self): 37 | target = {'payload'} 38 | self.assertEqual(target, self.x.valid_kwarg_keys) 39 | 40 | def test_execute_calls_execute_on_receiver_with_payload_attr_as_arg(self): 41 | target = self.x.receiver = MagicMock() 42 | self.x.execute() 43 | target.execute.assert_called_with(self.x.payload) -------------------------------------------------------------------------------- /disappeer/executor/commands/tests/test_receivednewmessagecommand.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_receivednewmessagecommand.py 3 | 4 | Test suite for ReceivedNewMessageCommand module and class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import MagicMock 12 | 13 | from disappeer.constants import constants 14 | from disappeer.executor.commands import abstractcommand 15 | from disappeer.executor.commands import receivednewmessagecommand as command 16 | 17 | 18 | class TestReceivedNewMessageCommand(unittest.TestCase): 19 | 20 | def setUp(self): 21 | self.receiver = MagicMock() 22 | self.payload = dict() 23 | self.kwargs = dict(payload=self.payload) 24 | self.x = command.ReceivedNewMessageCommand(self.receiver, **self.kwargs) 25 | 26 | def test_instance(self): 27 | self.assertIsInstance(self.x, command.ReceivedNewMessageCommand) 28 | self.assertIsInstance(self.x, abstractcommand.AbstractCommand) 29 | 30 | def test_name_attr(self): 31 | self.assertEqual(self.x.name, constants.command_list.Received_New_Message) 32 | 33 | def test_receiver_attr(self): 34 | self.assertEqual(self.x.receiver, self.receiver) 35 | 36 | def test_valid_kwarg_keys_set(self): 37 | target = {'payload'} 38 | self.assertEqual(target, self.x.valid_kwarg_keys) 39 | 40 | def test_execute_calls_execute_on_receiver_with_payload_attr_as_arg(self): 41 | target = self.x.receiver = MagicMock() 42 | self.x.execute() 43 | target.execute.assert_called_with(self.x.payload) 44 | 45 | -------------------------------------------------------------------------------- /disappeer/executor/commands/tests/test_sendnewmessageclientresponsecommand.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_sendnewmessageclientresponsecommand.py 3 | 4 | Test suite for HandleSendNewMessageClientResponseCommand class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | 11 | import unittest 12 | from unittest.mock import MagicMock 13 | from disappeer.constants import constants 14 | from disappeer.executor.commands import abstractcommand 15 | from disappeer.executor.commands import sendnewmessageclientresponsecommand as command 16 | 17 | 18 | class TestImports(unittest.TestCase): 19 | def test_constants(self): 20 | self.assertEqual(constants, command.constants) 21 | 22 | def test_abstractcommand(self): 23 | self.assertEqual(abstractcommand, command.abstractcommand) 24 | 25 | 26 | class TestSendNewMessageClientResponseCommand(unittest.TestCase): 27 | 28 | def setUp(self): 29 | self.receiver = MagicMock() 30 | self.payload = dict() 31 | self.kwargs = dict(payload=self.payload) 32 | self.x = command.SendNewMessageClientResponseCommand(self.receiver, **self.kwargs) 33 | 34 | def test_instance(self): 35 | self.assertIsInstance(self.x, command.SendNewMessageClientResponseCommand) 36 | self.assertIsInstance(self.x, abstractcommand.AbstractCommand) 37 | 38 | def test_name_attr(self): 39 | self.assertEqual(self.x.name, constants.command_list.Send_New_Message_Client_Res) 40 | 41 | def test_receiver_attr(self): 42 | self.assertEqual(self.x.receiver, self.receiver) 43 | 44 | def test_valid_kwarg_keys_set(self): 45 | target = {'payload'} 46 | self.assertEqual(target, self.x.valid_kwarg_keys) 47 | 48 | def test_execute_calls_execute_on_receiver_with_payload_attr_as_arg(self): 49 | target = self.x.receiver = MagicMock() 50 | self.x.execute() 51 | target.execute.assert_called_with(self.x.payload) 52 | -------------------------------------------------------------------------------- /disappeer/executor/commands/tests/test_sendnewmessagecommand.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_sendnewmessagecommand.py 3 | 4 | Test suite for SendNewMessageCommand module and class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import MagicMock 12 | 13 | from disappeer.constants import constants 14 | from disappeer.executor.commands import abstractcommand 15 | from disappeer.executor.commands import sendnewmessagecommand as command 16 | 17 | 18 | class TestSendNewMessageCommand(unittest.TestCase): 19 | 20 | def setUp(self): 21 | self.receiver = MagicMock() 22 | self.payload = dict() 23 | self.kwargs = dict(payload=self.payload) 24 | self.x = command.SendNewMessageCommand(self.receiver, **self.kwargs) 25 | 26 | def test_instance(self): 27 | self.assertIsInstance(self.x, command.SendNewMessageCommand) 28 | self.assertIsInstance(self.x, abstractcommand.AbstractCommand) 29 | 30 | def test_name_attr(self): 31 | self.assertEqual(self.x.name, constants.command_list.Send_New_Message) 32 | 33 | def test_receiver_attr(self): 34 | self.assertEqual(self.x.receiver, self.receiver) 35 | 36 | def test_valid_kwarg_keys_set(self): 37 | target = {'payload'} 38 | self.assertEqual(target, self.x.valid_kwarg_keys) 39 | 40 | def test_execute_calls_execute_on_receiver_with_payload_attr_as_arg(self): 41 | target = self.x.receiver = MagicMock() 42 | self.x.execute() 43 | target.execute.assert_called_with(self.x.payload) -------------------------------------------------------------------------------- /disappeer/executor/controllermediator.py: -------------------------------------------------------------------------------- 1 | """ 2 | controllermediator.py 3 | 4 | Module for ControllerMediator mediator object for controllers 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | 11 | class ControllerMediator: 12 | 13 | def __init__(self, 14 | database_facade, 15 | gpg_data_context, 16 | tor_datacontext, 17 | requests_controller, 18 | message_controller, 19 | console_controller, 20 | root_params): 21 | self.database_facade = database_facade 22 | self.gpg_datacontext = gpg_data_context 23 | self.tor_datacontext = tor_datacontext 24 | self.requests_controller = requests_controller 25 | self.message_controller = message_controller 26 | self.console_controller = console_controller 27 | self.root_params = root_params 28 | 29 | -------------------------------------------------------------------------------- /disappeer/executor/invoker.py: -------------------------------------------------------------------------------- 1 | """ 2 | invoker.py 3 | 4 | Module for command pattern Invoker object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | 11 | class Invoker: 12 | 13 | @classmethod 14 | def execute(cls, command): 15 | command.execute() 16 | -------------------------------------------------------------------------------- /disappeer/executor/receivers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/executor/receivers/__init__.py -------------------------------------------------------------------------------- /disappeer/executor/receivers/abstractreceiver.py: -------------------------------------------------------------------------------- 1 | """ 2 | abstractreceiver.py 3 | 4 | Module for command pattern AbstractReceiver class object and module 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import abc 11 | from disappeer.utilities.logger import log 12 | 13 | 14 | class AbstractReceiver(metaclass=abc.ABCMeta): 15 | 16 | def __init__(self, **kwargs): 17 | self.kwargs = kwargs 18 | self.validate() 19 | 20 | @property 21 | @abc.abstractmethod 22 | def name(self): 23 | raise NotImplementedError 24 | 25 | @property 26 | @abc.abstractmethod 27 | def valid_kwarg_keys(self): 28 | raise NotImplementedError 29 | 30 | @abc.abstractmethod 31 | def execute(self, *args, **kwargs): 32 | raise NotImplementedError 33 | 34 | def validate(self): 35 | if not isinstance(self.valid_kwarg_keys, set): 36 | log.error("Valid kwarg keys must be a set.") 37 | raise ValueError 38 | if self.valid_kwarg_keys != self.kwargs.keys(): 39 | log.error("Key Error: Invalid keys in receiver object.\nValid kwarg keys: {}.\nGiven kwarg keys: {}".format(self.valid_kwarg_keys, self.kwargs.keys())) 40 | raise KeyError 41 | self.update_attrs_with_kwargs() 42 | 43 | def update_attrs_with_kwargs(self): 44 | self.__dict__.update((k, v) for k, v in self.kwargs.items()) -------------------------------------------------------------------------------- /disappeer/executor/receivers/checksanityreceiver.py: -------------------------------------------------------------------------------- 1 | """ 2 | checksanityreceiver.py 3 | 4 | Module for command pattern check sanity receiver object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.constants import constants 11 | from disappeer.executor.receivers import abstractreceiver 12 | from disappeer.utilities.logger import log 13 | 14 | command_list = constants.command_list 15 | 16 | 17 | class CheckSanityReceiver(abstractreceiver.AbstractReceiver): 18 | 19 | def __init__(self, **kwargs): 20 | super().__init__(**kwargs) 21 | 22 | @property 23 | def name(self): 24 | suffix = 'Receiver' 25 | return command_list.Check_Sanity + suffix 26 | 27 | @property 28 | def valid_kwarg_keys(self): 29 | return set() 30 | 31 | def execute(self): 32 | pass 33 | 34 | def log_message(self, message): 35 | log.debug("Check Sanity Receiver: {}.".format(message)) 36 | -------------------------------------------------------------------------------- /disappeer/executor/receivers/newcontactrequestclientresponsereceiver.py: -------------------------------------------------------------------------------- 1 | """ 2 | newcontactrequestclientresponsereceiver.py 3 | 4 | Module for NewContactRequestClientResponseReceiver class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.constants import constants 11 | from disappeer.executor.receivers import abstractreceiver 12 | from disappeer.gpg.helpers import gpgpubkeyvalidator 13 | 14 | from disappeer.utilities.logger import log 15 | 16 | command_list = constants.command_list 17 | 18 | 19 | class NewContactRequestClientResponseReceiver(abstractreceiver.AbstractReceiver): 20 | 21 | kwarg_keys = {'database_facade', 22 | 'requests_controller'} 23 | 24 | def __init__(self, **kwargs): 25 | super().__init__(**kwargs) 26 | 27 | @property 28 | def name(self): 29 | suffix = '_Receiver' 30 | return command_list.New_Contact_Req_Client_Res + suffix 31 | 32 | @property 33 | def valid_kwarg_keys(self): 34 | return self.kwarg_keys 35 | 36 | def execute(self, payload): 37 | if not self.is_nonce_valid(payload): 38 | # TODO: Should we also alert user with popup? 39 | log.warning("Invalid contact request response nonce from remote peer.") 40 | return False 41 | 42 | gpg_pub_key = self.get_gpg_pubkey_from_payload(payload) 43 | validator = self.validate_pubkey(gpg_pub_key) 44 | if not validator.valid: 45 | # TODO: Should we also alert user with popup? 46 | log.warning("Invalid contact request response pub_key from remote peer.") 47 | return False 48 | else: 49 | payload['fingerprint'] = validator.key_dict['fingerprint'] 50 | self.database_facade.insert_pending_contact_response(payload) 51 | self.requests_controller.update_sent_requests_treeview() 52 | 53 | success_msg = 'Contact Request was received by peer.' 54 | self.requests_controller.launch_user_alert(success_msg) 55 | 56 | def is_nonce_valid(self, payload): 57 | if payload['nonce_valid']: 58 | return True 59 | else: 60 | return False 61 | 62 | def get_gpg_pubkey_from_payload(self, payload): 63 | pubkey = payload['result']['gpg_pub_key'] 64 | return pubkey 65 | 66 | def validate_pubkey(self, pubkey_string): 67 | validator = gpgpubkeyvalidator.GPGPubKeyValidator(pubkey_string) 68 | return validator 69 | 70 | -------------------------------------------------------------------------------- /disappeer/executor/receivers/newcontactresponseclientresponsereceiver.py: -------------------------------------------------------------------------------- 1 | """ 2 | newcontactresponseclientresreceiver.py 3 | 4 | Module for command pattern receiver object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.constants import constants 11 | from disappeer.executor.receivers import abstractreceiver 12 | from disappeer.utilities.logger import log 13 | 14 | command_list = constants.command_list 15 | 16 | 17 | class NewContactResponseClientResponseReceiver(abstractreceiver.AbstractReceiver): 18 | 19 | kwarg_keys = {'database_facade', 20 | 'gpg_datacontext', 21 | 'requests_controller'} 22 | 23 | def __init__(self, **kwargs): 24 | super().__init__(**kwargs) 25 | 26 | @property 27 | def name(self): 28 | suffix = 'Receiver' 29 | return command_list.New_Contact_Res_Client_Res + suffix 30 | 31 | @property 32 | def valid_kwarg_keys(self): 33 | return self.kwarg_keys 34 | 35 | def execute(self, payload): 36 | if not self.is_nonce_valid(payload): 37 | # TODO: alert user with popup? 38 | log.warning("Invalid contact request response nonce from remote peer.") 39 | return False 40 | 41 | gpg_pub_key = self.fetch_contact_request_pubkey_by_nonce(payload) 42 | if gpg_pub_key is None: 43 | # TODO: alert user with popup? 44 | log.warning("GPG Pubkey Not found in database for request response nonce") 45 | return False 46 | 47 | self.import_gpg_pub_key_to_key_ring(gpg_pub_key) 48 | self.delete_contact_request_by_gpg_pubkey(gpg_pub_key) 49 | self.update_received_requests_treeview() 50 | 51 | success_msg = 'Contact Response was received by peer.' 52 | self.requests_controller.launch_user_alert(success_msg) 53 | 54 | def is_nonce_valid(self, payload): 55 | if payload['nonce_valid']: 56 | return True 57 | else: 58 | return False 59 | 60 | def fetch_contact_request_pubkey_by_nonce(self, payload): 61 | nonce = payload['request_nonce'] 62 | result = self.database_facade.fetch_contact_request_pub_key_by_nonce(nonce) 63 | return result 64 | 65 | def import_gpg_pub_key_to_key_ring(self, pub_key_string): 66 | self.gpg_datacontext.import_gpg_pub_key_to_key_ring(pub_key_string) 67 | self.gpg_datacontext.set_key_list() 68 | 69 | def delete_contact_request_by_gpg_pubkey(self, pub_key_string): 70 | self.database_facade.delete_contact_request_where_x_is_y('gpg_pub_key', pub_key_string) 71 | 72 | def update_received_requests_treeview(self): 73 | self.requests_controller.update_received_requests_treeview() 74 | 75 | -------------------------------------------------------------------------------- /disappeer/executor/receivers/sendnewmessageclientresponsereceiver.py: -------------------------------------------------------------------------------- 1 | """ 2 | sendnewmessageclientresponsereceiver.py 3 | 4 | Module for HandleSendNewMessageClientResponseReceiver class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.constants import constants 11 | from disappeer.executor.receivers import abstractreceiver 12 | from disappeer.utilities.logger import log 13 | 14 | command_list = constants.command_list 15 | 16 | 17 | class SendNewMessageClientResponseReceiver(abstractreceiver.AbstractReceiver): 18 | 19 | kwarg_keys = {'database_facade', 20 | 'message_controller'} 21 | 22 | def __init__(self, **kwargs): 23 | super().__init__(**kwargs) 24 | 25 | @property 26 | def name(self): 27 | suffix = '_Receiver' 28 | return command_list.Send_New_Message_Client_Res + suffix 29 | 30 | @property 31 | def valid_kwarg_keys(self): 32 | return self.kwarg_keys 33 | 34 | def execute(self, payload): 35 | if not self.is_nonce_valid(payload): 36 | # TODO: alert user with popup? 37 | msg = "Major error, client found nonce error, but did not return as error" 38 | log.error(msg) 39 | return False 40 | 41 | self.insert_sent_message_from_payload_argspace_payload_dict(payload) 42 | self.update_sent_messages_treeview() 43 | 44 | success_message = 'Message successfully received by peer.' 45 | self.message_controller.launch_user_alert(success_message) 46 | 47 | def is_nonce_valid(self, payload): 48 | if payload['nonce_valid']: 49 | return True 50 | else: 51 | return False 52 | 53 | def insert_sent_message_from_payload_argspace_payload_dict(self, payload): 54 | argnamespace = payload['argnamespace'] 55 | payload_dict = argnamespace.payload_dict 56 | self.database_facade.insert_sent_message(payload_dict) 57 | 58 | def update_sent_messages_treeview(self): 59 | self.message_controller.update_sent_messages_treeview() 60 | -------------------------------------------------------------------------------- /disappeer/executor/receivers/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/executor/receivers/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/executor/receivers/tests/test_checksanityreceiver.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_checksanityreceiver.py 3 | 4 | Test suite for command pattern check sanity receiver module and class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | 12 | from disappeer.constants import constants 13 | from disappeer.executor.receivers import abstractreceiver 14 | from disappeer.executor.receivers import checksanityreceiver 15 | 16 | 17 | class TestImports(unittest.TestCase): 18 | 19 | def test_abstractreceiver(self): 20 | self.assertEqual(abstractreceiver, checksanityreceiver.abstractreceiver) 21 | 22 | def test_constants(self): 23 | self.assertEqual(constants, checksanityreceiver.constants) 24 | 25 | 26 | class TestCheckSanityReceiver(unittest.TestCase): 27 | 28 | def setUp(self): 29 | self.msg = 'hello' 30 | self.kwargs = dict(message='hello') 31 | self.x = checksanityreceiver.CheckSanityReceiver() 32 | 33 | def test_Wtf(self): 34 | pass 35 | 36 | def test_instance(self): 37 | self.assertIsInstance(self.x, checksanityreceiver.CheckSanityReceiver) 38 | self.assertIsInstance(self.x, abstractreceiver.AbstractReceiver) 39 | 40 | def test_name_property_set(self): 41 | name = constants.command_list.Check_Sanity + 'Receiver' 42 | self.assertEqual(self.x.name, name) 43 | 44 | def test_valid_kwarg_keys_set(self): 45 | target = set() 46 | self.assertEqual(target, self.x.valid_kwarg_keys) 47 | 48 | def test_log_message(self): 49 | self.x.log_message(self.msg) 50 | -------------------------------------------------------------------------------- /disappeer/executor/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/executor/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/executor/tests/test_controllermediator.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_controllermediator.py 3 | 4 | Test suite for the ControllerMediator module and class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import MagicMock 12 | import executor.controllermediator as controllermediator 13 | 14 | 15 | class TestClassBasics(unittest.TestCase): 16 | 17 | def setUp(self): 18 | self.database_facade = MagicMock() 19 | self.gpg_datacontext = MagicMock() 20 | self.tor_datacontext = MagicMock() 21 | self.requests_controller = MagicMock() 22 | self.message_controller = MagicMock() 23 | self.console_controller = MagicMock() 24 | self.root_params = MagicMock() 25 | self.x = controllermediator.ControllerMediator(self.database_facade, 26 | self.gpg_datacontext, 27 | self.tor_datacontext, 28 | self.requests_controller, 29 | self.message_controller, 30 | self.console_controller, 31 | self.root_params) 32 | 33 | def test_instance(self): 34 | self.assertIsInstance(self.x, controllermediator.ControllerMediator) 35 | 36 | def test_attributes_set(self): 37 | self.assertEqual(self.x.database_facade, self.database_facade) 38 | self.assertEqual(self.x.gpg_datacontext, self.gpg_datacontext) 39 | self.assertEqual(self.x.tor_datacontext, self.tor_datacontext) 40 | self.assertEqual(self.x.requests_controller, self.requests_controller) 41 | self.assertEqual(self.x.message_controller, self.message_controller) 42 | self.assertEqual(self.x.console_controller, self.console_controller) 43 | self.assertEqual(self.x.root_params, self.root_params) 44 | 45 | -------------------------------------------------------------------------------- /disappeer/executor/tests/test_invoker.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_invoker.py 3 | 4 | Test suite for command pattern invoker object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import MagicMock 12 | import executor.invoker as invoker 13 | 14 | 15 | class TestClassBasics(unittest.TestCase): 16 | 17 | def setUp(self): 18 | self.x = invoker.Invoker() 19 | 20 | def test_instance(self): 21 | self.assertIsInstance(self.x, invoker.Invoker) 22 | 23 | def test_invoker_has_class_execute_method_calls_execute_on_arg(self): 24 | cmd = MagicMock() 25 | invoker.Invoker.execute(cmd) 26 | cmd.execute.assert_called_with() 27 | -------------------------------------------------------------------------------- /disappeer/gpg/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/gpg/__init__.py -------------------------------------------------------------------------------- /disappeer/gpg/agents/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/gpg/agents/__init__.py -------------------------------------------------------------------------------- /disappeer/gpg/agents/decrypter.py: -------------------------------------------------------------------------------- 1 | """ 2 | decrypter.py 3 | 4 | Module for Decrypter gpg agent class 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.gpg.agents import gpgagent 11 | 12 | 13 | class Decrypter(gpgagent.GPGAgent): 14 | 15 | def __init__(self, key_dir): 16 | super().__init__(key_dir) 17 | 18 | def execute(self, ciphertext, passphrase): 19 | result = self.gpg.decrypt(ciphertext, passphrase=passphrase) 20 | return result 21 | -------------------------------------------------------------------------------- /disappeer/gpg/agents/detachedverifier.py: -------------------------------------------------------------------------------- 1 | """ 2 | detachedverifier.py 3 | 4 | Module for DetachedVerifier class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.gpg.agents import gpgagent 11 | 12 | 13 | class DetachedVerifier(gpgagent.GPGAgent): 14 | 15 | def __init__(self, keydir): 16 | super().__init__(keydir) 17 | 18 | def execute(self, path_to_sig_file, data_bytestring): 19 | result = self.gpg.verify_data(path_to_sig_file, data_bytestring) 20 | return result 21 | 22 | -------------------------------------------------------------------------------- /disappeer/gpg/agents/encrypter.py: -------------------------------------------------------------------------------- 1 | """ 2 | encrypter.py 3 | 4 | Module for the Encrypter class gpg agent. 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.gpg.agents import gpgagent 11 | 12 | 13 | class Encrypter(gpgagent.GPGAgent): 14 | 15 | def __init__(self, key_dir): 16 | super().__init__(key_dir) 17 | 18 | def execute(self, plaintext, fingerprint): 19 | result = self.gpg.encrypt(plaintext, fingerprint, always_trust=True) 20 | return result 21 | 22 | -------------------------------------------------------------------------------- /disappeer/gpg/agents/gpgagent.py: -------------------------------------------------------------------------------- 1 | """ 2 | gpgagent.py 3 | 4 | Module for GPGAgent base class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import gnupg 11 | 12 | 13 | class GPGAgent: 14 | 15 | def __init__(self, key_dir): 16 | self.home = key_dir 17 | self.gpg = self.get_gpg_obj() 18 | 19 | def get_gpg_obj(self): 20 | """Create a new gpg obj at self,home and return it""" 21 | gpg_obj = gnupg.GPG(gnupghome=self.home) 22 | gpg_obj.encoding = 'utf-8' 23 | return gpg_obj 24 | 25 | def set(self, key_dir): 26 | self.home = key_dir 27 | self.gpg = self.get_gpg_obj() -------------------------------------------------------------------------------- /disappeer/gpg/agents/gpgclient.py: -------------------------------------------------------------------------------- 1 | """ 2 | gpgclient.py 3 | 4 | Module for GPGClient class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.gpg.agents import keyring 11 | from disappeer.gpg.helpers import keyfinder 12 | from disappeer.gpg.agents import encrypter 13 | from disappeer.gpg.agents import decrypter 14 | from disappeer.gpg.agents import signer 15 | from disappeer.gpg.agents import verifier 16 | 17 | 18 | class GPGClient: 19 | 20 | def __init__(self, key_dir): 21 | self.key_dir = key_dir 22 | self.key_ring = keyring.KeyRing(self.key_dir) 23 | self.key_finder = keyfinder.KeyFinder(self.key_ring) 24 | 25 | def set(self, new_key_dir): 26 | self.key_dir = new_key_dir 27 | self.key_ring.set(new_key_dir) 28 | 29 | def encrypt(self, plaintext, keyid): 30 | fingerprint = self.key_finder.get_fingerprint_by_keyid(keyid) 31 | if fingerprint is None: 32 | return None 33 | else: 34 | agent = encrypter.Encrypter(self.key_dir) 35 | result = agent.execute(plaintext, fingerprint) 36 | return result 37 | 38 | def decrypt(self, ciphertext, passphrase): 39 | agent = decrypter.Decrypter(self.key_dir) 40 | result = agent.execute(ciphertext, passphrase) 41 | return result 42 | 43 | def export_key(self, keyid): 44 | result = self.key_ring.export_key(keyid) 45 | return result 46 | 47 | def import_key(self, pub_key): 48 | result = self.key_ring.import_key(pub_key) 49 | return result 50 | 51 | def sign(self, message, keyid, passphrase, detach=False): 52 | agent = signer.Signer(self.key_dir) 53 | result = agent.execute(message, keyid, passphrase, detach=detach) 54 | return result 55 | 56 | def verify(self, message): 57 | agent = verifier.Verifier(self.key_dir) 58 | result = agent.execute(message) 59 | return result 60 | -------------------------------------------------------------------------------- /disappeer/gpg/agents/keycreator.py: -------------------------------------------------------------------------------- 1 | """ 2 | keycreator.py 3 | 4 | KeyCreator GPG Agent module and class 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.constants import constants 11 | from disappeer.gpg.agents import gpgagent 12 | import threading 13 | 14 | command_list = constants.command_list 15 | 16 | 17 | class KeyCreator(gpgagent.GPGAgent): 18 | 19 | def __init__(self, keydir, queue): 20 | super().__init__(keydir) 21 | self.queue = queue 22 | 23 | def execute(self, key_input_dict): 24 | t = threading.Thread(name=command_list.Create_New_Key, 25 | target=self._create_new_key_worker, 26 | args=(key_input_dict,)) 27 | t.start() 28 | 29 | def _create_new_key_worker(self, key_input_dict): 30 | input_data = self.gpg.gen_key_input(**key_input_dict) 31 | result = self.gpg.gen_key(input_data) 32 | desc = command_list.Create_New_Key 33 | payload = {"desc": desc, "result": result} 34 | self.queue.put(payload) 35 | -------------------------------------------------------------------------------- /disappeer/gpg/agents/keydeleter.py: -------------------------------------------------------------------------------- 1 | """ 2 | keydeleter.py 3 | 4 | Module for KeyDeleter class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.gpg.agents import gpgagent 11 | 12 | 13 | class KeyDeleter(gpgagent.GPGAgent): 14 | 15 | def __init__(self, keydir): 16 | super().__init__(keydir) 17 | 18 | def execute(self, key_fingerprint_list): 19 | # TODO: investigate: Delete secret key fails without passphrase 20 | # - True flag allows to delete secret key 21 | # - but python-gnupg does not provide interface for passphrase 22 | # prep = self.gpg.delete_keys(key_fingerprint_list, True) 23 | result = self.gpg.delete_keys(key_fingerprint_list) 24 | return result 25 | -------------------------------------------------------------------------------- /disappeer/gpg/agents/keyring.py: -------------------------------------------------------------------------------- 1 | """ 2 | keyring.py 3 | 4 | Module for the GPG KeyRing class. 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.gpg.agents import gpgagent 11 | 12 | 13 | class KeyRing(gpgagent.GPGAgent): 14 | 15 | def __init__(self, key_dir): 16 | super().__init__(key_dir) 17 | 18 | def get_raw_key_list(self, secret=False): 19 | result = self.gpg.list_keys(secret=secret) 20 | return result 21 | 22 | def export_key(self, identifier): 23 | result = self.gpg.export_keys(identifier) 24 | return result 25 | 26 | def import_key(self, pub_key): 27 | result = self.gpg.import_keys(pub_key) 28 | return result 29 | -------------------------------------------------------------------------------- /disappeer/gpg/agents/signer.py: -------------------------------------------------------------------------------- 1 | """ 2 | signer.py 3 | 4 | Module for Signer gpg agent class 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.gpg.agents import gpgagent 11 | 12 | 13 | class Signer(gpgagent.GPGAgent): 14 | 15 | def __init__(self, key_dir): 16 | super().__init__(key_dir) 17 | 18 | def execute(self, message, fingerprint, passphrase, detach=False): 19 | result = self.gpg.sign(message, 20 | keyid=fingerprint, 21 | passphrase=passphrase, 22 | detach=detach) 23 | return result 24 | -------------------------------------------------------------------------------- /disappeer/gpg/agents/verifier.py: -------------------------------------------------------------------------------- 1 | """ 2 | verifier.py 3 | 4 | Module for the Verifier gpg agent class 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.gpg.agents import gpgagent 11 | 12 | 13 | class Verifier(gpgagent.GPGAgent): 14 | 15 | def __init__(self, keydir): 16 | super().__init__(keydir) 17 | 18 | def execute(self, message): 19 | result = self.gpg.verify(message) 20 | return result 21 | 22 | -------------------------------------------------------------------------------- /disappeer/gpg/helpers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/gpg/helpers/__init__.py -------------------------------------------------------------------------------- /disappeer/gpg/helpers/gpgpubkeyvalidator.py: -------------------------------------------------------------------------------- 1 | """ 2 | gpgpubkeyvalidator.py 3 | 4 | Module for GPGPubKeyValidator class object. 5 | Object takes gpg pubkey as input, imports to tempdir, validates with keyring 6 | 7 | Copyright (C) 2018 Disappeer Labs 8 | License: GPLv3 9 | """ 10 | 11 | from disappeer.gpg.agents import keyring 12 | import tempfile 13 | 14 | 15 | class GPGPubKeyValidator: 16 | 17 | def __init__(self, gpg_pub_key): 18 | self.target_pubkey = gpg_pub_key 19 | self.temp_dir = self.create_temp_dir() 20 | self.temp_dir_name = self.temp_dir.name 21 | self.key_ring = keyring.KeyRing(self.temp_dir_name) 22 | self.result = None 23 | self.valid = None 24 | self.key_dict = None 25 | self.validate() 26 | 27 | def validate(self): 28 | self.import_pubkey_to_keyring() 29 | if self.result.count == 1: 30 | self.valid = True 31 | self.key_dict = self.key_ring.get_raw_key_list()[0] 32 | else: 33 | self.valid = False 34 | 35 | def import_pubkey_to_keyring(self): 36 | self.result = self.key_ring.import_key(self.target_pubkey) 37 | return self.result 38 | 39 | def create_temp_dir(self): 40 | temp_dir = tempfile.TemporaryDirectory() 41 | return temp_dir 42 | 43 | def close_temp_dir(self): 44 | self.temp_dir.cleanup() 45 | 46 | def __del__(self): 47 | try: 48 | self.close_temp_dir() 49 | except (AttributeError, FileNotFoundError): 50 | pass 51 | -------------------------------------------------------------------------------- /disappeer/gpg/helpers/hostkeyobservable.py: -------------------------------------------------------------------------------- 1 | """ 2 | hostkeyobservable.py 3 | 4 | Module for HostKeyObservable class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.utilities import observable 11 | from disappeer.gpg.helpers import keylistformatter 12 | from disappeer import settings 13 | 14 | 15 | class HostKeyObservable(observable.Observable): 16 | """ 17 | Adapted observable to keep track of key list, 18 | while keeping it formatted. 19 | """ 20 | 21 | def __init__(self, keyring): 22 | super().__init__() 23 | self.key_ring = keyring 24 | self.key_formatter = keylistformatter.KeyListFormatter() 25 | self.key_list = self._run_ops() 26 | 27 | def get(self): 28 | if len(self.key_list) == 0: 29 | return "No Private Key in Ring" 30 | else: 31 | return self.key_list[0] 32 | 33 | def set(self, param): 34 | self.key_list = self._run_ops() 35 | self.run_callbacks() 36 | self.write_pub_key_to_file() 37 | 38 | def _run_ops(self): 39 | raw_list = self.key_ring.get_raw_key_list(secret=True)[:1] 40 | result = self.key_formatter.format(raw_list) 41 | return result 42 | 43 | def get_pub_key(self): 44 | current_key_id = self.get().split(', ').pop() 45 | result = self.key_ring.export_key(current_key_id) 46 | return result 47 | 48 | def write_pub_key_to_file(self): 49 | text = self.get_pub_key() 50 | with open(settings.gpg_host_pubkey, 'w') as f: 51 | f.write(text) 52 | -------------------------------------------------------------------------------- /disappeer/gpg/helpers/keyfinder.py: -------------------------------------------------------------------------------- 1 | """ 2 | keyfinder.py 3 | 4 | Module for KeyFinder class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | 11 | class KeyFinder: 12 | 13 | def __init__(self, key_ring): 14 | self.key_ring = key_ring 15 | 16 | def find(self, identifier): 17 | key_list = self.key_ring.get_raw_key_list() 18 | search = self._search_list(key_list, identifier) 19 | return search 20 | 21 | def find_secret(self, identifier): 22 | key_list = self.key_ring.get_raw_key_list(secret=True) 23 | search = self._search_list(key_list, identifier) 24 | return search 25 | 26 | def _search_list(self, key_list, identifier): 27 | for key in key_list: 28 | if key['fingerprint'] == identifier: 29 | return key 30 | elif key['keyid'] == identifier: 31 | return key 32 | return None 33 | 34 | def get_fingerprint_by_keyid(self, keyid): 35 | key = self.find(keyid) 36 | if key is None: 37 | return None 38 | else: 39 | fingerprint = key['fingerprint'] 40 | return fingerprint 41 | -------------------------------------------------------------------------------- /disappeer/gpg/helpers/keylistformatter.py: -------------------------------------------------------------------------------- 1 | """ 2 | keylistformatter.py 3 | 4 | Module for KeyListFormatter class object. 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | 11 | class KeyListFormatter: 12 | 13 | def format(self, raw_key_list): 14 | userid_and_key_id_tuple_list = self.create_userid_and_keyid_tuple_list(raw_key_list) 15 | result = self.process_key_dropdown_list_strings(userid_and_key_id_tuple_list) 16 | return result 17 | 18 | def create_userid_and_keyid_tuple_list(self, raw_key_list): 19 | userid_and_keyid_tuple_list = [] 20 | for item in raw_key_list: 21 | name = item['uids'][0] 22 | key_id = item['keyid'] 23 | pack = (name, key_id) 24 | userid_and_keyid_tuple_list.append(pack) 25 | return userid_and_keyid_tuple_list 26 | 27 | def process_key_dropdown_list_strings(self, key_tuple_list): 28 | processed = [] 29 | for item in key_tuple_list: 30 | name_tuple = self.process_key_uid(item[0]) 31 | key_id = item[1] 32 | spacer = ', ' 33 | structured = name_tuple[0] + spacer + name_tuple[-1] + spacer + key_id 34 | processed.append(structured) 35 | return processed 36 | 37 | def process_key_uid(self, key_uid): 38 | split = key_uid.split() 39 | result = (split[0], split[-1]) 40 | return result 41 | 42 | -------------------------------------------------------------------------------- /disappeer/gpg/helpers/keylistobservable.py: -------------------------------------------------------------------------------- 1 | """ 2 | keylistobservable.py 3 | 4 | Module for the KeyListObservable class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.utilities import observable 11 | from disappeer.gpg.helpers import keylistformatter 12 | 13 | 14 | class KeyListObservable(observable.Observable): 15 | """ 16 | Adapted observable to keep track of key list, 17 | while keeping it formatted. 18 | """ 19 | 20 | def __init__(self, keyring): 21 | super().__init__() 22 | self.key_ring = keyring 23 | self.key_formatter = keylistformatter.KeyListFormatter() 24 | self.key_list = self._run_ops() 25 | 26 | def get(self): 27 | return self.key_list 28 | 29 | def set(self, param): 30 | self.key_list = self._run_ops() 31 | self.run_callbacks() 32 | 33 | def _run_ops(self): 34 | raw_list = self.key_ring.get_raw_key_list() 35 | result = self.key_formatter.format(raw_list) 36 | return result 37 | -------------------------------------------------------------------------------- /disappeer/gpg/helpers/passphrasevalidator.py: -------------------------------------------------------------------------------- 1 | """ 2 | passphrasevalidator.py 3 | 4 | Module for PassphraseValidator class object. 5 | Takes homedir, host key id, and passphrase, verifies passphrase against a sig. 6 | 7 | Copyright (C) 2018 Disappeer Labs 8 | License: GPLv3 9 | """ 10 | 11 | from disappeer.gpg.agents import signer 12 | from disappeer.gpg.agents import verifier 13 | 14 | 15 | class PassphraseValidator: 16 | 17 | def __init__(self, homedir, host_key_id, passphrase): 18 | self.home_dir = homedir 19 | self.host_key_id = host_key_id 20 | self.passphrase = passphrase 21 | self.msg = 'hello world' 22 | self.result = None 23 | 24 | def sign(self): 25 | sign_agent = signer.Signer(self.home_dir) 26 | result = sign_agent.execute(self.msg, self.host_key_id, self.passphrase) 27 | return result 28 | 29 | def verify(self, msg): 30 | verify_agent = verifier.Verifier(self.home_dir) 31 | result = verify_agent.execute(msg) 32 | return result 33 | 34 | def validate(self): 35 | sig = self.sign() 36 | self.result = self.verify(str(sig)) 37 | return self.result.valid 38 | 39 | def get_error_msg(self): 40 | try: 41 | msg = self.result.stderr 42 | except AttributeError as err: 43 | return None 44 | return msg 45 | 46 | -------------------------------------------------------------------------------- /disappeer/gpg/helpers/tempdetachedverifier.py: -------------------------------------------------------------------------------- 1 | """ 2 | tempdetachedverifier.py 3 | 4 | Module for TempDetachedVerifier class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.gpg.helpers import tempkeyring 11 | from disappeer.gpg.agents import detachedverifier 12 | import tempfile 13 | 14 | 15 | class TempDetachedVerifier(tempkeyring.TempKeyRing): 16 | 17 | def __init__(self, gpg_pub_key, sig_dict): 18 | super().__init__() 19 | self.detached_verifier = detachedverifier.DetachedVerifier(self.temp_dir_name) 20 | self.gpg_pub_key = gpg_pub_key 21 | self.sig_dict = sig_dict 22 | self.error = None 23 | self.valid = None 24 | self.run() 25 | 26 | def run(self): 27 | self.is_key_valid() 28 | if self.error is not None: 29 | return 30 | self.is_sig_dict_valid() 31 | if self.error is not None: 32 | return 33 | self.verify_sig() 34 | 35 | def verify_sig(self): 36 | sig_bytes = bytes(self.sig_dict['sig'], 'utf-8') 37 | data_bytes = bytes(self.sig_dict['data'], 'utf-8') 38 | 39 | with tempfile.NamedTemporaryFile() as tmp_file: 40 | tmp_file.write(sig_bytes) 41 | tmp_file.seek(0) 42 | verify_detached = self.detached_verifier.execute(tmp_file.name, data_bytes) 43 | if not verify_detached.valid: 44 | self.set_error(verify_detached.stderr) 45 | self.valid = verify_detached.valid 46 | return verify_detached.valid 47 | 48 | def is_sig_dict_valid(self): 49 | target_list = ['sig', 'data'] 50 | if all(name in target_list for name in self.sig_dict): 51 | return True 52 | else: 53 | msg = 'Error: sig dict is false: ' + str(self.sig_dict) 54 | self.set_error(msg) 55 | return False 56 | 57 | def is_key_valid(self): 58 | result = self.key_ring.import_key(self.gpg_pub_key) 59 | if result.count == 0: 60 | self.set_error(result.stderr) 61 | return False 62 | else: 63 | return True 64 | 65 | def set_error(self, err_msg): 66 | self.error = err_msg 67 | self.valid = False 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /disappeer/gpg/helpers/tempkeyring.py: -------------------------------------------------------------------------------- 1 | """ 2 | tempkeyring.py 3 | 4 | Module for TempKeyRing class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.gpg.agents import keyring 11 | import tempfile 12 | 13 | 14 | class TempKeyRing: 15 | 16 | def __init__(self): 17 | self.temp_dir = self.create_temp_dir() 18 | self.temp_dir_name = self.temp_dir.name 19 | self.key_ring = keyring.KeyRing(self.temp_dir_name) 20 | 21 | def create_temp_dir(self): 22 | temp_dir = tempfile.TemporaryDirectory() 23 | return temp_dir 24 | 25 | def close_temp_dir(self): 26 | self.temp_dir.cleanup() 27 | 28 | def __del__(self): 29 | try: 30 | self.close_temp_dir() 31 | except (AttributeError, FileNotFoundError): 32 | pass 33 | -------------------------------------------------------------------------------- /disappeer/gpg/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/gpg/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/gpg/tests/agents/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/gpg/tests/agents/__init__.py -------------------------------------------------------------------------------- /disappeer/gpg/tests/agents/test_decrypter.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_decrypter.py 3 | 4 | Test suite for Decrypter gpg agent module and class 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from disappeer.gpg.agents import decrypter 12 | from disappeer.gpg.agents import gpgagent 13 | from disappeer.gpg.agents import encrypter 14 | 15 | 16 | class TestImports(unittest.TestCase): 17 | 18 | def test_gpg_agent_import(self): 19 | self.assertEqual(gpgagent, decrypter.gpgagent) 20 | 21 | 22 | class TestDecrypterClass(unittest.TestCase): 23 | 24 | def setUp(self): 25 | self.keydir = "tests/data/keys" 26 | self.key_fingerprint = 'AA74BBFE8A31ADBC0E9ED26B190DB52959AC3560' 27 | self.d = decrypter.Decrypter(self.keydir) 28 | 29 | def test_instance(self): 30 | self.assertIsInstance(self.d, decrypter.Decrypter) 31 | 32 | def test_is_instance_of_agent(self): 33 | self.assertIsInstance(self.d, gpgagent.GPGAgent) 34 | 35 | def test_gpg_attribute(self): 36 | name = 'gpg' 37 | check = hasattr(self.d, name) 38 | self.assertTrue(check) 39 | 40 | def test_execute_attribute(self): 41 | name = 'execute' 42 | check = hasattr(self.d, name) 43 | self.assertTrue(check) 44 | 45 | def test_decrypt_message_result_valid_passphrase(self): 46 | self.encrypter = encrypter.Encrypter(self.keydir) 47 | self.message = "Hello world." 48 | encrypt_result = self.encrypter.execute(self.message, self.key_fingerprint) 49 | self.ciphertext = str(encrypt_result) 50 | self.passphrase = 'passphrase' 51 | result = self.d.execute(self.ciphertext, self.passphrase) 52 | self.assertTrue(result.ok) 53 | 54 | @unittest.skip("FAILS ON MAC") 55 | def test_decrypt_message_result_not_valid_passphrase(self): 56 | self.encrypter = encrypter.Encrypter(self.keydir) 57 | self.message = "Hello world." 58 | encrypt_result = self.encrypter.execute(self.message, self.key_fingerprint) 59 | self.ciphertext = str(encrypt_result) 60 | self.passphrase = 'passphddddrase' 61 | result = self.d.execute(self.ciphertext, self.passphrase) 62 | self.assertFalse(result.ok) 63 | -------------------------------------------------------------------------------- /disappeer/gpg/tests/agents/test_detachedverifier.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_detachedverifier.py 3 | 4 | Test suite for the DetachedVerifier class object and module 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from disappeer.gpg.agents import detachedverifier 12 | from disappeer.gpg.agents import gpgagent 13 | from disappeer.gpg.agents import signer 14 | import tempfile 15 | 16 | 17 | class TestImports(unittest.TestCase): 18 | 19 | def test_gpgagent_import(self): 20 | self.assertEqual(gpgagent, detachedverifier.gpgagent) 21 | 22 | 23 | class TestVerifierClass(unittest.TestCase): 24 | 25 | def setUp(self): 26 | self.keydir = "tests/data/keys" 27 | self.key_fingerprint = 'AA74BBFE8A31ADBC0E9ED26B190DB52959AC3560' 28 | self.x = detachedverifier.DetachedVerifier(self.keydir) 29 | 30 | def test_instance(self): 31 | self.assertIsInstance(self.x, detachedverifier.DetachedVerifier) 32 | 33 | def test_is_instance_of_agent(self): 34 | self.assertIsInstance(self.x, gpgagent.GPGAgent) 35 | 36 | def test_gpg_attribute(self): 37 | name = 'gpg' 38 | check = hasattr(self.x, name) 39 | self.assertTrue(check) 40 | 41 | def test_execute_attribute(self): 42 | name = 'execute' 43 | check = hasattr(self.x, name) 44 | self.assertTrue(check) 45 | 46 | def test_execute_method_valid(self): 47 | self.message = "Hello world." 48 | self.passphrase = 'passphrase' 49 | self.s = signer.Signer(self.keydir) 50 | sig = self.s.execute(self.message, self.key_fingerprint, self.passphrase, detach=True) 51 | data = bytes(self.message, 'utf-8') 52 | with tempfile.NamedTemporaryFile() as tmp_file: 53 | tmp_file.write(bytes(str(sig), 'utf-8')) 54 | tmp_file.seek(0) 55 | verify_detached = self.x.execute(tmp_file.name, data) 56 | self.assertTrue(verify_detached.valid) 57 | 58 | @unittest.skip("FAILS ON MAC") 59 | def test_execute_method_not_valid(self): 60 | self.message = "Hello world." 61 | self.passphrase = 'passsphrase' 62 | self.s = signer.Signer(self.keydir) 63 | sig = self.s.execute(self.message, self.key_fingerprint, self.passphrase, detach=True) 64 | data = bytes(self.message, 'utf-8') 65 | with tempfile.NamedTemporaryFile() as tmp_file: 66 | tmp_file.write(bytes(str(sig), 'utf-8')) 67 | tmp_file.seek(0) 68 | verify_detached = self.x.execute(tmp_file.name, data) 69 | self.assertFalse(verify_detached.valid) 70 | -------------------------------------------------------------------------------- /disappeer/gpg/tests/agents/test_encrypter.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_encrypter.py 3 | 4 | Test suite for the Encrypter gpg agent module and class 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import MagicMock 12 | from disappeer.gpg.agents import encrypter 13 | from disappeer.gpg.agents import keyring 14 | from disappeer.gpg.helpers import keyfinder 15 | from disappeer.gpg.agents import gpgagent 16 | 17 | 18 | class TestImports(unittest.TestCase): 19 | 20 | def test_gpgagent_import(self): 21 | self.assertEqual(gpgagent, encrypter.gpgagent) 22 | 23 | 24 | class TestKeyMakerClass(unittest.TestCase): 25 | 26 | def setUp(self): 27 | self.keydir = "tests/data/keys" 28 | self.key_fingerprint = 'C227D0EC9289CB9D1F06A9A85933EB9BDA9B62BB' 29 | self.key_ring = keyring.KeyRing(self.keydir) 30 | self.key_finder = keyfinder.KeyFinder(self.key_ring) 31 | self.message = "Hello world." 32 | self.e = encrypter.Encrypter(self.keydir) 33 | 34 | def test_instance(self): 35 | self.assertIsInstance(self.e, encrypter.Encrypter) 36 | 37 | def test_is_instance_of_agent(self): 38 | self.assertIsInstance(self.e, gpgagent.GPGAgent) 39 | 40 | def test_key_attribute(self): 41 | name = 'gpg' 42 | check = hasattr(self.e, name) 43 | self.assertTrue(check) 44 | 45 | def test_execute_attribute(self): 46 | name = 'execute' 47 | check = hasattr(self.e, name) 48 | self.assertTrue(check) 49 | 50 | def test_execute_calls_encrypt_with_args(self): 51 | sub = self.e.gpg.encrypt = MagicMock() 52 | self.e.execute(self.message, self.key_fingerprint) 53 | sub.assert_called_with(self.message, self.key_fingerprint, always_trust=True) 54 | 55 | def test_execute_returns_result(self): 56 | sub = self.e.gpg.encrypt = MagicMock(return_value='hello') 57 | result = self.e.execute(self.message, self.key_fingerprint) 58 | self.assertEqual(result, sub.return_value) -------------------------------------------------------------------------------- /disappeer/gpg/tests/agents/test_gpgagent.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_gpgagent.py 3 | 4 | Test suite for gpgagent module and class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from gpg.agents import gpgagent 12 | import gnupg 13 | 14 | 15 | class TestImports(unittest.TestCase): 16 | 17 | def test_gnupg(self): 18 | self.assertEqual(gnupg, gpgagent.gnupg) 19 | 20 | 21 | class TestAgentClass(unittest.TestCase): 22 | 23 | def setUp(self): 24 | self.keydir = "tests/data/keys" 25 | self.g = gpgagent.GPGAgent(self.keydir) 26 | 27 | def test_instance(self): 28 | self.assertIsInstance(self.g, gpgagent.GPGAgent) 29 | 30 | def test_keydir_attribute(self): 31 | self.assertEqual(self.keydir, self.g.home) 32 | 33 | def test_gpg_attribute(self): 34 | self.assertIsInstance(self.g.gpg, gnupg.GPG) 35 | 36 | 37 | class TestAgentGetGPGMethod(unittest.TestCase): 38 | 39 | def setUp(self): 40 | self.keydir = "tests/data/keys" 41 | self.g = gpgagent.GPGAgent(self.keydir) 42 | 43 | def test_get_gpg_obj_result_instance(self): 44 | result = self.g.get_gpg_obj() 45 | self.assertIsInstance(result, gnupg.GPG) 46 | 47 | def test_get_gpg_obj_result_home_attr(self): 48 | result = self.g.get_gpg_obj() 49 | self.assertEqual(result.gnupghome, self.keydir) 50 | 51 | def test_get_gpg_obj_result_encoding_attr(self): 52 | result = self.g.get_gpg_obj() 53 | self.assertEqual(result.encoding, 'utf-8') 54 | 55 | 56 | class TestAgentSetMethod(unittest.TestCase): 57 | 58 | def setUp(self): 59 | self.keydir = "tests/data/keys" 60 | self.alt = "tests/data/altkeys" 61 | 62 | self.g = gpgagent.GPGAgent(self.keydir) 63 | 64 | def test_set_method_check_new_home(self): 65 | self.g.set(self.alt) 66 | self.assertEqual(self.g.home, self.alt) 67 | 68 | def test_call_instance_check_new_gpg_obj(self): 69 | self.g.set(self.alt) 70 | self.assertEqual(self.g.gpg.gnupghome, self.alt) -------------------------------------------------------------------------------- /disappeer/gpg/tests/agents/test_keydeleter.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_keydeleter.py 3 | 4 | Test suite for KeyDeleter gpgagent module and class 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from disappeer.gpg.agents import keydeleter 12 | from disappeer.gpg.agents import gpgagent 13 | 14 | 15 | class TestImports(unittest.TestCase): 16 | 17 | def test_gpgagent(self): 18 | self.assertEqual(gpgagent, keydeleter.gpgagent) 19 | 20 | 21 | class TestKeyDeleterClass(unittest.TestCase): 22 | 23 | def setUp(self): 24 | self.keydir = "tests/data/keys" 25 | self.d = keydeleter.KeyDeleter(self.keydir) 26 | 27 | def test_instance(self): 28 | self.assertIsInstance(self.d, keydeleter.KeyDeleter) 29 | 30 | def test_is_instance_of_agent(self): 31 | self.assertIsInstance(self.d, gpgagent.GPGAgent) 32 | 33 | def test_gpg_attribute(self): 34 | name = 'gpg' 35 | check = hasattr(self.d, name) 36 | self.assertTrue(check) 37 | 38 | def test_execute_attribute(self): 39 | name = 'execute' 40 | check = hasattr(self.d, name) 41 | self.assertTrue(check) 42 | 43 | @unittest.skip("Skip key deletion, requires lengthy key creation") 44 | def test_execute_method(self): 45 | before = self.d.gpg.list_keys() 46 | before_len = len(before) 47 | target = 'EA65A9E6ABC97F54A6E63ACAA8E19FA23E3F1956' 48 | result = self.d.execute(target) 49 | after = self.d.gpg.list_keys() 50 | after_len = len(after) 51 | self.assertEqual(after_len - before_len, -1) 52 | 53 | -------------------------------------------------------------------------------- /disappeer/gpg/tests/agents/test_signer.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_signer.py 3 | 4 | Test suite for the Signer module gpg agent class 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from disappeer.gpg.agents import signer 12 | from disappeer.gpg.agents import gpgagent 13 | 14 | 15 | class TestImports(unittest.TestCase): 16 | 17 | def test_gpgagent_import(self): 18 | self.assertEqual(gpgagent, signer.gpgagent) 19 | 20 | 21 | class TestSignerClass(unittest.TestCase): 22 | 23 | def setUp(self): 24 | self.keydir = "tests/data/keys" 25 | self.key_fingerprint = 'AA74BBFE8A31ADBC0E9ED26B190DB52959AC3560' 26 | self.s = signer.Signer(self.keydir) 27 | 28 | def test_instance(self): 29 | self.assertIsInstance(self.s, signer.Signer) 30 | 31 | def test_is_instance_of_agent(self): 32 | self.assertIsInstance(self.s, gpgagent.GPGAgent) 33 | 34 | def test_gpg_attribute(self): 35 | name = 'gpg' 36 | check = hasattr(self.s, name) 37 | self.assertTrue(check) 38 | 39 | def test_execute_attribute(self): 40 | name = 'execute' 41 | check = hasattr(self.s, name) 42 | self.assertTrue(check) 43 | 44 | def test_execute_method_valid(self): 45 | self.message = "Hello world." 46 | self.passphrase = 'passphrase' 47 | result = self.s.execute(self.message, self.key_fingerprint, self.passphrase) 48 | self.assertIn("SIGNED MESSAGE", str(result)) 49 | 50 | @unittest.skip("FAILS ON MAC") 51 | def test_execute_method_not_valid(self): 52 | # TODO: This test does not pass on Mac machine, works on Debian 53 | self.message = "Hello world." 54 | self.passphrase = 'xxxyyy' 55 | result = self.s.execute(self.message, self.key_fingerprint, self.passphrase) 56 | self.assertEqual(0, len(str(result))) 57 | 58 | def test_execute_method_valid_detached(self): 59 | self.message = "Hello world." 60 | self.passphrase = 'passphrase' 61 | result = self.s.execute(self.message, 62 | self.key_fingerprint, 63 | self.passphrase, 64 | detach=True) 65 | self.assertNotIn(self.message, str(result)) 66 | 67 | -------------------------------------------------------------------------------- /disappeer/gpg/tests/agents/test_verifier.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_verifier.py 3 | 4 | Test suite for the Verifier gpg agent module and class 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from disappeer.gpg.agents import verifier 12 | from disappeer.gpg.agents import gpgagent 13 | from disappeer.gpg.agents import signer 14 | 15 | 16 | class TestImports(unittest.TestCase): 17 | 18 | def test_gpgagent_import(self): 19 | self.assertEqual(gpgagent, verifier.gpgagent) 20 | 21 | 22 | class TestVerifierClass(unittest.TestCase): 23 | 24 | def setUp(self): 25 | self.keydir = "tests/data/keys" 26 | self.key_fingerprint = 'AA74BBFE8A31ADBC0E9ED26B190DB52959AC3560' 27 | self.v = verifier.Verifier(self.keydir) 28 | 29 | def test_instance(self): 30 | self.assertIsInstance(self.v, verifier.Verifier) 31 | 32 | def test_is_instance_of_agent(self): 33 | self.assertIsInstance(self.v, gpgagent.GPGAgent) 34 | 35 | def test_gpg_attribute(self): 36 | name = 'gpg' 37 | check = hasattr(self.v, name) 38 | self.assertTrue(check) 39 | 40 | def test_execute_attribute(self): 41 | name = 'execute' 42 | check = hasattr(self.v, name) 43 | self.assertTrue(check) 44 | 45 | def test_execute_method_valid(self): 46 | self.message = "Hello world." 47 | self.passphrase = 'passphrase' 48 | self.s = signer.Signer(self.keydir) 49 | sig = self.s.execute(self.message, self.key_fingerprint, self.passphrase) 50 | result = self.v.execute(str(sig)) 51 | self.assertTrue(result.valid) 52 | 53 | def test_execute_method_not_valid(self): 54 | self.message = "Hello world." 55 | result = self.v.execute(self.message) 56 | self.assertFalse(result.valid) -------------------------------------------------------------------------------- /disappeer/gpg/tests/gpgcontroller/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/gpg/tests/gpgcontroller/__init__.py -------------------------------------------------------------------------------- /disappeer/gpg/tests/gpgcontroller/gpgcontrollersetupclass.py: -------------------------------------------------------------------------------- 1 | """ 2 | gpgcontrollersetupclass.py 3 | 4 | Primary setup class for GPG Controller test cases 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import MagicMock 12 | import tkinter 13 | from disappeer.models.db import databasefacade 14 | from disappeer.root import rootparameters 15 | from disappeer.models import gpgdatacontext 16 | from disappeer.gpg import gpgcontroller 17 | import time 18 | import copy 19 | 20 | 21 | class TestGPGControllerSetupClass(unittest.TestCase): 22 | command = "" 23 | root = tkinter.Tk() 24 | root_view = MagicMock() 25 | queue = MagicMock() 26 | database_facade = MagicMock(spec=databasefacade.DatabaseFacade) 27 | mock_observer = MagicMock() 28 | root_params = rootparameters.RootParameters(root, root_view, queue, database_facade, mock_observer) 29 | mock_view_method = root_params.get_gpg_frame = MagicMock(return_value=MagicMock()) 30 | view = mock_view_method.return_value 31 | 32 | key_dir = 'tests/data/keys' 33 | data_context = gpgdatacontext.GPGDataContext(key_dir) 34 | 35 | def setUp(self): 36 | self.data_context = copy.deepcopy(self.data_context) 37 | self.x = gpgcontroller.GPGController(self.root_params, 38 | self.data_context) 39 | 40 | def altsetup(self): 41 | x = gpgcontroller.GPGController(self.root_params, 42 | self.data_context) 43 | return x 44 | 45 | -------------------------------------------------------------------------------- /disappeer/gpg/tests/helpers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/gpg/tests/helpers/__init__.py -------------------------------------------------------------------------------- /disappeer/gpg/tests/helpers/test_keylistobservable.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_keylistobservable.py 3 | 4 | Test suite for the KeyListObservable module and class 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import MagicMock 12 | from disappeer.utilities import observable 13 | from disappeer.gpg.helpers import keylistobservable 14 | from disappeer.gpg.helpers import keylistformatter 15 | from disappeer.gpg.agents import keyring 16 | 17 | 18 | class TestImports(unittest.TestCase): 19 | 20 | def test_observable(self): 21 | self.assertEqual(observable, keylistobservable.observable) 22 | 23 | def test_key_list_formatter(self): 24 | self.assertEqual(keylistformatter, keylistobservable.keylistformatter) 25 | 26 | 27 | class TestKeyListObservableBasics(unittest.TestCase): 28 | 29 | def setUp(self): 30 | self.target = ['alice, , 190DB52959AC3560'] 31 | self.home = 'tests/data/keys' 32 | self.keyring = keyring.KeyRing(self.home) 33 | self.formatter = keylistformatter.KeyListFormatter() 34 | self.x = keylistobservable.KeyListObservable(self.keyring) 35 | 36 | def test_instance(self): 37 | self.assertIsInstance(self.x, keylistobservable.KeyListObservable) 38 | 39 | def test_instance_observable(self): 40 | self.assertIsInstance(self.x, observable.Observable) 41 | 42 | def test_keyring_arg(self): 43 | self.assertEqual(self.x.key_ring, self.keyring) 44 | 45 | def test_formatter_attribute(self): 46 | self.assertIsInstance(self.x.key_formatter, keylistformatter.KeyListFormatter) 47 | 48 | def test_keylist_attribute(self): 49 | name = 'key_list' 50 | check = hasattr(self.x, name) 51 | self.assertTrue(check) 52 | 53 | def test_get_method(self): 54 | result = self.x.get() 55 | self.assertEqual(result, self.x.key_list) 56 | 57 | def test_set_method_calls_formatter(self): 58 | self.x.key_formatter.format = MagicMock() 59 | result = self.x.set(None) 60 | self.assertTrue(self.x.key_formatter.format.called) 61 | 62 | def test_set_method_calls_run_callbacks(self): 63 | self.x.run_callbacks = MagicMock() 64 | result = self.x.set(None) 65 | self.assertTrue(self.x.run_callbacks.called) 66 | 67 | def test_set_method_sets_key_list_formatted(self): 68 | result = self.x.set(None) 69 | for item in self.target: 70 | self.assertIn(item, self.x.key_list) 71 | 72 | def test_key_list_attribute_set_by_constructor(self): 73 | for item in self.target: 74 | self.assertIn(item, self.x.key_list) 75 | 76 | def test_run_method(self): 77 | result = self.x._run_ops() 78 | for item in self.target: 79 | self.assertIn(item, result) 80 | -------------------------------------------------------------------------------- /disappeer/gpg/tests/helpers/test_tempkeyring.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_tempkeyring.py 3 | 4 | Test suite for TempKeyRing class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import MagicMock, patch 12 | from disappeer.gpg.helpers import tempkeyring 13 | from disappeer.gpg.agents import keyring 14 | import tempfile 15 | 16 | 17 | class TestImports(unittest.TestCase): 18 | 19 | def test_keyring(self): 20 | self.assertEqual(keyring, tempkeyring.keyring) 21 | 22 | def test_tempfile(self): 23 | self.assertEqual(tempfile, tempkeyring.tempfile) 24 | 25 | 26 | class TestClassBasics(unittest.TestCase): 27 | 28 | def setUp(self): 29 | self.x = tempkeyring.TempKeyRing() 30 | 31 | def test_instance(self): 32 | self.assertIsInstance(self.x, tempkeyring.TempKeyRing) 33 | 34 | def test_create_temp_dir_returns_temp_dir(self): 35 | result = self.x.create_temp_dir() 36 | self.assertIsInstance(result, tempfile.TemporaryDirectory) 37 | result.cleanup() 38 | 39 | def test_temp_dir_attribute_is_temp_dir(self): 40 | self.assertIsInstance(self.x.temp_dir, tempfile.TemporaryDirectory) 41 | 42 | def test_close_temp_dir_calls_close_on_temp_dir(self): 43 | try: 44 | self.x.close_temp_dir() 45 | except: 46 | self.assertTrue(False) 47 | 48 | def test_close_temp_dir_called_by_del(self): 49 | target = self.x.close_temp_dir = MagicMock() 50 | self.x.__del__() 51 | target.assert_called_with() 52 | self.x.temp_dir.cleanup() 53 | 54 | def test_temp_dir_name_attribute_is_temp_dir_name(self): 55 | self.assertEqual(self.x.temp_dir_name, self.x.temp_dir.name) 56 | 57 | def test_key_ring_attribute_is_keyring_with_temp_dir(self): 58 | self.assertIsInstance(self.x.key_ring, keyring.KeyRing) 59 | self.assertEqual(self.x.key_ring.home, self.x.temp_dir_name) -------------------------------------------------------------------------------- /disappeer/images/Farm-Fresh_lightning_go.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/images/Farm-Fresh_lightning_go.png -------------------------------------------------------------------------------- /disappeer/images/Farm-Fresh_update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/images/Farm-Fresh_update.png -------------------------------------------------------------------------------- /disappeer/images/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/images/__init__.py -------------------------------------------------------------------------------- /disappeer/images/bullet_green_small.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/images/bullet_green_small.gif -------------------------------------------------------------------------------- /disappeer/images/crypto_key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/images/crypto_key.png -------------------------------------------------------------------------------- /disappeer/images/delete_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/images/delete_icon.png -------------------------------------------------------------------------------- /disappeer/images/logo_64x64.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/images/logo_64x64.gif -------------------------------------------------------------------------------- /disappeer/images/logo_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/images/logo_icon.png -------------------------------------------------------------------------------- /disappeer/images/logo_icon_huge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/images/logo_icon_huge.png -------------------------------------------------------------------------------- /disappeer/images/logo_icon_large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/images/logo_icon_large.png -------------------------------------------------------------------------------- /disappeer/images/logo_icon_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/images/logo_icon_small.png -------------------------------------------------------------------------------- /disappeer/images/no_image.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/images/no_image.gif -------------------------------------------------------------------------------- /disappeer/images/open_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/images/open_icon.png -------------------------------------------------------------------------------- /disappeer/images/play_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/images/play_icon.png -------------------------------------------------------------------------------- /disappeer/images/run_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/images/run_icon.png -------------------------------------------------------------------------------- /disappeer/images/save_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/images/save_icon.png -------------------------------------------------------------------------------- /disappeer/images/send_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/images/send_icon.png -------------------------------------------------------------------------------- /disappeer/images/send_icon_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/images/send_icon_1.png -------------------------------------------------------------------------------- /disappeer/images/small_gnupg_full_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/images/small_gnupg_full_logo.png -------------------------------------------------------------------------------- /disappeer/images/tor_icon_small.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/images/tor_icon_small.gif -------------------------------------------------------------------------------- /disappeer/messages/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/messages/__init__.py -------------------------------------------------------------------------------- /disappeer/messages/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/messages/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/metainfo.py: -------------------------------------------------------------------------------- 1 | """ 2 | metainfo.py 3 | 4 | Disappeer Meta Info 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | 11 | title = 'Disappeer' 12 | 13 | version = '0.1.0' 14 | 15 | license = 'GPLv3' 16 | 17 | github = 'https://github.com/disappeerlabs/disappeer' 18 | 19 | email = 'disappeerlabs@gmail.com' 20 | -------------------------------------------------------------------------------- /disappeer/models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/models/__init__.py -------------------------------------------------------------------------------- /disappeer/models/db/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/models/db/__init__.py -------------------------------------------------------------------------------- /disappeer/models/db/bases/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/models/db/bases/__init__.py -------------------------------------------------------------------------------- /disappeer/models/db/bases/basemessagestable.py: -------------------------------------------------------------------------------- 1 | """ 2 | basemessagestable.py 3 | 4 | Moduel for BaseMessagesTable class object, to hold methods common to sent and received messages tables. 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.models.db.bases import abstractdbtable 11 | import hashlib 12 | import random 13 | import sys 14 | 15 | 16 | class BaseMessagesTable(abstractdbtable.AbstractDBTable): 17 | 18 | def __init__(self, db_file_path): 19 | super().__init__(db_file_path) 20 | 21 | @property 22 | def column_names_tuple(self): 23 | cols = ('nonce', 'ciphertext', 'status') 24 | return cols 25 | 26 | def build_input_from_payload(self, payload): 27 | nonce = self.random_hash() 28 | ciphertext = payload['ciphertext'] 29 | status = 'unread' 30 | data_row = (nonce, ciphertext, status) 31 | result = self.build_named_tuple(data_row) 32 | return result 33 | 34 | def handle_new_payload(self, payload): 35 | data_row = self.build_input_from_payload(payload) 36 | self.insert_data_row(data_row) 37 | 38 | def fetch_all_nonces(self): 39 | command = 'select {} from {}'.format(self.column_names_tuple[0], 40 | self.table_name) 41 | result = self.fetch_all(command) 42 | return result 43 | 44 | def fetch_all_nonces_with_status(self): 45 | command = 'select {}, {} from {}'.format(self.column_names_tuple[0], 46 | self.column_names_tuple[2], 47 | self.table_name) 48 | result = self.fetch_all(command) 49 | return result 50 | 51 | 52 | def fetch_named_tuple_by_nonce(self, nonce): 53 | command = "select * from {} where nonce='{}'".format(self.table_name, 54 | nonce) 55 | result = self.fetch_one(command) 56 | result = self.build_named_tuple(result[1:]) 57 | return result 58 | 59 | def delete_record_by_nonce(self, nonce_val): 60 | self.delete_record_where_x_equals_y(self.column_names_tuple[0], nonce_val) 61 | 62 | def update_record_status_to_read(self, nonce_val): 63 | new_status_val = 'read' 64 | self.update_record_col_to_val_where_x_equals_y('status', new_status_val, 'nonce', nonce_val) 65 | 66 | def hash_message(self, message): 67 | hasher = hashlib.sha1() 68 | hasher.update(bytes(message, 'UTF-8')) 69 | digest = hasher.hexdigest() 70 | return digest 71 | 72 | def random_hash(self): 73 | num_str = str(random.randint(0, sys.maxsize)) 74 | result = self.hash_message(num_str) 75 | return result -------------------------------------------------------------------------------- /disappeer/models/db/bases/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/models/db/bases/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/models/db/dbexecutor.py: -------------------------------------------------------------------------------- 1 | """ 2 | dbexecutor.py 3 | 4 | Module for DBExecutor class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import sqlite3 11 | 12 | 13 | class DBExecutor: 14 | 15 | def __init__(self, db_file_path): 16 | self.database = db_file_path 17 | 18 | def execute(self, *args): 19 | connection = sqlite3.connect(self.database) 20 | cursor = connection.cursor() 21 | cursor.execute(*args) 22 | connection.commit() 23 | connection.close() 24 | 25 | def fetch_all(self, *args): 26 | connection = sqlite3.connect(self.database) 27 | cursor = connection.cursor() 28 | cursor.execute(*args) 29 | result = cursor.fetchall() 30 | connection.commit() 31 | connection.close() 32 | return result 33 | 34 | def fetch_one(self, *args): 35 | connection = sqlite3.connect(self.database) 36 | cursor = connection.cursor() 37 | cursor.execute(*args) 38 | result = cursor.fetchone() 39 | connection.commit() 40 | connection.close() 41 | return result 42 | -------------------------------------------------------------------------------- /disappeer/models/db/dbreceivedmessagestable.py: -------------------------------------------------------------------------------- 1 | """ 2 | dbreceivedmessagestable.py 3 | 4 | Module for DBReceivedMessagesTable class object and module 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.models.db.bases import basemessagestable 11 | 12 | 13 | class DBPReceivedMessagesTable(basemessagestable.BaseMessagesTable): 14 | 15 | def __init__(self, db_file_path): 16 | super().__init__(db_file_path) 17 | 18 | @property 19 | def table_name(self): 20 | return 'ReceivedMessages' 21 | 22 | @property 23 | def data_row_name(self): 24 | return 'ReceivedMessagesTableRow' 25 | 26 | -------------------------------------------------------------------------------- /disappeer/models/db/dbsentmessagestable.py: -------------------------------------------------------------------------------- 1 | """ 2 | dbsentmessagestable.py 3 | 4 | Module for DBSentMessages class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.models.db.bases import basemessagestable 11 | 12 | 13 | class DBPSentMessagesTable(basemessagestable.BaseMessagesTable): 14 | 15 | def __init__(self, db_file_path): 16 | super().__init__(db_file_path) 17 | 18 | @property 19 | def table_name(self): 20 | return 'SentMessages' 21 | 22 | @property 23 | def data_row_name(self): 24 | return 'SentMessagesTableRow' 25 | 26 | 27 | -------------------------------------------------------------------------------- /disappeer/models/db/dbserversynctable.py: -------------------------------------------------------------------------------- 1 | """ 2 | dbserversynctable.py 3 | 4 | DBServerSyncTable module for syncing nonce vals to the ContactResponseServer thread. 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.models.db.bases import abstractdbtable 11 | import sqlite3 12 | 13 | 14 | class DBServerSyncTable(abstractdbtable.AbstractDBTable): 15 | 16 | def __init__(self, db_file_path): 17 | super().__init__(db_file_path) 18 | 19 | @property 20 | def table_name(self): 21 | return 'PendingContactResponseNoncesTable' 22 | 23 | @property 24 | def data_row_name(self): 25 | return 'PendingContactResponseNoncesTableRow' 26 | 27 | @property 28 | def column_names_tuple(self): 29 | cols = ('value', ) 30 | return cols 31 | 32 | def insert_new_vals(self, val_list): 33 | """ 34 | :param val_list: [('val1',), ('val2',), ('val3',)] 35 | """ 36 | # TODO: refactor, execute many method should be pulled up into the db executor class 37 | execution_string = 'INSERT into {} values(null, ?)'.format(self.table_name) 38 | connection = sqlite3.connect(self.database) 39 | cursor = connection.cursor() 40 | cursor.executemany(execution_string, val_list) 41 | connection.commit() 42 | connection.close() 43 | 44 | def fetch_all_nonces(self): 45 | command = 'select value from {}'.format(self.table_name) 46 | result = self.fetch_all(command) 47 | final = [x[0] for x in result] 48 | return final 49 | 50 | def delete_all_nonces(self): 51 | execution_string = 'delete from {}'.format(self.table_name) 52 | self.execute(execution_string) 53 | 54 | -------------------------------------------------------------------------------- /disappeer/models/db/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/models/db/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/models/db/tests/test_dbreceivedmessagestable.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_dbreceivedmessagestable.py 3 | 4 | Test suite for DBReceivedMessagesTable class object and module 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import MagicMock 12 | from disappeer.models.db import dbreceivedmessagestable 13 | from disappeer.models.db.bases import abstractdbtable 14 | from disappeer.models.db import dbexecutor 15 | from disappeer.models.db.bases import basemessagestable 16 | import os 17 | 18 | 19 | class TestImports(unittest.TestCase): 20 | 21 | def test_basemessagestable(self): 22 | self.assertEqual(basemessagestable, dbreceivedmessagestable.basemessagestable) 23 | 24 | 25 | class TestClassBasics(unittest.TestCase): 26 | 27 | def setUp(self): 28 | self.example_payload_valid = dict(nonce='nonce_string', ciphertext='ciphertext_string') 29 | self.db_file_path = 'models/db/tests/testdb.sqlite' 30 | self.x = dbreceivedmessagestable.DBPReceivedMessagesTable(self.db_file_path) 31 | 32 | def tearDown(self): 33 | if os.path.isfile(self.db_file_path): 34 | os.remove(self.db_file_path) 35 | 36 | def test_instance(self): 37 | self.assertIsInstance(self.x, dbreceivedmessagestable.DBPReceivedMessagesTable) 38 | 39 | def test_instance_basemessagestable(self): 40 | self.assertIsInstance(self.x, basemessagestable.BaseMessagesTable) 41 | 42 | def test_instance_executor(self): 43 | self.assertIsInstance(self.x, dbexecutor.DBExecutor) 44 | 45 | def test_instance_abstract_table(self): 46 | self.assertIsInstance(self.x, abstractdbtable.AbstractDBTable) 47 | 48 | def test_db_executor_database_path_attribute_set(self): 49 | self.assertEqual(self.x.database, self.db_file_path) 50 | 51 | def test_table_name_class_attribute(self): 52 | target = 'ReceivedMessages' 53 | self.assertEqual(self.x.table_name, target) 54 | with self.assertRaises(AttributeError): 55 | self.x.table_name = 'hello' 56 | 57 | def test_data_row_name_class_attribute(self): 58 | target = 'ReceivedMessagesTableRow' 59 | self.assertEqual(self.x.data_row_name, target) 60 | with self.assertRaises(AttributeError): 61 | self.x.data_row_name = 'hello' 62 | -------------------------------------------------------------------------------- /disappeer/models/db/tests/test_dbsentmessagestable.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_dbsentmessagestable.py 3 | 4 | Test suite for DBSentMessagesTable class object and module 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import MagicMock 12 | from disappeer.models.db import dbsentmessagestable 13 | from disappeer.models.db.bases import abstractdbtable 14 | from disappeer.models.db import dbexecutor 15 | from disappeer.models.db.bases import basemessagestable 16 | import os 17 | 18 | 19 | class TestImports(unittest.TestCase): 20 | 21 | def test_basemessagestable(self): 22 | self.assertEqual(basemessagestable, dbsentmessagestable.basemessagestable) 23 | 24 | 25 | class TestClassBasics(unittest.TestCase): 26 | 27 | def setUp(self): 28 | self.example_payload_valid = dict(nonce='nonce_string', ciphertext='ciphertext_string') 29 | self.db_file_path = 'models/db/tests/testdb.sqlite' 30 | self.x = dbsentmessagestable.DBPSentMessagesTable(self.db_file_path) 31 | 32 | def tearDown(self): 33 | if os.path.isfile(self.db_file_path): 34 | os.remove(self.db_file_path) 35 | 36 | def test_instance(self): 37 | self.assertIsInstance(self.x, dbsentmessagestable.DBPSentMessagesTable) 38 | 39 | def test_instance_basemessagestable(self): 40 | self.assertIsInstance(self.x, basemessagestable.BaseMessagesTable) 41 | 42 | def test_instance_executor(self): 43 | self.assertIsInstance(self.x, dbexecutor.DBExecutor) 44 | 45 | def test_instance_abstract_table(self): 46 | self.assertIsInstance(self.x, abstractdbtable.AbstractDBTable) 47 | 48 | def test_db_executor_database_path_attribute_set(self): 49 | self.assertEqual(self.x.database, self.db_file_path) 50 | 51 | def test_table_name_class_attribute(self): 52 | target = 'SentMessages' 53 | self.assertEqual(self.x.table_name, target) 54 | with self.assertRaises(AttributeError): 55 | self.x.table_name = 'hello' 56 | 57 | def test_data_row_name_class_attribute(self): 58 | target = 'SentMessagesTableRow' 59 | self.assertEqual(self.x.data_row_name, target) 60 | with self.assertRaises(AttributeError): 61 | self.x.data_row_name = 'hello' 62 | -------------------------------------------------------------------------------- /disappeer/models/db/tests/testdatabasesmain.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/models/db/tests/testdatabasesmain.sqlite -------------------------------------------------------------------------------- /disappeer/models/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/models/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/models/tordatacontext.py: -------------------------------------------------------------------------------- 1 | """ 2 | tordatacontext.py 3 | 4 | Module for TorDataContext class object, to hold observables for onion addresses 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.utilities import observable 11 | 12 | 13 | class TorDataContext: 14 | 15 | def __init__(self, get_user_tor_keys_dir_method): 16 | self.get_user_tor_keys_dir_method = get_user_tor_keys_dir_method 17 | self.tor_request_proxy_addr = observable.Observable('None...') 18 | self.tor_response_proxy_addr = observable.Observable('None...') 19 | self.tor_message_proxy_addr = observable.Observable('None...') 20 | 21 | def get_tor_request_proxy_addr(self): 22 | result = self.tor_request_proxy_addr.get() 23 | return result 24 | 25 | def set_tor_request_proxy_addr(self, data): 26 | self.tor_request_proxy_addr.set(data) 27 | 28 | def get_tor_response_proxy_addr(self): 29 | result = self.tor_response_proxy_addr.get() 30 | return result 31 | 32 | def set_tor_response_proxy_addr(self, data): 33 | self.tor_response_proxy_addr.set(data) 34 | 35 | def get_tor_message_proxy_addr(self): 36 | result = self.tor_message_proxy_addr.get() 37 | return result 38 | 39 | def set_tor_message_proxy_addr(self, data): 40 | self.tor_message_proxy_addr.set(data) 41 | 42 | def add_tor_request_proxy_addr_observer(self, observer): 43 | self.tor_request_proxy_addr.add_observer(observer) 44 | 45 | def add_tor_response_proxy_addr_observer(self, observer): 46 | self.tor_response_proxy_addr.add_observer(observer) 47 | 48 | def add_tor_message_proxy_addr_observer(self, observer): 49 | self.tor_message_proxy_addr.add_observer(observer) 50 | 51 | def get_user_tor_keys_dir(self, keyid_name): 52 | result = self.get_user_tor_keys_dir_method(keyid_name) 53 | return result 54 | -------------------------------------------------------------------------------- /disappeer/net/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/net/__init__.py -------------------------------------------------------------------------------- /disappeer/net/bases/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/net/bases/__init__.py -------------------------------------------------------------------------------- /disappeer/net/bases/abstractclient.py: -------------------------------------------------------------------------------- 1 | """ 2 | abstractclient.py 3 | 4 | Module for the AbstractClient base class 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import abc 11 | import socket 12 | import socks 13 | 14 | 15 | class AbstractClient(metaclass=abc.ABCMeta): 16 | 17 | def __init__(self, argnamespace): 18 | self.argnamespace = argnamespace 19 | self.sock = None 20 | self.protocol = None 21 | self.error = None 22 | 23 | @property 24 | def host(self): 25 | return self.argnamespace.host 26 | 27 | @property 28 | def port(self): 29 | return self.argnamespace.port 30 | 31 | @property 32 | def interface(self): 33 | return self.host, self.port 34 | 35 | @property 36 | def payload_dict(self): 37 | return self.argnamespace.payload_dict 38 | 39 | @property 40 | def nonce(self): 41 | return self.argnamespace.nonce 42 | 43 | @property 44 | def command(self): 45 | return self.argnamespace.command 46 | 47 | @property 48 | def queue(self): 49 | return self.argnamespace.queue 50 | 51 | def create_socket(self): 52 | # Original socket object 53 | # self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 54 | # self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 55 | # self.sock.settimeout(10) 56 | # return self.sock 57 | 58 | # # Second version, with bytes string 59 | # self.sock = socks.socksocket() 60 | # self.sock.set_proxy(socks.PROXY_TYPE_SOCKS5, b'127.0.0.1', 9050, True) 61 | # return self.sock 62 | 63 | self.sock = socks.socksocket() 64 | self.sock.set_proxy(socks.PROXY_TYPE_SOCKS5, '127.0.0.1', 9050, True) 65 | return self.sock 66 | 67 | def connect(self): 68 | self.sock.connect(self.interface) 69 | 70 | @abc.abstractmethod 71 | def wrap_socket(self): 72 | raise NotImplementedError 73 | 74 | @abc.abstractmethod 75 | def set_protocol(self): 76 | raise NotImplementedError 77 | 78 | @abc.abstractmethod 79 | def send(self): 80 | raise NotImplementedError 81 | 82 | @abc.abstractmethod 83 | def handle_response(self): 84 | raise NotImplementedError 85 | 86 | def stop(self): 87 | self.sock.close() 88 | 89 | def configure_transport(self): 90 | try: 91 | self.create_socket() 92 | self.connect() 93 | self.wrap_socket() 94 | except (socket.error, ConnectionRefusedError) as err: 95 | self.error = err 96 | return err 97 | self.set_protocol() 98 | -------------------------------------------------------------------------------- /disappeer/net/bases/abstractserverfactory.py: -------------------------------------------------------------------------------- 1 | """ 2 | abstractserverfactory.py 3 | 4 | Abstract base class for server factories 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import abc 11 | from disappeer.constants import constants 12 | 13 | 14 | class AbstractServerFactory(metaclass=abc.ABCMeta): 15 | 16 | def __init__(self, queue): 17 | self.queue = queue 18 | 19 | @property 20 | @abc.abstractmethod 21 | def name(self): 22 | raise NotImplementedError 23 | 24 | @property 25 | @abc.abstractmethod 26 | def host(self): 27 | raise NotImplementedError 28 | 29 | @property 30 | @abc.abstractmethod 31 | def port(self): 32 | raise NotImplementedError 33 | 34 | @property 35 | def interface(self): 36 | return self.host, self.port 37 | 38 | @property 39 | @abc.abstractmethod 40 | def request_handler_obj(self): 41 | raise NotImplementedError 42 | 43 | @property 44 | @abc.abstractmethod 45 | def server_obj(self): 46 | raise NotImplementedError 47 | 48 | def build(self): 49 | try: 50 | server = self.server_obj(self.interface, self.request_handler_obj) 51 | except OSError as err: 52 | error_dict = dict(desc=constants.command_list.Server_Error, 53 | error=err, 54 | interface=self.interface) 55 | self.queue.put(error_dict) 56 | return None 57 | server.queue = self.queue 58 | return server 59 | -------------------------------------------------------------------------------- /disappeer/net/bases/baseprotocol.py: -------------------------------------------------------------------------------- 1 | """ 2 | baseprotocol.py 3 | 4 | BaseProtocol class object to encapsulate protocol networking code . . . 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.net.bases import packet 11 | import struct 12 | 13 | 14 | class BaseProtocol: 15 | 16 | max_message_length = 65535 17 | header = packet.Header 18 | header_length = header.length 19 | payload = packet.Payload 20 | 21 | def __init__(self, sock): 22 | self.sock = sock 23 | self.ack_string = 'ACK' 24 | self.request_string = 'REQ' 25 | self.response_string = 'RES' 26 | self.message_string = 'MSG' 27 | 28 | def build_packet(self, payload_dict, command_string): 29 | payload = packet.Payload(payload_dict) 30 | result = packet.PacketFactory(payload).build(command_string) 31 | return result 32 | 33 | def _recvall(self, sock, num): 34 | fragments = [] 35 | while len(b"".join(fragments)) < num: 36 | current = sock.recv(num - len(b"".join(fragments))) 37 | if not current: 38 | break 39 | fragments.append(current) 40 | return b"".join(fragments) 41 | 42 | def recv_header(self): 43 | header_data = self._recvall(self.sock, self.header_length) 44 | return header_data 45 | 46 | def recv_payload(self, payload_length): 47 | result = self._recvall(self.sock, payload_length) 48 | return result 49 | 50 | def validate_header(self, header_data, command_string): 51 | try: 52 | unpacked = self.header.unpack(header_data) 53 | except struct.error: 54 | return False 55 | 56 | length_val = unpacked[0] 57 | command_val = unpacked[1] 58 | if command_val != command_string: 59 | return False 60 | elif length_val > self.max_message_length: 61 | return False 62 | else: 63 | return unpacked 64 | 65 | def process_incoming(self, command_string): 66 | header_data = self.recv_header() 67 | header = self.validate_header(header_data, command_string) 68 | if not header: 69 | return False 70 | 71 | payload_data = self.recv_payload(header[0]) 72 | decoded = self.payload(payload_data).decode() 73 | return decoded -------------------------------------------------------------------------------- /disappeer/net/bases/clientcontroller.py: -------------------------------------------------------------------------------- 1 | """ 2 | clientcontroller.py 3 | 4 | Module for the ClientController class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.net.bases import clientfactory 11 | from disappeer.net.bases import threadmanagers 12 | 13 | 14 | class ClientController: 15 | 16 | def __init__(self, client_type, argnamespace): 17 | self.client_factory = clientfactory.ClientFactory(client_type, argnamespace) 18 | self.client = threadmanagers.ClientThreadManager(self.client_factory) 19 | 20 | def start(self): 21 | self.client.start() 22 | 23 | def stop(self): 24 | self.client.stop() 25 | -------------------------------------------------------------------------------- /disappeer/net/bases/clientfactory.py: -------------------------------------------------------------------------------- 1 | """ 2 | clientfactory.py 3 | 4 | Module for the ClientFactory class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.net.contact import contactrequestclient 11 | from disappeer.net.contactresponse import contactresponseclient 12 | from disappeer.net.message import messageclient 13 | 14 | 15 | class ClientFactory: 16 | 17 | def __init__(self, client_type, argnamespace): 18 | self.client_type = client_type 19 | self.name = self.client_type 20 | self.argnamespace = argnamespace 21 | 22 | def build(self): 23 | if self.client_type == 'contact_request': 24 | return self.create_contact_request_client() 25 | elif self.client_type == 'contact_response': 26 | return self.create_contact_response_client() 27 | elif self.client_type == 'send_message': 28 | return self.create_message_client() 29 | 30 | def create_contact_request_client(self): 31 | # TODO: Should command be hardcoded into the Client class object itself? 32 | self.argnamespace.command = 'REQ' 33 | client = contactrequestclient.ContactRequestClient(self.argnamespace) 34 | return client 35 | 36 | def create_contact_response_client(self): 37 | client = contactresponseclient.ContactResponseClient(self.argnamespace) 38 | return client 39 | 40 | def create_message_client(self): 41 | client = messageclient.MessageClient(self.argnamespace) 42 | return client 43 | -------------------------------------------------------------------------------- /disappeer/net/bases/packet.py: -------------------------------------------------------------------------------- 1 | """ 2 | packet.py 3 | 4 | Module for packet-related networking classes: Header, Payload, PacketFactory 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import struct 11 | import json 12 | 13 | 14 | class Header: 15 | length = 7 16 | format_constant = 'I 3s' 17 | header_struct = struct.Struct(format_constant) 18 | 19 | @classmethod 20 | def pack(cls, msg_len_int, msg_cmd_string): 21 | msg_cmd_bytes = bytes(msg_cmd_string, 'utf-8') 22 | packed = cls.header_struct.pack(msg_len_int, msg_cmd_bytes) 23 | return packed 24 | 25 | @classmethod 26 | def unpack(cls, packed_bytes): 27 | unpacked = cls.header_struct.unpack(packed_bytes) 28 | final = (unpacked[0], unpacked[1].decode('utf-8')) 29 | return final 30 | 31 | @classmethod 32 | def build(cls, payload, command_string): 33 | length_payload = len(payload) 34 | header = cls.pack(length_payload, command_string) 35 | return header 36 | 37 | 38 | class Payload: 39 | 40 | def __init__(self, data): 41 | self.data = data 42 | 43 | def encode(self): 44 | encoded = bytes(json.dumps(self.data), 'utf-8') 45 | return encoded 46 | 47 | def decode(self): 48 | decoded = self.data.decode('utf-8') 49 | result = json.loads(decoded) 50 | return result 51 | 52 | 53 | class PacketFactory: 54 | 55 | def __init__(self, payload): 56 | self.header = Header 57 | self.payload = payload 58 | 59 | def build(self, command_string): 60 | encoded_payload = self.payload.encode() 61 | header = self.header.build(encoded_payload, command_string) 62 | return header + encoded_payload 63 | -------------------------------------------------------------------------------- /disappeer/net/bases/servercontroller.py: -------------------------------------------------------------------------------- 1 | """ 2 | servercontroller.py 3 | 4 | Module for ServerController class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.utilities import observable 11 | 12 | 13 | class ServerController: 14 | 15 | def __init__(self, que, factory, manager): 16 | self.status = observable.Observable(False) 17 | self.queue = que 18 | self.factory = factory(self.queue) 19 | self.server = manager(self.factory) 20 | 21 | def start(self): 22 | self.server.start() 23 | self.status.set(True) 24 | 25 | def stop(self): 26 | self.server.stop() 27 | self.status.set(False) 28 | 29 | def get_status(self): 30 | return self.status.get() 31 | -------------------------------------------------------------------------------- /disappeer/net/bases/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/net/bases/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/net/bases/tests/test_clientcontroller.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_clientcontroller.py 3 | 4 | Test suite for the ClientController class object and module 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import MagicMock 12 | from disappeer.net.bases import clientcontroller 13 | from disappeer.net.bases import clientfactory 14 | from disappeer.net.bases import threadmanagers 15 | from types import SimpleNamespace 16 | 17 | 18 | class TestImports(unittest.TestCase): 19 | 20 | def test_clientfactory(self): 21 | self.assertEqual(clientfactory, clientcontroller.clientfactory) 22 | 23 | def test_threadmanager(self): 24 | self.assertEqual(threadmanagers, clientcontroller.threadmanagers) 25 | 26 | 27 | class TestClassBasics(unittest.TestCase): 28 | 29 | def setUp(self): 30 | self.client_type = 'contact_request' 31 | self.argnamespace = SimpleNamespace() 32 | self.argnamespace.test = 'test' 33 | self.x = clientcontroller.ClientController(self.client_type, self.argnamespace) 34 | 35 | def test_instance(self): 36 | self.assertIsInstance(self.x, clientcontroller.ClientController) 37 | 38 | def test_client_factory_attribute_is_factory_instance(self): 39 | self.assertIsInstance(self.x.client_factory, clientfactory.ClientFactory) 40 | 41 | def test_client_factory_internal_attributes(self): 42 | self.assertEqual(self.client_type, self.x.client_factory.client_type) 43 | self.assertEqual(self.argnamespace, self.x.client_factory.argnamespace) 44 | 45 | def test_client_attribute_is_instance_threadmanager(self): 46 | self.assertIsInstance(self.x.client, threadmanagers.ClientThreadManager) 47 | 48 | def test_start_method_calls_start_on_client_attribute(self): 49 | target = self.x.client = MagicMock() 50 | self.x.start() 51 | self.assertTrue(target.start.called) 52 | 53 | def test_stop_method_calls_stop_on_client_attribute(self): 54 | target = self.x.client = MagicMock() 55 | self.x.stop() 56 | self.assertTrue(target.stop.called) 57 | -------------------------------------------------------------------------------- /disappeer/net/bases/tests/test_servercontroller.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_servercontroller.py 3 | 4 | Test suite for the ServerController class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import MagicMock 12 | from disappeer.net.bases import servercontroller 13 | from disappeer.utilities import observable 14 | 15 | 16 | class TestImports(unittest.TestCase): 17 | 18 | def test_observable(self): 19 | self.assertEqual(observable, servercontroller.observable) 20 | 21 | 22 | class TestServerControllerClassBasics(unittest.TestCase): 23 | 24 | def setUp(self): 25 | self.queue = MagicMock() 26 | self.factory = MagicMock() 27 | self.manager = MagicMock() 28 | self.x = servercontroller.ServerController(self.queue, self.factory, self.manager) 29 | 30 | def test_instance(self): 31 | self.assertIsInstance(self.x, servercontroller.ServerController) 32 | 33 | def test_status_attribute_is_observable(self): 34 | self.assertIsInstance(self.x.status, observable.Observable) 35 | 36 | def test_status_observable_set_false(self): 37 | check = self.x.status.get() 38 | self.assertFalse(check) 39 | 40 | def test_queue_attribute_is_queue(self): 41 | self.assertEqual(self.x.queue, self.queue) 42 | 43 | def test_factory_attribute_is_factory_called_with_queue(self): 44 | check = self.factory(self.queue) 45 | self.assertEqual(self.x.factory, check) 46 | 47 | def test_server_attribute_is_manager_called_with_factory(self): 48 | check = self.manager(self.factory) 49 | self.assertEqual(self.x.server, check) 50 | 51 | def test_start_method_calls_start_on_server(self): 52 | self.x.start() 53 | self.assertTrue(self.x.server.start.called) 54 | 55 | def test_start_method_sets_status_true(self): 56 | self.x.start() 57 | self.assertTrue(self.x.status.get()) 58 | 59 | def test_stop_method_calls_stop_on_server(self): 60 | self.x.stop() 61 | self.assertTrue(self.x.server.stop.called) 62 | 63 | def test_stop_method_sets_status_false(self): 64 | self.x.stop() 65 | self.assertFalse(self.x.status.get()) 66 | 67 | def test_get_status_method(self): 68 | target = 'hello' 69 | self.x.status.set(target) 70 | check = self.x.get_status() 71 | self.assertEqual(target, check) 72 | -------------------------------------------------------------------------------- /disappeer/net/bases/threadmanagers.py: -------------------------------------------------------------------------------- 1 | """ 2 | threadmanagers.py 3 | 4 | Threadmanager module for: 5 | - AbstractThreadManager 6 | - ServerThreadManager concrete class 7 | - ClientThreadManager concrete class 8 | 9 | Copyright (C) 2018 Disappeer Labs 10 | License: GPLv3 11 | """ 12 | 13 | import abc 14 | import threading 15 | 16 | 17 | class AbstractThreadManager(metaclass=abc.ABCMeta): 18 | 19 | def __init__(self, factory): 20 | self.factory = factory 21 | self.widget_thread = None 22 | self.widget = None 23 | 24 | def start(self): 25 | self.widget = self.factory.build() 26 | self.widget_thread = threading.Thread(target=self.run_widget_command, name=self.factory.name) 27 | self.widget_thread.daemon = True 28 | self.widget_thread.start() 29 | 30 | @abc.abstractmethod 31 | def run_widget_command(self): 32 | raise NotImplementedError 33 | 34 | @abc.abstractmethod 35 | def stop(self): 36 | """ 37 | Stop data thread, set running flag. 38 | """ 39 | raise NotImplementedError 40 | 41 | 42 | class ServerThreadManager(AbstractThreadManager): 43 | 44 | def run_widget_command(self): 45 | # TODO: add try/except to catch Attribute Error if object does not exist 46 | self.widget.serve_forever() 47 | 48 | def stop(self): 49 | # TODO: add try/except to catch Attribute Error if object does not exist 50 | self.widget.shutdown() 51 | self.widget.server_close() 52 | 53 | 54 | class ClientThreadManager(AbstractThreadManager): 55 | 56 | def run_widget_command(self): 57 | self.widget.send() 58 | 59 | def stop(self): 60 | self.widget.stop() 61 | 62 | -------------------------------------------------------------------------------- /disappeer/net/contact/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/net/contact/__init__.py -------------------------------------------------------------------------------- /disappeer/net/contact/contactprotocol.py: -------------------------------------------------------------------------------- 1 | """ 2 | contactprotocol.py 3 | 4 | Module for the ContactProtocol class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.net.bases import baseprotocol 11 | 12 | 13 | class ContactProtocol(baseprotocol.BaseProtocol): 14 | 15 | def __init__(self, sock): 16 | super().__init__(sock) 17 | 18 | def send_request(self, payload_dict, command_string): 19 | packet = self.build_packet(payload_dict, command_string) 20 | self.sock.sendall(packet) 21 | 22 | def handle_response(self): 23 | payload = self.process_incoming(self.ack_string) 24 | self.sock.close() 25 | return payload 26 | 27 | def send_ack(self, payload_dict): 28 | packet = self.build_packet(payload_dict, self.ack_string) 29 | self.sock.sendall(packet) 30 | self.sock.close() 31 | -------------------------------------------------------------------------------- /disappeer/net/contact/contactrequestclient.py: -------------------------------------------------------------------------------- 1 | """ 2 | contactrequestclient.py 3 | 4 | Module for the ContactRequestClient class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.net.bases import abstractclient 11 | from disappeer.net.contact import contactprotocol 12 | from disappeer.constants import constants 13 | 14 | 15 | class ContactRequestClient(abstractclient.AbstractClient): 16 | 17 | def __init__(self, argnamespace): 18 | super().__init__(argnamespace) 19 | 20 | def set_protocol(self): 21 | self.protocol = contactprotocol.ContactProtocol(self.sock) 22 | 23 | def send(self): 24 | self.configure_transport() 25 | if self.error: 26 | self.report_error() 27 | return self.error 28 | else: 29 | self.protocol.send_request(self.payload_dict, self.command) 30 | self.handle_response() 31 | 32 | def handle_response(self): 33 | result = self.protocol.handle_response() 34 | self.report_result(result) 35 | 36 | def report_result(self, result): 37 | result_dict = self.build_result_dict(result) 38 | self.queue.put(result_dict) 39 | 40 | def build_result_dict(self, result): 41 | try: 42 | if result['nonce'] == self.nonce: 43 | nonce_check = True 44 | else: 45 | nonce_check = False 46 | except KeyError: 47 | nonce_check = False 48 | 49 | result_dict = dict(desc=constants.command_list.New_Contact_Req_Client_Res, 50 | result=result, 51 | nonce=self.nonce, 52 | nonce_valid=nonce_check, 53 | host=self.host) 54 | return result_dict 55 | 56 | def report_error(self): 57 | error_dict = self.build_error_dict() 58 | self.queue.put(error_dict) 59 | 60 | def build_error_dict(self): 61 | error_dict = dict(desc=constants.command_list.New_Contact_Req_Client_Err, 62 | error=self.error, 63 | host=self.host, 64 | port=self.port) 65 | return error_dict 66 | 67 | def wrap_socket(self): 68 | pass 69 | -------------------------------------------------------------------------------- /disappeer/net/contact/contactrequestfactory.py: -------------------------------------------------------------------------------- 1 | """ 2 | contactrequestfactory.py 3 | 4 | Module for ContactRequestFactory class object, for generating contact request payload dicts 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import hashlib 11 | import random 12 | import sys 13 | import json 14 | from disappeer import settings 15 | from disappeer.gpg.agents import signer 16 | 17 | 18 | class ContactRequestFactory: 19 | 20 | def __init__(self, contact_response_host_address, key_home_dir, passphrase): 21 | self.key_home_dir = key_home_dir 22 | self.gpgsigner = signer.Signer(self.key_home_dir) 23 | self.contact_response_host = contact_response_host_address 24 | self.contact_response_port = settings.port_contact_response_server 25 | self.passphrase = passphrase 26 | 27 | def build(self): 28 | encoded_data_dict = self.encode_data_dict() 29 | detached_sig = self.sign_encoded_data(encoded_data_dict) 30 | if len(detached_sig.data) == 0: 31 | return detached_sig 32 | else: 33 | request_dict = dict(data=encoded_data_dict, sig=str(detached_sig)) 34 | return request_dict 35 | 36 | def sign_encoded_data(self, encoded_data): 37 | result = self.gpgsigner.execute(encoded_data, None, self.passphrase, detach=True) 38 | return result 39 | 40 | def encode_data_dict(self): 41 | return json.dumps(self.construct_data_dict()) 42 | 43 | def construct_data_dict(self): 44 | data_dict = dict(gpg_pub_key=self.read_file(settings.gpg_host_pubkey), 45 | address_host=self.contact_response_host, 46 | address_port=self.contact_response_port, 47 | nonce=self.random_hash()) 48 | return data_dict 49 | 50 | def read_file(self, file_path): 51 | with open(file_path, 'r') as f: 52 | result = f.read() 53 | return result 54 | 55 | def random_hash(self): 56 | num_str = str(random.randint(0, sys.maxsize)) 57 | result = self.hash_message(num_str) 58 | return result 59 | 60 | def hash_message(self, message): 61 | hasher = hashlib.sha1() 62 | hasher.update(bytes(message, 'UTF-8')) 63 | digest = hasher.hexdigest() 64 | return digest 65 | 66 | -------------------------------------------------------------------------------- /disappeer/net/contact/contactrequestserver.py: -------------------------------------------------------------------------------- 1 | """ 2 | contactrequestserver.py 3 | 4 | Module for classes related to contact request server 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import socketserver 11 | from disappeer.net.bases import abstractserverfactory 12 | from disappeer.net.contact import contactprotocol 13 | from disappeer.net.contact import contactrequestvalidator 14 | from disappeer import settings 15 | from disappeer.constants import constants 16 | command_list = constants.command_list 17 | 18 | 19 | class ContactRequestServerFactory(abstractserverfactory.AbstractServerFactory): 20 | 21 | def __init__(self, queue): 22 | super().__init__(queue) 23 | 24 | @property 25 | def name(self): 26 | return 'Contact_Request_Server' 27 | 28 | @property 29 | def host(self): 30 | return 'localhost' 31 | 32 | @property 33 | def port(self): 34 | return settings.port_contact_request_server 35 | 36 | @property 37 | def request_handler_obj(self): 38 | return ContactRequestServerRequestHandler 39 | 40 | @property 41 | def server_obj(self): 42 | return ThreadedTCPServer 43 | 44 | 45 | class ContactRequestServerRequestHandler(socketserver.BaseRequestHandler): 46 | 47 | def setup(self): 48 | self.protocol = contactprotocol.ContactProtocol(self.request) 49 | 50 | def handle(self): 51 | result = self.protocol.process_incoming(self.protocol.request_string) 52 | if result is False: 53 | return False 54 | else: 55 | self.validate_result(result) 56 | 57 | def validate_result(self, result_dict): 58 | check = contactrequestvalidator.ContactRequestValidator(result_dict) 59 | if check.valid: 60 | self.handle_valid_result(check.result_dict) 61 | 62 | def handle_valid_result(self, result_dict): 63 | self.send_response(result_dict) 64 | self.put_to_queue(result_dict) 65 | 66 | def send_response(self, result_dict): 67 | response_dict = self.build_response_dict(result_dict) 68 | self.protocol.send_ack(response_dict) 69 | 70 | def put_to_queue(self, result_dict): 71 | result_dict['desc'] = command_list.New_Contact_Req 72 | self.server.queue.put(result_dict) 73 | 74 | def build_response_dict(self, result_dict): 75 | target = dict(gpg_pub_key=self.read_file(settings.gpg_host_pubkey), 76 | nonce=result_dict['nonce'], 77 | desc='ACK') 78 | return target 79 | 80 | def read_file(self, file_path): 81 | with open(file_path, 'r') as f: 82 | result = f.read() 83 | return result 84 | 85 | 86 | class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): 87 | allow_reuse_address = True 88 | -------------------------------------------------------------------------------- /disappeer/net/contact/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/net/contact/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/net/contactresponse/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/net/contactresponse/__init__.py -------------------------------------------------------------------------------- /disappeer/net/contactresponse/contactresponseclient.py: -------------------------------------------------------------------------------- 1 | """ 2 | contactresponseclient.py 3 | 4 | Module for the ContactResponseClient class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.net.bases import abstractclient 11 | from disappeer.net.contact import contactprotocol 12 | import ssl 13 | import tempfile 14 | from disappeer.constants import constants 15 | 16 | 17 | class ContactResponseClient(abstractclient.AbstractClient): 18 | 19 | def __init__(self, argnamespace): 20 | super().__init__(argnamespace) 21 | self.request_nonce = self.argnamespace.request_nonce 22 | 23 | def wrap_socket(self): 24 | pass 25 | 26 | def set_protocol(self): 27 | self.protocol = contactprotocol.ContactProtocol(self.sock) 28 | 29 | def send(self): 30 | self.configure_transport() 31 | if self.error: 32 | self.report_error() 33 | return self.error 34 | else: 35 | self.protocol.send_request(self.payload_dict, self.command) 36 | self.handle_response() 37 | 38 | def handle_response(self): 39 | result = self.protocol.handle_response() 40 | self.report_result(result) 41 | 42 | def report_result(self, result): 43 | result_dict = self.build_result_dict(result) 44 | self.queue.put(result_dict) 45 | 46 | def build_result_dict(self, result): 47 | try: 48 | if result['nonce'] == self.nonce: 49 | nonce_check = True 50 | else: 51 | nonce_check = False 52 | except KeyError: 53 | nonce_check = False 54 | 55 | result_dict = dict(desc=constants.command_list.New_Contact_Res_Client_Res, 56 | result=result, 57 | nonce=self.nonce, 58 | nonce_valid=nonce_check, 59 | request_nonce=self.request_nonce) 60 | return result_dict 61 | 62 | def report_error(self): 63 | error_dict = self.build_error_dict() 64 | self.queue.put(error_dict) 65 | 66 | def build_error_dict(self): 67 | error_dict = dict(desc=constants.command_list.New_Contact_Res_Client_Err, 68 | error=self.error, 69 | host=self.host, 70 | port=self.port, 71 | request_nonce=self.request_nonce) 72 | return error_dict 73 | -------------------------------------------------------------------------------- /disappeer/net/contactresponse/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/net/contactresponse/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/net/message/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/net/message/__init__.py -------------------------------------------------------------------------------- /disappeer/net/message/messageclient.py: -------------------------------------------------------------------------------- 1 | """ 2 | messageclient.py 3 | 4 | Module for MessageClient class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.net.bases import abstractclient 11 | from disappeer.net.contact import contactprotocol 12 | import tempfile 13 | import ssl 14 | from disappeer.constants import constants 15 | 16 | 17 | class MessageClient(abstractclient.AbstractClient): 18 | 19 | def __init__(self, argnamespace): 20 | super().__init__(argnamespace) 21 | 22 | def send(self): 23 | self.configure_transport() 24 | if self.error: 25 | self.report_error() 26 | return self.error 27 | else: 28 | self.protocol.send_request(self.payload_dict, self.command) 29 | self.handle_response() 30 | 31 | def handle_response(self): 32 | result = self.protocol.handle_response() 33 | self.report_result(result) 34 | 35 | def report_result(self, result): 36 | result_dict = self.build_result_dict(result) 37 | self.queue.put(result_dict) 38 | 39 | def build_result_dict(self, result): 40 | try: 41 | if result['nonce'] == self.nonce: 42 | nonce_check = True 43 | else: 44 | nonce_check = False 45 | except KeyError: 46 | nonce_check = False 47 | 48 | # TODO: Is the whole argnamespace required here? Just need datarecord and plaintext, no? 49 | # - keeping whole argnamespace might make it easier to resend the message on failure 50 | result_dict = dict(desc=constants.command_list.Send_New_Message_Client_Res, 51 | result=result, 52 | nonce=self.nonce, 53 | nonce_valid=nonce_check, 54 | host=self.host, 55 | port=self.port, 56 | argnamespace=self.argnamespace) 57 | return result_dict 58 | 59 | def report_error(self): 60 | error_dict = self.build_error_dict() 61 | self.queue.put(error_dict) 62 | 63 | def build_error_dict(self): 64 | error_dict = dict(desc=constants.command_list.Send_New_Message_Client_Err, 65 | error=self.error, 66 | host=self.host, 67 | port=self.port, 68 | nonce=self.nonce, 69 | argnamespace=self.argnamespace) 70 | return error_dict 71 | 72 | def set_protocol(self): 73 | self.protocol = contactprotocol.ContactProtocol(self.sock) 74 | 75 | def wrap_socket(self): 76 | pass 77 | 78 | -------------------------------------------------------------------------------- /disappeer/net/message/messageserver.py: -------------------------------------------------------------------------------- 1 | """ 2 | messageserver.py 3 | 4 | Module for message server related class objects 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import socketserver 11 | import ssl 12 | from disappeer import settings 13 | from disappeer.net.bases import abstractserverfactory 14 | from disappeer.net.contact import contactprotocol 15 | from disappeer.constants import constants 16 | 17 | 18 | class MessageServerFactory(abstractserverfactory.AbstractServerFactory): 19 | 20 | def __init__(self, queue): 21 | super().__init__(queue) 22 | 23 | @property 24 | def name(self): 25 | return 'Message_Server' 26 | 27 | @property 28 | def host(self): 29 | return 'localhost' 30 | 31 | @property 32 | def port(self): 33 | return settings.port_message_server 34 | 35 | @property 36 | def request_handler_obj(self): 37 | return SSLMessageRequestHandler 38 | 39 | @property 40 | def server_obj(self): 41 | return SSLThreadedMessageTCPServer 42 | 43 | 44 | class SSLMessageRequestHandler(socketserver.BaseRequestHandler): 45 | 46 | def setup(self): 47 | self.protocol = contactprotocol.ContactProtocol(self.request) 48 | 49 | def handle(self): 50 | result = self.protocol.process_incoming(self.protocol.message_string) 51 | if result is False: 52 | return False 53 | elif self.dict_keys_are_valid(result): 54 | self.handle_valid_result(result) 55 | 56 | def handle_valid_result(self, result_dict): 57 | self.send_response(result_dict) 58 | self.put_to_queue(result_dict) 59 | 60 | def send_response(self, result_dict): 61 | response_dict = self.build_response_dict(result_dict) 62 | self.protocol.send_ack(response_dict) 63 | 64 | def put_to_queue(self, result_dict): 65 | target = dict(desc=constants.command_list.Received_New_Message, 66 | payload=result_dict) 67 | self.server.queue.put(target) 68 | 69 | def build_response_dict(self, result_dict): 70 | target = dict(nonce=result_dict['nonce'], 71 | desc='ACK') 72 | return target 73 | 74 | def dict_keys_are_valid(self, result_dict): 75 | target_list = ['ciphertext', 'nonce'] 76 | if all(name in target_list for name in result_dict): 77 | return True 78 | else: 79 | return False 80 | 81 | 82 | class SSLThreadedMessageTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): 83 | allow_reuse_address = True 84 | 85 | 86 | -------------------------------------------------------------------------------- /disappeer/net/message/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/net/message/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/net/networkservers.py: -------------------------------------------------------------------------------- 1 | """ 2 | networkservers.py 3 | 4 | Module for NetworkServers class object, contains references to and controls for network servers 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.net.contact import contactrequestserver 11 | from disappeer.net.contactresponse import contactresponseserver 12 | from disappeer.net.message import messageserver 13 | from disappeer.net.bases import servercontroller 14 | from disappeer.net.bases import threadmanagers 15 | 16 | 17 | class NetworkServers: 18 | 19 | def __init__(self, queue): 20 | self.queue = queue 21 | self.contact_request_server = servercontroller.ServerController(self.queue, 22 | contactrequestserver.ContactRequestServerFactory, 23 | threadmanagers.ServerThreadManager) 24 | self.contact_response_server = servercontroller.ServerController(self.queue, 25 | contactresponseserver.ContactResponseServerFactory, 26 | threadmanagers.ServerThreadManager) 27 | self.message_server = servercontroller.ServerController(self.queue, 28 | messageserver.MessageServerFactory, 29 | threadmanagers.ServerThreadManager) 30 | 31 | def start_network_services(self): 32 | self.contact_request_server.start() 33 | self.contact_response_server.start() 34 | self.message_server.start() 35 | 36 | def stop_network_services(self): 37 | self.contact_request_server.stop() 38 | self.contact_response_server.stop() 39 | self.message_server.stop() 40 | 41 | def are_running(self): 42 | request = self.contact_request_server.get_status() 43 | response = self.contact_response_server.get_status() 44 | message = self.message_server.get_status() 45 | result = all([request, response, message]) 46 | return result 47 | 48 | -------------------------------------------------------------------------------- /disappeer/net/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/net/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/aboutbox/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/aboutbox/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/aboutbox/aboutboxcontroller.py: -------------------------------------------------------------------------------- 1 | """ 2 | aboutboxcontroller.py 3 | 4 | Module for the AboutBoxController popup 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.popups.bases import basepopupcontroller 11 | from disappeer.popups.aboutbox import aboutboxview 12 | 13 | 14 | class AboutBoxController(basepopupcontroller.BasePopupController): 15 | 16 | def __init__(self, root): 17 | super().__init__(root) 18 | self.view = aboutboxview.AboutBoxView(self.window) 19 | self.config_event_bindings() 20 | 21 | @property 22 | def title(self): 23 | return 'About' 24 | 25 | def config_event_bindings(self): 26 | pass 27 | 28 | -------------------------------------------------------------------------------- /disappeer/popups/alertbox/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/alertbox/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/alertbox/alertboxcontroller.py: -------------------------------------------------------------------------------- 1 | """ 2 | alertboxcontroller.py 3 | 4 | Module for AlertBoxController popup 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.popups.alertbox import alertboxview 11 | from disappeer.popups.bases import basepopupcontroller 12 | 13 | 14 | class AlertBoxController(basepopupcontroller.BasePopupController): 15 | 16 | def __init__(self, root, message): 17 | super().__init__(root) 18 | self.message = message 19 | self.view = alertboxview.AlertBoxView(self.window, self.message) 20 | self.config_event_bindings() 21 | 22 | @property 23 | def title(self): 24 | return 'Alert!' 25 | 26 | def config_event_bindings(self): 27 | self.view.cancel_button.bind("", self.cancel_button_clicked) 28 | -------------------------------------------------------------------------------- /disappeer/popups/bases/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/bases/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/bases/basepopupcontroller.py: -------------------------------------------------------------------------------- 1 | """ 2 | basepopupcontroller.py 3 | 4 | Module for BasePopupController, abstract base for all popup controller classes. 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import tkinter 11 | import abc 12 | 13 | 14 | class BasePopupController(abc.ABC): 15 | 16 | def __init__(self, root): 17 | self.root = root 18 | self.window = tkinter.Toplevel(self.root) 19 | self.window.title(self.title) 20 | self.output = None 21 | 22 | def show(self): 23 | self.window.transient(self.root) 24 | self.window.grab_set() 25 | self.window.deiconify() 26 | self.window.wait_window() 27 | return self.output 28 | 29 | def cancel_button_clicked(self, event): 30 | self.window.destroy() 31 | 32 | def set_output_and_close(self, output): 33 | self.output = output 34 | self.window.destroy() 35 | 36 | @abc.abstractmethod 37 | def config_event_bindings(self): 38 | raise NotImplementedError 39 | 40 | @property 41 | @abc.abstractmethod 42 | def title(self): 43 | return 'Default Base Title' 44 | 45 | -------------------------------------------------------------------------------- /disappeer/popups/blinkalert/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/blinkalert/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/blinkalert/blinkalertcontroller.py: -------------------------------------------------------------------------------- 1 | """ 2 | blinkalertcontroller.py 3 | 4 | Module for BlinkAlertController popup 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.popups.bases import basepopupcontroller 11 | from disappeer.popups.blinkalert import blinkalertview 12 | import tkinter 13 | 14 | 15 | class BlinkAlertController(basepopupcontroller.BasePopupController): 16 | 17 | def __init__(self, root, message): 18 | super().__init__(root) 19 | self.message = message 20 | self.set_window_attributes() 21 | self.window.geometry('250x100-0+0') 22 | self.view = blinkalertview.BlinkAlertView(self.window, self.message) 23 | self.blink_count = 0 24 | 25 | @property 26 | def title(self): 27 | return 'Alert!' 28 | 29 | def set_window_attributes(self): 30 | self.window.attributes() 31 | self.window.attributes("-alpha", 0.0) 32 | 33 | def config_event_bindings(self): 34 | pass 35 | 36 | def show(self): 37 | self.fade_in() 38 | 39 | def fade_in(self): 40 | if self.blink_count >= 3: 41 | self.cancel_button_clicked(None) 42 | return None 43 | 44 | try: 45 | alpha = self.window.attributes("-alpha") 46 | except tkinter.TclError as err: 47 | return None 48 | 49 | if alpha < 1: 50 | alpha += .03 51 | self.window.attributes("-alpha", alpha) 52 | self.root.after(50, self.fade_in) 53 | else: 54 | self.blink_count += 1 55 | self.root.after(2000, self.fade_away) 56 | 57 | def fade_away(self): 58 | try: 59 | alpha = self.window.attributes("-alpha") 60 | except tkinter.TclError as err: 61 | return None 62 | 63 | if alpha > 0: 64 | alpha -= .1 65 | self.window.attributes("-alpha", alpha) 66 | self.root.after(50, self.fade_away) 67 | else: 68 | self.fade_in() -------------------------------------------------------------------------------- /disappeer/popups/blinkalert/blinkalertview.py: -------------------------------------------------------------------------------- 1 | """ 2 | blinkalertview.py 3 | 4 | View module for BlinkAlert popup window 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import tkinter 11 | import tkinter.ttk as ttk 12 | from disappeer.constants import constants 13 | from disappeer.constants import styling 14 | import logging 15 | 16 | log = logging.getLogger(constants.title) 17 | 18 | 19 | class BlinkAlertView: 20 | """ 21 | View for Key Info popup window. Takes raw key_dict to populate forms. 22 | """ 23 | 24 | def __init__(self, window, message): 25 | self.message = message 26 | self.window = window 27 | self.window.columnconfigure(0, weight=1) 28 | self.window.rowconfigure(0, weight=1) 29 | styling.config_ttk_styling() 30 | self.setup() 31 | 32 | def setup(self): 33 | self.config_main_frame() 34 | self.config_form_elements() 35 | 36 | def config_main_frame(self): 37 | """ 38 | Main frame, two rows, one column. 39 | """ 40 | self.main_frame = tkinter.Frame(self.window, background=styling.background_color, padx=10, pady=10) 41 | self.main_frame.grid(row=0, column=0, sticky=styling.sticky_all) 42 | self.main_frame.columnconfigure(0, weight=1) 43 | 44 | # Form elements frame row 45 | self.main_frame.rowconfigure(0, weight=1) 46 | 47 | # Form buttons frame row 48 | # self.main_frame.rowconfigure(1, weight=0) 49 | 50 | def config_form_elements(self): 51 | """ 52 | For each item in key info ordered fields list, create label and entry. 53 | Label is from ordered field list. Entry is corresponding val from self.key_dict. 54 | """ 55 | elements_frame = tkinter.Frame(self.main_frame, **styling.alert_box_elements_frame) 56 | elements_frame.grid(row=0, column=0, sticky=styling.sticky_all, pady=(0, 10)) 57 | 58 | elements_frame.columnconfigure(0, weight=1) 59 | elements_frame.rowconfigure(0, weight=1) 60 | 61 | self.alert_text_box = tkinter.Label(elements_frame, text=self.message, **styling.label_args_small_font) 62 | self.alert_text_box.grid(row=0, column=0, sticky=styling.sticky_all, pady=(0, 5)) 63 | 64 | def config_form_buttons(self): 65 | button_frame = tkinter.Frame(self.main_frame, relief='raised', background='yellow') 66 | button_frame.grid(row=1, column=0, sticky=styling.sticky_ew) 67 | 68 | button_frame.rowconfigure(0, weight=0) 69 | button_frame.columnconfigure(0, weight=1) 70 | 71 | self.cancel_button = ttk.Button(button_frame, text='OK') 72 | self.cancel_button.grid(row=0, column=0, sticky=styling.sticky_ew) -------------------------------------------------------------------------------- /disappeer/popups/contactrequest/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/contactrequest/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/contactrequest/contactrequestcontroller.py: -------------------------------------------------------------------------------- 1 | """ 2 | contactrequestcontroller.py 3 | 4 | Module for ContactRequestController class object, for contact request popup 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.popups.bases import basepopupcontroller 11 | from disappeer.popups.contactrequest import contactrequestview 12 | from disappeer.net.contact import contactrequestvalidator 13 | 14 | 15 | class ContactRequestController(basepopupcontroller.BasePopupController): 16 | 17 | def __init__(self, root, request_record): 18 | super().__init__(root) 19 | self.request_record = request_record 20 | self.data_dict = self.construct_contact_req_dict(self.request_record) 21 | self.validator = contactrequestvalidator.ContactRequestValidator(self.data_dict) 22 | if self.validator.valid: 23 | self.view = contactrequestview.ContactRequestView(self.window, self.validator.key_dict) 24 | self.config_event_bindings() 25 | else: 26 | self.handle_invalid_request() 27 | 28 | @property 29 | def title(self): 30 | return 'New Contact Request' 31 | 32 | def config_event_bindings(self): 33 | self.view.cancel_button.bind("", self.cancel_button_clicked) 34 | self.view.accept_button.bind("", self.accept_button_clicked) 35 | self.view.reject_button.bind("", self.reject_button_clicked) 36 | 37 | def construct_contact_req_dict(self, request_record): 38 | result = dict(sig=request_record.sig, data=request_record.data) 39 | return result 40 | 41 | def handle_invalid_request(self): 42 | self.set_output_and_close('invalid') 43 | 44 | def accept_button_clicked(self, event): 45 | self.set_output_and_close('accept') 46 | 47 | def reject_button_clicked(self, event): 48 | self.set_output_and_close('reject') 49 | -------------------------------------------------------------------------------- /disappeer/popups/deletekey/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/deletekey/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/deletekey/deletekeycontroller.py: -------------------------------------------------------------------------------- 1 | """ 2 | deletekeycontroller.py 3 | 4 | Module for popup DeleteKeyController class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.popups.deletekey import deletekeyview 11 | from disappeer.popups.bases import basepopupcontroller 12 | 13 | 14 | class DeleteKeyController(basepopupcontroller.BasePopupController): 15 | 16 | def __init__(self, root, key_list): 17 | super().__init__(root) 18 | self.key_list = key_list 19 | self.view = deletekeyview.DeleteKeyView(self.window, self.key_list) 20 | self.config_event_bindings() 21 | 22 | @property 23 | def title(self): 24 | return 'Delete Keys' 25 | 26 | def config_event_bindings(self): 27 | self.view.cancel_button.bind("", self.cancel_button_clicked) 28 | self.view.delete_key_button.bind("", self.delete_button_clicked) 29 | 30 | def delete_button_clicked(self, event): 31 | packed_val_tuple_list = self.read_check_button_vals_and_pack_list() 32 | targets = self.build_deletion_targets_list(packed_val_tuple_list) 33 | if len(targets) > 0: 34 | self.set_output_and_close(targets) 35 | 36 | def read_check_button_vals_and_pack_list(self): 37 | result_list = [] 38 | for idx, item in enumerate(self.key_list): 39 | uid = item['uids'] 40 | fingerprint = item['fingerprint'] 41 | val = self.view.int_vars[idx].get() 42 | pack = (val, fingerprint, uid) 43 | result_list.append(pack) 44 | return result_list 45 | 46 | def build_deletion_targets_list(self, packed_val_tuple_list): 47 | targets = [] 48 | for item in packed_val_tuple_list: 49 | if item[0]: 50 | targets.append(item[1]) 51 | return targets 52 | -------------------------------------------------------------------------------- /disappeer/popups/displaymessage/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/displaymessage/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/displaymessage/displaymessagecontroller.py: -------------------------------------------------------------------------------- 1 | """ 2 | displaymessagecontroller.py 3 | 4 | Module for DisplayMessageController popup 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.popups.bases import basepopupcontroller 11 | from disappeer.popups.displaymessage import displaymessageview 12 | 13 | 14 | class DisplayMessageController(basepopupcontroller.BasePopupController): 15 | 16 | def __init__(self, root, argnamespace): 17 | """ 18 | 19 | :param root: 20 | :param argnamespace: must contain: .message_type, .message_to, .message_from, .message_text 21 | """ 22 | super().__init__(root) 23 | self.argnamespace = argnamespace 24 | self.view = displaymessageview.DisplayMessageView(self.window, self.argnamespace) 25 | self.config_event_bindings() 26 | 27 | @property 28 | def title(self): 29 | return 'Message' 30 | 31 | def config_event_bindings(self): 32 | command_button_release_1 = "" 33 | self.view.cancel_button.bind(command_button_release_1, self.cancel_button_clicked) 34 | self.view.delete_button.bind(command_button_release_1, self.delete_button_clicked) 35 | self.view.inspect_button.bind(command_button_release_1, self.inspect_button_clicked) 36 | 37 | def delete_button_clicked(self, event): 38 | self.set_output_and_close('delete') 39 | 40 | def inspect_button_clicked(self, event): 41 | self.set_output_and_close('inspect') 42 | -------------------------------------------------------------------------------- /disappeer/popups/displaysentrequest/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/displaysentrequest/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/displaysentrequest/displaysentrequestcontroller.py: -------------------------------------------------------------------------------- 1 | """ 2 | displaysentrequestcontroller.py 3 | 4 | Module for popup DisplaySentRequestController, to display info in popup on click of sent request item. 5 | Display host address and pubkey info 6 | 7 | Copyright (C) 2018 Disappeer Labs 8 | License: GPLv3 9 | """ 10 | 11 | from disappeer.popups.displaysentrequest import displaysentrequestview 12 | from disappeer.popups.bases import basepopupcontroller 13 | from disappeer.gpg.helpers import gpgpubkeyvalidator 14 | 15 | 16 | class DisplaySentRequestController(basepopupcontroller.BasePopupController): 17 | 18 | def __init__(self, root, gpg_pub_key_string, onion_address): 19 | super().__init__(root) 20 | self.gpg_pub_key = gpg_pub_key_string 21 | self.address = onion_address 22 | self.pubkey_validator = gpgpubkeyvalidator.GPGPubKeyValidator(self.gpg_pub_key) 23 | if self.pubkey_validator.valid: 24 | self.view = displaysentrequestview.DisplaySentRequestView(self.window, 25 | self.pubkey_validator.key_dict, 26 | self.address) 27 | self.config_event_bindings() 28 | else: 29 | pass 30 | # TODO: ADD ELSE CLAUSE FOR INVALID KEY 31 | 32 | @property 33 | def title(self): 34 | return 'Sent Request Peer Info' 35 | 36 | def config_event_bindings(self): 37 | self.view.cancel_button.bind("", self.cancel_button_clicked) 38 | 39 | 40 | -------------------------------------------------------------------------------- /disappeer/popups/getpassphrase/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/getpassphrase/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/getpassphrase/getpassphrasecontroller.py: -------------------------------------------------------------------------------- 1 | """ 2 | getpassphrasecontroller.py 3 | 4 | Module for popup GetPassphraseController class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.popups.getpassphrase import getpassphraseview 11 | from disappeer.popups.bases import basepopupcontroller 12 | 13 | 14 | class GetPassphraseController(basepopupcontroller.BasePopupController): 15 | 16 | def __init__(self, root): 17 | super().__init__(root) 18 | self.view = getpassphraseview.GetPassphraseView(self.window) 19 | self.config_event_bindings() 20 | 21 | @property 22 | def title(self): 23 | return 'Enter Passphrase' 24 | 25 | def config_event_bindings(self): 26 | self.view.cancel_button.bind("", self.cancel_button_clicked) 27 | self.view.submit_button.bind("", self.submit_button_clicked) 28 | self.view.passphrase_entry.focus_force() 29 | 30 | def submit_button_clicked(self, event): 31 | user_input = self.view.passphrase_entry.get() 32 | self.set_output_and_close(user_input) 33 | 34 | -------------------------------------------------------------------------------- /disappeer/popups/getsessionpassphrase/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/getsessionpassphrase/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/getsessionpassphrase/getsessionpassphrasecontroller.py: -------------------------------------------------------------------------------- 1 | """ 2 | getsessionpassphrasecontroller.py 3 | 4 | Module for the popup GetSessionPassphraseController 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.popups.bases import basepopupcontroller 11 | from disappeer.popups.getsessionpassphrase import getsessionpassphraseview 12 | 13 | 14 | class GetSessionPassphraseController(basepopupcontroller.BasePopupController): 15 | 16 | def __init__(self, root): 17 | super().__init__(root) 18 | self.view = getsessionpassphraseview.GetSessionPassphraseView(self.window) 19 | self.config_event_bindings() 20 | 21 | @property 22 | def title(self): 23 | return 'Enter Session Passphrase' 24 | 25 | def config_event_bindings(self): 26 | self.view.cancel_button.bind("", self.cancel_button_clicked) 27 | self.view.submit_button.bind("", self.submit_button_clicked) 28 | self.view.passphrase_entry.focus_force() 29 | 30 | def submit_button_clicked(self, event): 31 | user_input = self.view.passphrase_entry.get() 32 | self.set_output_and_close(user_input) 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /disappeer/popups/keyinfo/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/keyinfo/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/keyinfo/keyinfocontroller.py: -------------------------------------------------------------------------------- 1 | """ 2 | keyinfocontroller.py 3 | 4 | Module for KeyInfoController popup controller 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.popups.keyinfo import keyinfoview 11 | from disappeer.popups.bases import basepopupcontroller 12 | 13 | 14 | class KeyInfoController(basepopupcontroller.BasePopupController): 15 | 16 | def __init__(self, root, key_dict): 17 | super().__init__(root) 18 | self.key_dict = key_dict 19 | self.view = keyinfoview.KeyInfoView(self.window, self.key_dict) 20 | self.config_event_bindings() 21 | 22 | @property 23 | def title(self): 24 | return 'Key Info' 25 | 26 | def config_event_bindings(self): 27 | self.view.cancel_button.bind("", self.close_window) 28 | 29 | def close_window(self, event): 30 | self.set_output_and_close(self.key_dict) 31 | -------------------------------------------------------------------------------- /disappeer/popups/newkey/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/newkey/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/newkey/newkeycontroller.py: -------------------------------------------------------------------------------- 1 | """ 2 | newkeycontroller.py 3 | 4 | Contains NewKeyController, controller class for new key popup 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.popups.bases import basepopupcontroller 11 | from disappeer.popups.newkey import newkeyview 12 | from disappeer.constants import constants 13 | 14 | 15 | class NewKeyController(basepopupcontroller.BasePopupController): 16 | 17 | def __init__(self, root): 18 | super().__init__(root) 19 | self.view = newkeyview.NewKeyView(self.window) 20 | self.config_event_bindings() 21 | 22 | @property 23 | def title(self): 24 | return 'Create New Key' 25 | 26 | def config_event_bindings(self): 27 | self.view.cancel_button.bind("", self.cancel_button_clicked) 28 | self.view.reset_button.bind("", self.reset_button_clicked) 29 | self.view.create_new_key_button.bind("", self.create_new_key_button_clicked) 30 | 31 | def reset_button_clicked(self, event): 32 | self.view.reset_entry_vals() 33 | 34 | def create_new_key_button_clicked(self, event): 35 | vals = self.get_view_string_var_vals() 36 | zipped_dict = self.zip_key_dict(vals) 37 | final = self.prepare_output_dict(zipped_dict) 38 | self.set_output_and_close(final) 39 | return final 40 | 41 | def get_view_string_var_vals(self): 42 | vals = [x.get() for x in self.view.string_vars] 43 | return vals 44 | 45 | def zip_key_dict(self, vals): 46 | form_field_vals_dict = dict(zip(constants.new_key_ordered_field_labels, vals)) 47 | return form_field_vals_dict 48 | 49 | def prepare_output_dict(self, zipped_key_dict): 50 | output_dict = {} 51 | for item in constants.new_key_ordered_field_labels: 52 | key = constants.new_key_input_dict[item] 53 | val = zipped_key_dict[item] 54 | output_dict[key] = val 55 | return output_dict -------------------------------------------------------------------------------- /disappeer/popups/peerconnect/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/peerconnect/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/peerconnect/peerconnectcontroller.py: -------------------------------------------------------------------------------- 1 | """ 2 | peerconnectcontroller.py 3 | 4 | Module for controller for PeerConnect popup window. 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.popups.peerconnect import peerconnectview 11 | from disappeer.popups.bases import basepopupcontroller 12 | import tkinter 13 | 14 | 15 | class PeerConnectController(basepopupcontroller.BasePopupController): 16 | 17 | def __init__(self, root): 18 | super().__init__(root) 19 | self.view = peerconnectview.PeerConnectView(self.window) 20 | self.config_event_bindings() 21 | 22 | @property 23 | def title(self): 24 | return 'Peer Connect' 25 | 26 | def config_event_bindings(self): 27 | self.view.cancel_button.bind("", self.cancel_button_clicked) 28 | self.view.connect_button.bind("", self.connect_button_clicked) 29 | 30 | def connect_button_clicked(self, event): 31 | host = self.view.host_entry_var.get() 32 | port = self.view.port_entry_var.get() 33 | result = (host, port) 34 | self.set_output_and_close(result) 35 | -------------------------------------------------------------------------------- /disappeer/popups/peercontact/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/peercontact/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/peercontact/peercontactcontroller.py: -------------------------------------------------------------------------------- 1 | """ 2 | peercontactcontroller.py 3 | 4 | Module for PeerContactController module and class object for PeerContact popup 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.popups.bases import basepopupcontroller 11 | from disappeer.popups.peercontact import peercontactview 12 | from disappeer.gpg.helpers import gpgpubkeyvalidator 13 | 14 | 15 | class PeerContactController(basepopupcontroller.BasePopupController): 16 | 17 | def __init__(self, root, data_record): 18 | super().__init__(root) 19 | self.data_record = data_record 20 | self.pubkey_validator = gpgpubkeyvalidator.GPGPubKeyValidator(self.data_record.gpg_pub_key) 21 | 22 | if self.pubkey_validator.valid: 23 | self.view = peercontactview.PeerContactView(self.window, self.pubkey_validator.key_dict) 24 | self.config_event_bindings() 25 | else: 26 | self.handle_invalid_data_record() 27 | 28 | @property 29 | def title(self): 30 | return 'Peer Contact' 31 | 32 | def config_event_bindings(self): 33 | self.view.cancel_button.bind("", self.cancel_button_clicked) 34 | self.view.send_button.bind("", self.send_button_clicked) 35 | self.view.delete_button.bind("", self.delete_button_clicked) 36 | 37 | def handle_invalid_data_record(self): 38 | self.set_output_and_close('invalid') 39 | 40 | def send_button_clicked(self, event): 41 | self.set_output_and_close('send') 42 | 43 | def delete_button_clicked(self, event): 44 | self.set_output_and_close('delete') 45 | 46 | -------------------------------------------------------------------------------- /disappeer/popups/sendmessage/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/sendmessage/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/sendmessage/sendmessagecontroller.py: -------------------------------------------------------------------------------- 1 | """ 2 | sendmessagecontroller.py 3 | 4 | Module for the SendMessageController popup class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.popups.sendmessage import sendmessageview 11 | from disappeer.popups.bases import basepopupcontroller 12 | 13 | 14 | class SendMessageController(basepopupcontroller.BasePopupController): 15 | 16 | def __init__(self, root, recipient_data_record, console_text): 17 | super().__init__(root) 18 | self.recipient_data_record = recipient_data_record 19 | self.console_text = console_text 20 | self.view = sendmessageview.SendMessageView(self.window, 21 | self.recipient_data_record.gpg_uid, 22 | self.console_text) 23 | self.config_event_bindings() 24 | 25 | @property 26 | def title(self): 27 | return 'Send Message' 28 | 29 | def config_event_bindings(self): 30 | self.view.cancel_button.bind("", self.cancel_button_clicked) 31 | self.view.send_button.bind("", self.send_button_clicked) 32 | 33 | def send_button_clicked(self, event): 34 | message = self.view.get_text_area() 35 | self.set_output_and_close(message) 36 | 37 | -------------------------------------------------------------------------------- /disappeer/popups/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/tests/aboutbox/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/tests/aboutbox/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/tests/aboutbox/test_aboutboxcontroller.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_aboutboxcontroller.py 3 | 4 | Test suite for the popup AboutBoxController module for the about info window 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import MagicMock, patch 12 | from disappeer.popups.aboutbox import aboutboxview 13 | from disappeer.popups.bases import basepopupcontroller 14 | from disappeer.popups.aboutbox import aboutboxcontroller 15 | import tkinter 16 | 17 | 18 | class TestImports(unittest.TestCase): 19 | 20 | def test_alertbox_view(self): 21 | self.assertEqual(aboutboxview, aboutboxcontroller.aboutboxview) 22 | 23 | def test_basecontroller(self): 24 | self.assertEqual(basepopupcontroller, aboutboxcontroller.basepopupcontroller) 25 | 26 | 27 | class TestAboutBoxControllerClassBasics(unittest.TestCase): 28 | 29 | def setUp(self): 30 | self.root = tkinter.Tk() 31 | self.x = aboutboxcontroller.AboutBoxController(self.root) 32 | 33 | def test_instance(self): 34 | self.assertIsInstance(self.x, aboutboxcontroller.AboutBoxController) 35 | 36 | def test_instance_basecontroller(self): 37 | self.assertIsInstance(self.x, basepopupcontroller.BasePopupController) 38 | 39 | def test_title(self): 40 | name = "About" 41 | self.assertEqual(name, self.x.title) 42 | 43 | def test_config_event_bindings_attribute(self): 44 | name = 'config_event_bindings' 45 | check = hasattr(self.x, name) 46 | self.assertTrue(check) 47 | 48 | def test_root_attribute_set(self): 49 | self.assertEqual(self.root, self.x.root) 50 | 51 | def test_view_attribute(self): 52 | self.assertIsInstance(self.x.view, aboutboxview.AboutBoxView) 53 | 54 | -------------------------------------------------------------------------------- /disappeer/popups/tests/alertbox/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/tests/alertbox/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/tests/alertbox/test_alertboxcontroller.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_alertboxcontroller.py 3 | 4 | Test suite for AlertBoxController module popup 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import MagicMock, patch 12 | from disappeer.popups.alertbox import alertboxview 13 | from disappeer.popups.bases import basepopupcontroller 14 | from disappeer.popups.alertbox import alertboxcontroller 15 | import tkinter 16 | 17 | 18 | class TestImports(unittest.TestCase): 19 | 20 | def test_alertbox_view(self): 21 | self.assertEqual(alertboxview, alertboxcontroller.alertboxview) 22 | 23 | def test_basecontroller(self): 24 | self.assertEqual(basepopupcontroller, alertboxcontroller.basepopupcontroller) 25 | 26 | 27 | class TestAlertBoxControllerClassBasics(unittest.TestCase): 28 | 29 | def setUp(self): 30 | self.root = tkinter.Tk() 31 | self.msg = "This is a test message" 32 | self.x = alertboxcontroller.AlertBoxController(self.root, self.msg) 33 | 34 | def test_instance(self): 35 | self.assertIsInstance(self.x, alertboxcontroller.AlertBoxController) 36 | 37 | def test_instance_basecontroller(self): 38 | self.assertIsInstance(self.x, basepopupcontroller.BasePopupController) 39 | 40 | def test_title(self): 41 | name = "Alert!" 42 | self.assertEqual(name, self.x.title) 43 | 44 | def test_config_event_bindings_attribute(self): 45 | name = 'config_event_bindings' 46 | check = hasattr(self.x, name) 47 | self.assertTrue(check) 48 | 49 | def test_root_attribute_set(self): 50 | self.assertEqual(self.root, self.x.root) 51 | 52 | def test_message_attribute_set(self): 53 | self.assertEqual(self.msg, self.x.message) 54 | 55 | def test_view_attribute(self): 56 | self.assertIsInstance(self.x.view, alertboxview.AlertBoxView) 57 | 58 | def test_config_event_bindings_calls_bind_on_cancel_button(self): 59 | self.x.view = MagicMock() 60 | self.x.view.cancel_button = MagicMock() 61 | self.x.config_event_bindings() 62 | self.assertTrue(self.x.view.cancel_button.bind.called) 63 | 64 | @patch.object(alertboxcontroller.AlertBoxController, 'config_event_bindings') 65 | def test_config_event_bindings_method_called_by_constructor(self, mocked): 66 | x = alertboxcontroller.AlertBoxController(self.root, self.msg) 67 | self.assertTrue(mocked.called) -------------------------------------------------------------------------------- /disappeer/popups/tests/bases/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/tests/bases/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/tests/blinkalert/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/tests/blinkalert/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/tests/contactrequest/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/tests/contactrequest/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/tests/deletekey/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/tests/deletekey/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/tests/displaymessage/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/tests/displaymessage/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/tests/displaysentrequest/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/tests/displaysentrequest/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/tests/getpassphrase/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/tests/getpassphrase/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/tests/getsessionpassphrase/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/tests/getsessionpassphrase/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/tests/keyinfo/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/tests/keyinfo/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/tests/newkey/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/tests/newkey/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/tests/peerconnect/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/tests/peerconnect/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/tests/peercontact/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/tests/peercontact/__init__.py -------------------------------------------------------------------------------- /disappeer/popups/tests/sendmessage/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/popups/tests/sendmessage/__init__.py -------------------------------------------------------------------------------- /disappeer/requests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/requests/__init__.py -------------------------------------------------------------------------------- /disappeer/requests/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/requests/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/root/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/root/__init__.py -------------------------------------------------------------------------------- /disappeer/root/rightpanel.py: -------------------------------------------------------------------------------- 1 | """ 2 | rightpanel.py 3 | 4 | right Panel View for Main Window Paneled View 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import logging 11 | import tkinter 12 | import tkinter.ttk as ttk 13 | from disappeer.console import consoleframe 14 | from disappeer.constants import constants 15 | from disappeer.constants import styling 16 | 17 | log = logging.getLogger(constants.title) 18 | 19 | 20 | class RightPanelView: 21 | """ 22 | Main right panel view for root window 23 | """ 24 | 25 | def __init__(self, parent): 26 | self.parent = parent 27 | self.setup() 28 | 29 | def setup(self): 30 | self.config_main_frame() 31 | self.config_notebook() 32 | self.parent.add(self.main_frame) 33 | 34 | def config_main_frame(self): 35 | """ 36 | Main outermost frame for right panel. 37 | """ 38 | self.main_frame = tkinter.Frame(self.parent, background=styling.background_color) 39 | self.main_frame.columnconfigure(0, weight=1) 40 | self.main_frame.rowconfigure(0, weight=1) 41 | 42 | def config_notebook(self): 43 | """ 44 | Configure ttk notebook widget and call methods for its tab widgets 45 | """ 46 | self.notebook = ttk.Notebook(self.main_frame, padding=(10, 5, 10, 10)) 47 | 48 | self.config_console_tab() 49 | 50 | # Enable to configure more notebaook tabs in frame 51 | # tab1 = tkinter.Frame(self.notebook, background=styling.background_color) 52 | # self.notebook.add(tab1, text="Monitor") 53 | 54 | self.notebook.grid(row=0, column=0, sticky=styling.sticky_all) 55 | 56 | def config_console_tab(self): 57 | self.console_frame = consoleframe.ConsoleFrame(self.notebook) 58 | self.console_frame.grid(sticky=styling.sticky_all) 59 | self.notebook.add(self.console_frame, text="Console") 60 | 61 | -------------------------------------------------------------------------------- /disappeer/root/rootparameters.py: -------------------------------------------------------------------------------- 1 | """ 2 | rootparamesters.py 3 | 4 | Module for RootParameters object, for encapsulating root params to be passed into controllers. 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | from disappeer.utilities import observable 11 | 12 | 13 | class RootParameters: 14 | 15 | def __init__(self, root_obj, root_view, root_queue, database_facade, host_key_observer): 16 | self.root = root_obj 17 | self.root_view = root_view 18 | self.root_queue = root_queue 19 | self.database_facade = database_facade 20 | self.host_key_observer = host_key_observer 21 | self.tor_proxy_running_observable = observable.Observable(False) 22 | self.host_key_session_passphrase_observable = observable.Observable() 23 | 24 | def get_tor_net_frame(self): 25 | return self.root_view.left_panel.tor_net_frame 26 | 27 | def get_requests_frame(self): 28 | return self.root_view.left_panel.requests_frame 29 | 30 | def get_gpg_frame(self): 31 | return self.root_view.left_panel.gpg_frame 32 | 33 | def get_messages_frame(self): 34 | return self.root_view.left_panel.messages_frame 35 | 36 | def get_console_frame(self): 37 | return self.root_view.right_panel.console_frame 38 | 39 | def get_root_menubar(self): 40 | return self.root_view.root_menubar 41 | 42 | def get_app_menu_obj(self): 43 | return self.root_view.app_menu 44 | 45 | def get_file_menu_obj(self): 46 | return self.root_view.file_menu 47 | 48 | def get_gpg_menu_obj(self): 49 | return self.root_view.gpg_menu 50 | 51 | def get_host_key_id(self): 52 | key_vals = self.host_key_observer.get() 53 | split = key_vals.split(',') 54 | key_id = split.pop().strip() 55 | return key_id 56 | 57 | def set_tor_proxy_running_observable(self, val): 58 | self.tor_proxy_running_observable.set(val) 59 | 60 | def get_tor_proxy_running_observable(self): 61 | return self.tor_proxy_running_observable.get() 62 | 63 | def set_session_passphrase_observable(self, val): 64 | self.host_key_session_passphrase_observable.set(val) 65 | 66 | def get_session_passphrase_observable(self): 67 | result = self.host_key_session_passphrase_observable.get() 68 | return result 69 | 70 | def add_session_passphrase_observable_callback(self, func): 71 | self.host_key_session_passphrase_observable.add_callback(func) 72 | -------------------------------------------------------------------------------- /disappeer/root/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/root/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/root/tests/rootsetupclass.py: -------------------------------------------------------------------------------- 1 | """ 2 | rootsetupclass.py 3 | 4 | Helper class for RootController setup 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from unittest.mock import MagicMock 12 | import time 13 | import tkinter 14 | from disappeer.root import rootcontroller 15 | from disappeer.root import rootview 16 | from disappeer.utilities import dirmaker 17 | from disappeer import settings 18 | from disappeer.models import gpgdatacontext 19 | from disappeer.models.db import databasefacade 20 | from disappeer.models import tordatacontext 21 | import copy 22 | 23 | 24 | class RootSetupClass(unittest.TestCase): 25 | root = tkinter.Tk() 26 | root_view_obj = rootview.RootView(root) 27 | root_test_dir = "tests/data/dirmaker/" 28 | 29 | dir_maker = dirmaker.DirMaker(root_test_dir) 30 | gpg_data_context = gpgdatacontext.GPGDataContext(dir_maker.get_keys_default_dir()) 31 | database_facade = databasefacade.DatabaseFacade(gpg_data_context.get_host_key_observer(), 32 | dir_maker.get_user_database_dir) 33 | tor_data_context = tordatacontext.TorDataContext(dir_maker.get_user_tor_keys_dir) 34 | gpg_data_context = gpgdatacontext.GPGDataContext(dir_maker.get_keys_default_dir()) 35 | 36 | def setUp(self): 37 | self.root_view = MagicMock(spec=self.root_view_obj) 38 | self.copy_gpg_data_context = copy.deepcopy(self.gpg_data_context) 39 | self.copy_database_facade = copy.deepcopy(self.database_facade) 40 | self.copy_tor_data_context = copy.deepcopy(self.tor_data_context) 41 | self.x = rootcontroller.RootController(self.root, self.root_view, self.copy_gpg_data_context, self.copy_database_facade, self.copy_tor_data_context) 42 | 43 | def altsetup(self): 44 | x = rootcontroller.RootController(self.root, self.root_view, self.copy_gpg_data_context, self.copy_database_facade, self.copy_tor_data_context) 45 | return x 46 | -------------------------------------------------------------------------------- /disappeer/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | settings.py 3 | 4 | App Level settings 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import os 11 | import pathlib 12 | 13 | 14 | if os.environ.get('TESTING'): 15 | root_data_dir = os.path.abspath('tests/data/root_data_dir_test') + '/' 16 | else: 17 | root_data_dir_name = '/.disappeer/' 18 | root_data_dir = str(pathlib.Path.home()) + root_data_dir_name 19 | 20 | default_key_dir = root_data_dir + 'keys' 21 | default_log_dir = root_data_dir + 'log/' 22 | 23 | port_contact_request_server = 16661 24 | port_contact_response_server = 16662 25 | port_message_server = 16663 26 | port_tor_controller = 9051 27 | 28 | gpg_host_pubkey = root_data_dir + 'host_gpg_pubkey.gpg' 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /disappeer/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/tests/data/altkeys/pubring.kbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/altkeys/pubring.kbx -------------------------------------------------------------------------------- /disappeer/tests/data/altkeys/trustdb.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/altkeys/trustdb.gpg -------------------------------------------------------------------------------- /disappeer/tests/data/dirmaker/data/55A45A99FE45E540/databases/55A45A99FE45E540.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/dirmaker/data/55A45A99FE45E540/databases/55A45A99FE45E540.sqlite -------------------------------------------------------------------------------- /disappeer/tests/data/dirmaker/data/55A45A99FE45E540/databases/server_sync.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/dirmaker/data/55A45A99FE45E540/databases/server_sync.sqlite -------------------------------------------------------------------------------- /disappeer/tests/data/dirmaker/keys/default/.#lk0x00007fee80501220.niemand.local.74548: -------------------------------------------------------------------------------- 1 | 74548 2 | niemand.local 3 | -------------------------------------------------------------------------------- /disappeer/tests/data/dirmaker/keys/default/.gpg-v21-migrated: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/dirmaker/keys/default/.gpg-v21-migrated -------------------------------------------------------------------------------- /disappeer/tests/data/dirmaker/keys/default/private-keys-v1.d/291A515859B553CEFEEE91B95443F1B172CE206A.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/dirmaker/keys/default/private-keys-v1.d/291A515859B553CEFEEE91B95443F1B172CE206A.key -------------------------------------------------------------------------------- /disappeer/tests/data/dirmaker/keys/default/private-keys-v1.d/8DC8015AE89B9D4E6B02FAB83FEE523483A6DB84.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/dirmaker/keys/default/private-keys-v1.d/8DC8015AE89B9D4E6B02FAB83FEE523483A6DB84.key -------------------------------------------------------------------------------- /disappeer/tests/data/dirmaker/keys/default/pubring.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/dirmaker/keys/default/pubring.gpg -------------------------------------------------------------------------------- /disappeer/tests/data/dirmaker/keys/default/pubring.gpg~: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/dirmaker/keys/default/pubring.gpg~ -------------------------------------------------------------------------------- /disappeer/tests/data/dirmaker/keys/default/random_seed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/dirmaker/keys/default/random_seed -------------------------------------------------------------------------------- /disappeer/tests/data/dirmaker/keys/default/secring.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/dirmaker/keys/default/secring.gpg -------------------------------------------------------------------------------- /disappeer/tests/data/dirmaker/keys/default/trustdb.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/dirmaker/keys/default/trustdb.gpg -------------------------------------------------------------------------------- /disappeer/tests/data/keys/.gpg-v21-migrated: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/keys/.gpg-v21-migrated -------------------------------------------------------------------------------- /disappeer/tests/data/keys/private-keys-v1.d/0BD83B491C590E2CF9710E75DFB474977AA80CB4.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/keys/private-keys-v1.d/0BD83B491C590E2CF9710E75DFB474977AA80CB4.key -------------------------------------------------------------------------------- /disappeer/tests/data/keys/private-keys-v1.d/543A3A58E42A4026115A3FF05BE57748DF264557.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/keys/private-keys-v1.d/543A3A58E42A4026115A3FF05BE57748DF264557.key -------------------------------------------------------------------------------- /disappeer/tests/data/keys/pubring.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/keys/pubring.gpg -------------------------------------------------------------------------------- /disappeer/tests/data/keys/pubring.gpg~: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/keys/pubring.gpg~ -------------------------------------------------------------------------------- /disappeer/tests/data/keys/random_seed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/keys/random_seed -------------------------------------------------------------------------------- /disappeer/tests/data/keys/secring.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/keys/secring.gpg -------------------------------------------------------------------------------- /disappeer/tests/data/keys/trustdb.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/keys/trustdb.gpg -------------------------------------------------------------------------------- /disappeer/tests/data/msg_ctrlr_keys/pubring.kbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/msg_ctrlr_keys/pubring.kbx -------------------------------------------------------------------------------- /disappeer/tests/data/root_data_dir_test/data/No Private Key in Ring/databases/No Private Key in Ring.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/root_data_dir_test/data/No Private Key in Ring/databases/No Private Key in Ring.sqlite -------------------------------------------------------------------------------- /disappeer/tests/data/root_data_dir_test/data/No Private Key in Ring/databases/server_sync.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/root_data_dir_test/data/No Private Key in Ring/databases/server_sync.sqlite -------------------------------------------------------------------------------- /disappeer/tests/data/root_data_dir_test/host_gpg_pubkey.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/root_data_dir_test/host_gpg_pubkey.gpg -------------------------------------------------------------------------------- /disappeer/tests/data/root_data_dir_test/keys/pubring.kbx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/root_data_dir_test/keys/pubring.kbx -------------------------------------------------------------------------------- /disappeer/tests/data/root_data_dir_test/keys/trustdb.gpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/root_data_dir_test/keys/trustdb.gpg -------------------------------------------------------------------------------- /disappeer/tests/data/testdb.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/testdb.sqlite -------------------------------------------------------------------------------- /disappeer/tests/data/tor_data/ServiceName: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tests/data/tor_data/ServiceName -------------------------------------------------------------------------------- /disappeer/tests/test_metainfo.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_metainfo.py 3 | 4 | Test suite for app metainfo 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from disappeer import metainfo 12 | 13 | 14 | class TestBasics(unittest.TestCase): 15 | 16 | def test_title(self): 17 | name = 'Disappeer' 18 | self.assertEqual(name, metainfo.title) 19 | 20 | def test_version(self): 21 | name = 'version' 22 | check = hasattr(metainfo, name) 23 | self.assertTrue(check) 24 | self.assertIsNotNone(metainfo.version) 25 | 26 | def test_license(self): 27 | name = 'license' 28 | check = hasattr(metainfo, name) 29 | self.assertTrue(check) 30 | self.assertIsNotNone(metainfo.license) 31 | 32 | def test_github(self): 33 | name = 'github' 34 | check = hasattr(metainfo, name) 35 | self.assertTrue(check) 36 | self.assertIsNotNone(metainfo.github) 37 | 38 | def test_email(self): 39 | name = 'email' 40 | check = hasattr(metainfo, name) 41 | self.assertTrue(check) 42 | self.assertIsNotNone(metainfo.email) 43 | 44 | -------------------------------------------------------------------------------- /disappeer/tests/test_settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_settings.py 3 | 4 | Test Suite for the app level settings file 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from disappeer import settings 12 | import os 13 | 14 | 15 | class TestImports(unittest.TestCase): 16 | 17 | def test_os(self): 18 | self.assertEqual(os, settings.os) 19 | 20 | 21 | class TestBasicVars(unittest.TestCase): 22 | 23 | def test_port_contact_request_server(self): 24 | target = 16661 25 | self.assertEqual(target, settings.port_contact_request_server) 26 | 27 | def test_port_contact_response_server(self): 28 | target = 16662 29 | self.assertEqual(target, settings.port_contact_response_server) 30 | 31 | def test_port_message_server(self): 32 | target = 16663 33 | self.assertEqual(target, settings.port_message_server) 34 | 35 | def test_port_tor_controller(self): 36 | target = 9051 37 | self.assertEqual(target, settings.port_tor_controller) 38 | 39 | def test_gpg_host_pubkey_file(self): 40 | name = 'host_gpg_pubkey.gpg' 41 | target = settings.root_data_dir + name 42 | self.assertEqual(target, settings.gpg_host_pubkey) 43 | 44 | def test_root_data_dir(self): 45 | name = 'root_data_dir' 46 | check = hasattr(settings, name) 47 | self.assertEqual(type('t'), type(settings.root_data_dir)) 48 | self.assertEqual(settings.root_data_dir[-1], '/') 49 | import pathlib 50 | self.assertIn(str(pathlib.Path.home()), settings.root_data_dir) 51 | 52 | def test_default_key_dir_exists_is_dir(self): 53 | name = 'default_key_dir' 54 | check = hasattr(settings, name) 55 | self.assertEqual(settings.default_key_dir, settings.root_data_dir + 'keys') 56 | 57 | def test_default_log_dir_exists_is_dir(self): 58 | name = 'default_log_dir' 59 | check = hasattr(settings, name) 60 | self.assertEqual(settings.default_log_dir, settings.root_data_dir + 'log/') -------------------------------------------------------------------------------- /disappeer/tornet/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tornet/__init__.py -------------------------------------------------------------------------------- /disappeer/tornet/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/tornet/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/torproxy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/torproxy/__init__.py -------------------------------------------------------------------------------- /disappeer/torproxy/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/torproxy/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/utilities/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/utilities/__init__.py -------------------------------------------------------------------------------- /disappeer/utilities/helpers.py: -------------------------------------------------------------------------------- 1 | """ 2 | helpers.py 3 | 4 | Module with app utility helper functions 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import datetime 11 | import os 12 | import pathlib 13 | 14 | 15 | def get_date_time_stamp(secs): 16 | """ 17 | Take epoch secs int as input, return datetime stamp 18 | """ 19 | converted = float(secs) 20 | return datetime.datetime.fromtimestamp(converted).strftime('%m/%d/%Y') 21 | 22 | 23 | def get_local_ipaddress(): 24 | import socket 25 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 26 | s.connect(('8.8.8.8', 53)) 27 | result = s.getsockname()[0] 28 | s.close() 29 | return result 30 | 31 | 32 | def get_images_dir_path(): 33 | from disappeer import images 34 | return os.path.dirname(images.__file__) + '/' 35 | 36 | 37 | def get_user_home_dir(): 38 | return pathlib.Path.home() 39 | -------------------------------------------------------------------------------- /disappeer/utilities/observable.py: -------------------------------------------------------------------------------- 1 | """ 2 | observable.py 3 | 4 | A simple observable class object 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | 11 | class Observable: 12 | 13 | def __init__(self, data=None): 14 | self.data = data 15 | self.callbacks = {} 16 | self.observer_list = [] 17 | self.add_callback(self.update_observers) 18 | 19 | def get(self): 20 | return self.data 21 | 22 | def set(self, data): 23 | self.data = data 24 | self.run_callbacks() 25 | 26 | def unset(self): 27 | self.data = None 28 | 29 | ############################## 30 | # CALLBACK METHODS # 31 | ############################## 32 | 33 | def add_callback(self, func): 34 | self.callbacks[func] = 1 35 | 36 | def run_callbacks(self): 37 | for func in self.callbacks: 38 | func(self) 39 | 40 | def delete_callback(self, func): 41 | del self.callbacks[func] 42 | 43 | ############################## 44 | # OBSERVER METHODS # 45 | ############################## 46 | 47 | def update_widget(self, widget_var): 48 | widget_var.set(self.get()) 49 | 50 | def add_observer(self, observer): 51 | self.observer_list.append(observer) 52 | self.set(self.data) 53 | 54 | def update_observers(self, param): 55 | for item in self.observer_list: 56 | self.update_widget(item) -------------------------------------------------------------------------------- /disappeer/utilities/queueconsumer.py: -------------------------------------------------------------------------------- 1 | """ 2 | queueconsumer.py 3 | 4 | Module for QueueConsumer controller base class 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import queue 11 | from disappeer.constants import constants 12 | import logging 13 | 14 | log = logging.getLogger(constants.title) 15 | 16 | 17 | class QueueConsumer: 18 | 19 | def __init__(self, root): 20 | self.root = root 21 | self.queue = queue.Queue() 22 | self.poll_queue() 23 | 24 | def poll_queue(self): 25 | self.consume_queue() 26 | self.root.after(200, self.poll_queue) 27 | 28 | def consume_queue(self): 29 | if not self.queue.empty(): 30 | got = self.queue.get() 31 | self.process_queue_result(got) 32 | self.queue.task_done() 33 | 34 | def process_queue_result(self, payload): 35 | check = self.check_payload(payload) 36 | if check: 37 | self.handle_queue_payload(payload) 38 | 39 | def check_payload(self, payload): 40 | if not isinstance(payload, dict): 41 | log.error("{}-QueueConsumer payload of type {} is not dict: {}".format(type(self).__name__, type(payload), payload)) 42 | return False 43 | try: 44 | desc = payload['desc'] 45 | except KeyError as err: 46 | log.error("{}-QueueConsumer, malformed payload: {}, {}".format(type(self).__name__, err, payload)) 47 | return False 48 | return payload 49 | 50 | def handle_queue_payload(self, payload): 51 | raise NotImplementedError -------------------------------------------------------------------------------- /disappeer/utilities/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/disappeerlabs/disappeer/fcce446948bdc7dab624388f01f96da56d88d778/disappeer/utilities/tests/__init__.py -------------------------------------------------------------------------------- /disappeer/utilities/tests/test_helpers.py: -------------------------------------------------------------------------------- 1 | """ 2 | test_helpers.py 3 | 4 | Test suite for app utilities.helpers module 5 | 6 | Copyright (C) 2018 Disappeer Labs 7 | License: GPLv3 8 | """ 9 | 10 | import unittest 11 | from disappeer.utilities import helpers 12 | import datetime 13 | import os 14 | import pathlib 15 | 16 | 17 | class TestImports(unittest.TestCase): 18 | 19 | def test_datetime(self): 20 | self.assertEqual(datetime, helpers.datetime) 21 | 22 | def test_os(self): 23 | self.assertEqual(os, helpers.os) 24 | 25 | def test_pathlib(self): 26 | self.assertEqual(pathlib, helpers.pathlib) 27 | 28 | 29 | class TestBasics(unittest.TestCase): 30 | 31 | def test_get_date_time_stamp(self): 32 | secs = '1495828561' 33 | target = '05/26/2017' 34 | result = helpers.get_date_time_stamp(secs) 35 | self.assertEqual(result, target) 36 | 37 | def test_get_local_ipaddress(self): 38 | import socket 39 | s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 40 | s.connect(('8.8.8.8', 53)) 41 | check = s.getsockname()[0] 42 | s.close() 43 | result = helpers.get_local_ipaddress() 44 | self.assertEqual(check, result) 45 | 46 | def test_get_images_dir_path(self): 47 | from disappeer import images 48 | expected = os.path.dirname(images.__file__) + '/' 49 | actual = helpers.get_images_dir_path() 50 | self.assertEqual(expected, actual) 51 | 52 | def test_get_user_home_dir(self): 53 | self.assertEqual(pathlib.Path.home(), helpers.get_user_home_dir()) 54 | 55 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | PySocks==1.6.8 2 | python-gnupg==0.4.4 3 | stem==1.7.1 4 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | from disappeer import metainfo 3 | 4 | 5 | setup( 6 | name='disappeer', 7 | version=metainfo.version, 8 | description='A pure Python GUI app that provides access to gnupg, and P2P GPG-encrypted messaging over Tor', 9 | author='Disappeer Labs', 10 | author_email=metainfo.email, 11 | license='GPLv3', 12 | packages=find_packages(exclude=('tests',)), 13 | entry_points={ 14 | 'console_scripts': [ 15 | 'disappeer = disappeer.__main__:main' 16 | ] 17 | } 18 | ) 19 | 20 | --------------------------------------------------------------------------------