diff --git a/.gitignore b/.gitignore index 0aa56849..5bebe49f 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,9 @@ backend/go-app/generated* functions/generated_apps *.zip +*openapi-parsers/generated/* +*openapi-parsers/other/* + backend/onprem/app_sdk/apps *test.py diff --git a/backend/Dockerfile b/backend/Dockerfile index a7a0de05..14d9137c 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -11,6 +11,11 @@ ADD ./go-app/codegen.go /app ADD ./go-app/go.mod /app +# Required files for code generation +ADD ./app_sdk/app_base.py /app_sdk +ADD ./app_sdk/static_baseline.py /app_sdk +ADD ./app_gen /app_gen + RUN go get -v RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o webapp . @@ -20,14 +25,10 @@ FROM alpine:latest as certs RUN apk --update add ca-certificates from scratch -RUN mkdir /app -RUN mkdir /app_sdk - -# Required files for code generation -ADD ./app_sdk/app_sdk.py /app_sdk -ADD ./app_sdk/static_baseline.py /app_sdk COPY --from=builder /app/ /app +COPY --from=builder /app_sdk/ /app_sdk +COPY --from=builder /app_gen/ /app_gen COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt WORKDIR /app diff --git a/backend/README.md b/backend/README.md index 8cea3c80..4a3e0599 100644 --- a/backend/README.md +++ b/backend/README.md @@ -1,61 +1,18 @@ -# Backend setup -1 Go to https://console.cloud.google.com/apis/credentials?project=shuffle-241517&folder&organizationId and get credentials -2. Move the file to current folder (or make step 3 be your download folder or w/e) -3. export GOOGLE_APPLICATION_CREDENTIALS=$(pwd)/Shuffle-2a19ff64af66.json +# Backend +This folder has all parts necessary for the backend to run locally and in Docker -# Backend run testserver (appengine) -1. Set up gcloud locally -```bash -dev_appserver.py go-app/ --port=5001 --host=0.0.0.0 --enable_host_checking=false -``` +## Structure +* go-app: The backend. Modify these to edit the backend API. +* database: The datastore database. +* app_sdk: The app_sdk for apps. MIT licensed. +* app_gen: Code used when generating docker images. MIT licensed +* tests: A bunch of cronscripts. There are no real, good tests yet -# Backend deploy -* I created a simple script that moves the data into your GOPATH and deploys for you. This will require more tests in the future. +## Development +Shuffle's backend is written in Go, with apps being python (for now). More about local development can be seen in the main README. -# OpenAPI spec checks -Paths: -* /path/{variablename}?queryvar= <-- variable -* ^variablename needs to be part of parameters too. -* ^queryvar needs to be part of parameters too. +Running the backend: ``` -parameters: -- name: variablename - in: path - description: Blah blah - required: true/false - schema: - type: string - enum: [a, b, c] # <-- not necessary, but could be great -- name: queryvar - in: query - description: blah blah - required: true/false - schema: - type: string - enum: [a, b, c] -``` -* requestBody? Not in GET, DELETE & HEAD. Can consume JSON, XML, form data, plai ntext & others. Can use markdown for the description. -* Do I care about the response? Maybe :o - -``` -requestBody: - description: Optional kind of description - required: false/true - content: - application/json: - schema: - type: object - additionalProperties: true - properties: - name: - type: string - fav_number: - type: integer - required: - - name - - email - encoding: - color: - style: form - explode: false +cd go-app +go run *.go ``` diff --git a/backend/app_gen/LICENSE b/backend/app_gen/LICENSE new file mode 100644 index 00000000..ce11f6f3 --- /dev/null +++ b/backend/app_gen/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Frikkylikeme + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/app_gen/openapi-parsers/generated/carbon_black_response.yaml b/backend/app_gen/openapi-parsers/generated/carbon_black_response.yaml similarity index 100% rename from app_gen/openapi-parsers/generated/carbon_black_response.yaml rename to backend/app_gen/openapi-parsers/generated/carbon_black_response.yaml diff --git a/app_gen/openapi-parsers/generated/cyberreason.yaml b/backend/app_gen/openapi-parsers/generated/cyberreason.yaml similarity index 100% rename from app_gen/openapi-parsers/generated/cyberreason.yaml rename to backend/app_gen/openapi-parsers/generated/cyberreason.yaml diff --git a/app_gen/openapi-parsers/generated/recorded_future.yaml b/backend/app_gen/openapi-parsers/generated/recorded_future.yaml similarity index 100% rename from app_gen/openapi-parsers/generated/recorded_future.yaml rename to backend/app_gen/openapi-parsers/generated/recorded_future.yaml diff --git a/app_gen/openapi-parsers/generated/shodan.yaml b/backend/app_gen/openapi-parsers/generated/shodan.yaml similarity index 100% rename from app_gen/openapi-parsers/generated/shodan.yaml rename to backend/app_gen/openapi-parsers/generated/shodan.yaml diff --git a/app_gen/openapi-parsers/generated/tenable_tenable.io.yaml b/backend/app_gen/openapi-parsers/generated/tenable_tenable.io.yaml similarity index 100% rename from app_gen/openapi-parsers/generated/tenable_tenable.io.yaml rename to backend/app_gen/openapi-parsers/generated/tenable_tenable.io.yaml diff --git a/app_gen/openapi-parsers/misp.py b/backend/app_gen/openapi-parsers/misp.py similarity index 100% rename from app_gen/openapi-parsers/misp.py rename to backend/app_gen/openapi-parsers/misp.py diff --git a/app_gen/openapi-parsers/other/TIO-API-Container-Security-v1.json b/backend/app_gen/openapi-parsers/other/TIO-API-Container-Security-v1.json similarity index 100% rename from app_gen/openapi-parsers/other/TIO-API-Container-Security-v1.json rename to backend/app_gen/openapi-parsers/other/TIO-API-Container-Security-v1.json diff --git a/app_gen/openapi-parsers/other/TIO-API-Container-Security-v2.json b/backend/app_gen/openapi-parsers/other/TIO-API-Container-Security-v2.json similarity index 100% rename from app_gen/openapi-parsers/other/TIO-API-Container-Security-v2.json rename to backend/app_gen/openapi-parsers/other/TIO-API-Container-Security-v2.json diff --git a/app_gen/openapi-parsers/other/TIO-API-Downloads-API.json b/backend/app_gen/openapi-parsers/other/TIO-API-Downloads-API.json similarity index 100% rename from app_gen/openapi-parsers/other/TIO-API-Downloads-API.json rename to backend/app_gen/openapi-parsers/other/TIO-API-Downloads-API.json diff --git a/app_gen/openapi-parsers/other/TIO-API-Tenable-Platform.json b/backend/app_gen/openapi-parsers/other/TIO-API-Tenable-Platform.json similarity index 100% rename from app_gen/openapi-parsers/other/TIO-API-Tenable-Platform.json rename to backend/app_gen/openapi-parsers/other/TIO-API-Tenable-Platform.json diff --git a/app_gen/openapi-parsers/other/TIO-API-Vulnerability-Management.json b/backend/app_gen/openapi-parsers/other/TIO-API-Vulnerability-Management.json similarity index 100% rename from app_gen/openapi-parsers/other/TIO-API-Vulnerability-Management.json rename to backend/app_gen/openapi-parsers/other/TIO-API-Vulnerability-Management.json diff --git a/app_gen/openapi-parsers/other/TIO-API-Web-Application-Scanning.json b/backend/app_gen/openapi-parsers/other/TIO-API-Web-Application-Scanning.json similarity index 100% rename from app_gen/openapi-parsers/other/TIO-API-Web-Application-Scanning.json rename to backend/app_gen/openapi-parsers/other/TIO-API-Web-Application-Scanning.json diff --git a/app_gen/openapi-parsers/swimlane.py b/backend/app_gen/openapi-parsers/swimlane.py similarity index 100% rename from app_gen/openapi-parsers/swimlane.py rename to backend/app_gen/openapi-parsers/swimlane.py diff --git a/app_gen/openapi/README.md b/backend/app_gen/openapi/README.md similarity index 100% rename from app_gen/openapi/README.md rename to backend/app_gen/openapi/README.md diff --git a/app_gen/openapi/baseline/Dockerfile b/backend/app_gen/openapi/baseline/Dockerfile similarity index 100% rename from app_gen/openapi/baseline/Dockerfile rename to backend/app_gen/openapi/baseline/Dockerfile diff --git a/app_gen/openapi/baseline/requirements.txt b/backend/app_gen/openapi/baseline/requirements.txt similarity index 100% rename from app_gen/openapi/baseline/requirements.txt rename to backend/app_gen/openapi/baseline/requirements.txt diff --git a/app_gen/openapi/test.go b/backend/app_gen/openapi/test.go similarity index 100% rename from app_gen/openapi/test.go rename to backend/app_gen/openapi/test.go diff --git a/app_gen/openapi/testGCP.go b/backend/app_gen/openapi/testGCP.go similarity index 100% rename from app_gen/openapi/testGCP.go rename to backend/app_gen/openapi/testGCP.go diff --git a/app_gen/python-lib/README.md b/backend/app_gen/python-lib/README.md similarity index 100% rename from app_gen/python-lib/README.md rename to backend/app_gen/python-lib/README.md diff --git a/app_gen/python-lib/baseline/Dockerfile b/backend/app_gen/python-lib/baseline/Dockerfile similarity index 100% rename from app_gen/python-lib/baseline/Dockerfile rename to backend/app_gen/python-lib/baseline/Dockerfile diff --git a/app_gen/python-lib/baseline/docker-compose.yml b/backend/app_gen/python-lib/baseline/docker-compose.yml similarity index 100% rename from app_gen/python-lib/baseline/docker-compose.yml rename to backend/app_gen/python-lib/baseline/docker-compose.yml diff --git a/app_gen/python-lib/baseline/env.txt b/backend/app_gen/python-lib/baseline/env.txt similarity index 100% rename from app_gen/python-lib/baseline/env.txt rename to backend/app_gen/python-lib/baseline/env.txt diff --git a/app_gen/python-lib/baseline/requirements.txt b/backend/app_gen/python-lib/baseline/requirements.txt similarity index 100% rename from app_gen/python-lib/baseline/requirements.txt rename to backend/app_gen/python-lib/baseline/requirements.txt diff --git a/app_gen/python-lib/generator.py b/backend/app_gen/python-lib/generator.py similarity index 100% rename from app_gen/python-lib/generator.py rename to backend/app_gen/python-lib/generator.py diff --git a/app_gen/python-lib/requirements.txt b/backend/app_gen/python-lib/requirements.txt similarity index 100% rename from app_gen/python-lib/requirements.txt rename to backend/app_gen/python-lib/requirements.txt diff --git a/backend/app_sdk/readme b/backend/app_sdk/readme deleted file mode 100644 index 4a01094d..00000000 --- a/backend/app_sdk/readme +++ /dev/null @@ -1,8 +0,0 @@ -# App_sdk -App_sdk development is continued here: https://github.com/frikky/Shuffle-apps/tree/master/app_sdk - -# Added static:baseline.py -It's used for python code generation and should be under MIT. - -# LICENSE -Everything in this folder is MIT, not AGPLv3 diff --git a/backend/build.sh b/backend/build.sh new file mode 100644 index 00000000..5679ae8b --- /dev/null +++ b/backend/build.sh @@ -0,0 +1,13 @@ +#!/bin/sh +docker stop shuffle-backend +docker rm shuffle-backend +docker rmi frikky/shuffle:backend + +docker build . -t frikky/shuffle:backend + +echo "Starting server" +#docker run -it \ +# -p 5001:5001 \ +# -v /var/run/docker.sock:/var/run/docker.sock \ +# --env DATASTORE_EMULATOR_HOST=192.168.3.6:8000 \ +# frikky/shuffle:backend diff --git a/backend/deploy-backend.sh b/backend/deploy-backend.sh deleted file mode 100644 index bb51e6de..00000000 --- a/backend/deploy-backend.sh +++ /dev/null @@ -1,8 +0,0 @@ -# Deploys to backend -echo "Deploying to appengine." -mkdir -p $GOPATH/src/github.com/frikky/shuffle -cp -r go-app/* $GOPATH/src/github.com/frikky/shuffle -cd $GOPATH/src/github.com/frikky/shuffle -go build -go test -gcloud app deploy $GOPATH/src/github.com/frikky/shuffle/app.yaml diff --git a/backend/go-app/codegen.go b/backend/go-app/codegen.go index 29c06917..d37954a9 100644 --- a/backend/go-app/codegen.go +++ b/backend/go-app/codegen.go @@ -218,7 +218,7 @@ func buildStructure(swagger *openapi3.Swagger, curHash string) (string, error) { // adding md5 based on input data to not overwrite earlier data. generatedPath := "generated" - subpath := "../../app_gen/openapi/" + subpath := "../app_gen/openapi/" identifier := fmt.Sprintf("%s-%s", swagger.Info.Title, curHash) appPath := fmt.Sprintf("%s/%s", generatedPath, identifier) @@ -704,6 +704,9 @@ func handleConnect(swagger *openapi3.Swagger, api WorkflowApp, extraParameters [ optionalParameters := []WorkflowAppActionParameter{} if len(path.Connect.Parameters) > 0 { for _, param := range path.Connect.Parameters { + if param.Value.Schema == nil { + continue + } curParam := WorkflowAppActionParameter{ Name: param.Value.Name, Description: param.Value.Description, @@ -876,6 +879,9 @@ func handleHead(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo optionalParameters := []WorkflowAppActionParameter{} if len(path.Head.Parameters) > 0 { for _, param := range path.Head.Parameters { + if param.Value.Schema == nil { + continue + } curParam := WorkflowAppActionParameter{ Name: param.Value.Name, Description: param.Value.Description, @@ -958,6 +964,9 @@ func handleDelete(swagger *openapi3.Swagger, api WorkflowApp, extraParameters [] optionalParameters := []WorkflowAppActionParameter{} if len(path.Delete.Parameters) > 0 { for _, param := range path.Delete.Parameters { + if param.Value.Schema == nil { + continue + } curParam := WorkflowAppActionParameter{ Name: param.Value.Name, Description: param.Value.Description, @@ -1052,6 +1061,9 @@ func handlePost(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wo } if len(path.Post.Parameters) > 0 { for _, param := range path.Post.Parameters { + if param.Value.Schema == nil { + continue + } curParam := WorkflowAppActionParameter{ Name: param.Value.Name, Description: param.Value.Description, @@ -1145,6 +1157,9 @@ func handlePatch(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []W } if len(path.Patch.Parameters) > 0 { for _, param := range path.Patch.Parameters { + if param.Value.Schema == nil { + continue + } curParam := WorkflowAppActionParameter{ Name: param.Value.Name, Description: param.Value.Description, @@ -1238,6 +1253,9 @@ func handlePut(swagger *openapi3.Swagger, api WorkflowApp, extraParameters []Wor } if len(path.Put.Parameters) > 0 { for _, param := range path.Put.Parameters { + if param.Value.Schema == nil { + continue + } curParam := WorkflowAppActionParameter{ Name: param.Value.Name, Description: param.Value.Description, diff --git a/backend/go-app/main.go b/backend/go-app/main.go index ef466fcc..54cd69ba 100644 --- a/backend/go-app/main.go +++ b/backend/go-app/main.go @@ -5698,7 +5698,7 @@ func verifySwagger(resp http.ResponseWriter, request *http.Request) { log.Println(len(user.PrivateApps)) c, err := request.Cookie("session_token") if err == nil { - log.Printf("Should've deleted cache for %s with token %s", user.Username, c.Value) + //log.Printf("Should've deleted cache for %s with token %s", user.Username, c.Value) //err = memcache.Delete(request.Context(), c.Value) //err = memcache.Delete(request.Context(), user.ApiKey) } diff --git a/backend/run.sh b/backend/run.sh deleted file mode 100644 index edfe195c..00000000 --- a/backend/run.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# docker stop nginx -# docker rm nginx -# docker rmi nginx -# -# echo "Running build for website" -# sudo npm run build -# docker build . -t nginx - -echo "Starting server" -docker run -it \ - -p 5001:5001 \ - -v /var/run/docker.sock:/var/run/docker.sock \ - --env DATASTORE_EMULATOR_HOST=192.168.3.6:8000 \ - frikky/shuffle:backend diff --git a/backend/webhook/Dockerfile b/backend/webhook/Dockerfile deleted file mode 100644 index 4b709eb5..00000000 --- a/backend/webhook/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -# Build environment -# production environment -from golang as builder - -RUN go get github.com/gorilla/handlers -RUN go get github.com/gorilla/mux - -WORKDIR /app -COPY webhook.go /app/webhook.go -RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o webhook . - -from scratch -COPY --from=builder /app/ / - -CMD ["./webhook"] diff --git a/backend/webhook/README.md b/backend/webhook/README.md deleted file mode 100644 index 8b87bffb..00000000 --- a/backend/webhook/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Steps to deploy to Google cloud function -1. -```bash -zip webhook.zip * -``` -2. Go to google cloud bucket and upload the zip -3. Go to worker for webhook and upload diff --git a/backend/webhook/functionhook.go b/backend/webhook/functionhook.go deleted file mode 100644 index 2df691b0..00000000 --- a/backend/webhook/functionhook.go +++ /dev/null @@ -1,44 +0,0 @@ -package function - -import ( - "encoding/json" - "io/ioutil" - "log" - "net/http" - "time" -) - -// GetUserDetails - Get one user's details from randomuser.me API -func GetUserDetails(w http.ResponseWriter, r *http.Request) { - randomUserClient := http.Client{ - Timeout: time.Second * 3, - } - - req, err := http.NewRequest(http.MethodGet, "https://randomuser.me/api/", nil) - if err != nil { - log.Fatal(err) - return - } - - res, err2 := randomUserClient.Do(req) - if err2 != nil { - log.Fatal(err2) - return - } - - body, err3 := ioutil.ReadAll(res.Body) - if err3 != nil { - log.Fatal(err3) - } - - var o map[string]interface{} - json.Unmarshal([]byte(body), &o) - - results := o["results"].([]interface{}) - result := results[0].(map[string]interface{}) - - result["generator"] = "google-cloud-function" - - w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(result) -} diff --git a/backend/webhook/gcp_run.sh b/backend/webhook/gcp_run.sh deleted file mode 100644 index 605777b5..00000000 --- a/backend/webhook/gcp_run.sh +++ /dev/null @@ -1,4 +0,0 @@ -docker build . -t gcr.io/shuffle-241517/webhook -docker push gcr.io/shuffle-241517/webhook - -gcloud beta run deploy webhook --image gcr.io/shuffle-241517/webhook diff --git a/backend/webhook/run.sh b/backend/webhook/run.sh deleted file mode 100644 index c9914de7..00000000 --- a/backend/webhook/run.sh +++ /dev/null @@ -1,16 +0,0 @@ -docker stop webhook -docker rm webhook -docker rmi webhook - -docker build . -t webhook -docker run -d \ - -e "HOOKPORT=5001" \ - -e "URIPATH=/webhook" \ - -e "CALLBACKURL=http://192.168.3.6:5001/api/v1/hooks/d6ef8912e8bd37776e654cbc14c2629c/result" \ - -p 6000:6000 \ - --name webhook \ - -h webhook \ - --restart always \ - webhook - -docker logs -f webhook diff --git a/backend/webhook/webhook.go b/backend/webhook/webhook.go deleted file mode 100644 index bd256d78..00000000 --- a/backend/webhook/webhook.go +++ /dev/null @@ -1,260 +0,0 @@ -package main - -import ( - "bytes" - "encoding/json" - "fmt" - "io/ioutil" - "log" - "net/http" - "os" - - "github.com/gorilla/handlers" - "github.com/gorilla/mux" -) - -type Info struct { - Url string `json:"url" datastore:"url"` - Name string `json:"name" datastore:"name"` - Description string `json:"description" datastore:"description"` -} - -// Actions to be done by webhooks etc -// Field is the actual field to use from json -type HookAction struct { - Type string `json:"type" datastore:"type"` - Name string `json:"name" datastore:"name"` - Id string `json:"id" datastore:"id"` - Field string `json:"field" datastore:"field"` -} - -type Hook struct { - Id string `json:"id" datastore:"id"` - Info Info `json:"info" datastore:"info"` - Transforms struct{} `json:"transforms" datastore:"transforms"` - Actions []HookAction `json:"actions" datastore:"actions"` - Type string `json:"type" datastore:"type"` - Status string `json:"status" datastore:"status"` - Running bool `json:"running" datastore:"running"` -} - -var hook Hook - -func handleWorkflowAction(request *http.Request, action HookAction) error { - //log.Printf("WORKFLOW!: %#v", action) - log.Printf("Should execute workflow %s", action.Id) - - callbackUrl := os.Getenv("CALLBACKURL") - apikey := os.Getenv("APIKEY") - fullUrl := fmt.Sprintf("%s/api/v1/workflows/%s/execute", callbackUrl, action.Id) - - // ret = requests.post(fullurl, headers=headers, json=data) - //if ret.status_code != 202: - // print(ret.text) - // print(ret.status_code) - // print("Exiting workflows - run queue") - // exit() - - body, err := ioutil.ReadAll(request.Body) - if err != nil { - return err - } - - // Execute a workflow - client := &http.Client{} - req, err := http.NewRequest( - "POST", - fullUrl, - bytes.NewBuffer(body), - ) - - if err != nil { - log.Printf("Error making http request: %s", req) - return err - } - - req.Header.Add("Authorization", fmt.Sprintf(`Bearer %s`, apikey)) - req.Header.Add("Content-Type", "application/json") - resp, err := client.Do(req) - if err != nil { - log.Printf("Error in http request: %s", req) - } - - log.Printf("%#v", resp) - return nil -} - -// FIXME - refresh hook information once in a while. Compare timestamps or something -func callback(resp http.ResponseWriter, request *http.Request) { - //apikey = os.Getenv("APIKEY") - //hookId = os.Getenv("HOOKID") - - handledWorkflowIds := []string{} - for _, item := range hook.Actions { - if item.Type == "" { - log.Printf("CONTINUE AAS EMPTY ITEM: %#v", item) - continue - } - - if item.Type == "workflow" { - found := false - for _, workflowId := range handledWorkflowIds { - if item.Id == workflowId { - found = true - break - } - } - - if found { - continue - } - - handledWorkflowIds = append(handledWorkflowIds, item.Id) - err := handleWorkflowAction(request, item) - if err != nil { - log.Printf("Error in workflow exec: %s", err) - } - } - } - - // FIXME - send the webhookdata to a logging service? Idk - //body, err := ioutil.ReadAll(request.Body) - //if err != nil { - // log.Println("Failed reading body") - // resp.WriteHeader(401) - // resp.Write([]byte(fmt.Sprintf(`{"success": false}`))) - // return - //} - - //callback, err := http.Post(callbackUrl, "application/json", bytes.NewBuffer(body)) - //if err != nil { - // log.Printf("Failed sending callback to %s", callbackUrl) - //} - - resp.WriteHeader(200) - resp.Write([]byte(fmt.Sprintf(`{"success": true}`))) - return -} - -func loadConfiguration(fullUrl string, apikey string) error { - client := &http.Client{} - - req, err := http.NewRequest( - "GET", - fullUrl, - nil, - ) - - if err != nil { - log.Printf("Error making http request: %s", req) - return err - } - - req.Header.Add("Authorization", fmt.Sprintf(`Bearer %s`, apikey)) - req.Header.Add("Content-Type", "application/json") - resp, err := client.Do(req) - if err != nil { - log.Printf("Error in http request: %s", req) - return err - } - - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - log.Printf("Error reading response: %s", req) - return err - } - - err = json.Unmarshal(body, &hook) - if err != nil { - log.Printf("Failed unmarshaling hook API", req) - return err - } - - log.Printf("%#v", hook) - log.Println(hook.Actions) - return nil -} - -func webhook() { - // FIXME - remove static - ip := "0.0.0.0" - - // Basic webserver stuff - baseFilePath := os.Getenv("URIPATH") - basePort := os.Getenv("HOOKPORT") - callbackUrl := os.Getenv("CALLBACKURL") - apikey := os.Getenv("APIKEY") - hookId := os.Getenv("HOOKID") - - if len(baseFilePath) == 0 { - log.Println("Env URIPATH not set") - os.Exit(3) - } - - if len(basePort) == 0 { - log.Println("Env HOOKPORT not set") - os.Exit(3) - } - - if len(callbackUrl) == 0 { - log.Println("Env CALLBACKURL not set") - os.Exit(3) - } - - if len(apikey) == 0 { - log.Println("Env APIKEY not set") - os.Exit(3) - } - - if len(hookId) == 0 { - log.Println("Env HOOKID not set") - os.Exit(3) - } - - log.Println("Loading hook configuration") - err := loadConfiguration( - fmt.Sprintf("%s/api/v1/hooks/%s", callbackUrl, hookId), - apikey, - ) - - if err != nil { - log.Fatalf("Error loading config: %s", err) - } - - // Optional - // if len(callbackOpts) == 0 { - // log.Println("Env CALLBACKOPTS not set") - // os.Exit(3) - // } - - port := fmt.Sprintf(":%s", basePort) - log.Printf("Starting webhook on %s%s with path %s", ip, port, baseFilePath) - - // Routing - mux := mux.NewRouter() - mux.SkipClean(true) - - // FIXME - Add path for updating the hook? Can be a specific POST requeuest from backend - mux.HandleFunc(baseFilePath, callback).Methods("POST") - - handlers.LoggingHandler(os.Stdout, mux) - loggedRouter := handlers.LoggingHandler(os.Stdout, mux) - - err = http.ListenAndServe( - port, - loggedRouter, - ) - - if err != nil { - log.Fatal("ListenAndServer: ", err) - } -} - -func F(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "text/plain; charset=utf-8") - w.Write([]byte(r.Header.Get("X-Forwarded-For"))) -} - -func main() { - webhook() -} diff --git a/frontend/src/App.js b/frontend/src/App.js index 0b65efd2..f22d9f9f 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -38,10 +38,10 @@ import AlertTemplate from "react-alert-template-basic"; import { positions, Provider } from "react-alert"; // Testing - localhost -//const globalUrl = "http://192.168.3.6:5001" +const globalUrl = "http://192.168.3.6:5001" // Production - backend proxy forwarding in nginx -const globalUrl = window.location.origin +//const globalUrl = window.location.origin const surfaceColor = "#27292D" const inputColor = "#383B40" @@ -77,7 +77,7 @@ const App = (message, props) => { }}) if (isLoaded && !isLoggedIn && (!window.location.pathname.startsWith("/login") && (!window.location.pathname.startsWith("/docs") && (!window.location.pathname.startsWith("/adminsetup"))))) { - window.location = "login" + window.location = "/login" } const checkLogin = () => { diff --git a/frontend/src/Apps.js b/frontend/src/Apps.js index dcc55e17..e5c3b5bf 100644 --- a/frontend/src/Apps.js +++ b/frontend/src/Apps.js @@ -286,7 +286,7 @@ const Apps = (props) => { var description = selectedApp.description const url = "/apps/edit/"+selectedApp.id - var editButton = selectedApp.private_id !== undefined && selectedApp.private_id.length > 0 && selectedApp.generated ? + var editButton = selectedApp.activated && selectedApp.private_id !== undefined && selectedApp.private_id.length > 0 && selectedApp.generated ? : null + var activateButton = selectedApp.generated && !selectedApp.activated ? + + : null + var deleteButton = (selectedApp.private_id !== undefined && selectedApp.private_id.length > 0 && selectedApp.generated) || (selectedApp.downloaded != undefined && selectedApp.downloaded == true) ?