mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-13 02:29:26 +00:00
Clean up and weave crypto into service account permissions
This commit is contained in:
@@ -5,8 +5,8 @@ import bcrypt from 'bcrypt';
|
||||
import {
|
||||
ServiceAccount,
|
||||
ServiceAccountKey,
|
||||
ServiceAccountOrganizationPermissions,
|
||||
ServiceAccountWorkspacePermissions
|
||||
ServiceAccountOrganizationPermission,
|
||||
ServiceAccountWorkspacePermission
|
||||
} from '../../models';
|
||||
import {
|
||||
CreateServiceAccountDto
|
||||
@@ -71,8 +71,8 @@ export const createServiceAccount = async (req: Request, res: Response) => {
|
||||
|
||||
delete serviceAccountObj.secretHash;
|
||||
|
||||
// provision default org-level permissions for service account
|
||||
const permissions = await new ServiceAccountOrganizationPermissions({
|
||||
// provision default org-level permission for service account
|
||||
await new ServiceAccountOrganizationPermission({
|
||||
serviceAccount: serviceAccount._id
|
||||
}).save();
|
||||
|
||||
@@ -136,57 +136,57 @@ export const addServiceAccountKey = async (req: Request, res: Response) => {
|
||||
return serviceAccountKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return organization-level permissions for service account with id [serviceAccountId]
|
||||
* @param req
|
||||
* @param res
|
||||
*/
|
||||
export const getServiceAccountOrganizationPermissions = async (req: Request, res: Response) => {
|
||||
const { serviceAccountId } = req.params;
|
||||
// /**
|
||||
// * Return organization-level permissions for service account with id [serviceAccountId]
|
||||
// * @param req
|
||||
// * @param res
|
||||
// */
|
||||
// export const getServiceAccountOrganizationPermissions = async (req: Request, res: Response) => {
|
||||
// const { serviceAccountId } = req.params;
|
||||
|
||||
const permissions = await ServiceAccountOrganizationPermissions.findOne({
|
||||
serviceAccount: new Types.ObjectId(serviceAccountId),
|
||||
});
|
||||
// const permissions = await ServiceAccountOrganizationPermissions.findOne({
|
||||
// serviceAccount: new Types.ObjectId(serviceAccountId),
|
||||
// });
|
||||
|
||||
return res.status(200).send({
|
||||
permissions
|
||||
});
|
||||
}
|
||||
// return res.status(200).send({
|
||||
// permissions
|
||||
// });
|
||||
// }
|
||||
|
||||
/**
|
||||
* Return workspace-level permissions for service account with id [serviceAccountId]
|
||||
* Return workspace-level permission for service account with id [serviceAccountId]
|
||||
* @param req
|
||||
* @param res
|
||||
*/
|
||||
export const getServiceAccountWorkspacePermissions = async (req: Request, res: Response) => {
|
||||
const permissions = await ServiceAccountWorkspacePermissions.find({
|
||||
const serviceAccountWorkspacePermissions = await ServiceAccountWorkspacePermission.find({
|
||||
serviceAccount: req.serviceAccount._id
|
||||
}).populate('workspace');
|
||||
|
||||
return res.status(200).send({
|
||||
permissions
|
||||
serviceAccountWorkspacePermissions
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add organization permissions to service account with id [serviceAccountId]
|
||||
* @param req
|
||||
* @param res
|
||||
*/
|
||||
export const addServiceAccountOrganizationPermission = async (req: Request, res: Response) => {
|
||||
const permissions = ServiceAccountOrganizationPermissions.findOne({
|
||||
serviceAccount: req.serviceAccount._id
|
||||
});
|
||||
// /**
|
||||
// * Add organization permissions to service account with id [serviceAccountId]
|
||||
// * @param req
|
||||
// * @param res
|
||||
// */
|
||||
// export const addServiceAccountOrganizationPermission = async (req: Request, res: Response) => {
|
||||
// const permissions = ServiceAccountOrganizationPermissions.findOne({
|
||||
// serviceAccount: req.serviceAccount._id
|
||||
// });
|
||||
|
||||
// TODO
|
||||
// // TODO
|
||||
|
||||
return res.status(200).send({
|
||||
permissions
|
||||
});
|
||||
}
|
||||
// return res.status(200).send({
|
||||
// permissions
|
||||
// });
|
||||
// }
|
||||
|
||||
/**
|
||||
* Add a workspace permissions to service account with id [serviceAccountId]
|
||||
* Add a workspace permission to service account with id [serviceAccountId]
|
||||
* @param req
|
||||
* @param res
|
||||
*/
|
||||
@@ -198,7 +198,9 @@ export const addServiceAccountWorkspacePermission = async (req: Request, res: Re
|
||||
canRead = false,
|
||||
canWrite = false,
|
||||
canUpdate = false,
|
||||
canDelete = false
|
||||
canDelete = false,
|
||||
encryptedKey,
|
||||
nonce
|
||||
} = req.body;
|
||||
|
||||
if (!req.membership.workspace.environments.some((e: { name: string; slug: string }) => e.slug === environment)) {
|
||||
@@ -207,7 +209,7 @@ export const addServiceAccountWorkspacePermission = async (req: Request, res: Re
|
||||
});
|
||||
}
|
||||
|
||||
const existingPermission = await ServiceAccountWorkspacePermissions.findOne({
|
||||
const existingPermission = await ServiceAccountWorkspacePermission.findOne({
|
||||
serviceAccount: new Types.ObjectId(serviceAccountId),
|
||||
workspaceId: new Types.ObjectId(workspaceId),
|
||||
environment
|
||||
@@ -215,7 +217,7 @@ export const addServiceAccountWorkspacePermission = async (req: Request, res: Re
|
||||
|
||||
if (existingPermission) throw BadRequestError({ message: 'Failed to add workspace permission to service account due to already-existing ' });
|
||||
|
||||
const permissions = await new ServiceAccountWorkspacePermissions({
|
||||
const serviceAccountWorkspacePermission = await new ServiceAccountWorkspacePermission({
|
||||
serviceAccount: new Types.ObjectId(serviceAccountId),
|
||||
workspace: new Types.ObjectId(workspaceId),
|
||||
environment,
|
||||
@@ -225,23 +227,52 @@ export const addServiceAccountWorkspacePermission = async (req: Request, res: Re
|
||||
canDelete
|
||||
}).save();
|
||||
|
||||
const existingServiceAccountKey = await ServiceAccountKey.findOne({
|
||||
serviceAccount: new Types.ObjectId(serviceAccountId),
|
||||
workspace: new Types.ObjectId(workspaceId)
|
||||
});
|
||||
|
||||
if (!existingServiceAccountKey) {
|
||||
await new ServiceAccountKey({
|
||||
encryptedKey,
|
||||
nonce,
|
||||
sender: req.user._id,
|
||||
serviceAccount: new Types.ObjectId(serviceAccountId),
|
||||
workspace: new Types.ObjectId(workspaceId)
|
||||
}).save();
|
||||
}
|
||||
|
||||
return res.status(200).send({
|
||||
permissions
|
||||
serviceAccountWorkspacePermission
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete workspace permissions from service account with id [serviceAccountId]
|
||||
* Delete workspace permission from service account with id [serviceAccountId]
|
||||
* @param req
|
||||
* @param res
|
||||
*/
|
||||
export const deleteServiceAccountWorkspacePermission = async (req: Request, res: Response) => {
|
||||
const { serviceAccountWorkspacePermissionsId } = req.params;
|
||||
|
||||
const permissions = await ServiceAccountWorkspacePermissions.findByIdAndDelete(serviceAccountWorkspacePermissionsId);
|
||||
|
||||
const { serviceAccountWorkspacePermissionId } = req.params;
|
||||
const serviceAccountWorkspacePermission = await ServiceAccountWorkspacePermission.findByIdAndDelete(serviceAccountWorkspacePermissionId);
|
||||
|
||||
if (serviceAccountWorkspacePermission) {
|
||||
const { serviceAccount, workspace } = serviceAccountWorkspacePermission;
|
||||
const count = await ServiceAccountWorkspacePermission.countDocuments({
|
||||
serviceAccount,
|
||||
workspace
|
||||
});
|
||||
|
||||
if (count === 0) {
|
||||
await ServiceAccountKey.findOneAndDelete({
|
||||
serviceAccount,
|
||||
workspace
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return res.status(200).send({
|
||||
permissions
|
||||
serviceAccountWorkspacePermission
|
||||
});
|
||||
}
|
||||
|
||||
@@ -257,17 +288,15 @@ export const deleteServiceAccount = async (req: Request, res: Response) => {
|
||||
const serviceAccount = await ServiceAccount.findByIdAndDelete(serviceAccountId);
|
||||
|
||||
if (serviceAccount) {
|
||||
// case: service account with id [serviceAccountId] was deleted
|
||||
|
||||
await ServiceAccountKey.deleteMany({
|
||||
serviceAccount: serviceAccount._id
|
||||
});
|
||||
|
||||
await ServiceAccountOrganizationPermissions.deleteMany({
|
||||
await ServiceAccountOrganizationPermission.deleteMany({
|
||||
serviceAccount: new Types.ObjectId(serviceAccountId)
|
||||
});
|
||||
|
||||
await ServiceAccountWorkspacePermissions.deleteMany({
|
||||
await ServiceAccountWorkspacePermission.deleteMany({
|
||||
serviceAccount: new Types.ObjectId(serviceAccountId)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import requireIntegrationAuthorizationAuth from './requireIntegrationAuthorizati
|
||||
import requireServiceTokenAuth from './requireServiceTokenAuth';
|
||||
import requireServiceTokenDataAuth from './requireServiceTokenDataAuth';
|
||||
import requireServiceAccountAuth from './requireServiceAccountAuth';
|
||||
import requireServiceAccountWorkspacePermissionsAuth from './requireServiceAccountWorkspacePermissionsAuth';
|
||||
import requireServiceAccountWorkspacePermissionAuth from './requireServiceAccountWorkspacePermissionAuth';
|
||||
import requireSecretAuth from './requireSecretAuth';
|
||||
import requireSecretsAuth from './requireSecretsAuth';
|
||||
import validateRequest from './validateRequest';
|
||||
@@ -30,7 +30,7 @@ export {
|
||||
requireServiceTokenAuth,
|
||||
requireServiceTokenDataAuth,
|
||||
requireServiceAccountAuth,
|
||||
requireServiceAccountWorkspacePermissionsAuth,
|
||||
requireServiceAccountWorkspacePermissionAuth,
|
||||
requireSecretAuth,
|
||||
requireSecretsAuth,
|
||||
validateRequest
|
||||
|
||||
+7
-7
@@ -1,5 +1,5 @@
|
||||
import { Request, Response, NextFunction } from 'express';
|
||||
import { ServiceAccount, ServiceAccountWorkspacePermissions } from '../models';
|
||||
import { ServiceAccount, ServiceAccountWorkspacePermission } from '../models';
|
||||
import {
|
||||
ServiceAccountNotFoundError
|
||||
} from '../utils/errors';
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
|
||||
type req = 'params' | 'body' | 'query';
|
||||
|
||||
const requireServiceAccountWorkspacePermissionsAuth = ({
|
||||
const requireServiceAccountWorkspacePermissionAuth = ({
|
||||
acceptedRoles,
|
||||
acceptedStatuses,
|
||||
location = 'params'
|
||||
@@ -19,14 +19,14 @@ const requireServiceAccountWorkspacePermissionsAuth = ({
|
||||
location?: req;
|
||||
}) => {
|
||||
return async (req: Request, res: Response, next: NextFunction) => {
|
||||
const serviceAccountWorkspacePermissionsId = req[location].serviceAccountWorkspacePermissionsId;
|
||||
const serviceAccountWorkspacePermissions = await ServiceAccountWorkspacePermissions.findById(serviceAccountWorkspacePermissionsId);
|
||||
const serviceAccountWorkspacePermissionId = req[location].serviceAccountWorkspacePermissionId;
|
||||
const serviceAccountWorkspacePermission = await ServiceAccountWorkspacePermission.findById(serviceAccountWorkspacePermissionId);
|
||||
|
||||
if (!serviceAccountWorkspacePermissions) {
|
||||
if (!serviceAccountWorkspacePermission) {
|
||||
return next(ServiceAccountNotFoundError({ message: 'Failed to locate Service Account workspace permission' }));
|
||||
}
|
||||
|
||||
const serviceAccount = await ServiceAccount.findById(serviceAccountWorkspacePermissions.serviceAccount);
|
||||
const serviceAccount = await ServiceAccount.findById(serviceAccountWorkspacePermission.serviceAccount);
|
||||
|
||||
if (!serviceAccount) {
|
||||
return next(ServiceAccountNotFoundError({ message: 'Failed to locate Service Account' }));
|
||||
@@ -49,4 +49,4 @@ const requireServiceAccountWorkspacePermissionsAuth = ({
|
||||
}
|
||||
}
|
||||
|
||||
export default requireServiceAccountWorkspacePermissionsAuth;
|
||||
export default requireServiceAccountWorkspacePermissionAuth;
|
||||
@@ -12,8 +12,8 @@ import Secret, { ISecret } from './secret';
|
||||
import ServiceToken, { IServiceToken } from './serviceToken';
|
||||
import ServiceAccount, { IServiceAccount } from './serviceAccount'; // new
|
||||
import ServiceAccountKey, { IServiceAccountKey } from './serviceAccountKey'; // new
|
||||
import ServiceAccountOrganizationPermissions, { IServiceAccountOrganizationPermissions } from './serviceAccountOrganizationPermission'; // new
|
||||
import ServiceAccountWorkspacePermissions, { IServiceAccountWorkspacePermissions } from './serviceAccountWorkspacePermissions'; // new
|
||||
import ServiceAccountOrganizationPermission, { IServiceAccountOrganizationPermission } from './serviceAccountOrganizationPermission'; // new
|
||||
import ServiceAccountWorkspacePermission, { IServiceAccountWorkspacePermission } from './serviceAccountWorkspacePermission'; // new
|
||||
import TokenData, { ITokenData } from './tokenData';
|
||||
import User, { IUser } from './user';
|
||||
import UserAction, { IUserAction } from './userAction';
|
||||
@@ -51,10 +51,10 @@ export {
|
||||
IServiceAccount,
|
||||
ServiceAccountKey,
|
||||
IServiceAccountKey,
|
||||
ServiceAccountOrganizationPermissions,
|
||||
IServiceAccountOrganizationPermissions,
|
||||
ServiceAccountWorkspacePermissions,
|
||||
IServiceAccountWorkspacePermissions,
|
||||
ServiceAccountOrganizationPermission,
|
||||
IServiceAccountOrganizationPermission,
|
||||
ServiceAccountWorkspacePermission,
|
||||
IServiceAccountWorkspacePermission,
|
||||
TokenData,
|
||||
ITokenData,
|
||||
User,
|
||||
|
||||
@@ -1,21 +1,16 @@
|
||||
import { Schema, model, Types, Document } from 'mongoose';
|
||||
|
||||
export interface IServiceAccountOrganizationPermissions extends Document {
|
||||
export interface IServiceAccountOrganizationPermission extends Document {
|
||||
_id: Types.ObjectId;
|
||||
serviceAccount: Types.ObjectId;
|
||||
canFoo: boolean;
|
||||
}
|
||||
|
||||
const serviceAccountOrganizationPermissionsSchema = new Schema<IServiceAccountOrganizationPermissions>(
|
||||
const serviceAccountOrganizationPermissionSchema = new Schema<IServiceAccountOrganizationPermission>(
|
||||
{
|
||||
serviceAccount: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'ServiceAccount',
|
||||
required: true
|
||||
},
|
||||
canFoo: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -23,6 +18,6 @@ const serviceAccountOrganizationPermissionsSchema = new Schema<IServiceAccountOr
|
||||
}
|
||||
);
|
||||
|
||||
const ServiceAccountOrganizationPermissions = model<IServiceAccountOrganizationPermissions>('ServiceAccountOrganizationPermissions', serviceAccountOrganizationPermissionsSchema);
|
||||
const ServiceAccountOrganizationPermission = model<IServiceAccountOrganizationPermission>('ServiceAccountOrganizationPermission', serviceAccountOrganizationPermissionSchema);
|
||||
|
||||
export default ServiceAccountOrganizationPermissions;
|
||||
export default ServiceAccountOrganizationPermission;
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
import { Schema, model, Types, Document } from 'mongoose';
|
||||
|
||||
export interface IServiceAccountWorkspacePermissions extends Document {
|
||||
export interface IServiceAccountWorkspacePermission extends Document {
|
||||
_id: Types.ObjectId;
|
||||
serviceAccount: Types.ObjectId;
|
||||
workspace: Types.ObjectId;
|
||||
@@ -11,7 +11,7 @@ export interface IServiceAccountWorkspacePermissions extends Document {
|
||||
canDelete: boolean;
|
||||
}
|
||||
|
||||
const serviceAccountWorkspacePermissions = new Schema<IServiceAccountWorkspacePermissions>(
|
||||
const serviceAccountWorkspacePermissionSchema = new Schema<IServiceAccountWorkspacePermission>(
|
||||
{
|
||||
serviceAccount: {
|
||||
type: Schema.Types.ObjectId,
|
||||
@@ -49,6 +49,6 @@ const serviceAccountWorkspacePermissions = new Schema<IServiceAccountWorkspacePe
|
||||
}
|
||||
);
|
||||
|
||||
const ServiceAccountWorkspacePermissions = model<IServiceAccountWorkspacePermissions>('ServiceAccountWorkspacePermissions', serviceAccountWorkspacePermissions);
|
||||
const ServiceAccountWorkspacePermission = model<IServiceAccountWorkspacePermission>('ServiceAccountWorkspacePermission', serviceAccountWorkspacePermissionSchema);
|
||||
|
||||
export default ServiceAccountWorkspacePermissions;
|
||||
export default ServiceAccountWorkspacePermission;
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
requireOrganizationAuth,
|
||||
requireWorkspaceAuth,
|
||||
requireServiceAccountAuth,
|
||||
requireServiceAccountWorkspacePermissionsAuth,
|
||||
requireServiceAccountWorkspacePermissionAuth,
|
||||
validateRequest
|
||||
} from '../../middleware';
|
||||
import { param, query, body } from 'express-validator';
|
||||
@@ -76,21 +76,21 @@ router.delete(
|
||||
serviceAccountsController.deleteServiceAccount
|
||||
);
|
||||
|
||||
router.get(
|
||||
'/:serviceAccountId/permissions/organization',
|
||||
param('serviceAccountId').exists().isString().trim(),
|
||||
query('offset').exists(),
|
||||
query('limit').exists(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: ['jwt']
|
||||
}),
|
||||
requireServiceAccountAuth({
|
||||
acceptedRoles: [OWNER, ADMIN],
|
||||
acceptedStatuses: [ACCEPTED]
|
||||
}),
|
||||
serviceAccountsController.getServiceAccountOrganizationPermissions
|
||||
);
|
||||
// router.get(
|
||||
// '/:serviceAccountId/permissions/organization',
|
||||
// param('serviceAccountId').exists().isString().trim(),
|
||||
// query('offset').exists(),
|
||||
// query('limit').exists(),
|
||||
// validateRequest,
|
||||
// requireAuth({
|
||||
// acceptedAuthModes: ['jwt']
|
||||
// }),
|
||||
// requireServiceAccountAuth({
|
||||
// acceptedRoles: [OWNER, ADMIN],
|
||||
// acceptedStatuses: [ACCEPTED]
|
||||
// }),
|
||||
// serviceAccountsController.getServiceAccountOrganizationPermission
|
||||
// );
|
||||
|
||||
router.get(
|
||||
'/:serviceAccountId/permissions/workspace',
|
||||
@@ -106,19 +106,19 @@ router.get(
|
||||
serviceAccountsController.getServiceAccountWorkspacePermissions
|
||||
);
|
||||
|
||||
router.post(
|
||||
'/:serviceAccountId/permissions/organization',
|
||||
param('serviceAccountId').exists().isString().trim(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: ['jwt']
|
||||
}),
|
||||
requireServiceAccountAuth({
|
||||
acceptedRoles: [OWNER, ADMIN],
|
||||
acceptedStatuses: [ACCEPTED]
|
||||
}),
|
||||
serviceAccountsController.addServiceAccountOrganizationPermission
|
||||
);
|
||||
// router.post(
|
||||
// '/:serviceAccountId/permissions/organization',
|
||||
// param('serviceAccountId').exists().isString().trim(),
|
||||
// validateRequest,
|
||||
// requireAuth({
|
||||
// acceptedAuthModes: ['jwt']
|
||||
// }),
|
||||
// requireServiceAccountAuth({
|
||||
// acceptedRoles: [OWNER, ADMIN],
|
||||
// acceptedStatuses: [ACCEPTED]
|
||||
// }),
|
||||
// serviceAccountsController.addServiceAccountOrganizationPermission
|
||||
// );
|
||||
|
||||
router.post(
|
||||
'/:serviceAccountId/permissions/workspace',
|
||||
@@ -129,6 +129,8 @@ router.post(
|
||||
body('canWrite').isBoolean().optional(),
|
||||
body('canUpdate').isBoolean().optional(),
|
||||
body('canDelete').isBoolean().optional(),
|
||||
body('encryptedKey').exists().isString().notEmpty(),
|
||||
body('nonce').exists().isString().notEmpty(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: ['jwt']
|
||||
@@ -145,9 +147,9 @@ router.post(
|
||||
);
|
||||
|
||||
router.delete(
|
||||
'/:serviceAccountId/permissions/workspace/:serviceAccountWorkspacePermissionsId',
|
||||
'/:serviceAccountId/permissions/workspace/:serviceAccountWorkspacePermissionId',
|
||||
param('serviceAccountId').exists().isString().trim(),
|
||||
param('serviceAccountWorkspacePermissionsId').exists().isString().trim(),
|
||||
param('serviceAccountWorkspacePermissionId').exists().isString().trim(),
|
||||
validateRequest,
|
||||
requireAuth({
|
||||
acceptedAuthModes: ['jwt']
|
||||
@@ -156,7 +158,7 @@ router.delete(
|
||||
acceptedRoles: [OWNER, ADMIN],
|
||||
acceptedStatuses: [ACCEPTED]
|
||||
}),
|
||||
requireServiceAccountWorkspacePermissionsAuth({
|
||||
requireServiceAccountWorkspacePermissionAuth({
|
||||
acceptedRoles: [OWNER, ADMIN],
|
||||
acceptedStatuses: [ACCEPTED]
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user