feat: move feature to org level

This commit is contained in:
ShubhamPalriwala
2024-05-28 23:40:50 +05:30
parent 3b40f37f50
commit f85a35fde8
16 changed files with 71 additions and 105 deletions

View File

@@ -21,6 +21,7 @@ export enum OrgPermissionSubjects {
Groups = "groups",
Billing = "billing",
SecretScanning = "secret-scanning",
SecretSharing = "secret-sharing",
Identity = "identity"
}
@@ -36,6 +37,7 @@ export type OrgPermissionSet =
| [OrgPermissionActions, OrgPermissionSubjects.Ldap]
| [OrgPermissionActions, OrgPermissionSubjects.Groups]
| [OrgPermissionActions, OrgPermissionSubjects.SecretScanning]
| [OrgPermissionActions, OrgPermissionSubjects.SecretSharing]
| [OrgPermissionActions, OrgPermissionSubjects.Billing]
| [OrgPermissionActions, OrgPermissionSubjects.Identity];
@@ -60,6 +62,10 @@ const buildAdminPermission = () => {
can(OrgPermissionActions.Edit, OrgPermissionSubjects.SecretScanning);
can(OrgPermissionActions.Delete, OrgPermissionSubjects.SecretScanning);
can(OrgPermissionActions.Read, OrgPermissionSubjects.SecretSharing);
can(OrgPermissionActions.Create, OrgPermissionSubjects.SecretSharing);
can(OrgPermissionActions.Delete, OrgPermissionSubjects.SecretSharing);
can(OrgPermissionActions.Read, OrgPermissionSubjects.Settings);
can(OrgPermissionActions.Create, OrgPermissionSubjects.Settings);
can(OrgPermissionActions.Edit, OrgPermissionSubjects.Settings);
@@ -124,6 +130,10 @@ const buildMemberPermission = () => {
can(OrgPermissionActions.Edit, OrgPermissionSubjects.SecretScanning);
can(OrgPermissionActions.Delete, OrgPermissionSubjects.SecretScanning);
can(OrgPermissionActions.Read, OrgPermissionSubjects.SecretSharing);
can(OrgPermissionActions.Create, OrgPermissionSubjects.SecretSharing);
can(OrgPermissionActions.Delete, OrgPermissionSubjects.SecretSharing);
can(OrgPermissionActions.Read, OrgPermissionSubjects.Identity);
can(OrgPermissionActions.Create, OrgPermissionSubjects.Identity);
can(OrgPermissionActions.Edit, OrgPermissionSubjects.Identity);

View File

@@ -26,7 +26,6 @@ export enum ProjectPermissionSub {
SecretRollback = "secret-rollback",
SecretApproval = "secret-approval",
SecretRotation = "secret-rotation",
SecretSharing = "secret-sharing",
Identity = "identity"
}
@@ -53,7 +52,6 @@ export type ProjectPermissionSet =
| [ProjectPermissionActions, ProjectPermissionSub.ServiceTokens]
| [ProjectPermissionActions, ProjectPermissionSub.SecretApproval]
| [ProjectPermissionActions, ProjectPermissionSub.SecretRotation]
| [ProjectPermissionActions, ProjectPermissionSub.SecretSharing]
| [ProjectPermissionActions, ProjectPermissionSub.Identity]
| [ProjectPermissionActions.Delete, ProjectPermissionSub.Project]
| [ProjectPermissionActions.Edit, ProjectPermissionSub.Project]
@@ -73,10 +71,6 @@ const buildAdminPermissionRules = () => {
can(ProjectPermissionActions.Edit, ProjectPermissionSub.SecretApproval);
can(ProjectPermissionActions.Delete, ProjectPermissionSub.SecretApproval);
can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretSharing);
can(ProjectPermissionActions.Create, ProjectPermissionSub.SecretSharing);
can(ProjectPermissionActions.Delete, ProjectPermissionSub.SecretSharing);
can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRotation);
can(ProjectPermissionActions.Create, ProjectPermissionSub.SecretRotation);
can(ProjectPermissionActions.Edit, ProjectPermissionSub.SecretRotation);
@@ -164,10 +158,6 @@ const buildMemberPermissionRules = () => {
can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval);
can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRotation);
can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretSharing);
can(ProjectPermissionActions.Create, ProjectPermissionSub.SecretSharing);
can(ProjectPermissionActions.Delete, ProjectPermissionSub.SecretSharing);
can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
can(ProjectPermissionActions.Create, ProjectPermissionSub.SecretRollback);
@@ -227,7 +217,6 @@ const buildViewerPermissionRules = () => {
can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval);
can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRotation);
can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretSharing);
can(ProjectPermissionActions.Read, ProjectPermissionSub.Member);
can(ProjectPermissionActions.Read, ProjectPermissionSub.Groups);
can(ProjectPermissionActions.Read, ProjectPermissionSub.Role);

View File

