cat_gateway/service/common/responses/
code_403_forbidden.rs

1//! Define `Forbidden` response type.
2
3use poem_openapi::{
4    types::{Example, ToJSON},
5    Object,
6};
7use uuid::Uuid;
8
9use crate::service::{common, common::types::array_types::impl_array_types};
10
11#[derive(Object)]
12#[oai(example)]
13/// The client has not sent valid authentication credentials for the requested
14/// resource.
15pub(crate) struct Forbidden {
16    /// Unique ID of this Server Error so that it can be located easily for debugging.
17    id: common::types::generic::error_uuid::ErrorUuid,
18    /// Error message.
19    // Will not contain sensitive information, internal details or backtraces.
20    msg: common::types::generic::error_msg::ErrorMessage,
21    /// List or Roles required to access the resource.
22    // TODO: This should be a Vector of defined Roles/Grants.
23    // When those are defined, use that type instead of "String"
24    // It should look like an enum.
25    required: Option<RoleList>,
26}
27
28impl Forbidden {
29    /// Create a new Server Error Response Payload.
30    pub(crate) fn new(msg: Option<String>, roles: Option<Vec<String>>) -> Self {
31        let msg = msg.unwrap_or(
32            "Your request was not successful because your authentication credentials do not have the required roles for the requested resource.".to_string(),
33        );
34        let id = Uuid::new_v4();
35
36        Self {
37            id: id.into(),
38            msg: msg.into(),
39            required: roles.map(Into::into),
40        }
41    }
42}
43
44impl Example for Forbidden {
45    /// Example for the Too Many Requests Payload.
46    fn example() -> Self {
47        Self::new(
48            None,
49            Some(vec!["VOTER".to_string(), "PROPOSER".to_string()]),
50        )
51    }
52}
53
54// List of roles
55impl_array_types!(
56    RoleList,
57    String,
58    Some(poem_openapi::registry::MetaSchema {
59        example: Self::example().to_json(),
60        max_items: Some(100),
61        items: Some(Box::new(poem_openapi::registry::MetaSchemaRef::Inline(
62            Box::new(poem_openapi::registry::MetaSchema::new("string").merge(
63                poem_openapi::registry::MetaSchema {
64                    max_length: Some(100),
65                    pattern: Some("^[0-9a-zA-Z].*$".into()),
66                    ..poem_openapi::registry::MetaSchema::ANY
67                }
68            ))
69        ))),
70        ..poem_openapi::registry::MetaSchema::ANY
71    })
72);
73
74impl Example for RoleList {
75    fn example() -> Self {
76        Self(vec!["VOTER".to_string(), "PROPOSER".to_string()])
77    }
78}