From eaabd28fc2212b5cdee4f768e14c4d22a6e41b8b Mon Sep 17 00:00:00 2001 From: vinchent Date: Wed, 28 Aug 2024 20:54:54 +0200 Subject: [PATCH] Add handler to auth servic --- authentication-service/cmd/api/handlers.go | 40 ++++++++++++ authentication-service/cmd/api/helpers.go | 75 ++++++++++++++++++++++ authentication-service/cmd/api/routes.go | 2 + 3 files changed, 117 insertions(+) create mode 100644 authentication-service/cmd/api/handlers.go create mode 100644 authentication-service/cmd/api/helpers.go diff --git a/authentication-service/cmd/api/handlers.go b/authentication-service/cmd/api/handlers.go new file mode 100644 index 0000000..8b03218 --- /dev/null +++ b/authentication-service/cmd/api/handlers.go @@ -0,0 +1,40 @@ +package main + +import ( + "errors" + "fmt" + "net/http" +) + +func (app *Config) Authenticate(w http.ResponseWriter, r *http.Request) { + var requestPayload struct { + Email string `json:"email"` + Password string `json:"password"` + } + + err := app.readJSON(w, r, &requestPayload) + if err != nil { + app.errorJSON(w, err, http.StatusBadRequest) + return + } + + user, err := app.Models.User.GetByEmail(requestPayload.Email) + if err != nil { + // user not found + app.errorJSON(w, errors.New("invalid credentials"), http.StatusBadRequest) + return + } + + valid, err := user.PasswordMatches(requestPayload.Password) + if err != nil || !valid { + app.errorJSON(w, errors.New("invalid credentials"), http.StatusBadRequest) + return + } + payload := jsonResponse{ + Error: false, + Message: fmt.Sprintf("%s %s is authorized to log in.", user.FirstName, user.LastName), + Data: user, + } + + app.writeJSON(w, http.StatusAccepted, payload) +} diff --git a/authentication-service/cmd/api/helpers.go b/authentication-service/cmd/api/helpers.go new file mode 100644 index 0000000..fa14808 --- /dev/null +++ b/authentication-service/cmd/api/helpers.go @@ -0,0 +1,75 @@ +package main + +import ( + "encoding/json" + "errors" + "io" + "net/http" +) + +type jsonResponse struct { + Error bool `json:"error"` + Message string `json:"message"` + Data any `json:"data,omitempty"` +} + +func (app *Config) readJSON(w http.ResponseWriter, r *http.Request, data any) error { + maxBytes := 1048576 // one megabyte + + r.Body = http.MaxBytesReader(w, r.Body, int64(maxBytes)) + + dec := json.NewDecoder(r.Body) + + err := dec.Decode(data) + if err != nil { + return err + } + + err = dec.Decode(&struct{}{}) + if err != io.EOF { + return errors.New("body must have only a single JSON value") + } + + return nil +} + +func (app *Config) writeJSON( + w http.ResponseWriter, + status int, + data any, + headers ...http.Header, +) error { + out, err := json.Marshal(data) + if err != nil { + return err + } + + if len(headers) > 0 { + for key, value := range headers[0] { + w.Header()[key] = value + } + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(status) + _, err = w.Write(out) + if err != nil { + return err + } + + return nil +} + +func (app *Config) errorJSON(w http.ResponseWriter, err error, status ...int) error { + statusCode := http.StatusBadRequest + + if len(status) > 0 { + statusCode = status[0] + } + + var payload jsonResponse + payload.Error = true + payload.Message = err.Error() + + return app.writeJSON(w, statusCode, payload) +} diff --git a/authentication-service/cmd/api/routes.go b/authentication-service/cmd/api/routes.go index def0f4f..8e83552 100644 --- a/authentication-service/cmd/api/routes.go +++ b/authentication-service/cmd/api/routes.go @@ -23,5 +23,7 @@ func (app *Config) routes() http.Handler { mux.Use(middleware.Heartbeat("/ping")) + mux.Post("/authenticate", app.Authenticate) + return mux }