Add (untested) get_url_for_private_file
This commit is contained in:
parent
3e6a05cd04
commit
9e1f613aae
@ -9,7 +9,7 @@ use ariadne::ids::DecodingError;
|
||||
#[error("{}", .error_type)]
|
||||
pub struct OAuthError {
|
||||
#[source]
|
||||
pub error_type: OAuthErrorType,
|
||||
pub error_type: Box<OAuthErrorType>,
|
||||
|
||||
pub state: Option<String>,
|
||||
pub valid_redirect_uri: Option<ValidatedRedirectUri>,
|
||||
@ -32,7 +32,7 @@ impl OAuthError {
|
||||
/// See: IETF RFC 6749 4.1.2.1 (https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1)
|
||||
pub fn error(error_type: impl Into<OAuthErrorType>) -> Self {
|
||||
Self {
|
||||
error_type: error_type.into(),
|
||||
error_type: Box::new(error_type.into()),
|
||||
valid_redirect_uri: None,
|
||||
state: None,
|
||||
}
|
||||
@ -48,7 +48,7 @@ impl OAuthError {
|
||||
valid_redirect_uri: &ValidatedRedirectUri,
|
||||
) -> Self {
|
||||
Self {
|
||||
error_type: err.into(),
|
||||
error_type: Box::new(err.into()),
|
||||
state: state.clone(),
|
||||
valid_redirect_uri: Some(valid_redirect_uri.clone()),
|
||||
}
|
||||
@ -57,7 +57,7 @@ impl OAuthError {
|
||||
|
||||
impl actix_web::ResponseError for OAuthError {
|
||||
fn status_code(&self) -> StatusCode {
|
||||
match self.error_type {
|
||||
match *self.error_type {
|
||||
OAuthErrorType::AuthenticationError(_)
|
||||
| OAuthErrorType::FailedScopeParse(_)
|
||||
| OAuthErrorType::ScopesTooBroad
|
||||
|
@ -101,7 +101,7 @@ mod tests {
|
||||
);
|
||||
|
||||
assert!(validated.is_err_and(|e| matches!(
|
||||
e.error_type,
|
||||
*e.error_type,
|
||||
OAuthErrorType::RedirectUriNotConfigured(_)
|
||||
)));
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ use chrono::Utc;
|
||||
use hex::ToHex;
|
||||
use sha2::Digest;
|
||||
use std::path::PathBuf;
|
||||
use std::time::Duration;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct MockHost(());
|
||||
@ -47,6 +48,15 @@ impl FileHost for MockHost {
|
||||
})
|
||||
}
|
||||
|
||||
async fn get_url_for_private_file(
|
||||
&self,
|
||||
file_name: &str,
|
||||
_expiry: Duration,
|
||||
) -> Result<String, FileHostingError> {
|
||||
let cdn_url = dotenvy::var("CDN_URL").unwrap();
|
||||
Ok(format!("{cdn_url}/private/{file_name}"))
|
||||
}
|
||||
|
||||
async fn delete_file(
|
||||
&self,
|
||||
file_name: &str,
|
||||
|
@ -1,4 +1,5 @@
|
||||
use async_trait::async_trait;
|
||||
use std::time::Duration;
|
||||
use thiserror::Error;
|
||||
|
||||
mod mock;
|
||||
@ -10,8 +11,8 @@ pub use s3_host::S3Host;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum FileHostingError {
|
||||
#[error("S3 error: {0}")]
|
||||
S3Error(String),
|
||||
#[error("S3 error when {0}: {1}")]
|
||||
S3Error(&'static str, s3::error::S3Error),
|
||||
#[error("File system error in file hosting: {0}")]
|
||||
FileSystemError(#[from] std::io::Error),
|
||||
#[error("Invalid Filename")]
|
||||
@ -51,6 +52,12 @@ pub trait FileHost {
|
||||
file_bytes: Bytes,
|
||||
) -> Result<UploadFileData, FileHostingError>;
|
||||
|
||||
async fn get_url_for_private_file(
|
||||
&self,
|
||||
file_name: &str,
|
||||
expiry: Duration,
|
||||
) -> Result<String, FileHostingError>;
|
||||
|
||||
async fn delete_file(
|
||||
&self,
|
||||
file_name: &str,
|
||||
|
@ -10,6 +10,7 @@ use s3::bucket::Bucket;
|
||||
use s3::creds::Credentials;
|
||||
use s3::region::Region;
|
||||
use sha2::Digest;
|
||||
use std::time::Duration;
|
||||
|
||||
pub struct S3Host {
|
||||
public_bucket: Bucket,
|
||||
@ -46,16 +47,12 @@ impl S3Host {
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.map_err(|_| {
|
||||
FileHostingError::S3Error(
|
||||
"Error while creating credentials".to_string(),
|
||||
)
|
||||
.map_err(|e| {
|
||||
FileHostingError::S3Error("creating credentials", e.into())
|
||||
})?,
|
||||
)
|
||||
.map_err(|_| {
|
||||
FileHostingError::S3Error(
|
||||
"Error while creating Bucket instance".to_string(),
|
||||
)
|
||||
.map_err(|e| {
|
||||
FileHostingError::S3Error("creating Bucket instance", e)
|
||||
})?;
|
||||
|
||||
if bucket_uses_path_style {
|
||||
@ -100,11 +97,7 @@ impl FileHost for S3Host {
|
||||
content_type,
|
||||
)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
FileHostingError::S3Error(format!(
|
||||
"Error while uploading file {file_name} to S3: {err}"
|
||||
))
|
||||
})?;
|
||||
.map_err(|e| FileHostingError::S3Error("uploading file", e))?;
|
||||
|
||||
Ok(UploadFileData {
|
||||
file_name: file_name.to_string(),
|
||||
@ -118,6 +111,25 @@ impl FileHost for S3Host {
|
||||
})
|
||||
}
|
||||
|
||||
async fn get_url_for_private_file(
|
||||
&self,
|
||||
file_name: &str,
|
||||
expiry: Duration,
|
||||
) -> Result<String, FileHostingError> {
|
||||
let url = self
|
||||
.private_bucket
|
||||
.presign_get(
|
||||
format!("/{file_name}"),
|
||||
expiry.as_secs().try_into().unwrap(),
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
FileHostingError::S3Error("generating presigned URL", e)
|
||||
})?;
|
||||
Ok(url)
|
||||
}
|
||||
|
||||
async fn delete_file(
|
||||
&self,
|
||||
file_name: &str,
|
||||
@ -126,11 +138,7 @@ impl FileHost for S3Host {
|
||||
self.get_bucket(file_publicity)
|
||||
.delete_object(format!("/{file_name}"))
|
||||
.await
|
||||
.map_err(|err| {
|
||||
FileHostingError::S3Error(format!(
|
||||
"Error while deleting file {file_name} to S3: {err}"
|
||||
))
|
||||
})?;
|
||||
.map_err(|e| FileHostingError::S3Error("deleting file", e))?;
|
||||
|
||||
Ok(DeleteFileData {
|
||||
file_name: file_name.to_string(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user