Skip to content

Commit

Permalink
Update legacy errors, middleware and logger package
Browse files Browse the repository at this point in the history
Also, remove log request middleware from auth module and use it from global internal package
  • Loading branch information
jessicatarra committed Dec 11, 2023
1 parent 404f359 commit 3776bb9
Show file tree
Hide file tree
Showing 21 changed files with 144 additions and 385 deletions.
74 changes: 0 additions & 74 deletions cmd/api/errors.go

This file was deleted.

3 changes: 2 additions & 1 deletion cmd/api/healthcheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"github.com/jessicatarra/greenlight/internal/config"
"github.com/jessicatarra/greenlight/internal/errors"
"net/http"
)

Expand All @@ -16,6 +17,6 @@ func (app *application) healthcheckHandler(writer http.ResponseWriter, request *
}
err := app.writeJSON(writer, http.StatusOK, env, nil)
if err != nil {
app.serverErrorResponse(writer, request, err)
errors.ServerError(writer, request, err)
}
}
31 changes: 18 additions & 13 deletions cmd/api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@ import (
"expvar"
"github.com/jessicatarra/greenlight/internal/config"
"github.com/jessicatarra/greenlight/internal/database"
"github.com/jessicatarra/greenlight/internal/jsonlog"
"github.com/jessicatarra/greenlight/internal/mailer"
_auth "github.com/jessicatarra/greenlight/ms/auth"
"log/slog"
"os"
"runtime"
"runtime/debug"
"sync"
"time"
)

type application struct {
config config.Config
logger *jsonlog.Logger
logger *slog.Logger
models database.Models
mailer mailer.Mailer
wg sync.WaitGroup
Expand All @@ -32,19 +33,27 @@ type application struct {
// @in header
// @name Authorization
func main() {
logger := jsonlog.New(os.Stdout, jsonlog.LevelInfo)
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug}))

err := run(logger)
if err != nil {
trace := string(debug.Stack())
logger.Error(err.Error(), "trace", trace)
os.Exit(1)
}
}

func run(logger *slog.Logger) error {
cfg, err := config.Init()
if err != nil {
logger.PrintFatal(err, nil)
return err
}

db, err := database.New(cfg.DB.Dsn, cfg.DB.MaxOpenConns, cfg.DB.MaxIdleConns, cfg.DB.MaxIdleTime, true)
if err != nil {
logger.PrintFatal(err, nil)
return err
}
defer db.Close()
logger.PrintInfo("database connection pool established", nil)

initMetrics(db)

Expand All @@ -53,13 +62,9 @@ func main() {
monolith := NewModularMonolith(&app.wg)

monolith.AddModule(NewModule(cfg, app.routes(), app.logger))
monolith.AddModule(_auth.NewModule(db, cfg, &app.wg))
monolith.AddModule(_auth.NewModule(db, cfg, &app.wg, app.logger))

err = monolith.Run()
if err != nil {
logger.PrintFatal(err, nil)
return
}
return monolith.Run()
}

func initMetrics(db *sql.DB) {
Expand All @@ -78,7 +83,7 @@ func initMetrics(db *sql.DB) {
}))
}

func newLegacyApplication(cfg config.Config, logger *jsonlog.Logger, db *sql.DB) *application {
func newLegacyApplication(cfg config.Config, logger *slog.Logger, db *sql.DB) *application {
return &application{
config: cfg,
logger: logger,
Expand Down
38 changes: 13 additions & 25 deletions cmd/api/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,14 @@ package main
import (
"errors"
"github.com/jessicatarra/greenlight/internal/database"
_errors "github.com/jessicatarra/greenlight/internal/errors"
"github.com/pascaldekloe/jwt"
"net/http"
"strconv"
"strings"
"time"
)

func (app *application) logRequest(next http.Handler) http.Handler {
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
app.logger.PrintInfo("request", map[string]string{
"request_remote_addr": request.RemoteAddr,
"request_proto": request.Proto,
"request_method": request.Method,
"request_url_request_uri": request.URL.RequestURI(),
})

next.ServeHTTP(writer, request)
})
}

// TODO: relocate following middleware into auth module and remote called then from legacy module

func (app *application) authenticate(next http.Handler) http.Handler {
Expand All @@ -36,44 +24,44 @@ func (app *application) authenticate(next http.Handler) http.Handler {
}
headerParts := strings.Split(authorizationHeader, " ")
if len(headerParts) != 2 || headerParts[0] != "Bearer" {
app.invalidAuthenticationTokenResponse(writer, request)
_errors.InvalidAuthenticationToken(writer, request)
return
}
token := headerParts[1]

claims, err := jwt.HMACCheck([]byte(token), []byte(app.config.Jwt.Secret))
if err != nil {
app.invalidAuthenticationTokenResponse(writer, request)
_errors.InvalidAuthenticationToken(writer, request)
return
}

if !claims.Valid(time.Now()) {
app.invalidAuthenticationTokenResponse(writer, request)
_errors.InvalidAuthenticationToken(writer, request)
return
}
if claims.Issuer != "greenlight.tarralva.com" {
app.invalidAuthenticationTokenResponse(writer, request)
_errors.InvalidAuthenticationToken(writer, request)
return
}
if !claims.AcceptAudience("greenlight.tarralva.com") {
app.invalidAuthenticationTokenResponse(writer, request)
_errors.InvalidAuthenticationToken(writer, request)
return
}

userID, err := strconv.ParseInt(claims.Subject, 10, 64)
if err != nil {
app.serverErrorResponse(writer, request, err)
_errors.ServerError(writer, request, err)
return
}
user, err := app.models.Users.Get(userID)

if err != nil {
switch {
case errors.Is(err, database.ErrRecordNotFound):
app.invalidAuthenticationTokenResponse(writer, request)
_errors.InvalidAuthenticationToken(writer, request)

default:
app.serverErrorResponse(writer, request, err)
_errors.ServerError(writer, request, err)
}
return
}
Expand All @@ -88,12 +76,12 @@ func (app *application) requireActivatedUser(next http.HandlerFunc) http.Handler
user := app.contextGetUser(request)

if user.IsAnonymous() {
app.authenticationRequiredResponse(writer, request)
_errors.AuthenticationRequired(writer, request)
return
}

if !user.Activated {
app.inactiveAccountResponse(writer, request)
_errors.InactiveAccount(writer, request)
return
}

Expand All @@ -107,11 +95,11 @@ func (app *application) requirePermission(code string, next http.HandlerFunc) ht

permissions, err := app.models.Permissions.GetAllForUser(user.ID)
if err != nil {
app.serverErrorResponse(writer, request, err)
_errors.ServerError(writer, request, err)
return
}
if !permissions.Include(code) {
app.notPermittedResponse(writer, request)
_errors.NotPermitted(writer, request)
return
}

Expand Down
Loading

0 comments on commit 3776bb9

Please sign in to comment.