Skip to content

Commit

Permalink
feat: extend precondition and contentType metadata to files in public…
Browse files Browse the repository at this point in the history
… directory (#185)

* feat: add metadata to object exposed in public directory

At the moment the onyl metadata that are present are precondition and contentType

* test: use ./public as public directory during tests

* test: precondition works also with files in public directory

* refactor: get slangroom istance in runPrecedontion function

* fix: do not show files whose path start with a dot

* test: hide precondtion keys and contract
  • Loading branch information
matteo-cristino authored Jun 3, 2024
1 parent b70558f commit 08c63da
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 17 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"dev": "nodemon -e ts -w ./src -x pnpm run watch -z ./contracts -p 3000",
"watch": "node --loader ts-node/esm src/index.ts",
"test": "pnpm e2e && jest",
"start": "node --loader ts-node/esm src/index.ts -z ./tests/fixtures -p 3000",
"start": "node --loader ts-node/esm src/index.ts -z ./tests/fixtures -p 3000 --public-directory ./public",
"e2e": "start-server-and-test http-get://0.0.0.0:3000 'pnpm stepci run ./tests/workflow.stepci.yml'"
},
"engines": {
Expand Down
3 changes: 3 additions & 0 deletions public/.hello_world.keys.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"check_for_query_param": "hello"
}
6 changes: 6 additions & 0 deletions public/.hello_world.slang
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Given I have a 'string' named 'query_param'
and I have a 'string' named 'check_for_query_param'

When I verify 'query_param' is equal to 'check_for_query_param'

Then print the data
8 changes: 8 additions & 0 deletions public/hello_world
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<html>
<head>
<title>Benvenuto</title>
</head>
<body>
<div align="center">Hello World!</div>
</body>
</html>
4 changes: 4 additions & 0 deletions public/hello_world.metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"contentType": "text/html",
"precondition": ".hello_world"
}
50 changes: 35 additions & 15 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
openapiTemplate
} from './openapi.js';
import { SlangroomManager } from './slangroom.js';
import { getSchema, validateData } from './utils.js';
import { getSchema, validateData, getQueryParams } from './utils.js';
import { readFileContent, readJsonObject } from './fileUtils.js';
import { execute as slangroomChainExecute } from '@dyne/slangroom-chain';
dotenv.config();
Expand Down Expand Up @@ -148,6 +148,14 @@ Then print the 'result'
return app;
};

const runPrecondition = async (preconditionPath: string, data: Record<string, any>) => {
const s = SlangroomManager.getInstance();
const zen = fs.readFileSync(preconditionPath+".slang").toString();
const keys = fs.existsSync(preconditionPath+".keys.json") ?
JSON.parse(fs.readFileSync(preconditionPath+".keys.json")) : null;
await s.execute(zen, {data, keys});
};

Dir.ready(async () => {
let listen_socket: us_listen_socket;

Expand All @@ -159,10 +167,32 @@ Dir.ready(async () => {

const { publicDirectory } = config;
if (publicDirectory) {
app.get('/*', (res, req) => {
app.get('/*', async (res, req) => {
if (req.getUrl().replace(/^\/+/g, '/').startsWith('/.')) return res.writeStatus('404 Not Found').end('Not found');
let file = path.join(publicDirectory, req.getUrl());
if (fs.existsSync(file)) {
const contentType = mime.getType(file) || 'application/json';
let contentType = mime.getType(file) || 'application/json';
if(fs.existsSync(file+'.metadata.json')) {
let publicMetadata
try {
publicMetadata = JSON.parse(fs.readFileSync(file+'.metadata.json'));
} catch (e) {
L.fatal(e);
res.writeStatus('422 UNPROCESSABLE ENTITY').end('Malformed metadata file');
return;
}
if(publicMetadata.contentType) contentType = publicMetadata.contentType
if(publicMetadata.precondition) {
try{
const data: Record<string, any> = getQueryParams(req);
await runPrecondition(path.join(publicDirectory, publicMetadata.precondition), data);
} catch(e) {
L.fatal(e);
res.writeStatus('403 FORBIDDEN').end()
return;
}
}
}
res.writeHeader('Access-Control-Allow-Origin', '*')
.writeHeader('Content-Type', contentType);
res.end(fs.readFileSync(file));
Expand Down Expand Up @@ -263,11 +293,8 @@ const generateRoutes = (app: TemplatedApp) => {
}
}
if (metadata.precondition) {
const zen = await readFileContent(metadata.precondition+".slang");
const keys = fs.existsSync(metadata.precondition+".keys.json") ?
await readJsonObject(metadata.precondition+".keys.json") : null;
try {
await s.execute(zen, {data, keys});
await runPrecondition(metadata.precondition, data);
} catch (e) {
LOG.fatal(e);
res.writeStatus('403 FORBIDDEN').end((e as Error).message)
Expand Down Expand Up @@ -411,14 +438,7 @@ const generateRoutes = (app: TemplatedApp) => {
});

try {
const data: Record<string, unknown> = {};
const q = req.getQuery();
if (q) {
q.split('&').map((r) => {
const [k, v] = r.split('=');
data[k] = v;
});
}
const data: Record<string, unknown> = getQueryParams(req);
execZencodeAndReply(res, data, headers);
} catch (e) {
LOG.fatal(e);
Expand Down
12 changes: 12 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,15 @@ function createAjv(): Ajv {
addFormats.default(ajv);
return ajv;
}

export const getQueryParams = (req): Record<string, unknown> => {
const data: Record<string, unknown> = {};
const q = req.getQuery();
if (q) {
q.split('&').map((r) => {
const [k, v] = r.split('=');
data[k] = v;
});
}
return data;
}
22 changes: 21 additions & 1 deletion tests/workflow.stepci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ tests:
method: GET
check:
status: 404
body: <html><body><h1>File Not Found</h1><hr><i>uWebSockets/20 Server</i></body></html>
body: Not found

broken:
steps:
Expand Down Expand Up @@ -382,3 +382,23 @@ tests:
status: 200
json:
say_hi: hello

public_dir:
steps:
- name: public with wrong precondition
http:
url: http://${{env.host}}/hello_world?query_param=wrong_param
method: GET
check:
status: 403
- name: public with right precondition
http:
url: http://${{env.host}}/hello_world?query_param=hello
method: GET
check:
status: 200
selctors:
title: Benvenuto
body: Hello World!
headers:
Content-Type: text/html

0 comments on commit 08c63da

Please sign in to comment.