dmart 1.4.40.post8__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.
Files changed (489) hide show
  1. dmart/__init__.py +7 -0
  2. dmart/alembic/README +1 -0
  3. dmart/alembic/__init__.py +0 -0
  4. dmart/alembic/env.py +91 -0
  5. dmart/alembic/notes.txt +11 -0
  6. dmart/alembic/script.py.mako +28 -0
  7. dmart/alembic/scripts/__init__.py +0 -0
  8. dmart/alembic/scripts/calculate_checksums.py +77 -0
  9. dmart/alembic/scripts/migration_f7a4949eed19.py +28 -0
  10. dmart/alembic/versions/0f3d2b1a7c21_add_authz_materialized_views.py +87 -0
  11. dmart/alembic/versions/10d2041b94d4_last_checksum_history.py +62 -0
  12. dmart/alembic/versions/1cf4e1ee3cb8_ext_permission_with_filter_fields_values.py +33 -0
  13. dmart/alembic/versions/26bfe19b49d4_rm_failedloginattempts.py +42 -0
  14. dmart/alembic/versions/3c8bca2219cc_add_otp_table.py +38 -0
  15. dmart/alembic/versions/6675fd9dfe42_remove_unique_from_sessions_table.py +36 -0
  16. dmart/alembic/versions/71bc1df82e6a_adding_user_last_login_at.py +43 -0
  17. dmart/alembic/versions/74288ccbd3b5_initial.py +264 -0
  18. dmart/alembic/versions/7520a89a8467_rm_activesession_table.py +39 -0
  19. dmart/alembic/versions/848b623755a4_make_created_nd_updated_at_required.py +138 -0
  20. dmart/alembic/versions/8640dcbebf85_add_notes_to_users.py +32 -0
  21. dmart/alembic/versions/91c94250232a_adding_fk_on_owner_shortname.py +104 -0
  22. dmart/alembic/versions/98ecd6f56f9a_ext_meta_with_owner_group_shortname.py +66 -0
  23. dmart/alembic/versions/9aae9138c4ef_indexing_created_at_updated_at.py +80 -0
  24. dmart/alembic/versions/__init__.py +0 -0
  25. dmart/alembic/versions/b53f916b3f6d_json_to_jsonb.py +492 -0
  26. dmart/alembic/versions/eb5f1ec65156_adding_user_locked_to_device.py +36 -0
  27. dmart/alembic/versions/f7a4949eed19_adding_query_policies_to_meta.py +60 -0
  28. dmart/alembic.ini +117 -0
  29. dmart/api/__init__.py +0 -0
  30. dmart/api/info/__init__.py +0 -0
  31. dmart/api/info/router.py +109 -0
  32. dmart/api/managed/__init__.py +0 -0
  33. dmart/api/managed/router.py +1541 -0
  34. dmart/api/managed/utils.py +1879 -0
  35. dmart/api/public/__init__.py +0 -0
  36. dmart/api/public/router.py +758 -0
  37. dmart/api/qr/__init__.py +0 -0
  38. dmart/api/qr/router.py +108 -0
  39. dmart/api/user/__init__.py +0 -0
  40. dmart/api/user/model/__init__.py +0 -0
  41. dmart/api/user/model/errors.py +14 -0
  42. dmart/api/user/model/requests.py +165 -0
  43. dmart/api/user/model/responses.py +11 -0
  44. dmart/api/user/router.py +1413 -0
  45. dmart/api/user/service.py +270 -0
  46. dmart/bundler.py +52 -0
  47. dmart/cli.py +1133 -0
  48. dmart/config/__init__.py +0 -0
  49. dmart/config/channels.json +11 -0
  50. dmart/config/notification.json +17 -0
  51. dmart/config.env.sample +27 -0
  52. dmart/config.ini.sample +7 -0
  53. dmart/conftest.py +13 -0
  54. dmart/curl.sh +196 -0
  55. dmart/cxb/__init__.py +0 -0
  56. dmart/cxb/assets/@codemirror-Rn7_6DkE.js +10 -0
  57. dmart/cxb/assets/@edraj-CS4NwVbD.js +1 -0
  58. dmart/cxb/assets/@floating-ui-BwwcF-xh.js +1 -0
  59. dmart/cxb/assets/@formatjs-yKEsAtjs.js +1 -0
  60. dmart/cxb/assets/@fortawesome-DRW1UCdr.js +9 -0
  61. dmart/cxb/assets/@jsonquerylang-laKNoFFq.js +12 -0
  62. dmart/cxb/assets/@lezer-za4Q-8Ew.js +1 -0
  63. dmart/cxb/assets/@marijn-DXwl3gUT.js +1 -0
  64. dmart/cxb/assets/@popperjs-l0sNRNKZ.js +1 -0
  65. dmart/cxb/assets/@replit--ERk53eB.js +1 -0
  66. dmart/cxb/assets/@roxi-CGMFK4i8.js +6 -0
  67. dmart/cxb/assets/@typewriter-cCzskkIv.js +17 -0
  68. dmart/cxb/assets/@zerodevx-BlBZjKxu.js +1 -0
  69. dmart/cxb/assets/@zerodevx-CVEpe6WZ.css +1 -0
  70. dmart/cxb/assets/BreadCrumbLite-DAhOx38v.js +1 -0
  71. dmart/cxb/assets/EntryRenderer-CCqV8Rkg.js +32 -0
  72. dmart/cxb/assets/EntryRenderer-DXytdFp9.css +1 -0
  73. dmart/cxb/assets/ListView-BQelo7vZ.js +16 -0
  74. dmart/cxb/assets/ListView-U8of-_c-.css +1 -0
  75. dmart/cxb/assets/Prism--hMplq-p.js +3 -0
  76. dmart/cxb/assets/Prism-Uh6uStUw.css +1 -0
  77. dmart/cxb/assets/Table2Cols-BsbwicQm.js +1 -0
  78. dmart/cxb/assets/_..-BvT6vdHa.css +1 -0
  79. dmart/cxb/assets/_...404_-fuLH_rX9.js +2 -0
  80. dmart/cxb/assets/_...fallback_-Ba_NLmAE.js +1 -0
  81. dmart/cxb/assets/_module-3HrtKAWo.js +3 -0
  82. dmart/cxb/assets/_module-DFKFq0AM.js +4 -0
  83. dmart/cxb/assets/_module-Dgq0ZVtz.js +1 -0
  84. dmart/cxb/assets/ajv-Cpj98o6Y.js +1 -0
  85. dmart/cxb/assets/axios-CG2WSiiR.js +6 -0
  86. dmart/cxb/assets/clsx-B-dksMZM.js +1 -0
  87. dmart/cxb/assets/codemirror-wrapped-line-indent-DPhKvljI.js +1 -0
  88. dmart/cxb/assets/compare-C3AjiGFR.js +1 -0
  89. dmart/cxb/assets/compute-scroll-into-view-Bl8rNFhg.js +1 -0
  90. dmart/cxb/assets/consolite-DlCuI0F9.js +1 -0
  91. dmart/cxb/assets/crelt-C8TCjufn.js +1 -0
  92. dmart/cxb/assets/date-fns-l0sNRNKZ.js +1 -0
  93. dmart/cxb/assets/deepmerge-rn4rBaHU.js +1 -0
  94. dmart/cxb/assets/dmart_services-AL6-IdDE.js +1 -0
  95. dmart/cxb/assets/downloadFile-D08i0YDh.js +1 -0
  96. dmart/cxb/assets/easy-signal-BiPFIK3O.js +1 -0
  97. dmart/cxb/assets/esm-env-rsSWfq8L.js +1 -0
  98. dmart/cxb/assets/export-OF_rTiXu.js +1 -0
  99. dmart/cxb/assets/fast-deep-equal-l0sNRNKZ.js +1 -0
  100. dmart/cxb/assets/fast-diff-C-IidNf4.js +1 -0
  101. dmart/cxb/assets/fast-uri-l0sNRNKZ.js +1 -0
  102. dmart/cxb/assets/flowbite-svelte-BLvjb-sa.js +1 -0
  103. dmart/cxb/assets/flowbite-svelte-CD54FDqW.css +1 -0
  104. dmart/cxb/assets/flowbite-svelte-icons-BI8GVhw_.js +1 -0
  105. dmart/cxb/assets/github-slugger-CQ4oX9Ud.js +1 -0
  106. dmart/cxb/assets/global-igKv-1g9.js +1 -0
  107. dmart/cxb/assets/hookar-BMRD9G9H.js +1 -0
  108. dmart/cxb/assets/immutable-json-patch-DtRO2E_S.js +1 -0
  109. dmart/cxb/assets/import-1vE3gBat.js +1 -0
  110. dmart/cxb/assets/index-B-eTh-ZX.js +1 -0
  111. dmart/cxb/assets/index-BSsK-X71.js +1 -0
  112. dmart/cxb/assets/index-BVyxzKtH.js +1 -0
  113. dmart/cxb/assets/index-BdeNM69f.js +1 -0
  114. dmart/cxb/assets/index-CC-A1ipE.js +1 -0
  115. dmart/cxb/assets/index-CQohGiYB.js +1 -0
  116. dmart/cxb/assets/index-ChjnkpdZ.js +4 -0
  117. dmart/cxb/assets/index-DLP7csA4.js +1 -0
  118. dmart/cxb/assets/index-DTfhnhwd.js +1 -0
  119. dmart/cxb/assets/index-DdXRK7n9.js +2 -0
  120. dmart/cxb/assets/index-DtiCmB4o.js +1 -0
  121. dmart/cxb/assets/index-NBrXBlLA.css +2 -0
  122. dmart/cxb/assets/index-X1uNehO7.js +1 -0
  123. dmart/cxb/assets/index-nrQW6Nrr.js +1 -0
  124. dmart/cxb/assets/info-B986lRiM.js +1 -0
  125. dmart/cxb/assets/intl-messageformat-Dc5UU-HB.js +3 -0
  126. dmart/cxb/assets/jmespath-l0sNRNKZ.js +1 -0
  127. dmart/cxb/assets/json-schema-traverse-l0sNRNKZ.js +1 -0
  128. dmart/cxb/assets/json-source-map-DRgZidqy.js +5 -0
  129. dmart/cxb/assets/jsonpath-plus-l0sNRNKZ.js +1 -0
  130. dmart/cxb/assets/jsonrepair-B30Dx381.js +8 -0
  131. dmart/cxb/assets/lodash-es-DZVAA2ox.js +1 -0
  132. dmart/cxb/assets/marked-DKjyhwJX.js +56 -0
  133. dmart/cxb/assets/marked-gfm-heading-id-U5zO829x.js +2 -0
  134. dmart/cxb/assets/marked-mangle-CDMeiHC6.js +1 -0
  135. dmart/cxb/assets/memoize-one-BdPwpGay.js +1 -0
  136. dmart/cxb/assets/natural-compare-lite-Bg2Xcf-o.js +7 -0
  137. dmart/cxb/assets/pagination-svelte-D5CyoiE_.js +13 -0
  138. dmart/cxb/assets/pagination-svelte-v10nAbbM.css +1 -0
  139. dmart/cxb/assets/plantuml-encoder-C47mzt9T.js +1 -0
  140. dmart/cxb/assets/prismjs-DTUiLGJu.js +9 -0
  141. dmart/cxb/assets/profile-BUf-tKMe.js +1 -0
  142. dmart/cxb/assets/query-CNmXTsgf.js +1 -0
  143. dmart/cxb/assets/queryHelpers-C9iBWwqe.js +1 -0
  144. dmart/cxb/assets/scroll-into-view-if-needed-KR58zyjF.js +1 -0
  145. dmart/cxb/assets/spaces-0oyGvpii.js +1 -0
  146. dmart/cxb/assets/style-mod-Bs6eFhZE.js +3 -0
  147. dmart/cxb/assets/svelte-B2XmcTi_.js +4 -0
  148. dmart/cxb/assets/svelte-awesome-COLlx0DN.css +1 -0
  149. dmart/cxb/assets/svelte-awesome-DhnMA6Q_.js +1 -0
  150. dmart/cxb/assets/svelte-datatables-net-CY7LBj6I.js +1 -0
  151. dmart/cxb/assets/svelte-floating-ui-BlS3sOAQ.js +1 -0
  152. dmart/cxb/assets/svelte-i18n-CT2KkQaN.js +3 -0
  153. dmart/cxb/assets/svelte-jsoneditor-BzfX6Usi.css +1 -0
  154. dmart/cxb/assets/svelte-jsoneditor-CUGSvWId.js +25 -0
  155. dmart/cxb/assets/svelte-select-CegQKzqH.css +1 -0
  156. dmart/cxb/assets/svelte-select-CjHAt_85.js +6 -0
  157. dmart/cxb/assets/tailwind-merge-CJvxXMcu.js +1 -0
  158. dmart/cxb/assets/tailwind-variants-Cj20BoQ3.js +1 -0
  159. dmart/cxb/assets/toast-B9WDyfyI.js +1 -0
  160. dmart/cxb/assets/tslib-pJfR_DrR.js +1 -0
  161. dmart/cxb/assets/typewriter-editor-DkTVIJdm.js +25 -0
  162. dmart/cxb/assets/user-DeK_NB5v.js +1 -0
  163. dmart/cxb/assets/vanilla-picker-l5rcX3cq.js +8 -0
  164. dmart/cxb/assets/w3c-keyname-Vcq4gwWv.js +1 -0
  165. dmart/cxb/config.json +11 -0
  166. dmart/cxb/config.sample.json +11 -0
  167. dmart/cxb/favicon.ico +0 -0
  168. dmart/cxb/favicon.png +0 -0
  169. dmart/cxb/index.html +28 -0
  170. dmart/data_adapters/__init__.py +0 -0
  171. dmart/data_adapters/adapter.py +16 -0
  172. dmart/data_adapters/base_data_adapter.py +467 -0
  173. dmart/data_adapters/file/__init__.py +0 -0
  174. dmart/data_adapters/file/adapter.py +2043 -0
  175. dmart/data_adapters/file/adapter_helpers.py +1013 -0
  176. dmart/data_adapters/file/archive.py +150 -0
  177. dmart/data_adapters/file/create_index.py +331 -0
  178. dmart/data_adapters/file/create_users_folders.py +52 -0
  179. dmart/data_adapters/file/custom_validations.py +68 -0
  180. dmart/data_adapters/file/drop_index.py +40 -0
  181. dmart/data_adapters/file/health_check.py +560 -0
  182. dmart/data_adapters/file/redis_services.py +1110 -0
  183. dmart/data_adapters/helpers.py +27 -0
  184. dmart/data_adapters/sql/__init__.py +0 -0
  185. dmart/data_adapters/sql/adapter.py +3218 -0
  186. dmart/data_adapters/sql/adapter_helpers.py +491 -0
  187. dmart/data_adapters/sql/create_tables.py +451 -0
  188. dmart/data_adapters/sql/create_users_folders.py +53 -0
  189. dmart/data_adapters/sql/db_to_json_migration.py +485 -0
  190. dmart/data_adapters/sql/health_check_sql.py +232 -0
  191. dmart/data_adapters/sql/json_to_db_migration.py +454 -0
  192. dmart/data_adapters/sql/update_query_policies.py +101 -0
  193. dmart/data_generator.py +81 -0
  194. dmart/dmart.py +761 -0
  195. dmart/get_settings.py +7 -0
  196. dmart/hypercorn_config.toml +3 -0
  197. dmart/info.json +1 -0
  198. dmart/languages/__init__.py +0 -0
  199. dmart/languages/arabic.json +15 -0
  200. dmart/languages/english.json +16 -0
  201. dmart/languages/kurdish.json +14 -0
  202. dmart/languages/loader.py +12 -0
  203. dmart/login_creds.sh +7 -0
  204. dmart/login_creds.sh.sample +7 -0
  205. dmart/main.py +563 -0
  206. dmart/manifest.sh +12 -0
  207. dmart/migrate.py +24 -0
  208. dmart/models/__init__.py +0 -0
  209. dmart/models/api.py +203 -0
  210. dmart/models/core.py +597 -0
  211. dmart/models/enums.py +255 -0
  212. dmart/password_gen.py +8 -0
  213. dmart/plugins/__init__.py +0 -0
  214. dmart/plugins/action_log/__init__.py +0 -0
  215. dmart/plugins/action_log/config.json +13 -0
  216. dmart/plugins/action_log/plugin.py +121 -0
  217. dmart/plugins/admin_notification_sender/__init__.py +0 -0
  218. dmart/plugins/admin_notification_sender/config.json +13 -0
  219. dmart/plugins/admin_notification_sender/plugin.py +124 -0
  220. dmart/plugins/ldap_manager/__init__.py +0 -0
  221. dmart/plugins/ldap_manager/config.json +12 -0
  222. dmart/plugins/ldap_manager/dmart.schema +146 -0
  223. dmart/plugins/ldap_manager/plugin.py +100 -0
  224. dmart/plugins/ldap_manager/slapd.conf +53 -0
  225. dmart/plugins/local_notification/__init__.py +0 -0
  226. dmart/plugins/local_notification/config.json +13 -0
  227. dmart/plugins/local_notification/plugin.py +123 -0
  228. dmart/plugins/realtime_updates_notifier/__init__.py +0 -0
  229. dmart/plugins/realtime_updates_notifier/config.json +12 -0
  230. dmart/plugins/realtime_updates_notifier/plugin.py +58 -0
  231. dmart/plugins/redis_db_update/__init__.py +0 -0
  232. dmart/plugins/redis_db_update/config.json +13 -0
  233. dmart/plugins/redis_db_update/plugin.py +188 -0
  234. dmart/plugins/resource_folders_creation/__init__.py +0 -0
  235. dmart/plugins/resource_folders_creation/config.json +12 -0
  236. dmart/plugins/resource_folders_creation/plugin.py +81 -0
  237. dmart/plugins/system_notification_sender/__init__.py +0 -0
  238. dmart/plugins/system_notification_sender/config.json +13 -0
  239. dmart/plugins/system_notification_sender/plugin.py +188 -0
  240. dmart/plugins/update_access_controls/__init__.py +0 -0
  241. dmart/plugins/update_access_controls/config.json +12 -0
  242. dmart/plugins/update_access_controls/plugin.py +9 -0
  243. dmart/publish.sh +57 -0
  244. dmart/pylint.sh +16 -0
  245. dmart/pyrightconfig.json +7 -0
  246. dmart/redis_connections.sh +13 -0
  247. dmart/reload.sh +56 -0
  248. dmart/run.sh +3 -0
  249. dmart/run_notification_campaign.py +85 -0
  250. dmart/sample/spaces/applications/.dm/meta.space.json +30 -0
  251. dmart/sample/spaces/applications/api/.dm/meta.folder.json +1 -0
  252. dmart/sample/spaces/applications/api/.dm/query_all_applications/meta.content.json +1 -0
  253. dmart/sample/spaces/applications/api/.dm/test_by_saad/attachments.media/meta.warframe.json +1 -0
  254. dmart/sample/spaces/applications/api/.dm/test_by_saad/attachments.media/warframe.png +0 -0
  255. dmart/sample/spaces/applications/api/.dm/test_by_saad/meta.content.json +1 -0
  256. dmart/sample/spaces/applications/api/.dm/user_profile/meta.content.json +1 -0
  257. dmart/sample/spaces/applications/api/applications/.dm/create_log/meta.content.json +1 -0
  258. dmart/sample/spaces/applications/api/applications/.dm/create_public_logs/meta.content.json +1 -0
  259. dmart/sample/spaces/applications/api/applications/.dm/meta.folder.json +1 -0
  260. dmart/sample/spaces/applications/api/applications/.dm/query_all_translated_data/meta.content.json +1 -0
  261. dmart/sample/spaces/applications/api/applications/.dm/query_logs/meta.content.json +1 -0
  262. dmart/sample/spaces/applications/api/applications/.dm/query_translated_enums/meta.content.json +1 -0
  263. dmart/sample/spaces/applications/api/applications/.dm/query_translated_others/meta.content.json +1 -0
  264. dmart/sample/spaces/applications/api/applications/.dm/query_translated_resolution/meta.content.json +1 -0
  265. dmart/sample/spaces/applications/api/applications/create_log.json +1 -0
  266. dmart/sample/spaces/applications/api/applications/create_public_logs.json +1 -0
  267. dmart/sample/spaces/applications/api/applications/query_all_translated_data.json +1 -0
  268. dmart/sample/spaces/applications/api/applications/query_logs.json +1 -0
  269. dmart/sample/spaces/applications/api/applications/query_translated_enums.json +1 -0
  270. dmart/sample/spaces/applications/api/applications/query_translated_others.json +1 -0
  271. dmart/sample/spaces/applications/api/applications/query_translated_resolution.json +1 -0
  272. dmart/sample/spaces/applications/api/applications.json +1 -0
  273. dmart/sample/spaces/applications/api/management/.dm/create_subaccount/meta.content.json +1 -0
  274. dmart/sample/spaces/applications/api/management/.dm/meta.folder.json +1 -0
  275. dmart/sample/spaces/applications/api/management/.dm/update_password/meta.content.json +1 -0
  276. dmart/sample/spaces/applications/api/management/create_subaccount.json +53 -0
  277. dmart/sample/spaces/applications/api/management/update_password.json +1 -0
  278. dmart/sample/spaces/applications/api/management.json +1 -0
  279. dmart/sample/spaces/applications/api/query_all_applications.json +15 -0
  280. dmart/sample/spaces/applications/api/test_by_saad.json +1 -0
  281. dmart/sample/spaces/applications/api/user/.dm/meta.folder.json +1 -0
  282. dmart/sample/spaces/applications/api/user/.dm/test_by_saad/meta.content.json +1 -0
  283. dmart/sample/spaces/applications/api/user/.dm/user_profile/meta.content.json +1 -0
  284. dmart/sample/spaces/applications/api/user/test_by_saad.json +1 -0
  285. dmart/sample/spaces/applications/api/user/user_profile.json +1 -0
  286. dmart/sample/spaces/applications/api/user_profile.json +1 -0
  287. dmart/sample/spaces/applications/api.json +1 -0
  288. dmart/sample/spaces/applications/collections/.dm/meta.folder.json +19 -0
  289. dmart/sample/spaces/applications/collections.json +1 -0
  290. dmart/sample/spaces/applications/configurations/.dm/meta.folder.json +1 -0
  291. dmart/sample/spaces/applications/configurations/time_out.json +1 -0
  292. dmart/sample/spaces/applications/configurations.json +19 -0
  293. dmart/sample/spaces/applications/errors.json +1 -0
  294. dmart/sample/spaces/applications/logs/.dm/meta.folder.json +1 -0
  295. dmart/sample/spaces/applications/logs.json +1 -0
  296. dmart/sample/spaces/applications/queries/.dm/meta.folder.json +1 -0
  297. dmart/sample/spaces/applications/queries/.dm/order/meta.content.json +1 -0
  298. dmart/sample/spaces/applications/queries/order.json +1 -0
  299. dmart/sample/spaces/applications/queries.json +1 -0
  300. dmart/sample/spaces/applications/schema/.dm/api/meta.schema.json +1 -0
  301. dmart/sample/spaces/applications/schema/.dm/configuration/meta.schema.json +1 -0
  302. dmart/sample/spaces/applications/schema/.dm/error/meta.schema.json +1 -0
  303. dmart/sample/spaces/applications/schema/.dm/log/meta.schema.json +1 -0
  304. dmart/sample/spaces/applications/schema/.dm/meta.folder.json +1 -0
  305. dmart/sample/spaces/applications/schema/.dm/query/meta.schema.json +16 -0
  306. dmart/sample/spaces/applications/schema/.dm/translation/meta.schema.json +1 -0
  307. dmart/sample/spaces/applications/schema/api.json +28 -0
  308. dmart/sample/spaces/applications/schema/configuration.json +1 -0
  309. dmart/sample/spaces/applications/schema/error.json +43 -0
  310. dmart/sample/spaces/applications/schema/log.json +1 -0
  311. dmart/sample/spaces/applications/schema/query.json +118 -0
  312. dmart/sample/spaces/applications/schema/translation.json +26 -0
  313. dmart/sample/spaces/applications/schema.json +1 -0
  314. dmart/sample/spaces/applications/translations/.dm/meta.folder.json +1 -0
  315. dmart/sample/spaces/applications/translations.json +1 -0
  316. dmart/sample/spaces/archive/.dm/meta.space.json +27 -0
  317. dmart/sample/spaces/custom_plugins/dummy/__pycache__/plugin.cpython-314.pyc +0 -0
  318. dmart/sample/spaces/custom_plugins/dummy/config.json +28 -0
  319. dmart/sample/spaces/custom_plugins/dummy/plugin.py +6 -0
  320. dmart/sample/spaces/custom_plugins/missed_entry/config.json +12 -0
  321. dmart/sample/spaces/custom_plugins/missed_entry/plugin.py +119 -0
  322. dmart/sample/spaces/custom_plugins/own_changed_notification/__pycache__/plugin.cpython-314.pyc +0 -0
  323. dmart/sample/spaces/custom_plugins/own_changed_notification/config.json +12 -0
  324. dmart/sample/spaces/custom_plugins/own_changed_notification/plugin.py +65 -0
  325. dmart/sample/spaces/custom_plugins/reports_stats/config.json +14 -0
  326. dmart/sample/spaces/custom_plugins/reports_stats/plugin.py +82 -0
  327. dmart/sample/spaces/custom_plugins/system_notification_sender/config.json +22 -0
  328. dmart/sample/spaces/custom_plugins/system_notification_sender/notification.py +268 -0
  329. dmart/sample/spaces/custom_plugins/system_notification_sender/plugin.py +98 -0
  330. dmart/sample/spaces/management/.dm/events.jsonl +32 -0
  331. dmart/sample/spaces/management/.dm/meta.space.json +48 -0
  332. dmart/sample/spaces/management/.dm/notifications/attachments.view.json/admin.json +36 -0
  333. dmart/sample/spaces/management/.dm/notifications/attachments.view.json/meta.admin.json +1 -0
  334. dmart/sample/spaces/management/.dm/notifications/attachments.view.json/meta.system.json +1 -0
  335. dmart/sample/spaces/management/.dm/notifications/attachments.view.json/system.json +32 -0
  336. dmart/sample/spaces/management/collections/.dm/meta.folder.json +1 -0
  337. dmart/sample/spaces/management/collections.json +1 -0
  338. dmart/sample/spaces/management/groups/.dm/meta.folder.json +1 -0
  339. dmart/sample/spaces/management/groups.json +1 -0
  340. dmart/sample/spaces/management/health_check/.dm/meta.folder.json +1 -0
  341. dmart/sample/spaces/management/health_check.json +1 -0
  342. dmart/sample/spaces/management/notifications/.dm/meta.folder.json +1 -0
  343. dmart/sample/spaces/management/notifications/admin/.dm/meta.folder.json +9 -0
  344. dmart/sample/spaces/management/notifications/system/.dm/meta.folder.json +9 -0
  345. dmart/sample/spaces/management/notifications.json +1 -0
  346. dmart/sample/spaces/management/permissions/.dm/access_applications/meta.permission.json +31 -0
  347. dmart/sample/spaces/management/permissions/.dm/access_applications_world/meta.permission.json +31 -0
  348. dmart/sample/spaces/management/permissions/.dm/access_messages/meta.permission.json +23 -0
  349. dmart/sample/spaces/management/permissions/.dm/access_personal/meta.permission.json +40 -0
  350. dmart/sample/spaces/management/permissions/.dm/access_protected/meta.permission.json +33 -0
  351. dmart/sample/spaces/management/permissions/.dm/access_public/meta.permission.json +24 -0
  352. dmart/sample/spaces/management/permissions/.dm/browse_all_folders/meta.permission.json +23 -0
  353. dmart/sample/spaces/management/permissions/.dm/create_log/meta.permission.json +24 -0
  354. dmart/sample/spaces/management/permissions/.dm/interviewer/meta.permission.json +1 -0
  355. dmart/sample/spaces/management/permissions/.dm/manage_applications/meta.permission.json +1 -0
  356. dmart/sample/spaces/management/permissions/.dm/manage_debug/meta.permission.json +25 -0
  357. dmart/sample/spaces/management/permissions/.dm/manage_spaces/meta.permission.json +24 -0
  358. dmart/sample/spaces/management/permissions/.dm/meta.folder.json +1 -0
  359. dmart/sample/spaces/management/permissions/.dm/rules_management_default/meta.permission.json +32 -0
  360. dmart/sample/spaces/management/permissions/.dm/super_manager/meta.permission.json +52 -0
  361. dmart/sample/spaces/management/permissions/.dm/view_activity_log/meta.permission.json +26 -0
  362. dmart/sample/spaces/management/permissions/.dm/view_collections/meta.permission.json +29 -0
  363. dmart/sample/spaces/management/permissions/.dm/view_logs/meta.permission.json +30 -0
  364. dmart/sample/spaces/management/permissions/.dm/view_roles/meta.permission.json +29 -0
  365. dmart/sample/spaces/management/permissions/.dm/view_users/meta.permission.json +25 -0
  366. dmart/sample/spaces/management/permissions/.dm/view_world/meta.permission.json +31 -0
  367. dmart/sample/spaces/management/permissions/.dm/world/meta.permission.json +35 -0
  368. dmart/sample/spaces/management/permissions.json +1 -0
  369. dmart/sample/spaces/management/requests.json +1 -0
  370. dmart/sample/spaces/management/roles/.dm/dummy/meta.role.json +12 -0
  371. dmart/sample/spaces/management/roles/.dm/logged_in/meta.role.json +18 -0
  372. dmart/sample/spaces/management/roles/.dm/manager/meta.role.json +13 -0
  373. dmart/sample/spaces/management/roles/.dm/meta.folder.json +1 -0
  374. dmart/sample/spaces/management/roles/.dm/moderator/meta.role.json +13 -0
  375. dmart/sample/spaces/management/roles/.dm/super_admin/meta.role.json +14 -0
  376. dmart/sample/spaces/management/roles/.dm/test_role/meta.role.json +13 -0
  377. dmart/sample/spaces/management/roles/.dm/world/meta.role.json +15 -0
  378. dmart/sample/spaces/management/roles.json +1 -0
  379. dmart/sample/spaces/management/schema/.dm/admin_notification_request/attachments.media/meta.ui_schema.json +10 -0
  380. dmart/sample/spaces/management/schema/.dm/admin_notification_request/attachments.media/ui_schema.json +32 -0
  381. dmart/sample/spaces/management/schema/.dm/admin_notification_request/meta.schema.json +1 -0
  382. dmart/sample/spaces/management/schema/.dm/api/meta.schema.json +1 -0
  383. dmart/sample/spaces/management/schema/.dm/folder_rendering/meta.schema.json +1 -0
  384. dmart/sample/spaces/management/schema/.dm/health_check/meta.schema.json +17 -0
  385. dmart/sample/spaces/management/schema/.dm/meta.folder.json +1 -0
  386. dmart/sample/spaces/management/schema/.dm/meta_schema/meta.schema.json +1 -0
  387. dmart/sample/spaces/management/schema/.dm/metafile/meta.schema.json +14 -0
  388. dmart/sample/spaces/management/schema/.dm/notification/meta.schema.json +1 -0
  389. dmart/sample/spaces/management/schema/.dm/system_notification_request/attachments.media/meta.ui_schema.json +10 -0
  390. dmart/sample/spaces/management/schema/.dm/system_notification_request/attachments.media/ui_schema.json +32 -0
  391. dmart/sample/spaces/management/schema/.dm/system_notification_request/meta.schema.json +1 -0
  392. dmart/sample/spaces/management/schema/.dm/view/meta.schema.json +1 -0
  393. dmart/sample/spaces/management/schema/.dm/workflow/meta.schema.json +1 -0
  394. dmart/sample/spaces/management/schema/admin_notification_request.json +89 -0
  395. dmart/sample/spaces/management/schema/api.json +1 -0
  396. dmart/sample/spaces/management/schema/folder_rendering.json +238 -0
  397. dmart/sample/spaces/management/schema/health_check.json +8 -0
  398. dmart/sample/spaces/management/schema/meta_schema.json +74 -0
  399. dmart/sample/spaces/management/schema/metafile.json +153 -0
  400. dmart/sample/spaces/management/schema/notification.json +28 -0
  401. dmart/sample/spaces/management/schema/system_notification_request.json +57 -0
  402. dmart/sample/spaces/management/schema/view.json +23 -0
  403. dmart/sample/spaces/management/schema/workflow.json +87 -0
  404. dmart/sample/spaces/management/schema.json +1 -0
  405. dmart/sample/spaces/management/users/.dm/alibaba/meta.user.json +23 -0
  406. dmart/sample/spaces/management/users/.dm/anonymous/meta.user.json +18 -0
  407. dmart/sample/spaces/management/users/.dm/dmart/meta.user.json +26 -0
  408. dmart/sample/spaces/management/users/.dm/meta.folder.json +14 -0
  409. dmart/sample/spaces/management/workflows/.dm/channel/meta.content.json +1 -0
  410. dmart/sample/spaces/management/workflows/.dm/meta.folder.json +1 -0
  411. dmart/sample/spaces/management/workflows/channel.json +148 -0
  412. dmart/sample/spaces/management/workflows.json +1 -0
  413. dmart/sample/spaces/maqola/.dm/meta.space.json +33 -0
  414. dmart/sample/spaces/personal/.dm/meta.space.json +24 -0
  415. dmart/sample/spaces/personal/people/.dm/meta.folder.json +1 -0
  416. dmart/sample/spaces/personal/people/dmart/.dm/meta.folder.json +1 -0
  417. dmart/sample/spaces/personal/people/dmart/messages/.dm/0b5f7e7f/meta.content.json +1 -0
  418. dmart/sample/spaces/personal/people/dmart/messages/.dm/meta.folder.json +1 -0
  419. dmart/sample/spaces/personal/people/dmart/messages/.dm/mytest/meta.content.json +1 -0
  420. dmart/sample/spaces/personal/people/dmart/messages/0b5f7e7f.json +1 -0
  421. dmart/sample/spaces/personal/people/dmart/messages/mytest.json +1 -0
  422. dmart/sample/spaces/personal/people/dmart/notifications/.dm/meta.folder.json +1 -0
  423. dmart/sample/spaces/personal/people/dmart/private/.dm/inner/meta.content.json +1 -0
  424. dmart/sample/spaces/personal/people/dmart/private/.dm/meta.folder.json +1 -0
  425. dmart/sample/spaces/personal/people/dmart/private/inner.json +1 -0
  426. dmart/sample/spaces/personal/people/dmart/protected/.dm/avatar/meta.content.json +1 -0
  427. dmart/sample/spaces/personal/people/dmart/protected/.dm/meta.folder.json +1 -0
  428. dmart/sample/spaces/personal/people/dmart/protected/avatar.png +0 -0
  429. dmart/sample/spaces/personal/people/dmart/public/.dm/meta.folder.json +1 -0
  430. dmart/sample/test/.gitignore +2 -0
  431. dmart/sample/test/createcontent.json +9 -0
  432. dmart/sample/test/createmedia.json +9 -0
  433. dmart/sample/test/createmedia_entry.json +6 -0
  434. dmart/sample/test/createschema.json +8 -0
  435. dmart/sample/test/createschemawork.json +11 -0
  436. dmart/sample/test/createticket.json +13 -0
  437. dmart/sample/test/data.json +4 -0
  438. dmart/sample/test/deletecontent.json +12 -0
  439. dmart/sample/test/logo.jpeg +0 -0
  440. dmart/sample/test/my.jpg +0 -0
  441. dmart/sample/test/myticket.json +23 -0
  442. dmart/sample/test/resources.csv +12 -0
  443. dmart/sample/test/schema.json +16 -0
  444. dmart/sample/test/temp.json +1 -0
  445. dmart/sample/test/test.dmart +45 -0
  446. dmart/sample/test/ticket_schema.json +23 -0
  447. dmart/sample/test/ticket_workflow.json +85 -0
  448. dmart/sample/test/ticketbody.json +4 -0
  449. dmart/sample/test/ticketcontent.json +14 -0
  450. dmart/sample/test/updatecontent.json +20 -0
  451. dmart/sample/test/workflow_schema.json +68 -0
  452. dmart/scheduled_notification_handler.py +121 -0
  453. dmart/schema_migration.py +208 -0
  454. dmart/schema_modulate.py +192 -0
  455. dmart/set_admin_passwd.py +75 -0
  456. dmart/sync.py +202 -0
  457. dmart/test_utils.py +34 -0
  458. dmart/utils/__init__.py +0 -0
  459. dmart/utils/access_control.py +306 -0
  460. dmart/utils/async_request.py +8 -0
  461. dmart/utils/exporter.py +309 -0
  462. dmart/utils/firebase_notifier.py +57 -0
  463. dmart/utils/generate_email.py +37 -0
  464. dmart/utils/helpers.py +352 -0
  465. dmart/utils/hypercorn_config.py +12 -0
  466. dmart/utils/internal_error_code.py +60 -0
  467. dmart/utils/jwt.py +124 -0
  468. dmart/utils/logger.py +167 -0
  469. dmart/utils/middleware.py +99 -0
  470. dmart/utils/notification.py +75 -0
  471. dmart/utils/password_hashing.py +16 -0
  472. dmart/utils/plugin_manager.py +202 -0
  473. dmart/utils/query_policies_helper.py +128 -0
  474. dmart/utils/regex.py +44 -0
  475. dmart/utils/repository.py +529 -0
  476. dmart/utils/router_helper.py +19 -0
  477. dmart/utils/settings.py +212 -0
  478. dmart/utils/sms_notifier.py +21 -0
  479. dmart/utils/social_sso.py +67 -0
  480. dmart/utils/templates/activation.html.j2 +26 -0
  481. dmart/utils/templates/reminder.html.j2 +17 -0
  482. dmart/utils/ticket_sys_utils.py +203 -0
  483. dmart/utils/web_notifier.py +29 -0
  484. dmart/websocket.py +231 -0
  485. dmart-1.4.40.post8.dist-info/METADATA +75 -0
  486. dmart-1.4.40.post8.dist-info/RECORD +489 -0
  487. dmart-1.4.40.post8.dist-info/WHEEL +5 -0
  488. dmart-1.4.40.post8.dist-info/entry_points.txt +2 -0
  489. dmart-1.4.40.post8.dist-info/top_level.txt +1 -0
