12 # PSK Management Data model : |
12 # PSK Management Data model : |
13 # [[ID,Desc, LastKnownURI, LastConnect]] |
13 # [[ID,Desc, LastKnownURI, LastConnect]] |
14 COL_ID, COL_URI, COL_DESC, COL_LAST = range(4) |
14 COL_ID, COL_URI, COL_DESC, COL_LAST = range(4) |
15 REPLACE, REPLACE_ALL, KEEP, KEEP_ALL, CANCEL = range(5) |
15 REPLACE, REPLACE_ALL, KEEP, KEEP_ALL, CANCEL = range(5) |
16 |
16 |
|
17 |
17 def _pskpath(project_path): |
18 def _pskpath(project_path): |
18 return os.path.join(project_path, 'psk') |
19 return os.path.join(project_path, 'psk') |
19 |
20 |
|
21 |
20 def _mgtpath(project_path): |
22 def _mgtpath(project_path): |
21 return os.path.join(_pskpath(project_path), 'management.json') |
23 return os.path.join(_pskpath(project_path), 'management.json') |
|
24 |
22 |
25 |
23 def _ensurePSKdir(project_path): |
26 def _ensurePSKdir(project_path): |
24 pskpath = _pskpath(project_path) |
27 pskpath = _pskpath(project_path) |
25 if not os.path.exists(pskpath): |
28 if not os.path.exists(pskpath): |
26 os.mkdir(pskpath) |
29 os.mkdir(pskpath) |
27 return pskpath |
30 return pskpath |
28 |
31 |
|
32 |
29 def _default(ID): |
33 def _default(ID): |
30 return [ID, |
34 return [ID, |
31 '', # default description |
35 '', # default description |
32 None, # last known URI |
36 None, # last known URI |
33 None] # last connection date |
37 None] # last connection date |
34 |
38 |
|
39 |
35 def _dataByID(data): |
40 def _dataByID(data): |
36 return {row[COL_ID]:row for row in data} |
41 return {row[COL_ID]: row for row in data} |
|
42 |
37 |
43 |
38 def _LoadData(project_path): |
44 def _LoadData(project_path): |
39 """ load known keys metadata """ |
45 """ load known keys metadata """ |
40 if os.path.isdir(_pskpath(project_path)): |
46 if os.path.isdir(_pskpath(project_path)): |
41 _path = _mgtpath(project_path) |
47 _path = _mgtpath(project_path) |
42 if os.path.exists(_path): |
48 if os.path.exists(_path): |
43 return json.loads(open(_path).read()) |
49 return json.loads(open(_path).read()) |
44 return [] |
50 return [] |
45 |
51 |
|
52 |
46 def _filterData(psk_files, data_input): |
53 def _filterData(psk_files, data_input): |
47 input_by_ID = _dataByID(data_input) |
54 input_by_ID = _dataByID(data_input) |
48 output = [] |
55 output = [] |
49 # go through all secret files available an build data |
56 # go through all secret files available an build data |
50 # out of data recoverd from json and list of secret. |
57 # out of data recoverd from json and list of secret. |
51 # this implicitly filters IDs out of metadata who's |
58 # this implicitly filters IDs out of metadata who's |
52 # secret is missing |
59 # secret is missing |
53 for filename in psk_files: |
60 for filename in psk_files: |
54 if filename.endswith('.secret'): |
61 if filename.endswith('.secret'): |
55 ID = filename[:-7] # strip filename extension |
62 ID = filename[:-7] # strip filename extension |
56 output.append(input_by_ID.get(ID,_default(ID))) |
63 output.append(input_by_ID.get(ID, _default(ID))) |
57 return output |
64 return output |
|
65 |
58 |
66 |
59 def GetData(project_path): |
67 def GetData(project_path): |
60 loaded_data = _LoadData(project_path) |
68 loaded_data = _LoadData(project_path) |
61 if loaded_data: |
69 if loaded_data: |
62 psk_files = os.listdir(_pskpath(project_path)) |
70 psk_files = os.listdir(_pskpath(project_path)) |
63 return _filterData(psk_files, loaded_data) |
71 return _filterData(psk_files, loaded_data) |
64 return [] |
72 return [] |
65 |
73 |
|
74 |
66 def DeleteID(project_path, ID): |
75 def DeleteID(project_path, ID): |
67 secret_path = os.path.join(_pskpath(project_path), ID+'.secret') |
76 secret_path = os.path.join(_pskpath(project_path), ID+'.secret') |
68 os.remove(secret_path) |
77 os.remove(secret_path) |
|
78 |
69 |
79 |
70 def SaveData(project_path, data): |
80 def SaveData(project_path, data): |
71 _ensurePSKdir(project_path) |
81 _ensurePSKdir(project_path) |
72 with open(_mgtpath(project_path), 'w') as f: |
82 with open(_mgtpath(project_path), 'w') as f: |
73 f.write(json.dumps(data)) |
83 f.write(json.dumps(data)) |
|
84 |
74 |
85 |
75 def UpdateID(project_path, ID, secret, URI): |
86 def UpdateID(project_path, ID, secret, URI): |
76 pskpath = _ensurePSKdir(project_path) |
87 pskpath = _ensurePSKdir(project_path) |
77 if not os.path.exists(pskpath): |
88 if not os.path.exists(pskpath): |
78 os.mkdir(pskpath) |
89 os.mkdir(pskpath) |
86 idata = _dataByID(data) |
97 idata = _dataByID(data) |
87 dataForID = idata.get(ID, None) if data else None |
98 dataForID = idata.get(ID, None) if data else None |
88 |
99 |
89 _is_new_ID = dataForID is None |
100 _is_new_ID = dataForID is None |
90 if _is_new_ID: |
101 if _is_new_ID: |
91 dataForID = _default(ID) |
102 dataForID = _default(ID) |
92 |
103 |
93 dataForID[COL_URI] = URI |
104 dataForID[COL_URI] = URI |
94 # FIXME : could store time instead os a string and use DVC model's cmp |
105 # FIXME : could store time instead os a string and use DVC model's cmp |
95 # then date display could be smarter, etc - sortable sting hack for now |
106 # then date display could be smarter, etc - sortable sting hack for now |
96 dataForID[COL_LAST] = time.strftime('%y/%M/%d-%H:%M:%S') |
107 dataForID[COL_LAST] = time.strftime('%y/%M/%d-%H:%M:%S') |
97 |
108 |
98 if _is_new_ID: |
109 if _is_new_ID: |
99 data.append(dataForID) |
110 data.append(dataForID) |
100 |
111 |
101 SaveData(project_path, data) |
112 SaveData(project_path, data) |
102 |
113 |
|
114 |
103 def ExportIDs(project_path, export_zip): |
115 def ExportIDs(project_path, export_zip): |
104 with ZipFile(export_zip, 'w') as zf: |
116 with ZipFile(export_zip, 'w') as zf: |
105 path = _pskpath(project_path) |
117 path = _pskpath(project_path) |
106 for nm in os.listdir(path): |
118 for nm in os.listdir(path): |
107 if nm.endswith('.secret') or nm == 'management.json': |
119 if nm.endswith('.secret') or nm == 'management.json': |
108 zf.write(os.path.join(path, nm), nm) |
120 zf.write(os.path.join(path, nm), nm) |
|
121 |
109 |
122 |
110 def ImportIDs(project_path, import_zip, should_I_replace_callback): |
123 def ImportIDs(project_path, import_zip, should_I_replace_callback): |
111 zf = ZipFile(import_zip, 'r') |
124 zf = ZipFile(import_zip, 'r') |
112 data = GetData(project_path) |
125 data = GetData(project_path) |
113 |
126 |
130 if result not in [REPLACE_ALL, KEEP_ALL]: |
143 if result not in [REPLACE_ALL, KEEP_ALL]: |
131 result = should_I_replace_callback(existing_row, imported_row) |
144 result = should_I_replace_callback(existing_row, imported_row) |
132 |
145 |
133 if result == CANCEL: |
146 if result == CANCEL: |
134 return |
147 return |
135 |
148 |
136 if result in [REPLACE_ALL, REPLACE]: |
149 if result in [REPLACE_ALL, REPLACE]: |
137 # replace with imported |
150 # replace with imported |
138 existing_row[:] = imported_row |
151 existing_row[:] = imported_row |
139 # copy the key of selected |
152 # copy the key of selected |
140 keys_to_import.append(ID) |
153 keys_to_import.append(ID) |
141 |
154 |
142 for ID in keys_to_import: |
155 for ID in keys_to_import: |
143 zf.extract(ID+".secret", _pskpath(project_path)) |
156 zf.extract(ID+".secret", _pskpath(project_path)) |
144 |
157 |
145 SaveData(project_path, data) |
158 SaveData(project_path, data) |
146 |
159 |
147 return data |
160 return data |
148 |
|
149 |
|