// Copyright (c) 2025 Nikolai Papin // // This file is part of Easywish // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See // the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . package middleware import ( "easywish/internal/utils/enums" "net/http" "github.com/gin-gonic/gin" ) type UserInfo struct { Username string Role enums.Role } type Request[T any] struct { User UserInfo Body T } const requestKey = "request" func UserInfoFromContext(c *gin.Context) (*UserInfo, bool) { var username any var role any var ok bool username, ok = c.Get("username") ; if !ok { return &UserInfo{Username: "", Role: enums.GuestRole}, true } role, ok = c.Get("role"); if !ok { return nil, false } if username == nil { return &UserInfo{Username: "", Role: enums.GuestRole}, true } if role == nil { return nil, false } return &UserInfo{Username: username.(string), Role: role.(enums.Role)}, true } func RequestFromContext[T any](c *gin.Context) Request[T] { return c.Value(requestKey).(Request[T]) } func RequestMiddleware[T any](role enums.Role) gin.HandlerFunc { return gin.HandlerFunc(func(c *gin.Context) { userInfo, ok := UserInfoFromContext(c) if !ok { c.Status(http.StatusUnauthorized) return } if userInfo.Role < role { c.Status(http.StatusForbidden) return } var body T if err := c.ShouldBindJSON(&body); err != nil { c.String(http.StatusBadRequest, err.Error()) return } request := Request[T]{ User: *userInfo, Body: body, } c.Set(requestKey, request) c.Next() }) }