commit 8d3bf8b198cdc88c4e16b687542860a69a7c29ff Author: Simon Rieger Date: Sun Jan 19 18:46:23 2025 +0100 first commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..1691f9d --- /dev/null +++ b/README.md @@ -0,0 +1,42 @@ +https://owntracks.org/booklet/tech/http/ + +https://medium.com/@tech_18484/deploying-a-php-web-app-with-docker-compose-nginx-and-mariadb-d61a84239c0d + +https://muetsch.io/open-source-self-hosted-location-tracking-with-owntracks-and-grafana.html + +~~~ +-- Adminer 4.8.1 MySQL 11.1.3-MariaDB-1:11.1.3+maria~ubu2204 dump + +SET NAMES utf8; +SET time_zone = '+00:00'; +SET foreign_key_checks = 0; +SET sql_mode = 'NO_AUTO_VALUE_ON_ZERO'; + +SET NAMES utf8mb4; + +DROP TABLE IF EXISTS `recordings`; +CREATE TABLE `recordings` ( + `user` varchar(255) DEFAULT NULL, + `device` varchar(255) DEFAULT NULL, + `acc` int(11) DEFAULT NULL, + `alt` int(11) DEFAULT NULL, + `batt` int(11) DEFAULT NULL, + `bs` int(11) DEFAULT NULL, + `conn` char(255) DEFAULT NULL, + `created_at` varchar(255) DEFAULT NULL, + `t` char(255) DEFAULT NULL, + `tst` bigint(20) DEFAULT NULL, + `vac` int(11) DEFAULT NULL, + `vel` int(11) DEFAULT NULL, + `dt` timestamp NULL DEFAULT NULL, + `tid` char(2) DEFAULT NULL, + `lat` decimal(9,6) DEFAULT NULL, + `lon` decimal(9,6) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +INSERT INTO `recordings` (`user`, `device`, `acc`, `alt`, `batt`, `bs`, `conn`, `created_at`, `t`, `tst`, `vac`, `vel`, `dt`, `tid`, `lat`, `lon`) VALUES +('simono41', '6193B679-AD67-4B93-9DF2-158501A055AF', 35, 80, 80, 1, 'm', NULL, NULL, '1700663979', 20, NULL, NULL, 'AF', 52.252686, 10.500029), +('simono41', '6193B679-AD67-4B93-9DF2-158501A055AF', 35, 80, 80, 1, 'm', NULL, NULL, '1700664006', 18, NULL, NULL, 'AF', 52.252533, 10.500295); + +-- 2023-11-22 14:40:35 +~~~ diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100755 index 0000000..f3adb06 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,47 @@ +version: "3.9" + +services: + +# Go application service + go-app: + build: + context: go/. + args: + - GO111MODULE=on + #ports: + # - "8080:8080" + depends_on: + - db + environment: + - DB_HOST=172.28.0.25 + - DB_PORT=3306 + - DB_USER=root + - DB_PASSWORD=owntracks + - DB_NAME=owntracks + volumes: + - /etc/localtime:/etc/localtime:ro + + restart: always + + networks: + default: + dns: + ipv4_address: 172.28.0.24 + + db: + image: mariadb:11 + volumes: + - ./mysql-data:/var/lib/mysql + environment: + MYSQL_ROOT_PASSWORD: owntracks + MYSQL_DATABASE: owntracks + restart: always + networks: + default: + dns: + ipv4_address: 172.28.0.25 + +networks: + dns: + name: dns + external: true diff --git a/go/Dockerfile b/go/Dockerfile new file mode 100755 index 0000000..2c572c4 --- /dev/null +++ b/go/Dockerfile @@ -0,0 +1,22 @@ +# Use an official Golang runtime as a parent image +FROM golang:1.21.4 + +# Set the working directory in the container +WORKDIR /go/src/app + +# Copy the local package files to the container's workspace +COPY . . + +# Download and install any required third-party dependencies into the container. +#RUN go get -u github.com/gorilla/mux +RUN go get -u github.com/go-sql-driver/mysql +RUN go get -u github.com/sirupsen/logrus + +# Build the Go application +RUN go build -o main . + +# Expose port 8080 to the outside world +EXPOSE 8080 + +# Command to run the application with environment variables +CMD ["./main"] diff --git a/go/go.mod b/go/go.mod new file mode 100755 index 0000000..119d48a --- /dev/null +++ b/go/go.mod @@ -0,0 +1,10 @@ +module go-app + +go 1.21.4 + +require ( + github.com/go-sql-driver/mysql v1.7.1 + github.com/sirupsen/logrus v1.9.3 +) + +require golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect diff --git a/go/go.sum b/go/go.sum new file mode 100755 index 0000000..05471c9 --- /dev/null +++ b/go/go.sum @@ -0,0 +1,17 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= +github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/go/main.go b/go/main.go new file mode 100644 index 0000000..68eafae --- /dev/null +++ b/go/main.go @@ -0,0 +1,110 @@ +package main + +import ( + "database/sql" + "encoding/json" + "fmt" + "net/http" + "os" + "time" + + "github.com/sirupsen/logrus" + _ "github.com/go-sql-driver/mysql" +) + +var log = logrus.New() + +// Location represents the JSON payload structure +type Location struct { + Type string `json:"_type"` + Tst int64 `json:"tst"` + Lat float64 `json:"lat"` + Lon float64 `json:"lon"` + Tid string `json:"tid"` + Batt int `json:"batt"` + Vac int `json:"vac"` +} + +func init() { + // Log as JSON instead of the default ASCII formatter. + log.SetFormatter(&logrus.JSONFormatter{}) + + // Output to stdout instead of the default stderr + // Can be any io.Writer, see below for File example + log.SetOutput(os.Stdout) + + // Only log the warning severity or above. + log.SetLevel(logrus.InfoLevel) +} + +func main() { + log.Info("Server started. Listening on :8080") + + http.HandleFunc("/", handleRequest) + http.ListenAndServe(":8080", nil) +} + +func handleRequest(w http.ResponseWriter, r *http.Request) { + log.Info("Handling request") + + if r.Method != http.MethodPost { + log.Warn("Method not allowed") + http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) + return + } + + // Extract values from headers + device := r.Header.Get("X-Limit-D") + user := r.Header.Get("X-Limit-U") + + log.Infof("Received request with device=%s and user=%s", device, user) + + var loc Location + decoder := json.NewDecoder(r.Body) + err := decoder.Decode(&loc) + if err != nil { + log.Error("Invalid JSON payload: ", err) + http.Error(w, "Invalid JSON payload", http.StatusBadRequest) + return + } + + log.Infof("Received JSON payload: %+v", loc) + + if loc.Type == "location" { + db, err := sql.Open("mysql", getDBConnectionString()) + if err != nil { + log.Error("Database connection error: ", err) + http.Error(w, fmt.Sprintf("Database connection error: %v", err), http.StatusInternalServerError) + return + } + defer db.Close() + + dt := time.Unix(loc.Tst, 0).Format("2006-01-02 15:04:05") + + _, err = db.Exec("INSERT INTO locations (dt, tid, lat, lon, batt, vac, device, user) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", + dt, loc.Tid, loc.Lat, loc.Lon, loc.Batt, loc.Vac, device, user) + if err != nil { + log.Error("Database insertion error: ", err) + http.Error(w, fmt.Sprintf("Database insertion error: %v", err), http.StatusInternalServerError) + return + } + + log.Info("Location data inserted into the database") + } + + response := make(map[string]interface{}) + // Optionally add objects to return to the app (e.g., friends or cards) + json.NewEncoder(w).Encode(response) + + log.Info("Request handled successfully") +} + +func getDBConnectionString() string { + user := os.Getenv("DB_USER") + password := os.Getenv("DB_PASSWORD") + host := os.Getenv("DB_HOST") + port := os.Getenv("DB_PORT") + dbName := os.Getenv("DB_NAME") + + return fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", user, password, host, port, dbName) +} diff --git a/test-script.sh b/test-script.sh new file mode 100755 index 0000000..a12e3df --- /dev/null +++ b/test-script.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +user=jane +device=phone + +payload=$(jo _type=location \ + t=u \ + batt=11 \ + lat=48.856826 \ + lon=2.292713 \ + tid=JJ \ + tst=$(date +%s) \ + topic="owntracks/$user/$device") + +curl --data "${payload}" http://172.28.0.24:8080/?u=${user}&d=${device}