-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding source and submitted_by fields to privacy request #5206
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 1 Skipped Deployment
|
clients/admin-ui/src/features/privacy-requests/privacy-requests.slice.ts
Show resolved
Hide resolved
getattr(privacy_request_data, "source") | ||
== PrivacyRequestSource.request_manager | ||
): | ||
kwargs["submitted_by"] = user_id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This ticket adds a new submitted_by
field to privacy requests so we can track the user that submitted a request from the Request manager page within the Admin UI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we have an enum set of accepted optional privacy req kwargs somewhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No enums here unfortunately but I do have a test for this so we'll know if the kwarg name ever changes
fides Run #9659
Run Properties:
|
Project |
fides
|
Branch Review |
refs/pull/5206/merge
|
Run status |
Passed #9659
|
Run duration | 00m 38s |
Commit |
cc6eb2b3a3 ℹ️: Merge fa75aa11264c5a08020860a630cec374d2d33fe7 into b47f171d9b5b4ee1dd1236e824c1...
|
Committer | Adrian Galvan |
View all properties for this run ↗︎ |
Test results | |
---|---|
Failures |
0
|
Flaky |
0
|
Pending |
0
|
Skipped |
0
|
Passing |
4
|
Upgrade your plan to view test results. | |
View all changes introduced in this branch ↗︎ |
Starting review... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great @galvana , just a couple clean-up items / suggestions for improvement.
Also kudos for knocking out general improvements to the codebase as you come across them!!
clients/fides-js/src/services/api.ts
Outdated
@@ -183,7 +183,7 @@ export const patchUserPreference = async ( | |||
debugLog(options.debug, "Calling Fides save preferences API"); | |||
const fetchOptions: RequestInit = { | |||
...PATCH_FETCH_OPTIONS, | |||
body: JSON.stringify(preferences), | |||
body: JSON.stringify({ ...preferences, source: "Fides.js" }), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
possible to use a shared CONST here? instead of "Fides.js"
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// See: PrivacyRequestSource enum in Fides
const REQUEST_SOURCE = "Fides.js";
if not include_consent_webhook_requests: | ||
query = query.filter( | ||
or_( | ||
PrivacyRequest.source != PrivacyRequestSource.consent_webhook, | ||
PrivacyRequest.source.is_(None), | ||
) | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm do we want to filter where source is None? Won't this affect the ability to filter for privacy requests created before this work gets merged?
@@ -2003,6 +2021,9 @@ def create_privacy_request_func( | |||
"Application redis cache required, but it is currently disabled! Please update your application configuration to enable integration with a redis cache." | |||
) | |||
|
|||
if privacy_preferences is None: | |||
privacy_preferences = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we set this default in the func signature instead?
privacy_preferences: Optional[
List[PrivacyPreferenceHistory]
] = []
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I set this as a None
value to avoid this gotcha with mutable default arguments https://docs.python-guide.org/writing/gotchas/. We don't mutate privacy_preferences
in our function right now but I figured I'd do this now to avoid any pitfalls in the future.
I also changed the None
check to this to let mypy know that privacy_preferences
will be valued, even if it's an empty array
privacy_preferences = privacy_preferences or []
getattr(privacy_request_data, "source") | ||
== PrivacyRequestSource.request_manager | ||
): | ||
kwargs["submitted_by"] = user_id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we have an enum set of accepted optional privacy req kwargs somewhere?
@@ -294,6 +299,7 @@ class PrivacyRequest( | |||
cancel_reason = Column(String(200)) | |||
canceled_at = Column(DateTime(timezone=True), nullable=True) | |||
consent_preferences = Column(MutableList.as_mutable(JSONB), nullable=True) | |||
source = Column(String, nullable=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we instead use a Column(EnumColumn(PrivacyRequestSource), nullable=True)
here? This way we can still have the benefit of explicitly defining what we should expect in this column without having the enums formalized in the DB?
See how we do something similar with method = Column(EnumColumn(ConsentMethod))
in our PrivacyPreferenceHistory
model
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good suggestion 👍
"""The source where the privacy request originated from""" | ||
|
||
privacy_center = "Privacy Center" | ||
request_manager = "Request Manager" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you add a comment as to what each of these sources mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated the docstring
The source where the privacy request originated from
- Privacy Center: Request created from the Privacy Center
- Request Manager: Request submitted from the Admin UI's Request manager page
- Consent Webhook: Request created as a side-effect of a consent webhook request (bidirectional consent)
- Fides.js: Request created as a side-effect of a privacy preference update from Fides.js
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks! This is awesome!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review @eastandwestwind! I made the suggestions you recommended and I left some responses to your questions and concerns
clients/fides-js/src/services/api.ts
Outdated
@@ -183,7 +183,7 @@ export const patchUserPreference = async ( | |||
debugLog(options.debug, "Calling Fides save preferences API"); | |||
const fetchOptions: RequestInit = { | |||
...PATCH_FETCH_OPTIONS, | |||
body: JSON.stringify(preferences), | |||
body: JSON.stringify({ ...preferences, source: "Fides.js" }), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// See: PrivacyRequestSource enum in Fides
const REQUEST_SOURCE = "Fides.js";
@@ -294,6 +299,7 @@ class PrivacyRequest( | |||
cancel_reason = Column(String(200)) | |||
canceled_at = Column(DateTime(timezone=True), nullable=True) | |||
consent_preferences = Column(MutableList.as_mutable(JSONB), nullable=True) | |||
source = Column(String, nullable=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good suggestion 👍
"""The source where the privacy request originated from""" | ||
|
||
privacy_center = "Privacy Center" | ||
request_manager = "Request Manager" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated the docstring
The source where the privacy request originated from
- Privacy Center: Request created from the Privacy Center
- Request Manager: Request submitted from the Admin UI's Request manager page
- Consent Webhook: Request created as a side-effect of a consent webhook request (bidirectional consent)
- Fides.js: Request created as a side-effect of a privacy preference update from Fides.js
getattr(privacy_request_data, "source") | ||
== PrivacyRequestSource.request_manager | ||
): | ||
kwargs["submitted_by"] = user_id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No enums here unfortunately but I do have a test for this so we'll know if the kwarg name ever changes
if not include_consent_webhook_requests: | ||
query = query.filter( | ||
or_( | ||
PrivacyRequest.source != PrivacyRequestSource.consent_webhook, | ||
PrivacyRequest.source.is_(None), | ||
) | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This threw me off at first too but if I only do
PrivacyRequest.source != PrivacyRequestSource.consent_webhook,
The query will only return privacy requests where source
is valued and doesn't equal consent_webook
but it won't automatically include any privacy requests with null source
values. So the full statement should read:
If we're not including consent webhook requests, then give me all the privacy requests where source
(valued) does not equal consent_webhook
or all privacy requests where source
is null (inclusive or).
@@ -2003,6 +2021,9 @@ def create_privacy_request_func( | |||
"Application redis cache required, but it is currently disabled! Please update your application configuration to enable integration with a redis cache." | |||
) | |||
|
|||
if privacy_preferences is None: | |||
privacy_preferences = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I set this as a None
value to avoid this gotcha with mutable default arguments https://docs.python-guide.org/writing/gotchas/. We don't mutate privacy_preferences
in our function right now but I figured I'd do this now to avoid any pitfalls in the future.
I also changed the None
check to this to let mypy know that privacy_preferences
will be valued, even if it's an empty array
privacy_preferences = privacy_preferences or []
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review @eastandwestwind! I made the suggestions you recommended and I left some responses to your questions and concerns
@@ -2003,6 +2021,8 @@ def create_privacy_request_func( | |||
"Application redis cache required, but it is currently disabled! Please update your application configuration to enable integration with a redis cache." | |||
) | |||
|
|||
privacy_preferences = privacy_preferences or [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the way I did this check so my response to your old comment got flagged as "outdated" but I wanted to make sure you read my response.
I set this as a None
value to avoid this gotcha with mutable default arguments https://docs.python-guide.org/writing/gotchas/. We don't mutate privacy_preferences
in our function right now but I figured I'd do this now to avoid any pitfalls in the future.
I also changed the None
check to this to let mypy know that privacy_preferences
will be valued, even if it's an empty array
privacy_preferences = privacy_preferences or []
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh noooo this is the worst gotcha! Wow, thanks for explaining!
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5206 +/- ##
=======================================
Coverage 86.41% 86.41%
=======================================
Files 362 362
Lines 22765 22781 +16
Branches 3056 3058 +2
=======================================
+ Hits 19672 19687 +15
Misses 2537 2537
- Partials 556 557 +1 ☔ View full report in Codecov by Sentry. |
fides Run #9660
Run Properties:
|
Project |
fides
|
Branch Review |
main
|
Run status |
Passed #9660
|
Run duration | 00m 39s |
Commit |
619ca8589e: Adding source and submitted_by fields to privacy request (#5206)
|
Committer | Adrian Galvan |
View all properties for this run ↗︎ |
Test results | |
---|---|
Failures |
0
|
Flaky |
0
|
Pending |
0
|
Skipped |
0
|
Passing |
4
|
Upgrade your plan to view test results. | |
View all changes introduced in this branch ↗︎ |
Closes PROD-1809 and PROD-1788
❗Contains migration to add new columns to the
consentrequest
andprivacyrequest
tablesDescription Of Changes
Updating privacy requests to include an optional
source
field. The options are currently restricted to the following:Privacy Center
- The most common source, for requests sent from the Privacy CenterRequest Manager
- For request submitted via the Request manager page in the Admin UI (plus only)Consent Webhook
- For requests created as part of the consent webhook flow for bidirectional consent (plus only)This is a plus feature so I tried to draw the line in a reasonable way that wouldn't add to much scope. For example, I decided against creating overrides for the
/consent
and/privacy-request
endpoints in plus that accept thesource
value in the request.Code Changes
Privacy Center
Request Manager
and to store the submitting user ID under the new privacy request column,submitted_by
source
column in the privacy request table and privacy request detail page if plus is enabledSteps to Confirm
Pre-Merge Checklist
CHANGELOG.md
main
downgrade()
migration is correct and works