misc: added option for trusting OIDC emails by default

This commit is contained in:
Sheen Capadngan
2024-06-19 13:46:17 +08:00
parent 18e69578f0
commit 92f2f16656
6 changed files with 65 additions and 11 deletions

View File

@@ -24,8 +24,24 @@ export async function up(knex: Knex): Promise<void> {
tb.foreign("orgId").references("id").inTable(TableName.Organization); tb.foreign("orgId").references("id").inTable(TableName.Organization);
}); });
} }
if (await knex.schema.hasTable(TableName.SuperAdmin)) {
if (!(await knex.schema.hasColumn(TableName.SuperAdmin, "trustOidcEmails"))) {
await knex.schema.alterTable(TableName.SuperAdmin, (tb) => {
tb.boolean("trustOidcEmails").defaultTo(false);
});
}
}
} }
export async function down(knex: Knex): Promise<void> { export async function down(knex: Knex): Promise<void> {
await knex.schema.dropTableIfExists(TableName.OidcConfig); await knex.schema.dropTableIfExists(TableName.OidcConfig);
if (await knex.schema.hasTable(TableName.SuperAdmin)) {
if (await knex.schema.hasColumn(TableName.SuperAdmin, "trustOidcEmails")) {
await knex.schema.alterTable(TableName.SuperAdmin, (t) => {
t.dropColumn("trustOidcEmails");
});
}
}
} }

View File

@@ -16,7 +16,8 @@ export const SuperAdminSchema = z.object({
allowedSignUpDomain: z.string().nullable().optional(), allowedSignUpDomain: z.string().nullable().optional(),
instanceId: z.string().uuid().default("00000000-0000-0000-0000-000000000000"), instanceId: z.string().uuid().default("00000000-0000-0000-0000-000000000000"),
trustSamlEmails: z.boolean().default(false).nullable().optional(), trustSamlEmails: z.boolean().default(false).nullable().optional(),
trustLdapEmails: z.boolean().default(false).nullable().optional() trustLdapEmails: z.boolean().default(false).nullable().optional(),
trustOidcEmails: z.boolean().default(false).nullable().optional()
}); });
export type TSuperAdmin = z.infer<typeof SuperAdminSchema>; export type TSuperAdmin = z.infer<typeof SuperAdminSchema>;

View File

