mirror of https://github.com/h44z/wg-portal.git
				
				
				
			
		
			
				
	
	
		
			121 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			3.9 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.GetData(r.Context()).CsrfToken
 | 
						|
			}, func(r *http.Request, token string) {
 | 
						|
				currentSession := session.GetData(r.Context())
 | 
						|
				currentSession.CsrfToken = token
 | 
						|
				session.SetData(r.Context(), currentSession)
 | 
						|
			})
 | 
						|
 | 
						|
			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
 | 
						|
	// InfoOnly only add user info to the request context. No login check is performed.
 | 
						|
	InfoOnly() 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
 |