mirror of
https://github.com/h44z/wg-portal.git
synced 2025-04-19 08:55:12 +00:00
117 lines
3.7 KiB
Go
117 lines
3.7 KiB
Go
package handlers
|
|
|
|
import (
|
|
"context"
|
|
"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/core/middleware/csrf"
|
|
"github.com/h44z/wg-portal/internal/app/api/core/respond"
|
|
)
|
|
|
|
type SessionMiddleware interface {
|
|
// SetData sets the session data for the given context.
|
|
SetData(ctx context.Context, val SessionData)
|
|
// GetData returns the session data for the given context. If no data is found, the default session data is returned.
|
|
GetData(ctx context.Context) SessionData
|
|
// DestroyData destroys the session data for the given context.
|
|
DestroyData(ctx context.Context)
|
|
|
|
// GetString returns the string value for the given key. If no value is found, an empty string is returned.
|
|
GetString(ctx context.Context, key string) string
|
|
// Put sets the value for the given key.
|
|
Put(ctx context.Context, key string, value any)
|
|
// LoadAndSave is a middleware that loads the session data for the given request and saves it after the request is
|
|
// finished.
|
|
LoadAndSave(next http.Handler) http.Handler
|
|
}
|
|
|
|
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 SPA-UI API
|
|
// @version 0.0
|
|
// @description WireGuard Portal API - UI Endpoints
|
|
|
|
// @contact.name WireGuard Portal Developers
|
|
// @contact.url https://github.com/h44z/wg-portal
|
|
|
|
// @BasePath /api/v0
|
|
// @query.collection.format multi
|
|
|
|
func NewRestApi(
|
|
session SessionMiddleware,
|
|
handlers ...Handler,
|
|
) core.ApiEndpointSetupFunc {
|
|
return func() (core.ApiVersion, core.GroupSetupFn) {
|
|
return "v0", func(group *routegroup.Bundle) {
|
|
csrfMiddleware := csrf.New(func(r *http.Request) string {
|
|
return session.GetString(r.Context(), "csrf_token")
|
|
}, func(r *http.Request, token string) {
|
|
session.Put(r.Context(), "csrf_token", token)
|
|
})
|
|
|
|
group.Use(session.LoadAndSave)
|
|
group.Use(csrfMiddleware.Handler)
|
|
group.Use(cors.New().Handler)
|
|
|
|
group.With(csrfMiddleware.RefreshToken).HandleFunc("GET /csrf", handleCsrfGet())
|
|
|
|
// Handler functions
|
|
for _, h := range handlers {
|
|
h.RegisterRoutes(group)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// handleCsrfGet returns a gorm Handler function.
|
|
//
|
|
// @ID base_handleCsrfGet
|
|
// @Tags Security
|
|
// @Summary Get a CSRF token for the current session.
|
|
// @Produce json
|
|
// @Success 200 {object} string
|
|
// @Router /csrf [get]
|
|
func handleCsrfGet() http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
respond.JSON(w, http.StatusOK, csrf.GetToken(r.Context()))
|
|
}
|
|
}
|
|
|
|
// 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
|
|
// UserIdMatch checks if the user id in the session matches the user id in the request. If not, the request is aborted.
|
|
UserIdMatch(idParameter string) func(next http.Handler) http.Handler
|
|
}
|
|
|
|
type Session interface {
|
|
// SetData sets the session data for the given context.
|
|
SetData(ctx context.Context, val SessionData)
|
|
// GetData returns the session data for the given context. If no data is found, the default session data is returned.
|
|
GetData(ctx context.Context) SessionData
|
|
// DestroyData destroys the session data for the given context.
|
|
DestroyData(ctx context.Context)
|
|
}
|
|
|
|
type Validator interface {
|
|
// Struct validates the given struct.
|
|
Struct(s interface{}) error
|
|
}
|
|
|
|
// endregion handler-interfaces
|