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
1 change: 1 addition & 0 deletions .fpm
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
--description "Defguard Core service"
--url "https://defguard.net/"
--maintainer "Defguard"
--config-files /etc/defguard/core.conf
4 changes: 3 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ jobs:
uses: ./.github/workflows/build-docker.yml
with:
tags: |
type=raw,value=latest
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha
# Explicitly disable latest tag. It will be added otherwise.
flavor: |
latest=false

build-docker-prerelease:
# Only build tags with -, like v1.0.0-alpha
Expand Down
39 changes: 39 additions & 0 deletions .github/workflows/test-web.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
on:
push:
branches:
- main
- dev
- "release/**"
paths-ignore:
- "*.md"
- "LICENSE"
pull_request:
branches:
- main
- dev
- "release/**"
paths-ignore:
- "*.md"
- "LICENSE"

permissions:
contents: read
jobs:
test-web:
runs-on:
- codebuild-defguard-core-runner-${{ github.run_id }}-${{ github.run_attempt }}
steps:
- uses: actions/checkout@v4
with:
submodules: "recursive"
- uses: actions/setup-node@v4
with:
node-version: 24
- name: install deps
working-directory: ./web
run: |
npm i -g npm pnpm
pnpm i --frozen-lockfile
- name: Run tests
working-directory: ./web
run: pnpm run test

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

This file was deleted.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

This file was deleted.

