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 JSONResponse payload.OK = false 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 JSONResponse payload.OK = false 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 } func (app *application) failedValidation( w http.ResponseWriter, r *http.Request, errors map[string]string, ) { var payload struct { OK bool `json:"ok"` Message string `json:"message"` Errors map[string]string `json:"errors"` } payload.OK = false payload.Message = "failed validation" payload.Errors = errors app.writeJSON(w, http.StatusUnprocessableEntity, payload) }