Begin service account middleware

This commit is contained in:
Tuan Dang
2023-03-30 23:55:24 +07:00
parent 54e099f8a8
commit 9c18adf35f
31 changed files with 279 additions and 146 deletions
+37
View File
@@ -5,11 +5,13 @@ import {
IUser,
User,
ServiceTokenData,
ServiceAccount,
APIKeyData
} from '../models';
import {
AccountNotFoundError,
ServiceTokenDataNotFoundError,
ServiceAccountNotFoundError,
APIKeyDataNotFoundError,
UnauthorizedRequestError,
BadRequestError
@@ -63,9 +65,13 @@ const validateAuthMode = ({
case 'st':
authTokenType = 'serviceToken';
break;
case 'sa':
authTokenType = 'serviceAccount';
break;
default:
authTokenType = 'jwt';
}
authTokenValue = tokenValue;
}
@@ -164,6 +170,36 @@ const getAuthSTDPayload = async ({
}
/**
* Return service account access key payload
* @param {Object} obj
* @param {String} obj.authTokenValue - service account access token value
* @returns {ServiceAccount} serviceAccount
*/
const getAuthSAAKPayload = async ({
authTokenValue
}: {
authTokenValue: string;
}) => {
const [_, TOKEN_IDENTIFIER, TOKEN_SECRET] = <[string, string, string]>authTokenValue.split('.', 3);
const serviceAccount = await ServiceAccount.findById(
Buffer.from(TOKEN_IDENTIFIER, 'base64').toString('hex')
).select('+secretHash');
if (!serviceAccount) {
throw ServiceAccountNotFoundError({ message: 'Failed to find service account' });
}
const result = await bcrypt.compare(TOKEN_SECRET, serviceAccount.secretHash);
if (!result) throw UnauthorizedRequestError({
message: 'Failed to authenticate service account access key'
});
return serviceAccount;
}
/**
* TODO: deprecate API keys
* Return API key data payload corresponding to API key [authTokenValue]
* @param {Object} obj
* @param {String} obj.authTokenValue - API key value
@@ -300,6 +336,7 @@ export {
validateAuthMode,
getAuthUserPayload,
getAuthSTDPayload,
getAuthSAAKPayload,
getAuthAPIKeyPayload,
createToken,
issueAuthTokens,
+8 -5
View File
@@ -1,4 +1,5 @@
import * as Sentry from '@sentry/node';
import { Types } from 'mongoose';
import { Membership, Key } from '../models';
import {
MembershipNotFoundError,
@@ -18,9 +19,9 @@ const validateMembership = async ({
workspaceId,
acceptedRoles,
}: {
userId: string;
workspaceId: string;
acceptedRoles: string[];
userId: Types.ObjectId;
workspaceId: Types.ObjectId;
acceptedRoles?: string[];
}) => {
const membership = await Membership.findOne({
@@ -32,8 +33,10 @@ const validateMembership = async ({
throw MembershipNotFoundError({ message: 'Failed to find workspace membership' });
}
if (!acceptedRoles.includes(membership.role)) {
throw BadRequestError({ message: 'Failed to validate workspace membership role' });
if (acceptedRoles) {
if (!acceptedRoles.includes(membership.role)) {
throw BadRequestError({ message: 'Failed to validate workspace membership role' });
}
}
return membership;
+50 -1
View File
@@ -1,4 +1,5 @@
import * as Sentry from '@sentry/node';
import { Types } from 'mongoose';
import {
Workspace,
Bot,
@@ -7,6 +8,50 @@ import {
Secret
} from '../models';
import { createBot } from '../helpers/bot';
import { validateMembership } from '../helpers/membership';
/**
* Validate accepted clients by id including [userId], [serviceAccountId],
* and [serviceTokenDataId] for workspace with id [workspaceId] based
* on any known permissions.
* @param {Object} obj
* @param {Types.ObjectId} obj.userId - id of user
*/
const validateClientForWorkspace = async ({
userId,
serviceAccountId,
serviceTokenDataId,
workspaceId,
environment
}: {
userId?: Types.ObjectId;
serviceAccountId?: Types.ObjectId;
serviceTokenDataId?: Types.ObjectId;
workspaceId: Types.ObjectId;
environment?: string;
}) => {
let membership;
if (userId) {
membership = await validateMembership({
userId,
workspaceId
});
}
if (serviceAccountId) {
// TODO
}
if (serviceTokenDataId) {
// TODO
}
return ({
membership
});
}
/**
* Create a workspace with name [name] in organization with id [organizationId]
@@ -71,4 +116,8 @@ const deleteWorkspace = async ({ id }: { id: string }) => {
}
};
export { createWorkspace, deleteWorkspace };
export {
validateClientForWorkspace,
createWorkspace,
deleteWorkspace
};