2 changes: 1 addition & 1 deletion crates/defguard_core/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
&["src/enterprise/proto/license.proto"],
&["src/enterprise/proto"],
)?;
println!("cargo:rerun-if-changed=src/enterprise");
println!("cargo:rerun-if-changed=src/enterprise/proto");
Ok(())
}
4 changes: 2 additions & 2 deletions crates/defguard_core/src/auth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use defguard_common::db::{

use crate::{
appstate::AppState,
enterprise::{db::models::api_tokens::ApiToken, is_enterprise_enabled},
enterprise::{db::models::api_tokens::ApiToken, is_business_license_active},
error::WebError,
handlers::SESSION_COOKIE_NAME,
};
Expand All @@ -40,7 +40,7 @@ where
let appstate = AppState::from_ref(state);

// first try to authenticate by API token if one is found in header
if is_enterprise_enabled() {
if is_business_license_active() {
let maybe_auth_header: Option<TypedHeader<Authorization<Bearer>>> =
<TypedHeader<_> as OptionalFromRequestParts<S>>::from_request_parts(parts, state)
.await
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use super::ActivityLogStreamReconfigurationNotification;
use crate::enterprise::{
activity_log_stream::http_stream::{HttpActivityLogStreamConfig, run_http_stream_task},
db::models::activity_log_stream::{ActivityLogStream, ActivityLogStreamConfig},
is_enterprise_enabled,
is_business_license_active,
};

// check if enterprise features are enabled every minute
Expand All @@ -27,7 +27,7 @@ pub async fn run_activity_log_stream_manager(
let mut enterprise_check_timer = interval(Duration::from_secs(ENTERPRISE_CHECK_PERIOD_SECS));

// initialize enterprise features status
let mut enterprise_features_enabled = is_enterprise_enabled();
let mut enterprise_features_enabled = is_business_license_active();

loop {
let mut handles = JoinSet::<()>::new();
Expand Down Expand Up @@ -94,7 +94,7 @@ pub async fn run_activity_log_stream_manager(
}
_ = enterprise_check_timer.tick() => {
// check if enterprise features status has changed
let current_enterprise_features_enabled = is_enterprise_enabled();
let current_enterprise_features_enabled = is_business_license_active();
if current_enterprise_features_enabled != enterprise_features_enabled {
warn!("Activity log stream manager will reload, detected license enterprise features status has changed");
enterprise_features_enabled = current_enterprise_features_enabled;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use sqlx::{PgExecutor, query, query_as};
use sqlx::{PgExecutor, Type, query, query_as};
use struct_patch::Patch;

use crate::enterprise::is_enterprise_enabled;
use crate::enterprise::is_business_license_active;

#[derive(Debug, Deserialize, Patch, Serialize)]
#[patch(attribute(derive(Deserialize, Serialize)))]
pub struct EnterpriseSettings {
// If true, only admins can manage devices
/// If true, only admins can manage devices
pub admin_device_management: bool,
// If true, the option to route all traffic through the vpn is disabled in the client
pub disable_all_traffic: bool,
// If true, manual WireGuard setup is disabled
/// Describes allowed routing options for clients connecting to the instance.
pub client_traffic_policy: ClientTrafficPolicy,
/// If true, manual WireGuard setup is disabled
pub only_client_activation: bool,
}

Expand All @@ -20,8 +20,8 @@ impl Default for EnterpriseSettings {
fn default() -> Self {
Self {
admin_device_management: false,
disable_all_traffic: false,
only_client_activation: false,
client_traffic_policy: ClientTrafficPolicy::default(),
}
}
}
Expand All @@ -35,11 +35,12 @@ impl EnterpriseSettings {
{
// avoid holding the rwlock across await, makes the future !Send
// and therefore unusable in axum handlers
if is_enterprise_enabled() {
if is_business_license_active() {
let settings = query_as!(
Self,
"SELECT admin_device_management, \
disable_all_traffic, only_client_activation \
client_traffic_policy \"client_traffic_policy: ClientTrafficPolicy\", \
only_client_activation \
FROM \"enterprisesettings\" WHERE id = 1",
)
.fetch_optional(executor)
Expand All @@ -57,11 +58,11 @@ impl EnterpriseSettings {
query!(
"UPDATE \"enterprisesettings\" SET \
admin_device_management = $1, \
disable_all_traffic = $2, \
client_traffic_policy = $2, \
only_client_activation = $3 \
WHERE id = 1",
self.admin_device_management,
self.disable_all_traffic,
self.client_traffic_policy as ClientTrafficPolicy,
self.only_client_activation,
)
.execute(executor)
Expand All @@ -70,3 +71,17 @@ impl EnterpriseSettings {
Ok(())
}
}

/// Describes allowed traffic options for clients connecting to the instance.
#[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Type, Debug, Default, Copy)]
#[sqlx(type_name = "client_traffic_policy", rename_all = "snake_case")]
#[serde(rename_all = "snake_case")]
pub enum ClientTrafficPolicy {
/// No restrictions
#[default]
None,
/// Clients are not allowed to route all traffic through the VPN.
DisableAllTraffic,
/// Clients are forced to route all traffic through the VPN.
ForceAllTraffic,
}
10 changes: 5 additions & 5 deletions crates/defguard_core/src/enterprise/directory_sync/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ use sqlx::{PgConnection, PgPool, error::Error as SqlxError};
use thiserror::Error;
use tokio::sync::broadcast::Sender;

#[cfg(not(test))]
use super::is_enterprise_enabled;
use super::{
db::models::openid_provider::{DirectorySyncTarget, OpenIdProvider},
ldap::utils::ldap_update_users_state,
};
#[cfg(not(test))]
use crate::enterprise::is_business_license_active;
use crate::{
enterprise::{
db::models::openid_provider::DirectorySyncUserBehavior,
Expand Down Expand Up @@ -390,7 +390,7 @@ pub(crate) async fn test_directory_sync_connection(
pool: &PgPool,
) -> Result<(), DirectorySyncError> {
#[cfg(not(test))]
if !is_enterprise_enabled() {
if !is_business_license_active() {
debug!("Enterprise is not enabled, skipping testing directory sync connection");
return Ok(());
}
Expand All @@ -415,7 +415,7 @@ pub(crate) async fn sync_user_groups_if_configured(
wg_tx: &Sender<GatewayEvent>,
) -> Result<(), DirectorySyncError> {
#[cfg(not(test))]
if !is_enterprise_enabled() {
if !is_business_license_active() {
debug!("Enterprise is not enabled, skipping syncing user groups");
return Ok(());
}
Expand Down Expand Up @@ -975,7 +975,7 @@ pub(crate) async fn do_directory_sync(
wireguard_tx: &Sender<GatewayEvent>,
) -> Result<(), DirectorySyncError> {
#[cfg(not(test))]
if !is_enterprise_enabled() {
if !is_business_license_active() {
debug!("Enterprise is not enabled, skipping performing directory sync");
return Ok(());
}
Expand Down
4 changes: 2 additions & 2 deletions crates/defguard_core/src/enterprise/firewall/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use super::{
};
use crate::enterprise::{
db::models::{acl::AliasKind, snat::UserSnatBinding},
is_enterprise_enabled,
is_business_license_active,
};

#[derive(Debug, thiserror::Error)]
Expand Down Expand Up @@ -905,7 +905,7 @@ pub async fn try_get_location_firewall_config(
conn: &mut PgConnection,
) -> Result<Option<FirewallConfig>, FirewallError> {
// do a license check
if !is_enterprise_enabled() {
if !is_business_license_active() {
debug!(
"Enterprise features are disabled, skipping generating firewall config for \
location {location}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use tonic::Status;
use crate::{
enterprise::{
handlers::openid_login::{extract_state_data, user_from_claims},
is_enterprise_enabled,
is_business_license_active,
},
events::{BidiRequestContext, BidiStreamEvent, BidiStreamEventType, DesktopClientMfaEvent},
grpc::{
Expand All @@ -23,7 +23,7 @@ impl ClientMfaServer {
info: Option<DeviceInfo>,
) -> Result<(), Status> {
debug!("Received OIDC MFA authentication request: {request:?}");
if !is_enterprise_enabled() {
if !is_business_license_active() {
error!("OIDC MFA method requires enterprise feature to be enabled");
return Err(Status::invalid_argument("OIDC MFA method is not supported"));
}
Expand Down
Loading