dmart 0.1.0__py3-none-any.whl
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.
- alembic/__init__.py +0 -0
- alembic/env.py +91 -0
- api/__init__.py +0 -0
- api/info/__init__.py +0 -0
- api/info/router.py +109 -0
- api/managed/__init__.py +0 -0
- api/managed/router.py +1541 -0
- api/managed/utils.py +1850 -0
- api/public/__init__.py +0 -0
- api/public/router.py +758 -0
- api/qr/__init__.py +0 -0
- api/qr/router.py +108 -0
- api/user/__init__.py +0 -0
- api/user/router.py +1401 -0
- api/user/service.py +270 -0
- bundler.py +44 -0
- config/__init__.py +0 -0
- config/channels.json +11 -0
- config/notification.json +17 -0
- data_adapters/__init__.py +0 -0
- data_adapters/adapter.py +16 -0
- data_adapters/base_data_adapter.py +467 -0
- data_adapters/file/__init__.py +0 -0
- data_adapters/file/adapter.py +2043 -0
- data_adapters/file/adapter_helpers.py +1013 -0
- data_adapters/file/archive.py +150 -0
- data_adapters/file/create_index.py +331 -0
- data_adapters/file/create_users_folders.py +52 -0
- data_adapters/file/custom_validations.py +68 -0
- data_adapters/file/drop_index.py +40 -0
- data_adapters/file/health_check.py +560 -0
- data_adapters/file/redis_services.py +1110 -0
- data_adapters/helpers.py +27 -0
- data_adapters/sql/__init__.py +0 -0
- data_adapters/sql/adapter.py +3210 -0
- data_adapters/sql/adapter_helpers.py +491 -0
- data_adapters/sql/create_tables.py +451 -0
- data_adapters/sql/create_users_folders.py +53 -0
- data_adapters/sql/db_to_json_migration.py +482 -0
- data_adapters/sql/health_check_sql.py +232 -0
- data_adapters/sql/json_to_db_migration.py +454 -0
- data_adapters/sql/update_query_policies.py +101 -0
- data_generator.py +81 -0
- dmart-0.1.0.dist-info/METADATA +27 -0
- dmart-0.1.0.dist-info/RECORD +106 -0
- dmart-0.1.0.dist-info/WHEEL +5 -0
- dmart-0.1.0.dist-info/entry_points.txt +2 -0
- dmart-0.1.0.dist-info/top_level.txt +23 -0
- dmart.py +513 -0
- get_settings.py +7 -0
- languages/__init__.py +0 -0
- languages/arabic.json +15 -0
- languages/english.json +16 -0
- languages/kurdish.json +14 -0
- languages/loader.py +13 -0
- main.py +506 -0
- migrate.py +24 -0
- models/__init__.py +0 -0
- models/api.py +203 -0
- models/core.py +597 -0
- models/enums.py +255 -0
- password_gen.py +8 -0
- plugins/__init__.py +0 -0
- pytests/__init__.py +0 -0
- pytests/api_user_models_erros_test.py +16 -0
- pytests/api_user_models_requests_test.py +98 -0
- pytests/archive_test.py +72 -0
- pytests/base_test.py +300 -0
- pytests/get_settings_test.py +14 -0
- pytests/json_to_db_migration_test.py +237 -0
- pytests/service_test.py +26 -0
- pytests/test_info.py +55 -0
- pytests/test_status.py +15 -0
- run_notification_campaign.py +98 -0
- scheduled_notification_handler.py +121 -0
- schema_migration.py +208 -0
- schema_modulate.py +192 -0
- set_admin_passwd.py +55 -0
- sync.py +202 -0
- utils/__init__.py +0 -0
- utils/access_control.py +306 -0
- utils/async_request.py +8 -0
- utils/exporter.py +309 -0
- utils/firebase_notifier.py +57 -0
- utils/generate_email.py +38 -0
- utils/helpers.py +352 -0
- utils/hypercorn_config.py +12 -0
- utils/internal_error_code.py +60 -0
- utils/jwt.py +124 -0
- utils/logger.py +167 -0
- utils/middleware.py +99 -0
- utils/notification.py +75 -0
- utils/password_hashing.py +16 -0
- utils/plugin_manager.py +215 -0
- utils/query_policies_helper.py +112 -0
- utils/regex.py +44 -0
- utils/repository.py +529 -0
- utils/router_helper.py +19 -0
- utils/settings.py +165 -0
- utils/sms_notifier.py +21 -0
- utils/social_sso.py +67 -0
- utils/templates/activation.html.j2 +26 -0
- utils/templates/reminder.html.j2 +17 -0
- utils/ticket_sys_utils.py +203 -0
- utils/web_notifier.py +29 -0
- websocket.py +231 -0
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Any, Tuple, Type, TypeVar
|
|
4
|
+
from starlette.datastructures import UploadFile
|
|
5
|
+
import models.api as api
|
|
6
|
+
import models.core as core
|
|
7
|
+
from models.enums import LockAction
|
|
8
|
+
import io
|
|
9
|
+
from models.core import Record
|
|
10
|
+
from models.enums import RequestType
|
|
11
|
+
|
|
12
|
+
MetaChild = TypeVar("MetaChild", bound=core.Meta)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class BaseDataAdapter(ABC):
|
|
16
|
+
@abstractmethod
|
|
17
|
+
def locators_query(self, query: api.Query) -> tuple[int, list[core.Locator]]:
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
@abstractmethod
|
|
21
|
+
def folder_path(
|
|
22
|
+
self,
|
|
23
|
+
space_name: str,
|
|
24
|
+
subpath: str,
|
|
25
|
+
shortname: str,
|
|
26
|
+
) -> str:
|
|
27
|
+
pass
|
|
28
|
+
|
|
29
|
+
@abstractmethod
|
|
30
|
+
async def save_otp(
|
|
31
|
+
self,
|
|
32
|
+
key: str,
|
|
33
|
+
otp: str,
|
|
34
|
+
):
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
@abstractmethod
|
|
38
|
+
async def otp_created_since(self, key: str) -> int | None:
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
@abstractmethod
|
|
42
|
+
async def get_otp(
|
|
43
|
+
self,
|
|
44
|
+
key: str,
|
|
45
|
+
):
|
|
46
|
+
pass
|
|
47
|
+
|
|
48
|
+
@abstractmethod
|
|
49
|
+
async def delete_otp(self, key):
|
|
50
|
+
pass
|
|
51
|
+
|
|
52
|
+
@abstractmethod
|
|
53
|
+
def metapath(
|
|
54
|
+
self,
|
|
55
|
+
space_name: str,
|
|
56
|
+
subpath: str,
|
|
57
|
+
shortname: str,
|
|
58
|
+
class_type: Type[MetaChild],
|
|
59
|
+
schema_shortname: str | None = None,
|
|
60
|
+
) -> tuple[Path, str]:
|
|
61
|
+
"""Construct the full path of the meta file"""
|
|
62
|
+
pass
|
|
63
|
+
|
|
64
|
+
@abstractmethod
|
|
65
|
+
def payload_path(
|
|
66
|
+
self,
|
|
67
|
+
space_name: str,
|
|
68
|
+
subpath: str,
|
|
69
|
+
class_type: Type[MetaChild],
|
|
70
|
+
schema_shortname: str | None = None,
|
|
71
|
+
) -> Path:
|
|
72
|
+
"""Construct the full path of the meta file"""
|
|
73
|
+
pass
|
|
74
|
+
|
|
75
|
+
@abstractmethod
|
|
76
|
+
async def load_or_none(
|
|
77
|
+
self,
|
|
78
|
+
space_name: str,
|
|
79
|
+
subpath: str,
|
|
80
|
+
shortname: str,
|
|
81
|
+
class_type: Type[MetaChild],
|
|
82
|
+
user_shortname: str | None = None,
|
|
83
|
+
schema_shortname: str | None = None,
|
|
84
|
+
) -> MetaChild | None:
|
|
85
|
+
"""Load a Meta Json according to the reuqested Class type"""
|
|
86
|
+
pass
|
|
87
|
+
|
|
88
|
+
@abstractmethod
|
|
89
|
+
async def get_latest_history(
|
|
90
|
+
self,
|
|
91
|
+
space_name: str,
|
|
92
|
+
subpath: str,
|
|
93
|
+
shortname: str,
|
|
94
|
+
) -> Any | None:
|
|
95
|
+
pass
|
|
96
|
+
|
|
97
|
+
@abstractmethod
|
|
98
|
+
async def get_entry_by_criteria(self, criteria: dict, table: Any = None) -> core.Record | None:
|
|
99
|
+
pass
|
|
100
|
+
|
|
101
|
+
@abstractmethod
|
|
102
|
+
async def query(self, query: api.Query, user_shortname: str | None = None) \
|
|
103
|
+
-> Tuple[int, list[core.Record]]:
|
|
104
|
+
pass
|
|
105
|
+
|
|
106
|
+
@abstractmethod
|
|
107
|
+
async def load(
|
|
108
|
+
self,
|
|
109
|
+
space_name: str,
|
|
110
|
+
subpath: str,
|
|
111
|
+
shortname: str,
|
|
112
|
+
class_type: Type[MetaChild],
|
|
113
|
+
user_shortname: str | None = None,
|
|
114
|
+
schema_shortname: str | None = None,
|
|
115
|
+
) -> MetaChild:
|
|
116
|
+
pass
|
|
117
|
+
|
|
118
|
+
@abstractmethod
|
|
119
|
+
async def load_resource_payload(
|
|
120
|
+
self,
|
|
121
|
+
space_name: str,
|
|
122
|
+
subpath: str,
|
|
123
|
+
filename: str,
|
|
124
|
+
class_type: Type[MetaChild],
|
|
125
|
+
schema_shortname: str | None = None,
|
|
126
|
+
) -> dict[str, Any] | None:
|
|
127
|
+
pass
|
|
128
|
+
|
|
129
|
+
@abstractmethod
|
|
130
|
+
async def save(
|
|
131
|
+
self, space_name: str, subpath: str, meta: core.Meta
|
|
132
|
+
):
|
|
133
|
+
"""Save Meta Json to respectiv file"""
|
|
134
|
+
pass
|
|
135
|
+
|
|
136
|
+
@abstractmethod
|
|
137
|
+
async def create(
|
|
138
|
+
self, space_name: str, subpath: str, meta: core.Meta
|
|
139
|
+
):
|
|
140
|
+
pass
|
|
141
|
+
|
|
142
|
+
@abstractmethod
|
|
143
|
+
async def save_payload(
|
|
144
|
+
self, space_name: str, subpath: str, meta: core.Meta, attachment
|
|
145
|
+
):
|
|
146
|
+
pass
|
|
147
|
+
|
|
148
|
+
@abstractmethod
|
|
149
|
+
async def save_payload_from_json(
|
|
150
|
+
self,
|
|
151
|
+
space_name: str,
|
|
152
|
+
subpath: str,
|
|
153
|
+
meta: core.Meta,
|
|
154
|
+
payload_data: dict[str, Any],
|
|
155
|
+
):
|
|
156
|
+
pass
|
|
157
|
+
|
|
158
|
+
@abstractmethod
|
|
159
|
+
async def update(
|
|
160
|
+
self,
|
|
161
|
+
space_name: str,
|
|
162
|
+
subpath: str,
|
|
163
|
+
meta: core.Meta,
|
|
164
|
+
old_version_flattend: dict,
|
|
165
|
+
new_version_flattend: dict,
|
|
166
|
+
updated_attributes_flattend: list,
|
|
167
|
+
user_shortname: str,
|
|
168
|
+
schema_shortname: str | None = None,
|
|
169
|
+
retrieve_lock_status: bool | None = False,
|
|
170
|
+
) -> dict:
|
|
171
|
+
pass
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
@abstractmethod
|
|
175
|
+
async def update_payload(
|
|
176
|
+
self,
|
|
177
|
+
space_name: str,
|
|
178
|
+
subpath: str,
|
|
179
|
+
meta: core.Meta,
|
|
180
|
+
payload_data: dict[str, Any],
|
|
181
|
+
owner_shortname: str,
|
|
182
|
+
):
|
|
183
|
+
pass
|
|
184
|
+
|
|
185
|
+
@abstractmethod
|
|
186
|
+
async def store_entry_diff(
|
|
187
|
+
self,
|
|
188
|
+
space_name: str,
|
|
189
|
+
subpath: str,
|
|
190
|
+
shortname: str,
|
|
191
|
+
owner_shortname: str,
|
|
192
|
+
old_version_flattend: dict,
|
|
193
|
+
new_version_flattend: dict,
|
|
194
|
+
updated_attributes_flattend: list,
|
|
195
|
+
resource_type,
|
|
196
|
+
) -> dict:
|
|
197
|
+
pass
|
|
198
|
+
|
|
199
|
+
@abstractmethod
|
|
200
|
+
async def move(
|
|
201
|
+
self,
|
|
202
|
+
src_space_name: str,
|
|
203
|
+
src_subpath: str,
|
|
204
|
+
src_shortname: str,
|
|
205
|
+
dest_space_name: str,
|
|
206
|
+
dest_subpath: str,
|
|
207
|
+
dest_shortname: str,
|
|
208
|
+
meta: core.Meta,
|
|
209
|
+
):
|
|
210
|
+
"""Move the file that match the criteria given, remove source folder if empty"""
|
|
211
|
+
pass
|
|
212
|
+
|
|
213
|
+
@abstractmethod
|
|
214
|
+
def delete_empty(self, path: Path):
|
|
215
|
+
pass
|
|
216
|
+
|
|
217
|
+
@abstractmethod
|
|
218
|
+
async def clone(
|
|
219
|
+
self,
|
|
220
|
+
src_space: str,
|
|
221
|
+
dest_space: str,
|
|
222
|
+
src_subpath: str,
|
|
223
|
+
src_shortname: str,
|
|
224
|
+
dest_subpath: str,
|
|
225
|
+
dest_shortname: str,
|
|
226
|
+
class_type: Type[MetaChild],
|
|
227
|
+
):
|
|
228
|
+
pass
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
@abstractmethod
|
|
232
|
+
async def is_entry_exist(self,
|
|
233
|
+
space_name: str,
|
|
234
|
+
subpath: str,
|
|
235
|
+
shortname: str,
|
|
236
|
+
resource_type: core.ResourceType,
|
|
237
|
+
schema_shortname: str | None = None, ) -> bool:
|
|
238
|
+
pass
|
|
239
|
+
|
|
240
|
+
@abstractmethod
|
|
241
|
+
async def delete(
|
|
242
|
+
self,
|
|
243
|
+
space_name: str,
|
|
244
|
+
subpath: str,
|
|
245
|
+
meta: core.Meta,
|
|
246
|
+
user_shortname: str,
|
|
247
|
+
schema_shortname: str | None = None,
|
|
248
|
+
retrieve_lock_status: bool | None = False,
|
|
249
|
+
):
|
|
250
|
+
pass
|
|
251
|
+
|
|
252
|
+
@abstractmethod
|
|
253
|
+
async def lock_handler(
|
|
254
|
+
self, space_name: str, subpath: str, shortname: str, user_shortname: str, action: LockAction
|
|
255
|
+
) -> dict|None:
|
|
256
|
+
pass
|
|
257
|
+
|
|
258
|
+
@abstractmethod
|
|
259
|
+
async def fetch_space(self, space_name: str) -> core.Space | None:
|
|
260
|
+
pass
|
|
261
|
+
|
|
262
|
+
@abstractmethod
|
|
263
|
+
async def get_entry_attachments(
|
|
264
|
+
self,
|
|
265
|
+
subpath: str,
|
|
266
|
+
attachments_path: Path,
|
|
267
|
+
filter_types: list | None = None,
|
|
268
|
+
include_fields: list | None = None,
|
|
269
|
+
filter_shortnames: list | None = None,
|
|
270
|
+
retrieve_json_payload: bool = False,
|
|
271
|
+
) -> dict:
|
|
272
|
+
return {}
|
|
273
|
+
|
|
274
|
+
@abstractmethod
|
|
275
|
+
async def set_user_session(self, user_shortname: str, token: str) -> bool:
|
|
276
|
+
pass
|
|
277
|
+
|
|
278
|
+
@abstractmethod
|
|
279
|
+
async def get_user_session(self, user_shortname: str, token: str) -> Tuple[int, str | None]:
|
|
280
|
+
pass
|
|
281
|
+
|
|
282
|
+
@abstractmethod
|
|
283
|
+
async def remove_user_session(self, user_shortname: str) -> bool:
|
|
284
|
+
pass
|
|
285
|
+
|
|
286
|
+
@abstractmethod
|
|
287
|
+
async def set_invitation(self, invitation_token: str, invitation_value):
|
|
288
|
+
pass
|
|
289
|
+
|
|
290
|
+
@abstractmethod
|
|
291
|
+
async def get_invitation(self, invitation_token: str) -> str | None:
|
|
292
|
+
pass
|
|
293
|
+
|
|
294
|
+
@abstractmethod
|
|
295
|
+
async def delete_invitation(self, invitation_token: str) -> bool:
|
|
296
|
+
pass
|
|
297
|
+
|
|
298
|
+
@abstractmethod
|
|
299
|
+
async def set_url_shortner(self, token_uuid: str, url: str):
|
|
300
|
+
pass
|
|
301
|
+
|
|
302
|
+
@abstractmethod
|
|
303
|
+
async def get_url_shortner(self, token_uuid: str) -> str | None:
|
|
304
|
+
pass
|
|
305
|
+
|
|
306
|
+
@abstractmethod
|
|
307
|
+
async def delete_url_shortner(self, token_uuid: str) -> bool:
|
|
308
|
+
pass
|
|
309
|
+
|
|
310
|
+
@abstractmethod
|
|
311
|
+
async def delete_url_shortner_by_token(self, invitation_token: str) -> bool:
|
|
312
|
+
pass
|
|
313
|
+
|
|
314
|
+
@abstractmethod
|
|
315
|
+
async def clear_failed_password_attempts(self, user_shortname: str) -> bool:
|
|
316
|
+
pass
|
|
317
|
+
|
|
318
|
+
@abstractmethod
|
|
319
|
+
async def get_failed_password_attempt_count(self, user_shortname: str) -> int:
|
|
320
|
+
return 0
|
|
321
|
+
|
|
322
|
+
@abstractmethod
|
|
323
|
+
async def set_failed_password_attempt_count(self, user_shortname: str, attempt_count: int) -> bool:
|
|
324
|
+
pass
|
|
325
|
+
|
|
326
|
+
@abstractmethod
|
|
327
|
+
async def get_spaces(self) -> dict:
|
|
328
|
+
return {}
|
|
329
|
+
|
|
330
|
+
@abstractmethod
|
|
331
|
+
async def get_media_attachment(self, space_name: str, subpath: str, shortname: str) -> io.BytesIO | None:
|
|
332
|
+
pass
|
|
333
|
+
|
|
334
|
+
@abstractmethod
|
|
335
|
+
async def validate_uniqueness(
|
|
336
|
+
self, space_name: str, record: Record, action: str = RequestType.create, user_shortname=None
|
|
337
|
+
) -> bool:
|
|
338
|
+
pass
|
|
339
|
+
|
|
340
|
+
@abstractmethod
|
|
341
|
+
async def validate_payload_with_schema(
|
|
342
|
+
self,
|
|
343
|
+
payload_data: UploadFile | dict,
|
|
344
|
+
space_name: str,
|
|
345
|
+
schema_shortname: str,
|
|
346
|
+
):
|
|
347
|
+
pass
|
|
348
|
+
|
|
349
|
+
@abstractmethod
|
|
350
|
+
async def get_schema(self, space_name: str, schema_shortname: str, owner_shortname: str) -> dict:
|
|
351
|
+
pass
|
|
352
|
+
|
|
353
|
+
@abstractmethod
|
|
354
|
+
async def check_uniqueness(self, unique_fields, search_str, redis_escape_chars) -> dict:
|
|
355
|
+
pass
|
|
356
|
+
|
|
357
|
+
@abstractmethod
|
|
358
|
+
async def get_role_permissions(self, role: core.Role) -> list[core.Permission]:
|
|
359
|
+
pass
|
|
360
|
+
|
|
361
|
+
@abstractmethod
|
|
362
|
+
async def get_user_roles(self, user_shortname: str) -> dict[str, core.Role]:
|
|
363
|
+
pass
|
|
364
|
+
|
|
365
|
+
@abstractmethod
|
|
366
|
+
async def load_user_meta(self, user_shortname: str) -> Any:
|
|
367
|
+
pass
|
|
368
|
+
|
|
369
|
+
@abstractmethod
|
|
370
|
+
async def generate_user_permissions(self, user_shortname: str) -> dict:
|
|
371
|
+
pass
|
|
372
|
+
|
|
373
|
+
@abstractmethod
|
|
374
|
+
async def get_user_permissions(self, user_shortname: str) -> dict:
|
|
375
|
+
pass
|
|
376
|
+
|
|
377
|
+
@abstractmethod
|
|
378
|
+
async def get_user_by_criteria(self, key: str, value: str) -> str | None:
|
|
379
|
+
pass
|
|
380
|
+
|
|
381
|
+
@abstractmethod
|
|
382
|
+
async def get_payload_from_event(self, event) -> dict:
|
|
383
|
+
pass
|
|
384
|
+
|
|
385
|
+
@abstractmethod
|
|
386
|
+
async def get_user_roles_from_groups(self, user_meta: core.User) -> list:
|
|
387
|
+
pass
|
|
388
|
+
|
|
389
|
+
@abstractmethod
|
|
390
|
+
async def drop_index(self, space_name):
|
|
391
|
+
pass
|
|
392
|
+
|
|
393
|
+
@abstractmethod
|
|
394
|
+
async def initialize_spaces(self) -> None:
|
|
395
|
+
pass
|
|
396
|
+
|
|
397
|
+
@abstractmethod
|
|
398
|
+
async def create_user_premission_index(self) -> None:
|
|
399
|
+
pass
|
|
400
|
+
|
|
401
|
+
@abstractmethod
|
|
402
|
+
async def store_modules_to_redis(self, roles, groups, permissions) -> None:
|
|
403
|
+
pass
|
|
404
|
+
|
|
405
|
+
@abstractmethod
|
|
406
|
+
async def delete_user_permissions_map_in_redis(self) -> None:
|
|
407
|
+
pass
|
|
408
|
+
|
|
409
|
+
@abstractmethod
|
|
410
|
+
async def get_entry_by_var(
|
|
411
|
+
self,
|
|
412
|
+
key: str,
|
|
413
|
+
val: str,
|
|
414
|
+
logged_in_user,
|
|
415
|
+
retrieve_json_payload: bool = False,
|
|
416
|
+
retrieve_attachments: bool = False,
|
|
417
|
+
retrieve_lock_status: bool = False,
|
|
418
|
+
) -> core.Record | None:
|
|
419
|
+
pass
|
|
420
|
+
|
|
421
|
+
@abstractmethod
|
|
422
|
+
async def internal_save_model(
|
|
423
|
+
self,
|
|
424
|
+
space_name: str,
|
|
425
|
+
subpath: str,
|
|
426
|
+
meta: core.Meta,
|
|
427
|
+
payload: dict | None = None
|
|
428
|
+
):
|
|
429
|
+
pass
|
|
430
|
+
|
|
431
|
+
@abstractmethod
|
|
432
|
+
async def internal_sys_update_model(
|
|
433
|
+
self,
|
|
434
|
+
space_name: str,
|
|
435
|
+
subpath: str,
|
|
436
|
+
meta: core.Meta,
|
|
437
|
+
updates: dict,
|
|
438
|
+
sync_redis: bool = True,
|
|
439
|
+
payload_dict: dict[str, Any] = {},
|
|
440
|
+
):
|
|
441
|
+
pass
|
|
442
|
+
|
|
443
|
+
@abstractmethod
|
|
444
|
+
async def delete_space(self, space_name, record, owner_shortname):
|
|
445
|
+
pass
|
|
446
|
+
|
|
447
|
+
@abstractmethod
|
|
448
|
+
async def get_last_updated_entry(
|
|
449
|
+
self,
|
|
450
|
+
space_name: str,
|
|
451
|
+
schema_names: list,
|
|
452
|
+
retrieve_json_payload: bool,
|
|
453
|
+
logged_in_user: str,
|
|
454
|
+
):
|
|
455
|
+
pass
|
|
456
|
+
|
|
457
|
+
@abstractmethod
|
|
458
|
+
async def get_group_users(self, group_name: str) -> list:
|
|
459
|
+
pass
|
|
460
|
+
|
|
461
|
+
@abstractmethod
|
|
462
|
+
async def is_user_verified(self, user_shortname: str | None, identifier: str | None) -> bool:
|
|
463
|
+
pass
|
|
464
|
+
|
|
465
|
+
@abstractmethod
|
|
466
|
+
async def test_connection(self):
|
|
467
|
+
pass
|
|
File without changes
|