feat: fixing more and more ts

This commit is contained in:
=
2025-10-10 00:09:46 +05:30
parent 5a8bad3556
commit fd98465dec
47 changed files with 1369 additions and 1161 deletions
+2 -9
View File
@@ -20,8 +20,6 @@ import { TGatewayV2ServiceFactory } from "@app/ee/services/gateway-v2/gateway-v2
import { TGithubOrgSyncServiceFactory } from "@app/ee/services/github-org-sync/github-org-sync-service"; import { TGithubOrgSyncServiceFactory } from "@app/ee/services/github-org-sync/github-org-sync-service";
import { TGroupServiceFactory } from "@app/ee/services/group/group-service"; import { TGroupServiceFactory } from "@app/ee/services/group/group-service";
import { TIdentityAuthTemplateServiceFactory } from "@app/ee/services/identity-auth-template"; import { TIdentityAuthTemplateServiceFactory } from "@app/ee/services/identity-auth-template";
import { TIdentityProjectAdditionalPrivilegeServiceFactory } from "@app/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service";
import { TIdentityProjectAdditionalPrivilegeV2ServiceFactory } from "@app/ee/services/identity-project-additional-privilege-v2/identity-project-additional-privilege-v2-service";
import { TKmipClientDALFactory } from "@app/ee/services/kmip/kmip-client-dal"; import { TKmipClientDALFactory } from "@app/ee/services/kmip/kmip-client-dal";
import { TKmipOperationServiceFactory } from "@app/ee/services/kmip/kmip-operation-service"; import { TKmipOperationServiceFactory } from "@app/ee/services/kmip/kmip-operation-service";
import { TKmipServiceFactory } from "@app/ee/services/kmip/kmip-service"; import { TKmipServiceFactory } from "@app/ee/services/kmip/kmip-service";
@@ -35,7 +33,6 @@ import { TPamSessionServiceFactory } from "@app/ee/services/pam-session/pam-sess
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
import { TPitServiceFactory } from "@app/ee/services/pit/pit-service"; import { TPitServiceFactory } from "@app/ee/services/pit/pit-service";
import { TProjectTemplateServiceFactory } from "@app/ee/services/project-template/project-template-types"; import { TProjectTemplateServiceFactory } from "@app/ee/services/project-template/project-template-types";
import { TProjectUserAdditionalPrivilegeServiceFactory } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-types";
import { RateLimitConfiguration, TRateLimitServiceFactory } from "@app/ee/services/rate-limit/rate-limit-types"; import { RateLimitConfiguration, TRateLimitServiceFactory } from "@app/ee/services/rate-limit/rate-limit-types";
import { TRelayServiceFactory } from "@app/ee/services/relay/relay-service"; import { TRelayServiceFactory } from "@app/ee/services/relay/relay-service";
import { TSamlConfigServiceFactory } from "@app/ee/services/saml-config/saml-config-types"; import { TSamlConfigServiceFactory } from "@app/ee/services/saml-config/saml-config-types";
@@ -53,7 +50,6 @@ import { TSshHostServiceFactory } from "@app/ee/services/ssh-host/ssh-host-servi
import { TSshHostGroupServiceFactory } from "@app/ee/services/ssh-host-group/ssh-host-group-service"; import { TSshHostGroupServiceFactory } from "@app/ee/services/ssh-host-group/ssh-host-group-service";
import { TTrustedIpServiceFactory } from "@app/ee/services/trusted-ip/trusted-ip-types"; import { TTrustedIpServiceFactory } from "@app/ee/services/trusted-ip/trusted-ip-types";
import { TAuthMode } from "@app/server/plugins/auth/inject-identity"; import { TAuthMode } from "@app/server/plugins/auth/inject-identity";
import { TAdditionalPrivilegeServiceFactory } from "@app/services/additional-privilege/additional-privilege-service";
import { TApiKeyServiceFactory } from "@app/services/api-key/api-key-service"; import { TApiKeyServiceFactory } from "@app/services/api-key/api-key-service";
import { TAppConnectionServiceFactory } from "@app/services/app-connection/app-connection-service"; import { TAppConnectionServiceFactory } from "@app/services/app-connection/app-connection-service";
import { TAuthLoginFactory } from "@app/services/auth/auth-login-service"; import { TAuthLoginFactory } from "@app/services/auth/auth-login-service";
@@ -95,7 +91,6 @@ import { TMembershipUserServiceFactory } from "@app/services/membership-user/mem
import { TMicrosoftTeamsServiceFactory } from "@app/services/microsoft-teams/microsoft-teams-service"; import { TMicrosoftTeamsServiceFactory } from "@app/services/microsoft-teams/microsoft-teams-service";
import { TNotificationServiceFactory } from "@app/services/notification/notification-service"; import { TNotificationServiceFactory } from "@app/services/notification/notification-service";
import { TOfflineUsageReportServiceFactory } from "@app/services/offline-usage-report/offline-usage-report-service"; import { TOfflineUsageReportServiceFactory } from "@app/services/offline-usage-report/offline-usage-report-service";
import { TOrgRoleServiceFactory } from "@app/services/org/org-role-service";
import { TOrgServiceFactory } from "@app/services/org/org-service"; import { TOrgServiceFactory } from "@app/services/org/org-service";
import { TOrgAdminServiceFactory } from "@app/services/org-admin/org-admin-service"; import { TOrgAdminServiceFactory } from "@app/services/org-admin/org-admin-service";
import { TPkiAlertServiceFactory } from "@app/services/pki-alert/pki-alert-service"; import { TPkiAlertServiceFactory } from "@app/services/pki-alert/pki-alert-service";
@@ -108,7 +103,6 @@ import { TProjectBotServiceFactory } from "@app/services/project-bot/project-bot
import { TProjectEnvServiceFactory } from "@app/services/project-env/project-env-service"; import { TProjectEnvServiceFactory } from "@app/services/project-env/project-env-service";
import { TProjectKeyServiceFactory } from "@app/services/project-key/project-key-service"; import { TProjectKeyServiceFactory } from "@app/services/project-key/project-key-service";
import { TProjectMembershipServiceFactory } from "@app/services/project-membership/project-membership-service"; import { TProjectMembershipServiceFactory } from "@app/services/project-membership/project-membership-service";
import { TProjectRoleServiceFactory } from "@app/services/project-role/project-role-service";
import { TReminderServiceFactory } from "@app/services/reminder/reminder-types"; import { TReminderServiceFactory } from "@app/services/reminder/reminder-types";
import { TRoleServiceFactory } from "@app/services/role/role-service"; import { TRoleServiceFactory } from "@app/services/role/role-service";
import { TSecretServiceFactory } from "@app/services/secret/secret-service"; import { TSecretServiceFactory } from "@app/services/secret/secret-service";
@@ -131,6 +125,7 @@ import { TUserEngagementServiceFactory } from "@app/services/user-engagement/use
import { TWebhookServiceFactory } from "@app/services/webhook/webhook-service"; import { TWebhookServiceFactory } from "@app/services/webhook/webhook-service";
import { TWorkflowIntegrationServiceFactory } from "@app/services/workflow-integration/workflow-integration-service"; import { TWorkflowIntegrationServiceFactory } from "@app/services/workflow-integration/workflow-integration-service";
import { TConvertorServiceFactory } from "@app/services/convertor/convertor-service"; import { TConvertorServiceFactory } from "@app/services/convertor/convertor-service";
import { TAdditionalPrivilegeServiceFactory } from "@app/services/additional-privilege/additional-privilege-service";
declare module "@fastify/request-context" { declare module "@fastify/request-context" {
interface RequestContextData { interface RequestContextData {
@@ -219,7 +214,6 @@ declare module "fastify" {
authToken: TAuthTokenServiceFactory; authToken: TAuthTokenServiceFactory;
permission: TPermissionServiceFactory; permission: TPermissionServiceFactory;
org: TOrgServiceFactory; org: TOrgServiceFactory;
orgRole: TOrgRoleServiceFactory;
oidc: TOidcConfigServiceFactory; oidc: TOidcConfigServiceFactory;
superAdmin: TSuperAdminServiceFactory; superAdmin: TSuperAdminServiceFactory;
user: TUserServiceFactory; user: TUserServiceFactory;
@@ -231,7 +225,6 @@ declare module "fastify" {
projectMembership: TProjectMembershipServiceFactory; projectMembership: TProjectMembershipServiceFactory;
projectEnv: TProjectEnvServiceFactory; projectEnv: TProjectEnvServiceFactory;
projectKey: TProjectKeyServiceFactory; projectKey: TProjectKeyServiceFactory;
projectRole: TProjectRoleServiceFactory;
secret: TSecretServiceFactory; secret: TSecretServiceFactory;
secretReplication: TSecretReplicationServiceFactory; secretReplication: TSecretReplicationServiceFactory;
secretTag: TSecretTagServiceFactory; secretTag: TSecretTagServiceFactory;
@@ -331,8 +324,8 @@ declare module "fastify" {
membershipUser: TMembershipUserServiceFactory; membershipUser: TMembershipUserServiceFactory;
membershipIdentity: TMembershipIdentityServiceFactory; membershipIdentity: TMembershipIdentityServiceFactory;
membershipGroup: TMembershipGroupServiceFactory; membershipGroup: TMembershipGroupServiceFactory;
role: TRoleServiceFactory;
additionalPrivilege: TAdditionalPrivilegeServiceFactory; additionalPrivilege: TAdditionalPrivilegeServiceFactory;
role: TRoleServiceFactory;
convertor: TConvertorServiceFactory; convertor: TConvertorServiceFactory;
}; };
// this is exclusive use for middlewares in which we need to inject data // this is exclusive use for middlewares in which we need to inject data
+8 -13
View File
@@ -277,21 +277,16 @@ export const registerOrgRoleRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT]), onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => { handler: async (req) => {
const { permissions, memberships } = await server.services.orgRole.getUserPermission( const { permissions, memberships } = await server.services.role.getUserPermission({
req.permission.id, permission: req.permission,
req.params.organizationId, scopeData: {
req.permission.authMethod, scope: AccessScope.Organization,
req.permission.orgId orgId: req.permission.orgId
); }
});
return { return {
permissions, permissions,
memberships: memberships.map((el) => ({ memberships
...el,
role: el.roles[0].customRoleSlug || el.roles[0].role,
orgId: el.scopeOrgId,
status: el.status || "",
isActive: el.isActive || true
}))
}; };
} }
}); });
@@ -337,12 +337,14 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT]), onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => { handler: async (req) => {
const { permissions, memberships, assumedPrivilegeDetails } = await server.services.projectRole.getUserPermission( const { permissions, memberships, assumedPrivilegeDetails } = await server.services.role.getUserPermission({
req.permission.id, permission: req.permission,
req.params.projectId, scopeData: {
req.permission.authMethod, scope: AccessScope.Project,
req.permission.orgId projectId: req.params.projectId,
); orgId: req.permission.orgId
}
});
return { return {
data: { data: {
+96 -164
View File
@@ -50,9 +50,6 @@ import { hsmServiceFactory } from "@app/ee/services/hsm/hsm-service";
import { HsmModule } from "@app/ee/services/hsm/hsm-types"; import { HsmModule } from "@app/ee/services/hsm/hsm-types";
import { identityAuthTemplateDALFactory } from "@app/ee/services/identity-auth-template/identity-auth-template-dal"; import { identityAuthTemplateDALFactory } from "@app/ee/services/identity-auth-template/identity-auth-template-dal";
import { identityAuthTemplateServiceFactory } from "@app/ee/services/identity-auth-template/identity-auth-template-service"; import { identityAuthTemplateServiceFactory } from "@app/ee/services/identity-auth-template/identity-auth-template-service";
import { identityProjectAdditionalPrivilegeDALFactory } from "@app/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-dal";
import { identityProjectAdditionalPrivilegeServiceFactory } from "@app/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service";
import { identityProjectAdditionalPrivilegeV2ServiceFactory } from "@app/ee/services/identity-project-additional-privilege-v2/identity-project-additional-privilege-v2-service";
import { kmipClientCertificateDALFactory } from "@app/ee/services/kmip/kmip-client-certificate-dal"; import { kmipClientCertificateDALFactory } from "@app/ee/services/kmip/kmip-client-certificate-dal";
import { kmipClientDALFactory } from "@app/ee/services/kmip/kmip-client-dal"; import { kmipClientDALFactory } from "@app/ee/services/kmip/kmip-client-dal";
import { kmipOperationServiceFactory } from "@app/ee/services/kmip/kmip-operation-service"; import { kmipOperationServiceFactory } from "@app/ee/services/kmip/kmip-operation-service";
@@ -79,8 +76,6 @@ import { permissionServiceFactory } from "@app/ee/services/permission/permission
import { pitServiceFactory } from "@app/ee/services/pit/pit-service"; import { pitServiceFactory } from "@app/ee/services/pit/pit-service";
import { projectTemplateDALFactory } from "@app/ee/services/project-template/project-template-dal"; import { projectTemplateDALFactory } from "@app/ee/services/project-template/project-template-dal";
import { projectTemplateServiceFactory } from "@app/ee/services/project-template/project-template-service"; import { projectTemplateServiceFactory } from "@app/ee/services/project-template/project-template-service";
import { projectUserAdditionalPrivilegeDALFactory } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-dal";
import { projectUserAdditionalPrivilegeServiceFactory } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-service";
import { rateLimitDALFactory } from "@app/ee/services/rate-limit/rate-limit-dal"; import { rateLimitDALFactory } from "@app/ee/services/rate-limit/rate-limit-dal";
import { rateLimitServiceFactory } from "@app/ee/services/rate-limit/rate-limit-service"; import { rateLimitServiceFactory } from "@app/ee/services/rate-limit/rate-limit-service";
import { instanceRelayConfigDalFactory } from "@app/ee/services/relay/instance-relay-config-dal"; import { instanceRelayConfigDalFactory } from "@app/ee/services/relay/instance-relay-config-dal";
@@ -189,8 +184,6 @@ import { folderCommitChangesDALFactory } from "@app/services/folder-commit-chang
import { folderTreeCheckpointDALFactory } from "@app/services/folder-tree-checkpoint/folder-tree-checkpoint-dal"; import { folderTreeCheckpointDALFactory } from "@app/services/folder-tree-checkpoint/folder-tree-checkpoint-dal";
import { folderTreeCheckpointResourcesDALFactory } from "@app/services/folder-tree-checkpoint-resources/folder-tree-checkpoint-resources-dal"; import { folderTreeCheckpointResourcesDALFactory } from "@app/services/folder-tree-checkpoint-resources/folder-tree-checkpoint-resources-dal";
import { groupProjectDALFactory } from "@app/services/group-project/group-project-dal"; import { groupProjectDALFactory } from "@app/services/group-project/group-project-dal";
import { groupProjectMembershipRoleDALFactory } from "@app/services/group-project/group-project-membership-role-dal";
import { groupProjectServiceFactory } from "@app/services/group-project/group-project-service";
import { identityDALFactory } from "@app/services/identity/identity-dal"; import { identityDALFactory } from "@app/services/identity/identity-dal";
import { identityMetadataDALFactory } from "@app/services/identity/identity-metadata-dal"; import { identityMetadataDALFactory } from "@app/services/identity/identity-metadata-dal";
import { identityOrgDALFactory } from "@app/services/identity/identity-org-dal"; import { identityOrgDALFactory } from "@app/services/identity/identity-org-dal";
@@ -216,8 +209,6 @@ import { identityOciAuthServiceFactory } from "@app/services/identity-oci-auth/i
import { identityOidcAuthDALFactory } from "@app/services/identity-oidc-auth/identity-oidc-auth-dal"; import { identityOidcAuthDALFactory } from "@app/services/identity-oidc-auth/identity-oidc-auth-dal";
import { identityOidcAuthServiceFactory } from "@app/services/identity-oidc-auth/identity-oidc-auth-service"; import { identityOidcAuthServiceFactory } from "@app/services/identity-oidc-auth/identity-oidc-auth-service";
import { identityProjectDALFactory } from "@app/services/identity-project/identity-project-dal"; import { identityProjectDALFactory } from "@app/services/identity-project/identity-project-dal";
import { identityProjectMembershipRoleDALFactory } from "@app/services/identity-project/identity-project-membership-role-dal";
import { identityProjectServiceFactory } from "@app/services/identity-project/identity-project-service";
import { identityTlsCertAuthDALFactory } from "@app/services/identity-tls-cert-auth/identity-tls-cert-auth-dal"; import { identityTlsCertAuthDALFactory } from "@app/services/identity-tls-cert-auth/identity-tls-cert-auth-dal";
import { identityTlsCertAuthServiceFactory } from "@app/services/identity-tls-cert-auth/identity-tls-cert-auth-service"; import { identityTlsCertAuthServiceFactory } from "@app/services/identity-tls-cert-auth/identity-tls-cert-auth-service";
import { identityTokenAuthDALFactory } from "@app/services/identity-token-auth/identity-token-auth-dal"; import { identityTokenAuthDALFactory } from "@app/services/identity-token-auth/identity-token-auth-dal";
@@ -252,7 +243,6 @@ import { offlineUsageReportServiceFactory } from "@app/services/offline-usage-re
import { incidentContactDALFactory } from "@app/services/org/incident-contacts-dal"; import { incidentContactDALFactory } from "@app/services/org/incident-contacts-dal";
import { orgBotDALFactory } from "@app/services/org/org-bot-dal"; import { orgBotDALFactory } from "@app/services/org/org-bot-dal";
import { orgDALFactory } from "@app/services/org/org-dal"; import { orgDALFactory } from "@app/services/org/org-dal";
import { orgRoleServiceFactory } from "@app/services/org/org-role-service";
import { orgServiceFactory } from "@app/services/org/org-service"; import { orgServiceFactory } from "@app/services/org/org-service";
import { orgAdminServiceFactory } from "@app/services/org-admin/org-admin-service"; import { orgAdminServiceFactory } from "@app/services/org-admin/org-admin-service";
import { orgMembershipDALFactory } from "@app/services/org-membership/org-membership-dal"; import { orgMembershipDALFactory } from "@app/services/org-membership/org-membership-dal";
@@ -283,9 +273,6 @@ import { projectKeyDALFactory } from "@app/services/project-key/project-key-dal"
import { projectKeyServiceFactory } from "@app/services/project-key/project-key-service"; import { projectKeyServiceFactory } from "@app/services/project-key/project-key-service";
import { projectMembershipDALFactory } from "@app/services/project-membership/project-membership-dal"; import { projectMembershipDALFactory } from "@app/services/project-membership/project-membership-dal";
import { projectMembershipServiceFactory } from "@app/services/project-membership/project-membership-service"; import { projectMembershipServiceFactory } from "@app/services/project-membership/project-membership-service";
import { projectUserMembershipRoleDALFactory } from "@app/services/project-membership/project-user-membership-role-dal";
import { projectRoleDALFactory } from "@app/services/project-role/project-role-dal";
import { projectRoleServiceFactory } from "@app/services/project-role/project-role-service";
import { reminderDALFactory } from "@app/services/reminder/reminder-dal"; import { reminderDALFactory } from "@app/services/reminder/reminder-dal";
import { dailyReminderQueueServiceFactory } from "@app/services/reminder/reminder-queue"; import { dailyReminderQueueServiceFactory } from "@app/services/reminder/reminder-queue";
import { reminderServiceFactory } from "@app/services/reminder/reminder-service"; import { reminderServiceFactory } from "@app/services/reminder/reminder-service";
@@ -353,6 +340,9 @@ import { initializeOauthConfigSync } from "./v1/sso-router";
import { registerV2Routes } from "./v2"; import { registerV2Routes } from "./v2";
import { registerV3Routes } from "./v3"; import { registerV3Routes } from "./v3";
import { registerV4Routes } from "./v4"; import { registerV4Routes } from "./v4";
import { groupProjectServiceFactory } from "@app/services/group-project/group-project-service";
import { identityProjectServiceFactory } from "@app/services/identity-project/identity-project-service";
import { convertorServiceFactory } from "@app/services/convertor/convertor-service";
const histogram = monitorEventLoopDelay({ resolution: 20 }); const histogram = monitorEventLoopDelay({ resolution: 20 });
histogram.enable(); histogram.enable();
@@ -399,9 +389,6 @@ export const registerRoutes = async (
const projectDAL = projectDALFactory(db); const projectDAL = projectDALFactory(db);
const projectSshConfigDAL = projectSshConfigDALFactory(db); const projectSshConfigDAL = projectSshConfigDALFactory(db);
const projectMembershipDAL = projectMembershipDALFactory(db); const projectMembershipDAL = projectMembershipDALFactory(db);
const projectUserAdditionalPrivilegeDAL = projectUserAdditionalPrivilegeDALFactory(db);
const projectUserMembershipRoleDAL = projectUserMembershipRoleDALFactory(db);
const projectRoleDAL = projectRoleDALFactory(db);
const projectEnvDAL = projectEnvDALFactory(db); const projectEnvDAL = projectEnvDALFactory(db);
const projectKeyDAL = projectKeyDALFactory(db); const projectKeyDAL = projectKeyDALFactory(db);
const projectBotDAL = projectBotDALFactory(db); const projectBotDAL = projectBotDALFactory(db);
@@ -433,8 +420,6 @@ export const registerRoutes = async (
const identityAccessTokenDAL = identityAccessTokenDALFactory(db); const identityAccessTokenDAL = identityAccessTokenDALFactory(db);
const identityOrgMembershipDAL = identityOrgDALFactory(db); const identityOrgMembershipDAL = identityOrgDALFactory(db);
const identityProjectDAL = identityProjectDALFactory(db); const identityProjectDAL = identityProjectDALFactory(db);
const identityProjectMembershipRoleDAL = identityProjectMembershipRoleDALFactory(db);
const identityProjectAdditionalPrivilegeDAL = identityProjectAdditionalPrivilegeDALFactory(db);
const identityAuthTemplateDAL = identityAuthTemplateDALFactory(db); const identityAuthTemplateDAL = identityAuthTemplateDALFactory(db);
const identityTokenAuthDAL = identityTokenAuthDALFactory(db); const identityTokenAuthDAL = identityTokenAuthDALFactory(db);
@@ -492,7 +477,6 @@ export const registerRoutes = async (
const gitAppOrgDAL = gitAppDALFactory(db); const gitAppOrgDAL = gitAppDALFactory(db);
const groupDAL = groupDALFactory(db); const groupDAL = groupDALFactory(db);
const groupProjectDAL = groupProjectDALFactory(db); const groupProjectDAL = groupProjectDALFactory(db);
const groupProjectMembershipRoleDAL = groupProjectMembershipRoleDALFactory(db);
const userGroupMembershipDAL = userGroupMembershipDALFactory(db); const userGroupMembershipDAL = userGroupMembershipDALFactory(db);
const secretScanningDAL = secretScanningDALFactory(db); const secretScanningDAL = secretScanningDALFactory(db);
const secretSharingDAL = secretSharingDALFactory(db); const secretSharingDAL = secretSharingDALFactory(db);
@@ -602,7 +586,10 @@ export const registerRoutes = async (
const roleService = roleServiceFactory({ const roleService = roleServiceFactory({
permissionService, permissionService,
roleDAL roleDAL,
projectDAL,
identityDAL,
userDAL
}); });
const additionalPrivilegeService = additionalPrivilegeServiceFactory({ const additionalPrivilegeService = additionalPrivilegeServiceFactory({
additionalPrivilegeDAL, additionalPrivilegeDAL,
@@ -676,13 +663,12 @@ export const registerRoutes = async (
userDAL, userDAL,
secretApprovalRequestDAL secretApprovalRequestDAL
}); });
const tokenService = tokenServiceFactory({ tokenDAL: authTokenDAL, userDAL, orgMembershipDAL }); const tokenService = tokenServiceFactory({ tokenDAL: authTokenDAL, userDAL, membershipUserDAL });
const samlService = samlConfigServiceFactory({ const samlService = samlConfigServiceFactory({
identityMetadataDAL, identityMetadataDAL,
permissionService, permissionService,
orgDAL, orgDAL,
orgMembershipDAL,
userDAL, userDAL,
userAliasDAL, userAliasDAL,
samlConfigDAL, samlConfigDAL,
@@ -695,12 +681,12 @@ export const registerRoutes = async (
licenseService, licenseService,
tokenService, tokenService,
smtpService, smtpService,
kmsService kmsService,
membershipRoleDAL
}); });
const groupService = groupServiceFactory({ const groupService = groupServiceFactory({
userDAL, userDAL,
groupDAL, groupDAL,
groupProjectDAL,
orgDAL, orgDAL,
userGroupMembershipDAL, userGroupMembershipDAL,
projectDAL, projectDAL,
@@ -708,17 +694,13 @@ export const registerRoutes = async (
projectKeyDAL, projectKeyDAL,
permissionService, permissionService,
licenseService, licenseService,
oidcConfigDAL oidcConfigDAL,
membershipGroupDAL,
membershipRoleDAL
}); });
const groupProjectService = groupProjectServiceFactory({ const groupProjectService = groupProjectServiceFactory({
groupDAL, groupDAL,
groupProjectDAL,
groupProjectMembershipRoleDAL,
userGroupMembershipDAL,
projectDAL, projectDAL,
projectKeyDAL,
projectBotDAL,
projectRoleDAL,
permissionService permissionService
}); });
@@ -763,18 +745,18 @@ export const registerRoutes = async (
userDAL, userDAL,
userAliasDAL, userAliasDAL,
orgDAL, orgDAL,
orgMembershipDAL,
projectDAL, projectDAL,
projectUserAdditionalPrivilegeDAL,
projectMembershipDAL, projectMembershipDAL,
groupDAL,
groupProjectDAL,
userGroupMembershipDAL, userGroupMembershipDAL,
projectKeyDAL, projectKeyDAL,
projectBotDAL, projectBotDAL,
permissionService, permissionService,
smtpService, smtpService,
externalGroupOrgRoleMappingDAL externalGroupOrgRoleMappingDAL,
groupDAL,
membershipGroupDAL,
membershipRoleDAL,
membershipUserDAL
}); });
const githubOrgSyncConfigService = githubOrgSyncServiceFactory({ const githubOrgSyncConfigService = githubOrgSyncServiceFactory({
@@ -791,9 +773,7 @@ export const registerRoutes = async (
ldapConfigDAL, ldapConfigDAL,
ldapGroupMapDAL, ldapGroupMapDAL,
orgDAL, orgDAL,
orgMembershipDAL,
groupDAL, groupDAL,
groupProjectDAL,
projectKeyDAL, projectKeyDAL,
projectDAL, projectDAL,
projectBotDAL, projectBotDAL,
@@ -804,7 +784,9 @@ export const registerRoutes = async (
licenseService, licenseService,
tokenService, tokenService,
smtpService, smtpService,
kmsService kmsService,
membershipGroupDAL,
membershipRoleDAL
}); });
const telemetryService = telemetryServiceFactory({ const telemetryService = telemetryServiceFactory({
@@ -826,13 +808,12 @@ export const registerRoutes = async (
const userService = userServiceFactory({ const userService = userServiceFactory({
userDAL, userDAL,
orgDAL, orgDAL,
orgMembershipDAL,
tokenService, tokenService,
permissionService, permissionService,
groupProjectDAL, groupProjectDAL,
smtpService, smtpService,
projectMembershipDAL, userAliasDAL,
userAliasDAL membershipUserDAL
}); });
const upgradePathService = upgradePathServiceFactory({ keyStore }); const upgradePathService = upgradePathServiceFactory({ keyStore });
@@ -849,9 +830,10 @@ export const registerRoutes = async (
tokenService, tokenService,
orgDAL, orgDAL,
totpService, totpService,
orgMembershipDAL,
auditLogService, auditLogService,
notificationService notificationService,
membershipRoleDAL,
membershipUserDAL
}); });
const passwordService = authPaswordServiceFactory({ const passwordService = authPaswordServiceFactory({
tokenService, tokenService,
@@ -881,14 +863,10 @@ export const registerRoutes = async (
folderDAL, folderDAL,
licenseService, licenseService,
samlConfigDAL, samlConfigDAL,
orgRoleDAL,
permissionService, permissionService,
orgDAL, orgDAL,
incidentContactDAL, incidentContactDAL,
tokenService, tokenService,
projectUserAdditionalPrivilegeDAL,
projectUserMembershipRoleDAL,
projectRoleDAL,
projectDAL, projectDAL,
projectMembershipDAL, projectMembershipDAL,
orgMembershipDAL, orgMembershipDAL,
@@ -901,7 +879,10 @@ export const registerRoutes = async (
ldapConfigDAL, ldapConfigDAL,
loginService, loginService,
projectBotService, projectBotService,
reminderService reminderService,
membershipRoleDAL,
membershipUserDAL,
roleDAL
}); });
const signupService = authSignupServiceFactory({ const signupService = authSignupServiceFactory({
tokenService, tokenService,
@@ -912,18 +893,10 @@ export const registerRoutes = async (
projectKeyDAL, projectKeyDAL,
projectDAL, projectDAL,
projectBotDAL, projectBotDAL,
groupProjectDAL,
projectMembershipDAL,
projectUserMembershipRoleDAL,
orgDAL, orgDAL,
orgService, orgService,
licenseService licenseService,
}); membershipGroupDAL
const orgRoleService = orgRoleServiceFactory({
permissionService,
orgRoleDAL,
orgDAL,
externalGroupOrgRoleMappingDAL
}); });
const microsoftTeamsService = microsoftTeamsServiceFactory({ const microsoftTeamsService = microsoftTeamsServiceFactory({
@@ -940,8 +913,6 @@ export const registerRoutes = async (
userAliasDAL, userAliasDAL,
identityTokenAuthDAL, identityTokenAuthDAL,
identityAccessTokenDAL, identityAccessTokenDAL,
orgMembershipDAL,
identityOrgMembershipDAL,
authService: loginService, authService: loginService,
serverCfgDAL: superAdminDAL, serverCfgDAL: superAdminDAL,
kmsRootConfigDAL, kmsRootConfigDAL,
@@ -953,7 +924,10 @@ export const registerRoutes = async (
microsoftTeamsService, microsoftTeamsService,
invalidateCacheQueue, invalidateCacheQueue,
smtpService, smtpService,
tokenService tokenService,
membershipIdentityDAL,
membershipRoleDAL,
membershipUserDAL
}); });
const offlineUsageReportService = offlineUsageReportServiceFactory({ const offlineUsageReportService = offlineUsageReportServiceFactory({
@@ -965,9 +939,10 @@ export const registerRoutes = async (
smtpService, smtpService,
projectDAL, projectDAL,
permissionService, permissionService,
projectUserMembershipRoleDAL, notificationService,
projectMembershipDAL, membershipRoleDAL,
notificationService membershipUserDAL,
projectMembershipDAL
}); });
const rateLimitService = rateLimitServiceFactory({ const rateLimitService = rateLimitServiceFactory({
@@ -993,32 +968,24 @@ export const registerRoutes = async (
const projectMembershipService = projectMembershipServiceFactory({ const projectMembershipService = projectMembershipServiceFactory({
projectMembershipDAL, projectMembershipDAL,
projectUserMembershipRoleDAL,
projectDAL, projectDAL,
permissionService, permissionService,
projectBotDAL,
orgDAL, orgDAL,
userDAL, userDAL,
projectUserAdditionalPrivilegeDAL,
userGroupMembershipDAL, userGroupMembershipDAL,
smtpService, smtpService,
projectKeyDAL, projectKeyDAL,
projectRoleDAL,
groupProjectDAL, groupProjectDAL,
secretReminderRecipientsDAL, secretReminderRecipientsDAL,
licenseService, licenseService,
notificationService notificationService,
}); membershipDAL
const projectUserAdditionalPrivilegeService = projectUserAdditionalPrivilegeServiceFactory({
permissionService,
projectMembershipDAL,
projectUserAdditionalPrivilegeDAL,
accessApprovalRequestDAL
}); });
const projectKeyService = projectKeyServiceFactory({ const projectKeyService = projectKeyServiceFactory({
permissionService, permissionService,
projectKeyDAL, projectKeyDAL,
projectMembershipDAL membershipUserDAL
}); });
const projectQueueService = projectQueueFactory({ const projectQueueService = projectQueueFactory({
@@ -1034,10 +1001,10 @@ export const registerRoutes = async (
secretVersionDAL, secretVersionDAL,
projectKeyDAL, projectKeyDAL,
projectBotDAL, projectBotDAL,
projectMembershipDAL,
secretApprovalRequestDAL, secretApprovalRequestDAL,
secretApprovalSecretDAL: secretApprovalRequestSecretDAL, secretApprovalSecretDAL: secretApprovalRequestSecretDAL,
projectUserMembershipRoleDAL membershipRoleDAL,
membershipUserDAL
}); });
const certificateAuthorityDAL = certificateAuthorityDALFactory(db); const certificateAuthorityDAL = certificateAuthorityDALFactory(db);
@@ -1249,14 +1216,15 @@ export const registerRoutes = async (
snapshotSecretV2BridgeDAL, snapshotSecretV2BridgeDAL,
secretApprovalRequestDAL, secretApprovalRequestDAL,
projectKeyDAL, projectKeyDAL,
projectUserMembershipRoleDAL,
orgService, orgService,
resourceMetadataDAL, resourceMetadataDAL,
folderCommitService, folderCommitService,
secretSyncQueue, secretSyncQueue,
reminderService, reminderService,
eventBusService, eventBusService,
licenseService licenseService,
membershipRoleDAL,
membershipUserDAL
}); });
const projectService = projectServiceFactory({ const projectService = projectServiceFactory({
@@ -1267,13 +1235,10 @@ export const registerRoutes = async (
secretV2BridgeDAL, secretV2BridgeDAL,
projectQueue: projectQueueService, projectQueue: projectQueueService,
projectBotService, projectBotService,
identityProjectDAL,
identityOrgMembershipDAL,
userDAL, userDAL,
projectEnvDAL, projectEnvDAL,
orgDAL, orgDAL,
projectMembershipDAL, projectMembershipDAL,
projectRoleDAL,
folderDAL, folderDAL,
licenseService, licenseService,
pkiSubscriberDAL, pkiSubscriberDAL,
@@ -1287,8 +1252,6 @@ export const registerRoutes = async (
sshCertificateTemplateDAL, sshCertificateTemplateDAL,
sshHostDAL, sshHostDAL,
sshHostGroupDAL, sshHostGroupDAL,
projectUserMembershipRoleDAL,
identityProjectMembershipRoleDAL,
keyStore, keyStore,
kmsService, kmsService,
certificateTemplateDAL, certificateTemplateDAL,
@@ -1297,7 +1260,6 @@ export const registerRoutes = async (
projectMicrosoftTeamsConfigDAL, projectMicrosoftTeamsConfigDAL,
microsoftTeamsIntegrationDAL, microsoftTeamsIntegrationDAL,
projectTemplateService, projectTemplateService,
groupProjectDAL,
smtpService, smtpService,
reminderService, reminderService,
notificationService notificationService
@@ -1314,16 +1276,6 @@ export const registerRoutes = async (
secretApprovalPolicyEnvironmentDAL: sapEnvironmentDAL secretApprovalPolicyEnvironmentDAL: sapEnvironmentDAL
}); });
const projectRoleService = projectRoleServiceFactory({
permissionService,
projectRoleDAL,
projectUserMembershipRoleDAL,
identityProjectMembershipRoleDAL,
projectDAL,
identityDAL,
userDAL
});
const snapshotService = secretSnapshotServiceFactory({ const snapshotService = secretSnapshotServiceFactory({
permissionService, permissionService,
licenseService, licenseService,
@@ -1478,21 +1430,16 @@ export const registerRoutes = async (
groupDAL, groupDAL,
permissionService, permissionService,
projectEnvDAL, projectEnvDAL,
projectMembershipDAL,
projectDAL, projectDAL,
userDAL, userDAL,
accessApprovalRequestDAL, accessApprovalRequestDAL,
additionalPrivilegeDAL: projectUserAdditionalPrivilegeDAL, accessApprovalRequestReviewerDAL
accessApprovalRequestReviewerDAL,
orgMembershipDAL
}); });
const accessApprovalRequestService = accessApprovalRequestServiceFactory({ const accessApprovalRequestService = accessApprovalRequestServiceFactory({
projectDAL, projectDAL,
permissionService, permissionService,
accessApprovalRequestReviewerDAL, accessApprovalRequestReviewerDAL,
additionalPrivilegeDAL: projectUserAdditionalPrivilegeDAL,
projectMembershipDAL,
accessApprovalPolicyDAL, accessApprovalPolicyDAL,
accessApprovalRequestDAL, accessApprovalRequestDAL,
projectEnvDAL, projectEnvDAL,
@@ -1594,7 +1541,14 @@ export const registerRoutes = async (
licenseService, licenseService,
identityMetadataDAL, identityMetadataDAL,
keyStore, keyStore,
orgDAL orgDAL,
membershipIdentityDAL,
membershipRoleDAL
});
const identityProjectService = identityProjectServiceFactory({
identityProjectDAL,
membershipIdentityDAL,
permissionService
}); });
const identityAuthTemplateService = identityAuthTemplateServiceFactory({ const identityAuthTemplateService = identityAuthTemplateServiceFactory({
@@ -1613,53 +1567,28 @@ export const registerRoutes = async (
identityDAL identityDAL
}); });
const identityProjectService = identityProjectServiceFactory({
permissionService,
projectDAL,
identityProjectDAL,
identityOrgMembershipDAL,
identityProjectMembershipRoleDAL,
projectRoleDAL,
orgDAL
});
const identityProjectAdditionalPrivilegeService = identityProjectAdditionalPrivilegeServiceFactory({
projectDAL,
identityProjectAdditionalPrivilegeDAL,
permissionService,
identityProjectDAL
});
const identityProjectAdditionalPrivilegeV2Service = identityProjectAdditionalPrivilegeV2ServiceFactory({
projectDAL,
identityProjectAdditionalPrivilegeDAL,
permissionService,
identityProjectDAL
});
const identityTokenAuthService = identityTokenAuthServiceFactory({ const identityTokenAuthService = identityTokenAuthServiceFactory({
identityTokenAuthDAL, identityTokenAuthDAL,
identityOrgMembershipDAL,
identityAccessTokenDAL, identityAccessTokenDAL,
permissionService, permissionService,
licenseService, licenseService,
orgDAL orgDAL,
membershipIdentityDAL
}); });
const identityUaService = identityUaServiceFactory({ const identityUaService = identityUaServiceFactory({
identityOrgMembershipDAL,
permissionService, permissionService,
identityAccessTokenDAL, identityAccessTokenDAL,
identityUaClientSecretDAL, identityUaClientSecretDAL,
identityUaDAL, identityUaDAL,
licenseService, licenseService,
keyStore, keyStore,
orgDAL orgDAL,
membershipIdentityDAL
}); });
const identityKubernetesAuthService = identityKubernetesAuthServiceFactory({ const identityKubernetesAuthService = identityKubernetesAuthServiceFactory({
identityKubernetesAuthDAL, identityKubernetesAuthDAL,
identityOrgMembershipDAL,
identityAccessTokenDAL, identityAccessTokenDAL,
permissionService, permissionService,
licenseService, licenseService,
@@ -1668,61 +1597,62 @@ export const registerRoutes = async (
gatewayV2Service, gatewayV2Service,
gatewayV2DAL, gatewayV2DAL,
gatewayDAL, gatewayDAL,
kmsService kmsService,
membershipIdentityDAL
}); });
const identityGcpAuthService = identityGcpAuthServiceFactory({ const identityGcpAuthService = identityGcpAuthServiceFactory({
identityGcpAuthDAL, identityGcpAuthDAL,
orgDAL, orgDAL,
identityOrgMembershipDAL,
identityAccessTokenDAL, identityAccessTokenDAL,
permissionService, permissionService,
licenseService licenseService,
membershipIdentityDAL
}); });
const identityAliCloudAuthService = identityAliCloudAuthServiceFactory({ const identityAliCloudAuthService = identityAliCloudAuthServiceFactory({
identityAccessTokenDAL, identityAccessTokenDAL,
orgDAL, orgDAL,
identityAliCloudAuthDAL, identityAliCloudAuthDAL,
identityOrgMembershipDAL,
licenseService, licenseService,
permissionService permissionService,
membershipIdentityDAL
}); });
const identityTlsCertAuthService = identityTlsCertAuthServiceFactory({ const identityTlsCertAuthService = identityTlsCertAuthServiceFactory({
identityAccessTokenDAL, identityAccessTokenDAL,
orgDAL, orgDAL,
identityTlsCertAuthDAL, identityTlsCertAuthDAL,
identityOrgMembershipDAL,
licenseService, licenseService,
permissionService, permissionService,
kmsService kmsService,
membershipIdentityDAL
}); });
const identityAwsAuthService = identityAwsAuthServiceFactory({ const identityAwsAuthService = identityAwsAuthServiceFactory({
identityAccessTokenDAL, identityAccessTokenDAL,
orgDAL, orgDAL,
identityAwsAuthDAL, identityAwsAuthDAL,
identityOrgMembershipDAL,
licenseService, licenseService,
permissionService permissionService,
membershipIdentityDAL
}); });
const identityAzureAuthService = identityAzureAuthServiceFactory({ const identityAzureAuthService = identityAzureAuthServiceFactory({
identityAzureAuthDAL, identityAzureAuthDAL,
orgDAL, orgDAL,
identityOrgMembershipDAL,
identityAccessTokenDAL, identityAccessTokenDAL,
permissionService, permissionService,
licenseService licenseService,
membershipIdentityDAL
}); });
const identityOciAuthService = identityOciAuthServiceFactory({ const identityOciAuthService = identityOciAuthServiceFactory({
identityAccessTokenDAL, identityAccessTokenDAL,
orgDAL, orgDAL,
identityOciAuthDAL, identityOciAuthDAL,
identityOrgMembershipDAL,
licenseService, licenseService,
permissionService permissionService,
membershipIdentityDAL
}); });
const pitService = pitServiceFactory({ const pitService = pitServiceFactory({
@@ -1742,11 +1672,11 @@ export const registerRoutes = async (
const identityOidcAuthService = identityOidcAuthServiceFactory({ const identityOidcAuthService = identityOidcAuthServiceFactory({
identityOidcAuthDAL, identityOidcAuthDAL,
orgDAL, orgDAL,
identityOrgMembershipDAL,
identityAccessTokenDAL, identityAccessTokenDAL,
permissionService, permissionService,
licenseService, licenseService,
kmsService kmsService,
membershipIdentityDAL
}); });
const identityJwtAuthService = identityJwtAuthServiceFactory({ const identityJwtAuthService = identityJwtAuthServiceFactory({
@@ -1754,9 +1684,9 @@ export const registerRoutes = async (
orgDAL, orgDAL,
permissionService, permissionService,
identityAccessTokenDAL, identityAccessTokenDAL,
identityOrgMembershipDAL,
licenseService, licenseService,
kmsService kmsService,
membershipIdentityDAL
}); });
const identityLdapAuthService = identityLdapAuthServiceFactory({ const identityLdapAuthService = identityLdapAuthServiceFactory({
@@ -1765,11 +1695,17 @@ export const registerRoutes = async (
permissionService, permissionService,
kmsService, kmsService,
identityAccessTokenDAL, identityAccessTokenDAL,
identityOrgMembershipDAL,
licenseService, licenseService,
identityDAL, identityDAL,
identityAuthTemplateDAL, identityAuthTemplateDAL,
keyStore keyStore,
membershipIdentityDAL
});
const convertorService = convertorServiceFactory({
additionalPrivilegeDAL,
membershipDAL,
projectDAL
}); });
const dynamicSecretProviders = buildDynamicSecretProviders({ const dynamicSecretProviders = buildDynamicSecretProviders({
@@ -1844,7 +1780,6 @@ export const registerRoutes = async (
const oidcService = oidcConfigServiceFactory({ const oidcService = oidcConfigServiceFactory({
orgDAL, orgDAL,
orgMembershipDAL,
userDAL, userDAL,
userAliasDAL, userAliasDAL,
licenseService, licenseService,
@@ -1857,9 +1792,10 @@ export const registerRoutes = async (
projectKeyDAL, projectKeyDAL,
projectDAL, projectDAL,
userGroupMembershipDAL, userGroupMembershipDAL,
groupProjectDAL,
groupDAL, groupDAL,
auditLogService auditLogService,
membershipGroupDAL,
membershipRoleDAL
}); });
const userEngagementService = userEngagementServiceFactory({ const userEngagementService = userEngagementServiceFactory({
@@ -1915,8 +1851,8 @@ export const registerRoutes = async (
const externalGroupOrgRoleMappingService = externalGroupOrgRoleMappingServiceFactory({ const externalGroupOrgRoleMappingService = externalGroupOrgRoleMappingServiceFactory({
permissionService, permissionService,
licenseService, licenseService,
orgRoleDAL, externalGroupOrgRoleMappingDAL,
externalGroupOrgRoleMappingDAL roleDAL
}); });
const appConnectionService = appConnectionServiceFactory({ const appConnectionService = appConnectionServiceFactory({
@@ -2262,7 +2198,6 @@ export const registerRoutes = async (
groupProject: groupProjectService, groupProject: groupProjectService,
permission: permissionService, permission: permissionService,
org: orgService, org: orgService,
orgRole: orgRoleService,
oidc: oidcService, oidc: oidcService,
apiKey: apiKeyService, apiKey: apiKeyService,
authToken: tokenService, authToken: tokenService,
@@ -2272,7 +2207,6 @@ export const registerRoutes = async (
projectMembership: projectMembershipService, projectMembership: projectMembershipService,
projectKey: projectKeyService, projectKey: projectKeyService,
projectEnv: projectEnvService, projectEnv: projectEnvService,
projectRole: projectRoleService,
secret: secretService, secret: secretService,
secretReplication: secretReplicationService, secretReplication: secretReplicationService,
secretTag: secretTagService, secretTag: secretTagService,
@@ -2287,7 +2221,6 @@ export const registerRoutes = async (
identity: identityService, identity: identityService,
identityAuthTemplate: identityAuthTemplateService, identityAuthTemplate: identityAuthTemplateService,
identityAccessToken: identityAccessTokenService, identityAccessToken: identityAccessTokenService,
identityProject: identityProjectService,
identityTokenAuth: identityTokenAuthService, identityTokenAuth: identityTokenAuthService,
identityUa: identityUaService, identityUa: identityUaService,
identityKubernetesAuth: identityKubernetesAuthService, identityKubernetesAuth: identityKubernetesAuthService,
@@ -2334,9 +2267,6 @@ export const registerRoutes = async (
scim: scimService, scim: scimService,
secretBlindIndex: secretBlindIndexService, secretBlindIndex: secretBlindIndexService,
telemetry: telemetryService, telemetry: telemetryService,
projectUserAdditionalPrivilege: projectUserAdditionalPrivilegeService,
identityProjectAdditionalPrivilege: identityProjectAdditionalPrivilegeService,
identityProjectAdditionalPrivilegeV2: identityProjectAdditionalPrivilegeV2Service,
secretSharing: secretSharingService, secretSharing: secretSharingService,
userEngagement: userEngagementService, userEngagement: userEngagementService,
externalKms: externalKmsService, externalKms: externalKmsService,
@@ -2376,7 +2306,9 @@ export const registerRoutes = async (
membershipIdentity: membershipIdentityService, membershipIdentity: membershipIdentityService,
membershipGroup: membershipGroupService, membershipGroup: membershipGroupService,
role: roleService, role: roleService,
additionalPrivilege: additionalPrivilegeService additionalPrivilege: additionalPrivilegeService,
identityProject: identityProjectService,
convertor: convertorService
}); });
const cronJobs: CronJob[] = []; const cronJobs: CronJob[] = [];
@@ -78,7 +78,7 @@ export const registerIdentityAliCloudAuthRouter = async (server: FastifyZodProvi
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
...req.auditLogInfo, ...req.auditLogInfo,
orgId: identityMembershipOrg?.orgId, orgId: identityMembershipOrg.scopeOrgId,
event: { event: {
type: EventType.LOGIN_IDENTITY_ALICLOUD_AUTH, type: EventType.LOGIN_IDENTITY_ALICLOUD_AUTH,
metadata: { metadata: {
@@ -45,7 +45,7 @@ export const registerIdentityAwsAuthRouter = async (server: FastifyZodProvider)
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
...req.auditLogInfo, ...req.auditLogInfo,
orgId: identityMembershipOrg?.orgId, orgId: identityMembershipOrg.scopeOrgId,
event: { event: {
type: EventType.LOGIN_IDENTITY_AWS_AUTH, type: EventType.LOGIN_IDENTITY_AWS_AUTH,
metadata: { metadata: {
@@ -40,7 +40,7 @@ export const registerIdentityAzureAuthRouter = async (server: FastifyZodProvider
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
...req.auditLogInfo, ...req.auditLogInfo,
orgId: identityMembershipOrg.orgId, orgId: identityMembershipOrg.scopeOrgId,
event: { event: {
type: EventType.LOGIN_IDENTITY_AZURE_AUTH, type: EventType.LOGIN_IDENTITY_AZURE_AUTH,
metadata: { metadata: {
@@ -40,7 +40,7 @@ export const registerIdentityGcpAuthRouter = async (server: FastifyZodProvider)
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
...req.auditLogInfo, ...req.auditLogInfo,
orgId: identityMembershipOrg?.orgId, orgId: identityMembershipOrg.scopeOrgId,
event: { event: {
type: EventType.LOGIN_IDENTITY_GCP_AUTH, type: EventType.LOGIN_IDENTITY_GCP_AUTH,
metadata: { metadata: {
@@ -119,7 +119,7 @@ export const registerIdentityJwtAuthRouter = async (server: FastifyZodProvider)
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
...req.auditLogInfo, ...req.auditLogInfo,
orgId: identityMembershipOrg?.orgId, orgId: identityMembershipOrg.scopeOrgId,
event: { event: {
type: EventType.LOGIN_IDENTITY_JWT_AUTH, type: EventType.LOGIN_IDENTITY_JWT_AUTH,
metadata: { metadata: {
@@ -64,7 +64,7 @@ export const registerIdentityKubernetesRouter = async (server: FastifyZodProvide
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
...req.auditLogInfo, ...req.auditLogInfo,
orgId: identityMembershipOrg?.orgId, orgId: identityMembershipOrg.scopeOrgId,
event: { event: {
type: EventType.LOGIN_IDENTITY_KUBERNETES_AUTH, type: EventType.LOGIN_IDENTITY_KUBERNETES_AUTH,
metadata: { metadata: {
@@ -168,7 +168,7 @@ export const registerIdentityLdapAuthRouter = async (server: FastifyZodProvider)
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
...req.auditLogInfo, ...req.auditLogInfo,
orgId: identityMembershipOrg?.orgId, orgId: identityMembershipOrg.scopeOrgId,
event: { event: {
type: EventType.LOGIN_IDENTITY_LDAP_AUTH, type: EventType.LOGIN_IDENTITY_LDAP_AUTH,
metadata: { metadata: {
@@ -57,7 +57,7 @@ export const registerIdentityOciAuthRouter = async (server: FastifyZodProvider)
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
...req.auditLogInfo, ...req.auditLogInfo,
orgId: identityMembershipOrg?.orgId, orgId: identityMembershipOrg.scopeOrgId,
event: { event: {
type: EventType.LOGIN_IDENTITY_OCI_AUTH, type: EventType.LOGIN_IDENTITY_OCI_AUTH,
metadata: { metadata: {
@@ -67,7 +67,7 @@ export const registerIdentityOidcAuthRouter = async (server: FastifyZodProvider)
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
...req.auditLogInfo, ...req.auditLogInfo,
orgId: identityMembershipOrg?.orgId, orgId: identityMembershipOrg.scopeOrgId,
event: { event: {
type: EventType.LOGIN_IDENTITY_OIDC_AUTH, type: EventType.LOGIN_IDENTITY_OIDC_AUTH,
metadata: { metadata: {
@@ -72,7 +72,7 @@ export const registerIdentityTlsCertAuthRouter = async (server: FastifyZodProvid
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
...req.auditLogInfo, ...req.auditLogInfo,
orgId: identityMembershipOrg?.orgId, orgId: identityMembershipOrg.scopeOrgId,
event: { event: {
type: EventType.LOGIN_IDENTITY_TLS_CERT_AUTH, type: EventType.LOGIN_IDENTITY_TLS_CERT_AUTH,
metadata: { metadata: {
@@ -332,7 +332,7 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
...req.auditLogInfo, ...req.auditLogInfo,
orgId: identityMembershipOrg.orgId, orgId: identityMembershipOrg.scopeOrgId,
event: { event: {
type: EventType.CREATE_TOKEN_IDENTITY_TOKEN_AUTH, type: EventType.CREATE_TOKEN_IDENTITY_TOKEN_AUTH,
metadata: { metadata: {
@@ -393,7 +393,7 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
...req.auditLogInfo, ...req.auditLogInfo,
orgId: identityMembershipOrg.orgId, orgId: identityMembershipOrg.scopeOrgId,
event: { event: {
type: EventType.GET_TOKENS_IDENTITY_TOKEN_AUTH, type: EventType.GET_TOKENS_IDENTITY_TOKEN_AUTH,
metadata: { metadata: {
@@ -447,7 +447,7 @@ export const registerIdentityTokenAuthRouter = async (server: FastifyZodProvider
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
...req.auditLogInfo, ...req.auditLogInfo,
orgId: identityMembershipOrg.orgId, orgId: identityMembershipOrg.scopeOrgId,
event: { event: {
type: EventType.UPDATE_TOKEN_IDENTITY_TOKEN_AUTH, type: EventType.UPDATE_TOKEN_IDENTITY_TOKEN_AUTH,
metadata: { metadata: {
@@ -59,7 +59,7 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
...req.auditLogInfo, ...req.auditLogInfo,
orgId: identityMembershipOrg?.orgId, orgId: identityMembershipOrg.scopeOrgId,
event: { event: {
type: EventType.LOGIN_IDENTITY_UNIVERSAL_AUTH, type: EventType.LOGIN_IDENTITY_UNIVERSAL_AUTH,
metadata: { metadata: {
@@ -204,7 +204,7 @@ export const identityAccessTokenServiceFactory = ({
} }
const identityOrgMembership = await identityOrgMembershipDAL.findOne({ const identityOrgMembership = await identityOrgMembershipDAL.findOne({
identityId: identityAccessToken.identityId actorIdentityId: identityAccessToken.identityId
}); });
if (!identityOrgMembership) { if (!identityOrgMembership) {
@@ -219,7 +219,7 @@ export const identityAccessTokenServiceFactory = ({
await validateAccessTokenExp({ ...identityAccessToken, accessTokenNumUses }); await validateAccessTokenExp({ ...identityAccessToken, accessTokenNumUses });
await accessTokenQueue.updateIdentityAccessTokenStatus(identityAccessToken.id, Number(accessTokenNumUses) + 1); await accessTokenQueue.updateIdentityAccessTokenStatus(identityAccessToken.id, Number(accessTokenNumUses) + 1);
return { ...identityAccessToken, orgId: identityOrgMembership.orgId }; return { ...identityAccessToken, orgId: identityOrgMembership.scopeOrgId };
}; };
return { renewAccessToken, revokeAccessToken, fnValidateIdentityAccessToken }; return { renewAccessToken, revokeAccessToken, fnValidateIdentityAccessToken };
@@ -2,7 +2,7 @@
import { ForbiddenError } from "@casl/ability"; import { ForbiddenError } from "@casl/ability";
import { AxiosError } from "axios"; import { AxiosError } from "axios";
import { IdentityAuthMethod } from "@app/db/schemas"; import { AccessScope, IdentityAuthMethod } 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 {
@@ -18,7 +18,7 @@ import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
import { logger } from "@app/lib/logger"; import { logger } from "@app/lib/logger";
import { ActorType, AuthTokenType } from "../auth/auth-type"; import { ActorType, AuthTokenType } from "../auth/auth-type";
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal"; import { TMembershipIdentityDALFactory } from "../membership-identity/membership-identity-dal";
import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal"; import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal";
import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types"; import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types";
import { TOrgDALFactory } from "../org/org-dal"; import { TOrgDALFactory } from "../org/org-dal";
@@ -39,7 +39,7 @@ type TIdentityAliCloudAuthServiceFactoryDep = {
TIdentityAliCloudAuthDALFactory, TIdentityAliCloudAuthDALFactory,
"findOne" | "transaction" | "create" | "updateById" | "delete" "findOne" | "transaction" | "create" | "updateById" | "delete"
>; >;
identityOrgMembershipDAL: Pick<TIdentityOrgDALFactory, "findOne" | "updateById">; membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "updateById" | "getIdentityById">;
licenseService: Pick<TLicenseServiceFactory, "getPlan">; licenseService: Pick<TLicenseServiceFactory, "getPlan">;
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">; permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
orgDAL: Pick<TOrgDALFactory, "findById">; orgDAL: Pick<TOrgDALFactory, "findById">;
@@ -50,7 +50,7 @@ export type TIdentityAliCloudAuthServiceFactory = ReturnType<typeof identityAliC
export const identityAliCloudAuthServiceFactory = ({ export const identityAliCloudAuthServiceFactory = ({
identityAccessTokenDAL, identityAccessTokenDAL,
identityAliCloudAuthDAL, identityAliCloudAuthDAL,
identityOrgMembershipDAL, membershipIdentityDAL,
licenseService, licenseService,
permissionService, permissionService,
orgDAL orgDAL
@@ -63,8 +63,9 @@ export const identityAliCloudAuthServiceFactory = ({
}); });
} }
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ const identityMembershipOrg = await membershipIdentityDAL.findOne({
identityId: identityAliCloudAuth.identityId actorIdentityId: identityAliCloudAuth.identityId,
scope: AccessScope.Organization
}); });
if (!identityMembershipOrg) throw new UnauthorizedError({ message: "Identity not attached to a organization" }); if (!identityMembershipOrg) throw new UnauthorizedError({ message: "Identity not attached to a organization" });
@@ -92,7 +93,7 @@ export const identityAliCloudAuthServiceFactory = ({
// Generate the token // Generate the token
const identityAccessToken = await identityAliCloudAuthDAL.transaction(async (tx) => { const identityAccessToken = await identityAliCloudAuthDAL.transaction(async (tx) => {
await identityOrgMembershipDAL.updateById( await membershipIdentityDAL.updateById(
identityMembershipOrg.id, identityMembershipOrg.id,
{ {
lastLoginAuthMethod: IdentityAuthMethod.ALICLOUD_AUTH, lastLoginAuthMethod: IdentityAuthMethod.ALICLOUD_AUTH,
@@ -153,7 +154,13 @@ export const identityAliCloudAuthServiceFactory = ({
}: TAttachAliCloudAuthDTO) => { }: TAttachAliCloudAuthDTO) => {
await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin); await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin);
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.ALICLOUD_AUTH)) { if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.ALICLOUD_AUTH)) {
@@ -169,13 +176,13 @@ export const identityAliCloudAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => { const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -196,7 +203,7 @@ export const identityAliCloudAuthServiceFactory = ({
const identityAliCloudAuth = await identityAliCloudAuthDAL.transaction(async (tx) => { const identityAliCloudAuth = await identityAliCloudAuthDAL.transaction(async (tx) => {
const doc = await identityAliCloudAuthDAL.create( const doc = await identityAliCloudAuthDAL.create(
{ {
identityId: identityMembershipOrg.identityId, identityId: identityMembershipOrg.identity.id,
type: "iam", type: "iam",
allowedArns, allowedArns,
accessTokenMaxTTL, accessTokenMaxTTL,
@@ -208,7 +215,7 @@ export const identityAliCloudAuthServiceFactory = ({
); );
return doc; return doc;
}); });
return { ...identityAliCloudAuth, orgId: identityMembershipOrg.orgId }; return { ...identityAliCloudAuth, orgId: identityMembershipOrg.scopeOrgId };
}; };
const updateAliCloudAuth = async ({ const updateAliCloudAuth = async ({
@@ -223,7 +230,13 @@ export const identityAliCloudAuthServiceFactory = ({
actor, actor,
actorOrgId actorOrgId
}: TUpdateAliCloudAuthDTO) => { }: TUpdateAliCloudAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.ALICLOUD_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.ALICLOUD_AUTH)) {
@@ -245,13 +258,13 @@ export const identityAliCloudAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => { const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -279,11 +292,17 @@ export const identityAliCloudAuthServiceFactory = ({
: undefined : undefined
}); });
return { ...updatedAliCloudAuth, orgId: identityMembershipOrg.orgId }; return { ...updatedAliCloudAuth, orgId: identityMembershipOrg.scopeOrgId };
}; };
const getAliCloudAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetAliCloudAuthDTO) => { const getAliCloudAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetAliCloudAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.ALICLOUD_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.ALICLOUD_AUTH)) {
@@ -297,12 +316,12 @@ export const identityAliCloudAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
return { ...alicloudIdentityAuth, orgId: identityMembershipOrg.orgId }; return { ...alicloudIdentityAuth, orgId: identityMembershipOrg.scopeOrgId };
}; };
const revokeIdentityAliCloudAuth = async ({ const revokeIdentityAliCloudAuth = async ({
@@ -312,7 +331,13 @@ export const identityAliCloudAuthServiceFactory = ({
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}: TRevokeAliCloudAuthDTO) => { }: TRevokeAliCloudAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.ALICLOUD_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.ALICLOUD_AUTH)) {
throw new BadRequestError({ throw new BadRequestError({
@@ -322,7 +347,7 @@ export const identityAliCloudAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -330,13 +355,13 @@ export const identityAliCloudAuthServiceFactory = ({
const { permission: rolePermission } = await permissionService.getOrgPermission( const { permission: rolePermission } = await permissionService.getOrgPermission(
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identity.id,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.orgId); const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
const permissionBoundary = validatePrivilegeChangeOperation( const permissionBoundary = validatePrivilegeChangeOperation(
shouldUseNewPrivilegeSystem, shouldUseNewPrivilegeSystem,
OrgPermissionIdentityActions.RevokeAuth, OrgPermissionIdentityActions.RevokeAuth,
@@ -360,7 +385,7 @@ export const identityAliCloudAuthServiceFactory = ({
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);
return { ...deletedAliCloudAuth?.[0], orgId: identityMembershipOrg.orgId }; return { ...deletedAliCloudAuth?.[0], orgId: identityMembershipOrg.scopeOrgId };
}); });
return revokedIdentityAliCloudAuth; return revokedIdentityAliCloudAuth;
}; };
@@ -3,7 +3,7 @@ import { ForbiddenError } from "@casl/ability";
import axios from "axios"; import axios from "axios";
import RE2 from "re2"; import RE2 from "re2";
import { IdentityAuthMethod } from "@app/db/schemas"; import { AccessScope, IdentityAuthMethod } from "@app/db/schemas";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
import { TOrgDALFactory } from "../org/org-dal"; import { TOrgDALFactory } from "../org/org-dal";
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
@@ -18,7 +18,7 @@ import { BadRequestError, NotFoundError, PermissionBoundaryError, UnauthorizedEr
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip"; import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
import { ActorType, AuthTokenType } from "../auth/auth-type"; import { ActorType, AuthTokenType } from "../auth/auth-type";
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal"; import { TMembershipIdentityDALFactory } from "../membership-identity/membership-identity-dal";
import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal"; import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal";
import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types"; import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types";
import { validateIdentityUpdateForSuperAdminPrivileges } from "../super-admin/super-admin-fns"; import { validateIdentityUpdateForSuperAdminPrivileges } from "../super-admin/super-admin-fns";
@@ -37,7 +37,7 @@ import {
type TIdentityAwsAuthServiceFactoryDep = { type TIdentityAwsAuthServiceFactoryDep = {
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">; identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">;
identityAwsAuthDAL: Pick<TIdentityAwsAuthDALFactory, "findOne" | "transaction" | "create" | "updateById" | "delete">; identityAwsAuthDAL: Pick<TIdentityAwsAuthDALFactory, "findOne" | "transaction" | "create" | "updateById" | "delete">;
identityOrgMembershipDAL: Pick<TIdentityOrgDALFactory, "findOne" | "updateById">; membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "updateById" | "getIdentityById">;
licenseService: Pick<TLicenseServiceFactory, "getPlan">; licenseService: Pick<TLicenseServiceFactory, "getPlan">;
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">; permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
orgDAL: Pick<TOrgDALFactory, "findById">; orgDAL: Pick<TOrgDALFactory, "findById">;
@@ -82,7 +82,7 @@ function isValidAwsRegion(region: string | null): boolean {
export const identityAwsAuthServiceFactory = ({ export const identityAwsAuthServiceFactory = ({
identityAccessTokenDAL, identityAccessTokenDAL,
identityAwsAuthDAL, identityAwsAuthDAL,
identityOrgMembershipDAL, membershipIdentityDAL,
licenseService, licenseService,
permissionService, permissionService,
orgDAL orgDAL
@@ -93,7 +93,10 @@ export const identityAwsAuthServiceFactory = ({
throw new NotFoundError({ message: "AWS auth method not found for identity, did you configure AWS auth?" }); throw new NotFoundError({ message: "AWS auth method not found for identity, did you configure AWS auth?" });
} }
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId: identityAwsAuth.identityId }); const identityMembershipOrg = await membershipIdentityDAL.findOne({
actorIdentityId: identityAwsAuth.identityId,
scope: AccessScope.Organization
});
if (!identityMembershipOrg) throw new UnauthorizedError({ message: "Identity not attached to a organization" }); if (!identityMembershipOrg) throw new UnauthorizedError({ message: "Identity not attached to a organization" });
const headers: TAwsGetCallerIdentityHeaders = JSON.parse(Buffer.from(iamRequestHeaders, "base64").toString()); const headers: TAwsGetCallerIdentityHeaders = JSON.parse(Buffer.from(iamRequestHeaders, "base64").toString());
@@ -156,7 +159,7 @@ export const identityAwsAuthServiceFactory = ({
} }
const identityAccessToken = await identityAwsAuthDAL.transaction(async (tx) => { const identityAccessToken = await identityAwsAuthDAL.transaction(async (tx) => {
await identityOrgMembershipDAL.updateById( await membershipIdentityDAL.updateById(
identityMembershipOrg.id, identityMembershipOrg.id,
{ {
lastLoginAuthMethod: IdentityAuthMethod.AWS_AUTH, lastLoginAuthMethod: IdentityAuthMethod.AWS_AUTH,
@@ -229,7 +232,13 @@ export const identityAwsAuthServiceFactory = ({
}: TAttachAwsAuthDTO) => { }: TAttachAwsAuthDTO) => {
await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin); await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin);
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.AWS_AUTH)) { if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.AWS_AUTH)) {
@@ -245,13 +254,13 @@ export const identityAwsAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => { const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -272,7 +281,7 @@ export const identityAwsAuthServiceFactory = ({
const identityAwsAuth = await identityAwsAuthDAL.transaction(async (tx) => { const identityAwsAuth = await identityAwsAuthDAL.transaction(async (tx) => {
const doc = await identityAwsAuthDAL.create( const doc = await identityAwsAuthDAL.create(
{ {
identityId: identityMembershipOrg.identityId, identityId: identityMembershipOrg.identity.id,
type: "iam", type: "iam",
stsEndpoint, stsEndpoint,
allowedPrincipalArns, allowedPrincipalArns,
@@ -286,7 +295,7 @@ export const identityAwsAuthServiceFactory = ({
); );
return doc; return doc;
}); });
return { ...identityAwsAuth, orgId: identityMembershipOrg.orgId }; return { ...identityAwsAuth, orgId: identityMembershipOrg.scopeOrgId };
}; };
const updateAwsAuth = async ({ const updateAwsAuth = async ({
@@ -303,7 +312,13 @@ export const identityAwsAuthServiceFactory = ({
actor, actor,
actorOrgId actorOrgId
}: TUpdateAwsAuthDTO) => { }: TUpdateAwsAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.AWS_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.AWS_AUTH)) {
@@ -324,13 +339,13 @@ export const identityAwsAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => { const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -360,11 +375,17 @@ export const identityAwsAuthServiceFactory = ({
: undefined : undefined
}); });
return { ...updatedAwsAuth, orgId: identityMembershipOrg.orgId }; return { ...updatedAwsAuth, orgId: identityMembershipOrg.scopeOrgId };
}; };
const getAwsAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetAwsAuthDTO) => { const getAwsAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetAwsAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.AWS_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.AWS_AUTH)) {
@@ -378,12 +399,12 @@ export const identityAwsAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
return { ...awsIdentityAuth, orgId: identityMembershipOrg.orgId }; return { ...awsIdentityAuth, orgId: identityMembershipOrg.scopeOrgId };
}; };
const revokeIdentityAwsAuth = async ({ const revokeIdentityAwsAuth = async ({
@@ -393,7 +414,13 @@ export const identityAwsAuthServiceFactory = ({
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}: TRevokeAwsAuthDTO) => { }: TRevokeAwsAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.AWS_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.AWS_AUTH)) {
throw new BadRequestError({ throw new BadRequestError({
@@ -403,7 +430,7 @@ export const identityAwsAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -411,13 +438,13 @@ export const identityAwsAuthServiceFactory = ({
const { permission: rolePermission } = await permissionService.getOrgPermission( const { permission: rolePermission } = await permissionService.getOrgPermission(
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identity.id,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.orgId); const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
const permissionBoundary = validatePrivilegeChangeOperation( const permissionBoundary = validatePrivilegeChangeOperation(
shouldUseNewPrivilegeSystem, shouldUseNewPrivilegeSystem,
OrgPermissionIdentityActions.RevokeAuth, OrgPermissionIdentityActions.RevokeAuth,
@@ -441,7 +468,7 @@ export const identityAwsAuthServiceFactory = ({
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);
return { ...deletedAwsAuth?.[0], orgId: identityMembershipOrg.orgId }; return { ...deletedAwsAuth?.[0], orgId: identityMembershipOrg.scopeOrgId };
}); });
return revokedIdentityAwsAuth; return revokedIdentityAwsAuth;
}; };
@@ -1,6 +1,6 @@
import { ForbiddenError } from "@casl/ability"; import { ForbiddenError } from "@casl/ability";
import { IdentityAuthMethod } from "@app/db/schemas"; import { AccessScope, IdentityAuthMethod } from "@app/db/schemas";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
import { TOrgDALFactory } from "../org/org-dal"; import { TOrgDALFactory } from "../org/org-dal";
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
@@ -15,7 +15,7 @@ import { BadRequestError, NotFoundError, PermissionBoundaryError, UnauthorizedEr
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip"; import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
import { ActorType, AuthTokenType } from "../auth/auth-type"; import { ActorType, AuthTokenType } from "../auth/auth-type";
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal"; import { TMembershipIdentityDALFactory } from "../membership-identity/membership-identity-dal";
import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal"; import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal";
import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types"; import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types";
import { validateIdentityUpdateForSuperAdminPrivileges } from "../super-admin/super-admin-fns"; import { validateIdentityUpdateForSuperAdminPrivileges } from "../super-admin/super-admin-fns";
@@ -34,7 +34,7 @@ type TIdentityAzureAuthServiceFactoryDep = {
TIdentityAzureAuthDALFactory, TIdentityAzureAuthDALFactory,
"findOne" | "transaction" | "create" | "updateById" | "delete" "findOne" | "transaction" | "create" | "updateById" | "delete"
>; >;
identityOrgMembershipDAL: Pick<TIdentityOrgDALFactory, "findOne" | "updateById">; membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "updateById" | "getIdentityById">;
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">; identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">;
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">; permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
licenseService: Pick<TLicenseServiceFactory, "getPlan">; licenseService: Pick<TLicenseServiceFactory, "getPlan">;
@@ -45,7 +45,7 @@ export type TIdentityAzureAuthServiceFactory = ReturnType<typeof identityAzureAu
export const identityAzureAuthServiceFactory = ({ export const identityAzureAuthServiceFactory = ({
identityAzureAuthDAL, identityAzureAuthDAL,
identityOrgMembershipDAL, membershipIdentityDAL,
identityAccessTokenDAL, identityAccessTokenDAL,
permissionService, permissionService,
licenseService, licenseService,
@@ -57,7 +57,10 @@ export const identityAzureAuthServiceFactory = ({
throw new NotFoundError({ message: "Azure auth method not found for identity, did you configure Azure Auth?" }); throw new NotFoundError({ message: "Azure auth method not found for identity, did you configure Azure Auth?" });
} }
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId: identityAzureAuth.identityId }); const identityMembershipOrg = await membershipIdentityDAL.findOne({
actorIdentityId: identityAzureAuth.identityId,
scope: AccessScope.Organization
});
if (!identityMembershipOrg) throw new UnauthorizedError({ message: "Identity not attached to a organization" }); if (!identityMembershipOrg) throw new UnauthorizedError({ message: "Identity not attached to a organization" });
const azureIdentity = await validateAzureIdentity({ const azureIdentity = await validateAzureIdentity({
@@ -83,7 +86,7 @@ export const identityAzureAuthServiceFactory = ({
} }
const identityAccessToken = await identityAzureAuthDAL.transaction(async (tx) => { const identityAccessToken = await identityAzureAuthDAL.transaction(async (tx) => {
await identityOrgMembershipDAL.updateById( await membershipIdentityDAL.updateById(
identityMembershipOrg.id, identityMembershipOrg.id,
{ {
lastLoginAuthMethod: IdentityAuthMethod.AZURE_AUTH, lastLoginAuthMethod: IdentityAuthMethod.AZURE_AUTH,
@@ -142,7 +145,13 @@ export const identityAzureAuthServiceFactory = ({
}: TAttachAzureAuthDTO) => { }: TAttachAzureAuthDTO) => {
await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin); await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin);
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.AZURE_AUTH)) { if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.AZURE_AUTH)) {
@@ -157,13 +166,13 @@ export const identityAzureAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => { const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -184,7 +193,7 @@ export const identityAzureAuthServiceFactory = ({
const identityAzureAuth = await identityAzureAuthDAL.transaction(async (tx) => { const identityAzureAuth = await identityAzureAuthDAL.transaction(async (tx) => {
const doc = await identityAzureAuthDAL.create( const doc = await identityAzureAuthDAL.create(
{ {
identityId: identityMembershipOrg.identityId, identityId: identityMembershipOrg.identity.id,
tenantId, tenantId,
resource, resource,
allowedServicePrincipalIds, allowedServicePrincipalIds,
@@ -198,7 +207,7 @@ export const identityAzureAuthServiceFactory = ({
return doc; return doc;
}); });
return { ...identityAzureAuth, orgId: identityMembershipOrg.orgId }; return { ...identityAzureAuth, orgId: identityMembershipOrg.scopeOrgId };
}; };
const updateAzureAuth = async ({ const updateAzureAuth = async ({
@@ -215,7 +224,13 @@ export const identityAzureAuthServiceFactory = ({
actor, actor,
actorOrgId actorOrgId
}: TUpdateAzureAuthDTO) => { }: TUpdateAzureAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.AZURE_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.AZURE_AUTH)) {
throw new BadRequestError({ throw new BadRequestError({
@@ -235,13 +250,13 @@ export const identityAzureAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => { const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -273,12 +288,18 @@ export const identityAzureAuthServiceFactory = ({
return { return {
...updatedAzureAuth, ...updatedAzureAuth,
orgId: identityMembershipOrg.orgId orgId: identityMembershipOrg.scopeOrgId
}; };
}; };
const getAzureAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetAzureAuthDTO) => { const getAzureAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetAzureAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.AZURE_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.AZURE_AUTH)) {
throw new BadRequestError({ throw new BadRequestError({
@@ -291,13 +312,13 @@ export const identityAzureAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
return { ...identityAzureAuth, orgId: identityMembershipOrg.orgId }; return { ...identityAzureAuth, orgId: identityMembershipOrg.scopeOrgId };
}; };
const revokeIdentityAzureAuth = async ({ const revokeIdentityAzureAuth = async ({
@@ -307,7 +328,13 @@ export const identityAzureAuthServiceFactory = ({
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}: TRevokeAzureAuthDTO) => { }: TRevokeAzureAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.AZURE_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.AZURE_AUTH)) {
throw new BadRequestError({ throw new BadRequestError({
@@ -317,7 +344,7 @@ export const identityAzureAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -325,12 +352,12 @@ export const identityAzureAuthServiceFactory = ({
const { permission: rolePermission } = await permissionService.getOrgPermission( const { permission: rolePermission } = await permissionService.getOrgPermission(
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identity.id,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.orgId); const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
const permissionBoundary = validatePrivilegeChangeOperation( const permissionBoundary = validatePrivilegeChangeOperation(
shouldUseNewPrivilegeSystem, shouldUseNewPrivilegeSystem,
OrgPermissionIdentityActions.RevokeAuth, OrgPermissionIdentityActions.RevokeAuth,
@@ -353,7 +380,7 @@ export const identityAzureAuthServiceFactory = ({
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);
return { ...deletedAzureAuth?.[0], orgId: identityMembershipOrg.orgId }; return { ...deletedAzureAuth?.[0], orgId: identityMembershipOrg.scopeOrgId };
}); });
return revokedIdentityAzureAuth; return revokedIdentityAzureAuth;
}; };
@@ -1,6 +1,6 @@
import { ForbiddenError } from "@casl/ability"; import { ForbiddenError } from "@casl/ability";
import { IdentityAuthMethod } from "@app/db/schemas"; import { AccessScope, IdentityAuthMethod } from "@app/db/schemas";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
import { TOrgDALFactory } from "../org/org-dal"; import { TOrgDALFactory } from "../org/org-dal";
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
@@ -15,7 +15,7 @@ import { BadRequestError, NotFoundError, PermissionBoundaryError, UnauthorizedEr
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip"; import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
import { ActorType, AuthTokenType } from "../auth/auth-type"; import { ActorType, AuthTokenType } from "../auth/auth-type";
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal"; import { TMembershipIdentityDALFactory } from "../membership-identity/membership-identity-dal";
import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal"; import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal";
import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types"; import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types";
import { validateIdentityUpdateForSuperAdminPrivileges } from "../super-admin/super-admin-fns"; import { validateIdentityUpdateForSuperAdminPrivileges } from "../super-admin/super-admin-fns";
@@ -32,7 +32,7 @@ import {
type TIdentityGcpAuthServiceFactoryDep = { type TIdentityGcpAuthServiceFactoryDep = {
identityGcpAuthDAL: Pick<TIdentityGcpAuthDALFactory, "findOne" | "transaction" | "create" | "updateById" | "delete">; identityGcpAuthDAL: Pick<TIdentityGcpAuthDALFactory, "findOne" | "transaction" | "create" | "updateById" | "delete">;
identityOrgMembershipDAL: Pick<TIdentityOrgDALFactory, "findOne" | "updateById">; membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "updateById" | "getIdentityById">;
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">; identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">;
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">; permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
licenseService: Pick<TLicenseServiceFactory, "getPlan">; licenseService: Pick<TLicenseServiceFactory, "getPlan">;
@@ -43,7 +43,7 @@ export type TIdentityGcpAuthServiceFactory = ReturnType<typeof identityGcpAuthSe
export const identityGcpAuthServiceFactory = ({ export const identityGcpAuthServiceFactory = ({
identityGcpAuthDAL, identityGcpAuthDAL,
identityOrgMembershipDAL, membershipIdentityDAL,
identityAccessTokenDAL, identityAccessTokenDAL,
permissionService, permissionService,
licenseService, licenseService,
@@ -55,7 +55,10 @@ export const identityGcpAuthServiceFactory = ({
throw new NotFoundError({ message: "GCP auth method not found for identity, did you configure GCP auth?" }); throw new NotFoundError({ message: "GCP auth method not found for identity, did you configure GCP auth?" });
} }
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId: identityGcpAuth.identityId }); const identityMembershipOrg = await membershipIdentityDAL.findOne({
actorIdentityId: identityGcpAuth.identityId,
scope: AccessScope.Organization
});
if (!identityMembershipOrg) { if (!identityMembershipOrg) {
throw new UnauthorizedError({ message: "Identity does not belong to any organization" }); throw new UnauthorizedError({ message: "Identity does not belong to any organization" });
} }
@@ -122,7 +125,7 @@ export const identityGcpAuthServiceFactory = ({
} }
const identityAccessToken = await identityGcpAuthDAL.transaction(async (tx) => { const identityAccessToken = await identityGcpAuthDAL.transaction(async (tx) => {
await identityOrgMembershipDAL.updateById( await membershipIdentityDAL.updateById(
identityMembershipOrg.id, identityMembershipOrg.id,
{ {
lastLoginAuthMethod: IdentityAuthMethod.GCP_AUTH, lastLoginAuthMethod: IdentityAuthMethod.GCP_AUTH,
@@ -182,7 +185,13 @@ export const identityGcpAuthServiceFactory = ({
}: TAttachGcpAuthDTO) => { }: TAttachGcpAuthDTO) => {
await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin); await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin);
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.GCP_AUTH)) { if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.GCP_AUTH)) {
@@ -198,13 +207,13 @@ export const identityGcpAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => { const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -225,7 +234,7 @@ export const identityGcpAuthServiceFactory = ({
const identityGcpAuth = await identityGcpAuthDAL.transaction(async (tx) => { const identityGcpAuth = await identityGcpAuthDAL.transaction(async (tx) => {
const doc = await identityGcpAuthDAL.create( const doc = await identityGcpAuthDAL.create(
{ {
identityId: identityMembershipOrg.identityId, identityId: identityMembershipOrg.identity.id,
type, type,
allowedServiceAccounts, allowedServiceAccounts,
allowedProjects, allowedProjects,
@@ -239,7 +248,7 @@ export const identityGcpAuthServiceFactory = ({
); );
return doc; return doc;
}); });
return { ...identityGcpAuth, orgId: identityMembershipOrg.orgId }; return { ...identityGcpAuth, orgId: identityMembershipOrg.scopeOrgId };
}; };
const updateGcpAuth = async ({ const updateGcpAuth = async ({
@@ -257,7 +266,13 @@ export const identityGcpAuthServiceFactory = ({
actor, actor,
actorOrgId actorOrgId
}: TUpdateGcpAuthDTO) => { }: TUpdateGcpAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.GCP_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.GCP_AUTH)) {
@@ -278,13 +293,13 @@ export const identityGcpAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => { const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -317,12 +332,18 @@ export const identityGcpAuthServiceFactory = ({
return { return {
...updatedGcpAuth, ...updatedGcpAuth,
orgId: identityMembershipOrg.orgId orgId: identityMembershipOrg.scopeOrgId
}; };
}; };
const getGcpAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetGcpAuthDTO) => { const getGcpAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetGcpAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.GCP_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.GCP_AUTH)) {
@@ -336,13 +357,13 @@ export const identityGcpAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
return { ...identityGcpAuth, orgId: identityMembershipOrg.orgId }; return { ...identityGcpAuth, orgId: identityMembershipOrg.scopeOrgId };
}; };
const revokeIdentityGcpAuth = async ({ const revokeIdentityGcpAuth = async ({
@@ -352,7 +373,13 @@ export const identityGcpAuthServiceFactory = ({
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}: TRevokeGcpAuthDTO) => { }: TRevokeGcpAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.GCP_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.GCP_AUTH)) {
@@ -363,7 +390,7 @@ export const identityGcpAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -371,12 +398,12 @@ export const identityGcpAuthServiceFactory = ({
const { permission: rolePermission } = await permissionService.getOrgPermission( const { permission: rolePermission } = await permissionService.getOrgPermission(
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identity.id,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.orgId); const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
const permissionBoundary = validatePrivilegeChangeOperation( const permissionBoundary = validatePrivilegeChangeOperation(
shouldUseNewPrivilegeSystem, shouldUseNewPrivilegeSystem,
OrgPermissionIdentityActions.RevokeAuth, OrgPermissionIdentityActions.RevokeAuth,
@@ -399,7 +426,7 @@ export const identityGcpAuthServiceFactory = ({
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);
return { ...deletedGcpAuth?.[0], orgId: identityMembershipOrg.orgId }; return { ...deletedGcpAuth?.[0], orgId: identityMembershipOrg.scopeOrgId };
}); });
return revokedIdentityGcpAuth; return revokedIdentityGcpAuth;
}; };
@@ -3,7 +3,7 @@ import https from "https";
import jwt from "jsonwebtoken"; import jwt from "jsonwebtoken";
import { JwksClient } from "jwks-rsa"; import { JwksClient } from "jwks-rsa";
import { IdentityAuthMethod, TIdentityJwtAuthsUpdate } from "@app/db/schemas"; import { AccessScope, IdentityAuthMethod, TIdentityJwtAuthsUpdate } from "@app/db/schemas";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
import { TOrgDALFactory } from "../org/org-dal"; import { TOrgDALFactory } from "../org/org-dal";
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
@@ -25,7 +25,7 @@ import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
import { getValueByDot } from "@app/lib/template/dot-access"; import { getValueByDot } from "@app/lib/template/dot-access";
import { ActorType, AuthTokenType } from "../auth/auth-type"; import { ActorType, AuthTokenType } from "../auth/auth-type";
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal"; import { TMembershipIdentityDALFactory } from "../membership-identity/membership-identity-dal";
import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal"; import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal";
import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types"; import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types";
import { TKmsServiceFactory } from "../kms/kms-service"; import { TKmsServiceFactory } from "../kms/kms-service";
@@ -44,7 +44,7 @@ import {
type TIdentityJwtAuthServiceFactoryDep = { type TIdentityJwtAuthServiceFactoryDep = {
identityJwtAuthDAL: TIdentityJwtAuthDALFactory; identityJwtAuthDAL: TIdentityJwtAuthDALFactory;
identityOrgMembershipDAL: Pick<TIdentityOrgDALFactory, "findOne" | "updateById">; membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "updateById" | "getIdentityById">;
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">; identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">;
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">; permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
licenseService: Pick<TLicenseServiceFactory, "getPlan">; licenseService: Pick<TLicenseServiceFactory, "getPlan">;
@@ -56,7 +56,7 @@ export type TIdentityJwtAuthServiceFactory = ReturnType<typeof identityJwtAuthSe
export const identityJwtAuthServiceFactory = ({ export const identityJwtAuthServiceFactory = ({
identityJwtAuthDAL, identityJwtAuthDAL,
identityOrgMembershipDAL, membershipIdentityDAL,
permissionService, permissionService,
licenseService, licenseService,
identityAccessTokenDAL, identityAccessTokenDAL,
@@ -69,8 +69,9 @@ export const identityJwtAuthServiceFactory = ({
throw new NotFoundError({ message: "JWT auth method not found for identity, did you configure JWT auth?" }); throw new NotFoundError({ message: "JWT auth method not found for identity, did you configure JWT auth?" });
} }
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ const identityMembershipOrg = await membershipIdentityDAL.findOne({
identityId: identityJwtAuth.identityId actorIdentityId: identityJwtAuth.identityId,
scope: AccessScope.Organization
}); });
if (!identityMembershipOrg) { if (!identityMembershipOrg) {
throw new NotFoundError({ throw new NotFoundError({
@@ -80,7 +81,7 @@ export const identityJwtAuthServiceFactory = ({
const { decryptor: orgDataKeyDecryptor } = await kmsService.createCipherPairWithDataKey({ const { decryptor: orgDataKeyDecryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
orgId: identityMembershipOrg.orgId orgId: identityMembershipOrg.scopeOrgId
}); });
const decodedToken = crypto.jwt().decode(jwtValue, { complete: true }); const decodedToken = crypto.jwt().decode(jwtValue, { complete: true });
@@ -210,7 +211,7 @@ export const identityJwtAuthServiceFactory = ({
} }
const identityAccessToken = await identityJwtAuthDAL.transaction(async (tx) => { const identityAccessToken = await identityJwtAuthDAL.transaction(async (tx) => {
await identityOrgMembershipDAL.updateById( await membershipIdentityDAL.updateById(
identityMembershipOrg.id, identityMembershipOrg.id,
{ {
lastLoginAuthMethod: IdentityAuthMethod.JWT_AUTH, lastLoginAuthMethod: IdentityAuthMethod.JWT_AUTH,
@@ -275,10 +276,14 @@ export const identityJwtAuthServiceFactory = ({
}: TAttachJwtAuthDTO) => { }: TAttachJwtAuthDTO) => {
await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin); await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin);
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
if (!identityMembershipOrg) { scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
}
if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.JWT_AUTH)) { if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.JWT_AUTH)) {
throw new BadRequestError({ throw new BadRequestError({
message: "Failed to add JWT Auth to already configured identity" message: "Failed to add JWT Auth to already configured identity"
@@ -292,14 +297,14 @@ export const identityJwtAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => { const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -333,7 +338,7 @@ export const identityJwtAuthServiceFactory = ({
const identityJwtAuth = await identityJwtAuthDAL.transaction(async (tx) => { const identityJwtAuth = await identityJwtAuthDAL.transaction(async (tx) => {
const doc = await identityJwtAuthDAL.create( const doc = await identityJwtAuthDAL.create(
{ {
identityId: identityMembershipOrg.identityId, identityId: identityMembershipOrg.identity.id,
configurationType, configurationType,
jwksUrl, jwksUrl,
encryptedJwksCaCert, encryptedJwksCaCert,
@@ -352,7 +357,7 @@ export const identityJwtAuthServiceFactory = ({
return doc; return doc;
}); });
return { ...identityJwtAuth, orgId: identityMembershipOrg.orgId, jwksCaCert, publicKeys }; return { ...identityJwtAuth, orgId: identityMembershipOrg.scopeOrgId, jwksCaCert, publicKeys };
}; };
const updateJwtAuth = async ({ const updateJwtAuth = async ({
@@ -374,7 +379,13 @@ export const identityJwtAuthServiceFactory = ({
actor, actor,
actorOrgId actorOrgId
}: TUpdateJwtAuthDTO) => { }: TUpdateJwtAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.JWT_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.JWT_AUTH)) {
@@ -395,14 +406,14 @@ export const identityJwtAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => { const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -465,14 +476,20 @@ export const identityJwtAuthServiceFactory = ({
return { return {
...updatedJwtAuth, ...updatedJwtAuth,
orgId: identityMembershipOrg.orgId, orgId: identityMembershipOrg.scopeOrgId,
jwksCaCert: decryptedJwksCaCert, jwksCaCert: decryptedJwksCaCert,
publicKeys: decryptedPublicKeys publicKeys: decryptedPublicKeys
}; };
}; };
const getJwtAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetJwtAuthDTO) => { const getJwtAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetJwtAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.JWT_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.JWT_AUTH)) {
@@ -484,7 +501,7 @@ export const identityJwtAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -505,14 +522,20 @@ export const identityJwtAuthServiceFactory = ({
return { return {
...identityJwtAuth, ...identityJwtAuth,
orgId: identityMembershipOrg.orgId, orgId: identityMembershipOrg.scopeOrgId,
jwksCaCert: decryptedJwksCaCert, jwksCaCert: decryptedJwksCaCert,
publicKeys: decryptedPublicKeys publicKeys: decryptedPublicKeys
}; };
}; };
const revokeJwtAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TRevokeJwtAuthDTO) => { const revokeJwtAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TRevokeJwtAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) { if (!identityMembershipOrg) {
throw new NotFoundError({ message: "Failed to find identity" }); throw new NotFoundError({ message: "Failed to find identity" });
} }
@@ -526,7 +549,7 @@ export const identityJwtAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -535,13 +558,13 @@ export const identityJwtAuthServiceFactory = ({
const { permission: rolePermission } = await permissionService.getOrgPermission( const { permission: rolePermission } = await permissionService.getOrgPermission(
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identity.id,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.orgId); const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
const permissionBoundary = validatePrivilegeChangeOperation( const permissionBoundary = validatePrivilegeChangeOperation(
shouldUseNewPrivilegeSystem, shouldUseNewPrivilegeSystem,
OrgPermissionIdentityActions.RevokeAuth, OrgPermissionIdentityActions.RevokeAuth,
@@ -564,7 +587,7 @@ export const identityJwtAuthServiceFactory = ({
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);
return { ...deletedJwtAuth?.[0], orgId: identityMembershipOrg.orgId }; return { ...deletedJwtAuth?.[0], orgId: identityMembershipOrg.scopeOrgId };
}); });
return revokedIdentityJwtAuth; return revokedIdentityJwtAuth;
@@ -3,7 +3,7 @@ import axios, { AxiosError } from "axios";
import https from "https"; import https from "https";
import RE2 from "re2"; import RE2 from "re2";
import { IdentityAuthMethod, TIdentityKubernetesAuthsUpdate } from "@app/db/schemas"; import { AccessScope, IdentityAuthMethod, TIdentityKubernetesAuthsUpdate } from "@app/db/schemas";
import { TGatewayDALFactory } from "@app/ee/services/gateway/gateway-dal"; import { TGatewayDALFactory } from "@app/ee/services/gateway/gateway-dal";
import { TGatewayServiceFactory } from "@app/ee/services/gateway/gateway-service"; import { TGatewayServiceFactory } from "@app/ee/services/gateway/gateway-service";
import { TGatewayV2DALFactory } from "@app/ee/services/gateway-v2/gateway-v2-dal"; import { TGatewayV2DALFactory } from "@app/ee/services/gateway-v2/gateway-v2-dal";
@@ -29,7 +29,7 @@ import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
import { logger } from "@app/lib/logger"; import { logger } from "@app/lib/logger";
import { ActorType, AuthTokenType } from "../auth/auth-type"; import { ActorType, AuthTokenType } from "../auth/auth-type";
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal"; import { TMembershipIdentityDALFactory } from "../membership-identity/membership-identity-dal";
import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal"; import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal";
import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types"; import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types";
import { TKmsServiceFactory } from "../kms/kms-service"; import { TKmsServiceFactory } from "../kms/kms-service";
@@ -53,7 +53,7 @@ type TIdentityKubernetesAuthServiceFactoryDep = {
"create" | "findOne" | "transaction" | "updateById" | "delete" "create" | "findOne" | "transaction" | "updateById" | "delete"
>; >;
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">; identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">;
identityOrgMembershipDAL: Pick<TIdentityOrgDALFactory, "findOne" | "findById" | "updateById">; membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "updateById" | "getIdentityById">;
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">; permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
licenseService: Pick<TLicenseServiceFactory, "getPlan">; licenseService: Pick<TLicenseServiceFactory, "getPlan">;
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">; kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
@@ -70,7 +70,7 @@ const GATEWAY_AUTH_DEFAULT_HOST = "https://kubernetes.default.svc.cluster.local"
export const identityKubernetesAuthServiceFactory = ({ export const identityKubernetesAuthServiceFactory = ({
identityKubernetesAuthDAL, identityKubernetesAuthDAL,
identityOrgMembershipDAL, membershipIdentityDAL,
identityAccessTokenDAL, identityAccessTokenDAL,
permissionService, permissionService,
licenseService, licenseService,
@@ -175,8 +175,9 @@ export const identityKubernetesAuthServiceFactory = ({
}); });
} }
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ const identityMembershipOrg = await membershipIdentityDAL.findOne({
identityId: identityKubernetesAuth.identityId actorIdentityId: identityKubernetesAuth.identityId,
scope: AccessScope.Organization
}); });
if (!identityMembershipOrg) { if (!identityMembershipOrg) {
throw new NotFoundError({ throw new NotFoundError({
@@ -186,7 +187,7 @@ export const identityKubernetesAuthServiceFactory = ({
const { decryptor } = await kmsService.createCipherPairWithDataKey({ const { decryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
orgId: identityMembershipOrg.orgId orgId: identityMembershipOrg.scopeOrgId
}); });
let caCert = ""; let caCert = "";
@@ -429,7 +430,7 @@ export const identityKubernetesAuthServiceFactory = ({
} }
const identityAccessToken = await identityKubernetesAuthDAL.transaction(async (tx) => { const identityAccessToken = await identityKubernetesAuthDAL.transaction(async (tx) => {
await identityOrgMembershipDAL.updateById( await membershipIdentityDAL.updateById(
identityMembershipOrg.id, identityMembershipOrg.id,
{ {
lastLoginAuthMethod: IdentityAuthMethod.KUBERNETES_AUTH, lastLoginAuthMethod: IdentityAuthMethod.KUBERNETES_AUTH,
@@ -499,7 +500,13 @@ export const identityKubernetesAuthServiceFactory = ({
}: TAttachKubernetesAuthDTO) => { }: TAttachKubernetesAuthDTO) => {
await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin); await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin);
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.KUBERNETES_AUTH)) { if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.KUBERNETES_AUTH)) {
@@ -515,13 +522,13 @@ export const identityKubernetesAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => { const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -541,8 +548,8 @@ export const identityKubernetesAuthServiceFactory = ({
let isGatewayV1 = true; let isGatewayV1 = true;
if (gatewayId) { if (gatewayId) {
const [gateway] = await gatewayDAL.find({ id: gatewayId, orgId: identityMembershipOrg.orgId }); const [gateway] = await gatewayDAL.find({ id: gatewayId, orgId: identityMembershipOrg.scopeOrgId });
const [gatewayV2] = await gatewayV2DAL.find({ id: gatewayId, orgId: identityMembershipOrg.orgId }); const [gatewayV2] = await gatewayV2DAL.find({ id: gatewayId, orgId: identityMembershipOrg.scopeOrgId });
if (!gateway && !gatewayV2) { if (!gateway && !gatewayV2) {
throw new NotFoundError({ throw new NotFoundError({
message: `Gateway with ID ${gatewayId} not found` message: `Gateway with ID ${gatewayId} not found`
@@ -556,7 +563,7 @@ export const identityKubernetesAuthServiceFactory = ({
const { permission: orgPermission } = await permissionService.getOrgPermission( const { permission: orgPermission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -568,13 +575,13 @@ export const identityKubernetesAuthServiceFactory = ({
const { encryptor } = await kmsService.createCipherPairWithDataKey({ const { encryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
orgId: identityMembershipOrg.orgId orgId: identityMembershipOrg.scopeOrgId
}); });
const identityKubernetesAuth = await identityKubernetesAuthDAL.transaction(async (tx) => { const identityKubernetesAuth = await identityKubernetesAuthDAL.transaction(async (tx) => {
const doc = await identityKubernetesAuthDAL.create( const doc = await identityKubernetesAuthDAL.create(
{ {
identityId: identityMembershipOrg.identityId, identityId: identityMembershipOrg.identity.id,
kubernetesHost, kubernetesHost,
tokenReviewMode, tokenReviewMode,
allowedNamespaces, allowedNamespaces,
@@ -596,7 +603,7 @@ export const identityKubernetesAuthServiceFactory = ({
return doc; return doc;
}); });
return { ...identityKubernetesAuth, caCert, tokenReviewerJwt, orgId: identityMembershipOrg.orgId }; return { ...identityKubernetesAuth, caCert, tokenReviewerJwt, orgId: identityMembershipOrg.scopeOrgId };
}; };
const updateKubernetesAuth = async ({ const updateKubernetesAuth = async ({
@@ -618,7 +625,13 @@ export const identityKubernetesAuthServiceFactory = ({
actor, actor,
actorOrgId actorOrgId
}: TUpdateKubernetesAuthDTO) => { }: TUpdateKubernetesAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.KUBERNETES_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.KUBERNETES_AUTH)) {
@@ -640,13 +653,13 @@ export const identityKubernetesAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => { const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -666,8 +679,8 @@ export const identityKubernetesAuthServiceFactory = ({
let isGatewayV1 = true; let isGatewayV1 = true;
if (gatewayId) { if (gatewayId) {
const [gateway] = await gatewayDAL.find({ id: gatewayId, orgId: identityMembershipOrg.orgId }); const [gateway] = await gatewayDAL.find({ id: gatewayId, orgId: identityMembershipOrg.scopeOrgId });
const [gatewayV2] = await gatewayV2DAL.find({ id: gatewayId, orgId: identityMembershipOrg.orgId }); const [gatewayV2] = await gatewayV2DAL.find({ id: gatewayId, orgId: identityMembershipOrg.scopeOrgId });
if (!gateway && !gatewayV2) { if (!gateway && !gatewayV2) {
throw new NotFoundError({ throw new NotFoundError({
@@ -682,7 +695,7 @@ export const identityKubernetesAuthServiceFactory = ({
const { permission: orgPermission } = await permissionService.getOrgPermission( const { permission: orgPermission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -714,7 +727,7 @@ export const identityKubernetesAuthServiceFactory = ({
const { encryptor, decryptor } = await kmsService.createCipherPairWithDataKey({ const { encryptor, decryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
orgId: identityMembershipOrg.orgId orgId: identityMembershipOrg.scopeOrgId
}); });
if (caCert !== undefined) { if (caCert !== undefined) {
@@ -745,7 +758,7 @@ export const identityKubernetesAuthServiceFactory = ({
return { return {
...updatedKubernetesAuth, ...updatedKubernetesAuth,
orgId: identityMembershipOrg.orgId, orgId: identityMembershipOrg.scopeOrgId,
caCert: updatedCACert, caCert: updatedCACert,
tokenReviewerJwt: updatedTokenReviewerJwt tokenReviewerJwt: updatedTokenReviewerJwt
}; };
@@ -758,7 +771,13 @@ export const identityKubernetesAuthServiceFactory = ({
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}: TGetKubernetesAuthDTO) => { }: TGetKubernetesAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
const identityKubernetesAuth = await identityKubernetesAuthDAL.findOne({ identityId }); const identityKubernetesAuth = await identityKubernetesAuthDAL.findOne({ identityId });
@@ -775,7 +794,7 @@ export const identityKubernetesAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -783,7 +802,7 @@ export const identityKubernetesAuthServiceFactory = ({
const { decryptor } = await kmsService.createCipherPairWithDataKey({ const { decryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
orgId: identityMembershipOrg.orgId orgId: identityMembershipOrg.scopeOrgId
}); });
let caCert = ""; let caCert = "";
@@ -802,7 +821,7 @@ export const identityKubernetesAuthServiceFactory = ({
...identityKubernetesAuth, ...identityKubernetesAuth,
caCert, caCert,
tokenReviewerJwt, tokenReviewerJwt,
orgId: identityMembershipOrg.orgId, orgId: identityMembershipOrg.scopeOrgId,
gatewayId: identityKubernetesAuth.gatewayId ?? identityKubernetesAuth.gatewayV2Id gatewayId: identityKubernetesAuth.gatewayId ?? identityKubernetesAuth.gatewayV2Id
}; };
}; };
@@ -814,7 +833,13 @@ export const identityKubernetesAuthServiceFactory = ({
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}: TRevokeKubernetesAuthDTO) => { }: TRevokeKubernetesAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.KUBERNETES_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.KUBERNETES_AUTH)) {
@@ -825,7 +850,7 @@ export const identityKubernetesAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -833,12 +858,12 @@ export const identityKubernetesAuthServiceFactory = ({
const { permission: rolePermission } = await permissionService.getOrgPermission( const { permission: rolePermission } = await permissionService.getOrgPermission(
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identity.id,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.orgId); const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
const permissionBoundary = validatePrivilegeChangeOperation( const permissionBoundary = validatePrivilegeChangeOperation(
shouldUseNewPrivilegeSystem, shouldUseNewPrivilegeSystem,
OrgPermissionIdentityActions.RevokeAuth, OrgPermissionIdentityActions.RevokeAuth,
@@ -860,7 +885,7 @@ export const identityKubernetesAuthServiceFactory = ({
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);
return { ...deletedKubernetesAuth?.[0], orgId: identityMembershipOrg.orgId }; return { ...deletedKubernetesAuth?.[0], orgId: identityMembershipOrg.scopeOrgId };
}); });
return revokedIdentityKubernetesAuth; return revokedIdentityKubernetesAuth;
}; };
@@ -2,7 +2,7 @@
import { ForbiddenError } from "@casl/ability"; import { ForbiddenError } from "@casl/ability";
import slugify from "@sindresorhus/slugify"; import slugify from "@sindresorhus/slugify";
import { IdentityAuthMethod } from "@app/db/schemas"; import { AccessScope, IdentityAuthMethod } 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";
@@ -32,7 +32,7 @@ import { logger } from "@app/lib/logger";
import { ActorType, AuthTokenType } from "../auth/auth-type"; import { ActorType, AuthTokenType } from "../auth/auth-type";
import { TIdentityDALFactory } from "../identity/identity-dal"; import { TIdentityDALFactory } from "../identity/identity-dal";
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal"; import { TMembershipIdentityDALFactory } from "../membership-identity/membership-identity-dal";
import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal"; import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal";
import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types"; import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types";
import { TKmsServiceFactory } from "../kms/kms-service"; import { TKmsServiceFactory } from "../kms/kms-service";
@@ -56,7 +56,7 @@ type TIdentityLdapAuthServiceFactoryDep = {
TIdentityLdapAuthDALFactory, TIdentityLdapAuthDALFactory,
"findOne" | "transaction" | "create" | "updateById" | "delete" "findOne" | "transaction" | "create" | "updateById" | "delete"
>; >;
identityOrgMembershipDAL: Pick<TIdentityOrgDALFactory, "findOne" | "updateById">; membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "updateById" | "getIdentityById">;
licenseService: Pick<TLicenseServiceFactory, "getPlan">; licenseService: Pick<TLicenseServiceFactory, "getPlan">;
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">; permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
kmsService: TKmsServiceFactory; kmsService: TKmsServiceFactory;
@@ -80,7 +80,7 @@ export const identityLdapAuthServiceFactory = ({
identityAccessTokenDAL, identityAccessTokenDAL,
identityDAL, identityDAL,
identityLdapAuthDAL, identityLdapAuthDAL,
identityOrgMembershipDAL, membershipIdentityDAL,
licenseService, licenseService,
permissionService, permissionService,
kmsService, kmsService,
@@ -92,7 +92,10 @@ export const identityLdapAuthServiceFactory = ({
const identity = await identityDAL.findOne({ id: identityId }); const identity = await identityDAL.findOne({ id: identityId });
if (!identity) throw new NotFoundError({ message: `Identity with ID '${identityId}' not found` }); if (!identity) throw new NotFoundError({ message: `Identity with ID '${identityId}' not found` });
const identityOrgMembership = await identityOrgMembershipDAL.findOne({ identityId: identity.id }); const identityOrgMembership = await membershipIdentityDAL.findOne({
actorIdentityId: identity.id,
scope: AccessScope.Organization
});
if (!identityOrgMembership) throw new NotFoundError({ message: `Identity with ID '${identityId}' not found` }); if (!identityOrgMembership) throw new NotFoundError({ message: `Identity with ID '${identityId}' not found` });
const ldapAuth = await identityLdapAuthDAL.findOne({ identityId: identity.id }); const ldapAuth = await identityLdapAuthDAL.findOne({ identityId: identity.id });
@@ -104,7 +107,7 @@ export const identityLdapAuthServiceFactory = ({
const { decryptor } = await kmsService.createCipherPairWithDataKey({ const { decryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
orgId: identityOrgMembership.orgId orgId: identityOrgMembership.scopeOrgId
}); });
const bindDN = decryptor({ cipherTextBlob: ldapAuth.encryptedBindDN }).toString(); const bindDN = decryptor({ cipherTextBlob: ldapAuth.encryptedBindDN }).toString();
@@ -115,7 +118,7 @@ export const identityLdapAuthServiceFactory = ({
const ldapConfig = { const ldapConfig = {
id: ldapAuth.id, id: ldapAuth.id,
organization: identityOrgMembership.orgId, organization: identityOrgMembership.scopeOrgId,
url: ldapAuth.url, url: ldapAuth.url,
bindDN, bindDN,
bindPass, bindPass,
@@ -147,7 +150,10 @@ export const identityLdapAuthServiceFactory = ({
}; };
const login = async ({ identityId }: TLoginLdapAuthDTO) => { const login = async ({ identityId }: TLoginLdapAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.findOne({
actorIdentityId: identityId,
scope: AccessScope.Organization
});
if (!identityMembershipOrg) { if (!identityMembershipOrg) {
throw new UnauthorizedError({ throw new UnauthorizedError({
@@ -163,7 +169,7 @@ export const identityLdapAuthServiceFactory = ({
}); });
} }
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
if (!plan.ldap) { if (!plan.ldap) {
throw new BadRequestError({ throw new BadRequestError({
message: message:
@@ -172,7 +178,7 @@ export const identityLdapAuthServiceFactory = ({
} }
const identityAccessToken = await identityLdapAuthDAL.transaction(async (tx) => { const identityAccessToken = await identityLdapAuthDAL.transaction(async (tx) => {
await identityOrgMembershipDAL.updateById( await membershipIdentityDAL.updateById(
identityMembershipOrg.id, identityMembershipOrg.id,
{ {
lastLoginAuthMethod: IdentityAuthMethod.LDAP_AUTH, lastLoginAuthMethod: IdentityAuthMethod.LDAP_AUTH,
@@ -240,7 +246,13 @@ export const identityLdapAuthServiceFactory = ({
}: TAttachLdapAuthDTO) => { }: TAttachLdapAuthDTO) => {
await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin); await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin);
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.LDAP_AUTH)) { if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.LDAP_AUTH)) {
@@ -256,7 +268,7 @@ export const identityLdapAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -269,7 +281,7 @@ export const identityLdapAuthServiceFactory = ({
); );
} }
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
if (!plan.ldap) { if (!plan.ldap) {
throw new BadRequestError({ throw new BadRequestError({
@@ -299,11 +311,11 @@ export const identityLdapAuthServiceFactory = ({
const identityLdapAuth = await identityLdapAuthDAL.transaction(async (tx) => { const identityLdapAuth = await identityLdapAuthDAL.transaction(async (tx) => {
const { encryptor, decryptor } = await kmsService.createCipherPairWithDataKey({ const { encryptor, decryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
orgId: identityMembershipOrg.orgId orgId: identityMembershipOrg.scopeOrgId
}); });
const template = templateId const template = templateId
? await identityAuthTemplateDAL.findByIdAndOrgId(templateId, identityMembershipOrg.orgId) ? await identityAuthTemplateDAL.findByIdAndOrgId(templateId, identityMembershipOrg.scopeOrgId)
: undefined; : undefined;
let ldapConfig: { bindDN: string; bindPass: string; searchBase: string; url: string; ldapCaCertificate?: string }; let ldapConfig: { bindDN: string; bindPass: string; searchBase: string; url: string; ldapCaCertificate?: string };
@@ -357,7 +369,7 @@ export const identityLdapAuthServiceFactory = ({
const doc = await identityLdapAuthDAL.create( const doc = await identityLdapAuthDAL.create(
{ {
identityId: identityMembershipOrg.identityId, identityId: identityMembershipOrg.identity.id,
encryptedBindDN, encryptedBindDN,
encryptedBindPass, encryptedBindPass,
searchBase: ldapConfig.searchBase, searchBase: ldapConfig.searchBase,
@@ -379,7 +391,7 @@ export const identityLdapAuthServiceFactory = ({
); );
return doc; return doc;
}); });
return { ...identityLdapAuth, orgId: identityMembershipOrg.orgId }; return { ...identityLdapAuth, orgId: identityMembershipOrg.scopeOrgId };
}; };
const updateLdapAuth = async ({ const updateLdapAuth = async ({
@@ -405,7 +417,13 @@ export const identityLdapAuthServiceFactory = ({
lockoutDurationSeconds, lockoutDurationSeconds,
lockoutCounterResetSeconds lockoutCounterResetSeconds
}: TUpdateLdapAuthDTO) => { }: TUpdateLdapAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.LDAP_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.LDAP_AUTH)) {
@@ -426,7 +444,7 @@ export const identityLdapAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -439,7 +457,7 @@ export const identityLdapAuthServiceFactory = ({
); );
} }
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
if (!plan.ldap) { if (!plan.ldap) {
throw new BadRequestError({ throw new BadRequestError({
@@ -468,11 +486,11 @@ export const identityLdapAuthServiceFactory = ({
const { encryptor, decryptor } = await kmsService.createCipherPairWithDataKey({ const { encryptor, decryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
orgId: identityMembershipOrg.orgId orgId: identityMembershipOrg.scopeOrgId
}); });
const template = templateId const template = templateId
? await identityAuthTemplateDAL.findByIdAndOrgId(templateId, identityMembershipOrg.orgId) ? await identityAuthTemplateDAL.findByIdAndOrgId(templateId, identityMembershipOrg.scopeOrgId)
: undefined; : undefined;
let config: { let config: {
bindDN?: string; bindDN?: string;
@@ -558,11 +576,17 @@ export const identityLdapAuthServiceFactory = ({
lockoutCounterResetSeconds lockoutCounterResetSeconds
}); });
return { ...updatedLdapAuth, orgId: identityMembershipOrg.orgId }; return { ...updatedLdapAuth, orgId: identityMembershipOrg.scopeOrgId };
}; };
const getLdapAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetLdapAuthDTO) => { const getLdapAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetLdapAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.LDAP_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.LDAP_AUTH)) {
@@ -576,14 +600,14 @@ export const identityLdapAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
const { decryptor } = await kmsService.createCipherPairWithDataKey({ const { decryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
orgId: identityMembershipOrg.orgId orgId: identityMembershipOrg.scopeOrgId
}); });
const bindDN = decryptor({ cipherTextBlob: ldapIdentityAuth.encryptedBindDN }).toString(); const bindDN = decryptor({ cipherTextBlob: ldapIdentityAuth.encryptedBindDN }).toString();
@@ -593,7 +617,7 @@ export const identityLdapAuthServiceFactory = ({
: undefined; : undefined;
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
return { ...ldapIdentityAuth, orgId: identityMembershipOrg.orgId, bindDN, bindPass, ldapCaCertificate }; return { ...ldapIdentityAuth, orgId: identityMembershipOrg.scopeOrgId, bindDN, bindPass, ldapCaCertificate };
}; };
const revokeIdentityLdapAuth = async ({ const revokeIdentityLdapAuth = async ({
@@ -603,7 +627,13 @@ export const identityLdapAuthServiceFactory = ({
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}: TRevokeLdapAuthDTO) => { }: TRevokeLdapAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.LDAP_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.LDAP_AUTH)) {
throw new BadRequestError({ throw new BadRequestError({
@@ -613,7 +643,7 @@ export const identityLdapAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -621,13 +651,13 @@ export const identityLdapAuthServiceFactory = ({
const { permission: rolePermission } = await permissionService.getOrgPermission( const { permission: rolePermission } = await permissionService.getOrgPermission(
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identity.id,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.orgId); const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
const permissionBoundary = validatePrivilegeChangeOperation( const permissionBoundary = validatePrivilegeChangeOperation(
shouldUseNewPrivilegeSystem, shouldUseNewPrivilegeSystem,
OrgPermissionIdentityActions.RevokeAuth, OrgPermissionIdentityActions.RevokeAuth,
@@ -651,7 +681,7 @@ export const identityLdapAuthServiceFactory = ({
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);
return { ...deletedLdapAuth, orgId: identityMembershipOrg.orgId }; return { ...deletedLdapAuth, orgId: identityMembershipOrg.scopeOrgId };
}); });
return revokedIdentityLdapAuth; return revokedIdentityLdapAuth;
}; };
@@ -740,7 +770,13 @@ export const identityLdapAuthServiceFactory = ({
actorOrgId, actorOrgId,
actorAuthMethod actorAuthMethod
}: TClearLdapAuthLockoutsDTO) => { }: TClearLdapAuthLockoutsDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.LDAP_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.LDAP_AUTH)) {
@@ -752,7 +788,7 @@ export const identityLdapAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -762,7 +798,7 @@ export const identityLdapAuthServiceFactory = ({
pattern: `lockout:identity:${identityId}:${IdentityAuthMethod.LDAP_AUTH}:*` pattern: `lockout:identity:${identityId}:${IdentityAuthMethod.LDAP_AUTH}:*`
}); });
return { deleted, identityId, orgId: identityMembershipOrg.orgId }; return { deleted, identityId, orgId: identityMembershipOrg.scopeOrgId };
}; };
return { return {
@@ -3,7 +3,7 @@ import { ForbiddenError } from "@casl/ability";
import { AxiosError } from "axios"; import { AxiosError } from "axios";
import RE2 from "re2"; import RE2 from "re2";
import { IdentityAuthMethod } from "@app/db/schemas"; import { AccessScope, IdentityAuthMethod } 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 {
@@ -19,7 +19,7 @@ import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
import { logger } from "@app/lib/logger"; import { logger } from "@app/lib/logger";
import { ActorType, AuthTokenType } from "../auth/auth-type"; import { ActorType, AuthTokenType } from "../auth/auth-type";
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal"; import { TMembershipIdentityDALFactory } from "../membership-identity/membership-identity-dal";
import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal"; import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal";
import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types"; import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types";
import { validateIdentityUpdateForSuperAdminPrivileges } from "../super-admin/super-admin-fns"; import { validateIdentityUpdateForSuperAdminPrivileges } from "../super-admin/super-admin-fns";
@@ -37,7 +37,7 @@ import { TOrgDALFactory } from "../org/org-dal";
type TIdentityOciAuthServiceFactoryDep = { type TIdentityOciAuthServiceFactoryDep = {
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">; identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">;
identityOciAuthDAL: Pick<TIdentityOciAuthDALFactory, "findOne" | "transaction" | "create" | "updateById" | "delete">; identityOciAuthDAL: Pick<TIdentityOciAuthDALFactory, "findOne" | "transaction" | "create" | "updateById" | "delete">;
identityOrgMembershipDAL: Pick<TIdentityOrgDALFactory, "findOne" | "updateById">; membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "updateById" | "getIdentityById">;
licenseService: Pick<TLicenseServiceFactory, "getPlan">; licenseService: Pick<TLicenseServiceFactory, "getPlan">;
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">; permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
orgDAL: Pick<TOrgDALFactory, "findById">; orgDAL: Pick<TOrgDALFactory, "findById">;
@@ -48,7 +48,7 @@ export type TIdentityOciAuthServiceFactory = ReturnType<typeof identityOciAuthSe
export const identityOciAuthServiceFactory = ({ export const identityOciAuthServiceFactory = ({
identityAccessTokenDAL, identityAccessTokenDAL,
identityOciAuthDAL, identityOciAuthDAL,
identityOrgMembershipDAL, membershipIdentityDAL,
licenseService, licenseService,
permissionService, permissionService,
orgDAL orgDAL
@@ -59,7 +59,10 @@ export const identityOciAuthServiceFactory = ({
throw new NotFoundError({ message: "OCI auth method not found for identity, did you configure OCI auth?" }); throw new NotFoundError({ message: "OCI auth method not found for identity, did you configure OCI auth?" });
} }
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId: identityOciAuth.identityId }); const identityMembershipOrg = await membershipIdentityDAL.findOne({
actorIdentityId: identityOciAuth.identityId,
scope: AccessScope.Organization
});
if (!identityMembershipOrg) throw new UnauthorizedError({ message: "Identity not attached to a organization" }); if (!identityMembershipOrg) throw new UnauthorizedError({ message: "Identity not attached to a organization" });
// Validate OCI host format. Ensures that the host is in "identity.<region>.oraclecloud.com" format. // Validate OCI host format. Ensures that the host is in "identity.<region>.oraclecloud.com" format.
@@ -95,7 +98,7 @@ export const identityOciAuthServiceFactory = ({
// Generate the token // Generate the token
const identityAccessToken = await identityOciAuthDAL.transaction(async (tx) => { const identityAccessToken = await identityOciAuthDAL.transaction(async (tx) => {
await identityOrgMembershipDAL.updateById( await membershipIdentityDAL.updateById(
identityMembershipOrg.id, identityMembershipOrg.id,
{ {
lastLoginAuthMethod: IdentityAuthMethod.OCI_AUTH, lastLoginAuthMethod: IdentityAuthMethod.OCI_AUTH,
@@ -157,7 +160,13 @@ export const identityOciAuthServiceFactory = ({
}: TAttachOciAuthDTO) => { }: TAttachOciAuthDTO) => {
await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin); await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin);
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.OCI_AUTH)) { if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.OCI_AUTH)) {
@@ -173,13 +182,13 @@ export const identityOciAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => { const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -200,7 +209,7 @@ export const identityOciAuthServiceFactory = ({
const identityOciAuth = await identityOciAuthDAL.transaction(async (tx) => { const identityOciAuth = await identityOciAuthDAL.transaction(async (tx) => {
const doc = await identityOciAuthDAL.create( const doc = await identityOciAuthDAL.create(
{ {
identityId: identityMembershipOrg.identityId, identityId: identityMembershipOrg.identity.id,
type: "iam", type: "iam",
tenancyOcid, tenancyOcid,
allowedUsernames, allowedUsernames,
@@ -213,7 +222,7 @@ export const identityOciAuthServiceFactory = ({
); );
return doc; return doc;
}); });
return { ...identityOciAuth, orgId: identityMembershipOrg.orgId }; return { ...identityOciAuth, orgId: identityMembershipOrg.scopeOrgId };
}; };
const updateOciAuth = async ({ const updateOciAuth = async ({
@@ -229,7 +238,13 @@ export const identityOciAuthServiceFactory = ({
actor, actor,
actorOrgId actorOrgId
}: TUpdateOciAuthDTO) => { }: TUpdateOciAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.OCI_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.OCI_AUTH)) {
@@ -250,13 +265,13 @@ export const identityOciAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => { const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -285,11 +300,17 @@ export const identityOciAuthServiceFactory = ({
: undefined : undefined
}); });
return { ...updatedOciAuth, orgId: identityMembershipOrg.orgId }; return { ...updatedOciAuth, orgId: identityMembershipOrg.scopeOrgId };
}; };
const getOciAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetOciAuthDTO) => { const getOciAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetOciAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.OCI_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.OCI_AUTH)) {
@@ -303,12 +324,12 @@ export const identityOciAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
return { ...ociIdentityAuth, orgId: identityMembershipOrg.orgId }; return { ...ociIdentityAuth, orgId: identityMembershipOrg.scopeOrgId };
}; };
const revokeIdentityOciAuth = async ({ const revokeIdentityOciAuth = async ({
@@ -318,7 +339,13 @@ export const identityOciAuthServiceFactory = ({
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}: TRevokeOciAuthDTO) => { }: TRevokeOciAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.OCI_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.OCI_AUTH)) {
throw new BadRequestError({ throw new BadRequestError({
@@ -328,7 +355,7 @@ export const identityOciAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -336,8 +363,8 @@ export const identityOciAuthServiceFactory = ({
const { permission: rolePermission } = await permissionService.getOrgPermission( const { permission: rolePermission } = await permissionService.getOrgPermission(
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identity.id,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -366,7 +393,7 @@ export const identityOciAuthServiceFactory = ({
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);
return { ...deletedOciAuth?.[0], orgId: identityMembershipOrg.orgId }; return { ...deletedOciAuth?.[0], orgId: identityMembershipOrg.scopeOrgId };
}); });
return revokedIdentityOciAuth; return revokedIdentityOciAuth;
}; };
@@ -4,7 +4,7 @@ import https from "https";
import jwt from "jsonwebtoken"; import jwt from "jsonwebtoken";
import { JwksClient } from "jwks-rsa"; import { JwksClient } from "jwks-rsa";
import { IdentityAuthMethod, TIdentityOidcAuthsUpdate } from "@app/db/schemas"; import { AccessScope, IdentityAuthMethod, TIdentityOidcAuthsUpdate } from "@app/db/schemas";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
import { TOrgDALFactory } from "../org/org-dal"; import { TOrgDALFactory } from "../org/org-dal";
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
@@ -26,7 +26,7 @@ import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
import { getValueByDot } from "@app/lib/template/dot-access"; import { getValueByDot } from "@app/lib/template/dot-access";
import { ActorType, AuthTokenType } from "../auth/auth-type"; import { ActorType, AuthTokenType } from "../auth/auth-type";
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal"; import { TMembershipIdentityDALFactory } from "../membership-identity/membership-identity-dal";
import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal"; import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal";
import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types"; import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types";
import { TKmsServiceFactory } from "../kms/kms-service"; import { TKmsServiceFactory } from "../kms/kms-service";
@@ -44,7 +44,7 @@ import {
type TIdentityOidcAuthServiceFactoryDep = { type TIdentityOidcAuthServiceFactoryDep = {
identityOidcAuthDAL: TIdentityOidcAuthDALFactory; identityOidcAuthDAL: TIdentityOidcAuthDALFactory;
identityOrgMembershipDAL: Pick<TIdentityOrgDALFactory, "findOne" | "updateById">; membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "updateById" | "getIdentityById">;
identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">; identityAccessTokenDAL: Pick<TIdentityAccessTokenDALFactory, "create" | "delete">;
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">; permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
licenseService: Pick<TLicenseServiceFactory, "getPlan">; licenseService: Pick<TLicenseServiceFactory, "getPlan">;
@@ -56,7 +56,7 @@ export type TIdentityOidcAuthServiceFactory = ReturnType<typeof identityOidcAuth
export const identityOidcAuthServiceFactory = ({ export const identityOidcAuthServiceFactory = ({
identityOidcAuthDAL, identityOidcAuthDAL,
identityOrgMembershipDAL, membershipIdentityDAL,
permissionService, permissionService,
licenseService, licenseService,
identityAccessTokenDAL, identityAccessTokenDAL,
@@ -69,8 +69,9 @@ export const identityOidcAuthServiceFactory = ({
throw new NotFoundError({ message: "OIDC auth method not found for identity, did you configure OIDC auth?" }); throw new NotFoundError({ message: "OIDC auth method not found for identity, did you configure OIDC auth?" });
} }
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ const identityMembershipOrg = await membershipIdentityDAL.findOne({
identityId: identityOidcAuth.identityId actorIdentityId: identityOidcAuth.identityId,
scope: AccessScope.Organization
}); });
if (!identityMembershipOrg) { if (!identityMembershipOrg) {
throw new NotFoundError({ throw new NotFoundError({
@@ -80,7 +81,7 @@ export const identityOidcAuthServiceFactory = ({
const { decryptor } = await kmsService.createCipherPairWithDataKey({ const { decryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
orgId: identityMembershipOrg.orgId orgId: identityMembershipOrg.scopeOrgId
}); });
let caCert = ""; let caCert = "";
@@ -181,7 +182,7 @@ export const identityOidcAuthServiceFactory = ({
} }
const identityAccessToken = await identityOidcAuthDAL.transaction(async (tx) => { const identityAccessToken = await identityOidcAuthDAL.transaction(async (tx) => {
await identityOrgMembershipDAL.updateById( await membershipIdentityDAL.updateById(
identityMembershipOrg.id, identityMembershipOrg.id,
{ {
lastLoginAuthMethod: IdentityAuthMethod.OIDC_AUTH, lastLoginAuthMethod: IdentityAuthMethod.OIDC_AUTH,
@@ -248,7 +249,13 @@ export const identityOidcAuthServiceFactory = ({
isActorSuperAdmin isActorSuperAdmin
}: TAttachOidcAuthDTO) => { }: TAttachOidcAuthDTO) => {
await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin); await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin);
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) { if (!identityMembershipOrg) {
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
} }
@@ -265,14 +272,14 @@ export const identityOidcAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => { const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -292,13 +299,13 @@ export const identityOidcAuthServiceFactory = ({
const { encryptor } = await kmsService.createCipherPairWithDataKey({ const { encryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
orgId: identityMembershipOrg.orgId orgId: identityMembershipOrg.scopeOrgId
}); });
const identityOidcAuth = await identityOidcAuthDAL.transaction(async (tx) => { const identityOidcAuth = await identityOidcAuthDAL.transaction(async (tx) => {
const doc = await identityOidcAuthDAL.create( const doc = await identityOidcAuthDAL.create(
{ {
identityId: identityMembershipOrg.identityId, identityId: identityMembershipOrg.identity.id,
oidcDiscoveryUrl, oidcDiscoveryUrl,
encryptedCaCertificate: encryptor({ plainText: Buffer.from(caCert) }).cipherTextBlob, encryptedCaCertificate: encryptor({ plainText: Buffer.from(caCert) }).cipherTextBlob,
boundIssuer, boundIssuer,
@@ -315,7 +322,7 @@ export const identityOidcAuthServiceFactory = ({
); );
return doc; return doc;
}); });
return { ...identityOidcAuth, orgId: identityMembershipOrg.orgId, caCert }; return { ...identityOidcAuth, orgId: identityMembershipOrg.scopeOrgId, caCert };
}; };
const updateOidcAuth = async ({ const updateOidcAuth = async ({
@@ -336,7 +343,13 @@ export const identityOidcAuthServiceFactory = ({
actor, actor,
actorOrgId actorOrgId
}: TUpdateOidcAuthDTO) => { }: TUpdateOidcAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.OIDC_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.OIDC_AUTH)) {
@@ -357,14 +370,14 @@ export const identityOidcAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => { const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -399,7 +412,7 @@ export const identityOidcAuthServiceFactory = ({
const { encryptor, decryptor } = await kmsService.createCipherPairWithDataKey({ const { encryptor, decryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
orgId: identityMembershipOrg.orgId orgId: identityMembershipOrg.scopeOrgId
}); });
if (caCert !== undefined) { if (caCert !== undefined) {
@@ -413,13 +426,19 @@ export const identityOidcAuthServiceFactory = ({
return { return {
...updatedOidcAuth, ...updatedOidcAuth,
orgId: identityMembershipOrg.orgId, orgId: identityMembershipOrg.scopeOrgId,
caCert: updatedCACert caCert: updatedCACert
}; };
}; };
const getOidcAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetOidcAuthDTO) => { const getOidcAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetOidcAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.OIDC_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.OIDC_AUTH)) {
@@ -431,7 +450,7 @@ export const identityOidcAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -441,18 +460,24 @@ export const identityOidcAuthServiceFactory = ({
const { decryptor } = await kmsService.createCipherPairWithDataKey({ const { decryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
orgId: identityMembershipOrg.orgId orgId: identityMembershipOrg.scopeOrgId
}); });
const caCert = identityOidcAuth.encryptedCaCertificate const caCert = identityOidcAuth.encryptedCaCertificate
? decryptor({ cipherTextBlob: identityOidcAuth.encryptedCaCertificate }).toString() ? decryptor({ cipherTextBlob: identityOidcAuth.encryptedCaCertificate }).toString()
: ""; : "";
return { ...identityOidcAuth, orgId: identityMembershipOrg.orgId, caCert }; return { ...identityOidcAuth, orgId: identityMembershipOrg.scopeOrgId, caCert };
}; };
const revokeOidcAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TRevokeOidcAuthDTO) => { const revokeOidcAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TRevokeOidcAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) { if (!identityMembershipOrg) {
throw new NotFoundError({ message: "Failed to find identity" }); throw new NotFoundError({ message: "Failed to find identity" });
} }
@@ -466,7 +491,7 @@ export const identityOidcAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -475,13 +500,13 @@ export const identityOidcAuthServiceFactory = ({
const { permission: rolePermission } = await permissionService.getOrgPermission( const { permission: rolePermission } = await permissionService.getOrgPermission(
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identity.id,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.orgId); const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
const permissionBoundary = validatePrivilegeChangeOperation( const permissionBoundary = validatePrivilegeChangeOperation(
shouldUseNewPrivilegeSystem, shouldUseNewPrivilegeSystem,
OrgPermissionIdentityActions.RevokeAuth, OrgPermissionIdentityActions.RevokeAuth,
@@ -505,7 +530,7 @@ export const identityOidcAuthServiceFactory = ({
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);
return { ...deletedOidcAuth?.[0], orgId: identityMembershipOrg.orgId }; return { ...deletedOidcAuth?.[0], orgId: identityMembershipOrg.scopeOrgId };
}); });
return revokedIdentityOidcAuth; return revokedIdentityOidcAuth;
@@ -1,46 +1,22 @@
import { ForbiddenError, subject } from "@casl/ability"; import { ForbiddenError, subject } from "@casl/ability";
import { ActionProjectType, ProjectMembershipRole } from "@app/db/schemas"; import { AccessScope, ActionProjectType } from "@app/db/schemas";
import {
constructPermissionErrorMessage,
validatePrivilegeChangeOperation
} 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 { ProjectPermissionIdentityActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
import { BadRequestError, NotFoundError, PermissionBoundaryError } from "@app/lib/errors"; import { NotFoundError } from "@app/lib/errors";
import { groupBy } from "@app/lib/fn";
import { ms } from "@app/lib/ms";
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal"; import { TMembershipIdentityDALFactory } from "../membership-identity/membership-identity-dal";
import { TOrgDALFactory } from "../org/org-dal";
import { TProjectDALFactory } from "../project/project-dal";
import { ProjectUserMembershipTemporaryMode } from "../project-membership/project-membership-types";
import { TProjectRoleDALFactory } from "../project-role/project-role-dal";
import { TIdentityProjectDALFactory } from "./identity-project-dal"; import { TIdentityProjectDALFactory } from "./identity-project-dal";
import { TIdentityProjectMembershipRoleDALFactory } from "./identity-project-membership-role-dal";
import { import {
TCreateProjectIdentityDTO,
TDeleteProjectIdentityDTO,
TGetProjectIdentityByIdentityIdDTO, TGetProjectIdentityByIdentityIdDTO,
TGetProjectIdentityByMembershipIdDTO, TGetProjectIdentityByMembershipIdDTO,
TListProjectIdentityDTO, TListProjectIdentityDTO
TUpdateProjectIdentityDTO
} from "./identity-project-types"; } from "./identity-project-types";
type TIdentityProjectServiceFactoryDep = { type TIdentityProjectServiceFactoryDep = {
identityProjectDAL: TIdentityProjectDALFactory; identityProjectDAL: TIdentityProjectDALFactory;
orgDAL: Pick<TOrgDALFactory, "findById">; permissionService: Pick<TPermissionServiceFactory, "getProjectPermission" | "getProjectPermissionByRoles">;
identityProjectMembershipRoleDAL: Pick< membershipIdentityDAL: TMembershipIdentityDALFactory;
TIdentityProjectMembershipRoleDALFactory,
"create" | "transaction" | "insertMany" | "delete"
>;
projectDAL: Pick<TProjectDALFactory, "findById">;
projectRoleDAL: Pick<TProjectRoleDALFactory, "find">;
identityOrgMembershipDAL: Pick<TIdentityOrgDALFactory, "findOne">;
permissionService: Pick<
TPermissionServiceFactory,
"getProjectPermission" | "getProjectPermissionByRoles" | "invalidateProjectPermissionCache"
>;
}; };
export type TIdentityProjectServiceFactory = ReturnType<typeof identityProjectServiceFactory>; export type TIdentityProjectServiceFactory = ReturnType<typeof identityProjectServiceFactory>;
@@ -48,275 +24,8 @@ export type TIdentityProjectServiceFactory = ReturnType<typeof identityProjectSe
export const identityProjectServiceFactory = ({ export const identityProjectServiceFactory = ({
identityProjectDAL, identityProjectDAL,
permissionService, permissionService,
identityOrgMembershipDAL, membershipIdentityDAL
identityProjectMembershipRoleDAL,
projectDAL,
projectRoleDAL,
orgDAL
}: TIdentityProjectServiceFactoryDep) => { }: TIdentityProjectServiceFactoryDep) => {
const createProjectIdentity = async ({
identityId,
actor,
actorId,
actorOrgId,
actorAuthMethod,
projectId,
roles
}: TCreateProjectIdentityDTO) => {
const { permission } = await permissionService.getProjectPermission({
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId,
actionProjectType: ActionProjectType.Any
});
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionIdentityActions.Create,
subject(ProjectPermissionSub.Identity, {
identityId
})
);
const existingIdentity = await identityProjectDAL.findOne({ identityId, projectId });
if (existingIdentity)
throw new BadRequestError({
message: `Identity with ID ${identityId} already exists in project with ID ${projectId}`
});
const project = await projectDAL.findById(projectId);
const identityOrgMembership = await identityOrgMembershipDAL.findOne({
identityId,
orgId: project.orgId
});
if (!identityOrgMembership)
throw new NotFoundError({
message: `Failed to find identity with ID ${identityId}`
});
const providedRolePermissionDetails = await permissionService.getProjectPermissionByRoles(
roles.map((el) => el.role).filter((el) => el !== ProjectMembershipRole.NoAccess),
projectId
);
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(actorOrgId);
for await (const { permission: rolePermission } of providedRolePermissionDetails) {
const permissionBoundary = validatePrivilegeChangeOperation(
shouldUseNewPrivilegeSystem,
ProjectPermissionIdentityActions.GrantPrivileges,
ProjectPermissionSub.Identity,
permission,
rolePermission
);
if (!permissionBoundary.isValid)
throw new PermissionBoundaryError({
message: constructPermissionErrorMessage(
"Failed to assign to role",
shouldUseNewPrivilegeSystem,
ProjectPermissionIdentityActions.GrantPrivileges,
ProjectPermissionSub.Identity
),
details: { missingPermissions: permissionBoundary.missingPermissions }
});
}
// validate custom roles input
const customInputRoles = roles.filter(
({ role }) => !Object.values(ProjectMembershipRole).includes(role as ProjectMembershipRole)
);
const hasCustomRole = Boolean(customInputRoles.length);
const customRoles = hasCustomRole
? await projectRoleDAL.find({
projectId,
$in: { slug: customInputRoles.map(({ role }) => role) }
})
: [];
if (customRoles.length !== customInputRoles.length)
throw new NotFoundError({ message: "One or more custom project roles not found" });
const customRolesGroupBySlug = groupBy(customRoles, ({ slug }) => slug);
const projectIdentity = await identityProjectDAL.transaction(async (tx) => {
const identityProjectMembership = await identityProjectDAL.create(
{
identityId,
projectId: project.id
},
tx
);
const sanitizedProjectMembershipRoles = roles.map((inputRole) => {
const isCustomRole = Boolean(customRolesGroupBySlug?.[inputRole.role]?.[0]);
if (!inputRole.isTemporary) {
return {
projectMembershipId: identityProjectMembership.id,
role: isCustomRole ? ProjectMembershipRole.Custom : inputRole.role,
customRoleId: customRolesGroupBySlug[inputRole.role] ? customRolesGroupBySlug[inputRole.role][0].id : null
};
}
// check cron or relative here later for now its just relative
const relativeTimeInMs = ms(inputRole.temporaryRange);
return {
projectMembershipId: identityProjectMembership.id,
role: isCustomRole ? ProjectMembershipRole.Custom : inputRole.role,
customRoleId: customRolesGroupBySlug[inputRole.role] ? customRolesGroupBySlug[inputRole.role][0].id : null,
isTemporary: true,
temporaryMode: ProjectUserMembershipTemporaryMode.Relative,
temporaryRange: inputRole.temporaryRange,
temporaryAccessStartTime: new Date(inputRole.temporaryAccessStartTime),
temporaryAccessEndTime: new Date(new Date(inputRole.temporaryAccessStartTime).getTime() + relativeTimeInMs)
};
});
const identityRoles = await identityProjectMembershipRoleDAL.insertMany(sanitizedProjectMembershipRoles, tx);
return { ...identityProjectMembership, roles: identityRoles };
});
await permissionService.invalidateProjectPermissionCache(projectId);
return projectIdentity;
};
const updateProjectIdentity = async ({
projectId,
identityId,
roles,
actor,
actorId,
actorAuthMethod,
actorOrgId
}: TUpdateProjectIdentityDTO) => {
const { permission } = await permissionService.getProjectPermission({
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId,
actionProjectType: ActionProjectType.Any
});
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionIdentityActions.Edit,
subject(ProjectPermissionSub.Identity, { identityId })
);
const projectIdentity = await identityProjectDAL.findOne({ identityId, projectId });
if (!projectIdentity)
throw new NotFoundError({
message: `Identity with ID ${identityId} doesn't exists in project with ID ${projectId}`
});
const providedRolePermissionDetails = await permissionService.getProjectPermissionByRoles(
roles.map((el) => el.role).filter((el) => el !== ProjectMembershipRole.NoAccess),
projectId
);
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(actorOrgId);
for await (const { permission: rolePermission } of providedRolePermissionDetails) {
const permissionBoundary = validatePrivilegeChangeOperation(
shouldUseNewPrivilegeSystem,
ProjectPermissionIdentityActions.GrantPrivileges,
ProjectPermissionSub.Identity,
permission,
rolePermission
);
if (!permissionBoundary.isValid)
throw new PermissionBoundaryError({
message: constructPermissionErrorMessage(
"Failed to change role",
shouldUseNewPrivilegeSystem,
ProjectPermissionIdentityActions.GrantPrivileges,
ProjectPermissionSub.Identity
),
details: { missingPermissions: permissionBoundary.missingPermissions }
});
}
// validate custom roles input
const customInputRoles = roles.filter(
({ role }) =>
!Object.values(ProjectMembershipRole)
// we don't want to include custom in this check;
// this unintentionally enables setting slug to custom which is reserved
.filter((r) => r !== ProjectMembershipRole.Custom)
.includes(role as ProjectMembershipRole.Admin)
);
const hasCustomRole = Boolean(customInputRoles.length);
const customRoles = hasCustomRole
? await projectRoleDAL.find({
projectId,
$in: { slug: customInputRoles.map(({ role }) => role) }
})
: [];
if (customRoles.length !== customInputRoles.length)
throw new NotFoundError({ message: "One or more custom project roles not found" });
const customRolesGroupBySlug = groupBy(customRoles, ({ slug }) => slug);
const sanitizedProjectMembershipRoles = roles.map((inputRole) => {
const isCustomRole = Boolean(customRolesGroupBySlug?.[inputRole.role]?.[0]);
if (!inputRole.isTemporary) {
return {
projectMembershipId: projectIdentity.id,
role: isCustomRole ? ProjectMembershipRole.Custom : inputRole.role,
customRoleId: customRolesGroupBySlug[inputRole.role] ? customRolesGroupBySlug[inputRole.role][0].id : null
};
}
// check cron or relative here later for now its just relative
const relativeTimeInMs = ms(inputRole.temporaryRange);
return {
projectMembershipId: projectIdentity.id,
role: isCustomRole ? ProjectMembershipRole.Custom : inputRole.role,
customRoleId: customRolesGroupBySlug[inputRole.role] ? customRolesGroupBySlug[inputRole.role][0].id : null,
isTemporary: true,
temporaryMode: ProjectUserMembershipTemporaryMode.Relative,
temporaryRange: inputRole.temporaryRange,
temporaryAccessStartTime: new Date(inputRole.temporaryAccessStartTime),
temporaryAccessEndTime: new Date(new Date(inputRole.temporaryAccessStartTime).getTime() + relativeTimeInMs)
};
});
const updatedRoles = await identityProjectMembershipRoleDAL.transaction(async (tx) => {
await identityProjectMembershipRoleDAL.delete({ projectMembershipId: projectIdentity.id }, tx);
return identityProjectMembershipRoleDAL.insertMany(sanitizedProjectMembershipRoles, tx);
});
await permissionService.invalidateProjectPermissionCache(projectId);
return updatedRoles;
};
const deleteProjectIdentity = async ({
identityId,
actorId,
actor,
actorOrgId,
actorAuthMethod,
projectId
}: TDeleteProjectIdentityDTO) => {
const identityProjectMembership = await identityProjectDAL.findOne({ identityId, projectId });
if (!identityProjectMembership) {
throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
}
const { permission } = await permissionService.getProjectPermission({
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId,
actionProjectType: ActionProjectType.Any
});
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionIdentityActions.Delete,
subject(ProjectPermissionSub.Identity, { identityId })
);
const [deletedIdentity] = await identityProjectDAL.delete({ identityId, projectId });
await permissionService.invalidateProjectPermissionCache(projectId);
return deletedIdentity;
};
const listProjectIdentities = async ({ const listProjectIdentities = async ({
projectId, projectId,
actor, actor,
@@ -392,9 +101,13 @@ export const identityProjectServiceFactory = ({
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}: TGetProjectIdentityByMembershipIdDTO) => { }: TGetProjectIdentityByMembershipIdDTO) => {
const membership = await identityProjectDAL.findOne({ id: identityMembershipId }); const membership = await membershipIdentityDAL.findOne({
id: identityMembershipId,
scope: AccessScope.Project,
scopeOrgId: actorOrgId
});
if (!membership) { if (!membership || !membership.scopeProjectId || !membership.actorIdentityId) {
throw new NotFoundError({ throw new NotFoundError({
message: `Project membership with ID '${identityMembershipId}' not found` message: `Project membership with ID '${identityMembershipId}' not found`
}); });
@@ -403,7 +116,7 @@ export const identityProjectServiceFactory = ({
const { permission } = await permissionService.getProjectPermission({ const { permission } = await permissionService.getProjectPermission({
actor, actor,
actorId, actorId,
projectId: membership.projectId, projectId: membership.scopeProjectId,
actorAuthMethod, actorAuthMethod,
actorOrgId, actorOrgId,
actionProjectType: ActionProjectType.Any actionProjectType: ActionProjectType.Any
@@ -411,20 +124,17 @@ export const identityProjectServiceFactory = ({
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionIdentityActions.Read, ProjectPermissionIdentityActions.Read,
subject(ProjectPermissionSub.Identity, { identityId: membership.identityId }) subject(ProjectPermissionSub.Identity, { identityId: membership.actorIdentityId })
); );
const [identityMembership] = await identityProjectDAL.findByProjectId(membership.projectId, { const [identityMembership] = await identityProjectDAL.findByProjectId(membership.scopeProjectId, {
identityId: membership.identityId identityId: membership.actorIdentityId
}); });
return identityMembership; return identityMembership;
}; };
return { return {
createProjectIdentity,
updateProjectIdentity,
deleteProjectIdentity,
listProjectIdentities, listProjectIdentities,
getProjectIdentityByIdentityId, getProjectIdentityByIdentityId,
getProjectIdentityByMembershipId getProjectIdentityByMembershipId
@@ -1,6 +1,6 @@
import { ForbiddenError } from "@casl/ability"; import { ForbiddenError } from "@casl/ability";
import { IdentityAuthMethod } from "@app/db/schemas"; import { AccessScope, IdentityAuthMethod } from "@app/db/schemas";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
import { TOrgDALFactory } from "../org/org-dal"; import { TOrgDALFactory } from "../org/org-dal";
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
@@ -16,7 +16,7 @@ import { BadRequestError, NotFoundError, PermissionBoundaryError, UnauthorizedEr
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip"; import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
import { ActorType, AuthTokenType } from "../auth/auth-type"; import { ActorType, AuthTokenType } from "../auth/auth-type";
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal"; import { TMembershipIdentityDALFactory } from "../membership-identity/membership-identity-dal";
import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal"; import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal";
import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types"; import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types";
import { TKmsServiceFactory } from "../kms/kms-service"; import { TKmsServiceFactory } from "../kms/kms-service";
@@ -31,7 +31,7 @@ type TIdentityTlsCertAuthServiceFactoryDep = {
TIdentityTlsCertAuthDALFactory, TIdentityTlsCertAuthDALFactory,
"findOne" | "transaction" | "create" | "updateById" | "delete" "findOne" | "transaction" | "create" | "updateById" | "delete"
>; >;
identityOrgMembershipDAL: Pick<TIdentityOrgDALFactory, "findOne" | "updateById">; membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "updateById" | "getIdentityById">;
licenseService: Pick<TLicenseServiceFactory, "getPlan">; licenseService: Pick<TLicenseServiceFactory, "getPlan">;
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">; permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">; kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
@@ -50,7 +50,7 @@ const parseSubjectDetails = (data: string) => {
export const identityTlsCertAuthServiceFactory = ({ export const identityTlsCertAuthServiceFactory = ({
identityAccessTokenDAL, identityAccessTokenDAL,
identityTlsCertAuthDAL, identityTlsCertAuthDAL,
identityOrgMembershipDAL, membershipIdentityDAL,
licenseService, licenseService,
permissionService, permissionService,
kmsService, kmsService,
@@ -64,8 +64,9 @@ export const identityTlsCertAuthServiceFactory = ({
}); });
} }
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ const identityMembershipOrg = await membershipIdentityDAL.findOne({
identityId: identityTlsCertAuth.identityId actorIdentityId: identityTlsCertAuth.identityId,
scope: AccessScope.Organization
}); });
if (!identityMembershipOrg) { if (!identityMembershipOrg) {
@@ -76,7 +77,7 @@ export const identityTlsCertAuthServiceFactory = ({
const { decryptor } = await kmsService.createCipherPairWithDataKey({ const { decryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
orgId: identityMembershipOrg.orgId orgId: identityMembershipOrg.scopeOrgId
}); });
const caCertificate = decryptor({ const caCertificate = decryptor({
@@ -121,7 +122,7 @@ export const identityTlsCertAuthServiceFactory = ({
// Generate the token // Generate the token
const identityAccessToken = await identityTlsCertAuthDAL.transaction(async (tx) => { const identityAccessToken = await identityTlsCertAuthDAL.transaction(async (tx) => {
await identityOrgMembershipDAL.updateById( await membershipIdentityDAL.updateById(
identityMembershipOrg.id, identityMembershipOrg.id,
{ {
lastLoginAuthMethod: IdentityAuthMethod.TLS_CERT_AUTH, lastLoginAuthMethod: IdentityAuthMethod.TLS_CERT_AUTH,
@@ -183,7 +184,13 @@ export const identityTlsCertAuthServiceFactory = ({
}) => { }) => {
await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin); await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin);
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TLS_CERT_AUTH)) { if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TLS_CERT_AUTH)) {
@@ -199,13 +206,13 @@ export const identityTlsCertAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => { const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -225,13 +232,13 @@ export const identityTlsCertAuthServiceFactory = ({
const { encryptor } = await kmsService.createCipherPairWithDataKey({ const { encryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
orgId: identityMembershipOrg.orgId orgId: identityMembershipOrg.scopeOrgId
}); });
const identityTlsCertAuth = await identityTlsCertAuthDAL.transaction(async (tx) => { const identityTlsCertAuth = await identityTlsCertAuthDAL.transaction(async (tx) => {
const doc = await identityTlsCertAuthDAL.create( const doc = await identityTlsCertAuthDAL.create(
{ {
identityId: identityMembershipOrg.identityId, identityId: identityMembershipOrg.identity.id,
accessTokenMaxTTL, accessTokenMaxTTL,
allowedCommonNames, allowedCommonNames,
accessTokenTTL, accessTokenTTL,
@@ -243,7 +250,7 @@ export const identityTlsCertAuthServiceFactory = ({
); );
return doc; return doc;
}); });
return { ...identityTlsCertAuth, orgId: identityMembershipOrg.orgId }; return { ...identityTlsCertAuth, orgId: identityMembershipOrg.scopeOrgId };
}; };
const updateTlsCertAuth: TIdentityTlsCertAuthServiceFactory["updateTlsCertAuth"] = async ({ const updateTlsCertAuth: TIdentityTlsCertAuthServiceFactory["updateTlsCertAuth"] = async ({
@@ -259,7 +266,13 @@ export const identityTlsCertAuthServiceFactory = ({
actor, actor,
actorOrgId actorOrgId
}) => { }) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TLS_CERT_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TLS_CERT_AUTH)) {
@@ -281,13 +294,13 @@ export const identityTlsCertAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => { const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -306,7 +319,7 @@ export const identityTlsCertAuthServiceFactory = ({
}); });
const { encryptor } = await kmsService.createCipherPairWithDataKey({ const { encryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
orgId: identityMembershipOrg.orgId orgId: identityMembershipOrg.scopeOrgId
}); });
const updatedTlsCertAuth = await identityTlsCertAuthDAL.updateById(identityTlsCertAuth.id, { const updatedTlsCertAuth = await identityTlsCertAuthDAL.updateById(identityTlsCertAuth.id, {
@@ -322,7 +335,7 @@ export const identityTlsCertAuthServiceFactory = ({
: undefined : undefined
}); });
return { ...updatedTlsCertAuth, orgId: identityMembershipOrg.orgId }; return { ...updatedTlsCertAuth, orgId: identityMembershipOrg.scopeOrgId };
}; };
const getTlsCertAuth: TIdentityTlsCertAuthServiceFactory["getTlsCertAuth"] = async ({ const getTlsCertAuth: TIdentityTlsCertAuthServiceFactory["getTlsCertAuth"] = async ({
@@ -332,7 +345,13 @@ export const identityTlsCertAuthServiceFactory = ({
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}) => { }) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TLS_CERT_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TLS_CERT_AUTH)) {
@@ -346,21 +365,21 @@ export const identityTlsCertAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity); 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.orgId orgId: identityMembershipOrg.scopeOrgId
}); });
let caCertificate = ""; let caCertificate = "";
if (identityAuth.encryptedCaCertificate) { if (identityAuth.encryptedCaCertificate) {
caCertificate = decryptor({ cipherTextBlob: identityAuth.encryptedCaCertificate }).toString(); caCertificate = decryptor({ cipherTextBlob: identityAuth.encryptedCaCertificate }).toString();
} }
return { ...identityAuth, caCertificate, orgId: identityMembershipOrg.orgId }; return { ...identityAuth, caCertificate, orgId: identityMembershipOrg.scopeOrgId };
}; };
const revokeTlsCertAuth: TIdentityTlsCertAuthServiceFactory["revokeTlsCertAuth"] = async ({ const revokeTlsCertAuth: TIdentityTlsCertAuthServiceFactory["revokeTlsCertAuth"] = async ({
@@ -370,7 +389,13 @@ export const identityTlsCertAuthServiceFactory = ({
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}) => { }) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TLS_CERT_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TLS_CERT_AUTH)) {
throw new BadRequestError({ throw new BadRequestError({
@@ -380,7 +405,7 @@ export const identityTlsCertAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -388,13 +413,13 @@ export const identityTlsCertAuthServiceFactory = ({
const { permission: rolePermission } = await permissionService.getOrgPermission( const { permission: rolePermission } = await permissionService.getOrgPermission(
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identity.id,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.orgId); const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
const permissionBoundary = validatePrivilegeChangeOperation( const permissionBoundary = validatePrivilegeChangeOperation(
shouldUseNewPrivilegeSystem, shouldUseNewPrivilegeSystem,
OrgPermissionIdentityActions.RevokeAuth, OrgPermissionIdentityActions.RevokeAuth,
@@ -418,7 +443,7 @@ export const identityTlsCertAuthServiceFactory = ({
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);
return { ...deletedTlsCertAuth?.[0], orgId: identityMembershipOrg.orgId }; return { ...deletedTlsCertAuth?.[0], orgId: identityMembershipOrg.scopeOrgId };
}); });
return revokedIdentityTlsCertAuth; return revokedIdentityTlsCertAuth;
}; };
@@ -1,4 +1,4 @@
import { TIdentityAccessTokens, TIdentityOrgMemberships, TIdentityTlsCertAuths } from "@app/db/schemas"; import { TIdentityAccessTokens, TMemberships, TIdentityTlsCertAuths } from "@app/db/schemas";
import { TProjectPermission } from "@app/lib/types"; import { TProjectPermission } from "@app/lib/types";
export type TLoginTlsCertAuthDTO = { export type TLoginTlsCertAuthDTO = {
@@ -40,7 +40,7 @@ export type TIdentityTlsCertAuthServiceFactory = {
identityTlsCertAuth: TIdentityTlsCertAuths; identityTlsCertAuth: TIdentityTlsCertAuths;
accessToken: string; accessToken: string;
identityAccessToken: TIdentityAccessTokens; identityAccessToken: TIdentityAccessTokens;
identityMembershipOrg: TIdentityOrgMemberships; identityMembershipOrg: TMemberships;
}>; }>;
attachTlsCertAuth: (dto: TAttachTlsCertAuthDTO) => Promise<TIdentityTlsCertAuths>; attachTlsCertAuth: (dto: TAttachTlsCertAuthDTO) => Promise<TIdentityTlsCertAuths>;
updateTlsCertAuth: (dto: TUpdateTlsCertAuthDTO) => Promise<TIdentityTlsCertAuths>; updateTlsCertAuth: (dto: TUpdateTlsCertAuthDTO) => Promise<TIdentityTlsCertAuths>;
@@ -1,6 +1,6 @@
import { ForbiddenError } from "@casl/ability"; import { ForbiddenError } from "@casl/ability";
import { IdentityAuthMethod, TableName } from "@app/db/schemas"; import { AccessScope, IdentityAuthMethod, TableName } from "@app/db/schemas";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
import { TOrgDALFactory } from "../org/org-dal"; import { TOrgDALFactory } from "../org/org-dal";
import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
@@ -15,7 +15,7 @@ import { BadRequestError, NotFoundError, PermissionBoundaryError } from "@app/li
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip"; import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
import { ActorType, AuthTokenType } from "../auth/auth-type"; import { ActorType, AuthTokenType } from "../auth/auth-type";
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal"; import { TMembershipIdentityDALFactory } from "../membership-identity/membership-identity-dal";
import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal"; import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal";
import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types"; import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types";
import { validateIdentityUpdateForSuperAdminPrivileges } from "../super-admin/super-admin-fns"; import { validateIdentityUpdateForSuperAdminPrivileges } from "../super-admin/super-admin-fns";
@@ -36,7 +36,7 @@ type TIdentityTokenAuthServiceFactoryDep = {
TIdentityTokenAuthDALFactory, TIdentityTokenAuthDALFactory,
"transaction" | "create" | "findOne" | "updateById" | "delete" "transaction" | "create" | "findOne" | "updateById" | "delete"
>; >;
identityOrgMembershipDAL: Pick<TIdentityOrgDALFactory, "findOne" | "updateById">; membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "findOne" | "updateById" | "getIdentityById">;
identityAccessTokenDAL: Pick< identityAccessTokenDAL: Pick<
TIdentityAccessTokenDALFactory, TIdentityAccessTokenDALFactory,
"create" | "find" | "update" | "findById" | "findOne" | "updateById" | "delete" "create" | "find" | "update" | "findById" | "findOne" | "updateById" | "delete"
@@ -51,7 +51,7 @@ export type TIdentityTokenAuthServiceFactory = ReturnType<typeof identityTokenAu
export const identityTokenAuthServiceFactory = ({ export const identityTokenAuthServiceFactory = ({
identityTokenAuthDAL, identityTokenAuthDAL,
// identityDAL, // identityDAL,
identityOrgMembershipDAL, membershipIdentityDAL,
identityAccessTokenDAL, identityAccessTokenDAL,
permissionService, permissionService,
licenseService, licenseService,
@@ -71,7 +71,13 @@ export const identityTokenAuthServiceFactory = ({
}: TAttachTokenAuthDTO) => { }: TAttachTokenAuthDTO) => {
await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin); await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin);
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TOKEN_AUTH)) { if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TOKEN_AUTH)) {
@@ -87,13 +93,13 @@ export const identityTokenAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => { const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -114,7 +120,7 @@ export const identityTokenAuthServiceFactory = ({
const identityTokenAuth = await identityTokenAuthDAL.transaction(async (tx) => { const identityTokenAuth = await identityTokenAuthDAL.transaction(async (tx) => {
const doc = await identityTokenAuthDAL.create( const doc = await identityTokenAuthDAL.create(
{ {
identityId: identityMembershipOrg.identityId, identityId: identityMembershipOrg.identity.id,
accessTokenMaxTTL, accessTokenMaxTTL,
accessTokenTTL, accessTokenTTL,
accessTokenNumUsesLimit, accessTokenNumUsesLimit,
@@ -124,7 +130,7 @@ export const identityTokenAuthServiceFactory = ({
); );
return doc; return doc;
}); });
return { ...identityTokenAuth, orgId: identityMembershipOrg.orgId }; return { ...identityTokenAuth, orgId: identityMembershipOrg.scopeOrgId };
}; };
const updateTokenAuth = async ({ const updateTokenAuth = async ({
@@ -141,7 +147,13 @@ export const identityTokenAuthServiceFactory = ({
}: TUpdateTokenAuthDTO) => { }: TUpdateTokenAuthDTO) => {
await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin); await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin);
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TOKEN_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TOKEN_AUTH)) {
@@ -163,13 +175,13 @@ export const identityTokenAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => { const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -198,12 +210,18 @@ export const identityTokenAuthServiceFactory = ({
return { return {
...updatedTokenAuth, ...updatedTokenAuth,
orgId: identityMembershipOrg.orgId orgId: identityMembershipOrg.scopeOrgId
}; };
}; };
const getTokenAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetTokenAuthDTO) => { const getTokenAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetTokenAuthDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TOKEN_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TOKEN_AUTH)) {
@@ -217,13 +235,13 @@ export const identityTokenAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
return { ...identityTokenAuth, orgId: identityMembershipOrg.orgId }; return { ...identityTokenAuth, orgId: identityMembershipOrg.scopeOrgId };
}; };
const revokeIdentityTokenAuth = async ({ const revokeIdentityTokenAuth = async ({
@@ -236,7 +254,13 @@ export const identityTokenAuthServiceFactory = ({
}: TRevokeTokenAuthDTO) => { }: TRevokeTokenAuthDTO) => {
await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin); await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin);
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TOKEN_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TOKEN_AUTH)) {
@@ -247,7 +271,7 @@ export const identityTokenAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -255,13 +279,13 @@ export const identityTokenAuthServiceFactory = ({
const { permission: rolePermission } = await permissionService.getOrgPermission( const { permission: rolePermission } = await permissionService.getOrgPermission(
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identity.id,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.orgId); const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
const permissionBoundary = validatePrivilegeChangeOperation( const permissionBoundary = validatePrivilegeChangeOperation(
shouldUseNewPrivilegeSystem, shouldUseNewPrivilegeSystem,
OrgPermissionIdentityActions.RevokeAuth, OrgPermissionIdentityActions.RevokeAuth,
@@ -287,7 +311,7 @@ export const identityTokenAuthServiceFactory = ({
authMethod: IdentityAuthMethod.TOKEN_AUTH authMethod: IdentityAuthMethod.TOKEN_AUTH
}); });
return { ...deletedTokenAuth?.[0], orgId: identityMembershipOrg.orgId }; return { ...deletedTokenAuth?.[0], orgId: identityMembershipOrg.scopeOrgId };
}); });
return revokedIdentityTokenAuth; return revokedIdentityTokenAuth;
}; };
@@ -303,7 +327,13 @@ export const identityTokenAuthServiceFactory = ({
}: TCreateTokenAuthTokenDTO) => { }: TCreateTokenAuthTokenDTO) => {
await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin); await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin);
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TOKEN_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TOKEN_AUTH)) {
@@ -314,7 +344,7 @@ export const identityTokenAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -322,13 +352,13 @@ export const identityTokenAuthServiceFactory = ({
const { permission: rolePermission } = await permissionService.getOrgPermission( const { permission: rolePermission } = await permissionService.getOrgPermission(
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identity.id,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.orgId); const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
const permissionBoundary = validatePrivilegeChangeOperation( const permissionBoundary = validatePrivilegeChangeOperation(
shouldUseNewPrivilegeSystem, shouldUseNewPrivilegeSystem,
OrgPermissionIdentityActions.CreateToken, OrgPermissionIdentityActions.CreateToken,
@@ -350,7 +380,7 @@ export const identityTokenAuthServiceFactory = ({
const identityTokenAuth = await identityTokenAuthDAL.findOne({ identityId }); const identityTokenAuth = await identityTokenAuthDAL.findOne({ identityId });
const identityAccessToken = await identityTokenAuthDAL.transaction(async (tx) => { const identityAccessToken = await identityTokenAuthDAL.transaction(async (tx) => {
await identityOrgMembershipDAL.updateById( await membershipIdentityDAL.updateById(
identityMembershipOrg.id, identityMembershipOrg.id,
{ {
lastLoginAuthMethod: IdentityAuthMethod.TOKEN_AUTH, lastLoginAuthMethod: IdentityAuthMethod.TOKEN_AUTH,
@@ -405,7 +435,13 @@ export const identityTokenAuthServiceFactory = ({
}: TGetTokenAuthTokensDTO) => { }: TGetTokenAuthTokensDTO) => {
await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin); await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin);
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TOKEN_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.TOKEN_AUTH)) {
@@ -416,7 +452,7 @@ export const identityTokenAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -448,7 +484,13 @@ export const identityTokenAuthServiceFactory = ({
}); });
if (!foundToken) throw new NotFoundError({ message: `Token with ID ${tokenId} not found` }); if (!foundToken) throw new NotFoundError({ message: `Token with ID ${tokenId} not found` });
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId: foundToken.identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId: foundToken.identityId
});
if (!identityMembershipOrg) { if (!identityMembershipOrg) {
throw new NotFoundError({ message: `Failed to find identity with ID ${foundToken.identityId}` }); throw new NotFoundError({ message: `Failed to find identity with ID ${foundToken.identityId}` });
} }
@@ -462,7 +504,7 @@ export const identityTokenAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -470,12 +512,12 @@ export const identityTokenAuthServiceFactory = ({
const { permission: rolePermission } = await permissionService.getOrgPermission( const { permission: rolePermission } = await permissionService.getOrgPermission(
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identity.id,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.orgId); const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
const permissionBoundary = validatePrivilegeChangeOperation( const permissionBoundary = validatePrivilegeChangeOperation(
shouldUseNewPrivilegeSystem, shouldUseNewPrivilegeSystem,
OrgPermissionIdentityActions.CreateToken, OrgPermissionIdentityActions.CreateToken,
@@ -529,8 +571,9 @@ export const identityTokenAuthServiceFactory = ({
await validateIdentityUpdateForSuperAdminPrivileges(identityAccessToken.identityId, isActorSuperAdmin); await validateIdentityUpdateForSuperAdminPrivileges(identityAccessToken.identityId, isActorSuperAdmin);
const identityOrgMembership = await identityOrgMembershipDAL.findOne({ const identityOrgMembership = await membershipIdentityDAL.findOne({
identityId: identityAccessToken.identityId actorIdentityId: identityAccessToken.identityId,
scope: AccessScope.Organization
}); });
if (!identityOrgMembership) { if (!identityOrgMembership) {
@@ -540,7 +583,7 @@ export const identityTokenAuthServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityOrgMembership.orgId, identityOrgMembership.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -1,6 +1,6 @@
import { ForbiddenError } from "@casl/ability"; import { ForbiddenError } from "@casl/ability";
import { IdentityAuthMethod } from "@app/db/schemas"; import { AccessScope, IdentityAuthMethod } 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 {
@@ -22,9 +22,9 @@ import { checkIPAgainstBlocklist, extractIPDetails, isValidIpOrCidr, TIp } from
import { logger } from "@app/lib/logger"; import { logger } from "@app/lib/logger";
import { ActorType, AuthTokenType } from "../auth/auth-type"; import { ActorType, AuthTokenType } from "../auth/auth-type";
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal";
import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal"; import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal";
import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types"; import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types";
import { TMembershipIdentityDALFactory } from "../membership-identity/membership-identity-dal";
import { TOrgDALFactory } from "../org/org-dal"; import { TOrgDALFactory } from "../org/org-dal";
import { validateIdentityUpdateForSuperAdminPrivileges } from "../super-admin/super-admin-fns"; import { validateIdentityUpdateForSuperAdminPrivileges } from "../super-admin/super-admin-fns";
import { TIdentityUaClientSecretDALFactory } from "./identity-ua-client-secret-dal"; import { TIdentityUaClientSecretDALFactory } from "./identity-ua-client-secret-dal";
@@ -45,7 +45,7 @@ type TIdentityUaServiceFactoryDep = {
identityUaDAL: TIdentityUaDALFactory; identityUaDAL: TIdentityUaDALFactory;
identityUaClientSecretDAL: TIdentityUaClientSecretDALFactory; identityUaClientSecretDAL: TIdentityUaClientSecretDALFactory;
identityAccessTokenDAL: TIdentityAccessTokenDALFactory; identityAccessTokenDAL: TIdentityAccessTokenDALFactory;
identityOrgMembershipDAL: TIdentityOrgDALFactory; membershipIdentityDAL: TMembershipIdentityDALFactory;
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">; permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
licenseService: Pick<TLicenseServiceFactory, "getPlan">; licenseService: Pick<TLicenseServiceFactory, "getPlan">;
orgDAL: Pick<TOrgDALFactory, "findById">; orgDAL: Pick<TOrgDALFactory, "findById">;
@@ -66,7 +66,7 @@ export const identityUaServiceFactory = ({
identityUaDAL, identityUaDAL,
identityUaClientSecretDAL, identityUaClientSecretDAL,
identityAccessTokenDAL, identityAccessTokenDAL,
identityOrgMembershipDAL, membershipIdentityDAL,
permissionService, permissionService,
licenseService, licenseService,
orgDAL, orgDAL,
@@ -100,7 +100,10 @@ export const identityUaServiceFactory = ({
}); });
} }
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId: identityUa.identityId }); const identityMembershipOrg = await membershipIdentityDAL.findOne({
actorIdentityId: identityUa.identityId,
scope: AccessScope.Organization
});
if (!identityMembershipOrg) { if (!identityMembershipOrg) {
throw new UnauthorizedError({ throw new UnauthorizedError({
message: "Invalid credentials" message: "Invalid credentials"
@@ -226,7 +229,7 @@ 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 identityOrgMembershipDAL.updateById( await membershipIdentityDAL.updateById(
identityMembershipOrg.id, identityMembershipOrg.id,
{ {
lastLoginAuthMethod: IdentityAuthMethod.UNIVERSAL_AUTH, lastLoginAuthMethod: IdentityAuthMethod.UNIVERSAL_AUTH,
@@ -298,7 +301,13 @@ export const identityUaServiceFactory = ({
}: TAttachUaDTO) => { }: TAttachUaDTO) => {
await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin); await validateIdentityUpdateForSuperAdminPrivileges(identityId, isActorSuperAdmin);
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.UNIVERSAL_AUTH)) { if (identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.UNIVERSAL_AUTH)) {
@@ -314,13 +323,13 @@ export const identityUaServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedClientSecretTrustedIps = clientSecretTrustedIps.map((clientSecretTrustedIp) => { const reformattedClientSecretTrustedIps = clientSecretTrustedIps.map((clientSecretTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -357,7 +366,7 @@ export const identityUaServiceFactory = ({
const identityUa = await identityUaDAL.transaction(async (tx) => { const identityUa = await identityUaDAL.transaction(async (tx) => {
const doc = await identityUaDAL.create( const doc = await identityUaDAL.create(
{ {
identityId: identityMembershipOrg.identityId, identityId: identityMembershipOrg.identity.id,
clientId: crypto.nativeCrypto.randomUUID(), clientId: crypto.nativeCrypto.randomUUID(),
clientSecretTrustedIps: JSON.stringify(reformattedClientSecretTrustedIps), clientSecretTrustedIps: JSON.stringify(reformattedClientSecretTrustedIps),
accessTokenMaxTTL, accessTokenMaxTTL,
@@ -374,7 +383,7 @@ export const identityUaServiceFactory = ({
); );
return doc; return doc;
}); });
return { ...identityUa, orgId: identityMembershipOrg.orgId }; return { ...identityUa, orgId: identityMembershipOrg.scopeOrgId };
}; };
const updateUniversalAuth = async ({ const updateUniversalAuth = async ({
@@ -394,7 +403,13 @@ export const identityUaServiceFactory = ({
lockoutDurationSeconds, lockoutDurationSeconds,
lockoutCounterResetSeconds lockoutCounterResetSeconds
}: TUpdateUaDTO) => { }: TUpdateUaDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
const uaIdentityAuth = await identityUaDAL.findOne({ identityId }); const uaIdentityAuth = await identityUaDAL.findOne({ identityId });
@@ -418,13 +433,13 @@ export const identityUaServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Edit, OrgPermissionSubjects.Identity);
const plan = await licenseService.getPlan(identityMembershipOrg.orgId); const plan = await licenseService.getPlan(identityMembershipOrg.scopeOrgId);
const reformattedClientSecretTrustedIps = clientSecretTrustedIps?.map((clientSecretTrustedIp) => { const reformattedClientSecretTrustedIps = clientSecretTrustedIps?.map((clientSecretTrustedIp) => {
if ( if (
!plan.ipAllowlisting && !plan.ipAllowlisting &&
@@ -474,11 +489,17 @@ export const identityUaServiceFactory = ({
lockoutDurationSeconds, lockoutDurationSeconds,
lockoutCounterResetSeconds lockoutCounterResetSeconds
}); });
return { ...updatedUaAuth, orgId: identityMembershipOrg.orgId }; return { ...updatedUaAuth, orgId: identityMembershipOrg.scopeOrgId };
}; };
const getIdentityUniversalAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetUaDTO) => { const getIdentityUniversalAuth = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetUaDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
const uaIdentityAuth = await identityUaDAL.findOne({ identityId }); const uaIdentityAuth = await identityUaDAL.findOne({ identityId });
@@ -495,12 +516,12 @@ export const identityUaServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
return { ...uaIdentityAuth, orgId: identityMembershipOrg.orgId }; return { ...uaIdentityAuth, orgId: identityMembershipOrg.scopeOrgId };
}; };
const revokeIdentityUniversalAuth = async ({ const revokeIdentityUniversalAuth = async ({
@@ -510,7 +531,13 @@ export const identityUaServiceFactory = ({
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}: TRevokeUaDTO) => { }: TRevokeUaDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.UNIVERSAL_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.UNIVERSAL_AUTH)) {
@@ -521,7 +548,7 @@ export const identityUaServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -529,12 +556,12 @@ export const identityUaServiceFactory = ({
const { permission: rolePermission } = await permissionService.getOrgPermission( const { permission: rolePermission } = await permissionService.getOrgPermission(
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identity.id,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.orgId); const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
const permissionBoundary = validatePrivilegeChangeOperation( const permissionBoundary = validatePrivilegeChangeOperation(
shouldUseNewPrivilegeSystem, shouldUseNewPrivilegeSystem,
OrgPermissionIdentityActions.RevokeAuth, OrgPermissionIdentityActions.RevokeAuth,
@@ -555,7 +582,7 @@ export const identityUaServiceFactory = ({
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.orgId }; return { ...deletedUniversalAuth?.[0], orgId: identityMembershipOrg.scopeOrgId };
}); });
return revokedIdentityUniversalAuth; return revokedIdentityUniversalAuth;
}; };
@@ -570,7 +597,13 @@ export const identityUaServiceFactory = ({
description, description,
numUsesLimit numUsesLimit
}: TCreateUaClientSecretDTO) => { }: TCreateUaClientSecretDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.UNIVERSAL_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.UNIVERSAL_AUTH)) {
@@ -582,7 +615,7 @@ export const identityUaServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -590,12 +623,12 @@ export const identityUaServiceFactory = ({
const { permission: rolePermission } = await permissionService.getOrgPermission( const { permission: rolePermission } = await permissionService.getOrgPermission(
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identity.id,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.orgId); const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
const permissionBoundary = validatePrivilegeChangeOperation( const permissionBoundary = validatePrivilegeChangeOperation(
shouldUseNewPrivilegeSystem, shouldUseNewPrivilegeSystem,
OrgPermissionIdentityActions.CreateToken, OrgPermissionIdentityActions.CreateToken,
@@ -618,7 +651,7 @@ export const identityUaServiceFactory = ({
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);
const identityUaAuth = await identityUaDAL.findOne({ identityId: identityMembershipOrg.identityId }); const identityUaAuth = await identityUaDAL.findOne({ identityId: identityMembershipOrg.identity.id });
if (!identityUaAuth) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityUaAuth) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
const identityUaClientSecret = await identityUaClientSecretDAL.create({ const identityUaClientSecret = await identityUaClientSecretDAL.create({
@@ -634,7 +667,7 @@ export const identityUaServiceFactory = ({
return { return {
clientSecret, clientSecret,
clientSecretData: identityUaClientSecret, clientSecretData: identityUaClientSecret,
orgId: identityMembershipOrg.orgId orgId: identityMembershipOrg.scopeOrgId
}; };
}; };
@@ -645,7 +678,13 @@ export const identityUaServiceFactory = ({
actorAuthMethod, actorAuthMethod,
identityId identityId
}: TGetUaClientSecretsDTO) => { }: TGetUaClientSecretsDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.UNIVERSAL_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.UNIVERSAL_AUTH)) {
@@ -656,7 +695,7 @@ export const identityUaServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -664,13 +703,13 @@ export const identityUaServiceFactory = ({
const { permission: rolePermission } = await permissionService.getOrgPermission( const { permission: rolePermission } = await permissionService.getOrgPermission(
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identity.id,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.orgId); const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
const permissionBoundary = validatePrivilegeChangeOperation( const permissionBoundary = validatePrivilegeChangeOperation(
shouldUseNewPrivilegeSystem, shouldUseNewPrivilegeSystem,
OrgPermissionIdentityActions.GetToken, OrgPermissionIdentityActions.GetToken,
@@ -697,7 +736,7 @@ export const identityUaServiceFactory = ({
identityUAId: identityUniversalAuth.id, identityUAId: identityUniversalAuth.id,
isClientSecretRevoked: false isClientSecretRevoked: false
}); });
return { clientSecrets, orgId: identityMembershipOrg.orgId }; return { clientSecrets, orgId: identityMembershipOrg.scopeOrgId };
}; };
const getUniversalAuthClientSecretById = async ({ const getUniversalAuthClientSecretById = async ({
@@ -708,7 +747,13 @@ export const identityUaServiceFactory = ({
actorAuthMethod, actorAuthMethod,
clientSecretId clientSecretId
}: TGetUniversalAuthClientSecretByIdDTO) => { }: TGetUniversalAuthClientSecretByIdDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.UNIVERSAL_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.UNIVERSAL_AUTH)) {
@@ -726,7 +771,7 @@ export const identityUaServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -734,12 +779,12 @@ export const identityUaServiceFactory = ({
const { permission: rolePermission } = await permissionService.getOrgPermission( const { permission: rolePermission } = await permissionService.getOrgPermission(
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identity.id,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.orgId); const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
const permissionBoundary = validatePrivilegeChangeOperation( const permissionBoundary = validatePrivilegeChangeOperation(
shouldUseNewPrivilegeSystem, shouldUseNewPrivilegeSystem,
OrgPermissionIdentityActions.GetToken, OrgPermissionIdentityActions.GetToken,
@@ -758,7 +803,7 @@ export const identityUaServiceFactory = ({
details: { missingPermissions: permissionBoundary.missingPermissions } details: { missingPermissions: permissionBoundary.missingPermissions }
}); });
return { ...clientSecret, identityId, orgId: identityMembershipOrg.orgId }; return { ...clientSecret, identityId, orgId: identityMembershipOrg.scopeOrgId };
}; };
const revokeUniversalAuthClientSecret = async ({ const revokeUniversalAuthClientSecret = async ({
@@ -769,7 +814,13 @@ export const identityUaServiceFactory = ({
actorAuthMethod, actorAuthMethod,
clientSecretId clientSecretId
}: TRevokeUaClientSecretDTO) => { }: TRevokeUaClientSecretDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.UNIVERSAL_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.UNIVERSAL_AUTH)) {
@@ -787,7 +838,7 @@ export const identityUaServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -795,13 +846,13 @@ export const identityUaServiceFactory = ({
const { permission: rolePermission } = await permissionService.getOrgPermission( const { permission: rolePermission } = await permissionService.getOrgPermission(
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identity.id,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.orgId); const { shouldUseNewPrivilegeSystem } = await orgDAL.findById(identityMembershipOrg.scopeOrgId);
const permissionBoundary = validatePrivilegeChangeOperation( const permissionBoundary = validatePrivilegeChangeOperation(
shouldUseNewPrivilegeSystem, shouldUseNewPrivilegeSystem,
OrgPermissionIdentityActions.DeleteToken, OrgPermissionIdentityActions.DeleteToken,
@@ -825,7 +876,7 @@ export const identityUaServiceFactory = ({
isClientSecretRevoked: true isClientSecretRevoked: true
}); });
return { ...updatedClientSecret, identityId, orgId: identityMembershipOrg.orgId }; return { ...updatedClientSecret, identityId, orgId: identityMembershipOrg.scopeOrgId };
}; };
const clearUniversalAuthLockouts = async ({ const clearUniversalAuthLockouts = async ({
@@ -835,7 +886,13 @@ export const identityUaServiceFactory = ({
actorOrgId, actorOrgId,
actorAuthMethod actorAuthMethod
}: TClearUaLockoutsDTO) => { }: TClearUaLockoutsDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await membershipIdentityDAL.getIdentityById({
scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId
});
if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` }); if (!identityMembershipOrg) throw new NotFoundError({ message: `Failed to find identity with ID ${identityId}` });
if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.UNIVERSAL_AUTH)) { if (!identityMembershipOrg.identity.authMethods.includes(IdentityAuthMethod.UNIVERSAL_AUTH)) {
@@ -847,7 +904,7 @@ export const identityUaServiceFactory = ({
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -857,7 +914,7 @@ export const identityUaServiceFactory = ({
pattern: `lockout:identity:${identityId}:${IdentityAuthMethod.UNIVERSAL_AUTH}:*` pattern: `lockout:identity:${identityId}:${IdentityAuthMethod.UNIVERSAL_AUTH}:*`
}); });
return { deleted, identityId, orgId: identityMembershipOrg.orgId }; return { deleted, identityId, orgId: identityMembershipOrg.scopeOrgId };
}; };
return { return {
@@ -608,7 +608,7 @@ export const identityOrgDALFactory = (db: TDbClient) => {
} }
: undefined, : undefined,
identity: { identity: {
id: identityId, id: identityId as string,
name: identityName, name: identityName,
hasDeleteProtection, hasDeleteProtection,
authMethods: buildAuthMethods({ authMethods: buildAuthMethods({
@@ -1,6 +1,6 @@
import { ForbiddenError } from "@casl/ability"; import { ForbiddenError } from "@casl/ability";
import { OrgMembershipRole, TableName, TRoles } from "@app/db/schemas"; import { AccessScope, OrgMembershipRole, TableName, TRoles } 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 {
@@ -26,11 +26,15 @@ import {
TSearchOrgIdentitiesByOrgIdDTO, TSearchOrgIdentitiesByOrgIdDTO,
TUpdateIdentityDTO TUpdateIdentityDTO
} from "./identity-types"; } from "./identity-types";
import { TMembershipIdentityDALFactory } from "../membership-identity/membership-identity-dal";
import { TMembershipRoleDALFactory } from "../membership/membership-role-dal";
type TIdentityServiceFactoryDep = { type TIdentityServiceFactoryDep = {
identityDAL: TIdentityDALFactory; identityDAL: TIdentityDALFactory;
identityMetadataDAL: TIdentityMetadataDALFactory; identityMetadataDAL: TIdentityMetadataDALFactory;
identityOrgMembershipDAL: TIdentityOrgDALFactory; identityOrgMembershipDAL: TIdentityOrgDALFactory;
membershipIdentityDAL: TMembershipIdentityDALFactory;
membershipRoleDAL: TMembershipRoleDALFactory;
identityProjectDAL: Pick<TIdentityProjectDALFactory, "findByIdentityId">; identityProjectDAL: Pick<TIdentityProjectDALFactory, "findByIdentityId">;
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission" | "getOrgPermissionByRoles">; permissionService: Pick<TPermissionServiceFactory, "getOrgPermission" | "getOrgPermissionByRoles">;
licenseService: Pick<TLicenseServiceFactory, "getPlan" | "updateSubscriptionOrgMemberCount">; licenseService: Pick<TLicenseServiceFactory, "getPlan" | "updateSubscriptionOrgMemberCount">;
@@ -48,7 +52,9 @@ export const identityServiceFactory = ({
permissionService, permissionService,
licenseService, licenseService,
keyStore, keyStore,
orgDAL orgDAL,
membershipIdentityDAL,
membershipRoleDAL
}: TIdentityServiceFactoryDep) => { }: TIdentityServiceFactoryDep) => {
const createIdentity = async ({ const createIdentity = async ({
name, name,
@@ -99,12 +105,20 @@ export const identityServiceFactory = ({
const identity = await identityDAL.transaction(async (tx) => { const identity = await identityDAL.transaction(async (tx) => {
const newIdentity = await identityDAL.create({ name, hasDeleteProtection }, tx); const newIdentity = await identityDAL.create({ name, hasDeleteProtection }, tx);
await identityOrgMembershipDAL.create( const membership = await membershipIdentityDAL.create(
{ {
identityId: newIdentity.id, scope: AccessScope.Organization,
orgId, actorIdentityId: newIdentity.id,
scopeOrgId: orgId
},
tx
);
await membershipRoleDAL.create(
{
membershipId: membership.id,
role: isCustomRole ? OrgMembershipRole.Custom : role, role: isCustomRole ? OrgMembershipRole.Custom : role,
roleId: rolePermissionDetails?.role?.id customRoleId: rolePermissionDetails?.role?.id
}, },
tx tx
); );
@@ -151,13 +165,17 @@ export const identityServiceFactory = ({
}: TUpdateIdentityDTO) => { }: TUpdateIdentityDTO) => {
await validateIdentityUpdateForSuperAdminPrivileges(id, isActorSuperAdmin); await validateIdentityUpdateForSuperAdminPrivileges(id, isActorSuperAdmin);
const identityOrgMembership = await identityOrgMembershipDAL.findOne({ identityId: id }); const identityOrgMembership = await membershipIdentityDAL.findOne({
actorIdentityId: id,
scope: AccessScope.Organization,
scopeOrgId: actorOrgId
});
if (!identityOrgMembership) throw new NotFoundError({ message: `Failed to find identity with id ${id}` }); if (!identityOrgMembership) throw new NotFoundError({ message: `Failed to find identity with id ${id}` });
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityOrgMembership.orgId, identityOrgMembership.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -197,11 +215,14 @@ export const identityServiceFactory = ({
: await identityDAL.findById(id, tx); : await identityDAL.findById(id, tx);
if (role) { if (role) {
await identityOrgMembershipDAL.updateById( await membershipRoleDAL.delete({ membershipId: identityOrgMembership.id }, tx);
identityOrgMembership.id, await membershipRoleDAL.update(
{
membershipId: identityOrgMembership.id
},
{ {
role: customRole ? OrgMembershipRole.Custom : role, role: customRole ? OrgMembershipRole.Custom : role,
roleId: customRole?.id || null customRoleId: customRole?.id || null
}, },
tx tx
); );
@@ -213,12 +234,12 @@ export const identityServiceFactory = ({
}> = []; }> = [];
if (metadata) { if (metadata) {
await identityMetadataDAL.delete({ orgId: identityOrgMembership.orgId, identityId: id }, tx); await identityMetadataDAL.delete({ orgId: identityOrgMembership.scopeOrgId, identityId: id }, tx);
if (metadata.length) { if (metadata.length) {
const rowsToInsert = metadata.map(({ key, value }) => ({ const rowsToInsert = metadata.map(({ key, value }) => ({
identityId: newIdentity.id, identityId: newIdentity.id,
orgId: identityOrgMembership.orgId, orgId: identityOrgMembership.scopeOrgId,
key, key,
value value
})); }));
@@ -233,12 +254,14 @@ export const identityServiceFactory = ({
}; };
}); });
return { ...identity, orgId: identityOrgMembership.orgId }; return { ...identity, orgId: identityOrgMembership.scopeOrgId };
}; };
const getIdentityById = async ({ id, actor, actorId, actorOrgId, actorAuthMethod }: TGetIdentityByIdDTO) => { const getIdentityById = async ({ id, actor, actorId, actorOrgId, actorAuthMethod }: TGetIdentityByIdDTO) => {
const doc = await identityOrgMembershipDAL.find({ const doc = await identityOrgMembershipDAL.find({
[`${TableName.IdentityOrgMembership}.identityId` as "identityId"]: id [`${TableName.Membership}.actorIdentityId` as "actorIdentityId"]: id,
scope: AccessScope.Organization,
scopeOrgId: actorOrgId
}); });
const identity = doc[0]; const identity = doc[0];
if (!identity) throw new NotFoundError({ message: `Failed to find identity with id ${id}` }); if (!identity) throw new NotFoundError({ message: `Failed to find identity with id ${id}` });
@@ -252,6 +275,7 @@ export const identityServiceFactory = ({
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
// TODO(simp): check this in identity service
const activeLockouts = await keyStore.getKeysByPattern(`lockout:identity:${id}:*`); const activeLockouts = await keyStore.getKeysByPattern(`lockout:identity:${id}:*`);
const activeLockoutAuthMethods = new Set<string>(); const activeLockoutAuthMethods = new Set<string>();
@@ -283,14 +307,19 @@ export const identityServiceFactory = ({
isActorSuperAdmin isActorSuperAdmin
}: TDeleteIdentityDTO) => { }: TDeleteIdentityDTO) => {
await validateIdentityUpdateForSuperAdminPrivileges(id, isActorSuperAdmin); await validateIdentityUpdateForSuperAdminPrivileges(id, isActorSuperAdmin);
const identityOrgMembership = await membershipIdentityDAL.getIdentityById({
const identityOrgMembership = await identityOrgMembershipDAL.findOne({ identityId: id }); scopeData: {
scope: AccessScope.Organization,
orgId: actorOrgId
},
identityId: id
});
if (!identityOrgMembership) throw new NotFoundError({ message: `Failed to find identity with id ${id}` }); if (!identityOrgMembership) throw new NotFoundError({ message: `Failed to find identity with id ${id}` });
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityOrgMembership.orgId, identityOrgMembership.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -302,9 +331,9 @@ export const identityServiceFactory = ({
const deletedIdentity = await identityDAL.deleteById(id); const deletedIdentity = await identityDAL.deleteById(id);
await licenseService.updateSubscriptionOrgMemberCount(identityOrgMembership.orgId); await licenseService.updateSubscriptionOrgMemberCount(identityOrgMembership.scopeOrgId);
return { ...deletedIdentity, orgId: identityOrgMembership.orgId }; return { ...deletedIdentity, orgId: identityOrgMembership.scopeOrgId };
}; };
const listOrgIdentities = async ({ const listOrgIdentities = async ({
@@ -323,7 +352,8 @@ export const identityServiceFactory = ({
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
const identityMemberships = await identityOrgMembershipDAL.find({ const identityMemberships = await identityOrgMembershipDAL.find({
[`${TableName.IdentityOrgMembership}.orgId` as "orgId"]: orgId, [`${TableName.Membership}.scopeOrgId` as "scopeOrgId"]: orgId,
scope: AccessScope.Organization,
limit, limit,
offset, offset,
orderBy, orderBy,
@@ -332,7 +362,7 @@ export const identityServiceFactory = ({
}); });
const totalCount = await identityOrgMembershipDAL.countAllOrgIdentities({ const totalCount = await identityOrgMembershipDAL.countAllOrgIdentities({
[`${TableName.IdentityOrgMembership}.orgId` as "orgId"]: orgId, [`${TableName.Membership}.scopeOrgId` as "scopeOrgId"]: orgId,
search search
}); });
@@ -373,13 +403,17 @@ export const identityServiceFactory = ({
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}: TListProjectIdentitiesByIdentityIdDTO) => { }: TListProjectIdentitiesByIdentityIdDTO) => {
const identityOrgMembership = await identityOrgMembershipDAL.findOne({ identityId }); const identityOrgMembership = await membershipIdentityDAL.findOne({
actorIdentityId: identityId,
scope: AccessScope.Organization,
scopeOrgId: actorOrgId
});
if (!identityOrgMembership) throw new NotFoundError({ message: `Failed to find identity with id ${identityId}` }); if (!identityOrgMembership) throw new NotFoundError({ message: `Failed to find identity with id ${identityId}` });
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
actor, actor,
actorId, actorId,
identityOrgMembership.orgId, identityOrgMembership.scopeOrgId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
@@ -269,7 +269,7 @@ export const membershipGroupServiceFactory = ({
[SearchResourceOperators.$contains]: dto.data.groupName [SearchResourceOperators.$contains]: dto.data.groupName
} }
: undefined, : undefined,
role: dto.data.roles.length role: dto.data.roles?.length
? { ? {
[SearchResourceOperators.$in]: dto.data.roles [SearchResourceOperators.$in]: dto.data.roles
} }
@@ -1,26 +1,25 @@
import { ForbiddenError } from "@casl/ability"; import { ForbiddenError } from "@casl/ability";
import { ProjectMembershipRole, ProjectVersion } from "@app/db/schemas"; import { AccessScope, ProjectMembershipRole, ProjectVersion } from "@app/db/schemas";
import { OrgPermissionAdminConsoleAction, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; import { OrgPermissionAdminConsoleAction, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { BadRequestError, NotFoundError } from "@app/lib/errors";
import { TMembershipRoleDALFactory } from "../membership/membership-role-dal";
import { TMembershipUserDALFactory } from "../membership-user/membership-user-dal";
import { TNotificationServiceFactory } from "../notification/notification-service"; import { TNotificationServiceFactory } from "../notification/notification-service";
import { NotificationType } from "../notification/notification-types"; import { NotificationType } from "../notification/notification-types";
import { TProjectDALFactory } from "../project/project-dal"; import { TProjectDALFactory } from "../project/project-dal";
import { TProjectMembershipDALFactory } from "../project-membership/project-membership-dal"; import { TProjectMembershipDALFactory } from "../project-membership/project-membership-dal";
import { TProjectUserMembershipRoleDALFactory } from "../project-membership/project-user-membership-role-dal";
import { SmtpTemplates, TSmtpService } from "../smtp/smtp-service"; import { SmtpTemplates, TSmtpService } from "../smtp/smtp-service";
import { TAccessProjectDTO, TListOrgProjectsDTO } from "./org-admin-types"; import { TAccessProjectDTO, TListOrgProjectsDTO } from "./org-admin-types";
type TOrgAdminServiceFactoryDep = { type TOrgAdminServiceFactoryDep = {
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">; permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
projectDAL: Pick<TProjectDALFactory, "find" | "findById" | "findProjectGhostUser" | "findOne">; projectDAL: Pick<TProjectDALFactory, "find" | "findById" | "findProjectGhostUser" | "findOne">;
projectMembershipDAL: Pick< projectMembershipDAL: Pick<TProjectMembershipDALFactory, "findAllProjectMembers">;
TProjectMembershipDALFactory, membershipUserDAL: TMembershipUserDALFactory;
"findOne" | "create" | "transaction" | "delete" | "findAllProjectMembers" membershipRoleDAL: TMembershipRoleDALFactory;
>;
projectUserMembershipRoleDAL: Pick<TProjectUserMembershipRoleDALFactory, "create" | "delete">;
smtpService: Pick<TSmtpService, "sendMail">; smtpService: Pick<TSmtpService, "sendMail">;
notificationService: Pick<TNotificationServiceFactory, "createUserNotifications">; notificationService: Pick<TNotificationServiceFactory, "createUserNotifications">;
}; };
@@ -31,9 +30,10 @@ export const orgAdminServiceFactory = ({
permissionService, permissionService,
projectDAL, projectDAL,
projectMembershipDAL, projectMembershipDAL,
projectUserMembershipRoleDAL,
smtpService, smtpService,
notificationService notificationService,
membershipUserDAL,
membershipRoleDAL
}: TOrgAdminServiceFactoryDep) => { }: TOrgAdminServiceFactoryDep) => {
const listOrgProjects = async ({ const listOrgProjects = async ({
actor, actor,
@@ -98,17 +98,18 @@ export const orgAdminServiceFactory = ({
} }
// check already there exist a membership if there return it // check already there exist a membership if there return it
const projectMembership = await projectMembershipDAL.findOne({ const projectMembership = await membershipUserDAL.findOne({
projectId, scopeProjectId: projectId,
userId: actorId scope: AccessScope.Project,
actorUserId: actorId
}); });
if (projectMembership) { if (projectMembership) {
// reset and make the user admin // reset and make the user admin
await projectMembershipDAL.transaction(async (tx) => { await membershipUserDAL.transaction(async (tx) => {
await projectUserMembershipRoleDAL.delete({ projectMembershipId: projectMembership.id }, tx); await membershipRoleDAL.delete({ membershipId: projectMembership.id }, tx);
await projectUserMembershipRoleDAL.create( await membershipRoleDAL.create(
{ {
projectMembershipId: projectMembership.id, membershipId: projectMembership.id,
role: ProjectMembershipRole.Admin role: ProjectMembershipRole.Admin
}, },
tx tx
@@ -117,18 +118,16 @@ export const orgAdminServiceFactory = ({
return { isExistingMember: true, membership: projectMembership }; return { isExistingMember: true, membership: projectMembership };
} }
const updatedMembership = await projectMembershipDAL.transaction(async (tx) => { const updatedMembership = await membershipUserDAL.transaction(async (tx) => {
const newProjectMembership = await projectMembershipDAL.create( const newProjectMembership = await membershipUserDAL.create(
{ {
projectId, scopeProjectId: projectId,
userId: actorId actorUserId: actorId,
scope: AccessScope.Project
}, },
tx tx
); );
await projectUserMembershipRoleDAL.create( await membershipRoleDAL.create({ membershipId: newProjectMembership.id, role: ProjectMembershipRole.Admin }, tx);
{ projectMembershipId: newProjectMembership.id, role: ProjectMembershipRole.Admin },
tx
);
return newProjectMembership; return newProjectMembership;
}); });
@@ -15,7 +15,6 @@ import { TExternalGroupOrgRoleMappingDALFactory } from "@app/services/external-g
import { TOrgDALFactory } from "@app/services/org/org-dal"; import { TOrgDALFactory } from "@app/services/org/org-dal";
import { ActorAuthMethod, ActorType } from "../auth/auth-type"; import { ActorAuthMethod, ActorType } from "../auth/auth-type";
import { TOrgRoleDALFactory } from "./org-role-dal";
type TOrgRoleServiceFactoryDep = { type TOrgRoleServiceFactoryDep = {
orgRoleDAL: TOrgRoleDALFactory; orgRoleDAL: TOrgRoleDALFactory;
+131 -71
View File
@@ -3,6 +3,7 @@ import slugify from "@sindresorhus/slugify";
import { Knex } from "knex"; import { Knex } from "knex";
import { import {
AccessScope,
ActionProjectType, ActionProjectType,
OrgMembershipRole, OrgMembershipRole,
OrgMembershipStatus, OrgMembershipStatus,
@@ -31,7 +32,6 @@ import {
} 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 { ProjectPermissionMemberActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { ProjectPermissionMemberActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
import { TProjectUserAdditionalPrivilegeDALFactory } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-dal";
import { TSamlConfigDALFactory } from "@app/ee/services/saml-config/saml-config-dal"; import { TSamlConfigDALFactory } from "@app/ee/services/saml-config/saml-config-dal";
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";
@@ -59,13 +59,14 @@ import { ActorAuthMethod, ActorType, AuthMethod, AuthModeJwtTokenPayload, AuthTo
import { TAuthTokenServiceFactory } from "../auth-token/auth-token-service"; import { TAuthTokenServiceFactory } from "../auth-token/auth-token-service";
import { TokenType } from "../auth-token/auth-token-types"; import { TokenType } from "../auth-token/auth-token-types";
import { TIdentityMetadataDALFactory } from "../identity/identity-metadata-dal"; import { TIdentityMetadataDALFactory } from "../identity/identity-metadata-dal";
import { TMembershipRoleDALFactory } from "../membership/membership-role-dal";
import { TMembershipUserDALFactory } from "../membership-user/membership-user-dal";
import { TProjectDALFactory } from "../project/project-dal"; import { TProjectDALFactory } from "../project/project-dal";
import { TProjectBotServiceFactory } from "../project-bot/project-bot-service"; import { TProjectBotServiceFactory } from "../project-bot/project-bot-service";
import { TProjectKeyDALFactory } from "../project-key/project-key-dal"; import { TProjectKeyDALFactory } from "../project-key/project-key-dal";
import { TProjectMembershipDALFactory } from "../project-membership/project-membership-dal"; import { TProjectMembershipDALFactory } from "../project-membership/project-membership-dal";
import { TProjectUserMembershipRoleDALFactory } from "../project-membership/project-user-membership-role-dal";
import { TProjectRoleDALFactory } from "../project-role/project-role-dal";
import { TReminderServiceFactory } from "../reminder/reminder-types"; import { TReminderServiceFactory } from "../reminder/reminder-types";
import { TRoleDALFactory } from "../role/role-dal";
import { TSecretDALFactory } from "../secret/secret-dal"; import { TSecretDALFactory } from "../secret/secret-dal";
import { fnDeleteProjectSecretReminders } from "../secret/secret-fns"; import { fnDeleteProjectSecretReminders } from "../secret/secret-fns";
import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal"; import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal";
@@ -91,7 +92,6 @@ import {
TUpgradePrivilegeSystemDTO, TUpgradePrivilegeSystemDTO,
TVerifyUserToOrgDTO TVerifyUserToOrgDTO
} from "./org-types"; } from "./org-types";
import { TRoleDALFactory } from "../role/role-dal";
type TOrgServiceFactoryDep = { type TOrgServiceFactoryDep = {
userAliasDAL: Pick<TUserAliasDALFactory, "delete">; userAliasDAL: Pick<TUserAliasDALFactory, "delete">;
@@ -105,26 +105,17 @@ type TOrgServiceFactoryDep = {
groupDAL: TGroupDALFactory; groupDAL: TGroupDALFactory;
projectDAL: TProjectDALFactory; projectDAL: TProjectDALFactory;
identityMetadataDAL: Pick<TIdentityMetadataDALFactory, "delete" | "insertMany" | "transaction">; identityMetadataDAL: Pick<TIdentityMetadataDALFactory, "delete" | "insertMany" | "transaction">;
membershipUserDAL: TMembershipUserDALFactory;
projectMembershipDAL: Pick< projectMembershipDAL: Pick<
TProjectMembershipDALFactory, TProjectMembershipDALFactory,
| "findProjectMembershipsByUserId" "findProjectMembershipsByUserId" | "findProjectMembershipsByUserIds"
| "delete"
| "create"
| "find"
| "insertMany"
| "transaction"
| "findProjectMembershipsByUserIds"
>; >;
projectKeyDAL: Pick<TProjectKeyDALFactory, "find" | "delete" | "insertMany" | "findLatestProjectKey" | "create">; projectKeyDAL: Pick<TProjectKeyDALFactory, "find" | "delete" | "insertMany" | "findLatestProjectKey" | "create">;
orgMembershipDAL: Pick< orgMembershipDAL: Pick<
TOrgMembershipDALFactory, TOrgMembershipDALFactory,
| "findOrgMembershipById" "findOrgMembershipById" | "findRecentInvitedMemberships" | "updateLastInvitedAtByIds"
| "findOne"
| "findById"
| "findRecentInvitedMemberships"
| "updateById"
| "updateLastInvitedAtByIds"
>; >;
membershipRoleDAL: TMembershipRoleDALFactory;
incidentContactDAL: TIncidentContactsDALFactory; incidentContactDAL: TIncidentContactsDALFactory;
samlConfigDAL: Pick<TSamlConfigDALFactory, "findOne">; samlConfigDAL: Pick<TSamlConfigDALFactory, "findOne">;
oidcConfigDAL: Pick<TOidcConfigDALFactory, "findOne">; oidcConfigDAL: Pick<TOidcConfigDALFactory, "findOne">;
@@ -136,9 +127,6 @@ type TOrgServiceFactoryDep = {
TLicenseServiceFactory, TLicenseServiceFactory,
"getPlan" | "updateSubscriptionOrgMemberCount" | "generateOrgCustomerId" | "removeOrgCustomer" "getPlan" | "updateSubscriptionOrgMemberCount" | "generateOrgCustomerId" | "removeOrgCustomer"
>; >;
projectUserAdditionalPrivilegeDAL: Pick<TProjectUserAdditionalPrivilegeDALFactory, "delete">;
projectRoleDAL: Pick<TProjectRoleDALFactory, "find">;
projectUserMembershipRoleDAL: Pick<TProjectUserMembershipRoleDALFactory, "insertMany" | "create">;
projectBotService: Pick<TProjectBotServiceFactory, "getBotKey">; projectBotService: Pick<TProjectBotServiceFactory, "getBotKey">;
loginService: Pick<TAuthLoginFactory, "generateUserTokens">; loginService: Pick<TAuthLoginFactory, "generateUserTokens">;
reminderService: Pick<TReminderServiceFactory, "deleteReminderBySecretId">; reminderService: Pick<TReminderServiceFactory, "deleteReminderBySecretId">;
@@ -162,19 +150,18 @@ export const orgServiceFactory = ({
projectMembershipDAL, projectMembershipDAL,
projectKeyDAL, projectKeyDAL,
orgMembershipDAL, orgMembershipDAL,
projectUserAdditionalPrivilegeDAL,
tokenService, tokenService,
orgBotDAL, orgBotDAL,
licenseService, licenseService,
projectRoleDAL,
samlConfigDAL, samlConfigDAL,
oidcConfigDAL, oidcConfigDAL,
ldapConfigDAL, ldapConfigDAL,
projectUserMembershipRoleDAL,
identityMetadataDAL, identityMetadataDAL,
projectBotService, projectBotService,
loginService, loginService,
reminderService reminderService,
membershipRoleDAL,
membershipUserDAL
}: TOrgServiceFactoryDep) => { }: TOrgServiceFactoryDep) => {
/* /*
* Get organization details by the organization id * Get organization details by the organization id
@@ -273,7 +260,7 @@ export const orgServiceFactory = ({
} }
if (actor === ActorType.IDENTITY) { if (actor === ActorType.IDENTITY) {
const workspaces = await projectDAL.findAllProjectsByIdentity(actorId); const workspaces = await projectDAL.findIdentityProjects(actorId, orgId);
return workspaces; return workspaces;
} }
@@ -308,14 +295,21 @@ export const orgServiceFactory = ({
); );
const createMembershipData = { const createMembershipData = {
orgId, scopeOrgId: orgId,
userId: user.id, scope: AccessScope.Organization,
role: OrgMembershipRole.Admin, actorUserId: user.id,
status: OrgMembershipStatus.Accepted, status: OrgMembershipStatus.Accepted,
isActive: true isActive: true
}; };
await orgDAL.createMembership(createMembershipData, tx); const membership = await orgDAL.createMembership(createMembershipData, tx);
await membershipRoleDAL.create(
{
membershipId: membership.id,
role: OrgMembershipRole.Admin
},
tx
);
return { return {
user, user,
@@ -613,16 +607,23 @@ export const orgServiceFactory = ({
tx tx
); );
if (userId) { if (userId) {
await orgDAL.createMembership( const membership = await orgDAL.createMembership(
{ {
userId, scope: AccessScope.Organization,
orgId: org.id, actorUserId: userId,
role: OrgMembershipRole.Admin, scopeOrgId: org.id,
status: OrgMembershipStatus.Accepted, status: OrgMembershipStatus.Accepted,
isActive: true isActive: true
}, },
tx tx
); );
await membershipRoleDAL.create(
{
membershipId: membership.id,
role: OrgMembershipRole.Admin
},
tx
);
} }
await orgBotDAL.create( await orgBotDAL.create(
{ {
@@ -766,12 +767,16 @@ export const orgServiceFactory = ({
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Member); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Member);
const foundMembership = await orgMembershipDAL.findById(membershipId); const foundMembership = await membershipUserDAL.findOne({
id: membershipId,
scope: AccessScope.Organization,
scopeOrgId: actorOrgId
});
if (!foundMembership) if (!foundMembership)
throw new NotFoundError({ message: `Organization membership with ID ${membershipId} not found` }); throw new NotFoundError({ message: `Organization membership with ID ${membershipId} not found` });
if (foundMembership.orgId !== orgId) if (foundMembership.scopeOrgId !== orgId)
throw new UnauthorizedError({ message: "Updated org member doesn't belong to the organization" }); throw new UnauthorizedError({ message: "Updated org member doesn't belong to the organization" });
if (foundMembership.userId === userId) if (foundMembership.scopeOrgId === userId)
throw new UnauthorizedError({ message: "Cannot update own organization membership" }); throw new UnauthorizedError({ message: "Cannot update own organization membership" });
const isCustomRole = !Object.values(OrgMembershipRole).includes(role as OrgMembershipRole); const isCustomRole = !Object.values(OrgMembershipRole).includes(role as OrgMembershipRole);
@@ -793,8 +798,20 @@ export const orgServiceFactory = ({
const membership = await orgDAL.transaction(async (tx) => { const membership = await orgDAL.transaction(async (tx) => {
const [updatedOrgMembership] = await orgDAL.updateMembership( const [updatedOrgMembership] = await orgDAL.updateMembership(
{ id: membershipId, scopeOrgId: orgId }, { id: membershipId, scopeOrgId: orgId },
{ role: userRole, roleId: userRoleId, isActive } { isActive },
tx
); );
if (userRole) {
await membershipRoleDAL.delete({ membershipId: updatedOrgMembership.id }, tx);
await membershipRoleDAL.create(
{
membershipId: updatedOrgMembership.id,
role: userRole,
customRoleId: userRoleId
},
tx
);
}
if (metadata) { if (metadata) {
await identityMetadataDAL.delete({ userId: updatedOrgMembership.actorUserId, orgId }, tx); await identityMetadataDAL.delete({ userId: updatedOrgMembership.actorUserId, orgId }, tx);
@@ -833,8 +850,9 @@ export const orgServiceFactory = ({
const org = await orgDAL.findOrgById(orgId); const org = await orgDAL.findOrgById(orgId);
const [inviteeOrgMembership] = await orgDAL.findMembership({ const [inviteeOrgMembership] = await orgDAL.findMembership({
[`${TableName.OrgMembership}.orgId` as "orgId"]: orgId, [`${TableName.Membership}.scopeOrgId` as "scopeOrgId"]: orgId,
[`${TableName.OrgMembership}.id` as "id"]: membershipId [`${TableName.Membership}.scope` as "scope"]: AccessScope.Organization,
[`${TableName.Membership}.id` as "id"]: membershipId
}); });
if (inviteeOrgMembership.status !== OrgMembershipStatus.Invited) { if (inviteeOrgMembership.status !== OrgMembershipStatus.Invited) {
@@ -845,7 +863,7 @@ export const orgServiceFactory = ({
const token = await tokenService.createTokenForUser({ const token = await tokenService.createTokenForUser({
type: TokenType.TOKEN_EMAIL_ORG_INVITATION, type: TokenType.TOKEN_EMAIL_ORG_INVITATION,
userId: inviteeOrgMembership.userId, userId: inviteeOrgMembership.actorUserId as string,
orgId orgId
}); });
@@ -873,7 +891,7 @@ export const orgServiceFactory = ({
} }
}); });
await orgMembershipDAL.updateById(inviteeOrgMembership.id, { await membershipUserDAL.updateById(inviteeOrgMembership.id, {
lastInvitedAt: new Date() lastInvitedAt: new Date()
}); });
@@ -991,8 +1009,9 @@ export const orgServiceFactory = ({
const [inviteeOrgMembership] = await orgDAL.findMembership( const [inviteeOrgMembership] = await orgDAL.findMembership(
{ {
[`${TableName.OrgMembership}.orgId` as "orgId"]: orgId, [`${TableName.Membership}.scopeOrgId` as "scopeOrgId"]: orgId,
[`${TableName.OrgMembership}.userId` as "userId"]: inviteeUserId [`${TableName.Membership}.scope` as "scope"]: AccessScope.Organization,
[`${TableName.Membership}.id` as "id"]: inviteeUserId
}, },
{ tx } { tx }
); );
@@ -1019,7 +1038,7 @@ export const orgServiceFactory = ({
let roleId; let roleId;
const orgRole = isCustomOrgRole ? OrgMembershipRole.Custom : organizationRoleSlug; const orgRole = isCustomOrgRole ? OrgMembershipRole.Custom : organizationRoleSlug;
if (isCustomOrgRole) { if (isCustomOrgRole) {
const customRole = await orgRoleDAL.findOne({ slug: organizationRoleSlug, orgId }); const customRole = await roleDAL.findOne({ slug: organizationRoleSlug, orgId });
if (!customRole) { if (!customRole) {
throw new NotFoundError({ throw new NotFoundError({
name: "InviteUser", name: "InviteUser",
@@ -1029,15 +1048,22 @@ export const orgServiceFactory = ({
roleId = customRole.id; roleId = customRole.id;
} }
await orgDAL.createMembership( const membership = await orgDAL.createMembership(
{ {
userId: inviteeUser.id, actorUserId: inviteeUser.id,
inviteEmail: inviteeEmail, inviteEmail: inviteeEmail,
orgId, scopeOrgId: orgId,
role: orgRole,
status: OrgMembershipStatus.Invited, status: OrgMembershipStatus.Invited,
isActive: true, isActive: true,
roleId scope: AccessScope.Organization
},
tx
);
await membershipRoleDAL.create(
{
membershipId: membership.id,
role: orgRole,
customRoleId: roleId
}, },
tx tx
); );
@@ -1072,14 +1098,16 @@ export const orgServiceFactory = ({
ProjectPermissionMemberActions.Create, ProjectPermissionMemberActions.Create,
ProjectPermissionSub.Member ProjectPermissionSub.Member
); );
const existingMembers = await projectMembershipDAL.find( const existingMembers = await membershipUserDAL.find(
{ {
projectId: project.id, scopeOrgId: project.orgId,
scope: AccessScope.Project,
scopeProjectId: project.id,
$in: { userId: userIds } $in: { userId: userIds }
}, },
{ tx } { tx }
); );
const existingMembersGroupByUserId = groupBy(existingMembers, (i) => i.userId); const existingMembersGroupByUserId = groupBy(existingMembers, (i) => i.actorUserId as string);
const userWithEncryptionKeyInvitedToProject = userEncryptionKeys.filter( const userWithEncryptionKeyInvitedToProject = userEncryptionKeys.filter(
(user) => !existingMembersGroupByUserId?.[user.userId] (user) => !existingMembersGroupByUserId?.[user.userId]
); );
@@ -1246,9 +1274,10 @@ export const orgServiceFactory = ({
} }
const [orgMembership] = await orgDAL.findMembership({ const [orgMembership] = await orgDAL.findMembership({
[`${TableName.OrgMembership}.userId` as "userId"]: user.id, [`${TableName.Membership}.actorUserId` as "actorUserId"]: user.id,
scope: AccessScope.Organization,
status: OrgMembershipStatus.Invited, status: OrgMembershipStatus.Invited,
[`${TableName.OrgMembership}.orgId` as "orgId"]: orgId [`${TableName.Membership}.scopeOrgId` as "scopeOrgId"]: orgId
}); });
if (!orgMembership) if (!orgMembership)
@@ -1261,7 +1290,7 @@ export const orgServiceFactory = ({
await tokenService.validateTokenForUser({ await tokenService.validateTokenForUser({
type: TokenType.TOKEN_EMAIL_ORG_INVITATION, type: TokenType.TOKEN_EMAIL_ORG_INVITATION,
userId: user.id, userId: user.id,
orgId: orgMembership.orgId, orgId: orgMembership.scopeOrgId,
code code
}); });
@@ -1273,16 +1302,17 @@ export const orgServiceFactory = ({
// this means user has already completed signup process // this means user has already completed signup process
// isAccepted is set true when keys are exchanged // isAccepted is set true when keys are exchanged
await orgDAL.updateMembershipById(orgMembership.id, { await orgDAL.updateMembershipById(orgMembership.id, {
orgId, scopeOrgId: orgId,
status: OrgMembershipStatus.Accepted status: OrgMembershipStatus.Accepted
}); });
await licenseService.updateSubscriptionOrgMemberCount(orgId); await licenseService.updateSubscriptionOrgMemberCount(orgId);
return { user }; return { user };
} }
const membershipRole = await membershipRoleDAL.findOne({ membershipId: orgMembership.id });
if ( if (
organization.authEnforced && organization.authEnforced &&
!(organization.bypassOrgAuthEnabled && orgMembership.role === OrgMembershipRole.Admin) !(organization.bypassOrgAuthEnabled && membershipRole.role === OrgMembershipRole.Admin)
) { ) {
return { user }; return { user };
} }
@@ -1331,7 +1361,13 @@ export const orgServiceFactory = ({
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}: TDeleteOrgMembershipDTO) => { }: TDeleteOrgMembershipDTO) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId); const { permission } = await permissionService.getOrgPermission(
ActorType.USER,
userId,
orgId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Member); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Member);
const deletedMembership = await deleteOrgMembershipFn({ const deletedMembership = await deleteOrgMembershipFn({
@@ -1339,11 +1375,11 @@ export const orgServiceFactory = ({
orgId, orgId,
orgDAL, orgDAL,
projectMembershipDAL, projectMembershipDAL,
projectUserAdditionalPrivilegeDAL,
projectKeyDAL, projectKeyDAL,
userAliasDAL, userAliasDAL,
licenseService, licenseService,
userId userId,
membershipUserDAL
}); });
return deletedMembership; return deletedMembership;
@@ -1356,7 +1392,13 @@ export const orgServiceFactory = ({
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}: TDeleteOrgMembershipsDTO) => { }: TDeleteOrgMembershipsDTO) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId); const { permission } = await permissionService.getOrgPermission(
ActorType.USER,
userId,
orgId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Member); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Member);
if (membershipIds.includes(userId)) { if (membershipIds.includes(userId)) {
@@ -1368,11 +1410,11 @@ export const orgServiceFactory = ({
orgId, orgId,
orgDAL, orgDAL,
projectMembershipDAL, projectMembershipDAL,
projectUserAdditionalPrivilegeDAL,
projectKeyDAL, projectKeyDAL,
userAliasDAL, userAliasDAL,
licenseService, licenseService,
userId userId,
membershipUserDAL
}); });
return deletedMemberships; return deletedMemberships;
@@ -1409,7 +1451,13 @@ export const orgServiceFactory = ({
actorAuthMethod: ActorAuthMethod, actorAuthMethod: ActorAuthMethod,
actorOrgId: string | undefined actorOrgId: string | undefined
) => { ) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId); const { permission } = await permissionService.getOrgPermission(
ActorType.USER,
userId,
orgId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.IncidentAccount); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.IncidentAccount);
const incidentContacts = await incidentContactDAL.findByOrgId(orgId); const incidentContacts = await incidentContactDAL.findByOrgId(orgId);
return incidentContacts; return incidentContacts;
@@ -1422,7 +1470,13 @@ export const orgServiceFactory = ({
actorAuthMethod: ActorAuthMethod, actorAuthMethod: ActorAuthMethod,
actorOrgId: string | undefined actorOrgId: string | undefined
) => { ) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId); const { permission } = await permissionService.getOrgPermission(
ActorType.USER,
userId,
orgId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.IncidentAccount); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.IncidentAccount);
const doesIncidentContactExist = await incidentContactDAL.findOne(orgId, { email }); const doesIncidentContactExist = await incidentContactDAL.findOne(orgId, { email });
if (doesIncidentContactExist) { if (doesIncidentContactExist) {
@@ -1443,7 +1497,13 @@ export const orgServiceFactory = ({
actorAuthMethod: ActorAuthMethod, actorAuthMethod: ActorAuthMethod,
actorOrgId: string | undefined actorOrgId: string | undefined
) => { ) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId); const { permission } = await permissionService.getOrgPermission(
ActorType.USER,
userId,
orgId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.IncidentAccount); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.IncidentAccount);
const incidentContact = await incidentContactDAL.deleteById(id, orgId); const incidentContact = await incidentContactDAL.deleteById(id, orgId);
@@ -1464,17 +1524,17 @@ export const orgServiceFactory = ({
await Promise.all( await Promise.all(
invitedUsers.map(async (invitedUser) => { invitedUsers.map(async (invitedUser) => {
let org = orgCache[invitedUser.orgId]; let org = orgCache[invitedUser.scopeOrgId];
if (!org) { if (!org) {
org = await orgDAL.findById(invitedUser.orgId); org = await orgDAL.findById(invitedUser.scopeOrgId);
orgCache[invitedUser.orgId] = org; orgCache[invitedUser.scopeOrgId] = org;
} }
if (!org || !invitedUser.userId) return; if (!org || !invitedUser.actorUserId) return;
const token = await tokenService.createTokenForUser({ const token = await tokenService.createTokenForUser({
type: TokenType.TOKEN_EMAIL_ORG_INVITATION, type: TokenType.TOKEN_EMAIL_ORG_INVITATION,
userId: invitedUser.userId, userId: invitedUser.actorUserId,
orgId: org.id orgId: org.id
}); });
@@ -1,25 +1,25 @@
import { ForbiddenError } from "@casl/ability"; import { ForbiddenError } from "@casl/ability";
import { 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";
import { ProjectPermissionMemberActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { ProjectPermissionMemberActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
import { BadRequestError } from "@app/lib/errors"; import { BadRequestError } from "@app/lib/errors";
import { TProjectMembershipDALFactory } from "../project-membership/project-membership-dal"; import { TMembershipUserDALFactory } from "../membership-user/membership-user-dal";
import { TProjectKeyDALFactory } from "./project-key-dal"; import { TProjectKeyDALFactory } from "./project-key-dal";
import { TGetLatestProjectKeyDTO, TUploadProjectKeyDTO } from "./project-key-types"; import { TGetLatestProjectKeyDTO, TUploadProjectKeyDTO } from "./project-key-types";
type TProjectKeyServiceFactoryDep = { type TProjectKeyServiceFactoryDep = {
permissionService: TPermissionServiceFactory; permissionService: TPermissionServiceFactory;
projectKeyDAL: TProjectKeyDALFactory; projectKeyDAL: TProjectKeyDALFactory;
projectMembershipDAL: TProjectMembershipDALFactory; membershipUserDAL: TMembershipUserDALFactory;
}; };
export type TProjectKeyServiceFactory = ReturnType<typeof projectKeyServiceFactory>; export type TProjectKeyServiceFactory = ReturnType<typeof projectKeyServiceFactory>;
export const projectKeyServiceFactory = ({ export const projectKeyServiceFactory = ({
projectKeyDAL, projectKeyDAL,
projectMembershipDAL, membershipUserDAL,
permissionService permissionService
}: TProjectKeyServiceFactoryDep) => { }: TProjectKeyServiceFactoryDep) => {
const uploadProjectKeys = async ({ const uploadProjectKeys = async ({
@@ -42,9 +42,10 @@ export const projectKeyServiceFactory = ({
}); });
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Edit, ProjectPermissionSub.Member); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionMemberActions.Edit, ProjectPermissionSub.Member);
const receiverMembership = await projectMembershipDAL.findOne({ const receiverMembership = await membershipUserDAL.findOne({
userId: receiverId, actorUserId: receiverId,
projectId scopeProjectId: projectId,
scope: AccessScope.Project
}); });
if (!receiverMembership) if (!receiverMembership)
throw new BadRequestError({ throw new BadRequestError({
+5 -18
View File
@@ -348,10 +348,11 @@ export const projectDALFactory = (db: TDbClient) => {
.where(`${TableName.Groups}.orgId`, dto.orgId) .where(`${TableName.Groups}.orgId`, dto.orgId)
.where(`${TableName.UserGroupMembership}.userId`, dto.actorId) .where(`${TableName.UserGroupMembership}.userId`, dto.actorId)
.select(db.ref("id").withSchema(TableName.Groups)); .select(db.ref("id").withSchema(TableName.Groups));
const userMembershipSubquery = db(TableName.Membership) const membershipSubQuery = db(TableName.Membership)
.where(`${TableName.Membership}.scope`, AccessScope.Project) .where(`${TableName.Membership}.scope`, AccessScope.Project)
.where((qb) => { .where((qb) => {
if (dto.actor === ActorType.IDENTITY) { if (dto.actor === ActorType.IDENTITY) {
void qb.where(`${TableName.Membership}.actorIdentityId`, dto.actorId);
} else { } else {
void qb void qb
.where(`${TableName.Membership}.actorUserId`, dto.actorId) .where(`${TableName.Membership}.actorUserId`, dto.actorId)
@@ -360,11 +361,8 @@ export const projectDALFactory = (db: TDbClient) => {
}) })
.select("scopeProjectId"); .select("scopeProjectId");
const identityMembershipSubQuery = db(TableName.Membership).where({ identityId: dto.actorId }).select("projectId");
// Get the SQL strings for the subqueries // Get the SQL strings for the subqueries
const userMembershipSql = userMembershipSubquery.toQuery(); const membershipSQL = membershipSubQuery.toQuery();
const identityMembershipSql = identityMembershipSubQuery.toQuery();
const query = db const query = db
.replicaNode()(TableName.Project) .replicaNode()(TableName.Project)
@@ -372,25 +370,14 @@ export const projectDALFactory = (db: TDbClient) => {
.select(selectAllTableCols(TableName.Project)) .select(selectAllTableCols(TableName.Project))
.select(db.raw("COUNT(*) OVER() AS count")) .select(db.raw("COUNT(*) OVER() AS count"))
.select<(TProjects & { isMember: boolean; count: number })[]>( .select<(TProjects & { isMember: boolean; count: number })[]>(
dto.actor === ActorType.USER db.raw(
? db.raw(
`
CASE
WHEN ${TableName.Project}.id IN (?) THEN TRUE
WHEN ${TableName.Project}.id IN (?) THEN TRUE
ELSE FALSE
END as "isMember"
`,
[db.raw(userMembershipSql)]
)
: db.raw(
` `
CASE CASE
WHEN ${TableName.Project}.id IN (?) THEN TRUE WHEN ${TableName.Project}.id IN (?) THEN TRUE
ELSE FALSE ELSE FALSE
END as "isMember" END as "isMember"
`, `,
[db.raw(identityMembershipSql)] [db.raw(membershipSQL)]
) )
) )
.limit(limit) .limit(limit)
+16 -15
View File
@@ -1,5 +1,6 @@
/* eslint-disable no-await-in-loop */ /* eslint-disable no-await-in-loop */
import { import {
AccessScope,
IntegrationAuthsSchema, IntegrationAuthsSchema,
ProjectMembershipRole, ProjectMembershipRole,
ProjectUpgradeStatus, ProjectUpgradeStatus,
@@ -34,14 +35,14 @@ import { TOrgServiceFactory } from "../org/org-service";
import { TProjectBotDALFactory } from "../project-bot/project-bot-dal"; import { TProjectBotDALFactory } from "../project-bot/project-bot-dal";
import { TProjectEnvDALFactory } from "../project-env/project-env-dal"; import { TProjectEnvDALFactory } from "../project-env/project-env-dal";
import { TProjectKeyDALFactory } from "../project-key/project-key-dal"; import { TProjectKeyDALFactory } from "../project-key/project-key-dal";
import { TProjectMembershipDALFactory } from "../project-membership/project-membership-dal";
import { TProjectUserMembershipRoleDALFactory } from "../project-membership/project-user-membership-role-dal";
import { TSecretDALFactory } from "../secret/secret-dal"; import { TSecretDALFactory } from "../secret/secret-dal";
import { TSecretVersionDALFactory } from "../secret/secret-version-dal"; import { TSecretVersionDALFactory } from "../secret/secret-version-dal";
import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal"; import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal";
import { TUserDALFactory } from "../user/user-dal"; import { TUserDALFactory } from "../user/user-dal";
import { TProjectDALFactory } from "./project-dal"; import { TProjectDALFactory } from "./project-dal";
import { assignWorkspaceKeysToMembers, createProjectKey } from "./project-fns"; import { assignWorkspaceKeysToMembers, createProjectKey } from "./project-fns";
import { TMembershipUserDALFactory } from "../membership-user/membership-user-dal";
import { TMembershipRoleDALFactory } from "../membership/membership-role-dal";
export type TProjectQueueFactory = ReturnType<typeof projectQueueFactory>; export type TProjectQueueFactory = ReturnType<typeof projectQueueFactory>;
@@ -55,13 +56,13 @@ type TProjectQueueFactoryDep = {
secretApprovalSecretDAL: Pick<TSecretApprovalRequestSecretDALFactory, "find" | "bulkUpdateNoVersionIncrement">; secretApprovalSecretDAL: Pick<TSecretApprovalRequestSecretDALFactory, "find" | "bulkUpdateNoVersionIncrement">;
projectBotDAL: Pick<TProjectBotDALFactory, "findOne" | "delete" | "create">; projectBotDAL: Pick<TProjectBotDALFactory, "findOne" | "delete" | "create">;
orgService: Pick<TOrgServiceFactory, "addGhostUser">; orgService: Pick<TOrgServiceFactory, "addGhostUser">;
projectMembershipDAL: Pick<TProjectMembershipDALFactory, "create">;
projectUserMembershipRoleDAL: Pick<TProjectUserMembershipRoleDALFactory, "create">;
integrationAuthDAL: TIntegrationAuthDALFactory; integrationAuthDAL: TIntegrationAuthDALFactory;
userDAL: Pick<TUserDALFactory, "findUserEncKeyByUserId">; userDAL: Pick<TUserDALFactory, "findUserEncKeyByUserId">;
projectEnvDAL: Pick<TProjectEnvDALFactory, "find">; projectEnvDAL: Pick<TProjectEnvDALFactory, "find">;
projectDAL: Pick<TProjectDALFactory, "findOne" | "transaction" | "updateById" | "setProjectUpgradeStatus" | "find">; projectDAL: Pick<TProjectDALFactory, "findOne" | "transaction" | "updateById" | "setProjectUpgradeStatus" | "find">;
orgDAL: Pick<TOrgDALFactory, "findMembership">; orgDAL: Pick<TOrgDALFactory, "findMembership">;
membershipUserDAL: TMembershipUserDALFactory;
membershipRoleDAL: TMembershipRoleDALFactory;
}; };
export const projectQueueFactory = ({ export const projectQueueFactory = ({
@@ -79,8 +80,8 @@ export const projectQueueFactory = ({
orgDAL, orgDAL,
projectDAL, projectDAL,
orgService, orgService,
projectMembershipDAL, membershipUserDAL,
projectUserMembershipRoleDAL membershipRoleDAL
}: TProjectQueueFactoryDep) => { }: TProjectQueueFactoryDep) => {
const upgradeProject = async (dto: TQueueJobTypes["upgrade-project-to-ghost"]["payload"]) => { const upgradeProject = async (dto: TQueueJobTypes["upgrade-project-to-ghost"]["payload"]) => {
await queueService.queue(QueueName.UpgradeProjectToGhost, QueueJobs.UpgradeProjectToGhost, dto, { await queueService.queue(QueueName.UpgradeProjectToGhost, QueueJobs.UpgradeProjectToGhost, dto, {
@@ -227,17 +228,16 @@ export const projectQueueFactory = ({
); );
// Create a membership for the ghost user // Create a membership for the ghost user
const projectMembership = await projectMembershipDAL.create( const projectMembership = await membershipUserDAL.create(
{ {
projectId: project.id, scopeProjectId: project.id,
userId: ghostUser.user.id scope: AccessScope.Project,
actorUserId: ghostUser.user.id,
scopeOrgId: project.orgId
}, },
tx tx
); );
await projectUserMembershipRoleDAL.create( await membershipRoleDAL.create({ membershipId: projectMembership.id, role: ProjectMembershipRole.Admin }, tx);
{ projectMembershipId: projectMembership.id, role: ProjectMembershipRole.Admin },
tx
);
// If a bot already exists, delete it // If a bot already exists, delete it
if (existingBot) { if (existingBot) {
@@ -272,8 +272,9 @@ export const projectQueueFactory = ({
for (const key of existingProjectKeys) { for (const key of existingProjectKeys) {
const user = await userDAL.findUserEncKeyByUserId(key.receiverId); const user = await userDAL.findUserEncKeyByUserId(key.receiverId);
const [orgMembership] = await orgDAL.findMembership({ const [orgMembership] = await orgDAL.findMembership({
[`${TableName.OrgMembership}.userId` as "userId"]: key.receiverId, [`${TableName.Membership}.actorUserId` as "actorUserId"]: key.receiverId,
[`${TableName.OrgMembership}.orgId` as "orgId"]: project.orgId [`${TableName.Membership}.scopeOrgId` as "scopeOrgId"]: project.orgId,
[`${TableName.Membership}.scope` as "scope"]: AccessScope.Organization
}); });
if (!user) { if (!user) {
+44 -42
View File
@@ -3,6 +3,7 @@ import { PackRule, unpackRules } from "@casl/ability/extra";
import slugify from "@sindresorhus/slugify"; import slugify from "@sindresorhus/slugify";
import { import {
AccessScope,
ActionProjectType, ActionProjectType,
ProjectMembershipRole, ProjectMembershipRole,
ProjectType, ProjectType,
@@ -49,11 +50,11 @@ import { TCertificateDALFactory } from "../certificate/certificate-dal";
import { TCertificateAuthorityDALFactory } from "../certificate-authority/certificate-authority-dal"; import { TCertificateAuthorityDALFactory } from "../certificate-authority/certificate-authority-dal";
import { expandInternalCa } from "../certificate-authority/certificate-authority-fns"; import { expandInternalCa } from "../certificate-authority/certificate-authority-fns";
import { TCertificateTemplateDALFactory } from "../certificate-template/certificate-template-dal"; import { TCertificateTemplateDALFactory } from "../certificate-template/certificate-template-dal";
import { TGroupProjectDALFactory } from "../group-project/group-project-dal";
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal";
import { TIdentityProjectDALFactory } from "../identity-project/identity-project-dal";
import { TIdentityProjectMembershipRoleDALFactory } from "../identity-project/identity-project-membership-role-dal";
import { TKmsServiceFactory } from "../kms/kms-service"; import { TKmsServiceFactory } from "../kms/kms-service";
import { TMembershipRoleDALFactory } from "../membership/membership-role-dal";
import { TMembershipGroupDALFactory } from "../membership-group/membership-group-dal";
import { TMembershipIdentityDALFactory } from "../membership-identity/membership-identity-dal";
import { TMembershipUserDALFactory } from "../membership-user/membership-user-dal";
import { validateMicrosoftTeamsChannelsSchema } from "../microsoft-teams/microsoft-teams-fns"; import { validateMicrosoftTeamsChannelsSchema } from "../microsoft-teams/microsoft-teams-fns";
import { TMicrosoftTeamsIntegrationDALFactory } from "../microsoft-teams/microsoft-teams-integration-dal"; import { TMicrosoftTeamsIntegrationDALFactory } from "../microsoft-teams/microsoft-teams-integration-dal";
import { TProjectMicrosoftTeamsConfigDALFactory } from "../microsoft-teams/project-microsoft-teams-config-dal"; import { TProjectMicrosoftTeamsConfigDALFactory } from "../microsoft-teams/project-microsoft-teams-config-dal";
@@ -65,10 +66,9 @@ import { TPkiCollectionDALFactory } from "../pki-collection/pki-collection-dal";
import { TProjectBotServiceFactory } from "../project-bot/project-bot-service"; import { TProjectBotServiceFactory } from "../project-bot/project-bot-service";
import { TProjectEnvDALFactory } from "../project-env/project-env-dal"; import { TProjectEnvDALFactory } from "../project-env/project-env-dal";
import { TProjectMembershipDALFactory } from "../project-membership/project-membership-dal"; import { TProjectMembershipDALFactory } from "../project-membership/project-membership-dal";
import { TProjectUserMembershipRoleDALFactory } from "../project-membership/project-user-membership-role-dal";
import { TProjectRoleDALFactory } from "../project-role/project-role-dal";
import { getPredefinedRoles } from "../project-role/project-role-fns"; import { getPredefinedRoles } from "../project-role/project-role-fns";
import { TReminderServiceFactory } from "../reminder/reminder-types"; import { TReminderServiceFactory } from "../reminder/reminder-types";
import { TRoleDALFactory } from "../role/role-dal";
import { TSecretDALFactory } from "../secret/secret-dal"; import { TSecretDALFactory } from "../secret/secret-dal";
import { fnDeleteProjectSecretReminders } from "../secret/secret-fns"; import { fnDeleteProjectSecretReminders } from "../secret/secret-fns";
import { ROOT_FOLDER_NAME, TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal"; import { ROOT_FOLDER_NAME, TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal";
@@ -125,7 +125,6 @@ export const DEFAULT_PROJECT_ENVS = [
type TProjectServiceFactoryDep = { type TProjectServiceFactoryDep = {
projectDAL: TProjectDALFactory; projectDAL: TProjectDALFactory;
identityProjectDAL: Pick<TIdentityProjectDALFactory, "create">;
projectSshConfigDAL: Pick<TProjectSshConfigDALFactory, "transaction" | "create" | "findOne" | "updateById">; projectSshConfigDAL: Pick<TProjectSshConfigDALFactory, "transaction" | "create" | "findOne" | "updateById">;
projectQueue: TProjectQueueFactory; projectQueue: TProjectQueueFactory;
userDAL: TUserDALFactory; userDAL: TUserDALFactory;
@@ -134,13 +133,11 @@ type TProjectServiceFactoryDep = {
secretDAL: Pick<TSecretDALFactory, "find">; secretDAL: Pick<TSecretDALFactory, "find">;
secretV2BridgeDAL: Pick<TSecretV2BridgeDALFactory, "find">; secretV2BridgeDAL: Pick<TSecretV2BridgeDALFactory, "find">;
projectEnvDAL: Pick<TProjectEnvDALFactory, "insertMany" | "find">; projectEnvDAL: Pick<TProjectEnvDALFactory, "insertMany" | "find">;
identityOrgMembershipDAL: TIdentityOrgDALFactory; projectMembershipDAL: Pick<TProjectMembershipDALFactory, "findProjectGhostUser" | "findAllProjectMembers">;
identityProjectMembershipRoleDAL: Pick<TIdentityProjectMembershipRoleDALFactory, "create">; membershipUserDAL: Pick<TMembershipUserDALFactory, "create" | "findOne" | "delete">;
projectMembershipDAL: Pick< membershipGroupDAL: Pick<TMembershipGroupDALFactory, "delete">;
TProjectMembershipDALFactory, membershipIdentityDAL: Pick<TMembershipIdentityDALFactory, "create" | "findOne">;
"create" | "findProjectGhostUser" | "findOne" | "delete" | "findAllProjectMembers" membershipRoleDAL: Pick<TMembershipRoleDALFactory, "create">;
>;
groupProjectDAL: Pick<TGroupProjectDALFactory, "delete">;
projectSlackConfigDAL: Pick< projectSlackConfigDAL: Pick<
TProjectSlackConfigDALFactory, TProjectSlackConfigDALFactory,
"findOne" | "transaction" | "updateById" | "create" | "delete" "findOne" | "transaction" | "updateById" | "create" | "delete"
@@ -154,7 +151,6 @@ type TProjectServiceFactoryDep = {
TMicrosoftTeamsIntegrationDALFactory, TMicrosoftTeamsIntegrationDALFactory,
"findById" | "findByIdWithWorkflowIntegrationDetails" "findById" | "findByIdWithWorkflowIntegrationDetails"
>; >;
projectUserMembershipRoleDAL: Pick<TProjectUserMembershipRoleDALFactory, "create">;
pkiSubscriberDAL: Pick<TPkiSubscriberDALFactory, "find">; pkiSubscriberDAL: Pick<TPkiSubscriberDALFactory, "find">;
certificateAuthorityDAL: Pick<TCertificateAuthorityDALFactory, "find" | "findWithAssociatedCa">; certificateAuthorityDAL: Pick<TCertificateAuthorityDALFactory, "find" | "findWithAssociatedCa">;
certificateDAL: Pick<TCertificateDALFactory, "find" | "countCertificatesInProject">; certificateDAL: Pick<TCertificateDALFactory, "find" | "countCertificatesInProject">;
@@ -172,7 +168,7 @@ type TProjectServiceFactoryDep = {
smtpService: Pick<TSmtpService, "sendMail">; smtpService: Pick<TSmtpService, "sendMail">;
orgDAL: Pick<TOrgDALFactory, "findOne">; orgDAL: Pick<TOrgDALFactory, "findOne">;
keyStore: Pick<TKeyStoreFactory, "deleteItem">; keyStore: Pick<TKeyStoreFactory, "deleteItem">;
projectRoleDAL: Pick<TProjectRoleDALFactory, "find" | "insertMany" | "delete">; roleDAL: Pick<TRoleDALFactory, "find" | "insertMany" | "delete">;
kmsService: Pick< kmsService: Pick<
TKmsServiceFactory, TKmsServiceFactory,
| "updateProjectSecretManagerKmsKey" | "updateProjectSecretManagerKmsKey"
@@ -201,20 +197,15 @@ export const projectServiceFactory = ({
orgDAL, orgDAL,
userDAL, userDAL,
folderDAL, folderDAL,
identityOrgMembershipDAL,
projectMembershipDAL, projectMembershipDAL,
projectEnvDAL, projectEnvDAL,
licenseService, licenseService,
projectUserMembershipRoleDAL,
projectRoleDAL,
certificateAuthorityDAL, certificateAuthorityDAL,
certificateDAL, certificateDAL,
certificateTemplateDAL, certificateTemplateDAL,
pkiCollectionDAL, pkiCollectionDAL,
pkiAlertDAL, pkiAlertDAL,
pkiSubscriberDAL, pkiSubscriberDAL,
identityProjectDAL,
identityProjectMembershipRoleDAL,
sshCertificateAuthorityDAL, sshCertificateAuthorityDAL,
sshCertificateAuthoritySecretDAL, sshCertificateAuthoritySecretDAL,
sshCertificateDAL, sshCertificateDAL,
@@ -228,10 +219,13 @@ export const projectServiceFactory = ({
slackIntegrationDAL, slackIntegrationDAL,
microsoftTeamsIntegrationDAL, microsoftTeamsIntegrationDAL,
projectTemplateService, projectTemplateService,
groupProjectDAL,
smtpService, smtpService,
reminderService, reminderService,
notificationService notificationService,
membershipIdentityDAL,
membershipUserDAL,
membershipRoleDAL,
roleDAL
}: TProjectServiceFactoryDep) => { }: TProjectServiceFactoryDep) => {
/* /*
* Create workspace. Make user the admin * Create workspace. Make user the admin
@@ -345,7 +339,7 @@ export const projectServiceFactory = ({
tx tx
); );
} }
await projectRoleDAL.insertMany( await roleDAL.insertMany(
projectTemplate.packedRoles.map((role) => ({ projectTemplate.packedRoles.map((role) => ({
...role, ...role,
permissions: JSON.stringify(role.permissions), permissions: JSON.stringify(role.permissions),
@@ -374,15 +368,17 @@ export const projectServiceFactory = ({
} }
// Create a membership for the user // Create a membership for the user
const userProjectMembership = await projectMembershipDAL.create( const userProjectMembership = await membershipUserDAL.create(
{ {
projectId: project.id, scopeProjectId: project.id,
userId: user.id actorUserId: user.id,
scope: AccessScope.Project,
scopeOrgId: project.orgId
}, },
tx tx
); );
await projectUserMembershipRoleDAL.create( await membershipRoleDAL.create(
{ projectMembershipId: userProjectMembership.id, role: ProjectMembershipRole.Admin }, { membershipId: userProjectMembership.id, role: ProjectMembershipRole.Admin },
tx tx
); );
} }
@@ -390,10 +386,11 @@ export const projectServiceFactory = ({
// If the project is being created by an identity, add the identity to the project as an admin // If the project is being created by an identity, add the identity to the project as an admin
else if (actor === ActorType.IDENTITY) { else if (actor === ActorType.IDENTITY) {
// Find identity org membership // Find identity org membership
const identityOrgMembership = await identityOrgMembershipDAL.findOne( const identityOrgMembership = await membershipIdentityDAL.findOne(
{ {
identityId: actorId, actorIdentityId: actorId,
orgId: project.orgId scopeOrgId: project.orgId,
scope: AccessScope.Organization
}, },
tx tx
); );
@@ -405,17 +402,19 @@ export const projectServiceFactory = ({
}); });
} }
const identityProjectMembership = await identityProjectDAL.create( const identityProjectMembership = await membershipIdentityDAL.create(
{ {
identityId: actorId, actorIdentityId: actorId,
projectId: project.id scopeProjectId: project.id,
scope: AccessScope.Project,
scopeOrgId: project.orgId
}, },
tx tx
); );
await identityProjectMembershipRoleDAL.create( await membershipRoleDAL.create(
{ {
projectMembershipId: identityProjectMembership.id, membershipId: identityProjectMembership.id,
role: ProjectMembershipRole.Admin role: ProjectMembershipRole.Admin
}, },
tx tx
@@ -459,8 +458,11 @@ export const projectServiceFactory = ({
const deletedProject = await projectDAL.transaction(async (tx) => { const deletedProject = await projectDAL.transaction(async (tx) => {
// delete these so that project custom roles can be deleted in cascade effect // delete these so that project custom roles can be deleted in cascade effect
// direct deletion of project without these will cause fk error // direct deletion of project without these will cause fk error
await projectMembershipDAL.delete({ projectId: project.id }, tx); // this will clean up all memberships
await groupProjectDAL.delete({ projectId: project.id }, tx); await membershipUserDAL.delete(
{ scopeOrgId: project.orgId, scopeProjectId: project.id, scope: AccessScope.Project },
tx
);
const delProject = await projectDAL.deleteById(project.id, tx); const delProject = await projectDAL.deleteById(project.id, tx);
const projectGhostUser = await projectMembershipDAL.findProjectGhostUser(project.id, tx).catch(() => null); const projectGhostUser = await projectMembershipDAL.findProjectGhostUser(project.id, tx).catch(() => null);
// akhilmhdh: before removing those kms checking any other project uses it // akhilmhdh: before removing those kms checking any other project uses it
@@ -521,13 +523,13 @@ export const projectServiceFactory = ({
// `includeRoles` is specifically used by organization admins when inviting new users to the organizations to avoid looping redundant api calls. // `includeRoles` is specifically used by organization admins when inviting new users to the organizations to avoid looping redundant api calls.
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Member); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Member);
const customRoles = await projectRoleDAL.find({ const customRoles = await roleDAL.find({
$in: { $in: {
projectId: workspaces.map((workspace) => workspace.id) projectId: workspaces.map((workspace) => workspace.id)
} }
}); });
const workspaceMappedToRoles = groupBy(customRoles, (role) => role.projectId); const workspaceMappedToRoles = groupBy(customRoles, (role) => role.projectId as string);
const workspacesWithRoles = await Promise.all( const workspacesWithRoles = await Promise.all(
workspaces.map(async (workspace) => { workspaces.map(async (workspace) => {
@@ -1872,7 +1874,7 @@ export const projectServiceFactory = ({
.filter((member) => member.roles.some((role) => role.role === ProjectMembershipRole.Admin)) .filter((member) => member.roles.some((role) => role.role === ProjectMembershipRole.Admin))
.map((el) => el.user.email!); .map((el) => el.user.email!);
if (filteredProjectMembers.length === 0) { if (filteredProjectMembers.length === 0) {
const customRolesWithMemberCreate = await projectRoleDAL.find({ projectId }); const customRolesWithMemberCreate = await roleDAL.find({ projectId });
const customRoleSlugsCanCreate = customRolesWithMemberCreate const customRoleSlugsCanCreate = customRolesWithMemberCreate
.filter((role) => { .filter((role) => {
try { try {
@@ -14,6 +14,7 @@ import { BadRequestError } from "@app/lib/errors";
import { TRoleScopeFactory } from "../role-types"; import { TRoleScopeFactory } from "../role-types";
import { isCustomOrgRole } from "@app/services/org/org-role-fns"; import { isCustomOrgRole } from "@app/services/org/org-role-fns";
// TODO(simp): missing external group checking
type TOrgRoleScopeFactoryDep = { type TOrgRoleScopeFactoryDep = {
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">; permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
}; };
+70 -3
View File
@@ -1,4 +1,4 @@
import { AccessScope, TableName } from "@app/db/schemas"; import { AccessScope, ActionProjectType, TableName } from "@app/db/schemas";
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
import { BadRequestError, NotFoundError } from "@app/lib/errors"; import { BadRequestError, NotFoundError } from "@app/lib/errors";
import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars"; import { validateHandlebarTemplate } from "@app/lib/template/validate-handlebars";
@@ -13,20 +13,34 @@ import {
TDeleteRoleDTO, TDeleteRoleDTO,
TGetRoleByIdDTO, TGetRoleByIdDTO,
TGetRoleBySlugDTO, TGetRoleBySlugDTO,
TGetUserPermissionDTO,
TListRoleDTO, TListRoleDTO,
TUpdateRoleDTO TUpdateRoleDTO
} from "./role-types"; } from "./role-types";
import { TProjectDALFactory } from "../project/project-dal"; import { TProjectDALFactory } from "../project/project-dal";
import { packRules } from "@casl/ability/extra";
import { requestContext } from "@fastify/request-context";
import { TIdentityDALFactory } from "../identity/identity-dal";
import { TUserDALFactory } from "../user/user-dal";
import { ActorType } from "../auth/auth-type";
type TRoleServiceFactoryDep = { type TRoleServiceFactoryDep = {
roleDAL: TRoleDALFactory; roleDAL: TRoleDALFactory;
identityDAL: Pick<TIdentityDALFactory, "findById">;
userDAL: Pick<TUserDALFactory, "findById">;
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission" | "getOrgPermission">; permissionService: Pick<TPermissionServiceFactory, "getProjectPermission" | "getOrgPermission">;
projectDAL: Pick<TProjectDALFactory, "findById">; projectDAL: Pick<TProjectDALFactory, "findById">;
}; };
export type TRoleServiceFactory = ReturnType<typeof roleServiceFactory>; export type TRoleServiceFactory = ReturnType<typeof roleServiceFactory>;
export const roleServiceFactory = ({ roleDAL, permissionService, projectDAL }: TRoleServiceFactoryDep) => { export const roleServiceFactory = ({
roleDAL,
permissionService,
projectDAL,
identityDAL,
userDAL
}: TRoleServiceFactoryDep) => {
const orgRoleFactory = newOrgRoleFactory({ const orgRoleFactory = newOrgRoleFactory({
permissionService permissionService
}); });
@@ -186,12 +200,65 @@ export const roleServiceFactory = ({ roleDAL, permissionService, projectDAL }: T
return { ...role, [scope.key]: scope.value, permissions: unpackPermissions(role.permissions) }; return { ...role, [scope.key]: scope.value, permissions: unpackPermissions(role.permissions) };
}; };
const getUserPermission = async (dto: TGetUserPermissionDTO) => {
if (dto.scopeData.scope === AccessScope.Organization) {
const { permission, memberships } = await permissionService.getOrgPermission(
dto.permission.type,
dto.permission.id,
dto.permission.orgId,
dto.permission.authMethod,
dto.permission.orgId
);
return { permissions: packRules(permission.rules), memberships, assumedPrivilegeDetails: undefined };
}
if (dto.scopeData.scope === AccessScope.Project) {
const { permission, memberships } = await permissionService.getProjectPermission({
actor: dto.permission.type,
actorId: dto.permission.id,
actionProjectType: ActionProjectType.Any,
actorAuthMethod: dto.permission.authMethod,
projectId: dto.scopeData.projectId,
actorOrgId: dto.permission.orgId
});
const assumedPrivilegeDetailsCtx = requestContext.get("assumedPrivilegeDetails");
const isAssumingPrivilege = assumedPrivilegeDetailsCtx?.projectId === dto.scopeData.projectId;
const assumedPrivilegeDetails = isAssumingPrivilege
? {
actorId: assumedPrivilegeDetailsCtx?.actorId,
actorType: assumedPrivilegeDetailsCtx?.actorType,
actorName: "",
actorEmail: ""
}
: undefined;
if (assumedPrivilegeDetails?.actorType === ActorType.IDENTITY) {
const identityDetails = await identityDAL.findById(assumedPrivilegeDetails.actorId);
if (!identityDetails)
throw new NotFoundError({ message: `Identity with ID ${assumedPrivilegeDetails.actorId} not found` });
assumedPrivilegeDetails.actorName = identityDetails.name;
} else if (assumedPrivilegeDetails?.actorType === ActorType.USER) {
const userDetails = await userDAL.findById(assumedPrivilegeDetails?.actorId);
if (!userDetails)
throw new NotFoundError({ message: `User with ID ${assumedPrivilegeDetails.actorId} not found` });
assumedPrivilegeDetails.actorName = `${userDetails?.firstName} ${userDetails?.lastName || ""}`;
assumedPrivilegeDetails.actorEmail = userDetails?.email || "";
}
return { permissions: packRules(permission.rules), memberships, assumedPrivilegeDetails };
}
throw new BadRequestError({ message: "Invalid scope defined" });
};
return { return {
createRole, createRole,
updateRole, updateRole,
deleteRole, deleteRole,
listRoles, listRoles,
getRoleById, getRoleById,
getRoleBySlug getRoleBySlug,
getUserPermission
}; };
}; };
+5
View File
@@ -71,3 +71,8 @@ export type TGetRoleBySlugDTO = {
slug: string; slug: string;
}; };
}; };
export type TGetUserPermissionDTO = {
permission: OrgServiceActor;
scopeData: AccessScopeData;
};
+15 -12
View File
@@ -4,6 +4,7 @@ import { AxiosError } from "axios";
import { Knex } from "knex"; import { Knex } from "knex";
import { import {
AccessScope,
ProjectMembershipRole, ProjectMembershipRole,
ProjectType, ProjectType,
ProjectUpgradeStatus, ProjectUpgradeStatus,
@@ -50,7 +51,6 @@ import { TProjectBotServiceFactory } from "../project-bot/project-bot-service";
import { TProjectEnvDALFactory } from "../project-env/project-env-dal"; import { TProjectEnvDALFactory } from "../project-env/project-env-dal";
import { TProjectKeyDALFactory } from "../project-key/project-key-dal"; import { TProjectKeyDALFactory } from "../project-key/project-key-dal";
import { TProjectMembershipDALFactory } from "../project-membership/project-membership-dal"; import { TProjectMembershipDALFactory } from "../project-membership/project-membership-dal";
import { TProjectUserMembershipRoleDALFactory } from "../project-membership/project-user-membership-role-dal";
import { TReminderServiceFactory } from "../reminder/reminder-types"; import { TReminderServiceFactory } from "../reminder/reminder-types";
import { TResourceMetadataDALFactory } from "../resource-metadata/resource-metadata-dal"; import { TResourceMetadataDALFactory } from "../resource-metadata/resource-metadata-dal";
import { ResourceMetadataDTO } from "../resource-metadata/resource-metadata-schema"; import { ResourceMetadataDTO } from "../resource-metadata/resource-metadata-schema";
@@ -76,6 +76,8 @@ import {
TRemoveSecretReminderDTO, TRemoveSecretReminderDTO,
TSyncSecretsDTO TSyncSecretsDTO
} from "./secret-types"; } from "./secret-types";
import { TMembershipDALFactory } from "../membership/membership-dal";
import { TMembershipRoleDALFactory } from "../membership/membership-role-dal";
export type TSecretQueueFactory = ReturnType<typeof secretQueueFactory>; export type TSecretQueueFactory = ReturnType<typeof secretQueueFactory>;
type TSecretQueueFactoryDep = { type TSecretQueueFactoryDep = {
@@ -92,7 +94,9 @@ type TSecretQueueFactoryDep = {
projectDAL: TProjectDALFactory; projectDAL: TProjectDALFactory;
projectBotDAL: TProjectBotDALFactory; projectBotDAL: TProjectBotDALFactory;
projectKeyDAL: Pick<TProjectKeyDALFactory, "create">; projectKeyDAL: Pick<TProjectKeyDALFactory, "create">;
projectMembershipDAL: Pick<TProjectMembershipDALFactory, "findAllProjectMembers" | "create">; projectMembershipDAL: Pick<TProjectMembershipDALFactory, "findAllProjectMembers">;
membershipUserDAL: Pick<TMembershipDALFactory, "create">;
membershipRoleDAL: Pick<TMembershipRoleDALFactory, "create">;
smtpService: TSmtpService; smtpService: TSmtpService;
secretVersionDAL: TSecretVersionDALFactory; secretVersionDAL: TSecretVersionDALFactory;
secretBlindIndexDAL: TSecretBlindIndexDALFactory; secretBlindIndexDAL: TSecretBlindIndexDALFactory;
@@ -110,7 +114,6 @@ type TSecretQueueFactoryDep = {
keyStore: Pick<TKeyStoreFactory, "acquireLock" | "setItemWithExpiry" | "getItem">; keyStore: Pick<TKeyStoreFactory, "acquireLock" | "setItemWithExpiry" | "getItem">;
auditLogService: Pick<TAuditLogServiceFactory, "createAuditLog">; auditLogService: Pick<TAuditLogServiceFactory, "createAuditLog">;
orgService: Pick<TOrgServiceFactory, "addGhostUser">; orgService: Pick<TOrgServiceFactory, "addGhostUser">;
projectUserMembershipRoleDAL: Pick<TProjectUserMembershipRoleDALFactory, "create">;
resourceMetadataDAL: Pick<TResourceMetadataDALFactory, "insertMany" | "delete">; resourceMetadataDAL: Pick<TResourceMetadataDALFactory, "insertMany" | "delete">;
folderCommitService: Pick<TFolderCommitServiceFactory, "createCommit">; folderCommitService: Pick<TFolderCommitServiceFactory, "createCommit">;
secretSyncQueue: Pick<TSecretSyncQueueFactory, "queueSecretSyncsSyncSecretsByPath">; secretSyncQueue: Pick<TSecretSyncQueueFactory, "queueSecretSyncsSyncSecretsByPath">;
@@ -173,14 +176,15 @@ export const secretQueueFactory = ({
keyStore, keyStore,
auditLogService, auditLogService,
orgService, orgService,
projectUserMembershipRoleDAL,
projectKeyDAL, projectKeyDAL,
resourceMetadataDAL, resourceMetadataDAL,
secretSyncQueue, secretSyncQueue,
folderCommitService, folderCommitService,
reminderService, reminderService,
eventBusService, eventBusService,
licenseService licenseService,
membershipUserDAL,
membershipRoleDAL
}: TSecretQueueFactoryDep) => { }: TSecretQueueFactoryDep) => {
const integrationMeter = opentelemetry.metrics.getMeter("Integrations"); const integrationMeter = opentelemetry.metrics.getMeter("Integrations");
const errorHistogram = integrationMeter.createHistogram("integration_secret_sync_errors", { const errorHistogram = integrationMeter.createHistogram("integration_secret_sync_errors", {
@@ -1165,17 +1169,16 @@ export const secretQueueFactory = ({
// if project v1 create the project ghost user // if project v1 create the project ghost user
if (project.version === ProjectVersion.V1) { if (project.version === ProjectVersion.V1) {
const ghostUser = await orgService.addGhostUser(project.orgId, tx); const ghostUser = await orgService.addGhostUser(project.orgId, tx);
const projectMembership = await projectMembershipDAL.create( const projectMembership = await membershipUserDAL.create(
{ {
userId: ghostUser.user.id, actorUserId: ghostUser.user.id,
projectId: project.id scopeOrgId: project.orgId,
scope: AccessScope.Project,
scopeProjectId: project.id
}, },
tx tx
); );
await projectUserMembershipRoleDAL.create( await membershipRoleDAL.create({ membershipId: projectMembership.id, role: ProjectMembershipRole.Admin }, tx);
{ projectMembershipId: projectMembership.id, role: ProjectMembershipRole.Admin },
tx
);
const { key: encryptedProjectKey, iv: encryptedProjectKeyIv } = createProjectKey({ const { key: encryptedProjectKey, iv: encryptedProjectKeyIv } = createProjectKey({
publicKey: ghostUser.keys.publicKey, publicKey: ghostUser.keys.publicKey,
@@ -1,6 +1,7 @@
import { CronJob } from "cron"; import { CronJob } from "cron";
import { import {
AccessScope,
IdentityAuthMethod, IdentityAuthMethod,
OrgMembershipRole, OrgMembershipRole,
OrgMembershipStatus, OrgMembershipStatus,
@@ -29,7 +30,6 @@ import { SmtpTemplates, TSmtpService } from "@app/services/smtp/smtp-service";
import { TAuthLoginFactory } from "../auth/auth-login-service"; import { TAuthLoginFactory } from "../auth/auth-login-service";
import { ActorType, AuthMethod, AuthTokenType } from "../auth/auth-type"; import { ActorType, AuthMethod, AuthTokenType } from "../auth/auth-type";
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal";
import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal"; import { TIdentityAccessTokenDALFactory } from "../identity-access-token/identity-access-token-dal";
import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types"; import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identity-access-token-types";
import { TIdentityTokenAuthDALFactory } from "../identity-token-auth/identity-token-auth-dal"; import { TIdentityTokenAuthDALFactory } from "../identity-token-auth/identity-token-auth-dal";
@@ -37,10 +37,12 @@ import { KMS_ROOT_CONFIG_UUID } from "../kms/kms-fns";
import { TKmsRootConfigDALFactory } from "../kms/kms-root-config-dal"; import { TKmsRootConfigDALFactory } from "../kms/kms-root-config-dal";
import { TKmsServiceFactory } from "../kms/kms-service"; import { TKmsServiceFactory } from "../kms/kms-service";
import { RootKeyEncryptionStrategy } from "../kms/kms-types"; import { RootKeyEncryptionStrategy } from "../kms/kms-types";
import { TMembershipRoleDALFactory } from "../membership/membership-role-dal";
import { TMembershipIdentityDALFactory } from "../membership-identity/membership-identity-dal";
import { TMembershipUserDALFactory } from "../membership-user/membership-user-dal";
import { TMicrosoftTeamsServiceFactory } from "../microsoft-teams/microsoft-teams-service"; import { TMicrosoftTeamsServiceFactory } from "../microsoft-teams/microsoft-teams-service";
import { TOrgDALFactory } from "../org/org-dal"; import { TOrgDALFactory } from "../org/org-dal";
import { TOrgServiceFactory } from "../org/org-service"; import { TOrgServiceFactory } from "../org/org-service";
import { TOrgMembershipDALFactory } from "../org-membership/org-membership-dal";
import { TUserDALFactory } from "../user/user-dal"; import { TUserDALFactory } from "../user/user-dal";
import { TUserAliasDALFactory } from "../user-alias/user-alias-dal"; import { TUserAliasDALFactory } from "../user-alias/user-alias-dal";
import { UserAliasType } from "../user-alias/user-alias-types"; import { UserAliasType } from "../user-alias/user-alias-types";
@@ -64,11 +66,12 @@ type TSuperAdminServiceFactoryDep = {
identityDAL: TIdentityDALFactory; identityDAL: TIdentityDALFactory;
identityTokenAuthDAL: TIdentityTokenAuthDALFactory; identityTokenAuthDAL: TIdentityTokenAuthDALFactory;
identityAccessTokenDAL: TIdentityAccessTokenDALFactory; identityAccessTokenDAL: TIdentityAccessTokenDALFactory;
identityOrgMembershipDAL: TIdentityOrgDALFactory;
orgDAL: TOrgDALFactory; orgDAL: TOrgDALFactory;
orgMembershipDAL: TOrgMembershipDALFactory;
serverCfgDAL: TSuperAdminDALFactory; serverCfgDAL: TSuperAdminDALFactory;
userDAL: TUserDALFactory; userDAL: TUserDALFactory;
membershipUserDAL: TMembershipUserDALFactory;
membershipIdentityDAL: TMembershipIdentityDALFactory;
membershipRoleDAL: TMembershipRoleDALFactory;
userAliasDAL: Pick<TUserAliasDALFactory, "findOne">; userAliasDAL: Pick<TUserAliasDALFactory, "findOne">;
authService: Pick<TAuthLoginFactory, "generateUserTokens">; authService: Pick<TAuthLoginFactory, "generateUserTokens">;
kmsService: Pick<TKmsServiceFactory, "encryptWithRootKey" | "decryptWithRootKey" | "updateEncryptionStrategy">; kmsService: Pick<TKmsServiceFactory, "encryptWithRootKey" | "decryptWithRootKey" | "updateEncryptionStrategy">;
@@ -127,7 +130,6 @@ export const superAdminServiceFactory = ({
userDAL, userDAL,
identityDAL, identityDAL,
orgDAL, orgDAL,
orgMembershipDAL,
userAliasDAL, userAliasDAL,
authService, authService,
orgService, orgService,
@@ -137,11 +139,13 @@ export const superAdminServiceFactory = ({
licenseService, licenseService,
identityAccessTokenDAL, identityAccessTokenDAL,
identityTokenAuthDAL, identityTokenAuthDAL,
identityOrgMembershipDAL,
microsoftTeamsService, microsoftTeamsService,
invalidateCacheQueue, invalidateCacheQueue,
smtpService, smtpService,
tokenService tokenService,
membershipIdentityDAL,
membershipUserDAL,
membershipRoleDAL
}: TSuperAdminServiceFactoryDep) => { }: TSuperAdminServiceFactoryDep) => {
const initServerCfg = async () => { const initServerCfg = async () => {
// TODO(akhilmhdh): bad pattern time less change this later to me itself // TODO(akhilmhdh): bad pattern time less change this later to me itself
@@ -589,10 +593,17 @@ export const superAdminServiceFactory = ({
const { identity, credentials } = await identityDAL.transaction(async (tx) => { const { identity, credentials } = await identityDAL.transaction(async (tx) => {
const newIdentity = await identityDAL.create({ name: "Instance Admin Identity" }, tx); const newIdentity = await identityDAL.create({ name: "Instance Admin Identity" }, tx);
await identityOrgMembershipDAL.create( const membership = await membershipIdentityDAL.create(
{ {
identityId: newIdentity.id, actorIdentityId: newIdentity.id,
orgId: organization.id, scopeOrgId: organization.id,
scope: AccessScope.Project
},
tx
);
await membershipRoleDAL.create(
{
membershipId: membership.id,
role: OrgMembershipRole.Admin role: OrgMembershipRole.Admin
}, },
tx tx
@@ -834,18 +845,23 @@ export const superAdminServiceFactory = ({
}); });
} }
await orgDAL.createMembership( const membership = await orgDAL.createMembership(
{ {
userId: inviteeUser.id, actorUserId: inviteeUser.id,
scope: AccessScope.Organization,
inviteEmail: inviteeEmail, inviteEmail: inviteeEmail,
orgId: org.id, scopeOrgId: org.id,
role: OrgMembershipRole.Admin,
status: inviteeUser.isAccepted ? OrgMembershipStatus.Accepted : OrgMembershipStatus.Invited, status: inviteeUser.isAccepted ? OrgMembershipStatus.Accepted : OrgMembershipStatus.Invited,
isActive: true isActive: true
}, },
tx tx
); );
await membershipRoleDAL.create({
membershipId: membership.id,
role: OrgMembershipRole.Admin
});
users.push(inviteeUser); users.push(inviteeUser);
} }
@@ -914,20 +930,25 @@ export const superAdminServiceFactory = ({
actorType: ActorType actorType: ActorType
) => { ) => {
if (actorType === ActorType.USER) { if (actorType === ActorType.USER) {
const orgMembership = await orgMembershipDAL.findById(membershipId); const orgMembership = await membershipUserDAL.findOne({
scope: AccessScope.Organization,
id: membershipId,
scopeOrgId: organizationId
});
if (!orgMembership) { if (!orgMembership) {
throw new NotFoundError({ name: "Organization Membership", message: "Organization membership not found" }); throw new NotFoundError({ name: "Organization Membership", message: "Organization membership not found" });
} }
if (orgMembership.userId === actorId) { if (orgMembership.actorUserId === actorId) {
throw new BadRequestError({ throw new BadRequestError({
message: "You cannot remove yourself from the organization from the instance management panel." message: "You cannot remove yourself from the organization from the instance management panel."
}); });
} }
} }
const [organizationMembership] = await orgMembershipDAL.delete({ const [organizationMembership] = await membershipUserDAL.delete({
orgId: organizationId, scopeOrgId: organizationId,
scope: AccessScope.Organization,
id: membershipId id: membershipId
}); });
return organizationMembership; return organizationMembership;
@@ -946,25 +967,46 @@ export const superAdminServiceFactory = ({
throw new NotFoundError({ message: `Could not organization with ID "${orgId}"` }); throw new NotFoundError({ message: `Could not organization with ID "${orgId}"` });
} }
const existingOrgMembership = await orgMembershipDAL.findOne({ userId: serverAdmin.id, orgId }); const existingOrgMembership = await membershipUserDAL.findOne({
actorUserId: serverAdmin.id,
scopeOrgId: org.id,
scope: AccessScope.Organization
});
if (existingOrgMembership) { if (existingOrgMembership) {
throw new BadRequestError({ message: `You are already a part of the organization with ID ${orgId}` }); throw new BadRequestError({ message: `You are already a part of the organization with ID ${orgId}` });
} }
const orgMembership = await orgDAL.createMembership({ const orgMembership = await orgDAL.transaction(async (tx) => {
userId: serverAdmin.id, const membership = await orgDAL.createMembership(
orgId: org.id, {
role: OrgMembershipRole.Admin, actorUserId: serverAdmin.id,
scopeOrgId: org.id,
status: OrgMembershipStatus.Accepted, status: OrgMembershipStatus.Accepted,
isActive: true isActive: true,
scope: AccessScope.Organization
},
tx
);
await membershipRoleDAL.create(
{
membershipId: membership.id,
role: OrgMembershipRole.Admin
},
tx
);
return membership;
}); });
return orgMembership; return orgMembership;
}; };
const resendOrgInvite = async ({ organizationId, membershipId }: TResendOrgInviteDTO, actor: OrgServiceActor) => { const resendOrgInvite = async ({ organizationId, membershipId }: TResendOrgInviteDTO, actor: OrgServiceActor) => {
const orgMembership = await orgMembershipDAL.findOne({ id: membershipId, orgId: organizationId }); const orgMembership = await membershipUserDAL.findOne({
id: membershipId,
scopeOrgId: organizationId,
scope: AccessScope.Organization
});
if (!orgMembership) { if (!orgMembership) {
throw new NotFoundError({ name: "Organization Membership", message: "Organization membership not found" }); throw new NotFoundError({ name: "Organization Membership", message: "Organization membership not found" });
@@ -976,7 +1018,7 @@ export const superAdminServiceFactory = ({
}); });
} }
if (!orgMembership.userId) { if (!orgMembership.actorUserId) {
throw new NotFoundError({ message: "Cannot find user associated with Org Membership." }); throw new NotFoundError({ message: "Cannot find user associated with Org Membership." });
} }
@@ -984,15 +1026,15 @@ export const superAdminServiceFactory = ({
throw new BadRequestError({ message: "No invite email associated with user." }); throw new BadRequestError({ message: "No invite email associated with user." });
} }
const org = await orgDAL.findOrgById(orgMembership.orgId); const org = await orgDAL.findOrgById(orgMembership.scopeOrgId);
const appCfg = getConfig(); const appCfg = getConfig();
const serverAdmin = await userDAL.findById(actor.id); const serverAdmin = await userDAL.findById(actor.id);
const token = await tokenService.createTokenForUser({ const token = await tokenService.createTokenForUser({
type: TokenType.TOKEN_EMAIL_ORG_INVITATION, type: TokenType.TOKEN_EMAIL_ORG_INVITATION,
userId: orgMembership.userId, userId: orgMembership.actorUserId,
orgId: orgMembership.orgId orgId: orgMembership.scopeOrgId
}); });
await smtpService.sendMail({ await smtpService.sendMail({
@@ -1004,7 +1046,7 @@ export const superAdminServiceFactory = ({
inviterUsername: serverAdmin?.email, inviterUsername: serverAdmin?.email,
organizationName: org?.name, organizationName: org?.name,
email: orgMembership.inviteEmail, email: orgMembership.inviteEmail,
organizationId: orgMembership.orgId, organizationId: orgMembership.scopeOrgId,
token, token,
callback_url: `${appCfg.SITE_URL}/signupinvite` callback_url: `${appCfg.SITE_URL}/signupinvite`
} }
+27 -19
View File
@@ -1,6 +1,7 @@
import { ForbiddenError } from "@casl/ability"; import { ForbiddenError } from "@casl/ability";
import { Knex } from "knex"; import { Knex } from "knex";
import { AccessScope } from "@app/db/schemas";
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
import { crypto } from "@app/lib/crypto"; import { crypto } from "@app/lib/crypto";
@@ -9,12 +10,11 @@ import { logger } from "@app/lib/logger";
import { TAuthTokenServiceFactory } from "@app/services/auth-token/auth-token-service"; import { TAuthTokenServiceFactory } from "@app/services/auth-token/auth-token-service";
import { TokenType } from "@app/services/auth-token/auth-token-types"; import { TokenType } from "@app/services/auth-token/auth-token-types";
import { TOrgDALFactory } from "@app/services/org/org-dal"; import { TOrgDALFactory } from "@app/services/org/org-dal";
import { TOrgMembershipDALFactory } from "@app/services/org-membership/org-membership-dal";
import { SmtpTemplates, TSmtpService } from "@app/services/smtp/smtp-service"; import { SmtpTemplates, TSmtpService } from "@app/services/smtp/smtp-service";
import { AuthMethod, AuthTokenType } from "../auth/auth-type"; import { AuthMethod, AuthTokenType } from "../auth/auth-type";
import { TGroupProjectDALFactory } from "../group-project/group-project-dal"; import { TGroupProjectDALFactory } from "../group-project/group-project-dal";
import { TProjectMembershipDALFactory } from "../project-membership/project-membership-dal"; import { TMembershipUserDALFactory } from "../membership-user/membership-user-dal";
import { TUserAliasDALFactory } from "../user-alias/user-alias-dal"; import { TUserAliasDALFactory } from "../user-alias/user-alias-dal";
import { TUserDALFactory } from "./user-dal"; import { TUserDALFactory } from "./user-dal";
import { TListUserGroupsDTO, TUpdateUserEmailDTO, TUpdateUserMfaDTO } from "./user-types"; import { TListUserGroupsDTO, TUpdateUserEmailDTO, TUpdateUserMfaDTO } from "./user-types";
@@ -37,9 +37,8 @@ type TUserServiceFactoryDep = {
>; >;
groupProjectDAL: Pick<TGroupProjectDALFactory, "findByUserId">; groupProjectDAL: Pick<TGroupProjectDALFactory, "findByUserId">;
orgDAL: Pick<TOrgDALFactory, "findById" | "find">; orgDAL: Pick<TOrgDALFactory, "findById" | "find">;
orgMembershipDAL: Pick<TOrgMembershipDALFactory, "find" | "insertMany" | "findOne" | "updateById">; membershipUserDAL: Pick<TMembershipUserDALFactory, "find" | "insertMany" | "findOne" | "updateById">;
tokenService: Pick<TAuthTokenServiceFactory, "createTokenForUser" | "validateTokenForUser" | "revokeAllMySessions">; tokenService: Pick<TAuthTokenServiceFactory, "createTokenForUser" | "validateTokenForUser" | "revokeAllMySessions">;
projectMembershipDAL: Pick<TProjectMembershipDALFactory, "find">;
smtpService: Pick<TSmtpService, "sendMail">; smtpService: Pick<TSmtpService, "sendMail">;
permissionService: TPermissionServiceFactory; permissionService: TPermissionServiceFactory;
userAliasDAL: Pick<TUserAliasDALFactory, "findOne" | "find" | "updateById" | "delete">; userAliasDAL: Pick<TUserAliasDALFactory, "findOne" | "find" | "updateById" | "delete">;
@@ -50,8 +49,7 @@ export type TUserServiceFactory = ReturnType<typeof userServiceFactory>;
export const userServiceFactory = ({ export const userServiceFactory = ({
userDAL, userDAL,
orgDAL, orgDAL,
orgMembershipDAL, membershipUserDAL,
projectMembershipDAL,
groupProjectDAL, groupProjectDAL,
tokenService, tokenService,
smtpService, smtpService,
@@ -183,13 +181,19 @@ export const userServiceFactory = ({
}; };
const checkUserScimRestriction = async (userId: string, tx?: Knex) => { const checkUserScimRestriction = async (userId: string, tx?: Knex) => {
const userOrgs = await orgMembershipDAL.find({ userId }, { tx }); const userOrgs = await membershipUserDAL.find(
{
actorUserId: userId,
scope: AccessScope.Organization
},
{ tx }
);
if (userOrgs.length === 0) { if (userOrgs.length === 0) {
return false; return false;
} }
const orgIds = userOrgs.map((membership) => membership.orgId); const orgIds = userOrgs.map((membership) => membership.scopeOrgId);
const organizations = await orgDAL.find({ $in: { id: orgIds } }, { tx }); const organizations = await orgDAL.find({ $in: { id: orgIds } }, { tx });
return organizations.some((org) => org.scimEnabled); return organizations.some((org) => org.scimEnabled);
@@ -397,9 +401,10 @@ export const userServiceFactory = ({
}; };
const getUserProjectFavorites = async (userId: string, orgId: string) => { const getUserProjectFavorites = async (userId: string, orgId: string) => {
const orgMembership = await orgMembershipDAL.findOne({ const orgMembership = await membershipUserDAL.findOne({
userId, scope: AccessScope.Organization,
orgId actorUserId: userId,
scopeOrgId: orgId
}); });
if (!orgMembership) { if (!orgMembership) {
@@ -412,9 +417,10 @@ export const userServiceFactory = ({
}; };
const updateUserProjectFavorites = async (userId: string, orgId: string, projectIds: string[]) => { const updateUserProjectFavorites = async (userId: string, orgId: string, projectIds: string[]) => {
const orgMembership = await orgMembershipDAL.findOne({ const orgMembership = await membershipUserDAL.findOne({
userId, scope: AccessScope.Organization,
orgId actorUserId: userId,
scopeOrgId: orgId
}); });
if (!orgMembership) { if (!orgMembership) {
@@ -423,18 +429,20 @@ export const userServiceFactory = ({
}); });
} }
const matchingUserProjectMemberships = await projectMembershipDAL.find({ const matchingUserProjectMemberships = await membershipUserDAL.find({
userId, scope: AccessScope.Project,
scopeOrgId: orgId,
actorUserId: userId,
$in: { $in: {
projectId: projectIds scopeProjectId: projectIds
} }
}); });
const memberProjectFavorites = matchingUserProjectMemberships.map( const memberProjectFavorites = matchingUserProjectMemberships.map(
(projectMembership) => projectMembership.projectId (projectMembership) => projectMembership.scopeProjectId as string
); );
const updatedOrgMembership = await orgMembershipDAL.updateById(orgMembership.id, { const updatedOrgMembership = await membershipUserDAL.updateById(orgMembership.id, {
projectFavorites: memberProjectFavorites projectFavorites: memberProjectFavorites
}); });