2025-03-09 21:48:38 +01:00

95 lines
2.6 KiB
Go

package handlers
import (
"errors"
"net/http"
"github.com/go-pkgz/routegroup"
"github.com/h44z/wg-portal/internal/app/api/core"
"github.com/h44z/wg-portal/internal/app/api/core/middleware/cors"
"github.com/h44z/wg-portal/internal/app/api/v1/models"
"github.com/h44z/wg-portal/internal/domain"
)
type Handler interface {
// GetName returns the name of the handler.
GetName() string
// RegisterRoutes registers the routes for the handler. The session manager is passed to the handler.
RegisterRoutes(g *routegroup.Bundle)
}
// To compile the API documentation use the
// api_build_tool
// command that can be found in the $PROJECT_ROOT/cmd/api_build_tool directory.
// @title WireGuard Portal Public API
// @version 1.0
// @description The WireGuard Portal REST API enables efficient management of WireGuard VPN configurations through a set of JSON-based endpoints.
// @description It supports creating and editing peers, interfaces, and user profiles, while also providing role-based access control and auditing.
// @description This API allows seamless integration with external tools or scripts for automated network configuration and administration.
// @license.name MIT
// @license.url https://github.com/h44z/wg-portal/blob/master/LICENSE.txt
// @contact.name WireGuard Portal Project
// @contact.url https://github.com/h44z/wg-portal
// @securityDefinitions.basic BasicAuth
// @BasePath /api/v1
// @query.collection.format multi
func NewRestApi(handlers ...Handler) core.ApiEndpointSetupFunc {
return func() (core.ApiVersion, core.GroupSetupFn) {
return "v1", func(group *routegroup.Bundle) {
group.Use(cors.New().Handler)
// Handler functions
for _, h := range handlers {
h.RegisterRoutes(group)
}
}
}
}
func ParseServiceError(err error) (int, models.Error) {
if err == nil {
return 500, models.Error{
Code: 500,
Message: "unknown server error",
}
}
code := http.StatusInternalServerError
switch {
case errors.Is(err, domain.ErrNotFound):
code = http.StatusNotFound
case errors.Is(err, domain.ErrNoPermission):
code = http.StatusForbidden
case errors.Is(err, domain.ErrDuplicateEntry):
code = http.StatusConflict
case errors.Is(err, domain.ErrInvalidData):
code = http.StatusBadRequest
}
return code, models.Error{
Code: code,
Message: err.Error(),
}
}
// region handler-interfaces
type Authenticator interface {
// LoggedIn checks if a user is logged in. If scopes are given, they are validated as well.
LoggedIn(scopes ...Scope) func(next http.Handler) http.Handler
}
type Validator interface {
// Struct validates the given struct.
Struct(s interface{}) error
}
// endregion handler-interfaces