cloud_file_signer/gcp/
mod.rs1use std::time::Duration;
4use std::time::SystemTime;
5
6use google_cloud_storage::client::Client;
7use google_cloud_storage::client::ClientConfig;
8use google_cloud_storage::sign::SignedURLMethod;
9use google_cloud_storage::sign::SignedURLOptions;
10
11use crate::CloudFileSigner;
12use crate::Permission;
13use crate::PresignedUrl;
14use crate::SignerError;
15
16use self::uri::GcpUri;
17
18mod uri;
19
20pub struct GcpFileSigner {
22 client: Client,
23}
24
25impl GcpFileSigner {
26 #[must_use]
28 pub fn new(client: Client) -> Self {
29 Self { client }
30 }
31
32 pub async fn from_env() -> Self {
34 let client_config = ClientConfig::default().with_auth().await.unwrap();
35 let client = Client::new(client_config);
36 Self { client }
37 }
38
39 async fn sign_read_request(
40 &self,
41 uri: &GcpUri,
42 expiration: Duration,
43 ) -> Result<PresignedUrl, SignerError> {
44 let valid_from = SystemTime::now();
45
46 let opts = SignedURLOptions {
47 expires: expiration,
48 method: SignedURLMethod::GET,
49 ..Default::default()
50 };
51
52 let signed_url = self
53 .client
54 .signed_url(uri.bucket(), uri.key(), None, None, opts)
55 .await
56 .map_err(|e| SignerError::other_error(e.to_string()))?;
57 Ok(PresignedUrl::new(signed_url, valid_from, expiration))
58 }
59}
60
61#[async_trait::async_trait]
62impl CloudFileSigner for GcpFileSigner {
63 async fn sign(
64 &self,
65 path: &str,
66 _valid_from: SystemTime,
67 expiration: Duration,
68 permission: Permission,
69 ) -> Result<PresignedUrl, SignerError> {
70 let uri = path.parse::<GcpUri>()?;
71 match permission {
72 Permission::Read => self.sign_read_request(&uri, expiration).await,
73 Permission::Write => Err(SignerError::permission_not_supported(
74 "GCP does not support write permissions",
75 )),
76 }
77 }
78}