Skip to content

Commit b5d26cd

Browse files
authored
DG26-4: Extending the number of locations (#2843)
1 parent 094a8ea commit b5d26cd

4 files changed

Lines changed: 110 additions & 4 deletions

File tree

crates/defguard_core/src/handlers/user.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ pub(crate) async fn add_user(
332332
if get_cached_license()
333333
.as_ref()
334334
.and_then(|l| l.limits.as_ref())
335-
.is_some_and(|l| l.users == user_count)
335+
.is_some_and(|l| user_count >= l.users)
336336
{
337337
error!("Adding user {username} blocked! License limit reached.");
338338
return Ok(WebError::Forbidden("License limit reached").into());

crates/defguard_core/src/handlers/wireguard.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ pub(crate) async fn create_network(
204204
if get_cached_license()
205205
.as_ref()
206206
.and_then(|l| l.limits.as_ref())
207-
.is_some_and(|l| l.locations == location_count)
207+
.is_some_and(|l| location_count >= l.locations)
208208
{
209209
error!("Adding location {network_name} blocked! License limit reached.");
210210
return Ok(WebError::Forbidden("License limit reached").into());

crates/defguard_core/tests/integration/api/user.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@ use defguard_common::{
1616
types::user_info::UserInfo,
1717
};
1818
use defguard_core::{
19+
enterprise::{
20+
license::{License, LicenseTier, SupportType, get_cached_license, set_cached_license},
21+
limits::update_counts,
22+
},
1923
events::ApiEventType,
24+
grpc::proto::enterprise::license::LicenseLimits,
2025
handlers::{
2126
AddUserData, Auth, PasswordChange, PasswordChangeSelf, Username,
2227
openid_clients::NewOpenIDClient,
@@ -612,6 +617,49 @@ async fn test_crud_user(_: PgPoolOptions, options: PgConnectOptions) {
612617
]);
613618
}
614619

620+
#[sqlx::test]
621+
async fn test_add_user_blocked_when_user_count_exceeds_license_limit(
622+
_: PgPoolOptions,
623+
options: PgConnectOptions,
624+
) {
625+
let pool = setup_pool(options).await;
626+
627+
let (mut client, pool) = make_client_with_db(pool).await;
628+
629+
client.login_user("admin", "pass123").await;
630+
update_counts(&pool).await.unwrap();
631+
632+
let license = get_cached_license().clone();
633+
set_cached_license(Some(License::new(
634+
"test_customer".to_string(),
635+
false,
636+
None,
637+
Some(LicenseLimits {
638+
users: 1,
639+
devices: 100,
640+
locations: 100,
641+
network_devices: Some(100),
642+
}),
643+
None,
644+
LicenseTier::Business,
645+
SupportType::Basic,
646+
)));
647+
648+
let new_user = AddUserData {
649+
username: "adumbledore".into(),
650+
last_name: "Dumbledore".into(),
651+
first_name: "Albus".into(),
652+
email: "a.dumbledore@hogwart.edu.uk".into(),
653+
phone: Some("1234".into()),
654+
password: Some("Password1234543$!".into()),
655+
};
656+
let response = client.post("/api/v1/user").json(&new_user).send().await;
657+
assert_eq!(response.status(), StatusCode::FORBIDDEN);
658+
659+
set_cached_license(license);
660+
client.assert_event_queue_is_empty();
661+
}
662+
615663
#[sqlx::test]
616664
async fn test_check_username(_: PgPoolOptions, options: PgConnectOptions) {
617665
let pool = setup_pool(options).await;

crates/defguard_core/tests/integration/api/wireguard.rs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ use defguard_core::{
1919
DirectorySyncTarget, DirectorySyncUserBehavior, OpenIdProviderKind,
2020
},
2121
handlers::openid_providers::AddProviderData,
22-
license::{get_cached_license, set_cached_license},
22+
license::{License, LicenseTier, SupportType, get_cached_license, set_cached_license},
23+
limits::update_counts,
2324
},
24-
grpc::GatewayEvent,
25+
grpc::{GatewayEvent, proto::enterprise::license::LicenseLimits},
2526
handlers::{Auth, GroupInfo, wireguard::WireguardNetworkData},
2627
};
2728
use ipnetwork::IpNetwork;
@@ -137,6 +138,63 @@ async fn test_network(_: PgPoolOptions, options: PgConnectOptions) {
137138
assert_matches!(event, GatewayEvent::NetworkDeleted(..));
138139
}
139140

141+
#[sqlx::test]
142+
async fn test_create_network_blocked_when_location_count_exceeds_license_limit(
143+
_: PgPoolOptions,
144+
options: PgConnectOptions,
145+
) {
146+
let pool = setup_pool(options).await;
147+
148+
let (mut client, client_state) = make_test_client(pool).await;
149+
authenticate_admin(&mut client).await;
150+
151+
make_network(&client, "network1").await;
152+
make_network(&client, "network2").await;
153+
update_counts(&client_state.pool).await.unwrap();
154+
155+
let license = get_cached_license().clone();
156+
set_cached_license(Some(License::new(
157+
"test_customer".to_string(),
158+
false,
159+
None,
160+
Some(LicenseLimits {
161+
users: 100,
162+
devices: 100,
163+
locations: 1,
164+
network_devices: Some(100),
165+
}),
166+
None,
167+
LicenseTier::Business,
168+
SupportType::Basic,
169+
)));
170+
171+
let response = client
172+
.post("/api/v1/network")
173+
.json(&json!({
174+
"name": "network3",
175+
"address": "10.1.1.1/24",
176+
"port": 55555,
177+
"endpoint": "192.168.4.14",
178+
"allowed_ips": "10.1.1.0/24",
179+
"dns": "1.1.1.1",
180+
"mtu": 1420,
181+
"fwmark": 0,
182+
"allowed_groups": ["admin"],
183+
"allow_all_groups": false,
184+
"keepalive_interval": 25,
185+
"peer_disconnect_threshold": 300,
186+
"acl_enabled": false,
187+
"acl_default_allow": false,
188+
"location_mfa_mode": "disabled",
189+
"service_location_mode": "disabled"
190+
}))
191+
.send()
192+
.await;
193+
assert_eq!(response.status(), StatusCode::FORBIDDEN);
194+
195+
set_cached_license(license);
196+
}
197+
140198
#[sqlx::test]
141199
async fn test_location_mfa_mode_validation_create(_: PgPoolOptions, options: PgConnectOptions) {
142200
let pool = setup_pool(options).await;

0 commit comments

Comments
 (0)