2023-06-07 20:51:54 +03:00
|
|
|
package web
|
|
|
|
|
|
|
|
import (
|
2023-06-08 20:44:32 +03:00
|
|
|
"context"
|
2023-06-07 20:51:54 +03:00
|
|
|
"github.com/go-chi/chi/v5"
|
2023-06-08 20:55:43 +03:00
|
|
|
"github.com/lus/pasty/internal/meta"
|
2023-06-08 20:24:32 +03:00
|
|
|
"github.com/lus/pasty/internal/pastes"
|
2023-06-17 16:16:22 +03:00
|
|
|
"github.com/lus/pasty/internal/reports"
|
2023-06-07 20:51:54 +03:00
|
|
|
"github.com/lus/pasty/internal/storage"
|
2023-06-17 18:00:44 +03:00
|
|
|
"github.com/lus/pasty/pkg/chizerolog"
|
2023-06-07 20:51:54 +03:00
|
|
|
"net/http"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Server struct {
|
|
|
|
// The address the web server should listen to.
|
|
|
|
Address string
|
|
|
|
|
|
|
|
// The storage driver to use.
|
|
|
|
Storage storage.Driver
|
|
|
|
|
2023-06-17 16:16:22 +03:00
|
|
|
// The report client to use to send reports.
|
|
|
|
// If this is set to nil, the report system will be considered deactivated.
|
|
|
|
ReportClient *reports.Client
|
|
|
|
|
2023-06-07 20:51:54 +03:00
|
|
|
// Whether the Hastebin support should be enabled.
|
|
|
|
// If this is set to 'false', the Hastebin specific endpoints will not be registered.
|
|
|
|
HastebinSupport bool
|
|
|
|
|
|
|
|
// The length of newly generated paste IDs.
|
|
|
|
PasteIDLength int
|
|
|
|
// The charset to use when generating new paste IDs.
|
|
|
|
PasteIDCharset string
|
|
|
|
|
|
|
|
// The maximum length of newly generated pastes.
|
|
|
|
PasteLengthCap int
|
|
|
|
|
|
|
|
// Whether modification tokens are enabled.
|
|
|
|
ModificationTokensEnabled bool
|
|
|
|
// The length of newly generated modification tokens.
|
|
|
|
ModificationTokenLength int
|
|
|
|
// The charset to use when generating new modification tokens.
|
|
|
|
ModificationTokenCharset string
|
|
|
|
|
|
|
|
// The administration tokens.
|
|
|
|
AdminTokens []string
|
2023-06-08 20:44:32 +03:00
|
|
|
|
|
|
|
httpServer *http.Server
|
2023-06-07 20:51:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func (server *Server) Start() error {
|
|
|
|
router := chi.NewRouter()
|
|
|
|
|
2023-06-17 18:00:44 +03:00
|
|
|
router.Use(chizerolog.Logger)
|
|
|
|
router.Use(chizerolog.Recover)
|
|
|
|
|
2023-06-08 20:24:32 +03:00
|
|
|
// Register the web frontend handler
|
2023-06-08 20:17:34 +03:00
|
|
|
router.Get("/*", frontendHandler(router.NotFoundHandler()))
|
|
|
|
|
2023-06-08 20:24:32 +03:00
|
|
|
// Register the raw paste handler
|
|
|
|
router.With(server.v2MiddlewareInjectPaste).Get("/{paste_id}/raw", func(writer http.ResponseWriter, request *http.Request) {
|
|
|
|
paste, ok := request.Context().Value("paste").(*pastes.Paste)
|
|
|
|
if !ok {
|
|
|
|
writeString(writer, http.StatusInternalServerError, "missing paste object")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
_, _ = writer.Write([]byte(paste.Content))
|
|
|
|
})
|
|
|
|
|
2023-06-07 20:51:54 +03:00
|
|
|
// Register the paste API endpoints
|
2023-06-08 20:17:34 +03:00
|
|
|
router.Get("/api/*", router.NotFoundHandler())
|
2023-06-07 20:51:54 +03:00
|
|
|
router.With(server.v2MiddlewareInjectPaste).Get("/api/v2/pastes/{paste_id}", server.v2EndpointGetPaste)
|
|
|
|
router.Post("/api/v2/pastes", server.v2EndpointCreatePaste)
|
|
|
|
router.With(server.v2MiddlewareInjectPaste, server.v2MiddlewareAuthorize).Patch("/api/v2/pastes/{paste_id}", server.v2EndpointModifyPaste)
|
2023-06-08 20:55:43 +03:00
|
|
|
router.With(server.v2MiddlewareInjectPaste, server.v2MiddlewareAuthorize).Delete("/api/v2/pastes/{paste_id}", server.v2EndpointDeletePaste)
|
2023-06-17 16:16:22 +03:00
|
|
|
if server.ReportClient != nil {
|
|
|
|
router.With(server.v2MiddlewareInjectPaste).Post("/api/v2/pastes/{paste_id}/report", server.v2EndpointReportPaste)
|
|
|
|
}
|
2023-06-08 20:55:43 +03:00
|
|
|
router.Get("/api/v2/info", func(writer http.ResponseWriter, request *http.Request) {
|
2023-06-17 18:00:44 +03:00
|
|
|
writeJSONOrErr(request, writer, http.StatusOK, map[string]any{
|
2023-06-08 20:55:43 +03:00
|
|
|
"version": meta.Version,
|
|
|
|
"modificationTokens": server.ModificationTokensEnabled,
|
2023-06-17 16:16:22 +03:00
|
|
|
"reports": server.ReportClient != nil,
|
|
|
|
"pasteLifetime": -1, // TODO: Return paste lifetime
|
2023-06-08 20:55:43 +03:00
|
|
|
})
|
|
|
|
})
|
2023-06-07 20:51:54 +03:00
|
|
|
|
2023-06-08 20:44:32 +03:00
|
|
|
// Start the HTTP server
|
|
|
|
server.httpServer = &http.Server{
|
|
|
|
Addr: server.Address,
|
|
|
|
Handler: router,
|
|
|
|
}
|
|
|
|
return server.httpServer.ListenAndServe()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (server *Server) Shutdown(ctx context.Context) error {
|
|
|
|
if err := server.httpServer.Shutdown(ctx); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
server.httpServer = nil
|
|
|
|
return nil
|
2023-06-07 20:51:54 +03:00
|
|
|
}
|