dimples 0.5.1__tar.gz → 0.5.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dimples-0.5.1 → dimples-0.5.3}/PKG-INFO +1 -1
- {dimples-0.5.1 → dimples-0.5.3}/dimples/__init__.py +2 -1
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/messenger.py +15 -2
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/processor.py +18 -12
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/__init__.py +2 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/messenger.py +38 -7
- dimples-0.5.3/dimples/common/processer.py +70 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/group/emitter.py +10 -4
- {dimples-0.5.1 → dimples-0.5.3}/dimples/server/cpu/handshake.py +5 -4
- {dimples-0.5.1 → dimples-0.5.3}/dimples/server/cpu/login.py +1 -1
- {dimples-0.5.1 → dimples-0.5.3}/dimples/server/packer.py +21 -15
- {dimples-0.5.1 → dimples-0.5.3}/dimples/server/processor.py +2 -7
- {dimples-0.5.1 → dimples-0.5.3}/dimples.egg-info/PKG-INFO +1 -1
- {dimples-0.5.1 → dimples-0.5.3}/dimples.egg-info/SOURCES.txt +1 -0
- {dimples-0.5.1 → dimples-0.5.3}/setup.py +1 -1
- {dimples-0.5.1 → dimples-0.5.3}/README.md +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/__init__.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/archivist.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/checkpoint.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/cpu/__init__.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/cpu/commands.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/cpu/creator.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/cpu/group.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/cpu/grp_expel.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/cpu/grp_invite.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/cpu/grp_join.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/cpu/grp_query.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/cpu/grp_quit.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/cpu/grp_reset.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/cpu/grp_resign.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/cpu/handshake.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/facebook.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/network/__init__.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/network/session.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/network/state.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/network/transition.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/packer.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/client/terminal.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/anonymous.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/ans.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/archivist.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/compat/__init__.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/compat/btc.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/compat/compatible.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/compat/entity.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/compat/meta.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/compat/network.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/dbi/__init__.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/dbi/account.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/dbi/message.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/dbi/session.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/facebook.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/packer.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/protocol/__init__.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/protocol/ans.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/protocol/block.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/protocol/handshake.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/protocol/login.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/protocol/mute.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/protocol/report.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/register.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/common/session.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/conn/__init__.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/conn/gate.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/conn/gatekeeper.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/conn/mars.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/conn/mtp.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/conn/protocol/__init__.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/conn/protocol/mars.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/conn/protocol/ws.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/conn/queue.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/conn/seeker.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/conn/session.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/conn/ws.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/__init__.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/account.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/dos/__init__.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/dos/base.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/dos/document.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/dos/group.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/dos/group_history.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/dos/group_keys.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/dos/login.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/dos/meta.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/dos/private.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/dos/station.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/dos/user.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/message.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/session.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/t_cipherkey.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/t_document.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/t_group.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/t_group_history.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/t_group_keys.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/t_login.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/t_message.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/t_meta.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/t_private.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/t_station.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/database/t_user.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/edge/__init__.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/edge/octopus.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/edge/shared.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/edge/start.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/group/__init__.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/group/admin.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/group/builder.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/group/delegate.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/group/helper.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/group/manager.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/group/packer.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/register/__init__.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/register/base.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/register/ext.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/register/run.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/register/shared.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/server/__init__.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/server/archivist.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/server/cpu/__init__.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/server/cpu/ans.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/server/cpu/document.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/server/cpu/report.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/server/dispatcher.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/server/messenger.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/server/push.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/server/session.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/server/session_center.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/server/trace.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/station/__init__.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/station/handler.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/station/shared.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/station/start.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/utils/__init__.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/utils/cache.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/utils/config.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/utils/dos.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/utils/log.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples/utils/singleton.py +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples.egg-info/dependency_links.txt +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples.egg-info/entry_points.txt +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples.egg-info/requires.txt +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/dimples.egg-info/top_level.txt +0 -0
- {dimples-0.5.1 → dimples-0.5.3}/setup.cfg +0 -0
|
@@ -333,7 +333,8 @@ __all__ = [
|
|
|
333
333
|
'AddressNameServer', 'ANSFactory',
|
|
334
334
|
'CommonArchivist',
|
|
335
335
|
'CommonFacebook', 'CommonMessenger',
|
|
336
|
-
'CommonMessagePacker', '
|
|
336
|
+
'CommonMessagePacker', 'CommonMessageProcessor',
|
|
337
|
+
'Transmitter',
|
|
337
338
|
'Session',
|
|
338
339
|
|
|
339
340
|
####################################
|
|
@@ -62,14 +62,27 @@ class ClientMessenger(CommonMessenger):
|
|
|
62
62
|
facebook = self.facebook
|
|
63
63
|
user = facebook.current_user
|
|
64
64
|
assert user is not None, 'current user not found'
|
|
65
|
+
meta = user.meta
|
|
66
|
+
visa = user.visa
|
|
67
|
+
if visa is None:
|
|
68
|
+
self.warning(msg='user visa not found: %s' % user)
|
|
69
|
+
else:
|
|
70
|
+
device = {
|
|
71
|
+
'os': 'Linux',
|
|
72
|
+
}
|
|
73
|
+
visa.set_property(key='sys', value=device)
|
|
74
|
+
# sign to update
|
|
75
|
+
pri_key = facebook.private_key_for_visa_signature(identifier=user.identifier)
|
|
76
|
+
assert pri_key is not None, 'failed to get private key for visa: %s' % visa
|
|
77
|
+
visa.sign(private_key=pri_key)
|
|
65
78
|
env = Envelope.create(sender=user.identifier, receiver=srv_id)
|
|
66
79
|
cmd = HandshakeCommand.start()
|
|
67
80
|
# send first handshake command as broadcast message
|
|
68
81
|
cmd.group = Station.EVERY
|
|
69
82
|
# create instant message with meta & visa
|
|
70
83
|
i_msg = InstantMessage.create(head=env, body=cmd)
|
|
71
|
-
i_msg.set_map(key='meta', value=
|
|
72
|
-
i_msg.set_map(key='visa', value=
|
|
84
|
+
i_msg.set_map(key='meta', value=meta)
|
|
85
|
+
i_msg.set_map(key='visa', value=visa)
|
|
73
86
|
self.send_instant_message(msg=i_msg, priority=-1)
|
|
74
87
|
else:
|
|
75
88
|
# handshake again
|
|
@@ -37,18 +37,17 @@ from dimsdk import ReliableMessage
|
|
|
37
37
|
from dimsdk import Content, TextContent
|
|
38
38
|
from dimsdk import ReceiptCommand
|
|
39
39
|
from dimsdk import ContentProcessorCreator
|
|
40
|
-
from dimsdk import MessageProcessor
|
|
41
40
|
|
|
42
|
-
from ..utils import Logging
|
|
43
41
|
from ..common import HandshakeCommand
|
|
44
42
|
from ..common import CommonMessenger
|
|
43
|
+
from ..common import CommonMessageProcessor
|
|
45
44
|
|
|
46
45
|
from .cpu import ClientContentProcessorCreator
|
|
47
46
|
|
|
48
47
|
from .archivist import ClientArchivist
|
|
49
48
|
|
|
50
49
|
|
|
51
|
-
class ClientMessageProcessor(
|
|
50
|
+
class ClientMessageProcessor(CommonMessageProcessor):
|
|
52
51
|
|
|
53
52
|
@property
|
|
54
53
|
def messenger(self) -> CommonMessenger:
|
|
@@ -56,10 +55,11 @@ class ClientMessageProcessor(MessageProcessor, Logging):
|
|
|
56
55
|
assert isinstance(transceiver, CommonMessenger), 'messenger error: %s' % transceiver
|
|
57
56
|
return transceiver
|
|
58
57
|
|
|
59
|
-
|
|
58
|
+
# private
|
|
59
|
+
def _check_group_times(self, content: Content, r_msg: ReliableMessage) -> bool:
|
|
60
60
|
group = content.group
|
|
61
61
|
if group is None:
|
|
62
|
-
return
|
|
62
|
+
return False
|
|
63
63
|
facebook = self.facebook
|
|
64
64
|
archivist = facebook.archivist
|
|
65
65
|
assert isinstance(archivist, ClientArchivist), 'client archivist error: %s' % archivist
|
|
@@ -70,27 +70,33 @@ class ClientMessageProcessor(MessageProcessor, Logging):
|
|
|
70
70
|
last_doc_time = r_msg.get_datetime(key='GDT', default=None)
|
|
71
71
|
if last_doc_time is not None:
|
|
72
72
|
if last_doc_time.after(now):
|
|
73
|
+
# calibrate the clock
|
|
73
74
|
last_doc_time = now
|
|
74
75
|
doc_updated = archivist.set_last_document_time(identifier=group, last_time=last_doc_time)
|
|
76
|
+
# check whether needs update
|
|
77
|
+
if doc_updated:
|
|
78
|
+
self.info(msg='checking for new bulletin: %s' % group)
|
|
79
|
+
facebook.documents(identifier=group)
|
|
75
80
|
# check group history time
|
|
76
81
|
last_his_time = r_msg.get_datetime(key='GHT', default=None)
|
|
77
82
|
if last_his_time is not None:
|
|
78
83
|
if last_his_time.after(now):
|
|
84
|
+
# calibrate the clock
|
|
79
85
|
last_his_time = now
|
|
80
86
|
mem_updated = archivist.set_last_group_history_time(group=group, last_time=last_his_time)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
+
# check whether needs update
|
|
88
|
+
if mem_updated:
|
|
89
|
+
archivist.set_last_active_member(member=r_msg.sender, group=group)
|
|
90
|
+
self.info(msg='checking for group members: %s' % group)
|
|
91
|
+
facebook.members(identifier=group)
|
|
92
|
+
return doc_updated or mem_updated
|
|
87
93
|
|
|
88
94
|
# Override
|
|
89
95
|
def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
|
|
90
96
|
responses = super().process_content(content=content, r_msg=r_msg)
|
|
91
97
|
# check group document & history times from the message
|
|
92
98
|
# to make sure the group info synchronized
|
|
93
|
-
self.
|
|
99
|
+
self._check_group_times(content=content, r_msg=r_msg)
|
|
94
100
|
# check responses
|
|
95
101
|
if len(responses) == 0:
|
|
96
102
|
# respond nothing
|
|
@@ -40,6 +40,7 @@ from .archivist import CommonArchivist
|
|
|
40
40
|
from .facebook import CommonFacebook
|
|
41
41
|
from .messenger import CommonMessenger
|
|
42
42
|
from .packer import CommonMessagePacker
|
|
43
|
+
from .processer import CommonMessageProcessor
|
|
43
44
|
from .session import Transmitter, Session
|
|
44
45
|
|
|
45
46
|
from .compat import register_compatible_factories
|
|
@@ -87,6 +88,7 @@ __all__ = [
|
|
|
87
88
|
'CommonFacebook',
|
|
88
89
|
'CommonMessenger',
|
|
89
90
|
'CommonMessagePacker',
|
|
91
|
+
'CommonMessageProcessor',
|
|
90
92
|
'Transmitter',
|
|
91
93
|
'Session',
|
|
92
94
|
|
|
@@ -41,7 +41,7 @@ from typing import Optional, Union, Tuple
|
|
|
41
41
|
from dimsdk import SymmetricKey
|
|
42
42
|
from dimsdk import ID
|
|
43
43
|
from dimsdk import Content, Envelope
|
|
44
|
-
from dimsdk import Command
|
|
44
|
+
from dimsdk import Command, DocumentCommand
|
|
45
45
|
from dimsdk import InstantMessage, SecureMessage, ReliableMessage
|
|
46
46
|
from dimsdk import EntityDelegate, CipherKeyDelegate
|
|
47
47
|
from dimsdk import Messenger, Packer, Processor
|
|
@@ -168,26 +168,57 @@ class CommonMessenger(Messenger, Transmitter, Logging, ABC):
|
|
|
168
168
|
r_msg = self.send_instant_message(msg=i_msg, priority=priority)
|
|
169
169
|
return i_msg, r_msg
|
|
170
170
|
|
|
171
|
+
# private
|
|
172
|
+
def _attach_visa_time(self, sender: ID, msg: InstantMessage) -> bool:
|
|
173
|
+
if isinstance(msg.content, DocumentCommand):
|
|
174
|
+
# no need to attach times for command
|
|
175
|
+
return True
|
|
176
|
+
doc = self.facebook.visa(identifier=sender)
|
|
177
|
+
if doc is None:
|
|
178
|
+
self.error(msg='failed to get visa document for sender: %s' % sender)
|
|
179
|
+
return False
|
|
180
|
+
# attach sender document time
|
|
181
|
+
last_doc_time = doc.time
|
|
182
|
+
if last_doc_time is None:
|
|
183
|
+
self.error(msg='document error: %s' % doc)
|
|
184
|
+
return False
|
|
185
|
+
else:
|
|
186
|
+
msg.set_datetime(key='SDT', value=last_doc_time)
|
|
187
|
+
return True
|
|
188
|
+
|
|
171
189
|
# Override
|
|
172
190
|
def send_instant_message(self, msg: InstantMessage, priority: int = 0) -> Optional[ReliableMessage]:
|
|
173
191
|
""" send instant message with priority """
|
|
192
|
+
sender = msg.sender
|
|
174
193
|
# 0. check cycled message
|
|
175
|
-
if
|
|
176
|
-
self.warning(msg='drop cycled message: %s => %s, %s' % (
|
|
194
|
+
if sender == msg.receiver:
|
|
195
|
+
self.warning(msg='drop cycled message: %s => %s, %s' % (sender, msg.receiver, msg.group))
|
|
196
|
+
# return None
|
|
177
197
|
else:
|
|
178
198
|
self.debug(msg='send instant message message (type=%d): %s => %s, %s'
|
|
179
|
-
% (msg.content.type,
|
|
180
|
-
|
|
199
|
+
% (msg.content.type, sender, msg.receiver, msg.group))
|
|
200
|
+
# attach sender's document times
|
|
201
|
+
# for the receiver to check whether user info synchronized
|
|
202
|
+
ok = self._attach_visa_time(sender=sender, msg=msg)
|
|
203
|
+
if not ok:
|
|
204
|
+
self.warning(msg='failed to attach document time: %s => %s' % (sender, msg.content))
|
|
205
|
+
#
|
|
206
|
+
# 1. encrypt message
|
|
207
|
+
#
|
|
181
208
|
s_msg = self.encrypt_message(msg=msg)
|
|
182
209
|
if s_msg is None:
|
|
183
210
|
# public key not found?
|
|
184
211
|
return None
|
|
185
|
-
#
|
|
212
|
+
#
|
|
213
|
+
# 2. sign message
|
|
214
|
+
#
|
|
186
215
|
r_msg = self.sign_message(msg=s_msg)
|
|
187
216
|
if r_msg is None:
|
|
188
217
|
# TODO: set msg.state = error
|
|
189
218
|
raise AssertionError('failed to sign message: %s' % s_msg)
|
|
190
|
-
#
|
|
219
|
+
#
|
|
220
|
+
# 3. send message
|
|
221
|
+
#
|
|
191
222
|
if self.send_reliable_message(msg=r_msg, priority=priority):
|
|
192
223
|
return r_msg
|
|
193
224
|
# failed
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# ==============================================================================
|
|
3
|
+
# MIT License
|
|
4
|
+
#
|
|
5
|
+
# Copyright (c) 2023 Albert Moky
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
# ==============================================================================
|
|
25
|
+
|
|
26
|
+
from abc import ABC
|
|
27
|
+
from typing import List
|
|
28
|
+
|
|
29
|
+
from dimsdk import DateTime
|
|
30
|
+
from dimsdk import Content
|
|
31
|
+
from dimsdk import ReliableMessage
|
|
32
|
+
from dimsdk import MessageProcessor
|
|
33
|
+
|
|
34
|
+
from ..utils import Logging
|
|
35
|
+
|
|
36
|
+
from .archivist import CommonArchivist
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# noinspection PyAbstractClass
|
|
40
|
+
class CommonMessageProcessor(MessageProcessor, Logging, ABC):
|
|
41
|
+
|
|
42
|
+
# private
|
|
43
|
+
# noinspection PyUnusedLocal
|
|
44
|
+
def _check_visa_time(self, content: Content, r_msg: ReliableMessage) -> bool:
|
|
45
|
+
facebook = self.facebook
|
|
46
|
+
archivist = facebook.archivist
|
|
47
|
+
assert isinstance(archivist, CommonArchivist), 'archivist error: %s' % archivist
|
|
48
|
+
doc_updated = False
|
|
49
|
+
# check sender document time
|
|
50
|
+
last_doc_time = r_msg.get_datetime(key='SDT', default=None)
|
|
51
|
+
if last_doc_time is not None:
|
|
52
|
+
now = DateTime.now()
|
|
53
|
+
if last_doc_time.after(now):
|
|
54
|
+
# calibrate the clock
|
|
55
|
+
last_doc_time = now
|
|
56
|
+
sender = r_msg.sender
|
|
57
|
+
doc_updated = archivist.set_last_document_time(identifier=sender, last_time=last_doc_time)
|
|
58
|
+
# check whether needs update
|
|
59
|
+
if doc_updated:
|
|
60
|
+
self.info(msg='checking for new visa: %s' % sender)
|
|
61
|
+
facebook.documents(identifier=sender)
|
|
62
|
+
return doc_updated
|
|
63
|
+
|
|
64
|
+
# Override
|
|
65
|
+
def process_content(self, content: Content, r_msg: ReliableMessage) -> List[Content]:
|
|
66
|
+
responses = super().process_content(content=content, r_msg=r_msg)
|
|
67
|
+
# check sender's document times from the message
|
|
68
|
+
# to make sure the user info synchronized
|
|
69
|
+
self._check_visa_time(content=content, r_msg=r_msg)
|
|
70
|
+
return responses
|
|
@@ -93,19 +93,21 @@ class GroupEmitter(Logging):
|
|
|
93
93
|
def messenger(self) -> CommonMessenger:
|
|
94
94
|
return self.delegate.messenger
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
# private
|
|
97
|
+
def _attach_group_times(self, group: ID, msg: InstantMessage) -> bool:
|
|
97
98
|
if isinstance(msg.content, GroupCommand):
|
|
98
99
|
# no need to attach times for group command
|
|
99
|
-
return
|
|
100
|
+
return True
|
|
100
101
|
facebook = self.facebook
|
|
101
102
|
doc = facebook.bulletin(identifier=group)
|
|
102
103
|
if doc is None:
|
|
103
104
|
self.error(msg='failed to get bulletin document for group: %s' % group)
|
|
104
|
-
return
|
|
105
|
+
return False
|
|
105
106
|
# attach group document time
|
|
106
107
|
last_doc_time = doc.time
|
|
107
108
|
if last_doc_time is None:
|
|
108
109
|
self.error(msg='document error: %s' % doc)
|
|
110
|
+
return False
|
|
109
111
|
else:
|
|
110
112
|
msg.set_datetime(key='GDT', value=last_doc_time)
|
|
111
113
|
# attach group history time
|
|
@@ -113,8 +115,10 @@ class GroupEmitter(Logging):
|
|
|
113
115
|
last_his_time = archivist.get_last_group_history_time(group=group)
|
|
114
116
|
if last_his_time is None:
|
|
115
117
|
self.error(msg='failed to get history time: %s' % group)
|
|
118
|
+
return False
|
|
116
119
|
else:
|
|
117
120
|
msg.set_datetime(key='GHT', value=last_his_time)
|
|
121
|
+
return True
|
|
118
122
|
|
|
119
123
|
def send_message(self, msg: InstantMessage, priority: int = 0) -> Optional[ReliableMessage]:
|
|
120
124
|
content = msg.content
|
|
@@ -125,7 +129,9 @@ class GroupEmitter(Logging):
|
|
|
125
129
|
assert msg.receiver == group, 'group message error: %s' % msg
|
|
126
130
|
# attach group document & history times
|
|
127
131
|
# for the receiver to check whether group info synchronized
|
|
128
|
-
self.
|
|
132
|
+
ok = self._attach_group_times(group=group, msg=msg)
|
|
133
|
+
if not ok:
|
|
134
|
+
self.warning(msg='failed to attach group times: %s => %s' % (group, content))
|
|
129
135
|
# TODO: if it's a file message
|
|
130
136
|
# please upload the file data first
|
|
131
137
|
# before calling this
|
|
@@ -30,8 +30,9 @@
|
|
|
30
30
|
Handshake Protocol
|
|
31
31
|
"""
|
|
32
32
|
|
|
33
|
-
from typing import List
|
|
33
|
+
from typing import Optional, List
|
|
34
34
|
|
|
35
|
+
from dimsdk import DateTime
|
|
35
36
|
from dimsdk import ID, Content, ReliableMessage
|
|
36
37
|
|
|
37
38
|
from dimsdk.cpu import BaseCommandProcessor
|
|
@@ -75,7 +76,7 @@ class HandshakeCommandProcessor(BaseCommandProcessor):
|
|
|
75
76
|
# session key match
|
|
76
77
|
Log.info(msg='handshake accepted: %s, session: %s' % (sender, session.key))
|
|
77
78
|
# verified success
|
|
78
|
-
handshake_accepted(identifier=sender, session=session, messenger=messenger)
|
|
79
|
+
handshake_accepted(identifier=sender, when=content.time, session=session, messenger=messenger)
|
|
79
80
|
res = HandshakeCommand.success(session=session.key)
|
|
80
81
|
else:
|
|
81
82
|
# session key not match
|
|
@@ -85,12 +86,12 @@ class HandshakeCommandProcessor(BaseCommandProcessor):
|
|
|
85
86
|
return [res]
|
|
86
87
|
|
|
87
88
|
|
|
88
|
-
def handshake_accepted(identifier: ID, session: Session, messenger: CommonMessenger):
|
|
89
|
+
def handshake_accepted(identifier: ID, when: Optional[DateTime], session: Session, messenger: CommonMessenger):
|
|
89
90
|
from ..session_center import SessionCenter
|
|
90
91
|
center = SessionCenter()
|
|
91
92
|
# 1. update session ID
|
|
92
93
|
center.update_session(session=session, identifier=identifier)
|
|
93
94
|
# 2. update session flag
|
|
94
|
-
session.set_active(active=True)
|
|
95
|
+
session.set_active(active=True, when=when)
|
|
95
96
|
# 3. callback
|
|
96
97
|
messenger.handshake_success()
|
|
@@ -85,7 +85,7 @@ class LoginCommandProcessor(BaseCommandProcessor, Logging):
|
|
|
85
85
|
self.info(msg='user login: %s -> %s, forwarded by %s' % (sender, roaming, session.identifier))
|
|
86
86
|
return []
|
|
87
87
|
# 3. update session flag
|
|
88
|
-
session.set_active(active=True)
|
|
88
|
+
session.set_active(active=True, when=content.time)
|
|
89
89
|
# only respond the user login to this station
|
|
90
90
|
self.info(msg='user login: %s -> %s' % (sender, roaming))
|
|
91
91
|
text = 'Login received.'
|
|
@@ -76,23 +76,29 @@ class ServerMessagePacker(CommonMessagePacker):
|
|
|
76
76
|
# TODO: trusted station list
|
|
77
77
|
return True
|
|
78
78
|
|
|
79
|
+
# Override
|
|
80
|
+
def deserialize_message(self, data: bytes) -> Optional[ReliableMessage]:
|
|
81
|
+
msg = super().deserialize_message(data=data)
|
|
82
|
+
if msg is not None:
|
|
83
|
+
sender = msg.sender
|
|
84
|
+
receiver = msg.receiver
|
|
85
|
+
# check duplicated
|
|
86
|
+
if self.__is_traced(msg=msg):
|
|
87
|
+
# cycled message
|
|
88
|
+
if sender.type == EntityType.STATION or receiver.type == EntityType.STATION:
|
|
89
|
+
# ignore cycled station message
|
|
90
|
+
self.warning(msg='drop cycled station message: %s -> %s' % (sender, receiver))
|
|
91
|
+
return None
|
|
92
|
+
elif receiver.is_broadcast:
|
|
93
|
+
# ignore cycled broadcast message
|
|
94
|
+
self.warning(msg='drop cycled broadcast message: %s -> %s' % (sender, receiver))
|
|
95
|
+
return None
|
|
96
|
+
self.warning(msg='cycled message: %s -> %s' % (sender, receiver))
|
|
97
|
+
return msg
|
|
98
|
+
|
|
79
99
|
# Override
|
|
80
100
|
def verify_message(self, msg: ReliableMessage) -> Optional[SecureMessage]:
|
|
81
|
-
|
|
82
|
-
receiver = msg.receiver
|
|
83
|
-
# check duplicated
|
|
84
|
-
if self.__is_traced(msg=msg):
|
|
85
|
-
# cycled message
|
|
86
|
-
if sender.type == EntityType.STATION or receiver.type == EntityType.STATION:
|
|
87
|
-
# ignore cycled station message
|
|
88
|
-
self.warning(msg='cycled station message: %s -> %s' % (sender, receiver))
|
|
89
|
-
return None
|
|
90
|
-
elif receiver.is_broadcast:
|
|
91
|
-
# ignore cycled broadcast message
|
|
92
|
-
self.warning(msg='cycled broadcast message: %s -> %s' % (sender, receiver))
|
|
93
|
-
return None
|
|
94
|
-
self.warning(msg='cycled message: %s -> %s' % (sender, receiver))
|
|
95
|
-
# check session
|
|
101
|
+
# check session ready
|
|
96
102
|
if self.__is_trusted(sender=msg.sender):
|
|
97
103
|
# no need to verify message from this sender
|
|
98
104
|
self.debug(msg='trusted sender: %s' % msg.sender)
|
|
@@ -38,16 +38,14 @@ from dimsdk import Envelope
|
|
|
38
38
|
from dimsdk import Content, ContentType, Command
|
|
39
39
|
from dimsdk import TextContent, ReceiptCommand
|
|
40
40
|
from dimsdk import ContentProcessor, ContentProcessorCreator
|
|
41
|
-
from dimsdk import MessageProcessor
|
|
42
41
|
|
|
43
42
|
from dimsdk.cpu import BaseContentProcessor, BaseContentProcessorCreator
|
|
44
43
|
|
|
45
|
-
from ..utils import get_msg_info
|
|
46
|
-
from ..utils import Logging
|
|
47
44
|
from ..common import HandshakeCommand, LoginCommand
|
|
48
45
|
from ..common import ReportCommand, AnsCommand
|
|
49
46
|
from ..common import CommonFacebook, CommonMessenger
|
|
50
47
|
from ..common import CommonMessagePacker
|
|
48
|
+
from ..common import CommonMessageProcessor
|
|
51
49
|
|
|
52
50
|
from .cpu import HandshakeCommandProcessor
|
|
53
51
|
from .cpu import LoginCommandProcessor
|
|
@@ -61,7 +59,7 @@ from .dispatcher import Dispatcher
|
|
|
61
59
|
from .archivist import ServerArchivist
|
|
62
60
|
|
|
63
61
|
|
|
64
|
-
class ServerMessageProcessor(
|
|
62
|
+
class ServerMessageProcessor(CommonMessageProcessor):
|
|
65
63
|
|
|
66
64
|
@property
|
|
67
65
|
def messenger(self) -> CommonMessenger:
|
|
@@ -166,9 +164,6 @@ class ServerMessageProcessor(MessageProcessor, Logging):
|
|
|
166
164
|
# TODO: override to deliver to the receiver when catch exception "receiver error ..."
|
|
167
165
|
|
|
168
166
|
def _force_handshake(self, msg: ReliableMessage) -> List[ReliableMessage]:
|
|
169
|
-
if self.messenger.verify_message(msg=msg) is None:
|
|
170
|
-
assert False, 'failed to verify message: %s' % get_msg_info(msg=msg)
|
|
171
|
-
# return []
|
|
172
167
|
session = self.messenger.session
|
|
173
168
|
sess_id = session.identifier
|
|
174
169
|
current = self.facebook.current_user
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|