diff --git a/backend/windmill-api-workspaces/src/workspaces.rs b/backend/windmill-api-workspaces/src/workspaces.rs index cb5d9c2a03..64c07754e9 100644 --- a/backend/windmill-api-workspaces/src/workspaces.rs +++ b/backend/windmill-api-workspaces/src/workspaces.rs @@ -4044,6 +4044,13 @@ async fn invite_user( ) -> Result<(StatusCode, String)> { require_admin(is_admin, &username)?; + #[cfg(not(feature = "enterprise"))] + if w_id == "admins" { + return Err(Error::BadRequest( + "The admins workspace is reserved for superadmins. Members cannot be added to it without an enterprise license.".to_string(), + )); + } + nu.email = nu.email.to_lowercase(); let mut tx = db.begin().await?; @@ -4109,6 +4116,14 @@ async fn add_user( Json(mut nu): Json, ) -> Result<(StatusCode, String)> { require_admin(authed.is_admin, &authed.username)?; + + #[cfg(not(feature = "enterprise"))] + if w_id == "admins" { + return Err(Error::BadRequest( + "The admins workspace is reserved for superadmins. Members cannot be added to it without an enterprise license.".to_string(), + )); + } + nu.email = nu.email.to_lowercase(); let mut tx = db.begin().await?; diff --git a/frontend/src/lib/components/settings/WorkspaceUserSettings.svelte b/frontend/src/lib/components/settings/WorkspaceUserSettings.svelte index 8b245c7c70..839dd0c138 100644 --- a/frontend/src/lib/components/settings/WorkspaceUserSettings.svelte +++ b/frontend/src/lib/components/settings/WorkspaceUserSettings.svelte @@ -402,6 +402,8 @@ } return autoAdd ? 'add' : 'invite' }) + + const isAdminsWorkspaceWithoutEE = $derived($workspaceStore === 'admins' && !$enterpriseLicense) +{#if isAdminsWorkspaceWithoutEE} + + The admins workspace is reserved for superadmins. Only users with superadmin privileges can + access it. Members cannot be manually added or invited to this workspace. + +{/if} +
{#snippet action()}
- - {#snippet trigger()} - - {/snippet} - {#snippet content()} -
- {#if showAutoInviteToggle} -
Mode Whether to invite or add users directly to the workspace. -
- { - const switchingToAdd = e.detail === 'add' && !autoAdd - - // If switching from invite to add on non-cloud, show confirmation with warning - if (switchingToAdd && isLegacyAutoInvite) { - switchToAutoAddConfirmCallback = async () => { - autoAdd = true - if (autoInviteOrAddEnabled) { - await updateAutoInvite(true) - } - } - } else { - autoAdd = e.detail === 'add' - if (autoInviteOrAddEnabled) { - await updateAutoInvite(true) - } - } - }} - > - {#snippet children({ item })} - - - {/snippet} - - - {#if isLegacyAutoInvite && !autoAdd} -
- - Auto-invite is deprecated. Switching to auto-add will permanently disable - auto-invite for this workspace. - -
- {/if} - -
- {/if} - - Role Role of the auto-added users - { - operatorOnly = e.detail === 'operator' - if (auto_invite_domain != undefined) { - await updateAutoInvite(true) - } - }} - > - {#snippet children({ item })} - - - {/snippet} - - -
- { - const enabling = e.detail - - if (enabling) { - // Non-cloud users without legacy auto-invite: force auto-add mode - if (!isCloudHosted() && !isLegacyAutoInvite) { - autoAdd = true - } - - // Show confirmation when enabling auto-add - if (autoAdd || (!isCloudHosted() && !showAutoInviteToggle)) { - autoAddConfirmCallback = async () => { - await updateAutoInvite(true) - } - } else { - await updateAutoInvite(true) - } - } else { - // Disabling: show confirmation if currently using auto-invite (legacy) - if (isLegacyAutoInvite) { - autoInviteDisableConfirmCallback = async () => { - await updateAutoInvite(false) - } - } else { - await updateAutoInvite(false) - } - } - }} - disabled={isCloudHosted() && !allowedAutoDomain} - options={{ - right: isCloudHosted() - ? `Auto-${displayMode} anyone from ${ - autoInviteOrAddEnabled ? auto_invite_domain : domain - }` - : `Auto-${displayMode} anyone joining the instance` - }} - /> -
- {#if isCloudHosted() && !allowedAutoDomain} -
{domain} domain not allowed for auto-add
- {/if} -
- {/snippet} -
- - {#if instanceGroups.length > 0} + {#if !isAdminsWorkspaceWithoutEE} {#snippet trigger()} {/snippet} {#snippet content()} -
-
- Auto-add instance groups +
+ {#if showAutoInviteToggle} +
Mode Whether to invite or add users directly to the workspace. +
+ { + const switchingToAdd = e.detail === 'add' && !autoAdd - - {#if availableGroupItems.length > 0} -
-
-
- Instance group - +
+ +
+ Role + { + selectedNewRole = e.detail + }} + > + {#snippet children({ item })} + + + + {/snippet} + +
+
+ + +
+ {/if} + + + {#if autoAddInstanceGroups.length > 0} +
+

Configured groups:

+
+ + + + + + + + + + {#each autoAddInstanceGroups as groupName (groupName)} + {@const group = instanceGroups.find((g) => g.name === groupName)} + + + + + + {/each} + +
GroupRole
+
{groupName}
+ {#if group?.summary} +
{group.summary}
+ {/if} +
+
+ { + autoAddInstanceGroupsRoles[groupName] = e.detail + await updateGroupRole(groupName, e.detail) + }} + > + {#snippet children({ item })} + + + + {/snippet} + +
+
+
+ +
+
+
+
+ {:else} +
+ No instance groups configured for auto-add +
+ {/if} +
+
+ {/snippet} + + {/if} + + {#if showAutoInviteToggle} + + {/if} + + { + listUsers() + listInvites() + }} + /> + {/if}
{/snippet} @@ -1028,7 +1040,7 @@ documentationLink="https://www.windmill.dev/docs/core_concepts/authentification#adding-users-to-a-workspace" > {#snippet action()} - {#if showAutoInviteToggle} + {#if showAutoInviteToggle && !isAdminsWorkspaceWithoutEE}