mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 19:44:52 +00:00
Merge pull request #1999 from akhilmhdh/feat/ui-permission-check-broken
Terraform identity management apis
This commit is contained in:
@@ -7,11 +7,12 @@ import { IdentityAuthMethod } from "@app/db/schemas";
|
||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import { isAtLeastAsPrivileged } from "@app/lib/casl";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
|
||||
import { BadRequestError, ForbiddenRequestError, UnauthorizedError } from "@app/lib/errors";
|
||||
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
|
||||
|
||||
import { AuthTokenType } from "../auth/auth-type";
|
||||
import { ActorType, AuthTokenType } from "../auth/auth-type";
|
||||
import { TIdentityDALFactory } from "../identity/identity-dal";
|
||||
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal";
|
||||
import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal";
|
||||
@@ -24,12 +25,13 @@ import {
|
||||
TGetAwsAuthDTO,
|
||||
TGetCallerIdentityResponse,
|
||||
TLoginAwsAuthDTO,
|
||||
TRevokeAwsAuthDTO,
|
||||
TUpdateAwsAuthDTO
|
||||
} from "./identity-aws-auth-types";
|
||||
|
||||
type TIdentityAwsAuthServiceFactoryDep = {
|
||||
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create">;
|
||||
identityAwsAuthDAL: Pick<TIdentityAwsAuthDALFactory, "findOne" | "transaction" | "create" | "updateById">;
|
||||
identityAwsAuthDAL: Pick<TIdentityAwsAuthDALFactory, "findOne" | "transaction" | "create" | "updateById" | "delete">;
|
||||
identityOrgMembershipDAL: Pick<TIdentityOrgDALFactory, "findOne">;
|
||||
identityDAL: Pick<TIdentityDALFactory, "updateById">;
|
||||
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
||||
@@ -301,10 +303,54 @@ export const identityAwsAuthServiceFactory = ({
|
||||
return { ...awsIdentityAuth, orgId: identityMembershipOrg.orgId };
|
||||
};
|
||||
|
||||
const revokeIdentityAwsAuth = async ({
|
||||
identityId,
|
||||
actorId,
|
||||
actor,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
}: TRevokeAwsAuthDTO) => {
|
||||
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
|
||||
if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" });
|
||||
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.AWS_AUTH)
|
||||
throw new BadRequestError({
|
||||
message: "The identity does not have aws auth"
|
||||
});
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
identityMembershipOrg.orgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Identity);
|
||||
|
||||
const { permission: rolePermission } = await permissionService.getOrgPermission(
|
||||
ActorType.IDENTITY,
|
||||
identityMembershipOrg.identityId,
|
||||
identityMembershipOrg.orgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission);
|
||||
if (!hasPriviledge)
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Failed to revoke aws auth of identity with more privileged role"
|
||||
});
|
||||
|
||||
const revokedIdentityAwsAuth = await identityAwsAuthDAL.transaction(async (tx) => {
|
||||
const deletedAwsAuth = await identityAwsAuthDAL.delete({ identityId }, tx);
|
||||
await identityDAL.updateById(identityId, { authMethod: null }, tx);
|
||||
return { ...deletedAwsAuth?.[0], orgId: identityMembershipOrg.orgId };
|
||||
});
|
||||
return revokedIdentityAwsAuth;
|
||||
};
|
||||
|
||||
return {
|
||||
login,
|
||||
attachAwsAuth,
|
||||
updateAwsAuth,
|
||||
getAwsAuth
|
||||
getAwsAuth,
|
||||
revokeIdentityAwsAuth
|
||||
};
|
||||
};
|
||||
|
||||
@@ -52,3 +52,7 @@ export type TGetCallerIdentityResponse = {
|
||||
ResponseMetadata: { RequestId: string };
|
||||
};
|
||||
};
|
||||
|
||||
export type TRevokeAwsAuthDTO = {
|
||||
identityId: string;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
@@ -5,11 +5,12 @@ import { IdentityAuthMethod } from "@app/db/schemas";
|
||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import { isAtLeastAsPrivileged } from "@app/lib/casl";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
|
||||
import { BadRequestError, ForbiddenRequestError, UnauthorizedError } from "@app/lib/errors";
|
||||
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
|
||||
|
||||
import { AuthTokenType } from "../auth/auth-type";
|
||||
import { ActorType, AuthTokenType } from "../auth/auth-type";
|
||||
import { TIdentityDALFactory } from "../identity/identity-dal";
|
||||
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal";
|
||||
import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal";
|
||||
@@ -20,11 +21,15 @@ import {
|
||||
TAttachAzureAuthDTO,
|
||||
TGetAzureAuthDTO,
|
||||
TLoginAzureAuthDTO,
|
||||
TRevokeAzureAuthDTO,
|
||||
TUpdateAzureAuthDTO
|
||||
} from "./identity-azure-auth-types";
|
||||
|
||||
type TIdentityAzureAuthServiceFactoryDep = {
|
||||
identityAzureAuthDAL: Pick<TIdentityAzureAuthDALFactory, "findOne" | "transaction" | "create" | "updateById">;
|
||||
identityAzureAuthDAL: Pick<
|
||||
TIdentityAzureAuthDALFactory,
|
||||
"findOne" | "transaction" | "create" | "updateById" | "delete"
|
||||
>;
|
||||
identityOrgMembershipDAL: Pick<TIdentityOrgDALFactory, "findOne">;
|
||||
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create">;
|
||||
identityDAL: Pick<TIdentityDALFactory, "updateById">;
|
||||
@@ -277,10 +282,54 @@ export const identityAzureAuthServiceFactory = ({
|
||||
return { ...identityAzureAuth, orgId: identityMembershipOrg.orgId };
|
||||
};
|
||||
|
||||
const revokeIdentityAzureAuth = async ({
|
||||
identityId,
|
||||
actorId,
|
||||
actor,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
}: TRevokeAzureAuthDTO) => {
|
||||
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
|
||||
if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" });
|
||||
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.AZURE_AUTH)
|
||||
throw new BadRequestError({
|
||||
message: "The identity does not have azure auth"
|
||||
});
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
identityMembershipOrg.orgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Identity);
|
||||
|
||||
const { permission: rolePermission } = await permissionService.getOrgPermission(
|
||||
ActorType.IDENTITY,
|
||||
identityMembershipOrg.identityId,
|
||||
identityMembershipOrg.orgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission);
|
||||
if (!hasPriviledge)
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Failed to revoke azure auth of identity with more privileged role"
|
||||
});
|
||||
|
||||
const revokedIdentityAzureAuth = await identityAzureAuthDAL.transaction(async (tx) => {
|
||||
const deletedAzureAuth = await identityAzureAuthDAL.delete({ identityId }, tx);
|
||||
await identityDAL.updateById(identityId, { authMethod: null }, tx);
|
||||
return { ...deletedAzureAuth?.[0], orgId: identityMembershipOrg.orgId };
|
||||
});
|
||||
return revokedIdentityAzureAuth;
|
||||
};
|
||||
|
||||
return {
|
||||
login,
|
||||
attachAzureAuth,
|
||||
updateAzureAuth,
|
||||
getAzureAuth
|
||||
getAzureAuth,
|
||||
revokeIdentityAzureAuth
|
||||
};
|
||||
};
|
||||
|
||||
@@ -118,3 +118,7 @@ export type TDecodedAzureAuthJwt = {
|
||||
[key: string]: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type TRevokeAzureAuthDTO = {
|
||||
identityId: string;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
@@ -5,11 +5,12 @@ import { IdentityAuthMethod } from "@app/db/schemas";
|
||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import { isAtLeastAsPrivileged } from "@app/lib/casl";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
|
||||
import { BadRequestError, ForbiddenRequestError, UnauthorizedError } from "@app/lib/errors";
|
||||
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
|
||||
|
||||
import { AuthTokenType } from "../auth/auth-type";
|
||||
import { ActorType, AuthTokenType } from "../auth/auth-type";
|
||||
import { TIdentityDALFactory } from "../identity/identity-dal";
|
||||
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal";
|
||||
import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal";
|
||||
@@ -21,11 +22,12 @@ import {
|
||||
TGcpIdentityDetails,
|
||||
TGetGcpAuthDTO,
|
||||
TLoginGcpAuthDTO,
|
||||
TRevokeGcpAuthDTO,
|
||||
TUpdateGcpAuthDTO
|
||||
} from "./identity-gcp-auth-types";
|
||||
|
||||
type TIdentityGcpAuthServiceFactoryDep = {
|
||||
identityGcpAuthDAL: Pick<TIdentityGcpAuthDALFactory, "findOne" | "transaction" | "create" | "updateById">;
|
||||
identityGcpAuthDAL: Pick<TIdentityGcpAuthDALFactory, "findOne" | "transaction" | "create" | "updateById" | "delete">;
|
||||
identityOrgMembershipDAL: Pick<TIdentityOrgDALFactory, "findOne">;
|
||||
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create">;
|
||||
identityDAL: Pick<TIdentityDALFactory, "updateById">;
|
||||
@@ -315,10 +317,54 @@ export const identityGcpAuthServiceFactory = ({
|
||||
return { ...identityGcpAuth, orgId: identityMembershipOrg.orgId };
|
||||
};
|
||||
|
||||
const revokeIdentityGcpAuth = async ({
|
||||
identityId,
|
||||
actorId,
|
||||
actor,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
}: TRevokeGcpAuthDTO) => {
|
||||
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
|
||||
if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" });
|
||||
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.GCP_AUTH)
|
||||
throw new BadRequestError({
|
||||
message: "The identity does not have gcp auth"
|
||||
});
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
identityMembershipOrg.orgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Identity);
|
||||
|
||||
const { permission: rolePermission } = await permissionService.getOrgPermission(
|
||||
ActorType.IDENTITY,
|
||||
identityMembershipOrg.identityId,
|
||||
identityMembershipOrg.orgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission);
|
||||
if (!hasPriviledge)
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Failed to revoke gcp auth of identity with more privileged role"
|
||||
});
|
||||
|
||||
const revokedIdentityGcpAuth = await identityGcpAuthDAL.transaction(async (tx) => {
|
||||
const deletedGcpAuth = await identityGcpAuthDAL.delete({ identityId }, tx);
|
||||
await identityDAL.updateById(identityId, { authMethod: null }, tx);
|
||||
return { ...deletedGcpAuth?.[0], orgId: identityMembershipOrg.orgId };
|
||||
});
|
||||
return revokedIdentityGcpAuth;
|
||||
};
|
||||
|
||||
return {
|
||||
login,
|
||||
attachGcpAuth,
|
||||
updateGcpAuth,
|
||||
getGcpAuth
|
||||
getGcpAuth,
|
||||
revokeIdentityGcpAuth
|
||||
};
|
||||
};
|
||||
|
||||
@@ -76,3 +76,7 @@ export type TDecodedGcpIamAuthJwt = {
|
||||
[key: string]: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type TRevokeGcpAuthDTO = {
|
||||
identityId: string;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
@@ -7,6 +7,7 @@ import { IdentityAuthMethod, SecretKeyEncoding, TIdentityKubernetesAuthsUpdate }
|
||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import { isAtLeastAsPrivileged } from "@app/lib/casl";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import {
|
||||
decryptSymmetric,
|
||||
@@ -16,11 +17,11 @@ import {
|
||||
infisicalSymmetricDecrypt,
|
||||
infisicalSymmetricEncypt
|
||||
} from "@app/lib/crypto/encryption";
|
||||
import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
|
||||
import { BadRequestError, ForbiddenRequestError, UnauthorizedError } from "@app/lib/errors";
|
||||
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
|
||||
import { TOrgBotDALFactory } from "@app/services/org/org-bot-dal";
|
||||
|
||||
import { AuthTokenType } from "../auth/auth-type";
|
||||
import { ActorType, AuthTokenType } from "../auth/auth-type";
|
||||
import { TIdentityDALFactory } from "../identity/identity-dal";
|
||||
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal";
|
||||
import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal";
|
||||
@@ -32,13 +33,14 @@ import {
|
||||
TCreateTokenReviewResponse,
|
||||
TGetKubernetesAuthDTO,
|
||||
TLoginKubernetesAuthDTO,
|
||||
TRevokeKubernetesAuthDTO,
|
||||
TUpdateKubernetesAuthDTO
|
||||
} from "./identity-kubernetes-auth-types";
|
||||
|
||||
type TIdentityKubernetesAuthServiceFactoryDep = {
|
||||
identityKubernetesAuthDAL: Pick<
|
||||
TIdentityKubernetesAuthDALFactory,
|
||||
"create" | "findOne" | "transaction" | "updateById"
|
||||
"create" | "findOne" | "transaction" | "updateById" | "delete"
|
||||
>;
|
||||
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create">;
|
||||
identityOrgMembershipDAL: Pick<TIdentityOrgDALFactory, "findOne" | "findById">;
|
||||
@@ -533,10 +535,54 @@ export const identityKubernetesAuthServiceFactory = ({
|
||||
return { ...identityKubernetesAuth, caCert, tokenReviewerJwt, orgId: identityMembershipOrg.orgId };
|
||||
};
|
||||
|
||||
const revokeIdentityKubernetesAuth = async ({
|
||||
identityId,
|
||||
actorId,
|
||||
actor,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
}: TRevokeKubernetesAuthDTO) => {
|
||||
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
|
||||
if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" });
|
||||
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.KUBERNETES_AUTH)
|
||||
throw new BadRequestError({
|
||||
message: "The identity does not have kubenetes auth"
|
||||
});
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
identityMembershipOrg.orgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Identity);
|
||||
|
||||
const { permission: rolePermission } = await permissionService.getOrgPermission(
|
||||
ActorType.IDENTITY,
|
||||
identityMembershipOrg.identityId,
|
||||
identityMembershipOrg.orgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission);
|
||||
if (!hasPriviledge)
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Failed to revoke kubenetes auth of identity with more privileged role"
|
||||
});
|
||||
|
||||
const revokedIdentityKubernetesAuth = await identityKubernetesAuthDAL.transaction(async (tx) => {
|
||||
const deletedKubernetesAuth = await identityKubernetesAuthDAL.delete({ identityId }, tx);
|
||||
await identityDAL.updateById(identityId, { authMethod: null }, tx);
|
||||
return { ...deletedKubernetesAuth?.[0], orgId: identityMembershipOrg.orgId };
|
||||
});
|
||||
return revokedIdentityKubernetesAuth;
|
||||
};
|
||||
|
||||
return {
|
||||
login,
|
||||
attachKubernetesAuth,
|
||||
updateKubernetesAuth,
|
||||
getKubernetesAuth
|
||||
getKubernetesAuth,
|
||||
revokeIdentityKubernetesAuth
|
||||
};
|
||||
};
|
||||
|
||||
@@ -59,3 +59,7 @@ export type TCreateTokenReviewResponse = {
|
||||
};
|
||||
status: TCreateTokenReviewSuccessResponse | TCreateTokenReviewErrorResponse;
|
||||
};
|
||||
|
||||
export type TRevokeKubernetesAuthDTO = {
|
||||
identityId: string;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
@@ -25,7 +25,9 @@ import {
|
||||
TCreateUaClientSecretDTO,
|
||||
TGetUaClientSecretsDTO,
|
||||
TGetUaDTO,
|
||||
TGetUniversalAuthClientSecretByIdDTO,
|
||||
TRevokeUaClientSecretDTO,
|
||||
TRevokeUaDTO,
|
||||
TUpdateUaDTO
|
||||
} from "./identity-ua-types";
|
||||
|
||||
@@ -136,7 +138,7 @@ export const identityUaServiceFactory = ({
|
||||
return { accessToken, identityUa, validClientSecretInfo, identityAccessToken, identityMembershipOrg };
|
||||
};
|
||||
|
||||
const attachUa = async ({
|
||||
const attachUniversalAuth = async ({
|
||||
accessTokenMaxTTL,
|
||||
identityId,
|
||||
accessTokenNumUsesLimit,
|
||||
@@ -227,7 +229,7 @@ export const identityUaServiceFactory = ({
|
||||
return { ...identityUa, orgId: identityMembershipOrg.orgId };
|
||||
};
|
||||
|
||||
const updateUa = async ({
|
||||
const updateUniversalAuth = async ({
|
||||
accessTokenMaxTTL,
|
||||
identityId,
|
||||
accessTokenNumUsesLimit,
|
||||
@@ -312,7 +314,7 @@ export const identityUaServiceFactory = ({
|
||||
return { ...updatedUaAuth, orgId: identityMembershipOrg.orgId };
|
||||
};
|
||||
|
||||
const getIdentityUa = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetUaDTO) => {
|
||||
const getIdentityUniversalAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetUaDTO) => {
|
||||
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
|
||||
if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" });
|
||||
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.Univeral)
|
||||
@@ -333,7 +335,50 @@ export const identityUaServiceFactory = ({
|
||||
return { ...uaIdentityAuth, orgId: identityMembershipOrg.orgId };
|
||||
};
|
||||
|
||||
const createUaClientSecret = async ({
|
||||
const revokeIdentityUniversalAuth = async ({
|
||||
identityId,
|
||||
actorId,
|
||||
actor,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
}: TRevokeUaDTO) => {
|
||||
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
|
||||
if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" });
|
||||
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.Univeral)
|
||||
throw new BadRequestError({
|
||||
message: "The identity does not have universal auth"
|
||||
});
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
identityMembershipOrg.orgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Identity);
|
||||
|
||||
const { permission: rolePermission } = await permissionService.getOrgPermission(
|
||||
ActorType.IDENTITY,
|
||||
identityMembershipOrg.identityId,
|
||||
identityMembershipOrg.orgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission);
|
||||
if (!hasPriviledge)
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Failed to revoke universal auth of identity with more privileged role"
|
||||
});
|
||||
|
||||
const revokedIdentityUniversalAuth = await identityUaDAL.transaction(async (tx) => {
|
||||
const deletedUniversalAuth = await identityUaDAL.delete({ identityId }, tx);
|
||||
await identityDAL.updateById(identityId, { authMethod: null }, tx);
|
||||
return { ...deletedUniversalAuth?.[0], orgId: identityMembershipOrg.orgId };
|
||||
});
|
||||
return revokedIdentityUniversalAuth;
|
||||
};
|
||||
|
||||
const createUniversalAuthClientSecret = async ({
|
||||
actor,
|
||||
actorId,
|
||||
actorOrgId,
|
||||
@@ -396,7 +441,7 @@ export const identityUaServiceFactory = ({
|
||||
};
|
||||
};
|
||||
|
||||
const getUaClientSecrets = async ({
|
||||
const getUniversalAuthClientSecrets = async ({
|
||||
actor,
|
||||
actorId,
|
||||
actorOrgId,
|
||||
@@ -442,7 +487,47 @@ export const identityUaServiceFactory = ({
|
||||
return { clientSecrets, orgId: identityMembershipOrg.orgId };
|
||||
};
|
||||
|
||||
const revokeUaClientSecret = async ({
|
||||
const getUniversalAuthClientSecretById = async ({
|
||||
identityId,
|
||||
actorId,
|
||||
actor,
|
||||
actorOrgId,
|
||||
actorAuthMethod,
|
||||
clientSecretId
|
||||
}: TGetUniversalAuthClientSecretByIdDTO) => {
|
||||
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
|
||||
if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" });
|
||||
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.Univeral)
|
||||
throw new BadRequestError({
|
||||
message: "The identity does not have universal auth"
|
||||
});
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
identityMembershipOrg.orgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity);
|
||||
|
||||
const { permission: rolePermission } = await permissionService.getOrgPermission(
|
||||
ActorType.IDENTITY,
|
||||
identityMembershipOrg.identityId,
|
||||
identityMembershipOrg.orgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission);
|
||||
if (!hasPriviledge)
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Failed to read identity client secret of project with more privileged role"
|
||||
});
|
||||
|
||||
const clientSecret = await identityUaClientSecretDAL.findById(clientSecretId);
|
||||
return { ...clientSecret, identityId, orgId: identityMembershipOrg.orgId };
|
||||
};
|
||||
|
||||
const revokeUniversalAuthClientSecret = async ({
|
||||
identityId,
|
||||
actorId,
|
||||
actor,
|
||||
@@ -475,7 +560,7 @@ export const identityUaServiceFactory = ({
|
||||
const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission);
|
||||
if (!hasPriviledge)
|
||||
throw new ForbiddenRequestError({
|
||||
message: "Failed to add identity to project with more privileged role"
|
||||
message: "Failed to revoke identity client secret with more privileged role"
|
||||
});
|
||||
|
||||
const clientSecret = await identityUaClientSecretDAL.updateById(clientSecretId, {
|
||||
@@ -486,11 +571,13 @@ export const identityUaServiceFactory = ({
|
||||
|
||||
return {
|
||||
login,
|
||||
attachUa,
|
||||
updateUa,
|
||||
getIdentityUa,
|
||||
createUaClientSecret,
|
||||
getUaClientSecrets,
|
||||
revokeUaClientSecret
|
||||
attachUniversalAuth,
|
||||
updateUniversalAuth,
|
||||
getIdentityUniversalAuth,
|
||||
revokeIdentityUniversalAuth,
|
||||
createUniversalAuthClientSecret,
|
||||
getUniversalAuthClientSecrets,
|
||||
revokeUniversalAuthClientSecret,
|
||||
getUniversalAuthClientSecretById
|
||||
};
|
||||
};
|
||||
|
||||
@@ -22,6 +22,10 @@ export type TGetUaDTO = {
|
||||
identityId: string;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
export type TRevokeUaDTO = {
|
||||
identityId: string;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
export type TCreateUaClientSecretDTO = {
|
||||
identityId: string;
|
||||
description: string;
|
||||
@@ -37,3 +41,8 @@ export type TRevokeUaClientSecretDTO = {
|
||||
identityId: string;
|
||||
clientSecretId: string;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
export type TGetUniversalAuthClientSecretByIdDTO = {
|
||||
identityId: string;
|
||||
clientSecretId: string;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
@@ -27,10 +27,10 @@ export const identityOrgDALFactory = (db: TDbClient) => {
|
||||
}
|
||||
};
|
||||
|
||||
const findByOrgId = async (orgId: string, tx?: Knex) => {
|
||||
const find = async (filter: Partial<TIdentityOrgMemberships>, tx?: Knex) => {
|
||||
try {
|
||||
const docs = await (tx || db)(TableName.IdentityOrgMembership)
|
||||
.where(`${TableName.IdentityOrgMembership}.orgId`, orgId)
|
||||
.where(filter)
|
||||
.join(TableName.Identity, `${TableName.IdentityOrgMembership}.identityId`, `${TableName.Identity}.id`)
|
||||
.leftJoin(TableName.OrgRoles, `${TableName.IdentityOrgMembership}.roleId`, `${TableName.OrgRoles}.id`)
|
||||
.select(selectAllTableCols(TableName.IdentityOrgMembership))
|
||||
@@ -79,5 +79,5 @@ export const identityOrgDALFactory = (db: TDbClient) => {
|
||||
}
|
||||
};
|
||||
|
||||
return { ...identityOrgOrm, findOne, findByOrgId };
|
||||
return { ...identityOrgOrm, find, findOne };
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
|
||||
import { OrgMembershipRole, TOrgRoles } from "@app/db/schemas";
|
||||
import { OrgMembershipRole, TableName, TOrgRoles } from "@app/db/schemas";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import { isAtLeastAsPrivileged } from "@app/lib/casl";
|
||||
@@ -10,7 +10,7 @@ import { TOrgPermission } from "@app/lib/types";
|
||||
import { ActorType } from "../auth/auth-type";
|
||||
import { TIdentityDALFactory } from "./identity-dal";
|
||||
import { TIdentityOrgDALFactory } from "./identity-org-dal";
|
||||
import { TCreateIdentityDTO, TDeleteIdentityDTO, TUpdateIdentityDTO } from "./identity-types";
|
||||
import { TCreateIdentityDTO, TDeleteIdentityDTO, TGetIdentityByIdDTO, TUpdateIdentityDTO } from "./identity-types";
|
||||
|
||||
type TIdentityServiceFactoryDep = {
|
||||
identityDAL: TIdentityDALFactory;
|
||||
@@ -126,6 +126,24 @@ export const identityServiceFactory = ({
|
||||
return { ...identity, orgId: identityOrgMembership.orgId };
|
||||
};
|
||||
|
||||
const getIdentityById = async ({ id, actor, actorId, actorOrgId, actorAuthMethod }: TGetIdentityByIdDTO) => {
|
||||
const doc = await identityOrgMembershipDAL.find({
|
||||
[`${TableName.IdentityOrgMembership}.identityId` as "identityId"]: id
|
||||
});
|
||||
const identity = doc[0];
|
||||
if (!identity) throw new BadRequestError({ message: `Failed to find identity with id ${id}` });
|
||||
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor,
|
||||
actorId,
|
||||
identity.orgId,
|
||||
actorAuthMethod,
|
||||
actorOrgId
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity);
|
||||
return identity;
|
||||
};
|
||||
|
||||
const deleteIdentity = async ({ actorId, actor, actorOrgId, actorAuthMethod, id }: TDeleteIdentityDTO) => {
|
||||
const identityOrgMembership = await identityOrgMembershipDAL.findOne({ identityId: id });
|
||||
if (!identityOrgMembership) throw new BadRequestError({ message: `Failed to find identity with id ${id}` });
|
||||
@@ -157,7 +175,9 @@ export const identityServiceFactory = ({
|
||||
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity);
|
||||
|
||||
const identityMemberships = await identityOrgMembershipDAL.findByOrgId(orgId);
|
||||
const identityMemberships = await identityOrgMembershipDAL.find({
|
||||
[`${TableName.IdentityOrgMembership}.orgId` as "orgId"]: orgId
|
||||
});
|
||||
return identityMemberships;
|
||||
};
|
||||
|
||||
@@ -165,6 +185,7 @@ export const identityServiceFactory = ({
|
||||
createIdentity,
|
||||
updateIdentity,
|
||||
deleteIdentity,
|
||||
listOrgIdentities
|
||||
listOrgIdentities,
|
||||
getIdentityById
|
||||
};
|
||||
};
|
||||
|
||||
@@ -16,6 +16,10 @@ export type TDeleteIdentityDTO = {
|
||||
id: string;
|
||||
} & Omit<TOrgPermission, "orgId">;
|
||||
|
||||
export type TGetIdentityByIdDTO = {
|
||||
id: string;
|
||||
} & Omit<TOrgPermission, "orgId">;
|
||||
|
||||
export interface TIdentityTrustedIp {
|
||||
ipAddress: string;
|
||||
type: IPType;
|
||||
|
||||
Reference in New Issue
Block a user