예제 #1
0
 def __init__(self,
              router,
              interface,
              controller,
              filter='.*',
              encryptor_cache=None,
              make_jack=True):
     Client.__init__(self, router, interface, encryptor_cache, make_jack)
     self.controller = py_address(controller)
     self.set_filter(filter)
예제 #2
0
 def __init__(self, router, interface, **kwargs):
     Client.__init__(self, router, interface, **kwargs)
     self.client_data = {}
     self.default_data = {
         'messages': {},
         'chopping_block': [],
         'status': {
             'total_count': 1000,
             'total_space': 32 * 1024,  # 32kb of space default
             'used_count': 0,
             'used_space': 0,
         },
     }
    def setUp(self):
        # Reuse setup, without being subclass and pulling in tests
        DexterCommandTester.setUp(self)

        self.j_loc = ["local", None, "jackson"]
        self.t_loc = ["local", None, "tealc"]

        self.interface.data = {
            "identity": self.j_loc,
            "idcache": {
                '["local",null,"jackson"]': {
                    "location": self.j_loc,
                    "name": "*****@*****.**",
                    "encryptor": ["rotate", 4],
                },
                '["local",null,"tealc"]': {"location": self.t_loc, "name": "*****@*****.**", "encryptor": ["rotate", 5]},
            },
            "docname": "example",
            "docserialized": handler_document("echo_chamber").serialize(),
        }
        with self.io:
            self.interface.do_command("dinit")
        self.router = self.interface.owner.router
        self.tealc = Client(self.router, self.t_loc, self.interface.owner.identities)
        self.daniel = self.interface.owner.client
예제 #4
0
 def __init__(self, interface, router=None, cpsdesc=None):
     self.interface = interface
     self.router = router or Router()
     self.client = Client(self.router, self.interface)
     self.client.rcv_callback = self.rcv_callback
     self.cpsdesc = cpsdesc or ('ramdict', ['rotate', 0])
     self.storage = Storage([self.cpsdesc])
     self.unread = {}
     self.conversations = {}
예제 #5
0
 def test_sig_verify(self):
     client = Client(None, ['demo_interface'])
     client.encryptor_set(client.interface, ['rotate', 41])
     original = ['catamaran']
     self.assertTrue(
         client.sig_verify(original, client.interface,
                           client.sign(original)))
예제 #6
0
 def test_client_already_loaded(self):
     from ejtp.client import Client
     client = Client(None, (4, 5, 6), make_jack=False)
     self.router._loadclient(client)
     self.assertRaisesRegexp(ValueError, 'client already loaded',
                             self.router._loadclient, client)
예제 #7
0
    def test_clients_chat(self):
        router = Router()
        c1 = Client(router, ['udp', ['127.0.0.1', 555], 'c1'], make_jack=False)
        c2 = Client(router, ['udp', ['127.0.0.1', 555], 'c2'], make_jack=False)

        c1.encryptor_cache = c2.encryptor_cache  # Let's only set this stuff once
        c1.encryptor_set(c1.interface, ['rotate', 3])
        c1.encryptor_set(c2.interface, ['rotate', -7])
        self.assertEqual(c1.router, c2.router)

        c1.write_json(c2.interface, "hello")
        c2.write_json(c1.interface, "goodbye")
        self.assertInLog(
            "Client ['udp', ['127.0.0.1', 555], 'c2'] recieved from ['udp', ['127.0.0.1', 555], 'c1']: JSONFrame: RawData((0x6a,0x0,0x22,0x68,0x65,0x6c,0x6c,0x6f,0x22))"
        )
        self.assertInLog(
            "Client ['udp', ['127.0.0.1', 555], 'c1'] recieved from ['udp', ['127.0.0.1', 555], 'c2']: JSONFrame: RawData((0x6a,0x0,0x22,0x67,0x6f,0x6f,0x64,0x62,0x79,0x65,0x22))"
        )
