Fix frontend login for nextcloud flows

This commit is contained in:
Lennart
2025-04-13 20:22:15 +02:00
parent b2c1bd6b8d
commit 354c6c97eb
4 changed files with 32 additions and 5 deletions

View File

@@ -25,3 +25,4 @@ rand.workspace = true
chrono.workspace = true
uuid.workspace = true
url.workspace = true
tracing.workspace = true

View File

@@ -1,5 +1,9 @@
use actix_session::{
SessionMiddleware, config::CookieContentSecurity, storage::CookieSessionStore,
};
use actix_web::{
HttpRequest, HttpResponse, Responder,
cookie::{Key, SameSite},
http::{
StatusCode,
header::{self},
@@ -14,6 +18,7 @@ use rustical_store::auth::{AuthenticationMiddleware, AuthenticationProvider, Use
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, sync::Arc};
use tokio::sync::RwLock;
use tracing::instrument;
use crate::unauthorized_handler;
@@ -153,6 +158,7 @@ struct NextcloudLoginPage {
app_name: String,
}
#[instrument(skip(state, req))]
async fn get_nextcloud_flow(
user: User,
state: Data<NextcloudFlows>,
@@ -187,6 +193,7 @@ struct NextcloudLoginSuccessPage {
app_name: String,
}
#[instrument(skip(state, req))]
async fn post_nextcloud_flow(
user: User,
state: Data<NextcloudFlows>,
@@ -220,11 +227,22 @@ pub fn configure_nextcloud_login<AP: AuthenticationProvider>(
cfg: &mut ServiceConfig,
nextcloud_flows_state: Arc<NextcloudFlows>,
auth_provider: Arc<AP>,
frontend_secret: [u8; 64],
) {
cfg.service(
web::scope("/index.php/login/v2")
.wrap(ErrorHandlers::new().handler(StatusCode::UNAUTHORIZED, unauthorized_handler))
.wrap(AuthenticationMiddleware::new(auth_provider.clone()))
.wrap(
SessionMiddleware::builder(
CookieSessionStore::default(),
Key::from(&frontend_secret),
)
.cookie_secure(true)
.cookie_same_site(SameSite::Strict)
.cookie_content_security(CookieContentSecurity::Private)
.build(),
)
.app_data(Data::from(nextcloud_flows_state))
.app_data(Data::from(auth_provider.clone()))
.service(web::resource("").post(post_nextcloud_login))

View File

@@ -9,6 +9,7 @@ use askama::Template;
use askama_web::WebTemplate;
use rustical_store::auth::AuthenticationProvider;
use serde::Deserialize;
use tracing::instrument;
#[derive(Template, WebTemplate)]
#[template(path = "pages/login.html")]
@@ -22,6 +23,7 @@ pub struct GetLoginQuery {
redirect_uri: Option<String>,
}
#[instrument(skip(req))]
pub async fn route_get_login(
Query(GetLoginQuery { redirect_uri }): Query<GetLoginQuery>,
req: HttpRequest,
@@ -47,6 +49,7 @@ pub struct PostLoginForm {
redirect_uri: Option<String>,
}
#[instrument(skip(req, password, auth_provider, session))]
pub async fn route_post_login<AP: AuthenticationProvider>(
req: HttpRequest,
Form(PostLoginForm {

View File

@@ -51,6 +51,16 @@ pub fn make_app<AS: AddressbookStore, CS: CalendarStore, S: SubscriptionStore>(
.service(web::redirect("/carddav", "/carddav")),
);
if nextcloud_login_config.enabled {
app = app.configure(|cfg| {
configure_nextcloud_login(
cfg,
nextcloud_flows_state,
auth_provider.clone(),
frontend_config.secret_key,
)
});
}
if frontend_config.enabled {
app = app
.service(web::scope("/frontend").configure(|cfg| {
@@ -64,10 +74,5 @@ pub fn make_app<AS: AddressbookStore, CS: CalendarStore, S: SubscriptionStore>(
}))
.service(web::redirect("/", "/frontend").see_other());
}
if nextcloud_login_config.enabled {
app = app.configure(|cfg| {
configure_nextcloud_login(cfg, nextcloud_flows_state, auth_provider.clone())
});
}
app
}