ethyca-fides 2.58.2b3__py2.py3-none-any.whl → 2.58.2rc0__py2.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.
- {ethyca_fides-2.58.2b3.dist-info → ethyca_fides-2.58.2rc0.dist-info}/METADATA +1 -1
- {ethyca_fides-2.58.2b3.dist-info → ethyca_fides-2.58.2rc0.dist-info}/RECORD +172 -181
- fides/_version.py +3 -3
- fides/api/api/deps.py +2 -8
- fides/api/api/v1/endpoints/user_endpoints.py +12 -8
- fides/api/cryptography/identity_salt.py +13 -12
- fides/api/custom_types.py +1 -6
- fides/api/db/base.py +0 -5
- fides/api/db/system.py +3 -1
- fides/api/migrations/hash_migration_job.py +2 -2
- fides/api/models/attachment.py +11 -80
- fides/api/models/comment.py +15 -45
- fides/api/models/detection_discovery.py +0 -31
- fides/api/models/fides_user.py +9 -26
- fides/api/models/fides_user_invite.py +0 -2
- fides/api/models/privacy_experience.py +0 -42
- fides/api/models/privacy_request/privacy_request.py +6 -23
- fides/api/schemas/connection_configuration/connection_config.py +16 -30
- fides/api/schemas/user.py +1 -5
- fides/api/service/deps.py +0 -9
- fides/api/service/storage/s3.py +1 -14
- fides/api/service/user/fides_user_service.py +128 -0
- fides/api/task/graph_task.py +1 -1
- fides/ui-build/static/admin/404.html +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{1150-2642cd9cdc8a52f6.js → 1150-035a721a04f4451e.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/1376-5cea5ef9362215e8.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{2397-0d1c289b788fcc11.js → 2397-ee53235fb21b5e97.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/3412-7ec8751b8182e1bf.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{3855-63495367531cb776.js → 3855-b6b7865dedd7bc2a.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{3872-472bb47eb34d8fdb.js → 3872-4e053c20d546f027.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{4060-53a5c6347690a8fa.js → 4060-8d165e1236ea521a.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/4450-36234280bee624ff.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/4481-aab99ff80f707473.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{5258-cf7b27ef51f38392.js → 5258-0658dc2274df6832.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{5480-52dc446be40725f5.js → 5480-f49696df5e8ae500.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{5487-8678d75ee1d1ef09.js → 5487-3ad50d21cdbc9209.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/5973-52aee296edc44f7e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{6315-1adb10a8b98b4a13.js → 6315-fa1519cdf080f42d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{6372-e0bb9f8d07cc3b04.js → 6372-ca9c12ac8902365b.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{6853-09e831e9dff7fd3b.js → 6853-8941824350c3c1a8.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{6954-baa1d873abfe8b77.js → 6954-3b887fb444f9228c.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/7453-39761c38da31257e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{7751-a70fe0e5f67f5538.js → 7751-a8f31c062d4cb09d.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{79-8e060d36d36c752c.js → 79-f9b948ebb186900f.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{7980-72f745bff9fabcc9.js → 7980-4bd08957448dea32.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{9046-8a5fdd335a76d224.js → 9046-04bd7becea207cb1.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/9767-1a23925d2cb27b51.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/{main-090643377c8254e6.js → main-24f422f93845a596.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/{main-app-59156a9331ac7bce.js → main-app-94a0711202e08b15.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{_app-fbe3db87623c87a0.js → _app-fc89ce7bed454c84.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/add-systems/{manual-9f9500c639362aa6.js → manual-9acaab973dfe86e2.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{add-systems-fac606150b65d494.js → add-systems-d258f0c25fa020bf.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/[id]-fb75fa0aea77678d.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/{new-c02b14c50b19bd91.js → new-a9d9402c219d13e5.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience-c946b33b0322b8ad.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-ea57f9d6ad17e957.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/{reporting-100234c23a85d235.js → reporting-788cf0e34829af46.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{data-catalog-49bffaf07973fead.js → data-catalog-900004e402c31797.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]/{[systemId]-727f1f5d06be674b.js → [systemId]-b66831fdafcdf67c.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-5f9ef1f99818117c.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/{action-center-719949074f10bd6e.js → action-center-d001337d1bb73bd1.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-11b3ce9f61d9bfe9.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/dataset/{new-4d4a31d0186a4a5b.js → new-803c1b577ab17ae3.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{dataset-29317d18ce34adfe.js → dataset-fa743ddc7f89d76b.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{[id]-14c57e5069e9cccd.js → [id]-bbe1ca2793798e6b.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection/{new-f0a4e385c1ad8fee.js → new-abc17fef69cd951b.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-a78a73b65929853a.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/{index-b70def65e264270e.js → index-bfaacdb55a5a6c9f.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-d4329043219fed9b.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/{[id]-72d64a02b7ef175e.js → [id]-fe765154315782cf.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/{messaging-5e2687ab5ab10275.js → messaging-f5f7a8069909ef24.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/privacy-requests/configure/{storage-2914aade73dcaecc.js → storage-9f7eaad05e5b9292.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{privacy-requests-b0f801d66e79a31a.js → privacy-requests-d85c0d16ba09ba35.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/reporting/{datamap-f035cddf17f4d898.js → datamap-afedc48ef4e7f858.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-89524101b7279f6e.js +1 -0
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/{custom-fields-dfcd7a4b6aa773bd.js → custom-fields-52d030b1db2ca1b9.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/{organization-0e0aa552f520f913.js → organization-a08693d0d1e10bc8.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/[id]/{test-datasets-1d83d5178b3eb216.js → test-datasets-151571cff4e85894.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/systems/configure/{[id]-a158fa77df288523.js → [id]-4f5a28226575c976.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{systems-8490aaaee9d76a4a.js → systems-abd68fc5ddde5482.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{taxonomy-be1ffe267b1602e1.js → taxonomy-16b4d75c49276add.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/user-management/profile/{[id]-c0378fd1a26a71da.js → [id]-78eaf933f755bfe8.js} +1 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/{user-management-3ca3c687e72d1364.js → user-management-6c9ad62479a7d03e.js} +1 -1
- fides/ui-build/static/admin/_next/static/css/{cf2744a40308fc4a.css → 113d823fe71f6af0.css} +1 -1
- fides/ui-build/static/admin/_next/static/o0mKeH0cB6eAYV6qOlVD0/_buildManifest.js +1 -0
- fides/ui-build/static/admin/add-systems/manual.html +1 -1
- fides/ui-build/static/admin/add-systems/multiple.html +1 -1
- fides/ui-build/static/admin/add-systems.html +1 -1
- fides/ui-build/static/admin/ant-poc.html +1 -1
- fides/ui-build/static/admin/consent/configure/add-vendors.html +1 -1
- fides/ui-build/static/admin/consent/configure.html +1 -1
- fides/ui-build/static/admin/consent/privacy-experience/[id].html +1 -1
- fides/ui-build/static/admin/consent/privacy-experience/new.html +1 -1
- fides/ui-build/static/admin/consent/privacy-experience.html +1 -1
- fides/ui-build/static/admin/consent/privacy-notices/[id].html +1 -1
- fides/ui-build/static/admin/consent/privacy-notices/new.html +1 -1
- fides/ui-build/static/admin/consent/privacy-notices.html +1 -1
- fides/ui-build/static/admin/consent/properties.html +1 -1
- fides/ui-build/static/admin/consent/reporting.html +1 -1
- fides/ui-build/static/admin/consent.html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn]/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/projects/[projectUrn].html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/projects.html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/resources/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-catalog/[systemId]/resources.html +1 -1
- fides/ui-build/static/admin/data-catalog.html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center/[monitorId]/[systemId].html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center/[monitorId].html +1 -1
- fides/ui-build/static/admin/data-discovery/action-center.html +1 -1
- fides/ui-build/static/admin/data-discovery/activity.html +1 -1
- fides/ui-build/static/admin/data-discovery/detection/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-discovery/detection.html +1 -1
- fides/ui-build/static/admin/data-discovery/discovery/[resourceUrn].html +1 -1
- fides/ui-build/static/admin/data-discovery/discovery.html +1 -1
- fides/ui-build/static/admin/datamap.html +1 -1
- fides/ui-build/static/admin/dataset/[datasetId]/[collectionName]/[...subfieldNames].html +1 -1
- fides/ui-build/static/admin/dataset/[datasetId]/[collectionName].html +1 -1
- fides/ui-build/static/admin/dataset/[datasetId].html +1 -1
- fides/ui-build/static/admin/dataset/new.html +1 -1
- fides/ui-build/static/admin/dataset.html +1 -1
- fides/ui-build/static/admin/datastore-connection/[id].html +1 -1
- fides/ui-build/static/admin/datastore-connection/new.html +1 -1
- fides/ui-build/static/admin/datastore-connection.html +1 -1
- fides/ui-build/static/admin/index.html +1 -1
- fides/ui-build/static/admin/integrations/[id].html +1 -1
- fides/ui-build/static/admin/integrations.html +1 -1
- fides/ui-build/static/admin/lib/fides-ext-gpp.js +1 -1
- fides/ui-build/static/admin/lib/fides-headless.js +1 -1
- fides/ui-build/static/admin/lib/fides-tcf.js +4 -4
- fides/ui-build/static/admin/lib/fides.js +3 -3
- fides/ui-build/static/admin/login/[provider].html +1 -1
- fides/ui-build/static/admin/login.html +1 -1
- fides/ui-build/static/admin/messaging/[id].html +1 -1
- fides/ui-build/static/admin/messaging/add-template.html +1 -1
- fides/ui-build/static/admin/messaging.html +1 -1
- fides/ui-build/static/admin/privacy-requests/[id].html +1 -1
- fides/ui-build/static/admin/privacy-requests/configure/messaging.html +1 -1
- fides/ui-build/static/admin/privacy-requests/configure/storage.html +1 -1
- fides/ui-build/static/admin/privacy-requests/configure.html +1 -1
- fides/ui-build/static/admin/privacy-requests.html +1 -1
- fides/ui-build/static/admin/properties/[id].html +1 -1
- fides/ui-build/static/admin/properties/add-property.html +1 -1
- fides/ui-build/static/admin/properties.html +1 -1
- fides/ui-build/static/admin/reporting/datamap.html +1 -1
- fides/ui-build/static/admin/settings/about.html +1 -1
- fides/ui-build/static/admin/settings/consent.html +1 -1
- fides/ui-build/static/admin/settings/custom-fields.html +1 -1
- fides/ui-build/static/admin/settings/domain-records.html +1 -1
- fides/ui-build/static/admin/settings/domains.html +1 -1
- fides/ui-build/static/admin/settings/email-templates.html +1 -1
- fides/ui-build/static/admin/settings/locations.html +1 -1
- fides/ui-build/static/admin/settings/organization.html +1 -1
- fides/ui-build/static/admin/settings/regulations.html +1 -1
- fides/ui-build/static/admin/systems/configure/[id]/test-datasets.html +1 -1
- fides/ui-build/static/admin/systems/configure/[id].html +1 -1
- fides/ui-build/static/admin/systems.html +1 -1
- fides/ui-build/static/admin/taxonomy.html +1 -1
- fides/ui-build/static/admin/user-management/new.html +1 -1
- fides/ui-build/static/admin/user-management/profile/[id].html +1 -1
- fides/ui-build/static/admin/user-management.html +1 -1
- fides/api/alembic/migrations/versions/67d01c4e124e_add_reject_all_mechanism_to_privacy_.py +0 -56
- fides/api/alembic/migrations/versions/6e565c16dae1_add_tcf_publisher_restrictions.py +0 -107
- fides/api/alembic/migrations/versions/99c603c1b8f9_add_password_login_enabled_and_totp_secret_to_fidesuser.py +0 -45
- fides/api/models/tcf_publisher_restrictions.py +0 -304
- fides/service/error_handling/__init__.py +0 -0
- fides/service/error_handling/error_handler.py +0 -202
- fides/service/user/__init__.py +0 -0
- fides/service/user/user_service.py +0 -140
- fides/ui-build/static/admin/_next/static/S7gURhIaHGAv7MFBTEOOS/_buildManifest.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1376-03e7f50e708b7589.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/146-0ae2d30ec71fce09.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/1817-f82105a9608bba1a.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/3938-6a1c07d06a80cf4c.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4450-6a8aa0d7358ac26f.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/4481-275aa9f4c10bce53.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/5973-d3d3872692c1d0fa.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/9767-8179ce7336727141.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience/[id]-ab3ef485f6101697.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-experience-ba5325035c71a97e.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices-ef31c181cac86c64.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/action-center/[monitorId]-53efbed54d230f07.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/data-discovery/activity-4892603e743cd6ab.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/datastore-connection-d2f88a8fc68944db.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/integrations/[id]-b75ab4ee677f118d.js +0 -1
- fides/ui-build/static/admin/_next/static/chunks/pages/settings/consent-3ac1e5d3de5dd4a7.js +0 -1
- fides/ui-build/static/admin/images/connector-logos/website.svg +0 -10
- {ethyca_fides-2.58.2b3.dist-info → ethyca_fides-2.58.2rc0.dist-info}/LICENSE +0 -0
- {ethyca_fides-2.58.2b3.dist-info → ethyca_fides-2.58.2rc0.dist-info}/WHEEL +0 -0
- {ethyca_fides-2.58.2b3.dist-info → ethyca_fides-2.58.2rc0.dist-info}/entry_points.txt +0 -0
- {ethyca_fides-2.58.2b3.dist-info → ethyca_fides-2.58.2rc0.dist-info}/top_level.txt +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{4723-1dd1d16f404d56a2.js → 4723-0a3c5e2ce143a7d0.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/{5826-ef0aa43ffad83acc.js → 5826-e5dcb4e68cfe6289.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/{configure-a4e636eecaba5324.js → configure-723cc3d4f5740ea6.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/consent/privacy-notices/{[id]-606457ef5bd1eb04.js → [id]-72251b48e2e03a1e.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{about-2ae030f3a28f057a.js → about-a49d0f84cf0cf05e.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/settings/{domain-records-72ec54ee8755a503.js → domain-records-fa42d8f18df44927.js} +0 -0
- /fides/ui-build/static/admin/_next/static/chunks/pages/user-management/{new-f8bca2e322ddf252.js → new-be690621a944bfe2.js} +0 -0
- /fides/ui-build/static/admin/_next/static/{S7gURhIaHGAv7MFBTEOOS → o0mKeH0cB6eAYV6qOlVD0}/_ssgManifest.js +0 -0
fides/_version.py
CHANGED
@@ -8,11 +8,11 @@ import json
|
|
8
8
|
|
9
9
|
version_json = '''
|
10
10
|
{
|
11
|
-
"date": "2025-04-
|
11
|
+
"date": "2025-04-09T11:48:07+0200",
|
12
12
|
"dirty": false,
|
13
13
|
"error": null,
|
14
|
-
"full-revisionid": "
|
15
|
-
"version": "2.58.
|
14
|
+
"full-revisionid": "90178f03d530f5525b2acc955bdea0cde7751c7a",
|
15
|
+
"version": "2.58.2rc0"
|
16
16
|
}
|
17
17
|
''' # END VERSION_JSON
|
18
18
|
|
fides/api/api/deps.py
CHANGED
@@ -29,14 +29,8 @@ def get_db() -> Generator:
|
|
29
29
|
|
30
30
|
|
31
31
|
@contextmanager
|
32
|
-
def
|
33
|
-
"""
|
34
|
-
Return a database session as a context manager that automatically closes when the context exits.
|
35
|
-
|
36
|
-
Unlike get_api_session which is managed by FastAPI's dependency injection,
|
37
|
-
this context manager explicitly closes the session when exiting the context.
|
38
|
-
Use this when you need manual control over the session lifecycle outside of API endpoints.
|
39
|
-
"""
|
32
|
+
def get_db_contextmanager() -> Generator[Session, None, None]:
|
33
|
+
"""Return our database session as a context manager"""
|
40
34
|
try:
|
41
35
|
db = get_api_session()
|
42
36
|
yield db
|
@@ -54,7 +54,11 @@ from fides.api.schemas.user import (
|
|
54
54
|
UserResponse,
|
55
55
|
UserUpdate,
|
56
56
|
)
|
57
|
-
from fides.api.service.
|
57
|
+
from fides.api.service.user.fides_user_service import (
|
58
|
+
accept_invite,
|
59
|
+
invite_user,
|
60
|
+
perform_login,
|
61
|
+
)
|
58
62
|
from fides.api.util.api_router import APIRouter
|
59
63
|
from fides.common.api.scope_registry import (
|
60
64
|
SCOPE_REGISTRY,
|
@@ -71,7 +75,6 @@ from fides.common.api.v1 import urn_registry as urls
|
|
71
75
|
from fides.common.api.v1.urn_registry import V1_URL_PREFIX
|
72
76
|
from fides.config import CONFIG, FidesConfig, get_config
|
73
77
|
from fides.config.config_proxy import ConfigProxy
|
74
|
-
from fides.service.user.user_service import UserService
|
75
78
|
|
76
79
|
router = APIRouter(tags=["Users"], prefix=V1_URL_PREFIX)
|
77
80
|
|
@@ -420,7 +423,6 @@ def create_user(
|
|
420
423
|
db: Session = Depends(get_db),
|
421
424
|
user_data: UserCreate,
|
422
425
|
config_proxy: ConfigProxy = Depends(get_config_proxy),
|
423
|
-
user_service: UserService = Depends(get_user_service),
|
424
426
|
) -> FidesUser:
|
425
427
|
"""
|
426
428
|
Create a user given a username and password.
|
@@ -459,7 +461,7 @@ def create_user(
|
|
459
461
|
user = FidesUser.create(db=db, data=user_data.model_dump(mode="json"))
|
460
462
|
|
461
463
|
# invite user via email
|
462
|
-
|
464
|
+
invite_user(db=db, config_proxy=config_proxy, user=user)
|
463
465
|
|
464
466
|
logger.info("Created user with id: '{}'.", user.id)
|
465
467
|
FidesUserPermissions.create(
|
@@ -542,7 +544,6 @@ def user_login(
|
|
542
544
|
db: Session = Depends(get_db),
|
543
545
|
config: FidesConfig = Depends(get_config),
|
544
546
|
user_data: UserLogin,
|
545
|
-
user_service: UserService = Depends(get_user_service),
|
546
547
|
) -> UserLoginResponse:
|
547
548
|
"""Login the user by creating a client if it doesn't exist, and have that client
|
548
549
|
generate a token."""
|
@@ -601,7 +602,8 @@ def user_login(
|
|
601
602
|
# from complaining.
|
602
603
|
user = user_check
|
603
604
|
|
604
|
-
client =
|
605
|
+
client = perform_login(
|
606
|
+
db,
|
605
607
|
config.security.oauth_client_id_length_bytes,
|
606
608
|
config.security.oauth_client_secret_length_bytes,
|
607
609
|
user,
|
@@ -664,9 +666,9 @@ def verify_invite_code(
|
|
664
666
|
def accept_user_invite(
|
665
667
|
*,
|
666
668
|
db: Session = Depends(get_db),
|
669
|
+
config: FidesConfig = Depends(get_config),
|
667
670
|
user_data: UserForcePasswordReset,
|
668
671
|
verified_invite: FidesUserInvite = Depends(verify_invite_code),
|
669
|
-
user_service: UserService = Depends(get_user_service),
|
670
672
|
) -> UserLoginResponse:
|
671
673
|
"""Sets the password and enables the user if a valid username and invite code are provided."""
|
672
674
|
|
@@ -679,7 +681,9 @@ def accept_user_invite(
|
|
679
681
|
detail=f"User with username {verified_invite.username} does not exist.",
|
680
682
|
)
|
681
683
|
|
682
|
-
user, access_code =
|
684
|
+
user, access_code = accept_invite(
|
685
|
+
db=db, config=config, user=user, new_password=user_data.new_password
|
686
|
+
)
|
683
687
|
|
684
688
|
return UserLoginResponse(
|
685
689
|
user_data=user,
|
@@ -3,8 +3,9 @@ from functools import cache
|
|
3
3
|
|
4
4
|
from loguru import logger
|
5
5
|
|
6
|
-
from fides.api.
|
6
|
+
from fides.api.db.session import get_db_session
|
7
7
|
from fides.api.models.identity_salt import IdentitySalt
|
8
|
+
from fides.config import CONFIG
|
8
9
|
|
9
10
|
|
10
11
|
@cache
|
@@ -14,14 +15,14 @@ def get_identity_salt() -> str:
|
|
14
15
|
This function is cached to avoid repeated calls to the database for the same value.
|
15
16
|
"""
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
)
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
18
|
+
SessionLocal = get_db_session(CONFIG)
|
19
|
+
db = SessionLocal()
|
20
|
+
existing_salt = db.query(IdentitySalt).first()
|
21
|
+
if existing_salt is None:
|
22
|
+
new_salt = IdentitySalt.create(
|
23
|
+
db, data={"encrypted_value": {"value": secrets.token_hex(32)}}
|
24
|
+
)
|
25
|
+
logger.info("Created new identity salt.")
|
26
|
+
return new_salt.encrypted_value.get("value")
|
27
|
+
logger.info("Caching existing identity salt.")
|
28
|
+
return existing_salt.encrypted_value.get("value")
|
fides/api/custom_types.py
CHANGED
@@ -66,13 +66,8 @@ def validate_html_str(val: str) -> str:
|
|
66
66
|
"strong",
|
67
67
|
"u",
|
68
68
|
}
|
69
|
-
|
70
|
-
ALLOWED_ATTRIBUTES = {
|
71
|
-
"a": {"href", "hreflang", "target"},
|
72
|
-
}
|
73
|
-
|
74
69
|
if val:
|
75
|
-
return clean(val, tags=ALLOWED_HTML_TAGS
|
70
|
+
return clean(val, tags=ALLOWED_HTML_TAGS)
|
76
71
|
return val
|
77
72
|
|
78
73
|
|
fides/api/db/base.py
CHANGED
@@ -8,7 +8,6 @@ from fides.api.models.attachment import Attachment, AttachmentReference
|
|
8
8
|
from fides.api.models.audit_log import AuditLog
|
9
9
|
from fides.api.models.authentication_request import AuthenticationRequest
|
10
10
|
from fides.api.models.client import ClientDetail
|
11
|
-
from fides.api.models.comment import Comment, CommentReference
|
12
11
|
from fides.api.models.connectionconfig import ConnectionConfig
|
13
12
|
from fides.api.models.consent_automation import ConsentAutomation
|
14
13
|
from fides.api.models.custom_asset import CustomAsset
|
@@ -59,8 +58,4 @@ from fides.api.models.storage import StorageConfig
|
|
59
58
|
from fides.api.models.system_compass_sync import SystemCompassSync
|
60
59
|
from fides.api.models.system_history import SystemHistory
|
61
60
|
from fides.api.models.system_manager import SystemManager
|
62
|
-
from fides.api.models.tcf_publisher_restrictions import (
|
63
|
-
TCFConfiguration,
|
64
|
-
TCFPublisherRestriction,
|
65
|
-
)
|
66
61
|
from fides.api.models.tcf_purpose_overrides import TCFPurposeOverride
|
fides/api/db/system.py
CHANGED
@@ -406,7 +406,9 @@ async def create_system(
|
|
406
406
|
|
407
407
|
# create the system resource using generic creation
|
408
408
|
# the system must be created before the privacy declarations so that it can be referenced
|
409
|
-
resource_dict = resource.model_dump(
|
409
|
+
resource_dict = resource.model_dump(
|
410
|
+
mode="json"
|
411
|
+
) # mode=json helps Url fields be converted to strings before saving to db
|
410
412
|
|
411
413
|
# set the current user's ID
|
412
414
|
resource_dict["user_id"] = current_user_id
|
@@ -2,7 +2,7 @@ from loguru import logger
|
|
2
2
|
from sqlalchemy import text
|
3
3
|
from sqlalchemy.orm import Session
|
4
4
|
|
5
|
-
from fides.api.api.deps import
|
5
|
+
from fides.api.api.deps import get_db_contextmanager
|
6
6
|
from fides.api.db.base_class import FidesBase
|
7
7
|
from fides.api.migrations.hash_migration_mixin import HashMigrationMixin
|
8
8
|
from fides.api.migrations.hash_migration_tracker import HashMigrationTracker
|
@@ -47,7 +47,7 @@ def bcrypt_migration_task() -> None:
|
|
47
47
|
Job to migrate all the tables using bcrypt hashes for general data (excludes tables with credentials).
|
48
48
|
"""
|
49
49
|
|
50
|
-
with
|
50
|
+
with get_db_contextmanager() as db:
|
51
51
|
# Do a single pass to check if any of the models have already been migrated.
|
52
52
|
# This will allow us to optimize searching for these models by not calling
|
53
53
|
# the previously used bcrypt hash.
|
fides/api/models/attachment.py
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
import os
|
2
2
|
from enum import Enum as EnumType
|
3
|
-
from
|
4
|
-
from typing import IO, TYPE_CHECKING, Any, Optional, Tuple, Union
|
3
|
+
from typing import IO, Any, Optional
|
5
4
|
|
6
|
-
from fideslang.validation import AnyHttpUrlString
|
7
5
|
from loguru import logger as log
|
8
6
|
from sqlalchemy import Column
|
9
7
|
from sqlalchemy import Enum as EnumColumn
|
10
|
-
from sqlalchemy import ForeignKey, String, UniqueConstraint
|
8
|
+
from sqlalchemy import ForeignKey, String, UniqueConstraint
|
11
9
|
from sqlalchemy.ext.declarative import declared_attr
|
12
10
|
from sqlalchemy.orm import Session, relationship
|
13
11
|
|
@@ -25,10 +23,6 @@ from fides.api.service.storage.util import (
|
|
25
23
|
get_local_filename,
|
26
24
|
)
|
27
25
|
|
28
|
-
if TYPE_CHECKING:
|
29
|
-
from fides.api.models.comment import Comment
|
30
|
-
from fides.api.models.privacy_request import PrivacyRequest
|
31
|
-
|
32
26
|
|
33
27
|
class AttachmentType(str, EnumType):
|
34
28
|
"""
|
@@ -59,9 +53,7 @@ class AttachmentReference(Base):
|
|
59
53
|
"""Overriding base class method to set the table name."""
|
60
54
|
return "attachment_reference"
|
61
55
|
|
62
|
-
attachment_id = Column(
|
63
|
-
String, ForeignKey("attachment.id", ondelete="CASCADE"), nullable=False
|
64
|
-
)
|
56
|
+
attachment_id = Column(String, ForeignKey("attachment.id"), nullable=False)
|
65
57
|
reference_id = Column(String, nullable=False)
|
66
58
|
reference_type = Column(EnumColumn(AttachmentReferenceType), nullable=False)
|
67
59
|
|
@@ -71,8 +63,11 @@ class AttachmentReference(Base):
|
|
71
63
|
),
|
72
64
|
)
|
73
65
|
|
74
|
-
|
75
|
-
|
66
|
+
attachment = relationship(
|
67
|
+
"Attachment",
|
68
|
+
back_populates="references",
|
69
|
+
uselist=False,
|
70
|
+
)
|
76
71
|
|
77
72
|
@classmethod
|
78
73
|
def create(
|
@@ -105,11 +100,8 @@ class Attachment(Base):
|
|
105
100
|
references = relationship(
|
106
101
|
"AttachmentReference",
|
107
102
|
back_populates="attachment",
|
108
|
-
cascade="all, delete
|
103
|
+
cascade="all, delete",
|
109
104
|
uselist=True,
|
110
|
-
foreign_keys=[AttachmentReference.attachment_id],
|
111
|
-
primaryjoin=lambda: Attachment.id
|
112
|
-
== orm.foreign(AttachmentReference.attachment_id),
|
113
105
|
)
|
114
106
|
|
115
107
|
config = relationship(
|
@@ -135,34 +127,13 @@ class Attachment(Base):
|
|
135
127
|
|
136
128
|
if self.config.type == StorageType.local:
|
137
129
|
filename = get_local_filename(self.id)
|
138
|
-
|
139
|
-
# Validate that attachment is a file-like object
|
140
|
-
if not hasattr(attachment, "read"):
|
141
|
-
raise TypeError(f"Expected a file-like object, got {type(attachment)}")
|
142
|
-
|
143
|
-
# Reset the file pointer to the beginning
|
144
|
-
try:
|
145
|
-
attachment.seek(0)
|
146
|
-
except Exception as e:
|
147
|
-
raise ValueError(f"Failed to reset file pointer for attachment: {e}")
|
148
|
-
|
149
|
-
# Write the file in chunks to avoid loading the entire content into memory
|
150
130
|
with open(filename, "wb") as file:
|
151
|
-
|
152
|
-
lambda: attachment.read(1024 * 1024), b""
|
153
|
-
): # 1 MB chunks
|
154
|
-
if not isinstance(chunk, bytes):
|
155
|
-
raise TypeError(f"Expected bytes, got {type(chunk)}")
|
156
|
-
file.write(chunk)
|
157
|
-
|
158
|
-
log.info(f"Uploaded {self.file_name} to local storage at {filename}")
|
131
|
+
file.write(attachment.read())
|
159
132
|
return
|
160
133
|
|
161
134
|
raise ValueError(f"Unsupported storage type: {self.config.type}")
|
162
135
|
|
163
|
-
def retrieve_attachment(
|
164
|
-
self,
|
165
|
-
) -> Optional[Tuple[BytesIO, Union[AnyHttpUrlString, str]]]:
|
136
|
+
def retrieve_attachment(self) -> Optional[bytes]:
|
166
137
|
"""Returns the attachment from S3 in bytes form."""
|
167
138
|
if self.config.type == StorageType.s3:
|
168
139
|
bucket_name = f"{self.config.details[StorageDetails.BUCKET.value]}"
|
@@ -237,44 +208,4 @@ class Attachment(Base):
|
|
237
208
|
def delete(self, db: Session) -> None:
|
238
209
|
"""Deletes an attachment record from the database and deletes the attachment from S3."""
|
239
210
|
self.delete_attachment_from_storage()
|
240
|
-
for attachment_reference in self.references:
|
241
|
-
attachment_reference.delete(db)
|
242
211
|
super().delete(db=db)
|
243
|
-
|
244
|
-
@staticmethod
|
245
|
-
def delete_attachments_for_reference_and_type(
|
246
|
-
db: Session, reference_id: str, reference_type: AttachmentReferenceType
|
247
|
-
) -> None:
|
248
|
-
"""
|
249
|
-
Deletes attachments associated with a given reference_id and reference_type.
|
250
|
-
Deletes all references to the attachments.
|
251
|
-
|
252
|
-
Args:
|
253
|
-
db: Database session
|
254
|
-
reference_id: ID of the reference
|
255
|
-
reference_type: Type of the reference
|
256
|
-
|
257
|
-
Examples:
|
258
|
-
|
259
|
-
- Delete all attachments associated with a comment.
|
260
|
-
``Attachment.delete_attachments_for_reference_and_type(
|
261
|
-
db, comment.id, AttachmentReferenceType.comment
|
262
|
-
)``
|
263
|
-
- Delete all attachments associated with a privacy request.
|
264
|
-
``Attachment.delete_attachments_for_reference_and_type(
|
265
|
-
db, privacy_request.id, AttachmentReferenceType.privacy_request
|
266
|
-
)``
|
267
|
-
"""
|
268
|
-
# Query attachments explicitly to avoid lazy loading
|
269
|
-
attachments = (
|
270
|
-
db.query(Attachment)
|
271
|
-
.join(AttachmentReference)
|
272
|
-
.filter(
|
273
|
-
AttachmentReference.reference_id == reference_id,
|
274
|
-
AttachmentReference.reference_type == reference_type,
|
275
|
-
)
|
276
|
-
.all()
|
277
|
-
)
|
278
|
-
|
279
|
-
for attachment in attachments:
|
280
|
-
attachment.delete(db)
|
fides/api/models/comment.py
CHANGED
@@ -3,17 +3,15 @@ from typing import TYPE_CHECKING, Any
|
|
3
3
|
|
4
4
|
from sqlalchemy import Column
|
5
5
|
from sqlalchemy import Enum as EnumColumn
|
6
|
-
from sqlalchemy import ForeignKey, String, UniqueConstraint
|
6
|
+
from sqlalchemy import ForeignKey, String, UniqueConstraint
|
7
7
|
from sqlalchemy.ext.declarative import declared_attr
|
8
8
|
from sqlalchemy.orm import Session, relationship
|
9
9
|
|
10
10
|
from fides.api.db.base_class import Base
|
11
|
-
from fides.api.models.attachment import Attachment, AttachmentReferenceType
|
12
11
|
|
13
12
|
if TYPE_CHECKING:
|
14
|
-
from fides.api.models.attachment import
|
13
|
+
from fides.api.models.attachment import Attachment
|
15
14
|
from fides.api.models.fides_user import FidesUser
|
16
|
-
from fides.api.models.privacy_request import PrivacyRequest
|
17
15
|
|
18
16
|
|
19
17
|
class CommentType(str, EnumType):
|
@@ -89,51 +87,23 @@ class Comment(Base):
|
|
89
87
|
references = relationship(
|
90
88
|
"CommentReference",
|
91
89
|
back_populates="comment",
|
92
|
-
cascade="all, delete
|
90
|
+
cascade="all, delete",
|
91
|
+
uselist=True,
|
92
|
+
)
|
93
|
+
|
94
|
+
attachments = relationship(
|
95
|
+
"Attachment",
|
96
|
+
secondary="attachment_reference",
|
97
|
+
primaryjoin="Comment.id == AttachmentReference.reference_id",
|
98
|
+
secondaryjoin="Attachment.id == AttachmentReference.attachment_id",
|
99
|
+
order_by="Attachment.created_at",
|
93
100
|
uselist=True,
|
94
|
-
foreign_keys=[CommentReference.comment_id],
|
95
|
-
primaryjoin=lambda: Comment.id == orm.foreign(CommentReference.comment_id),
|
96
101
|
)
|
97
102
|
|
98
103
|
def delete(self, db: Session) -> None:
|
99
104
|
"""Delete the comment and all associated references."""
|
100
105
|
# Delete the comment
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
for reference in self.references:
|
105
|
-
reference.delete(db)
|
106
|
+
for attachment in self.attachments:
|
107
|
+
if len(attachment.references) == 1:
|
108
|
+
attachment.delete(db)
|
106
109
|
db.delete(self)
|
107
|
-
|
108
|
-
@staticmethod
|
109
|
-
def delete_comments_for_reference_and_type(
|
110
|
-
db: Session, reference_id: str, reference_type: CommentReferenceType
|
111
|
-
) -> None:
|
112
|
-
"""
|
113
|
-
Deletes comments associated with a given reference_id and reference_type.
|
114
|
-
Delete all references to the comments.
|
115
|
-
|
116
|
-
Args:
|
117
|
-
db: Database session.
|
118
|
-
reference_id: The reference id to delete.
|
119
|
-
reference_type: The reference type to delete
|
120
|
-
|
121
|
-
Examples:
|
122
|
-
- Delete all comments associated with a privacy request.
|
123
|
-
``Comment.delete_comments_for_reference_and_type(
|
124
|
-
db, privacy_request.id, CommentReferenceType.privacy_request
|
125
|
-
)``
|
126
|
-
"""
|
127
|
-
# Query comments explicitly to avoid lazy loading
|
128
|
-
comments = (
|
129
|
-
db.query(Comment)
|
130
|
-
.join(CommentReference)
|
131
|
-
.filter(
|
132
|
-
CommentReference.reference_id == reference_id,
|
133
|
-
CommentReference.reference_type == reference_type,
|
134
|
-
)
|
135
|
-
.all()
|
136
|
-
)
|
137
|
-
|
138
|
-
for comment in comments:
|
139
|
-
comment.delete(db)
|
@@ -2,7 +2,6 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
from datetime import datetime
|
4
4
|
from enum import Enum
|
5
|
-
from re import match
|
6
5
|
from typing import Any, Dict, Iterable, List, Optional, Type
|
7
6
|
|
8
7
|
from loguru import logger
|
@@ -36,17 +35,9 @@ class MonitorFrequency(Enum):
|
|
36
35
|
DAILY = "Daily"
|
37
36
|
WEEKLY = "Weekly"
|
38
37
|
MONTHLY = "Monthly"
|
39
|
-
QUARTERLY = "Quarterly"
|
40
|
-
YEARLY = "Yearly"
|
41
38
|
NOT_SCHEDULED = "Not scheduled"
|
42
39
|
|
43
40
|
|
44
|
-
# pattern for a string of 4 comma-separated integers,
|
45
|
-
# used to represent the months of the year that the monitor will run
|
46
|
-
# on quarterly basis, in cron format
|
47
|
-
QUARTERLY_MONTH_PATTERN = r"^\d+,\d+,\d+,\d+$"
|
48
|
-
|
49
|
-
|
50
41
|
class MonitorConfig(Base):
|
51
42
|
"""
|
52
43
|
Monitor configuration used for data detection and discovery.
|
@@ -147,13 +138,6 @@ class MonitorConfig(Base):
|
|
147
138
|
or self.monitor_execution_trigger.get("hour", None) is None
|
148
139
|
):
|
149
140
|
return MonitorFrequency.NOT_SCHEDULED
|
150
|
-
month_trigger = self.monitor_execution_trigger.get("month", None)
|
151
|
-
if month_trigger is not None:
|
152
|
-
if isinstance(month_trigger, str) and match(
|
153
|
-
QUARTERLY_MONTH_PATTERN, month_trigger
|
154
|
-
):
|
155
|
-
return MonitorFrequency.QUARTERLY
|
156
|
-
return MonitorFrequency.YEARLY
|
157
141
|
if self.monitor_execution_trigger.get("day", None) is not None:
|
158
142
|
return MonitorFrequency.MONTHLY
|
159
143
|
if self.monitor_execution_trigger.get("day_of_week", None) is not None:
|
@@ -217,10 +201,6 @@ class MonitorConfig(Base):
|
|
217
201
|
a Tuesday.
|
218
202
|
- with an `execution_frequency` of "monthly", it will result in monthly
|
219
203
|
execution at 12:00:00+00:00 on the 14th day of every month.
|
220
|
-
- with an `execution_frequency` of "quarterly", it will result in quarterly
|
221
|
-
execution at 12:00:00+00:00 on the 14th day of the first month of each quarter.
|
222
|
-
- with an `execution_frequency` of "yearly", it will result in yearly
|
223
|
-
execution at 12:00:00+00:00 on May 14th of each year.
|
224
204
|
|
225
205
|
See https://apscheduler.readthedocs.io/en/3.x/modules/triggers/cron.html
|
226
206
|
for more information about the cron trigger parameters.
|
@@ -241,17 +221,6 @@ class MonitorConfig(Base):
|
|
241
221
|
cron_trigger_dict["day_of_week"] = execution_start_date.weekday()
|
242
222
|
if execution_frequency == MonitorFrequency.MONTHLY:
|
243
223
|
cron_trigger_dict["day"] = execution_start_date.day
|
244
|
-
if execution_frequency == MonitorFrequency.QUARTERLY:
|
245
|
-
cron_trigger_dict["day"] = execution_start_date.day
|
246
|
-
# Calculate which month of the quarter (0-2) this is
|
247
|
-
month_of_quarter = (execution_start_date.month - 1) % 3
|
248
|
-
# Set to run in the same month of each quarter (1, 4, 7, 10 for first month)
|
249
|
-
cron_trigger_dict["month"] = (
|
250
|
-
f"{1 + month_of_quarter},{4 + month_of_quarter},{7 + month_of_quarter},{10 + month_of_quarter}"
|
251
|
-
)
|
252
|
-
if execution_frequency == MonitorFrequency.YEARLY:
|
253
|
-
cron_trigger_dict["day"] = execution_start_date.day
|
254
|
-
cron_trigger_dict["month"] = execution_start_date.month
|
255
224
|
data["monitor_execution_trigger"] = cron_trigger_dict
|
256
225
|
|
257
226
|
|
fides/api/models/fides_user.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# pylint: disable=unused-import
|
2
2
|
from __future__ import annotations
|
3
3
|
|
4
|
+
import uuid
|
4
5
|
from datetime import datetime
|
5
6
|
from typing import TYPE_CHECKING, Any, List
|
6
7
|
|
@@ -9,10 +10,6 @@ from sqlalchemy import Boolean, Column, DateTime
|
|
9
10
|
from sqlalchemy import Enum as EnumColumn
|
10
11
|
from sqlalchemy import String
|
11
12
|
from sqlalchemy.orm import Session, relationship
|
12
|
-
from sqlalchemy_utils.types.encrypted.encrypted_type import (
|
13
|
-
AesGcmEngine,
|
14
|
-
StringEncryptedType,
|
15
|
-
)
|
16
13
|
|
17
14
|
from fides.api.common_exceptions import SystemManagerException
|
18
15
|
from fides.api.cryptography.cryptographic_util import (
|
@@ -23,8 +20,8 @@ from fides.api.db.base_class import Base
|
|
23
20
|
from fides.api.models.audit_log import AuditLog
|
24
21
|
|
25
22
|
# Intentionally importing SystemManager here to build the FidesUser.systems relationship
|
23
|
+
from fides.api.models.system_manager import SystemManager # type: ignore[unused-import]
|
26
24
|
from fides.api.schemas.user import DisabledReason
|
27
|
-
from fides.config import CONFIG
|
28
25
|
|
29
26
|
if TYPE_CHECKING:
|
30
27
|
from fides.api.models.sql_models import System # type: ignore[attr-defined]
|
@@ -37,22 +34,12 @@ class FidesUser(Base):
|
|
37
34
|
email_address = Column(CIText, unique=True, nullable=True)
|
38
35
|
first_name = Column(String, nullable=True)
|
39
36
|
last_name = Column(String, nullable=True)
|
40
|
-
hashed_password = Column(String, nullable=
|
41
|
-
salt = Column(String, nullable=
|
37
|
+
hashed_password = Column(String, nullable=False)
|
38
|
+
salt = Column(String, nullable=False)
|
42
39
|
disabled = Column(Boolean, nullable=False, server_default="f")
|
43
40
|
disabled_reason = Column(EnumColumn(DisabledReason), nullable=True)
|
44
41
|
last_login_at = Column(DateTime(timezone=True), nullable=True)
|
45
42
|
password_reset_at = Column(DateTime(timezone=True), nullable=True)
|
46
|
-
password_login_enabled = Column(Boolean, nullable=True)
|
47
|
-
totp_secret = Column(
|
48
|
-
StringEncryptedType(
|
49
|
-
type_in=String(),
|
50
|
-
key=CONFIG.security.app_encryption_key,
|
51
|
-
engine=AesGcmEngine,
|
52
|
-
padding="pkcs5",
|
53
|
-
),
|
54
|
-
nullable=True,
|
55
|
-
)
|
56
43
|
|
57
44
|
# passive_deletes="all" prevents audit logs from having their
|
58
45
|
# privacy_request_id set to null when a privacy_request is deleted.
|
@@ -92,11 +79,11 @@ class FidesUser(Base):
|
|
92
79
|
"""Create a FidesUser by hashing the password with a generated salt
|
93
80
|
and storing the hashed password and the salt"""
|
94
81
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
82
|
+
# we set a dummy password if one isn't provided because this means it's part of the user
|
83
|
+
# invite flow and the password will be set by the user after they accept their invite
|
84
|
+
hashed_password, salt = FidesUser.hash_password(
|
85
|
+
data.get("password") or str(uuid.uuid4())
|
86
|
+
)
|
100
87
|
|
101
88
|
user = super().create(
|
102
89
|
db,
|
@@ -109,7 +96,6 @@ class FidesUser(Base):
|
|
109
96
|
"last_name": data.get("last_name"),
|
110
97
|
"disabled": data.get("disabled") or False,
|
111
98
|
"disabled_reason": data.get("disabled_reason"),
|
112
|
-
"password_login_enabled": data.get("password_login_enabled"),
|
113
99
|
},
|
114
100
|
check_name=check_name,
|
115
101
|
)
|
@@ -118,9 +104,6 @@ class FidesUser(Base):
|
|
118
104
|
|
119
105
|
def credentials_valid(self, password: str, encoding: str = "UTF-8") -> bool:
|
120
106
|
"""Verifies that the provided password is correct."""
|
121
|
-
if self.salt is None:
|
122
|
-
return False
|
123
|
-
|
124
107
|
provided_password_hash = hash_credential_with_salt(
|
125
108
|
password.encode(encoding),
|
126
109
|
self.salt.encode(encoding),
|
@@ -67,8 +67,6 @@ class FidesUserInvite(Base):
|
|
67
67
|
|
68
68
|
def invite_code_valid(self, invite_code: str, encoding: str = "UTF-8") -> bool:
|
69
69
|
"""Verifies that the provided invite code is correct."""
|
70
|
-
if self.salt is None:
|
71
|
-
return False
|
72
70
|
|
73
71
|
invite_code_hash = hash_credential_with_salt(
|
74
72
|
invite_code.encode(encoding),
|