77 "strings"
88
99 "golang-rest-api-template/pkg/cache"
10+ "golang-rest-api-template/pkg/middleware"
1011 "golang-rest-api-template/pkg/models"
1112 "golang-rest-api-template/pkg/repository"
1213 "golang-rest-api-template/pkg/service"
@@ -80,6 +81,19 @@ func parseOffsetLimit(c *gin.Context) (offset, limit int, ok bool) {
8081 return o , l , true
8182}
8283
84+ // contextUserID returns the authenticated users.id set by middleware.JWTAuth.
85+ func contextUserID (c * gin.Context ) (uint , bool ) {
86+ if c == nil {
87+ return 0 , false
88+ }
89+ v , ok := c .Get (middleware .ContextUserID )
90+ if ! ok {
91+ return 0 , false
92+ }
93+ id , ok := v .(uint )
94+ return id , ok && id > 0
95+ }
96+
8397// @BasePath /api/v1
8498
8599// Healthcheck godoc
@@ -146,12 +160,17 @@ func (h *bookHandler) FindBooks(c *gin.Context) {
146160// @Failure 500 {string} string "Internal Server Error"
147161// @Router /books [post]
148162func (h * bookHandler ) CreateBook (c * gin.Context ) {
163+ ownerID , ok := contextUserID (c )
164+ if ! ok {
165+ c .JSON (http .StatusUnauthorized , gin.H {"error" : "Unauthorized" })
166+ return
167+ }
149168 var input models.CreateBook
150169 if err := c .ShouldBindJSON (& input ); err != nil {
151170 c .JSON (http .StatusBadRequest , gin.H {"error" : err .Error ()})
152171 return
153172 }
154- book , err := h .svc .CreateBook (c .Request .Context (), input .Title , input .Author )
173+ book , err := h .svc .CreateBook (c .Request .Context (), ownerID , input .Title , input .Author )
155174 if err != nil {
156175 c .JSON (http .StatusInternalServerError , gin.H {"error" : "Failed to create book" })
157176 return
@@ -199,10 +218,16 @@ func (h *bookHandler) FindBook(c *gin.Context) {
199218// @Success 200 {object} models.Book "Successfully updated book"
200219// @Failure 400 {string} string "Bad Request"
201220// @Failure 401 {string} string "Unauthorized"
221+ // @Failure 403 {string} string "Forbidden"
202222// @Failure 404 {string} string "book not found"
203223// @Failure 500 {string} string "Internal Server Error"
204224// @Router /books/{id} [put]
205225func (h * bookHandler ) UpdateBook (c * gin.Context ) {
226+ actorID , ok := contextUserID (c )
227+ if ! ok {
228+ c .JSON (http .StatusUnauthorized , gin.H {"error" : "Unauthorized" })
229+ return
230+ }
206231 var input models.UpdateBook
207232 id , ok := parseIDParam (c )
208233 if ! ok {
@@ -212,12 +237,16 @@ func (h *bookHandler) UpdateBook(c *gin.Context) {
212237 c .JSON (http .StatusBadRequest , gin.H {"error" : err .Error ()})
213238 return
214239 }
215- book , err := h .svc .UpdateBook (c .Request .Context (), id , input .Title , input .Author )
240+ book , err := h .svc .UpdateBook (c .Request .Context (), actorID , id , input .Title , input .Author )
216241 if err != nil {
217242 if repository .IsBookNotFound (err ) {
218243 c .JSON (http .StatusNotFound , gin.H {"error" : "book not found" })
219244 return
220245 }
246+ if errors .Is (err , service .ErrBookForbidden ) {
247+ c .JSON (http .StatusForbidden , gin.H {"error" : "forbidden" })
248+ return
249+ }
221250 c .JSON (http .StatusInternalServerError , gin.H {"error" : "Failed to update book" })
222251 return
223252 }
@@ -234,19 +263,29 @@ func (h *bookHandler) UpdateBook(c *gin.Context) {
234263// @Param id path string true "Book ID"
235264// @Success 204 "Successfully deleted book"
236265// @Failure 401 {string} string "Unauthorized"
266+ // @Failure 403 {string} string "Forbidden"
237267// @Failure 404 {string} string "book not found"
238268// @Failure 500 {string} string "Internal Server Error"
239269// @Router /books/{id} [delete]
240270func (h * bookHandler ) DeleteBook (c * gin.Context ) {
271+ actorID , ok := contextUserID (c )
272+ if ! ok {
273+ c .JSON (http .StatusUnauthorized , gin.H {"error" : "Unauthorized" })
274+ return
275+ }
241276 id , ok := parseIDParam (c )
242277 if ! ok {
243278 return
244279 }
245- if err := h .svc .DeleteBook (c .Request .Context (), id ); err != nil {
280+ if err := h .svc .DeleteBook (c .Request .Context (), actorID , id ); err != nil {
246281 if repository .IsBookNotFound (err ) {
247282 c .JSON (http .StatusNotFound , gin.H {"error" : "book not found" })
248283 return
249284 }
285+ if errors .Is (err , service .ErrBookForbidden ) {
286+ c .JSON (http .StatusForbidden , gin.H {"error" : "forbidden" })
287+ return
288+ }
250289 c .JSON (http .StatusInternalServerError , gin.H {"error" : "Failed to delete book" })
251290 return
252291 }
0 commit comments