allow service tokens to continue to support overrides

This commit is contained in:
Maidul Islam
2023-04-12 11:59:41 -07:00
parent c7a402c4cb
commit e2c67ffbef
+52 -50
View File
@@ -550,7 +550,10 @@ export const getSecrets = async (req: Request, res: Response) => {
const workspaceId = req.query.workspaceId as string; const workspaceId = req.query.workspaceId as string;
const environment = req.query.environment as string; const environment = req.query.environment as string;
// tags logic // secrets to return
let secrets: ISecret[] = [];
// query tags table to get all tags ids for the tag names for the given workspace
let tagIds = []; let tagIds = [];
const tagNamesList = typeof tagSlugs === 'string' && tagSlugs !== '' ? tagSlugs.split(',') : []; const tagNamesList = typeof tagSlugs === 'string' && tagSlugs !== '' ? tagSlugs.split(',') : [];
if (tagNamesList != undefined && tagNamesList.length != 0) { if (tagNamesList != undefined && tagNamesList.length != 0) {
@@ -561,71 +564,70 @@ export const getSecrets = async (req: Request, res: Response) => {
}); });
} }
let secrets: ISecret[] = [];
if (req.user) { if (req.user) {
// case: client authorization is via JWT // case: client authorization is via JWT
const hasWriteOnlyAccess = await userHasWriteOnlyAbility(req.user._id, new Types.ObjectId(workspaceId), environment)
let hasWriteOnlyAccess const hasNoAccess = await userHasNoAbility(req.user._id, new Types.ObjectId(workspaceId), environment)
if (!req.serviceTokenData) { if (hasNoAccess) {
hasWriteOnlyAccess = await userHasWriteOnlyAbility(req.user._id, new Types.ObjectId(workspaceId), environment) throw UnauthorizedRequestError({ message: "You do not have the necessary permission(s) perform this action" })
const hasNoAccess = await userHasNoAbility(req.user._id, new Types.ObjectId(workspaceId), environment)
if (hasNoAccess) {
throw UnauthorizedRequestError({ message: "You do not have the necessary permission(s) perform this action" })
}
} }
let secretQuery: any; const secretQuery: any = {
if (tagNamesList != undefined && tagNamesList.length != 0) { workspace: workspaceId,
const workspaceFromDB = await Tag.find({ workspace: workspaceId }) environment,
$or: [
{ user: req.user._id }, // personal secrets for this user
{ user: { $exists: false } } // shared secrets from workspace
]
}
const tagIds = _.map(tagNamesList, (tagName) => { if (tagIds.length > 0) {
const tag = _.find(workspaceFromDB, { slug: tagName }); secretQuery.tags = { $in: tagIds };
return tag ? tag.id : null;
});
secretQuery = {
workspace: workspaceId,
environment,
$or: [
{ user: req.user._id },
{ user: { $exists: false } }
],
tags: { $in: tagIds },
type: { $in: [SECRET_SHARED, SECRET_PERSONAL] }
}
} else {
secretQuery = {
workspace: workspaceId,
environment,
$or: [
{ user: req.user._id },
{ user: { $exists: false } }
],
type: { $in: [SECRET_SHARED, SECRET_PERSONAL] }
}
} }
if (hasWriteOnlyAccess) { if (hasWriteOnlyAccess) {
// (i.e. you don't get values to decrypt since you can only write) // only return the secret keys and not the values since user does not have right to see values
secrets = await Secret.find(secretQuery).select("secretKeyCiphertext secretKeyIV secretKeyTag").populate("tags") secrets = await Secret.find(secretQuery).select("secretKeyCiphertext secretKeyIV secretKeyTag").populate("tags")
} else { } else {
secrets = await Secret.find(secretQuery).populate("tags") secrets = await Secret.find(secretQuery).populate("tags")
} }
} }
if (req.serviceAccount || req.serviceTokenData) { // case: client authorization is via service token
// case: client authorization is either via service account or service token if (req.serviceTokenData) {
const userId = req.serviceTokenData.user._id
secrets = await Secret.find({ const secretQuery: any = {
workspace: new Types.ObjectId(workspaceId), workspace: workspaceId,
environment, environment,
user: { $or: [
$exists: false { user: userId }, // personal secrets for this user
}, { user: { $exists: false } } // shared secrets from workspace
...(tagIds.length > 0 ? { tags: { $in: tagIds } } : {}), ]
type: SECRET_SHARED }
}).populate("tags");
if (tagIds.length > 0) {
secretQuery.tags = { $in: tagIds };
}
// TODO check if service token has write only permission
secrets = await Secret.find(secretQuery).populate("tags");
}
// case: client authorization is via service account
if (req.serviceAccount) {
const secretQuery: any = {
workspace: workspaceId,
environment,
user: { $exists: false } // shared secrets only from workspace
}
if (tagIds.length > 0) {
secretQuery.tags = { $in: tagIds };
}
secrets = await Secret.find(secretQuery).populate("tags");
} }
const channel = getChannelFromUserAgent(req.headers['user-agent']) const channel = getChannelFromUserAgent(req.headers['user-agent'])