From ed952b48dfca27a980293167b7db90405b147eda Mon Sep 17 00:00:00 2001
From: blint <rethelyibalint@gmail.com>
Date: Sun, 20 Aug 2023 20:49:12 +0200
Subject: [PATCH] Add API endpoints and middleware for user and product
 manipulation

Introduced API endpoints in api.go for handling product saving, user updates, user retrieval, and cart functionality. Added middleware for checking user and admin permissions. These changes form part of implementing core features of the application and to ensure appropriate security measures are in place.
---
 api/api.go | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 180 insertions(+)
 create mode 100644 api/api.go

diff --git a/api/api.go b/api/api.go
new file mode 100644
index 0000000..baa8b33
--- /dev/null
+++ b/api/api.go
@@ -0,0 +1,180 @@
+package api
+
+import (
+	"encoding/json"
+	"fmt"
+	"git.sch.bme.hu/disappointment-industries/becskasszasch/db"
+	"git.sch.bme.hu/disappointment-industries/becskasszasch/helpers"
+	"git.sch.bme.hu/disappointment-industries/becskasszasch/homepage"
+	"net/http"
+)
+
+var router = http.NewServeMux()
+var Handler = pultoschMW(router)
+
+func init() {
+	router.Handle("/product", adminMW(http.HandlerFunc(ProductHandler)))
+	router.HandleFunc("/products", ProductHandler)
+	router.Handle("/user", adminMW(http.HandlerFunc(UpdateUserHandler)))
+	router.HandleFunc("/users", GetUsers)
+	router.HandleFunc("/cart", BuyInPult)
+}
+
+func adminMW(h http.Handler) http.Handler {
+	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		admin, err := homepage.GetUserInfoBySession(r)
+		if err != nil {
+			helpers.Logger.Println(err)
+			return
+		}
+		if admin.IsAdmin {
+			h.ServeHTTP(w, r)
+		} else {
+			w.WriteHeader(http.StatusForbidden)
+		}
+	})
+}
+
+func pultoschMW(h http.Handler) http.Handler {
+	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		user, err := homepage.GetUserInfoBySession(r)
+		if err != nil {
+			helpers.Logger.Println(err)
+			return
+		}
+		if user.IsPultosch {
+			h.ServeHTTP(w, r)
+		} else {
+			w.WriteHeader(http.StatusForbidden)
+		}
+	})
+}
+
+func ProductHandler(w http.ResponseWriter, r *http.Request) {
+	switch r.Method {
+	case http.MethodPut:
+
+		var product db.Product
+
+		if err := json.NewDecoder(r.Body).Decode(&product); err != nil {
+			http.Error(w, err.Error(), http.StatusBadRequest)
+			return
+		}
+
+		err := product.Save()
+		if err != nil {
+			// TODO: handle error
+			return
+		}
+		w.WriteHeader(http.StatusOK)
+
+	case http.MethodPatch:
+		var product db.Product
+
+		if err := json.NewDecoder(r.Body).Decode(&product); err != nil {
+			http.Error(w, err.Error(), http.StatusBadRequest)
+			return
+		}
+
+		err := product.Save()
+		if err != nil {
+			// TODO: handle error
+			return
+		}
+		w.WriteHeader(http.StatusOK)
+
+	case http.MethodGet:
+		var product db.Product
+		id := r.URL.Query().Get("id")
+		product.ID = id
+
+		product.Load()
+
+		json.NewEncoder(w).Encode(product)
+
+	default:
+		http.Error(w, "Invalid method", http.StatusMethodNotAllowed)
+	}
+}
+
+func UpdateUserHandler(w http.ResponseWriter, r *http.Request) {
+	switch r.Method {
+	case http.MethodPatch:
+		var user db.User
+
+		if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
+			http.Error(w, err.Error(), http.StatusBadRequest)
+			return
+		}
+		oldUser := db.User{SchAcc: user.SchAcc}
+		err := oldUser.Load()
+		if err != nil {
+			// TODO: handle error
+			return
+		}
+		user.Money = oldUser.Money
+		user.Spends = oldUser.Spends
+		user.Name = oldUser.Name
+
+		err = user.Save()
+		if err != nil {
+			// TODO: handle error
+			return
+		}
+		w.WriteHeader(http.StatusOK)
+
+	default:
+		http.Error(w, "Invalid method", http.StatusMethodNotAllowed)
+	}
+}
+
+func GetUsers(w http.ResponseWriter, r *http.Request) {
+	switch r.Method {
+	case http.MethodGet:
+
+		users, err := db.GetUsersSorted(db.GetDB())
+		if err != nil {
+			http.Error(w, err.Error(), http.StatusBadRequest)
+			return
+		}
+
+		json.NewEncoder(w).Encode(users)
+	}
+}
+
+func BuyInPult(w http.ResponseWriter, r *http.Request) {
+	switch r.Method {
+	case http.MethodPost:
+		var boughtInPult BoughtInPult
+
+		err := r.ParseForm()
+		if err != nil {
+			http.Error(w, err.Error(), http.StatusBadRequest)
+			return
+		}
+
+		for key, values := range r.PostForm {
+			fmt.Println(key, values)
+			for _, value := range values {
+				fmt.Printf("Form field %s has value %s\n", key, value)
+			}
+		}
+
+		asd := r.Form["amount"]
+		fmt.Println(asd)
+
+		for _, productInPult := range boughtInPult.ProductsInPult {
+			spend := db.Spend{
+				User:    boughtInPult.User,
+				Product: productInPult.Product,
+				Amount:  productInPult.Amount,
+				Date:    boughtInPult.Date,
+				Notes:   "Pultosch: " + boughtInPult.Pultosch.Name,
+			}
+			err := spend.Save()
+			if err != nil {
+				helpers.Logger.Println(err)
+			}
+		}
+	}
+}
-- 
GitLab