package api import ( "encoding/json" "errors" "log" "net/http" "strconv" "github.com/gorilla/mux" "gorm.io/gorm" ) type Member struct { gorm.Model `json:"-"` Num int `json:"num" gorm:"unique;index"` Name string `json:"name" gorm:"unique;index"` Email string `json:"email"` Balance int `json:"balance"` Role string `json:"role"` PassHash []byte `json:"-"` Salt []byte `json:"-"` } func (a *api) AddMember(w http.ResponseWriter, req *http.Request) { var memberReq struct { Member Password string `json:"password"` } err := json.NewDecoder(req.Body).Decode(&memberReq) if err != nil { log.Printf("Can't create member: %v", err) w.WriteHeader(http.StatusInternalServerError) return } member := Member{ Num: memberReq.Num, Name: memberReq.Name, Email: memberReq.Email, Balance: memberReq.Balance, Role: memberReq.Role, } member.PassHash, member.Salt, err = newHashPass(memberReq.Password) if err != nil { log.Printf("Can't hash new member: %v\n%v", err, member) w.WriteHeader(http.StatusInternalServerError) return } err = a.db.Create(&member).Error if err != nil { log.Printf("Can't create member: %v\n%v", err, member) w.WriteHeader(http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) err = json.NewEncoder(w).Encode(member) if err != nil { log.Printf("Can't encode added member: %v", err) w.WriteHeader(http.StatusInternalServerError) return } } func (a *api) ListMembers(w http.ResponseWriter, req *http.Request) { var members []Member err := a.db.Find(&members).Error if err != nil { log.Printf("Can't list members: %v", err) w.WriteHeader(http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) err = json.NewEncoder(w).Encode(members) if err != nil { log.Printf("Can't encode members: %v", err) w.WriteHeader(http.StatusInternalServerError) return } } func (a *api) GetMember(w http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) num, _ := strconv.Atoi(vars["num"]) a.getMemberNum(num, w, req) } func (a *api) getMemberNum(num int, w http.ResponseWriter, req *http.Request) { var member Member err := a.db.Where("num = ?", num).First(&member).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { w.WriteHeader(http.StatusNotFound) return } log.Printf("Can't get member %d: %v", num, err) w.WriteHeader(http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) err = json.NewEncoder(w).Encode(member) if err != nil { log.Printf("Can't encode member: %v", err) w.WriteHeader(http.StatusInternalServerError) return } } func (a *api) DeleteMember(w http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) err := a.db.Where("num = ?", vars["num"]).Delete(&Member{}).Error if err != nil { log.Printf("Can't delete member %s: %v", vars["num"], err) w.WriteHeader(http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) } func (a *api) UpdateMember(w http.ResponseWriter, req *http.Request) { var member Member err := json.NewDecoder(req.Body).Decode(&member) if err != nil { log.Printf("Can't decode memeber: %v", err) w.WriteHeader(http.StatusInternalServerError) return } vars := mux.Vars(req) var dbMember Member err = a.db.Where("num = ?", vars["num"]).First(&dbMember).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { w.WriteHeader(http.StatusNotFound) return } log.Printf("Can't get member %s: %v", vars["num"], err) w.WriteHeader(http.StatusInternalServerError) return } if member.Num != 0 { dbMember.Num = member.Num } if member.Name != "" { dbMember.Name = member.Name } if member.Email != "" { dbMember.Email = member.Email } if member.Balance >= 0 { dbMember.Balance = member.Balance } err = a.db.Save(&dbMember).Error if err != nil { log.Printf("Can't update member %s: %v %v", vars["num"], err, member) w.WriteHeader(http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusAccepted) err = json.NewEncoder(w).Encode(dbMember) if err != nil { log.Printf("Can't encode updated memeber: %v", err) w.WriteHeader(http.StatusInternalServerError) return } }