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 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
//! A loginmanager for actix-web
//!
//! ## Example
//! ```rust
//! use std::pin::Pin;
//! use actix_web::{get, web, App, HttpRequest, HttpResponse, HttpServer};
//! use actix_loginmanager as loginmanager;
//! use loginmanager::{CookieSession, LoginManager, UserMinix, UserWrap};
//!
//! use futures::Future;
//! use loginmanager_codegen::login_required;
//!
//! use futures::{future, future::Ready};
//!
//! #[derive(Clone)]
//! struct User {
//! id: i32,
//! name: &'static str,
//! }
//!
//! impl UserMinix for User {
//! type Future = Pin<Box<dyn Future<Output = Option<Self>>>>;
//! type Key = i32;
//! fn get_user(i: &Self::Key, _: &HttpRequest) -> Self::Future {
//! // let req = req.clone();
//! let i = i.clone();
//! Box::pin(async move {
//! for id in 0..USERS.len() {
//! if USERS[id].id == i {
//! return Some(USERS[id].clone());
//! }
//! }
//! None
//! })
//! }
//!
//! fn get_id(&self) -> &Self::Key {
//! &self.id
//! }
//! }
//!
//! const USERS: [User; 3] = [
//! User { id: 1, name: "Tom" },
//! User { id: 2, name: "Jerry" },
//! User { id: 3, name: "Spike" },
//! ];
//!
//! #[login_required(User)]
//! async fn hello() -> impl actix_web::Responder {
//! return format!("hello {}",user.name);
//! }
//!
//! async fn auto_login(req: HttpRequest) -> impl actix_web::Responder {
//! let user = UserWrap::from(USERS[0].clone());
//! loginmanager::login(&user, &req);
//! HttpResponse::Ok().body(format!("login:{:?} ", user.user().name))
//! }
//!
//! async fn logout(req: HttpRequest, UserWrap(user): UserWrap<User>) -> impl actix_web::Responder {
//! loginmanager::logout(&user, &req);
//! HttpResponse::Ok().body(format!("logout:{:?} ", user.name))
//! }
//!
//! #[get("/")]
//! async fn index(UserWrap(user): UserWrap<User>) -> impl actix_web::Responder {
//! HttpResponse::Ok().body(format!(
//! "Hello:{:?} is_authenticated:{}",
//! user.name,
//! user.is_authenticated()
//! ))
//! }
//!
//! #[actix_web::main]
//! #[test]
//! async fn main() {
//! HttpServer::new(|| {
//! App::new()
//! .wrap(LoginManager::new(
//! CookieSession::new(&[0; 32]).secure(false),
//! ))
//! .service(index)
//! .route("/hello", web::get().to(hello))
//! .route("/login", web::get().to(auto_login))
//! .route("/logout", web::get().to(logout))
//! })
//! .bind("0.0.0.0:7081")
//! .unwrap()
//! .run()
//! .await
//! .unwrap();
//! }
//! ```
mod cooke_session;
mod loginmanager;
mod user;
pub use crate::cooke_session::CookieSession;
pub use crate::loginmanager::{DecodeRequest, LoginInfo, LoginManager, LoginState};
pub use crate::user::{UserMinix, UserWrap, UserWrapAuth};
use actix_web::HttpMessage;
pub use loginmanager_codegen::login_required;
/// The method of user login
pub fn login<U>(user: &dyn AsRef<U>, req: &actix_web::HttpRequest)
where
U: 'static + UserMinix,
{
let mut extensions = req.extensions_mut();
let id = user.as_ref().get_id();
let id_str = serde_json::to_string(&id).ok();
extensions.insert(LoginInfo::new(id_str, LoginState::Login));
}
/// The method of user logout
pub fn logout<U>(user: &dyn AsRef<U>, req: &actix_web::HttpRequest)
where
U: 'static + UserMinix,
{
let mut extensions = req.extensions_mut();
let id = user.as_ref().get_id();
let id_str = serde_json::to_string(&id).ok();
extensions.insert(LoginInfo::new(id_str, LoginState::Logout));
}