feat: removed old membership table

This commit is contained in:
=
2026-01-07 19:34:14 +05:30
parent 815af3a892
commit ffd1bd53f3
10 changed files with 132 additions and 51 deletions

View File

@@ -0,0 +1,76 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
import { dropOnUpdateTrigger } from "../utils";
export async function up(knex: Knex): Promise<void> {
await dropOnUpdateTrigger(knex, TableName.GroupProjectMembershipRole);
await knex.schema.dropTableIfExists(TableName.GroupProjectMembershipRole);
await dropOnUpdateTrigger(knex, TableName.GroupProjectMembership);
await knex.schema.dropTableIfExists(TableName.GroupProjectMembership);
await dropOnUpdateTrigger(knex, TableName.IdentityProjectAdditionalPrivilege);
await knex.schema.dropTableIfExists(TableName.IdentityProjectAdditionalPrivilege);
await dropOnUpdateTrigger(knex, TableName.IdentityProjectMembershipRole);
await knex.schema.dropTableIfExists(TableName.IdentityProjectMembershipRole);
await dropOnUpdateTrigger(knex, TableName.IdentityProjectMembership);
await knex.schema.dropTableIfExists(TableName.IdentityProjectMembership);
await dropOnUpdateTrigger(knex, TableName.ProjectUserAdditionalPrivilege);
await knex.schema.dropTableIfExists(TableName.ProjectUserAdditionalPrivilege);
await dropOnUpdateTrigger(knex, TableName.ProjectUserMembershipRole);
await knex.schema.dropTableIfExists(TableName.ProjectUserMembershipRole);
// before dropping membership need to remove some dependent fields
const hasMembershipInApprovalRequestTable = await knex.schema.hasColumn(
TableName.AccessApprovalRequest,
"requestedBy"
);
if (hasMembershipInApprovalRequestTable) {
await knex.schema.alterTable(TableName.AccessApprovalRequest, (t) => {
t.dropColumn("requestedBy");
});
}
const hasMembershipInApprovalRequestReviewerTable = await knex.schema.hasColumn(
TableName.AccessApprovalRequestReviewer,
"member"
);
if (hasMembershipInApprovalRequestReviewerTable) {
await knex.schema.alterTable(TableName.AccessApprovalRequestReviewer, (t) => {
t.dropColumn("member");
});
}
await dropOnUpdateTrigger(knex, TableName.ProjectMembership);
await knex.schema.dropTableIfExists(TableName.ProjectMembership);
await dropOnUpdateTrigger(knex, TableName.ProjectRoles);
await knex.schema.dropTableIfExists(TableName.ProjectRoles);
await dropOnUpdateTrigger(knex, TableName.IdentityOrgMembership);
await knex.schema.dropTableIfExists(TableName.IdentityOrgMembership);
await dropOnUpdateTrigger(knex, TableName.OrgMembership);
await knex.schema.dropTableIfExists(TableName.OrgMembership);
const hasOrgRoleIdInGroup = await knex.schema.hasColumn(TableName.Groups, "roleId");
const hasRoleInGroup = await knex.schema.hasColumn(TableName.Groups, "role");
if (hasOrgRoleIdInGroup || hasRoleInGroup) {
await knex.schema.alterTable(TableName.Groups, (t) => {
if (hasOrgRoleIdInGroup) t.dropColumn("roleId");
if (hasRoleInGroup) t.dropColumn("role");
});
}
await dropOnUpdateTrigger(knex, TableName.OrgRoles);
await knex.schema.dropTableIfExists(TableName.OrgRoles);
}
export async function down(): Promise<void> {
// sometimes life is all about moving forward
}

View File

