From a441b32900d935bec38989f5dcfc9047d88914e0 Mon Sep 17 00:00:00 2001 From: lbenedar Date: Fri, 20 Mar 2026 18:59:26 +0300 Subject: [PATCH] ch17.4 --- cmd/api/errors.go | 5 +++++ cmd/api/middleware.go | 20 ++++++++++++++++++++ cmd/api/routes.go | 10 +++++----- internal/data/permissions.go | 2 +- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/cmd/api/errors.go b/cmd/api/errors.go index c27467f..5b6a71d 100644 --- a/cmd/api/errors.go +++ b/cmd/api/errors.go @@ -78,3 +78,8 @@ func (app *application) inactiveAccountResponse(w http.ResponseWriter, r *http.R message := "your user account must be activated to access this resource" app.errorResponse(w, r, http.StatusForbidden, message) } + +func (app *application) notPermittedResponse(w http.ResponseWriter, r *http.Request) { + message := "your user account doesn't have the necessary permissions to access this resource" + app.errorResponse(w, r, http.StatusForbidden, message) +} diff --git a/cmd/api/middleware.go b/cmd/api/middleware.go index 9f15592..4d8acba 100644 --- a/cmd/api/middleware.go +++ b/cmd/api/middleware.go @@ -150,3 +150,23 @@ func (app *application) requireActivatedUser(next http.HandlerFunc) http.Handler }) return app.requireAuthenticatedUser(fn) } + +func (app *application) requirePermissions(code string, next http.HandlerFunc) http.HandlerFunc { + fn := func(w http.ResponseWriter, r *http.Request) { + user := app.contextGetUser(r) + + permissions, err := app.models.Permissions.GetAllForUser(user.ID) + if err != nil { + app.serverErrorResponse(w, r, err) + return + } + + if !permissions.Include(code) { + app.notPermittedResponse(w, r) + return + } + + next.ServeHTTP(w, r) + } + return app.requireActivatedUser(fn) +} diff --git a/cmd/api/routes.go b/cmd/api/routes.go index c203671..616dd2c 100644 --- a/cmd/api/routes.go +++ b/cmd/api/routes.go @@ -14,11 +14,11 @@ func (app *application) routes() http.Handler { router.HandlerFunc(http.MethodGet, "/v1/healthcheck", app.healthcheckHandler) - router.HandlerFunc(http.MethodGet, "/v1/movies", app.requireActivatedUser(app.listMoviesHandler)) - router.HandlerFunc(http.MethodPost, "/v1/movies", app.requireActivatedUser(app.createMovieHandler)) - router.HandlerFunc(http.MethodGet, "/v1/movies/:id", app.requireActivatedUser(app.showMovieHandler)) - router.HandlerFunc(http.MethodPatch, "/v1/movies/:id", app.requireActivatedUser(app.updateMovieHandler)) - router.HandlerFunc(http.MethodDelete, "/v1/movies/:id", app.requireActivatedUser(app.deleteMovieHandler)) + router.HandlerFunc(http.MethodGet, "/v1/movies", app.requirePermissions("movies:read", app.listMoviesHandler)) + router.HandlerFunc(http.MethodPost, "/v1/movies", app.requirePermissions("movies:write", app.createMovieHandler)) + router.HandlerFunc(http.MethodGet, "/v1/movies/:id", app.requirePermissions("movies:read", app.showMovieHandler)) + router.HandlerFunc(http.MethodPatch, "/v1/movies/:id", app.requirePermissions("movies:write", app.updateMovieHandler)) + router.HandlerFunc(http.MethodDelete, "/v1/movies/:id", app.requirePermissions("movies:write", app.deleteMovieHandler)) router.HandlerFunc(http.MethodPost, "/v1/users", app.registerUserHandler) router.HandlerFunc(http.MethodPut, "/v1/users/activated", app.activateUserHandler) diff --git a/internal/data/permissions.go b/internal/data/permissions.go index 571473f..276df41 100644 --- a/internal/data/permissions.go +++ b/internal/data/permissions.go @@ -1,4 +1,4 @@ -package main +package data import ( "context"