initial commit from original sev version
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
package middlewares
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"abuse_registration_poc/internal/handlers"
|
||||
"abuse_registration_poc/internal/utils"
|
||||
)
|
||||
|
||||
type contextKey string
|
||||
|
||||
const (
|
||||
RoleContextKey contextKey = "role"
|
||||
UserIDContextKey contextKey = "userId"
|
||||
)
|
||||
|
||||
func Authenticate(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
|
||||
token := strings.TrimSpace(request.Header.Get("Authorization"))
|
||||
if token == "" {
|
||||
handlers.WriteJSON(writer, http.StatusUnauthorized, map[string]string{"message": "Not authorized."})
|
||||
return
|
||||
}
|
||||
token = strings.TrimPrefix(token, "Bearer ")
|
||||
|
||||
userID, role, err := utils.VerifyToken(token)
|
||||
if err != nil {
|
||||
handlers.WriteJSON(writer, http.StatusUnauthorized, map[string]string{"message": "Not authorized."})
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.WithValue(request.Context(), RoleContextKey, role)
|
||||
ctx = context.WithValue(ctx, UserIDContextKey, userID)
|
||||
next.ServeHTTP(writer, request.WithContext(ctx))
|
||||
})
|
||||
}
|
||||
|
||||
func RoleFromContext(ctx context.Context) (string, bool) {
|
||||
role, ok := ctx.Value(RoleContextKey).(string)
|
||||
return role, ok
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package middlewares
|
||||
|
||||
import "net/http"
|
||||
|
||||
func CORS(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
|
||||
writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
|
||||
writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
|
||||
if request.Method == http.MethodOptions {
|
||||
writer.WriteHeader(http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
next.ServeHTTP(writer, request)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package middlewares
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"abuse_registration_poc/internal/handlers"
|
||||
"abuse_registration_poc/internal/models"
|
||||
)
|
||||
|
||||
var routePermissions = map[string]map[string][]string{
|
||||
"GET": {
|
||||
"/api/v1/categories": {models.RoleReader, models.RoleAdmin},
|
||||
"/api/v1/locations": {models.RoleReader, models.RoleAdmin},
|
||||
"/api/v1/registrations": {models.RoleReader, models.RoleAdmin},
|
||||
"/api/v1/registrations/:id": {models.RoleReader, models.RoleAdmin},
|
||||
},
|
||||
"POST": {
|
||||
"/api/v1/registrations": {models.RoleAdmin},
|
||||
"/api/v1/reset": {models.RoleAdmin},
|
||||
},
|
||||
"PUT": {
|
||||
"/api/v1/registrations/:id": {models.RoleAdmin},
|
||||
},
|
||||
"DELETE": {
|
||||
"/api/v1/registrations/:id": {models.RoleAdmin},
|
||||
},
|
||||
}
|
||||
|
||||
func DynamicAuthorize(routePattern string, next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
|
||||
role, exists := RoleFromContext(request.Context())
|
||||
if !exists {
|
||||
handlers.WriteJSON(writer, http.StatusForbidden, map[string]string{"message": "Access denied."})
|
||||
return
|
||||
}
|
||||
|
||||
if !hasPermission(role, request.Method, routePattern) {
|
||||
handlers.WriteJSON(writer, http.StatusForbidden, map[string]string{"message": "Access denied to this resource."})
|
||||
return
|
||||
}
|
||||
|
||||
next.ServeHTTP(writer, request)
|
||||
})
|
||||
}
|
||||
|
||||
func Protected(routePattern string, next http.Handler) http.Handler {
|
||||
return Authenticate(DynamicAuthorize(routePattern, next))
|
||||
}
|
||||
|
||||
func hasPermission(role string, method string, path string) bool {
|
||||
methodPermissions, ok := routePermissions[method]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
roles, ok := methodPermissions[path]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
for _, allowed := range roles {
|
||||
if allowed == role {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user