dimp 2.3.0__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.0 → dimp-2.3.2}/PKG-INFO +1 -1
- {dimp-2.3.0 → dimp-2.3.2}/dimp/__init__.py +3 -2
- {dimp-2.3.0 → dimp-2.3.2}/dimp/crypto/keys.py +46 -21
- {dimp-2.3.0 → dimp-2.3.2}/dimp/crypto/pnf.py +11 -10
- {dimp-2.3.0 → dimp-2.3.2}/dimp/crypto/ted.py +26 -22
- {dimp-2.3.0 → dimp-2.3.2}/dimp/dkd/__init__.py +17 -16
- {dimp-2.3.0 → dimp-2.3.2}/dimp/mkm/docs.py +19 -15
- {dimp-2.3.0 → dimp-2.3.2}/dimp/mkm/document.py +6 -21
- {dimp-2.3.0 → dimp-2.3.2}/dimp/mkm/meta.py +7 -8
- {dimp-2.3.0 → dimp-2.3.2}/dimp/msg/base.py +2 -2
- {dimp-2.3.0 → dimp-2.3.2}/dimp/msg/envelope.py +17 -14
- {dimp-2.3.0 → dimp-2.3.2}/dimp/msg/instant.py +13 -11
- {dimp-2.3.0 → dimp-2.3.2}/dimp/msg/reliable.py +2 -2
- {dimp-2.3.0 → dimp-2.3.2}/dimp/msg/secure.py +15 -9
- {dimp-2.3.0 → dimp-2.3.2}/dimp/plugins/__init__.py +2 -2
- {dimp-2.3.0 → dimp-2.3.2}/dimp/protocol/__init__.py +8 -8
- {dimp-2.3.0/dimp/dkd → dimp-2.3.2/dimp/protocol}/base.py +140 -15
- {dimp-2.3.0/dimp/dkd → dimp-2.3.2/dimp/protocol}/commands.py +126 -30
- {dimp-2.3.0/dimp/dkd → dimp-2.3.2/dimp/protocol}/contents.py +164 -128
- {dimp-2.3.0 → 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.0/dimp/dkd → dimp-2.3.2/dimp/protocol}/money.py +100 -26
- {dimp-2.3.0 → dimp-2.3.2}/dimp/protocol/quote.py +51 -34
- {dimp-2.3.0/dimp/dkd → dimp-2.3.2/dimp/protocol}/receipt.py +83 -11
- {dimp-2.3.0 → dimp-2.3.2}/dimp.egg-info/PKG-INFO +1 -1
- {dimp-2.3.0 → 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.0 → dimp-2.3.2}/setup.py +3 -3
- dimp-2.3.0/dimp/dkd/files.py +0 -181
- dimp-2.3.0/dimp/dkd/group_admins.py +0 -106
- dimp-2.3.0/dimp/dkd/groups.py +0 -234
- dimp-2.3.0/dimp/dkd/quote.py +0 -141
- dimp-2.3.0/dimp/plugins/cmd.py +0 -79
- dimp-2.3.0/dimp/protocol/commands.py +0 -247
- dimp-2.3.0/dimp/protocol/contents.py +0 -279
- dimp-2.3.0/dimp/protocol/groups.py +0 -269
- dimp-2.3.0/dimp/protocol/money.py +0 -124
- dimp-2.3.0/dimp/protocol/receipt.py +0 -130
- dimp-2.3.0/dimp.egg-info/requires.txt +0 -2
- {dimp-2.3.0 → dimp-2.3.2}/LICENSE +0 -0
- {dimp-2.3.0 → dimp-2.3.2}/README.md +0 -0
- {dimp-2.3.0 → dimp-2.3.2}/dimp/crypto/__init__.py +0 -0
- {dimp-2.3.0 → dimp-2.3.2}/dimp/crypto/algorithms.py +0 -0
- {dimp-2.3.0 → dimp-2.3.2}/dimp/mkm/__init__.py +0 -0
- {dimp-2.3.0 → dimp-2.3.2}/dimp/msg/__init__.py +0 -0
- {dimp-2.3.0 → dimp-2.3.2}/dimp/protocol/docs.py +0 -0
- {dimp-2.3.0 → dimp-2.3.2}/dimp/protocol/helpers.py +0 -0
- {dimp-2.3.0 → dimp-2.3.2}/dimp/protocol/types.py +0 -0
- {dimp-2.3.0 → dimp-2.3.2}/dimp.egg-info/dependency_links.txt +0 -0
- {dimp-2.3.0 → dimp-2.3.2}/dimp.egg-info/top_level.txt +0 -0
- {dimp-2.3.0 → dimp-2.3.2}/setup.cfg +0 -0
|
@@ -34,7 +34,7 @@ from mkm.crypto import *
|
|
|
34
34
|
from mkm import *
|
|
35
35
|
from dkd import *
|
|
36
36
|
|
|
37
|
-
from .protocol.
|
|
37
|
+
from .protocol.base import CommandFactory
|
|
38
38
|
from .protocol import *
|
|
39
39
|
from .crypto import *
|
|
40
40
|
from .mkm import *
|
|
@@ -52,7 +52,8 @@ __all__ = [
|
|
|
52
52
|
|
|
53
53
|
'URI', 'DateTime',
|
|
54
54
|
|
|
55
|
-
'Converter', '
|
|
55
|
+
'Converter', 'DataConverter', 'BaseConverter',
|
|
56
|
+
'Copier',
|
|
56
57
|
'Wrapper', 'Stringer', 'Mapper',
|
|
57
58
|
'ConstantString', # 'String',
|
|
58
59
|
'Dictionary',
|
|
@@ -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,9 +58,10 @@ 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
|
+
return '' if algorithm is None else algorithm
|
|
64
65
|
|
|
65
66
|
@classmethod
|
|
66
67
|
def match_encrypt_key(cls, encrypt_key: EncryptKey, decrypt_key: DecryptKey) -> bool:
|
|
@@ -96,20 +97,32 @@ class BaseKey(Dictionary, CryptographyKey, ABC):
|
|
|
96
97
|
# noinspection PyAbstractClass
|
|
97
98
|
class BaseSymmetricKey(Dictionary, SymmetricKey, ABC):
|
|
98
99
|
|
|
99
|
-
def __init__(self, key: Dict
|
|
100
|
+
def __init__(self, key: Dict):
|
|
100
101
|
super().__init__(dictionary=key)
|
|
101
102
|
|
|
102
103
|
# Override
|
|
103
104
|
def __eq__(self, other) -> bool:
|
|
104
|
-
if isinstance(other,
|
|
105
|
-
|
|
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)
|
|
106
114
|
|
|
107
115
|
# Override
|
|
108
116
|
def __ne__(self, other) -> bool:
|
|
109
|
-
if isinstance(other,
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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)
|
|
113
126
|
|
|
114
127
|
@property # Override
|
|
115
128
|
def algorithm(self) -> str:
|
|
@@ -123,7 +136,7 @@ class BaseSymmetricKey(Dictionary, SymmetricKey, ABC):
|
|
|
123
136
|
# noinspection PyAbstractClass
|
|
124
137
|
class BaseAsymmetricKey(Dictionary, AsymmetricKey, ABC):
|
|
125
138
|
|
|
126
|
-
def __init__(self, key: Dict
|
|
139
|
+
def __init__(self, key: Dict):
|
|
127
140
|
super().__init__(dictionary=key)
|
|
128
141
|
|
|
129
142
|
@property # Override
|
|
@@ -134,7 +147,7 @@ class BaseAsymmetricKey(Dictionary, AsymmetricKey, ABC):
|
|
|
134
147
|
# noinspection PyAbstractClass
|
|
135
148
|
class BasePublicKey(Dictionary, PublicKey, ABC):
|
|
136
149
|
|
|
137
|
-
def __init__(self, key: Dict
|
|
150
|
+
def __init__(self, key: Dict):
|
|
138
151
|
super().__init__(dictionary=key)
|
|
139
152
|
|
|
140
153
|
@property # Override
|
|
@@ -149,20 +162,32 @@ class BasePublicKey(Dictionary, PublicKey, ABC):
|
|
|
149
162
|
# noinspection PyAbstractClass
|
|
150
163
|
class BasePrivateKey(Dictionary, PrivateKey, ABC):
|
|
151
164
|
|
|
152
|
-
def __init__(self, key: Dict
|
|
165
|
+
def __init__(self, key: Dict):
|
|
153
166
|
super().__init__(dictionary=key)
|
|
154
167
|
|
|
155
168
|
# Override
|
|
156
169
|
def __eq__(self, other) -> bool:
|
|
157
|
-
if isinstance(other,
|
|
158
|
-
|
|
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)
|
|
159
179
|
|
|
160
180
|
# Override
|
|
161
181
|
def __ne__(self, other) -> bool:
|
|
162
|
-
if isinstance(other,
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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)
|
|
166
191
|
|
|
167
192
|
@property # Override
|
|
168
193
|
def algorithm(self) -> str:
|
|
@@ -28,15 +28,13 @@
|
|
|
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
|
|
35
35
|
from mkm.types import Dictionary
|
|
36
36
|
from mkm.crypto import DecryptKey, SymmetricKey
|
|
37
37
|
|
|
38
|
-
from .algorithms import EncodeAlgorithms
|
|
39
|
-
|
|
40
38
|
|
|
41
39
|
class BaseFileWrapper(Dictionary):
|
|
42
40
|
"""
|
|
@@ -57,7 +55,7 @@ class BaseFileWrapper(Dictionary):
|
|
|
57
55
|
}
|
|
58
56
|
"""
|
|
59
57
|
|
|
60
|
-
def __init__(self, dictionary: Dict
|
|
58
|
+
def __init__(self, dictionary: Dict):
|
|
61
59
|
super().__init__(dictionary=dictionary)
|
|
62
60
|
# file data (not encrypted)
|
|
63
61
|
self.__attachment: Optional[TransportableData] = None
|
|
@@ -92,7 +90,7 @@ class BaseFileWrapper(Dictionary):
|
|
|
92
90
|
ted = None
|
|
93
91
|
self.pop('data', None)
|
|
94
92
|
else:
|
|
95
|
-
ted = TransportableData.create(data=binary
|
|
93
|
+
ted = TransportableData.create(data=binary)
|
|
96
94
|
self['data'] = ted.object
|
|
97
95
|
self.__attachment = ted
|
|
98
96
|
|
|
@@ -117,11 +115,12 @@ class BaseFileWrapper(Dictionary):
|
|
|
117
115
|
|
|
118
116
|
@property
|
|
119
117
|
def url(self) -> Optional[URI]:
|
|
120
|
-
|
|
118
|
+
remote = self.__url
|
|
119
|
+
if remote is None:
|
|
121
120
|
remote = self.get_str(key='URL', default=None)
|
|
122
121
|
# TODO: convert str to URI
|
|
123
122
|
self.__url = remote
|
|
124
|
-
return
|
|
123
|
+
return remote
|
|
125
124
|
|
|
126
125
|
@url.setter
|
|
127
126
|
def url(self, remote: Optional[URI]):
|
|
@@ -138,10 +137,12 @@ class BaseFileWrapper(Dictionary):
|
|
|
138
137
|
|
|
139
138
|
@property
|
|
140
139
|
def password(self) -> Optional[DecryptKey]:
|
|
141
|
-
|
|
140
|
+
key = self.__password
|
|
141
|
+
if key is None:
|
|
142
142
|
info = self.get('key')
|
|
143
|
-
|
|
144
|
-
|
|
143
|
+
key = SymmetricKey.parse(key=info)
|
|
144
|
+
self.__password = key
|
|
145
|
+
return key
|
|
145
146
|
|
|
146
147
|
@password.setter
|
|
147
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,26 +54,26 @@ 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:
|
|
72
|
-
text = self.get_str(key='data', default=
|
|
73
|
-
if len(text) == 0:
|
|
74
|
-
return
|
|
75
|
-
alg = self.get_str(key='algorithm', default=
|
|
76
|
-
if alg == EncodeAlgorithms.DEFAULT:
|
|
72
|
+
text = self.get_str(key='data', default=None)
|
|
73
|
+
if text is None: # or len(text) == 0:
|
|
74
|
+
return ''
|
|
75
|
+
alg = self.get_str(key='algorithm', default=None)
|
|
76
|
+
if alg is None or alg == EncodeAlgorithms.DEFAULT:
|
|
77
77
|
alg = ''
|
|
78
78
|
if len(alg) == 0:
|
|
79
79
|
# 0. "{BASE64_ENCODE}"
|
|
@@ -85,9 +85,9 @@ class BaseDataWrapper(Dictionary):
|
|
|
85
85
|
def encode(self, mime_type: str) -> str:
|
|
86
86
|
""" toString(mimeType) """
|
|
87
87
|
# get encoded data
|
|
88
|
-
text = self.get_str(key='data', default=
|
|
89
|
-
if len(text) == 0:
|
|
90
|
-
return
|
|
88
|
+
text = self.get_str(key='data', default=None)
|
|
89
|
+
if text is None: # or len(text) == 0:
|
|
90
|
+
return ''
|
|
91
91
|
alg = self.algorithm
|
|
92
92
|
# 2. "data:image/png;base64,{BASE64_ENCODE}"
|
|
93
93
|
return 'data:%s;%s,%s' % (mime_type, alg, text)
|
|
@@ -98,8 +98,8 @@ class BaseDataWrapper(Dictionary):
|
|
|
98
98
|
|
|
99
99
|
@property
|
|
100
100
|
def algorithm(self) -> str:
|
|
101
|
-
alg = self.get_str(key='algorithm', default=
|
|
102
|
-
if len(alg) == 0:
|
|
101
|
+
alg = self.get_str(key='algorithm', default=None)
|
|
102
|
+
if alg is None or len(alg) == 0:
|
|
103
103
|
alg = EncodeAlgorithms.DEFAULT
|
|
104
104
|
return alg
|
|
105
105
|
|
|
@@ -118,8 +118,11 @@ class BaseDataWrapper(Dictionary):
|
|
|
118
118
|
def data(self) -> Optional[bytes]:
|
|
119
119
|
binary = self.__data
|
|
120
120
|
if binary is None:
|
|
121
|
-
text = self.get_str(key='data', default=
|
|
122
|
-
if len(text)
|
|
121
|
+
text = self.get_str(key='data', default=None)
|
|
122
|
+
if text is None or len(text) == 0:
|
|
123
|
+
# assert False, 'TED data empty: %s' % self.dictionary
|
|
124
|
+
return None
|
|
125
|
+
else:
|
|
123
126
|
alg = self.algorithm
|
|
124
127
|
if alg == EncodeAlgorithms.BASE_64:
|
|
125
128
|
binary = base64_decode(string=text)
|
|
@@ -145,6 +148,7 @@ class BaseDataWrapper(Dictionary):
|
|
|
145
148
|
elif alg == EncodeAlgorithms.HEX:
|
|
146
149
|
text = hex_encode(data=binary)
|
|
147
150
|
else:
|
|
148
|
-
|
|
151
|
+
raise ArithmeticError('data algorithm not support: %s' % alg)
|
|
152
|
+
# assert False, 'data algorithm not support: %s' % alg
|
|
149
153
|
self['data'] = text
|
|
150
154
|
self.__data = binary
|
|
@@ -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
|
|
@@ -37,8 +37,6 @@ from mkm.format import TransportableData
|
|
|
37
37
|
from mkm.format import json_encode, json_decode, utf8_encode
|
|
38
38
|
from mkm import ID, Document
|
|
39
39
|
|
|
40
|
-
from ..crypto import EncodeAlgorithms
|
|
41
|
-
|
|
42
40
|
|
|
43
41
|
"""
|
|
44
42
|
Base Documents
|
|
@@ -50,7 +48,7 @@ from ..crypto import EncodeAlgorithms
|
|
|
50
48
|
|
|
51
49
|
class BaseDocument(Dictionary, Document):
|
|
52
50
|
|
|
53
|
-
def __init__(self, document: Dict
|
|
51
|
+
def __init__(self, document: Dict = None,
|
|
54
52
|
doc_type: str = None, identifier: ID = None,
|
|
55
53
|
data: Optional[str] = None, signature: Optional[TransportableData] = None):
|
|
56
54
|
# check parameters
|
|
@@ -102,15 +100,6 @@ class BaseDocument(Dictionary, Document):
|
|
|
102
100
|
self.__properties = properties
|
|
103
101
|
self.__status = status # 1 for valid, -1 for invalid
|
|
104
102
|
|
|
105
|
-
# @property # Override
|
|
106
|
-
# def type(self) -> Optional[str]:
|
|
107
|
-
# doc_type = self.get_property(name='type') # deprecated
|
|
108
|
-
# if doc_type is None:
|
|
109
|
-
# ext = SharedAccountExtensions()
|
|
110
|
-
# doc_type = ext.helper.get_document_type(document=self.dictionary, default=None)
|
|
111
|
-
# # doc_type = self.get_str(key='type', default=None)
|
|
112
|
-
# return doc_type
|
|
113
|
-
|
|
114
103
|
@property # Override
|
|
115
104
|
def identifier(self) -> ID:
|
|
116
105
|
if self.__identifier is None:
|
|
@@ -200,17 +189,13 @@ class BaseDocument(Dictionary, Document):
|
|
|
200
189
|
# 2. encode & sign
|
|
201
190
|
info = self.properties
|
|
202
191
|
if info is None:
|
|
203
|
-
# assert False, '
|
|
192
|
+
# assert False, 'document invalid: %s' % self.dictionary
|
|
204
193
|
return None
|
|
205
194
|
data = json_encode(info)
|
|
206
|
-
|
|
207
|
-
# properties error
|
|
208
|
-
return None
|
|
195
|
+
assert len(data) > 0, 'should not happen: %s' % info
|
|
209
196
|
signature = private_key.sign(data=utf8_encode(string=data))
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
return None
|
|
213
|
-
ted = TransportableData.create(data=signature, algorithm=EncodeAlgorithms.DEFAULT)
|
|
197
|
+
assert len(signature) > 0, 'should not happen: %s' % info
|
|
198
|
+
ted = TransportableData.create(data=signature)
|
|
214
199
|
# 3. update 'data' & 'signature' fields
|
|
215
200
|
self['data'] = data # JsON string
|
|
216
201
|
self['signature'] = ted.object # BASE-64
|
|
@@ -225,7 +210,7 @@ class BaseDocument(Dictionary, Document):
|
|
|
225
210
|
#
|
|
226
211
|
|
|
227
212
|
@property # Override
|
|
228
|
-
def properties(self) -> Optional[Dict
|
|
213
|
+
def properties(self) -> Optional[Dict]:
|
|
229
214
|
""" Load properties from data """
|
|
230
215
|
if self.__status < 0:
|
|
231
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:
|
|
@@ -59,10 +59,9 @@ from mkm import Meta
|
|
|
59
59
|
"""
|
|
60
60
|
|
|
61
61
|
|
|
62
|
-
# noinspection PyAbstractClass
|
|
63
62
|
class BaseMeta(Dictionary, Meta, ABC):
|
|
64
63
|
|
|
65
|
-
def __init__(self, meta: Dict
|
|
64
|
+
def __init__(self, meta: Dict = None,
|
|
66
65
|
version: str = None, public_key: VerifyKey = None,
|
|
67
66
|
seed: Optional[str] = None, fingerprint: Optional[TransportableData] = None):
|
|
68
67
|
# check parameters
|
|
@@ -143,7 +142,7 @@ class BaseMeta(Dictionary, Meta, ABC):
|
|
|
143
142
|
ted = self.__fingerprint
|
|
144
143
|
if ted is None and self.has_seed:
|
|
145
144
|
base64 = self.get('fingerprint')
|
|
146
|
-
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
|
|
147
146
|
self.__fingerprint = ted = TransportableData.parse(base64)
|
|
148
147
|
assert ted is not None, 'meta.fingerprint error: %s' % base64
|
|
149
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]:
|