mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 15:27:46 +00:00
feat: resolved all missing things
This commit is contained in:
@@ -127,7 +127,8 @@ export async function down(knex: Knex): Promise<void> {
|
|||||||
});
|
});
|
||||||
await knex.schema.alterTable(TableName.SecretApprovalPolicyApprover, (tb) => {
|
await knex.schema.alterTable(TableName.SecretApprovalPolicyApprover, (tb) => {
|
||||||
tb.dropColumn("approverUserId");
|
tb.dropColumn("approverUserId");
|
||||||
tb.uuid("approverId").notNullable().alter();
|
// akhilmhdh: i had to comment this out and is not possible as membership is now changed in structure
|
||||||
|
// tb.uuid("approverId").notNullable().alter();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,9 @@ import { selectAllTableCols, sqlNestRelationships } from "@app/lib/knex";
|
|||||||
import { ActorType } from "@app/services/auth/auth-type";
|
import { ActorType } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
interface TPermissionDataReturn extends TMemberships {
|
interface TPermissionDataReturn extends TMemberships {
|
||||||
|
orgAuthEnforced?: boolean | null;
|
||||||
|
orgGoogleSsoAuthEnforced?: boolean | null;
|
||||||
|
bypassOrgAuthEnabled?: boolean | null;
|
||||||
roles: {
|
roles: {
|
||||||
id: string;
|
id: string;
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
@@ -177,6 +180,7 @@ export const permissionDALFactory = (db: TDbClient): TPermissionDALFactory => {
|
|||||||
const docs = await (tx || db)
|
const docs = await (tx || db)
|
||||||
.replicaNode()(TableName.Membership)
|
.replicaNode()(TableName.Membership)
|
||||||
.join(TableName.MembershipRole, `${TableName.Membership}.id`, `${TableName.MembershipRole}.membershipId`)
|
.join(TableName.MembershipRole, `${TableName.Membership}.id`, `${TableName.MembershipRole}.membershipId`)
|
||||||
|
.join(TableName.Organization, `${TableName.Membership}.scopeOrgId`, `${TableName.Organization}.id`)
|
||||||
.leftJoin(TableName.Role, `${TableName.MembershipRole}.customRoleId`, `${TableName.Role}.id`)
|
.leftJoin(TableName.Role, `${TableName.MembershipRole}.customRoleId`, `${TableName.Role}.id`)
|
||||||
.leftJoin(TableName.AdditionalPrivilege, (qb) => {
|
.leftJoin(TableName.AdditionalPrivilege, (qb) => {
|
||||||
if (actorType === ActorType.IDENTITY) {
|
if (actorType === ActorType.IDENTITY) {
|
||||||
@@ -264,13 +268,22 @@ export const permissionDALFactory = (db: TDbClient): TPermissionDALFactory => {
|
|||||||
db.ref("updatedAt").withSchema(TableName.AdditionalPrivilege).as("additionalPrivilegeUpdatedAt"),
|
db.ref("updatedAt").withSchema(TableName.AdditionalPrivilege).as("additionalPrivilegeUpdatedAt"),
|
||||||
db.ref("id").withSchema(TableName.IdentityMetadata).as("metadataId"),
|
db.ref("id").withSchema(TableName.IdentityMetadata).as("metadataId"),
|
||||||
db.ref("key").withSchema(TableName.IdentityMetadata).as("metadataKey"),
|
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("shouldUseNewPrivilegeSystem").withSchema(TableName.Organization),
|
||||||
|
db.ref("authEnforced").withSchema(TableName.Organization).as("orgAuthEnforced"),
|
||||||
|
db.ref("googleSsoAuthEnforced").withSchema(TableName.Organization).as("orgGoogleSsoAuthEnforced"),
|
||||||
|
db.ref("bypassOrgAuthEnabled").withSchema(TableName.Organization).as("bypassOrgAuthEnabled")
|
||||||
);
|
);
|
||||||
|
|
||||||
const data = sqlNestRelationships({
|
const data = sqlNestRelationships({
|
||||||
data: docs,
|
data: docs,
|
||||||
key: "id",
|
key: "id",
|
||||||
parentMapper: (el) => MembershipsSchema.parse(el),
|
parentMapper: (el) =>
|
||||||
|
MembershipsSchema.extend({
|
||||||
|
orgAuthEnforced: z.boolean().optional().nullable(),
|
||||||
|
orgGoogleSsoAuthEnforced: z.boolean(),
|
||||||
|
bypassOrgAuthEnabled: z.boolean()
|
||||||
|
}).parse(el),
|
||||||
childrenMapper: [
|
childrenMapper: [
|
||||||
{
|
{
|
||||||
key: "additionalPrivilegeId",
|
key: "additionalPrivilegeId",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { ForbiddenError, MongoAbility, PureAbility, subject } from "@casl/ability";
|
import { ForbiddenError, MongoAbility, PureAbility, subject } from "@casl/ability";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { OrgMembershipRole, TOrganizations } from "@app/db/schemas";
|
import { TOrganizations } from "@app/db/schemas";
|
||||||
import { validatePermissionBoundary } from "@app/lib/casl/boundary";
|
import { validatePermissionBoundary } from "@app/lib/casl/boundary";
|
||||||
import { BadRequestError, ForbiddenRequestError, UnauthorizedError } from "@app/lib/errors";
|
import { BadRequestError, ForbiddenRequestError, UnauthorizedError } from "@app/lib/errors";
|
||||||
import { ActorAuthMethod, AuthMethod } from "@app/services/auth/auth-type";
|
import { ActorAuthMethod, AuthMethod } from "@app/services/auth/auth-type";
|
||||||
@@ -123,13 +123,13 @@ function validateOrgSSO(
|
|||||||
isOrgSsoEnforced: TOrganizations["authEnforced"],
|
isOrgSsoEnforced: TOrganizations["authEnforced"],
|
||||||
isOrgGoogleSsoEnforced: TOrganizations["googleSsoAuthEnforced"],
|
isOrgGoogleSsoEnforced: TOrganizations["googleSsoAuthEnforced"],
|
||||||
isOrgSsoBypassEnabled: TOrganizations["bypassOrgAuthEnabled"],
|
isOrgSsoBypassEnabled: TOrganizations["bypassOrgAuthEnabled"],
|
||||||
orgRole: OrgMembershipRole
|
isAdmin: boolean
|
||||||
) {
|
) {
|
||||||
if (actorAuthMethod === undefined) {
|
if (actorAuthMethod === undefined) {
|
||||||
throw new UnauthorizedError({ name: "No auth method defined" });
|
throw new UnauthorizedError({ name: "No auth method defined" });
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((isOrgSsoEnforced || isOrgGoogleSsoEnforced) && isOrgSsoBypassEnabled && orgRole === OrgMembershipRole.Admin) {
|
if ((isOrgSsoEnforced || isOrgGoogleSsoEnforced) && isOrgSsoBypassEnabled && isAdmin) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import { TUserDALFactory } from "@app/services/user/user-dal";
|
|||||||
|
|
||||||
import { orgAdminPermissions, orgMemberPermissions, orgNoAccessPermissions, OrgPermissionSet } from "./org-permission";
|
import { orgAdminPermissions, orgMemberPermissions, orgNoAccessPermissions, OrgPermissionSet } from "./org-permission";
|
||||||
import { TPermissionDALFactory } from "./permission-dal";
|
import { TPermissionDALFactory } from "./permission-dal";
|
||||||
import { escapeHandlebarsMissingDict } from "./permission-fns";
|
import { escapeHandlebarsMissingDict, validateOrgSSO } from "./permission-fns";
|
||||||
import {
|
import {
|
||||||
TBuildOrgPermissionDTO,
|
TBuildOrgPermissionDTO,
|
||||||
TBuildProjectPermissionDTO,
|
TBuildProjectPermissionDTO,
|
||||||
@@ -223,24 +223,25 @@ export const permissionServiceFactory = ({
|
|||||||
return activeRoles.concat(activeAdditionalPrivileges);
|
return activeRoles.concat(activeAdditionalPrivileges);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const hasRole = (role: string) =>
|
||||||
|
permissionData.some((memberships) => memberships.roles.some((el) => role === (el.customRoleSlug || el.role)));
|
||||||
|
|
||||||
|
validateOrgSSO(
|
||||||
|
authMethod,
|
||||||
|
permissionData?.[0].orgAuthEnforced,
|
||||||
|
Boolean(permissionData?.[0].orgGoogleSsoAuthEnforced),
|
||||||
|
Boolean(permissionData?.[0].bypassOrgAuthEnabled),
|
||||||
|
hasRole(OrgMembershipRole.Admin)
|
||||||
|
);
|
||||||
|
|
||||||
const permission = createMongoAbility<OrgPermissionSet>(buildOrgPermissionRules(permissionFromRoles), {
|
const permission = createMongoAbility<OrgPermissionSet>(buildOrgPermissionRules(permissionFromRoles), {
|
||||||
conditionsMatcher
|
conditionsMatcher
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO(simp): validate this
|
|
||||||
// validateOrgSSO(
|
|
||||||
// authMethod,
|
|
||||||
// membership.orgAuthEnforced,
|
|
||||||
// membership.orgGoogleSsoAuthEnforced,
|
|
||||||
// membership.bypassOrgAuthEnabled,
|
|
||||||
// membership.role as OrgMembershipRole
|
|
||||||
// );
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
permission,
|
permission,
|
||||||
memberships: permissionData,
|
memberships: permissionData,
|
||||||
hasRole: (role: string) =>
|
hasRole
|
||||||
permissionData.some((memberships) => memberships.roles.some((el) => role === (el.customRoleSlug || el.role)))
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -367,13 +368,16 @@ export const permissionServiceFactory = ({
|
|||||||
return activeRoles.concat(activeAdditionalPrivileges);
|
return activeRoles.concat(activeAdditionalPrivileges);
|
||||||
});
|
});
|
||||||
|
|
||||||
// validateOrgSSO(
|
const hasRole = (role: string) =>
|
||||||
// authMethod,
|
permissionData.some((memberships) => memberships.roles.some((el) => role === (el.customRoleSlug || el.role)));
|
||||||
// userProjectPermission.orgAuthEnforced,
|
|
||||||
// userProjectPermission.orgGoogleSsoAuthEnforced,
|
validateOrgSSO(
|
||||||
// userProjectPermission.bypassOrgAuthEnabled,
|
actorAuthMethod,
|
||||||
// userProjectPermission.orgRole
|
permissionData?.[0].orgAuthEnforced,
|
||||||
// );
|
Boolean(permissionData?.[0].orgGoogleSsoAuthEnforced),
|
||||||
|
Boolean(permissionData?.[0].bypassOrgAuthEnabled),
|
||||||
|
hasRole(ProjectMembershipRole.Admin)
|
||||||
|
);
|
||||||
|
|
||||||
const rules = buildProjectPermissionRules(permissionFromRoles);
|
const rules = buildProjectPermissionRules(permissionFromRoles);
|
||||||
const templatedRules = handlebars.compile(JSON.stringify(rules), { data: false });
|
const templatedRules = handlebars.compile(JSON.stringify(rules), { data: false });
|
||||||
@@ -422,8 +426,7 @@ export const permissionServiceFactory = ({
|
|||||||
return {
|
return {
|
||||||
permission,
|
permission,
|
||||||
memberships: permissionData,
|
memberships: permissionData,
|
||||||
hasRole: (role: string) =>
|
hasRole
|
||||||
permissionData.some((memberships) => memberships.roles.some((el) => role === (el.customRoleSlug || el.role)))
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import { getConfig } from "@app/lib/config/env";
|
|||||||
import { crypto } from "@app/lib/crypto";
|
import { crypto } from "@app/lib/crypto";
|
||||||
import { BadRequestError, NotFoundError, ScimRequestError, UnauthorizedError } from "@app/lib/errors";
|
import { BadRequestError, NotFoundError, ScimRequestError, UnauthorizedError } from "@app/lib/errors";
|
||||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||||
|
import { TAdditionalPrivilegeDALFactory } from "@app/services/additional-privilege/additional-privilege-dal";
|
||||||
import { AuthTokenType } from "@app/services/auth/auth-type";
|
import { AuthTokenType } from "@app/services/auth/auth-type";
|
||||||
import { TExternalGroupOrgRoleMappingDALFactory } from "@app/services/external-group-org-role-mapping/external-group-org-role-mapping-dal";
|
import { TExternalGroupOrgRoleMappingDALFactory } from "@app/services/external-group-org-role-mapping/external-group-org-role-mapping-dal";
|
||||||
import { TMembershipRoleDALFactory } from "@app/services/membership/membership-role-dal";
|
import { TMembershipRoleDALFactory } from "@app/services/membership/membership-role-dal";
|
||||||
@@ -93,6 +94,7 @@ type TScimServiceFactoryDep = {
|
|||||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
||||||
smtpService: Pick<TSmtpService, "sendMail">;
|
smtpService: Pick<TSmtpService, "sendMail">;
|
||||||
externalGroupOrgRoleMappingDAL: TExternalGroupOrgRoleMappingDALFactory;
|
externalGroupOrgRoleMappingDAL: TExternalGroupOrgRoleMappingDALFactory;
|
||||||
|
additionalPrivilegeDAL: TAdditionalPrivilegeDALFactory;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const scimServiceFactory = ({
|
export const scimServiceFactory = ({
|
||||||
@@ -111,7 +113,8 @@ export const scimServiceFactory = ({
|
|||||||
externalGroupOrgRoleMappingDAL,
|
externalGroupOrgRoleMappingDAL,
|
||||||
membershipGroupDAL,
|
membershipGroupDAL,
|
||||||
membershipUserDAL,
|
membershipUserDAL,
|
||||||
membershipRoleDAL
|
membershipRoleDAL,
|
||||||
|
additionalPrivilegeDAL
|
||||||
}: TScimServiceFactoryDep): TScimServiceFactory => {
|
}: TScimServiceFactoryDep): TScimServiceFactory => {
|
||||||
const createScimToken: TScimServiceFactory["createScimToken"] = async ({
|
const createScimToken: TScimServiceFactory["createScimToken"] = async ({
|
||||||
actor,
|
actor,
|
||||||
@@ -673,7 +676,8 @@ export const scimServiceFactory = ({
|
|||||||
licenseService,
|
licenseService,
|
||||||
membershipUserDAL,
|
membershipUserDAL,
|
||||||
membershipRoleDAL,
|
membershipRoleDAL,
|
||||||
userGroupMembershipDAL
|
userGroupMembershipDAL,
|
||||||
|
additionalPrivilegeDAL
|
||||||
});
|
});
|
||||||
|
|
||||||
return {}; // intentionally return empty object upon success
|
return {}; // intentionally return empty object upon success
|
||||||
|
|||||||
@@ -575,7 +575,8 @@ export const registerRoutes = async (
|
|||||||
smtpService,
|
smtpService,
|
||||||
tokenService,
|
tokenService,
|
||||||
userAliasDAL,
|
userAliasDAL,
|
||||||
userGroupMembershipDAL
|
userGroupMembershipDAL,
|
||||||
|
additionalPrivilegeDAL
|
||||||
});
|
});
|
||||||
|
|
||||||
const membershipIdentityService = membershipIdentityServiceFactory({
|
const membershipIdentityService = membershipIdentityServiceFactory({
|
||||||
@@ -583,7 +584,8 @@ export const registerRoutes = async (
|
|||||||
membershipRoleDAL,
|
membershipRoleDAL,
|
||||||
orgDAL,
|
orgDAL,
|
||||||
permissionService,
|
permissionService,
|
||||||
roleDAL
|
roleDAL,
|
||||||
|
additionalPrivilegeDAL
|
||||||
});
|
});
|
||||||
|
|
||||||
const membershipGroupService = membershipGroupServiceFactory({
|
const membershipGroupService = membershipGroupServiceFactory({
|
||||||
@@ -599,7 +601,8 @@ export const registerRoutes = async (
|
|||||||
roleDAL,
|
roleDAL,
|
||||||
projectDAL,
|
projectDAL,
|
||||||
identityDAL,
|
identityDAL,
|
||||||
userDAL
|
userDAL,
|
||||||
|
externalGroupOrgRoleMappingDAL
|
||||||
});
|
});
|
||||||
const additionalPrivilegeService = additionalPrivilegeServiceFactory({
|
const additionalPrivilegeService = additionalPrivilegeServiceFactory({
|
||||||
additionalPrivilegeDAL,
|
additionalPrivilegeDAL,
|
||||||
@@ -764,7 +767,8 @@ export const registerRoutes = async (
|
|||||||
groupDAL,
|
groupDAL,
|
||||||
membershipGroupDAL,
|
membershipGroupDAL,
|
||||||
membershipRoleDAL,
|
membershipRoleDAL,
|
||||||
membershipUserDAL
|
membershipUserDAL,
|
||||||
|
additionalPrivilegeDAL
|
||||||
});
|
});
|
||||||
|
|
||||||
const githubOrgSyncConfigService = githubOrgSyncServiceFactory({
|
const githubOrgSyncConfigService = githubOrgSyncServiceFactory({
|
||||||
@@ -891,7 +895,8 @@ export const registerRoutes = async (
|
|||||||
membershipRoleDAL,
|
membershipRoleDAL,
|
||||||
membershipUserDAL,
|
membershipUserDAL,
|
||||||
roleDAL,
|
roleDAL,
|
||||||
userGroupMembershipDAL
|
userGroupMembershipDAL,
|
||||||
|
additionalPrivilegeDAL
|
||||||
});
|
});
|
||||||
const signupService = authSignupServiceFactory({
|
const signupService = authSignupServiceFactory({
|
||||||
tokenService,
|
tokenService,
|
||||||
|
|||||||
@@ -161,7 +161,6 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO(simp): look into multi deletion and this as well
|
|
||||||
server.route({
|
server.route({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
url: "/:projectId/memberships/details",
|
url: "/:projectId/memberships/details",
|
||||||
|
|||||||
@@ -273,7 +273,7 @@ export const identityServiceFactory = ({
|
|||||||
);
|
);
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
||||||
|
|
||||||
// TODO(simp): check this in identity service
|
// TODO(namespace): check this in identity service
|
||||||
const activeLockouts = await keyStore.getKeysByPattern(`lockout:identity:${id}:*`);
|
const activeLockouts = await keyStore.getKeysByPattern(`lockout:identity:${id}:*`);
|
||||||
|
|
||||||
const activeLockoutAuthMethods = new Set<string>();
|
const activeLockoutAuthMethods = new Set<string>();
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { groupBy } from "@app/lib/fn";
|
|||||||
import { ms } from "@app/lib/ms";
|
import { ms } from "@app/lib/ms";
|
||||||
import { SearchResourceOperators } from "@app/lib/search-resource/search";
|
import { SearchResourceOperators } from "@app/lib/search-resource/search";
|
||||||
|
|
||||||
|
import { TAdditionalPrivilegeDALFactory } from "../additional-privilege/additional-privilege-dal";
|
||||||
import { TMembershipRoleDALFactory } from "../membership/membership-role-dal";
|
import { TMembershipRoleDALFactory } from "../membership/membership-role-dal";
|
||||||
import { TOrgDALFactory } from "../org/org-dal";
|
import { TOrgDALFactory } from "../org/org-dal";
|
||||||
import { TRoleDALFactory } from "../role/role-dal";
|
import { TRoleDALFactory } from "../role/role-dal";
|
||||||
@@ -29,6 +30,7 @@ type TMembershipIdentityServiceFactoryDep = {
|
|||||||
"getOrgPermission" | "getProjectPermission" | "getProjectPermissionByRoles" | "getOrgPermissionByRoles"
|
"getOrgPermission" | "getProjectPermission" | "getProjectPermissionByRoles" | "getOrgPermissionByRoles"
|
||||||
>;
|
>;
|
||||||
orgDAL: Pick<TOrgDALFactory, "findById">;
|
orgDAL: Pick<TOrgDALFactory, "findById">;
|
||||||
|
additionalPrivilegeDAL: Pick<TAdditionalPrivilegeDALFactory, "delete">;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TMembershipIdentityServiceFactory = ReturnType<typeof membershipIdentityServiceFactory>;
|
export type TMembershipIdentityServiceFactory = ReturnType<typeof membershipIdentityServiceFactory>;
|
||||||
@@ -38,7 +40,8 @@ export const membershipIdentityServiceFactory = ({
|
|||||||
roleDAL,
|
roleDAL,
|
||||||
membershipRoleDAL,
|
membershipRoleDAL,
|
||||||
permissionService,
|
permissionService,
|
||||||
orgDAL
|
orgDAL,
|
||||||
|
additionalPrivilegeDAL
|
||||||
}: TMembershipIdentityServiceFactoryDep) => {
|
}: TMembershipIdentityServiceFactoryDep) => {
|
||||||
const scopeFactory = {
|
const scopeFactory = {
|
||||||
[AccessScope.Organization]: newOrgMembershipIdentityFactory({
|
[AccessScope.Organization]: newOrgMembershipIdentityFactory({
|
||||||
@@ -255,6 +258,7 @@ export const membershipIdentityServiceFactory = ({
|
|||||||
|
|
||||||
await factory.onDeleteMembershipIdentityGuard(dto);
|
await factory.onDeleteMembershipIdentityGuard(dto);
|
||||||
|
|
||||||
|
const scopeField = factory.getScopeField(scopeData);
|
||||||
const scopeDatabaseFields = factory.getScopeDatabaseFields(dto.scopeData);
|
const scopeDatabaseFields = factory.getScopeDatabaseFields(dto.scopeData);
|
||||||
const existingMembership = await membershipIdentityDAL.findOne({
|
const existingMembership = await membershipIdentityDAL.findOne({
|
||||||
scope: scopeData.scope,
|
scope: scopeData.scope,
|
||||||
@@ -272,6 +276,13 @@ export const membershipIdentityServiceFactory = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const membershipDoc = await membershipIdentityDAL.transaction(async (tx) => {
|
const membershipDoc = await membershipIdentityDAL.transaction(async (tx) => {
|
||||||
|
await additionalPrivilegeDAL.delete(
|
||||||
|
{
|
||||||
|
actorIdentityId: dto.selector.identityId,
|
||||||
|
[scopeField.key]: scopeField.value
|
||||||
|
},
|
||||||
|
tx
|
||||||
|
);
|
||||||
await membershipRoleDAL.delete({ membershipId: existingMembership.id }, tx);
|
await membershipRoleDAL.delete({ membershipId: existingMembership.id }, tx);
|
||||||
const doc = await membershipIdentityDAL.deleteById(existingMembership.id, tx);
|
const doc = await membershipIdentityDAL.deleteById(existingMembership.id, tx);
|
||||||
return doc;
|
return doc;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { groupBy } from "@app/lib/fn";
|
|||||||
import { ms } from "@app/lib/ms";
|
import { ms } from "@app/lib/ms";
|
||||||
import { SearchResourceOperators } from "@app/lib/search-resource/search";
|
import { SearchResourceOperators } from "@app/lib/search-resource/search";
|
||||||
|
|
||||||
|
import { TAdditionalPrivilegeDALFactory } from "../additional-privilege/additional-privilege-dal";
|
||||||
import { AuthMethod } from "../auth/auth-type";
|
import { AuthMethod } from "../auth/auth-type";
|
||||||
import { TAuthTokenServiceFactory } from "../auth-token/auth-token-service";
|
import { TAuthTokenServiceFactory } from "../auth-token/auth-token-service";
|
||||||
import { TMembershipRoleDALFactory } from "../membership/membership-role-dal";
|
import { TMembershipRoleDALFactory } from "../membership/membership-role-dal";
|
||||||
@@ -53,6 +54,7 @@ type TMembershipUserServiceFactoryDep = {
|
|||||||
tokenService: TAuthTokenServiceFactory;
|
tokenService: TAuthTokenServiceFactory;
|
||||||
userGroupMembershipDAL: TUserGroupMembershipDALFactory;
|
userGroupMembershipDAL: TUserGroupMembershipDALFactory;
|
||||||
projectDAL: TProjectDALFactory;
|
projectDAL: TProjectDALFactory;
|
||||||
|
additionalPrivilegeDAL: TAdditionalPrivilegeDALFactory;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TMembershipUserServiceFactory = ReturnType<typeof membershipUserServiceFactory>;
|
export type TMembershipUserServiceFactory = ReturnType<typeof membershipUserServiceFactory>;
|
||||||
@@ -70,7 +72,8 @@ export const membershipUserServiceFactory = ({
|
|||||||
smtpService,
|
smtpService,
|
||||||
tokenService,
|
tokenService,
|
||||||
userGroupMembershipDAL,
|
userGroupMembershipDAL,
|
||||||
projectDAL
|
projectDAL,
|
||||||
|
additionalPrivilegeDAL
|
||||||
}: TMembershipUserServiceFactoryDep) => {
|
}: TMembershipUserServiceFactoryDep) => {
|
||||||
const scopeFactory = {
|
const scopeFactory = {
|
||||||
[AccessScope.Organization]: newOrgMembershipUserFactory({
|
[AccessScope.Organization]: newOrgMembershipUserFactory({
|
||||||
@@ -410,11 +413,22 @@ export const membershipUserServiceFactory = ({
|
|||||||
userId: dto.permission.id,
|
userId: dto.permission.id,
|
||||||
membershipUserDAL,
|
membershipUserDAL,
|
||||||
userGroupMembershipDAL,
|
userGroupMembershipDAL,
|
||||||
membershipRoleDAL
|
membershipRoleDAL,
|
||||||
|
additionalPrivilegeDAL
|
||||||
});
|
});
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dto.scopeData.scope === AccessScope.Project) {
|
||||||
|
await additionalPrivilegeDAL.delete(
|
||||||
|
{
|
||||||
|
actorUserId: dto.selector.userId,
|
||||||
|
projectId: dto.scopeData.projectId
|
||||||
|
},
|
||||||
|
tx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
await membershipRoleDAL.delete({ membershipId: existingMembership.id }, tx);
|
await membershipRoleDAL.delete({ membershipId: existingMembership.id }, tx);
|
||||||
const doc = await membershipUserDAL.deleteById(existingMembership.id, tx);
|
const doc = await membershipUserDAL.deleteById(existingMembership.id, tx);
|
||||||
return doc;
|
return doc;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { TOrgDALFactory } from "@app/services/org/org-dal";
|
|||||||
import { TProjectKeyDALFactory } from "@app/services/project-key/project-key-dal";
|
import { TProjectKeyDALFactory } from "@app/services/project-key/project-key-dal";
|
||||||
import { TUserAliasDALFactory } from "@app/services/user-alias/user-alias-dal";
|
import { TUserAliasDALFactory } from "@app/services/user-alias/user-alias-dal";
|
||||||
|
|
||||||
|
import { TAdditionalPrivilegeDALFactory } from "../additional-privilege/additional-privilege-dal";
|
||||||
import { TMembershipRoleDALFactory } from "../membership/membership-role-dal";
|
import { TMembershipRoleDALFactory } from "../membership/membership-role-dal";
|
||||||
import { TMembershipUserDALFactory } from "../membership-user/membership-user-dal";
|
import { TMembershipUserDALFactory } from "../membership-user/membership-user-dal";
|
||||||
|
|
||||||
@@ -20,6 +21,7 @@ type TDeleteOrgMemberships = {
|
|||||||
userAliasDAL: Pick<TUserAliasDALFactory, "delete">;
|
userAliasDAL: Pick<TUserAliasDALFactory, "delete">;
|
||||||
licenseService: Pick<TLicenseServiceFactory, "updateSubscriptionOrgMemberCount">;
|
licenseService: Pick<TLicenseServiceFactory, "updateSubscriptionOrgMemberCount">;
|
||||||
userId?: string;
|
userId?: string;
|
||||||
|
additionalPrivilegeDAL: Pick<TAdditionalPrivilegeDALFactory, "delete">;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const deleteOrgMembershipsFn = async ({
|
export const deleteOrgMembershipsFn = async ({
|
||||||
@@ -32,7 +34,8 @@ export const deleteOrgMembershipsFn = async ({
|
|||||||
userId,
|
userId,
|
||||||
membershipUserDAL,
|
membershipUserDAL,
|
||||||
userGroupMembershipDAL,
|
userGroupMembershipDAL,
|
||||||
membershipRoleDAL
|
membershipRoleDAL,
|
||||||
|
additionalPrivilegeDAL
|
||||||
}: TDeleteOrgMemberships) => {
|
}: TDeleteOrgMemberships) => {
|
||||||
const deletedMemberships = await orgDAL.transaction(async (tx) => {
|
const deletedMemberships = await orgDAL.transaction(async (tx) => {
|
||||||
await membershipRoleDAL.delete(
|
await membershipRoleDAL.delete(
|
||||||
@@ -112,6 +115,16 @@ export const deleteOrgMembershipsFn = async ({
|
|||||||
.filter((el) => el.scope === AccessScope.Project && el.scopeProjectId)
|
.filter((el) => el.scope === AccessScope.Project && el.scopeProjectId)
|
||||||
.map((el) => el.scopeProjectId as string);
|
.map((el) => el.scopeProjectId as string);
|
||||||
|
|
||||||
|
await additionalPrivilegeDAL.delete(
|
||||||
|
{
|
||||||
|
$in: {
|
||||||
|
projectId: projectIds,
|
||||||
|
actorUserId: membershipUserIds
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tx
|
||||||
|
);
|
||||||
|
|
||||||
// Delete all the project keys of the user in the organization
|
// Delete all the project keys of the user in the organization
|
||||||
await projectKeyDAL.delete(
|
await projectKeyDAL.delete(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import { getDefaultOrgMembershipRoleForUpdateOrg } from "@app/services/org/org-r
|
|||||||
import { TOrgMembershipDALFactory } from "@app/services/org-membership/org-membership-dal";
|
import { TOrgMembershipDALFactory } from "@app/services/org-membership/org-membership-dal";
|
||||||
import { TUserAliasDALFactory } from "@app/services/user-alias/user-alias-dal";
|
import { TUserAliasDALFactory } from "@app/services/user-alias/user-alias-dal";
|
||||||
|
|
||||||
|
import { TAdditionalPrivilegeDALFactory } from "../additional-privilege/additional-privilege-dal";
|
||||||
import { TAuthLoginFactory } from "../auth/auth-login-service";
|
import { TAuthLoginFactory } from "../auth/auth-login-service";
|
||||||
import { ActorAuthMethod, ActorType, AuthMethod, AuthModeJwtTokenPayload, AuthTokenType } from "../auth/auth-type";
|
import { ActorAuthMethod, ActorType, AuthMethod, AuthModeJwtTokenPayload, AuthTokenType } from "../auth/auth-type";
|
||||||
import { TAuthTokenServiceFactory } from "../auth-token/auth-token-service";
|
import { TAuthTokenServiceFactory } from "../auth-token/auth-token-service";
|
||||||
@@ -112,6 +113,7 @@ type TOrgServiceFactoryDep = {
|
|||||||
loginService: Pick<TAuthLoginFactory, "generateUserTokens">;
|
loginService: Pick<TAuthLoginFactory, "generateUserTokens">;
|
||||||
reminderService: Pick<TReminderServiceFactory, "deleteReminderBySecretId">;
|
reminderService: Pick<TReminderServiceFactory, "deleteReminderBySecretId">;
|
||||||
userGroupMembershipDAL: TUserGroupMembershipDALFactory;
|
userGroupMembershipDAL: TUserGroupMembershipDALFactory;
|
||||||
|
additionalPrivilegeDAL: TAdditionalPrivilegeDALFactory;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TOrgServiceFactory = ReturnType<typeof orgServiceFactory>;
|
export type TOrgServiceFactory = ReturnType<typeof orgServiceFactory>;
|
||||||
@@ -144,7 +146,8 @@ export const orgServiceFactory = ({
|
|||||||
reminderService,
|
reminderService,
|
||||||
membershipRoleDAL,
|
membershipRoleDAL,
|
||||||
membershipUserDAL,
|
membershipUserDAL,
|
||||||
userGroupMembershipDAL
|
userGroupMembershipDAL,
|
||||||
|
additionalPrivilegeDAL
|
||||||
}: TOrgServiceFactoryDep) => {
|
}: TOrgServiceFactoryDep) => {
|
||||||
/*
|
/*
|
||||||
* Get organization details by the organization id
|
* Get organization details by the organization id
|
||||||
@@ -1004,7 +1007,8 @@ export const orgServiceFactory = ({
|
|||||||
userId,
|
userId,
|
||||||
membershipUserDAL,
|
membershipUserDAL,
|
||||||
membershipRoleDAL,
|
membershipRoleDAL,
|
||||||
userGroupMembershipDAL
|
userGroupMembershipDAL,
|
||||||
|
additionalPrivilegeDAL
|
||||||
});
|
});
|
||||||
|
|
||||||
return deletedMembership;
|
return deletedMembership;
|
||||||
@@ -1040,7 +1044,8 @@ export const orgServiceFactory = ({
|
|||||||
userId,
|
userId,
|
||||||
membershipUserDAL,
|
membershipUserDAL,
|
||||||
membershipRoleDAL,
|
membershipRoleDAL,
|
||||||
userGroupMembershipDAL
|
userGroupMembershipDAL,
|
||||||
|
additionalPrivilegeDAL
|
||||||
});
|
});
|
||||||
|
|
||||||
return deletedMemberships;
|
return deletedMemberships;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
} from "@app/ee/services/permission/org-permission";
|
} from "@app/ee/services/permission/org-permission";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
import { BadRequestError } from "@app/lib/errors";
|
import { BadRequestError } from "@app/lib/errors";
|
||||||
|
import { TExternalGroupOrgRoleMappingDALFactory } from "@app/services/external-group-org-role-mapping/external-group-org-role-mapping-dal";
|
||||||
import { isCustomOrgRole } from "@app/services/org/org-role-fns";
|
import { isCustomOrgRole } from "@app/services/org/org-role-fns";
|
||||||
|
|
||||||
import { TRoleScopeFactory } from "../role-types";
|
import { TRoleScopeFactory } from "../role-types";
|
||||||
@@ -17,9 +18,13 @@ import { TRoleScopeFactory } from "../role-types";
|
|||||||
// TODO(simp): missing external group checking
|
// TODO(simp): missing external group checking
|
||||||
type TOrgRoleScopeFactoryDep = {
|
type TOrgRoleScopeFactoryDep = {
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
||||||
|
externalGroupOrgRoleMappingDAL: Pick<TExternalGroupOrgRoleMappingDALFactory, "findOne">;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const newOrgRoleFactory = ({ permissionService }: TOrgRoleScopeFactoryDep): TRoleScopeFactory => {
|
export const newOrgRoleFactory = ({
|
||||||
|
permissionService,
|
||||||
|
externalGroupOrgRoleMappingDAL
|
||||||
|
}: TOrgRoleScopeFactoryDep): TRoleScopeFactory => {
|
||||||
const getScopeField: TRoleScopeFactory["getScopeField"] = (dto) => {
|
const getScopeField: TRoleScopeFactory["getScopeField"] = (dto) => {
|
||||||
if (dto.scope === AccessScope.Organization) {
|
if (dto.scope === AccessScope.Organization) {
|
||||||
return { key: "orgId" as const, value: dto.orgId };
|
return { key: "orgId" as const, value: dto.orgId };
|
||||||
@@ -60,6 +65,17 @@ export const newOrgRoleFactory = ({ permissionService }: TOrgRoleScopeFactoryDep
|
|||||||
dto.permission.orgId
|
dto.permission.orgId
|
||||||
);
|
);
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Role);
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Role);
|
||||||
|
|
||||||
|
const externalGroupMapping = await externalGroupOrgRoleMappingDAL.findOne({
|
||||||
|
orgId: dto.permission.orgId,
|
||||||
|
roleId: dto.selector.id
|
||||||
|
});
|
||||||
|
|
||||||
|
if (externalGroupMapping)
|
||||||
|
throw new BadRequestError({
|
||||||
|
message:
|
||||||
|
"Cannot delete role assigned to external group organization role mapping. Please re-assign external mapping and try again."
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onListRoleGuard: TRoleScopeFactory["onListRoleGuard"] = async (dto) => {
|
const onListRoleGuard: TRoleScopeFactory["onListRoleGuard"] = async (dto) => {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars
|
|||||||
import { UnpackedPermissionSchema, unpackPermissions } from "@app/server/routes/sanitizedSchema/permission";
|
import { UnpackedPermissionSchema, unpackPermissions } from "@app/server/routes/sanitizedSchema/permission";
|
||||||
|
|
||||||
import { ActorType } from "../auth/auth-type";
|
import { ActorType } from "../auth/auth-type";
|
||||||
|
import { TExternalGroupOrgRoleMappingDALFactory } from "../external-group-org-role-mapping/external-group-org-role-mapping-dal";
|
||||||
import { TIdentityDALFactory } from "../identity/identity-dal";
|
import { TIdentityDALFactory } from "../identity/identity-dal";
|
||||||
import { TProjectDALFactory } from "../project/project-dal";
|
import { TProjectDALFactory } from "../project/project-dal";
|
||||||
import { TUserDALFactory } from "../user/user-dal";
|
import { TUserDALFactory } from "../user/user-dal";
|
||||||
@@ -31,6 +32,7 @@ type TRoleServiceFactoryDep = {
|
|||||||
userDAL: Pick<TUserDALFactory, "findById">;
|
userDAL: Pick<TUserDALFactory, "findById">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission" | "getOrgPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission" | "getOrgPermission">;
|
||||||
projectDAL: Pick<TProjectDALFactory, "findById">;
|
projectDAL: Pick<TProjectDALFactory, "findById">;
|
||||||
|
externalGroupOrgRoleMappingDAL: Pick<TExternalGroupOrgRoleMappingDALFactory, "findOne">;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TRoleServiceFactory = ReturnType<typeof roleServiceFactory>;
|
export type TRoleServiceFactory = ReturnType<typeof roleServiceFactory>;
|
||||||
@@ -40,10 +42,12 @@ export const roleServiceFactory = ({
|
|||||||
permissionService,
|
permissionService,
|
||||||
projectDAL,
|
projectDAL,
|
||||||
identityDAL,
|
identityDAL,
|
||||||
userDAL
|
userDAL,
|
||||||
|
externalGroupOrgRoleMappingDAL
|
||||||
}: TRoleServiceFactoryDep) => {
|
}: TRoleServiceFactoryDep) => {
|
||||||
const orgRoleFactory = newOrgRoleFactory({
|
const orgRoleFactory = newOrgRoleFactory({
|
||||||
permissionService
|
permissionService,
|
||||||
|
externalGroupOrgRoleMappingDAL
|
||||||
});
|
});
|
||||||
const projectRoleFactory = newProjectRoleFactory({
|
const projectRoleFactory = newProjectRoleFactory({
|
||||||
permissionService,
|
permissionService,
|
||||||
|
|||||||
Reference in New Issue
Block a user