Skip to content

Commit

Permalink
Parse tome paramdefs on startup (#298)
Browse files Browse the repository at this point in the history
* Set paramdefs on parse.

* Removes debug statements.

* Should fix tests

* Missed this one

* Updated UI.

* Yay this works.

* Remove debug statements.

* Remove debug.

* Rebuild UI.

* auto reformat paramdefs to a JSON string.

* Increase param def string size.

* Updated UI

* Add a non param example.

* Add default value to params

* Remove test.

* Rebuild ui.

* Remove test tome.

* Add test 3

* Remove example 3

* Try updating parameters too.

* Manually generated

* Switch back to entry name metadata name is complex

* Increase quest output drawer size (#306)

* Set paramdefs on parse.

* Removes debug statements.

* Should fix tests

* Missed this one

* Updated UI.

* Yay this works.

* Remove debug statements.

* Remove debug.

* Rebuild UI.

* auto reformat paramdefs to a JSON string.

* Increase param def string size.

* Updated UI

* Add a non param example.

* Add default value to params

* Remove test.

* Rebuild ui.

* Remove test tome.

* Add test 3

* Remove example 3

* Try updating parameters too.

* Manually generated

* Switch back to entry name metadata name is complex

* Update UI.
  • Loading branch information
hulto authored Oct 5, 2023
1 parent c70933e commit d29a4a0
Show file tree
Hide file tree
Showing 20 changed files with 86 additions and 30 deletions.
1 change: 1 addition & 0 deletions implants/imix/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ async fn main_loop(config_path: String, run_once: bool) -> Result<()> {
if debug { println!("[{}]: Starting {} new tasks", (Utc::now().time() - start_time).num_milliseconds(), new_tasks.len()); }
// 2. Start new tasks
for task in new_tasks {
if debug { println!("Parameters:\n{:?}", task.clone().quest.parameters); }
if debug { println!("Launching:\n{:?}", task.clone().quest.tome.eldritch); }

let (sender, receiver) = channel::<String>();
Expand Down
1 change: 0 additions & 1 deletion implants/lib/eldritch/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ pub fn eldritch_run(tome_filename: String, tome_contents: String, tome_parameter
};
input_params.insert_hashed(hashed_key, new_value);
}

module.set("input_params", input_params.alloc_value(module.heap()));

let mut eval: Evaluator = Evaluator::new(&module);
Expand Down
4 changes: 2 additions & 2 deletions tavern/internal/ent/migrate/schema.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions tavern/internal/ent/schema/quest.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package schema
import (
"entgo.io/contrib/entgql"
"entgo.io/ent"
"entgo.io/ent/dialect"
"entgo.io/ent/schema"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
Expand All @@ -23,6 +24,9 @@ func (Quest) Fields() []ent.Field {
).
Comment("Name of the quest"),
field.String("parameters").
SchemaType(map[string]string{
dialect.MySQL: "LONGTEXT", // Override MySQL, improve length maximum
}).
Optional().
Comment("Value of parameters that were specified for the quest (as a JSON string)."),
}
Expand Down
3 changes: 3 additions & 0 deletions tavern/internal/ent/schema/tome.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ func (Tome) Fields() []ent.Field {
Comment("Information about the tome"),
field.String("param_defs").
Optional().
SchemaType(map[string]string{
dialect.MySQL: "LONGTEXT", // Override MySQL, improve length maximum
}).
Comment("JSON string describing what parameters are used with the tome"),
field.String("hash").
MaxLen(100).
Expand Down
6 changes: 3 additions & 3 deletions tavern/internal/www/build/asset-manifest.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
{
"files": {
"main.css": "/static/css/main.d3a1f05a.css",
"main.js": "/static/js/main.d00b684e.js",
"main.js": "/static/js/main.dce5904d.js",
"static/js/787.4af0fb89.chunk.js": "/static/js/787.4af0fb89.chunk.js",
"static/media/eldrich.png": "/static/media/eldrich.a80c74e8249d2461e174.png",
"index.html": "/index.html",
"main.d3a1f05a.css.map": "/static/css/main.d3a1f05a.css.map",
"main.d00b684e.js.map": "/static/js/main.d00b684e.js.map",
"main.dce5904d.js.map": "/static/js/main.dce5904d.js.map",
"787.4af0fb89.chunk.js.map": "/static/js/787.4af0fb89.chunk.js.map"
},
"entrypoints": [
"static/css/main.d3a1f05a.css",
"static/js/main.d00b684e.js"
"static/js/main.dce5904d.js"
]
}
2 changes: 1 addition & 1 deletion tavern/internal/www/build/index.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>React App</title><script defer="defer" src="/static/js/main.d00b684e.js"></script><link href="/static/css/main.d3a1f05a.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>React App</title><script defer="defer" src="/static/js/main.dce5904d.js"></script><link href="/static/css/main.d3a1f05a.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
1 change: 0 additions & 1 deletion tavern/internal/www/build/static/js/main.d00b684e.js.map

This file was deleted.

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions tavern/internal/www/build/static/js/main.dce5904d.js.map

Large diffs are not rendered by default.

13 changes: 12 additions & 1 deletion tavern/internal/www/src/hooks/useSubmitQuest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,23 @@ export const useSubmitQuest = () => {
]});

const submitQuest = (props: CreateQuestProps) => {
var param_obj = {}
for (var param of props.params) {
var tmp_param = {
[param.name]: param.value
}
param_obj = {
...tmp_param,
...param_obj,
}
}
const formatVariables = {
"variables": {
"IDs": props.beacons,
"input": {
"name": props?.name,
"tomeID": props.tome?.id
"tomeID": props.tome?.id,
"parameters": JSON.stringify(param_obj),
}
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ const GET_TOMES = gql`
export const SelectTome = (props: Props) => {
const { loading, error, data } = useQuery(GET_TOMES);
const step = 0;
const {setCurrStep, formik} = props;
const { setCurrStep, formik } = props;

const handleSelectTome = (tome: Tome) => {
const { params } = safelyJsonParse(tome?.paramDefs);
formik.setFieldValue('tome', tome);
formik.setFieldValue('params', params);
formik.setFieldValue('params', params ? params : []);
}

const handleNameQuest = (name: string) => {
Expand All @@ -44,7 +44,7 @@ export const SelectTome = (props: Props) => {
// PARAMS SUBMITTED FOR CREATE QUEST FORMAT: JSON STRING Dict<string, string>: '{"blah": "some value"}'
// * This is what is submitted for creating a quest

const hasAllParamsSet = formik?.values?.params.filter( (param: TomeParams) => {
const hasAllParamsSet = formik?.values?.params.filter((param: TomeParams) => {
return param?.value && param?.value !== "";
});

Expand All @@ -59,16 +59,16 @@ export const SelectTome = (props: Props) => {
label="Quest name"
placeholder={"Provide a recognizable name to this quest"}
value={formik?.values?.name}
onChange={(event)=> handleNameQuest(event?.target?.value)}
onChange={(event) => handleNameQuest(event?.target?.value)}
/>

<FormRadioGroup
<FormRadioGroup
label="Select a tome"
data={data?.tomes || []}
selected={formik?.values?.tome}
setSelected={handleSelectTome}
/>
{formik?.values?.params.length > 0 && formik?.values?.params.map((field: TomeParams, index: number) => {
{formik?.values?.params.length > 0 && formik?.values?.params.map((field: TomeParams, index: number) => {
return (
<FormTextArea
key={field.name}
Expand All @@ -77,17 +77,17 @@ export const SelectTome = (props: Props) => {
formik={formik}
/>
);
})}
})}

<div className="flex flex-row gap-2">
<div className="flex flex-row gap-2">
<button
className="btn-primary"
onClick={() => setCurrStep(step +1)}
onClick={() => setCurrStep(step + 1)}
disabled={isContinueDisabled}
>
Continue
</button>
</div>
</div>
</div>
)
}
}
9 changes: 8 additions & 1 deletion tavern/internal/www/src/utils/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,17 @@ export type TagContextType = {
groupTags: Array<TomeTag>,
serviceTags: Array<TomeTag>
}
export type QuestParam = {
label: string,
name: string,
placeholder: string,
type: string,
value: string,
}
export type CreateQuestProps = {
name: string,
tome: Tome | null,
params: any,
params: Array<QuestParam>,
beacons: Array<string>,
};

Expand Down
1 change: 1 addition & 0 deletions tavern/tomes/example/linux/test-file
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This file exists
1 change: 0 additions & 1 deletion tavern/tomes/example/linux/test-implant

This file was deleted.

2 changes: 1 addition & 1 deletion tavern/tomes/example/main.eldritch
Original file line number Diff line number Diff line change
@@ -1 +1 @@
print("Hello World")
print(input_params['msg'])
7 changes: 6 additions & 1 deletion tavern/tomes/example/metadata.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
name: example
description: An example tome!
description: An example tome!
paramdefs:
- name: msg
label: Message
type: string
placeholder: Something to print
25 changes: 25 additions & 0 deletions tavern/tomes/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package tomes

import (
"context"
"encoding/json"
"fmt"
"io/fs"
"path/filepath"
Expand All @@ -12,7 +13,25 @@ import (
)

type tomeMetadata struct {
Name string
Description string
ParamDefs []interface{}
}

func convert_yaml_to_json(i interface{}) interface{} {
switch x := i.(type) {
case map[interface{}]interface{}:
m2 := map[string]interface{}{}
for k, v := range x {
m2[k.(string)] = convert_yaml_to_json(v)
}
return m2
case []interface{}:
for i, v := range x {
x[i] = convert_yaml_to_json(v)
}
}
return i
}

// UploadTomes traverses the provided filesystem and creates tomes using the provided graph.
Expand Down Expand Up @@ -92,10 +111,16 @@ func UploadTomes(ctx context.Context, graph *ent.Client, fileSystem fs.ReadDirFS
return rollback(tx, fmt.Errorf("failed to parse and upload tome %q: %w", entry.Name(), err))
}

jsonified_paramdefs, err := json.Marshal(convert_yaml_to_json(metadata.ParamDefs))
if err != nil {
return rollback(tx, fmt.Errorf("failed to prase param defs for %q: %w", metadata.Name, err))
}

// Create the tome
if _, err := graph.Tome.Create().
SetName(entry.Name()).
SetDescription(metadata.Description).
SetParamDefs(string(jsonified_paramdefs)).
SetEldritch(eldritch).
AddFiles(tomeFiles...).
Save(ctx); err != nil {
Expand Down
7 changes: 4 additions & 3 deletions tavern/tomes/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ func TestUploadTomes(t *testing.T) {
Where(tome.Name("example")).
OnlyX(ctx)
require.NotNil(t, testTome)
assert.Equal(t, `print("Hello World")`, testTome.Eldritch)
assert.Equal(t, `print(input_params['msg'])`, testTome.Eldritch)
assert.Equal(t, `An example tome!`, testTome.Description)
assert.Equal(t, `[{"label":"Message","name":"msg","placeholder":"Something to print","type":"string"}]`, testTome.ParamDefs)
testTomeFiles, err := testTome.Files(ctx)
assert.NoError(t, err)
assert.Len(t, testTomeFiles, 1)
assert.Equal(t, "example/linux/test-implant", testTomeFiles[0].Name)
assert.Equal(t, []byte("meowware"), testTomeFiles[0].Content)
assert.Equal(t, "example/linux/test-file", testTomeFiles[0].Name)
assert.Equal(t, []byte("This file exists "), testTomeFiles[0].Content)
}

0 comments on commit d29a4a0

Please sign in to comment.