class TestDexterDEJEGroupInitialized(DexterCommandTester):
    def setUp(self):
        # Reuse setup, without being subclass and pulling in tests
        DexterCommandTester.setUp(self)

        self.j_loc = ["local", None, "jackson"]
        self.t_loc = ["local", None, "tealc"]

        self.interface.data = {
            "identity": self.j_loc,
            "idcache": {
                '["local",null,"jackson"]': {
                    "location": self.j_loc,
                    "name": "*****@*****.**",
                    "encryptor": ["rotate", 4],
                },
                '["local",null,"tealc"]': {"location": self.t_loc, "name": "*****@*****.**", "encryptor": ["rotate", 5]},
            },
            "docname": "example",
            "docserialized": handler_document("echo_chamber").serialize(),
        }
        with self.io:
            self.interface.do_command("dinit")
        self.router = self.interface.owner.router
        self.tealc = Client(self.router, self.t_loc, self.interface.owner.identities)
        self.daniel = self.interface.owner.client

    def test_basic_assertions(self):
        self.assertEqual(self.tealc.encryptor_cache, self.daniel.encryptor_cache)

    def test_enact_event_signal(self):
        class DemoActionIshThing(object):
            def hash(self):
                return String("123456789ABCDEFG")

        with self.io:
            signal = self.interface.document.signals["enact-event"]
            signal.send(DemoActionIshThing())
        self.assertEqual(self.interface.get_view("doc").contents, ["Applied event (hash 123456789A...)"])

    def test_msg_external_str(self):
        with self.io:
            self.tealc.write_json(self.j_loc, "Hello, world")
        self.assertEqual(
            self.interface.view.contents,
            [
                "msglog> dinit",
                "DEJE initialized",
                '["local",null,"tealc"] : <could not parse>',
                '["local",null,"jackson"] (ME) : deje-error',
            ],
        )

    def test_msg_external_map(self):
        with self.io:
            self.tealc.write_json(self.j_loc, {"type": "example"})
        self.assertEqual(
            self.interface.view.contents,
            [
                "msglog> dinit",
                "DEJE initialized",
                '["local",null,"tealc"] : example',
                '["local",null,"jackson"] (ME) : deje-error',
            ],
        )

    def test_msg_external_valid(self):
        rcvd = []
        self.tealc.rcv_callback = lambda msg, client: rcvd.append(msg)
        with self.io:
            self.tealc.write_json(self.j_loc, {"type": "deje-sub-list-query", "qid": 5})
        self.assertEqual(
            self.interface.view.contents,
            [
                "msglog> dinit",
                "DEJE initialized",
                '["local",null,"tealc"] : deje-sub-list-query',
                '["local",null,"jackson"] (ME) : deje-sub-list-response',
            ],
        )
        self.assertEqual(rcvd.pop().unpack(), {"type": "deje-sub-list-response", "qid": 5, "subs": {}})

    def test_msg_sent_str(self):
        with self.io:
            self.interface.owner.client.write_json(self.t_loc, "Not even a mapping")
        self.assertEqual(
            self.interface.view.contents,
            ["msglog> dinit", "DEJE initialized", '["local",null,"jackson"] (ME) : <msg type not provided>'],
        )

    def test_msg_sent_map(self):
        with self.io:
            self.interface.owner.client.write_json(self.t_loc, {"Does not have": "a type key"})
        self.assertEqual(
            self.interface.view.contents,
            ["msglog> dinit", "DEJE initialized", '["local",null,"jackson"] (ME) : <msg type not provided>'],
        )

    def test_msg_sent_valid(self):
        with self.io:
            self.interface.owner.client.write_json(self.t_loc, {"type": "example"})
        self.assertEqual(
            self.interface.view.contents,
            ["msglog> dinit", "DEJE initialized", '["local",null,"jackson"] (ME) : example'],
        )

    def test_msg_solo_transmit(self):
        with self.io:
            self.interface.owner.transmit(self.interface.document, "example", {}, participants=True, subscribers=False)
        self.assertEqual(
            self.interface.view.contents,
            [
                "msglog> dinit",
                "DEJE initialized",
                '["local",null,"jackson"] (ME) : example',
                '["local",null,"jackson"] : example',
                '["local",null,"jackson"] (ME) : deje-error',
                '["local",null,"jackson"] : deje-error',
            ],
        )

    def test_devent_wrong_num_args(self):
        with self.io:
            self.interface.do_command("devent")
            self.interface.do_command("devent a b")
        self.assertEqual(
            self.interface.view.contents,
            [
                "msglog> dinit",
                "DEJE initialized",
                "msglog> devent",
                "devent takes exactly 1 arg(s), got 0",
                "msglog> devent a b",
                "devent takes exactly 1 arg(s), got 2",
            ],
        )

    def test_devent_no_such_var(self):
        with self.io:
            self.interface.do_command("devent eventstuff")
        self.assertEqual(
            self.interface.get_view("msglog").contents,
            ["msglog> dinit", "DEJE initialized", "msglog> devent eventstuff", "No such variable 'eventstuff'"],
        )

    def test_devent(self):
        with self.io:
            self.interface.data["eventstuff"] = "example"
            self.interface.do_command("devent eventstuff")
        self.assertEqual(
            self.interface.get_view("msglog").contents,
            [
                "msglog> dinit",
                "DEJE initialized",
                "msglog> devent eventstuff",
                '["local",null,"jackson"] (ME) : deje-paxos-accept',
                '["local",null,"jackson"] : deje-paxos-accept',
                '["local",null,"jackson"] (ME) : deje-paxos-accepted',
                '["local",null,"jackson"] : deje-paxos-accepted',
                '["local",null,"jackson"] (ME) : deje-paxos-complete',
                '["local",null,"jackson"] : deje-paxos-complete',
                '["local",null,"jackson"] (ME) : deje-action-completion',
                '["local",null,"jackson"] : deje-action-completion',
                '["local",null,"jackson"] (ME) : deje-paxos-accepted',
                '["local",null,"jackson"] : deje-paxos-accepted',
            ],
        )
        self.assertEqual(self.interface.get_view("doc").contents, ["Applied event (hash 56c9a782dc...)"])
        self.assertEqual(self.interface.get_view("dbg").contents, ["Event 'example' achieved."])

    def test_dget_latest(self):
        with self.io:
            self.interface.do_command("dget_latest")
        self.assertEqual(
            self.interface.get_view("msglog").contents,
            [
                "msglog> dinit",
                "DEJE initialized",
                "msglog> dget_latest",
                '["local",null,"jackson"] (ME) : deje-paxos-accept',
                '["local",null,"jackson"] : deje-paxos-accept',
                '["local",null,"jackson"] (ME) : deje-paxos-accepted',
                '["local",null,"jackson"] : deje-paxos-accepted',
                '["local",null,"jackson"] (ME) : deje-paxos-complete',
                '["local",null,"jackson"] : deje-paxos-complete',
                '["local",null,"jackson"] (ME) : deje-action-completion',
                '["local",null,"jackson"] : deje-action-completion',
                '["local",null,"jackson"] (ME) : deje-paxos-accepted',
                '["local",null,"jackson"] : deje-paxos-accepted',
            ],
        )
        # Nnreaaagghhh Python 2
        doc_contents = self.interface.get_view("doc").contents
        self.assertEqual(len(doc_contents), 1)
        self.assertIn(
            doc_contents.pop(), ["Document latest version is 'current'", "Document latest version is u'current'"]
        )
        self.assertEqual(self.interface.get_view("dbg").contents, [])

    def test_dvexport_wrong_num_args(self):
        with self.io:
            self.interface.do_command("dvexport")
            self.interface.do_command("dvexport a b")
        self.assertEqual(
            self.interface.view.contents,
            [
                "msglog> dinit",
                "DEJE initialized",
                "msglog> dvexport",
                "dvexport takes exactly 1 arg(s), got 0",
                "msglog> dvexport a b",
                "dvexport takes exactly 1 arg(s), got 2",
            ],
        )

    def test_dvexport(self):
        with self.io:
            self.interface.do_command("dvexport x")
        self.assertEqual(self.interface.view.contents, ["msglog> dinit", "DEJE initialized", "msglog> dvexport x"])
        self.assertEqual(self.interface.data["x"], self.interface.document.serialize())

    def test_dexport_wrong_num_args(self):
        with self.io:
            self.interface.do_command("dexport")
            self.interface.do_command("dexport a b")
        self.assertEqual(
            self.interface.view.contents,
            [
                "msglog> dinit",
                "DEJE initialized",
                "msglog> dexport",
                "dexport takes exactly 1 arg(s), got 0",
                "msglog> dexport a b",
                "dexport takes exactly 1 arg(s), got 2",
            ],
        )

    def test_dexport(self):
        with Tempfile() as fname:
            cmd = "dexport " + fname
            with self.io:
                self.interface.do_command(cmd)
            written = open(fname, "r").read()
        self.assertEqual(json.loads(written), self.interface.document.serialize())
        self.assertEqual(self.interface.view.contents, ["msglog> dinit", "DEJE initialized", "msglog> " + cmd])