@@ -9,7 +9,6 @@ import { TImmutableDBKeys } from "./models";
export const AccessApprovalRequestsReviewersSchema = z.object({
id: z.string().uuid(),
member: z.string().uuid().nullable().optional(),
status: z.string(),
requestId: z.string().uuid(),
createdAt: z.date(),

View File

@@ -11,7 +11,6 @@ export const AccessApprovalRequestsSchema = z.object({
id: z.string().uuid(),
policyId: z.string().uuid(),
privilegeId: z.string().uuid().nullable().optional(),
requestedBy: z.string().uuid().nullable().optional(),
isTemporary: z.boolean(),
temporaryRange: z.string().nullable().optional(),
permissions: z.unknown(),

View File

@@ -12,8 +12,6 @@ export const GroupsSchema = z.object({
orgId: z.string().uuid(),
name: z.string(),
slug: z.string(),
role: z.string(),
roleId: z.string().uuid().nullable().optional(),
createdAt: z.date(),
updatedAt: z.date()
});

View File

@@ -60,7 +60,7 @@ type TGroupServiceFactoryDep = {
| "transaction"
| "findAllGroupProjects"
>;
membershipGroupDAL: Pick<TMembershipGroupDALFactory, "find" | "findOne" | "create">;
membershipGroupDAL: Pick<TMembershipGroupDALFactory, "find" | "findOne" | "create" | "getGroupById">;
membershipDAL: Pick<TMembershipDALFactory, "find" | "findOne">;
membershipRoleDAL: Pick<TMembershipRoleDALFactory, "create" | "delete">;
orgDAL: Pick<TOrgDALFactory, "findMembership" | "countAllOrgMembers" | "findById">;
@@ -153,9 +153,7 @@ export const groupServiceFactory = ({
{
name,
slug: slug || slugify(`${name}-${alphaNumericNanoId(4)}`),
orgId: actorOrgId,
role: isCustomRole ? OrgMembershipRole.Custom : role,
roleId: null
orgId: actorOrgId
},
tx
);
@@ -552,18 +550,21 @@ export const groupServiceFactory = ({
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionGroupActions.Edit, OrgPermissionSubjects.Groups);
// check if group with slug exists
const group = await groupDAL.findOne({
orgId: actorOrgId,
id
const groupMembership = await membershipGroupDAL.getGroupById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
groupId: id
});
if (!group)
if (!groupMembership)
throw new NotFoundError({
message: `Failed to find group with ID ${id}`
});
const oidcConfig = await oidcConfigDAL.findOne({
orgId: group.orgId,
orgId: actorOrgId,
isActive: true
});
@@ -574,7 +575,8 @@ export const groupServiceFactory = ({
});
}
const [rolePermissionDetails] = await permissionService.getOrgPermissionByRoles([group.role], actorOrgId);
const groupRoles = groupMembership.roles.map((el) => el.customRoleSlug || el.role);
const [rolePermissionDetails] = await permissionService.getOrgPermissionByRoles(groupRoles, actorOrgId);
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(actorOrgId);
// check if user has broader or equal to privileges than group
@@ -604,7 +606,7 @@ export const groupServiceFactory = ({
if (!user) throw new NotFoundError({ message: `Failed to find user with username ${username}` });
const users = await addUsersToGroupByUserIds({
group,
group: groupMembership.group,
userIds: [user.id],
userDAL,
userGroupMembershipDAL,
@@ -639,17 +641,21 @@ export const groupServiceFactory = ({
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionGroupActions.Edit, OrgPermissionSubjects.Groups);
// check if group with slug exists
const group = await groupDAL.findOne({
orgId: actorOrgId,
id
const groupMembership = await membershipGroupDAL.getGroupById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
groupId: id
});
if (!group)
if (!groupMembership)
throw new NotFoundError({
message: `Failed to find group with ID ${id}`
});
const [rolePermissionDetails] = await permissionService.getOrgPermissionByRoles([group.role], actorOrgId);
const groupRoles = groupMembership.roles.map((el) => el.customRoleSlug || el.role);
const [rolePermissionDetails] = await permissionService.getOrgPermissionByRoles(groupRoles, actorOrgId);
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(actorOrgId);
// check if user has broader or equal to privileges than group
@@ -674,7 +680,7 @@ export const groupServiceFactory = ({
const identityMembership = await membershipDAL.findOne({
scope: AccessScope.Organization,
scopeOrgId: group.orgId,
scopeOrgId: groupMembership.group.orgId,
actorIdentityId: identityId
});
@@ -683,7 +689,7 @@ export const groupServiceFactory = ({
}
const identities = await addIdentitiesToGroup({
group,
group: groupMembership.group,
identityIds: [identityId],
identityDAL,
membershipDAL,
@@ -714,18 +720,21 @@ export const groupServiceFactory = ({
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionGroupActions.Edit, OrgPermissionSubjects.Groups);
// check if group with slug exists
const group = await groupDAL.findOne({
orgId: actorOrgId,
id
const groupMembership = await membershipGroupDAL.getGroupById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
groupId: id
});
if (!group)
if (!groupMembership)
throw new NotFoundError({
message: `Failed to find group with ID ${id}`
});
const oidcConfig = await oidcConfigDAL.findOne({
orgId: group.orgId,
orgId: groupMembership.group.orgId,
isActive: true
});
@@ -736,7 +745,8 @@ export const groupServiceFactory = ({
});
}
const [rolePermissionDetails] = await permissionService.getOrgPermissionByRoles([group.role], actorOrgId);
const groupRoles = groupMembership.roles.map((el) => el.customRoleSlug || el.role);
const [rolePermissionDetails] = await permissionService.getOrgPermissionByRoles(groupRoles, actorOrgId);
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(actorOrgId);
// check if user has broader or equal to privileges than group
@@ -765,7 +775,7 @@ export const groupServiceFactory = ({
if (!user) throw new NotFoundError({ message: `Failed to find user with username ${username}` });
const users = await removeUsersFromGroupByUserIds({
group,
group: groupMembership.group,
userIds: [user.id],
userDAL,
userGroupMembershipDAL,
@@ -796,17 +806,21 @@ export const groupServiceFactory = ({
});
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionGroupActions.Edit, OrgPermissionSubjects.Groups);
const group = await groupDAL.findOne({
orgId: actorOrgId,
id
const groupMembership = await membershipGroupDAL.getGroupById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
groupId: id
});
if (!group)
if (!groupMembership)
throw new NotFoundError({
message: `Failed to find group with ID ${id}`
});
const [rolePermissionDetails] = await permissionService.getOrgPermissionByRoles([group.role], actorOrgId);
const groupRoles = groupMembership.roles.map((el) => el.customRoleSlug || el.role);
const [rolePermissionDetails] = await permissionService.getOrgPermissionByRoles(groupRoles, actorOrgId);
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(actorOrgId);
// check if user has broader or equal to privileges than group
@@ -830,7 +844,7 @@ export const groupServiceFactory = ({
const identityMembership = await membershipDAL.findOne({
scope: AccessScope.Organization,
scopeOrgId: group.orgId,
scopeOrgId: groupMembership.group.orgId,
actorIdentityId: identityId
});
@@ -839,7 +853,7 @@ export const groupServiceFactory = ({
}
const identities = await removeIdentitiesFromGroup({
group,
group: groupMembership.group,
identityIds: [identityId],
identityDAL,
membershipDAL,

View File

@@ -1,6 +1,5 @@
import { Knex } from "knex";
import { TGroups } from "@app/db/schemas";
import { TUserGroupMembershipDALFactory } from "@app/ee/services/group/user-group-membership-dal";
import { OrderByDirection, TGenericPermission } from "@app/lib/types";
import { TIdentityDALFactory } from "@app/services/identity/identity-dal";
@@ -102,7 +101,7 @@ export type TRemoveMachineIdentityFromGroupDTO = {
export type TAddUsersToGroup = {
userIds: string[];
group: TGroups;
group: { id: string; name: string; slug: string; orgId: string };
userDAL: Pick<TUserDALFactory, "findUserEncKeyByUserIdsBatch">;
userGroupMembershipDAL: Pick<TUserGroupMembershipDALFactory, "find" | "transaction" | "insertMany">;
membershipGroupDAL: Pick<TMembershipGroupDALFactory, "find">;
@@ -113,7 +112,7 @@ export type TAddUsersToGroup = {
};
export type TAddUsersToGroupByUserIds = {
group: TGroups;
group: { id: string; name: string; slug: string; orgId: string };
userIds: string[];
userDAL: Pick<TUserDALFactory, "find" | "findUserEncKeyByUserIdsBatch" | "transaction">;
userGroupMembershipDAL: Pick<TUserGroupMembershipDALFactory, "find" | "transaction" | "insertMany">;
@@ -126,7 +125,7 @@ export type TAddUsersToGroupByUserIds = {
};
export type TAddIdentitiesToGroup = {
group: TGroups;
group: { id: string; name: string; slug: string; orgId: string };
identityIds: string[];
identityDAL: Pick<TIdentityDALFactory, "transaction">;
identityGroupMembershipDAL: Pick<TIdentityGroupMembershipDALFactory, "find" | "insertMany">;
@@ -134,7 +133,7 @@ export type TAddIdentitiesToGroup = {
};
export type TRemoveUsersFromGroupByUserIds = {
group: TGroups;
group: { id: string; name: string; slug: string; orgId: string };
userIds: string[];
userDAL: Pick<TUserDALFactory, "find" | "transaction">;
userGroupMembershipDAL: Pick<TUserGroupMembershipDALFactory, "find" | "filterProjectsByUserMembership" | "delete">;
@@ -144,7 +143,7 @@ export type TRemoveUsersFromGroupByUserIds = {
};
export type TRemoveIdentitiesFromGroup = {
group: TGroups;
group: { id: string; name: string; slug: string; orgId: string };
identityIds: string[];
identityDAL: Pick<TIdentityDALFactory, "find" | "transaction">;
membershipDAL: Pick<TMembershipDALFactory, "find">;

View File

@@ -136,7 +136,7 @@ export const userGroupMembershipDALFactory = (db: TDbClient) => {
tx
);
return members.map(({ userId, username, groupId, orgId, name, slug, role, roleId }) => ({
return members.map(({ userId, username, groupId, orgId, name, slug }) => ({
user: {
id: userId,
username
@@ -146,8 +146,6 @@ export const userGroupMembershipDALFactory = (db: TDbClient) => {
orgId,
name,
slug,
role,
roleId,
createdAt: new Date(),
updatedAt: new Date()
}

View File

@@ -176,9 +176,7 @@ export const samlConfigServiceFactory = ({
{
name: groupName,
slug: `${groupName.toLowerCase().replace(new RE2("[^a-z0-9]", "g"), "-")}-${Date.now()}`,
orgId,
role: OrgMembershipRole.NoAccess,
roleId: null
orgId
},
transaction
);

View File

@@ -860,8 +860,7 @@ export const scimServiceFactory = ({
{
name: displayName,
slug: slugify(`${displayName}-${alphaNumericNanoId(4)}`),
orgId,
role: OrgMembershipRole.NoAccess
orgId
},
tx
);

View File

@@ -85,7 +85,8 @@ export const membershipGroupDALFactory = (db: TDbClient) => {
group: {
id: groupId,
name: groupName,
slug: groupSlug
slug: groupSlug,
orgId: scopeData.orgId
}
};
},