Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions crates/defguard_core/src/handlers/group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<AppState>,
) -> 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,
Expand Down Expand Up @@ -266,6 +267,7 @@ pub(crate) async fn list_groups(
)
)]
pub(crate) async fn get_group(
_admin: AdminRole,
_session: SessionInfo,
State(appstate): State<AppState>,
Path(name): Path<String>,
Expand Down Expand Up @@ -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<AppState>,
context: ApiRequestContext,
Path(name): Path<String>,
) -> 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 {
Expand All @@ -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 }),
Expand Down
29 changes: 29 additions & 0 deletions crates/defguard_core/tests/integration/api/group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
19 changes: 0 additions & 19 deletions crates/defguard_core/tests/integration/api/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions web/src/i18n/i18n-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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​>​

Expand Down Expand Up @@ -8315,7 +8315,7 @@ export type TranslationFunctions = {
/**
*
<p>
You need to configure WireGuardVPN on your device, please visit&nbsp;
You need to configure WireGuard® VPN on your device, please visit&nbsp;
<a href="{addDevicesDocs}">documentation</a> if you don&apos;t know how to do it.
</p>

Expand Down