From 53a26ad063a3567cc227358671edb7836cc1b725 Mon Sep 17 00:00:00 2001 From: Ben Busby Date: Tue, 4 Feb 2025 13:46:58 -0700 Subject: [PATCH] Implement "lockdown" mode (#21) Lockdown mode prevents unauthenticated users form using any feature of YeetFile, including sending text content (which is normally available to any user). This can be enabled using `YEETFILE_LOCKDOWN=1` --- README.md | 5 +++-- backend/config/config.go | 1 + backend/server/html/handlers.go | 2 +- backend/server/middleware.go | 14 ++++++++++++++ backend/server/server.go | 6 +++--- backend/server/transfer/send/handlers.go | 2 +- 6 files changed, 23 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 296a276..d383a4c 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,7 @@ If you need to access the web interface using a machine IP on your network, for generate a cert and set the `YEETFILE_TLS_CERT` and `YEETFILE_TLS_KEY` environment variables (see [Environment Variables](#environment-variables)) -> [!NOTE] +> [!NOTE] > This does not apply to the CLI tool. You can still use all features of YeetFile from the CLI tool > without a secure connection. @@ -173,7 +173,7 @@ default_view: "vault" # debug_file: "~/.config/yeetfile/debug.log" ``` -You can change the `server` directive to your own instance of YeetFile. +You can change the `server` directive to your own instance of YeetFile. ## Development @@ -235,6 +235,7 @@ All environment variables can be defined in a file named `.env` at the root leve | YEETFILE_CACHE_MAX_FILE_SIZE | The maximum file size to cache | 0 | An int value of bytes | | YEETFILE_TLS_KEY | The SSL key to use for connections | | The string key contents (not a file path) | | YEETFILE_TLS_CERT | The SSL cert to use for connections | | The string cert contents (not a file path) | +| YEETFILE_LOCKDOWN | Disables anonymous (not logged in) interactions | 0 | `1` to enable lockdown, `0` to allow anonymous usage | #### Backblaze Environment Variables diff --git a/backend/config/config.go b/backend/config/config.go index 2c46385..1ed4abc 100644 --- a/backend/config/config.go +++ b/backend/config/config.go @@ -37,6 +37,7 @@ var TLSCert = utils.GetEnvVar("YEETFILE_TLS_CERT", "") var TLSKey = utils.GetEnvVar("YEETFILE_TLS_KEY", "") var IsDebugMode = utils.GetEnvVarBool("YEETFILE_DEBUG", false) +var IsLockedDown = utils.GetEnvVarBool("YEETFILE_LOCKDOWN", false) // ============================================================================= // Email configuration (used in account verification and billing reminders) diff --git a/backend/server/html/handlers.go b/backend/server/html/handlers.go index ec0acb1..8d80e37 100644 --- a/backend/server/html/handlers.go +++ b/backend/server/html/handlers.go @@ -86,7 +86,7 @@ func PassVaultPageHandler(w http.ResponseWriter, _ *http.Request, userID string) } // SendPageHandler returns the html template used for sending files -func SendPageHandler(w http.ResponseWriter, req *http.Request) { +func SendPageHandler(w http.ResponseWriter, req *http.Request, _ string) { var ( sendUsed int64 sendAvailable int64 diff --git a/backend/server/middleware.go b/backend/server/middleware.go index 0c543c6..bc3e1b0 100644 --- a/backend/server/middleware.go +++ b/backend/server/middleware.go @@ -74,6 +74,20 @@ func LimiterMiddleware(next http.HandlerFunc) http.HandlerFunc { return handler } +// LockdownAuthMiddleware conditionally prevents access to certain pages/actions +// if the instance is configured to be locked down. +func LockdownAuthMiddleware(next session.HandlerFunc) http.HandlerFunc { + if config.IsLockedDown { + return AuthMiddleware(next) + } + + handler := func(w http.ResponseWriter, req *http.Request) { + next(w, req, "") + } + + return handler +} + // AuthMiddleware enforces that a particular request has a valid session before // handling. func AuthMiddleware(next session.HandlerFunc) http.HandlerFunc { diff --git a/backend/server/server.go b/backend/server/server.go index 7fbd529..17ee924 100644 --- a/backend/server/server.go +++ b/backend/server/server.go @@ -50,7 +50,7 @@ func Run(host, port string) { // YeetFile Send {POST, endpoints.UploadSendFileMetadata, AuthMiddleware(send.UploadMetadataHandler)}, {POST, endpoints.UploadSendFileData, AuthMiddleware(send.UploadDataHandler)}, - {POST, endpoints.UploadSendText, LimiterMiddleware(send.UploadPlaintextHandler)}, + {POST, endpoints.UploadSendText, LimiterMiddleware(LockdownAuthMiddleware(send.UploadPlaintextHandler))}, {GET, endpoints.DownloadSendFileMetadata, send.DownloadHandler}, {GET, endpoints.DownloadSendFileData, send.DownloadChunkHandler}, @@ -94,8 +94,8 @@ func Run(host, port string) { {GET, endpoints.BTCPayCheckout, BTCPayMiddleware(AuthMiddleware(payments.BTCPayCheckout))}, // HTML - {GET, endpoints.HTMLHome, html.SendPageHandler}, - {GET, endpoints.HTMLSend, html.SendPageHandler}, + {GET, endpoints.HTMLHome, LockdownAuthMiddleware(html.SendPageHandler)}, + {GET, endpoints.HTMLSend, LockdownAuthMiddleware(html.SendPageHandler)}, {GET, endpoints.HTMLPass, AuthMiddleware(html.PassVaultPageHandler)}, {GET, endpoints.HTMLPassFolder, AuthMiddleware(html.PassVaultPageHandler)}, {GET, endpoints.HTMLPassEntry, AuthMiddleware(html.PassVaultPageHandler)}, diff --git a/backend/server/transfer/send/handlers.go b/backend/server/transfer/send/handlers.go index 17aa773..ad58e6a 100644 --- a/backend/server/transfer/send/handlers.go +++ b/backend/server/transfer/send/handlers.go @@ -129,7 +129,7 @@ func UploadDataHandler(w http.ResponseWriter, req *http.Request, userID string) // UploadPlaintextHandler handles uploading plaintext with a max size of // shared.MaxPlaintextLen characters (constants.go). -func UploadPlaintextHandler(w http.ResponseWriter, req *http.Request) { +func UploadPlaintextHandler(w http.ResponseWriter, req *http.Request, _ string) { var plaintextUpload shared.PlaintextUpload err := utils.LimitedJSONReader(w, req.Body).Decode(&plaintextUpload) if err != nil {