mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-11 23:29:05 +00:00
feat: complete project identities
This commit is contained in:
@@ -171,7 +171,11 @@ const buildAdminPermissionRules = () => {
|
|||||||
ProjectPermissionIdentityActions.Delete,
|
ProjectPermissionIdentityActions.Delete,
|
||||||
ProjectPermissionIdentityActions.Read,
|
ProjectPermissionIdentityActions.Read,
|
||||||
ProjectPermissionIdentityActions.GrantPrivileges,
|
ProjectPermissionIdentityActions.GrantPrivileges,
|
||||||
ProjectPermissionIdentityActions.AssumePrivileges
|
ProjectPermissionIdentityActions.AssumePrivileges,
|
||||||
|
ProjectPermissionIdentityActions.GetToken,
|
||||||
|
ProjectPermissionIdentityActions.CreateToken,
|
||||||
|
ProjectPermissionIdentityActions.DeleteToken,
|
||||||
|
ProjectPermissionIdentityActions.RevokeAuth
|
||||||
],
|
],
|
||||||
ProjectPermissionSub.Identity
|
ProjectPermissionSub.Identity
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -65,7 +65,11 @@ export enum ProjectPermissionIdentityActions {
|
|||||||
Edit = "edit",
|
Edit = "edit",
|
||||||
Delete = "delete",
|
Delete = "delete",
|
||||||
GrantPrivileges = "grant-privileges",
|
GrantPrivileges = "grant-privileges",
|
||||||
AssumePrivileges = "assume-privileges"
|
AssumePrivileges = "assume-privileges",
|
||||||
|
RevokeAuth = "revoke-auth",
|
||||||
|
CreateToken = "create-token",
|
||||||
|
GetToken = "get-token",
|
||||||
|
DeleteToken = "delete-token"
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ProjectPermissionMemberActions {
|
export enum ProjectPermissionMemberActions {
|
||||||
|
|||||||
@@ -757,7 +757,7 @@ export const ORG_IDENTITY_MEMBERSHIP = {
|
|||||||
LIST_IDENTITY_MEMBERSHIPS: {
|
LIST_IDENTITY_MEMBERSHIPS: {
|
||||||
offset: "The offset to start from. If you enter 10, it will start from the 10th identity membership.",
|
offset: "The offset to start from. If you enter 10, it will start from the 10th identity membership.",
|
||||||
limit: "The number of identity memberships to return.",
|
limit: "The number of identity memberships to return.",
|
||||||
identityName: "The text string that identity membership names will be filtered by.",
|
identityName: "",
|
||||||
roles: "The role slugs to filter identity memberships by."
|
roles: "The role slugs to filter identity memberships by."
|
||||||
},
|
},
|
||||||
GET_IDENTITY_MEMBERSHIP_BY_ID: {
|
GET_IDENTITY_MEMBERSHIP_BY_ID: {
|
||||||
@@ -765,7 +765,8 @@ export const ORG_IDENTITY_MEMBERSHIP = {
|
|||||||
},
|
},
|
||||||
LIST_AVAILABLE_IDENTITIES: {
|
LIST_AVAILABLE_IDENTITIES: {
|
||||||
offset: "The offset to start from. If you enter 10, it will start from the 10th identity.",
|
offset: "The offset to start from. If you enter 10, it will start from the 10th identity.",
|
||||||
limit: "The number of identities to return."
|
limit: "The number of identities to return.",
|
||||||
|
identityName: "The text string that identity membership names will be filtered by."
|
||||||
}
|
}
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
@@ -1002,7 +1003,8 @@ export const PROJECT_IDENTITY_MEMBERSHIP = {
|
|||||||
LIST_AVAILABLE_IDENTITIES: {
|
LIST_AVAILABLE_IDENTITIES: {
|
||||||
projectId: "The ID of the project to list available identities for.",
|
projectId: "The ID of the project to list available identities for.",
|
||||||
offset: "The offset to start from. If you enter 10, it will start from the 10th identity.",
|
offset: "The offset to start from. If you enter 10, it will start from the 10th identity.",
|
||||||
limit: "The number of identities to return."
|
limit: "The number of identities to return.",
|
||||||
|
identityName: "The text string that identity membership names will be filtered by."
|
||||||
}
|
}
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { fastifyRequestContext } from "@fastify/request-context";
|
|||||||
import fastify from "fastify";
|
import fastify from "fastify";
|
||||||
import { Cluster, Redis } from "ioredis";
|
import { Cluster, Redis } from "ioredis";
|
||||||
import { Knex } from "knex";
|
import { Knex } from "knex";
|
||||||
|
import { monitorEventLoopDelay } from "perf_hooks";
|
||||||
|
|
||||||
import { THsmServiceFactory } from "@app/ee/services/hsm/hsm-service";
|
import { THsmServiceFactory } from "@app/ee/services/hsm/hsm-service";
|
||||||
import { TKeyStoreFactory } from "@app/keystore/keystore";
|
import { TKeyStoreFactory } from "@app/keystore/keystore";
|
||||||
|
|||||||
@@ -1666,7 +1666,8 @@ export const registerRoutes = async (
|
|||||||
identityMetadataDAL,
|
identityMetadataDAL,
|
||||||
licenseService,
|
licenseService,
|
||||||
permissionService,
|
permissionService,
|
||||||
identityDAL: identityV2DAL
|
identityDAL: identityV2DAL,
|
||||||
|
keyStore
|
||||||
});
|
});
|
||||||
|
|
||||||
const identityProjectService = identityProjectServiceFactory({
|
const identityProjectService = identityProjectServiceFactory({
|
||||||
|
|||||||
@@ -430,7 +430,8 @@ export const registerIdentityOrgMembershipRouter = async (server: FastifyZodProv
|
|||||||
.max(100)
|
.max(100)
|
||||||
.default(20)
|
.default(20)
|
||||||
.describe(ORG_IDENTITY_MEMBERSHIP.LIST_AVAILABLE_IDENTITIES.limit)
|
.describe(ORG_IDENTITY_MEMBERSHIP.LIST_AVAILABLE_IDENTITIES.limit)
|
||||||
.optional()
|
.optional(),
|
||||||
|
identityName: z.string().describe(ORG_IDENTITY_MEMBERSHIP.LIST_AVAILABLE_IDENTITIES.identityName).optional()
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
@@ -447,7 +448,8 @@ export const registerIdentityOrgMembershipRouter = async (server: FastifyZodProv
|
|||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
offset: req.query.offset,
|
offset: req.query.offset,
|
||||||
limit: req.query.limit
|
limit: req.query.limit,
|
||||||
|
identityName: req.query.identityName
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+11
-3
@@ -293,7 +293,7 @@ export const registerIdentityProjectMembershipRouter = async (server: FastifyZod
|
|||||||
temporaryAccessEndTime: z.date().nullable().optional()
|
temporaryAccessEndTime: z.date().nullable().optional()
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
identity: IdentitiesSchema.pick({ name: true, id: true }).extend({
|
identity: IdentitiesSchema.pick({ name: true, id: true, projectId: true, orgId: true }).extend({
|
||||||
authMethods: z.array(z.string())
|
authMethods: z.array(z.string())
|
||||||
}),
|
}),
|
||||||
project: SanitizedProjectSchema.pick({ name: true, id: true })
|
project: SanitizedProjectSchema.pick({ name: true, id: true })
|
||||||
@@ -362,7 +362,9 @@ export const registerIdentityProjectMembershipRouter = async (server: FastifyZod
|
|||||||
temporaryAccessEndTime: z.date().nullable().optional()
|
temporaryAccessEndTime: z.date().nullable().optional()
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
identity: IdentitiesSchema.pick({ name: true, id: true }).extend({
|
lastLoginAuthMethod: z.string().nullable().optional(),
|
||||||
|
lastLoginTime: z.date().nullable().optional(),
|
||||||
|
identity: IdentitiesSchema.pick({ name: true, id: true, projectId: true, orgId: true }).extend({
|
||||||
authMethods: z.array(z.string())
|
authMethods: z.array(z.string())
|
||||||
}),
|
}),
|
||||||
project: SanitizedProjectSchema.pick({ name: true, id: true })
|
project: SanitizedProjectSchema.pick({ name: true, id: true })
|
||||||
@@ -469,6 +471,11 @@ export const registerIdentityProjectMembershipRouter = async (server: FastifyZod
|
|||||||
.max(100)
|
.max(100)
|
||||||
.default(20)
|
.default(20)
|
||||||
.describe(PROJECT_IDENTITY_MEMBERSHIP.LIST_AVAILABLE_IDENTITIES.limit)
|
.describe(PROJECT_IDENTITY_MEMBERSHIP.LIST_AVAILABLE_IDENTITIES.limit)
|
||||||
|
.optional(),
|
||||||
|
identityName: z
|
||||||
|
.string()
|
||||||
|
.trim()
|
||||||
|
.describe(PROJECT_IDENTITY_MEMBERSHIP.LIST_AVAILABLE_IDENTITIES.identityName)
|
||||||
.optional()
|
.optional()
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
@@ -487,7 +494,8 @@ export const registerIdentityProjectMembershipRouter = async (server: FastifyZod
|
|||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
offset: req.query.offset,
|
offset: req.query.offset,
|
||||||
limit: req.query.limit
|
limit: req.query.limit,
|
||||||
|
identityName: req.query.identityName
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ import { registerIdentityLdapAuthRouter } from "./identity-ldap-auth-router";
|
|||||||
import { registerIdentityOciAuthRouter } from "./identity-oci-auth-router";
|
import { registerIdentityOciAuthRouter } from "./identity-oci-auth-router";
|
||||||
import { registerIdentityOidcAuthRouter } from "./identity-oidc-auth-router";
|
import { registerIdentityOidcAuthRouter } from "./identity-oidc-auth-router";
|
||||||
import { registerIdentityOrgMembershipRouter } from "./identity-org-membership-router";
|
import { registerIdentityOrgMembershipRouter } from "./identity-org-membership-router";
|
||||||
import { registerIdentityProjectMembershipRouter } from "./identity-project-router";
|
import { registerIdentityProjectMembershipRouter } from "./identity-project-membership-router";
|
||||||
import { registerIdentityRouter } from "./identity-router";
|
import { registerIdentityRouter } from "./identity-router";
|
||||||
import { registerIdentityTlsCertAuthRouter } from "./identity-tls-cert-auth-router";
|
import { registerIdentityTlsCertAuthRouter } from "./identity-tls-cert-auth-router";
|
||||||
import { registerIdentityTokenAuthRouter } from "./identity-token-auth-router";
|
import { registerIdentityTokenAuthRouter } from "./identity-token-auth-router";
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ const sanitizedIdentitySchema = IdentitiesSchema.pick({
|
|||||||
updatedAt: true,
|
updatedAt: true,
|
||||||
hasDeleteProtection: true
|
hasDeleteProtection: true
|
||||||
}).extend({
|
}).extend({
|
||||||
|
activeLockoutAuthMethods: z.string().array().optional(),
|
||||||
|
authMethods: z.string().array().optional(),
|
||||||
metadata: z
|
metadata: z
|
||||||
.object({
|
.object({
|
||||||
key: z.string(),
|
key: z.string(),
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
import { requestContext } from "@fastify/request-context";
|
import { requestContext } from "@fastify/request-context";
|
||||||
import { AxiosError } from "axios";
|
import { AxiosError } from "axios";
|
||||||
|
|
||||||
import { AccessScope, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
|
import { AccessScope, ActionProjectType, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
|
||||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||||
import {
|
import {
|
||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
validatePrivilegeChangeOperation
|
validatePrivilegeChangeOperation
|
||||||
} from "@app/ee/services/permission/permission-fns";
|
} from "@app/ee/services/permission/permission-fns";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
|
import { ProjectPermissionIdentityActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { request } from "@app/lib/config/request";
|
import { request } from "@app/lib/config/request";
|
||||||
import { crypto } from "@app/lib/crypto";
|
import { crypto } from "@app/lib/crypto";
|
||||||
@@ -51,7 +52,7 @@ type TIdentityAliCloudAuthServiceFactoryDep = {
|
|||||||
>;
|
>;
|
||||||
membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "update" | "getIdentityById">;
|
membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "update" | "getIdentityById">;
|
||||||
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission" | "getProjectPermission">;
|
||||||
orgDAL: Pick<TOrgDALFactory, "findById">;
|
orgDAL: Pick<TOrgDALFactory, "findById">;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -105,7 +106,18 @@ export const identityAliCloudAuthServiceFactory = ({
|
|||||||
// Generate the token
|
// Generate the token
|
||||||
const identityAccessToken = await identityAliCloudAuthDAL.transaction(async (tx) => {
|
const identityAccessToken = await identityAliCloudAuthDAL.transaction(async (tx) => {
|
||||||
await membershipIdentityDAL.update(
|
await membershipIdentityDAL.update(
|
||||||
{ scope: AccessScope.Organization, scopeOrgId: identity.orgId, actorIdentityId: identity.id },
|
identity.projectId
|
||||||
|
? {
|
||||||
|
scope: AccessScope.Project,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
scopeProjectId: identity.projectId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
scope: AccessScope.Organization,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
},
|
||||||
{
|
{
|
||||||
lastLoginAuthMethod: IdentityAuthMethod.ALICLOUD_AUTH,
|
lastLoginAuthMethod: IdentityAuthMethod.ALICLOUD_AUTH,
|
||||||
lastLoginTime: new Date()
|
lastLoginTime: new Date()
|
||||||
@@ -214,16 +226,34 @@ export const identityAliCloudAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Create,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
OrgPermissionIdentityActions.Create,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
);
|
||||||
|
}
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
||||||
if (
|
if (
|
||||||
@@ -300,16 +330,31 @@ export const identityAliCloudAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Edit,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
||||||
if (
|
if (
|
||||||
@@ -362,15 +407,31 @@ export const identityAliCloudAuthServiceFactory = ({
|
|||||||
|
|
||||||
const alicloudIdentityAuth = await identityAliCloudAuthDAL.findOne({ identityId });
|
const alicloudIdentityAuth = await identityAliCloudAuthDAL.findOne({ identityId });
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Read,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
return { ...alicloudIdentityAuth, orgId: identityMembershipOrg.scopeOrgId };
|
return { ...alicloudIdentityAuth, orgId: identityMembershipOrg.scopeOrgId };
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -397,45 +458,61 @@ export const identityAliCloudAuthServiceFactory = ({
|
|||||||
message: "The identity does not have Alibaba Cloud auth"
|
message: "The identity does not have Alibaba Cloud auth"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
|
||||||
|
|
||||||
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
|
||||||
scope: OrganizationActionScope.Any,
|
|
||||||
actor: ActorType.IDENTITY,
|
|
||||||
actorId: identityMembershipOrg.identity.id,
|
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
|
||||||
actorAuthMethod,
|
|
||||||
actorOrgId
|
|
||||||
});
|
|
||||||
|
|
||||||
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
|
||||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity,
|
|
||||||
permission,
|
|
||||||
rolePermission
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!permissionBoundary.isValid)
|
|
||||||
throw new PermissionBoundaryError({
|
|
||||||
message: constructPermissionErrorMessage(
|
|
||||||
"Failed to revoke Alibaba Cloud auth of identity with more privileged role",
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity
|
|
||||||
),
|
|
||||||
details: { missingPermissions: permissionBoundary.missingPermissions }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.RevokeAuth,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
|
||||||
|
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor: ActorType.IDENTITY,
|
||||||
|
actorId: identityMembershipOrg.identity.id,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
|
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
||||||
|
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity,
|
||||||
|
permission,
|
||||||
|
rolePermission
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!permissionBoundary.isValid)
|
||||||
|
throw new PermissionBoundaryError({
|
||||||
|
message: constructPermissionErrorMessage(
|
||||||
|
"Failed to revoke Alibaba Cloud auth of identity with more privileged role",
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
),
|
||||||
|
details: { missingPermissions: permissionBoundary.missingPermissions }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const revokedIdentityAliCloudAuth = await identityAliCloudAuthDAL.transaction(async (tx) => {
|
const revokedIdentityAliCloudAuth = await identityAliCloudAuthDAL.transaction(async (tx) => {
|
||||||
const deletedAliCloudAuth = await identityAliCloudAuthDAL.delete({ identityId }, tx);
|
const deletedAliCloudAuth = await identityAliCloudAuthDAL.delete({ identityId }, tx);
|
||||||
await identityAccessTokenDAL.delete({ identityId, authMethod: IdentityAuthMethod.ALICLOUD_AUTH }, tx);
|
await identityAccessTokenDAL.delete({ identityId, authMethod: IdentityAuthMethod.ALICLOUD_AUTH }, tx);
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */
|
||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
import { requestContext } from "@fastify/request-context";
|
import { requestContext } from "@fastify/request-context";
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import RE2 from "re2";
|
import RE2 from "re2";
|
||||||
|
|
||||||
import { AccessScope, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
|
import { AccessScope, ActionProjectType, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
|
||||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||||
import {
|
import {
|
||||||
@@ -12,6 +13,7 @@ import {
|
|||||||
validatePrivilegeChangeOperation
|
validatePrivilegeChangeOperation
|
||||||
} from "@app/ee/services/permission/permission-fns";
|
} from "@app/ee/services/permission/permission-fns";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
|
import { ProjectPermissionIdentityActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { crypto } from "@app/lib/crypto";
|
import { crypto } from "@app/lib/crypto";
|
||||||
import {
|
import {
|
||||||
@@ -50,7 +52,7 @@ type TIdentityAwsAuthServiceFactoryDep = {
|
|||||||
identityAwsAuthDAL: Pick<TIdentityAwsAuthDALFactory, "findOne" | "transaction" | "create" | "updateById" | "delete">;
|
identityAwsAuthDAL: Pick<TIdentityAwsAuthDALFactory, "findOne" | "transaction" | "create" | "updateById" | "delete">;
|
||||||
membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "update" | "getIdentityById">;
|
membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "update" | "getIdentityById">;
|
||||||
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission" | "getProjectPermission">;
|
||||||
orgDAL: Pick<TOrgDALFactory, "findById">;
|
orgDAL: Pick<TOrgDALFactory, "findById">;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -179,7 +181,18 @@ export const identityAwsAuthServiceFactory = ({
|
|||||||
|
|
||||||
const identityAccessToken = await identityAwsAuthDAL.transaction(async (tx) => {
|
const identityAccessToken = await identityAwsAuthDAL.transaction(async (tx) => {
|
||||||
await membershipIdentityDAL.update(
|
await membershipIdentityDAL.update(
|
||||||
{ scope: AccessScope.Organization, scopeOrgId: identity.orgId, actorIdentityId: identity.id },
|
identity.projectId
|
||||||
|
? {
|
||||||
|
scope: AccessScope.Project,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
scopeProjectId: identity.projectId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
scope: AccessScope.Organization,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
},
|
||||||
{
|
{
|
||||||
lastLoginAuthMethod: IdentityAuthMethod.AWS_AUTH,
|
lastLoginAuthMethod: IdentityAuthMethod.AWS_AUTH,
|
||||||
lastLoginTime: new Date()
|
lastLoginTime: new Date()
|
||||||
@@ -300,16 +313,34 @@ export const identityAwsAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
actor,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actorId,
|
actionProjectType: ActionProjectType.Any,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actor,
|
||||||
actorAuthMethod,
|
actorId,
|
||||||
actorOrgId,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
scope: OrganizationActionScope.Any
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Create,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId,
|
||||||
|
scope: OrganizationActionScope.Any
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
OrgPermissionIdentityActions.Create,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
);
|
||||||
|
}
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
||||||
if (
|
if (
|
||||||
@@ -389,16 +420,31 @@ export const identityAwsAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Edit,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
||||||
if (
|
if (
|
||||||
@@ -453,15 +499,31 @@ export const identityAwsAuthServiceFactory = ({
|
|||||||
|
|
||||||
const awsIdentityAuth = await identityAwsAuthDAL.findOne({ identityId });
|
const awsIdentityAuth = await identityAwsAuthDAL.findOne({ identityId });
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Read,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
return { ...awsIdentityAuth, orgId: identityMembershipOrg.scopeOrgId };
|
return { ...awsIdentityAuth, orgId: identityMembershipOrg.scopeOrgId };
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -488,45 +550,60 @@ export const identityAwsAuthServiceFactory = ({
|
|||||||
message: "The identity does not have aws auth"
|
message: "The identity does not have aws auth"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
|
||||||
|
|
||||||
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
|
||||||
scope: OrganizationActionScope.Any,
|
|
||||||
actor: ActorType.IDENTITY,
|
|
||||||
actorId: identityMembershipOrg.identity.id,
|
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
|
||||||
actorAuthMethod,
|
|
||||||
actorOrgId
|
|
||||||
});
|
|
||||||
|
|
||||||
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
|
||||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity,
|
|
||||||
permission,
|
|
||||||
rolePermission
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!permissionBoundary.isValid)
|
|
||||||
throw new PermissionBoundaryError({
|
|
||||||
message: constructPermissionErrorMessage(
|
|
||||||
"Failed to revoke aws auth of identity with more privileged role",
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity
|
|
||||||
),
|
|
||||||
details: { missingPermissions: permissionBoundary.missingPermissions }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.RevokeAuth,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
|
||||||
|
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor: ActorType.IDENTITY,
|
||||||
|
actorId: identityMembershipOrg.identity.id,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
|
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
||||||
|
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity,
|
||||||
|
permission,
|
||||||
|
rolePermission
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!permissionBoundary.isValid)
|
||||||
|
throw new PermissionBoundaryError({
|
||||||
|
message: constructPermissionErrorMessage(
|
||||||
|
"Failed to revoke aws auth of identity with more privileged role",
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
),
|
||||||
|
details: { missingPermissions: permissionBoundary.missingPermissions }
|
||||||
|
});
|
||||||
|
}
|
||||||
const revokedIdentityAwsAuth = await identityAwsAuthDAL.transaction(async (tx) => {
|
const revokedIdentityAwsAuth = await identityAwsAuthDAL.transaction(async (tx) => {
|
||||||
const deletedAwsAuth = await identityAwsAuthDAL.delete({ identityId }, tx);
|
const deletedAwsAuth = await identityAwsAuthDAL.delete({ identityId }, tx);
|
||||||
await identityAccessTokenDAL.delete({ identityId, authMethod: IdentityAuthMethod.AWS_AUTH }, tx);
|
await identityAccessTokenDAL.delete({ identityId, authMethod: IdentityAuthMethod.AWS_AUTH }, tx);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
import { requestContext } from "@fastify/request-context";
|
import { requestContext } from "@fastify/request-context";
|
||||||
|
|
||||||
import { AccessScope, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
|
import { AccessScope, ActionProjectType, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
|
||||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||||
import {
|
import {
|
||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
validatePrivilegeChangeOperation
|
validatePrivilegeChangeOperation
|
||||||
} from "@app/ee/services/permission/permission-fns";
|
} from "@app/ee/services/permission/permission-fns";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
|
import { ProjectPermissionIdentityActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { crypto } from "@app/lib/crypto";
|
import { crypto } from "@app/lib/crypto";
|
||||||
import {
|
import {
|
||||||
@@ -46,7 +47,7 @@ type TIdentityAzureAuthServiceFactoryDep = {
|
|||||||
>;
|
>;
|
||||||
membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "update" | "getIdentityById">;
|
membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "update" | "getIdentityById">;
|
||||||
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">;
|
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission" | "getProjectPermission">;
|
||||||
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
||||||
orgDAL: Pick<TOrgDALFactory, "findById">;
|
orgDAL: Pick<TOrgDALFactory, "findById">;
|
||||||
};
|
};
|
||||||
@@ -99,7 +100,18 @@ export const identityAzureAuthServiceFactory = ({
|
|||||||
|
|
||||||
const identityAccessToken = await identityAzureAuthDAL.transaction(async (tx) => {
|
const identityAccessToken = await identityAzureAuthDAL.transaction(async (tx) => {
|
||||||
await membershipIdentityDAL.update(
|
await membershipIdentityDAL.update(
|
||||||
{ scope: AccessScope.Organization, scopeOrgId: identity.orgId, actorIdentityId: identity.id },
|
identity.projectId
|
||||||
|
? {
|
||||||
|
scope: AccessScope.Project,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
scopeProjectId: identity.projectId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
scope: AccessScope.Organization,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
},
|
||||||
{
|
{
|
||||||
lastLoginAuthMethod: IdentityAuthMethod.AZURE_AUTH,
|
lastLoginAuthMethod: IdentityAuthMethod.AZURE_AUTH,
|
||||||
lastLoginTime: new Date()
|
lastLoginTime: new Date()
|
||||||
@@ -205,16 +217,34 @@ export const identityAzureAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Create,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
OrgPermissionIdentityActions.Create,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
);
|
||||||
|
}
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
||||||
if (
|
if (
|
||||||
@@ -293,16 +323,31 @@ export const identityAzureAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Edit,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
||||||
if (
|
if (
|
||||||
@@ -359,16 +404,31 @@ export const identityAzureAuthServiceFactory = ({
|
|||||||
|
|
||||||
const identityAzureAuth = await identityAzureAuthDAL.findOne({ identityId });
|
const identityAzureAuth = await identityAzureAuthDAL.findOne({ identityId });
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Read,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
return { ...identityAzureAuth, orgId: identityMembershipOrg.scopeOrgId };
|
return { ...identityAzureAuth, orgId: identityMembershipOrg.scopeOrgId };
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -395,43 +455,59 @@ export const identityAzureAuthServiceFactory = ({
|
|||||||
message: "The identity does not have azure auth"
|
message: "The identity does not have azure auth"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
|
||||||
|
|
||||||
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
|
||||||
scope: OrganizationActionScope.Any,
|
|
||||||
actor: ActorType.IDENTITY,
|
|
||||||
actorId: identityMembershipOrg.identity.id,
|
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
|
||||||
actorAuthMethod,
|
|
||||||
actorOrgId
|
|
||||||
});
|
|
||||||
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
|
||||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity,
|
|
||||||
permission,
|
|
||||||
rolePermission
|
|
||||||
);
|
|
||||||
if (!permissionBoundary.isValid)
|
|
||||||
throw new PermissionBoundaryError({
|
|
||||||
message: constructPermissionErrorMessage(
|
|
||||||
"Failed to revoke azure auth of identity with more privileged role",
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity
|
|
||||||
),
|
|
||||||
details: { missingPermissions: permissionBoundary.missingPermissions }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.RevokeAuth,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
|
||||||
|
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor: ActorType.IDENTITY,
|
||||||
|
actorId: identityMembershipOrg.identity.id,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
||||||
|
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity,
|
||||||
|
permission,
|
||||||
|
rolePermission
|
||||||
|
);
|
||||||
|
if (!permissionBoundary.isValid)
|
||||||
|
throw new PermissionBoundaryError({
|
||||||
|
message: constructPermissionErrorMessage(
|
||||||
|
"Failed to revoke azure auth of identity with more privileged role",
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
),
|
||||||
|
details: { missingPermissions: permissionBoundary.missingPermissions }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const revokedIdentityAzureAuth = await identityAzureAuthDAL.transaction(async (tx) => {
|
const revokedIdentityAzureAuth = await identityAzureAuthDAL.transaction(async (tx) => {
|
||||||
const deletedAzureAuth = await identityAzureAuthDAL.delete({ identityId }, tx);
|
const deletedAzureAuth = await identityAzureAuthDAL.delete({ identityId }, tx);
|
||||||
await identityAccessTokenDAL.delete({ identityId, authMethod: IdentityAuthMethod.AZURE_AUTH }, tx);
|
await identityAccessTokenDAL.delete({ identityId, authMethod: IdentityAuthMethod.AZURE_AUTH }, tx);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
import { requestContext } from "@fastify/request-context";
|
import { requestContext } from "@fastify/request-context";
|
||||||
|
|
||||||
import { AccessScope, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
|
import { AccessScope, ActionProjectType, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
|
||||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||||
import {
|
import {
|
||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
validatePrivilegeChangeOperation
|
validatePrivilegeChangeOperation
|
||||||
} from "@app/ee/services/permission/permission-fns";
|
} from "@app/ee/services/permission/permission-fns";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
|
import { ProjectPermissionIdentityActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { crypto } from "@app/lib/crypto";
|
import { crypto } from "@app/lib/crypto";
|
||||||
import {
|
import {
|
||||||
@@ -44,7 +45,7 @@ type TIdentityGcpAuthServiceFactoryDep = {
|
|||||||
identityGcpAuthDAL: Pick<TIdentityGcpAuthDALFactory, "findOne" | "transaction" | "create" | "updateById" | "delete">;
|
identityGcpAuthDAL: Pick<TIdentityGcpAuthDALFactory, "findOne" | "transaction" | "create" | "updateById" | "delete">;
|
||||||
membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "update" | "getIdentityById">;
|
membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "update" | "getIdentityById">;
|
||||||
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">;
|
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission" | "getProjectPermission">;
|
||||||
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
||||||
orgDAL: Pick<TOrgDALFactory, "findById">;
|
orgDAL: Pick<TOrgDALFactory, "findById">;
|
||||||
};
|
};
|
||||||
@@ -139,7 +140,18 @@ export const identityGcpAuthServiceFactory = ({
|
|||||||
|
|
||||||
const identityAccessToken = await identityGcpAuthDAL.transaction(async (tx) => {
|
const identityAccessToken = await identityGcpAuthDAL.transaction(async (tx) => {
|
||||||
await membershipIdentityDAL.update(
|
await membershipIdentityDAL.update(
|
||||||
{ scope: AccessScope.Organization, scopeOrgId: identity.orgId, actorIdentityId: identity.id },
|
identity.projectId
|
||||||
|
? {
|
||||||
|
scope: AccessScope.Project,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
scopeProjectId: identity.projectId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
scope: AccessScope.Organization,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
},
|
||||||
{
|
{
|
||||||
lastLoginAuthMethod: IdentityAuthMethod.GCP_AUTH,
|
lastLoginAuthMethod: IdentityAuthMethod.GCP_AUTH,
|
||||||
lastLoginTime: new Date()
|
lastLoginTime: new Date()
|
||||||
@@ -246,16 +258,34 @@ export const identityGcpAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Create,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
OrgPermissionIdentityActions.Create,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
);
|
||||||
|
}
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
||||||
if (
|
if (
|
||||||
@@ -336,16 +366,31 @@ export const identityGcpAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Edit,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
||||||
if (
|
if (
|
||||||
@@ -404,16 +449,31 @@ export const identityGcpAuthServiceFactory = ({
|
|||||||
|
|
||||||
const identityGcpAuth = await identityGcpAuthDAL.findOne({ identityId });
|
const identityGcpAuth = await identityGcpAuthDAL.findOne({ identityId });
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Read,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
return { ...identityGcpAuth, orgId: identityMembershipOrg.scopeOrgId };
|
return { ...identityGcpAuth, orgId: identityMembershipOrg.scopeOrgId };
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -441,43 +501,58 @@ export const identityGcpAuthServiceFactory = ({
|
|||||||
message: "The identity does not have gcp auth"
|
message: "The identity does not have gcp auth"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
|
||||||
|
|
||||||
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
|
||||||
scope: OrganizationActionScope.Any,
|
|
||||||
actor: ActorType.IDENTITY,
|
|
||||||
actorId: identityMembershipOrg.identity.id,
|
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
|
||||||
actorAuthMethod,
|
|
||||||
actorOrgId
|
|
||||||
});
|
|
||||||
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
|
||||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity,
|
|
||||||
permission,
|
|
||||||
rolePermission
|
|
||||||
);
|
|
||||||
if (!permissionBoundary.isValid)
|
|
||||||
throw new PermissionBoundaryError({
|
|
||||||
message: constructPermissionErrorMessage(
|
|
||||||
"Failed to revoke gcp auth of identity with more privileged role",
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity
|
|
||||||
),
|
|
||||||
details: { missingPermissions: permissionBoundary.missingPermissions }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.RevokeAuth,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor: ActorType.IDENTITY,
|
||||||
|
actorId: identityMembershipOrg.identity.id,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
||||||
|
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity,
|
||||||
|
permission,
|
||||||
|
rolePermission
|
||||||
|
);
|
||||||
|
if (!permissionBoundary.isValid)
|
||||||
|
throw new PermissionBoundaryError({
|
||||||
|
message: constructPermissionErrorMessage(
|
||||||
|
"Failed to revoke gcp auth of identity with more privileged role",
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
),
|
||||||
|
details: { missingPermissions: permissionBoundary.missingPermissions }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const revokedIdentityGcpAuth = await identityGcpAuthDAL.transaction(async (tx) => {
|
const revokedIdentityGcpAuth = await identityGcpAuthDAL.transaction(async (tx) => {
|
||||||
const deletedGcpAuth = await identityGcpAuthDAL.delete({ identityId }, tx);
|
const deletedGcpAuth = await identityGcpAuthDAL.delete({ identityId }, tx);
|
||||||
await identityAccessTokenDAL.delete({ identityId, authMethod: IdentityAuthMethod.GCP_AUTH }, tx);
|
await identityAccessTokenDAL.delete({ identityId, authMethod: IdentityAuthMethod.GCP_AUTH }, tx);
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
import { requestContext } from "@fastify/request-context";
|
import { requestContext } from "@fastify/request-context";
|
||||||
import https from "https";
|
import https from "https";
|
||||||
import jwt from "jsonwebtoken";
|
import jwt from "jsonwebtoken";
|
||||||
import { JwksClient } from "jwks-rsa";
|
import { JwksClient } from "jwks-rsa";
|
||||||
|
|
||||||
import { AccessScope, IdentityAuthMethod, OrganizationActionScope, TIdentityJwtAuthsUpdate } from "@app/db/schemas";
|
import {
|
||||||
|
AccessScope,
|
||||||
|
ActionProjectType,
|
||||||
|
IdentityAuthMethod,
|
||||||
|
OrganizationActionScope,
|
||||||
|
TIdentityJwtAuthsUpdate
|
||||||
|
} from "@app/db/schemas";
|
||||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||||
import {
|
import {
|
||||||
@@ -12,6 +18,7 @@ import {
|
|||||||
validatePrivilegeChangeOperation
|
validatePrivilegeChangeOperation
|
||||||
} from "@app/ee/services/permission/permission-fns";
|
} from "@app/ee/services/permission/permission-fns";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
|
import { ProjectPermissionIdentityActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { crypto } from "@app/lib/crypto";
|
import { crypto } from "@app/lib/crypto";
|
||||||
import {
|
import {
|
||||||
@@ -50,7 +57,7 @@ type TIdentityJwtAuthServiceFactoryDep = {
|
|||||||
identityJwtAuthDAL: TIdentityJwtAuthDALFactory;
|
identityJwtAuthDAL: TIdentityJwtAuthDALFactory;
|
||||||
membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "update" | "getIdentityById">;
|
membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "update" | "getIdentityById">;
|
||||||
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">;
|
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission" | "getProjectPermission">;
|
||||||
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
||||||
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
|
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
|
||||||
orgDAL: Pick<TOrgDALFactory, "findById">;
|
orgDAL: Pick<TOrgDALFactory, "findById">;
|
||||||
@@ -213,8 +220,22 @@ export const identityJwtAuthServiceFactory = ({
|
|||||||
|
|
||||||
const identityAccessToken = await identityJwtAuthDAL.transaction(async (tx) => {
|
const identityAccessToken = await identityJwtAuthDAL.transaction(async (tx) => {
|
||||||
await membershipIdentityDAL.update(
|
await membershipIdentityDAL.update(
|
||||||
{ scope: AccessScope.Organization, scopeOrgId: identity.orgId, actorIdentityId: identity.id },
|
identity.projectId
|
||||||
{ lastLoginAuthMethod: IdentityAuthMethod.JWT_AUTH, lastLoginTime: new Date() },
|
? {
|
||||||
|
scope: AccessScope.Project,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
scopeProjectId: identity.projectId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
scope: AccessScope.Organization,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lastLoginAuthMethod: IdentityAuthMethod.JWT_AUTH,
|
||||||
|
lastLoginTime: new Date()
|
||||||
|
},
|
||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
const newToken = await identityAccessTokenDAL.create(
|
const newToken = await identityAccessTokenDAL.create(
|
||||||
@@ -322,16 +343,35 @@ export const identityJwtAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Create,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
OrgPermissionIdentityActions.Create,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
||||||
@@ -435,17 +475,32 @@ export const identityJwtAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Edit,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
||||||
if (
|
if (
|
||||||
@@ -534,17 +589,32 @@ export const identityJwtAuthServiceFactory = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Read,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
const identityJwtAuth = await identityJwtAuthDAL.findOne({ identityId });
|
const identityJwtAuth = await identityJwtAuthDAL.findOne({ identityId });
|
||||||
|
|
||||||
const { decryptor: orgDataKeyDecryptor } = await kmsService.createCipherPairWithDataKey({
|
const { decryptor: orgDataKeyDecryptor } = await kmsService.createCipherPairWithDataKey({
|
||||||
@@ -586,45 +656,60 @@ export const identityJwtAuthServiceFactory = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
|
||||||
|
|
||||||
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
|
||||||
scope: OrganizationActionScope.Any,
|
|
||||||
actor: ActorType.IDENTITY,
|
|
||||||
actorId: identityMembershipOrg.identity.id,
|
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
|
||||||
actorAuthMethod,
|
|
||||||
actorOrgId
|
|
||||||
});
|
|
||||||
|
|
||||||
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
|
||||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity,
|
|
||||||
permission,
|
|
||||||
rolePermission
|
|
||||||
);
|
|
||||||
if (!permissionBoundary.isValid)
|
|
||||||
throw new PermissionBoundaryError({
|
|
||||||
message: constructPermissionErrorMessage(
|
|
||||||
"Failed to revoke jwt auth of identity with more privileged role",
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity
|
|
||||||
),
|
|
||||||
details: { missingPermissions: permissionBoundary.missingPermissions }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.RevokeAuth,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
|
||||||
|
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor: ActorType.IDENTITY,
|
||||||
|
actorId: identityMembershipOrg.identity.id,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
|
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
||||||
|
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity,
|
||||||
|
permission,
|
||||||
|
rolePermission
|
||||||
|
);
|
||||||
|
if (!permissionBoundary.isValid)
|
||||||
|
throw new PermissionBoundaryError({
|
||||||
|
message: constructPermissionErrorMessage(
|
||||||
|
"Failed to revoke jwt auth of identity with more privileged role",
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
),
|
||||||
|
details: { missingPermissions: permissionBoundary.missingPermissions }
|
||||||
|
});
|
||||||
|
}
|
||||||
const revokedIdentityJwtAuth = await identityJwtAuthDAL.transaction(async (tx) => {
|
const revokedIdentityJwtAuth = await identityJwtAuthDAL.transaction(async (tx) => {
|
||||||
const deletedJwtAuth = await identityJwtAuthDAL.delete({ identityId }, tx);
|
const deletedJwtAuth = await identityJwtAuthDAL.delete({ identityId }, tx);
|
||||||
await identityAccessTokenDAL.delete({ identityId, authMethod: IdentityAuthMethod.JWT_AUTH }, tx);
|
await identityAccessTokenDAL.delete({ identityId, authMethod: IdentityAuthMethod.JWT_AUTH }, tx);
|
||||||
|
|||||||
+145
-66
@@ -1,4 +1,4 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
import { requestContext } from "@fastify/request-context";
|
import { requestContext } from "@fastify/request-context";
|
||||||
import axios, { AxiosError } from "axios";
|
import axios, { AxiosError } from "axios";
|
||||||
import https from "https";
|
import https from "https";
|
||||||
@@ -6,6 +6,7 @@ import RE2 from "re2";
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
AccessScope,
|
AccessScope,
|
||||||
|
ActionProjectType,
|
||||||
IdentityAuthMethod,
|
IdentityAuthMethod,
|
||||||
OrganizationActionScope,
|
OrganizationActionScope,
|
||||||
TIdentityKubernetesAuthsUpdate
|
TIdentityKubernetesAuthsUpdate
|
||||||
@@ -25,6 +26,7 @@ import {
|
|||||||
validatePrivilegeChangeOperation
|
validatePrivilegeChangeOperation
|
||||||
} from "@app/ee/services/permission/permission-fns";
|
} from "@app/ee/services/permission/permission-fns";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
|
import { ProjectPermissionIdentityActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { crypto } from "@app/lib/crypto";
|
import { crypto } from "@app/lib/crypto";
|
||||||
import {
|
import {
|
||||||
@@ -69,7 +71,7 @@ type TIdentityKubernetesAuthServiceFactoryDep = {
|
|||||||
>;
|
>;
|
||||||
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">;
|
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">;
|
||||||
membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "update" | "getIdentityById">;
|
membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "update" | "getIdentityById">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission" | "getProjectPermission">;
|
||||||
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
||||||
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
|
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
|
||||||
gatewayService: TGatewayServiceFactory;
|
gatewayService: TGatewayServiceFactory;
|
||||||
@@ -448,8 +450,22 @@ export const identityKubernetesAuthServiceFactory = ({
|
|||||||
|
|
||||||
const identityAccessToken = await identityKubernetesAuthDAL.transaction(async (tx) => {
|
const identityAccessToken = await identityKubernetesAuthDAL.transaction(async (tx) => {
|
||||||
await membershipIdentityDAL.update(
|
await membershipIdentityDAL.update(
|
||||||
{ scope: AccessScope.Organization, scopeOrgId: identity.orgId, actorIdentityId: identity.id },
|
identity.projectId
|
||||||
{ lastLoginAuthMethod: IdentityAuthMethod.KUBERNETES_AUTH, lastLoginTime: new Date() },
|
? {
|
||||||
|
scope: AccessScope.Project,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
scopeProjectId: identity.projectId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
scope: AccessScope.Organization,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lastLoginAuthMethod: IdentityAuthMethod.KUBERNETES_AUTH,
|
||||||
|
lastLoginTime: new Date()
|
||||||
|
},
|
||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
const newToken = await identityAccessTokenDAL.create(
|
const newToken = await identityAccessTokenDAL.create(
|
||||||
@@ -563,16 +579,34 @@ export const identityKubernetesAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Create,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
OrgPermissionIdentityActions.Create,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
);
|
||||||
|
}
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
||||||
if (
|
if (
|
||||||
@@ -699,16 +733,31 @@ export const identityKubernetesAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Edit,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
||||||
if (
|
if (
|
||||||
@@ -846,16 +895,31 @@ export const identityKubernetesAuthServiceFactory = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Read,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
const { decryptor } = await kmsService.createCipherPairWithDataKey({
|
const { decryptor } = await kmsService.createCipherPairWithDataKey({
|
||||||
type: KmsDataKey.Organization,
|
type: KmsDataKey.Organization,
|
||||||
orgId: identityMembershipOrg.scopeOrgId
|
orgId: identityMembershipOrg.scopeOrgId
|
||||||
@@ -906,43 +970,58 @@ export const identityKubernetesAuthServiceFactory = ({
|
|||||||
message: "The identity does not have kubernetes auth"
|
message: "The identity does not have kubernetes auth"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
|
||||||
|
|
||||||
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
|
||||||
actor: ActorType.IDENTITY,
|
|
||||||
actorId: identityMembershipOrg.identity.id,
|
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
|
||||||
actorAuthMethod,
|
|
||||||
actorOrgId,
|
|
||||||
scope: OrganizationActionScope.Any
|
|
||||||
});
|
|
||||||
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
|
||||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity,
|
|
||||||
permission,
|
|
||||||
rolePermission
|
|
||||||
);
|
|
||||||
if (!permissionBoundary.isValid)
|
|
||||||
throw new PermissionBoundaryError({
|
|
||||||
message: constructPermissionErrorMessage(
|
|
||||||
"Failed to revoke kubernetes auth of identity with more privileged role",
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity
|
|
||||||
),
|
|
||||||
details: { missingPermissions: permissionBoundary.missingPermissions }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.RevokeAuth,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
|
||||||
|
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
||||||
|
actor: ActorType.IDENTITY,
|
||||||
|
actorId: identityMembershipOrg.identity.id,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId,
|
||||||
|
scope: OrganizationActionScope.Any
|
||||||
|
});
|
||||||
|
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
||||||
|
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity,
|
||||||
|
permission,
|
||||||
|
rolePermission
|
||||||
|
);
|
||||||
|
if (!permissionBoundary.isValid)
|
||||||
|
throw new PermissionBoundaryError({
|
||||||
|
message: constructPermissionErrorMessage(
|
||||||
|
"Failed to revoke kubernetes auth of identity with more privileged role",
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
),
|
||||||
|
details: { missingPermissions: permissionBoundary.missingPermissions }
|
||||||
|
});
|
||||||
|
}
|
||||||
const revokedIdentityKubernetesAuth = await identityKubernetesAuthDAL.transaction(async (tx) => {
|
const revokedIdentityKubernetesAuth = await identityKubernetesAuthDAL.transaction(async (tx) => {
|
||||||
const deletedKubernetesAuth = await identityKubernetesAuthDAL.delete({ identityId }, tx);
|
const deletedKubernetesAuth = await identityKubernetesAuthDAL.delete({ identityId }, tx);
|
||||||
await identityAccessTokenDAL.delete({ identityId, authMethod: IdentityAuthMethod.KUBERNETES_AUTH }, tx);
|
await identityAccessTokenDAL.delete({ identityId, authMethod: IdentityAuthMethod.KUBERNETES_AUTH }, tx);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
import { requestContext } from "@fastify/request-context";
|
import { requestContext } from "@fastify/request-context";
|
||||||
import slugify from "@sindresorhus/slugify";
|
import slugify from "@sindresorhus/slugify";
|
||||||
|
|
||||||
import { AccessScope, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
|
import { AccessScope, ActionProjectType, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
|
||||||
import { TIdentityAuthTemplateDALFactory } from "@app/ee/services/identity-auth-template";
|
import { TIdentityAuthTemplateDALFactory } from "@app/ee/services/identity-auth-template";
|
||||||
import { testLDAPConfig } from "@app/ee/services/ldap-config/ldap-fns";
|
import { testLDAPConfig } from "@app/ee/services/ldap-config/ldap-fns";
|
||||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
validatePrivilegeChangeOperation
|
validatePrivilegeChangeOperation
|
||||||
} from "@app/ee/services/permission/permission-fns";
|
} from "@app/ee/services/permission/permission-fns";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
|
import { ProjectPermissionIdentityActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { KeyStorePrefixes, TKeyStoreFactory } from "@app/keystore/keystore";
|
import { KeyStorePrefixes, TKeyStoreFactory } from "@app/keystore/keystore";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { crypto } from "@app/lib/crypto";
|
import { crypto } from "@app/lib/crypto";
|
||||||
@@ -61,7 +62,7 @@ type TIdentityLdapAuthServiceFactoryDep = {
|
|||||||
>;
|
>;
|
||||||
membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "update" | "getIdentityById">;
|
membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "update" | "getIdentityById">;
|
||||||
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission" | "getProjectPermission">;
|
||||||
kmsService: TKmsServiceFactory;
|
kmsService: TKmsServiceFactory;
|
||||||
identityDAL: Pick<TIdentityDALFactory, "findById" | "findOne">;
|
identityDAL: Pick<TIdentityDALFactory, "findById" | "findOne">;
|
||||||
identityAuthTemplateDAL: TIdentityAuthTemplateDALFactory;
|
identityAuthTemplateDAL: TIdentityAuthTemplateDALFactory;
|
||||||
@@ -177,8 +178,22 @@ export const identityLdapAuthServiceFactory = ({
|
|||||||
try {
|
try {
|
||||||
const identityAccessToken = await identityLdapAuthDAL.transaction(async (tx) => {
|
const identityAccessToken = await identityLdapAuthDAL.transaction(async (tx) => {
|
||||||
await membershipIdentityDAL.update(
|
await membershipIdentityDAL.update(
|
||||||
{ scope: AccessScope.Organization, scopeOrgId: identity.orgId, actorIdentityId: identity.id },
|
identity.projectId
|
||||||
{ lastLoginAuthMethod: IdentityAuthMethod.LDAP_AUTH, lastLoginTime: new Date() },
|
? {
|
||||||
|
scope: AccessScope.Project,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
scopeProjectId: identity.projectId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
scope: AccessScope.Organization,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lastLoginAuthMethod: IdentityAuthMethod.LDAP_AUTH,
|
||||||
|
lastLoginTime: new Date()
|
||||||
|
},
|
||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
const newToken = await identityAccessTokenDAL.create(
|
const newToken = await identityAccessTokenDAL.create(
|
||||||
@@ -290,7 +305,7 @@ export const identityLdapAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
const { permission: orgPermission } = await permissionService.getOrgPermission({
|
||||||
scope: OrganizationActionScope.Any,
|
scope: OrganizationActionScope.Any,
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
@@ -298,10 +313,30 @@ export const identityLdapAuthServiceFactory = ({
|
|||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId
|
actorOrgId
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
|
|
||||||
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
|
const { permission: projectPermission } = await permissionService.getProjectPermission({
|
||||||
|
actionProjectType: ActionProjectType.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(projectPermission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Create,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
ForbiddenError.from(orgPermission).throwUnlessCan(
|
||||||
|
OrgPermissionIdentityActions.Create,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (templateId) {
|
if (templateId) {
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(orgPermission).throwUnlessCan(
|
||||||
OrgPermissionMachineIdentityAuthTemplateActions.AttachTemplates,
|
OrgPermissionMachineIdentityAuthTemplateActions.AttachTemplates,
|
||||||
OrgPermissionSubjects.MachineIdentityAuthTemplate
|
OrgPermissionSubjects.MachineIdentityAuthTemplate
|
||||||
);
|
);
|
||||||
@@ -470,7 +505,7 @@ export const identityLdapAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
const { permission: orgPermission } = await permissionService.getOrgPermission({
|
||||||
scope: OrganizationActionScope.Any,
|
scope: OrganizationActionScope.Any,
|
||||||
actor,
|
actor,
|
||||||
actorId,
|
actorId,
|
||||||
@@ -478,10 +513,30 @@ export const identityLdapAuthServiceFactory = ({
|
|||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId
|
actorOrgId
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
|
||||||
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
|
const { permission: projectPermission } = await permissionService.getProjectPermission({
|
||||||
|
actionProjectType: ActionProjectType.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(projectPermission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Create,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
ForbiddenError.from(orgPermission).throwUnlessCan(
|
||||||
|
OrgPermissionIdentityActions.Edit,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (templateId) {
|
if (templateId) {
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(orgPermission).throwUnlessCan(
|
||||||
OrgPermissionMachineIdentityAuthTemplateActions.AttachTemplates,
|
OrgPermissionMachineIdentityAuthTemplateActions.AttachTemplates,
|
||||||
OrgPermissionSubjects.MachineIdentityAuthTemplate
|
OrgPermissionSubjects.MachineIdentityAuthTemplate
|
||||||
);
|
);
|
||||||
@@ -630,14 +685,31 @@ export const identityLdapAuthServiceFactory = ({
|
|||||||
|
|
||||||
const ldapIdentityAuth = await identityLdapAuthDAL.findOne({ identityId });
|
const ldapIdentityAuth = await identityLdapAuthDAL.findOne({ identityId });
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Read,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
|
|
||||||
const { decryptor } = await kmsService.createCipherPairWithDataKey({
|
const { decryptor } = await kmsService.createCipherPairWithDataKey({
|
||||||
type: KmsDataKey.Organization,
|
type: KmsDataKey.Organization,
|
||||||
@@ -650,7 +722,6 @@ export const identityLdapAuthServiceFactory = ({
|
|||||||
? decryptor({ cipherTextBlob: ldapIdentityAuth.encryptedLdapCaCertificate }).toString()
|
? decryptor({ cipherTextBlob: ldapIdentityAuth.encryptedLdapCaCertificate }).toString()
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
|
||||||
return { ...ldapIdentityAuth, orgId: identityMembershipOrg.scopeOrgId, bindDN, bindPass, ldapCaCertificate };
|
return { ...ldapIdentityAuth, orgId: identityMembershipOrg.scopeOrgId, bindDN, bindPass, ldapCaCertificate };
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -677,45 +748,62 @@ export const identityLdapAuthServiceFactory = ({
|
|||||||
message: "The identity does not have LDAP Auth attached"
|
message: "The identity does not have LDAP Auth attached"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
|
||||||
scope: OrganizationActionScope.Any,
|
|
||||||
actor,
|
|
||||||
actorId,
|
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
|
||||||
actorAuthMethod,
|
|
||||||
actorOrgId
|
|
||||||
});
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
|
||||||
|
|
||||||
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
actor: ActorType.IDENTITY,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actorId: identityMembershipOrg.identity.id,
|
actionProjectType: ActionProjectType.Any,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actor,
|
||||||
actorAuthMethod,
|
actorId,
|
||||||
actorOrgId,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
scope: OrganizationActionScope.Any
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
|
|
||||||
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
|
||||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity,
|
|
||||||
permission,
|
|
||||||
rolePermission
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!permissionBoundary.isValid)
|
|
||||||
throw new PermissionBoundaryError({
|
|
||||||
message: constructPermissionErrorMessage(
|
|
||||||
"Failed to revoke LDAP auth of identity with more privileged role",
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity
|
|
||||||
),
|
|
||||||
details: { missingPermissions: permissionBoundary.missingPermissions }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.RevokeAuth,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
|
||||||
|
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
||||||
|
actor: ActorType.IDENTITY,
|
||||||
|
actorId: identityMembershipOrg.identity.id,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId,
|
||||||
|
scope: OrganizationActionScope.Any
|
||||||
|
});
|
||||||
|
|
||||||
|
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
||||||
|
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity,
|
||||||
|
permission,
|
||||||
|
rolePermission
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!permissionBoundary.isValid)
|
||||||
|
throw new PermissionBoundaryError({
|
||||||
|
message: constructPermissionErrorMessage(
|
||||||
|
"Failed to revoke LDAP auth of identity with more privileged role",
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
),
|
||||||
|
details: { missingPermissions: permissionBoundary.missingPermissions }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const revokedIdentityLdapAuth = await identityLdapAuthDAL.transaction(async (tx) => {
|
const revokedIdentityLdapAuth = await identityLdapAuthDAL.transaction(async (tx) => {
|
||||||
const [deletedLdapAuth] = await identityLdapAuthDAL.delete({ identityId }, tx);
|
const [deletedLdapAuth] = await identityLdapAuthDAL.delete({ identityId }, tx);
|
||||||
await identityAccessTokenDAL.delete({ identityId, authMethod: IdentityAuthMethod.LDAP_AUTH }, tx);
|
await identityAccessTokenDAL.delete({ identityId, authMethod: IdentityAuthMethod.LDAP_AUTH }, tx);
|
||||||
@@ -824,15 +912,31 @@ export const identityLdapAuthServiceFactory = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Edit,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
|
|
||||||
const deleted = await keyStore.deleteItems({
|
const deleted = await keyStore.deleteItems({
|
||||||
pattern: `lockout:identity:${identityId}:${IdentityAuthMethod.LDAP_AUTH}:*`
|
pattern: `lockout:identity:${identityId}:${IdentityAuthMethod.LDAP_AUTH}:*`
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
import { requestContext } from "@fastify/request-context";
|
import { requestContext } from "@fastify/request-context";
|
||||||
import { AxiosError } from "axios";
|
import { AxiosError } from "axios";
|
||||||
import RE2 from "re2";
|
import RE2 from "re2";
|
||||||
|
|
||||||
import { AccessScope, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
|
import { AccessScope, ActionProjectType, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
|
||||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||||
import {
|
import {
|
||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
validatePrivilegeChangeOperation
|
validatePrivilegeChangeOperation
|
||||||
} from "@app/ee/services/permission/permission-fns";
|
} from "@app/ee/services/permission/permission-fns";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
|
import { ProjectPermissionIdentityActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { request } from "@app/lib/config/request";
|
import { request } from "@app/lib/config/request";
|
||||||
import { crypto } from "@app/lib/crypto";
|
import { crypto } from "@app/lib/crypto";
|
||||||
@@ -49,7 +50,7 @@ type TIdentityOciAuthServiceFactoryDep = {
|
|||||||
identityOciAuthDAL: Pick<TIdentityOciAuthDALFactory, "findOne" | "transaction" | "create" | "updateById" | "delete">;
|
identityOciAuthDAL: Pick<TIdentityOciAuthDALFactory, "findOne" | "transaction" | "create" | "updateById" | "delete">;
|
||||||
membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "update" | "getIdentityById">;
|
membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "update" | "getIdentityById">;
|
||||||
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission" | "getProjectPermission">;
|
||||||
orgDAL: Pick<TOrgDALFactory, "findById">;
|
orgDAL: Pick<TOrgDALFactory, "findById">;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -110,8 +111,22 @@ export const identityOciAuthServiceFactory = ({
|
|||||||
// Generate the token
|
// Generate the token
|
||||||
const identityAccessToken = await identityOciAuthDAL.transaction(async (tx) => {
|
const identityAccessToken = await identityOciAuthDAL.transaction(async (tx) => {
|
||||||
await membershipIdentityDAL.update(
|
await membershipIdentityDAL.update(
|
||||||
{ scope: AccessScope.Organization, scopeOrgId: identity.orgId, actorIdentityId: identity.id },
|
identity.projectId
|
||||||
{ lastLoginAuthMethod: IdentityAuthMethod.OCI_AUTH, lastLoginTime: new Date() },
|
? {
|
||||||
|
scope: AccessScope.Project,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
scopeProjectId: identity.projectId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
scope: AccessScope.Organization,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lastLoginAuthMethod: IdentityAuthMethod.OCI_AUTH,
|
||||||
|
lastLoginTime: new Date()
|
||||||
|
},
|
||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
const newToken = await identityAccessTokenDAL.create(
|
const newToken = await identityAccessTokenDAL.create(
|
||||||
@@ -217,15 +232,34 @@ export const identityOciAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Create,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
OrgPermissionIdentityActions.Create,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
||||||
@@ -304,15 +338,31 @@ export const identityOciAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Edit,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
|
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
||||||
@@ -367,15 +417,31 @@ export const identityOciAuthServiceFactory = ({
|
|||||||
|
|
||||||
const ociIdentityAuth = await identityOciAuthDAL.findOne({ identityId });
|
const ociIdentityAuth = await identityOciAuthDAL.findOne({ identityId });
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Read,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
return { ...ociIdentityAuth, orgId: identityMembershipOrg.scopeOrgId };
|
return { ...ociIdentityAuth, orgId: identityMembershipOrg.scopeOrgId };
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -402,45 +468,62 @@ export const identityOciAuthServiceFactory = ({
|
|||||||
message: "The identity does not have OCI auth"
|
message: "The identity does not have OCI auth"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
|
||||||
scope: OrganizationActionScope.Any,
|
|
||||||
actor,
|
|
||||||
actorId,
|
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
|
||||||
actorAuthMethod,
|
|
||||||
actorOrgId
|
|
||||||
});
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
|
||||||
|
|
||||||
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
actor: ActorType.IDENTITY,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actorId: identityMembershipOrg.identity.id,
|
actionProjectType: ActionProjectType.Any,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actor,
|
||||||
actorAuthMethod,
|
actorId,
|
||||||
actorOrgId,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
scope: OrganizationActionScope.Any
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
|
|
||||||
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(actorOrgId);
|
|
||||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity,
|
|
||||||
permission,
|
|
||||||
rolePermission
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!permissionBoundary.isValid)
|
|
||||||
throw new PermissionBoundaryError({
|
|
||||||
message: constructPermissionErrorMessage(
|
|
||||||
"Failed to revoke OCI auth of identity with more privileged role",
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity
|
|
||||||
),
|
|
||||||
details: { missingPermissions: permissionBoundary.missingPermissions }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.RevokeAuth,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
|
||||||
|
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
||||||
|
actor: ActorType.IDENTITY,
|
||||||
|
actorId: identityMembershipOrg.identity.id,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId,
|
||||||
|
scope: OrganizationActionScope.Any
|
||||||
|
});
|
||||||
|
|
||||||
|
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(actorOrgId);
|
||||||
|
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity,
|
||||||
|
permission,
|
||||||
|
rolePermission
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!permissionBoundary.isValid)
|
||||||
|
throw new PermissionBoundaryError({
|
||||||
|
message: constructPermissionErrorMessage(
|
||||||
|
"Failed to revoke OCI auth of identity with more privileged role",
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
),
|
||||||
|
details: { missingPermissions: permissionBoundary.missingPermissions }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const revokedIdentityOciAuth = await identityOciAuthDAL.transaction(async (tx) => {
|
const revokedIdentityOciAuth = await identityOciAuthDAL.transaction(async (tx) => {
|
||||||
const deletedOciAuth = await identityOciAuthDAL.delete({ identityId }, tx);
|
const deletedOciAuth = await identityOciAuthDAL.delete({ identityId }, tx);
|
||||||
await identityAccessTokenDAL.delete({ identityId, authMethod: IdentityAuthMethod.OCI_AUTH }, tx);
|
await identityAccessTokenDAL.delete({ identityId, authMethod: IdentityAuthMethod.OCI_AUTH }, tx);
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
import { requestContext } from "@fastify/request-context";
|
import { requestContext } from "@fastify/request-context";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import https from "https";
|
import https from "https";
|
||||||
import jwt from "jsonwebtoken";
|
import jwt from "jsonwebtoken";
|
||||||
import { JwksClient } from "jwks-rsa";
|
import { JwksClient } from "jwks-rsa";
|
||||||
|
|
||||||
import { AccessScope, IdentityAuthMethod, OrganizationActionScope, TIdentityOidcAuthsUpdate } from "@app/db/schemas";
|
import {
|
||||||
|
AccessScope,
|
||||||
|
ActionProjectType,
|
||||||
|
IdentityAuthMethod,
|
||||||
|
OrganizationActionScope,
|
||||||
|
TIdentityOidcAuthsUpdate
|
||||||
|
} from "@app/db/schemas";
|
||||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||||
import {
|
import {
|
||||||
@@ -13,6 +19,7 @@ import {
|
|||||||
validatePrivilegeChangeOperation
|
validatePrivilegeChangeOperation
|
||||||
} from "@app/ee/services/permission/permission-fns";
|
} from "@app/ee/services/permission/permission-fns";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
|
import { ProjectPermissionIdentityActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { crypto } from "@app/lib/crypto";
|
import { crypto } from "@app/lib/crypto";
|
||||||
import {
|
import {
|
||||||
@@ -51,7 +58,7 @@ type TIdentityOidcAuthServiceFactoryDep = {
|
|||||||
identityOidcAuthDAL: TIdentityOidcAuthDALFactory;
|
identityOidcAuthDAL: TIdentityOidcAuthDALFactory;
|
||||||
membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "update" | "getIdentityById">;
|
membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "update" | "getIdentityById">;
|
||||||
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">;
|
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission" | "getProjectPermission">;
|
||||||
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
||||||
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
|
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
|
||||||
orgDAL: Pick<TOrgDALFactory, "findById">;
|
orgDAL: Pick<TOrgDALFactory, "findById">;
|
||||||
@@ -266,8 +273,22 @@ export const identityOidcAuthServiceFactory = ({
|
|||||||
|
|
||||||
const identityAccessToken = await identityOidcAuthDAL.transaction(async (tx) => {
|
const identityAccessToken = await identityOidcAuthDAL.transaction(async (tx) => {
|
||||||
await membershipIdentityDAL.update(
|
await membershipIdentityDAL.update(
|
||||||
{ scope: AccessScope.Organization, scopeOrgId: identity.orgId, actorIdentityId: identity.id },
|
identity.projectId
|
||||||
{ lastLoginAuthMethod: IdentityAuthMethod.OIDC_AUTH, lastLoginTime: new Date() },
|
? {
|
||||||
|
scope: AccessScope.Project,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
scopeProjectId: identity.projectId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
scope: AccessScope.Organization,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lastLoginAuthMethod: IdentityAuthMethod.OIDC_AUTH,
|
||||||
|
lastLoginTime: new Date()
|
||||||
|
},
|
||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
const newToken = await identityAccessTokenDAL.create(
|
const newToken = await identityAccessTokenDAL.create(
|
||||||
@@ -379,16 +400,35 @@ export const identityOidcAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Create,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
OrgPermissionIdentityActions.Create,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
||||||
@@ -481,16 +521,32 @@ export const identityOidcAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Edit,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
|
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
||||||
@@ -565,15 +621,31 @@ export const identityOidcAuthServiceFactory = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Read,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
|
|
||||||
const identityOidcAuth = await identityOidcAuthDAL.findOne({ identityId });
|
const identityOidcAuth = await identityOidcAuthDAL.findOne({ identityId });
|
||||||
|
|
||||||
@@ -610,46 +682,62 @@ export const identityOidcAuthServiceFactory = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
|
||||||
|
|
||||||
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
|
||||||
actor: ActorType.IDENTITY,
|
|
||||||
actorId: identityMembershipOrg.identity.id,
|
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
|
||||||
actorAuthMethod,
|
|
||||||
actorOrgId,
|
|
||||||
scope: OrganizationActionScope.Any
|
|
||||||
});
|
|
||||||
|
|
||||||
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
|
||||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity,
|
|
||||||
permission,
|
|
||||||
rolePermission
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!permissionBoundary.isValid)
|
|
||||||
throw new PermissionBoundaryError({
|
|
||||||
message: constructPermissionErrorMessage(
|
|
||||||
"Failed to revoke oidc auth of identity with more privileged role",
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity
|
|
||||||
),
|
|
||||||
details: { missingPermissions: permissionBoundary.missingPermissions }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.RevokeAuth,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
|
||||||
|
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
||||||
|
actor: ActorType.IDENTITY,
|
||||||
|
actorId: identityMembershipOrg.identity.id,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId,
|
||||||
|
scope: OrganizationActionScope.Any
|
||||||
|
});
|
||||||
|
|
||||||
|
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
||||||
|
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity,
|
||||||
|
permission,
|
||||||
|
rolePermission
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!permissionBoundary.isValid)
|
||||||
|
throw new PermissionBoundaryError({
|
||||||
|
message: constructPermissionErrorMessage(
|
||||||
|
"Failed to revoke oidc auth of identity with more privileged role",
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
),
|
||||||
|
details: { missingPermissions: permissionBoundary.missingPermissions }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const revokedIdentityOidcAuth = await identityOidcAuthDAL.transaction(async (tx) => {
|
const revokedIdentityOidcAuth = await identityOidcAuthDAL.transaction(async (tx) => {
|
||||||
const deletedOidcAuth = await identityOidcAuthDAL.delete({ identityId }, tx);
|
const deletedOidcAuth = await identityOidcAuthDAL.delete({ identityId }, tx);
|
||||||
await identityAccessTokenDAL.delete({ identityId, authMethod: IdentityAuthMethod.OIDC_AUTH }, tx);
|
await identityAccessTokenDAL.delete({ identityId, authMethod: IdentityAuthMethod.OIDC_AUTH }, tx);
|
||||||
|
|||||||
@@ -293,7 +293,11 @@ export const identityProjectDALFactory = (db: TDbClient) => {
|
|||||||
db.ref("authMethod").as("identityAuthMethod").withSchema(TableName.Identity),
|
db.ref("authMethod").as("identityAuthMethod").withSchema(TableName.Identity),
|
||||||
db.ref("id").as("identityId").withSchema(TableName.Identity),
|
db.ref("id").as("identityId").withSchema(TableName.Identity),
|
||||||
db.ref("name").as("identityName").withSchema(TableName.Identity),
|
db.ref("name").as("identityName").withSchema(TableName.Identity),
|
||||||
|
db.ref("orgId").as("identityOrgId").withSchema(TableName.Identity),
|
||||||
|
db.ref("projectId").as("identityProjectId").withSchema(TableName.Identity),
|
||||||
db.ref("id").withSchema(TableName.Membership),
|
db.ref("id").withSchema(TableName.Membership),
|
||||||
|
db.ref("lastLoginAuthMethod").withSchema(TableName.Membership),
|
||||||
|
db.ref("lastLoginTime").withSchema(TableName.Membership),
|
||||||
db.ref("role").withSchema(TableName.MembershipRole),
|
db.ref("role").withSchema(TableName.MembershipRole),
|
||||||
db.ref("id").withSchema(TableName.MembershipRole).as("membershipRoleId"),
|
db.ref("id").withSchema(TableName.MembershipRole).as("membershipRoleId"),
|
||||||
db.ref("customRoleId").withSchema(TableName.MembershipRole),
|
db.ref("customRoleId").withSchema(TableName.MembershipRole),
|
||||||
@@ -334,6 +338,8 @@ export const identityProjectDALFactory = (db: TDbClient) => {
|
|||||||
parentMapper: ({
|
parentMapper: ({
|
||||||
identityId,
|
identityId,
|
||||||
identityName,
|
identityName,
|
||||||
|
identityOrgId,
|
||||||
|
identityProjectId,
|
||||||
uaId,
|
uaId,
|
||||||
alicloudId,
|
alicloudId,
|
||||||
awsId,
|
awsId,
|
||||||
@@ -346,7 +352,9 @@ export const identityProjectDALFactory = (db: TDbClient) => {
|
|||||||
id,
|
id,
|
||||||
createdAt,
|
createdAt,
|
||||||
updatedAt,
|
updatedAt,
|
||||||
projectName
|
projectName,
|
||||||
|
lastLoginAuthMethod,
|
||||||
|
lastLoginTime
|
||||||
}) => ({
|
}) => ({
|
||||||
id,
|
id,
|
||||||
identityId,
|
identityId,
|
||||||
@@ -355,6 +363,8 @@ export const identityProjectDALFactory = (db: TDbClient) => {
|
|||||||
identity: {
|
identity: {
|
||||||
id: identityId,
|
id: identityId,
|
||||||
name: identityName,
|
name: identityName,
|
||||||
|
projectId: identityProjectId,
|
||||||
|
orgId: identityOrgId,
|
||||||
authMethods: buildAuthMethods({
|
authMethods: buildAuthMethods({
|
||||||
uaId,
|
uaId,
|
||||||
alicloudId,
|
alicloudId,
|
||||||
@@ -367,6 +377,11 @@ export const identityProjectDALFactory = (db: TDbClient) => {
|
|||||||
tokenId
|
tokenId
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
// TODO: scott - not sure why these aren't properly typed?
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
|
lastLoginAuthMethod,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
|
lastLoginTime,
|
||||||
project: {
|
project: {
|
||||||
id: projectId,
|
id: projectId,
|
||||||
name: projectName
|
name: projectName
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
import { requestContext } from "@fastify/request-context";
|
import { requestContext } from "@fastify/request-context";
|
||||||
|
|
||||||
import { AccessScope, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
|
import { AccessScope, ActionProjectType, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
|
||||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||||
import {
|
import {
|
||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
validatePrivilegeChangeOperation
|
validatePrivilegeChangeOperation
|
||||||
} from "@app/ee/services/permission/permission-fns";
|
} from "@app/ee/services/permission/permission-fns";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
|
import { ProjectPermissionIdentityActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { extractX509CertFromChain } from "@app/lib/certificates/extract-certificate";
|
import { extractX509CertFromChain } from "@app/lib/certificates/extract-certificate";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { crypto } from "@app/lib/crypto/cryptography";
|
import { crypto } from "@app/lib/crypto/cryptography";
|
||||||
@@ -43,7 +44,7 @@ type TIdentityTlsCertAuthServiceFactoryDep = {
|
|||||||
>;
|
>;
|
||||||
membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "update" | "getIdentityById">;
|
membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "update" | "getIdentityById">;
|
||||||
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission" | "getProjectPermission">;
|
||||||
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
|
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
|
||||||
orgDAL: Pick<TOrgDALFactory, "findById">;
|
orgDAL: Pick<TOrgDALFactory, "findById">;
|
||||||
};
|
};
|
||||||
@@ -130,8 +131,22 @@ export const identityTlsCertAuthServiceFactory = ({
|
|||||||
// Generate the token
|
// Generate the token
|
||||||
const identityAccessToken = await identityTlsCertAuthDAL.transaction(async (tx) => {
|
const identityAccessToken = await identityTlsCertAuthDAL.transaction(async (tx) => {
|
||||||
await membershipIdentityDAL.update(
|
await membershipIdentityDAL.update(
|
||||||
{ scope: AccessScope.Organization, scopeOrgId: identity.orgId, actorIdentityId: identity.id },
|
identity.projectId
|
||||||
{ lastLoginAuthMethod: IdentityAuthMethod.TLS_CERT_AUTH, lastLoginTime: new Date() },
|
? {
|
||||||
|
scope: AccessScope.Project,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
scopeProjectId: identity.projectId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
scope: AccessScope.Organization,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lastLoginAuthMethod: IdentityAuthMethod.TLS_CERT_AUTH,
|
||||||
|
lastLoginTime: new Date()
|
||||||
|
},
|
||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
const newToken = await identityAccessTokenDAL.create(
|
const newToken = await identityAccessTokenDAL.create(
|
||||||
@@ -237,15 +252,34 @@ export const identityTlsCertAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Create,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
OrgPermissionIdentityActions.Create,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
||||||
@@ -329,15 +363,31 @@ export const identityTlsCertAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Edit,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
|
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
||||||
@@ -404,15 +454,32 @@ export const identityTlsCertAuthServiceFactory = ({
|
|||||||
|
|
||||||
const identityAuth = await identityTlsCertAuthDAL.findOne({ identityId });
|
const identityAuth = await identityTlsCertAuthDAL.findOne({ identityId });
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Read,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
|
|
||||||
const { decryptor } = await kmsService.createCipherPairWithDataKey({
|
const { decryptor } = await kmsService.createCipherPairWithDataKey({
|
||||||
type: KmsDataKey.Organization,
|
type: KmsDataKey.Organization,
|
||||||
orgId: identityMembershipOrg.scopeOrgId
|
orgId: identityMembershipOrg.scopeOrgId
|
||||||
@@ -448,44 +515,61 @@ export const identityTlsCertAuthServiceFactory = ({
|
|||||||
message: "The identity does not have TLS Certificate auth"
|
message: "The identity does not have TLS Certificate auth"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
|
||||||
scope: OrganizationActionScope.Any,
|
|
||||||
actor,
|
|
||||||
actorId,
|
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
|
||||||
actorAuthMethod,
|
|
||||||
actorOrgId
|
|
||||||
});
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
|
||||||
|
|
||||||
const { permission: rolePermission, memberships } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
actor: ActorType.IDENTITY,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actorId: identityMembershipOrg.identity.id,
|
actionProjectType: ActionProjectType.Any,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actor,
|
||||||
actorAuthMethod,
|
actorId,
|
||||||
actorOrgId,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
scope: OrganizationActionScope.Any
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
const shouldUseNewPrivilegeSystem = Boolean(memberships?.[0]?.shouldUseNewPrivilegeSystem);
|
|
||||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity,
|
|
||||||
permission,
|
|
||||||
rolePermission
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!permissionBoundary.isValid)
|
|
||||||
throw new PermissionBoundaryError({
|
|
||||||
message: constructPermissionErrorMessage(
|
|
||||||
"Failed to revoke TLS Certificate auth of identity with more privileged role",
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity
|
|
||||||
),
|
|
||||||
details: { missingPermissions: permissionBoundary.missingPermissions }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.RevokeAuth,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
|
||||||
|
const { permission: rolePermission, memberships } = await permissionService.getOrgPermission({
|
||||||
|
actor: ActorType.IDENTITY,
|
||||||
|
actorId: identityMembershipOrg.identity.id,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId,
|
||||||
|
scope: OrganizationActionScope.Any
|
||||||
|
});
|
||||||
|
const shouldUseNewPrivilegeSystem = Boolean(memberships?.[0]?.shouldUseNewPrivilegeSystem);
|
||||||
|
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity,
|
||||||
|
permission,
|
||||||
|
rolePermission
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!permissionBoundary.isValid)
|
||||||
|
throw new PermissionBoundaryError({
|
||||||
|
message: constructPermissionErrorMessage(
|
||||||
|
"Failed to revoke TLS Certificate auth of identity with more privileged role",
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
),
|
||||||
|
details: { missingPermissions: permissionBoundary.missingPermissions }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const revokedIdentityTlsCertAuth = await identityTlsCertAuthDAL.transaction(async (tx) => {
|
const revokedIdentityTlsCertAuth = await identityTlsCertAuthDAL.transaction(async (tx) => {
|
||||||
const deletedTlsCertAuth = await identityTlsCertAuthDAL.delete({ identityId }, tx);
|
const deletedTlsCertAuth = await identityTlsCertAuthDAL.delete({ identityId }, tx);
|
||||||
await identityAccessTokenDAL.delete({ identityId, authMethod: IdentityAuthMethod.TLS_CERT_AUTH }, tx);
|
await identityAccessTokenDAL.delete({ identityId, authMethod: IdentityAuthMethod.TLS_CERT_AUTH }, tx);
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
|
|
||||||
import { AccessScope, IdentityAuthMethod, OrganizationActionScope, TableName } from "@app/db/schemas";
|
import {
|
||||||
|
AccessScope,
|
||||||
|
ActionProjectType,
|
||||||
|
IdentityAuthMethod,
|
||||||
|
OrganizationActionScope,
|
||||||
|
TableName
|
||||||
|
} from "@app/db/schemas";
|
||||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||||
import {
|
import {
|
||||||
@@ -8,6 +14,7 @@ import {
|
|||||||
validatePrivilegeChangeOperation
|
validatePrivilegeChangeOperation
|
||||||
} from "@app/ee/services/permission/permission-fns";
|
} from "@app/ee/services/permission/permission-fns";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
|
import { ProjectPermissionIdentityActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { crypto } from "@app/lib/crypto";
|
import { crypto } from "@app/lib/crypto";
|
||||||
import {
|
import {
|
||||||
@@ -49,7 +56,7 @@ type TIdentityTokenAuthServiceFactoryDep = {
|
|||||||
TIdentityAccessTokenDALFactory,
|
TIdentityAccessTokenDALFactory,
|
||||||
"create" | "find" | "update" | "findById" | "findOne" | "updateById" | "delete"
|
"create" | "find" | "update" | "findById" | "findOne" | "updateById" | "delete"
|
||||||
>;
|
>;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission" | "getProjectPermission">;
|
||||||
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
||||||
orgDAL: Pick<TOrgDALFactory, "findById">;
|
orgDAL: Pick<TOrgDALFactory, "findById">;
|
||||||
};
|
};
|
||||||
@@ -101,15 +108,34 @@ export const identityTokenAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Create,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
OrgPermissionIdentityActions.Create,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
||||||
@@ -187,15 +213,31 @@ export const identityTokenAuthServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Edit,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
|
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
||||||
@@ -251,15 +293,31 @@ export const identityTokenAuthServiceFactory = ({
|
|||||||
|
|
||||||
const identityTokenAuth = await identityTokenAuthDAL.findOne({ identityId });
|
const identityTokenAuth = await identityTokenAuthDAL.findOne({ identityId });
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Read,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
|
|
||||||
return { ...identityTokenAuth, orgId: identityMembershipOrg.scopeOrgId };
|
return { ...identityTokenAuth, orgId: identityMembershipOrg.scopeOrgId };
|
||||||
};
|
};
|
||||||
@@ -291,44 +349,61 @@ export const identityTokenAuthServiceFactory = ({
|
|||||||
message: "The identity does not have Token Auth"
|
message: "The identity does not have Token Auth"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
|
||||||
scope: OrganizationActionScope.Any,
|
|
||||||
actor,
|
|
||||||
actorId,
|
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
|
||||||
actorAuthMethod,
|
|
||||||
actorOrgId
|
|
||||||
});
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
|
||||||
|
|
||||||
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
actor: ActorType.IDENTITY,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actorId: identityMembershipOrg.identity.id,
|
actionProjectType: ActionProjectType.Any,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actor,
|
||||||
actorAuthMethod,
|
actorId,
|
||||||
actorOrgId,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
scope: OrganizationActionScope.Any
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
|
|
||||||
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
|
||||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity,
|
|
||||||
permission,
|
|
||||||
rolePermission
|
|
||||||
);
|
|
||||||
if (!permissionBoundary.isValid)
|
|
||||||
throw new PermissionBoundaryError({
|
|
||||||
message: constructPermissionErrorMessage(
|
|
||||||
"Failed to revoke token auth of identity with more privileged role",
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity
|
|
||||||
),
|
|
||||||
details: { missingPermissions: permissionBoundary.missingPermissions }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.RevokeAuth,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
|
||||||
|
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
||||||
|
actor: ActorType.IDENTITY,
|
||||||
|
actorId: identityMembershipOrg.identity.id,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId,
|
||||||
|
scope: OrganizationActionScope.Any
|
||||||
|
});
|
||||||
|
|
||||||
|
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
||||||
|
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity,
|
||||||
|
permission,
|
||||||
|
rolePermission
|
||||||
|
);
|
||||||
|
if (!permissionBoundary.isValid)
|
||||||
|
throw new PermissionBoundaryError({
|
||||||
|
message: constructPermissionErrorMessage(
|
||||||
|
"Failed to revoke token auth of identity with more privileged role",
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
),
|
||||||
|
details: { missingPermissions: permissionBoundary.missingPermissions }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const revokedIdentityTokenAuth = await identityTokenAuthDAL.transaction(async (tx) => {
|
const revokedIdentityTokenAuth = await identityTokenAuthDAL.transaction(async (tx) => {
|
||||||
const deletedTokenAuth = await identityTokenAuthDAL.delete({ identityId }, tx);
|
const deletedTokenAuth = await identityTokenAuthDAL.delete({ identityId }, tx);
|
||||||
await identityAccessTokenDAL.delete({
|
await identityAccessTokenDAL.delete({
|
||||||
@@ -367,45 +442,61 @@ export const identityTokenAuthServiceFactory = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
|
||||||
|
|
||||||
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
|
||||||
actor: ActorType.IDENTITY,
|
|
||||||
actorId: identityMembershipOrg.identity.id,
|
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
|
||||||
actorAuthMethod,
|
|
||||||
actorOrgId,
|
|
||||||
scope: OrganizationActionScope.Any
|
|
||||||
});
|
|
||||||
|
|
||||||
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
|
||||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.CreateToken,
|
|
||||||
OrgPermissionSubjects.Identity,
|
|
||||||
permission,
|
|
||||||
rolePermission
|
|
||||||
);
|
|
||||||
if (!permissionBoundary.isValid)
|
|
||||||
throw new PermissionBoundaryError({
|
|
||||||
message: constructPermissionErrorMessage(
|
|
||||||
"Failed to create token for identity with more privileged role",
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.CreateToken,
|
|
||||||
OrgPermissionSubjects.Identity
|
|
||||||
),
|
|
||||||
details: { missingPermissions: permissionBoundary.missingPermissions }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.CreateToken,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
|
||||||
|
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
||||||
|
actor: ActorType.IDENTITY,
|
||||||
|
actorId: identityMembershipOrg.identity.id,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId,
|
||||||
|
scope: OrganizationActionScope.Any
|
||||||
|
});
|
||||||
|
|
||||||
|
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
||||||
|
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.CreateToken,
|
||||||
|
OrgPermissionSubjects.Identity,
|
||||||
|
permission,
|
||||||
|
rolePermission
|
||||||
|
);
|
||||||
|
if (!permissionBoundary.isValid)
|
||||||
|
throw new PermissionBoundaryError({
|
||||||
|
message: constructPermissionErrorMessage(
|
||||||
|
"Failed to create token for identity with more privileged role",
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.CreateToken,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
),
|
||||||
|
details: { missingPermissions: permissionBoundary.missingPermissions }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const identityTokenAuth = await identityTokenAuthDAL.findOne({ identityId });
|
const identityTokenAuth = await identityTokenAuthDAL.findOne({ identityId });
|
||||||
|
|
||||||
const identity = await identityDAL.findById(identityTokenAuth.identityId);
|
const identity = await identityDAL.findById(identityTokenAuth.identityId);
|
||||||
@@ -413,7 +504,18 @@ export const identityTokenAuthServiceFactory = ({
|
|||||||
|
|
||||||
const identityAccessToken = await identityTokenAuthDAL.transaction(async (tx) => {
|
const identityAccessToken = await identityTokenAuthDAL.transaction(async (tx) => {
|
||||||
await membershipIdentityDAL.update(
|
await membershipIdentityDAL.update(
|
||||||
{ scope: AccessScope.Organization, scopeOrgId: identity.orgId, actorIdentityId: identity.id },
|
identity.projectId
|
||||||
|
? {
|
||||||
|
scope: AccessScope.Project,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
scopeProjectId: identity.projectId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
scope: AccessScope.Organization,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
},
|
||||||
{ lastLoginAuthMethod: IdentityAuthMethod.TOKEN_AUTH, lastLoginTime: new Date() },
|
{ lastLoginAuthMethod: IdentityAuthMethod.TOKEN_AUTH, lastLoginTime: new Date() },
|
||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
@@ -478,15 +580,32 @@ export const identityTokenAuthServiceFactory = ({
|
|||||||
message: "The identity does not have Token Auth"
|
message: "The identity does not have Token Auth"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
|
||||||
scope: OrganizationActionScope.Any,
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
actor,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actorId,
|
actionProjectType: ActionProjectType.Any,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actor,
|
||||||
actorAuthMethod,
|
actorId,
|
||||||
actorOrgId
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
});
|
actorAuthMethod,
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Read,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
|
|
||||||
const tokens = await identityAccessTokenDAL.find(
|
const tokens = await identityAccessTokenDAL.find(
|
||||||
{
|
{
|
||||||
@@ -531,43 +650,60 @@ export const identityTokenAuthServiceFactory = ({
|
|||||||
message: "The identity does not have Token Auth"
|
message: "The identity does not have Token Auth"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
|
||||||
scope: OrganizationActionScope.Any,
|
|
||||||
actor,
|
|
||||||
actorId,
|
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
|
||||||
actorAuthMethod,
|
|
||||||
actorOrgId
|
|
||||||
});
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
|
||||||
|
|
||||||
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
actor: ActorType.IDENTITY,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actorId: identityMembershipOrg.identity.id,
|
actionProjectType: ActionProjectType.Any,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actor,
|
||||||
actorAuthMethod,
|
actorId,
|
||||||
actorOrgId,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
scope: OrganizationActionScope.Any
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
|
||||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.CreateToken,
|
|
||||||
OrgPermissionSubjects.Identity,
|
|
||||||
permission,
|
|
||||||
rolePermission
|
|
||||||
);
|
|
||||||
if (!permissionBoundary.isValid)
|
|
||||||
throw new PermissionBoundaryError({
|
|
||||||
message: constructPermissionErrorMessage(
|
|
||||||
"Failed to update token for identity with more privileged role",
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.CreateToken,
|
|
||||||
OrgPermissionSubjects.Identity
|
|
||||||
),
|
|
||||||
details: { missingPermissions: permissionBoundary.missingPermissions }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.CreateToken,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId: identityMembershipOrg.identity.id })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
|
||||||
|
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
||||||
|
actor: ActorType.IDENTITY,
|
||||||
|
actorId: identityMembershipOrg.identity.id,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId,
|
||||||
|
scope: OrganizationActionScope.Any
|
||||||
|
});
|
||||||
|
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
||||||
|
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.CreateToken,
|
||||||
|
OrgPermissionSubjects.Identity,
|
||||||
|
permission,
|
||||||
|
rolePermission
|
||||||
|
);
|
||||||
|
if (!permissionBoundary.isValid)
|
||||||
|
throw new PermissionBoundaryError({
|
||||||
|
message: constructPermissionErrorMessage(
|
||||||
|
"Failed to update token for identity with more privileged role",
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.CreateToken,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
),
|
||||||
|
details: { missingPermissions: permissionBoundary.missingPermissions }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const [token] = await identityAccessTokenDAL.update(
|
const [token] = await identityAccessTokenDAL.update(
|
||||||
{
|
{
|
||||||
authMethod: IdentityAuthMethod.TOKEN_AUTH,
|
authMethod: IdentityAuthMethod.TOKEN_AUTH,
|
||||||
@@ -603,24 +739,43 @@ export const identityTokenAuthServiceFactory = ({
|
|||||||
|
|
||||||
await validateIdentityUpdateForSuperAdminPrivileges(identityAccessToken.identityId, isActorSuperAdmin);
|
await validateIdentityUpdateForSuperAdminPrivileges(identityAccessToken.identityId, isActorSuperAdmin);
|
||||||
|
|
||||||
const identityOrgMembership = await membershipIdentityDAL.findOne({
|
const identityOrgMembership = await membershipIdentityDAL.getIdentityById({
|
||||||
actorIdentityId: identityAccessToken.identityId,
|
scopeData: {
|
||||||
scope: AccessScope.Organization
|
scope: AccessScope.Organization,
|
||||||
|
orgId: actorOrgId
|
||||||
|
},
|
||||||
|
identityId: identityAccessToken.identityId
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!identityOrgMembership) {
|
if (!identityOrgMembership) {
|
||||||
throw new NotFoundError({ message: `Failed to find identity with ID ${identityAccessToken.identityId}` });
|
throw new NotFoundError({ message: `Failed to find identity with ID ${identityAccessToken.identityId}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityOrgMembership.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityOrgMembership.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityOrgMembership.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Edit,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId: identityOrgMembership.identity.id })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityOrgMembership.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
|
|
||||||
const [revokedToken] = await identityAccessTokenDAL.update(
|
const [revokedToken] = await identityAccessTokenDAL.update(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
import { requestContext } from "@fastify/request-context";
|
import { requestContext } from "@fastify/request-context";
|
||||||
|
|
||||||
import { AccessScope, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
|
import { AccessScope, ActionProjectType, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
|
||||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||||
import {
|
import {
|
||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
validatePrivilegeChangeOperation
|
validatePrivilegeChangeOperation
|
||||||
} from "@app/ee/services/permission/permission-fns";
|
} from "@app/ee/services/permission/permission-fns";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
|
import { ProjectPermissionIdentityActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||||
import { KeyStorePrefixes, TKeyStoreFactory } from "@app/keystore/keystore";
|
import { KeyStorePrefixes, TKeyStoreFactory } from "@app/keystore/keystore";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { crypto } from "@app/lib/crypto/cryptography";
|
import { crypto } from "@app/lib/crypto/cryptography";
|
||||||
@@ -51,7 +52,7 @@ type TIdentityUaServiceFactoryDep = {
|
|||||||
identityUaClientSecretDAL: TIdentityUaClientSecretDALFactory;
|
identityUaClientSecretDAL: TIdentityUaClientSecretDALFactory;
|
||||||
identityAccessTokenDAL: TIdentityAccessTokenDALFactory;
|
identityAccessTokenDAL: TIdentityAccessTokenDALFactory;
|
||||||
membershipIdentityDAL: TMembershipIdentityDALFactory;
|
membershipIdentityDAL: TMembershipIdentityDALFactory;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission" | "getProjectPermission">;
|
||||||
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
|
||||||
orgDAL: Pick<TOrgDALFactory, "findById">;
|
orgDAL: Pick<TOrgDALFactory, "findById">;
|
||||||
keyStore: Pick<
|
keyStore: Pick<
|
||||||
@@ -231,7 +232,18 @@ export const identityUaServiceFactory = ({
|
|||||||
const identityAccessToken = await identityUaDAL.transaction(async (tx) => {
|
const identityAccessToken = await identityUaDAL.transaction(async (tx) => {
|
||||||
const uaClientSecretDoc = await identityUaClientSecretDAL.incrementUsage(validClientSecretInfo!.id, tx);
|
const uaClientSecretDoc = await identityUaClientSecretDAL.incrementUsage(validClientSecretInfo!.id, tx);
|
||||||
await membershipIdentityDAL.update(
|
await membershipIdentityDAL.update(
|
||||||
{ scope: AccessScope.Organization, scopeOrgId: identity.orgId, actorIdentityId: identity.id },
|
identity.projectId
|
||||||
|
? {
|
||||||
|
scope: AccessScope.Project,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
scopeProjectId: identity.projectId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
scope: AccessScope.Organization,
|
||||||
|
scopeOrgId: identity.orgId,
|
||||||
|
actorIdentityId: identity.id
|
||||||
|
},
|
||||||
{
|
{
|
||||||
lastLoginAuthMethod: IdentityAuthMethod.UNIVERSAL_AUTH,
|
lastLoginAuthMethod: IdentityAuthMethod.UNIVERSAL_AUTH,
|
||||||
lastLoginTime: new Date()
|
lastLoginTime: new Date()
|
||||||
@@ -351,16 +363,35 @@ export const identityUaServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Create,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
OrgPermissionIdentityActions.Create,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedClientSecretTrustedIps = clientSecretTrustedIps.map((clientSecretTrustedIp) => {
|
const reformattedClientSecretTrustedIps = clientSecretTrustedIps.map((clientSecretTrustedIp) => {
|
||||||
@@ -467,15 +498,31 @@ export const identityUaServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
throw new BadRequestError({ message: "Access token TTL cannot be greater than max TTL" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Edit,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
|
|
||||||
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
|
||||||
const reformattedClientSecretTrustedIps = clientSecretTrustedIps?.map((clientSecretTrustedIp) => {
|
const reformattedClientSecretTrustedIps = clientSecretTrustedIps?.map((clientSecretTrustedIp) => {
|
||||||
@@ -554,15 +601,31 @@ export const identityUaServiceFactory = ({
|
|||||||
throw new ForbiddenRequestError({ message: "Sub organization not authorized to access this identity" });
|
throw new ForbiddenRequestError({ message: "Sub organization not authorized to access this identity" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Read,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
return { ...uaIdentityAuth, orgId: identityMembershipOrg.scopeOrgId };
|
return { ...uaIdentityAuth, orgId: identityMembershipOrg.scopeOrgId };
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -590,43 +653,59 @@ export const identityUaServiceFactory = ({
|
|||||||
if (identityMembershipOrg.identity.orgId !== actorOrgId) {
|
if (identityMembershipOrg.identity.orgId !== actorOrgId) {
|
||||||
throw new ForbiddenRequestError({ message: "Sub organization not authorized to access this identity" });
|
throw new ForbiddenRequestError({ message: "Sub organization not authorized to access this identity" });
|
||||||
}
|
}
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
|
||||||
scope: OrganizationActionScope.Any,
|
|
||||||
actor,
|
|
||||||
actorId,
|
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
|
||||||
actorAuthMethod,
|
|
||||||
actorOrgId
|
|
||||||
});
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
|
||||||
|
|
||||||
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
actor: ActorType.IDENTITY,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actorId: identityMembershipOrg.identity.id,
|
actionProjectType: ActionProjectType.Any,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actor,
|
||||||
actorAuthMethod,
|
actorId,
|
||||||
actorOrgId,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
scope: OrganizationActionScope.Any
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
|
||||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity,
|
|
||||||
permission,
|
|
||||||
rolePermission
|
|
||||||
);
|
|
||||||
if (!permissionBoundary.isValid)
|
|
||||||
throw new PermissionBoundaryError({
|
|
||||||
message: constructPermissionErrorMessage(
|
|
||||||
"Failed to revoke universal auth of identity with more privileged role",
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.RevokeAuth,
|
|
||||||
OrgPermissionSubjects.Identity
|
|
||||||
),
|
|
||||||
details: { missingPermissions: permissionBoundary.missingPermissions }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.RevokeAuth,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
|
||||||
|
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
||||||
|
actor: ActorType.IDENTITY,
|
||||||
|
actorId: identityMembershipOrg.identity.id,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId,
|
||||||
|
scope: OrganizationActionScope.Any
|
||||||
|
});
|
||||||
|
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
||||||
|
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity,
|
||||||
|
permission,
|
||||||
|
rolePermission
|
||||||
|
);
|
||||||
|
if (!permissionBoundary.isValid)
|
||||||
|
throw new PermissionBoundaryError({
|
||||||
|
message: constructPermissionErrorMessage(
|
||||||
|
"Failed to revoke universal auth of identity with more privileged role",
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.RevokeAuth,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
),
|
||||||
|
details: { missingPermissions: permissionBoundary.missingPermissions }
|
||||||
|
});
|
||||||
|
}
|
||||||
const revokedIdentityUniversalAuth = await identityUaDAL.transaction(async (tx) => {
|
const revokedIdentityUniversalAuth = await identityUaDAL.transaction(async (tx) => {
|
||||||
const deletedUniversalAuth = await identityUaDAL.delete({ identityId }, tx);
|
const deletedUniversalAuth = await identityUaDAL.delete({ identityId }, tx);
|
||||||
return { ...deletedUniversalAuth?.[0], orgId: identityMembershipOrg.scopeOrgId };
|
return { ...deletedUniversalAuth?.[0], orgId: identityMembershipOrg.scopeOrgId };
|
||||||
@@ -662,43 +741,61 @@ export const identityUaServiceFactory = ({
|
|||||||
throw new ForbiddenRequestError({ message: "Sub organization not authorized to access this identity" });
|
throw new ForbiddenRequestError({ message: "Sub organization not authorized to access this identity" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
|
|
||||||
|
|
||||||
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
|
||||||
actor: ActorType.IDENTITY,
|
|
||||||
actorId: identityMembershipOrg.identity.id,
|
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
|
||||||
actorAuthMethod,
|
|
||||||
actorOrgId,
|
|
||||||
scope: OrganizationActionScope.Any
|
|
||||||
});
|
|
||||||
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
|
||||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.CreateToken,
|
|
||||||
OrgPermissionSubjects.Identity,
|
|
||||||
permission,
|
|
||||||
rolePermission
|
|
||||||
);
|
|
||||||
if (!permissionBoundary.isValid)
|
|
||||||
throw new PermissionBoundaryError({
|
|
||||||
message: constructPermissionErrorMessage(
|
|
||||||
"Failed to create client secret for identity.",
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.CreateToken,
|
|
||||||
OrgPermissionSubjects.Identity
|
|
||||||
),
|
|
||||||
details: { missingPermissions: permissionBoundary.missingPermissions }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.CreateToken,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
OrgPermissionIdentityActions.Create,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
);
|
||||||
|
|
||||||
|
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
||||||
|
actor: ActorType.IDENTITY,
|
||||||
|
actorId: identityMembershipOrg.identity.id,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId,
|
||||||
|
scope: OrganizationActionScope.Any
|
||||||
|
});
|
||||||
|
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
||||||
|
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.CreateToken,
|
||||||
|
OrgPermissionSubjects.Identity,
|
||||||
|
permission,
|
||||||
|
rolePermission
|
||||||
|
);
|
||||||
|
if (!permissionBoundary.isValid)
|
||||||
|
throw new PermissionBoundaryError({
|
||||||
|
message: constructPermissionErrorMessage(
|
||||||
|
"Failed to create client secret for identity.",
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.CreateToken,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
),
|
||||||
|
details: { missingPermissions: permissionBoundary.missingPermissions }
|
||||||
|
});
|
||||||
|
}
|
||||||
const appCfg = getConfig();
|
const appCfg = getConfig();
|
||||||
const clientSecret = crypto.randomBytes(32).toString("hex");
|
const clientSecret = crypto.randomBytes(32).toString("hex");
|
||||||
const clientSecretHash = await crypto.hashing().createHash(clientSecret, appCfg.SALT_ROUNDS);
|
const clientSecretHash = await crypto.hashing().createHash(clientSecret, appCfg.SALT_ROUNDS);
|
||||||
@@ -748,43 +845,59 @@ export const identityUaServiceFactory = ({
|
|||||||
throw new ForbiddenRequestError({ message: "Sub organization not authorized to access this identity" });
|
throw new ForbiddenRequestError({ message: "Sub organization not authorized to access this identity" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
|
||||||
|
|
||||||
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
|
||||||
actor: ActorType.IDENTITY,
|
|
||||||
actorId: identityMembershipOrg.identity.id,
|
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
|
||||||
actorAuthMethod,
|
|
||||||
actorOrgId,
|
|
||||||
scope: OrganizationActionScope.Any
|
|
||||||
});
|
|
||||||
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
|
||||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.GetToken,
|
|
||||||
OrgPermissionSubjects.Identity,
|
|
||||||
permission,
|
|
||||||
rolePermission
|
|
||||||
);
|
|
||||||
if (!permissionBoundary.isValid)
|
|
||||||
throw new PermissionBoundaryError({
|
|
||||||
message: constructPermissionErrorMessage(
|
|
||||||
"Failed to get identity client secret with more privileged role",
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.GetToken,
|
|
||||||
OrgPermissionSubjects.Identity
|
|
||||||
),
|
|
||||||
details: { missingPermissions: permissionBoundary.missingPermissions }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.GetToken,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
||||||
|
|
||||||
|
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
||||||
|
actor: ActorType.IDENTITY,
|
||||||
|
actorId: identityMembershipOrg.identity.id,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId,
|
||||||
|
scope: OrganizationActionScope.Any
|
||||||
|
});
|
||||||
|
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
||||||
|
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.GetToken,
|
||||||
|
OrgPermissionSubjects.Identity,
|
||||||
|
permission,
|
||||||
|
rolePermission
|
||||||
|
);
|
||||||
|
if (!permissionBoundary.isValid)
|
||||||
|
throw new PermissionBoundaryError({
|
||||||
|
message: constructPermissionErrorMessage(
|
||||||
|
"Failed to get identity client secret with more privileged role",
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.GetToken,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
),
|
||||||
|
details: { missingPermissions: permissionBoundary.missingPermissions }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const identityUniversalAuth = await identityUaDAL.findOne({
|
const identityUniversalAuth = await identityUaDAL.findOne({
|
||||||
identityId
|
identityId
|
||||||
});
|
});
|
||||||
@@ -828,43 +941,57 @@ export const identityUaServiceFactory = ({
|
|||||||
const clientSecret = await identityUaClientSecretDAL.findOne({ id: clientSecretId, identityUAId: identityUa.id });
|
const clientSecret = await identityUaClientSecretDAL.findOne({ id: clientSecretId, identityUAId: identityUa.id });
|
||||||
if (!clientSecret) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
|
if (!clientSecret) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
|
||||||
|
|
||||||
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
|
||||||
actor: ActorType.IDENTITY,
|
|
||||||
actorId: identityMembershipOrg.identity.id,
|
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
|
||||||
actorAuthMethod,
|
|
||||||
actorOrgId,
|
|
||||||
scope: OrganizationActionScope.Any
|
|
||||||
});
|
|
||||||
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
|
||||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.GetToken,
|
|
||||||
OrgPermissionSubjects.Identity,
|
|
||||||
permission,
|
|
||||||
rolePermission
|
|
||||||
);
|
|
||||||
if (!permissionBoundary.isValid)
|
|
||||||
throw new PermissionBoundaryError({
|
|
||||||
message: constructPermissionErrorMessage(
|
|
||||||
"Failed to read identity client secret of identity with more privileged role",
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.GetToken,
|
|
||||||
OrgPermissionSubjects.Identity
|
|
||||||
),
|
|
||||||
details: { missingPermissions: permissionBoundary.missingPermissions }
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.GetToken,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
||||||
|
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
||||||
|
actor: ActorType.IDENTITY,
|
||||||
|
actorId: identityMembershipOrg.identity.id,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId,
|
||||||
|
scope: OrganizationActionScope.Any
|
||||||
|
});
|
||||||
|
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
||||||
|
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.GetToken,
|
||||||
|
OrgPermissionSubjects.Identity,
|
||||||
|
permission,
|
||||||
|
rolePermission
|
||||||
|
);
|
||||||
|
if (!permissionBoundary.isValid)
|
||||||
|
throw new PermissionBoundaryError({
|
||||||
|
message: constructPermissionErrorMessage(
|
||||||
|
"Failed to read identity client secret of identity with more privileged role",
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.GetToken,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
),
|
||||||
|
details: { missingPermissions: permissionBoundary.missingPermissions }
|
||||||
|
});
|
||||||
|
}
|
||||||
return { ...clientSecret, identityId, orgId: identityMembershipOrg.scopeOrgId };
|
return { ...clientSecret, identityId, orgId: identityMembershipOrg.scopeOrgId };
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -900,45 +1027,63 @@ export const identityUaServiceFactory = ({
|
|||||||
const clientSecret = await identityUaClientSecretDAL.findOne({ id: clientSecretId, identityUAId: identityUa.id });
|
const clientSecret = await identityUaClientSecretDAL.findOne({ id: clientSecretId, identityUAId: identityUa.id });
|
||||||
if (!clientSecret) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
|
if (!clientSecret) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Delete, OrgPermissionSubjects.Identity);
|
|
||||||
|
|
||||||
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
|
||||||
actor: ActorType.IDENTITY,
|
|
||||||
actorId: identityMembershipOrg.identity.id,
|
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
|
||||||
actorAuthMethod,
|
|
||||||
actorOrgId,
|
|
||||||
scope: OrganizationActionScope.Any
|
|
||||||
});
|
|
||||||
|
|
||||||
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
|
||||||
const permissionBoundary = validatePrivilegeChangeOperation(
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.DeleteToken,
|
|
||||||
OrgPermissionSubjects.Identity,
|
|
||||||
permission,
|
|
||||||
rolePermission
|
|
||||||
);
|
|
||||||
if (!permissionBoundary.isValid) {
|
|
||||||
throw new PermissionBoundaryError({
|
|
||||||
message: constructPermissionErrorMessage(
|
|
||||||
"Failed to revoke identity client secret with more privileged role",
|
|
||||||
shouldUseNewPrivilegeSystem,
|
|
||||||
OrgPermissionIdentityActions.DeleteToken,
|
|
||||||
OrgPermissionSubjects.Identity
|
|
||||||
),
|
|
||||||
details: { missingPermissions: permissionBoundary.missingPermissions }
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.DeleteToken,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
OrgPermissionIdentityActions.Delete,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
);
|
||||||
|
|
||||||
|
const { permission: rolePermission } = await permissionService.getOrgPermission({
|
||||||
|
actor: ActorType.IDENTITY,
|
||||||
|
actorId: identityMembershipOrg.identity.id,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId,
|
||||||
|
scope: OrganizationActionScope.Any
|
||||||
|
});
|
||||||
|
|
||||||
|
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
|
||||||
|
const permissionBoundary = validatePrivilegeChangeOperation(
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.DeleteToken,
|
||||||
|
OrgPermissionSubjects.Identity,
|
||||||
|
permission,
|
||||||
|
rolePermission
|
||||||
|
);
|
||||||
|
if (!permissionBoundary.isValid) {
|
||||||
|
throw new PermissionBoundaryError({
|
||||||
|
message: constructPermissionErrorMessage(
|
||||||
|
"Failed to revoke identity client secret with more privileged role",
|
||||||
|
shouldUseNewPrivilegeSystem,
|
||||||
|
OrgPermissionIdentityActions.DeleteToken,
|
||||||
|
OrgPermissionSubjects.Identity
|
||||||
|
),
|
||||||
|
details: { missingPermissions: permissionBoundary.missingPermissions }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
const updatedClientSecret = await identityUaClientSecretDAL.updateById(clientSecretId, {
|
const updatedClientSecret = await identityUaClientSecretDAL.updateById(clientSecretId, {
|
||||||
isClientSecretRevoked: true
|
isClientSecretRevoked: true
|
||||||
});
|
});
|
||||||
@@ -971,16 +1116,31 @@ export const identityUaServiceFactory = ({
|
|||||||
throw new ForbiddenRequestError({ message: "Sub organization not authorized to access this identity" });
|
throw new ForbiddenRequestError({ message: "Sub organization not authorized to access this identity" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { permission } = await permissionService.getOrgPermission({
|
if (identityMembershipOrg.identity.projectId) {
|
||||||
scope: OrganizationActionScope.Any,
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
actor,
|
actionProjectType: ActionProjectType.Any,
|
||||||
actorId,
|
actor,
|
||||||
orgId: identityMembershipOrg.scopeOrgId,
|
actorId,
|
||||||
actorAuthMethod,
|
projectId: identityMembershipOrg.identity.projectId,
|
||||||
actorOrgId
|
actorAuthMethod,
|
||||||
});
|
actorOrgId
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
});
|
||||||
|
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
|
ProjectPermissionIdentityActions.Edit,
|
||||||
|
subject(ProjectPermissionSub.Identity, { identityId })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
const { permission } = await permissionService.getOrgPermission({
|
||||||
|
scope: OrganizationActionScope.Any,
|
||||||
|
actor,
|
||||||
|
actorId,
|
||||||
|
orgId: identityMembershipOrg.scopeOrgId,
|
||||||
|
actorAuthMethod,
|
||||||
|
actorOrgId
|
||||||
|
});
|
||||||
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
|
||||||
|
}
|
||||||
const deleted = await keyStore.deleteItems({
|
const deleted = await keyStore.deleteItems({
|
||||||
pattern: `lockout:identity:${identityId}:${IdentityAuthMethod.UNIVERSAL_AUTH}:*`
|
pattern: `lockout:identity:${identityId}:${IdentityAuthMethod.UNIVERSAL_AUTH}:*`
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { TKeyStoreFactory } from "@app/keystore/keystore";
|
||||||
|
|
||||||
|
export const getIdentityActiveLockoutAuthMethods = async (
|
||||||
|
identityId: string,
|
||||||
|
keyStore: Pick<TKeyStoreFactory, "getKeysByPattern" | "getItem">
|
||||||
|
) => {
|
||||||
|
const activeLockouts = await keyStore.getKeysByPattern(`lockout:identity:${identityId}:*`);
|
||||||
|
|
||||||
|
const activeLockoutAuthMethods = new Set<string>();
|
||||||
|
for await (const key of activeLockouts) {
|
||||||
|
const parts = key.split(":");
|
||||||
|
if (parts.length > 3) {
|
||||||
|
const lockoutRaw = await keyStore.getItem(key);
|
||||||
|
if (lockoutRaw) {
|
||||||
|
const lockout = JSON.parse(lockoutRaw) as { lockedOut: boolean };
|
||||||
|
if (lockout.lockedOut) {
|
||||||
|
activeLockoutAuthMethods.add(parts[3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.from(activeLockoutAuthMethods);
|
||||||
|
};
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
import { AccessScope, OrgMembershipRole } from "@app/db/schemas";
|
import { AccessScope, OrgMembershipRole } from "@app/db/schemas";
|
||||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
|
import { TKeyStoreFactory } from "@app/keystore/keystore";
|
||||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||||
|
import { getIdentityActiveLockoutAuthMethods } from "@app/services/identity-v2/identity-fns";
|
||||||
|
|
||||||
import { TIdentityMetadataDALFactory } from "../identity/identity-metadata-dal";
|
import { TIdentityMetadataDALFactory } from "../identity/identity-metadata-dal";
|
||||||
import { TMembershipRoleDALFactory } from "../membership/membership-role-dal";
|
import { TMembershipRoleDALFactory } from "../membership/membership-role-dal";
|
||||||
@@ -24,6 +26,7 @@ type TScopedIdentityV2ServiceFactoryDep = {
|
|||||||
membershipIdentityDAL: TMembershipIdentityDALFactory;
|
membershipIdentityDAL: TMembershipIdentityDALFactory;
|
||||||
membershipRoleDAL: TMembershipRoleDALFactory;
|
membershipRoleDAL: TMembershipRoleDALFactory;
|
||||||
identityMetadataDAL: TIdentityMetadataDALFactory;
|
identityMetadataDAL: TIdentityMetadataDALFactory;
|
||||||
|
keyStore: Pick<TKeyStoreFactory, "getKeysByPattern" | "getItem">;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TScopedIdentityV2ServiceFactory = ReturnType<typeof identityV2ServiceFactory>;
|
export type TScopedIdentityV2ServiceFactory = ReturnType<typeof identityV2ServiceFactory>;
|
||||||
@@ -34,7 +37,8 @@ export const identityV2ServiceFactory = ({
|
|||||||
licenseService,
|
licenseService,
|
||||||
membershipIdentityDAL,
|
membershipIdentityDAL,
|
||||||
membershipRoleDAL,
|
membershipRoleDAL,
|
||||||
identityMetadataDAL
|
identityMetadataDAL,
|
||||||
|
keyStore
|
||||||
}: TScopedIdentityV2ServiceFactoryDep) => {
|
}: TScopedIdentityV2ServiceFactoryDep) => {
|
||||||
const orgFactory = newOrgIdentityFactory({
|
const orgFactory = newOrgIdentityFactory({
|
||||||
permissionService
|
permissionService
|
||||||
@@ -217,7 +221,9 @@ export const identityV2ServiceFactory = ({
|
|||||||
const identity = await identityDAL.getIdentityById(dto.scopeData, dto.selector.identityId);
|
const identity = await identityDAL.getIdentityById(dto.scopeData, dto.selector.identityId);
|
||||||
if (!identity) throw new NotFoundError({ message: `Identity with id ${dto.selector.identityId} not found` });
|
if (!identity) throw new NotFoundError({ message: `Identity with id ${dto.selector.identityId} not found` });
|
||||||
|
|
||||||
return { identity };
|
const activeLockoutAuthMethods = await getIdentityActiveLockoutAuthMethods(identity.id, keyStore);
|
||||||
|
|
||||||
|
return { identity: { ...identity, activeLockoutAuthMethods } };
|
||||||
};
|
};
|
||||||
|
|
||||||
const listIdentities = async (dto: TListIdentityV2DTO) => {
|
const listIdentities = async (dto: TListIdentityV2DTO) => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
|
|
||||||
import { AccessScope, ActionProjectType } from "@app/db/schemas";
|
import { AccessScope, ActionProjectType } from "@app/db/schemas";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
@@ -47,7 +47,7 @@ export const newProjectIdentityFactory = ({ permissionService }: TProjectIdentit
|
|||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionIdentityActions.Edit,
|
ProjectPermissionIdentityActions.Edit,
|
||||||
ProjectPermissionSub.Identity
|
subject(ProjectPermissionSub.Identity, { identityId: dto.selector.identityId })
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ export const newProjectIdentityFactory = ({ permissionService }: TProjectIdentit
|
|||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionIdentityActions.Delete,
|
ProjectPermissionIdentityActions.Delete,
|
||||||
ProjectPermissionSub.Identity
|
subject(ProjectPermissionSub.Identity, { identityId: dto.selector.identityId })
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ export const newProjectIdentityFactory = ({ permissionService }: TProjectIdentit
|
|||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionIdentityActions.Read,
|
ProjectPermissionIdentityActions.Read,
|
||||||
ProjectPermissionSub.Identity
|
subject(ProjectPermissionSub.Identity, { identityId: dto.selector.identityId })
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ export const identityOrgDALFactory = (db: TDbClient) => {
|
|||||||
.join(TableName.Membership, `${TableName.Membership}.actorIdentityId`, `${TableName.Identity}.id`)
|
.join(TableName.Membership, `${TableName.Membership}.actorIdentityId`, `${TableName.Identity}.id`)
|
||||||
.where(`${TableName.Membership}.scope`, AccessScope.Organization)
|
.where(`${TableName.Membership}.scope`, AccessScope.Organization)
|
||||||
.whereNotNull(`${TableName.Membership}.actorIdentityId`)
|
.whereNotNull(`${TableName.Membership}.actorIdentityId`)
|
||||||
|
.whereNull(`${TableName.Identity}.projectId`)
|
||||||
.orderBy(`${TableName.Identity}.${orderBy}`, orderDirection)
|
.orderBy(`${TableName.Identity}.${orderBy}`, orderDirection)
|
||||||
.select(
|
.select(
|
||||||
selectAllTableCols(TableName.Membership),
|
selectAllTableCols(TableName.Membership),
|
||||||
@@ -404,6 +405,7 @@ export const identityOrgDALFactory = (db: TDbClient) => {
|
|||||||
.whereNotNull(`${TableName.Membership}.actorIdentityId`)
|
.whereNotNull(`${TableName.Membership}.actorIdentityId`)
|
||||||
.where(`${TableName.Membership}.scopeOrgId`, orgId)
|
.where(`${TableName.Membership}.scopeOrgId`, orgId)
|
||||||
.join(TableName.Identity, `${TableName.Identity}.id`, `${TableName.Membership}.actorIdentityId`)
|
.join(TableName.Identity, `${TableName.Identity}.id`, `${TableName.Membership}.actorIdentityId`)
|
||||||
|
.whereNull(`${TableName.Identity}.projectId`)
|
||||||
.join(TableName.MembershipRole, `${TableName.MembershipRole}.membershipId`, `${TableName.Membership}.id`)
|
.join(TableName.MembershipRole, `${TableName.MembershipRole}.membershipId`, `${TableName.Membership}.id`)
|
||||||
.leftJoin(TableName.Role, `${TableName.MembershipRole}.customRoleId`, `${TableName.Role}.id`)
|
.leftJoin(TableName.Role, `${TableName.MembershipRole}.customRoleId`, `${TableName.Role}.id`)
|
||||||
.orderBy(
|
.orderBy(
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { TPermissionServiceFactory } from "@app/ee/services/permission/permissio
|
|||||||
import { TKeyStoreFactory } from "@app/keystore/keystore";
|
import { TKeyStoreFactory } from "@app/keystore/keystore";
|
||||||
import { BadRequestError, NotFoundError, PermissionBoundaryError } from "@app/lib/errors";
|
import { BadRequestError, NotFoundError, PermissionBoundaryError } from "@app/lib/errors";
|
||||||
import { TIdentityProjectDALFactory } from "@app/services/identity-project/identity-project-dal";
|
import { TIdentityProjectDALFactory } from "@app/services/identity-project/identity-project-dal";
|
||||||
|
import { getIdentityActiveLockoutAuthMethods } from "@app/services/identity-v2/identity-fns";
|
||||||
|
|
||||||
import { TAdditionalPrivilegeDALFactory } from "../additional-privilege/additional-privilege-dal";
|
import { TAdditionalPrivilegeDALFactory } from "../additional-privilege/additional-privilege-dal";
|
||||||
import { TMembershipRoleDALFactory } from "../membership/membership-role-dal";
|
import { TMembershipRoleDALFactory } from "../membership/membership-role-dal";
|
||||||
@@ -220,6 +221,13 @@ export const identityServiceFactory = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const identityDetails = await identityDAL.findById(id);
|
const identityDetails = await identityDAL.findById(id);
|
||||||
|
|
||||||
|
console.log("has project id", identityDetails);
|
||||||
|
|
||||||
|
if (identityDetails.projectId) {
|
||||||
|
throw new BadRequestError({ message: `Identity is managed by project` });
|
||||||
|
}
|
||||||
|
|
||||||
const identity = await identityDAL.transaction(async (tx) => {
|
const identity = await identityDAL.transaction(async (tx) => {
|
||||||
const newIdentity =
|
const newIdentity =
|
||||||
identityDetails.orgId === actorOrgId && (name || hasDeleteProtection)
|
identityDetails.orgId === actorOrgId && (name || hasDeleteProtection)
|
||||||
@@ -286,25 +294,11 @@ export const identityServiceFactory = ({
|
|||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
|
||||||
|
|
||||||
const activeLockouts = await keyStore.getKeysByPattern(`lockout:identity:${id}:*`);
|
const activeLockoutAuthMethods = await getIdentityActiveLockoutAuthMethods(id, keyStore);
|
||||||
|
|
||||||
const activeLockoutAuthMethods = new Set<string>();
|
|
||||||
for await (const key of activeLockouts) {
|
|
||||||
const parts = key.split(":");
|
|
||||||
if (parts.length > 3) {
|
|
||||||
const lockoutRaw = await keyStore.getItem(key);
|
|
||||||
if (lockoutRaw) {
|
|
||||||
const lockout = JSON.parse(lockoutRaw) as { lockedOut: boolean };
|
|
||||||
if (lockout.lockedOut) {
|
|
||||||
activeLockoutAuthMethods.add(parts[3]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...identity,
|
...identity,
|
||||||
identity: { ...identity.identity, activeLockoutAuthMethods: Array.from(activeLockoutAuthMethods) }
|
identity: { ...identity.identity, activeLockoutAuthMethods }
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -340,6 +334,10 @@ export const identityServiceFactory = ({
|
|||||||
if (identityOrgMembership.identity.hasDeleteProtection)
|
if (identityOrgMembership.identity.hasDeleteProtection)
|
||||||
throw new BadRequestError({ message: "Identity has delete protection" });
|
throw new BadRequestError({ message: "Identity has delete protection" });
|
||||||
|
|
||||||
|
if (identityOrgMembership.identity.projectId) {
|
||||||
|
throw new BadRequestError({ message: `Identity is managed by project` });
|
||||||
|
}
|
||||||
|
|
||||||
if (identityOrgMembership.identity.orgId === actorOrgId) {
|
if (identityOrgMembership.identity.orgId === actorOrgId) {
|
||||||
const deletedIdentity = await identityDAL.deleteById(id);
|
const deletedIdentity = await identityDAL.deleteById(id);
|
||||||
await licenseService.updateSubscriptionOrgMemberCount(identityOrgMembership.scopeOrgId);
|
await licenseService.updateSubscriptionOrgMemberCount(identityOrgMembership.scopeOrgId);
|
||||||
|
|||||||
@@ -371,8 +371,10 @@ export const membershipIdentityDALFactory = (db: TDbClient) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const listAvailableIdentities = async (scopeData: AccessScopeData, rootOrgId: string) => {
|
const listAvailableIdentities = async (scopeData: AccessScopeData, rootOrgId: string) => {
|
||||||
|
// TODO (akhil/scott): need to implement filters
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const identitesConnectedToOrg = db
|
const identitiesConnectedToOrg = db
|
||||||
.replicaNode()(TableName.Membership)
|
.replicaNode()(TableName.Membership)
|
||||||
.whereNotNull(`${TableName.Membership}.actorIdentityId`)
|
.whereNotNull(`${TableName.Membership}.actorIdentityId`)
|
||||||
.where(`${TableName.Membership}.scopeOrgId`, scopeData.orgId)
|
.where(`${TableName.Membership}.scopeOrgId`, scopeData.orgId)
|
||||||
@@ -389,6 +391,7 @@ export const membershipIdentityDALFactory = (db: TDbClient) => {
|
|||||||
.join(TableName.Identity, `${TableName.Identity}.id`, `${TableName.Membership}.actorIdentityId`)
|
.join(TableName.Identity, `${TableName.Identity}.id`, `${TableName.Membership}.actorIdentityId`)
|
||||||
.where(`${TableName.Membership}.scope`, AccessScope.Organization)
|
.where(`${TableName.Membership}.scope`, AccessScope.Organization)
|
||||||
.whereNotNull(`${TableName.Membership}.actorIdentityId`)
|
.whereNotNull(`${TableName.Membership}.actorIdentityId`)
|
||||||
|
.whereNull(`${TableName.Identity}.projectId`)
|
||||||
.where((qb) => {
|
.where((qb) => {
|
||||||
// if sub org pick from root and if project pick from org of project
|
// if sub org pick from root and if project pick from org of project
|
||||||
if (scopeData.scope === AccessScope.Organization) {
|
if (scopeData.scope === AccessScope.Organization) {
|
||||||
@@ -397,7 +400,7 @@ export const membershipIdentityDALFactory = (db: TDbClient) => {
|
|||||||
void qb.where(`${TableName.Membership}.scopeOrgId`, scopeData.orgId);
|
void qb.where(`${TableName.Membership}.scopeOrgId`, scopeData.orgId);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.whereNotIn(`${TableName.Membership}.actorIdentityId`, identitesConnectedToOrg)
|
.whereNotIn(`${TableName.Membership}.actorIdentityId`, identitiesConnectedToOrg)
|
||||||
.select(
|
.select(
|
||||||
db.ref("id").withSchema(TableName.Identity),
|
db.ref("id").withSchema(TableName.Identity),
|
||||||
db.ref("name").withSchema(TableName.Identity),
|
db.ref("name").withSchema(TableName.Identity),
|
||||||
|
|||||||
@@ -340,7 +340,8 @@ export const membershipIdentityServiceFactory = ({
|
|||||||
|
|
||||||
await factory.onListMembershipIdentityGuard(dto);
|
await factory.onListMembershipIdentityGuard(dto);
|
||||||
|
|
||||||
if (dto.permission.rootOrgId === dto.permission.orgId) return { identities: [] };
|
if (scopeData.scope !== AccessScope.Project && dto.permission.rootOrgId === dto.permission.orgId)
|
||||||
|
return { identities: [] };
|
||||||
|
|
||||||
const identities = await membershipIdentityDAL.listAvailableIdentities(dto.scopeData, dto.permission.rootOrgId);
|
const identities = await membershipIdentityDAL.listAvailableIdentities(dto.scopeData, dto.permission.rootOrgId);
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -1,4 +1,4 @@
|
|||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError, subject } from "@casl/ability";
|
||||||
|
|
||||||
import { AccessScope, ActionProjectType, ProjectMembershipRole } from "@app/db/schemas";
|
import { AccessScope, ActionProjectType, ProjectMembershipRole } from "@app/db/schemas";
|
||||||
import {
|
import {
|
||||||
@@ -119,7 +119,7 @@ export const newProjectMembershipIdentityFactory = ({
|
|||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionIdentityActions.Edit,
|
ProjectPermissionIdentityActions.Edit,
|
||||||
ProjectPermissionSub.Identity
|
subject(ProjectPermissionSub.Identity, { identityId: dto.selector.identityId })
|
||||||
);
|
);
|
||||||
|
|
||||||
const identityDetails = await identityDAL.findById(dto.selector.identityId);
|
const identityDetails = await identityDAL.findById(dto.selector.identityId);
|
||||||
@@ -168,7 +168,7 @@ export const newProjectMembershipIdentityFactory = ({
|
|||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionIdentityActions.Delete,
|
ProjectPermissionIdentityActions.Delete,
|
||||||
ProjectPermissionSub.Identity
|
subject(ProjectPermissionSub.Identity, { identityId: dto.selector.identityId })
|
||||||
);
|
);
|
||||||
|
|
||||||
const identityDetails = await identityDAL.findById(dto.selector.identityId);
|
const identityDetails = await identityDAL.findById(dto.selector.identityId);
|
||||||
@@ -210,7 +210,7 @@ export const newProjectMembershipIdentityFactory = ({
|
|||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(
|
ForbiddenError.from(permission).throwUnlessCan(
|
||||||
ProjectPermissionIdentityActions.Read,
|
ProjectPermissionIdentityActions.Read,
|
||||||
ProjectPermissionSub.Identity
|
subject(ProjectPermissionSub.Identity, { identityId: dto.selector.identityId })
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,11 @@ export enum ProjectPermissionIdentityActions {
|
|||||||
Edit = "edit",
|
Edit = "edit",
|
||||||
Delete = "delete",
|
Delete = "delete",
|
||||||
GrantPrivileges = "grant-privileges",
|
GrantPrivileges = "grant-privileges",
|
||||||
AssumePrivileges = "assume-privileges"
|
AssumePrivileges = "assume-privileges",
|
||||||
|
RevokeAuth = "revoke-auth",
|
||||||
|
CreateToken = "create-token",
|
||||||
|
GetToken = "get-token",
|
||||||
|
DeleteToken = "delete-token"
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ProjectPermissionMemberActions {
|
export enum ProjectPermissionMemberActions {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||||
|
|
||||||
import { apiRequest } from "@app/config/request";
|
import { apiRequest } from "@app/config/request";
|
||||||
|
import { projectIdentityQuery, projectKeys } from "@app/hooks/api";
|
||||||
|
|
||||||
import { organizationKeys } from "../organization/queries";
|
import { organizationKeys } from "../organization/queries";
|
||||||
import { subscriptionQueryKeys } from "../subscriptions/queries";
|
|
||||||
import { identitiesKeys } from "./queries";
|
import { identitiesKeys } from "./queries";
|
||||||
import {
|
import {
|
||||||
AddIdentityAliCloudAuthDTO,
|
AddIdentityAliCloudAuthDTO,
|
||||||
@@ -21,7 +21,6 @@ import {
|
|||||||
ClearIdentityLdapAuthLockoutsDTO,
|
ClearIdentityLdapAuthLockoutsDTO,
|
||||||
ClearIdentityUniversalAuthLockoutsDTO,
|
ClearIdentityUniversalAuthLockoutsDTO,
|
||||||
ClientSecretData,
|
ClientSecretData,
|
||||||
CreateIdentityDTO,
|
|
||||||
CreateIdentityUniversalAuthClientSecretDTO,
|
CreateIdentityUniversalAuthClientSecretDTO,
|
||||||
CreateIdentityUniversalAuthClientSecretRes,
|
CreateIdentityUniversalAuthClientSecretRes,
|
||||||
CreateTokenIdentityTokenAuthDTO,
|
CreateTokenIdentityTokenAuthDTO,
|
||||||
@@ -29,7 +28,6 @@ import {
|
|||||||
DeleteIdentityAliCloudAuthDTO,
|
DeleteIdentityAliCloudAuthDTO,
|
||||||
DeleteIdentityAwsAuthDTO,
|
DeleteIdentityAwsAuthDTO,
|
||||||
DeleteIdentityAzureAuthDTO,
|
DeleteIdentityAzureAuthDTO,
|
||||||
DeleteIdentityDTO,
|
|
||||||
DeleteIdentityGcpAuthDTO,
|
DeleteIdentityGcpAuthDTO,
|
||||||
DeleteIdentityJwtAuthDTO,
|
DeleteIdentityJwtAuthDTO,
|
||||||
DeleteIdentityKubernetesAuthDTO,
|
DeleteIdentityKubernetesAuthDTO,
|
||||||
@@ -40,7 +38,6 @@ import {
|
|||||||
DeleteIdentityTokenAuthDTO,
|
DeleteIdentityTokenAuthDTO,
|
||||||
DeleteIdentityUniversalAuthClientSecretDTO,
|
DeleteIdentityUniversalAuthClientSecretDTO,
|
||||||
DeleteIdentityUniversalAuthDTO,
|
DeleteIdentityUniversalAuthDTO,
|
||||||
Identity,
|
|
||||||
IdentityAccessToken,
|
IdentityAccessToken,
|
||||||
IdentityAliCloudAuth,
|
IdentityAliCloudAuth,
|
||||||
IdentityAwsAuth,
|
IdentityAwsAuth,
|
||||||
@@ -59,7 +56,6 @@ import {
|
|||||||
UpdateIdentityAliCloudAuthDTO,
|
UpdateIdentityAliCloudAuthDTO,
|
||||||
UpdateIdentityAwsAuthDTO,
|
UpdateIdentityAwsAuthDTO,
|
||||||
UpdateIdentityAzureAuthDTO,
|
UpdateIdentityAzureAuthDTO,
|
||||||
UpdateIdentityDTO,
|
|
||||||
UpdateIdentityGcpAuthDTO,
|
UpdateIdentityGcpAuthDTO,
|
||||||
UpdateIdentityJwtAuthDTO,
|
UpdateIdentityJwtAuthDTO,
|
||||||
UpdateIdentityKubernetesAuthDTO,
|
UpdateIdentityKubernetesAuthDTO,
|
||||||
@@ -72,73 +68,6 @@ import {
|
|||||||
UpdateTokenIdentityTokenAuthDTO
|
UpdateTokenIdentityTokenAuthDTO
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
export const useCreateIdentity = () => {
|
|
||||||
const queryClient = useQueryClient();
|
|
||||||
return useMutation<Identity, object, CreateIdentityDTO>({
|
|
||||||
mutationFn: async (body) => {
|
|
||||||
const {
|
|
||||||
data: { identity }
|
|
||||||
} = await apiRequest.post("/api/v1/identities/", body);
|
|
||||||
return identity;
|
|
||||||
},
|
|
||||||
onSuccess: (_, { organizationId }) => {
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: subscriptionQueryKeys.getOrgSubsription(organizationId)
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.searchIdentitiesRoot });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useUpdateIdentity = () => {
|
|
||||||
const queryClient = useQueryClient();
|
|
||||||
return useMutation<Identity, object, UpdateIdentityDTO>({
|
|
||||||
mutationFn: async ({ identityId, name, role, hasDeleteProtection, metadata }) => {
|
|
||||||
const {
|
|
||||||
data: { identity }
|
|
||||||
} = await apiRequest.patch(`/api/v1/identities/${identityId}`, {
|
|
||||||
name,
|
|
||||||
role,
|
|
||||||
hasDeleteProtection,
|
|
||||||
metadata
|
|
||||||
});
|
|
||||||
|
|
||||||
return identity;
|
|
||||||
},
|
|
||||||
onSuccess: (_, { organizationId, identityId }) => {
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.searchIdentitiesRoot });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useDeleteIdentity = () => {
|
|
||||||
const queryClient = useQueryClient();
|
|
||||||
return useMutation<Identity, object, DeleteIdentityDTO>({
|
|
||||||
mutationFn: async ({ identityId }) => {
|
|
||||||
const {
|
|
||||||
data: { identity }
|
|
||||||
} = await apiRequest.delete(`/api/v1/identities/${identityId}`);
|
|
||||||
return identity;
|
|
||||||
},
|
|
||||||
onSuccess: (_, { organizationId }) => {
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: subscriptionQueryKeys.getOrgSubsription(organizationId)
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.searchIdentitiesRoot });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: move these to /auth
|
// TODO: move these to /auth
|
||||||
|
|
||||||
export const useAddIdentityUniversalAuth = () => {
|
export const useAddIdentityUniversalAuth = () => {
|
||||||
@@ -171,10 +100,20 @@ export const useAddIdentityUniversalAuth = () => {
|
|||||||
});
|
});
|
||||||
return identityUniversalAuth;
|
return identityUniversalAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: identitiesKeys.getIdentityUniversalAuth(identityId)
|
queryKey: identitiesKeys.getIdentityUniversalAuth(identityId)
|
||||||
@@ -215,10 +154,20 @@ export const useUpdateIdentityUniversalAuth = () => {
|
|||||||
});
|
});
|
||||||
return identityUniversalAuth;
|
return identityUniversalAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: identitiesKeys.getIdentityUniversalAuth(identityId)
|
queryKey: identitiesKeys.getIdentityUniversalAuth(identityId)
|
||||||
@@ -236,10 +185,20 @@ export const useDeleteIdentityUniversalAuth = () => {
|
|||||||
} = await apiRequest.delete(`/api/v1/auth/universal-auth/identities/${identityId}`);
|
} = await apiRequest.delete(`/api/v1/auth/universal-auth/identities/${identityId}`);
|
||||||
return identityUniversalAuth;
|
return identityUniversalAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { organizationId, identityId }) => {
|
onSuccess: (_, { organizationId, identityId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: identitiesKeys.getIdentityUniversalAuth(identityId)
|
queryKey: identitiesKeys.getIdentityUniversalAuth(identityId)
|
||||||
@@ -344,10 +303,20 @@ export const useAddIdentityGcpAuth = () => {
|
|||||||
|
|
||||||
return identityGcpAuth;
|
return identityGcpAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityGcpAuth(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityGcpAuth(identityId) });
|
||||||
}
|
}
|
||||||
@@ -386,10 +355,20 @@ export const useUpdateIdentityGcpAuth = () => {
|
|||||||
|
|
||||||
return identityGcpAuth;
|
return identityGcpAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityGcpAuth(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityGcpAuth(identityId) });
|
||||||
}
|
}
|
||||||
@@ -405,10 +384,20 @@ export const useDeleteIdentityGcpAuth = () => {
|
|||||||
} = await apiRequest.delete(`/api/v1/auth/gcp-auth/identities/${identityId}`);
|
} = await apiRequest.delete(`/api/v1/auth/gcp-auth/identities/${identityId}`);
|
||||||
return identityGcpAuth;
|
return identityGcpAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { organizationId, identityId }) => {
|
onSuccess: (_, { organizationId, identityId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityGcpAuth(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityGcpAuth(identityId) });
|
||||||
}
|
}
|
||||||
@@ -445,10 +434,20 @@ export const useAddIdentityAwsAuth = () => {
|
|||||||
|
|
||||||
return identityAwsAuth;
|
return identityAwsAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityAwsAuth(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityAwsAuth(identityId) });
|
||||||
}
|
}
|
||||||
@@ -485,10 +484,20 @@ export const useUpdateIdentityAwsAuth = () => {
|
|||||||
|
|
||||||
return identityAwsAuth;
|
return identityAwsAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityAwsAuth(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityAwsAuth(identityId) });
|
||||||
}
|
}
|
||||||
@@ -504,10 +513,20 @@ export const useDeleteIdentityAwsAuth = () => {
|
|||||||
} = await apiRequest.delete(`/api/v1/auth/aws-auth/identities/${identityId}`);
|
} = await apiRequest.delete(`/api/v1/auth/aws-auth/identities/${identityId}`);
|
||||||
return identityAwsAuth;
|
return identityAwsAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { organizationId, identityId }) => {
|
onSuccess: (_, { organizationId, identityId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityAwsAuth(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityAwsAuth(identityId) });
|
||||||
}
|
}
|
||||||
@@ -542,10 +561,20 @@ export const useAddIdentityOciAuth = () => {
|
|||||||
|
|
||||||
return identityOciAuth;
|
return identityOciAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityOciAuth(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityOciAuth(identityId) });
|
||||||
}
|
}
|
||||||
@@ -580,10 +609,20 @@ export const useUpdateIdentityOciAuth = () => {
|
|||||||
|
|
||||||
return identityOciAuth;
|
return identityOciAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityOciAuth(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityOciAuth(identityId) });
|
||||||
}
|
}
|
||||||
@@ -599,10 +638,20 @@ export const useDeleteIdentityOciAuth = () => {
|
|||||||
} = await apiRequest.delete(`/api/v1/auth/oci-auth/identities/${identityId}`);
|
} = await apiRequest.delete(`/api/v1/auth/oci-auth/identities/${identityId}`);
|
||||||
return identityOciAuth;
|
return identityOciAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { organizationId, identityId }) => {
|
onSuccess: (_, { organizationId, identityId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityOciAuth(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityOciAuth(identityId) });
|
||||||
}
|
}
|
||||||
@@ -635,10 +684,20 @@ export const useAddIdentityAliCloudAuth = () => {
|
|||||||
|
|
||||||
return identityAliCloudAuth;
|
return identityAliCloudAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: identitiesKeys.getIdentityAliCloudAuth(identityId)
|
queryKey: identitiesKeys.getIdentityAliCloudAuth(identityId)
|
||||||
@@ -673,10 +732,20 @@ export const useUpdateIdentityAliCloudAuth = () => {
|
|||||||
|
|
||||||
return identityAliCloudAuth;
|
return identityAliCloudAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: identitiesKeys.getIdentityAliCloudAuth(identityId)
|
queryKey: identitiesKeys.getIdentityAliCloudAuth(identityId)
|
||||||
@@ -694,10 +763,20 @@ export const useDeleteIdentityAliCloudAuth = () => {
|
|||||||
} = await apiRequest.delete(`/api/v1/auth/alicloud-auth/identities/${identityId}`);
|
} = await apiRequest.delete(`/api/v1/auth/alicloud-auth/identities/${identityId}`);
|
||||||
return identityAliCloudAuth;
|
return identityAliCloudAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { organizationId, identityId }) => {
|
onSuccess: (_, { organizationId, identityId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: identitiesKeys.getIdentityAliCloudAuth(identityId)
|
queryKey: identitiesKeys.getIdentityAliCloudAuth(identityId)
|
||||||
@@ -734,10 +813,20 @@ export const useAddIdentityTlsCertAuth = () => {
|
|||||||
|
|
||||||
return identityTlsCertAuth;
|
return identityTlsCertAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: identitiesKeys.getIdentityTlsCertAuth(identityId)
|
queryKey: identitiesKeys.getIdentityTlsCertAuth(identityId)
|
||||||
@@ -774,10 +863,20 @@ export const useUpdateIdentityTlsCertAuth = () => {
|
|||||||
|
|
||||||
return identityTlsCertAuth;
|
return identityTlsCertAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: identitiesKeys.getIdentityTlsCertAuth(identityId)
|
queryKey: identitiesKeys.getIdentityTlsCertAuth(identityId)
|
||||||
@@ -795,10 +894,20 @@ export const useDeleteIdentityTlsCertAuth = () => {
|
|||||||
} = await apiRequest.delete(`/api/v1/auth/tls-cert-auth/identities/${identityId}`);
|
} = await apiRequest.delete(`/api/v1/auth/tls-cert-auth/identities/${identityId}`);
|
||||||
return identityTlsCertAuth;
|
return identityTlsCertAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { organizationId, identityId }) => {
|
onSuccess: (_, { organizationId, identityId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: identitiesKeys.getIdentityTlsCertAuth(identityId)
|
queryKey: identitiesKeys.getIdentityTlsCertAuth(identityId)
|
||||||
@@ -845,10 +954,20 @@ export const useUpdateIdentityOidcAuth = () => {
|
|||||||
|
|
||||||
return identityOidcAuth;
|
return identityOidcAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityOidcAuth(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityOidcAuth(identityId) });
|
||||||
}
|
}
|
||||||
@@ -893,10 +1012,20 @@ export const useAddIdentityOidcAuth = () => {
|
|||||||
|
|
||||||
return identityOidcAuth;
|
return identityOidcAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityOidcAuth(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityOidcAuth(identityId) });
|
||||||
}
|
}
|
||||||
@@ -912,10 +1041,20 @@ export const useDeleteIdentityOidcAuth = () => {
|
|||||||
} = await apiRequest.delete(`/api/v1/auth/oidc-auth/identities/${identityId}`);
|
} = await apiRequest.delete(`/api/v1/auth/oidc-auth/identities/${identityId}`);
|
||||||
return identityOidcAuth;
|
return identityOidcAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { organizationId, identityId }) => {
|
onSuccess: (_, { organizationId, identityId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityOidcAuth(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityOidcAuth(identityId) });
|
||||||
}
|
}
|
||||||
@@ -961,10 +1100,20 @@ export const useUpdateIdentityJwtAuth = () => {
|
|||||||
|
|
||||||
return identityJwtAuth;
|
return identityJwtAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityJwtAuth(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityJwtAuth(identityId) });
|
||||||
}
|
}
|
||||||
@@ -1011,10 +1160,20 @@ export const useAddIdentityJwtAuth = () => {
|
|||||||
|
|
||||||
return identityJwtAuth;
|
return identityJwtAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityJwtAuth(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityJwtAuth(identityId) });
|
||||||
}
|
}
|
||||||
@@ -1030,10 +1189,20 @@ export const useDeleteIdentityJwtAuth = () => {
|
|||||||
} = await apiRequest.delete(`/api/v1/auth/jwt-auth/identities/${identityId}`);
|
} = await apiRequest.delete(`/api/v1/auth/jwt-auth/identities/${identityId}`);
|
||||||
return identityJwtAuth;
|
return identityJwtAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { organizationId, identityId }) => {
|
onSuccess: (_, { organizationId, identityId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityJwtAuth(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityJwtAuth(identityId) });
|
||||||
}
|
}
|
||||||
@@ -1070,10 +1239,20 @@ export const useAddIdentityAzureAuth = () => {
|
|||||||
|
|
||||||
return identityAzureAuth;
|
return identityAzureAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: identitiesKeys.getIdentityKubernetesAuth(identityId)
|
queryKey: identitiesKeys.getIdentityKubernetesAuth(identityId)
|
||||||
@@ -1122,10 +1301,20 @@ export const useAddIdentityKubernetesAuth = () => {
|
|||||||
|
|
||||||
return identityKubernetesAuth;
|
return identityKubernetesAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityAzureAuth(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityAzureAuth(identityId) });
|
||||||
}
|
}
|
||||||
@@ -1162,10 +1351,20 @@ export const useUpdateIdentityAzureAuth = () => {
|
|||||||
|
|
||||||
return identityAzureAuth;
|
return identityAzureAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityAzureAuth(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityAzureAuth(identityId) });
|
||||||
}
|
}
|
||||||
@@ -1181,10 +1380,20 @@ export const useDeleteIdentityAzureAuth = () => {
|
|||||||
} = await apiRequest.delete(`/api/v1/auth/azure-auth/identities/${identityId}`);
|
} = await apiRequest.delete(`/api/v1/auth/azure-auth/identities/${identityId}`);
|
||||||
return identityAzureAuth;
|
return identityAzureAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { organizationId, identityId }) => {
|
onSuccess: (_, { organizationId, identityId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityAzureAuth(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityAzureAuth(identityId) });
|
||||||
}
|
}
|
||||||
@@ -1231,10 +1440,20 @@ export const useUpdateIdentityKubernetesAuth = () => {
|
|||||||
|
|
||||||
return identityKubernetesAuth;
|
return identityKubernetesAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: identitiesKeys.getIdentityKubernetesAuth(identityId)
|
queryKey: identitiesKeys.getIdentityKubernetesAuth(identityId)
|
||||||
@@ -1252,10 +1471,20 @@ export const useDeleteIdentityKubernetesAuth = () => {
|
|||||||
} = await apiRequest.delete(`/api/v1/auth/kubernetes-auth/identities/${identityId}`);
|
} = await apiRequest.delete(`/api/v1/auth/kubernetes-auth/identities/${identityId}`);
|
||||||
return identityKubernetesAuth;
|
return identityKubernetesAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { organizationId, identityId }) => {
|
onSuccess: (_, { organizationId, identityId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: identitiesKeys.getIdentityKubernetesAuth(identityId)
|
queryKey: identitiesKeys.getIdentityKubernetesAuth(identityId)
|
||||||
@@ -1288,10 +1517,20 @@ export const useAddIdentityTokenAuth = () => {
|
|||||||
|
|
||||||
return identityTokenAuth;
|
return identityTokenAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: identitiesKeys.getIdentityTokenAuth(identityId)
|
queryKey: identitiesKeys.getIdentityTokenAuth(identityId)
|
||||||
@@ -1324,10 +1563,20 @@ export const useUpdateIdentityTokenAuth = () => {
|
|||||||
|
|
||||||
return identityTokenAuth;
|
return identityTokenAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: identitiesKeys.getIdentityTokenAuth(identityId)
|
queryKey: identitiesKeys.getIdentityTokenAuth(identityId)
|
||||||
@@ -1345,10 +1594,20 @@ export const useDeleteIdentityTokenAuth = () => {
|
|||||||
} = await apiRequest.delete(`/api/v1/auth/token-auth/identities/${identityId}`);
|
} = await apiRequest.delete(`/api/v1/auth/token-auth/identities/${identityId}`);
|
||||||
return identityTokenAuth;
|
return identityTokenAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { organizationId, identityId }) => {
|
onSuccess: (_, { organizationId, identityId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityTokenAuth(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityTokenAuth(identityId) });
|
||||||
}
|
}
|
||||||
@@ -1462,10 +1721,20 @@ export const useAddIdentityLdapAuth = () => {
|
|||||||
);
|
);
|
||||||
return data.identityLdapAuth;
|
return data.identityLdapAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: identitiesKeys.getIdentityLdapAuth(identityId)
|
queryKey: identitiesKeys.getIdentityLdapAuth(identityId)
|
||||||
@@ -1519,10 +1788,20 @@ export const useUpdateIdentityLdapAuth = () => {
|
|||||||
);
|
);
|
||||||
return data.identityLdapAuth;
|
return data.identityLdapAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { identityId, organizationId }) => {
|
onSuccess: (_, { identityId, organizationId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: identitiesKeys.getIdentityLdapAuth(identityId)
|
queryKey: identitiesKeys.getIdentityLdapAuth(identityId)
|
||||||
@@ -1538,10 +1817,20 @@ export const useDeleteIdentityLdapAuth = () => {
|
|||||||
const { data } = await apiRequest.delete(`/api/v1/auth/ldap-auth/identities/${identityId}`);
|
const { data } = await apiRequest.delete(`/api/v1/auth/ldap-auth/identities/${identityId}`);
|
||||||
return data.identityLdapAuth;
|
return data.identityLdapAuth;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { organizationId, identityId }) => {
|
onSuccess: (_, { organizationId, identityId, projectId }) => {
|
||||||
queryClient.invalidateQueries({
|
if (organizationId) {
|
||||||
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
queryClient.invalidateQueries({
|
||||||
});
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (projectId) {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectIdentityQuery.getByIdKey({ identityId, projectId })
|
||||||
|
});
|
||||||
|
}
|
||||||
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
queryKey: identitiesKeys.getIdentityLdapAuth(identityId)
|
queryKey: identitiesKeys.getIdentityLdapAuth(identityId)
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ import {
|
|||||||
IdentityJwtAuth,
|
IdentityJwtAuth,
|
||||||
IdentityKubernetesAuth,
|
IdentityKubernetesAuth,
|
||||||
IdentityLdapAuth,
|
IdentityLdapAuth,
|
||||||
IdentityMembership,
|
|
||||||
IdentityMembershipOrg,
|
IdentityMembershipOrg,
|
||||||
IdentityOciAuth,
|
IdentityOciAuth,
|
||||||
IdentityOidcAuth,
|
IdentityOidcAuth,
|
||||||
|
IdentityProjectMembership,
|
||||||
IdentityTlsCertAuth,
|
IdentityTlsCertAuth,
|
||||||
IdentityTokenAuth,
|
IdentityTokenAuth,
|
||||||
IdentityUniversalAuth,
|
IdentityUniversalAuth,
|
||||||
@@ -52,7 +52,7 @@ export const identitiesKeys = {
|
|||||||
[{ identityId }, "identity-project-memberships"] as const
|
[{ identityId }, "identity-project-memberships"] as const
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetIdentityById = (identityId: string) => {
|
export const useGetOrgIdentityMembershipById = (identityId: string) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
enabled: Boolean(identityId),
|
enabled: Boolean(identityId),
|
||||||
queryKey: identitiesKeys.getIdentityById(identityId),
|
queryKey: identitiesKeys.getIdentityById(identityId),
|
||||||
@@ -67,7 +67,7 @@ export const useGetIdentityById = (identityId: string) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useSearchIdentities = (dto: TSearchIdentitiesDTO) => {
|
export const useSearchOrgIdentityMemberships = (dto: TSearchIdentitiesDTO) => {
|
||||||
const { limit, search, offset, orderBy, orderDirection } = dto;
|
const { limit, search, offset, orderBy, orderDirection } = dto;
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: identitiesKeys.searchIdentities(dto),
|
queryKey: identitiesKeys.searchIdentities(dto),
|
||||||
@@ -95,7 +95,7 @@ export const useGetIdentityProjectMemberships = (identityId: string) => {
|
|||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const {
|
const {
|
||||||
data: { identityMemberships }
|
data: { identityMemberships }
|
||||||
} = await apiRequest.get<{ identityMemberships: IdentityMembership[] }>(
|
} = await apiRequest.get<{ identityMemberships: IdentityProjectMembership[] }>(
|
||||||
`/api/v1/identities/${identityId}/identity-memberships`
|
`/api/v1/identities/${identityId}/identity-memberships`
|
||||||
);
|
);
|
||||||
return identityMemberships;
|
return identityMemberships;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
import { TemporaryPermissionMode } from "@app/hooks/api/shared";
|
||||||
|
|
||||||
import { OrderByDirection } from "../generic/types";
|
import { OrderByDirection } from "../generic/types";
|
||||||
import { OrgIdentityOrderBy } from "../organization/types";
|
import { OrgIdentityOrderBy } from "../organization/types";
|
||||||
import { Project, ProjectUserMembershipTemporaryMode } from "../projects/types";
|
import { Project } from "../projects/types";
|
||||||
import { TOrgRole } from "../roles/types";
|
import { TOrgRole } from "../roles/types";
|
||||||
import { IdentityAuthMethod, IdentityJwtConfigurationType } from "./enums";
|
import { IdentityAuthMethod, IdentityJwtConfigurationType } from "./enums";
|
||||||
|
|
||||||
@@ -21,6 +23,8 @@ export type Identity = {
|
|||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
isInstanceAdmin?: boolean;
|
isInstanceAdmin?: boolean;
|
||||||
orgId: string;
|
orgId: string;
|
||||||
|
projectId?: string | null;
|
||||||
|
metadata?: { key: string; value: string; id: string }[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type IdentityAccessToken = {
|
export type IdentityAccessToken = {
|
||||||
@@ -52,7 +56,7 @@ export type IdentityMembershipOrg = {
|
|||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type IdentityMembership = {
|
export type IdentityProjectMembership = {
|
||||||
id: string;
|
id: string;
|
||||||
identity: Identity;
|
identity: Identity;
|
||||||
project: Pick<Project, "id" | "name" | "type">;
|
project: Pick<Project, "id" | "name" | "type">;
|
||||||
@@ -74,7 +78,7 @@ export type IdentityMembership = {
|
|||||||
| {
|
| {
|
||||||
isTemporary: true;
|
isTemporary: true;
|
||||||
temporaryRange: string;
|
temporaryRange: string;
|
||||||
temporaryMode: ProjectUserMembershipTemporaryMode;
|
temporaryMode: TemporaryPermissionMode;
|
||||||
temporaryAccessEndTime: string;
|
temporaryAccessEndTime: string;
|
||||||
temporaryAccessStartTime: string;
|
temporaryAccessStartTime: string;
|
||||||
}
|
}
|
||||||
@@ -82,6 +86,8 @@ export type IdentityMembership = {
|
|||||||
>;
|
>;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
|
lastLoginTime?: string;
|
||||||
|
lastLoginAuthMethod?: IdentityAuthMethod;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type CreateIdentityDTO = {
|
export type CreateIdentityDTO = {
|
||||||
@@ -122,7 +128,8 @@ export type IdentityUniversalAuth = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type AddIdentityUniversalAuthDTO = {
|
export type AddIdentityUniversalAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
clientSecretTrustedIps: {
|
clientSecretTrustedIps: {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
@@ -138,10 +145,11 @@ export type AddIdentityUniversalAuthDTO = {
|
|||||||
lockoutThreshold: number;
|
lockoutThreshold: number;
|
||||||
lockoutDurationSeconds: number;
|
lockoutDurationSeconds: number;
|
||||||
lockoutCounterResetSeconds: number;
|
lockoutCounterResetSeconds: number;
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type UpdateIdentityUniversalAuthDTO = {
|
export type UpdateIdentityUniversalAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
clientSecretTrustedIps?: {
|
clientSecretTrustedIps?: {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
@@ -157,12 +165,13 @@ export type UpdateIdentityUniversalAuthDTO = {
|
|||||||
lockoutThreshold?: number;
|
lockoutThreshold?: number;
|
||||||
lockoutDurationSeconds?: number;
|
lockoutDurationSeconds?: number;
|
||||||
lockoutCounterResetSeconds?: number;
|
lockoutCounterResetSeconds?: number;
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type DeleteIdentityUniversalAuthDTO = {
|
export type DeleteIdentityUniversalAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type IdentityGcpAuth = {
|
export type IdentityGcpAuth = {
|
||||||
identityId: string;
|
identityId: string;
|
||||||
@@ -177,7 +186,8 @@ export type IdentityGcpAuth = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type AddIdentityGcpAuthDTO = {
|
export type AddIdentityGcpAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
type: "iam" | "gce";
|
type: "iam" | "gce";
|
||||||
allowedServiceAccounts: string;
|
allowedServiceAccounts: string;
|
||||||
@@ -189,10 +199,11 @@ export type AddIdentityGcpAuthDTO = {
|
|||||||
accessTokenTrustedIps: {
|
accessTokenTrustedIps: {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type UpdateIdentityGcpAuthDTO = {
|
export type UpdateIdentityGcpAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
type?: "iam" | "gce";
|
type?: "iam" | "gce";
|
||||||
allowedServiceAccounts?: string;
|
allowedServiceAccounts?: string;
|
||||||
@@ -204,12 +215,13 @@ export type UpdateIdentityGcpAuthDTO = {
|
|||||||
accessTokenTrustedIps?: {
|
accessTokenTrustedIps?: {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type DeleteIdentityGcpAuthDTO = {
|
export type DeleteIdentityGcpAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type IdentityOidcAuth = {
|
export type IdentityOidcAuth = {
|
||||||
identityId: string;
|
identityId: string;
|
||||||
@@ -227,7 +239,8 @@ export type IdentityOidcAuth = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type AddIdentityOidcAuthDTO = {
|
export type AddIdentityOidcAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
oidcDiscoveryUrl: string;
|
oidcDiscoveryUrl: string;
|
||||||
caCert: string;
|
caCert: string;
|
||||||
@@ -242,10 +255,11 @@ export type AddIdentityOidcAuthDTO = {
|
|||||||
accessTokenTrustedIps: {
|
accessTokenTrustedIps: {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type UpdateIdentityOidcAuthDTO = {
|
export type UpdateIdentityOidcAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
oidcDiscoveryUrl?: string;
|
oidcDiscoveryUrl?: string;
|
||||||
caCert?: string;
|
caCert?: string;
|
||||||
@@ -260,12 +274,13 @@ export type UpdateIdentityOidcAuthDTO = {
|
|||||||
accessTokenTrustedIps?: {
|
accessTokenTrustedIps?: {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type DeleteIdentityOidcAuthDTO = {
|
export type DeleteIdentityOidcAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type IdentityAwsAuth = {
|
export type IdentityAwsAuth = {
|
||||||
identityId: string;
|
identityId: string;
|
||||||
@@ -280,7 +295,8 @@ export type IdentityAwsAuth = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type AddIdentityAwsAuthDTO = {
|
export type AddIdentityAwsAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
stsEndpoint: string;
|
stsEndpoint: string;
|
||||||
allowedPrincipalArns: string;
|
allowedPrincipalArns: string;
|
||||||
@@ -291,10 +307,11 @@ export type AddIdentityAwsAuthDTO = {
|
|||||||
accessTokenTrustedIps: {
|
accessTokenTrustedIps: {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type UpdateIdentityAwsAuthDTO = {
|
export type UpdateIdentityAwsAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
stsEndpoint?: string;
|
stsEndpoint?: string;
|
||||||
allowedPrincipalArns?: string;
|
allowedPrincipalArns?: string;
|
||||||
@@ -308,9 +325,10 @@ export type UpdateIdentityAwsAuthDTO = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type DeleteIdentityAwsAuthDTO = {
|
export type DeleteIdentityAwsAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type IdentityAliCloudAuth = {
|
export type IdentityAliCloudAuth = {
|
||||||
identityId: string;
|
identityId: string;
|
||||||
@@ -323,7 +341,8 @@ export type IdentityAliCloudAuth = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type AddIdentityAliCloudAuthDTO = {
|
export type AddIdentityAliCloudAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
allowedArns: string;
|
allowedArns: string;
|
||||||
accessTokenTTL: number;
|
accessTokenTTL: number;
|
||||||
@@ -332,10 +351,11 @@ export type AddIdentityAliCloudAuthDTO = {
|
|||||||
accessTokenTrustedIps: {
|
accessTokenTrustedIps: {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type UpdateIdentityAliCloudAuthDTO = {
|
export type UpdateIdentityAliCloudAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
allowedArns: string;
|
allowedArns: string;
|
||||||
accessTokenTTL?: number;
|
accessTokenTTL?: number;
|
||||||
@@ -344,12 +364,13 @@ export type UpdateIdentityAliCloudAuthDTO = {
|
|||||||
accessTokenTrustedIps?: {
|
accessTokenTrustedIps?: {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type DeleteIdentityAliCloudAuthDTO = {
|
export type DeleteIdentityAliCloudAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type IdentityOciAuth = {
|
export type IdentityOciAuth = {
|
||||||
identityId: string;
|
identityId: string;
|
||||||
@@ -363,7 +384,8 @@ export type IdentityOciAuth = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type AddIdentityOciAuthDTO = {
|
export type AddIdentityOciAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
tenancyOcid: string;
|
tenancyOcid: string;
|
||||||
allowedUsernames?: string | null;
|
allowedUsernames?: string | null;
|
||||||
@@ -373,10 +395,11 @@ export type AddIdentityOciAuthDTO = {
|
|||||||
accessTokenTrustedIps: {
|
accessTokenTrustedIps: {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type UpdateIdentityOciAuthDTO = {
|
export type UpdateIdentityOciAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
tenancyOcid?: string;
|
tenancyOcid?: string;
|
||||||
allowedUsernames?: string | null;
|
allowedUsernames?: string | null;
|
||||||
@@ -386,12 +409,13 @@ export type UpdateIdentityOciAuthDTO = {
|
|||||||
accessTokenTrustedIps?: {
|
accessTokenTrustedIps?: {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type DeleteIdentityOciAuthDTO = {
|
export type DeleteIdentityOciAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type IdentityAzureAuth = {
|
export type IdentityAzureAuth = {
|
||||||
identityId: string;
|
identityId: string;
|
||||||
@@ -405,7 +429,8 @@ export type IdentityAzureAuth = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type AddIdentityAzureAuthDTO = {
|
export type AddIdentityAzureAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
tenantId: string;
|
tenantId: string;
|
||||||
resource: string;
|
resource: string;
|
||||||
@@ -416,10 +441,11 @@ export type AddIdentityAzureAuthDTO = {
|
|||||||
accessTokenTrustedIps: {
|
accessTokenTrustedIps: {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type UpdateIdentityAzureAuthDTO = {
|
export type UpdateIdentityAzureAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
tenantId?: string;
|
tenantId?: string;
|
||||||
resource?: string;
|
resource?: string;
|
||||||
@@ -430,12 +456,13 @@ export type UpdateIdentityAzureAuthDTO = {
|
|||||||
accessTokenTrustedIps?: {
|
accessTokenTrustedIps?: {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type DeleteIdentityAzureAuthDTO = {
|
export type DeleteIdentityAzureAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export enum IdentityKubernetesAuthTokenReviewMode {
|
export enum IdentityKubernetesAuthTokenReviewMode {
|
||||||
Api = "api",
|
Api = "api",
|
||||||
@@ -459,7 +486,8 @@ export type IdentityKubernetesAuth = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type AddIdentityKubernetesAuthDTO = {
|
export type AddIdentityKubernetesAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
kubernetesHost: string | null;
|
kubernetesHost: string | null;
|
||||||
tokenReviewerJwt?: string;
|
tokenReviewerJwt?: string;
|
||||||
@@ -475,10 +503,11 @@ export type AddIdentityKubernetesAuthDTO = {
|
|||||||
accessTokenTrustedIps: {
|
accessTokenTrustedIps: {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type UpdateIdentityKubernetesAuthDTO = {
|
export type UpdateIdentityKubernetesAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
kubernetesHost?: string | null;
|
kubernetesHost?: string | null;
|
||||||
tokenReviewerJwt?: string | null;
|
tokenReviewerJwt?: string | null;
|
||||||
@@ -494,12 +523,13 @@ export type UpdateIdentityKubernetesAuthDTO = {
|
|||||||
accessTokenTrustedIps?: {
|
accessTokenTrustedIps?: {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type DeleteIdentityKubernetesAuthDTO = {
|
export type DeleteIdentityKubernetesAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type IdentityTlsCertAuth = {
|
export type IdentityTlsCertAuth = {
|
||||||
identityId: string;
|
identityId: string;
|
||||||
@@ -512,7 +542,8 @@ export type IdentityTlsCertAuth = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type AddIdentityTlsCertAuthDTO = {
|
export type AddIdentityTlsCertAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
caCertificate: string;
|
caCertificate: string;
|
||||||
allowedCommonNames?: string;
|
allowedCommonNames?: string;
|
||||||
@@ -522,10 +553,11 @@ export type AddIdentityTlsCertAuthDTO = {
|
|||||||
accessTokenTrustedIps: {
|
accessTokenTrustedIps: {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type UpdateIdentityTlsCertAuthDTO = {
|
export type UpdateIdentityTlsCertAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
caCertificate: string;
|
caCertificate: string;
|
||||||
allowedCommonNames?: string | null;
|
allowedCommonNames?: string | null;
|
||||||
@@ -535,12 +567,13 @@ export type UpdateIdentityTlsCertAuthDTO = {
|
|||||||
accessTokenTrustedIps?: {
|
accessTokenTrustedIps?: {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type DeleteIdentityTlsCertAuthDTO = {
|
export type DeleteIdentityTlsCertAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type CreateIdentityUniversalAuthClientSecretDTO = {
|
export type CreateIdentityUniversalAuthClientSecretDTO = {
|
||||||
identityId: string;
|
identityId: string;
|
||||||
@@ -585,7 +618,8 @@ export type IdentityTokenAuth = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type AddIdentityLdapAuthDTO = {
|
export type AddIdentityLdapAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
templateId?: string;
|
templateId?: string;
|
||||||
url?: string;
|
url?: string;
|
||||||
@@ -609,11 +643,12 @@ export type AddIdentityLdapAuthDTO = {
|
|||||||
lockoutThreshold: number;
|
lockoutThreshold: number;
|
||||||
lockoutDurationSeconds: number;
|
lockoutDurationSeconds: number;
|
||||||
lockoutCounterResetSeconds: number;
|
lockoutCounterResetSeconds: number;
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type UpdateIdentityLdapAuthDTO = {
|
export type UpdateIdentityLdapAuthDTO = {
|
||||||
identityId: string;
|
identityId: string;
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
templateId?: string;
|
templateId?: string;
|
||||||
url?: string;
|
url?: string;
|
||||||
bindDN?: string;
|
bindDN?: string;
|
||||||
@@ -636,12 +671,13 @@ export type UpdateIdentityLdapAuthDTO = {
|
|||||||
lockoutThreshold?: number;
|
lockoutThreshold?: number;
|
||||||
lockoutDurationSeconds?: number;
|
lockoutDurationSeconds?: number;
|
||||||
lockoutCounterResetSeconds?: number;
|
lockoutCounterResetSeconds?: number;
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type DeleteIdentityLdapAuthDTO = {
|
export type DeleteIdentityLdapAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type IdentityLdapAuth = {
|
export type IdentityLdapAuth = {
|
||||||
url?: string;
|
url?: string;
|
||||||
@@ -673,7 +709,8 @@ export type ClearIdentityLdapAuthLockoutsDTO = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type AddIdentityTokenAuthDTO = {
|
export type AddIdentityTokenAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
accessTokenTTL: number;
|
accessTokenTTL: number;
|
||||||
accessTokenMaxTTL: number;
|
accessTokenMaxTTL: number;
|
||||||
@@ -681,10 +718,11 @@ export type AddIdentityTokenAuthDTO = {
|
|||||||
accessTokenTrustedIps: {
|
accessTokenTrustedIps: {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type UpdateIdentityTokenAuthDTO = {
|
export type UpdateIdentityTokenAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
accessTokenTTL?: number;
|
accessTokenTTL?: number;
|
||||||
accessTokenMaxTTL?: number;
|
accessTokenMaxTTL?: number;
|
||||||
@@ -692,12 +730,13 @@ export type UpdateIdentityTokenAuthDTO = {
|
|||||||
accessTokenTrustedIps?: {
|
accessTokenTrustedIps?: {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type DeleteIdentityTokenAuthDTO = {
|
export type DeleteIdentityTokenAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type IdentityJwtAuth = {
|
export type IdentityJwtAuth = {
|
||||||
identityId: string;
|
identityId: string;
|
||||||
@@ -716,7 +755,8 @@ export type IdentityJwtAuth = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type AddIdentityJwtAuthDTO = {
|
export type AddIdentityJwtAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
configurationType: string;
|
configurationType: string;
|
||||||
jwksUrl?: string;
|
jwksUrl?: string;
|
||||||
@@ -732,10 +772,11 @@ export type AddIdentityJwtAuthDTO = {
|
|||||||
accessTokenTrustedIps: {
|
accessTokenTrustedIps: {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type UpdateIdentityJwtAuthDTO = {
|
export type UpdateIdentityJwtAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
configurationType?: string;
|
configurationType?: string;
|
||||||
jwksUrl?: string;
|
jwksUrl?: string;
|
||||||
@@ -751,12 +792,13 @@ export type UpdateIdentityJwtAuthDTO = {
|
|||||||
accessTokenTrustedIps?: {
|
accessTokenTrustedIps?: {
|
||||||
ipAddress: string;
|
ipAddress: string;
|
||||||
}[];
|
}[];
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type DeleteIdentityJwtAuthDTO = {
|
export type DeleteIdentityJwtAuthDTO = {
|
||||||
organizationId: string;
|
organizationId?: string;
|
||||||
|
projectId?: string;
|
||||||
identityId: string;
|
identityId: string;
|
||||||
};
|
} & ({ organizationId: string } | { projectId: string });
|
||||||
|
|
||||||
export type CreateTokenIdentityTokenAuthDTO = {
|
export type CreateTokenIdentityTokenAuthDTO = {
|
||||||
identityId: string;
|
identityId: string;
|
||||||
@@ -785,8 +827,8 @@ export type RevokeTokenRes = {
|
|||||||
message: string;
|
message: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TProjectIdentitiesList = {
|
export type TProjectIdentityMembershipsList = {
|
||||||
identityMemberships: IdentityMembership[];
|
identityMemberships: IdentityProjectMembership[];
|
||||||
totalCount: number;
|
totalCount: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -25,10 +25,14 @@ export * from "./ldapConfig";
|
|||||||
export * from "./oidcConfig";
|
export * from "./oidcConfig";
|
||||||
export * from "./orgAdmin";
|
export * from "./orgAdmin";
|
||||||
export * from "./organization";
|
export * from "./organization";
|
||||||
|
export * from "./orgIdentity";
|
||||||
|
export * from "./orgIdentityMembership";
|
||||||
export * from "./pkiAlerts";
|
export * from "./pkiAlerts";
|
||||||
export * from "./pkiCollections";
|
export * from "./pkiCollections";
|
||||||
export * from "./pkiSubscriber";
|
export * from "./pkiSubscriber";
|
||||||
export * from "./pkiSyncs";
|
export * from "./pkiSyncs";
|
||||||
|
export * from "./projectIdentity";
|
||||||
|
export * from "./projectIdentityMembership";
|
||||||
export * from "./projects";
|
export * from "./projects";
|
||||||
export * from "./projectUserAdditionalPrivilege";
|
export * from "./projectUserAdditionalPrivilege";
|
||||||
export * from "./rateLimit";
|
export * from "./rateLimit";
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export * from "./mutations";
|
||||||
|
export * from "./queries";
|
||||||
|
export type * from "./types";
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
import { apiRequest } from "@app/config/request";
|
||||||
|
import { identitiesKeys } from "@app/hooks/api";
|
||||||
|
import { CreateIdentityDTO, Identity, UpdateIdentityDTO } from "@app/hooks/api/identities/types";
|
||||||
|
import { organizationKeys } from "@app/hooks/api/organization/queries";
|
||||||
|
import { subscriptionQueryKeys } from "@app/hooks/api/subscriptions/queries";
|
||||||
|
|
||||||
|
import { orgIdentityQuery } from "./queries";
|
||||||
|
import { TDeleteOrgIdentityDTO, TOrgIdentity } from "./types";
|
||||||
|
|
||||||
|
// TODO (scott/akhi): eventually move to the new api commented out below; the current ones use old api
|
||||||
|
|
||||||
|
export const useCreateOrgIdentity = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
return useMutation<Identity, object, CreateIdentityDTO>({
|
||||||
|
mutationFn: async (body) => {
|
||||||
|
const {
|
||||||
|
data: { identity }
|
||||||
|
} = await apiRequest.post("/api/v1/identities/", body);
|
||||||
|
return identity;
|
||||||
|
},
|
||||||
|
onSuccess: (_, { organizationId }) => {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: subscriptionQueryKeys.getOrgSubsription(organizationId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.searchIdentitiesRoot });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useUpdateOrgIdentity = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
return useMutation<Identity, object, UpdateIdentityDTO>({
|
||||||
|
mutationFn: async ({ identityId, name, role, hasDeleteProtection, metadata }) => {
|
||||||
|
const {
|
||||||
|
data: { identity }
|
||||||
|
} = await apiRequest.patch(`/api/v1/identities/${identityId}`, {
|
||||||
|
name,
|
||||||
|
role,
|
||||||
|
hasDeleteProtection,
|
||||||
|
metadata
|
||||||
|
});
|
||||||
|
|
||||||
|
return identity;
|
||||||
|
},
|
||||||
|
onSuccess: (_, { organizationId, identityId }) => {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: organizationKeys.getOrgIdentityMemberships(organizationId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(identityId) });
|
||||||
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.searchIdentitiesRoot });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// export const useCreateOrgIdentity = () => {
|
||||||
|
// const queryClient = useQueryClient();
|
||||||
|
// return useMutation({
|
||||||
|
// mutationFn: async (dto: TCreateOrgIdentityDTO) => {
|
||||||
|
// const { data } = await apiRequest.post<{ identity: TOrgIdentity }>(
|
||||||
|
// "/api/v1/organization/identities",
|
||||||
|
// dto
|
||||||
|
// );
|
||||||
|
// return data;
|
||||||
|
// },
|
||||||
|
// onSuccess: () => {
|
||||||
|
// queryClient.invalidateQueries({ queryKey: orgIdentityQuery.allKey() });
|
||||||
|
// queryClient.invalidateQueries({
|
||||||
|
// queryKey: subscriptionQueryKeys.all()
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// export const useUpdateOrgIdentity = () => {
|
||||||
|
// const queryClient = useQueryClient();
|
||||||
|
// return useMutation({
|
||||||
|
// mutationFn: async ({ identityId, ...updates }: TUpdateOrgIdentityDTO) => {
|
||||||
|
// const { data } = await apiRequest.patch<{ identity: TOrgIdentity }>(
|
||||||
|
// `/api/v1/organization/identities/${identityId}`,
|
||||||
|
// updates
|
||||||
|
// );
|
||||||
|
// return data;
|
||||||
|
// },
|
||||||
|
// onSuccess: () => {
|
||||||
|
// queryClient.invalidateQueries({ queryKey: orgIdentityQuery.allKey() });
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// };
|
||||||
|
|
||||||
|
export const useDeleteOrgIdentity = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: async ({ identityId }: TDeleteOrgIdentityDTO) => {
|
||||||
|
const { data } = await apiRequest.delete<{ identity: TOrgIdentity }>(
|
||||||
|
`/api/v1/identities/${identityId}`
|
||||||
|
);
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
onSuccess: (_, { orgId }) => {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: organizationKeys.getOrgIdentityMemberships(orgId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.searchIdentitiesRoot });
|
||||||
|
queryClient.invalidateQueries({ queryKey: identitiesKeys.getIdentityById(orgId) });
|
||||||
|
queryClient.invalidateQueries({ queryKey: orgIdentityQuery.allKey() });
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: subscriptionQueryKeys.all()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import { queryOptions } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
import { apiRequest } from "@app/config/request";
|
||||||
|
|
||||||
|
import { TGetOrgIdentityByIdDTO, TListOrgIdentitiesDTO, TOrgIdentity } from "./types";
|
||||||
|
|
||||||
|
export const orgIdentityQuery = {
|
||||||
|
allKey: () => ["organization-identities"] as const,
|
||||||
|
getByIdKey: (params: TGetOrgIdentityByIdDTO) =>
|
||||||
|
[...orgIdentityQuery.allKey(), "by-id", params] as const,
|
||||||
|
listKey: (params?: TListOrgIdentitiesDTO) =>
|
||||||
|
[...orgIdentityQuery.allKey(), "list", params] as const,
|
||||||
|
getById: (params: TGetOrgIdentityByIdDTO) =>
|
||||||
|
queryOptions({
|
||||||
|
queryKey: orgIdentityQuery.getByIdKey(params),
|
||||||
|
queryFn: async () => {
|
||||||
|
const { data } = await apiRequest.get<{ identity: TOrgIdentity }>(
|
||||||
|
`/api/v1/organization/identities/${params.identityId}`
|
||||||
|
);
|
||||||
|
return data.identity;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
list: (params: TListOrgIdentitiesDTO = {}) =>
|
||||||
|
queryOptions({
|
||||||
|
queryKey: orgIdentityQuery.listKey(params),
|
||||||
|
queryFn: async () => {
|
||||||
|
const { data } = await apiRequest.get<{
|
||||||
|
identities: TOrgIdentity[];
|
||||||
|
totalCount: number;
|
||||||
|
}>("/api/v1/organization/identities", {
|
||||||
|
params: {
|
||||||
|
offset: params.offset,
|
||||||
|
limit: params.limit,
|
||||||
|
search: params.search
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import { TIdentity, TMetadata } from "@app/hooks/api/shared";
|
||||||
|
|
||||||
|
export type TOrgIdentity = TIdentity;
|
||||||
|
|
||||||
|
export type TCreateOrgIdentityDTO = {
|
||||||
|
name: string;
|
||||||
|
hasDeleteProtection?: boolean;
|
||||||
|
metadata?: TMetadata;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TUpdateOrgIdentityDTO = {
|
||||||
|
identityId: string;
|
||||||
|
name?: string;
|
||||||
|
hasDeleteProtection?: boolean;
|
||||||
|
metadata?: TMetadata;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TGetOrgIdentityByIdDTO = {
|
||||||
|
identityId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TListOrgIdentitiesDTO = {
|
||||||
|
offset?: number;
|
||||||
|
limit?: number;
|
||||||
|
search?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TDeleteOrgIdentityDTO = {
|
||||||
|
identityId: string;
|
||||||
|
orgId: string;
|
||||||
|
};
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import { queryOptions } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
import { apiRequest } from "@app/config/request";
|
||||||
|
|
||||||
|
import {
|
||||||
|
TAvailableOrganizationIdentities,
|
||||||
|
TListAvailableOrganizationIdentitiesDTO,
|
||||||
|
TListOrgIdentityMembershipsDTO
|
||||||
|
} from "./types";
|
||||||
|
|
||||||
|
export const orgIdentityMembershipQuery = {
|
||||||
|
allKey: () => ["organization-identity-memberships"] as const,
|
||||||
|
listAvailableKey: (params?: TListOrgIdentityMembershipsDTO) =>
|
||||||
|
[...orgIdentityMembershipQuery.allKey(), "list-available", params] as const,
|
||||||
|
listAvailable: (params: TListAvailableOrganizationIdentitiesDTO = {}) =>
|
||||||
|
queryOptions({
|
||||||
|
queryKey: orgIdentityMembershipQuery.listAvailableKey(params),
|
||||||
|
queryFn: async () => {
|
||||||
|
const { data } = await apiRequest.get<{
|
||||||
|
identities: TAvailableOrganizationIdentities;
|
||||||
|
}>("/api/v1/organization/available-identities", {
|
||||||
|
params: {
|
||||||
|
offset: params.offset,
|
||||||
|
limit: params.limit,
|
||||||
|
identityName: params.identityName
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return data.identities;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
export enum TemporaryPermissionMode {
|
import { TRoles } from "@app/hooks/api/shared";
|
||||||
Relative = "relative"
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TOrgIdentityMembership = {
|
export type TOrgIdentityMembership = {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -12,21 +10,24 @@ export type TOrgIdentityMembership = {
|
|||||||
|
|
||||||
export type TCreateOrgIdentityMembershipDTO = {
|
export type TCreateOrgIdentityMembershipDTO = {
|
||||||
identityId: string;
|
identityId: string;
|
||||||
roles: Array<
|
roles: TRoles;
|
||||||
| {
|
|
||||||
role: string;
|
|
||||||
isTemporary?: false;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
role: string;
|
|
||||||
isTemporary: true;
|
|
||||||
temporaryMode: TemporaryPermissionMode;
|
|
||||||
temporaryRange: string;
|
|
||||||
temporaryAccessStartTime: string;
|
|
||||||
}
|
|
||||||
>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TDeleteOrgIdentityMembershipDTO = {
|
export type TDeleteOrgIdentityMembershipDTO = {
|
||||||
identityId: string;
|
identityId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type TListOrgIdentityMembershipsDTO = {
|
||||||
|
offset?: number;
|
||||||
|
limit?: number;
|
||||||
|
identityName?: string;
|
||||||
|
roles?: string[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TListAvailableOrganizationIdentitiesDTO = {
|
||||||
|
offset?: number;
|
||||||
|
limit?: number;
|
||||||
|
identityName?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TAvailableOrganizationIdentities = Array<{ id: string; name: string }>;
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ export {
|
|||||||
useDeleteOrgById,
|
useDeleteOrgById,
|
||||||
useDeleteOrgPmtMethod,
|
useDeleteOrgPmtMethod,
|
||||||
useDeleteOrgTaxId,
|
useDeleteOrgTaxId,
|
||||||
useGetAvailableOrgIdentities,
|
|
||||||
useGetIdentityMembershipOrgs,
|
useGetIdentityMembershipOrgs,
|
||||||
useGetOrganizationGroups,
|
useGetOrganizationGroups,
|
||||||
useGetOrganizations,
|
useGetOrganizations,
|
||||||
|
|||||||
@@ -579,19 +579,6 @@ export const useGetOrgIntegrationAuths = <TData = IntegrationAuth[],>(
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetAvailableOrgIdentities = (enabled = true) =>
|
|
||||||
useQuery({
|
|
||||||
queryKey: organizationKeys.getAvailableIdentities(),
|
|
||||||
queryFn: async () => {
|
|
||||||
const { data } = await apiRequest.get<{ identities: { name: string; id: string }[] }>(
|
|
||||||
"/api/v1/organization/identities/available"
|
|
||||||
);
|
|
||||||
|
|
||||||
return data.identities;
|
|
||||||
},
|
|
||||||
enabled
|
|
||||||
});
|
|
||||||
|
|
||||||
export const useGetAvailableOrgUsers = (enabled = true) =>
|
export const useGetAvailableOrgUsers = (enabled = true) =>
|
||||||
useQuery({
|
useQuery({
|
||||||
queryKey: organizationKeys.getAvailableUsers(),
|
queryKey: organizationKeys.getAvailableUsers(),
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
export {
|
|
||||||
useCreateOrganizationIdentity,
|
|
||||||
useDeleteOrganizationIdentity,
|
|
||||||
useUpdateOrganizationIdentity
|
|
||||||
} from "./mutations";
|
|
||||||
export { organizationIdentityQuery } from "./queries";
|
|
||||||
export type {
|
|
||||||
TCreateOrganizationIdentityDTO,
|
|
||||||
TDeleteOrganizationIdentityDTO,
|
|
||||||
TGetOrganizationIdentityByIdDTO,
|
|
||||||
TListOrganizationIdentitiesDTO,
|
|
||||||
TMetadata,
|
|
||||||
TOrganizationIdentity,
|
|
||||||
TUpdateOrganizationIdentityDTO
|
|
||||||
} from "./types";
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
||||||
|
|
||||||
import { apiRequest } from "@app/config/request";
|
|
||||||
|
|
||||||
import { organizationIdentityQuery } from "./queries";
|
|
||||||
import {
|
|
||||||
TCreateOrganizationIdentityDTO,
|
|
||||||
TDeleteOrganizationIdentityDTO,
|
|
||||||
TOrganizationIdentity,
|
|
||||||
TUpdateOrganizationIdentityDTO
|
|
||||||
} from "./types";
|
|
||||||
|
|
||||||
export const useCreateOrganizationIdentity = () => {
|
|
||||||
const queryClient = useQueryClient();
|
|
||||||
return useMutation({
|
|
||||||
mutationFn: async (dto: TCreateOrganizationIdentityDTO) => {
|
|
||||||
const { data } = await apiRequest.post<{ identity: TOrganizationIdentity }>(
|
|
||||||
"/api/v1/organization/identities",
|
|
||||||
dto
|
|
||||||
);
|
|
||||||
return data;
|
|
||||||
},
|
|
||||||
onSuccess: () => {
|
|
||||||
queryClient.invalidateQueries({ queryKey: organizationIdentityQuery.allKey() });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useUpdateOrganizationIdentity = () => {
|
|
||||||
const queryClient = useQueryClient();
|
|
||||||
return useMutation({
|
|
||||||
mutationFn: async ({ identityId, ...updates }: TUpdateOrganizationIdentityDTO) => {
|
|
||||||
const { data } = await apiRequest.patch<{ identity: TOrganizationIdentity }>(
|
|
||||||
`/api/v1/organization/identities/${identityId}`,
|
|
||||||
updates
|
|
||||||
);
|
|
||||||
return data;
|
|
||||||
},
|
|
||||||
onSuccess: () => {
|
|
||||||
queryClient.invalidateQueries({ queryKey: organizationIdentityQuery.allKey() });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useDeleteOrganizationIdentity = () => {
|
|
||||||
const queryClient = useQueryClient();
|
|
||||||
return useMutation({
|
|
||||||
mutationFn: async ({ identityId }: TDeleteOrganizationIdentityDTO) => {
|
|
||||||
const { data } = await apiRequest.delete<{ identity: TOrganizationIdentity }>(
|
|
||||||
`/api/v1/organization/identities/${identityId}`
|
|
||||||
);
|
|
||||||
return data;
|
|
||||||
},
|
|
||||||
onSuccess: () => {
|
|
||||||
queryClient.invalidateQueries({ queryKey: organizationIdentityQuery.allKey() });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
import { queryOptions } from "@tanstack/react-query";
|
|
||||||
|
|
||||||
import { apiRequest } from "@app/config/request";
|
|
||||||
|
|
||||||
import {
|
|
||||||
TGetOrganizationIdentityByIdDTO,
|
|
||||||
TListOrganizationIdentitiesDTO,
|
|
||||||
TOrganizationIdentity
|
|
||||||
} from "./types";
|
|
||||||
|
|
||||||
export const organizationIdentityQuery = {
|
|
||||||
allKey: () => ["organization-identities"] as const,
|
|
||||||
getByIdKey: (params: TGetOrganizationIdentityByIdDTO) =>
|
|
||||||
[...organizationIdentityQuery.allKey(), "by-id", params] as const,
|
|
||||||
listKey: (params?: TListOrganizationIdentitiesDTO) =>
|
|
||||||
[...organizationIdentityQuery.allKey(), "list", params] as const,
|
|
||||||
getById: (params: TGetOrganizationIdentityByIdDTO) =>
|
|
||||||
queryOptions({
|
|
||||||
queryKey: organizationIdentityQuery.getByIdKey(params),
|
|
||||||
queryFn: async () => {
|
|
||||||
const { data } = await apiRequest.get<{ identity: TOrganizationIdentity }>(
|
|
||||||
`/api/v1/organization/identities/${params.identityId}`
|
|
||||||
);
|
|
||||||
return data.identity;
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
list: (params: TListOrganizationIdentitiesDTO = {}) =>
|
|
||||||
queryOptions({
|
|
||||||
queryKey: organizationIdentityQuery.listKey(params),
|
|
||||||
queryFn: async () => {
|
|
||||||
const { data } = await apiRequest.get<{
|
|
||||||
identities: TOrganizationIdentity[];
|
|
||||||
totalCount: number;
|
|
||||||
}>("/api/v1/organization/identities", {
|
|
||||||
params: {
|
|
||||||
offset: params.offset,
|
|
||||||
limit: params.limit,
|
|
||||||
search: params.search
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
export type TMetadata = {
|
|
||||||
key: string;
|
|
||||||
value: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TOrganizationIdentity = {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
orgId: string;
|
|
||||||
projectId: string | null;
|
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
hasDeleteProtection: boolean;
|
|
||||||
authMethods?: string[];
|
|
||||||
metadata?: TMetadata[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TCreateOrganizationIdentityDTO = {
|
|
||||||
name: string;
|
|
||||||
hasDeleteProtection?: boolean;
|
|
||||||
metadata?: TMetadata[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TUpdateOrganizationIdentityDTO = {
|
|
||||||
identityId: string;
|
|
||||||
name?: string;
|
|
||||||
hasDeleteProtection?: boolean;
|
|
||||||
metadata?: TMetadata[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TGetOrganizationIdentityByIdDTO = {
|
|
||||||
identityId: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TListOrganizationIdentitiesDTO = {
|
|
||||||
offset?: number;
|
|
||||||
limit?: number;
|
|
||||||
search?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TDeleteOrganizationIdentityDTO = {
|
|
||||||
identityId: string;
|
|
||||||
};
|
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||||
|
|
||||||
import { apiRequest } from "@app/config/request";
|
import { apiRequest } from "@app/config/request";
|
||||||
|
import { identitiesKeys, projectKeys } from "@app/hooks/api";
|
||||||
|
import { subscriptionQueryKeys } from "@app/hooks/api/subscriptions/queries";
|
||||||
|
|
||||||
import { projectIdentityQuery } from "./queries";
|
import { projectIdentityQuery } from "./queries";
|
||||||
import {
|
import {
|
||||||
@@ -18,10 +20,13 @@ export const useCreateProjectIdentity = () => {
|
|||||||
`/api/v1/projects/${projectId}/identities`,
|
`/api/v1/projects/${projectId}/identities`,
|
||||||
dto
|
dto
|
||||||
);
|
);
|
||||||
return data;
|
return data.identity;
|
||||||
},
|
},
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries({ queryKey: projectIdentityQuery.allKey() });
|
queryClient.invalidateQueries({ queryKey: projectIdentityQuery.allKey() });
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: subscriptionQueryKeys.all()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -34,10 +39,13 @@ export const useUpdateProjectIdentity = () => {
|
|||||||
`/api/v1/projects/${projectId}/identities/${identityId}`,
|
`/api/v1/projects/${projectId}/identities/${identityId}`,
|
||||||
updates
|
updates
|
||||||
);
|
);
|
||||||
return data;
|
return data.identity;
|
||||||
},
|
},
|
||||||
onSuccess: () => {
|
onSuccess: (_, { projectId, identityId }) => {
|
||||||
queryClient.invalidateQueries({ queryKey: projectIdentityQuery.allKey() });
|
queryClient.invalidateQueries({ queryKey: projectIdentityQuery.allKey() });
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMembershipDetails(projectId, identityId)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -49,10 +57,20 @@ export const useDeleteProjectIdentity = () => {
|
|||||||
const { data } = await apiRequest.delete<{ identity: TProjectIdentity }>(
|
const { data } = await apiRequest.delete<{ identity: TProjectIdentity }>(
|
||||||
`/api/v1/projects/${projectId}/identities/${identityId}`
|
`/api/v1/projects/${projectId}/identities/${identityId}`
|
||||||
);
|
);
|
||||||
return data;
|
return data.identity;
|
||||||
},
|
},
|
||||||
onSuccess: () => {
|
onSuccess: (_, { projectId, identityId }) => {
|
||||||
queryClient.invalidateQueries({ queryKey: projectIdentityQuery.allKey() });
|
queryClient.invalidateQueries({ queryKey: projectIdentityQuery.allKey() });
|
||||||
|
queryClient.invalidateQueries({ queryKey: projectIdentityQuery.allKey() });
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: identitiesKeys.getIdentityProjectMemberships(identityId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: subscriptionQueryKeys.all()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,11 +2,7 @@ import { queryOptions } from "@tanstack/react-query";
|
|||||||
|
|
||||||
import { apiRequest } from "@app/config/request";
|
import { apiRequest } from "@app/config/request";
|
||||||
|
|
||||||
import {
|
import { TGetProjectIdentityByIdDTO, TListProjectIdentitiesDTO, TProjectIdentity } from "./types";
|
||||||
TGetProjectIdentityByIdDTO,
|
|
||||||
TListProjectIdentitiesDTO,
|
|
||||||
TProjectIdentity
|
|
||||||
} from "./types";
|
|
||||||
|
|
||||||
export const projectIdentityQuery = {
|
export const projectIdentityQuery = {
|
||||||
allKey: () => ["project-identities"] as const,
|
allKey: () => ["project-identities"] as const,
|
||||||
|
|||||||
@@ -1,28 +1,18 @@
|
|||||||
|
import { TIdentity, TMetadata } from "@app/hooks/api/shared";
|
||||||
|
|
||||||
export type TProjectIdentityMetadata = {
|
export type TProjectIdentityMetadata = {
|
||||||
key: string;
|
key: string;
|
||||||
value: string;
|
value: string;
|
||||||
id: string;
|
id: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TProjectIdentity = {
|
export type TProjectIdentity = TIdentity;
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
orgId: string;
|
|
||||||
projectId: string | null;
|
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
hasDeleteProtection: boolean;
|
|
||||||
metadata?: TProjectIdentityMetadata[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TCreateProjectIdentityDTO = {
|
export type TCreateProjectIdentityDTO = {
|
||||||
projectId: string;
|
projectId: string;
|
||||||
name: string;
|
name: string;
|
||||||
hasDeleteProtection?: boolean;
|
hasDeleteProtection?: boolean;
|
||||||
metadata?: Array<{
|
metadata?: TMetadata[];
|
||||||
key: string;
|
|
||||||
value: string;
|
|
||||||
}>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TUpdateProjectIdentityDTO = {
|
export type TUpdateProjectIdentityDTO = {
|
||||||
@@ -30,10 +20,7 @@ export type TUpdateProjectIdentityDTO = {
|
|||||||
identityId: string;
|
identityId: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
hasDeleteProtection?: boolean;
|
hasDeleteProtection?: boolean;
|
||||||
metadata?: Array<{
|
metadata?: TMetadata[];
|
||||||
key: string;
|
|
||||||
value: string;
|
|
||||||
}>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TGetProjectIdentityByIdDTO = {
|
export type TGetProjectIdentityByIdDTO = {
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export * from "./mutations";
|
||||||
|
export * from "./queries";
|
||||||
|
export * from "./types";
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
import { apiRequest } from "@app/config/request";
|
||||||
|
import { identitiesKeys, projectKeys } from "@app/hooks/api";
|
||||||
|
import { projectIdentityQuery } from "@app/hooks/api/projectIdentity";
|
||||||
|
|
||||||
|
import {
|
||||||
|
TCreateProjectIdentityMembershipDTO,
|
||||||
|
TDeleteProjectIdentityMembershipDTO,
|
||||||
|
TProjectIdentityMembership,
|
||||||
|
TUpdateProjectIdentityMembershipDTO
|
||||||
|
} from "./types";
|
||||||
|
|
||||||
|
export const useCreateProjectIdentityMembership = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: async ({ identityId, projectId, role }: TCreateProjectIdentityMembershipDTO) => {
|
||||||
|
const {
|
||||||
|
data: { identityMembership }
|
||||||
|
} = await apiRequest.post<{ identityMembership: TProjectIdentityMembership }>(
|
||||||
|
`/api/v1/projects/${projectId}/identity-memberships/${identityId}`,
|
||||||
|
{
|
||||||
|
role
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return identityMembership;
|
||||||
|
},
|
||||||
|
onSuccess: (_, { identityId, projectId }) => {
|
||||||
|
queryClient.invalidateQueries({ queryKey: projectIdentityQuery.allKey() });
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: identitiesKeys.getIdentityProjectMemberships(identityId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useUpdateProjectIdentityMembership = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: async ({
|
||||||
|
projectId,
|
||||||
|
identityId,
|
||||||
|
...updates
|
||||||
|
}: TUpdateProjectIdentityMembershipDTO) => {
|
||||||
|
const {
|
||||||
|
data: { identityMembership }
|
||||||
|
} = await apiRequest.patch<{ identityMembership: TProjectIdentityMembership }>(
|
||||||
|
`/api/v1/projects/${projectId}/identity-memberships/${identityId}`,
|
||||||
|
updates
|
||||||
|
);
|
||||||
|
return identityMembership;
|
||||||
|
},
|
||||||
|
onSuccess: (_, { projectId, identityId }) => {
|
||||||
|
queryClient.invalidateQueries({ queryKey: projectIdentityQuery.allKey() });
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: identitiesKeys.getIdentityProjectMemberships(identityId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMembershipDetails(projectId, identityId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useDeleteProjectIdentityMembership = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: async ({ identityId, projectId }: TDeleteProjectIdentityMembershipDTO) => {
|
||||||
|
const {
|
||||||
|
data: { identityMembership }
|
||||||
|
} = await apiRequest.delete<{ identityMembership: TProjectIdentityMembership }>(
|
||||||
|
`/api/v1/projects/${projectId}/identity-memberships/${identityId}`
|
||||||
|
);
|
||||||
|
return identityMembership;
|
||||||
|
},
|
||||||
|
onSuccess: (_, { identityId, projectId }) => {
|
||||||
|
queryClient.invalidateQueries({ queryKey: projectIdentityQuery.allKey() });
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
||||||
|
});
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: identitiesKeys.getIdentityProjectMemberships(identityId)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
import { queryOptions, useQuery, UseQueryOptions } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
import { apiRequest } from "@app/config/request";
|
||||||
|
import {
|
||||||
|
projectKeys,
|
||||||
|
TAvailableProjectIdentities,
|
||||||
|
TListAvailableProjectIdentitiesDTO
|
||||||
|
} from "@app/hooks/api";
|
||||||
|
import { OrderByDirection } from "@app/hooks/api/generic/types";
|
||||||
|
import {
|
||||||
|
IdentityProjectMembership,
|
||||||
|
TProjectIdentityMembershipsList
|
||||||
|
} from "@app/hooks/api/identities/types";
|
||||||
|
import { ProjectIdentityOrderBy, TListProjectIdentitiesDTO } from "@app/hooks/api/projects/types";
|
||||||
|
|
||||||
|
export const projectIdentityMembershipQuery = {
|
||||||
|
allKey: () => ["project-identity-memberships"] as const,
|
||||||
|
listAvailableKey: (params?: TListAvailableProjectIdentitiesDTO) =>
|
||||||
|
[...projectIdentityMembershipQuery.allKey(), "list-available", params] as const,
|
||||||
|
listAvailable: (params: TListAvailableProjectIdentitiesDTO) =>
|
||||||
|
queryOptions({
|
||||||
|
queryKey: projectIdentityMembershipQuery.listAvailableKey(params),
|
||||||
|
queryFn: async () => {
|
||||||
|
const { data } = await apiRequest.get<{
|
||||||
|
identities: TAvailableProjectIdentities;
|
||||||
|
}>(`/api/v1/projects/${params.projectId}/available-identities`, {
|
||||||
|
params: {
|
||||||
|
offset: params.offset,
|
||||||
|
limit: params.limit,
|
||||||
|
identityName: params.identityName
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return data.identities;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO (scott/akhi): move to new projectIdentityMembershipQuery structure
|
||||||
|
|
||||||
|
export const useListProjectIdentityMemberships = (
|
||||||
|
{
|
||||||
|
projectId,
|
||||||
|
offset = 0,
|
||||||
|
limit = 100,
|
||||||
|
orderBy = ProjectIdentityOrderBy.Name,
|
||||||
|
orderDirection = OrderByDirection.ASC,
|
||||||
|
search = ""
|
||||||
|
}: TListProjectIdentitiesDTO,
|
||||||
|
options?: Omit<
|
||||||
|
UseQueryOptions<
|
||||||
|
TProjectIdentityMembershipsList,
|
||||||
|
unknown,
|
||||||
|
TProjectIdentityMembershipsList,
|
||||||
|
ReturnType<typeof projectKeys.getProjectIdentityMembershipsWithParams>
|
||||||
|
>,
|
||||||
|
"queryKey" | "queryFn"
|
||||||
|
>
|
||||||
|
) => {
|
||||||
|
return useQuery({
|
||||||
|
queryKey: projectKeys.getProjectIdentityMembershipsWithParams({
|
||||||
|
projectId,
|
||||||
|
offset,
|
||||||
|
limit,
|
||||||
|
orderBy,
|
||||||
|
orderDirection,
|
||||||
|
search
|
||||||
|
}),
|
||||||
|
queryFn: async () => {
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
offset: String(offset),
|
||||||
|
limit: String(limit),
|
||||||
|
orderBy: String(orderBy),
|
||||||
|
orderDirection: String(orderDirection),
|
||||||
|
search: String(search)
|
||||||
|
});
|
||||||
|
|
||||||
|
const { data } = await apiRequest.get<TProjectIdentityMembershipsList>(
|
||||||
|
`/api/v1/projects/${projectId}/identity-memberships`,
|
||||||
|
{ params }
|
||||||
|
);
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
enabled: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useGetProjectIdentityMembership = (projectId: string, identityId: string) => {
|
||||||
|
return useQuery({
|
||||||
|
enabled: Boolean(projectId && identityId),
|
||||||
|
queryKey: projectKeys.getProjectIdentityMembershipDetails(projectId, identityId),
|
||||||
|
queryFn: async () => {
|
||||||
|
const {
|
||||||
|
data: { identityMembership }
|
||||||
|
} = await apiRequest.get<{ identityMembership: IdentityProjectMembership }>(
|
||||||
|
`/api/v1/projects/${projectId}/identity-memberships/${identityId}`
|
||||||
|
);
|
||||||
|
return identityMembership;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
import { TRoles } from "@app/hooks/api/shared";
|
||||||
|
|
||||||
|
export type TProjectIdentityMembership = {
|
||||||
|
id: string;
|
||||||
|
projectId: string;
|
||||||
|
identityId: string;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
// TODO
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TCreateProjectIdentityMembershipDTO = {
|
||||||
|
identityId: string;
|
||||||
|
projectId: string;
|
||||||
|
role?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TUpdateProjectIdentityMembershipDTO = {
|
||||||
|
identityId: string;
|
||||||
|
projectId: string;
|
||||||
|
roles: TRoles;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TDeleteProjectIdentityMembershipDTO = {
|
||||||
|
identityId: string;
|
||||||
|
projectId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TListAvailableProjectIdentitiesDTO = {
|
||||||
|
projectId: string;
|
||||||
|
offset?: number;
|
||||||
|
limit?: number;
|
||||||
|
identityName?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TAvailableProjectIdentities = Array<{ id: string; name: string }>;
|
||||||
@@ -8,10 +8,8 @@ export {
|
|||||||
useUpdateProjectSshConfig
|
useUpdateProjectSshConfig
|
||||||
} from "./mutations";
|
} from "./mutations";
|
||||||
export {
|
export {
|
||||||
useAddIdentityToWorkspace,
|
|
||||||
useCreateWorkspace,
|
useCreateWorkspace,
|
||||||
useCreateWsEnvironment,
|
useCreateWsEnvironment,
|
||||||
useDeleteIdentityFromWorkspace,
|
|
||||||
useDeleteUserFromWorkspace,
|
useDeleteUserFromWorkspace,
|
||||||
useDeleteWorkspace,
|
useDeleteWorkspace,
|
||||||
useDeleteWsEnvironment,
|
useDeleteWsEnvironment,
|
||||||
@@ -21,8 +19,6 @@ export {
|
|||||||
useGetUserWorkspaceMemberships,
|
useGetUserWorkspaceMemberships,
|
||||||
useGetWorkspaceAuthorizations,
|
useGetWorkspaceAuthorizations,
|
||||||
useGetWorkspaceById,
|
useGetWorkspaceById,
|
||||||
useGetWorkspaceIdentityMembershipDetails,
|
|
||||||
useGetWorkspaceIdentityMemberships,
|
|
||||||
useGetWorkspaceIndexStatus,
|
useGetWorkspaceIndexStatus,
|
||||||
useGetWorkspaceIntegrations,
|
useGetWorkspaceIntegrations,
|
||||||
useGetWorkspaceUserDetails,
|
useGetWorkspaceUserDetails,
|
||||||
@@ -41,7 +37,6 @@ export {
|
|||||||
useListWorkspaceSshHostGroups,
|
useListWorkspaceSshHostGroups,
|
||||||
useListWorkspaceSshHosts,
|
useListWorkspaceSshHosts,
|
||||||
useSearchProjects,
|
useSearchProjects,
|
||||||
useUpdateIdentityWorkspaceRole,
|
|
||||||
useUpdateProject,
|
useUpdateProject,
|
||||||
useUpdateUserWorkspaceRole,
|
useUpdateUserWorkspaceRole,
|
||||||
useUpdateWsEnvironment,
|
useUpdateWsEnvironment,
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
import { useMutation, useQuery, useQueryClient, UseQueryOptions } from "@tanstack/react-query";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
|
|
||||||
import { apiRequest } from "@app/config/request";
|
import { apiRequest } from "@app/config/request";
|
||||||
import { OrderByDirection } from "@app/hooks/api/generic/types";
|
|
||||||
|
|
||||||
import { CaStatus } from "../ca/enums";
|
import { CaStatus } from "../ca/enums";
|
||||||
import { TCertificateAuthority } from "../ca/types";
|
import { TCertificateAuthority } from "../ca/types";
|
||||||
import { TCertificate } from "../certificates/types";
|
import { TCertificate } from "../certificates/types";
|
||||||
import { TCertificateTemplate } from "../certificateTemplates/types";
|
import { TCertificateTemplate } from "../certificateTemplates/types";
|
||||||
import { TGroupMembership } from "../groups/types";
|
import { TGroupMembership } from "../groups/types";
|
||||||
import { identitiesKeys } from "../identities/queries";
|
|
||||||
import { IdentityMembership, TProjectIdentitiesList } from "../identities/types";
|
|
||||||
import { IntegrationAuth } from "../integrationAuth/types";
|
import { IntegrationAuth } from "../integrationAuth/types";
|
||||||
import { TIntegration } from "../integrations/types";
|
import { TIntegration } from "../integrations/types";
|
||||||
import { TPkiAlert } from "../pkiAlerts/types";
|
import { TPkiAlert } from "../pkiAlerts/types";
|
||||||
@@ -33,13 +30,10 @@ import {
|
|||||||
DeleteWorkspaceDTO,
|
DeleteWorkspaceDTO,
|
||||||
Project,
|
Project,
|
||||||
ProjectEnv,
|
ProjectEnv,
|
||||||
ProjectIdentityOrderBy,
|
|
||||||
ProjectType,
|
ProjectType,
|
||||||
TGetUpgradeProjectStatusDTO,
|
TGetUpgradeProjectStatusDTO,
|
||||||
TListProjectIdentitiesDTO,
|
|
||||||
TProjectSshConfig,
|
TProjectSshConfig,
|
||||||
TSearchProjectsDTO,
|
TSearchProjectsDTO,
|
||||||
TUpdateWorkspaceIdentityRoleDTO,
|
|
||||||
TUpdateWorkspaceUserRoleDTO,
|
TUpdateWorkspaceUserRoleDTO,
|
||||||
UpdateAuditLogsRetentionDTO,
|
UpdateAuditLogsRetentionDTO,
|
||||||
UpdateEnvironmentDTO,
|
UpdateEnvironmentDTO,
|
||||||
@@ -452,154 +446,6 @@ export const useUpdateUserWorkspaceRole = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useAddIdentityToWorkspace = () => {
|
|
||||||
const queryClient = useQueryClient();
|
|
||||||
return useMutation({
|
|
||||||
mutationFn: async ({
|
|
||||||
identityId,
|
|
||||||
projectId,
|
|
||||||
role
|
|
||||||
}: {
|
|
||||||
identityId: string;
|
|
||||||
projectId: string;
|
|
||||||
role?: string;
|
|
||||||
}) => {
|
|
||||||
const {
|
|
||||||
data: { identityMembership }
|
|
||||||
} = await apiRequest.post(
|
|
||||||
`/api/v1/projects/${projectId}/identity-memberships/${identityId}`,
|
|
||||||
{
|
|
||||||
role
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return identityMembership;
|
|
||||||
},
|
|
||||||
onSuccess: (_, { identityId, projectId }) => {
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: identitiesKeys.getIdentityProjectMemberships(identityId)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useUpdateIdentityWorkspaceRole = () => {
|
|
||||||
const queryClient = useQueryClient();
|
|
||||||
return useMutation({
|
|
||||||
mutationFn: async ({ identityId, projectId, roles }: TUpdateWorkspaceIdentityRoleDTO) => {
|
|
||||||
const {
|
|
||||||
data: { identityMembership }
|
|
||||||
} = await apiRequest.patch(
|
|
||||||
`/api/v1/projects/${projectId}/identity-memberships/${identityId}`,
|
|
||||||
{
|
|
||||||
roles
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return identityMembership;
|
|
||||||
},
|
|
||||||
onSuccess: (_, { identityId, projectId }) => {
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: identitiesKeys.getIdentityProjectMemberships(identityId)
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: projectKeys.getProjectIdentityMembershipDetails(projectId, identityId)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useDeleteIdentityFromWorkspace = () => {
|
|
||||||
const queryClient = useQueryClient();
|
|
||||||
return useMutation({
|
|
||||||
mutationFn: async ({ identityId, projectId }: { identityId: string; projectId: string }) => {
|
|
||||||
const {
|
|
||||||
data: { identityMembership }
|
|
||||||
} = await apiRequest.delete(
|
|
||||||
`/api/v1/projects/${projectId}/identity-memberships/${identityId}`
|
|
||||||
);
|
|
||||||
return identityMembership;
|
|
||||||
},
|
|
||||||
onSuccess: (_, { identityId, projectId }) => {
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: projectKeys.getProjectIdentityMemberships(projectId)
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries({
|
|
||||||
queryKey: identitiesKeys.getIdentityProjectMemberships(identityId)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useGetWorkspaceIdentityMemberships = (
|
|
||||||
{
|
|
||||||
projectId,
|
|
||||||
offset = 0,
|
|
||||||
limit = 100,
|
|
||||||
orderBy = ProjectIdentityOrderBy.Name,
|
|
||||||
orderDirection = OrderByDirection.ASC,
|
|
||||||
search = ""
|
|
||||||
}: TListProjectIdentitiesDTO,
|
|
||||||
options?: Omit<
|
|
||||||
UseQueryOptions<
|
|
||||||
TProjectIdentitiesList,
|
|
||||||
unknown,
|
|
||||||
TProjectIdentitiesList,
|
|
||||||
ReturnType<typeof projectKeys.getProjectIdentityMembershipsWithParams>
|
|
||||||
>,
|
|
||||||
"queryKey" | "queryFn"
|
|
||||||
>
|
|
||||||
) => {
|
|
||||||
return useQuery({
|
|
||||||
queryKey: projectKeys.getProjectIdentityMembershipsWithParams({
|
|
||||||
projectId,
|
|
||||||
offset,
|
|
||||||
limit,
|
|
||||||
orderBy,
|
|
||||||
orderDirection,
|
|
||||||
search
|
|
||||||
}),
|
|
||||||
queryFn: async () => {
|
|
||||||
const params = new URLSearchParams({
|
|
||||||
offset: String(offset),
|
|
||||||
limit: String(limit),
|
|
||||||
orderBy: String(orderBy),
|
|
||||||
orderDirection: String(orderDirection),
|
|
||||||
search: String(search)
|
|
||||||
});
|
|
||||||
|
|
||||||
const { data } = await apiRequest.get<TProjectIdentitiesList>(
|
|
||||||
`/api/v1/projects/${projectId}/identity-memberships`,
|
|
||||||
{ params }
|
|
||||||
);
|
|
||||||
return data;
|
|
||||||
},
|
|
||||||
enabled: true,
|
|
||||||
...options
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useGetWorkspaceIdentityMembershipDetails = (projectId: string, identityId: string) => {
|
|
||||||
return useQuery({
|
|
||||||
enabled: Boolean(projectId && identityId),
|
|
||||||
queryKey: projectKeys.getProjectIdentityMembershipDetails(projectId, identityId),
|
|
||||||
queryFn: async () => {
|
|
||||||
const {
|
|
||||||
data: { identityMembership }
|
|
||||||
} = await apiRequest.get<{ identityMembership: IdentityMembership }>(
|
|
||||||
`/api/v1/projects/${projectId}/identity-memberships/${identityId}`
|
|
||||||
);
|
|
||||||
return identityMembership;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useGetWorkspaceGroupMembershipDetails = (projectId: string, groupId: string) => {
|
export const useGetWorkspaceGroupMembershipDetails = (projectId: string, groupId: string) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
enabled: Boolean(projectId && groupId),
|
enabled: Boolean(projectId && groupId),
|
||||||
|
|||||||
@@ -138,24 +138,6 @@ export type TUpdateWorkspaceUserRoleDTO = {
|
|||||||
)[];
|
)[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TUpdateWorkspaceIdentityRoleDTO = {
|
|
||||||
identityId: string;
|
|
||||||
projectId: string;
|
|
||||||
roles: (
|
|
||||||
| {
|
|
||||||
role: string;
|
|
||||||
isTemporary?: false;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
role: string;
|
|
||||||
isTemporary: true;
|
|
||||||
temporaryMode: ProjectUserMembershipTemporaryMode;
|
|
||||||
temporaryRange: string;
|
|
||||||
temporaryAccessStartTime: string;
|
|
||||||
}
|
|
||||||
)[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TUpdateWorkspaceGroupRoleDTO = {
|
export type TUpdateWorkspaceGroupRoleDTO = {
|
||||||
groupId: string;
|
groupId: string;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from "./types";
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import { IdentityAuthMethod } from "@app/hooks/api";
|
||||||
|
|
||||||
|
export enum TemporaryPermissionMode {
|
||||||
|
Relative = "relative"
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TMetadata = {
|
||||||
|
key: string;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TIdentity = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
orgId: string;
|
||||||
|
projectId: string | null;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
hasDeleteProtection: boolean;
|
||||||
|
authMethods: IdentityAuthMethod[];
|
||||||
|
activeLockoutAuthMethods: string[];
|
||||||
|
metadata?: Array<TMetadata & { id: string }>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TRoles = Array<
|
||||||
|
| {
|
||||||
|
role: string;
|
||||||
|
isTemporary?: false;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
role: string;
|
||||||
|
isTemporary: true;
|
||||||
|
temporaryMode: TemporaryPermissionMode;
|
||||||
|
temporaryRange: string;
|
||||||
|
temporaryAccessStartTime: string;
|
||||||
|
}
|
||||||
|
>;
|
||||||
@@ -7,7 +7,8 @@ import { SubscriptionPlan } from "./types";
|
|||||||
// import { Workspace } from './types';
|
// import { Workspace } from './types';
|
||||||
|
|
||||||
export const subscriptionQueryKeys = {
|
export const subscriptionQueryKeys = {
|
||||||
getOrgSubsription: (orgID: string) => ["plan", { orgID }] as const
|
all: () => ["plan"] as const,
|
||||||
|
getOrgSubsription: (orgID: string) => [...subscriptionQueryKeys.all(), { orgID }] as const
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchOrgSubscription = async (orgID: string, refreshCache: boolean = false) => {
|
export const fetchOrgSubscription = async (orgID: string, refreshCache: boolean = false) => {
|
||||||
|
|||||||
+6
-3
@@ -3,6 +3,7 @@ import { Controller, useFieldArray, useForm } from "react-hook-form";
|
|||||||
import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { useParams } from "@tanstack/react-router";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
@@ -76,7 +77,9 @@ export const IdentityAliCloudAuthForm = ({
|
|||||||
const { currentOrg } = useOrganization();
|
const { currentOrg } = useOrganization();
|
||||||
const orgId = currentOrg?.id || "";
|
const orgId = currentOrg?.id || "";
|
||||||
const { subscription } = useSubscription();
|
const { subscription } = useSubscription();
|
||||||
|
const { projectId } = useParams({
|
||||||
|
strict: false
|
||||||
|
});
|
||||||
const { mutateAsync: addMutateAsync } = useAddIdentityAliCloudAuth();
|
const { mutateAsync: addMutateAsync } = useAddIdentityAliCloudAuth();
|
||||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityAliCloudAuth();
|
const { mutateAsync: updateMutateAsync } = useUpdateIdentityAliCloudAuth();
|
||||||
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
||||||
@@ -144,7 +147,7 @@ export const IdentityAliCloudAuthForm = ({
|
|||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
await updateMutateAsync({
|
await updateMutateAsync({
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
allowedArns,
|
allowedArns,
|
||||||
identityId,
|
identityId,
|
||||||
accessTokenTTL: Number(accessTokenTTL),
|
accessTokenTTL: Number(accessTokenTTL),
|
||||||
@@ -154,7 +157,7 @@ export const IdentityAliCloudAuthForm = ({
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await addMutateAsync({
|
await addMutateAsync({
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
identityId,
|
identityId,
|
||||||
allowedArns,
|
allowedArns,
|
||||||
accessTokenTTL: Number(accessTokenTTL),
|
accessTokenTTL: Number(accessTokenTTL),
|
||||||
|
|||||||
+7
-6
@@ -3,6 +3,7 @@ import { Controller, useFieldArray, useForm } from "react-hook-form";
|
|||||||
import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { useParams } from "@tanstack/react-router";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
@@ -78,7 +79,9 @@ export const IdentityAwsAuthForm = ({
|
|||||||
const { currentOrg } = useOrganization();
|
const { currentOrg } = useOrganization();
|
||||||
const orgId = currentOrg?.id || "";
|
const orgId = currentOrg?.id || "";
|
||||||
const { subscription } = useSubscription();
|
const { subscription } = useSubscription();
|
||||||
|
const { projectId } = useParams({
|
||||||
|
strict: false
|
||||||
|
});
|
||||||
const { mutateAsync: addMutateAsync } = useAddIdentityAwsAuth();
|
const { mutateAsync: addMutateAsync } = useAddIdentityAwsAuth();
|
||||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityAwsAuth();
|
const { mutateAsync: updateMutateAsync } = useUpdateIdentityAwsAuth();
|
||||||
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
||||||
@@ -154,7 +157,7 @@ export const IdentityAwsAuthForm = ({
|
|||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
await updateMutateAsync({
|
await updateMutateAsync({
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
stsEndpoint,
|
stsEndpoint,
|
||||||
allowedPrincipalArns,
|
allowedPrincipalArns,
|
||||||
allowedAccountIds,
|
allowedAccountIds,
|
||||||
@@ -166,7 +169,7 @@ export const IdentityAwsAuthForm = ({
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await addMutateAsync({
|
await addMutateAsync({
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
identityId,
|
identityId,
|
||||||
stsEndpoint: stsEndpoint || "",
|
stsEndpoint: stsEndpoint || "",
|
||||||
allowedPrincipalArns: allowedPrincipalArns || "",
|
allowedPrincipalArns: allowedPrincipalArns || "",
|
||||||
@@ -176,10 +179,8 @@ export const IdentityAwsAuthForm = ({
|
|||||||
accessTokenNumUsesLimit: Number(accessTokenNumUsesLimit),
|
accessTokenNumUsesLimit: Number(accessTokenNumUsesLimit),
|
||||||
accessTokenTrustedIps
|
accessTokenTrustedIps
|
||||||
});
|
});
|
||||||
|
handlePopUpToggle("identityAuthMethod", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePopUpToggle("identityAuthMethod", false);
|
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: `Successfully ${isUpdate ? "updated" : "configured"} auth method`,
|
text: `Successfully ${isUpdate ? "updated" : "configured"} auth method`,
|
||||||
type: "success"
|
type: "success"
|
||||||
|
|||||||
+6
-3
@@ -3,6 +3,7 @@ import { Controller, useFieldArray, useForm } from "react-hook-form";
|
|||||||
import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { useParams } from "@tanstack/react-router";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
@@ -73,7 +74,9 @@ export const IdentityAzureAuthForm = ({
|
|||||||
const { currentOrg } = useOrganization();
|
const { currentOrg } = useOrganization();
|
||||||
const orgId = currentOrg?.id || "";
|
const orgId = currentOrg?.id || "";
|
||||||
const { subscription } = useSubscription();
|
const { subscription } = useSubscription();
|
||||||
|
const { projectId } = useParams({
|
||||||
|
strict: false
|
||||||
|
});
|
||||||
const { mutateAsync: addMutateAsync } = useAddIdentityAzureAuth();
|
const { mutateAsync: addMutateAsync } = useAddIdentityAzureAuth();
|
||||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityAzureAuth();
|
const { mutateAsync: updateMutateAsync } = useUpdateIdentityAzureAuth();
|
||||||
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
||||||
@@ -150,7 +153,7 @@ export const IdentityAzureAuthForm = ({
|
|||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
await updateMutateAsync({
|
await updateMutateAsync({
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
identityId,
|
identityId,
|
||||||
tenantId,
|
tenantId,
|
||||||
resource,
|
resource,
|
||||||
@@ -162,7 +165,7 @@ export const IdentityAzureAuthForm = ({
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await addMutateAsync({
|
await addMutateAsync({
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
identityId,
|
identityId,
|
||||||
tenantId: tenantId || "",
|
tenantId: tenantId || "",
|
||||||
resource: resource || "",
|
resource: resource || "",
|
||||||
|
|||||||
+6
-4
@@ -3,6 +3,7 @@ import { Controller, useFieldArray, useForm } from "react-hook-form";
|
|||||||
import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { useParams } from "@tanstack/react-router";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
@@ -76,7 +77,9 @@ export const IdentityGcpAuthForm = ({
|
|||||||
const { currentOrg } = useOrganization();
|
const { currentOrg } = useOrganization();
|
||||||
const orgId = currentOrg?.id || "";
|
const orgId = currentOrg?.id || "";
|
||||||
const { subscription } = useSubscription();
|
const { subscription } = useSubscription();
|
||||||
|
const { projectId } = useParams({
|
||||||
|
strict: false
|
||||||
|
});
|
||||||
const { mutateAsync: addMutateAsync } = useAddIdentityGcpAuth();
|
const { mutateAsync: addMutateAsync } = useAddIdentityGcpAuth();
|
||||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityGcpAuth();
|
const { mutateAsync: updateMutateAsync } = useUpdateIdentityGcpAuth();
|
||||||
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
||||||
@@ -160,7 +163,7 @@ export const IdentityGcpAuthForm = ({
|
|||||||
if (data) {
|
if (data) {
|
||||||
await updateMutateAsync({
|
await updateMutateAsync({
|
||||||
identityId,
|
identityId,
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
type,
|
type,
|
||||||
allowedServiceAccounts,
|
allowedServiceAccounts,
|
||||||
allowedProjects,
|
allowedProjects,
|
||||||
@@ -173,7 +176,7 @@ export const IdentityGcpAuthForm = ({
|
|||||||
} else {
|
} else {
|
||||||
await addMutateAsync({
|
await addMutateAsync({
|
||||||
identityId,
|
identityId,
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
type,
|
type,
|
||||||
allowedServiceAccounts: allowedServiceAccounts || "",
|
allowedServiceAccounts: allowedServiceAccounts || "",
|
||||||
allowedProjects: allowedProjects || "",
|
allowedProjects: allowedProjects || "",
|
||||||
@@ -191,7 +194,6 @@ export const IdentityGcpAuthForm = ({
|
|||||||
text: `Successfully ${isUpdate ? "updated" : "configured"} auth method`,
|
text: `Successfully ${isUpdate ? "updated" : "configured"} auth method`,
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -4,6 +4,7 @@ import { faQuestionCircle } from "@fortawesome/free-regular-svg-icons";
|
|||||||
import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { useParams } from "@tanstack/react-router";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
@@ -109,7 +110,9 @@ export const IdentityJwtAuthForm = ({
|
|||||||
const { currentOrg } = useOrganization();
|
const { currentOrg } = useOrganization();
|
||||||
const orgId = currentOrg?.id || "";
|
const orgId = currentOrg?.id || "";
|
||||||
const { subscription } = useSubscription();
|
const { subscription } = useSubscription();
|
||||||
|
const { projectId } = useParams({
|
||||||
|
strict: false
|
||||||
|
});
|
||||||
const { mutateAsync: addMutateAsync } = useAddIdentityJwtAuth();
|
const { mutateAsync: addMutateAsync } = useAddIdentityJwtAuth();
|
||||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityJwtAuth();
|
const { mutateAsync: updateMutateAsync } = useUpdateIdentityJwtAuth();
|
||||||
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
||||||
@@ -227,7 +230,7 @@ export const IdentityJwtAuthForm = ({
|
|||||||
if (data) {
|
if (data) {
|
||||||
await updateMutateAsync({
|
await updateMutateAsync({
|
||||||
identityId,
|
identityId,
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
configurationType,
|
configurationType,
|
||||||
jwksUrl,
|
jwksUrl,
|
||||||
jwksCaCert,
|
jwksCaCert,
|
||||||
@@ -252,7 +255,7 @@ export const IdentityJwtAuthForm = ({
|
|||||||
boundAudiences,
|
boundAudiences,
|
||||||
boundClaims: Object.fromEntries(boundClaims.map((entry) => [entry.key, entry.value])),
|
boundClaims: Object.fromEntries(boundClaims.map((entry) => [entry.key, entry.value])),
|
||||||
boundSubject,
|
boundSubject,
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
accessTokenTTL: Number(accessTokenTTL),
|
accessTokenTTL: Number(accessTokenTTL),
|
||||||
accessTokenMaxTTL: Number(accessTokenMaxTTL),
|
accessTokenMaxTTL: Number(accessTokenMaxTTL),
|
||||||
accessTokenNumUsesLimit: Number(accessTokenNumUsesLimit),
|
accessTokenNumUsesLimit: Number(accessTokenNumUsesLimit),
|
||||||
@@ -266,7 +269,6 @@ export const IdentityJwtAuthForm = ({
|
|||||||
text: `Successfully ${isUpdate ? "updated" : "configured"} auth method`,
|
text: `Successfully ${isUpdate ? "updated" : "configured"} auth method`,
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+6
-3
@@ -4,6 +4,7 @@ import { faInfoCircle, faPlus, faXmark } from "@fortawesome/free-solid-svg-icons
|
|||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { useParams } from "@tanstack/react-router";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
@@ -117,7 +118,9 @@ export const IdentityKubernetesAuthForm = ({
|
|||||||
const { currentOrg } = useOrganization();
|
const { currentOrg } = useOrganization();
|
||||||
const orgId = currentOrg?.id || "";
|
const orgId = currentOrg?.id || "";
|
||||||
const { subscription } = useSubscription();
|
const { subscription } = useSubscription();
|
||||||
|
const { projectId } = useParams({
|
||||||
|
strict: false
|
||||||
|
});
|
||||||
const { mutateAsync: addMutateAsync } = useAddIdentityKubernetesAuth();
|
const { mutateAsync: addMutateAsync } = useAddIdentityKubernetesAuth();
|
||||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityKubernetesAuth();
|
const { mutateAsync: updateMutateAsync } = useUpdateIdentityKubernetesAuth();
|
||||||
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
||||||
@@ -318,7 +321,7 @@ export const IdentityKubernetesAuthForm = ({
|
|||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
await updateMutateAsync({
|
await updateMutateAsync({
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
...(tokenReviewMode === IdentityKubernetesAuthTokenReviewMode.Api
|
...(tokenReviewMode === IdentityKubernetesAuthTokenReviewMode.Api
|
||||||
? {
|
? {
|
||||||
kubernetesHost: kubernetesHost || ""
|
kubernetesHost: kubernetesHost || ""
|
||||||
@@ -341,7 +344,7 @@ export const IdentityKubernetesAuthForm = ({
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await addMutateAsync({
|
await addMutateAsync({
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
identityId,
|
identityId,
|
||||||
...(tokenReviewMode === IdentityKubernetesAuthTokenReviewMode.Api
|
...(tokenReviewMode === IdentityKubernetesAuthTokenReviewMode.Api
|
||||||
? {
|
? {
|
||||||
|
|||||||
+5
-2
@@ -3,6 +3,7 @@ import { Controller, useFieldArray, useForm } from "react-hook-form";
|
|||||||
import { faPlus, faQuestionCircle, faXmark } from "@fortawesome/free-solid-svg-icons";
|
import { faPlus, faQuestionCircle, faXmark } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { useParams } from "@tanstack/react-router";
|
||||||
import ms from "ms";
|
import ms from "ms";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
@@ -168,7 +169,9 @@ export const IdentityLdapAuthForm = ({
|
|||||||
const { currentOrg } = useOrganization();
|
const { currentOrg } = useOrganization();
|
||||||
const orgId = currentOrg?.id || "";
|
const orgId = currentOrg?.id || "";
|
||||||
const { subscription } = useSubscription();
|
const { subscription } = useSubscription();
|
||||||
|
const { projectId } = useParams({
|
||||||
|
strict: false
|
||||||
|
});
|
||||||
const { mutateAsync: addMutateAsync } = useAddIdentityLdapAuth();
|
const { mutateAsync: addMutateAsync } = useAddIdentityLdapAuth();
|
||||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityLdapAuth();
|
const { mutateAsync: updateMutateAsync } = useUpdateIdentityLdapAuth();
|
||||||
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
||||||
@@ -345,7 +348,7 @@ export const IdentityLdapAuthForm = ({
|
|||||||
ms(`${lockoutCounterResetValue}${lockoutCounterResetUnit}`) / 1000;
|
ms(`${lockoutCounterResetValue}${lockoutCounterResetUnit}`) / 1000;
|
||||||
|
|
||||||
const basePayload = {
|
const basePayload = {
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
identityId,
|
identityId,
|
||||||
searchFilter,
|
searchFilter,
|
||||||
ldapCaCertificate,
|
ldapCaCertificate,
|
||||||
|
|||||||
+6
-4
@@ -3,6 +3,7 @@ import { Controller, useFieldArray, useForm } from "react-hook-form";
|
|||||||
import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { useParams } from "@tanstack/react-router";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
@@ -84,7 +85,9 @@ export const IdentityOciAuthForm = ({
|
|||||||
const { currentOrg } = useOrganization();
|
const { currentOrg } = useOrganization();
|
||||||
const orgId = currentOrg?.id || "";
|
const orgId = currentOrg?.id || "";
|
||||||
const { subscription } = useSubscription();
|
const { subscription } = useSubscription();
|
||||||
|
const { projectId } = useParams({
|
||||||
|
strict: false
|
||||||
|
});
|
||||||
const { mutateAsync: addMutateAsync } = useAddIdentityOciAuth();
|
const { mutateAsync: addMutateAsync } = useAddIdentityOciAuth();
|
||||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityOciAuth();
|
const { mutateAsync: updateMutateAsync } = useUpdateIdentityOciAuth();
|
||||||
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
||||||
@@ -156,7 +159,7 @@ export const IdentityOciAuthForm = ({
|
|||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
await updateMutateAsync({
|
await updateMutateAsync({
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
tenancyOcid,
|
tenancyOcid,
|
||||||
allowedUsernames,
|
allowedUsernames,
|
||||||
identityId,
|
identityId,
|
||||||
@@ -167,7 +170,7 @@ export const IdentityOciAuthForm = ({
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await addMutateAsync({
|
await addMutateAsync({
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
identityId,
|
identityId,
|
||||||
tenancyOcid,
|
tenancyOcid,
|
||||||
allowedUsernames: allowedUsernames || undefined,
|
allowedUsernames: allowedUsernames || undefined,
|
||||||
@@ -184,7 +187,6 @@ export const IdentityOciAuthForm = ({
|
|||||||
text: `Successfully ${isUpdate ? "updated" : "configured"} auth method`,
|
text: `Successfully ${isUpdate ? "updated" : "configured"} auth method`,
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -4,6 +4,7 @@ import { faQuestionCircle } from "@fortawesome/free-regular-svg-icons";
|
|||||||
import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { useParams } from "@tanstack/react-router";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
@@ -96,7 +97,9 @@ export const IdentityOidcAuthForm = ({
|
|||||||
const { currentOrg } = useOrganization();
|
const { currentOrg } = useOrganization();
|
||||||
const orgId = currentOrg?.id || "";
|
const orgId = currentOrg?.id || "";
|
||||||
const { subscription } = useSubscription();
|
const { subscription } = useSubscription();
|
||||||
|
const { projectId } = useParams({
|
||||||
|
strict: false
|
||||||
|
});
|
||||||
const { mutateAsync: addMutateAsync } = useAddIdentityOidcAuth();
|
const { mutateAsync: addMutateAsync } = useAddIdentityOidcAuth();
|
||||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityOidcAuth();
|
const { mutateAsync: updateMutateAsync } = useUpdateIdentityOidcAuth();
|
||||||
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
||||||
@@ -211,7 +214,7 @@ export const IdentityOidcAuthForm = ({
|
|||||||
if (data) {
|
if (data) {
|
||||||
await updateMutateAsync({
|
await updateMutateAsync({
|
||||||
identityId,
|
identityId,
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
oidcDiscoveryUrl,
|
oidcDiscoveryUrl,
|
||||||
caCert,
|
caCert,
|
||||||
boundIssuer,
|
boundIssuer,
|
||||||
@@ -238,7 +241,7 @@ export const IdentityOidcAuthForm = ({
|
|||||||
? Object.fromEntries(claimMetadataMapping.map((entry) => [entry.key, entry.value]))
|
? Object.fromEntries(claimMetadataMapping.map((entry) => [entry.key, entry.value]))
|
||||||
: undefined,
|
: undefined,
|
||||||
boundSubject,
|
boundSubject,
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
accessTokenTTL: Number(accessTokenTTL),
|
accessTokenTTL: Number(accessTokenTTL),
|
||||||
accessTokenMaxTTL: Number(accessTokenMaxTTL),
|
accessTokenMaxTTL: Number(accessTokenMaxTTL),
|
||||||
accessTokenNumUsesLimit: Number(accessTokenNumUsesLimit),
|
accessTokenNumUsesLimit: Number(accessTokenNumUsesLimit),
|
||||||
@@ -252,7 +255,6 @@ export const IdentityOidcAuthForm = ({
|
|||||||
text: `Successfully ${isUpdate ? "updated" : "configured"} auth method`,
|
text: `Successfully ${isUpdate ? "updated" : "configured"} auth method`,
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+69
-40
@@ -1,10 +1,18 @@
|
|||||||
import { faLink, faPlus } from "@fortawesome/free-solid-svg-icons";
|
import { faChevronDown, faLink, faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
|
||||||
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
|
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
import { OrgPermissionCan } from "@app/components/permissions";
|
import { OrgPermissionCan } from "@app/components/permissions";
|
||||||
import { Button, DeleteActionModal, Modal, ModalContent } from "@app/components/v2";
|
import {
|
||||||
|
Button,
|
||||||
|
DeleteActionModal,
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
Modal,
|
||||||
|
ModalContent
|
||||||
|
} from "@app/components/v2";
|
||||||
import { DocumentationLinkBadge } from "@app/components/v3";
|
import { DocumentationLinkBadge } from "@app/components/v3";
|
||||||
import {
|
import {
|
||||||
OrgPermissionIdentityActions,
|
OrgPermissionIdentityActions,
|
||||||
@@ -14,17 +22,17 @@ import {
|
|||||||
} from "@app/context";
|
} from "@app/context";
|
||||||
import { OrgPermissionMachineIdentityAuthTemplateActions } from "@app/context/OrgPermissionContext/types";
|
import { OrgPermissionMachineIdentityAuthTemplateActions } from "@app/context/OrgPermissionContext/types";
|
||||||
import { withPermission } from "@app/hoc";
|
import { withPermission } from "@app/hoc";
|
||||||
import { useDeleteIdentity } from "@app/hooks/api";
|
import { useDeleteOrgIdentity } from "@app/hooks/api";
|
||||||
import { useDeleteIdentityAuthTemplate } from "@app/hooks/api/identityAuthTemplates";
|
import { useDeleteIdentityAuthTemplate } from "@app/hooks/api/identityAuthTemplates";
|
||||||
import { usePopUp } from "@app/hooks/usePopUp";
|
import { usePopUp } from "@app/hooks/usePopUp";
|
||||||
|
|
||||||
import { IdentityAuthTemplateModal } from "./IdentityAuthTemplateModal";
|
import { IdentityAuthTemplateModal } from "./IdentityAuthTemplateModal";
|
||||||
import { IdentityAuthTemplatesTable } from "./IdentityAuthTemplatesTable";
|
import { IdentityAuthTemplatesTable } from "./IdentityAuthTemplatesTable";
|
||||||
import { IdentityLinkForm } from "./IdentityLinkForm";
|
|
||||||
import { IdentityModal } from "./IdentityModal";
|
|
||||||
import { IdentityTable } from "./IdentityTable";
|
import { IdentityTable } from "./IdentityTable";
|
||||||
import { IdentityTokenAuthTokenModal } from "./IdentityTokenAuthTokenModal";
|
import { IdentityTokenAuthTokenModal } from "./IdentityTokenAuthTokenModal";
|
||||||
import { MachineAuthTemplateUsagesModal } from "./MachineAuthTemplateUsagesModal";
|
import { MachineAuthTemplateUsagesModal } from "./MachineAuthTemplateUsagesModal";
|
||||||
|
import { OrgIdentityLinkForm } from "./OrgIdentityLinkForm";
|
||||||
|
import { OrgIdentityModal } from "./OrgIdentityModal";
|
||||||
|
|
||||||
export const IdentitySection = withPermission(
|
export const IdentitySection = withPermission(
|
||||||
() => {
|
() => {
|
||||||
@@ -32,7 +40,7 @@ export const IdentitySection = withPermission(
|
|||||||
const { currentOrg, isSubOrganization } = useOrganization();
|
const { currentOrg, isSubOrganization } = useOrganization();
|
||||||
const orgId = currentOrg?.id || "";
|
const orgId = currentOrg?.id || "";
|
||||||
|
|
||||||
const { mutateAsync: deleteMutateAsync } = useDeleteIdentity();
|
const { mutateAsync: deleteMutateAsync } = useDeleteOrgIdentity();
|
||||||
const { mutateAsync: deleteTemplateMutateAsync } = useDeleteIdentityAuthTemplate();
|
const { mutateAsync: deleteTemplateMutateAsync } = useDeleteIdentityAuthTemplate();
|
||||||
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
|
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
|
||||||
"identity",
|
"identity",
|
||||||
@@ -46,7 +54,8 @@ export const IdentitySection = withPermission(
|
|||||||
"editTemplate",
|
"editTemplate",
|
||||||
"deleteTemplate",
|
"deleteTemplate",
|
||||||
"viewUsages",
|
"viewUsages",
|
||||||
"linkIdentity"
|
"linkIdentity",
|
||||||
|
"addOptions"
|
||||||
] as const);
|
] as const);
|
||||||
|
|
||||||
const isMoreIdentitiesAllowed = subscription?.identityLimit
|
const isMoreIdentitiesAllowed = subscription?.identityLimit
|
||||||
@@ -58,7 +67,7 @@ export const IdentitySection = withPermission(
|
|||||||
const onDeleteIdentitySubmit = async (identityId: string) => {
|
const onDeleteIdentitySubmit = async (identityId: string) => {
|
||||||
await deleteMutateAsync({
|
await deleteMutateAsync({
|
||||||
identityId,
|
identityId,
|
||||||
organizationId: orgId
|
orgId
|
||||||
});
|
});
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
@@ -91,50 +100,70 @@ export const IdentitySection = withPermission(
|
|||||||
<p className="text-xl font-medium text-mineshaft-100">Identities</p>
|
<p className="text-xl font-medium text-mineshaft-100">Identities</p>
|
||||||
<DocumentationLinkBadge href="https://infisical.com/docs/documentation/platform/identities/machine-identities" />
|
<DocumentationLinkBadge href="https://infisical.com/docs/documentation/platform/identities/machine-identities" />
|
||||||
</div>
|
</div>
|
||||||
{isSubOrganization && (
|
<div className="flex items-center">
|
||||||
<OrgPermissionCan
|
<OrgPermissionCan
|
||||||
I={OrgPermissionIdentityActions.Create}
|
I={OrgPermissionIdentityActions.Create}
|
||||||
a={OrgPermissionSubjects.Identity}
|
a={OrgPermissionSubjects.Identity}
|
||||||
>
|
>
|
||||||
{(isAllowed) => (
|
{(isAllowed) => (
|
||||||
<Button
|
<Button
|
||||||
variant="plain"
|
variant="outline_bg"
|
||||||
colorSchema="secondary"
|
className={isSubOrganization ? "rounded-r-none" : ""}
|
||||||
leftIcon={<FontAwesomeIcon icon={faLink} />}
|
type="submit"
|
||||||
|
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
handlePopUpOpen("linkIdentity");
|
if (!isMoreIdentitiesAllowed && !isEnterprise) {
|
||||||
|
handlePopUpOpen("upgradePlan", {
|
||||||
|
description:
|
||||||
|
"You can add more identities if you upgrade your Infisical Pro plan."
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
handlePopUpOpen("identity");
|
||||||
}}
|
}}
|
||||||
isDisabled={!isAllowed}
|
isDisabled={!isAllowed}
|
||||||
>
|
>
|
||||||
Link Identity
|
Create Identity
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</OrgPermissionCan>
|
</OrgPermissionCan>
|
||||||
)}
|
{isSubOrganization && (
|
||||||
<OrgPermissionCan
|
<DropdownMenu
|
||||||
I={OrgPermissionIdentityActions.Create}
|
open={popUp.addOptions.isOpen}
|
||||||
a={OrgPermissionSubjects.Identity}
|
onOpenChange={(isOpen) => handlePopUpToggle("addOptions", isOpen)}
|
||||||
>
|
|
||||||
{(isAllowed) => (
|
|
||||||
<Button
|
|
||||||
colorSchema="secondary"
|
|
||||||
type="submit"
|
|
||||||
leftIcon={<FontAwesomeIcon icon={faPlus} />}
|
|
||||||
onClick={() => {
|
|
||||||
if (!isMoreIdentitiesAllowed && !isEnterprise) {
|
|
||||||
handlePopUpOpen("upgradePlan", {
|
|
||||||
text: "You have reached the maximum number of identities allowed on your current plan. Upgrade to Infisical Pro plan to add more identities."
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
handlePopUpOpen("identity");
|
|
||||||
}}
|
|
||||||
isDisabled={!isAllowed}
|
|
||||||
>
|
>
|
||||||
Create Identity
|
<DropdownMenuTrigger>
|
||||||
</Button>
|
<Button
|
||||||
|
variant="outline_bg"
|
||||||
|
className="rounded-l-none border-l-mineshaft-800 px-3"
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faChevronDown} />
|
||||||
|
</Button>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent align="end" sideOffset={6} className="p-1">
|
||||||
|
<OrgPermissionCan
|
||||||
|
I={OrgPermissionIdentityActions.Create}
|
||||||
|
a={OrgPermissionSubjects.Identity}
|
||||||
|
>
|
||||||
|
{(isAllowed) => (
|
||||||
|
<Button
|
||||||
|
variant="outline_bg"
|
||||||
|
className="w-full"
|
||||||
|
isDisabled={!isAllowed}
|
||||||
|
leftIcon={<FontAwesomeIcon icon={faLink} />}
|
||||||
|
onClick={() => {
|
||||||
|
handlePopUpClose("addOptions");
|
||||||
|
handlePopUpOpen("linkIdentity");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Assign Org Identity
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</OrgPermissionCan>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
)}
|
)}
|
||||||
</OrgPermissionCan>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<IdentityTable handlePopUpOpen={handlePopUpOpen} />
|
<IdentityTable handlePopUpOpen={handlePopUpOpen} />
|
||||||
</div>
|
</div>
|
||||||
@@ -173,7 +202,7 @@ export const IdentitySection = withPermission(
|
|||||||
</div>
|
</div>
|
||||||
<IdentityAuthTemplatesTable handlePopUpOpen={handlePopUpOpen} />
|
<IdentityAuthTemplatesTable handlePopUpOpen={handlePopUpOpen} />
|
||||||
</div>
|
</div>
|
||||||
<IdentityModal popUp={popUp} handlePopUpToggle={handlePopUpToggle} />
|
<OrgIdentityModal popUp={popUp} handlePopUpToggle={handlePopUpToggle} />
|
||||||
<IdentityAuthTemplateModal popUp={popUp} handlePopUpToggle={handlePopUpToggle} />
|
<IdentityAuthTemplateModal popUp={popUp} handlePopUpToggle={handlePopUpToggle} />
|
||||||
<MachineAuthTemplateUsagesModal
|
<MachineAuthTemplateUsagesModal
|
||||||
isOpen={popUp.viewUsages.isOpen}
|
isOpen={popUp.viewUsages.isOpen}
|
||||||
@@ -193,10 +222,10 @@ export const IdentitySection = withPermission(
|
|||||||
>
|
>
|
||||||
<ModalContent
|
<ModalContent
|
||||||
title="Assign Existing Identity"
|
title="Assign Existing Identity"
|
||||||
subTitle="Assign an existing identity from your root organization to the sub organization. The identity will continue to be managed at its original scope."
|
subTitle="Assign an existing identity from your root organization to this sub organization. The identity will continue to be managed at its original scope."
|
||||||
bodyClassName="overflow-visible"
|
bodyClassName="overflow-visible"
|
||||||
>
|
>
|
||||||
<IdentityLinkForm onClose={() => handlePopUpClose("linkIdentity")} />
|
<OrgIdentityLinkForm onClose={() => handlePopUpClose("linkIdentity")} />
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
</Modal>
|
</Modal>
|
||||||
<IdentityTokenAuthTokenModal popUp={popUp} handlePopUpToggle={handlePopUpToggle} />
|
<IdentityTokenAuthTokenModal popUp={popUp} handlePopUpToggle={handlePopUpToggle} />
|
||||||
|
|||||||
+18
-9
@@ -2,7 +2,6 @@ import { useCallback, useState } from "react";
|
|||||||
import {
|
import {
|
||||||
faArrowDown,
|
faArrowDown,
|
||||||
faArrowUp,
|
faArrowUp,
|
||||||
faBuilding,
|
|
||||||
faCheckCircle,
|
faCheckCircle,
|
||||||
faChevronRight,
|
faChevronRight,
|
||||||
faEdit,
|
faEdit,
|
||||||
@@ -46,6 +45,7 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
Tr
|
Tr
|
||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
|
import { Badge, OrgIcon, SubOrgIcon } from "@app/components/v3";
|
||||||
import { OrgPermissionIdentityActions, OrgPermissionSubjects, useOrganization } from "@app/context";
|
import { OrgPermissionIdentityActions, OrgPermissionSubjects, useOrganization } from "@app/context";
|
||||||
import {
|
import {
|
||||||
getUserTablePreference,
|
getUserTablePreference,
|
||||||
@@ -56,8 +56,8 @@ import { usePagination, useResetPageHelper } from "@app/hooks";
|
|||||||
import {
|
import {
|
||||||
identityAuthToNameMap,
|
identityAuthToNameMap,
|
||||||
useGetOrgRoles,
|
useGetOrgRoles,
|
||||||
useSearchIdentities,
|
useSearchOrgIdentityMemberships,
|
||||||
useUpdateIdentity
|
useUpdateOrgIdentity
|
||||||
} from "@app/hooks/api";
|
} from "@app/hooks/api";
|
||||||
import { OrderByDirection } from "@app/hooks/api/generic/types";
|
import { OrderByDirection } from "@app/hooks/api/generic/types";
|
||||||
import { OrgIdentityOrderBy } from "@app/hooks/api/organization/types";
|
import { OrgIdentityOrderBy } from "@app/hooks/api/organization/types";
|
||||||
@@ -110,9 +110,9 @@ export const IdentityTable = ({ handlePopUpOpen }: Props) => {
|
|||||||
|
|
||||||
const organizationId = currentOrg?.id || "";
|
const organizationId = currentOrg?.id || "";
|
||||||
|
|
||||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentity();
|
const { mutateAsync: updateMutateAsync } = useUpdateOrgIdentity();
|
||||||
|
|
||||||
const { data, isPending, isFetching } = useSearchIdentities({
|
const { data, isPending, isFetching } = useSearchOrgIdentityMemberships({
|
||||||
offset,
|
offset,
|
||||||
limit,
|
limit,
|
||||||
orderDirection,
|
orderDirection,
|
||||||
@@ -357,10 +357,19 @@ export const IdentityTable = ({ handlePopUpOpen }: Props) => {
|
|||||||
</Td>
|
</Td>
|
||||||
{isSubOrganization && (
|
{isSubOrganization && (
|
||||||
<Td>
|
<Td>
|
||||||
<p className="truncate">
|
<Badge variant="ghost">
|
||||||
<FontAwesomeIcon size="sm" className="mr-1.5" icon={faBuilding} />
|
{currentOrg.id === orgId ? (
|
||||||
{currentOrg.id === orgId ? "Sub Organization" : "Root Organization"}
|
<>
|
||||||
</p>
|
<SubOrgIcon />
|
||||||
|
Sub-Organization
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<OrgIcon />
|
||||||
|
Root Organization
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Badge>
|
||||||
</Td>
|
</Td>
|
||||||
)}
|
)}
|
||||||
<Td>
|
<Td>
|
||||||
|
|||||||
+6
-4
@@ -3,6 +3,7 @@ import { Controller, useFieldArray, useForm } from "react-hook-form";
|
|||||||
import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { useParams } from "@tanstack/react-router";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
@@ -71,7 +72,9 @@ export const IdentityTlsCertAuthForm = ({
|
|||||||
const { currentOrg } = useOrganization();
|
const { currentOrg } = useOrganization();
|
||||||
const orgId = currentOrg?.id || "";
|
const orgId = currentOrg?.id || "";
|
||||||
const { subscription } = useSubscription();
|
const { subscription } = useSubscription();
|
||||||
|
const { projectId } = useParams({
|
||||||
|
strict: false
|
||||||
|
});
|
||||||
const { mutateAsync: addMutateAsync } = useAddIdentityTlsCertAuth();
|
const { mutateAsync: addMutateAsync } = useAddIdentityTlsCertAuth();
|
||||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityTlsCertAuth();
|
const { mutateAsync: updateMutateAsync } = useUpdateIdentityTlsCertAuth();
|
||||||
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
||||||
@@ -141,7 +144,7 @@ export const IdentityTlsCertAuthForm = ({
|
|||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
await updateMutateAsync({
|
await updateMutateAsync({
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
caCertificate,
|
caCertificate,
|
||||||
allowedCommonNames: allowedCommonNames || null,
|
allowedCommonNames: allowedCommonNames || null,
|
||||||
identityId,
|
identityId,
|
||||||
@@ -152,7 +155,7 @@ export const IdentityTlsCertAuthForm = ({
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await addMutateAsync({
|
await addMutateAsync({
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
identityId,
|
identityId,
|
||||||
caCertificate,
|
caCertificate,
|
||||||
allowedCommonNames: allowedCommonNames || undefined,
|
allowedCommonNames: allowedCommonNames || undefined,
|
||||||
@@ -169,7 +172,6 @@ export const IdentityTlsCertAuthForm = ({
|
|||||||
text: `Successfully ${isUpdate ? "updated" : "configured"} auth method`,
|
text: `Successfully ${isUpdate ? "updated" : "configured"} auth method`,
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+6
-3
@@ -3,6 +3,7 @@ import { Controller, useFieldArray, useForm } from "react-hook-form";
|
|||||||
import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { useParams } from "@tanstack/react-router";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
@@ -70,7 +71,9 @@ export const IdentityTokenAuthForm = ({
|
|||||||
const { currentOrg } = useOrganization();
|
const { currentOrg } = useOrganization();
|
||||||
const orgId = currentOrg?.id || "";
|
const orgId = currentOrg?.id || "";
|
||||||
const { subscription } = useSubscription();
|
const { subscription } = useSubscription();
|
||||||
|
const { projectId } = useParams({
|
||||||
|
strict: false
|
||||||
|
});
|
||||||
const { mutateAsync: addMutateAsync } = useAddIdentityTokenAuth();
|
const { mutateAsync: addMutateAsync } = useAddIdentityTokenAuth();
|
||||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentityTokenAuth();
|
const { mutateAsync: updateMutateAsync } = useUpdateIdentityTokenAuth();
|
||||||
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
const [tabValue, setTabValue] = useState<IdentityFormTab>(IdentityFormTab.Configuration);
|
||||||
@@ -134,7 +137,7 @@ export const IdentityTokenAuthForm = ({
|
|||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
await updateMutateAsync({
|
await updateMutateAsync({
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
identityId,
|
identityId,
|
||||||
accessTokenTTL: Number(accessTokenTTL),
|
accessTokenTTL: Number(accessTokenTTL),
|
||||||
accessTokenMaxTTL: Number(accessTokenMaxTTL),
|
accessTokenMaxTTL: Number(accessTokenMaxTTL),
|
||||||
@@ -143,7 +146,7 @@ export const IdentityTokenAuthForm = ({
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await addMutateAsync({
|
await addMutateAsync({
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
identityId,
|
identityId,
|
||||||
accessTokenTTL: Number(accessTokenTTL),
|
accessTokenTTL: Number(accessTokenTTL),
|
||||||
accessTokenMaxTTL: Number(accessTokenMaxTTL),
|
accessTokenMaxTTL: Number(accessTokenMaxTTL),
|
||||||
|
|||||||
+6
-3
@@ -3,6 +3,7 @@ import { Controller, useFieldArray, useForm } from "react-hook-form";
|
|||||||
import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
import { faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { useParams } from "@tanstack/react-router";
|
||||||
import ms from "ms";
|
import ms from "ms";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
@@ -105,6 +106,9 @@ export const IdentityUniversalAuthForm = ({
|
|||||||
identityId,
|
identityId,
|
||||||
isUpdate
|
isUpdate
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
|
const { projectId } = useParams({
|
||||||
|
strict: false
|
||||||
|
});
|
||||||
const { currentOrg } = useOrganization();
|
const { currentOrg } = useOrganization();
|
||||||
const orgId = currentOrg?.id || "";
|
const orgId = currentOrg?.id || "";
|
||||||
const { subscription } = useSubscription();
|
const { subscription } = useSubscription();
|
||||||
@@ -232,7 +236,7 @@ export const IdentityUniversalAuthForm = ({
|
|||||||
if (data) {
|
if (data) {
|
||||||
// update universal auth configuration
|
// update universal auth configuration
|
||||||
await updateMutateAsync({
|
await updateMutateAsync({
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
identityId,
|
identityId,
|
||||||
clientSecretTrustedIps,
|
clientSecretTrustedIps,
|
||||||
accessTokenTTL: Number(accessTokenTTL),
|
accessTokenTTL: Number(accessTokenTTL),
|
||||||
@@ -249,7 +253,7 @@ export const IdentityUniversalAuthForm = ({
|
|||||||
// create new universal auth configuration
|
// create new universal auth configuration
|
||||||
|
|
||||||
await addMutateAsync({
|
await addMutateAsync({
|
||||||
organizationId: orgId,
|
...(projectId ? { projectId } : { organizationId: orgId }),
|
||||||
identityId,
|
identityId,
|
||||||
clientSecretTrustedIps,
|
clientSecretTrustedIps,
|
||||||
accessTokenTTL: Number(accessTokenTTL),
|
accessTokenTTL: Number(accessTokenTTL),
|
||||||
@@ -270,7 +274,6 @@ export const IdentityUniversalAuthForm = ({
|
|||||||
text: `Successfully ${isUpdate ? "updated" : "created"} auth method`,
|
text: `Successfully ${isUpdate ? "updated" : "created"} auth method`,
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+17
-4
@@ -1,13 +1,15 @@
|
|||||||
import { Controller, useForm } from "react-hook-form";
|
import { Controller, useForm } from "react-hook-form";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import { useNavigate } from "@tanstack/react-router";
|
import { useNavigate } from "@tanstack/react-router";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
import { Button, FilterableSelect, FormControl } from "@app/components/v2";
|
import { Button, FilterableSelect, FormControl } from "@app/components/v2";
|
||||||
import { useOrganization } from "@app/context";
|
import { useOrganization } from "@app/context";
|
||||||
import { useGetAvailableOrgIdentities, useGetOrgRoles } from "@app/hooks/api";
|
import { useGetOrgRoles } from "@app/hooks/api";
|
||||||
import { useCreateOrgIdentityMembership } from "@app/hooks/api/orgIdentityMembership";
|
import { useCreateOrgIdentityMembership } from "@app/hooks/api/orgIdentityMembership";
|
||||||
|
import { orgIdentityMembershipQuery } from "@app/hooks/api/orgIdentityMembership/queries";
|
||||||
|
|
||||||
const schema = z
|
const schema = z
|
||||||
.object({
|
.object({
|
||||||
@@ -22,15 +24,26 @@ type Props = {
|
|||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const IdentityLinkForm = ({ onClose }: Props) => {
|
export const OrgIdentityLinkForm = ({ onClose }: Props) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { currentOrg } = useOrganization();
|
const { currentOrg } = useOrganization();
|
||||||
const orgId = currentOrg?.id || "";
|
const orgId = currentOrg?.id || "";
|
||||||
|
|
||||||
const { data: roles } = useGetOrgRoles(orgId);
|
const { data: roles } = useGetOrgRoles(orgId);
|
||||||
|
|
||||||
|
// const [searchValue, setSearchValue] = useState("");
|
||||||
|
//
|
||||||
|
// const [debouncedSearchValue] = useDebounce(searchValue);
|
||||||
|
|
||||||
const { mutateAsync: createMutateAsync } = useCreateOrgIdentityMembership();
|
const { mutateAsync: createMutateAsync } = useCreateOrgIdentityMembership();
|
||||||
const { data: rootOrgIdentities, isPending: isRootOrgLoading } = useGetAvailableOrgIdentities();
|
|
||||||
|
// TODO: name filter needs to be implemented on backend
|
||||||
|
const { data: rootOrgIdentities, isPending: isRootOrgLoading } = useQuery({
|
||||||
|
...orgIdentityMembershipQuery.listAvailable({
|
||||||
|
// identityName: debouncedSearchValue
|
||||||
|
}),
|
||||||
|
placeholderData: (prev) => prev
|
||||||
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
@@ -69,6 +82,7 @@ export const IdentityLinkForm = ({ onClose }: Props) => {
|
|||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
placeholder="Select identity..."
|
placeholder="Select identity..."
|
||||||
|
// onInputChange={setSearchValue}
|
||||||
options={rootOrgIdentities}
|
options={rootOrgIdentities}
|
||||||
getOptionValue={(option) => option.id}
|
getOptionValue={(option) => option.id}
|
||||||
getOptionLabel={(option) => option.name}
|
getOptionLabel={(option) => option.name}
|
||||||
@@ -94,7 +108,6 @@ export const IdentityLinkForm = ({ onClose }: Props) => {
|
|||||||
placeholder="Select role..."
|
placeholder="Select role..."
|
||||||
getOptionValue={(option) => option.slug}
|
getOptionValue={(option) => option.slug}
|
||||||
getOptionLabel={(option) => option.name}
|
getOptionLabel={(option) => option.name}
|
||||||
// menuPortalTarget={document.body}
|
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
)}
|
)}
|
||||||
+4
-4
@@ -20,7 +20,7 @@ import {
|
|||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
import { useOrganization } from "@app/context";
|
import { useOrganization } from "@app/context";
|
||||||
import { findOrgMembershipRole } from "@app/helpers/roles";
|
import { findOrgMembershipRole } from "@app/helpers/roles";
|
||||||
import { useCreateIdentity, useGetOrgRoles, useUpdateIdentity } from "@app/hooks/api";
|
import { useCreateOrgIdentity, useGetOrgRoles, useUpdateOrgIdentity } from "@app/hooks/api";
|
||||||
import { useAddIdentityUniversalAuth } from "@app/hooks/api/identities";
|
import { useAddIdentityUniversalAuth } from "@app/hooks/api/identities";
|
||||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ type Props = {
|
|||||||
handlePopUpToggle: (popUpName: keyof UsePopUpState<["identity"]>, state?: boolean) => void;
|
handlePopUpToggle: (popUpName: keyof UsePopUpState<["identity"]>, state?: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const IdentityModal = ({ popUp, handlePopUpToggle }: Props) => {
|
export const OrgIdentityModal = ({ popUp, handlePopUpToggle }: Props) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { currentOrg } = useOrganization();
|
const { currentOrg } = useOrganization();
|
||||||
const orgId = currentOrg?.id || "";
|
const orgId = currentOrg?.id || "";
|
||||||
@@ -55,8 +55,8 @@ export const IdentityModal = ({ popUp, handlePopUpToggle }: Props) => {
|
|||||||
const { data: roles } = useGetOrgRoles(orgId);
|
const { data: roles } = useGetOrgRoles(orgId);
|
||||||
const isOrgIdentity = popUp?.identity?.data ? orgId === popUp?.identity?.data?.orgId : true;
|
const isOrgIdentity = popUp?.identity?.data ? orgId === popUp?.identity?.data?.orgId : true;
|
||||||
|
|
||||||
const { mutateAsync: createMutateAsync } = useCreateIdentity();
|
const { mutateAsync: createMutateAsync } = useCreateOrgIdentity();
|
||||||
const { mutateAsync: updateMutateAsync } = useUpdateIdentity();
|
const { mutateAsync: updateMutateAsync } = useUpdateOrgIdentity();
|
||||||
const { mutateAsync: addMutateAsync } = useAddIdentityUniversalAuth();
|
const { mutateAsync: addMutateAsync } = useAddIdentityUniversalAuth();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -10,13 +10,13 @@ import { OrgPermissionCan } from "@app/components/permissions";
|
|||||||
import { DeleteActionModal, PageHeader } from "@app/components/v2";
|
import { DeleteActionModal, PageHeader } from "@app/components/v2";
|
||||||
import { ROUTE_PATHS } from "@app/const/routes";
|
import { ROUTE_PATHS } from "@app/const/routes";
|
||||||
import { OrgPermissionIdentityActions, OrgPermissionSubjects, useOrganization } from "@app/context";
|
import { OrgPermissionIdentityActions, OrgPermissionSubjects, useOrganization } from "@app/context";
|
||||||
import { useDeleteIdentity, useGetIdentityById } from "@app/hooks/api";
|
import { useDeleteOrgIdentity, useGetOrgIdentityMembershipById } from "@app/hooks/api";
|
||||||
import { usePopUp } from "@app/hooks/usePopUp";
|
import { usePopUp } from "@app/hooks/usePopUp";
|
||||||
import { ViewIdentityAuthModal } from "@app/pages/organization/IdentityDetailsByIDPage/components/ViewIdentityAuthModal/ViewIdentityAuthModal";
|
import { ViewIdentityAuthModal } from "@app/pages/organization/IdentityDetailsByIDPage/components/ViewIdentityAuthModal/ViewIdentityAuthModal";
|
||||||
import { OrgAccessControlTabSections } from "@app/types/org";
|
import { OrgAccessControlTabSections } from "@app/types/org";
|
||||||
|
|
||||||
import { IdentityAuthMethodModal } from "../AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityAuthMethodModal";
|
import { IdentityAuthMethodModal } from "../AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityAuthMethodModal";
|
||||||
import { IdentityModal } from "../AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/IdentityModal";
|
import { OrgIdentityModal } from "../AccessManagementPage/components/OrgIdentityTab/components/IdentitySection/OrgIdentityModal";
|
||||||
import {
|
import {
|
||||||
IdentityAuthenticationSection,
|
IdentityAuthenticationSection,
|
||||||
IdentityDetailsSection,
|
IdentityDetailsSection,
|
||||||
@@ -31,8 +31,8 @@ const Page = () => {
|
|||||||
const identityId = params.identityId as string;
|
const identityId = params.identityId as string;
|
||||||
const { currentOrg, isSubOrganization } = useOrganization();
|
const { currentOrg, isSubOrganization } = useOrganization();
|
||||||
const orgId = currentOrg?.id || "";
|
const orgId = currentOrg?.id || "";
|
||||||
const { data } = useGetIdentityById(identityId);
|
const { data } = useGetOrgIdentityMembershipById(identityId);
|
||||||
const { mutateAsync: deleteIdentity } = useDeleteIdentity();
|
const { mutateAsync: deleteIdentity } = useDeleteOrgIdentity();
|
||||||
const isAuthHidden = orgId !== data?.identity?.orgId;
|
const isAuthHidden = orgId !== data?.identity?.orgId;
|
||||||
|
|
||||||
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
|
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
|
||||||
@@ -46,7 +46,7 @@ const Page = () => {
|
|||||||
const onDeleteIdentitySubmit = async (id: string) => {
|
const onDeleteIdentitySubmit = async (id: string) => {
|
||||||
await deleteIdentity({
|
await deleteIdentity({
|
||||||
identityId: id,
|
identityId: id,
|
||||||
organizationId: orgId
|
orgId
|
||||||
});
|
});
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
@@ -100,7 +100,7 @@ const Page = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<IdentityModal popUp={popUp} handlePopUpToggle={handlePopUpToggle} />
|
<OrgIdentityModal popUp={popUp} handlePopUpToggle={handlePopUpToggle} />
|
||||||
<IdentityAuthMethodModal
|
<IdentityAuthMethodModal
|
||||||
popUp={popUp}
|
popUp={popUp}
|
||||||
handlePopUpOpen={handlePopUpOpen}
|
handlePopUpOpen={handlePopUpOpen}
|
||||||
|
|||||||
+6
-2
@@ -4,7 +4,11 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|||||||
import { OrgPermissionCan } from "@app/components/permissions";
|
import { OrgPermissionCan } from "@app/components/permissions";
|
||||||
import { Button, Tooltip } from "@app/components/v2";
|
import { Button, Tooltip } from "@app/components/v2";
|
||||||
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/context";
|
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/context";
|
||||||
import { IdentityAuthMethod, identityAuthToNameMap, useGetIdentityById } from "@app/hooks/api";
|
import {
|
||||||
|
IdentityAuthMethod,
|
||||||
|
identityAuthToNameMap,
|
||||||
|
useGetOrgIdentityMembershipById
|
||||||
|
} from "@app/hooks/api";
|
||||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -16,7 +20,7 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const IdentityAuthenticationSection = ({ identityId, handlePopUpOpen }: Props) => {
|
export const IdentityAuthenticationSection = ({ identityId, handlePopUpOpen }: Props) => {
|
||||||
const { data, refetch } = useGetIdentityById(identityId);
|
const { data, refetch } = useGetOrgIdentityMembershipById(identityId);
|
||||||
|
|
||||||
return data ? (
|
return data ? (
|
||||||
<div className="mt-4 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
<div className="mt-4 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||||
|
|||||||
+3
-3
@@ -7,9 +7,9 @@ import { Button, IconButton, Tooltip } from "@app/components/v2";
|
|||||||
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/context";
|
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/context";
|
||||||
import { useTimedReset } from "@app/hooks";
|
import { useTimedReset } from "@app/hooks";
|
||||||
import {
|
import {
|
||||||
useGetIdentityById,
|
|
||||||
useGetIdentityUniversalAuth,
|
useGetIdentityUniversalAuth,
|
||||||
useGetIdentityUniversalAuthClientSecrets
|
useGetIdentityUniversalAuthClientSecrets,
|
||||||
|
useGetOrgIdentityMembershipById
|
||||||
} from "@app/hooks/api";
|
} from "@app/hooks/api";
|
||||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ export const IdentityClientSecrets = ({ identityId, handlePopUpOpen }: Props) =>
|
|||||||
initialState: "Copy Client ID to clipboard"
|
initialState: "Copy Client ID to clipboard"
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data } = useGetIdentityById(identityId);
|
const { data } = useGetOrgIdentityMembershipById(identityId);
|
||||||
const { data: identityUniversalAuth } = useGetIdentityUniversalAuth(identityId);
|
const { data: identityUniversalAuth } = useGetIdentityUniversalAuth(identityId);
|
||||||
const { data: clientSecrets } = useGetIdentityUniversalAuthClientSecrets(identityId);
|
const { data: clientSecrets } = useGetIdentityUniversalAuthClientSecrets(identityId);
|
||||||
return (
|
return (
|
||||||
|
|||||||
+2
-2
@@ -11,7 +11,7 @@ import {
|
|||||||
IconButton,
|
IconButton,
|
||||||
Tooltip
|
Tooltip
|
||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
import { useGetIdentityById, useGetIdentityTokensTokenAuth } from "@app/hooks/api";
|
import { useGetIdentityTokensTokenAuth, useGetOrgIdentityMembershipById } from "@app/hooks/api";
|
||||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -23,7 +23,7 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const IdentityTokens = ({ identityId, handlePopUpOpen }: Props) => {
|
export const IdentityTokens = ({ identityId, handlePopUpOpen }: Props) => {
|
||||||
const { data } = useGetIdentityById(identityId);
|
const { data } = useGetOrgIdentityMembershipById(identityId);
|
||||||
const { data: tokens } = useGetIdentityTokensTokenAuth(identityId);
|
const { data: tokens } = useGetIdentityTokensTokenAuth(identityId);
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
+2
-2
@@ -23,7 +23,7 @@ import {
|
|||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
import { OrgPermissionIdentityActions, OrgPermissionSubjects, useOrganization } from "@app/context";
|
import { OrgPermissionIdentityActions, OrgPermissionSubjects, useOrganization } from "@app/context";
|
||||||
import { useTimedReset } from "@app/hooks";
|
import { useTimedReset } from "@app/hooks";
|
||||||
import { identityAuthToNameMap, useGetIdentityById } from "@app/hooks/api";
|
import { identityAuthToNameMap, useGetOrgIdentityMembershipById } from "@app/hooks/api";
|
||||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@@ -41,7 +41,7 @@ export const IdentityDetailsSection = ({ identityId, handlePopUpOpen, isOrgIdent
|
|||||||
});
|
});
|
||||||
const { isSubOrganization } = useOrganization();
|
const { isSubOrganization } = useOrganization();
|
||||||
|
|
||||||
const { data } = useGetIdentityById(identityId);
|
const { data } = useGetOrgIdentityMembershipById(identityId);
|
||||||
return data ? (
|
return data ? (
|
||||||
<div className="rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
<div className="rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||||
<div className="flex items-center justify-between border-b border-mineshaft-400 pb-4">
|
<div className="flex items-center justify-between border-b border-mineshaft-400 pb-4">
|
||||||
|
|||||||
+2
-2
@@ -14,7 +14,7 @@ import {
|
|||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
import { useOrganization } from "@app/context";
|
import { useOrganization } from "@app/context";
|
||||||
import {
|
import {
|
||||||
useAddIdentityToWorkspace,
|
useCreateProjectIdentityMembership,
|
||||||
useGetIdentityProjectMemberships,
|
useGetIdentityProjectMemberships,
|
||||||
useGetProjectRoles,
|
useGetProjectRoles,
|
||||||
useGetUserProjects,
|
useGetUserProjects,
|
||||||
@@ -45,7 +45,7 @@ type Props = {
|
|||||||
const Content = ({ identityId, handlePopUpToggle }: Omit<Props, "popUp">) => {
|
const Content = ({ identityId, handlePopUpToggle }: Omit<Props, "popUp">) => {
|
||||||
const { currentOrg } = useOrganization();
|
const { currentOrg } = useOrganization();
|
||||||
const { data: workspaces = [] } = useGetUserProjects();
|
const { data: workspaces = [] } = useGetUserProjects();
|
||||||
const { mutateAsync: addIdentityToWorkspace } = useAddIdentityToWorkspace();
|
const { mutateAsync: addIdentityToWorkspace } = useCreateProjectIdentityMembership();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
|
|||||||
+2
-2
@@ -9,7 +9,7 @@ import { IconButton, Td, Tooltip, Tr } from "@app/components/v2";
|
|||||||
import { getProjectBaseURL } from "@app/helpers/project";
|
import { getProjectBaseURL } from "@app/helpers/project";
|
||||||
import { formatProjectRoleName } from "@app/helpers/roles";
|
import { formatProjectRoleName } from "@app/helpers/roles";
|
||||||
import { useGetUserProjects } from "@app/hooks/api";
|
import { useGetUserProjects } from "@app/hooks/api";
|
||||||
import { IdentityMembership } from "@app/hooks/api/identities/types";
|
import { IdentityProjectMembership } from "@app/hooks/api/identities/types";
|
||||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||||
|
|
||||||
export enum TabSections {
|
export enum TabSections {
|
||||||
@@ -20,7 +20,7 @@ export enum TabSections {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
membership: IdentityMembership;
|
membership: IdentityProjectMembership;
|
||||||
handlePopUpOpen: (
|
handlePopUpOpen: (
|
||||||
popUpName: keyof UsePopUpState<["removeIdentityFromProject"]>,
|
popUpName: keyof UsePopUpState<["removeIdentityFromProject"]>,
|
||||||
data?: object
|
data?: object
|
||||||
|
|||||||
+2
-2
@@ -3,7 +3,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
import { DeleteActionModal, IconButton } from "@app/components/v2";
|
import { DeleteActionModal, IconButton } from "@app/components/v2";
|
||||||
import { useDeleteIdentityFromWorkspace } from "@app/hooks/api";
|
import { useDeleteProjectIdentityMembership } from "@app/hooks/api";
|
||||||
import { usePopUp } from "@app/hooks/usePopUp";
|
import { usePopUp } from "@app/hooks/usePopUp";
|
||||||
|
|
||||||
import { IdentityAddToProjectModal } from "./IdentityAddToProjectModal";
|
import { IdentityAddToProjectModal } from "./IdentityAddToProjectModal";
|
||||||
@@ -14,7 +14,7 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const IdentityProjectsSection = ({ identityId }: Props) => {
|
export const IdentityProjectsSection = ({ identityId }: Props) => {
|
||||||
const { mutateAsync: deleteMutateAsync } = useDeleteIdentityFromWorkspace();
|
const { mutateAsync: deleteMutateAsync } = useDeleteProjectIdentityMembership();
|
||||||
|
|
||||||
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
|
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
|
||||||
"addIdentityToProject",
|
"addIdentityToProject",
|
||||||
|
|||||||
+27
-6
@@ -1,11 +1,18 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
import { subject } from "@casl/ability";
|
||||||
import { UseMutationResult } from "@tanstack/react-query";
|
import { UseMutationResult } from "@tanstack/react-query";
|
||||||
|
import { useParams } from "@tanstack/react-router";
|
||||||
import ms from "ms";
|
import ms from "ms";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
import { OrgPermissionCan } from "@app/components/permissions";
|
import { VariablePermissionCan } from "@app/components/permissions";
|
||||||
import { Button } from "@app/components/v2";
|
import { Button } from "@app/components/v2";
|
||||||
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/context";
|
import {
|
||||||
|
OrgPermissionIdentityActions,
|
||||||
|
OrgPermissionSubjects,
|
||||||
|
ProjectPermissionIdentityActions,
|
||||||
|
ProjectPermissionSub
|
||||||
|
} from "@app/context";
|
||||||
|
|
||||||
import { IdentityAuthFieldDisplay } from "./IdentityAuthFieldDisplay";
|
import { IdentityAuthFieldDisplay } from "./IdentityAuthFieldDisplay";
|
||||||
|
|
||||||
@@ -31,7 +38,11 @@ export const LockoutFields = ({
|
|||||||
|
|
||||||
const [lockedOutState, setLockedOutState] = useState(lockedOut);
|
const [lockedOutState, setLockedOutState] = useState(lockedOut);
|
||||||
|
|
||||||
const clearLockouts = async () => {
|
const { projectId } = useParams({
|
||||||
|
strict: false
|
||||||
|
});
|
||||||
|
|
||||||
|
async function clearLockouts() {
|
||||||
const deleted = await mutateAsync({ identityId });
|
const deleted = await mutateAsync({ identityId });
|
||||||
createNotification({
|
createNotification({
|
||||||
text: `Successfully cleared ${deleted} lockout${deleted === 1 ? "" : "s"}`,
|
text: `Successfully cleared ${deleted} lockout${deleted === 1 ? "" : "s"}`,
|
||||||
@@ -39,13 +50,23 @@ export const LockoutFields = ({
|
|||||||
});
|
});
|
||||||
setLockedOutState(false);
|
setLockedOutState(false);
|
||||||
onResetAllLockouts();
|
onResetAllLockouts();
|
||||||
};
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="col-span-2 mt-3 flex justify-between border-b border-mineshaft-500 pb-2">
|
<div className="col-span-2 mt-3 flex justify-between border-b border-mineshaft-500 pb-2">
|
||||||
<span className="text-bunker-300">Lockout Options</span>
|
<span className="text-bunker-300">Lockout Options</span>
|
||||||
<OrgPermissionCan I={OrgPermissionIdentityActions.Edit} a={OrgPermissionSubjects.Identity}>
|
<VariablePermissionCan
|
||||||
|
type={projectId ? "project" : "org"}
|
||||||
|
I={projectId ? ProjectPermissionIdentityActions.Edit : OrgPermissionIdentityActions.Edit}
|
||||||
|
a={
|
||||||
|
projectId
|
||||||
|
? subject(ProjectPermissionSub.Identity, {
|
||||||
|
identityId
|
||||||
|
})
|
||||||
|
: OrgPermissionSubjects.Identity
|
||||||
|
}
|
||||||
|
>
|
||||||
{(isAllowed) => (
|
{(isAllowed) => (
|
||||||
<Button
|
<Button
|
||||||
isDisabled={!isAllowed || !lockedOutState || isPending}
|
isDisabled={!isAllowed || !lockedOutState || isPending}
|
||||||
@@ -57,7 +78,7 @@ export const LockoutFields = ({
|
|||||||
Reset All Lockouts
|
Reset All Lockouts
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</OrgPermissionCan>
|
</VariablePermissionCan>
|
||||||
</div>
|
</div>
|
||||||
<IdentityAuthFieldDisplay label="Lockout Threshold">
|
<IdentityAuthFieldDisplay label="Lockout Threshold">
|
||||||
{data.lockoutThreshold}
|
{data.lockoutThreshold}
|
||||||
|
|||||||
+55
-12
@@ -1,10 +1,12 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
import { subject } from "@casl/ability";
|
||||||
import { faBan, faEdit, faKey, faPlus } from "@fortawesome/free-solid-svg-icons";
|
import { faBan, faEdit, faKey, faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
import { useParams } from "@tanstack/react-router";
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
import { OrgPermissionCan } from "@app/components/permissions";
|
import { VariablePermissionCan } from "@app/components/permissions";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
DeleteActionModal,
|
DeleteActionModal,
|
||||||
@@ -20,7 +22,12 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
Tr
|
Tr
|
||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/context";
|
import {
|
||||||
|
OrgPermissionIdentityActions,
|
||||||
|
OrgPermissionSubjects,
|
||||||
|
ProjectPermissionIdentityActions,
|
||||||
|
ProjectPermissionSub
|
||||||
|
} from "@app/context";
|
||||||
import { usePopUp } from "@app/hooks";
|
import { usePopUp } from "@app/hooks";
|
||||||
import { useRevokeIdentityTokenAuthToken } from "@app/hooks/api";
|
import { useRevokeIdentityTokenAuthToken } from "@app/hooks/api";
|
||||||
import { IdentityAccessToken } from "@app/hooks/api/identities/types";
|
import { IdentityAccessToken } from "@app/hooks/api/identities/types";
|
||||||
@@ -37,6 +44,10 @@ export const IdentityTokenAuthTokensTable = ({ tokens, identityId }: Props) => {
|
|||||||
"revokeToken"
|
"revokeToken"
|
||||||
] as const);
|
] as const);
|
||||||
|
|
||||||
|
const { projectId } = useParams({
|
||||||
|
strict: false
|
||||||
|
});
|
||||||
|
|
||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const [perPage, setPerPage] = useState(5);
|
const [perPage, setPerPage] = useState(5);
|
||||||
|
|
||||||
@@ -68,7 +79,17 @@ export const IdentityTokenAuthTokensTable = ({ tokens, identityId }: Props) => {
|
|||||||
<div className="col-span-2 mt-3">
|
<div className="col-span-2 mt-3">
|
||||||
<div className="flex items-end justify-between border-b border-mineshaft-500 pb-2">
|
<div className="flex items-end justify-between border-b border-mineshaft-500 pb-2">
|
||||||
<span className="text-bunker-300">Access Tokens</span>
|
<span className="text-bunker-300">Access Tokens</span>
|
||||||
<OrgPermissionCan I={OrgPermissionIdentityActions.Edit} a={OrgPermissionSubjects.Identity}>
|
<VariablePermissionCan
|
||||||
|
type={projectId ? "project" : "org"}
|
||||||
|
I={projectId ? ProjectPermissionIdentityActions.Edit : OrgPermissionIdentityActions.Edit}
|
||||||
|
a={
|
||||||
|
projectId
|
||||||
|
? subject(ProjectPermissionSub.Identity, {
|
||||||
|
identityId
|
||||||
|
})
|
||||||
|
: OrgPermissionSubjects.Identity
|
||||||
|
}
|
||||||
|
>
|
||||||
{(isAllowed) => (
|
{(isAllowed) => (
|
||||||
<Button
|
<Button
|
||||||
size="xs"
|
size="xs"
|
||||||
@@ -84,7 +105,7 @@ export const IdentityTokenAuthTokensTable = ({ tokens, identityId }: Props) => {
|
|||||||
Add Token
|
Add Token
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</OrgPermissionCan>
|
</VariablePermissionCan>
|
||||||
</div>
|
</div>
|
||||||
<TableContainer className="mt-4 rounded-none border-none">
|
<TableContainer className="mt-4 rounded-none border-none">
|
||||||
<Table>
|
<Table>
|
||||||
@@ -132,9 +153,20 @@ export const IdentityTokenAuthTokensTable = ({ tokens, identityId }: Props) => {
|
|||||||
</Td>
|
</Td>
|
||||||
<Td>
|
<Td>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<OrgPermissionCan
|
<VariablePermissionCan
|
||||||
I={OrgPermissionIdentityActions.Edit}
|
type={projectId ? "project" : "org"}
|
||||||
a={OrgPermissionSubjects.Identity}
|
I={
|
||||||
|
projectId
|
||||||
|
? ProjectPermissionIdentityActions.Edit
|
||||||
|
: OrgPermissionIdentityActions.Edit
|
||||||
|
}
|
||||||
|
a={
|
||||||
|
projectId
|
||||||
|
? subject(ProjectPermissionSub.Identity, {
|
||||||
|
identityId
|
||||||
|
})
|
||||||
|
: OrgPermissionSubjects.Identity
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{(isAllowed) => (
|
{(isAllowed) => (
|
||||||
<Tooltip content={isAllowed ? "Edit Token" : "Access Restricted"}>
|
<Tooltip content={isAllowed ? "Edit Token" : "Access Restricted"}>
|
||||||
@@ -155,11 +187,22 @@ export const IdentityTokenAuthTokensTable = ({ tokens, identityId }: Props) => {
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
</OrgPermissionCan>
|
</VariablePermissionCan>
|
||||||
{!isAccessTokenRevoked && (
|
{!isAccessTokenRevoked && (
|
||||||
<OrgPermissionCan
|
<VariablePermissionCan
|
||||||
I={OrgPermissionIdentityActions.Edit}
|
type={projectId ? "project" : "org"}
|
||||||
a={OrgPermissionSubjects.Identity}
|
I={
|
||||||
|
projectId
|
||||||
|
? ProjectPermissionIdentityActions.Edit
|
||||||
|
: OrgPermissionIdentityActions.Edit
|
||||||
|
}
|
||||||
|
a={
|
||||||
|
projectId
|
||||||
|
? subject(ProjectPermissionSub.Identity, {
|
||||||
|
identityId
|
||||||
|
})
|
||||||
|
: OrgPermissionSubjects.Identity
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{(isAllowed) => (
|
{(isAllowed) => (
|
||||||
<Tooltip content={isAllowed ? "Revoke Token" : "Access Restricted"}>
|
<Tooltip content={isAllowed ? "Revoke Token" : "Access Restricted"}>
|
||||||
@@ -181,7 +224,7 @@ export const IdentityTokenAuthTokensTable = ({ tokens, identityId }: Props) => {
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
</OrgPermissionCan>
|
</VariablePermissionCan>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Td>
|
</Td>
|
||||||
|
|||||||
+40
-8
@@ -1,10 +1,12 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
import { subject } from "@casl/ability";
|
||||||
import { faKey, faPlus, faTrash } from "@fortawesome/free-solid-svg-icons";
|
import { faKey, faPlus, faTrash } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
import { useParams } from "@tanstack/react-router";
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
import { OrgPermissionCan } from "@app/components/permissions";
|
import { VariablePermissionCan } from "@app/components/permissions";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
DeleteActionModal,
|
DeleteActionModal,
|
||||||
@@ -20,7 +22,12 @@ import {
|
|||||||
Tooltip,
|
Tooltip,
|
||||||
Tr
|
Tr
|
||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/context";
|
import {
|
||||||
|
OrgPermissionIdentityActions,
|
||||||
|
OrgPermissionSubjects,
|
||||||
|
ProjectPermissionIdentityActions,
|
||||||
|
ProjectPermissionSub
|
||||||
|
} from "@app/context";
|
||||||
import { usePopUp } from "@app/hooks";
|
import { usePopUp } from "@app/hooks";
|
||||||
import { useRevokeIdentityUniversalAuthClientSecret } from "@app/hooks/api";
|
import { useRevokeIdentityUniversalAuthClientSecret } from "@app/hooks/api";
|
||||||
import { ClientSecretData } from "@app/hooks/api/identities/types";
|
import { ClientSecretData } from "@app/hooks/api/identities/types";
|
||||||
@@ -37,6 +44,10 @@ export const IdentityUniversalAuthClientSecretsTable = ({ clientSecrets, identit
|
|||||||
"clientSecret"
|
"clientSecret"
|
||||||
] as const);
|
] as const);
|
||||||
|
|
||||||
|
const { projectId } = useParams({
|
||||||
|
strict: false
|
||||||
|
});
|
||||||
|
|
||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const [perPage, setPerPage] = useState(5);
|
const [perPage, setPerPage] = useState(5);
|
||||||
|
|
||||||
@@ -60,7 +71,17 @@ export const IdentityUniversalAuthClientSecretsTable = ({ clientSecrets, identit
|
|||||||
<div className="col-span-2">
|
<div className="col-span-2">
|
||||||
<div className="flex items-end justify-between border-b border-mineshaft-500 pb-2">
|
<div className="flex items-end justify-between border-b border-mineshaft-500 pb-2">
|
||||||
<span className="text-bunker-300">Client Secrets</span>
|
<span className="text-bunker-300">Client Secrets</span>
|
||||||
<OrgPermissionCan I={OrgPermissionIdentityActions.Edit} a={OrgPermissionSubjects.Identity}>
|
<VariablePermissionCan
|
||||||
|
type={projectId ? "project" : "org"}
|
||||||
|
I={projectId ? ProjectPermissionIdentityActions.Edit : OrgPermissionIdentityActions.Edit}
|
||||||
|
a={
|
||||||
|
projectId
|
||||||
|
? subject(ProjectPermissionSub.Identity, {
|
||||||
|
identityId
|
||||||
|
})
|
||||||
|
: OrgPermissionSubjects.Identity
|
||||||
|
}
|
||||||
|
>
|
||||||
{(isAllowed) => (
|
{(isAllowed) => (
|
||||||
<Button
|
<Button
|
||||||
isDisabled={!isAllowed}
|
isDisabled={!isAllowed}
|
||||||
@@ -76,7 +97,7 @@ export const IdentityUniversalAuthClientSecretsTable = ({ clientSecrets, identit
|
|||||||
Add Client Secret
|
Add Client Secret
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</OrgPermissionCan>
|
</VariablePermissionCan>
|
||||||
</div>
|
</div>
|
||||||
<TableContainer className="mt-4 rounded-none border-none">
|
<TableContainer className="mt-4 rounded-none border-none">
|
||||||
<Table>
|
<Table>
|
||||||
@@ -120,9 +141,20 @@ export const IdentityUniversalAuthClientSecretsTable = ({ clientSecrets, identit
|
|||||||
{expiresAt ? format(expiresAt, "yyyy-MM-dd") : "-"}
|
{expiresAt ? format(expiresAt, "yyyy-MM-dd") : "-"}
|
||||||
</Td>
|
</Td>
|
||||||
<Td>
|
<Td>
|
||||||
<OrgPermissionCan
|
<VariablePermissionCan
|
||||||
I={OrgPermissionIdentityActions.Edit}
|
type={projectId ? "project" : "org"}
|
||||||
a={OrgPermissionSubjects.Identity}
|
I={
|
||||||
|
projectId
|
||||||
|
? ProjectPermissionIdentityActions.Edit
|
||||||
|
: OrgPermissionIdentityActions.Edit
|
||||||
|
}
|
||||||
|
a={
|
||||||
|
projectId
|
||||||
|
? subject(ProjectPermissionSub.Identity, {
|
||||||
|
identityId
|
||||||
|
})
|
||||||
|
: OrgPermissionSubjects.Identity
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{(isAllowed) => (
|
{(isAllowed) => (
|
||||||
<Tooltip content={isAllowed ? "Delete Secret" : "Access Restricted"}>
|
<Tooltip content={isAllowed ? "Delete Secret" : "Access Restricted"}>
|
||||||
@@ -143,7 +175,7 @@ export const IdentityUniversalAuthClientSecretsTable = ({ clientSecrets, identit
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
</OrgPermissionCan>
|
</VariablePermissionCan>
|
||||||
</Td>
|
</Td>
|
||||||
</Tr>
|
</Tr>
|
||||||
);
|
);
|
||||||
|
|||||||
+1
@@ -49,6 +49,7 @@ export const ViewIdentityAliCloudAuthContent = ({
|
|||||||
<ViewIdentityContentWrapper
|
<ViewIdentityContentWrapper
|
||||||
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
|
identityId={identityId}
|
||||||
>
|
>
|
||||||
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
||||||
{data.accessTokenTTL}
|
{data.accessTokenTTL}
|
||||||
|
|||||||
+11
-4
@@ -1,3 +1,5 @@
|
|||||||
|
import { useParams } from "@tanstack/react-router";
|
||||||
|
|
||||||
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
|
import { UpgradePlanModal } from "@app/components/license/UpgradePlanModal";
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
import { DeleteActionModal, Modal, ModalContent } from "@app/components/v2";
|
import { DeleteActionModal, Modal, ModalContent } from "@app/components/v2";
|
||||||
@@ -46,8 +48,7 @@ type Props = {
|
|||||||
|
|
||||||
type TRevokeOptions = {
|
type TRevokeOptions = {
|
||||||
identityId: string;
|
identityId: string;
|
||||||
organizationId: string;
|
} & ({ projectId: string } | { organizationId: string });
|
||||||
};
|
|
||||||
|
|
||||||
export const Content = ({
|
export const Content = ({
|
||||||
identityId,
|
identityId,
|
||||||
@@ -61,7 +62,9 @@ export const Content = ({
|
|||||||
>) => {
|
>) => {
|
||||||
const { currentOrg } = useOrganization();
|
const { currentOrg } = useOrganization();
|
||||||
const orgId = currentOrg?.id || "";
|
const orgId = currentOrg?.id || "";
|
||||||
|
const { projectId } = useParams({
|
||||||
|
strict: false
|
||||||
|
});
|
||||||
const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp([
|
const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp([
|
||||||
"revokeAuthMethod",
|
"revokeAuthMethod",
|
||||||
"upgradePlan",
|
"upgradePlan",
|
||||||
@@ -142,7 +145,11 @@ export const Content = ({
|
|||||||
const handleDeleteAuthMethod = async () => {
|
const handleDeleteAuthMethod = async () => {
|
||||||
await revokeMethod({
|
await revokeMethod({
|
||||||
identityId,
|
identityId,
|
||||||
organizationId: orgId
|
...(projectId
|
||||||
|
? { projectId }
|
||||||
|
: {
|
||||||
|
organizationId: orgId
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
|
|||||||
+1
@@ -46,6 +46,7 @@ export const ViewIdentityAwsAuthContent = ({
|
|||||||
<ViewIdentityContentWrapper
|
<ViewIdentityContentWrapper
|
||||||
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
|
identityId={identityId}
|
||||||
>
|
>
|
||||||
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
||||||
{data.accessTokenTTL}
|
{data.accessTokenTTL}
|
||||||
|
|||||||
+1
@@ -46,6 +46,7 @@ export const ViewIdentityAzureAuthContent = ({
|
|||||||
<ViewIdentityContentWrapper
|
<ViewIdentityContentWrapper
|
||||||
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
|
identityId={identityId}
|
||||||
>
|
>
|
||||||
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
||||||
{data.accessTokenTTL}
|
{data.accessTokenTTL}
|
||||||
|
|||||||
+45
-11
@@ -1,8 +1,10 @@
|
|||||||
import { ReactNode } from "react";
|
import { ReactNode } from "react";
|
||||||
|
import { subject } from "@casl/ability";
|
||||||
import { faChevronDown, faEdit, faTrash } from "@fortawesome/free-solid-svg-icons";
|
import { faChevronDown, faEdit, faTrash } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
import { useParams } from "@tanstack/react-router";
|
||||||
|
|
||||||
import { OrgPermissionCan } from "@app/components/permissions";
|
import { VariablePermissionCan } from "@app/components/permissions";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
@@ -10,15 +12,25 @@ import {
|
|||||||
DropdownMenuItem,
|
DropdownMenuItem,
|
||||||
DropdownMenuTrigger
|
DropdownMenuTrigger
|
||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/context";
|
import {
|
||||||
|
OrgPermissionIdentityActions,
|
||||||
|
OrgPermissionSubjects,
|
||||||
|
ProjectPermissionIdentityActions,
|
||||||
|
ProjectPermissionSub
|
||||||
|
} from "@app/context";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
onEdit: VoidFunction;
|
onEdit: VoidFunction;
|
||||||
onDelete: VoidFunction;
|
onDelete: VoidFunction;
|
||||||
|
identityId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ViewIdentityContentWrapper = ({ children, onDelete, onEdit }: Props) => {
|
export const ViewIdentityContentWrapper = ({ children, onDelete, onEdit, identityId }: Props) => {
|
||||||
|
const { projectId } = useParams({
|
||||||
|
strict: false
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
<div>
|
<div>
|
||||||
@@ -36,9 +48,20 @@ export const ViewIdentityContentWrapper = ({ children, onDelete, onEdit }: Props
|
|||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent className="mt-3 min-w-[120px]" align="end">
|
<DropdownMenuContent className="mt-3 min-w-[120px]" align="end">
|
||||||
<OrgPermissionCan
|
<VariablePermissionCan
|
||||||
I={OrgPermissionIdentityActions.Edit}
|
type={projectId ? "project" : "org"}
|
||||||
a={OrgPermissionSubjects.Identity}
|
I={
|
||||||
|
projectId
|
||||||
|
? ProjectPermissionIdentityActions.Edit
|
||||||
|
: OrgPermissionIdentityActions.Edit
|
||||||
|
}
|
||||||
|
a={
|
||||||
|
projectId
|
||||||
|
? subject(ProjectPermissionSub.Identity, {
|
||||||
|
identityId
|
||||||
|
})
|
||||||
|
: OrgPermissionSubjects.Identity
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{(isAllowed) => (
|
{(isAllowed) => (
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
@@ -49,10 +72,21 @@ export const ViewIdentityContentWrapper = ({ children, onDelete, onEdit }: Props
|
|||||||
Edit
|
Edit
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
)}
|
)}
|
||||||
</OrgPermissionCan>
|
</VariablePermissionCan>
|
||||||
<OrgPermissionCan
|
<VariablePermissionCan
|
||||||
I={OrgPermissionIdentityActions.Delete}
|
type={projectId ? "project" : "org"}
|
||||||
a={OrgPermissionSubjects.Identity}
|
I={
|
||||||
|
projectId
|
||||||
|
? ProjectPermissionIdentityActions.Delete
|
||||||
|
: OrgPermissionIdentityActions.Delete
|
||||||
|
}
|
||||||
|
a={
|
||||||
|
projectId
|
||||||
|
? subject(ProjectPermissionSub.Identity, {
|
||||||
|
identityId
|
||||||
|
})
|
||||||
|
: OrgPermissionSubjects.Identity
|
||||||
|
}
|
||||||
>
|
>
|
||||||
{(isAllowed) => (
|
{(isAllowed) => (
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
@@ -63,7 +97,7 @@ export const ViewIdentityContentWrapper = ({ children, onDelete, onEdit }: Props
|
|||||||
Delete
|
Delete
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
)}
|
)}
|
||||||
</OrgPermissionCan>
|
</VariablePermissionCan>
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+1
@@ -46,6 +46,7 @@ export const ViewIdentityGcpAuthContent = ({
|
|||||||
<ViewIdentityContentWrapper
|
<ViewIdentityContentWrapper
|
||||||
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
|
identityId={identityId}
|
||||||
>
|
>
|
||||||
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
||||||
{data.accessTokenTTL}
|
{data.accessTokenTTL}
|
||||||
|
|||||||
+1
@@ -49,6 +49,7 @@ export const ViewIdentityJwtAuthContent = ({
|
|||||||
<ViewIdentityContentWrapper
|
<ViewIdentityContentWrapper
|
||||||
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
|
identityId={identityId}
|
||||||
>
|
>
|
||||||
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
||||||
{data.accessTokenTTL}
|
{data.accessTokenTTL}
|
||||||
|
|||||||
+1
@@ -59,6 +59,7 @@ export const ViewIdentityKubernetesAuthContent = ({
|
|||||||
<ViewIdentityContentWrapper
|
<ViewIdentityContentWrapper
|
||||||
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
|
identityId={identityId}
|
||||||
>
|
>
|
||||||
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
||||||
{data.accessTokenTTL}
|
{data.accessTokenTTL}
|
||||||
|
|||||||
+1
@@ -52,6 +52,7 @@ export const ViewIdentityLdapAuthContent = ({
|
|||||||
<ViewIdentityContentWrapper
|
<ViewIdentityContentWrapper
|
||||||
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
|
identityId={identityId}
|
||||||
>
|
>
|
||||||
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
||||||
{data.accessTokenTTL}
|
{data.accessTokenTTL}
|
||||||
|
|||||||
+1
@@ -46,6 +46,7 @@ export const ViewIdentityOciAuthContent = ({
|
|||||||
<ViewIdentityContentWrapper
|
<ViewIdentityContentWrapper
|
||||||
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
|
identityId={identityId}
|
||||||
>
|
>
|
||||||
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
||||||
{data.accessTokenTTL}
|
{data.accessTokenTTL}
|
||||||
|
|||||||
+1
@@ -48,6 +48,7 @@ export const ViewIdentityOidcAuthContent = ({
|
|||||||
<ViewIdentityContentWrapper
|
<ViewIdentityContentWrapper
|
||||||
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
|
identityId={identityId}
|
||||||
>
|
>
|
||||||
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
||||||
{data.accessTokenTTL}
|
{data.accessTokenTTL}
|
||||||
|
|||||||
+1
@@ -51,6 +51,7 @@ export const ViewIdentityTlsCertAuthContent = ({
|
|||||||
<ViewIdentityContentWrapper
|
<ViewIdentityContentWrapper
|
||||||
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
|
identityId={identityId}
|
||||||
>
|
>
|
||||||
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
||||||
{data.accessTokenTTL}
|
{data.accessTokenTTL}
|
||||||
|
|||||||
+1
@@ -49,6 +49,7 @@ export const ViewIdentityTokenAuthContent = ({
|
|||||||
<ViewIdentityContentWrapper
|
<ViewIdentityContentWrapper
|
||||||
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
onEdit={() => handlePopUpOpen("identityAuthMethod")}
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
|
identityId={identityId}
|
||||||
>
|
>
|
||||||
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
<IdentityAuthFieldDisplay label="Access Token TTL (seconds)">
|
||||||
{data.accessTokenTTL}
|
{data.accessTokenTTL}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user