Rely on actorOrgId for group orgId refs

This commit is contained in:
Tuan Dang
2024-03-28 17:00:33 -07:00
parent bf13b81c0f
commit 8afecac7d8
6 changed files with 81 additions and 49 deletions
+1 -7
View File
@@ -12,7 +12,7 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => {
onRequest: verifyAuth([AuthMode.JWT]), onRequest: verifyAuth([AuthMode.JWT]),
schema: { schema: {
body: z.object({ body: z.object({
organizationId: z.string().trim(), // TODO: update on frontend to not send organizationId
name: z.string().trim().min(1), name: z.string().trim().min(1),
slug: z slug: z
.string() .string()
@@ -32,7 +32,6 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => {
const group = await server.services.group.createGroup({ const group = await server.services.group.createGroup({
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
orgId: req.body.organizationId,
actorAuthMethod: req.permission.authMethod, actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
...req.body ...req.body
@@ -72,7 +71,6 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => {
currentSlug: req.params.currentSlug, currentSlug: req.params.currentSlug,
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
orgId: req.permission.orgId, // note
actorAuthMethod: req.permission.authMethod, actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
...req.body ...req.body
@@ -99,7 +97,6 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => {
groupSlug: req.params.groupSlug, groupSlug: req.params.groupSlug,
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
orgId: req.permission.orgId, // note
actorAuthMethod: req.permission.authMethod, actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId actorOrgId: req.permission.orgId
}); });
@@ -137,7 +134,6 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => {
groupSlug: req.params.slug, groupSlug: req.params.slug,
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
orgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod, actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId actorOrgId: req.permission.orgId
}); });
@@ -170,7 +166,6 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => {
username: req.params.username, username: req.params.username,
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
orgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod, actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId actorOrgId: req.permission.orgId
}); });
@@ -204,7 +199,6 @@ export const registerGroupRouter = async (server: FastifyZodProvider) => {
username: req.params.username, username: req.params.username,
actor: req.permission.type, actor: req.permission.type,
actorId: req.permission.id, actorId: req.permission.id,
orgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod, actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId actorOrgId: req.permission.orgId
}); });
+70 -35
View File
@@ -57,20 +57,19 @@ export const groupServiceFactory = ({
permissionService, permissionService,
licenseService licenseService
}: TGroupServiceFactoryDep) => { }: TGroupServiceFactoryDep) => {
const createGroup = async ({ const createGroup = async ({ name, slug, role, actor, actorId, actorAuthMethod, actorOrgId }: TCreateGroupDTO) => {
name, if (!actorOrgId) throw new BadRequestError({ message: "Failed to create group without organization" });
slug,
role, const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
orgId, actorOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}: TCreateGroupDTO) => { );
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Groups); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Groups);
const plan = await licenseService.getPlan(orgId); const plan = await licenseService.getPlan(actorOrgId);
if (!plan.groups) if (!plan.groups)
throw new BadRequestError({ throw new BadRequestError({
message: "Failed to create group due to plan restriction. Upgrade plan to create group." message: "Failed to create group due to plan restriction. Upgrade plan to create group."
@@ -78,7 +77,7 @@ export const groupServiceFactory = ({
const { permission: rolePermission, role: customRole } = await permissionService.getOrgPermissionByRole( const { permission: rolePermission, role: customRole } = await permissionService.getOrgPermissionByRole(
role, role,
orgId actorOrgId
); );
const isCustomRole = Boolean(customRole); const isCustomRole = Boolean(customRole);
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, rolePermission); const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, rolePermission);
@@ -87,7 +86,7 @@ export const groupServiceFactory = ({
const group = await groupDAL.create({ const group = await groupDAL.create({
name, name,
slug: slug || slugify(`${name}-${alphaNumericNanoId(4)}`), slug: slug || slugify(`${name}-${alphaNumericNanoId(4)}`),
orgId, orgId: actorOrgId,
role: isCustomRole ? OrgMembershipRole.Custom : role, role: isCustomRole ? OrgMembershipRole.Custom : role,
roleId: customRole?.id roleId: customRole?.id
}); });
@@ -102,20 +101,27 @@ export const groupServiceFactory = ({
role, role,
actor, actor,
actorId, actorId,
orgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}: TUpdateGroupDTO) => { }: TUpdateGroupDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); if (!actorOrgId) throw new BadRequestError({ message: "Failed to create group without organization" });
const { permission } = await permissionService.getOrgPermission(
actor,
actorId,
actorOrgId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Groups); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Groups);
const plan = await licenseService.getPlan(orgId); const plan = await licenseService.getPlan(actorOrgId);
if (!plan.groups) if (!plan.groups)
throw new BadRequestError({ throw new BadRequestError({
message: "Failed to update group due to plan restrictio Upgrade plan to update group." message: "Failed to update group due to plan restrictio Upgrade plan to update group."
}); });
const group = await groupDAL.findOne({ orgId, slug: currentSlug }); const group = await groupDAL.findOne({ orgId: actorOrgId, slug: currentSlug });
if (!group) throw new BadRequestError({ message: `Failed to find group with slug ${currentSlug}` }); if (!group) throw new BadRequestError({ message: `Failed to find group with slug ${currentSlug}` });
let customRole: TOrgRoles | undefined; let customRole: TOrgRoles | undefined;
@@ -134,7 +140,7 @@ export const groupServiceFactory = ({
const [updatedGroup] = await groupDAL.update( const [updatedGroup] = await groupDAL.update(
{ {
orgId, orgId: actorOrgId,
slug: currentSlug slug: currentSlug
}, },
{ {
@@ -152,11 +158,19 @@ export const groupServiceFactory = ({
return updatedGroup; return updatedGroup;
}; };
const deleteGroup = async ({ groupSlug, actor, actorId, orgId, actorAuthMethod, actorOrgId }: TDeleteGroupDTO) => { const deleteGroup = async ({ groupSlug, actor, actorId, actorAuthMethod, actorOrgId }: TDeleteGroupDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); if (!actorOrgId) throw new BadRequestError({ message: "Failed to create group without organization" });
const { permission } = await permissionService.getOrgPermission(
actor,
actorId,
actorOrgId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Groups); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Groups);
const plan = await licenseService.getPlan(orgId); const plan = await licenseService.getPlan(actorOrgId);
if (!plan.groups) if (!plan.groups)
throw new BadRequestError({ throw new BadRequestError({
@@ -164,7 +178,7 @@ export const groupServiceFactory = ({
}); });
const [group] = await groupDAL.delete({ const [group] = await groupDAL.delete({
orgId, orgId: actorOrgId,
slug: groupSlug slug: groupSlug
}); });
@@ -175,15 +189,22 @@ export const groupServiceFactory = ({
groupSlug, groupSlug,
actor, actor,
actorId, actorId,
orgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}: TGetGroupUserMembershipsDTO) => { }: TGetGroupUserMembershipsDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); if (!actorOrgId) throw new BadRequestError({ message: "Failed to create group without organization" });
const { permission } = await permissionService.getOrgPermission(
actor,
actorId,
actorOrgId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Groups); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Groups);
const group = await groupDAL.findOne({ const group = await groupDAL.findOne({
orgId, orgId: actorOrgId,
slug: groupSlug slug: groupSlug
}); });
@@ -201,16 +222,23 @@ export const groupServiceFactory = ({
username, username,
actor, actor,
actorId, actorId,
orgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}: TCreateGroupUserMembershipDTO) => { }: TCreateGroupUserMembershipDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); if (!actorOrgId) throw new BadRequestError({ message: "Failed to create group without organization" });
const { permission } = await permissionService.getOrgPermission(
actor,
actorId,
actorOrgId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Groups); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Groups);
// check if group with slug exists // check if group with slug exists
const group = await groupDAL.findOne({ const group = await groupDAL.findOne({
orgId, orgId: actorOrgId,
slug: groupSlug slug: groupSlug
}); });
@@ -219,7 +247,7 @@ export const groupServiceFactory = ({
message: `Failed to find group with slug ${groupSlug}` message: `Failed to find group with slug ${groupSlug}`
}); });
const { permission: groupRolePermission } = await permissionService.getOrgPermissionByRole(group.role, orgId); const { permission: groupRolePermission } = await permissionService.getOrgPermissionByRole(group.role, actorOrgId);
// check if user has broader or equal to privileges than group // check if user has broader or equal to privileges than group
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, groupRolePermission); const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, groupRolePermission);
@@ -250,7 +278,7 @@ export const groupServiceFactory = ({
// check if user is even part of the organization // check if user is even part of the organization
const existingUserOrgMembership = await orgDAL.findMembership({ const existingUserOrgMembership = await orgDAL.findMembership({
userId: user.userId, userId: user.userId,
orgId orgId: actorOrgId
}); });
if (!existingUserOrgMembership) if (!existingUserOrgMembership)
@@ -338,16 +366,23 @@ export const groupServiceFactory = ({
username, username,
actor, actor,
actorId, actorId,
orgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}: TDeleteGroupUserMembershipDTO) => { }: TDeleteGroupUserMembershipDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); if (!actorOrgId) throw new BadRequestError({ message: "Failed to create group without organization" });
const { permission } = await permissionService.getOrgPermission(
actor,
actorId,
actorOrgId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Groups); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Groups);
// check if group with slug exists // check if group with slug exists
const group = await groupDAL.findOne({ const group = await groupDAL.findOne({
orgId, orgId: actorOrgId,
slug: groupSlug slug: groupSlug
}); });
@@ -356,7 +391,7 @@ export const groupServiceFactory = ({
message: `Failed to find group with slug ${groupSlug}` message: `Failed to find group with slug ${groupSlug}`
}); });
const { permission: groupRolePermission } = await permissionService.getOrgPermissionByRole(group.role, orgId); const { permission: groupRolePermission } = await permissionService.getOrgPermissionByRole(group.role, actorOrgId);
// check if user has broader or equal to privileges than group // check if user has broader or equal to privileges than group
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, groupRolePermission); const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, groupRolePermission);
@@ -12,7 +12,6 @@ import {
infisicalSymmetricEncypt infisicalSymmetricEncypt
} from "@app/lib/crypto/encryption"; } from "@app/lib/crypto/encryption";
import { BadRequestError } from "@app/lib/errors"; import { BadRequestError } from "@app/lib/errors";
import { TOrgPermission } from "@app/lib/types";
import { AuthMethod, AuthTokenType } from "@app/services/auth/auth-type"; import { AuthMethod, AuthTokenType } from "@app/services/auth/auth-type";
import { TOrgBotDALFactory } from "@app/services/org/org-bot-dal"; 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";
@@ -24,7 +23,7 @@ import { TLicenseServiceFactory } from "../license/license-service";
import { OrgPermissionActions, OrgPermissionSubjects } from "../permission/org-permission"; import { OrgPermissionActions, OrgPermissionSubjects } from "../permission/org-permission";
import { TPermissionServiceFactory } from "../permission/permission-service"; import { TPermissionServiceFactory } from "../permission/permission-service";
import { TLdapConfigDALFactory } from "./ldap-config-dal"; import { TLdapConfigDALFactory } from "./ldap-config-dal";
import { TCreateLdapCfgDTO, TLdapLoginDTO, TUpdateLdapCfgDTO } from "./ldap-config-types"; import { TCreateLdapCfgDTO, TGetLdapCfgDTO, TLdapLoginDTO, TUpdateLdapCfgDTO } from "./ldap-config-types";
type TLdapConfigServiceFactoryDep = { type TLdapConfigServiceFactoryDep = {
ldapConfigDAL: TLdapConfigDALFactory; ldapConfigDAL: TLdapConfigDALFactory;
@@ -282,7 +281,7 @@ export const ldapConfigServiceFactory = ({
orgId, orgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}: TOrgPermission) => { }: TGetLdapCfgDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Ldap); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Ldap);
return getLdapCfg({ return getLdapCfg({
@@ -1,6 +1,7 @@
import { TOrgPermission } from "@app/lib/types"; import { TOrgPermission } from "@app/lib/types";
export type TCreateLdapCfgDTO = { export type TCreateLdapCfgDTO = {
orgId: string;
isActive: boolean; isActive: boolean;
url: string; url: string;
bindDN: string; bindDN: string;
@@ -9,7 +10,9 @@ export type TCreateLdapCfgDTO = {
caCert: string; caCert: string;
} & TOrgPermission; } & TOrgPermission;
export type TUpdateLdapCfgDTO = Partial<{ export type TUpdateLdapCfgDTO = {
orgId: string;
} & Partial<{
isActive: boolean; isActive: boolean;
url: string; url: string;
bindDN: string; bindDN: string;
@@ -19,6 +22,10 @@ export type TUpdateLdapCfgDTO = Partial<{
}> & }> &
TOrgPermission; TOrgPermission;
export type TGetLdapCfgDTO = {
orgId: string;
} & TOrgPermission;
export type TLdapLoginDTO = { export type TLdapLoginDTO = {
externalId: string; externalId: string;
username: string; username: string;
-1
View File
@@ -3,7 +3,6 @@ import { ActorAuthMethod, ActorType } from "@app/services/auth/auth-type";
export type TOrgPermission = { export type TOrgPermission = {
actor: ActorType; actor: ActorType;
actorId: string; actorId: string;
orgId: string;
actorAuthMethod: ActorAuthMethod; actorAuthMethod: ActorAuthMethod;
actorOrgId: string | undefined; actorOrgId: string | undefined;
}; };
@@ -12,7 +12,6 @@ export const useCreateGroup = () => {
mutationFn: async ({ mutationFn: async ({
name, name,
slug, slug,
organizationId,
role role
}: { }: {
name: string; name: string;
@@ -25,7 +24,6 @@ export const useCreateGroup = () => {
} = await apiRequest.post<TGroup>("/api/v1/groups", { } = await apiRequest.post<TGroup>("/api/v1/groups", {
name, name,
slug, slug,
organizationId,
role role
}); });