mage-ai 0.9.32__py3-none-any.whl → 0.9.34__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.
Potentially problematic release.
This version of mage-ai might be problematic. Click here for more details.
- mage_ai/api/constants.py +37 -2
- mage_ai/api/errors.py +9 -5
- mage_ai/api/middleware.py +2 -2
- mage_ai/api/mixins/__init__.py +0 -0
- mage_ai/api/mixins/result_set.py +65 -0
- mage_ai/api/operations/base.py +41 -11
- mage_ai/api/operations/constants.py +7 -6
- mage_ai/api/parsers/BaseParser.py +6 -4
- mage_ai/api/parsers/PipelineScheduleParser.py +36 -2
- mage_ai/api/policies/BackfillPolicy.py +1 -0
- mage_ai/api/policies/BasePolicy.py +229 -40
- mage_ai/api/policies/PermissionPolicy.py +17 -0
- mage_ai/api/policies/PipelineSchedulePolicy.py +18 -2
- mage_ai/api/policies/RolePermissionPolicy.py +2 -1
- mage_ai/api/policies/RolePolicy.py +3 -0
- mage_ai/api/policies/SessionPolicy.py +36 -1
- mage_ai/api/policies/StatusPolicy.py +46 -3
- mage_ai/api/policies/UserPolicy.py +25 -2
- mage_ai/api/policies/mixins/__init__.py +0 -0
- mage_ai/api/policies/mixins/user_permissions.py +241 -0
- mage_ai/api/presenters/PermissionPresenter.py +35 -8
- mage_ai/api/presenters/RolePresenter.py +29 -12
- mage_ai/api/presenters/StatusPresenter.py +11 -0
- mage_ai/api/presenters/UserPresenter.py +21 -24
- mage_ai/api/resources/BaseResource.py +24 -9
- mage_ai/api/resources/BlockResource.py +3 -2
- mage_ai/api/resources/DatabaseResource.py +2 -2
- mage_ai/api/resources/PermissionResource.py +65 -3
- mage_ai/api/resources/Resource.py +8 -1
- mage_ai/api/resources/RolePermissionResource.py +23 -0
- mage_ai/api/resources/RoleResource.py +75 -4
- mage_ai/api/resources/StatusResource.py +34 -0
- mage_ai/api/resources/UserResource.py +35 -4
- mage_ai/api/result_set.py +8 -1
- mage_ai/authentication/permissions/constants.py +78 -0
- mage_ai/data_integrations/destinations/constants.py +1 -0
- mage_ai/data_integrations/utils/config.py +9 -0
- mage_ai/data_integrations/utils/scheduler.py +16 -7
- mage_ai/data_preparation/models/block/__init__.py +56 -16
- mage_ai/data_preparation/models/block/data_integration/mixins.py +92 -1
- mage_ai/data_preparation/models/block/data_integration/utils.py +5 -5
- mage_ai/data_preparation/models/block/integration/__init__.py +12 -7
- mage_ai/data_preparation/models/block/sql/__init__.py +5 -2
- mage_ai/data_preparation/models/block/sql/utils/shared.py +15 -1
- mage_ai/data_preparation/models/pipelines/interactions.py +15 -0
- mage_ai/data_preparation/shared/secrets.py +7 -17
- mage_ai/data_preparation/templates/data_exporters/streaming/google_cloud_pubsub.yaml +5 -0
- mage_ai/data_preparation/templates/repo/metadata.yaml +5 -0
- mage_ai/io/druid.py +9 -5
- mage_ai/io/mssql.py +52 -30
- mage_ai/io/postgres.py +1 -0
- mage_ai/io/sql.py +15 -1
- mage_ai/orchestration/db/models/oauth.py +181 -17
- mage_ai/orchestration/db/models/schedules.py +11 -0
- mage_ai/presenters/interactions/constants.py +1 -0
- mage_ai/presenters/pages/loaders/pipeline_schedules.py +9 -3
- mage_ai/server/api/base.py +16 -6
- mage_ai/server/api/v1.py +2 -1
- mage_ai/server/constants.py +1 -1
- mage_ai/server/frontend_dist/404.html +2 -2
- mage_ai/server/frontend_dist/_next/static/PBVuphyo_muEAj347ZP_b/_buildManifest.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/1124-d8fc76201b83b376.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/{1749-9ec0f4709f5a9284.js → 1749-a6bdce4ee8a09bce.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/1769-613e23e361eb5bce.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/1821-953efd0da290d25f.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/2327-1a797c758f8b064a.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/2677-a85c5a72bb695304.js +1 -0
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/3419-6c8ec8db8c398c12.js → frontend_dist/_next/static/chunks/3419-0df6c5ef72f2e672.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/3684-e1a713b7c16f0151.js +1 -0
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/3859-3501cdba0a33f9f2.js → frontend_dist/_next/static/chunks/3859-ba594d21a1260cd2.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/4636-84f545d1d238df13.js +1 -0
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/4839-963da65cea58054f.js → frontend_dist/_next/static/chunks/4839-e5fe343a369734bc.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/5457-97433bc45b42a88a.js +1 -0
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/5499-63667ad5a785dba5.js → frontend_dist/_next/static/chunks/5499-b74459f6be5f9229.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/6043-6ea109833b88eb1d.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/6333-ca4cd6a73a597a40.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/7022-80d082a1d7fd1234.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/7361-25f211ef377e5958.js +1 -0
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/8013-1d6b1f7c13264cb4.js → frontend_dist/_next/static/chunks/8013-e67c71ddea072a20.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/8146-941c5155c3bfcc35.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/9161-837b653aa849a76f.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/9264-5730e4e059db40a8.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-752d991f239a128f.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/{block-layout-a624972d126a3dbd.js → block-layout-a27a28d2a615e364.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/files-98e27a4d7bd0da47.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/global-data-products/{[...slug]-a95787fe1695f493.js → [...slug]-9eb5dad57da13efd.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/{global-data-products-0d55711df91a78d0.js → global-data-products-26909dec66f00231.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/settings-b9eea6abc676ca81.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/[user]-11c601c6ef07fe86.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/new-ae6083077c9c1c41.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users-bfce0ee677d57206.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-476c921d62f565fc.js +1 -0
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/overview-9bc34ef66d84330a.js → frontend_dist/_next/static/chunks/pages/overview-2ec6b17e45a52be8.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipeline-runs-605918f3a5c1aac4.js +1 -0
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-84ec3ab0770bcd68.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-ee65a62ed166bd85.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-2402004a19a6ad53.js +1 -0
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-9a5b4768a640cd68.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-8781db69f19759a1.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-d7fd4857579e2b00.js +1 -0
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/logs-bd4bd009146bab36.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/logs-234007c99efdccf6.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/{block-runs-8405a83adeaa8ff5.js → block-runs-da7510d4b277e47b.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/monitors/{block-runtime-98aa0840a00cc661.js → block-runtime-eae853ff34b09481.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/{monitors-0fb48e1cc51f78b2.js → monitors-a057b17847b82468.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs/{[run]-845c1f010d5ec380.js → [run]-99d11c86f8b15369.js} +1 -1
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs-9255f85760e1f57a.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs-3f0980d8810a540b.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/{settings-187ac359020704e1.js → settings-9edf75d03460aaeb.js} +1 -1
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/syncs-c52d0c49439ec620.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/syncs-e7692e54979f037d.js} +1 -1
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-7b3b57523b226a0e.js → frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-cb6a3bcaf4fa1a81.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers-5eff96c149584e87.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/{pipelines-efc080913a247e99.js → pipelines-270b912e1ac189b5.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/account/profile-2058d022972cdea4.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/permissions/[...slug]-1a95628ea8d0d846.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/permissions-cb1cdf5f8e5bf9c5.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-58978256db4efbda.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles/[...slug]-9ddd7eb842d5a911.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/roles-1694c5eb1acbcf30.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-6850e854fbedbb61.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users/[...slug]-5061c073e1c0de07.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users-f551c5665bfd3494.js +1 -0
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/sign-in-6fe3657070f98aca.js → frontend_dist/_next/static/chunks/pages/sign-in-e779dbab123e626e.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/templates/[...slug]-935113d252ada806.js +1 -0
- mage_ai/server/{frontend_dist_base_path_template/_next/static/chunks/pages/templates-25b6d24cfa81c306.js → frontend_dist/_next/static/chunks/pages/templates-7079d637e396f2a8.js} +1 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/terminal-67fdb4a3be93aa14.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/triggers-9c0374c7c783b34a.js +1 -0
- mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-ea3a0d48e5822b42.js +1 -0
- mage_ai/server/frontend_dist/block-layout.html +2 -2
- mage_ai/server/frontend_dist/files.html +2 -2
- mage_ai/server/frontend_dist/global-data-products/[...slug].html +2 -2
- mage_ai/server/frontend_dist/global-data-products.html +2 -2
- mage_ai/server/frontend_dist/index.html +2 -2
- mage_ai/server/frontend_dist/manage/settings.html +2 -2
- mage_ai/server/frontend_dist/manage/users/[user].html +2 -2
- mage_ai/server/frontend_dist/manage/users/new.html +2 -2
- mage_ai/server/frontend_dist/manage/users.html +2 -2
- mage_ai/server/frontend_dist/manage.html +2 -2
- mage_ai/server/frontend_dist/overview.html +2 -2
- mage_ai/server/frontend_dist/pipeline-runs.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills/[...slug].html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/backfills.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/dashboard.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/edit.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/logs.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runs.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors/block-runtime.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/monitors.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/runs/[run].html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/runs.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/settings.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/syncs.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers/[...slug].html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline]/triggers.html +2 -2
- mage_ai/server/frontend_dist/pipelines/[pipeline].html +2 -2
- mage_ai/server/frontend_dist/pipelines.html +2 -2
- mage_ai/server/frontend_dist/settings/account/profile.html +2 -2
- mage_ai/server/frontend_dist/settings/workspace/permissions/[...slug].html +24 -0
- mage_ai/server/frontend_dist/settings/workspace/permissions.html +24 -0
- mage_ai/server/frontend_dist/settings/workspace/preferences.html +2 -2
- mage_ai/server/frontend_dist/settings/workspace/roles/[...slug].html +24 -0
- mage_ai/server/frontend_dist/settings/workspace/roles.html +24 -0
- mage_ai/server/frontend_dist/settings/workspace/sync-data.html +2 -2
- mage_ai/server/frontend_dist/settings/workspace/users/[...slug].html +24 -0
- mage_ai/server/frontend_dist/settings/workspace/users.html +2 -2
- mage_ai/server/frontend_dist/settings.html +2 -2
- mage_ai/server/frontend_dist/sign-in.html +5 -5
- mage_ai/server/frontend_dist/templates/[...slug].html +2 -2
- mage_ai/server/frontend_dist/templates.html +2 -2
- mage_ai/server/frontend_dist/terminal.html +2 -2
- mage_ai/server/frontend_dist/test.html +2 -2
- mage_ai/server/frontend_dist/triggers.html +2 -2
- mage_ai/server/frontend_dist/version-control.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/404.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/_next/static/L-IKw5_bRZUs-wyjnpN_j/_buildManifest.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1124-d8fc76201b83b376.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/{1749-9ec0f4709f5a9284.js → 1749-a6bdce4ee8a09bce.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1769-613e23e361eb5bce.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1821-953efd0da290d25f.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2327-1a797c758f8b064a.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2677-a85c5a72bb695304.js +1 -0
- mage_ai/server/{frontend_dist/_next/static/chunks/3419-6c8ec8db8c398c12.js → frontend_dist_base_path_template/_next/static/chunks/3419-0df6c5ef72f2e672.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/3684-e1a713b7c16f0151.js +1 -0
- mage_ai/server/{frontend_dist/_next/static/chunks/3859-3501cdba0a33f9f2.js → frontend_dist_base_path_template/_next/static/chunks/3859-ba594d21a1260cd2.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/4636-84f545d1d238df13.js +1 -0
- mage_ai/server/{frontend_dist/_next/static/chunks/4839-963da65cea58054f.js → frontend_dist_base_path_template/_next/static/chunks/4839-e5fe343a369734bc.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5457-97433bc45b42a88a.js +1 -0
- mage_ai/server/{frontend_dist/_next/static/chunks/5499-63667ad5a785dba5.js → frontend_dist_base_path_template/_next/static/chunks/5499-b74459f6be5f9229.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6043-6ea109833b88eb1d.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6333-ca4cd6a73a597a40.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7022-80d082a1d7fd1234.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/7361-25f211ef377e5958.js +1 -0
- mage_ai/server/{frontend_dist/_next/static/chunks/8013-1d6b1f7c13264cb4.js → frontend_dist_base_path_template/_next/static/chunks/8013-e67c71ddea072a20.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/8146-941c5155c3bfcc35.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9161-837b653aa849a76f.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9264-5730e4e059db40a8.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-752d991f239a128f.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{block-layout-a624972d126a3dbd.js → block-layout-a27a28d2a615e364.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/files-98e27a4d7bd0da47.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/global-data-products/{[...slug]-a95787fe1695f493.js → [...slug]-9eb5dad57da13efd.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{global-data-products-0d55711df91a78d0.js → global-data-products-26909dec66f00231.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/settings-b9eea6abc676ca81.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/[user]-11c601c6ef07fe86.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/new-ae6083077c9c1c41.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users-bfce0ee677d57206.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-476c921d62f565fc.js +1 -0
- mage_ai/server/{frontend_dist/_next/static/chunks/pages/overview-9bc34ef66d84330a.js → frontend_dist_base_path_template/_next/static/chunks/pages/overview-2ec6b17e45a52be8.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipeline-runs-605918f3a5c1aac4.js +1 -0
- mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-84ec3ab0770bcd68.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills/[...slug]-ee65a62ed166bd85.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-2402004a19a6ad53.js +1 -0
- mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-9a5b4768a640cd68.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/dashboard-8781db69f19759a1.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-d7fd4857579e2b00.js +1 -0
- mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/logs-bd4bd009146bab36.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/logs-234007c99efdccf6.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/{block-runs-8405a83adeaa8ff5.js → block-runs-da7510d4b277e47b.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/monitors/{block-runtime-98aa0840a00cc661.js → block-runtime-eae853ff34b09481.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/{monitors-0fb48e1cc51f78b2.js → monitors-a057b17847b82468.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs/{[run]-845c1f010d5ec380.js → [run]-99d11c86f8b15369.js} +1 -1
- mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/runs-9255f85760e1f57a.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/runs-3f0980d8810a540b.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/{settings-187ac359020704e1.js → settings-9edf75d03460aaeb.js} +1 -1
- mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/syncs-c52d0c49439ec620.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/syncs-e7692e54979f037d.js} +1 -1
- mage_ai/server/{frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-7b3b57523b226a0e.js → frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers/[...slug]-cb6a3bcaf4fa1a81.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers-5eff96c149584e87.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/{pipelines-efc080913a247e99.js → pipelines-270b912e1ac189b5.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/profile-2058d022972cdea4.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/permissions/[...slug]-1a95628ea8d0d846.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/permissions-cb1cdf5f8e5bf9c5.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-58978256db4efbda.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles/[...slug]-9ddd7eb842d5a911.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/roles-1694c5eb1acbcf30.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-6850e854fbedbb61.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users/[...slug]-5061c073e1c0de07.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users-f551c5665bfd3494.js +1 -0
- mage_ai/server/{frontend_dist/_next/static/chunks/pages/sign-in-6fe3657070f98aca.js → frontend_dist_base_path_template/_next/static/chunks/pages/sign-in-e779dbab123e626e.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/templates/[...slug]-935113d252ada806.js +1 -0
- mage_ai/server/{frontend_dist/_next/static/chunks/pages/templates-25b6d24cfa81c306.js → frontend_dist_base_path_template/_next/static/chunks/pages/templates-7079d637e396f2a8.js} +1 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/terminal-67fdb4a3be93aa14.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/triggers-9c0374c7c783b34a.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-ea3a0d48e5822b42.js +1 -0
- mage_ai/server/frontend_dist_base_path_template/block-layout.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/files.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/global-data-products/[...slug].html +5 -5
- mage_ai/server/frontend_dist_base_path_template/global-data-products.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/index.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/manage/settings.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/manage/users/[user].html +5 -5
- mage_ai/server/frontend_dist_base_path_template/manage/users/new.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/manage/users.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/manage.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/overview.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/pipeline-runs.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills/[...slug].html +5 -5
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/backfills.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/dashboard.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/edit.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/logs.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runs.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors/block-runtime.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/monitors.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs/[run].html +5 -5
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/runs.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/settings.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/syncs.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers/[...slug].html +5 -5
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline]/triggers.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/pipelines/[pipeline].html +2 -2
- mage_ai/server/frontend_dist_base_path_template/pipelines.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/settings/account/profile.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions/[...slug].html +24 -0
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/permissions.html +24 -0
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/preferences.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles/[...slug].html +24 -0
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/roles.html +24 -0
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/sync-data.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/users/[...slug].html +24 -0
- mage_ai/server/frontend_dist_base_path_template/settings/workspace/users.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/settings.html +2 -2
- mage_ai/server/frontend_dist_base_path_template/sign-in.html +13 -13
- mage_ai/server/frontend_dist_base_path_template/templates/[...slug].html +5 -5
- mage_ai/server/frontend_dist_base_path_template/templates.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/terminal.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/test.html +4 -4
- mage_ai/server/frontend_dist_base_path_template/triggers.html +5 -5
- mage_ai/server/frontend_dist_base_path_template/version-control.html +5 -5
- mage_ai/server/server.py +37 -2
- mage_ai/services/aws/__init__.py +19 -8
- mage_ai/services/spark/config.py +5 -1
- mage_ai/services/spark/spark.py +5 -4
- mage_ai/settings/__init__.py +2 -0
- mage_ai/streaming/constants.py +1 -0
- mage_ai/streaming/sinks/google_cloud_pubsub.py +66 -0
- mage_ai/streaming/sinks/sink_factory.py +6 -0
- mage_ai/tests/api/operations/test_operations.py +8 -2
- mage_ai/tests/api/operations/test_pipeline_schedules.py +3 -0
- mage_ai/tests/data_preparation/models/block/sql/utils/test_shared.py +130 -5
- mage_ai/tests/factory.py +2 -0
- mage_ai/tests/orchestration/test_pipeline_scheduler.py +20 -3
- mage_ai/tests/streaming/sinks/test_google_cloud_pubsub.py +28 -0
- mage_ai/usage_statistics/logger.py +4 -1
- {mage_ai-0.9.32.dist-info → mage_ai-0.9.34.dist-info}/METADATA +1 -1
- {mage_ai-0.9.32.dist-info → mage_ai-0.9.34.dist-info}/RECORD +302 -268
- mage_ai/api/policies/utils.py +0 -14
- mage_ai/server/frontend_dist/_next/static/cbN7L4Ms6UUPoANozEh9w/_buildManifest.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/1769-e2efd4df8d09481f.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/2327-2d8a1555605cf4af.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/2369-cb9cd97052e18d27.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/2677-aea54e655c4a727f.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/5457-994e1044953f1425.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/5597-c034402ee26af3b4.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/6333-d1f8db4e7d9656a5.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/6648-9bd31397f1d1b551.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/9161-0101571a3635a938.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/9264-7c4fcfed1200046a.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/9696-3e8ab7786f0e3a0e.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/_app-976b488b8aea327f.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/files-1a6c6654bfc953ac.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/settings-49004d918b04c866.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/[user]-97177740fbb6eb9f.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users/new-5b6411c9eb8c4ba4.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage/users-0a7a746cc0998608.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/manage-606012a580245001.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipeline-runs-0801de3c9a2976ea.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/backfills-0a5865d4cf012127.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/edit-87b1a0601c4236cd.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/pipelines/[pipeline]/triggers-77ffaa2d721a0a4e.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/account/profile-4e72d40881ac0605.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/preferences-8da8f8e2fdb1c99f.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/sync-data-be029347e99fcea2.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/settings/workspace/users-d4b07df78b3d6037.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/templates/[...slug]-87c492e9edc6064e.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/terminal-2ab9f3d0c50cce81.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/triggers-0ba40243a030ddf4.js +0 -1
- mage_ai/server/frontend_dist/_next/static/chunks/pages/version-control-28a3a43d65074394.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/1769-e2efd4df8d09481f.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2327-2d8a1555605cf4af.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2369-cb9cd97052e18d27.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/2677-aea54e655c4a727f.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5457-994e1044953f1425.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/5597-c034402ee26af3b4.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6333-d1f8db4e7d9656a5.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/6648-9bd31397f1d1b551.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9161-0101571a3635a938.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9264-7c4fcfed1200046a.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/9696-3e8ab7786f0e3a0e.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/_app-976b488b8aea327f.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/files-1a6c6654bfc953ac.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/settings-49004d918b04c866.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/[user]-97177740fbb6eb9f.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users/new-5b6411c9eb8c4ba4.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage/users-0a7a746cc0998608.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/manage-606012a580245001.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipeline-runs-0801de3c9a2976ea.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/backfills-0a5865d4cf012127.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/edit-87b1a0601c4236cd.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/pipelines/[pipeline]/triggers-77ffaa2d721a0a4e.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/account/profile-4e72d40881ac0605.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/preferences-8da8f8e2fdb1c99f.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/sync-data-be029347e99fcea2.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/settings/workspace/users-d4b07df78b3d6037.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/templates/[...slug]-87c492e9edc6064e.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/terminal-2ab9f3d0c50cce81.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/triggers-0ba40243a030ddf4.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/chunks/pages/version-control-28a3a43d65074394.js +0 -1
- mage_ai/server/frontend_dist_base_path_template/_next/static/o_Yc57jh8Te2SI-VoipGQ/_buildManifest.js +0 -1
- /mage_ai/server/frontend_dist/_next/static/{cbN7L4Ms6UUPoANozEh9w → PBVuphyo_muEAj347ZP_b}/_ssgManifest.js +0 -0
- /mage_ai/server/frontend_dist_base_path_template/_next/static/{o_Yc57jh8Te2SI-VoipGQ → L-IKw5_bRZUs-wyjnpN_j}/_ssgManifest.js +0 -0
- {mage_ai-0.9.32.dist-info → mage_ai-0.9.34.dist-info}/LICENSE +0 -0
- {mage_ai-0.9.32.dist-info → mage_ai-0.9.34.dist-info}/WHEEL +0 -0
- {mage_ai-0.9.32.dist-info → mage_ai-0.9.34.dist-info}/entry_points.txt +0 -0
- {mage_ai-0.9.32.dist-info → mage_ai-0.9.34.dist-info}/top_level.txt +0 -0
mage_ai/api/constants.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
from mage_ai.api.operations.constants import OperationType
|
|
4
|
+
from mage_ai.orchestration.db.models.oauth import Permission
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class AttributeOperationType(str, Enum):
|
|
8
|
+
QUERY = 'query'
|
|
8
9
|
READ = 'read'
|
|
9
10
|
WRITE = 'write'
|
|
10
11
|
|
|
@@ -17,3 +18,37 @@ class AuthorizeStatusType(str, Enum):
|
|
|
17
18
|
ALL = 'all'
|
|
18
19
|
FAILED = 'failed'
|
|
19
20
|
SUCCEEDED = 'succeeded'
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
OPERATION_TYPE_TO_ACCESS_MAPPING = {
|
|
24
|
+
OperationType.ALL: Permission.Access.OPERATION_ALL,
|
|
25
|
+
OperationType.CREATE: Permission.Access.CREATE,
|
|
26
|
+
OperationType.DELETE: Permission.Access.DELETE,
|
|
27
|
+
OperationType.DETAIL: Permission.Access.DETAIL,
|
|
28
|
+
OperationType.LIST: Permission.Access.LIST,
|
|
29
|
+
OperationType.UPDATE: Permission.Access.UPDATE,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
OPERATION_TYPE_DISABLE_TO_ACCESS_MAPPING = {
|
|
33
|
+
OperationType.ALL: Permission.Access.DISABLE_OPERATION_ALL,
|
|
34
|
+
OperationType.CREATE: Permission.Access.DISABLE_CREATE,
|
|
35
|
+
OperationType.DELETE: Permission.Access.DISABLE_DELETE,
|
|
36
|
+
OperationType.DETAIL: Permission.Access.DISABLE_DETAIL,
|
|
37
|
+
OperationType.LIST: Permission.Access.DISABLE_LIST,
|
|
38
|
+
OperationType.UPDATE: Permission.Access.DISABLE_UPDATE,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
ATTRIBUTE_OPERATION_TYPE_TO_ACCESS_MAPPING = {
|
|
42
|
+
AttributeOperationType.QUERY: Permission.Access.QUERY,
|
|
43
|
+
AttributeOperationType.READ: Permission.Access.READ,
|
|
44
|
+
AttributeOperationType.WRITE: Permission.Access.WRITE,
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
ATTRIBUTE_OPERATION_TYPE_DISABLE_TO_ACCESS_MAPPING = {
|
|
48
|
+
AttributeOperationType.QUERY: Permission.Access.DISABLE_QUERY,
|
|
49
|
+
AttributeOperationType.READ: Permission.Access.DISABLE_READ,
|
|
50
|
+
AttributeOperationType.WRITE: Permission.Access.DISABLE_WRITE,
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
META_KEY_LIMIT = '_limit'
|
|
54
|
+
META_KEY_OFFSET = '_offset'
|
mage_ai/api/errors.py
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
from typing import Dict
|
|
2
|
+
|
|
3
|
+
|
|
1
4
|
class ApiError(Exception):
|
|
2
5
|
UNAUTHORIZED_ACCESS = {
|
|
3
6
|
'code': 403,
|
|
@@ -37,8 +40,9 @@ class ApiError(Exception):
|
|
|
37
40
|
'type': 'invalid_oauth_token',
|
|
38
41
|
}
|
|
39
42
|
|
|
40
|
-
def __init__(self, opts=
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
def __init__(self, opts: Dict = None):
|
|
44
|
+
if opts:
|
|
45
|
+
self.code = opts.get('code')
|
|
46
|
+
self.errors = opts.get('errors')
|
|
47
|
+
self.message = opts.get('message')
|
|
48
|
+
self.type = opts.get('type')
|
mage_ai/api/middleware.py
CHANGED
|
@@ -18,8 +18,8 @@ from mage_ai.shared.array import find
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class OAuthMiddleware(RequestHandler):
|
|
21
|
-
def initialize(self,
|
|
22
|
-
self.bypass_oauth_check = bypass_oauth_check
|
|
21
|
+
def initialize(self, **kwargs) -> None:
|
|
22
|
+
self.bypass_oauth_check = kwargs.get('bypass_oauth_check', False)
|
|
23
23
|
|
|
24
24
|
def prepare(self):
|
|
25
25
|
self.request.__setattr__('current_user', None)
|
|
File without changes
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
|
|
3
|
+
from mage_ai.orchestration.db import safe_db_query
|
|
4
|
+
from mage_ai.orchestration.db.models.oauth import (
|
|
5
|
+
Permission,
|
|
6
|
+
Role,
|
|
7
|
+
RolePermission,
|
|
8
|
+
UserRole,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
CONTEXT_DATA_KEY_USER_PERMISSIONS = '__user_permissions'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ResultSetMixIn:
|
|
15
|
+
@safe_db_query
|
|
16
|
+
async def load_and_cache_user_permissions(self) -> List[Permission]:
|
|
17
|
+
# This will fetch the user permissions and store it on the context data
|
|
18
|
+
# so that repeat policy user permission validations won’t keep querying the
|
|
19
|
+
# database for permissions.
|
|
20
|
+
if not self.current_user:
|
|
21
|
+
return
|
|
22
|
+
|
|
23
|
+
permissions = self.result_set().context.data.get(CONTEXT_DATA_KEY_USER_PERMISSIONS)
|
|
24
|
+
if permissions:
|
|
25
|
+
return permissions
|
|
26
|
+
|
|
27
|
+
query = (
|
|
28
|
+
Permission.
|
|
29
|
+
select(
|
|
30
|
+
Permission.access,
|
|
31
|
+
Permission.entity,
|
|
32
|
+
Permission.entity_id,
|
|
33
|
+
Permission.entity_name,
|
|
34
|
+
Permission.entity_type,
|
|
35
|
+
Permission.id,
|
|
36
|
+
Permission.options,
|
|
37
|
+
).
|
|
38
|
+
join(
|
|
39
|
+
RolePermission,
|
|
40
|
+
RolePermission.permission_id == Permission.id).
|
|
41
|
+
join(
|
|
42
|
+
Role,
|
|
43
|
+
Role.id == RolePermission.role_id).
|
|
44
|
+
join(
|
|
45
|
+
UserRole,
|
|
46
|
+
UserRole.role_id == Role.id).
|
|
47
|
+
filter(UserRole.user_id == self.current_user.id)
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
permissions = []
|
|
51
|
+
|
|
52
|
+
for row in query.all():
|
|
53
|
+
permission = Permission()
|
|
54
|
+
permission.access = row.access
|
|
55
|
+
permission.entity = row.entity
|
|
56
|
+
permission.entity_id = row.entity_id
|
|
57
|
+
permission.entity_name = row.entity_name
|
|
58
|
+
permission.entity_type = row.entity_type
|
|
59
|
+
permission.id = row.id
|
|
60
|
+
permission.options = row.options
|
|
61
|
+
permissions.append(permission)
|
|
62
|
+
|
|
63
|
+
self.result_set().context.data[CONTEXT_DATA_KEY_USER_PERMISSIONS] = permissions
|
|
64
|
+
|
|
65
|
+
return permissions
|
mage_ai/api/operations/base.py
CHANGED
|
@@ -27,6 +27,7 @@ from mage_ai.api.parsers.BaseParser import BaseParser
|
|
|
27
27
|
from mage_ai.api.presenters.BasePresenter import CustomDict, CustomList
|
|
28
28
|
from mage_ai.api.result_set import ResultSet
|
|
29
29
|
from mage_ai.orchestration.db.errors import DoesNotExistError
|
|
30
|
+
from mage_ai.settings import REQUIRE_USER_PERMISSIONS
|
|
30
31
|
from mage_ai.shared.array import flatten
|
|
31
32
|
from mage_ai.shared.hash import ignore_keys, merge_dict
|
|
32
33
|
from mage_ai.shared.strings import classify
|
|
@@ -170,9 +171,13 @@ class BaseOperation():
|
|
|
170
171
|
}
|
|
171
172
|
except ApiError as err:
|
|
172
173
|
if err.code == 403 and \
|
|
173
|
-
self.user and
|
|
174
|
-
|
|
175
|
-
|
|
174
|
+
self.user and \
|
|
175
|
+
self.user.project_access == 0 and \
|
|
176
|
+
not self.user.roles:
|
|
177
|
+
|
|
178
|
+
if not REQUIRE_USER_PERMISSIONS:
|
|
179
|
+
err.message = 'You don’t have access to this project. ' + \
|
|
180
|
+
'Please ask an admin or owner for permissions.'
|
|
176
181
|
if settings.DEBUG:
|
|
177
182
|
raise err
|
|
178
183
|
else:
|
|
@@ -255,11 +260,19 @@ class BaseOperation():
|
|
|
255
260
|
return await self.__resource_class().process_create(
|
|
256
261
|
payload,
|
|
257
262
|
self.user,
|
|
263
|
+
result_set_from_external=policy.result_set(),
|
|
258
264
|
**options,
|
|
259
265
|
)
|
|
260
266
|
elif LIST == self.action:
|
|
261
|
-
def _build_authorize_query(
|
|
262
|
-
|
|
267
|
+
def _build_authorize_query(
|
|
268
|
+
parsed_value: Any,
|
|
269
|
+
policy=policy,
|
|
270
|
+
updated_options=updated_options,
|
|
271
|
+
**_kwargs,
|
|
272
|
+
) -> Callable:
|
|
273
|
+
return policy.authorize_query(parsed_value, **ignore_keys(updated_options, [
|
|
274
|
+
'query',
|
|
275
|
+
]))
|
|
263
276
|
|
|
264
277
|
if parser:
|
|
265
278
|
value_parsed, parser_found, error = await parser.parse_query_and_authorize(
|
|
@@ -279,6 +292,7 @@ class BaseOperation():
|
|
|
279
292
|
self.query,
|
|
280
293
|
self.meta,
|
|
281
294
|
self.user,
|
|
295
|
+
result_set_from_external=policy.result_set(),
|
|
282
296
|
**options,
|
|
283
297
|
)
|
|
284
298
|
|
|
@@ -307,8 +321,15 @@ class BaseOperation():
|
|
|
307
321
|
if DELETE == self.action:
|
|
308
322
|
await res.process_delete(**updated_options)
|
|
309
323
|
elif DETAIL == self.action:
|
|
310
|
-
def _build_authorize_query(
|
|
311
|
-
|
|
324
|
+
def _build_authorize_query(
|
|
325
|
+
parsed_value: Any,
|
|
326
|
+
policy=policy,
|
|
327
|
+
updated_options=updated_options,
|
|
328
|
+
**_kwargs,
|
|
329
|
+
) -> Callable:
|
|
330
|
+
return policy.authorize_query(parsed_value, **ignore_keys(updated_options, [
|
|
331
|
+
'query',
|
|
332
|
+
]))
|
|
312
333
|
|
|
313
334
|
if parser:
|
|
314
335
|
value_parsed, parser_found, error = await parser.parse_query_and_authorize(
|
|
@@ -327,7 +348,9 @@ class BaseOperation():
|
|
|
327
348
|
**merge_dict(updated_options, dict(query=self.query)),
|
|
328
349
|
)
|
|
329
350
|
policy = self.__policy_class()(res, self.user, **updated_options)
|
|
330
|
-
await policy.authorize_query(self.query
|
|
351
|
+
await policy.authorize_query(self.query, **ignore_keys(updated_options, [
|
|
352
|
+
'query',
|
|
353
|
+
]))
|
|
331
354
|
else:
|
|
332
355
|
raise error
|
|
333
356
|
else:
|
|
@@ -351,8 +374,15 @@ class BaseOperation():
|
|
|
351
374
|
else:
|
|
352
375
|
await _build_authorize_attributes(payload)
|
|
353
376
|
|
|
354
|
-
def _build_authorize_query(
|
|
355
|
-
|
|
377
|
+
def _build_authorize_query(
|
|
378
|
+
parsed_value: Any,
|
|
379
|
+
policy=policy,
|
|
380
|
+
updated_options=updated_options,
|
|
381
|
+
**_kwargs,
|
|
382
|
+
) -> Callable:
|
|
383
|
+
return policy.authorize_query(parsed_value, **ignore_keys(updated_options, [
|
|
384
|
+
'query',
|
|
385
|
+
]))
|
|
356
386
|
|
|
357
387
|
if parser:
|
|
358
388
|
value_parsed, parser_found, error = await parser.parse_query_and_authorize(
|
|
@@ -362,7 +392,7 @@ class BaseOperation():
|
|
|
362
392
|
)
|
|
363
393
|
self.query = value_parsed
|
|
364
394
|
else:
|
|
365
|
-
await _build_authorize_query(self.query)
|
|
395
|
+
await _build_authorize_query(self.query, **updated_options)
|
|
366
396
|
|
|
367
397
|
options = merge_dict(updated_options.copy(), dict(query=self.query))
|
|
368
398
|
options.pop('payload', None)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
2
|
|
|
3
|
+
ALL = 'all'
|
|
3
4
|
CREATE = 'create'
|
|
4
5
|
DELETE = 'delete'
|
|
5
6
|
DETAIL = 'detail'
|
|
@@ -19,9 +20,9 @@ COOKIE_PREFIX = '__COOKIE__'
|
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
class OperationType(str, Enum):
|
|
22
|
-
ALL =
|
|
23
|
-
CREATE =
|
|
24
|
-
DELETE =
|
|
25
|
-
DETAIL =
|
|
26
|
-
LIST =
|
|
27
|
-
UPDATE =
|
|
23
|
+
ALL = ALL
|
|
24
|
+
CREATE = CREATE
|
|
25
|
+
DELETE = DELETE
|
|
26
|
+
DETAIL = DETAIL
|
|
27
|
+
LIST = LIST
|
|
28
|
+
UPDATE = UPDATE
|
|
@@ -53,7 +53,7 @@ class BaseParser:
|
|
|
53
53
|
@classmethod
|
|
54
54
|
def parse_query(
|
|
55
55
|
self,
|
|
56
|
-
parser: Callable[['BaseParser', Any, Dict], Any],
|
|
56
|
+
parser: Callable[['BaseParser', Any, Union[ApiError], Dict], Any],
|
|
57
57
|
on_action: Union[List[OperationType], OperationType] = None,
|
|
58
58
|
on_authorize_status: Union[List[AuthorizeStatusType], AuthorizeStatusType] = None,
|
|
59
59
|
scopes: List[OauthScopeType] = None,
|
|
@@ -83,7 +83,7 @@ class BaseParser:
|
|
|
83
83
|
@classmethod
|
|
84
84
|
def parse_read(
|
|
85
85
|
self,
|
|
86
|
-
parser: Callable[['BaseParser', Any, Dict], Any],
|
|
86
|
+
parser: Callable[['BaseParser', Any, Union[ApiError, Dict]], Any],
|
|
87
87
|
on_action: Union[List[OperationType], OperationType] = None,
|
|
88
88
|
on_authorize_status: Union[List[AuthorizeStatusType], AuthorizeStatusType] = None,
|
|
89
89
|
scopes: List[OauthScopeType] = None,
|
|
@@ -113,7 +113,7 @@ class BaseParser:
|
|
|
113
113
|
@classmethod
|
|
114
114
|
def parse_write(
|
|
115
115
|
self,
|
|
116
|
-
parser: Callable[['BaseParser', Any, Dict], Any],
|
|
116
|
+
parser: Callable[['BaseParser', Any, Union[ApiError, Dict]], Any],
|
|
117
117
|
on_action: Union[List[OperationType], OperationType] = None,
|
|
118
118
|
on_authorize_status: Union[List[AuthorizeStatusType], AuthorizeStatusType] = None,
|
|
119
119
|
scopes: List[OauthScopeType] = None,
|
|
@@ -161,6 +161,7 @@ class BaseParser:
|
|
|
161
161
|
self.query_parsers.get(self.__class__.__name__) or {},
|
|
162
162
|
value,
|
|
163
163
|
authorize_status,
|
|
164
|
+
error=error,
|
|
164
165
|
**kwargs,
|
|
165
166
|
)
|
|
166
167
|
|
|
@@ -242,6 +243,7 @@ class BaseParser:
|
|
|
242
243
|
parser_mapping: Dict,
|
|
243
244
|
value: Any,
|
|
244
245
|
authorize_status: AuthorizeStatusType,
|
|
246
|
+
error: ApiError = None,
|
|
245
247
|
**kwargs,
|
|
246
248
|
) -> Tuple[Any, bool]:
|
|
247
249
|
api_operation_action = self.options.get('api_operation_action') or \
|
|
@@ -262,7 +264,7 @@ class BaseParser:
|
|
|
262
264
|
if not parser:
|
|
263
265
|
return value, False
|
|
264
266
|
|
|
265
|
-
value_parsed = parser(self, value, **kwargs)
|
|
267
|
+
value_parsed = parser(self, value, authorize_status=authorize_status, error=error, **kwargs)
|
|
266
268
|
|
|
267
269
|
if value_parsed and inspect.isawaitable(value_parsed):
|
|
268
270
|
value_parsed = await value_parsed
|
|
@@ -8,6 +8,8 @@ from mage_ai.api.policies.PipelineSchedulePolicy import (
|
|
|
8
8
|
READABLE_ATTRIBUTES_FOR_PIPELINE_INTERACTIONS,
|
|
9
9
|
WRITABLE_ATTRIBUTES_FOR_PIPELINE_INTERACTIONS,
|
|
10
10
|
)
|
|
11
|
+
from mage_ai.data_preparation.models.project import Project
|
|
12
|
+
from mage_ai.data_preparation.models.project.constants import FeatureUUID
|
|
11
13
|
from mage_ai.shared.hash import extract
|
|
12
14
|
|
|
13
15
|
|
|
@@ -23,8 +25,39 @@ async def parse_read_update(parser, _value: Dict, **kwargs) -> Dict:
|
|
|
23
25
|
return {}
|
|
24
26
|
|
|
25
27
|
|
|
26
|
-
async def parse_write(
|
|
27
|
-
|
|
28
|
+
async def parse_write(
|
|
29
|
+
parser,
|
|
30
|
+
value: Dict,
|
|
31
|
+
authorize_status: AuthorizeStatusType = None,
|
|
32
|
+
**kwargs,
|
|
33
|
+
) -> Dict:
|
|
34
|
+
if AuthorizeStatusType.FAILED == authorize_status:
|
|
35
|
+
parsed_value = extract(value or {}, WRITABLE_ATTRIBUTES_FOR_PIPELINE_INTERACTIONS)
|
|
36
|
+
else:
|
|
37
|
+
parsed_value = (value or {}).copy()
|
|
38
|
+
|
|
39
|
+
pipeline = parser.policy.parent_model()
|
|
40
|
+
if not pipeline:
|
|
41
|
+
pipeline = parser.policy.resource.pipeline
|
|
42
|
+
|
|
43
|
+
if Project(pipeline.repo_config if pipeline else None).is_feature_enabled(
|
|
44
|
+
FeatureUUID.INTERACTIONS,
|
|
45
|
+
):
|
|
46
|
+
pipeline_interaction = (parser.policy.result_set().context.data or {}).get(
|
|
47
|
+
'pipeline_interactions',
|
|
48
|
+
{},
|
|
49
|
+
).get(pipeline.uuid)
|
|
50
|
+
|
|
51
|
+
if pipeline_interaction:
|
|
52
|
+
variables = parsed_value.get('variables')
|
|
53
|
+
if pipeline_interaction and variables:
|
|
54
|
+
variables_allowed = await pipeline_interaction.variables()
|
|
55
|
+
parsed_value['variables'] = extract(
|
|
56
|
+
variables or {},
|
|
57
|
+
(variables_allowed or {}).keys(),
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
return parsed_value
|
|
28
61
|
|
|
29
62
|
|
|
30
63
|
async def parse_write_update(parser, value: Dict, **kwargs) -> Dict:
|
|
@@ -66,6 +99,7 @@ PipelineScheduleParser.parse_write(
|
|
|
66
99
|
],
|
|
67
100
|
on_authorize_status=[
|
|
68
101
|
AuthorizeStatusType.FAILED,
|
|
102
|
+
AuthorizeStatusType.SUCCEEDED,
|
|
69
103
|
],
|
|
70
104
|
scopes=[
|
|
71
105
|
OauthScopeType.CLIENT_PRIVATE,
|