Skip to content

Commit

Permalink
Merge pull request #85 from solaoi/feature_add-some-features
Browse files Browse the repository at this point in the history
Feature add some features
  • Loading branch information
solaoi committed May 9, 2022
2 parents 650d9ff + 4f0bff4 commit b8688aa
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 35 deletions.
2 changes: 1 addition & 1 deletion README.ja.md
Expand Up @@ -72,7 +72,7 @@ brew upgrade tuna
```sh
# wget または curl でインストール
## releasesタブの最新のバージョンを指定してください。
VERSION=v0.0.17
VERSION=v0.0.19
## 利用OSを指定してください。
OS=linux_amd64
## wget経由の場合
Expand Down
48 changes: 28 additions & 20 deletions README.md
Expand Up @@ -18,25 +18,33 @@ TUNA-Mayonnaise is a CommandLineTool to generate and serve JSON/HTML on the node
<details>
<summary>CLICK</summary>

- [Why](#why)
- [Get Started](#get-started)
- [Install](#install)
- [Usage](#usage)
- [Tool Features](#tool-features)
- [Template Engine](#template-engine)
- [API](#api)
- [Database](#database)
- [API Features](#api-features)
- [Monitoring](#monitoring)
- [UseCases](#usecases)
- [1. Serve Static JSON](#1-serve-static-json)
- [2. Serve Static HTML](#2-serve-static-html)
- [3. Serve Dynamic JSON](#3-serve-dynamic-json)
- [4. Serve Dynamic HTML](#4-serve-dynamic-html)
- [Dependencies](#dependencies)
- [BACKEND Dependencies](#backend-dependencies)
- [FRONTEND Dependencies](#frontend-dependencies)
- [FRONTEND DEV Dependencies](#frontend-dev-dependencies)
- [!tuna-mayonnaise](#)
- [Table of Contents](#table-of-contents)
- [Why](#why)
- [Get Started](#get-started)
- [Install](#install)
- [For MacOS (Homebrew)](#for-macos-homebrew)
- [For Others (Binary Releases)](#for-others-binary-releases)
- [Usage](#usage)
- [1. Launch a tool on your browser](#1-launch-a-tool-on-your-browser)
- [2. Serve your JSON/HTML](#2-serve-your-jsonhtml)
- [Tool Features](#tool-features)
- [Template Engine](#template-engine)
- [API](#api)
- [Database](#database)
- [Connection Options](#connection-options)
- [TLS / SSL](#tls--ssl)
- [API Features](#api-features)
- [Monitoring](#monitoring)
- [UseCases](#usecases)
- [1. Serve Static JSON](#1-serve-static-json)
- [2. Serve Static HTML](#2-serve-static-html)
- [3. Serve Dynamic JSON](#3-serve-dynamic-json)
- [4. Serve Dynamic HTML](#4-serve-dynamic-html)
- [Dependencies](#dependencies)
- [BACKEND Dependencies](#backend-dependencies)
- [FRONTEND Dependencies](#frontend-dependencies)
- [FRONTEND DEV Dependencies](#frontend-dev-dependencies)

</details>
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
Expand Down Expand Up @@ -74,7 +82,7 @@ you can download a binary release [here](https://github.com/solaoi/tuna-mayonnai
```sh
# Install with wget or curl
## set the latest version on releases.
VERSION=v0.0.17
VERSION=v0.0.19
## set the OS you use.
OS=linux
## case you use wget
Expand Down
48 changes: 46 additions & 2 deletions command/cmd/api.go
Expand Up @@ -117,6 +117,21 @@ func isJSONorHTMLNode(name string) bool {
return isJSONNode(name) || name == "Template"
}

func isSQLInjectionParams(value string) bool {
regs := [...] *regexp.Regexp {
regexp.MustCompile(`(%27)|(')|(--)|(%23)|(#)`),
regexp.MustCompile(`((%3D)|(=))[^\n]*((%27)|(')|(--)|(%3B)|(;))`),
regexp.MustCompile(`w*((%27)|('))((%6F)|o|(%4F))((%72)|r|(%52))`),
regexp.MustCompile(`((%27)|('))union`),
}
val := strings.ToLower(value)
for _, reg := range regs {
isSQLInjection := reg.MatchString(val)
if isSQLInjection {return true}
}
return false
}

