Skip to main content

objectstore_server/auth/
error.rs

1use thiserror::Error;
2
3/// Error type for different authorization failure scenarios.
4#[derive(Error, Debug, PartialEq)]
5pub enum AuthError {
6    /// Indicates that something about the request prevented authorization verification from
7    /// happening properly.
8    #[error("bad request: {0}")]
9    BadRequest(&'static str),
10
11    /// Indicates that something about Objectstore prevented authorization verification from
12    /// happening properly.
13    #[error("internal error: {0}")]
14    InternalError(String),
15
16    /// Indicates that the provided authorization token/signature is invalid (e.g. expired or malformed).
17    #[error("failed to decode token: {0}")]
18    ValidationFailure(#[from] jsonwebtoken::errors::Error),
19
20    /// Indicates that an otherwise-valid token/signature was unable to be verified with configured keys.
21    #[error("failed to verify token")]
22    VerificationFailure,
23
24    /// Indicates that the requested operation is not permitted on the resource.
25    #[error("operation not allowed")]
26    NotPermitted,
27
28    /// Indicates that a pre-signed URL was used with an unsupported HTTP method.
29    #[error("presigned URLs are not supported for this method")]
30    UnsupportedPresignedMethod,
31
32    /// Indicates that the authorization token/signature was signed with a key that is unknown to
33    /// this server.
34    #[error("unknown key")]
35    UnknownKey,
36}
37
38impl AuthError {
39    /// Return a shortname for the failure reason that can be used to tag metrics.
40    pub fn code(&self) -> &'static str {
41        match self {
42            Self::UnknownKey => "unknown_key",
43            Self::BadRequest(_) => "bad_request",
44            Self::NotPermitted => "not_permitted",
45            Self::InternalError(_) => "internal_error",
46            Self::ValidationFailure(_) => "validation_failure",
47            Self::VerificationFailure => "verification_failure",
48            Self::UnsupportedPresignedMethod => "unsupported_presigned_method",
49        }
50    }
51
52    /// Increment a counter and emit a log for this auth failure.
53    ///
54    /// If `warn` is true, the log will be at WARN level; otherwise it will be at DEBUG level.
55    pub fn log(&self, warn: bool) {
56        let code = self.code();
57        objectstore_metrics::count!("server.auth.failure", code = code);
58
59        if warn {
60            objectstore_log::warn!(code, reason=%self, "Auth failure");
61        } else {
62            objectstore_log::debug!(code, reason=%self, "Auth failure");
63        }
64    }
65}