Add users authentication routes

This commit is contained in:
2025-11-03 22:17:29 +01:00
parent 830f47b61f
commit bc815a5cf1
21 changed files with 1417 additions and 451 deletions

View File

@@ -0,0 +1,91 @@
use crate::constants;
use crate::users::{User, UserEmail};
use crate::utils::rand_utils::rand_string;
use actix_session::Session;
use actix_web::dev::Payload;
use actix_web::{Error, FromRequest, HttpRequest};
use futures_util::future::{Ready, ready};
use std::net::IpAddr;
/// Matrix Gateway session errors
#[derive(thiserror::Error, Debug)]
enum MatrixGWSessionError {
#[error("Missing state!")]
OIDCMissingState,
#[error("Missing IP address!")]
OIDCMissingIP,
#[error("Invalid state!")]
OIDCInvalidState,
#[error("Invalid IP address!")]
OIDCInvalidIP,
}
/// Matrix Gateway session
///
/// Basic wrapper around actix-session extractor
pub struct MatrixGWSession(Session);
impl MatrixGWSession {
/// Generate OpenID state for this session
pub fn gen_oidc_state(&self, ip: IpAddr) -> anyhow::Result<String> {
let random_string = rand_string(50);
self.0
.insert(constants::sessions::OIDC_STATE_KEY, random_string.clone())?;
self.0.insert(constants::sessions::OIDC_REMOTE_IP, ip)?;
Ok(random_string)
}
/// Validate OpenID state
pub fn validate_state(&self, state: &str, ip: IpAddr) -> anyhow::Result<()> {
let session_state: String = self
.0
.get(constants::sessions::OIDC_STATE_KEY)?
.ok_or(MatrixGWSessionError::OIDCMissingState)?;
let session_ip: IpAddr = self
.0
.get(constants::sessions::OIDC_REMOTE_IP)?
.ok_or(MatrixGWSessionError::OIDCMissingIP)?;
if session_state != state {
return Err(anyhow::anyhow!(MatrixGWSessionError::OIDCInvalidState));
}
if session_ip != ip {
return Err(anyhow::anyhow!(MatrixGWSessionError::OIDCInvalidIP));
}
Ok(())
}
/// Set current user
pub fn set_user(&self, user: &User) -> anyhow::Result<()> {
self.0.insert(constants::sessions::USER_ID, &user.email)?;
Ok(())
}
/// Get current user
pub fn current_user(&self) -> anyhow::Result<Option<UserEmail>> {
Ok(self.0.get(constants::sessions::USER_ID)?)
}
/// Remove defined user
pub fn unset_current_user(&self) -> anyhow::Result<()> {
self.0.remove(constants::sessions::USER_ID);
Ok(())
}
}
impl FromRequest for MatrixGWSession {
type Error = Error;
type Future = Ready<Result<Self, Error>>;
#[inline]
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
ready(
Session::from_request(req, &mut Payload::None)
.into_inner()
.map(MatrixGWSession),
)
}
}