From 941f98e20543de6285d7b2f952de657265bb3b4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=9Al=C4=99zak?= Date: Fri, 5 Sep 2025 13:58:52 +0200 Subject: [PATCH 1/2] fix issue dg25-9 --- crates/defguard_core/src/handlers/group.rs | 15 ++++++---- .../tests/integration/api/group.rs | 29 +++++++++++++++++++ web/src/i18n/i18n-types.ts | 4 +-- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/crates/defguard_core/src/handlers/group.rs b/crates/defguard_core/src/handlers/group.rs index 3218b32542..192c5e8358 100644 --- a/crates/defguard_core/src/handlers/group.rs +++ b/crates/defguard_core/src/handlers/group.rs @@ -219,16 +219,17 @@ pub(crate) async fn list_groups_info( ) )] pub(crate) async fn list_groups( - _session: SessionInfo, + _admin: AdminRole, + session: SessionInfo, State(appstate): State, ) -> ApiResult { - debug!("Listing groups"); + debug!("User {} lists groups", &session.user.username); let groups = Group::all(&appstate.pool) .await? .into_iter() .map(|group| group.name) .collect(); - info!("Listed groups"); + info!("User {} listed groups", &session.user.username); Ok(ApiResponse { json: json!(Groups::new(groups)), status: StatusCode::OK, @@ -266,6 +267,7 @@ pub(crate) async fn list_groups( ) )] pub(crate) async fn get_group( + _admin: AdminRole, _session: SessionInfo, State(appstate): State, Path(name): Path, @@ -573,12 +575,13 @@ pub(crate) async fn modify_group( ) )] pub(crate) async fn delete_group( - _session: SessionInfo, + _admin: AdminRole, + session: SessionInfo, State(appstate): State, context: ApiRequestContext, Path(name): Path, ) -> ApiResult { - debug!("Deleting group {name}"); + debug!("User {} deletes group {name}", &session.user.username); if let Some(group) = Group::find_by_name(&appstate.pool, &name).await? { // Prevent removing the last admin group if group.is_admin { @@ -600,7 +603,7 @@ pub(crate) async fn delete_group( let mut conn = appstate.pool.acquire().await?; WireguardNetwork::sync_all_networks(&mut conn, &appstate.wireguard_tx).await?; - info!("Deleted group {name}"); + info!("User {} deleted group {name}", &session.user.username); appstate.emit_event(ApiEvent { context, event: Box::new(ApiEventType::GroupRemoved { group }), diff --git a/crates/defguard_core/tests/integration/api/group.rs b/crates/defguard_core/tests/integration/api/group.rs index f96d78904b..f882906be3 100644 --- a/crates/defguard_core/tests/integration/api/group.rs +++ b/crates/defguard_core/tests/integration/api/group.rs @@ -206,3 +206,32 @@ async fn test_modify_last_admin_group(_: PgPoolOptions, options: PgConnectOption let response = client.put("/api/v1/group/admin").json(&data).send().await; assert_eq!(response.status(), StatusCode::BAD_REQUEST); } + +#[sqlx::test] +async fn test_group_endpoints_access(_: PgPoolOptions, options: PgConnectOptions) { + let pool = setup_pool(options).await; + + // Auth client as normal user without admin access + let (client, _) = make_test_client(pool).await; + + let auth = Auth::new("hpotter", "pass123"); + let response = client.post("/api/v1/auth").json(&auth).send().await; + assert_eq!(response.status(), StatusCode::OK); + + let response = client.get("/api/v1/group").send().await; + assert_eq!(response.status(), StatusCode::FORBIDDEN); + + let response = client.get("/api/v1/group/admin").send().await; + assert_eq!(response.status(), StatusCode::FORBIDDEN); + + let response = client.delete("/api/v1/group/admin").send().await; + assert_eq!(response.status(), StatusCode::FORBIDDEN); + + let data = EditGroupInfo::new("hogwards", vec!["hpotter".into(), "admin".into()], true); + let response = client.post("/api/v1/group").json(&data).send().await; + assert_eq!(response.status(), StatusCode::FORBIDDEN); + + let data = EditGroupInfo::new("admin", vec!["hpotter".into()], true); + let response = client.put("/api/v1/group/admin").json(&data).send().await; + assert_eq!(response.status(), StatusCode::FORBIDDEN); +} diff --git a/web/src/i18n/i18n-types.ts b/web/src/i18n/i18n-types.ts index 25ee72f49a..d25eea32ba 100644 --- a/web/src/i18n/i18n-types.ts +++ b/web/src/i18n/i18n-types.ts @@ -1635,7 +1635,7 @@ type RootTranslation = { /** * ​ ​ ​ ​ ​ ​ ​ ​ ​<​p​>​ - ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​Y​o​u​ ​n​e​e​d​ ​t​o​ ​c​o​n​f​i​g​u​r​e​ ​W​i​r​e​G​u​a​r​d​V​P​N​ ​o​n​ ​y​o​u​r​ ​d​e​v​i​c​e​,​ ​p​l​e​a​s​e​ ​v​i​s​i​t​&​n​b​s​p​;​ + ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​Y​o​u​ ​n​e​e​d​ ​t​o​ ​c​o​n​f​i​g​u​r​e​ ​W​i​r​e​G​u​a​r​d​®​ ​V​P​N​ ​o​n​ ​y​o​u​r​ ​d​e​v​i​c​e​,​ ​p​l​e​a​s​e​ ​v​i​s​i​t​&​n​b​s​p​;​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​ ​<​a​ ​h​r​e​f​=​"​{​a​d​d​D​e​v​i​c​e​s​D​o​c​s​}​"​>​d​o​c​u​m​e​n​t​a​t​i​o​n​<​/​a​>​ ​i​f​ ​y​o​u​ ​d​o​n​&​a​p​o​s​;​t​ ​k​n​o​w​ ​h​o​w​ ​t​o​ ​d​o​ ​i​t​.​ ​ ​ ​ ​ ​ ​ ​ ​ ​<​/​p​>​ @@ -8315,7 +8315,7 @@ export type TranslationFunctions = { /** *

- You need to configure WireGuardVPN on your device, please visit  + You need to configure WireGuard® VPN on your device, please visit  documentation if you don't know how to do it.

From eca6eae96452f0f776fbebe33bdd49df1dfae415 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20=C5=9Al=C4=99zak?= Date: Fri, 5 Sep 2025 14:14:43 +0200 Subject: [PATCH 2/2] remove outdated gorups test --- .../tests/integration/api/user.rs | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/crates/defguard_core/tests/integration/api/user.rs b/crates/defguard_core/tests/integration/api/user.rs index a461fc9cb6..a2c6307e59 100644 --- a/crates/defguard_core/tests/integration/api/user.rs +++ b/crates/defguard_core/tests/integration/api/user.rs @@ -298,25 +298,6 @@ async fn test_crud_user(_: PgPoolOptions, options: PgConnectOptions) { assert_eq!(response.status(), StatusCode::OK); } -#[sqlx::test] -async fn test_admin_group(_: PgPoolOptions, options: PgConnectOptions) { - let pool = setup_pool(options).await; - - let client = make_client(pool).await; - - let auth = Auth::new("hpotter", "pass123"); - let response = client.post("/api/v1/auth").json(&auth).send().await; - assert_eq!(response.status(), StatusCode::OK); - - let response = client.get("/api/v1/group").send().await; - assert_eq!(response.status(), StatusCode::OK); - - let response = client.get("/api/v1/group/admin").send().await; - assert_eq!(response.status(), StatusCode::OK); - - // TODO: check group membership -} - #[sqlx::test] async fn test_check_username(_: PgPoolOptions, options: PgConnectOptions) { let pool = setup_pool(options).await;