mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat: completed all role routers
This commit is contained in:
13
backend/src/@types/fastify.d.ts
vendored
13
backend/src/@types/fastify.d.ts
vendored
@@ -53,6 +53,7 @@ import { TSshHostServiceFactory } from "@app/ee/services/ssh-host/ssh-host-servi
|
||||
import { TSshHostGroupServiceFactory } from "@app/ee/services/ssh-host-group/ssh-host-group-service";
|
||||
import { TTrustedIpServiceFactory } from "@app/ee/services/trusted-ip/trusted-ip-types";
|
||||
import { TAuthMode } from "@app/server/plugins/auth/inject-identity";
|
||||
import { TAdditionalPrivilegeServiceFactory } from "@app/services/additional-privilege/additional-privilege-service";
|
||||
import { TApiKeyServiceFactory } from "@app/services/api-key/api-key-service";
|
||||
import { TAppConnectionServiceFactory } from "@app/services/app-connection/app-connection-service";
|
||||
import { TAuthLoginFactory } from "@app/services/auth/auth-login-service";
|
||||
@@ -88,6 +89,9 @@ import { TIdentityTokenAuthServiceFactory } from "@app/services/identity-token-a
|
||||
import { TIdentityUaServiceFactory } from "@app/services/identity-ua/identity-ua-service";
|
||||
import { TIntegrationServiceFactory } from "@app/services/integration/integration-service";
|
||||
import { TIntegrationAuthServiceFactory } from "@app/services/integration-auth/integration-auth-service";
|
||||
import { TMembershipGroupServiceFactory } from "@app/services/membership-group/membership-group-service";
|
||||
import { TMembershipIdentityServiceFactory } from "@app/services/membership-identity/membership-identity-service";
|
||||
import { TMembershipUserServiceFactory } from "@app/services/membership-user/membership-user-service";
|
||||
import { TMicrosoftTeamsServiceFactory } from "@app/services/microsoft-teams/microsoft-teams-service";
|
||||
import { TNotificationServiceFactory } from "@app/services/notification/notification-service";
|
||||
import { TOfflineUsageReportServiceFactory } from "@app/services/offline-usage-report/offline-usage-report-service";
|
||||
@@ -106,6 +110,7 @@ import { TProjectKeyServiceFactory } from "@app/services/project-key/project-key
|
||||
import { TProjectMembershipServiceFactory } from "@app/services/project-membership/project-membership-service";
|
||||
import { TProjectRoleServiceFactory } from "@app/services/project-role/project-role-service";
|
||||
import { TReminderServiceFactory } from "@app/services/reminder/reminder-types";
|
||||
import { TRoleServiceFactory } from "@app/services/role/role-service";
|
||||
import { TSecretServiceFactory } from "@app/services/secret/secret-service";
|
||||
import { TSecretBlindIndexServiceFactory } from "@app/services/secret-blind-index/secret-blind-index-service";
|
||||
import { TSecretFolderServiceFactory } from "@app/services/secret-folder/secret-folder-service";
|
||||
@@ -125,6 +130,7 @@ import { TUserServiceFactory } from "@app/services/user/user-service";
|
||||
import { TUserEngagementServiceFactory } from "@app/services/user-engagement/user-engagement-service";
|
||||
import { TWebhookServiceFactory } from "@app/services/webhook/webhook-service";
|
||||
import { TWorkflowIntegrationServiceFactory } from "@app/services/workflow-integration/workflow-integration-service";
|
||||
import { TConvertorServiceFactory } from "@app/services/convertor/convertor-service";
|
||||
|
||||
declare module "@fastify/request-context" {
|
||||
interface RequestContextData {
|
||||
@@ -324,6 +330,13 @@ declare module "fastify" {
|
||||
pamAccount: TPamAccountServiceFactory;
|
||||
pamSession: TPamSessionServiceFactory;
|
||||
upgradePath: TUpgradePathService;
|
||||
|
||||
membershipUser: TMembershipUserServiceFactory;
|
||||
membershipIdentity: TMembershipIdentityServiceFactory;
|
||||
membershipGroup: TMembershipGroupServiceFactory;
|
||||
role: TRoleServiceFactory;
|
||||
additionalPrivilege: TAdditionalPrivilegeServiceFactory;
|
||||
convertor: TConvertorServiceFactory;
|
||||
};
|
||||
// this is exclusive use for middlewares in which we need to inject data
|
||||
// everywhere else access using service layer
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { packRules } from "@casl/ability/extra";
|
||||
import { z } from "zod";
|
||||
|
||||
import { ProjectMembershipRole, ProjectRolesSchema } from "@app/db/schemas";
|
||||
import { AccessScope, ProjectMembershipRole, ProjectRolesSchema } from "@app/db/schemas";
|
||||
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||
import {
|
||||
backfillPermissionV1SchemaToV2Schema,
|
||||
@@ -13,7 +13,6 @@ import { slugSchema } from "@app/server/lib/schemas";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
import { SanitizedRoleSchemaV1 } from "@app/server/routes/sanitizedSchemas";
|
||||
import { AuthMode } from "@app/services/auth/auth-type";
|
||||
import { ProjectRoleServiceIdentifierType } from "@app/services/project-role/project-role-types";
|
||||
|
||||
export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProvider) => {
|
||||
server.route({
|
||||
@@ -55,14 +54,16 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
|
||||
packRules(backfillPermissionV1SchemaToV2Schema(req.body.permissions, true))
|
||||
);
|
||||
|
||||
const role = await server.services.projectRole.createRole({
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
actor: req.permission.type,
|
||||
filter: {
|
||||
type: ProjectRoleServiceIdentifierType.SLUG,
|
||||
projectSlug: req.params.projectSlug
|
||||
const { id: projectId } = await server.services.convertor.projectSlugToId({
|
||||
slug: req.params.projectSlug,
|
||||
orgId: req.permission.orgId
|
||||
});
|
||||
const role = await server.services.role.createRole({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Project,
|
||||
orgId: req.permission.orgId,
|
||||
projectId
|
||||
},
|
||||
data: {
|
||||
...req.body,
|
||||
@@ -73,7 +74,7 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
|
||||
await server.services.auditLog.createAuditLog({
|
||||
...req.auditLogInfo,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: role.projectId,
|
||||
projectId,
|
||||
event: {
|
||||
type: EventType.CREATE_PROJECT_ROLE,
|
||||
metadata: {
|
||||
@@ -86,7 +87,7 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
|
||||
}
|
||||
});
|
||||
|
||||
return { role };
|
||||
return { role: { ...role, projectId: role.projectId as string } };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -131,12 +132,21 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
|
||||
? JSON.stringify(packRules(backfillPermissionV1SchemaToV2Schema(req.body.permissions, true)))
|
||||
: undefined;
|
||||
|
||||
const role = await server.services.projectRole.updateRole({
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
actor: req.permission.type,
|
||||
roleId: req.params.roleId,
|
||||
const { id: projectId } = await server.services.convertor.projectSlugToId({
|
||||
slug: req.params.projectSlug,
|
||||
orgId: req.permission.orgId
|
||||
});
|
||||
|
||||
const role = await server.services.role.updateRole({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Project,
|
||||
orgId: req.permission.orgId,
|
||||
projectId
|
||||
},
|
||||
selector: {
|
||||
id: req.params.roleId
|
||||
},
|
||||
data: {
|
||||
...req.body,
|
||||
permissions: stringifiedPermissions
|
||||
@@ -146,7 +156,7 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
|
||||
await server.services.auditLog.createAuditLog({
|
||||
...req.auditLogInfo,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: role.projectId,
|
||||
projectId: role.projectId as string,
|
||||
event: {
|
||||
type: EventType.UPDATE_PROJECT_ROLE,
|
||||
metadata: {
|
||||
@@ -159,7 +169,7 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
|
||||
}
|
||||
});
|
||||
|
||||
return { role };
|
||||
return { role: { ...role, projectId: role.projectId as string } };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -188,18 +198,27 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const role = await server.services.projectRole.deleteRole({
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
actor: req.permission.type,
|
||||
roleId: req.params.roleId
|
||||
const { id: projectId } = await server.services.convertor.projectSlugToId({
|
||||
slug: req.params.projectSlug,
|
||||
orgId: req.permission.orgId
|
||||
});
|
||||
|
||||
const role = await server.services.role.deleteRole({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Project,
|
||||
orgId: req.permission.orgId,
|
||||
projectId
|
||||
},
|
||||
selector: {
|
||||
id: req.params.roleId
|
||||
}
|
||||
});
|
||||
|
||||
await server.services.auditLog.createAuditLog({
|
||||
...req.auditLogInfo,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: role.projectId,
|
||||
projectId: role.projectId as string,
|
||||
event: {
|
||||
type: EventType.DELETE_PROJECT_ROLE,
|
||||
metadata: {
|
||||
@@ -210,7 +229,7 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
|
||||
}
|
||||
});
|
||||
|
||||
return { role };
|
||||
return { role: { ...role, projectId: role.projectId as string } };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -238,17 +257,21 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const roles = await server.services.projectRole.listRoles({
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
actor: req.permission.type,
|
||||
filter: {
|
||||
type: ProjectRoleServiceIdentifierType.SLUG,
|
||||
projectSlug: req.params.projectSlug
|
||||
}
|
||||
const { id: projectId } = await server.services.convertor.projectSlugToId({
|
||||
slug: req.params.projectSlug,
|
||||
orgId: req.permission.orgId
|
||||
});
|
||||
return { roles };
|
||||
|
||||
const { roles } = await server.services.role.listRoles({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Project,
|
||||
orgId: req.permission.orgId,
|
||||
projectId
|
||||
},
|
||||
data: {}
|
||||
});
|
||||
return { roles: roles.map((el) => ({ ...el, projectId: el.projectId as string })) };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -265,78 +288,30 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
role: SanitizedRoleSchemaV1.omit({ version: true })
|
||||
role: SanitizedRoleSchemaV1
|
||||
})
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const role = await server.services.projectRole.getRoleBySlug({
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
actor: req.permission.type,
|
||||
filter: {
|
||||
type: ProjectRoleServiceIdentifierType.SLUG,
|
||||
projectSlug: req.params.projectSlug
|
||||
},
|
||||
roleSlug: req.params.slug
|
||||
const { id: projectId } = await server.services.convertor.projectSlugToId({
|
||||
slug: req.params.projectSlug,
|
||||
orgId: req.permission.orgId
|
||||
});
|
||||
|
||||
return { role };
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "GET",
|
||||
url: "/:projectId/permissions",
|
||||
config: {
|
||||
rateLimit: readLimit
|
||||
},
|
||||
schema: {
|
||||
params: z.object({
|
||||
projectId: z.string().trim()
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
data: z.object({
|
||||
membership: z.object({
|
||||
id: z.string(),
|
||||
roles: z
|
||||
.object({
|
||||
role: z.string()
|
||||
})
|
||||
.array()
|
||||
}),
|
||||
assumedPrivilegeDetails: z
|
||||
.object({
|
||||
actorId: z.string(),
|
||||
actorType: z.string(),
|
||||
actorName: z.string(),
|
||||
actorEmail: z.string().optional()
|
||||
})
|
||||
.optional(),
|
||||
permissions: z.any().array()
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
const { permissions, membership, assumedPrivilegeDetails } = await server.services.projectRole.getUserPermission(
|
||||
req.permission.id,
|
||||
req.params.projectId,
|
||||
req.permission.authMethod,
|
||||
req.permission.orgId
|
||||
);
|
||||
|
||||
return {
|
||||
data: {
|
||||
permissions,
|
||||
membership,
|
||||
assumedPrivilegeDetails
|
||||
const role = await server.services.role.getRoleBySlug({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Project,
|
||||
orgId: req.permission.orgId,
|
||||
projectId
|
||||
},
|
||||
selector: {
|
||||
slug: req.params.slug
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
return { role: { ...role, projectId: role.projectId as string } };
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { packRules } from "@casl/ability/extra";
|
||||
import { z } from "zod";
|
||||
|
||||
import { OrgMembershipRole, OrgMembershipsSchema, OrgRolesSchema } from "@app/db/schemas";
|
||||
import { AccessScope, OrgMembershipRole, OrgMembershipsSchema, OrgRolesSchema } from "@app/db/schemas";
|
||||
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||
import { OrgPermissionSchema } from "@app/ee/services/permission/org-permission";
|
||||
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
|
||||
import { slugSchema } from "@app/server/lib/schemas";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
@@ -25,8 +27,7 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
|
||||
),
|
||||
name: z.string().trim(),
|
||||
description: z.string().trim().nullish(),
|
||||
// TODO(scott): once UI refactored permissions: OrgPermissionSchema.array()
|
||||
permissions: z.any().array()
|
||||
permissions: OrgPermissionSchema.array()
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
@@ -36,13 +37,18 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
const role = await server.services.orgRole.createRole(
|
||||
req.permission.id,
|
||||
req.params.organizationId,
|
||||
req.body,
|
||||
req.permission.authMethod,
|
||||
req.permission.orgId
|
||||
);
|
||||
const stringifiedPermissions = JSON.stringify(packRules(req.body.permissions));
|
||||
const role = await server.services.role.createRole({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Organization,
|
||||
orgId: req.params.organizationId
|
||||
},
|
||||
data: {
|
||||
...req.body,
|
||||
permissions: stringifiedPermissions
|
||||
}
|
||||
});
|
||||
|
||||
await server.services.auditLog.createAuditLog({
|
||||
...req.auditLogInfo,
|
||||
@@ -59,7 +65,7 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
|
||||
}
|
||||
});
|
||||
|
||||
return { role };
|
||||
return { role: { ...role, orgId: role.orgId as string } };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -82,14 +88,17 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
const role = await server.services.orgRole.getRole(
|
||||
req.permission.id,
|
||||
req.params.organizationId,
|
||||
req.params.roleId,
|
||||
req.permission.authMethod,
|
||||
req.permission.orgId
|
||||
);
|
||||
return { role };
|
||||
const role = await server.services.role.getRoleById({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Organization,
|
||||
orgId: req.params.organizationId
|
||||
},
|
||||
selector: {
|
||||
id: req.params.roleId
|
||||
}
|
||||
});
|
||||
return { role: { ...role, orgId: role.orgId as string } };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -114,8 +123,7 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
|
||||
.optional(),
|
||||
name: z.string().trim().optional(),
|
||||
description: z.string().trim().nullish(),
|
||||
// TODO(scott): once UI refactored permissions: OrgPermissionSchema.array().optional()
|
||||
permissions: z.any().array().optional()
|
||||
permissions: OrgPermissionSchema.array().optional()
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
@@ -125,14 +133,21 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
const role = await server.services.orgRole.updateRole(
|
||||
req.permission.id,
|
||||
req.params.organizationId,
|
||||
req.params.roleId,
|
||||
req.body,
|
||||
req.permission.authMethod,
|
||||
req.permission.orgId
|
||||
);
|
||||
const stringifiedPermissions = req.body.permissions ? JSON.stringify(packRules(req.body.permissions)) : undefined;
|
||||
const role = await server.services.role.updateRole({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Organization,
|
||||
orgId: req.params.organizationId
|
||||
},
|
||||
selector: {
|
||||
id: req.params.roleId
|
||||
},
|
||||
data: {
|
||||
...req.body,
|
||||
permissions: stringifiedPermissions
|
||||
}
|
||||
});
|
||||
|
||||
await server.services.auditLog.createAuditLog({
|
||||
...req.auditLogInfo,
|
||||
@@ -149,7 +164,7 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
|
||||
}
|
||||
});
|
||||
|
||||
return { role };
|
||||
return { role: { ...role, orgId: role.orgId as string } };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -172,13 +187,16 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
const role = await server.services.orgRole.deleteRole(
|
||||
req.permission.id,
|
||||
req.params.organizationId,
|
||||
req.params.roleId,
|
||||
req.permission.authMethod,
|
||||
req.permission.orgId
|
||||
);
|
||||
const role = await server.services.role.deleteRole({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Organization,
|
||||
orgId: req.params.organizationId
|
||||
},
|
||||
selector: {
|
||||
id: req.params.roleId
|
||||
}
|
||||
});
|
||||
|
||||
await server.services.auditLog.createAuditLog({
|
||||
...req.auditLogInfo,
|
||||
@@ -189,10 +207,11 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
|
||||
}
|
||||
});
|
||||
|
||||
return { role };
|
||||
return { role: { ...role, orgId: role.orgId as string } };
|
||||
}
|
||||
});
|
||||
|
||||
// TODO(simp): switch to top level roles
|
||||
server.route({
|
||||
method: "GET",
|
||||
url: "/:organizationId/roles",
|
||||
@@ -206,25 +225,30 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
|
||||
response: {
|
||||
200: z.object({
|
||||
data: z.object({
|
||||
roles: OrgRolesSchema.omit({ permissions: true })
|
||||
.merge(z.object({ permissions: z.unknown() }))
|
||||
.array()
|
||||
roles: OrgRolesSchema.omit({ permissions: true }).array()
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
const roles = await server.services.orgRole.listRoles(
|
||||
req.permission.id,
|
||||
req.params.organizationId,
|
||||
req.permission.authMethod,
|
||||
req.permission.orgId
|
||||
);
|
||||
return { data: { roles } };
|
||||
const { roles } = await server.services.role.listRoles({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Organization,
|
||||
orgId: req.permission.orgId
|
||||
},
|
||||
data: {}
|
||||
});
|
||||
return {
|
||||
data: {
|
||||
roles: roles.map((el) => ({ ...el, orgId: el.orgId as string }))
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// TODO(simp): get this fixed
|
||||
server.route({
|
||||
method: "GET",
|
||||
url: "/:organizationId/permissions",
|
||||
@@ -237,20 +261,20 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
membership: OrgMembershipsSchema,
|
||||
memberships: OrgMembershipsSchema.array(),
|
||||
permissions: z.any().array()
|
||||
})
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
const { permissions, membership } = await server.services.orgRole.getUserPermission(
|
||||
const { permissions, memberships } = await server.services.orgRole.getUserPermission(
|
||||
req.permission.id,
|
||||
req.params.organizationId,
|
||||
req.permission.authMethod,
|
||||
req.permission.orgId
|
||||
);
|
||||
return { permissions, membership };
|
||||
return { permissions, memberships };
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { packRules } from "@casl/ability/extra";
|
||||
import { z } from "zod";
|
||||
|
||||
import { ProjectMembershipRole, ProjectRolesSchema } from "@app/db/schemas";
|
||||
import { ProjectMembershipRole, ProjectRolesSchema, AccessScope } from "@app/db/schemas";
|
||||
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||
import { checkForInvalidPermissionCombination } from "@app/ee/services/permission/permission-fns";
|
||||
import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission";
|
||||
@@ -11,7 +11,6 @@ import { slugSchema } from "@app/server/lib/schemas";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
import { SanitizedRoleSchema } from "@app/server/routes/sanitizedSchemas";
|
||||
import { AuthMode } from "@app/services/auth/auth-type";
|
||||
import { ProjectRoleServiceIdentifierType } from "@app/services/project-role/project-role-types";
|
||||
|
||||
export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
|
||||
server.route({
|
||||
@@ -55,13 +54,11 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
|
||||
handler: async (req) => {
|
||||
const stringifiedPermissions = JSON.stringify(packRules(req.body.permissions));
|
||||
|
||||
const role = await server.services.projectRole.createRole({
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
actor: req.permission.type,
|
||||
filter: {
|
||||
type: ProjectRoleServiceIdentifierType.ID,
|
||||
const role = await server.services.role.createRole({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Project,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: req.params.projectId
|
||||
},
|
||||
data: {
|
||||
@@ -73,7 +70,7 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
|
||||
await server.services.auditLog.createAuditLog({
|
||||
...req.auditLogInfo,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: role.projectId,
|
||||
projectId: role.projectId as string,
|
||||
event: {
|
||||
type: EventType.CREATE_PROJECT_ROLE,
|
||||
metadata: {
|
||||
@@ -86,7 +83,7 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
|
||||
}
|
||||
});
|
||||
|
||||
return { role };
|
||||
return { role: { ...role, projectId: role.projectId as string } };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -133,12 +130,16 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const stringifiedPermissions = req.body.permissions ? JSON.stringify(packRules(req.body.permissions)) : undefined;
|
||||
const role = await server.services.projectRole.updateRole({
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
actor: req.permission.type,
|
||||
roleId: req.params.roleId,
|
||||
const role = await server.services.role.updateRole({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Project,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: req.params.projectId
|
||||
},
|
||||
selector: {
|
||||
id: req.params.roleId
|
||||
},
|
||||
data: {
|
||||
...req.body,
|
||||
permissions: stringifiedPermissions
|
||||
@@ -148,7 +149,7 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
|
||||
await server.services.auditLog.createAuditLog({
|
||||
...req.auditLogInfo,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: role.projectId,
|
||||
projectId: role.projectId as string,
|
||||
event: {
|
||||
type: EventType.UPDATE_PROJECT_ROLE,
|
||||
metadata: {
|
||||
@@ -161,7 +162,7 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
|
||||
}
|
||||
});
|
||||
|
||||
return { role };
|
||||
return { role: { ...role, projectId: role.projectId as string } };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -192,18 +193,22 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const role = await server.services.projectRole.deleteRole({
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
actor: req.permission.type,
|
||||
roleId: req.params.roleId
|
||||
const role = await server.services.role.deleteRole({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Project,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: req.params.projectId
|
||||
},
|
||||
selector: {
|
||||
id: req.params.roleId
|
||||
}
|
||||
});
|
||||
|
||||
await server.services.auditLog.createAuditLog({
|
||||
...req.auditLogInfo,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: role.projectId,
|
||||
projectId: role.projectId as string,
|
||||
event: {
|
||||
type: EventType.DELETE_PROJECT_ROLE,
|
||||
metadata: {
|
||||
@@ -214,7 +219,7 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
|
||||
}
|
||||
});
|
||||
|
||||
return { role };
|
||||
return { role: { ...role, projectId: role.projectId as string } };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -244,17 +249,16 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const roles = await server.services.projectRole.listRoles({
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
actor: req.permission.type,
|
||||
filter: {
|
||||
type: ProjectRoleServiceIdentifierType.ID,
|
||||
const { roles } = await server.services.role.listRoles({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Project,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: req.params.projectId
|
||||
}
|
||||
},
|
||||
data: {}
|
||||
});
|
||||
return { roles };
|
||||
return { roles: roles.map((el) => ({ ...el, projectId: el.projectId as string })) };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -273,24 +277,25 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
role: SanitizedRoleSchema.omit({ version: true })
|
||||
role: SanitizedRoleSchema
|
||||
})
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const role = await server.services.projectRole.getRoleBySlug({
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
actor: req.permission.type,
|
||||
filter: {
|
||||
type: ProjectRoleServiceIdentifierType.ID,
|
||||
const role = await server.services.role.getRoleBySlug({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Project,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: req.params.projectId
|
||||
},
|
||||
roleSlug: req.params.roleSlug
|
||||
selector: {
|
||||
slug: req.params.roleSlug
|
||||
}
|
||||
});
|
||||
return { role };
|
||||
|
||||
return { role: { ...role, projectId: role.projectId as string } };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -307,14 +312,16 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
|
||||
response: {
|
||||
200: z.object({
|
||||
data: z.object({
|
||||
membership: z.object({
|
||||
id: z.string(),
|
||||
roles: z
|
||||
.object({
|
||||
role: z.string()
|
||||
})
|
||||
.array()
|
||||
}),
|
||||
memberships: z
|
||||
.object({
|
||||
id: z.string(),
|
||||
roles: z
|
||||
.object({
|
||||
role: z.string()
|
||||
})
|
||||
.array()
|
||||
})
|
||||
.array(),
|
||||
assumedPrivilegeDetails: z
|
||||
.object({
|
||||
actorId: z.string(),
|
||||
@@ -330,7 +337,7 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
const { permissions, membership, assumedPrivilegeDetails } = await server.services.projectRole.getUserPermission(
|
||||
const { permissions, memberships, assumedPrivilegeDetails } = await server.services.projectRole.getUserPermission(
|
||||
req.permission.id,
|
||||
req.params.projectId,
|
||||
req.permission.authMethod,
|
||||
@@ -340,7 +347,7 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
|
||||
return {
|
||||
data: {
|
||||
permissions,
|
||||
membership,
|
||||
memberships,
|
||||
assumedPrivilegeDetails
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { packRules } from "@casl/ability/extra";
|
||||
import { z } from "zod";
|
||||
|
||||
import { ProjectMembershipRole, ProjectRolesSchema } from "@app/db/schemas";
|
||||
import { AccessScope, ProjectMembershipRole, ProjectRolesSchema } from "@app/db/schemas";
|
||||
import { EventType } from "@app/ee/services/audit-log/audit-log-types";
|
||||
import { checkForInvalidPermissionCombination } from "@app/ee/services/permission/permission-fns";
|
||||
import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission";
|
||||
@@ -11,7 +11,6 @@ import { slugSchema } from "@app/server/lib/schemas";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
import { SanitizedRoleSchema } from "@app/server/routes/sanitizedSchemas";
|
||||
import { AuthMode } from "@app/services/auth/auth-type";
|
||||
import { ProjectRoleServiceIdentifierType } from "@app/services/project-role/project-role-types";
|
||||
|
||||
export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProvider) => {
|
||||
server.route({
|
||||
@@ -55,13 +54,11 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
|
||||
handler: async (req) => {
|
||||
const stringifiedPermissions = JSON.stringify(packRules(req.body.permissions));
|
||||
|
||||
const role = await server.services.projectRole.createRole({
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
actor: req.permission.type,
|
||||
filter: {
|
||||
type: ProjectRoleServiceIdentifierType.ID,
|
||||
const role = await server.services.role.createRole({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Project,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: req.params.projectId
|
||||
},
|
||||
data: {
|
||||
@@ -73,7 +70,7 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
|
||||
await server.services.auditLog.createAuditLog({
|
||||
...req.auditLogInfo,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: role.projectId,
|
||||
projectId: req.params.projectId,
|
||||
event: {
|
||||
type: EventType.CREATE_PROJECT_ROLE,
|
||||
metadata: {
|
||||
@@ -86,7 +83,7 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
|
||||
}
|
||||
});
|
||||
|
||||
return { role };
|
||||
return { role: { ...role, projectId: role.projectId as string } };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -133,12 +130,16 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const stringifiedPermissions = req.body.permissions ? JSON.stringify(packRules(req.body.permissions)) : undefined;
|
||||
const role = await server.services.projectRole.updateRole({
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
actor: req.permission.type,
|
||||
roleId: req.params.roleId,
|
||||
const role = await server.services.role.updateRole({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Project,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: req.params.projectId
|
||||
},
|
||||
selector: {
|
||||
id: req.params.roleId
|
||||
},
|
||||
data: {
|
||||
...req.body,
|
||||
permissions: stringifiedPermissions
|
||||
@@ -148,7 +149,7 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
|
||||
await server.services.auditLog.createAuditLog({
|
||||
...req.auditLogInfo,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: role.projectId,
|
||||
projectId: role.projectId as string,
|
||||
event: {
|
||||
type: EventType.UPDATE_PROJECT_ROLE,
|
||||
metadata: {
|
||||
@@ -161,7 +162,7 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
|
||||
}
|
||||
});
|
||||
|
||||
return { role };
|
||||
return { role: { ...role, projectId: role.projectId as string } };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -192,18 +193,22 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const role = await server.services.projectRole.deleteRole({
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
actor: req.permission.type,
|
||||
roleId: req.params.roleId
|
||||
const role = await server.services.role.deleteRole({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Project,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: req.params.projectId
|
||||
},
|
||||
selector: {
|
||||
id: req.params.roleId
|
||||
}
|
||||
});
|
||||
|
||||
await server.services.auditLog.createAuditLog({
|
||||
...req.auditLogInfo,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: role.projectId,
|
||||
projectId: role.projectId as string,
|
||||
event: {
|
||||
type: EventType.DELETE_PROJECT_ROLE,
|
||||
metadata: {
|
||||
@@ -214,7 +219,7 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
|
||||
}
|
||||
});
|
||||
|
||||
return { role };
|
||||
return { role: { ...role, projectId: role.projectId as string } };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -244,17 +249,16 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const roles = await server.services.projectRole.listRoles({
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
actor: req.permission.type,
|
||||
filter: {
|
||||
type: ProjectRoleServiceIdentifierType.ID,
|
||||
const { roles } = await server.services.role.listRoles({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Project,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: req.params.projectId
|
||||
}
|
||||
},
|
||||
data: {}
|
||||
});
|
||||
return { roles };
|
||||
return { roles: roles.map((el) => ({ ...el, projectId: el.projectId as string })) };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -273,24 +277,25 @@ export const registerDeprecatedProjectRoleRouter = async (server: FastifyZodProv
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
role: SanitizedRoleSchema.omit({ version: true })
|
||||
role: SanitizedRoleSchema
|
||||
})
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const role = await server.services.projectRole.getRoleBySlug({
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
actor: req.permission.type,
|
||||
filter: {
|
||||
type: ProjectRoleServiceIdentifierType.ID,
|
||||
const role = await server.services.role.getRoleBySlug({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Project,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: req.params.projectId
|
||||
},
|
||||
roleSlug: req.params.roleSlug
|
||||
selector: {
|
||||
slug: req.params.roleSlug
|
||||
}
|
||||
});
|
||||
return { role };
|
||||
|
||||
return { role: { ...role, projectId: role.projectId as string } };
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -44,10 +44,7 @@ type TGroupServiceFactoryDep = {
|
||||
projectDAL: Pick<TProjectDALFactory, "findProjectGhostUser" | "findById">;
|
||||
projectBotDAL: Pick<TProjectBotDALFactory, "findOne">;
|
||||
projectKeyDAL: Pick<TProjectKeyDALFactory, "find" | "delete" | "findLatestProjectKey" | "insertMany">;
|
||||
permissionService: Pick<
|
||||
TPermissionServiceFactory,
|
||||
"getOrgPermission" | "getOrgPermissionByRole" | "invalidateProjectPermissionCache"
|
||||
>;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission" | "getOrgPermissionByRoles" | "invalidateProjectPermissionCache">;
|
||||
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
||||
oidcConfigDAL: Pick<TOidcConfigDALFactory, "findOne">;
|
||||
};
|
||||
|
||||
@@ -66,12 +66,12 @@ export type TPermissionServiceFactory = {
|
||||
actorOrgId: string | undefined
|
||||
) => Promise<{
|
||||
permission: MongoAbility<OrgPermissionSet, MongoQuery>;
|
||||
memberships: TMemberships[];
|
||||
memberships: Array<TMemberships & { roles: { role: string; customRoleSlug?: string | null }[] }>;
|
||||
hasRole: (role: string) => boolean;
|
||||
}>;
|
||||
getProjectPermission: (arg: TGetProjectPermissionArg) => Promise<{
|
||||
permission: MongoAbility<ProjectPermissionSet, MongoQuery>;
|
||||
memberships: TMemberships[];
|
||||
memberships: Array<TMemberships & { roles: { role: string; customRoleSlug?: string | null }[] }>;
|
||||
hasRole: (role: string) => boolean;
|
||||
}>;
|
||||
// TODO(simp): check what is this doing
|
||||
|
||||
@@ -147,6 +147,8 @@ import { TQueueServiceFactory } from "@app/queue";
|
||||
import { readLimit } from "@app/server/config/rateLimiter";
|
||||
import { registerSecretScanningV2Webhooks } from "@app/server/plugins/secret-scanner-v2";
|
||||
import { accessTokenQueueServiceFactory } from "@app/services/access-token-queue/access-token-queue";
|
||||
import { additionalPrivilegeDALFactory } from "@app/services/additional-privilege/additional-privilege-dal";
|
||||
import { additionalPrivilegeServiceFactory } from "@app/services/additional-privilege/additional-privilege-service";
|
||||
import { apiKeyDALFactory } from "@app/services/api-key/api-key-dal";
|
||||
import { apiKeyServiceFactory } from "@app/services/api-key/api-key-service";
|
||||
import { appConnectionDALFactory } from "@app/services/app-connection/app-connection-dal";
|
||||
@@ -231,6 +233,14 @@ import { internalKmsDALFactory } from "@app/services/kms/internal-kms-dal";
|
||||
import { kmskeyDALFactory } from "@app/services/kms/kms-key-dal";
|
||||
import { kmsRootConfigDALFactory } from "@app/services/kms/kms-root-config-dal";
|
||||
import { kmsServiceFactory } from "@app/services/kms/kms-service";
|
||||
import { membershipDALFactory } from "@app/services/membership/membership-dal";
|
||||
import { membershipRoleDALFactory } from "@app/services/membership/membership-role-dal";
|
||||
import { membershipGroupDALFactory } from "@app/services/membership-group/membership-group-dal";
|
||||
import { membershipGroupServiceFactory } from "@app/services/membership-group/membership-group-service";
|
||||
import { membershipIdentityDALFactory } from "@app/services/membership-identity/membership-identity-dal";
|
||||
import { membershipIdentityServiceFactory } from "@app/services/membership-identity/membership-identity-service";
|
||||
import { membershipUserDALFactory } from "@app/services/membership-user/membership-user-dal";
|
||||
import { membershipUserServiceFactory } from "@app/services/membership-user/membership-user-service";
|
||||
import { microsoftTeamsIntegrationDALFactory } from "@app/services/microsoft-teams/microsoft-teams-integration-dal";
|
||||
import { microsoftTeamsServiceFactory } from "@app/services/microsoft-teams/microsoft-teams-service";
|
||||
import { projectMicrosoftTeamsConfigDALFactory } from "@app/services/microsoft-teams/project-microsoft-teams-config-dal";
|
||||
@@ -283,6 +293,8 @@ import { reminderServiceFactory } from "@app/services/reminder/reminder-service"
|
||||
import { reminderRecipientDALFactory } from "@app/services/reminder-recipients/reminder-recipient-dal";
|
||||
import { dailyResourceCleanUpQueueServiceFactory } from "@app/services/resource-cleanup/resource-cleanup-queue";
|
||||
import { resourceMetadataDALFactory } from "@app/services/resource-metadata/resource-metadata-dal";
|
||||
import { roleDALFactory } from "@app/services/role/role-dal";
|
||||
import { roleServiceFactory } from "@app/services/role/role-service";
|
||||
import { secretDALFactory } from "@app/services/secret/secret-dal";
|
||||
import { secretQueueFactory } from "@app/services/secret/secret-queue";
|
||||
import { secretServiceFactory } from "@app/services/secret/secret-service";
|
||||
@@ -531,17 +543,27 @@ export const registerRoutes = async (
|
||||
const secretScanningV2DAL = secretScanningV2DALFactory(db);
|
||||
const keyValueStoreDAL = keyValueStoreDALFactory(db);
|
||||
|
||||
const membershipDAL = membershipDALFactory(db);
|
||||
const membershipUserDAL = membershipUserDALFactory(db);
|
||||
const membershipIdentityDAL = membershipIdentityDALFactory(db);
|
||||
const membershipGroupDAL = membershipGroupDALFactory(db);
|
||||
const additionalPrivilegeDAL = additionalPrivilegeDALFactory(db);
|
||||
const membershipRoleDAL = membershipRoleDALFactory(db);
|
||||
const roleDAL = roleDALFactory(db);
|
||||
|
||||
const eventBusService = eventBusFactory(server.redis);
|
||||
const sseService = sseServiceFactory(eventBusService, server.redis);
|
||||
|
||||
const permissionService = permissionServiceFactory({
|
||||
permissionDAL,
|
||||
orgRoleDAL,
|
||||
projectRoleDAL,
|
||||
serviceTokenDAL,
|
||||
projectDAL,
|
||||
keyStore
|
||||
keyStore,
|
||||
roleDAL,
|
||||
userDAL,
|
||||
identityDAL
|
||||
});
|
||||
|
||||
const assumePrivilegeService = assumePrivilegeServiceFactory({
|
||||
projectDAL,
|
||||
permissionService
|
||||
@@ -556,6 +578,41 @@ export const registerRoutes = async (
|
||||
projectDAL
|
||||
});
|
||||
|
||||
const membershipUserService = membershipUserServiceFactory({
|
||||
licenseService,
|
||||
membershipRoleDAL,
|
||||
membershipUserDAL,
|
||||
orgDAL,
|
||||
permissionService,
|
||||
roleDAL,
|
||||
userDAL
|
||||
});
|
||||
|
||||
const membershipIdentityService = membershipIdentityServiceFactory({
|
||||
membershipIdentityDAL,
|
||||
membershipRoleDAL,
|
||||
orgDAL,
|
||||
permissionService,
|
||||
roleDAL
|
||||
});
|
||||
|
||||
const membershipGroupService = membershipGroupServiceFactory({
|
||||
membershipGroupDAL,
|
||||
membershipRoleDAL,
|
||||
roleDAL
|
||||
});
|
||||
|
||||
const roleService = roleServiceFactory({
|
||||
permissionService,
|
||||
roleDAL
|
||||
});
|
||||
const additionalPrivilegeService = additionalPrivilegeServiceFactory({
|
||||
additionalPrivilegeDAL,
|
||||
membershipDAL,
|
||||
orgDAL,
|
||||
permissionService
|
||||
});
|
||||
|
||||
const hsmService = hsmServiceFactory({
|
||||
hsmModule,
|
||||
envConfig
|
||||
@@ -1538,7 +1595,8 @@ export const registerRoutes = async (
|
||||
identityProjectDAL,
|
||||
licenseService,
|
||||
identityMetadataDAL,
|
||||
keyStore
|
||||
keyStore,
|
||||
orgDAL
|
||||
});
|
||||
|
||||
const identityAuthTemplateService = identityAuthTemplateServiceFactory({
|
||||
@@ -1563,8 +1621,10 @@ export const registerRoutes = async (
|
||||
identityProjectDAL,
|
||||
identityOrgMembershipDAL,
|
||||
identityProjectMembershipRoleDAL,
|
||||
projectRoleDAL
|
||||
projectRoleDAL,
|
||||
orgDAL
|
||||
});
|
||||
|
||||
const identityProjectAdditionalPrivilegeService = identityProjectAdditionalPrivilegeServiceFactory({
|
||||
projectDAL,
|
||||
identityProjectAdditionalPrivilegeDAL,
|
||||
@@ -1584,7 +1644,8 @@ export const registerRoutes = async (
|
||||
identityOrgMembershipDAL,
|
||||
identityAccessTokenDAL,
|
||||
permissionService,
|
||||
licenseService
|
||||
licenseService,
|
||||
orgDAL
|
||||
});
|
||||
|
||||
const identityUaService = identityUaServiceFactory({
|
||||
@@ -1594,7 +1655,8 @@ export const registerRoutes = async (
|
||||
identityUaClientSecretDAL,
|
||||
identityUaDAL,
|
||||
licenseService,
|
||||
keyStore
|
||||
keyStore,
|
||||
orgDAL
|
||||
});
|
||||
|
||||
const identityKubernetesAuthService = identityKubernetesAuthServiceFactory({
|
||||
@@ -1604,6 +1666,7 @@ export const registerRoutes = async (
|
||||
permissionService,
|
||||
licenseService,
|
||||
gatewayService,
|
||||
orgDAL,
|
||||
gatewayV2Service,
|
||||
gatewayV2DAL,
|
||||
gatewayDAL,
|
||||
@@ -1611,6 +1674,7 @@ export const registerRoutes = async (
|
||||
});
|
||||
const identityGcpAuthService = identityGcpAuthServiceFactory({
|
||||
identityGcpAuthDAL,
|
||||
orgDAL,
|
||||
identityOrgMembershipDAL,
|
||||
identityAccessTokenDAL,
|
||||
permissionService,
|
||||
@@ -1619,6 +1683,7 @@ export const registerRoutes = async (
|
||||
|
||||
const identityAliCloudAuthService = identityAliCloudAuthServiceFactory({
|
||||
identityAccessTokenDAL,
|
||||
orgDAL,
|
||||
identityAliCloudAuthDAL,
|
||||
identityOrgMembershipDAL,
|
||||
licenseService,
|
||||
@@ -1627,6 +1692,7 @@ export const registerRoutes = async (
|
||||
|
||||
const identityTlsCertAuthService = identityTlsCertAuthServiceFactory({
|
||||
identityAccessTokenDAL,
|
||||
orgDAL,
|
||||
identityTlsCertAuthDAL,
|
||||
identityOrgMembershipDAL,
|
||||
licenseService,
|
||||
@@ -1636,6 +1702,7 @@ export const registerRoutes = async (
|
||||
|
||||
const identityAwsAuthService = identityAwsAuthServiceFactory({
|
||||
identityAccessTokenDAL,
|
||||
orgDAL,
|
||||
identityAwsAuthDAL,
|
||||
identityOrgMembershipDAL,
|
||||
licenseService,
|
||||
@@ -1644,6 +1711,7 @@ export const registerRoutes = async (
|
||||
|
||||
const identityAzureAuthService = identityAzureAuthServiceFactory({
|
||||
identityAzureAuthDAL,
|
||||
orgDAL,
|
||||
identityOrgMembershipDAL,
|
||||
identityAccessTokenDAL,
|
||||
permissionService,
|
||||
@@ -1652,6 +1720,7 @@ export const registerRoutes = async (
|
||||
|
||||
const identityOciAuthService = identityOciAuthServiceFactory({
|
||||
identityAccessTokenDAL,
|
||||
orgDAL,
|
||||
identityOciAuthDAL,
|
||||
identityOrgMembershipDAL,
|
||||
licenseService,
|
||||
@@ -1674,6 +1743,7 @@ export const registerRoutes = async (
|
||||
|
||||
const identityOidcAuthService = identityOidcAuthServiceFactory({
|
||||
identityOidcAuthDAL,
|
||||
orgDAL,
|
||||
identityOrgMembershipDAL,
|
||||
identityAccessTokenDAL,
|
||||
permissionService,
|
||||
@@ -1683,6 +1753,7 @@ export const registerRoutes = async (
|
||||
|
||||
const identityJwtAuthService = identityJwtAuthServiceFactory({
|
||||
identityJwtAuthDAL,
|
||||
orgDAL,
|
||||
permissionService,
|
||||
identityAccessTokenDAL,
|
||||
identityOrgMembershipDAL,
|
||||
@@ -1692,6 +1763,7 @@ export const registerRoutes = async (
|
||||
|
||||
const identityLdapAuthService = identityLdapAuthServiceFactory({
|
||||
identityLdapAuthDAL,
|
||||
orgDAL,
|
||||
permissionService,
|
||||
kmsService,
|
||||
identityAccessTokenDAL,
|
||||
@@ -2300,7 +2372,13 @@ export const registerRoutes = async (
|
||||
pamResource: pamResourceService,
|
||||
pamAccount: pamAccountService,
|
||||
pamSession: pamSessionService,
|
||||
upgradePath: upgradePathService
|
||||
upgradePath: upgradePathService,
|
||||
|
||||
membershipUser: membershipUserService,
|
||||
membershipIdentity: membershipIdentityService,
|
||||
membershipGroup: membershipGroupService,
|
||||
role: roleService,
|
||||
additionalPrivilege: additionalPrivilegeService
|
||||
});
|
||||
|
||||
const cronJobs: CronJob[] = [];
|
||||
|
||||
@@ -209,11 +209,11 @@ export const SanitizedIdentityPrivilegeSchema = IdentityProjectAdditionalPrivile
|
||||
)
|
||||
});
|
||||
|
||||
export const SanitizedRoleSchema = ProjectRolesSchema.extend({
|
||||
export const SanitizedRoleSchema = ProjectRolesSchema.omit({ version: true }).extend({
|
||||
permissions: UnpackedPermissionSchema.array()
|
||||
});
|
||||
|
||||
export const SanitizedRoleSchemaV1 = ProjectRolesSchema.extend({
|
||||
export const SanitizedRoleSchemaV1 = ProjectRolesSchema.omit({ version: true }).extend({
|
||||
permissions: UnpackedPermissionSchema.array().transform((caslPermission) =>
|
||||
// first map and remove other actions of folder permission
|
||||
caslPermission
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import {
|
||||
OrgMembershipRole,
|
||||
AccessScope,
|
||||
ProjectMembershipRole,
|
||||
ProjectMembershipsSchema,
|
||||
ProjectUserMembershipRolesSchema,
|
||||
@@ -67,14 +67,23 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const memberships = await server.services.projectMembership.getProjectMemberships({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorOrgId: req.permission.orgId,
|
||||
projectId: req.params.projectId
|
||||
const { data: memberships } = await server.services.membershipUser.listMemberships({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Project,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: req.params.projectId
|
||||
},
|
||||
data: {}
|
||||
});
|
||||
return { memberships };
|
||||
|
||||
return {
|
||||
memberships: memberships.map((el) => ({
|
||||
...el,
|
||||
userId: el.actorUserId as string,
|
||||
projectId: req.params.projectId
|
||||
}))
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -242,20 +251,17 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const usernamesAndEmails = [...req.body.emails, ...req.body.usernames];
|
||||
const { projectMemberships: memberships } = await server.services.org.inviteUserToOrganization({
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorId: req.permission.id,
|
||||
actorOrgId: req.permission.orgId,
|
||||
actor: req.permission.type,
|
||||
inviteeEmails: usernamesAndEmails,
|
||||
orgId: req.permission.orgId,
|
||||
organizationRoleSlug: OrgMembershipRole.NoAccess,
|
||||
projects: [
|
||||
{
|
||||
id: req.params.projectId,
|
||||
projectRoleSlug: req.body.roleSlugs || [ProjectMembershipRole.Member]
|
||||
}
|
||||
]
|
||||
const { memberships } = await server.services.membershipUser.createMembership({
|
||||
permission: req.permission,
|
||||
scopeData: {
|
||||
scope: AccessScope.Project,
|
||||
orgId: req.permission.orgId,
|
||||
projectId: req.params.projectId
|
||||
},
|
||||
data: {
|
||||
roles: (req.body.roleSlugs || [ProjectMembershipRole.Member]).map((role) => ({ isTemporary: false, role })),
|
||||
usernames: usernamesAndEmails
|
||||
}
|
||||
});
|
||||
|
||||
await server.services.auditLog.createAuditLog({
|
||||
@@ -263,15 +269,21 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
|
||||
...req.auditLogInfo,
|
||||
event: {
|
||||
type: EventType.ADD_BATCH_PROJECT_MEMBER,
|
||||
metadata: memberships.map(({ userId, id }) => ({
|
||||
userId: userId || "",
|
||||
metadata: memberships.map(({ actorUserId, id }) => ({
|
||||
userId: actorUserId || "",
|
||||
membershipId: id,
|
||||
email: ""
|
||||
}))
|
||||
}
|
||||
});
|
||||
|
||||
return { memberships };
|
||||
return {
|
||||
memberships: memberships.map((el) => ({
|
||||
...el,
|
||||
userId: el.actorUserId as string,
|
||||
projectId: req.params.projectId
|
||||
}))
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
88
backend/src/services/convertor/convertor-service.ts
Normal file
88
backend/src/services/convertor/convertor-service.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
import { NotFoundError } from "@app/lib/errors";
|
||||
import { TMembershipDALFactory } from "../membership/membership-dal";
|
||||
import { TProjectDALFactory } from "../project/project-dal";
|
||||
import { AccessScope, AccessScopeData } from "@app/db/schemas";
|
||||
|
||||
type TConvertorServiceFactoryDep = {
|
||||
projectDAL: Pick<TProjectDALFactory, "findOne">;
|
||||
membershipDAL: Pick<TMembershipDALFactory, "findOne">;
|
||||
};
|
||||
|
||||
export type TConvertorServiceFactory = ReturnType<typeof convertorServiceFactory>;
|
||||
|
||||
export const convertorServiceFactory = ({ projectDAL, membershipDAL }: TConvertorServiceFactoryDep) => {
|
||||
const $getScopeDatabaseFields = (scopeData: AccessScopeData) => {
|
||||
if (scopeData.scope === AccessScope.Organization) {
|
||||
return { scopeOrgId: scopeData.orgId };
|
||||
}
|
||||
|
||||
if (scopeData.scope === AccessScope.Namespace) {
|
||||
return { scopeNamespaceId: scopeData.namespaceId, scopeOrgId: scopeData.orgId };
|
||||
}
|
||||
|
||||
return { scopeProjectId: scopeData.projectId, scopeOrgId: scopeData.orgId };
|
||||
};
|
||||
|
||||
const projectSlugToId = async (dto: { slug: string; orgId: string }) => {
|
||||
const project = await projectDAL.findOne({
|
||||
orgId: dto.orgId,
|
||||
slug: dto.slug
|
||||
});
|
||||
if (!project) throw new NotFoundError({ message: `Project with slug ${slug} not found` });
|
||||
return project;
|
||||
};
|
||||
|
||||
const userMembershipIdToUserId = async (scopeData: AccessScopeData, membershipId: string) => {
|
||||
const dbFields = $getScopeDatabaseFields(scopeData);
|
||||
|
||||
const membership = await membershipDAL.findOne({
|
||||
scope: scopeData.scope,
|
||||
id: membershipId,
|
||||
...dbFields,
|
||||
scopeOrgId: scopeData.orgId
|
||||
});
|
||||
if (!membership || !membership.actorUserId) {
|
||||
throw new NotFoundError({ message: `Membership with id ${membershipId} not found` });
|
||||
}
|
||||
return membership.actorUserId;
|
||||
};
|
||||
|
||||
const groupMembershipIdToGroupId = async (scopeData: AccessScopeData, membershipId: string) => {
|
||||
const dbFields = $getScopeDatabaseFields(scopeData);
|
||||
|
||||
const membership = await membershipDAL.findOne({
|
||||
scope: scopeData.scope,
|
||||
id: membershipId,
|
||||
...dbFields,
|
||||
scopeOrgId: scopeData.orgId
|
||||
});
|
||||
if (!membership || !membership.actorGroupId) {
|
||||
throw new NotFoundError({ message: `Membership with id ${membershipId} not found` });
|
||||
}
|
||||
|
||||
return membership.actorGroupId;
|
||||
};
|
||||
|
||||
const identityMembershipIdToGroupId = async (scopeData: AccessScopeData, membershipId: string) => {
|
||||
const dbFields = $getScopeDatabaseFields(scopeData);
|
||||
|
||||
const membership = await membershipDAL.findOne({
|
||||
scope: scopeData.scope,
|
||||
id: membershipId,
|
||||
...dbFields,
|
||||
scopeOrgId: scopeData.orgId
|
||||
});
|
||||
if (!membership || !membership.actorIdentityId) {
|
||||
throw new NotFoundError({ message: `Membership with id ${membershipId} not found` });
|
||||
}
|
||||
|
||||
return membership.actorIdentityId;
|
||||
};
|
||||
|
||||
return {
|
||||
projectSlugToId,
|
||||
userMembershipIdToUserId,
|
||||
groupMembershipIdToGroupId,
|
||||
identityMembershipIdToGroupId
|
||||
};
|
||||
};
|
||||
0
backend/src/services/convertor/convertor-types.ts
Normal file
0
backend/src/services/convertor/convertor-types.ts
Normal file
@@ -43,10 +43,7 @@ type TGroupProjectServiceFactoryDep = {
|
||||
projectRoleDAL: Pick<TProjectRoleDALFactory, "find">;
|
||||
projectBotDAL: TProjectBotDALFactory;
|
||||
groupDAL: Pick<TGroupDALFactory, "findOne" | "findAllGroupPossibleMembers">;
|
||||
permissionService: Pick<
|
||||
TPermissionServiceFactory,
|
||||
"getProjectPermission" | "getProjectPermissionByRole" | "invalidateProjectPermissionCache"
|
||||
>;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission" | "getProjectPermissionByRoles" | "invalidateProjectPermissionCache">;
|
||||
};
|
||||
|
||||
export type TGroupProjectServiceFactory = ReturnType<typeof groupProjectServiceFactory>;
|
||||
|
||||
@@ -115,29 +115,27 @@ export const newProjectMembershipIdentityFactory = ({
|
||||
|
||||
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(dto.permission.orgId);
|
||||
const permissionRoles = await permissionService.getProjectPermissionByRoles(
|
||||
dto.data.roles.map((el) => el.role),
|
||||
dto.data.roles.filter((el) => el.role !== ProjectMembershipRole.NoAccess).map((el) => el.role),
|
||||
scope.value
|
||||
);
|
||||
for (const permissionRole of permissionRoles) {
|
||||
if (permissionRole?.role?.name !== ProjectMembershipRole.NoAccess) {
|
||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||
shouldUseNewPrivilegeSystem,
|
||||
ProjectPermissionIdentityActions.GrantPrivileges,
|
||||
ProjectPermissionSub.Identity,
|
||||
permission,
|
||||
permissionRole.permission
|
||||
);
|
||||
if (!permissionBoundary.isValid)
|
||||
throw new PermissionBoundaryError({
|
||||
message: constructPermissionErrorMessage(
|
||||
"Failed to create identity project membership",
|
||||
shouldUseNewPrivilegeSystem,
|
||||
ProjectPermissionIdentityActions.GrantPrivileges,
|
||||
ProjectPermissionSub.Identity
|
||||
),
|
||||
details: { missingPermissions: permissionBoundary.missingPermissions }
|
||||
});
|
||||
}
|
||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||
shouldUseNewPrivilegeSystem,
|
||||
ProjectPermissionIdentityActions.GrantPrivileges,
|
||||
ProjectPermissionSub.Identity,
|
||||
permission,
|
||||
permissionRole.permission
|
||||
);
|
||||
if (!permissionBoundary.isValid)
|
||||
throw new PermissionBoundaryError({
|
||||
message: constructPermissionErrorMessage(
|
||||
"Failed to create identity project membership",
|
||||
shouldUseNewPrivilegeSystem,
|
||||
ProjectPermissionIdentityActions.GrantPrivileges,
|
||||
ProjectPermissionSub.Identity
|
||||
),
|
||||
details: { missingPermissions: permissionBoundary.missingPermissions }
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ export const membershipUserDALFactory = (db: TDbClient) => {
|
||||
})
|
||||
.where(`${TableName.Membership}.scopeOrgId`, scopeData.orgId)
|
||||
.where(`${TableName.Membership}.actorUserId`, userId)
|
||||
.where(`${TableName.Users}.isGhost`, false)
|
||||
.where((qb) => {
|
||||
if (scopeData.scope === AccessScope.Organization) {
|
||||
void qb.where(`${TableName.Membership}.scope`, AccessScope.Organization);
|
||||
@@ -60,7 +61,9 @@ export const membershipUserDALFactory = (db: TDbClient) => {
|
||||
})
|
||||
.select(selectAllTableCols(TableName.Membership))
|
||||
.select(
|
||||
db.ref("slug").withSchema(TableName.Role).as("roleSlug"),
|
||||
db.ref("slug").withSchema(TableName.Role).as("customRoleSlug"),
|
||||
db.ref("name").withSchema(TableName.Role).as("customRoleName"),
|
||||
db.ref("id").withSchema(TableName.Role).as("customRoleId"),
|
||||
db.ref("id").withSchema(TableName.MembershipRole).as("membershipRoleId"),
|
||||
db.ref("role").withSchema(TableName.MembershipRole).as("membershipRole"),
|
||||
db.ref("temporaryMode").withSchema(TableName.MembershipRole).as("membershipRoleTemporaryMode"),
|
||||
@@ -78,19 +81,35 @@ export const membershipUserDALFactory = (db: TDbClient) => {
|
||||
db.ref("updatedAt").withSchema(TableName.MembershipRole).as("membershipRoleUpdatedAt"),
|
||||
db.ref("id").withSchema(TableName.IdentityMetadata).as("metadataId"),
|
||||
db.ref("key").withSchema(TableName.IdentityMetadata).as("metadataKey"),
|
||||
db.ref("value").withSchema(TableName.IdentityMetadata).as("metadataValue")
|
||||
db.ref("value").withSchema(TableName.IdentityMetadata).as("metadataValue"),
|
||||
db.ref("username").withSchema(TableName.Users).as("userUsername"),
|
||||
db.ref("email").withSchema(TableName.Users).as("userEmail"),
|
||||
db.ref("firstName").withSchema(TableName.Users).as("userFirstName"),
|
||||
db.ref("lastName").withSchema(TableName.Users).as("userLastName"),
|
||||
db.ref("id").withSchema(TableName.Users).as("userId")
|
||||
);
|
||||
|
||||
const data = sqlNestRelationships({
|
||||
data: docs,
|
||||
key: "id",
|
||||
parentMapper: (el) => MembershipsSchema.parse(el),
|
||||
parentMapper: (el) => ({
|
||||
...MembershipsSchema.parse(el),
|
||||
user: {
|
||||
username: el.userUsername,
|
||||
email: el.userEmail,
|
||||
firstName: el.userFirstName,
|
||||
lastName: el.userLastName,
|
||||
id: el.userId
|
||||
}
|
||||
}),
|
||||
childrenMapper: [
|
||||
{
|
||||
key: "membershipRoleId",
|
||||
label: "roles" as const,
|
||||
mapper: ({
|
||||
roleSlug,
|
||||
customRoleSlug,
|
||||
customRoleName,
|
||||
customRoleId,
|
||||
membershipRoleId,
|
||||
membershipRole,
|
||||
membershipRoleIsTemporary,
|
||||
@@ -103,7 +122,9 @@ export const membershipUserDALFactory = (db: TDbClient) => {
|
||||
}) => ({
|
||||
id: membershipRoleId,
|
||||
role: membershipRole,
|
||||
customRoleSlug: roleSlug,
|
||||
customRoleSlug,
|
||||
customRoleName,
|
||||
customRoleId,
|
||||
temporaryRange: membershipRoleTemporaryRange,
|
||||
temporaryMode: membershipRoleTemporaryMode,
|
||||
temporaryAccessStartTime: membershipRoleTemporaryAccessStartTime,
|
||||
@@ -140,6 +161,7 @@ export const membershipUserDALFactory = (db: TDbClient) => {
|
||||
.leftJoin(TableName.Role, `${TableName.MembershipRole}.customRoleId`, `${TableName.Role}.id`)
|
||||
.distinct(`${TableName.Membership}.id`)
|
||||
.where(`${TableName.Membership}.scopeOrgId`, scopeData.orgId)
|
||||
.where(`${TableName.Users}.isGhost`, false)
|
||||
.where((qb) => {
|
||||
if (scopeData.scope === AccessScope.Organization) {
|
||||
void qb.where(`${TableName.Membership}.scope`, AccessScope.Organization);
|
||||
@@ -188,7 +210,9 @@ export const membershipUserDALFactory = (db: TDbClient) => {
|
||||
.whereIn(`${TableName.Membership}.id`, paginatedUsers)
|
||||
.select(selectAllTableCols(TableName.Membership))
|
||||
.select(
|
||||
db.ref("slug").withSchema(TableName.Role).as("roleSlug"),
|
||||
db.ref("slug").withSchema(TableName.Role).as("customRoleSlug"),
|
||||
db.ref("name").withSchema(TableName.Role).as("customRoleName"),
|
||||
db.ref("id").withSchema(TableName.Role).as("customRoleId"),
|
||||
db.ref("id").withSchema(TableName.MembershipRole).as("membershipRoleId"),
|
||||
db.ref("role").withSchema(TableName.MembershipRole).as("membershipRole"),
|
||||
db.ref("temporaryMode").withSchema(TableName.MembershipRole).as("membershipRoleTemporaryMode"),
|
||||
@@ -203,7 +227,12 @@ export const membershipUserDALFactory = (db: TDbClient) => {
|
||||
.withSchema(TableName.MembershipRole)
|
||||
.as("membershipRoleTemporaryAccessEndTime"),
|
||||
db.ref("createdAt").withSchema(TableName.MembershipRole).as("membershipRoleCreatedAt"),
|
||||
db.ref("updatedAt").withSchema(TableName.MembershipRole).as("membershipRoleUpdatedAt")
|
||||
db.ref("updatedAt").withSchema(TableName.MembershipRole).as("membershipRoleUpdatedAt"),
|
||||
db.ref("username").withSchema(TableName.Users).as("userUsername"),
|
||||
db.ref("email").withSchema(TableName.Users).as("userEmail"),
|
||||
db.ref("firstName").withSchema(TableName.Users).as("userFirstName"),
|
||||
db.ref("lastName").withSchema(TableName.Users).as("userLastName"),
|
||||
db.ref("id").withSchema(TableName.Users).as("userId")
|
||||
)
|
||||
.select(
|
||||
db.raw(
|
||||
@@ -214,13 +243,24 @@ export const membershipUserDALFactory = (db: TDbClient) => {
|
||||
const data = sqlNestRelationships({
|
||||
data: docs,
|
||||
key: "id",
|
||||
parentMapper: (el) => MembershipsSchema.parse(el),
|
||||
parentMapper: (el) => ({
|
||||
...MembershipsSchema.parse(el),
|
||||
user: {
|
||||
username: el.userUsername,
|
||||
email: el.userEmail,
|
||||
firstName: el.userFirstName,
|
||||
lastName: el.userLastName,
|
||||
id: el.userId
|
||||
}
|
||||
}),
|
||||
childrenMapper: [
|
||||
{
|
||||
key: "membershipRoleId",
|
||||
label: "roles" as const,
|
||||
mapper: ({
|
||||
roleSlug,
|
||||
customRoleSlug,
|
||||
customRoleName,
|
||||
customRoleId,
|
||||
membershipRoleId,
|
||||
membershipRole,
|
||||
membershipRoleIsTemporary,
|
||||
@@ -233,7 +273,9 @@ export const membershipUserDALFactory = (db: TDbClient) => {
|
||||
}) => ({
|
||||
id: membershipRoleId,
|
||||
role: membershipRole,
|
||||
customRoleSlug: roleSlug,
|
||||
customRoleSlug,
|
||||
customRoleName,
|
||||
customRoleId,
|
||||
temporaryRange: membershipRoleTemporaryRange,
|
||||
temporaryMode: membershipRoleTemporaryMode,
|
||||
temporaryAccessStartTime: membershipRoleTemporaryAccessStartTime,
|
||||
|
||||
@@ -386,7 +386,7 @@ export const membershipUserServiceFactory = ({
|
||||
limit: dto.data.limit,
|
||||
offset: dto.data.offset,
|
||||
username: dto.data.username,
|
||||
role: dto.data.roles.length
|
||||
role: dto.data?.roles?.length
|
||||
? {
|
||||
[SearchResourceOperators.$in]: dto.data.roles
|
||||
}
|
||||
|
||||
@@ -55,14 +55,11 @@ export type TUpdateMembershipUserDTO = {
|
||||
export type TListMembershipUserDTO = {
|
||||
permission: OrgServiceActor;
|
||||
scopeData: AccessScopeData;
|
||||
selector: {
|
||||
actorId: string;
|
||||
};
|
||||
data: {
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
username?: string;
|
||||
roles: string[];
|
||||
roles?: string[];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -43,10 +43,7 @@ import {
|
||||
import { TProjectUserMembershipRoleDALFactory } from "./project-user-membership-role-dal";
|
||||
|
||||
type TProjectMembershipServiceFactoryDep = {
|
||||
permissionService: Pick<
|
||||
TPermissionServiceFactory,
|
||||
"getProjectPermission" | "getProjectPermissionByRole" | "invalidateProjectPermissionCache"
|
||||
>;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission" | "getProjectPermissionByRoles"| "invalidateProjectPermissionCache">;
|
||||
smtpService: TSmtpService;
|
||||
projectBotDAL: TProjectBotDALFactory;
|
||||
projectMembershipDAL: TProjectMembershipDALFactory;
|
||||
@@ -573,6 +570,8 @@ export const projectMembershipServiceFactory = ({
|
||||
tx
|
||||
);
|
||||
|
||||
// TODO(simp): likewise check in all services if i am missing anything
|
||||
// Deletion should handle all cleanups like wise
|
||||
await secretReminderRecipientsDAL.delete(
|
||||
{
|
||||
projectId,
|
||||
|
||||
@@ -2,6 +2,7 @@ import { AccessScope, TableName } from "@app/db/schemas";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars";
|
||||
import { unpackPermissions } from "@app/server/routes/sanitizedSchema/permission";
|
||||
|
||||
import { newNamespaceRoleFactory } from "./namespace/namespace-role-factory";
|
||||
import { newOrgRoleFactory } from "./org/org-role-factory";
|
||||
@@ -63,7 +64,7 @@ export const roleServiceFactory = ({ roleDAL, permissionService }: TRoleServiceF
|
||||
[scope.key]: scope.value
|
||||
});
|
||||
|
||||
return { ...role, [scope.key]: scope.value };
|
||||
return { ...role, [scope.key]: scope.value, permissions: unpackPermissions(role.permissions) };
|
||||
};
|
||||
|
||||
const updateRole = async (dto: TUpdateRoleDTO) => {
|
||||
@@ -99,7 +100,7 @@ export const roleServiceFactory = ({ roleDAL, permissionService }: TRoleServiceF
|
||||
permissions: data?.permissions
|
||||
});
|
||||
|
||||
return { ...role, [scope.key]: scope.value };
|
||||
return { ...role, [scope.key]: scope.value, permissions: unpackPermissions(role.permissions) };
|
||||
};
|
||||
|
||||
const deleteRole = async (dto: TDeleteRoleDTO) => {
|
||||
@@ -119,7 +120,7 @@ export const roleServiceFactory = ({ roleDAL, permissionService }: TRoleServiceF
|
||||
[scope.key]: scope.value
|
||||
});
|
||||
|
||||
return { ...role, [scope.key]: scope.value };
|
||||
return { ...role, [scope.key]: scope.value, permissions: unpackPermissions(role.permissions) };
|
||||
};
|
||||
|
||||
const listRoles = async (dto: TListRoleDTO) => {
|
||||
@@ -136,7 +137,7 @@ export const roleServiceFactory = ({ roleDAL, permissionService }: TRoleServiceF
|
||||
{ limit: dto.data.limit, offset: dto.data.offset, sort: [[`${TableName.Role}.slug` as "slug", "asc"]] }
|
||||
);
|
||||
|
||||
return { roles };
|
||||
return { roles: roles.map((el) => ({ ...el, permissions: unpackPermissions(el.permissions) })) };
|
||||
};
|
||||
|
||||
const getRoleById = async (dto: TGetRoleByIdDTO) => {
|
||||
@@ -152,7 +153,7 @@ export const roleServiceFactory = ({ roleDAL, permissionService }: TRoleServiceF
|
||||
});
|
||||
if (!role) throw new NotFoundError({ message: `Role with id ${dto.selector.id} not found` });
|
||||
|
||||
return { ...role, [scope.key]: scope.value };
|
||||
return { ...role, [scope.key]: scope.value, permissions: unpackPermissions(role.permissions) };
|
||||
};
|
||||
|
||||
const getRoleBySlug = async (dto: TGetRoleBySlugDTO) => {
|
||||
@@ -168,7 +169,7 @@ export const roleServiceFactory = ({ roleDAL, permissionService }: TRoleServiceF
|
||||
});
|
||||
if (!role) throw new NotFoundError({ message: `Role with slug ${dto.selector.slug} not found` });
|
||||
|
||||
return { ...role, [scope.key]: scope.value };
|
||||
return { ...role, [scope.key]: scope.value, permissions: unpackPermissions(role.permissions) };
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
@@ -16,7 +16,7 @@ export type TCreateRoleDTO = {
|
||||
scopeData: AccessScopeData;
|
||||
data: {
|
||||
name: string;
|
||||
description?: string;
|
||||
description?: string | null;
|
||||
slug: string;
|
||||
permissions: unknown;
|
||||
};
|
||||
@@ -30,7 +30,7 @@ export type TUpdateRoleDTO = {
|
||||
};
|
||||
data: Partial<{
|
||||
name: string;
|
||||
description?: string;
|
||||
description?: string | null;
|
||||
slug: string;
|
||||
permissions: unknown;
|
||||
}>;
|
||||
|
||||
@@ -76,6 +76,7 @@ export const useCreateOrgRole = () => {
|
||||
data: { role }
|
||||
} = await apiRequest.post(`/api/v1/organization/${orgId}/roles`, {
|
||||
...dto,
|
||||
// TODO(simp): removing packing
|
||||
permissions: permissions.length ? packRules(permissions) : []
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user