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

Add GCS signed URL support #5300

Merged
merged 29 commits into from
Apr 4, 2024
Merged

Conversation

l1nxy
Copy link
Contributor

@l1nxy l1nxy commented Jan 13, 2024

Which issue does this PR close?

Closes #5233.

Rationale for this change

Adding support for GCS Signed URL generation.

What changes are included in this PR?

Are there any user-facing changes?

@github-actions github-actions bot added the object-store Object Store Interface label Jan 13, 2024
@l1nxy l1nxy marked this pull request as draft January 13, 2024 14:18
@l1nxy l1nxy changed the title add util function for gcp sign url Add GCS signed URL support Jan 13, 2024
@l1nxy
Copy link
Contributor Author

l1nxy commented Feb 2, 2024

@tustvold Hi, I have completed the first version of GCP signed URL generation. Could you please take some time to review it? and then i can update the code gradually.
Regarding the credential structure, I think we need to add the client email field. This is because the signed URL generation requires the client email, not just the sign blob method. Even when generating a signed URL with an HMAC key, we still need the client email to create credentials with scope, the code example showed.

https://github.com/GoogleCloudPlatform/python-docs-samples/blob/6e591bec774bf0f3bf53864146f24028b98ac8df/storage/signed_urls/generate_signed_urls.py#L63-L65

next, i will add test for the sign blob and add code for using HAMC key to generating signed URL.

@tustvold
Copy link
Contributor

tustvold commented Feb 6, 2024

Sorry for the delay in reviewing this, I wonder if instead of modifying GcpCredential which is a breaking change, we could introduce a GcpSigningCredential with something like

struct GcpSigningCredential {
    credential: GcpCredential,
    email: String,
}

This could then have a separate CredentialProvider<GcpSigningCredential>

@l1nxy
Copy link
Contributor Author

l1nxy commented Feb 18, 2024

I completely agree with you. However, a question arises: if I add a new credential type, will all implementations for TokenProvider need to be rewritten for GcpSigningCredential? This is because it involves additional operations to retrieve the client's email address. I am wondering if this would be acceptable.

@tustvold
Copy link
Contributor

I would think you could use composition to avoid code duplication, with the GcpSigningCredential implementation calling through to the GcpCredential implementation

@s-i-l-k-e
Copy link

@l1nxy how is this going? Let me know if there is anything I can do to help -- would love to use this!

@l1nxy
Copy link
Contributor Author

l1nxy commented Feb 28, 2024

@l1nxy how is this going? Let me know if there is anything I can do to help -- would love to use this!

Apologies for the delayed update. I have been busy and unable to dedicate time to this. If you would like to proceed, feel free to do so, and I will close the pr.

@l1nxy
Copy link
Contributor Author

l1nxy commented Mar 11, 2024

@s-i-l-k-e Hi, I have time now and will continue working on this.

@l1nxy
Copy link
Contributor Author

l1nxy commented Mar 15, 2024

@tustvold Hi, sorry for the delayed update, i have a question and hope you can help me. my question is which part modification will cause a breaking change, can i add GcpSigningCredential provider to GoogleCloudStorageBuilder and GoogleStorageConfig?

@tustvold
Copy link
Contributor

So long as you don't change an existing public API it won't be a breaking change. So you could add additional fields or new methods, but not change existing ones

@l1nxy
Copy link
Contributor Author

l1nxy commented Mar 29, 2024

@tustvold Hi, I made changes to the sign URL implementation by adding a GcpSigningCredential Provider. There are some changes that I'm unsure about. The ServiceAccountCredentials now includes the Clone trait because I cannot construct both GcpCredentialProvider and GcpSigningCredentialProvider using just one ServiceAccountCredentials instance simultaneously.

Thank you for your patience and help.

@l1nxy l1nxy marked this pull request as ready for review March 31, 2024 12:37
@l1nxy l1nxy marked this pull request as draft March 31, 2024 14:05
@l1nxy l1nxy marked this pull request as ready for review April 1, 2024 10:41
@l1nxy
Copy link
Contributor Author

l1nxy commented Apr 1, 2024

@tustvold Hi, I tested it using my GCP account. The ServiceAccount approach yielded correct results, but testing the email from the meta server was not done. Perhaps adding more unit tests or addressing some code issues. maybe i can add sign by HMAC key.

the test result is:
Snipaste_2024-04-01_18-46-52

Copy link
Contributor

@tustvold tustvold left a comment

Choose a reason for hiding this comment

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

This is looking really nice, I took the liberty of pushing some relatively minor API tweaks. I'll test this out tomorrow, and assuming that all works get it merged


/// A private RSA key for a service account
#[derive(Debug)]
pub struct ServiceAccountKey(RsaKeyPair);
Copy link
Contributor

Choose a reason for hiding this comment

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

This prevents the ring types from leaking into the public API, whilst still avoiding needing to parse the RSA key for every sign request

@@ -295,21 +376,6 @@ fn seconds_since_epoch() -> u64 {
.as_secs()
}

fn decode_first_rsa_key(private_key_pem: String) -> Result<RsaKeyPair> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Moving this into ServiceAccountKey avoids doing this multiple times

@tustvold
Copy link
Contributor

tustvold commented Apr 4, 2024

I've tested this and it appears to be working correctly 🎉

Thank you for this, epic work

@tustvold tustvold merged commit 5a0baf1 into apache:master Apr 4, 2024
13 checks passed
@l1nxy l1nxy deleted the add-gcp-sign-url-support branch April 4, 2024 15:23
@alamb
Copy link
Contributor

alamb commented Apr 4, 2024

Thank you @l1nxy and @tustvold -- this is a very nice feature

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
object-store Object Store Interface
Projects
None yet
Development

Successfully merging this pull request may close these issues.

GCS Signed URL Support
4 participants