fix: review changes

This commit is contained in:
Piyush Gupta
2025-12-05 21:09:37 +05:30
parent fc9ded7d57
commit a6255d47b2
15 changed files with 303 additions and 208 deletions
+19 -10
View File
@@ -559,6 +559,8 @@ export const authLoginServiceFactory = ({
const membershipRole = (await membershipRoleDAL.findOne({ membershipId: orgMembership.id })).role; const membershipRole = (await membershipRoleDAL.findOne({ membershipId: orgMembership.id })).role;
let rootOrg = selectedOrg;
if (isSubOrganization) { if (isSubOrganization) {
if (!selectedOrg.rootOrgId) { if (!selectedOrg.rootOrgId) {
throw new BadRequestError({ throw new BadRequestError({
@@ -566,6 +568,13 @@ export const authLoginServiceFactory = ({
}); });
} }
rootOrg = await orgDAL.findById(selectedOrg.rootOrgId);
if (!rootOrg) {
throw new BadRequestError({
message: "Invalid sub-organization"
});
}
// Check user membership in the root organization // Check user membership in the root organization
const rootOrgMembership = await membershipUserDAL.findOne({ const rootOrgMembership = await membershipUserDAL.findOne({
actorUserId: user.id, actorUserId: user.id,
@@ -582,18 +591,18 @@ export const authLoginServiceFactory = ({
} }
if ( if (
selectedOrg.authEnforced && rootOrg.authEnforced &&
!isAuthMethodSaml(decodedToken.authMethod) && !isAuthMethodSaml(decodedToken.authMethod) &&
decodedToken.authMethod !== AuthMethod.OIDC && decodedToken.authMethod !== AuthMethod.OIDC &&
!(selectedOrg.bypassOrgAuthEnabled && membershipRole === OrgMembershipRole.Admin) !(rootOrg.bypassOrgAuthEnabled && membershipRole === OrgMembershipRole.Admin)
) { ) {
throw new BadRequestError({ throw new BadRequestError({
message: "Login with the auth method required by your organization." message: "Login with the auth method required by your organization."
}); });
} }
if (selectedOrg.googleSsoAuthEnforced && decodedToken.authMethod !== AuthMethod.GOOGLE) { if (rootOrg.googleSsoAuthEnforced && decodedToken.authMethod !== AuthMethod.GOOGLE) {
const canBypass = selectedOrg.bypassOrgAuthEnabled && membershipRole === OrgMembershipRole.Admin; const canBypass = rootOrg.bypassOrgAuthEnabled && membershipRole === OrgMembershipRole.Admin;
if (!canBypass) { if (!canBypass) {
throw new ForbiddenRequestError({ throw new ForbiddenRequestError({
@@ -604,13 +613,13 @@ export const authLoginServiceFactory = ({
} }
if (decodedToken.authMethod === AuthMethod.GOOGLE) { if (decodedToken.authMethod === AuthMethod.GOOGLE) {
await orgDAL.updateById(selectedOrg.id, { await orgDAL.updateById(rootOrg.id, {
googleSsoAuthLastUsed: new Date() googleSsoAuthLastUsed: new Date()
}); });
} }
const shouldCheckMfa = selectedOrg.enforceMfa || user.isMfaEnabled; const shouldCheckMfa = rootOrg.enforceMfa || user.isMfaEnabled;
const orgMfaMethod = selectedOrg.enforceMfa ? (selectedOrg.selectedMfaMethod ?? MfaMethod.EMAIL) : undefined; const orgMfaMethod = rootOrg.enforceMfa ? (rootOrg.selectedMfaMethod ?? MfaMethod.EMAIL) : undefined;
const userMfaMethod = user.isMfaEnabled ? (user.selectedMfaMethod ?? MfaMethod.EMAIL) : undefined; const userMfaMethod = user.isMfaEnabled ? (user.selectedMfaMethod ?? MfaMethod.EMAIL) : undefined;
const mfaMethod = orgMfaMethod ?? userMfaMethod; const mfaMethod = orgMfaMethod ?? userMfaMethod;
@@ -644,7 +653,7 @@ export const authLoginServiceFactory = ({
user, user,
userAgent, userAgent,
ip: ipAddress, ip: ipAddress,
organizationId: isSubOrganization ? selectedOrg.rootOrgId || "" : organizationId, organizationId: isSubOrganization ? rootOrg.id : organizationId,
subOrganizationId: isSubOrganization ? organizationId : undefined, subOrganizationId: isSubOrganization ? organizationId : undefined,
isMfaVerified: decodedToken.isMfaVerified, isMfaVerified: decodedToken.isMfaVerified,
mfaMethod: decodedToken.mfaMethod mfaMethod: decodedToken.mfaMethod
@@ -652,8 +661,8 @@ export const authLoginServiceFactory = ({
// In the event of this being a break-glass request (non-saml / non-oidc, when either is enforced) // In the event of this being a break-glass request (non-saml / non-oidc, when either is enforced)
if ( if (
selectedOrg.authEnforced && rootOrg.authEnforced &&
selectedOrg.bypassOrgAuthEnabled && rootOrg.bypassOrgAuthEnabled &&
!isAuthMethodSaml(decodedToken.authMethod) && !isAuthMethodSaml(decodedToken.authMethod) &&
decodedToken.authMethod !== AuthMethod.OIDC && decodedToken.authMethod !== AuthMethod.OIDC &&
decodedToken.authMethod !== AuthMethod.GOOGLE decodedToken.authMethod !== AuthMethod.GOOGLE
@@ -85,23 +85,6 @@ export const identityAliCloudAuthServiceFactory = ({
// If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified // If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified
let subOrganizationId = isSubOrgIdentity ? org.id : null; let subOrganizationId = isSubOrgIdentity ? org.id : null;
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (subOrg) {
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (subOrgMembership) {
subOrganizationId = subOrg.id;
}
}
}
}
try { try {
const requestUrl = new URL("https://sts.aliyuncs.com"); const requestUrl = new URL("https://sts.aliyuncs.com");
@@ -124,6 +107,30 @@ export const identityAliCloudAuthServiceFactory = ({
}); });
} }
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (!subOrg) {
throw new NotFoundError({ message: `Sub organization with name ${subOrganizationName} not found` });
}
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (!subOrgMembership) {
throw new UnauthorizedError({
message: `Identity not authorized to access sub organization ${subOrganizationName}`
});
}
subOrganizationId = subOrg.id;
}
}
// Generate the token // Generate the token
const identityAccessToken = await identityAliCloudAuthDAL.transaction(async (tx) => { const identityAccessToken = await identityAliCloudAuthDAL.transaction(async (tx) => {
await membershipIdentityDAL.update( await membershipIdentityDAL.update(
@@ -123,23 +123,6 @@ export const identityAwsAuthServiceFactory = ({
// If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified // If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified
let subOrganizationId = isSubOrgIdentity ? org.id : null; let subOrganizationId = isSubOrgIdentity ? org.id : null;
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (subOrg) {
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (subOrgMembership) {
subOrganizationId = subOrg.id;
}
}
}
}
try { try {
const headers: TAwsGetCallerIdentityHeaders = JSON.parse(Buffer.from(iamRequestHeaders, "base64").toString()); const headers: TAwsGetCallerIdentityHeaders = JSON.parse(Buffer.from(iamRequestHeaders, "base64").toString());
const body: string = Buffer.from(iamRequestBody, "base64").toString(); const body: string = Buffer.from(iamRequestBody, "base64").toString();
@@ -207,6 +190,30 @@ export const identityAwsAuthServiceFactory = ({
} }
} }
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (!subOrg) {
throw new NotFoundError({ message: `Sub organization with name ${subOrganizationName} not found` });
}
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (!subOrgMembership) {
throw new UnauthorizedError({
message: `Identity not authorized to access sub organization ${subOrganizationName}`
});
}
subOrganizationId = subOrg.id;
}
}
const identityAccessToken = await identityAwsAuthDAL.transaction(async (tx) => { const identityAccessToken = await identityAwsAuthDAL.transaction(async (tx) => {
await membershipIdentityDAL.update( await membershipIdentityDAL.update(
identity.projectId identity.projectId
@@ -79,23 +79,6 @@ export const identityAzureAuthServiceFactory = ({
// If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified // If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified
let subOrganizationId = isSubOrgIdentity ? org.id : null; let subOrganizationId = isSubOrgIdentity ? org.id : null;
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (subOrg) {
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (subOrgMembership) {
subOrganizationId = subOrg.id;
}
}
}
}
try { try {
const azureIdentity = await validateAzureIdentity({ const azureIdentity = await validateAzureIdentity({
tenantId: identityAzureAuth.tenantId, tenantId: identityAzureAuth.tenantId,
@@ -119,6 +102,30 @@ export const identityAzureAuthServiceFactory = ({
} }
} }
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (!subOrg) {
throw new NotFoundError({ message: `Sub organization with name ${subOrganizationName} not found` });
}
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (!subOrgMembership) {
throw new UnauthorizedError({
message: `Identity not authorized to access sub organization ${subOrganizationName}`
});
}
subOrganizationId = subOrg.id;
}
}
const identityAccessToken = await identityAzureAuthDAL.transaction(async (tx) => { const identityAccessToken = await identityAzureAuthDAL.transaction(async (tx) => {
await membershipIdentityDAL.update( await membershipIdentityDAL.update(
identity.projectId identity.projectId
@@ -77,23 +77,6 @@ export const identityGcpAuthServiceFactory = ({
// If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified // If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified
let subOrganizationId = isSubOrgIdentity ? org.id : null; let subOrganizationId = isSubOrgIdentity ? org.id : null;
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (subOrg) {
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (subOrgMembership) {
subOrganizationId = subOrg.id;
}
}
}
}
try { try {
let gcpIdentityDetails: TGcpIdentityDetails; let gcpIdentityDetails: TGcpIdentityDetails;
switch (identityGcpAuth.type) { switch (identityGcpAuth.type) {
@@ -160,6 +143,30 @@ export const identityGcpAuthServiceFactory = ({
}); });
} }
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (!subOrg) {
throw new NotFoundError({ message: `Sub organization with name ${subOrganizationName} not found` });
}
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (!subOrgMembership) {
throw new UnauthorizedError({
message: `Identity not authorized to access sub organization ${subOrganizationName}`
});
}
subOrganizationId = subOrg.id;
}
}
const identityAccessToken = await identityGcpAuthDAL.transaction(async (tx) => { const identityAccessToken = await identityGcpAuthDAL.transaction(async (tx) => {
await membershipIdentityDAL.update( await membershipIdentityDAL.update(
identity.projectId identity.projectId
@@ -91,22 +91,6 @@ export const identityJwtAuthServiceFactory = ({
// If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified // If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified
let subOrganizationId = isSubOrgIdentity ? org.id : null; let subOrganizationId = isSubOrgIdentity ? org.id : null;
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (subOrg) {
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (subOrgMembership) {
subOrganizationId = subOrg.id;
}
}
}
}
try { try {
const { decryptor: orgDataKeyDecryptor } = await kmsService.createCipherPairWithDataKey({ const { decryptor: orgDataKeyDecryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
@@ -239,6 +223,30 @@ export const identityJwtAuthServiceFactory = ({
}); });
} }
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (!subOrg) {
throw new NotFoundError({ message: `Sub organization with name ${subOrganizationName} not found` });
}
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (!subOrgMembership) {
throw new UnauthorizedError({
message: `Identity not authorized to access sub organization ${subOrganizationName}`
});
}
subOrganizationId = subOrg.id;
}
}
const identityAccessToken = await identityJwtAuthDAL.transaction(async (tx) => { const identityAccessToken = await identityJwtAuthDAL.transaction(async (tx) => {
await membershipIdentityDAL.update( await membershipIdentityDAL.update(
identity.projectId identity.projectId
@@ -203,23 +203,6 @@ export const identityKubernetesAuthServiceFactory = ({
// If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified // If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified
let subOrganizationId = isSubOrgIdentity ? org.id : null; let subOrganizationId = isSubOrgIdentity ? org.id : null;
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (subOrg) {
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (subOrgMembership) {
subOrganizationId = subOrg.id;
}
}
}
}
try { try {
const { decryptor } = await kmsService.createCipherPairWithDataKey({ const { decryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
@@ -480,6 +463,30 @@ export const identityKubernetesAuthServiceFactory = ({
}); });
} }
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (!subOrg) {
throw new NotFoundError({ message: `Sub organization with name ${subOrganizationName} not found` });
}
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (!subOrgMembership) {
throw new UnauthorizedError({
message: `Identity not authorized to access sub organization ${subOrganizationName}`
});
}
subOrganizationId = subOrg.id;
}
}
const identityAccessToken = await identityKubernetesAuthDAL.transaction(async (tx) => { const identityAccessToken = await identityKubernetesAuthDAL.transaction(async (tx) => {
await membershipIdentityDAL.update( await membershipIdentityDAL.update(
identity.projectId identity.projectId
@@ -172,23 +172,6 @@ export const identityLdapAuthServiceFactory = ({
// If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified // If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified
let subOrganizationId = isSubOrgIdentity ? org.id : null; let subOrganizationId = isSubOrgIdentity ? org.id : null;
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (subOrg) {
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (subOrgMembership) {
subOrganizationId = subOrg.id;
}
}
}
}
const plan = await licenseService.getPlan(identity.orgId); const plan = await licenseService.getPlan(identity.orgId);
if (!plan.ldap) { if (!plan.ldap) {
throw new BadRequestError({ throw new BadRequestError({
@@ -196,6 +179,29 @@ export const identityLdapAuthServiceFactory = ({
"Failed to login to identity due to plan restriction. Upgrade plan to login to use LDAP authentication." "Failed to login to identity due to plan restriction. Upgrade plan to login to use LDAP authentication."
}); });
} }
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (!subOrg) {
throw new NotFoundError({ message: `Sub organization with name ${subOrganizationName} not found` });
}
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (!subOrgMembership) {
throw new UnauthorizedError({
message: `Identity not authorized to access sub organization ${subOrganizationName}`
});
}
subOrganizationId = subOrg.id;
}
}
try { try {
const identityAccessToken = await identityLdapAuthDAL.transaction(async (tx) => { const identityAccessToken = await identityLdapAuthDAL.transaction(async (tx) => {
@@ -81,23 +81,6 @@ export const identityOciAuthServiceFactory = ({
// If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified // If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified
let subOrganizationId = isSubOrgIdentity ? org.id : null; let subOrganizationId = isSubOrgIdentity ? org.id : null;
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (subOrg) {
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (subOrgMembership) {
subOrganizationId = subOrg.id;
}
}
}
}
try { try {
// 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.
if (!headers.host || !new RE2("^identity\\.([a-z]{2}-[a-z]+-[1-9])\\.oraclecloud\\.com$").test(headers.host)) { if (!headers.host || !new RE2("^identity\\.([a-z]{2}-[a-z]+-[1-9])\\.oraclecloud\\.com$").test(headers.host)) {
@@ -130,6 +113,30 @@ export const identityOciAuthServiceFactory = ({
}); });
} }
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (!subOrg) {
throw new NotFoundError({ message: `Sub organization with name ${subOrganizationName} not found` });
}
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (!subOrgMembership) {
throw new UnauthorizedError({
message: `Identity not authorized to access sub organization ${subOrganizationName}`
});
}
subOrganizationId = subOrg.id;
}
}
// Generate the token // Generate the token
const identityAccessToken = await identityOciAuthDAL.transaction(async (tx) => { const identityAccessToken = await identityOciAuthDAL.transaction(async (tx) => {
await membershipIdentityDAL.update( await membershipIdentityDAL.update(
@@ -92,23 +92,6 @@ export const identityOidcAuthServiceFactory = ({
// If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified // If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified
let subOrganizationId = isSubOrgIdentity ? org.id : null; let subOrganizationId = isSubOrgIdentity ? org.id : null;
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (subOrg) {
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (subOrgMembership) {
subOrganizationId = subOrg.id;
}
}
}
}
try { try {
const { decryptor } = await kmsService.createCipherPairWithDataKey({ const { decryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
@@ -308,6 +291,30 @@ export const identityOidcAuthServiceFactory = ({
}); });
} }
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (!subOrg) {
throw new NotFoundError({ message: `Sub organization with name ${subOrganizationName} not found` });
}
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (!subOrgMembership) {
throw new UnauthorizedError({
message: `Identity not authorized to access sub organization ${subOrganizationName}`
});
}
subOrganizationId = subOrg.id;
}
}
const identityAccessToken = await identityOidcAuthDAL.transaction(async (tx) => { const identityAccessToken = await identityOidcAuthDAL.transaction(async (tx) => {
await membershipIdentityDAL.update( await membershipIdentityDAL.update(
identity.projectId identity.projectId
@@ -90,23 +90,6 @@ export const identityTlsCertAuthServiceFactory = ({
// If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified // If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified
let subOrganizationId = isSubOrgIdentity ? org.id : null; let subOrganizationId = isSubOrgIdentity ? org.id : null;
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (subOrg) {
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (subOrgMembership) {
subOrganizationId = subOrg.id;
}
}
}
}
try { try {
const { decryptor } = await kmsService.createCipherPairWithDataKey({ const { decryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
@@ -153,6 +136,30 @@ export const identityTlsCertAuthServiceFactory = ({
} }
} }
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (!subOrg) {
throw new NotFoundError({ message: `Sub organization with name ${subOrganizationName} not found` });
}
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (!subOrgMembership) {
throw new UnauthorizedError({
message: `Identity not authorized to access sub organization ${subOrganizationName}`
});
}
subOrganizationId = subOrg.id;
}
}
// Generate the token // Generate the token
const identityAccessToken = await identityTlsCertAuthDAL.transaction(async (tx) => { const identityAccessToken = await identityTlsCertAuthDAL.transaction(async (tx) => {
await membershipIdentityDAL.update( await membershipIdentityDAL.update(
@@ -514,16 +514,23 @@ export const identityTokenAuthServiceFactory = ({
if (!isSubOrgIdentity) { if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName }); const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (subOrg) { if (!subOrg) {
const subOrgMembership = await membershipIdentityDAL.findOne({ throw new NotFoundError({ message: `Sub organization with name ${subOrganizationName} not found` });
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (subOrgMembership) {
subOrganizationId = subOrg.id;
}
} }
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (!subOrgMembership) {
throw new UnauthorizedError({
message: `Identity not authorized to access sub organization ${subOrganizationName}`
});
}
subOrganizationId = subOrg.id;
} }
} }
@@ -96,23 +96,6 @@ export const identityUaServiceFactory = ({
// If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified // If the identity is a sub-org identity, then the scope is always the org.id, and if it's a root org identity, then we need to resolve the scope if a subOrganizationName is specified
let subOrganizationId = isSubOrgIdentity ? org.id : null; let subOrganizationId = isSubOrgIdentity ? org.id : null;
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (subOrg) {
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (subOrgMembership) {
subOrganizationId = subOrg.id;
}
}
}
}
try { try {
checkIPAgainstBlocklist({ checkIPAgainstBlocklist({
ipAddress: ip, ipAddress: ip,
@@ -251,6 +234,30 @@ export const identityUaServiceFactory = ({
accessTokenMaxTTL: 1000000000 accessTokenMaxTTL: 1000000000
}; };
if (subOrganizationName) {
if (!isSubOrgIdentity) {
const subOrg = await orgDAL.findOne({ rootOrgId: org.id, slug: subOrganizationName });
if (!subOrg) {
throw new NotFoundError({ message: `Sub organization with name ${subOrganizationName} not found` });
}
const subOrgMembership = await membershipIdentityDAL.findOne({
scope: AccessScope.Organization,
actorIdentityId: identity.id,
scopeOrgId: subOrg.id
});
if (!subOrgMembership) {
throw new UnauthorizedError({
message: `Identity not authorized to access sub organization ${subOrganizationName}`
});
}
subOrganizationId = subOrg.id;
}
}
const identityAccessToken = await identityUaDAL.transaction(async (tx) => { const identityAccessToken = await identityUaDAL.transaction(async (tx) => {
const uaClientSecretDoc = await identityUaClientSecretDAL.incrementUsage(validClientSecretInfo!.id, tx); const uaClientSecretDoc = await identityUaClientSecretDAL.incrementUsage(validClientSecretInfo!.id, tx);
await membershipIdentityDAL.update( await membershipIdentityDAL.update(
@@ -3,14 +3,16 @@ import { WorkflowIntegrationPlatform } from "../workflowIntegrations/types";
import { TListProjectIdentitiesDTO, TSearchProjectsDTO } from "./types"; import { TListProjectIdentitiesDTO, TSearchProjectsDTO } from "./types";
export const projectKeys = { export const projectKeys = {
getProjectById: (projectId: string) => ["projects", { projectId }] as const, allProjectQueries: () => ["projects"] as const,
getProjectById: (projectId: string) =>
[...projectKeys.allProjectQueries(), { projectId }] as const,
getProjectSecrets: (projectId: string) => [{ projectId }, "project-secrets"] as const, getProjectSecrets: (projectId: string) => [{ projectId }, "project-secrets"] as const,
getProjectIndexStatus: (projectId: string) => [{ projectId }, "project-index-status"] as const, getProjectIndexStatus: (projectId: string) => [{ projectId }, "project-index-status"] as const,
getProjectUpgradeStatus: (projectId: string) => [{ projectId }, "project-upgrade-status"], getProjectUpgradeStatus: (projectId: string) => [{ projectId }, "project-upgrade-status"],
getProjectMemberships: (orgId: string) => [{ orgId }, "project-memberships"], getProjectMemberships: (orgId: string) => [{ orgId }, "project-memberships"],
getProjectAuthorization: (projectId: string) => [{ projectId }, "project-authorizations"], getProjectAuthorization: (projectId: string) => [{ projectId }, "project-authorizations"],
getProjectIntegrations: (projectId: string) => [{ projectId }, "project-integrations"], getProjectIntegrations: (projectId: string) => [{ projectId }, "project-integrations"],
getAllUserProjects: () => ["projects"] as const, getAllUserProjects: () => [...projectKeys.allProjectQueries()] as const,
getProjectAuditLogs: (projectId: string) => [{ projectId }, "project-audit-logs"] as const, getProjectAuditLogs: (projectId: string) => [{ projectId }, "project-audit-logs"] as const,
getProjectUsers: ( getProjectUsers: (
projectId: string, projectId: string,
@@ -221,12 +221,12 @@ export const Navbar = () => {
SecurityClient.setToken(token); SecurityClient.setToken(token);
SecurityClient.setProviderAuthToken(""); SecurityClient.setProviderAuthToken("");
queryClient.removeQueries({ queryKey: authKeys.getAuthToken }); queryClient.removeQueries({ queryKey: authKeys.getAuthToken });
queryClient.removeQueries({ queryKey: projectKeys.getAllUserProjects() });
queryClient.removeQueries({ queryKey: subOrgQuery.queryKey }); queryClient.removeQueries({ queryKey: subOrgQuery.queryKey });
await queryClient.refetchQueries({ queryKey: authKeys.getAuthToken }); await queryClient.refetchQueries({ queryKey: authKeys.getAuthToken });
await navigateUserToOrg({ navigate, organizationId, navigateTo }); await navigateUserToOrg({ navigate, organizationId, navigateTo });
queryClient.removeQueries({ queryKey: projectKeys.allProjectQueries() });
if (onSuccess) { if (onSuccess) {
await onSuccess(); await onSuccess();