dmart 0.1.4__py3-none-any.whl → 0.1.8__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/scripts/__init__.py +0 -0
- alembic/scripts/calculate_checksums.py +77 -0
- alembic/scripts/migration_f7a4949eed19.py +28 -0
- alembic/versions/0f3d2b1a7c21_add_authz_materialized_views.py +87 -0
- alembic/versions/10d2041b94d4_last_checksum_history.py +62 -0
- alembic/versions/1cf4e1ee3cb8_ext_permission_with_filter_fields_values.py +33 -0
- alembic/versions/26bfe19b49d4_rm_failedloginattempts.py +42 -0
- alembic/versions/3c8bca2219cc_add_otp_table.py +38 -0
- alembic/versions/6675fd9dfe42_remove_unique_from_sessions_table.py +36 -0
- alembic/versions/71bc1df82e6a_adding_user_last_login_at.py +43 -0
- alembic/versions/74288ccbd3b5_initial.py +264 -0
- alembic/versions/7520a89a8467_rm_activesession_table.py +39 -0
- alembic/versions/848b623755a4_make_created_nd_updated_at_required.py +138 -0
- alembic/versions/8640dcbebf85_add_notes_to_users.py +32 -0
- alembic/versions/91c94250232a_adding_fk_on_owner_shortname.py +104 -0
- alembic/versions/98ecd6f56f9a_ext_meta_with_owner_group_shortname.py +66 -0
- alembic/versions/9aae9138c4ef_indexing_created_at_updated_at.py +80 -0
- alembic/versions/__init__.py +0 -0
- alembic/versions/b53f916b3f6d_json_to_jsonb.py +492 -0
- alembic/versions/eb5f1ec65156_adding_user_locked_to_device.py +36 -0
- alembic/versions/f7a4949eed19_adding_query_policies_to_meta.py +60 -0
- api/user/model/__init__.py +0 -0
- api/user/model/errors.py +14 -0
- api/user/model/requests.py +165 -0
- api/user/model/responses.py +11 -0
- dmart-0.1.8.dist-info/METADATA +64 -0
- {dmart-0.1.4.dist-info → dmart-0.1.8.dist-info}/RECORD +48 -5
- plugins/action_log/__init__.py +0 -0
- plugins/action_log/plugin.py +121 -0
- plugins/admin_notification_sender/__init__.py +0 -0
- plugins/admin_notification_sender/plugin.py +124 -0
- plugins/ldap_manager/__init__.py +0 -0
- plugins/ldap_manager/plugin.py +100 -0
- plugins/local_notification/__init__.py +0 -0
- plugins/local_notification/plugin.py +123 -0
- plugins/realtime_updates_notifier/__init__.py +0 -0
- plugins/realtime_updates_notifier/plugin.py +58 -0
- plugins/redis_db_update/__init__.py +0 -0
- plugins/redis_db_update/plugin.py +188 -0
- plugins/resource_folders_creation/__init__.py +0 -0
- plugins/resource_folders_creation/plugin.py +81 -0
- plugins/system_notification_sender/__init__.py +0 -0
- plugins/system_notification_sender/plugin.py +188 -0
- plugins/update_access_controls/__init__.py +0 -0
- plugins/update_access_controls/plugin.py +9 -0
- dmart-0.1.4.dist-info/METADATA +0 -9
- {dmart-0.1.4.dist-info → dmart-0.1.8.dist-info}/WHEEL +0 -0
- {dmart-0.1.4.dist-info → dmart-0.1.8.dist-info}/entry_points.txt +0 -0
- {dmart-0.1.4.dist-info → dmart-0.1.8.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
from sys import modules as sys_modules
|
|
2
|
+
from uuid import uuid4
|
|
3
|
+
from models import api
|
|
4
|
+
from models.enums import ContentType, QueryType
|
|
5
|
+
from models.core import (
|
|
6
|
+
ActionType,
|
|
7
|
+
Content,
|
|
8
|
+
NotificationData,
|
|
9
|
+
Payload,
|
|
10
|
+
PluginBase,
|
|
11
|
+
Event,
|
|
12
|
+
Translation,
|
|
13
|
+
)
|
|
14
|
+
from utils.notification import NotificationManager
|
|
15
|
+
from utils.helpers import camel_case, replace_message_vars
|
|
16
|
+
from utils.settings import settings
|
|
17
|
+
from fastapi.logger import logger
|
|
18
|
+
from data_adapters.adapter import data_adapter as db
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Plugin(PluginBase):
|
|
22
|
+
async def hook(self, data: Event):
|
|
23
|
+
"""
|
|
24
|
+
after any action
|
|
25
|
+
1- get the matching SystemNotificationRequest for this action
|
|
26
|
+
2- generate list of users to send the notification to (based on the action entry):
|
|
27
|
+
2.1- entry.owner_shortname, entry.group.members?, and entry.collaborators?
|
|
28
|
+
3- send the notification to the list of generated users
|
|
29
|
+
"""
|
|
30
|
+
# Type narrowing for PyRight
|
|
31
|
+
if not isinstance(data.shortname, str):
|
|
32
|
+
logger.warning(
|
|
33
|
+
"data.shortname is None and str is required at system_notification_sender"
|
|
34
|
+
)
|
|
35
|
+
return
|
|
36
|
+
|
|
37
|
+
if data.action_type == ActionType.delete and data.attributes.get("entry"):
|
|
38
|
+
entry = data.attributes["entry"].model_dump()
|
|
39
|
+
else:
|
|
40
|
+
entry = (
|
|
41
|
+
await db.load(
|
|
42
|
+
data.space_name,
|
|
43
|
+
data.subpath,
|
|
44
|
+
data.shortname,
|
|
45
|
+
getattr(sys_modules["models.core"], camel_case(data.resource_type)),
|
|
46
|
+
data.user_shortname,
|
|
47
|
+
)
|
|
48
|
+
).model_dump()
|
|
49
|
+
if entry["payload"] is not None:
|
|
50
|
+
try:
|
|
51
|
+
entry["payload"]["body"] = await db.load_resource_payload(
|
|
52
|
+
space_name=data.space_name,
|
|
53
|
+
subpath=data.subpath,
|
|
54
|
+
filename=entry["payload"]["body"],
|
|
55
|
+
class_type=getattr(
|
|
56
|
+
sys_modules["models.core"], camel_case(data.resource_type)
|
|
57
|
+
),
|
|
58
|
+
)
|
|
59
|
+
except Exception as e:
|
|
60
|
+
logger.warning(
|
|
61
|
+
f"Failed to load payload for entry {data.space_name}/{data.subpath}/{data.shortname}: {e}"
|
|
62
|
+
)
|
|
63
|
+
entry["space_name"] = data.space_name
|
|
64
|
+
entry["resource_type"] = str(data.resource_type)
|
|
65
|
+
entry["subpath"] = data.subpath
|
|
66
|
+
# 1- get the matching SystemNotificationRequests
|
|
67
|
+
total, matching_notification_requests = await db.query(api.Query(
|
|
68
|
+
type=QueryType.search,
|
|
69
|
+
retrieve_json_payload=True,
|
|
70
|
+
space_name="management",
|
|
71
|
+
subpath="notifications/system",
|
|
72
|
+
search=f"@payload.body.on_space:{data.space_name} @payload.body.on_subpath:{data.subpath.lstrip("/")} @payload.body.on_action:{data.action_type}",
|
|
73
|
+
limit=30,
|
|
74
|
+
offset=0
|
|
75
|
+
), "dmart")
|
|
76
|
+
if total == 0:
|
|
77
|
+
return
|
|
78
|
+
|
|
79
|
+
sub_matching_notification_requests = matching_notification_requests[0].model_dump()
|
|
80
|
+
notification_dict = sub_matching_notification_requests
|
|
81
|
+
if (
|
|
82
|
+
"state" in entry
|
|
83
|
+
and notification_dict.get("on_state", "") != ""
|
|
84
|
+
and notification_dict["on_state"] != entry["state"]
|
|
85
|
+
):
|
|
86
|
+
return
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
# 2- get list of subscribed users
|
|
90
|
+
notification_subscribers =[]
|
|
91
|
+
# if entry.get("collaborators", None):
|
|
92
|
+
# notification_subscribers.extend(entry["collaborators"].values())
|
|
93
|
+
|
|
94
|
+
data_owner_shortname = entry["owner_shortname"]
|
|
95
|
+
if entry.get("owner_group_shortname", None):
|
|
96
|
+
group_users = await db.get_group_users(entry["owner_group_shortname"])
|
|
97
|
+
notification_subscribers.extend(group_users)
|
|
98
|
+
if data_owner_shortname in notification_subscribers:
|
|
99
|
+
notification_subscribers.remove(data_owner_shortname)
|
|
100
|
+
users_objects: dict[str, dict] = {}
|
|
101
|
+
|
|
102
|
+
for subscriber in notification_subscribers:
|
|
103
|
+
users_objects[subscriber] = (await db.load(
|
|
104
|
+
settings.management_space,
|
|
105
|
+
settings.users_subpath,
|
|
106
|
+
subscriber,
|
|
107
|
+
getattr(sys_modules["models.core"], camel_case("user")),
|
|
108
|
+
data.user_shortname,
|
|
109
|
+
)).model_dump()
|
|
110
|
+
# 3- send the notification
|
|
111
|
+
notification_manager = NotificationManager()
|
|
112
|
+
|
|
113
|
+
formatted_req = await self.prepare_request(notification_dict, entry)
|
|
114
|
+
for receiver in set(notification_subscribers):
|
|
115
|
+
if not formatted_req["push_only"]:
|
|
116
|
+
notification_content = Content(
|
|
117
|
+
shortname=str(uuid4())[:8],
|
|
118
|
+
is_active=True,
|
|
119
|
+
displayname=notification_dict["attributes"]["displayname"],
|
|
120
|
+
description=notification_dict["attributes"]["description"],
|
|
121
|
+
owner_shortname=receiver,
|
|
122
|
+
payload=Payload(
|
|
123
|
+
content_type=ContentType.json,
|
|
124
|
+
body={
|
|
125
|
+
"type": "system",
|
|
126
|
+
"is_read": False,
|
|
127
|
+
"priority": notification_dict["attributes"]["payload"]["body"]["priority"],
|
|
128
|
+
"entry_space": entry["space_name"],
|
|
129
|
+
"entry_subpath": entry["subpath"],
|
|
130
|
+
"entry_shortname": entry["shortname"],
|
|
131
|
+
"resource_type": entry["resource_type"],
|
|
132
|
+
"created_by": data.user_shortname,
|
|
133
|
+
"action_type": str(data.action_type)
|
|
134
|
+
}
|
|
135
|
+
)
|
|
136
|
+
)
|
|
137
|
+
await db.internal_save_model(
|
|
138
|
+
space_name="personal",
|
|
139
|
+
subpath=f"people/{receiver}/notifications",
|
|
140
|
+
meta=notification_content
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
for platform in formatted_req["platforms"]:
|
|
144
|
+
await notification_manager.send(
|
|
145
|
+
platform=platform,
|
|
146
|
+
data=NotificationData(
|
|
147
|
+
receiver=users_objects[receiver],
|
|
148
|
+
title=formatted_req["title"],
|
|
149
|
+
body=formatted_req["body"],
|
|
150
|
+
image_urls=formatted_req["images_urls"],
|
|
151
|
+
deep_link=notification_dict.get("deep_link", {}),
|
|
152
|
+
entry_id=entry["shortname"],
|
|
153
|
+
),
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
async def prepare_request(self, notification_dict: dict, entry: dict) -> dict:
|
|
157
|
+
for locale in ["ar", "en", "ku"]:
|
|
158
|
+
if "displayname" in notification_dict:
|
|
159
|
+
notification_dict["displayname"][locale] = replace_message_vars(
|
|
160
|
+
notification_dict["displayname"][locale], entry, locale
|
|
161
|
+
)
|
|
162
|
+
if "description" in notification_dict:
|
|
163
|
+
notification_dict["description"][locale] = replace_message_vars(
|
|
164
|
+
notification_dict["description"][locale], entry, locale
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
# Get Notification Request Images
|
|
168
|
+
attachments_path = (
|
|
169
|
+
settings.spaces_folder
|
|
170
|
+
/ f"{settings.management_space}"
|
|
171
|
+
f"/{notification_dict['subpath']}/.dm/{notification_dict['shortname']}"
|
|
172
|
+
)
|
|
173
|
+
notification_attachments = await db.get_entry_attachments(
|
|
174
|
+
subpath=f"{notification_dict['subpath']}/{notification_dict['shortname']}",
|
|
175
|
+
attachments_path=attachments_path,
|
|
176
|
+
)
|
|
177
|
+
notification_images = {
|
|
178
|
+
"en": notification_attachments.get("media", {}).get("en"),
|
|
179
|
+
"ar": notification_attachments.get("media", {}).get("ar"),
|
|
180
|
+
"ku": notification_attachments.get("media", {}).get("ku"),
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
"platforms": notification_dict.get("types", []),
|
|
184
|
+
"title": Translation(**notification_dict.get("displayname", {})),
|
|
185
|
+
"body": Translation(**notification_dict.get("description", {})),
|
|
186
|
+
"images_urls": Translation(**notification_images),
|
|
187
|
+
"push_only": notification_dict.get("push_only", False),
|
|
188
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
from models.core import PluginBase, Event
|
|
2
|
+
from utils.access_control import access_control
|
|
3
|
+
from utils.settings import settings
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Plugin(PluginBase):
|
|
7
|
+
async def hook(self, data: Event):
|
|
8
|
+
if settings.active_data_db == "file":
|
|
9
|
+
await access_control.load_permissions_and_roles()
|
dmart-0.1.4.dist-info/METADATA
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|