package main import ( "arbeitszeitmessung/models" "encoding/json" "errors" "fmt" "log" "net/http" "os" "strconv" _ "github.com/lib/pq" ) func main() { var err error models.DB, err = OpenDatabase() if err != nil { log.Fatal(err) } defer models.DB.Close() http.HandleFunc("/time/new", timeCreateHandler) http.HandleFunc("/time", timeHandler) fmt.Printf("Server is running at http://localhost:8000 exposed to port %s\n", getEnv("EXPOSED_PORT", "8000")) log.Fatal(http.ListenAndServe(":8000", nil)) } func timeCreateHandler(w http.ResponseWriter, r *http.Request) { setCors(w) switch r.Method { case "PUT": createBooking(w, r) case "OPTIONS": w.WriteHeader(http.StatusOK) default: http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) } } func timeHandler(w http.ResponseWriter, r *http.Request) { setCors(w) switch r.Method { case "GET": getBookings(w, r) case "PUT": updateBooking(w, r) case "OPTIONS": w.WriteHeader(http.StatusOK) default: http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) } } func createBooking(w http.ResponseWriter, r *http.Request) { booking := (*models.Booking).FromUrlParams(nil, r.URL.Query()) if booking.Verify() { err := booking.Insert() if errors.Is(models.SameBookingError{}, err) { http.Error(w, "Booking already exists", http.StatusConflict) return } if err != nil { log.Println("Error inserting booking: ", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) json.NewEncoder(w).Encode(booking) } w.WriteHeader(http.StatusBadRequest) } func getBookings(w http.ResponseWriter, r *http.Request) { card_id := r.URL.Query().Get("card_uid") if card_id == "" { http.Error(w, "Missing cardID query parameter", http.StatusBadRequest) return } bookings, err := (*models.Booking).GetBookingsByCardID(nil, card_id) if err != nil { log.Println("Error getting bookings: ", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(bookings) } func updateBooking(w http.ResponseWriter, r *http.Request) { _booking_id := r.URL.Query().Get("counter_id") if _booking_id == "" { http.Error(w, "Missing bookingID query parameter", http.StatusBadRequest) return } booking_id, err := strconv.Atoi(_booking_id) if err != nil { http.Error(w, "Invalid bookingID query parameter", http.StatusBadRequest) return } _booking, err := (*models.Booking).GetBookingById(nil, booking_id) if err != nil { log.Println("Error getting booking: ", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } var booking models.Booking dec := json.NewDecoder(r.Body) dec.DisallowUnknownFields() err = dec.Decode(&booking) if err != nil { log.Println("Error parsing booking: ", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } if booking.CounterId != 0 && booking.CounterId != _booking.CounterId { log.Println("Booking Ids do not match") http.Error(w, "Booking Ids do not match", http.StatusBadRequest) return } _booking.Update(booking) _booking.Save() w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(_booking) } // func getBooking(w http.ResponseWriter, r *http.Request) func getEnv(key, fallback string) string { if value, ok := os.LookupEnv(key); ok { return value } return fallback } func setCors(w http.ResponseWriter) { if os.Getenv("DEBUG") == "true" { w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Methods", "*") w.Header().Set("Access-Control-Allow-Headers", "*") } }