package main import ( "encoding/json" "errors" "io" "net/http" "golang.org/x/crypto/bcrypt" ) func (app *application) readJSON(w http.ResponseWriter, r *http.Request, data interface{}) error { maxBytes := 1048576 r.Body = http.MaxBytesReader(w, r.Body, int64(maxBytes)) dec := json.NewDecoder(r.Body) err := dec.Decode(data) if err != nil { return err } // Make sure there is only one entry. err = dec.Decode(&struct{}{}) if err != io.EOF { return errors.New("body must only have a single JSON value") } return nil } // writeJSON writes arbitrary data out as JSON func (app *application) writeJSON( w http.ResponseWriter, status int, data interface{}, headers ...http.Header, ) error { out, err := json.MarshalIndent(data, "", "\t") if err != nil { return err } if len(headers) > 0 { for k, v := range headers[0] { w.Header()[k] = v } } w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) w.Write(out) return nil } func (app *application) badRequest(w http.ResponseWriter, r *http.Request, err error) error { var payload struct { Error bool `json:"error"` Message string `json:"message"` } payload.Error = true payload.Message = err.Error() out, err := json.MarshalIndent(payload, "", "\t") if err != nil { return err } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusBadGateway) w.Write(out) return nil } func (app *application) invalidCredentials(w http.ResponseWriter) error { var payload struct { Error bool `json:"error"` Message string `json:"message"` } payload.Error = true payload.Message = "invalid authentication credentials" err := app.writeJSON(w, http.StatusUnauthorized, payload) if err != nil { return err } return nil } func (app *application) passwordMatches(hash, password string) (bool, error) { app.errorLog.Println(hash, password) err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) if err != nil { switch { case errors.Is(err, bcrypt.ErrMismatchedHashAndPassword): return false, nil default: return false, err } } return true, nil }