mirror of
https://github.com/fosrl/pangolin.git
synced 2026-06-12 18:37:20 +00:00
Properly paywall the new resource types
This commit is contained in:
@@ -16,18 +16,18 @@ export enum TierFeature {
|
||||
SessionDurationPolicies = "sessionDurationPolicies", // handle downgrade by setting to default duration
|
||||
PasswordExpirationPolicies = "passwordExpirationPolicies", // handle downgrade by setting to default duration
|
||||
AutoProvisioning = "autoProvisioning", // handle downgrade by disabling auto provisioning
|
||||
SshPam = "sshPam",
|
||||
FullRbac = "fullRbac",
|
||||
SiteProvisioningKeys = "siteProvisioningKeys", // handle downgrade by revoking keys if needed
|
||||
SIEM = "siem", // handle downgrade by disabling SIEM integrations
|
||||
HTTPPrivateResources = "httpPrivateResources", // handle downgrade by disabling HTTP private resources
|
||||
DomainNamespaces = "domainNamespaces", // handle downgrade by removing custom domain namespaces
|
||||
StandaloneHealthChecks = "standaloneHealthChecks",
|
||||
AlertingRules = "alertingRules",
|
||||
WildcardSubdomain = "wildcardSubdomain",
|
||||
Labels = "labels",
|
||||
NewtAutoUpdate = "newtAutoUpdate",
|
||||
ResourcePolicies = "resourcePolicies"
|
||||
ResourcePolicies = "resourcePolicies",
|
||||
AdvancedPublicResources = "advancedPublicResources",
|
||||
AdvancedPrivateResources = "advancedPrivateResources"
|
||||
}
|
||||
|
||||
export const tierMatrix: Record<TierFeature, Tier[]> = {
|
||||
@@ -62,15 +62,25 @@ export const tierMatrix: Record<TierFeature, Tier[]> = {
|
||||
"enterprise"
|
||||
],
|
||||
[TierFeature.AutoProvisioning]: ["tier1", "tier3", "enterprise"],
|
||||
[TierFeature.SshPam]: ["tier1", "tier3", "enterprise"],
|
||||
[TierFeature.FullRbac]: ["tier1", "tier2", "tier3", "enterprise"],
|
||||
[TierFeature.SiteProvisioningKeys]: ["tier3", "enterprise"],
|
||||
[TierFeature.SIEM]: ["enterprise"],
|
||||
[TierFeature.HTTPPrivateResources]: ["tier3", "enterprise"],
|
||||
[TierFeature.DomainNamespaces]: ["tier1", "tier2", "tier3", "enterprise"],
|
||||
[TierFeature.StandaloneHealthChecks]: ["tier3", "enterprise"],
|
||||
[TierFeature.AlertingRules]: ["tier3", "enterprise"],
|
||||
[TierFeature.WildcardSubdomain]: ["tier1", "tier2", "tier3", "enterprise"],
|
||||
[TierFeature.NewtAutoUpdate]: ["tier1", "tier2", "tier3", "enterprise"],
|
||||
[TierFeature.ResourcePolicies]: ["tier3", "enterprise"]
|
||||
[TierFeature.ResourcePolicies]: ["tier3", "enterprise"],
|
||||
[TierFeature.AdvancedPublicResources]: [
|
||||
"tier1",
|
||||
"tier2",
|
||||
"tier3",
|
||||
"enterprise"
|
||||
],
|
||||
[TierFeature.AdvancedPrivateResources]: [
|
||||
"tier1",
|
||||
"tier2",
|
||||
"tier3",
|
||||
"enterprise"
|
||||
]
|
||||
};
|
||||
|
||||
@@ -308,8 +308,8 @@ async function disableFeature(
|
||||
await disableAutoProvisioning(orgId);
|
||||
break;
|
||||
|
||||
case TierFeature.SshPam:
|
||||
await disableSshPam(orgId);
|
||||
case TierFeature.AdvancedPrivateResources:
|
||||
await disableAdvancedPrivateResources(orgId);
|
||||
break;
|
||||
|
||||
case TierFeature.FullRbac:
|
||||
@@ -357,10 +357,11 @@ async function disableDeviceApprovals(orgId: string): Promise<void> {
|
||||
logger.info(`Disabled device approvals on all roles for org ${orgId}`);
|
||||
}
|
||||
|
||||
async function disableSshPam(orgId: string): Promise<void> {
|
||||
logger.info(
|
||||
`Disabled SSH PAM options on all roles and site resources for org ${orgId}`
|
||||
);
|
||||
async function disableAdvancedPrivateResources(orgId: string): Promise<void> {
|
||||
// TODO: implement logic to disable advanced private resourcs like ssh and ssh pam
|
||||
// logger.info(
|
||||
// `Disabled advanced private resources on all roles and site resources for org ${orgId}`
|
||||
// );
|
||||
}
|
||||
|
||||
async function disableFullRbac(orgId: string): Promise<void> {
|
||||
|
||||
@@ -610,7 +610,7 @@ authenticated.put(
|
||||
authenticated.post(
|
||||
"/org/:orgId/ssh/sign-key",
|
||||
verifyValidLicense,
|
||||
verifyValidSubscription(tierMatrix.sshPam),
|
||||
verifyValidSubscription(tierMatrix.advancedPrivateResources),
|
||||
verifyOrgAccess,
|
||||
verifyLimits,
|
||||
verifyUserHasAction(ActionsEnum.signSshKey),
|
||||
|
||||
@@ -149,7 +149,7 @@ export async function signSshKey(
|
||||
|
||||
const isLicensed = await isLicensedOrSubscribed(
|
||||
orgId,
|
||||
tierMatrix.sshPam
|
||||
tierMatrix.advancedPrivateResources
|
||||
);
|
||||
if (!isLicensed) {
|
||||
return next(
|
||||
|
||||
@@ -31,7 +31,7 @@ import {
|
||||
} from "@server/lib/domainUtils";
|
||||
import { isSubscribed } from "#dynamic/lib/isSubscribed";
|
||||
import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed";
|
||||
import { tierMatrix } from "@server/lib/billing/tierMatrix";
|
||||
import { TierFeature, tierMatrix } from "@server/lib/billing/tierMatrix";
|
||||
import {
|
||||
getUniqueResourceName,
|
||||
getUniqueResourcePolicyName
|
||||
@@ -342,6 +342,21 @@ async function createHttpResource(
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
["ssh", "rdp", "vnc"].includes(mode!) &&
|
||||
!isLicensedOrSubscribed(
|
||||
orgId!,
|
||||
tierMatrix[TierFeature.AdvancedPublicResources]
|
||||
)
|
||||
) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.BAD_REQUEST,
|
||||
"Your current subscription does not support browser gateway resources. Please upgrade to access this feature."
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Validate domain and construct full domain
|
||||
const domainResult = await validateAndConstructDomain(
|
||||
domainId,
|
||||
|
||||
@@ -123,23 +123,40 @@ export async function createRole(
|
||||
);
|
||||
}
|
||||
|
||||
const isLicensedDeviceApprovals = await isLicensedOrSubscribed(orgId, tierMatrix.deviceApprovals);
|
||||
const isLicensedDeviceApprovals = await isLicensedOrSubscribed(
|
||||
orgId,
|
||||
tierMatrix.deviceApprovals
|
||||
);
|
||||
if (!isLicensedDeviceApprovals) {
|
||||
roleData.requireDeviceApproval = undefined;
|
||||
}
|
||||
|
||||
const isLicensedSshPam = await isLicensedOrSubscribed(orgId, tierMatrix.sshPam);
|
||||
const isLicensedSshPam = await isLicensedOrSubscribed(
|
||||
orgId,
|
||||
tierMatrix.advancedPrivateResources
|
||||
);
|
||||
const roleInsertValues: Record<string, unknown> = {
|
||||
name: roleData.name,
|
||||
orgId
|
||||
};
|
||||
if (roleData.description !== undefined) roleInsertValues.description = roleData.description;
|
||||
if (roleData.requireDeviceApproval !== undefined) roleInsertValues.requireDeviceApproval = roleData.requireDeviceApproval;
|
||||
if (roleData.description !== undefined)
|
||||
roleInsertValues.description = roleData.description;
|
||||
if (roleData.requireDeviceApproval !== undefined)
|
||||
roleInsertValues.requireDeviceApproval =
|
||||
roleData.requireDeviceApproval;
|
||||
if (isLicensedSshPam) {
|
||||
if (roleData.sshSudoMode !== undefined) roleInsertValues.sshSudoMode = roleData.sshSudoMode;
|
||||
if (roleData.sshSudoCommands !== undefined) roleInsertValues.sshSudoCommands = JSON.stringify(roleData.sshSudoCommands);
|
||||
if (roleData.sshCreateHomeDir !== undefined) roleInsertValues.sshCreateHomeDir = roleData.sshCreateHomeDir;
|
||||
if (roleData.sshUnixGroups !== undefined) roleInsertValues.sshUnixGroups = JSON.stringify(roleData.sshUnixGroups);
|
||||
if (roleData.sshSudoMode !== undefined)
|
||||
roleInsertValues.sshSudoMode = roleData.sshSudoMode;
|
||||
if (roleData.sshSudoCommands !== undefined)
|
||||
roleInsertValues.sshSudoCommands = JSON.stringify(
|
||||
roleData.sshSudoCommands
|
||||
);
|
||||
if (roleData.sshCreateHomeDir !== undefined)
|
||||
roleInsertValues.sshCreateHomeDir = roleData.sshCreateHomeDir;
|
||||
if (roleData.sshUnixGroups !== undefined)
|
||||
roleInsertValues.sshUnixGroups = JSON.stringify(
|
||||
roleData.sshUnixGroups
|
||||
);
|
||||
}
|
||||
|
||||
await db.transaction(async (trx) => {
|
||||
|
||||
@@ -134,12 +134,18 @@ export async function updateRole(
|
||||
);
|
||||
}
|
||||
|
||||
const isLicensedDeviceApprovals = await isLicensedOrSubscribed(orgId, tierMatrix.deviceApprovals);
|
||||
const isLicensedDeviceApprovals = await isLicensedOrSubscribed(
|
||||
orgId,
|
||||
tierMatrix.deviceApprovals
|
||||
);
|
||||
if (!isLicensedDeviceApprovals) {
|
||||
updateData.requireDeviceApproval = undefined;
|
||||
}
|
||||
|
||||
const isLicensedSshPam = await isLicensedOrSubscribed(orgId, tierMatrix.sshPam);
|
||||
const isLicensedSshPam = await isLicensedOrSubscribed(
|
||||
orgId,
|
||||
tierMatrix.advancedPrivateResources
|
||||
);
|
||||
if (!isLicensedSshPam) {
|
||||
delete updateData.sshSudoMode;
|
||||
delete updateData.sshSudoCommands;
|
||||
@@ -147,10 +153,14 @@ export async function updateRole(
|
||||
delete updateData.sshUnixGroups;
|
||||
} else {
|
||||
if (Array.isArray(updateData.sshSudoCommands)) {
|
||||
updateData.sshSudoCommands = JSON.stringify(updateData.sshSudoCommands);
|
||||
updateData.sshSudoCommands = JSON.stringify(
|
||||
updateData.sshSudoCommands
|
||||
);
|
||||
}
|
||||
if (Array.isArray(updateData.sshUnixGroups)) {
|
||||
updateData.sshUnixGroups = JSON.stringify(updateData.sshUnixGroups);
|
||||
updateData.sshUnixGroups = JSON.stringify(
|
||||
updateData.sshUnixGroups
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -293,7 +293,7 @@ export async function createSiteResource(
|
||||
if (mode == "http") {
|
||||
const hasHttpFeature = await isLicensedOrSubscribed(
|
||||
orgId,
|
||||
tierMatrix[TierFeature.HTTPPrivateResources]
|
||||
tierMatrix[TierFeature.AdvancedPrivateResources]
|
||||
);
|
||||
if (!hasHttpFeature) {
|
||||
return next(
|
||||
@@ -425,9 +425,18 @@ export async function createSiteResource(
|
||||
|
||||
const isLicensedSshPam = await isLicensedOrSubscribed(
|
||||
orgId,
|
||||
tierMatrix.sshPam
|
||||
tierMatrix.advancedPrivateResources
|
||||
);
|
||||
|
||||
if (mode == "ssh" && !isLicensedSshPam) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.FORBIDDEN,
|
||||
"SSH private resources are not included in your current plan. Please upgrade."
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
let updatedNiceId = niceId;
|
||||
if (!niceId) {
|
||||
updatedNiceId = await getUniqueSiteResourceName(orgId);
|
||||
|
||||
@@ -314,7 +314,7 @@ export async function updateSiteResource(
|
||||
if (mode == "http") {
|
||||
const hasHttpFeature = await isLicensedOrSubscribed(
|
||||
existingSiteResource.orgId,
|
||||
tierMatrix[TierFeature.HTTPPrivateResources]
|
||||
tierMatrix[TierFeature.AdvancedPrivateResources]
|
||||
);
|
||||
if (!hasHttpFeature) {
|
||||
return next(
|
||||
@@ -328,7 +328,7 @@ export async function updateSiteResource(
|
||||
|
||||
const isLicensedSshPam = await isLicensedOrSubscribed(
|
||||
existingSiteResource.orgId,
|
||||
tierMatrix.sshPam
|
||||
tierMatrix.advancedPrivateResources
|
||||
);
|
||||
|
||||
const [org] = await db
|
||||
|
||||
Reference in New Issue
Block a user