1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
use actix_web::{
dev::{Extensions, Payload},
Error, FromRequest, HttpRequest,
};
use futures_util::future::{ready, Ready};
pub(crate) struct IdentityItem {
pub(crate) id: Option<String>,
pub(crate) changed: bool,
}
/// The extractor type to obtain your identity from a request.
///
/// ```
/// use actix_web::*;
/// use actix_identity::Identity;
///
/// #[get("/")]
/// async fn index(id: Identity) -> impl Responder {
/// // access request identity
/// if let Some(id) = id.identity() {
/// format!("Welcome! {}", id)
/// } else {
/// "Welcome Anonymous!".to_owned()
/// }
/// }
///
/// #[post("/login")]
/// async fn login(id: Identity) -> impl Responder {
/// // remember identity
/// id.remember("User1".to_owned());
///
/// HttpResponse::Ok()
/// }
///
/// #[post("/logout")]
/// async fn logout(id: Identity) -> impl Responder {
/// // remove identity
/// id.forget();
///
/// HttpResponse::Ok()
/// }
/// ```
#[derive(Clone)]
pub struct Identity(HttpRequest);
impl Identity {
/// Return the claimed identity of the user associated request or `None` if no identity can be
/// found associated with the request.
pub fn identity(&self) -> Option<String> {
Identity::get_identity(&self.0.extensions())
}
/// Remember identity.
pub fn remember(&self, identity: String) {
if let Some(id) = self.0.extensions_mut().get_mut::<IdentityItem>() {
id.id = Some(identity);
id.changed = true;
}
}
/// This method is used to 'forget' the current identity on subsequent requests.
pub fn forget(&self) {
if let Some(id) = self.0.extensions_mut().get_mut::<IdentityItem>() {
id.id = None;
id.changed = true;
}
}
pub(crate) fn get_identity(extensions: &Extensions) -> Option<String> {
let id = extensions.get::<IdentityItem>()?;
id.id.clone()
}
}
/// Extractor implementation for Identity type.
///
/// ```
/// # use actix_web::*;
/// use actix_identity::Identity;
///
/// #[get("/")]
/// async fn index(id: Identity) -> impl Responder {
/// // access request identity
/// if let Some(id) = id.identity() {
/// format!("Welcome! {}", id)
/// } else {
/// "Welcome Anonymous!".to_owned()
/// }
/// }
/// ```
impl FromRequest for Identity {
type Config = ();
type Error = Error;
type Future = Ready<Result<Identity, Error>>;
#[inline]
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
ready(Ok(Identity(req.clone())))
}
}