mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat(secret-ref): removed migration field unset op, refactored service token scope check to a utility fn
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import { Types } from "mongoose";
|
||||
import { Request, Response } from "express";
|
||||
import picomatch from "picomatch";
|
||||
import { ISecret, Secret, ServiceTokenData } from "../../models";
|
||||
import { IAction, SecretVersion } from "../../ee/models";
|
||||
import {
|
||||
@@ -33,6 +32,7 @@ import {
|
||||
getFolderIdFromServiceToken,
|
||||
searchByFolderId
|
||||
} from "../../services/FolderService";
|
||||
import { isValidScope } from "../../helpers/secrets";
|
||||
|
||||
/**
|
||||
* Peform a batch of any specified CUD secret operations
|
||||
@@ -74,16 +74,11 @@ export const batchSecrets = async (req: Request, res: Response) => {
|
||||
}
|
||||
|
||||
if (req.authData.authPayload instanceof ServiceTokenData) {
|
||||
const { scopes: tkScopes } = req.authData.authPayload;
|
||||
const validScope = tkScopes.find(
|
||||
(scope) =>
|
||||
picomatch.isMatch(secretPath, scope.secretPath, { strictSlashes: false }) &&
|
||||
scope.environment === environment
|
||||
);
|
||||
const isValidScopeAccess = isValidScope(req.authData.authPayload, environment, secretPath);
|
||||
|
||||
// in service token when not giving secretpath folderid must be root
|
||||
// this is to avoid giving folderid when service tokens are used
|
||||
if ((!secretPath && folderId !== "root") || (secretPath && !validScope)) {
|
||||
if ((!secretPath && folderId !== "root") || (secretPath && !isValidScopeAccess)) {
|
||||
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
||||
}
|
||||
}
|
||||
@@ -447,16 +442,15 @@ export const createSecrets = async (req: Request, res: Response) => {
|
||||
}
|
||||
|
||||
if (req.authData.authPayload instanceof ServiceTokenData) {
|
||||
const { scopes: tkScopes } = req.authData.authPayload;
|
||||
const validScope = tkScopes.find(
|
||||
(scope) =>
|
||||
picomatch.isMatch(secretPath || "/", scope.secretPath, { strictSlashes: false }) &&
|
||||
scope.environment === environment
|
||||
const isValidScopeAccess = isValidScope(
|
||||
req.authData.authPayload,
|
||||
environment,
|
||||
secretPath || "/"
|
||||
);
|
||||
|
||||
// in service token when not giving secretpath folderid must be root
|
||||
// this is to avoid giving folderid when service tokens are used
|
||||
if ((!secretPath && folderId !== "root") || (secretPath && !validScope)) {
|
||||
if ((!secretPath && folderId !== "root") || (secretPath && !isValidScopeAccess)) {
|
||||
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
||||
}
|
||||
}
|
||||
@@ -704,17 +698,15 @@ export const getSecrets = async (req: Request, res: Response) => {
|
||||
}
|
||||
|
||||
if (req.authData.authPayload instanceof ServiceTokenData) {
|
||||
const { scopes: tkScopes } = req.authData.authPayload;
|
||||
const validScope = tkScopes.find(
|
||||
(scope) =>
|
||||
picomatch.isMatch((secretPath as string) || "/", scope.secretPath, {
|
||||
strictSlashes: false
|
||||
}) && scope.environment === environment
|
||||
const isValidScopeAccess = isValidScope(
|
||||
req.authData.authPayload,
|
||||
environment,
|
||||
(secretPath as string) || "/"
|
||||
);
|
||||
|
||||
// in service token when not giving secretpath folderid must be root
|
||||
// this is to avoid giving folderid when service tokens are used
|
||||
if ((!secretPath && folderId !== "root") || (secretPath && !validScope)) {
|
||||
if ((!secretPath && folderId !== "root") || (secretPath && !isValidScopeAccess)) {
|
||||
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,13 @@ import {
|
||||
GetSecretsParams,
|
||||
UpdateSecretParams
|
||||
} from "../interfaces/services/SecretService";
|
||||
import { ISecret, Secret, SecretBlindIndexData, ServiceTokenData } from "../models";
|
||||
import {
|
||||
ISecret,
|
||||
IServiceTokenData,
|
||||
Secret,
|
||||
SecretBlindIndexData,
|
||||
ServiceTokenData
|
||||
} from "../models";
|
||||
import { SecretVersion } from "../ee/models";
|
||||
import {
|
||||
BadRequestError,
|
||||
@@ -39,6 +45,21 @@ import { getAuthDataPayloadIdObj, getAuthDataPayloadUserObj } from "../utils/aut
|
||||
import { getFolderIdFromServiceToken } from "../services/FolderService";
|
||||
import picomatch from "picomatch";
|
||||
|
||||
export const isValidScope = (
|
||||
authPayload: IServiceTokenData,
|
||||
environment: string,
|
||||
secretPath: string
|
||||
) => {
|
||||
const { scopes: tkScopes } = authPayload;
|
||||
const validScope = tkScopes.find(
|
||||
(scope) =>
|
||||
picomatch.isMatch(secretPath, scope.secretPath, { strictSlashes: false }) &&
|
||||
scope.environment === environment
|
||||
);
|
||||
|
||||
return Boolean(validScope);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns an object containing secret [secret] but with its value, key, comment decrypted.
|
||||
*
|
||||
@@ -306,14 +327,7 @@ export const createSecretHelper = async ({
|
||||
|
||||
// if using service token filter towards the folderId by secretpath
|
||||
if (authData.authPayload instanceof ServiceTokenData) {
|
||||
const { scopes: tkScopes } = authData.authPayload;
|
||||
const validScope = tkScopes.find(
|
||||
(scope) =>
|
||||
picomatch.isMatch(secretPath, scope.secretPath, { strictSlashes: false }) &&
|
||||
scope.environment === environment
|
||||
);
|
||||
|
||||
if (!validScope) {
|
||||
if (!isValidScope(authData.authPayload, environment, secretPath)) {
|
||||
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
||||
}
|
||||
}
|
||||
@@ -459,14 +473,7 @@ export const getSecretsHelper = async ({
|
||||
let secrets: ISecret[] = [];
|
||||
// if using service token filter towards the folderId by secretpath
|
||||
if (authData.authPayload instanceof ServiceTokenData) {
|
||||
const { scopes: tkScopes } = authData.authPayload;
|
||||
const validScope = tkScopes.find(
|
||||
(scope) =>
|
||||
picomatch.isMatch(secretPath, scope.secretPath, { strictSlashes: false }) &&
|
||||
scope.environment === environment
|
||||
);
|
||||
|
||||
if (!validScope) {
|
||||
if (!isValidScope(authData.authPayload, environment, secretPath)) {
|
||||
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
||||
}
|
||||
}
|
||||
@@ -562,14 +569,7 @@ export const getSecretHelper = async ({
|
||||
let secret: ISecret | null = null;
|
||||
// if using service token filter towards the folderId by secretpath
|
||||
if (authData.authPayload instanceof ServiceTokenData) {
|
||||
const { scopes: tkScopes } = authData.authPayload;
|
||||
const validScope = tkScopes.find(
|
||||
(scope) =>
|
||||
picomatch.isMatch(secretPath, scope.secretPath, { strictSlashes: false }) &&
|
||||
scope.environment === environment
|
||||
);
|
||||
|
||||
if (!validScope) {
|
||||
if (!isValidScope(authData.authPayload, environment, secretPath)) {
|
||||
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
||||
}
|
||||
}
|
||||
@@ -671,14 +671,7 @@ export const updateSecretHelper = async ({
|
||||
let secret: ISecret | null = null;
|
||||
// if using service token filter towards the folderId by secretpath
|
||||
if (authData.authPayload instanceof ServiceTokenData) {
|
||||
const { scopes: tkScopes } = authData.authPayload;
|
||||
const validScope = tkScopes.find(
|
||||
(scope) =>
|
||||
picomatch.isMatch(secretPath, scope.secretPath, { strictSlashes: false }) &&
|
||||
scope.environment === environment
|
||||
);
|
||||
|
||||
if (!validScope) {
|
||||
if (!isValidScope(authData.authPayload, environment, secretPath)) {
|
||||
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
||||
}
|
||||
}
|
||||
@@ -826,14 +819,7 @@ export const deleteSecretHelper = async ({
|
||||
|
||||
// if using service token filter towards the folderId by secretpath
|
||||
if (authData.authPayload instanceof ServiceTokenData) {
|
||||
const { scopes: tkScopes } = authData.authPayload;
|
||||
const validScope = tkScopes.find(
|
||||
(scope) =>
|
||||
picomatch.isMatch(secretPath, scope.secretPath, { strictSlashes: false }) &&
|
||||
scope.environment === environment
|
||||
);
|
||||
|
||||
if (!validScope) {
|
||||
if (!isValidScope(authData.authPayload, environment, secretPath)) {
|
||||
throw UnauthorizedRequestError({ message: "Folder Permission Denied" });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,9 +446,6 @@ export const backfillServiceTokenMultiScope = async () => {
|
||||
$set: {
|
||||
scopes: [{ environment: "$environment", secretPath: "$secretPath" }]
|
||||
}
|
||||
},
|
||||
{
|
||||
$unset: ["environment", "secretPath"]
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
@@ -292,7 +292,11 @@ func recursivelyExpandSecret(expandedSecs map[string]string, interpolatedSecs ma
|
||||
return v
|
||||
}
|
||||
|
||||
interpolatedVal := interpolatedSecs[key]
|
||||
interpolatedVal, ok := interpolatedSecs[key]
|
||||
if !ok {
|
||||
HandleError(fmt.Errorf("Could not find refered secret - %s", key), "Kindly check whether its provided")
|
||||
}
|
||||
|
||||
refs := secRefRegex.FindAllStringSubmatch(interpolatedVal, -1)
|
||||
for _, val := range refs {
|
||||
// key: "${something}" val: [${something},something]
|
||||
|
||||
Reference in New Issue
Block a user