Add service account support for organization endpoints and update docs images

This commit is contained in:
Tuan Dang
2023-04-10 17:30:51 +03:00
parent afa7b35d50
commit 5032450b1c
34 changed files with 189 additions and 57 deletions
+2 -2
View File
@@ -22,8 +22,8 @@ const validateMembershipOrg = async ({
}: {
userId: Types.ObjectId;
organizationId: Types.ObjectId;
acceptedRoles: string[];
acceptedStatuses: string[];
acceptedRoles: Array<'owner' | 'admin' | 'member'>;
acceptedStatuses: Array<'invited' | 'accepted'>;
}) => {
const membershipOrg = await MembershipOrg.findOne({
user: userId,
+50 -9
View File
@@ -15,7 +15,8 @@ import {
AUTH_MODE_JWT,
AUTH_MODE_SERVICE_ACCOUNT,
AUTH_MODE_SERVICE_TOKEN,
AUTH_MODE_API_KEY
AUTH_MODE_API_KEY,
OWNER
} from '../variables';
import {
getStripeSecretKey,
@@ -24,8 +25,15 @@ import {
getStripeProductStarter
} from '../config';
import {
UnauthorizedRequestError
UnauthorizedRequestError,
OrganizationNotFoundError
} from '../utils/errors';
import {
validateUserClientForOrganization
} from '../helpers/user';
import {
validateServiceAccountClientForOrganization
} from '../helpers/serviceAccount';
/**
* Validate accepted clients for organization with id [organizationId]
@@ -35,30 +43,62 @@ import {
*/
const validateClientForOrganization = async ({
authData,
organizationId
organizationId,
acceptedRoles,
acceptedStatuses
}: {
authData: {
authMode: string;
authPayload: IUser | IServiceAccount | IServiceTokenData;
},
organizationId: string;
organizationId: Types.ObjectId;
acceptedRoles: Array<'owner' | 'admin' | 'member'>;
acceptedStatuses: Array<'invited' | 'accepted'>;
}) => {
// TODO
const organization = await Organization.findById(organizationId);
if (!organization) {
throw OrganizationNotFoundError({
message: 'Failed to find organization'
});
}
if (authData.authMode === AUTH_MODE_JWT && authData.authPayload instanceof User) {
// TODO
const membershipOrg = await validateUserClientForOrganization({
user: authData.authPayload,
organization,
acceptedRoles,
acceptedStatuses
});
return ({ organization, membershipOrg });
}
if (authData.authMode === AUTH_MODE_SERVICE_ACCOUNT && authData.authPayload instanceof ServiceAccount) {
// TODO
await validateServiceAccountClientForOrganization({
serviceAccount: authData.authPayload,
organization
});
return ({ organization });
}
if (authData.authMode === AUTH_MODE_SERVICE_TOKEN && authData.authPayload instanceof ServiceTokenData) {
// TODO
throw UnauthorizedRequestError({
message: 'Failed service token authorization for organization resource'
});
}
if (authData.authMode === AUTH_MODE_API_KEY && authData.authPayload instanceof User) {
// TODO
const membershipOrg = await validateUserClientForOrganization({
user: authData.authPayload,
organization,
acceptedRoles,
acceptedStatuses
});
return ({ organization, membershipOrg });
}
throw UnauthorizedRequestError({
@@ -228,6 +268,7 @@ const updateSubscriptionOrgQuantity = async ({
};
export {
validateClientForOrganization,
createOrganization,
initSubscriptionOrg,
updateSubscriptionOrgQuantity
+23 -9
View File
@@ -8,6 +8,7 @@ import {
ServiceTokenData,
IServiceTokenData,
ISecret,
IOrganization,
ServiceAccountWorkspacePermission
} from '../models';
import {
@@ -109,9 +110,6 @@ const validateClientForServiceAccount = async ({
environment?: string;
requiredPermissions?: string[];
}) => {
// TODO: add service account API support for workspace-level endpoints that are not
// tied to any specific environment
if (environment) {
const permission = await ServiceAccountWorkspacePermission.findOne({
serviceAccount,
@@ -123,7 +121,6 @@ const validateClientForServiceAccount = async ({
message: 'Failed service account authorization for the given workspace environment'
});
// TODO: refactor
let runningIsDisallowed = false;
requiredPermissions?.forEach((requiredPermission: string) => {
switch (requiredPermission) {
@@ -180,7 +177,6 @@ const validateClientForServiceAccount = async ({
});
requiredPermissions?.forEach((requiredPermission: string) => {
// TODO: refactor
let runningIsDisallowed = false;
requiredPermissions?.forEach((requiredPermission: string) => {
switch (requiredPermission) {
@@ -202,9 +198,6 @@ const validateClientForServiceAccount = async ({
});
});
});
// TODO
return [];
}
/**
@@ -231,9 +224,30 @@ const validateServiceAccountClientForServiceAccount = ({
}
}
/**
* Validate that service account (client) can access organization [organization]
* @param {Object} obj
* @param {User} obj.user - service account client
* @param {Organization} obj.organization - organization to validate against
*/
const validateServiceAccountClientForOrganization = async ({
serviceAccount,
organization
}: {
serviceAccount: IServiceAccount;
organization: IOrganization;
}) => {
if (!serviceAccount.organization.equals(organization._id)) {
throw UnauthorizedRequestError({
message: 'Failed service account authorization for the given organization'
});
}
}
export {
validateClientForServiceAccount,
validateServiceAccountClientForWorkspace,
validateServiceAccountClientForSecrets,
validateServiceAccountClientForServiceAccount
validateServiceAccountClientForServiceAccount,
validateServiceAccountClientForOrganization
}
+32 -2
View File
@@ -5,7 +5,9 @@ import {
ISecret,
IServiceAccount,
User,
Membership
Membership,
IOrganization,
Organization,
} from '../models';
import { sendMail } from './nodemailer';
import { validateMembership } from './membership';
@@ -288,11 +290,39 @@ const validateUserClientForServiceAccount = async ({
}
}
/**
* Validate that user (client) can access organization [organization]
* @param {Object} obj
* @param {User} obj.user - user client
* @param {Organization} obj.organization - organization to validate against
*/
const validateUserClientForOrganization = async ({
user,
organization,
acceptedRoles,
acceptedStatuses
}: {
user: IUser;
organization: IOrganization;
acceptedRoles: Array<'owner' | 'admin' | 'member'>;
acceptedStatuses: Array<'invited' | 'accepted'>;
}) => {
const membershipOrg = await validateMembershipOrg({
userId: user._id,
organizationId: organization._id,
acceptedRoles,
acceptedStatuses
});
return membershipOrg;
}
export {
setupAccount,
completeAccount,
checkUserDevice,
validateUserClientForWorkspace,
validateUserClientForSecrets,
validateUserClientForServiceAccount
validateUserClientForServiceAccount,
validateUserClientForOrganization
};