dimp 2.3.1__tar.gz → 2.3.2__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.
- {dimp-2.3.1 → dimp-2.3.2}/PKG-INFO +1 -1
- {dimp-2.3.1 → dimp-2.3.2}/dimp/__init__.py +1 -1
- {dimp-2.3.1 → dimp-2.3.2}/dimp/crypto/keys.py +44 -20
- {dimp-2.3.1 → dimp-2.3.2}/dimp/crypto/pnf.py +10 -7
- {dimp-2.3.1 → dimp-2.3.2}/dimp/crypto/ted.py +11 -11
- {dimp-2.3.1 → dimp-2.3.2}/dimp/dkd/__init__.py +17 -16
- {dimp-2.3.1 → dimp-2.3.2}/dimp/mkm/docs.py +19 -15
- {dimp-2.3.1 → dimp-2.3.2}/dimp/mkm/document.py +5 -9
- {dimp-2.3.1 → dimp-2.3.2}/dimp/mkm/meta.py +7 -7
- {dimp-2.3.1 → dimp-2.3.2}/dimp/msg/base.py +2 -2
- {dimp-2.3.1 → dimp-2.3.2}/dimp/msg/envelope.py +17 -14
- {dimp-2.3.1 → dimp-2.3.2}/dimp/msg/instant.py +8 -6
- {dimp-2.3.1 → dimp-2.3.2}/dimp/msg/reliable.py +2 -2
- {dimp-2.3.1 → dimp-2.3.2}/dimp/msg/secure.py +15 -9
- {dimp-2.3.1 → dimp-2.3.2}/dimp/plugins/__init__.py +2 -2
- {dimp-2.3.1 → dimp-2.3.2}/dimp/protocol/__init__.py +8 -8
- {dimp-2.3.1/dimp/dkd → dimp-2.3.2/dimp/protocol}/base.py +140 -15
- {dimp-2.3.1/dimp/dkd → dimp-2.3.2/dimp/protocol}/commands.py +126 -30
- {dimp-2.3.1/dimp/dkd → dimp-2.3.2/dimp/protocol}/contents.py +166 -132
- {dimp-2.3.1 → dimp-2.3.2}/dimp/protocol/files.py +150 -9
- dimp-2.3.2/dimp/protocol/forward.py +253 -0
- dimp-2.3.2/dimp/protocol/groups.py +498 -0
- {dimp-2.3.1/dimp/dkd → dimp-2.3.2/dimp/protocol}/money.py +93 -27
- {dimp-2.3.1 → dimp-2.3.2}/dimp/protocol/quote.py +51 -34
- {dimp-2.3.1/dimp/dkd → dimp-2.3.2/dimp/protocol}/receipt.py +83 -11
- {dimp-2.3.1 → dimp-2.3.2}/dimp.egg-info/PKG-INFO +1 -1
- {dimp-2.3.1 → dimp-2.3.2}/dimp.egg-info/SOURCES.txt +2 -10
- dimp-2.3.2/dimp.egg-info/requires.txt +2 -0
- {dimp-2.3.1 → dimp-2.3.2}/setup.py +3 -3
- dimp-2.3.1/dimp/dkd/files.py +0 -181
- dimp-2.3.1/dimp/dkd/group_admins.py +0 -142
- dimp-2.3.1/dimp/dkd/groups.py +0 -234
- dimp-2.3.1/dimp/dkd/quote.py +0 -145
- dimp-2.3.1/dimp/plugins/cmd.py +0 -79
- dimp-2.3.1/dimp/protocol/commands.py +0 -247
- dimp-2.3.1/dimp/protocol/contents.py +0 -279
- dimp-2.3.1/dimp/protocol/groups.py +0 -286
- dimp-2.3.1/dimp/protocol/money.py +0 -124
- dimp-2.3.1/dimp/protocol/receipt.py +0 -130
- dimp-2.3.1/dimp.egg-info/requires.txt +0 -2
- {dimp-2.3.1 → dimp-2.3.2}/LICENSE +0 -0
- {dimp-2.3.1 → dimp-2.3.2}/README.md +0 -0
- {dimp-2.3.1 → dimp-2.3.2}/dimp/crypto/__init__.py +0 -0
- {dimp-2.3.1 → dimp-2.3.2}/dimp/crypto/algorithms.py +0 -0
- {dimp-2.3.1 → dimp-2.3.2}/dimp/mkm/__init__.py +0 -0
- {dimp-2.3.1 → dimp-2.3.2}/dimp/msg/__init__.py +0 -0
- {dimp-2.3.1 → dimp-2.3.2}/dimp/protocol/docs.py +0 -0
- {dimp-2.3.1 → dimp-2.3.2}/dimp/protocol/helpers.py +0 -0
- {dimp-2.3.1 → dimp-2.3.2}/dimp/protocol/types.py +0 -0
- {dimp-2.3.1 → dimp-2.3.2}/dimp.egg-info/dependency_links.txt +0 -0
- {dimp-2.3.1 → dimp-2.3.2}/dimp.egg-info/top_level.txt +0 -0
- {dimp-2.3.1 → dimp-2.3.2}/setup.cfg +0 -0
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
# ==============================================================================
|
|
30
30
|
|
|
31
31
|
from abc import ABC
|
|
32
|
-
from typing import
|
|
32
|
+
from typing import Dict
|
|
33
33
|
|
|
34
|
-
from mkm.types import Dictionary
|
|
34
|
+
from mkm.types import Mapper, Dictionary
|
|
35
35
|
from mkm.crypto import CryptographyKey, EncryptKey, DecryptKey, SignKey, VerifyKey
|
|
36
36
|
from mkm.crypto import SymmetricKey, AsymmetricKey, PublicKey, PrivateKey
|
|
37
37
|
from mkm.plugins import SharedCryptoExtensions
|
|
@@ -46,7 +46,7 @@ from mkm.plugins import SharedCryptoExtensions
|
|
|
46
46
|
# noinspection PyAbstractClass
|
|
47
47
|
class BaseKey(Dictionary, CryptographyKey, ABC):
|
|
48
48
|
|
|
49
|
-
def __init__(self, key: Dict
|
|
49
|
+
def __init__(self, key: Dict):
|
|
50
50
|
super().__init__(dictionary=key)
|
|
51
51
|
|
|
52
52
|
@property # Override
|
|
@@ -58,7 +58,7 @@ class BaseKey(Dictionary, CryptographyKey, ABC):
|
|
|
58
58
|
#
|
|
59
59
|
|
|
60
60
|
@classmethod
|
|
61
|
-
def get_key_algorithm(cls, key: Dict
|
|
61
|
+
def get_key_algorithm(cls, key: Dict) -> str:
|
|
62
62
|
ext = SharedCryptoExtensions()
|
|
63
63
|
algorithm = ext.helper.get_key_algorithm(key=key, default=None)
|
|
64
64
|
return '' if algorithm is None else algorithm
|
|
@@ -97,20 +97,32 @@ class BaseKey(Dictionary, CryptographyKey, ABC):
|
|
|
97
97
|
# noinspection PyAbstractClass
|
|
98
98
|
class BaseSymmetricKey(Dictionary, SymmetricKey, ABC):
|
|
99
99
|
|
|
100
|
-
def __init__(self, key: Dict
|
|
100
|
+
def __init__(self, key: Dict):
|
|
101
101
|
super().__init__(dictionary=key)
|
|
102
102
|
|
|
103
103
|
# Override
|
|
104
104
|
def __eq__(self, other) -> bool:
|
|
105
|
-
if isinstance(other,
|
|
106
|
-
|
|
105
|
+
if isinstance(other, Mapper):
|
|
106
|
+
if self is other:
|
|
107
|
+
# same object
|
|
108
|
+
return True
|
|
109
|
+
elif isinstance(other, SymmetricKey):
|
|
110
|
+
return BaseKey.symmetric_keys_equal(other, self)
|
|
111
|
+
# compare with inner map
|
|
112
|
+
other = other.dictionary
|
|
113
|
+
return self.dictionary.__eq__(other)
|
|
107
114
|
|
|
108
115
|
# Override
|
|
109
116
|
def __ne__(self, other) -> bool:
|
|
110
|
-
if isinstance(other,
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
117
|
+
if isinstance(other, Mapper):
|
|
118
|
+
if self is other:
|
|
119
|
+
# same object
|
|
120
|
+
return False
|
|
121
|
+
elif isinstance(other, SymmetricKey):
|
|
122
|
+
return not BaseKey.symmetric_keys_equal(other, self)
|
|
123
|
+
# compare with inner map
|
|
124
|
+
other = other.dictionary
|
|
125
|
+
return self.dictionary.__ne__(other)
|
|
114
126
|
|
|
115
127
|
@property # Override
|
|
116
128
|
def algorithm(self) -> str:
|
|
@@ -124,7 +136,7 @@ class BaseSymmetricKey(Dictionary, SymmetricKey, ABC):
|
|
|
124
136
|
# noinspection PyAbstractClass
|
|
125
137
|
class BaseAsymmetricKey(Dictionary, AsymmetricKey, ABC):
|
|
126
138
|
|
|
127
|
-
def __init__(self, key: Dict
|
|
139
|
+
def __init__(self, key: Dict):
|
|
128
140
|
super().__init__(dictionary=key)
|
|
129
141
|
|
|
130
142
|
@property # Override
|
|
@@ -135,7 +147,7 @@ class BaseAsymmetricKey(Dictionary, AsymmetricKey, ABC):
|
|
|
135
147
|
# noinspection PyAbstractClass
|
|
136
148
|
class BasePublicKey(Dictionary, PublicKey, ABC):
|
|
137
149
|
|
|
138
|
-
def __init__(self, key: Dict
|
|
150
|
+
def __init__(self, key: Dict):
|
|
139
151
|
super().__init__(dictionary=key)
|
|
140
152
|
|
|
141
153
|
@property # Override
|
|
@@ -150,20 +162,32 @@ class BasePublicKey(Dictionary, PublicKey, ABC):
|
|
|
150
162
|
# noinspection PyAbstractClass
|
|
151
163
|
class BasePrivateKey(Dictionary, PrivateKey, ABC):
|
|
152
164
|
|
|
153
|
-
def __init__(self, key: Dict
|
|
165
|
+
def __init__(self, key: Dict):
|
|
154
166
|
super().__init__(dictionary=key)
|
|
155
167
|
|
|
156
168
|
# Override
|
|
157
169
|
def __eq__(self, other) -> bool:
|
|
158
|
-
if isinstance(other,
|
|
159
|
-
|
|
170
|
+
if isinstance(other, Mapper):
|
|
171
|
+
if self is other:
|
|
172
|
+
# same object
|
|
173
|
+
return True
|
|
174
|
+
elif isinstance(other, PrivateKey):
|
|
175
|
+
return BaseKey.private_keys_equal(other, self)
|
|
176
|
+
# compare with inner map
|
|
177
|
+
other = other.dictionary
|
|
178
|
+
return self.dictionary.__eq__(other)
|
|
160
179
|
|
|
161
180
|
# Override
|
|
162
181
|
def __ne__(self, other) -> bool:
|
|
163
|
-
if isinstance(other,
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
182
|
+
if isinstance(other, Mapper):
|
|
183
|
+
if self is other:
|
|
184
|
+
# same object
|
|
185
|
+
return False
|
|
186
|
+
elif isinstance(other, PrivateKey):
|
|
187
|
+
return not BaseKey.private_keys_equal(other, self)
|
|
188
|
+
# compare with inner map
|
|
189
|
+
other = other.dictionary
|
|
190
|
+
return self.dictionary.__ne__(other)
|
|
167
191
|
|
|
168
192
|
@property # Override
|
|
169
193
|
def algorithm(self) -> str:
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
# SOFTWARE.
|
|
29
29
|
# ==============================================================================
|
|
30
30
|
|
|
31
|
-
from typing import Optional,
|
|
31
|
+
from typing import Optional, Dict
|
|
32
32
|
|
|
33
33
|
from mkm.format import TransportableData
|
|
34
34
|
from mkm.types import URI
|
|
@@ -55,7 +55,7 @@ class BaseFileWrapper(Dictionary):
|
|
|
55
55
|
}
|
|
56
56
|
"""
|
|
57
57
|
|
|
58
|
-
def __init__(self, dictionary: Dict
|
|
58
|
+
def __init__(self, dictionary: Dict):
|
|
59
59
|
super().__init__(dictionary=dictionary)
|
|
60
60
|
# file data (not encrypted)
|
|
61
61
|
self.__attachment: Optional[TransportableData] = None
|
|
@@ -115,11 +115,12 @@ class BaseFileWrapper(Dictionary):
|
|
|
115
115
|
|
|
116
116
|
@property
|
|
117
117
|
def url(self) -> Optional[URI]:
|
|
118
|
-
|
|
118
|
+
remote = self.__url
|
|
119
|
+
if remote is None:
|
|
119
120
|
remote = self.get_str(key='URL', default=None)
|
|
120
121
|
# TODO: convert str to URI
|
|
121
122
|
self.__url = remote
|
|
122
|
-
return
|
|
123
|
+
return remote
|
|
123
124
|
|
|
124
125
|
@url.setter
|
|
125
126
|
def url(self, remote: Optional[URI]):
|
|
@@ -136,10 +137,12 @@ class BaseFileWrapper(Dictionary):
|
|
|
136
137
|
|
|
137
138
|
@property
|
|
138
139
|
def password(self) -> Optional[DecryptKey]:
|
|
139
|
-
|
|
140
|
+
key = self.__password
|
|
141
|
+
if key is None:
|
|
140
142
|
info = self.get('key')
|
|
141
|
-
|
|
142
|
-
|
|
143
|
+
key = SymmetricKey.parse(key=info)
|
|
144
|
+
self.__password = key
|
|
145
|
+
return key
|
|
143
146
|
|
|
144
147
|
@password.setter
|
|
145
148
|
def password(self, key: Optional[DecryptKey]):
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
# SOFTWARE.
|
|
29
29
|
# ==============================================================================
|
|
30
30
|
|
|
31
|
-
from typing import Optional,
|
|
31
|
+
from typing import Optional, Dict
|
|
32
32
|
|
|
33
33
|
from mkm.format import base64_encode, base64_decode
|
|
34
34
|
from mkm.format import base58_encode, base58_decode
|
|
@@ -54,18 +54,18 @@ class BaseDataWrapper(Dictionary):
|
|
|
54
54
|
2. "data:image/png;base64,{BASE64_ENCODE}"
|
|
55
55
|
"""
|
|
56
56
|
|
|
57
|
-
def __init__(self, dictionary: Dict
|
|
57
|
+
def __init__(self, dictionary: Dict):
|
|
58
58
|
super().__init__(dictionary=dictionary)
|
|
59
59
|
# binary data
|
|
60
60
|
self.__data: Optional[bytes] = None
|
|
61
61
|
|
|
62
|
-
# Override
|
|
63
|
-
def __len__(self) -> int:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
# # Override
|
|
63
|
+
# def __len__(self) -> int:
|
|
64
|
+
# """ return len(self) """
|
|
65
|
+
# if super().__len__() == 0:
|
|
66
|
+
# return 0
|
|
67
|
+
# data = self.data
|
|
68
|
+
# return 0 if data is None else len(data)
|
|
69
69
|
|
|
70
70
|
# Override
|
|
71
71
|
def __str__(self) -> str:
|
|
@@ -120,8 +120,8 @@ class BaseDataWrapper(Dictionary):
|
|
|
120
120
|
if binary is None:
|
|
121
121
|
text = self.get_str(key='data', default=None)
|
|
122
122
|
if text is None or len(text) == 0:
|
|
123
|
-
assert False, 'TED data empty: %s' % self.dictionary
|
|
124
|
-
|
|
123
|
+
# assert False, 'TED data empty: %s' % self.dictionary
|
|
124
|
+
return None
|
|
125
125
|
else:
|
|
126
126
|
alg = self.algorithm
|
|
127
127
|
if alg == EncodeAlgorithms.BASE_64:
|
|
@@ -31,22 +31,23 @@
|
|
|
31
31
|
from dkd import *
|
|
32
32
|
from ..protocol import *
|
|
33
33
|
|
|
34
|
-
from .base import BaseContent
|
|
35
|
-
from .contents import BaseTextContent,
|
|
36
|
-
from .
|
|
37
|
-
from .files import BaseFileContent, ImageFileContent, AudioFileContent, VideoFileContent
|
|
38
|
-
from .money import BaseMoneyContent, TransferMoneyContent
|
|
39
|
-
from .quote import BaseQuoteContent
|
|
40
|
-
|
|
41
|
-
from .
|
|
42
|
-
from .
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
from .groups import
|
|
46
|
-
from .groups import
|
|
47
|
-
from .
|
|
48
|
-
|
|
49
|
-
|
|
34
|
+
from ..protocol.base import BaseContent
|
|
35
|
+
from ..protocol.contents import BaseTextContent, WebPageContent, NameCardContent
|
|
36
|
+
from ..protocol.forward import SecretContent, CombineForwardContent, ListContent
|
|
37
|
+
from ..protocol.files import BaseFileContent, ImageFileContent, AudioFileContent, VideoFileContent
|
|
38
|
+
from ..protocol.money import BaseMoneyContent, TransferMoneyContent
|
|
39
|
+
from ..protocol.quote import BaseQuoteContent
|
|
40
|
+
|
|
41
|
+
from ..protocol.base import BaseCommand
|
|
42
|
+
from ..protocol.commands import BaseMetaCommand, BaseDocumentCommand
|
|
43
|
+
from ..protocol.receipt import BaseReceiptCommand
|
|
44
|
+
|
|
45
|
+
from ..protocol.groups import BaseHistoryCommand, BaseGroupCommand
|
|
46
|
+
from ..protocol.groups import InviteGroupCommand, ExpelGroupCommand, JoinGroupCommand
|
|
47
|
+
from ..protocol.groups import QuitGroupCommand, QueryGroupCommand, ResetGroupCommand
|
|
48
|
+
from ..protocol.groups import HireGroupCommand, FireGroupCommand, ResignGroupCommand
|
|
49
|
+
|
|
50
|
+
# from ..protocol.base import CommandHelper
|
|
50
51
|
# from ..protocol.helpers import CommandExtensions
|
|
51
52
|
|
|
52
53
|
__all__ = [
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
# SOFTWARE.
|
|
29
29
|
# ==============================================================================
|
|
30
30
|
|
|
31
|
-
from typing import Optional,
|
|
31
|
+
from typing import Optional, Dict, List
|
|
32
32
|
|
|
33
33
|
from mkm.crypto import PublicKey, EncryptKey
|
|
34
34
|
from mkm.format import TransportableData
|
|
@@ -43,7 +43,7 @@ from .document import BaseDocument
|
|
|
43
43
|
|
|
44
44
|
class BaseVisa(BaseDocument, Visa):
|
|
45
45
|
|
|
46
|
-
def __init__(self, document: Optional[Dict
|
|
46
|
+
def __init__(self, document: Optional[Dict] = None,
|
|
47
47
|
identifier: ID = None, data: Optional[str] = None, signature: Optional[TransportableData] = None):
|
|
48
48
|
if document is None:
|
|
49
49
|
# 1. document from local
|
|
@@ -68,15 +68,17 @@ class BaseVisa(BaseDocument, Visa):
|
|
|
68
68
|
|
|
69
69
|
@property # Override
|
|
70
70
|
def public_key(self) -> Optional[EncryptKey]:
|
|
71
|
-
|
|
71
|
+
visa_key = self.__key
|
|
72
|
+
if visa_key is None:
|
|
72
73
|
info = self.get_property(name='key')
|
|
73
74
|
# assert info is not None, 'visa key not found: %s' % self.dictionary
|
|
74
75
|
pub = PublicKey.parse(key=info)
|
|
75
76
|
if isinstance(pub, EncryptKey):
|
|
76
|
-
|
|
77
|
+
visa_key = pub
|
|
78
|
+
self.__key = visa_key
|
|
77
79
|
else:
|
|
78
80
|
assert info is None, 'visa key error: %s' % info
|
|
79
|
-
return
|
|
81
|
+
return visa_key
|
|
80
82
|
|
|
81
83
|
@public_key.setter # Override
|
|
82
84
|
def public_key(self, key: EncryptKey):
|
|
@@ -91,25 +93,27 @@ class BaseVisa(BaseDocument, Visa):
|
|
|
91
93
|
|
|
92
94
|
@property # Override
|
|
93
95
|
def avatar(self) -> Optional[PortableNetworkFile]:
|
|
94
|
-
|
|
96
|
+
img = self.__avatar
|
|
97
|
+
if img is None:
|
|
95
98
|
url = self.get_property(name='avatar')
|
|
96
99
|
if isinstance(url, str) and len(url) == 0:
|
|
97
100
|
# ignore empty URL
|
|
98
101
|
pass
|
|
99
102
|
else:
|
|
100
|
-
|
|
101
|
-
|
|
103
|
+
img = PortableNetworkFile.parse(url)
|
|
104
|
+
self.__avatar = img
|
|
105
|
+
return img
|
|
102
106
|
|
|
103
107
|
@avatar.setter # Override
|
|
104
|
-
def avatar(self,
|
|
105
|
-
info = None if
|
|
108
|
+
def avatar(self, img: PortableNetworkFile):
|
|
109
|
+
info = None if img is None else img.object
|
|
106
110
|
self.set_property(name='avatar', value=info)
|
|
107
|
-
self.__avatar =
|
|
111
|
+
self.__avatar = img
|
|
108
112
|
|
|
109
113
|
|
|
110
114
|
class BaseBulletin(BaseDocument, Bulletin):
|
|
111
115
|
|
|
112
|
-
def __init__(self, document: Optional[Dict
|
|
116
|
+
def __init__(self, document: Optional[Dict] = None,
|
|
113
117
|
identifier: ID = None,
|
|
114
118
|
data: Optional[str] = None, signature: Optional[TransportableData] = None):
|
|
115
119
|
if document is None:
|
|
@@ -134,13 +138,13 @@ class BaseBulletin(BaseDocument, Bulletin):
|
|
|
134
138
|
def assistants(self) -> Optional[List[ID]]:
|
|
135
139
|
if self.__bots is None:
|
|
136
140
|
bots = self.get_property(name='assistants')
|
|
137
|
-
if bots
|
|
141
|
+
if isinstance(bots, List):
|
|
142
|
+
self.__bots = ID.convert(array=bots)
|
|
143
|
+
else:
|
|
138
144
|
# get from 'assistant'
|
|
139
145
|
single = self.get_property(name='assistant')
|
|
140
146
|
single = ID.parse(identifier=single)
|
|
141
147
|
self.__bots = [] if single is None else [single]
|
|
142
|
-
else:
|
|
143
|
-
self.__bots = ID.convert(array=bots)
|
|
144
148
|
return self.__bots
|
|
145
149
|
|
|
146
150
|
@assistants.setter # Override
|
|
@@ -48,7 +48,7 @@ from mkm import ID, Document
|
|
|
48
48
|
|
|
49
49
|
class BaseDocument(Dictionary, Document):
|
|
50
50
|
|
|
51
|
-
def __init__(self, document: Dict
|
|
51
|
+
def __init__(self, document: Dict = None,
|
|
52
52
|
doc_type: str = None, identifier: ID = None,
|
|
53
53
|
data: Optional[str] = None, signature: Optional[TransportableData] = None):
|
|
54
54
|
# check parameters
|
|
@@ -189,16 +189,12 @@ class BaseDocument(Dictionary, Document):
|
|
|
189
189
|
# 2. encode & sign
|
|
190
190
|
info = self.properties
|
|
191
191
|
if info is None:
|
|
192
|
-
# assert False, '
|
|
192
|
+
# assert False, 'document invalid: %s' % self.dictionary
|
|
193
193
|
return None
|
|
194
194
|
data = json_encode(info)
|
|
195
|
-
|
|
196
|
-
# properties error
|
|
197
|
-
return None
|
|
195
|
+
assert len(data) > 0, 'should not happen: %s' % info
|
|
198
196
|
signature = private_key.sign(data=utf8_encode(string=data))
|
|
199
|
-
|
|
200
|
-
# assert False, 'should not happen'
|
|
201
|
-
return None
|
|
197
|
+
assert len(signature) > 0, 'should not happen: %s' % info
|
|
202
198
|
ted = TransportableData.create(data=signature)
|
|
203
199
|
# 3. update 'data' & 'signature' fields
|
|
204
200
|
self['data'] = data # JsON string
|
|
@@ -214,7 +210,7 @@ class BaseDocument(Dictionary, Document):
|
|
|
214
210
|
#
|
|
215
211
|
|
|
216
212
|
@property # Override
|
|
217
|
-
def properties(self) -> Optional[Dict
|
|
213
|
+
def properties(self) -> Optional[Dict]:
|
|
218
214
|
""" Load properties from data """
|
|
219
215
|
if self.__status < 0:
|
|
220
216
|
# invalid
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
# ==============================================================================
|
|
30
30
|
|
|
31
31
|
from abc import ABC, abstractmethod
|
|
32
|
-
from typing import Optional,
|
|
32
|
+
from typing import Optional, Dict
|
|
33
33
|
|
|
34
34
|
from mkm.format import utf8_encode
|
|
35
35
|
from mkm.format import TransportableData
|
|
@@ -45,10 +45,10 @@ from mkm import Meta
|
|
|
45
45
|
This class is used to generate entity ID
|
|
46
46
|
|
|
47
47
|
data format: {
|
|
48
|
-
type
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
fingerprint: "..." // CT = sign(seed, SK);
|
|
48
|
+
type : 1, // meta version
|
|
49
|
+
key : "{public key}", // PK = secp256k1(SK);
|
|
50
|
+
seed : "moKy", // user/group name
|
|
51
|
+
fingerprint : "..." // CT = sign(seed, SK);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
algorithm:
|
|
@@ -61,7 +61,7 @@ from mkm import Meta
|
|
|
61
61
|
|
|
62
62
|
class BaseMeta(Dictionary, Meta, ABC):
|
|
63
63
|
|
|
64
|
-
def __init__(self, meta: Dict
|
|
64
|
+
def __init__(self, meta: Dict = None,
|
|
65
65
|
version: str = None, public_key: VerifyKey = None,
|
|
66
66
|
seed: Optional[str] = None, fingerprint: Optional[TransportableData] = None):
|
|
67
67
|
# check parameters
|
|
@@ -142,7 +142,7 @@ class BaseMeta(Dictionary, Meta, ABC):
|
|
|
142
142
|
ted = self.__fingerprint
|
|
143
143
|
if ted is None and self.has_seed:
|
|
144
144
|
base64 = self.get('fingerprint')
|
|
145
|
-
assert base64 is not None, 'meta.fingerprint should not be empty: %s' % self
|
|
145
|
+
assert base64 is not None, 'meta.fingerprint should not be empty: %s' % self.dictionary
|
|
146
146
|
self.__fingerprint = ted = TransportableData.parse(base64)
|
|
147
147
|
assert ted is not None, 'meta.fingerprint error: %s' % base64
|
|
148
148
|
if ted is not None:
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"""
|
|
51
51
|
|
|
52
52
|
|
|
53
|
-
from typing import Optional,
|
|
53
|
+
from typing import Optional, Dict
|
|
54
54
|
|
|
55
55
|
from mkm.types import DateTime
|
|
56
56
|
from mkm.types import Dictionary
|
|
@@ -61,7 +61,7 @@ from dkd import Envelope, Message
|
|
|
61
61
|
|
|
62
62
|
class BaseMessage(Dictionary, Message):
|
|
63
63
|
|
|
64
|
-
def __init__(self, msg: Dict
|
|
64
|
+
def __init__(self, msg: Dict = None, head: Envelope = None):
|
|
65
65
|
if msg is None:
|
|
66
66
|
# 1. new message with envelope
|
|
67
67
|
assert head is not None, 'message envelope should not be empty'
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
# SOFTWARE.
|
|
29
29
|
# ==============================================================================
|
|
30
30
|
|
|
31
|
-
from typing import Optional,
|
|
31
|
+
from typing import Optional, Dict
|
|
32
32
|
|
|
33
33
|
from mkm.types import DateTime
|
|
34
34
|
from mkm.types import Dictionary
|
|
@@ -53,7 +53,7 @@ from dkd import Envelope
|
|
|
53
53
|
|
|
54
54
|
class MessageEnvelope(Dictionary, Envelope):
|
|
55
55
|
|
|
56
|
-
def __init__(self, envelope: Dict
|
|
56
|
+
def __init__(self, envelope: Dict = None,
|
|
57
57
|
sender: ID = None, receiver: Optional[ID] = None, time: Optional[DateTime] = None):
|
|
58
58
|
if envelope is None:
|
|
59
59
|
# 1. new envelope with sender, receiver & time
|
|
@@ -80,21 +80,24 @@ class MessageEnvelope(Dictionary, Envelope):
|
|
|
80
80
|
|
|
81
81
|
@property # Override
|
|
82
82
|
def sender(self) -> ID:
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
did = self.__sender
|
|
84
|
+
if did is None:
|
|
85
|
+
did = self.get('sender')
|
|
86
|
+
did = ID.parse(identifier=did)
|
|
87
|
+
assert did is not None, 'message sender error: %s' % self.dictionary
|
|
88
|
+
self.__sender = did
|
|
89
|
+
return did
|
|
87
90
|
|
|
88
91
|
@property # Override
|
|
89
92
|
def receiver(self) -> ID:
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
return
|
|
93
|
+
did = self.__receiver
|
|
94
|
+
if did is None:
|
|
95
|
+
did = self.get('receiver')
|
|
96
|
+
did = ID.parse(identifier=did)
|
|
97
|
+
if did is None:
|
|
98
|
+
did = ANYONE
|
|
99
|
+
self.__receiver = did
|
|
100
|
+
return did
|
|
98
101
|
|
|
99
102
|
@property # Override
|
|
100
103
|
def time(self) -> Optional[DateTime]:
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
# SOFTWARE.
|
|
29
29
|
# ==============================================================================
|
|
30
30
|
|
|
31
|
-
from typing import Optional,
|
|
31
|
+
from typing import Optional, Dict
|
|
32
32
|
|
|
33
33
|
from mkm.types import DateTime
|
|
34
34
|
from mkm import ID
|
|
@@ -57,7 +57,7 @@ from .base import BaseMessage
|
|
|
57
57
|
|
|
58
58
|
class PlainMessage(BaseMessage, InstantMessage):
|
|
59
59
|
|
|
60
|
-
def __init__(self, msg: Dict
|
|
60
|
+
def __init__(self, msg: Dict = None,
|
|
61
61
|
head: Envelope = None, body: Content = None):
|
|
62
62
|
if msg is None:
|
|
63
63
|
# 1. new instant message with envelope & content
|
|
@@ -73,11 +73,13 @@ class PlainMessage(BaseMessage, InstantMessage):
|
|
|
73
73
|
|
|
74
74
|
@property # Override
|
|
75
75
|
def content(self) -> Content:
|
|
76
|
-
|
|
76
|
+
body = self.__content
|
|
77
|
+
if body is None:
|
|
77
78
|
info = self.get('content')
|
|
78
|
-
|
|
79
|
-
assert
|
|
80
|
-
|
|
79
|
+
body = Content.parse(content=info)
|
|
80
|
+
assert body is not None, 'message content error: %s' % self.dictionary
|
|
81
|
+
self.__content = body
|
|
82
|
+
return body
|
|
81
83
|
|
|
82
84
|
@content.setter # protected
|
|
83
85
|
def content(self, value: Content):
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
# SOFTWARE.
|
|
29
29
|
# ==============================================================================
|
|
30
30
|
|
|
31
|
-
from typing import Optional,
|
|
31
|
+
from typing import Optional, Dict
|
|
32
32
|
|
|
33
33
|
from mkm.format import TransportableData
|
|
34
34
|
|
|
@@ -62,7 +62,7 @@ from .secure import EncryptedMessage
|
|
|
62
62
|
|
|
63
63
|
class NetworkMessage(EncryptedMessage, ReliableMessage):
|
|
64
64
|
|
|
65
|
-
def __init__(self, msg: Dict
|
|
65
|
+
def __init__(self, msg: Dict):
|
|
66
66
|
super().__init__(msg=msg)
|
|
67
67
|
# lazy
|
|
68
68
|
self.__signature: Optional[TransportableData] = None
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
# SOFTWARE.
|
|
29
29
|
# ==============================================================================
|
|
30
30
|
|
|
31
|
-
from typing import Optional,
|
|
31
|
+
from typing import Optional, Dict
|
|
32
32
|
|
|
33
33
|
from mkm.format import utf8_encode
|
|
34
34
|
from mkm.format import TransportableData
|
|
@@ -60,7 +60,7 @@ from .base import BaseMessage
|
|
|
60
60
|
|
|
61
61
|
class EncryptedMessage(BaseMessage, SecureMessage):
|
|
62
62
|
|
|
63
|
-
def __init__(self, msg: Dict
|
|
63
|
+
def __init__(self, msg: Dict):
|
|
64
64
|
super().__init__(msg=msg)
|
|
65
65
|
# lazy
|
|
66
66
|
self.__data: Optional[bytes] = None
|
|
@@ -69,21 +69,23 @@ class EncryptedMessage(BaseMessage, SecureMessage):
|
|
|
69
69
|
|
|
70
70
|
@property # Override
|
|
71
71
|
def data(self) -> bytes:
|
|
72
|
-
|
|
72
|
+
binary = self.__data
|
|
73
|
+
if binary is None:
|
|
73
74
|
text = self.get('data')
|
|
74
75
|
if text is None:
|
|
75
|
-
assert False, 'message data
|
|
76
|
+
assert False, 'message data not found: %s' % self.dictionary
|
|
76
77
|
elif not BaseMessage.is_broadcast(msg=self):
|
|
77
78
|
# message content had been encrypted by a symmetric key,
|
|
78
79
|
# so the data should be encoded here (with algorithm 'base64' as default).
|
|
79
|
-
|
|
80
|
+
binary = TransportableData.decode(text)
|
|
80
81
|
elif isinstance(text, str):
|
|
81
82
|
# broadcast message content will not be encrypted (just encoded to JsON),
|
|
82
83
|
# so return the string data directly
|
|
83
|
-
|
|
84
|
+
binary = utf8_encode(string=text) # JsON
|
|
84
85
|
else:
|
|
85
86
|
assert False, 'content data error: %s' % text
|
|
86
|
-
|
|
87
|
+
self.__data = binary
|
|
88
|
+
return binary
|
|
87
89
|
|
|
88
90
|
@property # Override
|
|
89
91
|
def encrypted_key(self) -> Optional[bytes]:
|
|
@@ -102,7 +104,11 @@ class EncryptedMessage(BaseMessage, SecureMessage):
|
|
|
102
104
|
return ted.data
|
|
103
105
|
|
|
104
106
|
@property # Override
|
|
105
|
-
def encrypted_keys(self) -> Optional[Dict
|
|
107
|
+
def encrypted_keys(self) -> Optional[Dict]:
|
|
106
108
|
if self.__keys is None:
|
|
107
|
-
|
|
109
|
+
keys = self.get('keys')
|
|
110
|
+
if isinstance(keys, Dict):
|
|
111
|
+
self.__keys = keys
|
|
112
|
+
else:
|
|
113
|
+
assert keys is None, 'message keys error: %s' % keys
|
|
108
114
|
return self.__keys
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
from mkm.plugins import *
|
|
32
32
|
from dkd.plugins import *
|
|
33
33
|
|
|
34
|
-
from ..protocol.
|
|
34
|
+
from ..protocol.base import CommandHelper
|
|
35
35
|
# from ..protocol.helpers import CommandExtensions
|
|
36
36
|
|
|
37
|
-
from .
|
|
37
|
+
from ..protocol.base import GeneralCommandHelper, SharedCommandExtensions
|
|
38
38
|
|
|
39
39
|
__all__ = [
|
|
40
40
|
|