mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 02:51:51 +00:00
misc: added trigger for privilege upgrade
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
import { Knex } from "knex";
|
||||
import { TableName } from "../schemas";
|
||||
|
||||
export async function up(knex: Knex): Promise<void> {
|
||||
if (!(await knex.schema.hasColumn(TableName.Organization, "shouldUseNewPrivilegeSystem"))) {
|
||||
await knex.schema.alterTable(TableName.Organization, (t) => {
|
||||
t.boolean("shouldUseNewPrivilegeSystem");
|
||||
t.string("privilegeUpgradeInitiatedByUsername");
|
||||
t.dateTime("privilegeUpgradeInitiatedAt");
|
||||
});
|
||||
|
||||
await knex(TableName.Organization).update({
|
||||
shouldUseNewPrivilegeSystem: false
|
||||
});
|
||||
|
||||
await knex.schema.alterTable(TableName.Organization, (t) => {
|
||||
t.boolean("shouldUseNewPrivilegeSystem").defaultTo(true).notNullable().alter();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function down(knex: Knex): Promise<void> {
|
||||
if (await knex.schema.hasColumn(TableName.Organization, "shouldUseNewPrivilegeSystem")) {
|
||||
await knex.schema.alterTable(TableName.Organization, (t) => {
|
||||
t.dropColumn("shouldUseNewPrivilegeSystem");
|
||||
t.dropColumn("privilegeUpgradeInitiatedByUsername");
|
||||
t.dropColumn("privilegeUpgradeInitiatedAt");
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,10 @@ export const OrganizationsSchema = z.object({
|
||||
kmsEncryptedDataKey: zodBuffer.nullable().optional(),
|
||||
defaultMembershipRole: z.string().default("member"),
|
||||
enforceMfa: z.boolean().default(false),
|
||||
selectedMfaMethod: z.string().nullable().optional()
|
||||
selectedMfaMethod: z.string().nullable().optional(),
|
||||
shouldUseNewPrivilegeSystem: z.boolean().default(true),
|
||||
privilegeUpgradeInitiatedByUsername: z.string().nullable().optional(),
|
||||
privilegeUpgradeInitiatedAt: z.date().nullable().optional()
|
||||
});
|
||||
|
||||
export type TOrganizations = z.infer<typeof OrganizationsSchema>;
|
||||
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
AuditLogsSchema,
|
||||
GroupsSchema,
|
||||
IncidentContactsSchema,
|
||||
OrganizationsSchema,
|
||||
OrgMembershipsSchema,
|
||||
OrgRolesSchema,
|
||||
UsersSchema
|
||||
@@ -57,7 +56,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
organization: OrganizationsSchema
|
||||
organization: sanitizedOrganizationSchema
|
||||
})
|
||||
}
|
||||
},
|
||||
@@ -262,7 +261,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
|
||||
response: {
|
||||
200: z.object({
|
||||
message: z.string(),
|
||||
organization: OrganizationsSchema
|
||||
organization: sanitizedOrganizationSchema
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import {
|
||||
OrganizationsSchema,
|
||||
OrgMembershipsSchema,
|
||||
ProjectMembershipsSchema,
|
||||
ProjectsSchema,
|
||||
@@ -15,6 +14,7 @@ import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
|
||||
import { GenericResourceNameSchema } from "@app/server/lib/schemas";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
import { ActorType, AuthMode } from "@app/services/auth/auth-type";
|
||||
import { sanitizedOrganizationSchema } from "@app/services/org/org-schema";
|
||||
|
||||
export const registerOrgRouter = async (server: FastifyZodProvider) => {
|
||||
server.route({
|
||||
@@ -335,7 +335,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
organization: OrganizationsSchema
|
||||
organization: sanitizedOrganizationSchema
|
||||
})
|
||||
}
|
||||
},
|
||||
@@ -365,7 +365,7 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
organization: OrganizationsSchema,
|
||||
organization: sanitizedOrganizationSchema,
|
||||
accessToken: z.string()
|
||||
})
|
||||
}
|
||||
@@ -396,4 +396,30 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => {
|
||||
return { organization, accessToken: tokens.accessToken };
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "POST",
|
||||
url: "/privilege-system-upgrade",
|
||||
config: {
|
||||
rateLimit: writeLimit
|
||||
},
|
||||
schema: {
|
||||
response: {
|
||||
200: z.object({
|
||||
organization: sanitizedOrganizationSchema
|
||||
})
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
const organization = await server.services.org.upgradePrivilegeSystem({
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
orgId: req.permission.orgId
|
||||
});
|
||||
|
||||
return { organization };
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -12,5 +12,8 @@ export const sanitizedOrganizationSchema = OrganizationsSchema.pick({
|
||||
kmsDefaultKeyId: true,
|
||||
defaultMembershipRole: true,
|
||||
enforceMfa: true,
|
||||
selectedMfaMethod: true
|
||||
selectedMfaMethod: true,
|
||||
shouldUseNewPrivilegeSystem: true,
|
||||
privilegeUpgradeInitiatedByUsername: true,
|
||||
privilegeUpgradeInitiatedAt: true
|
||||
});
|
||||
|
||||
@@ -77,6 +77,7 @@ import {
|
||||
TResendOrgMemberInvitationDTO,
|
||||
TUpdateOrgDTO,
|
||||
TUpdateOrgMembershipDTO,
|
||||
TUpgradePrivilegeSystemDTO,
|
||||
TVerifyUserToOrgDTO
|
||||
} from "./org-types";
|
||||
|
||||
@@ -282,6 +283,45 @@ export const orgServiceFactory = ({
|
||||
};
|
||||
};
|
||||
|
||||
const upgradePrivilegeSystem = async ({
|
||||
actorId,
|
||||
actorOrgId,
|
||||
actorAuthMethod,
|
||||
orgId
|
||||
}: TUpgradePrivilegeSystemDTO) => {
|
||||
const { membership } = await permissionService.getUserOrgPermission(actorId, orgId, actorAuthMethod, actorOrgId);
|
||||
|
||||
if (membership.role != OrgMembershipRole.Admin) {
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Insufficient privileges - only the organization admin can upgrade the privilege system."
|
||||
});
|
||||
}
|
||||
|
||||
return orgDAL.transaction(async (tx) => {
|
||||
const org = await orgDAL.findById(actorOrgId, tx);
|
||||
if (org.shouldUseNewPrivilegeSystem) {
|
||||
throw new BadRequestError({
|
||||
message: "Privilege system already upgraded"
|
||||
});
|
||||
}
|
||||
|
||||
const user = await userDAL.findById(actorId, tx);
|
||||
if (!user) {
|
||||
throw new NotFoundError({ message: `User with ID '${actorId}' not found` });
|
||||
}
|
||||
|
||||
return orgDAL.updateById(
|
||||
actorOrgId,
|
||||
{
|
||||
shouldUseNewPrivilegeSystem: true,
|
||||
privilegeUpgradeInitiatedAt: new Date(),
|
||||
privilegeUpgradeInitiatedByUsername: user.username
|
||||
},
|
||||
tx
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* Update organization details
|
||||
* */
|
||||
@@ -1310,6 +1350,7 @@ export const orgServiceFactory = ({
|
||||
getOrgGroups,
|
||||
listProjectMembershipsByOrgMembershipId,
|
||||
findOrgBySlug,
|
||||
resendOrgMemberInvitation
|
||||
resendOrgMemberInvitation,
|
||||
upgradePrivilegeSystem
|
||||
};
|
||||
};
|
||||
|
||||
@@ -75,6 +75,8 @@ export type TUpdateOrgDTO = {
|
||||
}>;
|
||||
} & TOrgPermission;
|
||||
|
||||
export type TUpgradePrivilegeSystemDTO = Omit<TOrgPermission, "actor">;
|
||||
|
||||
export type TGetOrgGroupsDTO = TOrgPermission;
|
||||
|
||||
export type TListProjectMembershipsByOrgMembershipIdDTO = {
|
||||
|
||||
Reference in New Issue
Block a user