spaceapid/main.go
2023-11-04 22:30:39 +01:00

101 lines
2.8 KiB
Go

package main
import (
"encoding/json"
"io"
"log"
"net/http"
"os"
"slices"
"strconv"
"time"
"gitlab.hamburg.ccc.de/ccchh/spaceapid/types"
)
func main() {
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")
}
initialJson, success := os.LookupEnv("SPACE_API_JSON")
if !success || initialJson == "" {
log.Fatalln("Could not retrieve SPACE_API_JSON env variable or variable is empty")
}
spaceApiResponse := new(types.SpaceAPIResponseV14)
err := json.Unmarshal([]byte(initialJson), spaceApiResponse)
if err != nil {
log.Fatalln("Could not parse provided JSON")
}
if !slices.Contains(spaceApiResponse.APICompatibility, "14") {
log.Fatalln("Provided JSON 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")
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 body status update request 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 {
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))
}