Finish preliminary v2 audit logs

This commit is contained in:
Tuan Dang
2023-08-05 16:55:06 +07:00
parent 6fbcbc4807
commit 142fcf0a01
100 changed files with 1885 additions and 1269 deletions
+16 -67
View File
@@ -1,25 +1,15 @@
import { Types } from "mongoose";
import {
Bot,
IServiceAccount,
IServiceTokenData,
IUser,
ServiceAccount,
ServiceTokenData,
User,
} from "../models";
import { validateServiceAccountClientForWorkspace } from "./serviceAccount";
import { validateUserClientForWorkspace } from "./user";
import {
BotNotFoundError,
UnauthorizedRequestError,
} from "../utils/errors";
import {
AUTH_MODE_API_KEY,
AUTH_MODE_JWT,
AUTH_MODE_SERVICE_ACCOUNT,
AUTH_MODE_SERVICE_TOKEN,
} from "../variables";
import { AuthData } from "../interfaces/middleware";
import { ActorType } from "../ee/models";
/**
* Validate authenticated clients for bot with id [botId] based
@@ -34,65 +24,24 @@ export const validateClientForBot = async ({
botId,
acceptedRoles,
}: {
authData: {
authMode: string;
authPayload: IUser | IServiceAccount | IServiceTokenData;
};
authData: AuthData;
botId: Types.ObjectId;
acceptedRoles: Array<"admin" | "member">;
}) => {
const bot = await Bot.findById(botId);
if (!bot) throw BotNotFoundError();
if (
authData.authMode === AUTH_MODE_JWT &&
authData.authPayload instanceof User
) {
await validateUserClientForWorkspace({
user: authData.authPayload,
workspaceId: bot.workspace,
acceptedRoles,
});
return bot;
switch (authData.actor.type) {
case ActorType.USER:
await validateUserClientForWorkspace({
user: authData.authPayload as IUser,
workspaceId: bot.workspace,
acceptedRoles,
});
return bot;
case ActorType.SERVICE:
throw UnauthorizedRequestError({
message: "Failed service token authorization for bot",
});
}
if (
authData.authMode === AUTH_MODE_SERVICE_ACCOUNT &&
authData.authPayload instanceof ServiceAccount
) {
await validateServiceAccountClientForWorkspace({
serviceAccount: authData.authPayload,
workspaceId: bot.workspace,
});
return bot;
}
if (
authData.authMode === AUTH_MODE_SERVICE_TOKEN &&
authData.authPayload instanceof ServiceTokenData
) {
throw UnauthorizedRequestError({
message: "Failed service token authorization for bot",
});
}
if (
authData.authMode === AUTH_MODE_API_KEY &&
authData.authPayload instanceof User
) {
await validateUserClientForWorkspace({
user: authData.authPayload,
workspaceId: bot.workspace,
acceptedRoles,
});
return bot;
}
throw BotNotFoundError({
message: "Failed client authorization for bot",
});
};
+15 -52
View File
@@ -1,15 +1,9 @@
import { Types } from "mongoose";
import {
IServiceAccount,
IServiceTokenData,
IUser,
Integration,
IntegrationAuth,
ServiceAccount,
ServiceTokenData,
User,
} from "../models";
import { validateServiceAccountClientForWorkspace } from "./serviceAccount";
import { validateUserClientForWorkspace } from "./user";
import { IntegrationService } from "../services";
import {
@@ -17,12 +11,8 @@ import {
IntegrationNotFoundError,
UnauthorizedRequestError,
} from "../utils/errors";
import {
AUTH_MODE_API_KEY,
AUTH_MODE_JWT,
AUTH_MODE_SERVICE_ACCOUNT,
AUTH_MODE_SERVICE_TOKEN,
} from "../variables";
import { AuthData } from "../interfaces/middleware";
import { ActorType } from "../ee/models";
/**
* Validate authenticated clients for integration with id [integrationId] based
@@ -39,10 +29,7 @@ export const validateClientForIntegration = async ({
integrationId,
acceptedRoles,
}: {
authData: {
authMode: string;
authPayload: IUser | IServiceAccount | IServiceTokenData;
};
authData: AuthData;
integrationId: Types.ObjectId;
acceptedRoles: Array<"admin" | "member">;
}) => {
@@ -61,43 +48,19 @@ export const validateClientForIntegration = async ({
const accessToken = (await IntegrationService.getIntegrationAuthAccess({
integrationAuthId: integrationAuth._id,
})).accessToken;
if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) {
await validateUserClientForWorkspace({
user: authData.authPayload,
workspaceId: integration.workspace,
acceptedRoles,
});
return ({ integration, accessToken });
}
if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) {
await validateServiceAccountClientForWorkspace({
serviceAccount: authData.authPayload,
workspaceId: integration.workspace,
});
switch (authData.actor.type) {
case ActorType.USER:
await validateUserClientForWorkspace({
user: authData.authPayload as IUser,
workspaceId: integration.workspace,
acceptedRoles,
});
return ({ integration, accessToken });
return ({ integration, accessToken });
case ActorType.SERVICE:
throw UnauthorizedRequestError({
message: "Failed service token authorization for integration",
});
}
if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) {
throw UnauthorizedRequestError({
message: "Failed service token authorization for integration",
});
}
if (authData.authMode === AUTH_MODE_API_KEY && authData.authPayload instanceof User) {
await validateUserClientForWorkspace({
user: authData.authPayload,
workspaceId: integration.workspace,
acceptedRoles,
});
return ({ integration, accessToken });
}
throw UnauthorizedRequestError({
message: "Failed client authorization for integration",
});
}
+15 -52
View File
@@ -1,27 +1,17 @@
import { Types } from "mongoose";
import {
IServiceAccount,
IServiceTokenData,
IUser,
IWorkspace,
IntegrationAuth,
ServiceAccount,
ServiceTokenData,
User,
} from "../models";
import {
AUTH_MODE_API_KEY,
AUTH_MODE_JWT,
AUTH_MODE_SERVICE_ACCOUNT,
AUTH_MODE_SERVICE_TOKEN,
} from "../variables";
import {
IntegrationAuthNotFoundError,
UnauthorizedRequestError,
} from "../utils/errors";
import { IntegrationService } from "../services";
import { validateUserClientForWorkspace } from "./user";
import { validateServiceAccountClientForWorkspace } from "./serviceAccount";
import { AuthData } from "../interfaces/middleware";
import { ActorType } from "../ee/models";
/**
* Validate authenticated clients for integration authorization with id [integrationAuthId] based
@@ -38,10 +28,7 @@ import { validateServiceAccountClientForWorkspace } from "./serviceAccount";
acceptedRoles,
attachAccessToken,
}: {
authData: {
authMode: string;
authPayload: IUser | IServiceAccount | IServiceTokenData;
};
authData: AuthData;
integrationAuthId: Types.ObjectId;
acceptedRoles: Array<"admin" | "member">;
attachAccessToken?: boolean;
@@ -66,44 +53,20 @@ import { validateServiceAccountClientForWorkspace } from "./serviceAccount";
accessId = access.accessId;
}
if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) {
await validateUserClientForWorkspace({
user: authData.authPayload,
workspaceId: integrationAuth.workspace._id,
acceptedRoles,
});
switch (authData.actor.type) {
case ActorType.USER:
await validateUserClientForWorkspace({
user: authData.authPayload as IUser,
workspaceId: integrationAuth.workspace._id,
acceptedRoles,
});
return ({ integrationAuth, accessToken, accessId });
return ({ integrationAuth, accessToken, accessId });
case ActorType.SERVICE:
throw UnauthorizedRequestError({
message: "Failed service token authorization for integration authorization",
});
}
if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) {
await validateServiceAccountClientForWorkspace({
serviceAccount: authData.authPayload,
workspaceId: integrationAuth.workspace._id,
});
return ({ integrationAuth, accessToken, accessId });
}
if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) {
throw UnauthorizedRequestError({
message: "Failed service token authorization for integration authorization",
});
}
if (authData.authMode === AUTH_MODE_API_KEY && authData.authPayload instanceof User) {
await validateUserClientForWorkspace({
user: authData.authPayload,
workspaceId: integrationAuth.workspace._id,
acceptedRoles,
});
return ({ integrationAuth, accessToken, accessId });
}
throw UnauthorizedRequestError({
message: "Failed client authorization for integration authorization",
});
}
export {
+20 -50
View File
@@ -15,12 +15,9 @@ import {
MembershipNotFoundError,
UnauthorizedRequestError,
} from "../utils/errors";
import {
AUTH_MODE_API_KEY,
AUTH_MODE_JWT,
AUTH_MODE_SERVICE_ACCOUNT,
AUTH_MODE_SERVICE_TOKEN,
} from "../variables";
import { AuthData } from "../interfaces/middleware";
import { ActorType } from "../ee/models";
import { auth } from "../routes/v1";
/**
* Validate authenticated clients for membership with id [membershipId] based
@@ -36,10 +33,7 @@ export const validateClientForMembership = async ({
membershipId,
acceptedRoles,
}: {
authData: {
authMode: string;
authPayload: IUser | IServiceAccount | IServiceTokenData;
};
authData: AuthData;
membershipId: Types.ObjectId;
acceptedRoles: Array<"admin" | "member">;
}) => {
@@ -49,46 +43,22 @@ export const validateClientForMembership = async ({
if (!membership) throw MembershipNotFoundError({
message: "Failed to find membership",
});
if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) {
await validateUserClientForWorkspace({
user: authData.authPayload,
workspaceId: membership.workspace,
acceptedRoles,
});
return membership;
}
if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) {
await validateServiceAccountClientForWorkspace({
serviceAccount: authData.authPayload,
workspaceId: membership.workspace,
});
return membership;
switch (authData.actor.type) {
case ActorType.USER:
await validateUserClientForWorkspace({
user: authData.authPayload as IUser,
workspaceId: membership.workspace,
acceptedRoles,
});
return membership;
case ActorType.SERVICE:
await validateServiceTokenDataClientForWorkspace({
serviceTokenData: authData.authPayload as IServiceTokenData,
workspaceId: new Types.ObjectId(membership.workspace),
});
return membership;
}
if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) {
await validateServiceTokenDataClientForWorkspace({
serviceTokenData: authData.authPayload,
workspaceId: new Types.ObjectId(membership.workspace),
});
return membership;
}
if (authData.authMode == AUTH_MODE_API_KEY && authData.authPayload instanceof User) {
await validateUserClientForWorkspace({
user: authData.authPayload,
workspaceId: membership.workspace,
acceptedRoles,
});
return membership;
}
throw UnauthorizedRequestError({
message: "Failed client authorization for membership",
});
}
+17 -54
View File
@@ -1,12 +1,6 @@
import { Types } from "mongoose";
import {
IServiceAccount,
IServiceTokenData,
IUser,
MembershipOrg,
ServiceAccount,
ServiceTokenData,
User,
} from "../models";
import {
validateMembershipOrg,
@@ -15,12 +9,8 @@ import {
MembershipOrgNotFoundError,
UnauthorizedRequestError,
} from "../utils/errors";
import {
AUTH_MODE_API_KEY,
AUTH_MODE_JWT,
AUTH_MODE_SERVICE_ACCOUNT,
AUTH_MODE_SERVICE_TOKEN,
} from "../variables";
import { AuthData } from "../interfaces/middleware";
import { ActorType } from "../ee/models";
/**
* Validate authenticated clients for organization membership with id [membershipOrgId] based
@@ -37,10 +27,7 @@ export const validateClientForMembershipOrg = async ({
acceptedRoles,
acceptedStatuses,
}: {
authData: {
authMode: string;
authPayload: IUser | IServiceAccount | IServiceTokenData;
};
authData: AuthData;
membershipOrgId: Types.ObjectId;
acceptedRoles: Array<"owner" | "admin" | "member">;
acceptedStatuses: Array<"invited" | "accepted">;
@@ -50,44 +37,20 @@ export const validateClientForMembershipOrg = async ({
if (!membershipOrg) throw MembershipOrgNotFoundError({
message: "Failed to find organization membership ",
});
if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) {
await validateMembershipOrg({
userId: authData.authPayload._id,
organizationId: membershipOrg.organization,
acceptedRoles,
acceptedStatuses,
});
return membershipOrg;
}
if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) {
if (!authData.authPayload.organization.equals(membershipOrg.organization)) throw UnauthorizedRequestError({
message: "Failed service account client authorization for organization membership",
});
return membershipOrg;
}
if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) {
throw UnauthorizedRequestError({
message: "Failed service account client authorization for organization membership",
});
}
if (authData.authMode === AUTH_MODE_API_KEY && authData.authPayload instanceof User) {
await validateMembershipOrg({
userId: authData.authPayload._id,
organizationId: membershipOrg.organization,
acceptedRoles,
acceptedStatuses,
});
return membershipOrg;
switch (authData.actor.type) {
case ActorType.USER:
await validateMembershipOrg({
userId: authData.authPayload._id,
organizationId: membershipOrg.organization,
acceptedRoles,
acceptedStatuses,
});
return membershipOrg;
case ActorType.SERVICE:
throw UnauthorizedRequestError({
message: "Failed service account client authorization for organization membership",
});
}
throw UnauthorizedRequestError({
message: "Failed client authorization for organization membership",
});
}
+17 -67
View File
@@ -1,25 +1,15 @@
import { Types } from "mongoose";
import {
IServiceAccount,
IServiceTokenData,
IUser,
Organization,
ServiceAccount,
ServiceTokenData,
User,
} from "../models";
import {
AUTH_MODE_API_KEY,
AUTH_MODE_JWT,
AUTH_MODE_SERVICE_ACCOUNT,
AUTH_MODE_SERVICE_TOKEN,
} from "../variables";
import {
OrganizationNotFoundError,
UnauthorizedRequestError,
} from "../utils/errors";
import { validateUserClientForOrganization } from "./user";
import { validateServiceAccountClientForOrganization } from "./serviceAccount";
import { AuthData } from "../interfaces/middleware";
import { ActorType } from "../ee/models";
/**
* Validate accepted clients for organization with id [organizationId]
@@ -33,10 +23,7 @@ export const validateClientForOrganization = async ({
acceptedRoles,
acceptedStatuses,
}: {
authData: {
authMode: string;
authPayload: IUser | IServiceAccount | IServiceTokenData;
};
authData: AuthData;
organizationId: Types.ObjectId;
acceptedRoles: Array<"owner" | "admin" | "member">;
acceptedStatuses: Array<"invited" | "accepted">;
@@ -48,57 +35,20 @@ export const validateClientForOrganization = async ({
message: "Failed to find organization",
});
}
switch (authData.actor.type) {
case ActorType.USER:
const membershipOrg = await validateUserClientForOrganization({
user: authData.authPayload as IUser,
organization,
acceptedRoles,
acceptedStatuses,
});
if (
authData.authMode === AUTH_MODE_JWT &&
authData.authPayload instanceof User
) {
const membershipOrg = await validateUserClientForOrganization({
user: authData.authPayload,
organization,
acceptedRoles,
acceptedStatuses,
});
return { organization, membershipOrg };
return { organization, membershipOrg };
case ActorType.SERVICE:
throw UnauthorizedRequestError({
message: "Failed service token authorization for organization",
});
}
if (
authData.authMode === AUTH_MODE_SERVICE_ACCOUNT &&
authData.authPayload instanceof ServiceAccount
) {
await validateServiceAccountClientForOrganization({
serviceAccount: authData.authPayload,
organization,
});
return { organization };
}
if (
authData.authMode === AUTH_MODE_SERVICE_TOKEN &&
authData.authPayload instanceof ServiceTokenData
) {
throw UnauthorizedRequestError({
message: "Failed service token authorization for organization",
});
}
if (
authData.authMode === AUTH_MODE_API_KEY &&
authData.authPayload instanceof User
) {
const membershipOrg = await validateUserClientForOrganization({
user: authData.authPayload,
organization,
acceptedRoles,
acceptedStatuses,
});
return { organization, membershipOrg };
}
throw UnauthorizedRequestError({
message: "Failed client authorization for organization",
});
};
+38 -98
View File
@@ -2,25 +2,17 @@ import { Types } from "mongoose";
import {
ISecret,
Secret,
ServiceAccount,
ServiceTokenData,
User,
IUser,
IServiceTokenData,
} from "../models";
import { validateServiceAccountClientForSecrets, validateServiceAccountClientForWorkspace } from "./serviceAccount";
import { validateUserClientForSecret, validateUserClientForSecrets } from "./user";
import { validateServiceTokenDataClientForSecrets, validateServiceTokenDataClientForWorkspace } from "./serviceTokenData";
import { AuthData } from "../interfaces/middleware";
import {
BadRequestError,
SecretNotFoundError,
UnauthorizedRequestError,
} from "../utils/errors";
import {
AUTH_MODE_API_KEY,
AUTH_MODE_JWT,
AUTH_MODE_SERVICE_ACCOUNT,
AUTH_MODE_SERVICE_TOKEN,
} from "../variables";
import { AuthData } from "../interfaces/middleware";
import { ActorType } from "../ee/models";
/**
* Validate authenticated clients for secrets with id [secretId] based
@@ -47,53 +39,26 @@ export const validateClientForSecret = async ({
if (!secret) throw SecretNotFoundError({
message: "Failed to find secret",
});
switch (authData.actor.type) {
case ActorType.USER:
await validateUserClientForSecret({
user: authData.authPayload as IUser,
secret,
acceptedRoles,
requiredPermissions,
});
if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) {
await validateUserClientForSecret({
user: authData.authPayload,
secret,
acceptedRoles,
requiredPermissions,
});
return secret;
}
if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) {
await validateServiceAccountClientForWorkspace({
serviceAccount: authData.authPayload,
workspaceId: secret.workspace,
environment: secret.environment,
requiredPermissions,
});
return secret;
case ActorType.SERVICE:
await validateServiceTokenDataClientForWorkspace({
serviceTokenData: authData.authPayload as IServiceTokenData,
workspaceId: secret.workspace,
environment: secret.environment,
});
return secret;
return secret;
}
if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) {
await validateServiceTokenDataClientForWorkspace({
serviceTokenData: authData.authPayload,
workspaceId: secret.workspace,
environment: secret.environment,
});
return secret;
}
if (authData.authMode === AUTH_MODE_API_KEY && authData.authPayload instanceof User) {
await validateUserClientForSecret({
user: authData.authPayload,
secret,
acceptedRoles,
requiredPermissions,
});
return secret;
}
throw UnauthorizedRequestError({
message: "Failed client authorization for secret",
});
}
/**
@@ -127,48 +92,23 @@ export const validateClientForSecrets = async ({
if (secrets.length != secretIds.length) {
throw BadRequestError({ message: "Failed to validate non-existent secrets" })
}
if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) {
await validateUserClientForSecrets({
user: authData.authPayload,
secrets,
requiredPermissions,
});
return secrets;
}
if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) {
await validateServiceAccountClientForSecrets({
serviceAccount: authData.authPayload,
secrets,
requiredPermissions,
});
return secrets;
switch (authData.actor.type) {
case ActorType.USER:
await validateUserClientForSecrets({
user: authData.authPayload as IUser,
secrets,
requiredPermissions,
});
return secrets;
case ActorType.SERVICE:
await validateServiceTokenDataClientForSecrets({
serviceTokenData: authData.authPayload as IServiceTokenData,
secrets,
requiredPermissions,
});
return secrets;
}
if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) {
await validateServiceTokenDataClientForSecrets({
serviceTokenData: authData.authPayload,
secrets,
requiredPermissions,
});
return secrets;
}
if (authData.authMode === AUTH_MODE_API_KEY && authData.authPayload instanceof User) {
await validateUserClientForSecrets({
user: authData.authPayload,
secrets,
requiredPermissions,
});
return secrets;
}
throw UnauthorizedRequestError({
message: "Failed client authorization for secrets resource",
});
}
+16 -49
View File
@@ -4,12 +4,9 @@ import {
IOrganization,
ISecret,
IServiceAccount,
IServiceTokenData,
IUser,
ServiceAccount,
ServiceAccountWorkspacePermission,
ServiceTokenData,
User,
} from "../models";
import { validateUserClientForServiceAccount } from "./user";
import {
@@ -18,23 +15,18 @@ import {
UnauthorizedRequestError,
} from "../utils/errors";
import {
AUTH_MODE_API_KEY,
AUTH_MODE_JWT,
AUTH_MODE_SERVICE_ACCOUNT,
AUTH_MODE_SERVICE_TOKEN,
PERMISSION_READ_SECRETS,
PERMISSION_WRITE_SECRETS,
} from "../variables";
import { AuthData } from "../interfaces/middleware";
import { ActorType } from "../ee/models";
export const validateClientForServiceAccount = async ({
authData,
serviceAccountId,
requiredPermissions,
}: {
authData: {
authMode: string;
authPayload: IUser | IServiceAccount | IServiceTokenData;
},
authData: AuthData;
serviceAccountId: Types.ObjectId;
requiredPermissions?: string[];
}) => {
@@ -46,45 +38,20 @@ export const validateClientForServiceAccount = async ({
});
}
if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) {
await validateUserClientForServiceAccount({
user: authData.authPayload,
serviceAccount,
requiredPermissions,
});
return serviceAccount;
switch (authData.actor.type) {
case ActorType.USER:
await validateUserClientForServiceAccount({
user: authData.authPayload as IUser,
serviceAccount,
requiredPermissions,
});
return serviceAccount;
case ActorType.SERVICE:
throw UnauthorizedRequestError({
message: "Failed service token authorization for service account resource",
});
}
if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) {
await validateServiceAccountClientForServiceAccount({
serviceAccount: authData.authPayload,
targetServiceAccount: serviceAccount,
requiredPermissions,
});
return serviceAccount;
}
if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) {
throw UnauthorizedRequestError({
message: "Failed service token authorization for service account resource",
});
}
if (authData.authMode === AUTH_MODE_API_KEY && authData.authPayload instanceof User) {
await validateUserClientForServiceAccount({
user: authData.authPayload,
serviceAccount,
requiredPermissions,
});
return serviceAccount;
}
throw UnauthorizedRequestError({
message: "Failed client authorization for service account resource",
});
}
/**
+20 -62
View File
@@ -1,22 +1,14 @@
import { Types } from "mongoose";
import {
ISecret,
IServiceAccount,
IServiceTokenData,
IUser,
ServiceAccount,
ServiceTokenData,
User
} from "../models";
import { ServiceTokenDataNotFoundError, UnauthorizedRequestError } from "../utils/errors";
import {
AUTH_MODE_API_KEY,
AUTH_MODE_JWT,
AUTH_MODE_SERVICE_ACCOUNT,
AUTH_MODE_SERVICE_TOKEN
} from "../variables";
import { validateUserClientForWorkspace } from "./user";
import { validateServiceAccountClientForWorkspace } from "./serviceAccount";
import { ActorType } from "../ee/models";
import { AuthData } from "../interfaces/middleware";
/**
* Validate authenticated clients for service token with id [serviceTokenId] based
@@ -31,10 +23,7 @@ export const validateClientForServiceTokenData = async ({
serviceTokenDataId,
acceptedRoles
}: {
authData: {
authMode: string;
authPayload: IUser | IServiceAccount | IServiceTokenData;
};
authData: AuthData;
serviceTokenDataId: Types.ObjectId;
acceptedRoles: Array<"admin" | "member">;
}) => {
@@ -42,55 +31,24 @@ export const validateClientForServiceTokenData = async ({
.select("+encryptedKey +iv +tag")
.populate<{ user: IUser }>("user");
if (!serviceTokenData)
throw ServiceTokenDataNotFoundError({
message: "Failed to find service token data"
});
if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) {
await validateUserClientForWorkspace({
user: authData.authPayload,
workspaceId: serviceTokenData.workspace,
acceptedRoles
});
return serviceTokenData;
}
if (
authData.authMode === AUTH_MODE_SERVICE_ACCOUNT &&
authData.authPayload instanceof ServiceAccount
) {
await validateServiceAccountClientForWorkspace({
serviceAccount: authData.authPayload,
workspaceId: serviceTokenData.workspace
});
return serviceTokenData;
}
if (
authData.authMode === AUTH_MODE_SERVICE_TOKEN &&
authData.authPayload instanceof ServiceTokenData
) {
throw UnauthorizedRequestError({
message: "Failed service token authorization for service token data"
});
}
if (authData.authMode === AUTH_MODE_API_KEY && authData.authPayload instanceof User) {
await validateUserClientForWorkspace({
user: authData.authPayload,
workspaceId: serviceTokenData.workspace,
acceptedRoles
});
return serviceTokenData;
}
throw UnauthorizedRequestError({
message: "Failed client authorization for service token data"
if (!serviceTokenData) throw ServiceTokenDataNotFoundError({
message: "Failed to find service token data"
});
switch (authData.actor.type) {
case ActorType.USER:
await validateUserClientForWorkspace({
user: authData.authPayload as IUser,
workspaceId: serviceTokenData.workspace,
acceptedRoles
});
return serviceTokenData;
case ActorType.SERVICE:
throw UnauthorizedRequestError({
message: "Failed service token authorization for service token data"
});
}
};
/**
+52 -89
View File
@@ -2,15 +2,14 @@ import net from "net";
import { Types } from "mongoose";
import {
SecretBlindIndexData,
ServiceAccount,
ServiceTokenData,
User,
IServiceTokenData,
IUser,
Workspace,
} from "../models";
import {
ActorType,
TrustedIP
} from "../ee/models";
import { validateServiceAccountClientForWorkspace } from "./serviceAccount";
import { validateUserClientForWorkspace } from "./user";
import { validateServiceTokenDataClientForWorkspace } from "./serviceTokenData";
import {
@@ -18,12 +17,6 @@ import {
UnauthorizedRequestError,
WorkspaceNotFoundError,
} from "../utils/errors";
import {
AUTH_MODE_API_KEY,
AUTH_MODE_JWT,
AUTH_MODE_SERVICE_ACCOUNT,
AUTH_MODE_SERVICE_TOKEN,
} from "../variables";
import { BotService } from "../services";
import { AuthData } from "../interfaces/middleware";
import { extractIPDetails } from "../utils/ip";
@@ -85,89 +78,59 @@ export const validateClientForWorkspace = async ({
});
}
switch (authData.actor.type) {
case ActorType.USER:
const membership = await validateUserClientForWorkspace({
user: authData.authPayload as IUser,
workspaceId,
environment,
acceptedRoles,
requiredPermissions,
});
return ({ membership, workspace });
case ActorType.SERVICE:
if (checkIPAllowlist) {
const trustedIps = await TrustedIP.find({
workspace: workspaceId
});
if (trustedIps.length > 0) {
// case: check the IP address of the inbound request against trusted IPs
if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) {
const membership = await validateUserClientForWorkspace({
user: authData.authPayload,
workspaceId,
environment,
acceptedRoles,
requiredPermissions,
});
const blockList = new net.BlockList();
return ({ membership, workspace });
}
for (const trustedIp of trustedIps) {
if (trustedIp.prefix !== undefined) {
blockList.addSubnet(
trustedIp.ipAddress,
trustedIp.prefix,
trustedIp.type
);
} else {
blockList.addAddress(
trustedIp.ipAddress,
trustedIp.type
);
}
}
const { type } = extractIPDetails(authData.ipAddress);
const check = blockList.check(authData.ipAddress, type);
if (!check) throw UnauthorizedRequestError({
message: "Failed workspace authorization"
});
}
}
if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) {
await validateServiceAccountClientForWorkspace({
serviceAccount: authData.authPayload,
workspaceId,
environment,
requiredPermissions,
});
return {};
}
if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) {
if (checkIPAllowlist) {
const trustedIps = await TrustedIP.find({
workspace: workspaceId
await validateServiceTokenDataClientForWorkspace({
serviceTokenData: authData.authPayload as IServiceTokenData,
workspaceId,
environment,
requiredPermissions,
});
if (trustedIps.length > 0) {
// case: check the IP address of the inbound request against trusted IPs
const blockList = new net.BlockList();
for (const trustedIp of trustedIps) {
if (trustedIp.prefix !== undefined) {
blockList.addSubnet(
trustedIp.ipAddress,
trustedIp.prefix,
trustedIp.type
);
} else {
blockList.addAddress(
trustedIp.ipAddress,
trustedIp.type
);
}
}
const { type } = extractIPDetails(authData.authIP);
const check = blockList.check(authData.authIP, type);
if (!check) throw UnauthorizedRequestError({
message: "Failed workspace authorization"
});
}
}
await validateServiceTokenDataClientForWorkspace({
serviceTokenData: authData.authPayload,
workspaceId,
environment,
requiredPermissions,
});
return {};
return {};
}
if (authData.authMode === AUTH_MODE_API_KEY && authData.authPayload instanceof User) {
const membership = await validateUserClientForWorkspace({
user: authData.authPayload,
workspaceId,
environment,
acceptedRoles,
requiredPermissions,
});
return ({ membership, workspace });
}
throw UnauthorizedRequestError({
message: "Failed client authorization for workspace",
});
}