func endpointHandler(c echo.Context) error {
return c.Blob(http.StatusOK, staticEndpoints[c.Path()].ContentType, []byte(staticEndpoints[c.Path()].Content))
}
Expand Down Expand Up @@ -303,13 +318,42 @@ func contentBuilder(contents map[int]map[string]map[string]interface{}) func(req
tmp := map[string]string{}
err := json.Unmarshal([]byte(pathParams), &tmp)
if err != nil {
log.Fatal(err)
return body{http.StatusBadRequest, "", []apiResponse{}}
}
for k, v := range tmp {
unformattedURL = strings.ReplaceAll(unformattedURL, ":"+k, v)
}
}
c[i][k]["content"] = unformattedURL
} else if v["name"] == "SqlWithPlaceHolder" {
unformattedSQL := v["content"].(string)
placeHolderParams := ""
for _, v1 := range c[i+1] {
if v1["parent"] == k {
placeHolderParams = v1["content"].(string)
}
}
if placeHolderParams != "" {
tmp := map[string]string{}
err := json.Unmarshal([]byte(placeHolderParams), &tmp)
dbType := "Common"
if err != nil {
if reqDBCounter != nil {
reqDBCounter.WithLabelValues(dbType, err.Error()).Inc()
}
return body{http.StatusBadRequest, "", []apiResponse{}}
}
for k, v := range tmp {
if (isSQLInjectionParams(v)){
if reqDBCounter != nil {
reqDBCounter.WithLabelValues(dbType, "Reject SQL Injection: " + v).Inc()
}
return body{http.StatusBadRequest, "", []apiResponse{}}
}
unformattedSQL = strings.ReplaceAll(unformattedSQL, "${"+k+"}", v)
}
}
c[i][k]["content"] = unformattedSQL
} else if v["name"] == "Request" {
content := v["content"].(map[string]interface{})
requestType := fmt.Sprintf("%v", content["type"])
Expand Down Expand Up @@ -368,7 +412,7 @@ func contentBuilder(contents map[int]map[string]map[string]interface{}) func(req
dummyJSON := ""
for _, v1 := range c[i+1] {
if v1["parent"] == k {
if v1["name"] == "SQL" {
if v1["name"] == "SQL" || v1["name"] == "SqlWithPlaceHolder" {
query = v1["content"].(string)
} else if v1["name"] == "DummyJSON" {
dummyJSON = v1["content"].(string)
Expand Down
2 changes: 2 additions & 0 deletions ui/src/rete.jsx
Expand Up @@ -17,6 +17,7 @@ import { UrlComponent } from "./rete/components/input/UrlComponent";
import { UrlWithPathParamComponent } from "./rete/components/input/UrlWithPathParamComponent";
import { HtmlComponent } from "./rete/components/input/HtmlComponent";
import { SqlComponent } from "./rete/components/input/SqlComponent";
import { SqlWithPlaceHolderComponent } from "./rete/components/input/SqlWithPlaceHolderComponent";
import { TemplateComponent } from "./rete/components/template/TemplateComponent";
import { HandlebarsComponent } from "./rete/components/template/HandlebarsComponent";
import { PugComponent } from "./rete/components/template/PugComponent";
Expand Down Expand Up @@ -77,6 +78,7 @@ export async function createEditor(container) {
new HandlebarsComponent(handlebarsSocket),
new PugComponent(pugSocket),
new SqlComponent(sqlSocket),
new SqlWithPlaceHolderComponent(sqlSocket, jsonSocket),
new ApiComponent(jsonSocket, dummyJsonSocket, urlSocket),
new MySQLComponent(jsonSocket, dummyJsonSocket, sqlSocket),
new PostgreSQLComponent(jsonSocket, dummyJsonSocket, sqlSocket),
Expand Down
31 changes: 31 additions & 0 deletions ui/src/rete/components/input/SqlWithPlaceHolderComponent.js
@@ -0,0 +1,31 @@
import Rete from "rete";
import { SqlControl } from "../../controls/SqlControl";

export class SqlWithPlaceHolderComponent extends Rete.Component {
path = ["New"];

constructor(socket, jsonSocket) {
super("SqlWithPlaceHolder");
this.socket = socket;
this.jsonSocket = jsonSocket;
}

builder(node) {
const input = new Rete.Input(
"placeHolderParams",
"placeHolderParams (JSON)",
this.jsonSocket
);
const out = new Rete.Output("sql", "SQL", this.socket);

return node
.addInput(input)
.addControl(new SqlControl(this.editor, "sql", node))
.addOutput(out);
}

worker(node, _, outputs) {
outputs.sql = node.data.sql;
outputs.placeHolderParams = node.data.placeHolderParams;
}
}
3 changes: 2 additions & 1 deletion ui/src/rete/controls/EditableSqlComponent.jsx
Expand Up @@ -22,7 +22,8 @@ export const EditableSqlComponent = ({ value, onChange }) => {
value={code}
onValueChange={(c) => {
try {
parser.parse(c);
const replacedForPlaceHolder = c.replaceAll(/\$\{.*?\}/g, "dummy");
parser.parse(replacedForPlaceHolder);
setWarn(false);
setStack(null);
} catch (e) {
Expand Down
17 changes: 6 additions & 11 deletions ui/src/rete/controls/EndpointControl.jsx
Expand Up @@ -7,17 +7,12 @@ export class EndpointControl extends Rete.Control {
Preview
</label>
{contentType === "text/html; charset=utf-8" ? (
<div
className="hasScrollbar"
style={{
backgroundColor: "white",
overflowY: "auto",
maxHeight: "500px",
}}
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{
__html: value,
}}
<iframe
style={{ backgroundColor: "white" }}
title="preview"
srcDoc={value}
width={600}
height={400}
/>
) : (
<textarea
Expand Down

0 comments on commit b8688aa

Please sign in to comment.