mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 11:38:55 +00:00
Service account checkpoint
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
import * as Sentry from '@sentry/node';
|
||||
import { Membership, Key } from '../models';
|
||||
import {
|
||||
MembershipNotFoundError,
|
||||
BadRequestError
|
||||
} from '../utils/errors';
|
||||
|
||||
/**
|
||||
* Validate that user with id [userId] is a member of workspace with id [workspaceId]
|
||||
@@ -19,23 +23,17 @@ const validateMembership = async ({
|
||||
acceptedRoles: string[];
|
||||
}) => {
|
||||
|
||||
let membership;
|
||||
//TODO: Refactor code to take advantage of using RequestError. It's possible to create new types of errors for more detailed errors
|
||||
try {
|
||||
membership = await Membership.findOne({
|
||||
user: userId,
|
||||
workspace: workspaceId
|
||||
}).populate("workspace");
|
||||
|
||||
if (!membership) throw new Error('Failed to find membership');
|
||||
|
||||
if (!acceptedRoles.includes(membership.role)) {
|
||||
throw new Error('Failed to validate membership role');
|
||||
}
|
||||
} catch (err) {
|
||||
Sentry.setUser(null);
|
||||
Sentry.captureException(err);
|
||||
throw new Error('Failed to validate membership');
|
||||
const membership = await Membership.findOne({
|
||||
user: userId,
|
||||
workspace: workspaceId
|
||||
}).populate("workspace");
|
||||
|
||||
if (!membership) {
|
||||
throw MembershipNotFoundError({ message: 'Failed to find workspace membership' });
|
||||
}
|
||||
|
||||
if (!acceptedRoles.includes(membership.role)) {
|
||||
throw BadRequestError({ message: 'Failed to validate workspace membership role' });
|
||||
}
|
||||
|
||||
return membership;
|
||||
|
||||
@@ -1,40 +1,48 @@
|
||||
import * as Sentry from '@sentry/node';
|
||||
import { Types } from 'mongoose';
|
||||
import { MembershipOrg, Workspace, Membership, Key } from '../models';
|
||||
import {
|
||||
MembershipOrgNotFoundError,
|
||||
BadRequestError
|
||||
} from '../utils/errors';
|
||||
|
||||
/**
|
||||
* Validate that user with id [userId] is a member of organization with id [organizationId]
|
||||
* and has at least one of the roles in [acceptedRoles]
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @param {Types.ObjectId} obj.userId
|
||||
* @param {Types.ObjectId} obj.organizationId
|
||||
* @param {String[]} obj.acceptedRoles
|
||||
*/
|
||||
const validateMembership = async ({
|
||||
const validateMembershipOrg = async ({
|
||||
userId,
|
||||
organizationId,
|
||||
acceptedRoles
|
||||
acceptedRoles,
|
||||
acceptedStatuses
|
||||
}: {
|
||||
userId: string;
|
||||
organizationId: string;
|
||||
userId: Types.ObjectId;
|
||||
organizationId: Types.ObjectId;
|
||||
acceptedRoles: string[];
|
||||
acceptedStatuses: string[];
|
||||
}) => {
|
||||
let membership;
|
||||
try {
|
||||
membership = await MembershipOrg.findOne({
|
||||
user: new Types.ObjectId(userId),
|
||||
organization: new Types.ObjectId(organizationId)
|
||||
});
|
||||
|
||||
if (!membership) throw new Error('Failed to find organization membership');
|
||||
|
||||
if (!acceptedRoles.includes(membership.role)) {
|
||||
throw new Error('Failed to validate organization membership role');
|
||||
}
|
||||
} catch (err) {
|
||||
Sentry.setUser(null);
|
||||
Sentry.captureException(err);
|
||||
throw new Error('Failed to validate organization membership');
|
||||
const membershipOrg = await MembershipOrg.findOne({
|
||||
user: userId,
|
||||
organization: organizationId
|
||||
});
|
||||
|
||||
if (!membershipOrg) {
|
||||
throw MembershipOrgNotFoundError({ message: 'Failed to find organization membership' });
|
||||
}
|
||||
|
||||
return membership;
|
||||
if (!acceptedRoles.includes(membershipOrg.role)) {
|
||||
throw BadRequestError({ message: 'Failed to validate organization membership role' });
|
||||
}
|
||||
|
||||
if (!acceptedStatuses.includes(membershipOrg.status)) {
|
||||
throw BadRequestError({ message: 'Failed to validate organization membership status' });
|
||||
}
|
||||
|
||||
return membershipOrg;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,7 +164,7 @@ const deleteMembershipOrg = async ({
|
||||
};
|
||||
|
||||
export {
|
||||
validateMembership,
|
||||
validateMembershipOrg,
|
||||
findMembershipOrg,
|
||||
addMembershipsOrg,
|
||||
deleteMembershipOrg
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
import { Types } from 'mongoose';
|
||||
import {
|
||||
Workspace,
|
||||
ServiceAccount,
|
||||
ServiceAccountKey
|
||||
} from '../models';
|
||||
import {
|
||||
WorkspaceNotFoundError,
|
||||
ServiceAccountNotFoundError,
|
||||
ServiceAccountKeyNotFoundError
|
||||
} from '../utils/errors';
|
||||
import {
|
||||
PERMISSION_SA_WORKSPACE_READ,
|
||||
PERMISSION_SA_WORKSPACE_WRITE,
|
||||
PERMISSION_SA_SET
|
||||
} from '../variables';
|
||||
|
||||
/**
|
||||
* Validate that user with id [userId] can provision the permission
|
||||
* named [name] for a service account with id [serviceAccountId] and
|
||||
* optionally workspace with id [workspaceId] and environment [environment]
|
||||
* @param {Object} obj
|
||||
* @param {String} obj.name - name of permission to create
|
||||
* @param {Types.ObjectId} userId - id of user creating the permission
|
||||
* @param {Types.ObjectId} serviceAccountId - id of service account that permission will be bound to
|
||||
* @param {Types.ObjectId} workspaceId - id of workspace that permission concerns
|
||||
* @param {Types.ObjectId} workspaceId - id of service account that permission will be bound to
|
||||
*/
|
||||
const validateCreateServiceAccountPermission = async ({
|
||||
name,
|
||||
userId,
|
||||
serviceAccountId,
|
||||
workspaceId,
|
||||
environment
|
||||
}: {
|
||||
name: string;
|
||||
userId: Types.ObjectId;
|
||||
serviceAccountId: Types.ObjectId,
|
||||
workspaceId?: Types.ObjectId;
|
||||
environment?: string;
|
||||
}) => {
|
||||
|
||||
// TODO: as we upgrade user permissions to be more global, then we should take into account
|
||||
// the user's permissions as it concerns to being able to interact with service accounts
|
||||
|
||||
if (!PERMISSION_SA_SET.has(name)) throw new Error(`${name} is not a valid permission name`);
|
||||
|
||||
if ([
|
||||
PERMISSION_SA_WORKSPACE_READ,
|
||||
PERMISSION_SA_WORKSPACE_WRITE
|
||||
].includes(name)) {
|
||||
if (workspaceId && environment) {
|
||||
// case: either workspace id [workspaceId] or environment name [environment] is being passed in
|
||||
// (i.e. validating a service account permission concerning a workspace and/or environment)
|
||||
const workspace = await Workspace.findById(workspaceId);
|
||||
|
||||
if (!workspace) {
|
||||
// case: workspace does not exist
|
||||
throw WorkspaceNotFoundError({ message: 'Failed to locate workspace' });
|
||||
}
|
||||
|
||||
if (!workspace.environments.some((env) => env.slug === environment)) {
|
||||
// case: environment name [environment] is not a valid environment slug in workspace
|
||||
throw Error('Failed to locate environment in workspace');
|
||||
}
|
||||
|
||||
const serviceAccount = await ServiceAccount.findById(serviceAccountId);
|
||||
if (!serviceAccount) {
|
||||
// case: service account does not exist
|
||||
throw ServiceAccountNotFoundError({ message: 'Failed to locate service account' });
|
||||
}
|
||||
|
||||
const serviceAccountKey = await ServiceAccountKey.findOne({
|
||||
serviceAccount: serviceAccount._id,
|
||||
workspace: workspaceId
|
||||
});
|
||||
|
||||
if (!serviceAccountKey) {
|
||||
// case: service account key does not exist
|
||||
throw ServiceAccountKeyNotFoundError({ message: 'Failed to locate service account key' });
|
||||
}
|
||||
} else {
|
||||
throw new Error('Failed to validate workspace and environment for workspace-related permission');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const validateDeleteServiceAccountPermission = async ({
|
||||
userId,
|
||||
serviceAccountId,
|
||||
name,
|
||||
workspaceId,
|
||||
environment
|
||||
}: {
|
||||
userId: Types.ObjectId;
|
||||
serviceAccountId: Types.ObjectId;
|
||||
name: string;
|
||||
workspaceId: Types.ObjectId;
|
||||
environment: string;
|
||||
}) => {
|
||||
// does the user have the authority to delete the permission?
|
||||
// does the service account permission exist?
|
||||
|
||||
|
||||
}
|
||||
|
||||
export {
|
||||
validateCreateServiceAccountPermission
|
||||
}
|
||||
Reference in New Issue
Block a user