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 support for signed upload urls. #1661

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

erikcarlsson
Copy link

No description provided.

@encore-cla
Copy link

encore-cla bot commented Dec 19, 2024

All committers have signed the CLA.

@erikcarlsson erikcarlsson force-pushed the sign-url branch 3 times, most recently from 3d7696f to 6bf10f5 Compare December 19, 2024 10:31
export interface UploadUrlOptions {
/** The expiration time of the url, in seconds from signing. The maximum
* value is seven days */
ttl: number;
Copy link
Member

Choose a reason for hiding this comment

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

Options should typically be optional:

Suggested change
ttl: number;
ttl?: number;

Copy link
Author

Choose a reason for hiding this comment

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

Done

#[napi]
pub async fn get_upload_url(
&self,
options: Option<UploadUrlOptions>, // TODO: can/should this be made non-optional, since ttl is required?
Copy link
Member

Choose a reason for hiding this comment

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

ttl shouldn't be required, right? The user-facing docs state the ttl defaults to 7 days if not provided

impl From<UploadUrlOptions> for core::UploadUrlOptions {
fn from(value: UploadUrlOptions) -> Self {
Self {
ttl: value.ttl as u64,
Copy link
Member

Choose a reason for hiding this comment

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

Convert this to the default of 7 days here

#[napi(object)]
#[derive(Debug, Default)]
pub struct UploadUrlOptions {
pub ttl: i64,
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
pub ttl: i64,
pub ttl: Option<i64>,


// WithTtl is used for signed URLs, to specify the lifetime of the generated
// URL, in seconds. The max value is seven days.
func WithTtl(ttl uint64) withTtlOption {
Copy link
Member

Choose a reason for hiding this comment

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

Go convention is TTL not Ttl. Also make it take a time.Duration instead of an uint64

Suggested change
func WithTtl(ttl uint64) withTtlOption {
func WithTTL(ttl time.Duration) withTTLOption {

Copy link
Author

Choose a reason for hiding this comment

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

Done

* Anyone with possession of the URL can write to the given object name
* without any additional auth.
*/
async getUploadUrl(name: string, options?: UploadUrlOptions): Promise<string> {
Copy link
Member

Choose a reason for hiding this comment

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

Let's make this signedUploadUrl, and have it return a SignedURL object with just a single field {url: string}

Suggested change
async getUploadUrl(name: string, options?: UploadUrlOptions): Promise<string> {
async signedUploadUrl(name: string, options?: SignedUploadUrlOptions): Promise<SignedURL> {

Copy link
Author

@erikcarlsson erikcarlsson Dec 20, 2024

Choose a reason for hiding this comment

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

Done. Although used SignedUploadUrl instead of SignedUrl. I think we ended up agreeing on making upload URLs more flexible, but not so far as folding in signed GET and PUT URLs in one type. But let me know if I got that wrong.

@@ -120,6 +120,7 @@ pub fn resolve_bucket_usage(data: &ResolveUsageData, bucket: Lrc<Bucket>) -> Opt
"list" => Operation::ListObjects,
"exists" | "attrs" => Operation::GetObjectMetadata,
"upload" => Operation::WriteObject,
"getUploadUrl" => Operation::WriteObject,
Copy link
Member

Choose a reason for hiding this comment

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

Rename to signedUploadUrl as per above. Also, let's introduce a new SignedUploadUrl operation (needs to be done in legacymeta.rs as well)

Copy link
Author

Choose a reason for hiding this comment

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

Done

client: client,
cfg: runtimeCfg,
client: client,
presign_client: s3.NewPresignClient(client),
Copy link
Member

Choose a reason for hiding this comment

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

Instantiate in clientForProvider instead so we can cache it

Copy link
Author

Choose a reason for hiding this comment

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

Done, thanks

client *s3.Client
cfg *config.Bucket
client *s3.Client
presign_client *s3.PresignClient
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
presign_client *s3.PresignClient
presignClient *s3.PresignClient

Bucket: &b.cfg.CloudName,
Key: &object,
}
sign_opts := func(opts *s3.PresignOptions) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
sign_opts := func(opts *s3.PresignOptions) {
signOpts := func(opts *s3.PresignOptions) {

sign_opts := func(opts *s3.PresignOptions) {
opts.Expires = time.Duration(data.Ttl) * time.Second
}
req, err := b.presign_client.PresignPutObject(data.Ctx, &params, sign_opts)
Copy link
Member

Choose a reason for hiding this comment

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

Do the error check here instead

Suggested change
req, err := b.presign_client.PresignPutObject(data.Ctx, &params, sign_opts)
req, err := b.presign_client.PresignPutObject(data.Ctx, &params, sign_opts)
if err != nil {
return "", mapErr(err)
}
return req.URL, nil

@erikcarlsson erikcarlsson force-pushed the sign-url branch 2 times, most recently from 5790283 to 3b6d7b6 Compare December 20, 2024 18:26
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.

2 participants