mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 13:27:46 +00:00
feat: added support for configurable ldap user identifier
This commit is contained in:
@@ -0,0 +1,19 @@
|
|||||||
|
import { Knex } from "knex";
|
||||||
|
|
||||||
|
import { TableName } from "../schemas";
|
||||||
|
|
||||||
|
export async function up(knex: Knex): Promise<void> {
|
||||||
|
if (!(await knex.schema.hasColumn(TableName.LdapConfig, "uniqueUserAttribute"))) {
|
||||||
|
await knex.schema.alterTable(TableName.LdapConfig, (tb) => {
|
||||||
|
tb.string("uniqueUserAttribute").notNullable().defaultTo("");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function down(knex: Knex): Promise<void> {
|
||||||
|
if (await knex.schema.hasColumn(TableName.LdapConfig, "uniqueUserAttribute")) {
|
||||||
|
await knex.schema.alterTable(TableName.LdapConfig, (t) => {
|
||||||
|
t.dropColumn("uniqueUserAttribute");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,7 +26,8 @@ export const LdapConfigsSchema = z.object({
|
|||||||
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("")
|
searchFilter: z.string().default(""),
|
||||||
|
uniqueUserAttribute: z.string().default("")
|
||||||
});
|
});
|
||||||
|
|
||||||
export type TLdapConfigs = z.infer<typeof LdapConfigsSchema>;
|
export type TLdapConfigs = z.infer<typeof LdapConfigsSchema>;
|
||||||
|
|||||||
@@ -70,10 +70,13 @@ export const registerLdapRouter = async (server: FastifyZodProvider) => {
|
|||||||
groups = await searchGroups(ldapConfig, groupSearchFilter, ldapConfig.groupSearchBase);
|
groups = await searchGroups(ldapConfig, groupSearchFilter, ldapConfig.groupSearchBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const externalId = ldapConfig.uniqueUserAttribute ? user[ldapConfig.uniqueUserAttribute] : user.uidNumber;
|
||||||
|
const username = ldapConfig.uniqueUserAttribute ? externalId : user.uid;
|
||||||
|
|
||||||
const { isUserCompleted, providerAuthToken } = await server.services.ldap.ldapLogin({
|
const { isUserCompleted, providerAuthToken } = await server.services.ldap.ldapLogin({
|
||||||
|
externalId,
|
||||||
|
username,
|
||||||
ldapConfigId: ldapConfig.id,
|
ldapConfigId: ldapConfig.id,
|
||||||
externalId: user.uidNumber,
|
|
||||||
username: user.uid,
|
|
||||||
firstName: user.givenName ?? user.cn ?? "",
|
firstName: user.givenName ?? user.cn ?? "",
|
||||||
lastName: user.sn ?? "",
|
lastName: user.sn ?? "",
|
||||||
email: user.mail,
|
email: user.mail,
|
||||||
@@ -138,6 +141,7 @@ export const registerLdapRouter = async (server: FastifyZodProvider) => {
|
|||||||
url: z.string(),
|
url: z.string(),
|
||||||
bindDN: z.string(),
|
bindDN: z.string(),
|
||||||
bindPass: z.string(),
|
bindPass: z.string(),
|
||||||
|
uniqueUserAttribute: z.string(),
|
||||||
searchBase: z.string(),
|
searchBase: z.string(),
|
||||||
searchFilter: z.string(),
|
searchFilter: z.string(),
|
||||||
groupSearchBase: z.string(),
|
groupSearchBase: z.string(),
|
||||||
@@ -172,6 +176,7 @@ export const registerLdapRouter = async (server: FastifyZodProvider) => {
|
|||||||
url: z.string().trim(),
|
url: z.string().trim(),
|
||||||
bindDN: z.string().trim(),
|
bindDN: z.string().trim(),
|
||||||
bindPass: z.string().trim(),
|
bindPass: z.string().trim(),
|
||||||
|
uniqueUserAttribute: z.string().trim().default("uidNumber"),
|
||||||
searchBase: z.string().trim(),
|
searchBase: z.string().trim(),
|
||||||
searchFilter: z.string().trim().default("(uid={{username}})"),
|
searchFilter: z.string().trim().default("(uid={{username}})"),
|
||||||
groupSearchBase: z.string().trim(),
|
groupSearchBase: z.string().trim(),
|
||||||
@@ -213,6 +218,7 @@ export const registerLdapRouter = async (server: FastifyZodProvider) => {
|
|||||||
url: z.string().trim(),
|
url: z.string().trim(),
|
||||||
bindDN: z.string().trim(),
|
bindDN: z.string().trim(),
|
||||||
bindPass: z.string().trim(),
|
bindPass: z.string().trim(),
|
||||||
|
uniqueUserAttribute: z.string().trim(),
|
||||||
searchBase: z.string().trim(),
|
searchBase: z.string().trim(),
|
||||||
searchFilter: z.string().trim(),
|
searchFilter: z.string().trim(),
|
||||||
groupSearchBase: z.string().trim(),
|
groupSearchBase: z.string().trim(),
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ export const ldapConfigServiceFactory = ({
|
|||||||
url,
|
url,
|
||||||
bindDN,
|
bindDN,
|
||||||
bindPass,
|
bindPass,
|
||||||
|
uniqueUserAttribute,
|
||||||
searchBase,
|
searchBase,
|
||||||
searchFilter,
|
searchFilter,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
@@ -200,6 +201,7 @@ export const ldapConfigServiceFactory = ({
|
|||||||
encryptedBindPass,
|
encryptedBindPass,
|
||||||
bindPassIV,
|
bindPassIV,
|
||||||
bindPassTag,
|
bindPassTag,
|
||||||
|
uniqueUserAttribute,
|
||||||
searchBase,
|
searchBase,
|
||||||
searchFilter,
|
searchFilter,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
@@ -222,6 +224,7 @@ export const ldapConfigServiceFactory = ({
|
|||||||
url,
|
url,
|
||||||
bindDN,
|
bindDN,
|
||||||
bindPass,
|
bindPass,
|
||||||
|
uniqueUserAttribute,
|
||||||
searchBase,
|
searchBase,
|
||||||
searchFilter,
|
searchFilter,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
@@ -244,7 +247,8 @@ export const ldapConfigServiceFactory = ({
|
|||||||
searchBase,
|
searchBase,
|
||||||
searchFilter,
|
searchFilter,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
groupSearchFilter
|
groupSearchFilter,
|
||||||
|
uniqueUserAttribute
|
||||||
};
|
};
|
||||||
|
|
||||||
const orgBot = await orgBotDAL.findOne({ orgId });
|
const orgBot = await orgBotDAL.findOne({ orgId });
|
||||||
@@ -345,6 +349,7 @@ export const ldapConfigServiceFactory = ({
|
|||||||
url: ldapConfig.url,
|
url: ldapConfig.url,
|
||||||
bindDN,
|
bindDN,
|
||||||
bindPass,
|
bindPass,
|
||||||
|
uniqueUserAttribute: ldapConfig.uniqueUserAttribute,
|
||||||
searchBase: ldapConfig.searchBase,
|
searchBase: ldapConfig.searchBase,
|
||||||
searchFilter: ldapConfig.searchFilter,
|
searchFilter: ldapConfig.searchFilter,
|
||||||
groupSearchBase: ldapConfig.groupSearchBase,
|
groupSearchBase: ldapConfig.groupSearchBase,
|
||||||
@@ -381,6 +386,7 @@ export const ldapConfigServiceFactory = ({
|
|||||||
url: ldapConfig.url,
|
url: ldapConfig.url,
|
||||||
bindDN: ldapConfig.bindDN,
|
bindDN: ldapConfig.bindDN,
|
||||||
bindCredentials: ldapConfig.bindPass,
|
bindCredentials: ldapConfig.bindPass,
|
||||||
|
uniqueUserAttribute: ldapConfig.uniqueUserAttribute,
|
||||||
searchBase: ldapConfig.searchBase,
|
searchBase: ldapConfig.searchBase,
|
||||||
searchFilter: ldapConfig.searchFilter || "(uid={{username}})",
|
searchFilter: ldapConfig.searchFilter || "(uid={{username}})",
|
||||||
// searchAttributes: ["uid", "uidNumber", "givenName", "sn", "mail"],
|
// searchAttributes: ["uid", "uidNumber", "givenName", "sn", "mail"],
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export type TLDAPConfig = {
|
|||||||
url: string;
|
url: string;
|
||||||
bindDN: string;
|
bindDN: string;
|
||||||
bindPass: string;
|
bindPass: string;
|
||||||
|
uniqueUserAttribute: string;
|
||||||
searchBase: string;
|
searchBase: string;
|
||||||
groupSearchBase: string;
|
groupSearchBase: string;
|
||||||
groupSearchFilter: string;
|
groupSearchFilter: string;
|
||||||
@@ -19,6 +20,7 @@ export type TCreateLdapCfgDTO = {
|
|||||||
url: string;
|
url: string;
|
||||||
bindDN: string;
|
bindDN: string;
|
||||||
bindPass: string;
|
bindPass: string;
|
||||||
|
uniqueUserAttribute: string;
|
||||||
searchBase: string;
|
searchBase: string;
|
||||||
searchFilter: string;
|
searchFilter: string;
|
||||||
groupSearchBase: string;
|
groupSearchBase: string;
|
||||||
@@ -33,6 +35,7 @@ export type TUpdateLdapCfgDTO = {
|
|||||||
url: string;
|
url: string;
|
||||||
bindDN: string;
|
bindDN: string;
|
||||||
bindPass: string;
|
bindPass: string;
|
||||||
|
uniqueUserAttribute: string;
|
||||||
searchBase: string;
|
searchBase: string;
|
||||||
searchFilter: string;
|
searchFilter: string;
|
||||||
groupSearchBase: string;
|
groupSearchBase: string;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ export const useCreateLDAPConfig = () => {
|
|||||||
url,
|
url,
|
||||||
bindDN,
|
bindDN,
|
||||||
bindPass,
|
bindPass,
|
||||||
|
uniqueUserAttribute,
|
||||||
searchBase,
|
searchBase,
|
||||||
searchFilter,
|
searchFilter,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
@@ -24,6 +25,7 @@ export const useCreateLDAPConfig = () => {
|
|||||||
url: string;
|
url: string;
|
||||||
bindDN: string;
|
bindDN: string;
|
||||||
bindPass: string;
|
bindPass: string;
|
||||||
|
uniqueUserAttribute: string;
|
||||||
searchBase: string;
|
searchBase: string;
|
||||||
searchFilter: string;
|
searchFilter: string;
|
||||||
groupSearchBase: string;
|
groupSearchBase: string;
|
||||||
@@ -36,6 +38,7 @@ export const useCreateLDAPConfig = () => {
|
|||||||
url,
|
url,
|
||||||
bindDN,
|
bindDN,
|
||||||
bindPass,
|
bindPass,
|
||||||
|
uniqueUserAttribute,
|
||||||
searchBase,
|
searchBase,
|
||||||
searchFilter,
|
searchFilter,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
@@ -60,6 +63,7 @@ export const useUpdateLDAPConfig = () => {
|
|||||||
url,
|
url,
|
||||||
bindDN,
|
bindDN,
|
||||||
bindPass,
|
bindPass,
|
||||||
|
uniqueUserAttribute,
|
||||||
searchBase,
|
searchBase,
|
||||||
searchFilter,
|
searchFilter,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
@@ -71,6 +75,7 @@ export const useUpdateLDAPConfig = () => {
|
|||||||
url?: string;
|
url?: string;
|
||||||
bindDN?: string;
|
bindDN?: string;
|
||||||
bindPass?: string;
|
bindPass?: string;
|
||||||
|
uniqueUserAttribute: string;
|
||||||
searchBase?: string;
|
searchBase?: string;
|
||||||
searchFilter?: string;
|
searchFilter?: string;
|
||||||
groupSearchBase?: string;
|
groupSearchBase?: string;
|
||||||
@@ -83,6 +88,7 @@ export const useUpdateLDAPConfig = () => {
|
|||||||
url,
|
url,
|
||||||
bindDN,
|
bindDN,
|
||||||
bindPass,
|
bindPass,
|
||||||
|
uniqueUserAttribute,
|
||||||
searchBase,
|
searchBase,
|
||||||
searchFilter,
|
searchFilter,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ const LDAPFormSchema = z.object({
|
|||||||
bindPass: z.string().default(""),
|
bindPass: z.string().default(""),
|
||||||
searchBase: z.string().default(""),
|
searchBase: z.string().default(""),
|
||||||
searchFilter: z.string().default(""),
|
searchFilter: z.string().default(""),
|
||||||
|
uniqueUserAttribute: 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()
|
||||||
@@ -53,6 +54,7 @@ export const LDAPModal = ({ popUp, handlePopUpClose, handlePopUpToggle }: Props)
|
|||||||
const watchGroupSearchBase = watch("groupSearchBase");
|
const watchGroupSearchBase = watch("groupSearchBase");
|
||||||
const watchGroupSearchFilter = watch("groupSearchFilter");
|
const watchGroupSearchFilter = watch("groupSearchFilter");
|
||||||
const watchCaCert = watch("caCert");
|
const watchCaCert = watch("caCert");
|
||||||
|
const watchUniqueUserAttribute = watch("uniqueUserAttribute");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data) {
|
if (data) {
|
||||||
@@ -64,7 +66,8 @@ export const LDAPModal = ({ popUp, handlePopUpClose, handlePopUpToggle }: Props)
|
|||||||
searchFilter: data?.searchFilter ?? "",
|
searchFilter: data?.searchFilter ?? "",
|
||||||
groupSearchBase: data?.groupSearchBase ?? "",
|
groupSearchBase: data?.groupSearchBase ?? "",
|
||||||
groupSearchFilter: data?.groupSearchFilter ?? "",
|
groupSearchFilter: data?.groupSearchFilter ?? "",
|
||||||
caCert: data?.caCert ?? ""
|
caCert: data?.caCert ?? "",
|
||||||
|
uniqueUserAttribute: data?.uniqueUserAttribute ?? ""
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [data]);
|
}, [data]);
|
||||||
@@ -73,6 +76,7 @@ export const LDAPModal = ({ popUp, handlePopUpClose, handlePopUpToggle }: Props)
|
|||||||
url,
|
url,
|
||||||
bindDN,
|
bindDN,
|
||||||
bindPass,
|
bindPass,
|
||||||
|
uniqueUserAttribute,
|
||||||
searchBase,
|
searchBase,
|
||||||
searchFilter,
|
searchFilter,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
@@ -92,6 +96,7 @@ export const LDAPModal = ({ popUp, handlePopUpClose, handlePopUpToggle }: Props)
|
|||||||
bindPass,
|
bindPass,
|
||||||
searchBase,
|
searchBase,
|
||||||
searchFilter,
|
searchFilter,
|
||||||
|
uniqueUserAttribute,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
groupSearchFilter,
|
groupSearchFilter,
|
||||||
caCert
|
caCert
|
||||||
@@ -105,6 +110,7 @@ export const LDAPModal = ({ popUp, handlePopUpClose, handlePopUpToggle }: Props)
|
|||||||
bindPass,
|
bindPass,
|
||||||
searchBase,
|
searchBase,
|
||||||
searchFilter,
|
searchFilter,
|
||||||
|
uniqueUserAttribute,
|
||||||
groupSearchBase,
|
groupSearchBase,
|
||||||
groupSearchFilter,
|
groupSearchFilter,
|
||||||
caCert
|
caCert
|
||||||
@@ -138,6 +144,7 @@ export const LDAPModal = ({ popUp, handlePopUpClose, handlePopUpToggle }: Props)
|
|||||||
searchFilter: watchSearchFilter,
|
searchFilter: watchSearchFilter,
|
||||||
groupSearchBase: watchGroupSearchBase,
|
groupSearchBase: watchGroupSearchBase,
|
||||||
groupSearchFilter: watchGroupSearchFilter,
|
groupSearchFilter: watchGroupSearchFilter,
|
||||||
|
uniqueUserAttribute: watchUniqueUserAttribute,
|
||||||
caCert: watchCaCert,
|
caCert: watchCaCert,
|
||||||
shouldCloseModal: false
|
shouldCloseModal: false
|
||||||
});
|
});
|
||||||
@@ -217,6 +224,19 @@ export const LDAPModal = ({ popUp, handlePopUpClose, handlePopUpToggle }: Props)
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="uniqueUserAttribute"
|
||||||
|
render={({ field, fieldState: { error } }) => (
|
||||||
|
<FormControl
|
||||||
|
label="Unique User Attribute (Optional)"
|
||||||
|
errorText={error?.message}
|
||||||
|
isError={Boolean(error)}
|
||||||
|
>
|
||||||
|
<Input {...field} placeholder="uidNumber" />
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="searchFilter"
|
name="searchFilter"
|
||||||
|
|||||||
Reference in New Issue
Block a user