##// END OF EJS Templates
Added some minor info
neko259 -
r1238:a83ac0a9 decentral
parent child Browse files
Show More
@@ -1,160 +1,164 b''
1 1 import xml.etree.ElementTree as et
2 2 from django.db import transaction
3 3 from boards.models import KeyPair, GlobalId, Signature, Post
4 4
5 5 ENCODING_UNICODE = 'unicode'
6 6
7 7 TAG_MODEL = 'model'
8 8 TAG_REQUEST = 'request'
9 9 TAG_RESPONSE = 'response'
10 10 TAG_ID = 'id'
11 11 TAG_STATUS = 'status'
12 12 TAG_MODELS = 'models'
13 13 TAG_TITLE = 'title'
14 14 TAG_TEXT = 'text'
15 15 TAG_THREAD = 'thread'
16 16 TAG_PUB_TIME = 'pub-time'
17 17 TAG_SIGNATURES = 'signatures'
18 18 TAG_SIGNATURE = 'signature'
19 19 TAG_CONTENT = 'content'
20 20 TAG_ATTACHMENTS = 'attachments'
21 21 TAG_ATTACHMENT = 'attachment'
22 22
23 23 TYPE_GET = 'get'
24 24
25 25 ATTR_VERSION = 'version'
26 26 ATTR_TYPE = 'type'
27 27 ATTR_NAME = 'name'
28 28 ATTR_VALUE = 'value'
29 29 ATTR_MIMETYPE = 'mimetype'
30 30 ATTR_KEY = 'key'
31 31
32 32 STATUS_SUCCESS = 'success'
33 33
34 34
35 35 class SyncManager:
36 36 @staticmethod
37 37 def generate_response_get(model_list: list):
38 38 response = et.Element(TAG_RESPONSE)
39 39
40 40 status = et.SubElement(response, TAG_STATUS)
41 41 status.text = STATUS_SUCCESS
42 42
43 43 models = et.SubElement(response, TAG_MODELS)
44 44
45 45 for post in model_list:
46 46 model = et.SubElement(models, TAG_MODEL)
47 47 model.set(ATTR_NAME, 'post')
48 48
49 49 content_tag = et.SubElement(model, TAG_CONTENT)
50 50
51 51 tag_id = et.SubElement(content_tag, TAG_ID)
52 52 post.global_id.to_xml_element(tag_id)
53 53
54 54 title = et.SubElement(content_tag, TAG_TITLE)
55 55 title.text = post.title
56 56
57 57 text = et.SubElement(content_tag, TAG_TEXT)
58 58 text.text = post.get_sync_text()
59 59
60 60 if not post.is_opening():
61 61 thread = et.SubElement(content_tag, TAG_THREAD)
62 62 thread_id = et.SubElement(thread, TAG_ID)
63 63 post.get_thread().get_opening_post().global_id.to_xml_element(thread_id)
64 64 else:
65 65 # TODO Output tags here
66 66 pass
67 67
68 68 pub_time = et.SubElement(content_tag, TAG_PUB_TIME)
69 69 pub_time.text = str(post.get_pub_time_str())
70 70
71 71 signatures_tag = et.SubElement(model, TAG_SIGNATURES)
72 72 post_signatures = post.signature.all()
73 73 if post_signatures:
74 signatures = post.signatures
74 signatures = post_signatures
75 # TODO Adding signature to a post is not yet added. For now this
76 # block is useless
75 77 else:
76 78 # TODO Maybe the signature can be computed only once after
77 79 # the post is added? Need to add some on_save signal queue
78 80 # and add this there.
79 81 key = KeyPair.objects.get(public_key=post.global_id.key)
80 82 signatures = [Signature(
81 83 key_type=key.key_type,
82 84 key=key.public_key,
83 85 signature=key.sign(et.tostring(content_tag, ENCODING_UNICODE)),
84 86 )]
85 87 for signature in signatures:
86 88 signature_tag = et.SubElement(signatures_tag, TAG_SIGNATURE)
87 89 signature_tag.set(ATTR_TYPE, signature.key_type)
88 90 signature_tag.set(ATTR_VALUE, signature.signature)
89 91 signature_tag.set(ATTR_KEY, signature.key)
90 92
91 93 return et.tostring(response, ENCODING_UNICODE)
92 94
93 95 @staticmethod
94 96 @transaction.atomic
95 97 def parse_response_get(response_xml):
96 98 tag_root = et.fromstring(response_xml)
97 99 tag_status = tag_root.find(TAG_STATUS)
98 100 if STATUS_SUCCESS == tag_status.text:
99 101 tag_models = tag_root.find(TAG_MODELS)
100 102 for tag_model in tag_models:
101 103 tag_content = tag_model.find(TAG_CONTENT)
102 104
103 valid = SyncManager.verify_model(tag_content, tag_model)
105 valid = SyncManager._verify_model(tag_content, tag_model)
104 106
105 107 if not valid:
106 108 raise Exception('Invalid model signature')
107 109
108 110 tag_id = tag_content.find(TAG_ID)
109 111 global_id, exists = GlobalId.from_xml_element(tag_id)
110 112
111 113 if exists:
112 114 print('Post with same ID already exists')
113 115 else:
114 116 global_id.save()
115 117
116 118 title = tag_content.find(TAG_TITLE).text
117 119 text = tag_content.find(TAG_TEXT).text
118 120 pub_time = tag_content.find(TAG_PUB_TIME).text
119 121
120 122 thread = tag_content.find(TAG_THREAD)
121 123 if thread:
122 124 opening_post = Post.objects.get(
123 125 id=thread.find(TAG_ID).text)
124 126 else:
125 127 opening_post = None
126 128 # TODO Get tags here
127 129
128 130 # TODO Check that the replied posts are already present
129 131 # before adding new ones
130 132
133 # TODO Get images
134
131 135 post = Post.objects.import_post(
132 136 title=title, text=text, pub_time=pub_time,
133 137 opening_post=opening_post)
134 138 post.global_id = global_id
135 139 else:
136 140 # TODO Throw an exception?
137 141 pass
138 142
139 143 @staticmethod
140 def verify_model(tag_content, tag_model):
144 def _verify_model(tag_content, tag_model):
141 145 """
142 146 Verifies all signatures for a single model.
143 147 """
144 148
145 149 valid = True
146 150
147 151 tag_signatures = tag_model.find(TAG_SIGNATURES)
148 152 for tag_signature in tag_signatures:
149 153 signature_type = tag_signature.get(ATTR_TYPE)
150 154 signature_value = tag_signature.get(ATTR_VALUE)
151 155 signature_key = tag_signature.get(ATTR_KEY)
152 156
153 157 if not KeyPair.objects.verify(
154 158 signature_key,
155 159 et.tostring(tag_content, ENCODING_UNICODE),
156 160 signature_value, signature_type):
157 161 valid = False
158 162 break
159 163
160 164 return valid
General Comments 0
You need to be logged in to leave comments. Login now