@@ -201,8 +201,6 @@ export const registerRoutes = async (
const secretVersionTagDAL = secretVersionTagDALFactory(db);
const secretBlindIndexDAL = secretBlindIndexDALFactory(db);
const secretSharingDAL = secretSharingDALFactory(db);
const integrationDAL = integrationDALFactory(db);
const integrationAuthDAL = integrationAuthDALFactory(db);
const webhookDAL = webhookDALFactory(db);
@@ -257,6 +255,7 @@ export const registerRoutes = async (
const groupProjectMembershipRoleDAL = groupProjectMembershipRoleDALFactory(db);
const userGroupMembershipDAL = userGroupMembershipDALFactory(db);
const secretScanningDAL = secretScanningDALFactory(db);
const secretSharingDAL = secretSharingDALFactory(db);
const licenseDAL = licenseDALFactory(db);
const dynamicSecretDAL = dynamicSecretDALFactory(db);
const dynamicSecretLeaseDAL = dynamicSecretLeaseDALFactory(db);

View File

@@ -8,25 +8,21 @@ import { AuthMode } from "@app/services/auth/auth-type";
export const registerSecretSharingRouter = async (server: FastifyZodProvider) => {
server.route({
method: "GET",
url: "/:projectId",
url: "/",
config: {
rateLimit: readLimit
},
schema: {
params: z.object({
projectId: z.string().uuid()
}),
response: {
200: z.array(SecretSharingSchema)
}
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const { projectId } = req.params;
const sharedSecrets = await req.server.services.secretSharing.getSharedSecrets({
actor: req.permission.type,
actorId: req.permission.id,
projectId,
orgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId
});
@@ -72,8 +68,7 @@ export const registerSecretSharingRouter = async (server: FastifyZodProvider) =>
signedValue: z.string(),
expiresAt: z.string().refine((date) => new Date(date) > new Date(), {
message: "Expires at should be a future date"
}),
workspaceId: z.string().uuid()
})
}),
response: {
200: z.object({
@@ -83,11 +78,11 @@ export const registerSecretSharingRouter = async (server: FastifyZodProvider) =>
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const { name, signedValue, expiresAt, workspaceId } = req.body;
const { name, signedValue, expiresAt } = req.body;
const sharedSecret = await req.server.services.secretSharing.createSharedSecret({
actor: req.permission.type,
actorId: req.permission.id,
projectId: workspaceId,
orgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
name,
@@ -100,13 +95,12 @@ export const registerSecretSharingRouter = async (server: FastifyZodProvider) =>
server.route({
method: "DELETE",
url: "/:projectId/:sharedSecretId",
url: "/:sharedSecretId",
config: {
rateLimit: writeLimit
},
schema: {
params: z.object({
projectId: z.string().uuid(),
sharedSecretId: z.string().uuid()
}),
response: {
@@ -115,11 +109,11 @@ export const registerSecretSharingRouter = async (server: FastifyZodProvider) =>
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const { projectId, sharedSecretId } = req.params;
const { sharedSecretId } = req.params;
const deletedSharedSecret = await req.server.services.secretSharing.deleteSharedSecretById({
actor: req.permission.type,
actorId: req.permission.id,
projectId,
orgId: req.permission.orgId,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
sharedSecretId

View File

@@ -1,13 +1,13 @@
import { ForbiddenError } from "@casl/ability";
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
import { TSecretSharingDALFactory } from "./secret-sharing-dal";
import { TCreateSharedSecretDTO, TDeleteSharedSecretDTO, TSharedSecretPermission } from "./secret-sharing-types";
type TSecretSharingServiceFactoryDep = {
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
secretSharingDAL: TSecretSharingDALFactory;
};
@@ -18,16 +18,10 @@ export const secretSharingServiceFactory = ({
secretSharingDAL
}: TSecretSharingServiceFactoryDep) => {
const createSharedSecret = async (createSharedSecretInput: TCreateSharedSecretDTO) => {
const { actor, actorId, projectId, actorAuthMethod, actorOrgId, name, signedValue, expiresAt } =
const { actor, actorId, orgId, actorAuthMethod, actorOrgId, name, signedValue, expiresAt } =
createSharedSecretInput;
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.SecretSharing);
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.SecretSharing);
const newSharedSecret = await secretSharingDAL.create({
name,
signedValue,
@@ -38,15 +32,9 @@ export const secretSharingServiceFactory = ({
};
const getSharedSecrets = async (getSharedSecretsInput: TSharedSecretPermission) => {
const { actor, actorId, projectId, actorAuthMethod, actorOrgId } = getSharedSecretsInput;
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretSharing);
const { actor, actorId, orgId, actorAuthMethod, actorOrgId } = getSharedSecretsInput;
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.SecretSharing);
const userSharedSecrets = await secretSharingDAL.find({ userId: actorId }, { sort: [["expiresAt", "asc"]] });
return userSharedSecrets;
};
@@ -60,15 +48,9 @@ export const secretSharingServiceFactory = ({
};
const deleteSharedSecretById = async (deleteSharedSecretInput: TDeleteSharedSecretDTO) => {
const { actor, actorId, projectId, actorAuthMethod, actorOrgId, sharedSecretId } = deleteSharedSecretInput;
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.SecretSharing);
const { actor, actorId, orgId, actorAuthMethod, actorOrgId, sharedSecretId } = deleteSharedSecretInput;
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.SecretSharing);
const deletedSharedSecret = await secretSharingDAL.deleteById(sharedSecretId);
return deletedSharedSecret;
};

View File

@@ -5,7 +5,7 @@ export type TSharedSecretPermission = {
actorId: string;
actorAuthMethod: ActorAuthMethod;
actorOrgId: string;
projectId: string;
orgId: string;
};
export type TCreateSharedSecretDTO = {