Redirect anonymous user from authenticated pages
This commit is contained in:
parent
9e72e6a044
commit
91fd763fe1
@ -19,3 +19,12 @@ pub const MIN_PASS_LEN: usize = 4;
|
|||||||
|
|
||||||
/// The name of the cookie used to store session information
|
/// The name of the cookie used to store session information
|
||||||
pub const SESSION_COOKIE_NAME: &str = "auth-cookie";
|
pub const SESSION_COOKIE_NAME: &str = "auth-cookie";
|
||||||
|
|
||||||
|
/// Authenticated routes prefix
|
||||||
|
pub const AUTHENTICATED_ROUTES: &str = "/settings";
|
||||||
|
|
||||||
|
/// Admin routes prefix
|
||||||
|
pub const ADMIN_ROUTES: &str = "/admin";
|
||||||
|
|
||||||
|
/// Auth route
|
||||||
|
pub const LOGIN_ROUTE: &str = "/login";
|
@ -19,7 +19,7 @@ impl Default for SessionStatus {
|
|||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||||
struct SessionIdentityData {
|
pub struct SessionIdentityData {
|
||||||
pub id: UserID,
|
pub id: UserID,
|
||||||
pub is_admin: bool,
|
pub is_admin: bool,
|
||||||
pub status: SessionStatus,
|
pub status: SessionStatus,
|
||||||
@ -28,17 +28,12 @@ struct SessionIdentityData {
|
|||||||
pub struct SessionIdentity<'a>(pub &'a Identity);
|
pub struct SessionIdentity<'a>(pub &'a Identity);
|
||||||
|
|
||||||
impl<'a> SessionIdentity<'a> {
|
impl<'a> SessionIdentity<'a> {
|
||||||
pub fn set_user(&self, user: &User) {
|
fn get_session_data(&self) -> Option<SessionIdentityData> {
|
||||||
self.set_session_data(&SessionIdentityData {
|
Self::deserialize_session_data(self.0.identity())
|
||||||
id: user.uid.clone(),
|
|
||||||
is_admin: user.admin,
|
|
||||||
status: SessionStatus::SignedIn,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_session_data(&self) -> Option<SessionIdentityData> {
|
pub fn deserialize_session_data(data: Option<String>) -> Option<SessionIdentityData> {
|
||||||
let res: Option<SessionIdentityData> = self.0.identity()
|
let res: Option<SessionIdentityData> = data.as_deref()
|
||||||
.as_deref()
|
|
||||||
.map(serde_json::from_str)
|
.map(serde_json::from_str)
|
||||||
.map(|f| match f {
|
.map(|f| match f {
|
||||||
Ok(d) => Some(d),
|
Ok(d) => Some(d),
|
||||||
@ -66,6 +61,14 @@ impl<'a> SessionIdentity<'a> {
|
|||||||
self.0.remember(s);
|
self.0.remember(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_user(&self, user: &User) {
|
||||||
|
self.set_session_data(&SessionIdentityData {
|
||||||
|
id: user.uid.clone(),
|
||||||
|
is_admin: user.admin,
|
||||||
|
status: SessionStatus::SignedIn,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_status(&self, status: SessionStatus) {
|
pub fn set_status(&self, status: SessionStatus) {
|
||||||
let mut sess = self.get_session_data().unwrap_or_default();
|
let mut sess = self.get_session_data().unwrap_or_default();
|
||||||
sess.status = status;
|
sess.status = status;
|
||||||
|
@ -8,6 +8,10 @@ use actix_identity::RequestIdentity;
|
|||||||
use actix_web::{dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform}, Error, HttpResponse};
|
use actix_web::{dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform}, Error, HttpResponse};
|
||||||
use actix_web::body::EitherBody;
|
use actix_web::body::EitherBody;
|
||||||
|
|
||||||
|
use crate::constants::{ADMIN_ROUTES, AUTHENTICATED_ROUTES, LOGIN_ROUTE};
|
||||||
|
use crate::controllers::base_controller::redirect_user;
|
||||||
|
use crate::data::session_identity::{SessionIdentity, SessionIdentityData};
|
||||||
|
|
||||||
// There are two steps in middleware processing.
|
// There are two steps in middleware processing.
|
||||||
// 1. Middleware initialization, middleware factory gets called with
|
// 1. Middleware initialization, middleware factory gets called with
|
||||||
// next service in chain as parameter.
|
// next service in chain as parameter.
|
||||||
@ -41,6 +45,16 @@ enum SessionStatus {
|
|||||||
Admin,
|
Admin,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SessionStatus {
|
||||||
|
pub fn is_auth(&self) -> bool {
|
||||||
|
!matches!(self, SessionStatus::SignedOut)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_admin(&self) -> bool {
|
||||||
|
matches!(self, SessionStatus::Admin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct AuthInnerMiddleware<S> {
|
pub struct AuthInnerMiddleware<S> {
|
||||||
service: Rc<S>,
|
service: Rc<S>,
|
||||||
}
|
}
|
||||||
@ -60,8 +74,6 @@ impl<S, B> Service<ServiceRequest> for AuthInnerMiddleware<S>
|
|||||||
forward_ready!(service);
|
forward_ready!(service);
|
||||||
|
|
||||||
fn call(&self, req: ServiceRequest) -> Self::Future {
|
fn call(&self, req: ServiceRequest) -> Self::Future {
|
||||||
println!("Hi from start. You requested: {}", req.path());
|
|
||||||
|
|
||||||
let service = Rc::clone(&self.service);
|
let service = Rc::clone(&self.service);
|
||||||
|
|
||||||
// Forward request
|
// Forward request
|
||||||
@ -74,8 +86,20 @@ impl<S, B> Service<ServiceRequest> for AuthInnerMiddleware<S>
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let identity = req.get_identity();
|
let identity = match SessionIdentity::deserialize_session_data(req.get_identity()) {
|
||||||
println!("identity: {:?}", identity);
|
None => SessionStatus::SignedOut,
|
||||||
|
Some(SessionIdentityData { is_admin: true, .. }) => SessionStatus::Admin,
|
||||||
|
_ => SessionStatus::RegularUser,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Redirect user to login page
|
||||||
|
if !identity.is_auth() && (req.path().starts_with(ADMIN_ROUTES) ||
|
||||||
|
req.path().starts_with(AUTHENTICATED_ROUTES)) {
|
||||||
|
return Ok(req.into_response(redirect_user(LOGIN_ROUTE))
|
||||||
|
.map_into_right_body());
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO : restrict access to admin pages
|
||||||
|
|
||||||
service
|
service
|
||||||
.call(req)
|
.call(req)
|
||||||
|
Loading…
Reference in New Issue
Block a user