nginx-proxy-manager/backend/internal/api/router.go
Jamie Curnow 29990110b1
Convert db backend to use Gorm, with basis for support
for Mysql and Postgres in addition to existing Sqlite
2023-05-26 11:37:39 +10:00

336 lines
13 KiB
Go

package api
import (
"net/http"
"time"
"npm/internal/api/handler"
"npm/internal/api/middleware"
"npm/internal/api/schema"
"npm/internal/config"
"npm/internal/entity/user"
"npm/internal/logger"
"npm/internal/serverevents"
"github.com/go-chi/chi"
chiMiddleware "github.com/go-chi/chi/middleware"
"github.com/go-chi/cors"
)
// NewRouter returns a new router object
func NewRouter() http.Handler {
// Cors
cors := cors.New(cors.Options{
AllowedOrigins: []string{"*"},
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-Requested-With"},
AllowCredentials: true,
MaxAge: 300,
})
r := chi.NewRouter()
r.Use(
middleware.AccessControl,
middleware.Cors(r),
middleware.Options(r),
cors.Handler,
chiMiddleware.RealIP,
chiMiddleware.Recoverer,
chiMiddleware.Throttle(5),
middleware.PrettyPrint,
middleware.Expansion,
middleware.DecodeAuth(),
middleware.BodyContext(),
)
return applyRoutes(r)
}
// applyRoutes is where the magic happens
func applyRoutes(r chi.Router) chi.Router {
middleware.AuthCacheInit()
r.NotFound(handler.NotFound())
r.MethodNotAllowed(handler.NotAllowed())
// SSE - requires a sse token as the `jwt` get parameter
// Exists inside /api but it's here so that we can skip the Timeout middleware
// that applies to other endpoints.
r.With(middleware.EnforceSetup(true), middleware.SSEAuth).
Mount("/api/sse", serverevents.Get())
// API
r.With(chiMiddleware.Timeout(30*time.Second)).Route("/api", func(r chi.Router) {
r.Get("/", handler.Health())
r.Get("/schema", handler.Schema())
r.With(middleware.EnforceSetup(true), middleware.Enforce("")).
Get("/config", handler.Config())
// Tokens
r.With(middleware.EnforceSetup(true)).Route("/tokens", func(r chi.Router) {
r.With(middleware.EnforceRequestSchema(schema.GetToken())).
Post("/", handler.NewToken())
r.With(middleware.Enforce("")).
Get("/", handler.RefreshToken())
r.With(middleware.Enforce("")).
Post("/sse", handler.NewSSEToken())
})
// Users
r.Route("/users", func(r chi.Router) {
// Create - can be done in Setup stage as well
r.With(middleware.Enforce(user.CapabilityUsersManage), middleware.EnforceRequestSchema(schema.CreateUser())).
Post("/", handler.CreateUser())
// Requires Setup stage to be completed
r.With(middleware.EnforceSetup(true)).Route("/", func(r chi.Router) {
// Get yourself, requires a login but no other permissions
r.With(middleware.Enforce("")).
Get("/{userID:(?:me)}", handler.GetUser())
// Update yourself, requires a login but no other permissions
r.With(middleware.Enforce(""), middleware.EnforceRequestSchema(schema.UpdateUser())).
Put("/{userID:(?:me)}", handler.UpdateUser())
r.With(middleware.Enforce(user.CapabilityUsersManage)).Route("/", func(r chi.Router) {
// List
// r.With(middleware.Enforce(user.CapabilityUsersManage), middleware.Filters(user.GetFilterSchema())).
r.With(middleware.Enforce(user.CapabilityUsersManage)).
Get("/", handler.GetUsers())
// Specific Item
r.Get("/{userID:(?:[0-9]+)}", handler.GetUser())
r.Delete("/{userID:(?:[0-9]+|me)}", handler.DeleteUser())
// Update another user
r.With(middleware.EnforceRequestSchema(schema.UpdateUser())).
Put("/{userID:(?:[0-9]+)}", handler.UpdateUser())
})
// Auth - sets passwords
r.With(middleware.Enforce(""), middleware.EnforceRequestSchema(schema.SetAuth())).
Post("/{userID:(?:me)}/auth", handler.SetAuth())
r.With(middleware.Enforce(user.CapabilityUsersManage), middleware.EnforceRequestSchema(schema.SetAuth())).
Post("/{userID:(?:[0-9]+)}/auth", handler.SetAuth())
})
})
// Only available in debug mode
if config.GetLogLevel() == logger.DebugLevel {
// delete users without auth
r.Delete("/users", handler.DeleteUsers())
// SSE test endpoints
r.Post("/sse-notification", handler.TestSSENotification())
}
// Settings
r.With(middleware.EnforceSetup(true), middleware.Enforce(user.CapabilitySettingsManage)).Route("/settings", func(r chi.Router) {
// r.With(middleware.Filters(setting.GetFilterSchema())).
r.Get("/", handler.GetSettings())
r.Get("/{name}", handler.GetSetting())
r.With(middleware.EnforceRequestSchema(schema.CreateSetting())).
Post("/", handler.CreateSetting())
r.With(middleware.EnforceRequestSchema(schema.UpdateSetting())).
Put("/{name}", handler.UpdateSetting())
})
// Access Lists
r.With(middleware.EnforceSetup(true)).Route("/access-lists", func(r chi.Router) {
// List
// r.With(middleware.Filters(accesslist.GetFilterSchema()), middleware.Enforce(user.CapabilityAccessListsView)).
r.With(middleware.Enforce(user.CapabilityAccessListsView)).
Get("/", handler.GetAccessLists())
// Create
r.With(middleware.Enforce(user.CapabilityAccessListsManage), middleware.EnforceRequestSchema(schema.CreateAccessList())).
Post("/", handler.CreateAccessList())
// Specific Item
r.Route("/{accessListID:[0-9]+}", func(r chi.Router) {
r.With(middleware.Enforce(user.CapabilityAccessListsView)).
Get("/", handler.GetAccessList())
r.With(middleware.Enforce(user.CapabilityAccessListsManage)).Route("/", func(r chi.Router) {
r.Delete("/{accessListID:[0-9]+}", handler.DeleteAccessList())
r.With(middleware.EnforceRequestSchema(schema.UpdateAccessList())).
Put("/{accessListID:[0-9]+}", handler.UpdateAccessList())
})
})
})
// DNS Providers
r.With(middleware.EnforceSetup(true)).Route("/dns-providers", func(r chi.Router) {
// List
// r.With(middleware.Enforce(user.CapabilityDNSProvidersView), middleware.Filters(dnsprovider.GetFilterSchema())).
r.With(middleware.Enforce(user.CapabilityDNSProvidersView)).
Get("/", handler.GetDNSProviders())
// Create
r.With(middleware.Enforce(user.CapabilityDNSProvidersManage), middleware.EnforceRequestSchema(schema.CreateDNSProvider())).
Post("/", handler.CreateDNSProvider())
// Specific Item
r.Route("/{providerID:[0-9]+}", func(r chi.Router) {
r.With(middleware.Enforce(user.CapabilityDNSProvidersView)).
Get("/{providerID:[0-9]+}", handler.GetDNSProvider())
r.With(middleware.Enforce(user.CapabilityDNSProvidersManage)).Route("/", func(r chi.Router) {
r.Delete("/", handler.DeleteDNSProvider())
r.With(middleware.EnforceRequestSchema(schema.UpdateDNSProvider())).
Put("/{providerID:[0-9]+}", handler.UpdateDNSProvider())
})
})
// List Acme DNS Providers
r.With(middleware.Enforce(user.CapabilityDNSProvidersView)).Route("/acmesh", func(r chi.Router) {
r.Get("/{acmeshID:[a-z0-9_]+}", handler.GetAcmeshProvider())
r.Get("/", handler.GetAcmeshProviders())
})
})
// Certificate Authorities
r.With(middleware.EnforceSetup(true)).Route("/certificate-authorities", func(r chi.Router) {
// List
// r.With(middleware.Enforce(user.CapabilityCertificateAuthoritiesView), middleware.Filters(certificateauthority.GetFilterSchema())).
r.With(middleware.Enforce(user.CapabilityCertificateAuthoritiesView)).
Get("/", handler.GetCertificateAuthorities())
// Create
r.With(middleware.Enforce(user.CapabilityCertificateAuthoritiesManage), middleware.EnforceRequestSchema(schema.CreateCertificateAuthority())).
Post("/", handler.CreateCertificateAuthority())
// Specific Item
r.Route("/{caID:[0-9]+}", func(r chi.Router) {
r.With(middleware.Enforce(user.CapabilityCertificateAuthoritiesView)).
Get("/", handler.GetCertificateAuthority())
r.With(middleware.Enforce(user.CapabilityCertificateAuthoritiesManage)).Route("/", func(r chi.Router) {
r.Delete("/{caID:[0-9]+}", handler.DeleteCertificateAuthority())
r.With(middleware.EnforceRequestSchema(schema.UpdateCertificateAuthority())).
Put("/{caID:[0-9]+}", handler.UpdateCertificateAuthority())
})
})
})
// Certificates
r.With(middleware.EnforceSetup(true)).Route("/certificates", func(r chi.Router) {
// List
// r.With(middleware.Enforce(user.CapabilityCertificatesView), middleware.Filters(certificate.GetFilterSchema())).
r.With(middleware.Enforce(user.CapabilityCertificatesView)).
Get("/", handler.GetCertificates())
// Create
r.With(middleware.Enforce(user.CapabilityCertificatesManage), middleware.EnforceRequestSchema(schema.CreateCertificate())).
Post("/", handler.CreateCertificate())
// Specific Item
r.Route("/{certificateID:[0-9]+}", func(r chi.Router) {
r.With(middleware.Enforce(user.CapabilityCertificatesView)).
Get("/", handler.GetCertificate())
r.With(middleware.Enforce(user.CapabilityCertificatesManage)).Route("/", func(r chi.Router) {
r.Delete("/", handler.DeleteCertificate())
r.Put("/", handler.UpdateCertificate())
// r.With(middleware.EnforceRequestSchema(schema.UpdateCertificate())).
// Put("/", handler.UpdateCertificate())
r.Post("/renew", handler.RenewCertificate())
r.Get("/download", handler.DownloadCertificate())
})
})
})
// Hosts
r.With(middleware.EnforceSetup(true)).Route("/hosts", func(r chi.Router) {
// List
// r.With(middleware.Enforce(user.CapabilityHostsView), middleware.Filters(host.GetFilterSchema())).
r.With(middleware.Enforce(user.CapabilityHostsView)).
Get("/", handler.GetHosts())
// Create
r.With(middleware.Enforce(user.CapabilityHostsManage), middleware.EnforceRequestSchema(schema.CreateHost())).
Post("/", handler.CreateHost())
// Specific Item
r.Route("/{hostID:[0-9]+}", func(r chi.Router) {
r.With(middleware.Enforce(user.CapabilityHostsView)).
Get("/", handler.GetHost())
r.With(middleware.Enforce(user.CapabilityHostsManage)).Route("/", func(r chi.Router) {
r.Delete("/", handler.DeleteHost())
r.With(middleware.EnforceRequestSchema(schema.UpdateHost())).
Put("/", handler.UpdateHost())
r.Get("/nginx-config", handler.GetHostNginxConfig("json"))
r.Get("/nginx-config.txt", handler.GetHostNginxConfig("text"))
})
})
})
// Nginx Templates
r.With(middleware.EnforceSetup(true)).Route("/nginx-templates", func(r chi.Router) {
// List
// r.With(middleware.Enforce(user.CapabilityNginxTemplatesView), middleware.Filters(nginxtemplate.GetFilterSchema())).
r.With(middleware.Enforce(user.CapabilityNginxTemplatesView)).
Get("/", handler.GetNginxTemplates())
// Create
r.With(middleware.Enforce(user.CapabilityNginxTemplatesManage), middleware.EnforceRequestSchema(schema.CreateNginxTemplate())).
Post("/", handler.CreateNginxTemplate())
// Specific Item
r.Route("/{templateID:[0-9]+}", func(r chi.Router) {
r.With(middleware.Enforce(user.CapabilityNginxTemplatesView)).
Get("/", handler.GetNginxTemplates())
r.With(middleware.Enforce(user.CapabilityHostsManage)).Route("/", func(r chi.Router) {
r.Delete("/", handler.DeleteNginxTemplate())
r.With(middleware.EnforceRequestSchema(schema.UpdateNginxTemplate())).
Put("/", handler.UpdateNginxTemplate())
})
})
})
// Streams
r.With(middleware.EnforceSetup(true)).Route("/streams", func(r chi.Router) {
// List
// r.With(middleware.Enforce(user.CapabilityStreamsView), middleware.Filters(stream.GetFilterSchema())).
r.With(middleware.Enforce(user.CapabilityStreamsView)).
Get("/", handler.GetStreams())
// Create
r.With(middleware.Enforce(user.CapabilityStreamsManage), middleware.EnforceRequestSchema(schema.CreateStream())).
Post("/", handler.CreateStream())
// Specific Item
r.Route("/{hostID:[0-9]+}", func(r chi.Router) {
r.With(middleware.Enforce(user.CapabilityStreamsView)).
Get("/", handler.GetStream())
r.With(middleware.Enforce(user.CapabilityHostsManage)).Route("/", func(r chi.Router) {
r.Delete("/", handler.DeleteStream())
r.With(middleware.EnforceRequestSchema(schema.UpdateStream())).
Put("/", handler.UpdateStream())
})
})
})
// Upstreams
r.With(middleware.EnforceSetup(true)).Route("/upstreams", func(r chi.Router) {
// List
// r.With(middleware.Enforce(user.CapabilityHostsView), middleware.Filters(upstream.GetFilterSchema())).
r.With(middleware.Enforce(user.CapabilityHostsView)).
Get("/", handler.GetUpstreams())
// Create
r.With(middleware.Enforce(user.CapabilityHostsManage), middleware.EnforceRequestSchema(schema.CreateUpstream())).
Post("/", handler.CreateUpstream())
// Specific Item
r.Route("/{upstreamID:[0-9]+}", func(r chi.Router) {
r.With(middleware.Enforce(user.CapabilityHostsView)).
Get("/", handler.GetUpstream())
r.With(middleware.Enforce(user.CapabilityHostsManage)).Route("/", func(r chi.Router) {
r.Delete("/", handler.DeleteUpstream())
r.With(middleware.EnforceRequestSchema(schema.UpdateUpstream())).
Put("/", handler.UpdateUpstream())
r.Get("/nginx-config", handler.GetUpstreamNginxConfig("json"))
r.Get("/nginx-config.txt", handler.GetUpstreamNginxConfig("text"))
})
})
})
})
return r
}