Skip to content
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

Attachment blob upload #1229

Merged
merged 17 commits into from
Mar 30, 2021
Merged

Attachment blob upload #1229

merged 17 commits into from
Mar 30, 2021

Conversation

MGibson1
Copy link
Member

Overview

Server-side changes to support direct upload for cipher attachments. Similar changes to #1188.

Special care must be taken handling attachments which were uploaded prior to these changes. There are a few concerns here. Chief is that the attachments container is publicly available on the blob level. We can't give direct links to those attachments without either breaking old clients or allowing unfettered access to our storage accounts.

Therefore, a second attachments-v2 storage container is necessary. The container an attachment is stored in is saved along its other metadata, assuming attachments if not present.

Also Limits Send and Attachment size to 500MB per discussion this morning. Further evaluation on legitimate use cases may push this limit further, so it's defined as a couple of constants for Send and Cipher Attachments separately.

Files Changed

  • CiphersController: New endpoints for attachment upload and download
    • PostAttachment (v2): Notification to create an attachment of a certain size with associated with a cipher item. This is just the request part of the v1 PostAttachment endpoint. A URL to upload the file to is included in the response
    • RenewFileUploadUrl: Uploads are limited to 1 min. This endpoint allows renewal of the upload link if needed for large uploads as long as the blob has not yet been created
    • PostFileForExistingAttachment: Used for local attachment storage solutions. Allows upload of files direct to Bitwarden.
    • AzureValidateFile: Event Grid webhook endpoint to process Event Grid Events and validate files uploaded are of the size promised upon attachment creation.
  • EmergencyAccessController.cs: Emergency accesses with view permission need to be able to download attachments through emergency access.
  • SendsController/MultipartFormDataHelper: Rename method for code reuse
  • AttachmentRequestModel: Model specifying attachment data including whether or not the attachment is for an organization (adminRequest)
  • AttachmentUploadDataResponseModel: split attachment create response. Contains the created Cipher response (mini response for AdminRequests), a URL to upload data to, and the upload type (Azure vs Direct for self-hosted)
  • CipherAttachment: Validated property holds whether we have validated the Requested file size or not. Validated attachments will not renew upload URLs and have passed file size matching to within a specified limit (currently 1MB)
  • IAttachmentStorageService/NoopAttachmentStorageService: Interface and noop for direct attachment upload and validation.
  • CipherService:
    • CreateAttachmentForDelayedUploadAsync: Creates attachment and applies it to a Cipher. Stores the expected file size at creation time.
    • UploadFileForExistingAttachmentAsync: Uploads a file to the storage service. Exists for backwards compatibility with clients and local storage solutions
    • GetAttachmentDownloadDataAsync: Returns model specifying download information for an attachment. Used by CiphersController and EmergencyAccessController to allow for download of Cipher attachments.
    • ValidateCipherAttachmentFile: Handles validating actual file size on disk to the promised file size in the attachment request. If the size is not within a specified limit (Currently 1MB), the attachment is deleted.
  • EmergencyAccessService: GetAttachmentDownloadAsync returns model to allow client to directly download an attachment.
  • AzureAttachmentStorageService: Updates to allow for multiple containers storing attachments. The container used is specified in CipherAttachment.MetaData. attachments (the old container) is used everywhere unless using the new separate upload scheme by accessing GetAttachmentUploadUrlAsync, which only exists in new clients capable of uploading/downloading from Azure directly. Validate needs to set metadata since the blob is actually created by the client and we don't want to leave that job to trusting the client.
  • LocalAttachmentStorageService: Provide Upload URL and validate file sizes on disk.

@MGibson1 MGibson1 requested a review from a team March 22, 2021 17:10
Copy link
Contributor

@addisonbeck addisonbeck left a comment

Choose a reason for hiding this comment

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

A lot of this is a little whoosh for me (maybe a quick meeting to break down the changes for those of us that haven't been actively involved in this stuff?) but I did spot one weird thing 😁

src/Core/Models/Api/Request/AttachmentRequestModel.cs Outdated Show resolved Hide resolved
@addisonbeck addisonbeck requested a review from a team March 23, 2021 18:52
As long as we have the required information, we should always delete
attachments from each the Repository, the cipher in memory, and the
file storage service to ensure they're all synched.
@MGibson1 MGibson1 requested a review from cscharf March 30, 2021 18:03
@MGibson1 MGibson1 merged commit 022e404 into master Mar 30, 2021
@MGibson1 MGibson1 deleted the attachment-blob-upload branch March 30, 2021 23:41
addisonbeck pushed a commit that referenced this pull request Apr 8, 2021
* Add Cipher attachment upload endpoints

* Add validation bool to attachment storage data

This bool is used to determine whether or not to renew upload links

* Add model to request a new attachment to be made for later upload

* Add model to respond with created attachment.

The two cipher properties represent the two different
cipher model types that can be returned. Cipher Response from
personal items and mini response from organizations

* Create Azure SAS-authorized upload links for both one-shot and block uploads

* Add service methods to handle delayed upload and file size validation

* Add emergency access method for downloading attachments direct from Azure

* Add new attachment storage methods to other services

* Update service interfaces

* Log event grid exceptions

* Limit Send and Attachment Size to 500MB

* capitalize Key property

* Add key validation to Azure Event Grid endpoint

* Delete blob for unexpected blob creation events

* Set Event Grid key at API startup

* Change renew attachment upload url request path to match Send

* Shore up attachment cleanup method.

As long as we have the required information, we should always delete
attachments from each the Repository, the cipher in memory, and the
file storage service to ensure they're all synched.
jjlin added a commit to jjlin/vaultwarden that referenced this pull request May 25, 2021
jjlin added a commit to jjlin/vaultwarden that referenced this pull request May 25, 2021
jjlin added a commit to jjlin/vaultwarden that referenced this pull request May 25, 2021
jjlin added a commit to jjlin/vaultwarden that referenced this pull request May 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants