/ backend / src / api / container_spec / errors.rs
errors.rs
 1  use rocket::{http::Header, serde::json::Json};
 2  use serde::{Deserialize, Serialize};
 3  
 4  use crate::config::Config;
 5  
 6  #[derive(Serialize, Deserialize, Debug, Clone)]
 7  #[serde(rename_all = "SCREAMING_SNAKE_CASE")]
 8  pub enum OCIError {
 9      BlobUnknown,
10      BlobUploadInvalid,
11      BlobUploadUnknown,
12      DigestInvalid,
13      ManifestBlobUnknown,
14      ManifestInvalid,
15      ManifestUnverified,
16      NameInvalid,
17      NameUnknown,
18      SizeInvalid,
19      TagInvalid,
20      Unauthorized,
21      Denied,
22      Unsupported,
23  }
24  
25  impl OCIError {
26      pub fn to_response(self) -> ContainerSpecError {
27          let (message, detail) = match self {
28              OCIError::BlobUnknown => todo!(),
29              OCIError::BlobUploadInvalid => todo!(),
30              OCIError::BlobUploadUnknown => todo!(),
31              OCIError::DigestInvalid => todo!(),
32              OCIError::ManifestBlobUnknown => todo!(),
33              OCIError::ManifestInvalid => todo!(),
34              OCIError::ManifestUnverified => todo!(),
35              OCIError::NameInvalid => todo!(),
36              OCIError::NameUnknown => todo!(),
37              OCIError::SizeInvalid => todo!(),
38              OCIError::TagInvalid => todo!(),
39              OCIError::Unauthorized => ("access to the requested resource is not authorized", "Unable to authorize client, please follow indicated authorization steps before proceeding"),
40              OCIError::Denied => todo!(),
41              OCIError::Unsupported => todo!(),
42          };
43  
44          ContainerSpecError {
45              code: self,
46              message: message.to_string(),
47              detail: detail.to_string(),
48          }
49      }
50  }
51  
52  #[derive(Serialize, Debug, Clone)]
53  pub struct ContainerSpecErrorResponse {
54      errors: Vec<ContainerSpecError>,
55  }
56  
57  #[derive(Serialize, Debug, Clone)]
58  pub struct ContainerSpecError {
59      code: OCIError,
60      message: String,
61      detail: String,
62  }
63  
64  #[derive(Responder, Debug, Clone)]
65  #[response(status = 401, content_type = "json")]
66  pub struct UnauthorizedResponse {
67      inner: Json<ContainerSpecErrorResponse>,
68      www_authenticate: Header<'static>,
69  }
70  
71  impl UnauthorizedResponse {
72      pub fn new(config: &Config) -> Self {
73          Self {
74              inner: Json(ContainerSpecErrorResponse {
75                  errors: vec![OCIError::Unauthorized.to_response()],
76              }),
77              www_authenticate: Header::new(
78                  "www-authenticate",
79                  format!(
80                      r#"Bearer realm="{}", service="{}", scope=""#,
81                      config.accounts_rs_auth_endpoint, config.auth_service
82                  ),
83              ),
84          }
85      }
86  }