예제 #9
0
 def __init__(self, *args, **kwargs):
     Client.__init__(self, *args, **kwargs)
     self.callbacks = {}
예제 #10
0
class Mailbox(object):
    '''
    Class for persistent mail storage.

    >>> m = Mailbox(['udp4', ['localhost',9001], 'ejmail-test'])
    >>> m.interface
    ['udp4', ['localhost', 9001], 'ejmail-test']
    >>> m.router #doctest: +ELLIPSIS
    <ejtp.router.Router object at ...>
    >>> m.cpsdesc
    ('ramdict', ['rotate', 0])
    >>> m.storage #doctest: +ELLIPSIS
    <dbcps.storage.Storage object at ...>
    '''
    def __init__(self, interface, router=None, cpsdesc=None):
        self.interface = interface
        self.router = router or Router()
        self.client = Client(self.router, self.interface)
        self.client.rcv_callback = self.rcv_callback
        self.cpsdesc = cpsdesc or ('ramdict', ['rotate', 0])
        self.storage = Storage([self.cpsdesc])
        self.unread = {}
        self.conversations = {}

    def recv(self, data, addr=None):
        '''
        Interpret an email recieved through EJTP client.

        >>> m = Mailbox(['udp4', ['localhost',9002], 'ejmail-test'])
        >>> m.add_conversation("Demonstration") # Add ahead of time so we can set callback
        >>> def msgcallback(msg):
        ...     print msg.hash
        ...     print msg.content
        >>> m.conversations["Demonstration"].on_message = msgcallback
        >>> m.recv({'conversation':'Demonstration', 'content':'Demo content', 'timecode':'not an automatic one'})
        65d35f7482c0c610ada04ff4e7bf4fa66f4769dd
        Demo content
        '''
        message = Message(data)
        if addr:
            self.ack(message, addr)
        convo = message.conversation
        self.add_conversation(convo)
        convo_obj = self.conversations[convo]
        convo_obj.register_message(message)
        convo_obj.on_message(message)
        self.storage[message.hash] = str(message)

    def add_conversation(self, name):
        '''
        Set up a Conversation object for this mailbox.

        This is called by self.recv automatically.
        '''
        if not name in self.conversations:
            self.conversations[name] = Conversation(name)

    def rcv_callback(self, msg, client):
        '''
        Callback for EJTP client.

        TODO: Filter out messages where EJTP sender does not match "from" field.
        '''
        msg_dict = json.loads(msg.content)
        msg_type = msg_dict['type']
        msg_data = msg_dict['data']
        if msg_type == "ejmail-message":
            self.recv(msg_data, msg.addr)
        elif msg_type == "ejmail-mark":
            saddr = address.str_address(msg.addr)
            for hash in msg_data:
                del self.unread[saddr][hash]
            for unread in self.unread[saddr].values():
                self.send(unread, [('Retrying send...', saddr)])

    def send(self, msg, recipients=None):
        '''
        Send ejmail.message.Message object to its recipients.

        >>> import time
        >>> m3addr = ['udp4', ['localhost',9003], 'britta']
        >>> m4addr = ['udp4', ['localhost',9004], 'jeff']
        >>> m3 = Mailbox(m3addr)
        >>> m4 = Mailbox(m4addr)
        >>> m4.client.encryptor_cache = m3.client.encryptor_cache
        >>> m3.client.encryptor_set(m3addr, ['rotate', 5])
        >>> m3.client.encryptor_set(m4addr, ['rotate', -14])
        >>> msg = Message({
        ...     'to':[['Jeff Winger', m4addr]],
        ...     'from':['Britta Perry', m3addr],
        ...     'conversation':'Wazzaaaappp',
        ...     'content':"I'm druunnkkkk",
        ... })
        >>> m3.send(msg); time.sleep(0.1) #doctest: +ELLIPSIS
        UDPJack out: ...
        >>> m4.conversations.keys()
        [u'Wazzaaaappp']
        >>> m4.conversations['Wazzaaaappp'].timeline()[0].content
        u"I'm druunnkkkk"
        >>> m3.unread
        {'["udp4",["localhost",9004],"jeff"]': {}}
        '''
        convo = msg.conversation
        self.add_conversation(convo)
        convo_obj = self.conversations[convo]
        convo_obj.register_message(msg)
        recipients = recipients or msg.data['to']
        for recipient in recipients:
            name, addr = recipient
            self.client.write_json(address.py_address(addr), {
                'type':'ejmail-message',
                'data':msg.data,
            })
            saddr = address.str_address(addr)
            if not saddr in self.unread:
                self.unread[saddr] = {}
            self.unread[saddr][msg.hash] = msg

    def ack(self, message, addr):
        self.client.write_json(
            address.py_address(addr),
            {
                'type':'ejmail-mark',
                'data':[message.hash],
            }
        )