2020-05-01 14:48:11 +00:00
|
|
|
use gotham_restful_derive::ResourceError;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
This is an error type that always yields a _403 Forbidden_ response. This type is best used in
|
|
|
|
combination with [`AuthSuccess`] or [`AuthResult`].
|
|
|
|
|
|
|
|
[`AuthSuccess`]: type.AuthSuccess.html
|
|
|
|
[`AuthResult`]: type.AuthResult.html
|
|
|
|
*/
|
2020-05-03 18:21:50 +02:00
|
|
|
#[derive(Debug, Clone, Copy, ResourceError)]
|
2020-05-01 14:48:11 +00:00
|
|
|
pub enum AuthError
|
|
|
|
{
|
|
|
|
#[status(FORBIDDEN)]
|
|
|
|
#[display("Forbidden")]
|
|
|
|
Forbidden
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
This return type can be used to map another `ResourceResult` that can only be returned if the
|
|
|
|
client is authenticated. Otherwise, an empty _403 Forbidden_ response will be issued. Use can
|
|
|
|
look something like this (assuming the `auth` feature is enabled):
|
|
|
|
|
2020-05-16 01:01:20 +02:00
|
|
|
```rust
|
2020-05-16 01:03:17 +02:00
|
|
|
# #[macro_use] extern crate gotham_restful_derive;
|
2020-05-16 01:01:20 +02:00
|
|
|
# #[cfg(feature = "auth")]
|
|
|
|
# mod auth_feature_enabled {
|
2020-05-01 14:48:11 +00:00
|
|
|
# use gotham::state::State;
|
|
|
|
# use gotham_restful::*;
|
|
|
|
# use serde::Deserialize;
|
|
|
|
#
|
|
|
|
# #[derive(Resource)]
|
2020-05-04 21:34:20 +02:00
|
|
|
# #[resource(read_all)]
|
2020-05-01 14:48:11 +00:00
|
|
|
# struct MyResource;
|
|
|
|
#
|
|
|
|
# #[derive(Clone, Deserialize)]
|
|
|
|
# struct MyAuthData { exp : u64 }
|
|
|
|
#
|
2020-05-04 21:34:20 +02:00
|
|
|
#[read_all(MyResource)]
|
2020-05-01 14:48:11 +00:00
|
|
|
fn read_all(auth : AuthStatus<MyAuthData>) -> AuthSuccess<NoContent> {
|
|
|
|
let auth_data = match auth {
|
|
|
|
AuthStatus::Authenticated(data) => data,
|
|
|
|
_ => return Err(Forbidden)
|
|
|
|
};
|
|
|
|
// do something
|
|
|
|
Ok(NoContent::default())
|
|
|
|
}
|
|
|
|
# }
|
|
|
|
```
|
|
|
|
*/
|
|
|
|
pub type AuthSuccess<T> = Result<T, AuthError>;
|
|
|
|
|
|
|
|
/**
|
|
|
|
This is an error type that either yields a _403 Forbidden_ respone if produced from an authentication
|
|
|
|
error, or delegates to another error type. This type is best used with [`AuthResult`].
|
|
|
|
|
|
|
|
[`AuthResult`]: type.AuthResult.html
|
|
|
|
*/
|
2020-05-03 18:21:50 +02:00
|
|
|
#[derive(Debug, ResourceError)]
|
2020-05-01 14:48:11 +00:00
|
|
|
pub enum AuthErrorOrOther<E>
|
|
|
|
{
|
2020-05-08 22:54:54 +02:00
|
|
|
#[status(FORBIDDEN)]
|
2020-05-01 14:48:11 +00:00
|
|
|
#[display("Forbidden")]
|
|
|
|
Forbidden,
|
2020-05-20 19:50:17 +02:00
|
|
|
#[status(INTERNAL_SERVER_ERROR)]
|
2020-05-01 14:48:11 +00:00
|
|
|
#[display("{0}")]
|
2020-05-20 19:50:17 +02:00
|
|
|
Other(E)
|
2020-05-01 14:48:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<E> From<AuthError> for AuthErrorOrOther<E>
|
|
|
|
{
|
|
|
|
fn from(err : AuthError) -> Self
|
|
|
|
{
|
|
|
|
match err {
|
|
|
|
AuthError::Forbidden => Self::Forbidden
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-20 19:50:17 +02:00
|
|
|
impl<E, F> From<F> for AuthErrorOrOther<E>
|
|
|
|
where
|
|
|
|
// TODO https://gitlab.com/msrd0/gotham-restful/-/issues/20
|
|
|
|
F : std::error::Error + Into<E>
|
|
|
|
{
|
|
|
|
fn from(err : F) -> Self
|
|
|
|
{
|
|
|
|
Self::Other(err.into())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-01 14:48:11 +00:00
|
|
|
/**
|
|
|
|
This return type can be used to map another `ResourceResult` that can only be returned if the
|
|
|
|
client is authenticated. Otherwise, an empty _403 Forbidden_ response will be issued. Use can
|
|
|
|
look something like this (assuming the `auth` feature is enabled):
|
|
|
|
|
|
|
|
```
|
2020-05-16 01:03:17 +02:00
|
|
|
# #[macro_use] extern crate gotham_restful_derive;
|
2020-05-16 01:01:20 +02:00
|
|
|
# #[cfg(feature = "auth")]
|
|
|
|
# mod auth_feature_enabled {
|
2020-05-01 14:48:11 +00:00
|
|
|
# use gotham::state::State;
|
|
|
|
# use gotham_restful::*;
|
|
|
|
# use serde::Deserialize;
|
|
|
|
# use std::io;
|
|
|
|
#
|
|
|
|
# #[derive(Resource)]
|
2020-05-04 21:34:20 +02:00
|
|
|
# #[resource(read_all)]
|
2020-05-01 14:48:11 +00:00
|
|
|
# struct MyResource;
|
|
|
|
#
|
|
|
|
# #[derive(Clone, Deserialize)]
|
|
|
|
# struct MyAuthData { exp : u64 }
|
|
|
|
#
|
2020-05-04 21:34:20 +02:00
|
|
|
#[read_all(MyResource)]
|
2020-05-01 14:48:11 +00:00
|
|
|
fn read_all(auth : AuthStatus<MyAuthData>) -> AuthResult<NoContent, io::Error> {
|
|
|
|
let auth_data = match auth {
|
|
|
|
AuthStatus::Authenticated(data) => data,
|
|
|
|
_ => Err(Forbidden)?
|
|
|
|
};
|
|
|
|
// do something
|
|
|
|
Ok(NoContent::default().into())
|
|
|
|
}
|
|
|
|
# }
|
|
|
|
*/
|
|
|
|
pub type AuthResult<T, E> = Result<T, AuthErrorOrOther<E>>;
|