cognitect-labs / aws-api

AWS, data driven
Apache License 2.0
724 stars 100 forks source link

Missing `GeneratePresignedUrlRequest` S3 operation #236

Open onetom opened 1 year ago

onetom commented 1 year ago

Dependencies

{:deps {com.cognitect.aws/api       {:mvn/version "0.8.656"}
        com.cognitect.aws/endpoints {:mvn/version "1.1.12.437"}
        com.cognitect.aws/s3        {:mvn/version "825.2.1250.0"}}}

Description with failing test case

clojure -M \
  -e "(use 'cognitect.aws.client.api)" \
  -e "(run! println (keys (ops (client {:api :s3}))))" \
  | grep -i -E 'generate|sign|url'

I was expecting to find this GeneratePresignedUrlRequest operation in the S3 API.

Is it an oversight or it is not an actual HTTP API request, but something being computed locally?

Would it make sense to have an example in the documentation to show how to do this?

dchelimsky commented 1 year ago

There is no http endpoint for this, so It has to be calculated locally, and the algorithm is subtly different from calculating the signatures for all the other 1000s of operations. It's something we've wanted to support, but just haven't had time to do it since it would require a bit of redesign. There is experimental work on the execution-flow branch, but that represents a radical redesign and it's nearly 3 years old now, so it will be a non-trivial effort to extract that work when we get there.

Yes, it would make sense to have an example if we could provide one, but right now there is no means for you to get all the information you'd need to build the request yourself.

This is on our backlog, but it's not going to be resolved in the immediate near term.

onetom commented 1 year ago

Given com.amazonaws/aws-java-sdk-s3 {:mvn/version "1.12.445"} in deps.edn, the following seems to work:

(ns x
  (:import (java.util Date)
           (java.time Clock Instant)
           (com.amazonaws HttpMethod)
           (com.amazonaws.services.s3 AmazonS3ClientBuilder)
           (com.amazonaws.services.s3.model GeneratePresignedUrlRequest)))

(comment
  (-> (AmazonS3ClientBuilder/standard)
      (.build)
      (.generatePresignedUrl (-> (GeneratePresignedUrlRequest. "<bucket-name>"
                                                               "<object/key>")
                                 (.withMethod HttpMethod/GET)
                                 (.withExpiration (-> (Clock/systemUTC)
                                                      (Instant/now)
                                                      (.plusSeconds 30)
                                                      (Date/from))))))
  )

The problem is, that we would need to duplicate the logic of creating this Java S3 client the same way (same AWS profile & region or other creds provider) we created the cognitect/aws-api client with :/