feat(identities): ldap auth, requested changes

This commit is contained in:
Daniel Hougaard
2025-05-08 08:14:29 +04:00
parent 5c91d380b8
commit 0b31d7f860
18 changed files with 44 additions and 35 deletions
@@ -30,6 +30,7 @@ export const identityAccessTokenDALFactory = (db: TDbClient) => {
.leftJoin(TableName.IdentityGcpAuth, `${TableName.Identity}.id`, `${TableName.IdentityGcpAuth}.identityId`) .leftJoin(TableName.IdentityGcpAuth, `${TableName.Identity}.id`, `${TableName.IdentityGcpAuth}.identityId`)
.leftJoin(TableName.IdentityAwsAuth, `${TableName.Identity}.id`, `${TableName.IdentityAwsAuth}.identityId`) .leftJoin(TableName.IdentityAwsAuth, `${TableName.Identity}.id`, `${TableName.IdentityAwsAuth}.identityId`)
.leftJoin(TableName.IdentityAzureAuth, `${TableName.Identity}.id`, `${TableName.IdentityAzureAuth}.identityId`) .leftJoin(TableName.IdentityAzureAuth, `${TableName.Identity}.id`, `${TableName.IdentityAzureAuth}.identityId`)
.leftJoin(TableName.IdentityLdapAuth, `${TableName.Identity}.id`, `${TableName.IdentityLdapAuth}.identityId`)
.leftJoin( .leftJoin(
TableName.IdentityKubernetesAuth, TableName.IdentityKubernetesAuth,
`${TableName.Identity}.id`, `${TableName.Identity}.id`,
@@ -48,6 +49,7 @@ export const identityAccessTokenDALFactory = (db: TDbClient) => {
db.ref("accessTokenTrustedIps").withSchema(TableName.IdentityOidcAuth).as("accessTokenTrustedIpsOidc"), db.ref("accessTokenTrustedIps").withSchema(TableName.IdentityOidcAuth).as("accessTokenTrustedIpsOidc"),
db.ref("accessTokenTrustedIps").withSchema(TableName.IdentityTokenAuth).as("accessTokenTrustedIpsToken"), db.ref("accessTokenTrustedIps").withSchema(TableName.IdentityTokenAuth).as("accessTokenTrustedIpsToken"),
db.ref("accessTokenTrustedIps").withSchema(TableName.IdentityJwtAuth).as("accessTokenTrustedIpsJwt"), db.ref("accessTokenTrustedIps").withSchema(TableName.IdentityJwtAuth).as("accessTokenTrustedIpsJwt"),
db.ref("accessTokenTrustedIps").withSchema(TableName.IdentityLdapAuth).as("accessTokenTrustedIpsLdap"),
db.ref("name").withSchema(TableName.Identity) db.ref("name").withSchema(TableName.Identity)
) )
.first(); .first();
@@ -63,7 +65,8 @@ export const identityAccessTokenDALFactory = (db: TDbClient) => {
trustedIpsKubernetesAuth: doc.accessTokenTrustedIpsK8s, trustedIpsKubernetesAuth: doc.accessTokenTrustedIpsK8s,
trustedIpsOidcAuth: doc.accessTokenTrustedIpsOidc, trustedIpsOidcAuth: doc.accessTokenTrustedIpsOidc,
trustedIpsAccessTokenAuth: doc.accessTokenTrustedIpsToken, trustedIpsAccessTokenAuth: doc.accessTokenTrustedIpsToken,
trustedIpsAccessJwtAuth: doc.accessTokenTrustedIpsJwt trustedIpsAccessJwtAuth: doc.accessTokenTrustedIpsJwt,
trustedIpsAccessLdapAuth: doc.accessTokenTrustedIpsLdap
}; };
} catch (error) { } catch (error) {
throw new DatabaseError({ error, name: "IdAccessTokenFindOne" }); throw new DatabaseError({ error, name: "IdAccessTokenFindOne" });
@@ -186,7 +186,8 @@ export const identityAccessTokenServiceFactory = ({
[IdentityAuthMethod.KUBERNETES_AUTH]: identityAccessToken.trustedIpsKubernetesAuth, [IdentityAuthMethod.KUBERNETES_AUTH]: identityAccessToken.trustedIpsKubernetesAuth,
[IdentityAuthMethod.OIDC_AUTH]: identityAccessToken.trustedIpsOidcAuth, [IdentityAuthMethod.OIDC_AUTH]: identityAccessToken.trustedIpsOidcAuth,
[IdentityAuthMethod.TOKEN_AUTH]: identityAccessToken.trustedIpsAccessTokenAuth, [IdentityAuthMethod.TOKEN_AUTH]: identityAccessToken.trustedIpsAccessTokenAuth,
[IdentityAuthMethod.JWT_AUTH]: identityAccessToken.trustedIpsAccessJwtAuth [IdentityAuthMethod.JWT_AUTH]: identityAccessToken.trustedIpsAccessJwtAuth,
[IdentityAuthMethod.LDAP_AUTH]: identityAccessToken.trustedIpsAccessLdapAuth
}; };
const trustedIps = trustedIpsMap[identityAccessToken.authMethod as IdentityAuthMethod]; const trustedIps = trustedIpsMap[identityAccessToken.authMethod as IdentityAuthMethod];
@@ -241,6 +241,8 @@ export const identityLdapAuthServiceFactory = ({
return extractIPDetails(accessTokenTrustedIp.ipAddress); return extractIPDetails(accessTokenTrustedIp.ipAddress);
}); });
if (allowedFields) AllowedFieldsSchema.array().parse(allowedFields);
const identityLdapAuth = await identityLdapAuthDAL.transaction(async (tx) => { const identityLdapAuth = await identityLdapAuthDAL.transaction(async (tx) => {
const { encryptor } = await kmsService.createCipherPairWithDataKey({ const { encryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
@@ -264,8 +266,6 @@ export const identityLdapAuthServiceFactory = ({
plainText: Buffer.from(bindDN) plainText: Buffer.from(bindDN)
}); });
if (allowedFields) AllowedFieldsSchema.array().parse(allowedFields);
const isConnected = await testLDAPConfig({ const isConnected = await testLDAPConfig({
bindDN, bindDN,
bindPass, bindPass,
@@ -374,6 +374,8 @@ export const identityLdapAuthServiceFactory = ({
return extractIPDetails(accessTokenTrustedIp.ipAddress); return extractIPDetails(accessTokenTrustedIp.ipAddress);
}); });
if (allowedFields) AllowedFieldsSchema.array().parse(allowedFields);
const { encryptor } = await kmsService.createCipherPairWithDataKey({ const { encryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
orgId: identityMembershipOrg.orgId orgId: identityMembershipOrg.orgId
@@ -422,8 +424,6 @@ export const identityLdapAuthServiceFactory = ({
}); });
} }
if (allowedFields) AllowedFieldsSchema.array().parse(allowedFields);
const updatedLdapAuth = await identityLdapAuthDAL.updateById(identityLdapAuth.id, { const updatedLdapAuth = await identityLdapAuthDAL.updateById(identityLdapAuth.id, {
url, url,
searchBase, searchBase,
@@ -192,7 +192,7 @@ export const eventToNameMap: { [K in EventType]: string } = {
[EventType.REVOKE_IDENTITY_LDAP_AUTH]: "Revoked LDAP Auth for identity" [EventType.REVOKE_IDENTITY_LDAP_AUTH]: "Revoked LDAP Auth for identity"
}; };
export const userAgentTTypeoNameMap: { [K in UserAgentType]: string } = { export const userAgentTypeToNameMap: { [K in UserAgentType]: string } = {
[UserAgentType.WEB]: "Web", [UserAgentType.WEB]: "Web",
[UserAgentType.CLI]: "CLI", [UserAgentType.CLI]: "CLI",
[UserAgentType.K8_OPERATOR]: "K8s operator", [UserAgentType.K8_OPERATOR]: "K8s operator",
+8 -7
View File
@@ -47,6 +47,13 @@ export enum EventType {
CREATE_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRET = "create-identity-universal-auth-client-secret", CREATE_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRET = "create-identity-universal-auth-client-secret",
REVOKE_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRET = "revoke-identity-universal-auth-client-secret", REVOKE_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRET = "revoke-identity-universal-auth-client-secret",
GET_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRETS = "get-identity-universal-auth-client-secret", GET_IDENTITY_UNIVERSAL_AUTH_CLIENT_SECRETS = "get-identity-universal-auth-client-secret",
LOGIN_IDENTITY_LDAP_AUTH = "login-identity-ldap-auth",
ADD_IDENTITY_LDAP_AUTH = "add-identity-ldap-auth",
UPDATE_IDENTITY_LDAP_AUTH = "update-identity-ldap-auth",
GET_IDENTITY_LDAP_AUTH = "get-identity-ldap-auth",
REVOKE_IDENTITY_LDAP_AUTH = "revoke-identity-ldap-auth",
CREATE_ENVIRONMENT = "create-environment", CREATE_ENVIRONMENT = "create-environment",
UPDATE_ENVIRONMENT = "update-environment", UPDATE_ENVIRONMENT = "update-environment",
DELETE_ENVIRONMENT = "delete-environment", DELETE_ENVIRONMENT = "delete-environment",
@@ -176,11 +183,5 @@ export enum EventType {
MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_CHECK_INSTALLATION_STATUS = "microsoft-teams-workflow-integration-check-installation-status", MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_CHECK_INSTALLATION_STATUS = "microsoft-teams-workflow-integration-check-installation-status",
MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_GET_TEAMS = "microsoft-teams-workflow-integration-get-teams", MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_GET_TEAMS = "microsoft-teams-workflow-integration-get-teams",
MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_GET = "microsoft-teams-workflow-integration-get", MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_GET = "microsoft-teams-workflow-integration-get",
MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_LIST = "microsoft-teams-workflow-integration-list", MICROSOFT_TEAMS_WORKFLOW_INTEGRATION_LIST = "microsoft-teams-workflow-integration-list"
LOGIN_IDENTITY_LDAP_AUTH = "login-identity-ldap-auth",
ADD_IDENTITY_LDAP_AUTH = "add-identity-ldap-auth",
UPDATE_IDENTITY_LDAP_AUTH = "update-identity-ldap-auth",
GET_IDENTITY_LDAP_AUTH = "get-identity-ldap-auth",
REVOKE_IDENTITY_LDAP_AUTH = "revoke-identity-ldap-auth"
} }
@@ -1145,6 +1145,9 @@ export const useUpdateIdentityLdapAuth = () => {
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId) queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
}); });
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) }); queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
queryClient.invalidateQueries({
queryKey: identitiesKeys.getIdentityLdapAuth(identityId)
});
} }
}); });
}; };
@@ -253,6 +253,7 @@ export const useGetIdentityLdapAuth = (
enabled: Boolean(identityId) && (options?.enabled ?? true) enabled: Boolean(identityId) && (options?.enabled ?? true)
}); });
}; };
export const useGetIdentityTokensTokenAuth = (identityId: string) => { export const useGetIdentityTokensTokenAuth = (identityId: string) => {
return useQuery({ return useQuery({
enabled: Boolean(identityId), enabled: Boolean(identityId),
+1 -1
View File
@@ -482,7 +482,7 @@ export type IdentityLdapAuth = {
searchFilter: string; searchFilter: string;
uniqueAttribute: string; uniqueAttribute: string;
ldapCaCertificate?: string; ldapCaCertificate?: string;
allowedFields: { allowedFields?: {
key: string; key: string;
value: string; value: string;
}[]; }[];
@@ -38,7 +38,7 @@ import { useGetUserWorkspaces } from "@app/hooks/api";
import { import {
eventToNameMap, eventToNameMap,
secretEvents, secretEvents,
userAgentTTypeoNameMap userAgentTypeToNameMap
} from "@app/hooks/api/auditLogs/constants"; } from "@app/hooks/api/auditLogs/constants";
import { EventType } from "@app/hooks/api/auditLogs/enums"; import { EventType } from "@app/hooks/api/auditLogs/enums";
import { UserAgentType } from "@app/hooks/api/auth/types"; import { UserAgentType } from "@app/hooks/api/auth/types";
@@ -47,7 +47,7 @@ import { LogFilterItem } from "./LogFilterItem";
import { AuditLogFilterFormData, Presets } from "./types"; import { AuditLogFilterFormData, Presets } from "./types";
const eventTypes = Object.entries(eventToNameMap).map(([value, label]) => ({ label, value })); const eventTypes = Object.entries(eventToNameMap).map(([value, label]) => ({ label, value }));
const userAgentTypes = Object.entries(userAgentTTypeoNameMap).map(([value, label]) => ({ const userAgentTypes = Object.entries(userAgentTypeToNameMap).map(([value, label]) => ({
label, label,
value value
})); }));
@@ -47,10 +47,10 @@ export const ViewIdentityAwsAuthContent = ({
onEdit={() => handlePopUpOpen("identityAuthMethod")} onEdit={() => handlePopUpOpen("identityAuthMethod")}
onDelete={onDelete} onDelete={onDelete}
> >
<IdentityAuthFieldDisplay label="Access Token TLL (seconds)"> <IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
{data.accessTokenTTL} {data.accessTokenTTL}
</IdentityAuthFieldDisplay> </IdentityAuthFieldDisplay>
<IdentityAuthFieldDisplay label="Access Token Max TLL (seconds)"> <IdentityAuthFieldDisplay label="Access Token Max TTL (seconds)">
{data.accessTokenMaxTTL} {data.accessTokenMaxTTL}
</IdentityAuthFieldDisplay> </IdentityAuthFieldDisplay>
<IdentityAuthFieldDisplay label="Access Token Max Number of Uses"> <IdentityAuthFieldDisplay label="Access Token Max Number of Uses">
@@ -47,10 +47,10 @@ export const ViewIdentityAzureAuthContent = ({
onEdit={() => handlePopUpOpen("identityAuthMethod")} onEdit={() => handlePopUpOpen("identityAuthMethod")}
onDelete={onDelete} onDelete={onDelete}
> >
<IdentityAuthFieldDisplay label="Access Token TLL (seconds)"> <IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
{data.accessTokenTTL} {data.accessTokenTTL}
</IdentityAuthFieldDisplay> </IdentityAuthFieldDisplay>
<IdentityAuthFieldDisplay label="Access Token Max TLL (seconds)"> <IdentityAuthFieldDisplay label="Access Token Max TTL (seconds)">
{data.accessTokenMaxTTL} {data.accessTokenMaxTTL}
</IdentityAuthFieldDisplay> </IdentityAuthFieldDisplay>
<IdentityAuthFieldDisplay label="Access Token Max Number of Uses"> <IdentityAuthFieldDisplay label="Access Token Max Number of Uses">
@@ -47,10 +47,10 @@ export const ViewIdentityGcpAuthContent = ({
onEdit={() => handlePopUpOpen("identityAuthMethod")} onEdit={() => handlePopUpOpen("identityAuthMethod")}
onDelete={onDelete} onDelete={onDelete}
> >
<IdentityAuthFieldDisplay label="Access Token TLL (seconds)"> <IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
{data.accessTokenTTL} {data.accessTokenTTL}
</IdentityAuthFieldDisplay> </IdentityAuthFieldDisplay>
<IdentityAuthFieldDisplay label="Access Token Max TLL (seconds)"> <IdentityAuthFieldDisplay label="Access Token Max TTL (seconds)">
{data.accessTokenMaxTTL} {data.accessTokenMaxTTL}
</IdentityAuthFieldDisplay> </IdentityAuthFieldDisplay>
<IdentityAuthFieldDisplay label="Access Token Max Number of Uses"> <IdentityAuthFieldDisplay label="Access Token Max Number of Uses">
@@ -49,10 +49,10 @@ export const ViewIdentityJwtAuthContent = ({
onEdit={() => handlePopUpOpen("identityAuthMethod")} onEdit={() => handlePopUpOpen("identityAuthMethod")}
onDelete={onDelete} onDelete={onDelete}
> >
<IdentityAuthFieldDisplay label="Access Token TLL (seconds)"> <IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
{data.accessTokenTTL} {data.accessTokenTTL}
</IdentityAuthFieldDisplay> </IdentityAuthFieldDisplay>
<IdentityAuthFieldDisplay label="Access Token Max TLL (seconds)"> <IdentityAuthFieldDisplay label="Access Token Max TTL (seconds)">
{data.accessTokenMaxTTL} {data.accessTokenMaxTTL}
</IdentityAuthFieldDisplay> </IdentityAuthFieldDisplay>
<IdentityAuthFieldDisplay label="Access Token Max Number of Uses"> <IdentityAuthFieldDisplay label="Access Token Max Number of Uses">
@@ -51,10 +51,10 @@ export const ViewIdentityKubernetesAuthContent = ({
onEdit={() => handlePopUpOpen("identityAuthMethod")} onEdit={() => handlePopUpOpen("identityAuthMethod")}
onDelete={onDelete} onDelete={onDelete}
> >
<IdentityAuthFieldDisplay label="Access Token TLL (seconds)"> <IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
{data.accessTokenTTL} {data.accessTokenTTL}
</IdentityAuthFieldDisplay> </IdentityAuthFieldDisplay>
<IdentityAuthFieldDisplay label="Access Token Max TLL (seconds)"> <IdentityAuthFieldDisplay label="Access Token Max TTL (seconds)">
{data.accessTokenMaxTTL} {data.accessTokenMaxTTL}
</IdentityAuthFieldDisplay> </IdentityAuthFieldDisplay>
<IdentityAuthFieldDisplay label="Access Token Max Number of Uses"> <IdentityAuthFieldDisplay label="Access Token Max Number of Uses">
@@ -48,10 +48,10 @@ export const ViewIdentityLdapAuthContent = ({
onEdit={() => handlePopUpOpen("identityAuthMethod")} onEdit={() => handlePopUpOpen("identityAuthMethod")}
onDelete={onDelete} onDelete={onDelete}
> >
<IdentityAuthFieldDisplay label="Access Token TLL (seconds)"> <IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
{data.accessTokenTTL} {data.accessTokenTTL}
</IdentityAuthFieldDisplay> </IdentityAuthFieldDisplay>
<IdentityAuthFieldDisplay label="Access Token Max TLL (seconds)"> <IdentityAuthFieldDisplay label="Access Token Max TTL (seconds)">
{data.accessTokenMaxTTL} {data.accessTokenMaxTTL}
</IdentityAuthFieldDisplay> </IdentityAuthFieldDisplay>
<IdentityAuthFieldDisplay label="Access Token Max Number of Uses"> <IdentityAuthFieldDisplay label="Access Token Max Number of Uses">
@@ -48,10 +48,10 @@ export const ViewIdentityOidcAuthContent = ({
onEdit={() => handlePopUpOpen("identityAuthMethod")} onEdit={() => handlePopUpOpen("identityAuthMethod")}
onDelete={onDelete} onDelete={onDelete}
> >
<IdentityAuthFieldDisplay label="Access Token TLL (seconds)"> <IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
{data.accessTokenTTL} {data.accessTokenTTL}
</IdentityAuthFieldDisplay> </IdentityAuthFieldDisplay>
<IdentityAuthFieldDisplay label="Access Token Max TLL (seconds)"> <IdentityAuthFieldDisplay label="Access Token Max TTL (seconds)">
{data.accessTokenMaxTTL} {data.accessTokenMaxTTL}
</IdentityAuthFieldDisplay> </IdentityAuthFieldDisplay>
<IdentityAuthFieldDisplay label="Access Token Max Number of Uses"> <IdentityAuthFieldDisplay label="Access Token Max Number of Uses">
@@ -50,10 +50,10 @@ export const ViewIdentityTokenAuthContent = ({
onEdit={() => handlePopUpOpen("identityAuthMethod")} onEdit={() => handlePopUpOpen("identityAuthMethod")}
onDelete={onDelete} onDelete={onDelete}
> >
<IdentityAuthFieldDisplay label="Access Token TLL (seconds)"> <IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
{data.accessTokenTTL} {data.accessTokenTTL}
</IdentityAuthFieldDisplay> </IdentityAuthFieldDisplay>
<IdentityAuthFieldDisplay label="Access Token Max TLL (seconds)"> <IdentityAuthFieldDisplay label="Access Token Max TTL (seconds)">
{data.accessTokenMaxTTL} {data.accessTokenMaxTTL}
</IdentityAuthFieldDisplay> </IdentityAuthFieldDisplay>
<IdentityAuthFieldDisplay label="Access Token Max Number of Uses"> <IdentityAuthFieldDisplay label="Access Token Max Number of Uses">
@@ -62,10 +62,10 @@ export const ViewIdentityUniversalAuthContent = ({
onEdit={() => handlePopUpOpen("identityAuthMethod")} onEdit={() => handlePopUpOpen("identityAuthMethod")}
onDelete={onDelete} onDelete={onDelete}
> >
<IdentityAuthFieldDisplay label="Access Token TLL (seconds)"> <IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
{data.accessTokenTTL} {data.accessTokenTTL}
</IdentityAuthFieldDisplay> </IdentityAuthFieldDisplay>
<IdentityAuthFieldDisplay label="Access Token Max TLL (seconds)"> <IdentityAuthFieldDisplay label="Access Token Max TTL (seconds)">
{data.accessTokenMaxTTL} {data.accessTokenMaxTTL}
</IdentityAuthFieldDisplay> </IdentityAuthFieldDisplay>
<IdentityAuthFieldDisplay label="Access Token Max Number of Uses"> <IdentityAuthFieldDisplay label="Access Token Max Number of Uses">