spaceapid/main.go
Bendodroid 1a9922d5f1
Change initial SpaceAPI response source
- The environment variable is now called SPACE_API_JSON_TEMPLATE_PATH
- It is now the path to a file with the initial values, not the JSON itself
- Updated README.md accordingly
2023-11-04 23:31:24 +01:00

117 lines
3.3 KiB
Go

package main
import (
"encoding/json"
"io"
"log"
"net/http"
"os"
"path/filepath"
"slices"
"strconv"
"time"
"gitlab.hamburg.ccc.de/ccchh/spaceapid/types"
)
func main() {
var err error
validUsername, success := os.LookupEnv("DOORIS_USERNAME")
if !success || validUsername == "" {
log.Fatalln("Could not retrieve DOORIS_API_KEY env variable or variable is empty")
}
validPassword, success := os.LookupEnv("DOORIS_PASSWORD")
if !success || validPassword == "" {
log.Fatalln("Could not retrieve DOORIS_API_KEY env variable or variable is empty")
}
templatePath, success := os.LookupEnv("SPACE_API_JSON_TEMPLATE_PATH")
if !success || templatePath == "" {
log.Fatalln("Could not retrieve SPACE_API_JSON_TEMPLATE_PATH env variable or variable is empty")
}
templatePathAbs, err := filepath.Abs(templatePath)
if err != nil {
log.Fatalln("Failed converting", templatePath, "to absolute path:", err)
}
log.Println("Reading initial SpaceAPI response from", templatePathAbs)
initialJson, err := os.ReadFile(templatePathAbs)
if err != nil {
log.Fatalln("Failed reading file:", err)
}
spaceApiResponse := new(types.SpaceAPIResponseV14)
err = json.Unmarshal(initialJson, spaceApiResponse)
if err != nil {
log.Fatalln("Could not parse SpaceAPI response template:", err)
}
if !slices.Contains(spaceApiResponse.APICompatibility, "14") {
log.Fatalln("Provided SpaceAPI response doesn't specify compatibility with API version 14")
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
log.Println("Wrong METHOD from", r.RemoteAddr)
w.Header().Set("allow", http.MethodGet)
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
response, err := json.Marshal(spaceApiResponse)
if err != nil {
log.Println("Failed to serialize JSON response:", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
_, _ = w.Write(response)
})
http.HandleFunc("/state/open", func(w http.ResponseWriter, r *http.Request) {
username, password, ok := r.BasicAuth()
if !ok || username != validUsername || password != validPassword {
log.Println("Unauthorized request from", r.RemoteAddr)
w.Header().Set("www-authentication", "Basic realm=\"space-api\"")
w.WriteHeader(http.StatusUnauthorized)
return
}
if r.Method != http.MethodPut {
log.Println("Wrong METHOD from", r.RemoteAddr)
w.Header().Set("allow", http.MethodPut)
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
body, err := io.ReadAll(r.Body)
if err != nil {
log.Println("Failed to read request body from", r.RemoteAddr)
w.WriteHeader(http.StatusInternalServerError)
_, _ = io.WriteString(w, "Failed reading HTTP request body")
return
}
newState, err := strconv.ParseBool(string(body))
if err != nil {
log.Println("Failed to parse request body from", r.RemoteAddr)
w.WriteHeader(http.StatusBadRequest)
_, _ = io.WriteString(w, "HTTP request body should either be true or false")
return
}
spaceApiResponse.State.Open = newState
spaceApiResponse.State.LastChange = time.Now().Unix()
w.WriteHeader(http.StatusOK)
_, _ = io.WriteString(w, "Update Successful")
})
log.Println("Starting HTTP server...")
log.Fatalln(http.ListenAndServe(":8080", nil))
}