@@ -0,0 +1,212 @@
1
+ """ Application Settings """
2
+
3
+ import json
4
+ import os
5
+ import random
6
+ import re
7
+ import string
8
+ import secrets
9
+ from venv import logger
10
+
11
+ from pydantic import Field
12
+ from pydantic_settings import BaseSettings, SettingsConfigDict
13
+ from pathlib import Path
14
+
15
+ def get_env_file():
16
+ env_file = os.getenv("BACKEND_ENV")
17
+
18
+ if env_file and os.path.exists(env_file):
19
+ return env_file
20
+
21
+ if not env_file or env_file == "config.env":
22
+ if os.path.exists("config.env"):
23
+ return "config.env"
24
+
25
+ dmart_home = Path.home() / ".dmart"
26
+ home_config = dmart_home / "config.env"
27
+
28
+ if not home_config.exists():
29
+ if not (os.path.exists(".git") or os.path.exists("setup.py")):
30
+ try:
31
+ dmart_home.mkdir(parents=True, exist_ok=True)
32
+ (dmart_home / "logs").mkdir(parents=True, exist_ok=True)
33
+ (dmart_home / "spaces").mkdir(parents=True, exist_ok=True)
34
+ (dmart_home / "spaces" / "custom_plugins").mkdir(parents=True, exist_ok=True)
35
+
36
+ jwt_secret = secrets.token_urlsafe(32)
37
+
38
+ config_content = f"""# dmart configuration
39
+ JWT_SECRET="{jwt_secret}"
40
+ JWT_ALGORITHM="HS256"
41
+ LOG_FILE="{dmart_home / 'logs' / 'dmart.ljson.log'}"
42
+ WS_LOG_FILE="{dmart_home / 'logs' / 'websocket.ljson.log'}"
43
+
44
+ # Database configuration
45
+ ACTIVE_DATA_DB="file"
46
+ SPACES_FOLDER="{dmart_home / 'spaces'}"
47
+ DATABASE_DRIVER="sqlite+pysqlite"
48
+ DATABASE_NAME="{dmart_home / 'dmart.db'}"
49
+
50
+ # Server configuration
51
+ LISTENING_HOST="0.0.0.0"
52
+ LISTENING_PORT=8282
53
+ """
54
+ home_config.write_text(config_content)
55
+ except Exception:
56
+ pass
57
+
58
+ if home_config.exists():
59
+ return str(home_config)
60
+
61
+ return env_file or "config.env"
62
+
63
+ class Settings(BaseSettings):
64
+ """Main settings class"""
65
+
66
+ app_url: str = ""
67
+ cxb_url: str = "/cxb"
68
+ public_app_url: str = ""
69
+ app_name: str = "dmart"
70
+ websocket_url: str = "" #"http://127.0.0.1:8484"
71
+ websocket_port: int = 8484
72
+ base_path: str = ""
73
+ debug_enabled: bool = True
74
+ log_handlers: list[str] = ['file']
75
+ log_file: str = "../logs/dmart.ljson.log"
76
+ ws_log_file: str = "../logs/websocket.ljson.log"
77
+ jwt_secret: str = "".join(random.sample(string.ascii_letters + string.digits,12))
78
+ jwt_algorithm: str = "HS256"
79
+ jwt_access_expires: int = 30 * 86400 # 30 days
80
+ listening_host: str = "0.0.0.0"
81
+ listening_port: int = 8282
82
+ redis_host: str = "127.0.0.1"
83
+ redis_password: str = ""
84
+ redis_port: int = 6379
85
+ redis_pool_max_connections: int = 20
86
+ max_sessions_per_user: int = 5
87
+ management_space: str = "management"
88
+ users_subpath: str = "users"
89
+ spaces_folder: Path = Path("../sample/spaces/")
90
+ lock_period: int = 300
91
+ auto_uuid_rule: str = "auto" # Used to generate a shortname from UUID
92
+ google_application_credentials: str = ""
93
+ is_registrable: bool = True
94
+ is_otp_for_create_required: bool = True
95
+ social_login_allowed: bool = True
96
+ all_spaces_mw: str = (
97
+ "__all_spaces__" # magic word used in access control refers to any space
98
+ )
99
+ all_subpaths_mw: str = (
100
+ "__all_subpaths__" # used in access control refers to all subpaths
101
+ )
102
+ current_user_mw: str = (
103
+ "__current_user__" # used in access control refers to current logged-in user
104
+ )
105
+ root_subpath_mw : str = "__root__"
106
+ email_sender: str = "dmart@dmart.com"
107
+
108
+ otp_token_ttl: int = 60 * 5
109
+ allow_otp_resend_after: int = 60
110
+ comms_api: str = ""
111
+ send_sms_otp_api: str = ""
112
+ smpp_auth_key: str = ""
113
+ send_email_otp_api: str = ""
114
+ send_sms_api: str = ""
115
+ send_email_api: str = ""
116
+ mock_smtp_api: bool = True
117
+ files_query: str = "scandir"
118
+ mock_smpp_api: bool = True
119
+ mock_otp_code: str = "123456"
120
+ invitation_link: str = ""
121
+ ldap_url: str = "ldap://"
122
+ ldap_admin_dn: str = ""
123
+ ldap_root_dn: str = ""
124
+ ldap_pass: str = ""
125
+ max_query_limit: int = 10000
126
+ session_inactivity_ttl: int = 0 # Set initially to 0 to disable session timeout. Possible value : 60 * 60 * 24 * 7 # 7 days
127
+ request_timeout: int = 35 # In seconds the time of dmart requests.
128
+ jq_timeout: int = 2 # secs
129
+ is_sha_required: bool = False
130
+ logout_on_pwd_change: bool = True
131
+ url_shorter_expires: int = 60 * 60 * 48 # 48 hours
132
+
133
+ google_client_id: str = ""
134
+ google_client_secret: str = ""
135
+ apple_client_id: str = ""
136
+ apple_client_secret: str = ""
137
+
138
+ facebook_client_id: str = ""
139
+ facebook_client_secret: str = ""
140
+
141
+ enable_channel_auth: bool = False
142
+ channels: list = []
143
+ store_payload_string: bool = True
144
+
145
+ active_operational_db: str = "redis" # allowed values: redis, manticore
146
+ active_data_db: str = "file" # allowed values: file, sql
147
+
148
+ database_driver: str = 'sqlite+pysqlite'
149
+ database_username: str = 'postgres'
150
+ database_password: str = ''
151
+ database_host: str = 'localhost'
152
+ database_port: int = 5432
153
+ database_name: str = 'dmart'
154
+ database_pool_size: int = 2
155
+ database_max_overflow: int = 2
156
+ database_pool_timeout: int = 30
157
+ database_pool_recycle: int = 30
158
+
159
+ hide_stack_trace: bool = False
160
+ max_failed_login_attempts: int = 5
161
+
162
+
163
+ model_config = SettingsConfigDict(
164
+ env_file=get_env_file(),
165
+ env_file_encoding="utf-8"
166
+ )
167
+
168
+ def load_config_files(self) -> None:
169
+ channels_config_file = Path(__file__).resolve().parent.parent / 'config/channels.json'
170
+ if channels_config_file.exists():
171
+ try:
172
+ with open(channels_config_file, 'r') as file:
173
+ self.channels = json.load(file)
174
+
175
+ # Compile the patterns for better performance
176
+ for idx, channel in enumerate(self.channels):
177
+ compiled_patterns: list[re.Pattern] = []
178
+ for pattern in channel.get("allowed_api_patterns", []):
179
+ compiled_patterns.append(re.compile(pattern))
180
+ self.channels[idx]["allowed_api_patterns"] = compiled_patterns
181
+
182
+ except Exception as e:
183
+ logger.error(f"Failed to open the channel config file at {channels_config_file}. Error: {e}")
184
+
185
+ raw_allowed_submit_models: str = Field(default="",alias="allowed_submit_models")
186
+
187
+ @property
188
+ def allowed_submit_models(self) -> dict[str, list[str]]:
189
+ allowed_models_str = self.raw_allowed_submit_models
190
+ result: dict = {}
191
+ if allowed_models_str:
192
+ entries = allowed_models_str.split(",")
193
+ for entry in entries:
194
+ entry = entry.strip()
195
+ if "." in entry:
196
+ space, schema = entry.split(".", 1)
197
+ if space not in result:
198
+ result[space] = []
199
+ result[space].append(schema)
200
+ return result
201
+
202
+ try:
203
+ Settings.model_validate(
204
+ Settings()
205
+ )
206
+ except Exception as e:
207
+ logger.error(f"Failed to load settings.\nError: {e}")
208
+ # sys.exit(1)
209
+ pass
210
+
211
+ settings = Settings()
212
+ settings.load_config_files()
@@ -0,0 +1,21 @@
1
+ from api.user.service import send_sms
2
+ from models.core import NotificationData
3
+ from utils.helpers import lang_code
4
+ from utils.notification import Notifier
5
+
6
+
7
+ class SMSNotifier(Notifier):
8
+
9
+ async def send(
10
+ self,
11
+ data: NotificationData
12
+ ) -> bool:
13
+ user_lang = lang_code(data.receiver.get("language", "ar"))
14
+ if "msisdn" not in data.receiver:
15
+ return False
16
+ await send_sms(
17
+ data.receiver["msisdn"],
18
+ data.title.__getattribute__(user_lang)
19
+ )
20
+ return True
21
+
@@ -0,0 +1,67 @@
1
+ from typing import Any, Optional
2
+ from fastapi_sso.sso.facebook import FacebookSSO
3
+ from fastapi_sso.sso.google import GoogleSSO
4
+ from httpx import AsyncClient
5
+ from utils.settings import settings
6
+ from fastapi_sso.sso.generic import create_provider
7
+ from fastapi_sso.sso.base import OpenID, SSOBase, DiscoveryDocument
8
+
9
+
10
+ FACEBOOK_CLIENT_ID = settings.facebook_client_id
11
+ FACEBOOK_CLIENT_SECRET = settings.facebook_client_secret
12
+
13
+
14
+ def get_facebook_sso() -> FacebookSSO:
15
+ return FacebookSSO(
16
+ FACEBOOK_CLIENT_ID,
17
+ FACEBOOK_CLIENT_SECRET,
18
+ redirect_uri=f"{settings.app_url}/user/facebook/callback",
19
+ )
20
+
21
+
22
+ GOOGLE_CLIENT_ID = settings.google_client_id
23
+ GOOGLE_CLIENT_SECRET = settings.google_client_secret
24
+
25
+
26
+ def get_google_sso() -> GoogleSSO:
27
+ return GoogleSSO(
28
+ GOOGLE_CLIENT_ID,
29
+ GOOGLE_CLIENT_SECRET,
30
+ redirect_uri=f"{settings.app_url}/user/google/callback",
31
+ )
32
+
33
+ # Apple SSO
34
+ APPLE_CLIENT_ID = settings.apple_client_id # Your Apple Services ID
35
+ APPLE_CLIENT_SECRET = settings.apple_client_secret
36
+
37
+ def apple_response_convertor(response: dict[str, Any], client: Optional[AsyncClient] = None) -> OpenID:
38
+ return OpenID(
39
+ id=response.get("sub"),
40
+ email=response.get("email"),
41
+ first_name=response.get("fullName", []).split(" ")[0],
42
+ last_name=response.get("fullName", []).split(" ")[-1],
43
+ picture=response.get("picture"),
44
+ provider="apple",
45
+ )
46
+
47
+ def get_apple_sso() -> SSOBase:
48
+ apple_discovery = DiscoveryDocument({
49
+ "authorization_endpoint":"https://appleid.apple.com/auth/authorize",
50
+ "token_endpoint":"https://appleid.apple.com/auth/token",
51
+ #"jwks_uri":"https://appleid.apple.com/auth/keys",
52
+ "userinfo_endpoint": "http://localhost:9090/me",
53
+
54
+ })
55
+ AppleProvider: type[SSOBase] = create_provider(
56
+ name="apple",
57
+ discovery_document=apple_discovery,
58
+ default_scope=["fullName", "email"],
59
+ response_convertor=apple_response_convertor
60
+ )
61
+
62
+ return AppleProvider(
63
+ client_id=APPLE_CLIENT_ID,
64
+ client_secret=APPLE_CLIENT_SECRET,
65
+ redirect_uri=f"{settings.app_url}/user/apple/callback",
66
+ allow_insecure_http=True
67
+ )
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <title>Email</title>
5
+ <meta charset="utf-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
8
+ </head>
9
+ <body style="margin: 0; padding: 0">
10
+
11
+ <p>Hi {{name}}</p>
12
+ <p>MSISDN: {{msisdn}}</p>
13
+ <p>Username: {{shortname}}</p>
14
+
15
+ <p>Welcome, we're happy to see you on board!</p>
16
+
17
+ <p>Only Few steps are left to activate your account, please use the below account activation link.</p>
18
+
19
+ <p>Activation Link:</p>
20
+
21
+ <a href="{{ link }}">{{ link }}</a>
22
+
23
+ <p>Regards,</p>
24
+
25
+ </body>
26
+ </html>
@@ -0,0 +1,17 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <title>Email</title>
5
+ <meta charset="utf-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
8
+ </head>
9
+ <body style="margin: 0; padding: 0">
10
+ <p>Hi {{ name }},</p>
11
+ <p>We would like to remind you to activate your account. We will be happy to see you on board!</p>
12
+ <p>Few steps are left to activate your account, please use the below account activation link.</p>
13
+ <p>Activation Link:</p>
14
+ {{ link }}
15
+ <p>Regards,</p>
16
+ </body>
17
+ </html>
@@ -0,0 +1,203 @@
1
+ import models.api as api
2
+ from fastapi import status
3
+ from data_adapters.adapter import data_adapter as db
4
+ import models.core as core
5
+ from utils.internal_error_code import InternalErrorCode
6
+ from utils.settings import settings
7
+ from typing import Any
8
+
9
+
10
+ async def get_init_state_from_workflow(space_name: str, workflow_shortname: str):
11
+ payload = await db.load_resource_payload(
12
+ space_name=space_name,
13
+ subpath="workflows",
14
+ filename=workflow_shortname,
15
+ class_type=core.Content,
16
+ )
17
+
18
+ if payload is None:
19
+ raise api.Exception(
20
+ status.HTTP_400_BAD_REQUEST,
21
+ api.Error(
22
+ type="request",
23
+ code=InternalErrorCode.SHORTNAME_ALREADY_EXIST,
24
+ message="Workflow not found",
25
+ ),
26
+ )
27
+
28
+ return payload['initial_state'][0]['name']
29
+
30
+ async def set_init_state_for_record(record: core.Record, space_name: str, logged_in_user: str):
31
+ workflow_attr = record.attributes
32
+ workflow_shortname = workflow_attr["workflow_shortname"]
33
+
34
+ _user_roles = await db.get_user_roles(logged_in_user)
35
+ user_roles = _user_roles.keys()
36
+
37
+ workflows_data: core.Content = await db.load(
38
+ space_name=space_name,
39
+ subpath="workflows",
40
+ shortname=workflow_shortname,
41
+ class_type=core.Content,
42
+ user_shortname=logged_in_user,
43
+ )
44
+
45
+ if workflows_data is not None and workflows_data.payload is not None:
46
+ workflows_payload: dict[str,Any]
47
+ if isinstance(workflows_data.payload.body, dict):
48
+ workflows_payload = workflows_data.payload.body
49
+ else:
50
+ payload = await db.load_resource_payload(
51
+ space_name=space_name,
52
+ subpath="workflows",
53
+ filename=str(workflows_data.payload.body),
54
+ class_type=core.Content,
55
+ )
56
+ workflows_payload = payload if payload else {}
57
+
58
+ initial_state = None
59
+
60
+ for state in workflows_payload["initial_state"]:
61
+ if initial_state is None and "default" in state["roles"]:
62
+ initial_state = state["name"]
63
+ elif [role in user_roles for role in state["roles"]].count(True):
64
+ initial_state = state["name"]
65
+ break
66
+
67
+ if initial_state is None:
68
+ raise api.Exception(
69
+ status.HTTP_400_BAD_REQUEST,
70
+ api.Error(
71
+ type="request",
72
+ code=InternalErrorCode.NOT_ALLOWED,
73
+ message="The user does not have the required roles to create this ticket",
74
+ ),
75
+ )
76
+
77
+ record.attributes = {
78
+ **workflow_attr,
79
+ "state": initial_state,
80
+ "is_open": True,
81
+ }
82
+ return record
83
+
84
+ raise api.Exception(
85
+ status.HTTP_400_BAD_REQUEST,
86
+ api.Error(
87
+ type="request",
88
+ code=InternalErrorCode.SHORTNAME_ALREADY_EXIST,
89
+ message="This shortname already exists",
90
+ ),
91
+ )
92
+
93
+
94
+ async def set_init_state_from_record(
95
+ ticket: core.Record, logged_in_user, space_name
96
+ ):
97
+ workflow_attr = ticket.attributes
98
+ workflow_shortname = workflow_attr["workflow_shortname"]
99
+
100
+ workflows_data = await db.load(
101
+ space_name=space_name,
102
+ subpath="workflows",
103
+ shortname=workflow_shortname,
104
+ class_type=core.Content,
105
+ user_shortname=logged_in_user,
106
+ )
107
+
108
+ if workflows_data is not None and workflows_data.payload is not None:
109
+ # file: fetch payload from file
110
+ # sql: payload is already within the entry
111
+ workflows_payload : dict[str, Any] = {}
112
+ mypayload = workflows_data.payload.body
113
+ if settings.active_data_db == "file" and isinstance(mypayload, str):
114
+ payload = await db.load_resource_payload(
115
+ space_name=space_name,
116
+ subpath="workflows",
117
+ filename=mypayload,
118
+ class_type=core.Content,
119
+ )
120
+ workflows_payload = payload if payload else {}
121
+ elif isinstance(mypayload, dict):
122
+ workflows_payload = mypayload
123
+ else:
124
+ raise api.Exception(
125
+ status.HTTP_500_INTERNAL_SERVER_ERROR,
126
+ api.Error(
127
+ type="request",
128
+ code=InternalErrorCode.INVALID_DATA,
129
+ message=f"Invalid payload data {mypayload}",
130
+ ),
131
+ )
132
+
133
+
134
+
135
+ ticket.attributes = {
136
+ **workflow_attr,
137
+ "state": workflows_payload["initial_state"],
138
+ }
139
+ return ticket
140
+
141
+ raise api.Exception(
142
+ status.HTTP_400_BAD_REQUEST,
143
+ api.Error(
144
+ type="request",
145
+ code=InternalErrorCode.SHORTNAME_ALREADY_EXIST,
146
+ message="This shortname already exists",
147
+ ),
148
+ )
149
+
150
+
151
+ def transite(states, current_state: str, action: str, user_roles):
152
+ for state in states:
153
+ if state["state"] == current_state:
154
+ for next_state in state["next"]:
155
+ if next_state["action"] == action:
156
+ for role in next_state["roles"]:
157
+ if role in user_roles:
158
+ return {"status": True, "message": next_state["state"]}
159
+ return {
160
+ "status": False,
161
+ "message": f"You don't have the permission to progress this ticket with action {action}",
162
+ }
163
+
164
+ return {
165
+ "status": False,
166
+ "message": f"You can't progress from {current_state} using {action}",
167
+ }
168
+
169
+
170
+ def post_transite(states, next_state: str, resolution: str):
171
+ for state in states:
172
+ if state["state"] == next_state:
173
+ if "resolutions" in state:
174
+ available_resolutions = [one for one in state["resolutions"]]
175
+ if len(available_resolutions) == 0:
176
+ return {
177
+ "status": False,
178
+ "message": f"The state {next_state} does not have any resolutions defined",
179
+ }
180
+ else:
181
+ if isinstance(available_resolutions[0], str):
182
+ if resolution in available_resolutions:
183
+ return {"status": True, "message": resolution}
184
+ else:
185
+ if resolution in [item['key'] for item in available_resolutions]:
186
+ return {"status": True, "message": resolution}
187
+
188
+ return {
189
+ "status": False,
190
+ "message": f"The resolution {resolution} provided is not acceptable in state {next_state}",
191
+ }
192
+ return {
193
+ "status": False,
194
+ "message": f"Cannot fetch the next state {next_state} with resolution {resolution}",
195
+ }
196
+
197
+
198
+ def check_open_state(states, current_state: str):
199
+ for state in states:
200
+ if state["state"] == current_state:
201
+ return "next" in state
202
+
203
+ return True
@@ -0,0 +1,29 @@
1
+ from models.core import NotificationData
2
+ from utils.async_request import AsyncRequest
3
+ from utils.notification import Notifier
4
+ from utils.helpers import lang_code
5
+ from utils.settings import settings
6
+
7
+
8
+
9
+
10
+ class WebNotifier(Notifier):
11
+
12
+ async def send(
13
+ self,
14
+ data: NotificationData
15
+ ) -> bool:
16
+ if not settings.websocket_url:
17
+ return False
18
+ user_lang = lang_code(data.receiver.get("language", "ar"))
19
+ async with AsyncRequest() as client:
20
+ await client.post(
21
+ f"{settings.websocket_url}/send-message/{data.receiver.get('shortname')}",
22
+ json={
23
+ "title": data.title.__getattribute__(user_lang),
24
+ "description": data.body.__getattribute__(user_lang),
25
+ }
26
+ )
27
+
28
+ return True
29
+