mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Add user search filter field for LDAP and validation for search filters
This commit is contained in:
@@ -0,0 +1,15 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
await knex.schema.alterTable(TableName.LdapConfig, (t) => {
|
||||||
|
t.string("searchFilter").notNullable().defaultTo("");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function down(knex: Knex): Promise<void> {
|
||||||
|
await knex.schema.alterTable(TableName.LdapConfig, (t) => {
|
||||||
|
t.dropColumn("searchFilter");
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -25,7 +25,8 @@ export const LdapConfigsSchema = z.object({
|
|||||||
createdAt: z.date(),
|
createdAt: z.date(),
|
||||||
updatedAt: z.date(),
|
updatedAt: z.date(),
|
||||||
groupSearchBase: z.string().default(""),
|
groupSearchBase: z.string().default(""),
|
||||||
groupSearchFilter: z.string().default("")
|
groupSearchFilter: z.string().default(""),
|
||||||
|
searchFilter: z.string().default("")
|
||||||
});
|
});
|
||||||
|
|
||||||
export type TLdapConfigs = z.infer<typeof LdapConfigsSchema>;
|
export type TLdapConfigs = z.infer<typeof LdapConfigsSchema>;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { z } from "zod";
|
|||||||
|
|
||||||
import { LdapConfigsSchema, LdapGroupMapsSchema } from "@app/db/schemas";
|
import { LdapConfigsSchema, LdapGroupMapsSchema } from "@app/db/schemas";
|
||||||
import { TLDAPConfig } from "@app/ee/services/ldap-config/ldap-config-types";
|
import { TLDAPConfig } from "@app/ee/services/ldap-config/ldap-config-types";
|
||||||
import { searchGroups } from "@app/ee/services/ldap-config/ldap-fns";
|
import { isValidLdapFilter, searchGroups } from "@app/ee/services/ldap-config/ldap-fns";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { logger } from "@app/lib/logger";
|
import { logger } from "@app/lib/logger";
|
||||||
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
|
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
|
||||||
@@ -55,10 +55,14 @@ export const registerLdapRouter = async (server: FastifyZodProvider) => {
|
|||||||
const ldapConfig = (req as unknown as FastifyRequest).ldapConfig as TLDAPConfig;
|
const ldapConfig = (req as unknown as FastifyRequest).ldapConfig as TLDAPConfig;
|
||||||
|
|
||||||
const groupFilter = "(|(memberUid={{.Username}})(member={{.UserDN}})(uniqueMember={{.UserDN}}))";
|
const groupFilter = "(|(memberUid={{.Username}})(member={{.UserDN}})(uniqueMember={{.UserDN}}))";
|
||||||
const searchFilter = (ldapConfig.groupSearchFilter || groupFilter)
|
const groupSearchFilter = (ldapConfig.groupSearchFilter || groupFilter)
|
||||||
.replace(/{{\.Username}}/g, user.uid)
|
.replace(/{{\.Username}}/g, user.uid)
|
||||||
.replace(/{{\.UserDN}}/g, user.dn);
|
.replace(/{{\.UserDN}}/g, user.dn);
|
||||||
|
|
||||||
|
if (!isValidLdapFilter(groupSearchFilter)) {
|
||||||
|
throw new Error("Generated LDAP search filter is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
const { isUserCompleted, providerAuthToken } = await server.services.ldap.ldapLogin({
|
const { isUserCompleted, providerAuthToken } = await server.services.ldap.ldapLogin({
|
||||||
ldapConfigId: ldapConfig.id,
|
ldapConfigId: ldapConfig.id,
|
||||||
externalId: user.uidNumber,
|
externalId: user.uidNumber,
|
||||||
@@ -67,7 +71,7 @@ export const registerLdapRouter = async (server: FastifyZodProvider) => {
|
|||||||
lastName: user.sn ?? "",
|
lastName: user.sn ?? "",
|
||||||
emails: user.mail ? [user.mail] : [],
|
emails: user.mail ? [user.mail] : [],
|
||||||
groups: ldapConfig.groupSearchBase
|
groups: ldapConfig.groupSearchBase
|
||||||
? await searchGroups(ldapConfig, searchFilter, ldapConfig.groupSearchBase)
|
? await searchGroups(ldapConfig, groupSearchFilter, ldapConfig.groupSearchBase)
|
||||||
: undefined,
|
: undefined,
|
||||||
relayState: ((req as unknown as FastifyRequest).body as { RelayState?: string }).RelayState,
|
relayState: ((req as unknown as FastifyRequest).body as { RelayState?: string }).RelayState,
|
||||||
orgId: (req as unknown as FastifyRequest).ldapConfig.organization
|
orgId: (req as unknown as FastifyRequest).ldapConfig.organization
|
||||||
@@ -130,6 +134,7 @@ export const registerLdapRouter = async (server: FastifyZodProvider) => {
|
|||||||
bindDN: z.string(),
|
bindDN: z.string(),
|
||||||
bindPass: z.string(),
|
bindPass: z.string(),
|
||||||
searchBase: z.string(),
|
searchBase: z.string(),
|
||||||
|
searchFilter: z.string(),
|
||||||
groupSearchBase: z.string(),
|
groupSearchBase: z.string(),
|
||||||
groupSearchFilter: z.string(),
|
groupSearchFilter: z.string(),
|
||||||
caCert: z.string()
|
caCert: z.string()
|
||||||
@@ -163,8 +168,12 @@ export const registerLdapRouter = async (server: FastifyZodProvider) => {
|
|||||||
bindDN: z.string().trim(),
|
bindDN: z.string().trim(),
|
||||||
bindPass: z.string().trim(),
|
bindPass: z.string().trim(),
|
||||||
searchBase: z.string().trim(),
|
searchBase: z.string().trim(),
|
||||||
groupSearchBase: z.string().trim().default(""),
|
searchFilter: z.string().trim().default("(uid={{username}})"),
|
||||||
groupSearchFilter: z.string().trim().default(""),
|
groupSearchBase: z.string().trim(),
|
||||||
|
groupSearchFilter: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.default("(|(memberUid={{.Username}})(member={{.UserDN}})(uniqueMember={{.UserDN}}))"),
|
||||||
caCert: z.string().trim().default("")
|
caCert: z.string().trim().default("")
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
@@ -200,6 +209,7 @@ export const registerLdapRouter = async (server: FastifyZodProvider) => {
|
|||||||
bindDN: z.string().trim(),
|
bindDN: z.string().trim(),
|
||||||
bindPass: z.string().trim(),
|
bindPass: z.string().trim(),
|
||||||
searchBase: z.string().trim(),
|
searchBase: z.string().trim(),
|
||||||
|
searchFilter: z.string().trim(),
|
||||||
groupSearchBase: z.string().trim(),
|
groupSearchBase: z.string().trim(),
|
||||||
groupSearchFilter: z.string().trim(),
|
groupSearchFilter: z.string().trim(),
|
||||||
caCert: z.string().trim()
|
caCert: z.string().trim()
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ import {
|
|||||||
TTestLdapConnectionDTO,
|
TTestLdapConnectionDTO,
|
||||||
TUpdateLdapCfgDTO
|
TUpdateLdapCfgDTO
|
||||||
} from "./ldap-config-types";
|
} from "./ldap-config-types";
|
||||||
import { testLDAPConfig } from "./ldap-fns";
|
import { isValidLdapFilter, testLDAPConfig } from "./ldap-fns";
|
||||||
import { TLdapGroupMapDALFactory } from "./ldap-group-map-dal";
|
import { TLdapGroupMapDALFactory } from "./ldap-group-map-dal";
|
||||||
|
|
||||||
type TLdapConfigServiceFactoryDep = {
|
type TLdapConfigServiceFactoryDep = {
|
||||||
@@ -98,6 +98,7 @@ export const ldapConfigServiceFactory = ({
|
|||||||
bindDN,
|
bindDN,
|
||||||
bindPass,
|
bindPass,
|
||||||
searchBase,
|
searchBase,
|
||||||
|
searchFilter,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
groupSearchFilter,
|
groupSearchFilter,
|
||||||
caCert
|
caCert
|
||||||
@@ -112,6 +113,18 @@ export const ldapConfigServiceFactory = ({
|
|||||||
"Failed to create LDAP configuration due to plan restriction. Upgrade plan to create LDAP configuration."
|
"Failed to create LDAP configuration due to plan restriction. Upgrade plan to create LDAP configuration."
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isSearchFilterValid = isValidLdapFilter(searchFilter);
|
||||||
|
if (!isSearchFilterValid)
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: "Failed to create LDAP configuration due to invalid search filter."
|
||||||
|
});
|
||||||
|
|
||||||
|
const isGroupSearchFilterValid = isValidLdapFilter(groupSearchFilter);
|
||||||
|
if (!isGroupSearchFilterValid)
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: "Failed to create LDAP configuration due to invalid group search filter."
|
||||||
|
});
|
||||||
|
|
||||||
const orgBot = await orgBotDAL.transaction(async (tx) => {
|
const orgBot = await orgBotDAL.transaction(async (tx) => {
|
||||||
const doc = await orgBotDAL.findOne({ orgId }, tx);
|
const doc = await orgBotDAL.findOne({ orgId }, tx);
|
||||||
if (doc) return doc;
|
if (doc) return doc;
|
||||||
@@ -175,6 +188,7 @@ export const ldapConfigServiceFactory = ({
|
|||||||
bindPassIV,
|
bindPassIV,
|
||||||
bindPassTag,
|
bindPassTag,
|
||||||
searchBase,
|
searchBase,
|
||||||
|
searchFilter,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
groupSearchFilter,
|
groupSearchFilter,
|
||||||
encryptedCACert,
|
encryptedCACert,
|
||||||
@@ -196,6 +210,7 @@ export const ldapConfigServiceFactory = ({
|
|||||||
bindDN,
|
bindDN,
|
||||||
bindPass,
|
bindPass,
|
||||||
searchBase,
|
searchBase,
|
||||||
|
searchFilter,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
groupSearchFilter,
|
groupSearchFilter,
|
||||||
caCert
|
caCert
|
||||||
@@ -210,10 +225,27 @@ export const ldapConfigServiceFactory = ({
|
|||||||
"Failed to update LDAP configuration due to plan restriction. Upgrade plan to update LDAP configuration."
|
"Failed to update LDAP configuration due to plan restriction. Upgrade plan to update LDAP configuration."
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (searchFilter) {
|
||||||
|
const isSearchFilterValid = isValidLdapFilter(searchFilter);
|
||||||
|
if (!isSearchFilterValid)
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: "Failed to update LDAP configuration due to invalid search filter."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (groupSearchFilter) {
|
||||||
|
const isGroupSearchFilterValid = isValidLdapFilter(groupSearchFilter);
|
||||||
|
if (!isGroupSearchFilterValid)
|
||||||
|
throw new BadRequestError({
|
||||||
|
message: "Failed to update LDAP configuration due to invalid group search filter."
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const updateQuery: TLdapConfigsUpdate = {
|
const updateQuery: TLdapConfigsUpdate = {
|
||||||
isActive,
|
isActive,
|
||||||
url,
|
url,
|
||||||
searchBase,
|
searchBase,
|
||||||
|
searchFilter,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
groupSearchFilter
|
groupSearchFilter
|
||||||
};
|
};
|
||||||
@@ -317,6 +349,7 @@ export const ldapConfigServiceFactory = ({
|
|||||||
bindDN,
|
bindDN,
|
||||||
bindPass,
|
bindPass,
|
||||||
searchBase: ldapConfig.searchBase,
|
searchBase: ldapConfig.searchBase,
|
||||||
|
searchFilter: ldapConfig.searchFilter,
|
||||||
groupSearchBase: ldapConfig.groupSearchBase,
|
groupSearchBase: ldapConfig.groupSearchBase,
|
||||||
groupSearchFilter: ldapConfig.groupSearchFilter,
|
groupSearchFilter: ldapConfig.groupSearchFilter,
|
||||||
caCert
|
caCert
|
||||||
@@ -352,7 +385,7 @@ export const ldapConfigServiceFactory = ({
|
|||||||
bindDN: ldapConfig.bindDN,
|
bindDN: ldapConfig.bindDN,
|
||||||
bindCredentials: ldapConfig.bindPass,
|
bindCredentials: ldapConfig.bindPass,
|
||||||
searchBase: ldapConfig.searchBase,
|
searchBase: ldapConfig.searchBase,
|
||||||
searchFilter: "(uid={{username}})",
|
searchFilter: ldapConfig.searchFilter || "(uid={{username}})",
|
||||||
// searchAttributes: ["uid", "uidNumber", "givenName", "sn", "mail"],
|
// searchAttributes: ["uid", "uidNumber", "givenName", "sn", "mail"],
|
||||||
...(ldapConfig.caCert !== ""
|
...(ldapConfig.caCert !== ""
|
||||||
? {
|
? {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ export type TCreateLdapCfgDTO = {
|
|||||||
bindDN: string;
|
bindDN: string;
|
||||||
bindPass: string;
|
bindPass: string;
|
||||||
searchBase: string;
|
searchBase: string;
|
||||||
|
searchFilter: string;
|
||||||
groupSearchBase: string;
|
groupSearchBase: string;
|
||||||
groupSearchFilter: string;
|
groupSearchFilter: string;
|
||||||
caCert: string;
|
caCert: string;
|
||||||
@@ -33,6 +34,7 @@ export type TUpdateLdapCfgDTO = {
|
|||||||
bindDN: string;
|
bindDN: string;
|
||||||
bindPass: string;
|
bindPass: string;
|
||||||
searchBase: string;
|
searchBase: string;
|
||||||
|
searchFilter: string;
|
||||||
groupSearchBase: string;
|
groupSearchBase: string;
|
||||||
groupSearchFilter: string;
|
groupSearchFilter: string;
|
||||||
caCert: string;
|
caCert: string;
|
||||||
|
|||||||
@@ -4,6 +4,17 @@ import { logger } from "@app/lib/logger";
|
|||||||
|
|
||||||
import { TLDAPConfig } from "./ldap-config-types";
|
import { TLDAPConfig } from "./ldap-config-types";
|
||||||
|
|
||||||
|
export const isValidLdapFilter = (filter: string) => {
|
||||||
|
try {
|
||||||
|
ldapjs.parseFilter(filter);
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
logger.error("Invalid LDAP filter");
|
||||||
|
logger.error(error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the LDAP configuration by attempting to bind to the LDAP server
|
* Test the LDAP configuration by attempting to bind to the LDAP server
|
||||||
* @param ldapConfig - The LDAP configuration to test
|
* @param ldapConfig - The LDAP configuration to test
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ You can configure your organization in Infisical to have members authenticate wi
|
|||||||
- URL: The LDAP server to connect to such as `ldap://ldap.your-org.com`, `ldaps://ldap.myorg.com:636` (for connection over SSL/TLS), etc.
|
- URL: The LDAP server to connect to such as `ldap://ldap.your-org.com`, `ldaps://ldap.myorg.com:636` (for connection over SSL/TLS), etc.
|
||||||
- Bind DN: The distinguished name of object to bind when performing the user search such as `cn=infisical,ou=Users,dc=acme,dc=com`.
|
- Bind DN: The distinguished name of object to bind when performing the user search such as `cn=infisical,ou=Users,dc=acme,dc=com`.
|
||||||
- Bind Pass: The password to use along with `Bind DN` when performing the user search.
|
- Bind Pass: The password to use along with `Bind DN` when performing the user search.
|
||||||
- Search Base / User DN: Base DN under which to perform user search such as `ou=Users,dc=acme,dc=com`
|
- User Search Base / User DN: Base DN under which to perform user search such as `ou=Users,dc=acme,dc=com`.
|
||||||
|
- User Search Filter (optional): Template used to construct the LDAP user search filter such as `(uid={{username}})`; use literal `{{username}}` to have the given username used in the search. The default is `(uid={{username}})` which is compatible with several common directory schemas.
|
||||||
- Group Search Base / Group DN (optional): LDAP search base to use for group membership search such as `ou=Groups,dc=acme,dc=com`.
|
- Group Search Base / Group DN (optional): LDAP search base to use for group membership search such as `ou=Groups,dc=acme,dc=com`.
|
||||||
- Group Filter (optional): Template used when constructing the group membership query such as `(&(objectClass=posixGroup)(memberUid={{.Username}}))`. The template can access the following context variables: [`UserDN`, `UserName`]. The default is `(|(memberUid={{.Username}})(member={{.UserDN}})(uniqueMember={{.UserDN}}))` which is compatible with several common directory schemas.
|
- Group Filter (optional): Template used when constructing the group membership query such as `(&(objectClass=posixGroup)(memberUid={{.Username}}))`. The template can access the following context variables: [`UserDN`, `UserName`]. The default is `(|(memberUid={{.Username}})(member={{.UserDN}})(uniqueMember={{.UserDN}}))` which is compatible with several common directory schemas.
|
||||||
- CA Certificate: The CA certificate to use when verifying the LDAP server certificate.
|
- CA Certificate: The CA certificate to use when verifying the LDAP server certificate.
|
||||||
@@ -35,6 +36,14 @@ You can configure your organization in Infisical to have members authenticate wi
|
|||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
</Step>
|
</Step>
|
||||||
|
<Step title="Test the LDAP connection">
|
||||||
|
Once you've filled out the LDAP configuration, you can test that part of the configuration is correct by pressing the **Test Connection** button.
|
||||||
|
|
||||||
|
Infisical will attempt to bind to the LDAP server using the provided **URL**, **Bind DN**, and **Bind Pass**. If the operation is successful, then Infisical will display a success message; if not, then Infisical will display an error message and provide a fuller error in the server logs.
|
||||||
|
|
||||||
|

|
||||||
|
</Step>
|
||||||
|
|
||||||
<Step title="Define mappings from LDAP groups to groups in Infisical">
|
<Step title="Define mappings from LDAP groups to groups in Infisical">
|
||||||
In order to sync LDAP groups to Infisical, head to the **LDAP Group Mappings** section to define mappings from LDAP groups to groups in Infisical.
|
In order to sync LDAP groups to Infisical, head to the **LDAP Group Mappings** section to define mappings from LDAP groups to groups in Infisical.
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ description: "Learn how to configure JumpCloud LDAP for authenticating into Infi
|
|||||||
Next, under User Security Settings and Permissions > Permission Settings, check the box next to **Enable as LDAP Bind DN**.
|
Next, under User Security Settings and Permissions > Permission Settings, check the box next to **Enable as LDAP Bind DN**.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
</Step>
|
</Step>
|
||||||
<Step title="Prepare the LDAP configuration in Infisical">
|
<Step title="Prepare the LDAP configuration in Infisical">
|
||||||
In Infisical, head to your Organization Settings > Security > LDAP and select **Manage**.
|
In Infisical, head to your Organization Settings > Security > LDAP and select **Manage**.
|
||||||
@@ -35,7 +34,8 @@ description: "Learn how to configure JumpCloud LDAP for authenticating into Infi
|
|||||||
- URL: The LDAP server to connect to (`ldaps://ldap.jumpcloud.com:636`).
|
- URL: The LDAP server to connect to (`ldaps://ldap.jumpcloud.com:636`).
|
||||||
- Bind DN: The distinguished name of object to bind when performing the user search (`uid=<ldap-user-username>,ou=Users,o=<your-org-id>,dc=jumpcloud,dc=com`).
|
- Bind DN: The distinguished name of object to bind when performing the user search (`uid=<ldap-user-username>,ou=Users,o=<your-org-id>,dc=jumpcloud,dc=com`).
|
||||||
- Bind Pass: The password to use along with `Bind DN` when performing the user search.
|
- Bind Pass: The password to use along with `Bind DN` when performing the user search.
|
||||||
- Search Base / User DN: Base DN under which to perform user search (`ou=Users,o=<your-org-id>,dc=jumpcloud,dc=com`).
|
- User Search Base / User DN: Base DN under which to perform user search (`ou=Users,o=<your-org-id>,dc=jumpcloud,dc=com`).
|
||||||
|
- User Search Filter (optional): Template used to construct the LDAP user search filter (`(uid={{username}})`).
|
||||||
- Group Search Base / Group DN (optional): LDAP search base to use for group membership search (`ou=Users,o=<your-org-id>,dc=jumpcloud,dc=com`).
|
- Group Search Base / Group DN (optional): LDAP search base to use for group membership search (`ou=Users,o=<your-org-id>,dc=jumpcloud,dc=com`).
|
||||||
- Group Filter (optional): Template used when constructing the group membership query (`(&(objectClass=groupOfNames)(member=uid={{.Username}},ou=Users,o=<your-org-id>,dc=jumpcloud,dc=com))`)
|
- Group Filter (optional): Template used when constructing the group membership query (`(&(objectClass=groupOfNames)(member=uid={{.Username}},ou=Users,o=<your-org-id>,dc=jumpcloud,dc=com))`)
|
||||||
- CA Certificate: The CA certificate to use when verifying the LDAP server certificate (instructions to obtain the certificate for JumpCloud [here](https://jumpcloud.com/support/connect-to-ldap-with-tls-ssl)).
|
- CA Certificate: The CA certificate to use when verifying the LDAP server certificate (instructions to obtain the certificate for JumpCloud [here](https://jumpcloud.com/support/connect-to-ldap-with-tls-ssl)).
|
||||||
@@ -47,6 +47,13 @@ description: "Learn how to configure JumpCloud LDAP for authenticating into Infi
|
|||||||
in your LDAP instance **ORG DN**.
|
in your LDAP instance **ORG DN**.
|
||||||
</Tip>
|
</Tip>
|
||||||
</Step>
|
</Step>
|
||||||
|
<Step title="Test the LDAP connection">
|
||||||
|
Once you've filled out the LDAP configuration, you can test that part of the configuration is correct by pressing the **Test Connection** button.
|
||||||
|
|
||||||
|
Infisical will attempt to bind to the LDAP server using the provided **URL**, **Bind DN**, and **Bind Pass**. If the operation is successful, then Infisical will display a success message; if not, then Infisical will display an error message and provide a fuller error in the server logs.
|
||||||
|
|
||||||
|

|
||||||
|
</Step>
|
||||||
<Step title="Define mappings from LDAP groups to groups in Infisical">
|
<Step title="Define mappings from LDAP groups to groups in Infisical">
|
||||||
In order to sync LDAP groups to Infisical, head to the **LDAP Group Mappings** section to define mappings from LDAP groups to groups in Infisical.
|
In order to sync LDAP groups to Infisical, head to the **LDAP Group Mappings** section to define mappings from LDAP groups to groups in Infisical.
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 439 KiB After Width: | Height: | Size: 506 KiB |
BIN
docs/images/platform/ldap/ldap-test-connection.png
Normal file
BIN
docs/images/platform/ldap/ldap-test-connection.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 501 KiB |
@@ -14,6 +14,7 @@ export const useCreateLDAPConfig = () => {
|
|||||||
bindDN,
|
bindDN,
|
||||||
bindPass,
|
bindPass,
|
||||||
searchBase,
|
searchBase,
|
||||||
|
searchFilter,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
groupSearchFilter,
|
groupSearchFilter,
|
||||||
caCert
|
caCert
|
||||||
@@ -24,6 +25,7 @@ export const useCreateLDAPConfig = () => {
|
|||||||
bindDN: string;
|
bindDN: string;
|
||||||
bindPass: string;
|
bindPass: string;
|
||||||
searchBase: string;
|
searchBase: string;
|
||||||
|
searchFilter: string;
|
||||||
groupSearchBase: string;
|
groupSearchBase: string;
|
||||||
groupSearchFilter: string;
|
groupSearchFilter: string;
|
||||||
caCert?: string;
|
caCert?: string;
|
||||||
@@ -35,6 +37,7 @@ export const useCreateLDAPConfig = () => {
|
|||||||
bindDN,
|
bindDN,
|
||||||
bindPass,
|
bindPass,
|
||||||
searchBase,
|
searchBase,
|
||||||
|
searchFilter,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
groupSearchFilter,
|
groupSearchFilter,
|
||||||
caCert
|
caCert
|
||||||
@@ -58,6 +61,7 @@ export const useUpdateLDAPConfig = () => {
|
|||||||
bindDN,
|
bindDN,
|
||||||
bindPass,
|
bindPass,
|
||||||
searchBase,
|
searchBase,
|
||||||
|
searchFilter,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
groupSearchFilter,
|
groupSearchFilter,
|
||||||
caCert
|
caCert
|
||||||
@@ -68,6 +72,7 @@ export const useUpdateLDAPConfig = () => {
|
|||||||
bindDN?: string;
|
bindDN?: string;
|
||||||
bindPass?: string;
|
bindPass?: string;
|
||||||
searchBase?: string;
|
searchBase?: string;
|
||||||
|
searchFilter?: string;
|
||||||
groupSearchBase?: string;
|
groupSearchBase?: string;
|
||||||
groupSearchFilter?: string;
|
groupSearchFilter?: string;
|
||||||
caCert?: string;
|
caCert?: string;
|
||||||
@@ -79,6 +84,7 @@ export const useUpdateLDAPConfig = () => {
|
|||||||
bindDN,
|
bindDN,
|
||||||
bindPass,
|
bindPass,
|
||||||
searchBase,
|
searchBase,
|
||||||
|
searchFilter,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
groupSearchFilter,
|
groupSearchFilter,
|
||||||
caCert
|
caCert
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ import {
|
|||||||
useCreateLDAPConfig,
|
useCreateLDAPConfig,
|
||||||
useGetLDAPConfig,
|
useGetLDAPConfig,
|
||||||
useTestLDAPConnection,
|
useTestLDAPConnection,
|
||||||
useUpdateLDAPConfig} from "@app/hooks/api";
|
useUpdateLDAPConfig
|
||||||
|
} from "@app/hooks/api";
|
||||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||||
|
|
||||||
const LDAPFormSchema = z.object({
|
const LDAPFormSchema = z.object({
|
||||||
@@ -18,6 +19,7 @@ const LDAPFormSchema = z.object({
|
|||||||
bindDN: z.string().default(""),
|
bindDN: z.string().default(""),
|
||||||
bindPass: z.string().default(""),
|
bindPass: z.string().default(""),
|
||||||
searchBase: z.string().default(""),
|
searchBase: z.string().default(""),
|
||||||
|
searchFilter: z.string().default(""),
|
||||||
groupSearchBase: z.string().default(""),
|
groupSearchBase: z.string().default(""),
|
||||||
groupSearchFilter: z.string().default(""),
|
groupSearchFilter: z.string().default(""),
|
||||||
caCert: z.string().optional()
|
caCert: z.string().optional()
|
||||||
@@ -47,6 +49,7 @@ export const LDAPModal = ({ popUp, handlePopUpClose, handlePopUpToggle }: Props)
|
|||||||
const watchBindDN = watch("bindDN");
|
const watchBindDN = watch("bindDN");
|
||||||
const watchBindPass = watch("bindPass");
|
const watchBindPass = watch("bindPass");
|
||||||
const watchSearchBase = watch("searchBase");
|
const watchSearchBase = watch("searchBase");
|
||||||
|
const watchSearchFilter = watch("searchFilter");
|
||||||
const watchGroupSearchBase = watch("groupSearchBase");
|
const watchGroupSearchBase = watch("groupSearchBase");
|
||||||
const watchGroupSearchFilter = watch("groupSearchFilter");
|
const watchGroupSearchFilter = watch("groupSearchFilter");
|
||||||
const watchCaCert = watch("caCert");
|
const watchCaCert = watch("caCert");
|
||||||
@@ -58,6 +61,7 @@ export const LDAPModal = ({ popUp, handlePopUpClose, handlePopUpToggle }: Props)
|
|||||||
bindDN: data?.bindDN ?? "",
|
bindDN: data?.bindDN ?? "",
|
||||||
bindPass: data?.bindPass ?? "",
|
bindPass: data?.bindPass ?? "",
|
||||||
searchBase: data?.searchBase ?? "",
|
searchBase: data?.searchBase ?? "",
|
||||||
|
searchFilter: data?.searchFilter ?? "",
|
||||||
groupSearchBase: data?.groupSearchBase ?? "",
|
groupSearchBase: data?.groupSearchBase ?? "",
|
||||||
groupSearchFilter: data?.groupSearchFilter ?? "",
|
groupSearchFilter: data?.groupSearchFilter ?? "",
|
||||||
caCert: data?.caCert ?? ""
|
caCert: data?.caCert ?? ""
|
||||||
@@ -70,6 +74,7 @@ export const LDAPModal = ({ popUp, handlePopUpClose, handlePopUpToggle }: Props)
|
|||||||
bindDN,
|
bindDN,
|
||||||
bindPass,
|
bindPass,
|
||||||
searchBase,
|
searchBase,
|
||||||
|
searchFilter,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
groupSearchFilter,
|
groupSearchFilter,
|
||||||
caCert,
|
caCert,
|
||||||
@@ -86,6 +91,7 @@ export const LDAPModal = ({ popUp, handlePopUpClose, handlePopUpToggle }: Props)
|
|||||||
bindDN,
|
bindDN,
|
||||||
bindPass,
|
bindPass,
|
||||||
searchBase,
|
searchBase,
|
||||||
|
searchFilter,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
groupSearchFilter,
|
groupSearchFilter,
|
||||||
caCert
|
caCert
|
||||||
@@ -98,6 +104,7 @@ export const LDAPModal = ({ popUp, handlePopUpClose, handlePopUpToggle }: Props)
|
|||||||
bindDN,
|
bindDN,
|
||||||
bindPass,
|
bindPass,
|
||||||
searchBase,
|
searchBase,
|
||||||
|
searchFilter,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
groupSearchFilter,
|
groupSearchFilter,
|
||||||
caCert
|
caCert
|
||||||
@@ -128,6 +135,7 @@ export const LDAPModal = ({ popUp, handlePopUpClose, handlePopUpToggle }: Props)
|
|||||||
bindDN: watchBindDN,
|
bindDN: watchBindDN,
|
||||||
bindPass: watchBindPass,
|
bindPass: watchBindPass,
|
||||||
searchBase: watchSearchBase,
|
searchBase: watchSearchBase,
|
||||||
|
searchFilter: watchSearchFilter,
|
||||||
groupSearchBase: watchGroupSearchBase,
|
groupSearchBase: watchGroupSearchBase,
|
||||||
groupSearchFilter: watchGroupSearchFilter,
|
groupSearchFilter: watchGroupSearchFilter,
|
||||||
caCert: watchCaCert,
|
caCert: watchCaCert,
|
||||||
@@ -201,7 +209,7 @@ export const LDAPModal = ({ popUp, handlePopUpClose, handlePopUpToggle }: Props)
|
|||||||
name="searchBase"
|
name="searchBase"
|
||||||
render={({ field, fieldState: { error } }) => (
|
render={({ field, fieldState: { error } }) => (
|
||||||
<FormControl
|
<FormControl
|
||||||
label="Search Base / User DN"
|
label="User Search Base / User DN"
|
||||||
errorText={error?.message}
|
errorText={error?.message}
|
||||||
isError={Boolean(error)}
|
isError={Boolean(error)}
|
||||||
>
|
>
|
||||||
@@ -209,6 +217,19 @@ export const LDAPModal = ({ popUp, handlePopUpClose, handlePopUpToggle }: Props)
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="searchFilter"
|
||||||
|
render={({ field, fieldState: { error } }) => (
|
||||||
|
<FormControl
|
||||||
|
label="User Search Filter (Optional)"
|
||||||
|
errorText={error?.message}
|
||||||
|
isError={Boolean(error)}
|
||||||
|
>
|
||||||
|
<Input {...field} placeholder="(uid={{username}})" />
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="groupSearchBase"
|
name="groupSearchBase"
|
||||||
@@ -231,7 +252,10 @@ export const LDAPModal = ({ popUp, handlePopUpClose, handlePopUpToggle }: Props)
|
|||||||
errorText={error?.message}
|
errorText={error?.message}
|
||||||
isError={Boolean(error)}
|
isError={Boolean(error)}
|
||||||
>
|
>
|
||||||
<Input {...field} placeholder="(objectClass=posixGroup)" />
|
<Input
|
||||||
|
{...field}
|
||||||
|
placeholder="(&(objectClass=posixGroup)(memberUid={{.Username}}))"
|
||||||
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user