@@ -25,6 +25,7 @@ import { TOrgBotDALFactory } from "@app/services/org/org-bot-dal";
import { TOrgDALFactory } from "@app/services/org/org-dal"; import { TOrgDALFactory } from "@app/services/org/org-dal";
import { TOrgMembershipDALFactory } from "@app/services/org-membership/org-membership-dal"; import { TOrgMembershipDALFactory } from "@app/services/org-membership/org-membership-dal";
import { SmtpTemplates, TSmtpService } from "@app/services/smtp/smtp-service"; import { SmtpTemplates, TSmtpService } from "@app/services/smtp/smtp-service";
import { getServerCfg } from "@app/services/super-admin/super-admin-service";
import { TUserDALFactory } from "@app/services/user/user-dal"; import { TUserDALFactory } from "@app/services/user/user-dal";
import { normalizeUsername } from "@app/services/user/user-fns"; import { normalizeUsername } from "@app/services/user/user-fns";
import { TUserAliasDALFactory } from "@app/services/user-alias/user-alias-dal"; import { TUserAliasDALFactory } from "@app/services/user-alias/user-alias-dal";
@@ -144,6 +145,7 @@ export const oidcConfigServiceFactory = ({
}; };
const oidcLogin = async ({ externalId, email, firstName, lastName, orgId, callbackPort }: TOidcLoginDTO) => { const oidcLogin = async ({ externalId, email, firstName, lastName, orgId, callbackPort }: TOidcLoginDTO) => {
const serverCfg = await getServerCfg();
const appCfg = getConfig(); const appCfg = getConfig();
const userAlias = await userAliasDAL.findOne({ const userAlias = await userAliasDAL.findOne({
externalId, externalId,
@@ -192,14 +194,25 @@ export const oidcConfigServiceFactory = ({
} else { } else {
user = await userDAL.transaction(async (tx) => { user = await userDAL.transaction(async (tx) => {
let newUser: TUsers | undefined; let newUser: TUsers | undefined;
if (serverCfg.trustOidcEmails) {
newUser = await userDAL.findOne(
{
email,
isEmailVerified: true
},
tx
);
}
if (!newUser) { if (!newUser) {
const uniqueUsername = await normalizeUsername(externalId, userDAL); const uniqueUsername = await normalizeUsername(externalId, userDAL);
newUser = await userDAL.create( newUser = await userDAL.create(
{ {
email, email,
firstName, firstName,
isEmailVerified: false, isEmailVerified: serverCfg.trustOidcEmails,
username: uniqueUsername, username: serverCfg.trustOidcEmails ? email : uniqueUsername,
lastName, lastName,
authMethods: [], authMethods: [],
isGhost: false isGhost: false
@@ -252,6 +265,7 @@ export const oidcConfigServiceFactory = ({
return newUser; return newUser;
}); });
} }
await licenseService.updateSubscriptionOrgMemberCount(organization.id); await licenseService.updateSubscriptionOrgMemberCount(organization.id);
const isUserCompleted = Boolean(user.isAccepted); const isUserCompleted = Boolean(user.isAccepted);

View File

@@ -51,7 +51,8 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
allowSignUp: z.boolean().optional(), allowSignUp: z.boolean().optional(),
allowedSignUpDomain: z.string().optional().nullable(), allowedSignUpDomain: z.string().optional().nullable(),
trustSamlEmails: z.boolean().optional(), trustSamlEmails: z.boolean().optional(),
trustLdapEmails: z.boolean().optional() trustLdapEmails: z.boolean().optional(),
trustOidcEmails: z.boolean().optional()
}), }),
response: { response: {
200: z.object({ 200: z.object({

View File

@@ -5,6 +5,7 @@ export type TServerConfig = {
isMigrationModeOn?: boolean; isMigrationModeOn?: boolean;
trustSamlEmails: boolean; trustSamlEmails: boolean;
trustLdapEmails: boolean; trustLdapEmails: boolean;
trustOidcEmails: boolean;
isSecretScanningDisabled: boolean; isSecretScanningDisabled: boolean;
}; };

View File

@@ -39,7 +39,8 @@ const formSchema = z.object({
signUpMode: z.nativeEnum(SignUpModes), signUpMode: z.nativeEnum(SignUpModes),
allowedSignUpDomain: z.string().optional().nullable(), allowedSignUpDomain: z.string().optional().nullable(),
trustSamlEmails: z.boolean(), trustSamlEmails: z.boolean(),
trustLdapEmails: z.boolean() trustLdapEmails: z.boolean(),
trustOidcEmails: z.boolean()
}); });
type TDashboardForm = z.infer<typeof formSchema>; type TDashboardForm = z.infer<typeof formSchema>;
@@ -60,7 +61,8 @@ export const AdminDashboardPage = () => {
signUpMode: config.allowSignUp ? SignUpModes.Anyone : SignUpModes.Disabled, signUpMode: config.allowSignUp ? SignUpModes.Anyone : SignUpModes.Disabled,
allowedSignUpDomain: config.allowedSignUpDomain, allowedSignUpDomain: config.allowedSignUpDomain,
trustSamlEmails: config.trustSamlEmails, trustSamlEmails: config.trustSamlEmails,
trustLdapEmails: config.trustLdapEmails trustLdapEmails: config.trustLdapEmails,
trustOidcEmails: config.trustOidcEmails
} }
}); });
@@ -84,13 +86,15 @@ export const AdminDashboardPage = () => {
const onFormSubmit = async (formData: TDashboardForm) => { const onFormSubmit = async (formData: TDashboardForm) => {
try { try {
const { signUpMode, allowedSignUpDomain, trustSamlEmails, trustLdapEmails } = formData; const { signUpMode, allowedSignUpDomain, trustSamlEmails, trustLdapEmails, trustOidcEmails } =
formData;
await updateServerConfig({ await updateServerConfig({
allowSignUp: signUpMode !== SignUpModes.Disabled, allowSignUp: signUpMode !== SignUpModes.Disabled,
allowedSignUpDomain: signUpMode === SignUpModes.Anyone ? allowedSignUpDomain : null, allowedSignUpDomain: signUpMode === SignUpModes.Anyone ? allowedSignUpDomain : null,
trustSamlEmails, trustSamlEmails,
trustLdapEmails trustLdapEmails,
trustOidcEmails
}); });
createNotification({ createNotification({
text: "Successfully changed sign up setting.", text: "Successfully changed sign up setting.",
@@ -190,9 +194,9 @@ export const AdminDashboardPage = () => {
<div className="mt-8 mb-8 flex flex-col justify-start"> <div className="mt-8 mb-8 flex flex-col justify-start">
<div className="mb-2 text-xl font-semibold text-mineshaft-100">Trust emails</div> <div className="mb-2 text-xl font-semibold text-mineshaft-100">Trust emails</div>
<div className="mb-4 max-w-sm text-sm text-mineshaft-400"> <div className="mb-4 max-w-sm text-sm text-mineshaft-400">
Select if you want Infisical to trust external emails from SAML/LDAP identity Select if you want Infisical to trust external emails from SAML/LDAP/OIDC
providers. If set to false, then Infisical will prompt SAML/LDAP provisioned identity providers. If set to false, then Infisical will prompt SAML/LDAP
users to verify their email upon their first login. provisioned users to verify their email upon their first login.
</div> </div>
<Controller <Controller
control={control} control={control}
@@ -228,6 +232,23 @@ export const AdminDashboardPage = () => {
); );
}} }}
/> />
<Controller
control={control}
name="trustOidcEmails"
render={({ field, fieldState: { error } }) => {
return (
<FormControl isError={Boolean(error)} errorText={error?.message}>
<Switch
id="trust-oidc-emails"
onCheckedChange={(value) => field.onChange(value)}
isChecked={field.value}
>
<p className="w-full">Trust OIDC emails</p>
</Switch>
</FormControl>
);
}}
/>
</div> </div>
<Button <Button
type="submit" type="submit"