From ef190bcc4753e1dd44a5b635ff141a659e27d29d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Johannes=20Ke=C3=9Fler?= Date: Fri, 17 Feb 2023 16:22:54 +0100 Subject: [PATCH] cleanup and workin cli client --- client/go-cli/Makefile | 21 ++++++ client/go-cli/README | 24 ++++++- client/go-cli/go.mod | 5 ++ client/go-cli/go.sum | 4 ++ client/go-cli/scientia-cli.go | 105 +++++++++++++++++------------- documentation/clients.txt | 3 +- webroot/api.php | 6 +- webroot/config/config.php.default | 5 +- 8 files changed, 121 insertions(+), 52 deletions(-) create mode 100644 client/go-cli/Makefile create mode 100644 client/go-cli/go.mod create mode 100644 client/go-cli/go.sum diff --git a/client/go-cli/Makefile b/client/go-cli/Makefile new file mode 100644 index 0000000..7d554b6 --- /dev/null +++ b/client/go-cli/Makefile @@ -0,0 +1,21 @@ +# Determine this makefile's path. +# Be sure to place this BEFORE `include` directives, if any. +THIS_FILE := $(lastword $(MAKEFILE_LIST)) + +all: + @echo "Options are: build and buildall" + +build: + @echo "Building for local os/arch..." + go build -o scientia-cli-`go env GOOS`-`go env GOARCH` + +buildall: + @echo "Building for linux/amd64 arch..." + GOOS=linux GOARCH=amd64 go build -o scientia-cli-linux-amd64 + @echo "Done: scientia-cli-linux-amd64" + @echo "Building for windows/amd64 arch..." + GOOS=windows GOARCH=amd64 go build -o scientia-cli-windows-amd64 + @echo "Done: scientia-cli-windows-amd64" + @echo "Building for macOS/amd64 arch..." + GOOS=darwin GOARCH=amd64 go build -o scientia-cli-darwin-amd64 + @echo "Done: scientia-cli-darwin-amd64" \ No newline at end of file diff --git a/client/go-cli/README b/client/go-cli/README index f3f6d65..306ab15 100644 --- a/client/go-cli/README +++ b/client/go-cli/README @@ -5,5 +5,25 @@ https://://www.bananas-playground.net/projekt/scientia This is a very simple, with limited experience written, go program. Use at own risk and feel free to improve. -Howto build: -Nothing special, just go build -o scientia-cli +# Howto build +Nothing special, just "go build -o scientia-cli" to use your own arch settings. + +# Usage +At first usage you need to create the config and the individual secret. +Run $scientia-cli -create-config-file to create the default config file. +The path to the config file is printed. +Change the host address and update your server it with the secret, which is randomly created. + + +Read from a file +$ scientia-cli file.txt +or piped +$ cat file.txt | scientia-cli + +Commandline arguments: + -create-config-file + Create default config file + -debug + Print debug infos + -verbose + Produce verbose output diff --git a/client/go-cli/go.mod b/client/go-cli/go.mod new file mode 100644 index 0000000..5a0b7ac --- /dev/null +++ b/client/go-cli/go.mod @@ -0,0 +1,5 @@ +module scientia/go-client-cli + +go 1.20 + +require gopkg.in/yaml.v2 v2.4.0 diff --git a/client/go-cli/go.sum b/client/go-cli/go.sum new file mode 100644 index 0000000..dd0bc19 --- /dev/null +++ b/client/go-cli/go.sum @@ -0,0 +1,4 @@ +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/client/go-cli/scientia-cli.go b/client/go-cli/scientia-cli.go index 9ce1858..44864a9 100644 --- a/client/go-cli/scientia-cli.go +++ b/client/go-cli/scientia-cli.go @@ -1,18 +1,18 @@ package main import ( + "bytes" + "encoding/json" "errors" + "flag" "fmt" + "gopkg.in/yaml.v2" + "io" + "io/ioutil" "log" "math/rand" - "os" - "flag" - "gopkg.in/yaml.v2" "net/http" - "io/ioutil" - "bytes" - "mime/multipart" - "encoding/json" + "os" ) /** @@ -33,6 +33,7 @@ import ( const website = "https://www.bananas-playground.net/projekt/scientia" const version = "1.0" + // used for non-existing default config const letters = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-_" @@ -43,18 +44,25 @@ var optsDebug bool // config var cfg Config + // config file struct type Config struct { Endpoint struct { - Host string `yaml:"host"` + Host string `yaml:"host"` Secret string `yaml:"secret"` } `yaml:"endpoint"` } +// post json struct +type PayloadJson struct { + Asl string `json:"asl"` + Data string `json:"data"` +} + // response json struct type Response struct { Message string `json:"message"` - Status int `json:"status"` + Status int `json:"status"` } /** @@ -78,7 +86,9 @@ func main() { // get the payload payload := getInput() - if optsDebug { log.Println(payload) } + if optsDebug { + log.Println(payload) + } // do the upload and get the response responseString := uploadCall(payload) @@ -90,15 +100,12 @@ func main() { fmt.Printf("Message: %s\n", response.Message) } - - - /** * Check and display error with additional message */ func errorCheck(e error, msg string) { if e != nil { - log.Fatal(msg,e) + log.Fatal(msg, " ; Errrormsg: ", e) } } @@ -120,7 +127,9 @@ func randStringBytes(n int) string { func loadConfig() { homeDir, err := os.UserHomeDir() errorCheck(err, "No $HOME directory available?") - if optsVerbose { log.Printf("Your $HOME: %s \n", homeDir) } + if optsVerbose { + log.Printf("Your $HOME: %s \n", homeDir) + } var configFile = homeDir + "/.scientia.yaml" @@ -134,23 +143,24 @@ func loadConfig() { errorCheck(err, "Can not create config file!") defer newConfig.Close() - _, err = fmt.Fprintf(newConfig, "# scientia go client config file.\n") errorCheck(err, "Can not write to new config file") fmt.Fprintf(newConfig, "# See %s for more details.\n", website) fmt.Fprintf(newConfig, "# Version: %s\n", version) fmt.Fprintf(newConfig, "endpoint:\n") - fmt.Fprintf(newConfig, " host: http://your-scientia-endpoi.nt\n") + fmt.Fprintf(newConfig, " host: http://your-scientia-endpoi.nt/api.php\n") fmt.Fprintf(newConfig, " secret: %s\n", randStringBytes(50)) - log.Fatalf("New default config file created: - %s - Edit and launch again!",configFile) + log.Fatalf("New default config file created: - %s - Edit and launch again!", configFile) } } existingConfigFile, err := os.Open(configFile) - errorCheck(err, "Can not open config file") + errorCheck(err, "Can not open config file. Did you create one with -create-config-file?") defer existingConfigFile.Close() - if optsVerbose { log.Printf("Reading config file: %s \n", configFile) } + if optsVerbose { + log.Printf("Reading config file: %s \n", configFile) + } var decoder = yaml.NewDecoder(existingConfigFile) err = decoder.Decode(&cfg) @@ -173,46 +183,43 @@ func loadConfig() { */ func uploadCall(payload string) string { - if optsVerbose { log.Println("Starting to upload data") } - if optsDebug { log.Println(payload) } + if optsVerbose { + log.Println("Starting to upload data") + } + if optsDebug { + log.Println(payload) + } if len(payload) == 0 { log.Fatal("Nothing provided to upload") } - // Buffer to store our request body as bytes - var requestBody bytes.Buffer - - // Create a multipart writer - multiPartWriter := multipart.NewWriter(&requestBody) - - // file field - fileWriter, err := multiPartWriter.CreateFormFile("pasty", "pastyfile") - errorCheck(err, "Can not create form file field") - fileWriter.Write([]byte(payload)) - - dlField, err := multiPartWriter.CreateFormField("dl") - errorCheck(err, "Can not create form dl field") - dlField.Write([]byte(cfg.Endpoint.Secret)) + payloadStruct := PayloadJson{ + Asl: cfg.Endpoint.Secret, + Data: payload, + } - multiPartWriter.Close() + jsonData, err := json.Marshal(payloadStruct) + errorCheck(err, "Can not create json payload") - req, err := http.NewRequest(http.MethodPost, cfg.Endpoint.Host, &requestBody) + req, err := http.NewRequest(http.MethodPost, cfg.Endpoint.Host, bytes.NewBuffer(jsonData)) errorCheck(err, "Can not create http request") // We need to set the content type from the writer, it includes necessary boundary as well - req.Header.Set("Content-Type", multiPartWriter.FormDataContentType()) - req.Header.Set("User-Agent", "scientiaAgent/1.0"); + req.Header.Set("Content-Type", "application/json; charset=UTF-8") + req.Header.Set("User-Agent", "scientiaAgent/1.0") // Do the request client := &http.Client{} response, err := client.Do(req) errorCheck(err, "POST request failed") - responseBody, err := ioutil.ReadAll(response.Body) + responseBody, err := io.ReadAll(response.Body) errorCheck(err, "Can not read response body") - if optsVerbose { log.Println("Request done") } + if optsVerbose { + log.Println("Request done") + } if optsDebug { - log.Printf("Response status code: %d\n",response.StatusCode) + log.Printf("Response status code: %d\n", response.StatusCode) log.Printf("Response headers: %#v\n", response.Header) log.Println(string(responseBody)) } @@ -226,12 +233,16 @@ func uploadCall(payload string) string { * return the read data as string */ func getInput() string { - if optsVerbose { log.Println("Getting input") } + if optsVerbose { + log.Println("Getting input") + } var inputString string if filename := flag.Arg(0); filename != "" { - if optsVerbose { log.Println("Read from file argument") } + if optsVerbose { + log.Println("Read from file argument") + } bytes, err := os.ReadFile(filename) errorCheck(err, "Error opening file") @@ -239,7 +250,9 @@ func getInput() string { } else { stat, _ := os.Stdin.Stat() if (stat.Mode() & os.ModeCharDevice) == 0 { - if optsVerbose { log.Println("data is being piped") } + if optsVerbose { + log.Println("data is being piped") + } bytes, _ := ioutil.ReadAll(os.Stdin) inputString = string(bytes) diff --git a/documentation/clients.txt b/documentation/clients.txt index 25d14b8..d1e0d18 100644 --- a/documentation/clients.txt +++ b/documentation/clients.txt @@ -1,3 +1,4 @@ Work in progress. -Currently there is go client in the works. +A client needs to create its secret. This needs to be added to the server. After that a client is allowed +to add contents. diff --git a/webroot/api.php b/webroot/api.php index ac7ff84..3f5583b 100644 --- a/webroot/api.php +++ b/webroot/api.php @@ -49,10 +49,12 @@ require_once('lib/summoner.class.php'); if(DEBUG) error_log("Dump SERVER ".var_export($_SERVER,true)); +if(DEBUG) error_log("Dump SERVER ".var_export($_SERVER['REQUEST_METHOD'],true)); +if(DEBUG) error_log("Dump SERVER ".var_export($_SERVER['CONTENT_TYPE'],true)); ## check if request is valid $_create = false; $filteredData = ''; -if ($_SERVER['REQUEST_METHOD'] === 'POST' && $_SERVER['CONTENT_TYPE'] === 'application/json; charset=utf-8') { +if ($_SERVER['REQUEST_METHOD'] === 'POST' && $_SERVER['CONTENT_TYPE'] === 'application/json; charset=UTF-8') { $payload = json_decode(file_get_contents('php://input'), true); if(DEBUG) error_log("[DEBUG] Dump payload ".var_export($payload,true)); if(!empty($payload)) { @@ -99,7 +101,7 @@ require_once 'lib/entry.class.php'; $Entry = new Entry($DB); $do = $Entry->create($filteredData); if(!empty($do)) { - $contentBody['message'] = date('/Y/m/d/').$do; + $contentBody['message'] = INSTALL_URL . PATH_WEBROOT . date('/Y/m/d/').$do; } else { $hash = md5($do.time()); diff --git a/webroot/config/config.php.default b/webroot/config/config.php.default index 330c474..cb416a3 100644 --- a/webroot/config/config.php.default +++ b/webroot/config/config.php.default @@ -27,10 +27,13 @@ const TIMEZONE = 'Europe/Berlin'; const FRONTEND_LANGUAGE = 'en'; # path settings -const PATH_ABSOLUTE = '/home/banana/code/scientia/webroot'; +const PATH_ABSOLUTE = '/path/to/scientia/webroot'; const PATH_SYSTEMOUT = PATH_ABSOLUTE . '/systemout'; const PATH_WEBROOT = '/code/scientia/webroot'; +# Installation Domain. Webrootpath will be added automatically +const INSTALL_URL = 'http://www.example.tld'; + # database config const DB_HOST = '127.0.0.1'; const DB_USERNAME = 'user'; -- 2.39.5