Skip to content
This repository has been archived by the owner on Nov 30, 2022. It is now read-only.

Add Foundation for "Manual Webhooks" [#1224] #1267

Merged
merged 9 commits into from
Sep 8, 2022

Conversation

pattisdr
Copy link
Contributor

@pattisdr pattisdr commented Sep 7, 2022

❗ Contains migration. Verify downrev before merging.'
👉 Documentation will be added in follow-up #1228 once we've actually wired up manual webhooks

Purpose

Adds the foundation for a new connector type we're calling the "Manual Webhook". Manual Webhooks are a simple connector type that allows data to be manually uploaded for an access request. Erasure requests are out of scope here. Importantly, the manual webhook is not a part of the graph. Request execution will expect data for the manual webhooks to be uploaded before the graph traversal runs. Any manual data collected via a manual webhook will be returned as-is directly to the user. There is no filtering on data category, its outputs aren't used by any other connector, and the only inputs it can use are the original identity data.

Note that this differs from an existing "manual" connector type we have on the backend that plugs into the traversal. #554 #571

Changes

  • Add a new AccessManualWebhook model, a new "manual_webhook" ConnectionType, and a new "requires_input" PrivacyRequestStatus.
  • Add endpoints to get/create/update/delete the single AccessManualWebhook associated with a ConnectionConfig of type "manual_webhook". The new AccessManualWebhook primarily stores the fields that we are going to need to upload. The values uploaded will be passed directly to the user.
  • Add requires_input privacy request status to the frontend
  • Exposes a "manual_webhook" as a manual connector type.

Checklist

  • Update CHANGELOG.md file
    • Merge in main so the most recent CHANGELOG.md file is being appended to
    • Add description within the Unreleased section in an appropriate category. Add a new category from the list at the top of the file if the needed one isn't already there.
    • Add a link to this PR at the end of the description with the PR number as the text. example: #1
  • Applicable documentation updated (guides, quickstart, postman collections, tutorial, fidesdemo, database diagram.
  • If docs updated (select one):
    • documentation complete, or draft/outline provided (tag docs-team to complete/review on this branch)
    • documentation issue created (tag docs-team to complete issue separately)
  • Good unit test/integration test coverage
  • This PR contains a DB migration. If checked, the reviewer should confirm with the author that the down_revision correctly references the previous migration before merging
  • The Run Unsafe PR Checks label has been applied, and checks have passed, if this PR touches any external services

Ticket

Fixes #1224

…nType, and a new "requires_input" PrivacyRequestStatus.

- Add endpoints to get/create/update/delete the single AccessManualWebhook associated with a ConnectionConfig of type "manual_webhook".  The new AccessManualWebhook primarily stores the fields that we are going to need to upload. The values uploaded will be passed directly to the user.
…webhooks

# Conflicts:
#	tests/ops/api/v1/endpoints/test_connection_config_endpoints.py

Bump downrev.
…s a "manual_webhook" as a manual connector type.
…esponding webhook to the postman collection. Clean up some copy/paste issues with the email connector.
Comment on lines +10 to +25
class AccessManualWebhook(Base):
"""Describes a manual datasource that will be used for access requests.

These data sources are not treated as part of the traversal. Data uploaded
for an AccessManualWebhook is passed on as-is to the end user and is
not consumed as part of the graph.
"""

connection_config_id = Column(
String, ForeignKey(ConnectionConfig.id_field_path), unique=True, nullable=False
)
connection_config = relationship(
ConnectionConfig, backref=backref("access_manual_webhook", uselist=False)
)

fields = Column(MutableList.as_mutable(JSONB), nullable=False)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

manual_webhook ConnectionConfigs will not have DatasetConfigs associated with them because they are not part of the graph. Instead, we will define the fields that we need to collect in the AccessManualWebhook table. These AccessManualWebhooks will run first as part of privacy request execution, requesting manual input from a fidesops admin, and putting the privacy request in a requires_input state before data has been uploaded and then we'll proceed with building a graph and executing the remainder of the privacy request.

Comment on lines +79 to +94
if system_type == SystemType.manual or system_type is None:
manual_types: List[str] = sorted(
[
manual_type.value
for manual_type in ConnectionType
if manual_type == ConnectionType.manual_webhook
and is_match(manual_type.value)
]
)
connection_system_types.extend(
[
ConnectionSystemTypeMap(identifier=item, type=SystemType.manual)
for item in manual_types
]
)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This adds a new "manual" system type, which has one connector associated with it, the new manual_webhook construct.

@router.post(
ACCESS_MANUAL_WEBHOOK,
status_code=HTTP_201_CREATED,
dependencies=[Security(verify_oauth_client, scopes=[WEBHOOK_CREATE_OR_UPDATE])],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm reusing existing webhook scopes - I thought they were similar enough here. We have PolicyWebhooks where a user can define a series of requests that we should make before and after PrivacyRequest execution, some of which are capable of taking in data and adding it to known identities. Similarly, these manual webhooks run outside of the privacy request execution.

@@ -117,6 +117,7 @@ class PrivacyRequestStatus(str, EnumType):
"""Enum for privacy request statuses, reflecting where they are in the Privacy Request Lifecycle"""

identity_unverified = "identity_unverified"
requires_input = "requires_input"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will be implemented in the followup PR when we actually wire up the ManualWebhook. Privacy requests that still need manual input from a manual_webhook will be placed in a "requires_input" state.

As an aside, we're getting a lot of privacy request statuses, and most statuses have specific statuses that they transition to next, and ones in which they should never transition to. It might be nice to formalize this at some point with some sort of state machine.

Comment on lines 22 to 23
pii_field: ManualWebhookFieldType
dsr_package_label: Optional[ManualWebhookFieldType]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way I understand it, the pii_field will be what we display to the user who is manually uploading data for the given subject, and the dsr_package_label will be the key that is used in the json blob that we upload to the user. I am making the dsr_package_label optional and creating it from the pii field if it doesn't exist.

pattisdr and others added 4 commits September 8, 2022 11:48
… to fetch secret types for this schema - we are not currently collecting secrets for this connector at this time but will in the futuer.
Co-authored-by: Paul Sanders <paul@ethyca.com>
@sanders41 sanders41 merged commit dcfffce into main Sep 8, 2022
@sanders41 sanders41 deleted the fidesops_1224_manual_webhooks branch September 8, 2022 17:31
@pattisdr
Copy link
Contributor Author

pattisdr commented Sep 8, 2022

Thank you for your review @sanders41! ⭐

sanders41 pushed a commit that referenced this pull request Sep 22, 2022
* Add a new AccessManualWebhook model, a new "manual_webhook" ConnectionType, and a new "requires_input" PrivacyRequestStatus.

- Add endpoints to get/create/update/delete the single AccessManualWebhook associated with a ConnectionConfig of type "manual_webhook".  The new AccessManualWebhook primarily stores the fields that we are going to need to upload. The values uploaded will be passed directly to the user.

* Add requires_input privacy request status to the frontend, and exposes a "manual_webhook" as a manual connector type.

* Add the endpoints to create the manual connection config and its corresponding webhook to the postman collection. Clean up some copy/paste issues with the email connector.

* Run black.

* Add an empty ManualWebhookSchema to prevent a KeyError if you attempt to fetch secret types for this schema - we are not currently collecting secrets for this connector at this time but will in the futuer.

* Apply suggestions from code review

Co-authored-by: Paul Sanders <paul@ethyca.com>

* Catch possible integrity error.

Co-authored-by: Paul Sanders <paul@ethyca.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Backend - Create new connection config type for manual webhooks
2 participants