Skip to content

Commit

Permalink
Setting validation for transform APIs (#1191)
Browse files Browse the repository at this point in the history
* Enabling validation for transform APIs

Signed-off-by: Kshitij Tandon <tandonks@amazon.com>

* Updating snap files

Signed-off-by: Kshitij Tandon <tandonks@amazon.com>

* Reverting some of the updated snap files from previous commit

Signed-off-by: Kshitij Tandon <tandonks@amazon.com>

* Reverting some changes to test workflows

Signed-off-by: Kshitij Tandon <tandonks@amazon.com>

* Change workflows java version to 21 from 11

Signed-off-by: Kshitij Tandon <tandonks@amazon.com>

* Reverting some changes done just to test the workflows

Signed-off-by: Kshitij Tandon <tandonks@amazon.com>

* Updating vaidation rules and tests

Signed-off-by: Kshitij Tandon <tandonks@amazon.com>

* Fixing an issue with API validation

Signed-off-by: Kshitij Tandon <tandonks@amazon.com>

---------

Signed-off-by: Kshitij Tandon <tandonks@amazon.com>
  • Loading branch information
tandonks authored Oct 28, 2024
1 parent 66abae3 commit fd0e765
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cypress-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
uses: actions/setup-java@v1
with:
# TODO: Parse this from index management plugin
java-version: 11
java-version: 21
- name: Checkout index management
uses: actions/checkout@v2
with:
Expand Down
63 changes: 59 additions & 4 deletions server/routes/transforms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,27 @@ export default function (services: NodeServices, router: IRouter, dataSourceEnab
path: `${NODE_API._SEARCH_SAMPLE_DATA}/{index}`,
validate: {
params: schema.object({
index: schema.string(),
index: schema.string({
validate: (value) => {
const invalidCharactersPattern = /[\s,:\"*+\/\\|?#><]/;
if (value !== value.toLowerCase() || value.startsWith("_") || value.startsWith("-") || invalidCharactersPattern.test(value)) {
return "Invalid index name.";
}

return undefined;
},
}),
}),
query: schema.object({
from: schema.number(),
size: schema.number(),
...(dataSourceEnabled ? { dataSourceId: schema.string() } : {}),
...(dataSourceEnabled
? {
dataSourceId: schema.string({
maxLength: 100000,
}),
}
: {}),
}),
body: schema.any(),
},
Expand All @@ -129,10 +144,50 @@ export default function (services: NodeServices, router: IRouter, dataSourceEnab
path: `${NODE_API.TRANSFORMS}/_preview`,
validate: {
body: schema.object({
transform: schema.any(),
transform: schema.object(
{
source_index: schema.string({
validate: (value) => {
const invalidCharactersPattern = /[\s,:\"*+\/\\|?#><]/;
if (
value !== value.toLowerCase() ||
value.startsWith("_") ||
value.startsWith("-") ||
invalidCharactersPattern.test(value)
) {
return "Invalid index name.";
}

return undefined;
},
}),
target_index: schema.string({
validate: (value) => {
const invalidCharactersPattern = /[\s,:\"*+\/\\|?#><]/;
if (
value !== value.toLowerCase() ||
value.startsWith("_") ||
value.startsWith("-") ||
invalidCharactersPattern.test(value)
) {
return "Invalid index name.";
}

return undefined;
},
}),
},
{ unknowns: "allow" }
),
}),
query: schema.object({
...(dataSourceEnabled ? { dataSourceId: schema.string() } : {}),
...(dataSourceEnabled
? {
dataSourceId: schema.string({
maxLength: 100000,
}),
}
: {}),
}),
},
},
Expand Down
56 changes: 56 additions & 0 deletions server/services/TransformService.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { schema } from "@osd/config-schema";

describe("Index Name Validation", () => {
const validateSchema = schema.object({
indexName: schema.string({
validate: (value) => {
const invalidCharactersPattern = /[\s,:\"*+\/\\|?#><]/;
if (value !== value.toLowerCase() || value.startsWith("_") || value.startsWith("-") || invalidCharactersPattern.test(value)) {
return "Invalid index name.";
}

return undefined;
},
}),
dataSourceId: schema.maybe(schema.string()),
});

const validateQuery = (indexName: string) => {
try {
validateSchema.validate({ indexName });
return undefined;
} catch (e) {
return e.message;
}
};

it("should fail validation for index names with uppercase letters", () => {
const errorMessage = validateQuery("IndexNameWithUppercase");
expect(errorMessage).toBe("[indexName]: Invalid index name.");
});

it("should fail validation for index names starting with an underscore", () => {
const errorMessage = validateQuery("_indexname");
expect(errorMessage).toBe("[indexName]: Invalid index name.");
});

it("should fail validation for index names starting with a hyphen", () => {
const errorMessage = validateQuery("-indexname");
expect(errorMessage).toBe("[indexName]: Invalid index name.");
});

it("should fail validation for index names containing invalid characters", () => {
const errorMessage = validateQuery("********************************");
expect(errorMessage).toBe("[indexName]: Invalid index name.");
});

it("should pass validation for valid index names", () => {
const errorMessage = validateQuery("valid_index-name123");
expect(errorMessage).toBeUndefined();
});

it("should fail validation for index names containing spaces", () => {
const errorMessage = validateQuery("invalid index");
expect(errorMessage).toBe("[indexName]: Invalid index name.");
});
});
2 changes: 1 addition & 1 deletion server/services/TransformService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ export default class TransformService extends MDSEnabledClientService {
},
});
} catch (err) {
if (err.statusCode === 404 && err.body.error.type === "index_not_found_exception") {
if (err.statusCode === 404 && err.body?.error?.type === "index_not_found_exception") {
return response.custom({
statusCode: 200,
body: {
Expand Down

0 comments on commit fd0e765

Please sign in to comment.