From d88a3cdd1ebf9ead7df264dc0918ea6256e9ccb2 Mon Sep 17 00:00:00 2001 From: Marc Ole Bulling Date: Wed, 1 Dec 2021 22:25:33 +0100 Subject: [PATCH] Added env DISABLE_LOGIN in order to support 3rd party authentication #30 --- cmd/gokapi/Main.go | 4 +- docs/advanced.rst | 75 +++++++++++-------- docs/changelog.rst | 22 +++++- internal/configuration/Configuration.go | 11 ++- internal/configuration/Configuration_test.go | 4 + internal/environment/Environment.go | 11 ++- internal/webserver/Webserver.go | 15 +++- internal/webserver/Webserver_test.go | 27 +++++++ .../webserver/web/templates/html_header.tmpl | 2 +- .../web/templates/string_constants.tmpl | 2 +- 10 files changed, 129 insertions(+), 44 deletions(-) diff --git a/cmd/gokapi/Main.go b/cmd/gokapi/Main.go index 360a8dd..37f3fbf 100644 --- a/cmd/gokapi/Main.go +++ b/cmd/gokapi/Main.go @@ -23,9 +23,9 @@ import ( // Version is the current version in readable form. // The go generate call below needs to be modified as well -const Version = "1.3.1" +const Version = "1.3.2" -//go:generate sh "../../build/setVersionTemplate.sh" "1.3.1" +//go:generate sh "../../build/setVersionTemplate.sh" "1.3.2" // Main routine that is called on startup func main() { diff --git a/docs/advanced.rst b/docs/advanced.rst index 1598eff..01b7c64 100644 --- a/docs/advanced.rst +++ b/docs/advanced.rst @@ -60,39 +60,41 @@ General -------- -+---------------------+--------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ -| Name | Action | Persistent* | Default | Required for unattended setup | -+=====================+======================================================================================+=============+===================================+===============================+ -| GOKAPI_CONFIG_DIR | Sets the directory for the config file | No | config | No | -+---------------------+--------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ -| GOKAPI_CONFIG_FILE | Sets the name of the config file | No | config.json | No | -+---------------------+--------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ -| GOKAPI_DATA_DIR | Sets the directory for the data | Yes | data | No | -+---------------------+--------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ -| GOKAPI_USERNAME | Sets the admin username | Yes | unset | Yes | -+---------------------+--------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ -| GOKAPI_PASSWORD | Sets the admin password | Yes | unset | Yes | -+---------------------+--------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ -| GOKAPI_PORT | Sets the server port | Yes | 53842 | Yes | -+---------------------+--------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ -| GOKAPI_EXTERNAL_URL | Sets the external URL where Gokapi can be reached | Yes | unset | Yes | -+---------------------+--------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ -| GOKAPI_REDIRECT_URL | Sets the external URL where Gokapi will redirect to the index page is accesses | Yes | unset | Yes | -+---------------------+--------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ -| GOKAPI_LOCALHOST | Bind server to localhost. Expects true/false/yes/no, always false for Docker images | Yes | false for Docker, otherwise unset | Yes | -+---------------------+--------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ -| GOKAPI_SALT_FILES | Sets the salt for the file password hashes | Yes | random salt | Yes | -+---------------------+--------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ -| GOKAPI_USE_SSL | Serve all content through HTTPS and generate certificates. Expects true/false/yes/no | Yes | unset | Yes | -+---------------------+--------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ -| GOKAPI_SALT_ADMIN | Sets the salt for the admin password hash | Yes | random salt | No | -+---------------------+--------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ -| GOKAPI_SALT_FILES | Sets the salt for the file password hashes | Yes | random salt | No | -+---------------------+--------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ -| GOKAPI_LENGTH_ID | Sets the length of the download IDs. Value needs to be 5 or more | Yes | 15 | No | -+---------------------+--------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ -| GOKAPI_MAX_FILESIZE | Sets the maximum allowed file size in MB | Yes | 102400 (100GB) | No | -+---------------------+--------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ ++----------------------+----------------------------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ +| Name | Action | Persistent* | Default | Required for unattended setup | ++----------------------+----------------------------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ +| GOKAPI_CONFIG_DIR | Sets the directory for the config file | No | config | No | ++----------------------+----------------------------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ +| GOKAPI_CONFIG_FILE | Sets the name of the config file | No | config.json | No | ++----------------------+----------------------------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ +| GOKAPI_DATA_DIR | Sets the directory for the data | Yes | data | No | ++----------------------+----------------------------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ +| GOKAPI_USERNAME | Sets the admin username | Yes | unset | Yes | ++----------------------+----------------------------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ +| GOKAPI_PASSWORD | Sets the admin password | Yes | unset | Yes | ++----------------------+----------------------------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ +| GOKAPI_PORT | Sets the server port | Yes | 53842 | Yes | ++----------------------+----------------------------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ +| GOKAPI_EXTERNAL_URL | Sets the external URL where Gokapi can be reached | Yes | unset | Yes | ++----------------------+----------------------------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ +| GOKAPI_REDIRECT_URL | Sets the external URL where Gokapi will redirect to the index page is accesses | Yes | unset | Yes | ++----------------------+----------------------------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ +| GOKAPI_LOCALHOST | Bind server to localhost. Expects true/false/yes/no, always false for Docker images | Yes | false for Docker, otherwise unset | Yes | ++----------------------+----------------------------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ +| GOKAPI_SALT_FILES | Sets the salt for the file password hashes | Yes | random salt | Yes | ++----------------------+----------------------------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ +| GOKAPI_USE_SSL | Serve all content through HTTPS and generate certificates. Expects true/false/yes/no | Yes | unset | Yes | ++----------------------+----------------------------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ +| GOKAPI_SALT_ADMIN | Sets the salt for the admin password hash | Yes | random salt | No | ++----------------------+----------------------------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ +| GOKAPI_SALT_FILES | Sets the salt for the file password hashes | Yes | random salt | No | ++----------------------+----------------------------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ +| GOKAPI_LENGTH_ID | Sets the length of the download IDs. Value needs to be 5 or more | Yes | 15 | No | ++----------------------+----------------------------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ +| GOKAPI_MAX_FILESIZE | Sets the maximum allowed file size in MB | Yes | 102400 (100GB) | No | ++----------------------+----------------------------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ +| GOKAPI_DISABLE_LOGIN | Disables login for admin menu. DO NOT USE unless you have a 3rd party authentication for the ``/admin`` URL! | Yes | false | No | ++----------------------+----------------------------------------------------------------------------------------------------------+-------------+-----------------------------------+-------------------------------+ \*Variables that are persistent must be submitted during the first start when Gokapi creates a new config file. They can be omitted afterwards. Non-persistent variables need to be set on every start. @@ -116,6 +118,13 @@ All values that are described in :ref:`cloudstorage` can be passed as environmen +-----------------------+-------------------------+ +External Authentication +------------------------ + +In order to use external authentication (eg. services like Authelia or Authentik), set the environment variable ``GOKAPI_DISABLE_LOGIN`` to ``true`` on the first start. *Warning:* This will diasable authentication for the admin menu, which can be dangerous if not set up correctly! + +Refer to the documention of your reverse proxy on how to protect the ``/admin`` URL, as authentication is only required for this URL. + .. _api: ******************************** diff --git a/docs/changelog.rst b/docs/changelog.rst index 6921a48..6ae92ab 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -8,6 +8,22 @@ Overview of all Changes ----------------------- +v1.3.1: 03 Jul 2021 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +* Default upload limit is now 100GB and can be changed with environment variables on first start +* Fixed upload not working when using suburl on webserver for Gokapi +* Added log file +* Minor performance increase + +v1.3.0: 17 May 2021 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* Added cloudstorage support (AWS S3 / Backblaze B2) +* After changing password, all sessions will be logged out +* Fixed terminal input on Windows +* Added SSL support +* Documentation now hosted on ReadTheDocs + v1.2.0: 07 May 2021 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -59,4 +75,8 @@ v1.0: 12 Mar 2021 Upgrading ----------------------- -See TODO for upgrade instructions +Upgrading to 1.3 +^^^^^^^^^^^^^^^^^^ + +* If you would like to use native SSL, please pass the environment variable ``GOKAPI_USE_SSL`` on first start after the update or manually edit the configuration file +* AWS S3 and Backblaze B2 can now be used instead of local storage! Please refer to the documentation on how to set it up. diff --git a/internal/configuration/Configuration.go b/internal/configuration/Configuration.go index 0168acb..ba9323e 100644 --- a/internal/configuration/Configuration.go +++ b/internal/configuration/Configuration.go @@ -36,7 +36,7 @@ var Environment environment.Environment var serverSettings Configuration // Version of the configuration structure. Used for upgrading -const currentConfigVersion = 8 +const currentConfigVersion = 9 // For locking this object to prevent race conditions var mutex sync.RWMutex @@ -64,6 +64,7 @@ type Configuration struct { MaxMemory int `json:"MaxMemory"` UseSsl bool `json:"UseSsl"` MaxFileSizeMB int `json:"MaxFileSizeMB"` + DisableLogin bool `json:"DisableLogin"` } // Load loads the configuration or creates the folder structure and a default configuration @@ -157,6 +158,10 @@ func updateConfig() { if serverSettings.ConfigVersion < 8 { serverSettings.MaxFileSizeMB = Environment.MaxFileSize } + // < v1.3.2 + if serverSettings.ConfigVersion < 9 { + serverSettings.DisableLogin = environment.ToBool(Environment.DisableLogin) + } if serverSettings.ConfigVersion < currentConfigVersion { fmt.Println("Successfully upgraded database") @@ -435,4 +440,8 @@ func GetLengthId() int { return serverSettings.LengthId } +func IsLoginDisabled() bool { + return serverSettings.DisableLogin +} + var osExit = os.Exit diff --git a/internal/configuration/Configuration_test.go b/internal/configuration/Configuration_test.go index fa184d9..2a268bb 100644 --- a/internal/configuration/Configuration_test.go +++ b/internal/configuration/Configuration_test.go @@ -80,6 +80,7 @@ func TestCreateNewConfig(t *testing.T) { test.IsEqualInt(t, serverSettings.MaxMemory, 20) test.IsNotEqualString(t, serverSettings.SaltAdmin, "eefwkjqweduiotbrkl##$2342brerlk2321") test.IsEqualInt(t, serverSettings.MaxFileSizeMB, 102400) + test.IsEqualBool(t, serverSettings.DisableLogin, false) os.Unsetenv("GOKAPI_USERNAME") os.Unsetenv("GOKAPI_PASSWORD") os.Unsetenv("GOKAPI_PORT") @@ -92,6 +93,7 @@ func TestCreateNewConfig(t *testing.T) { func TestUpgradeDb(t *testing.T) { testconfiguration.WriteUpgradeConfigFile() os.Setenv("GOKAPI_USE_SSL", "true") + os.Setenv("GOKAPI_DISABLE_LOGIN", "true") os.Setenv("GOKAPI_MAX_FILESIZE", "5") Load() test.IsEqualString(t, serverSettings.SaltAdmin, "eefwkjqweduiotbrkl##$2342brerlk2321") @@ -105,8 +107,10 @@ func TestUpgradeDb(t *testing.T) { test.IsEqualInt(t, serverSettings.ConfigVersion, currentConfigVersion) test.IsEqualBool(t, serverSettings.UseSsl, true) test.IsEqualInt(t, serverSettings.MaxFileSizeMB, 5) + test.IsEqualBool(t, serverSettings.DisableLogin, true) os.Unsetenv("GOKAPI_USE_SSL") os.Unsetenv("GOKAPI_MAX_FILESIZE") + os.Unsetenv("GOKAPI_DISABLE_LOGIN") testconfiguration.Create(false) Load() } diff --git a/internal/environment/Environment.go b/internal/environment/Environment.go index 608b3fb..5970fd1 100644 --- a/internal/environment/Environment.go +++ b/internal/environment/Environment.go @@ -27,17 +27,23 @@ type Environment struct { RedirectUrl string SaltAdmin string SaltFiles string - LengthId int - MaxMemory int UseSsl string AwsBucket string AwsRegion string AwsKeyId string AwsKeySecret string AwsEndpoint string + DisableLogin string + LengthId int + MaxMemory int MaxFileSize int } +// ToBool checks if a string output by the environment package is equal true or false +func ToBool(input string) bool { + return input == IsTrue +} + // IsAwsProvided returns true if all required env variables have been set for using AWS S3 / Backblaze func (e *Environment) IsAwsProvided() bool { return e.AwsBucket != "" && @@ -83,6 +89,7 @@ func New() Environment { AwsKeySecret: envString("AWS_KEY_SECRET"), AwsEndpoint: envString("AWS_ENDPOINT"), MaxFileSize: envInt("MAX_FILESIZE", 1), + DisableLogin: envBool("DISABLE_LOGIN"), } } diff --git a/internal/webserver/Webserver.go b/internal/webserver/Webserver.go index 736f17f..770d2e5 100644 --- a/internal/webserver/Webserver.go +++ b/internal/webserver/Webserver.go @@ -211,6 +211,10 @@ func processApi(w http.ResponseWriter, r *http.Request) { // Shows a login form. If username / pw combo is incorrect, client needs to wait for three seconds. // If correct, a new session is created and the user is redirected to the admin menu func showLogin(w http.ResponseWriter, r *http.Request) { + if configuration.IsLoginDisabled() { + redirect(w, "admin") + return + } err := r.ParseForm() helper.Check(err) user := r.Form.Get("username") @@ -358,6 +362,7 @@ type UploadView struct { IsMainView bool IsApiView bool MaxFileSize int + IsLoginDisabled bool } // Converts the globalConfig variable to an UploadView struct to pass the infos to @@ -403,6 +408,7 @@ func (u *UploadView) convertGlobalConfig(isMainView bool) *UploadView { u.IsAdminView = true u.IsMainView = isMainView u.MaxFileSize = settings.MaxFileSizeMB + u.IsLoginDisabled = settings.DisableLogin configuration.ReleaseReadOnly() return u } @@ -446,17 +452,20 @@ func downloadFile(w http.ResponseWriter, r *http.Request) { storage.ServeFile(savedFile, w, r, true) } -// Checks if the user is logged in as an admin +// Checks if the user is logged in as an admin. func isAuthenticated(w http.ResponseWriter, r *http.Request, isUpload bool) bool { + if configuration.IsLoginDisabled() { + return true + } if sessionmanager.IsValidSession(w, r) { return true } if isUpload { _, err := io.WriteString(w, "{\"Result\":\"error\",\"ErrorMessage\":\"Not authenticated\"}") helper.Check(err) - } else { - redirect(w, "login") + return false } + redirect(w, "login") return false } diff --git a/internal/webserver/Webserver_test.go b/internal/webserver/Webserver_test.go index fe5402f..c1ec04c 100644 --- a/internal/webserver/Webserver_test.go +++ b/internal/webserver/Webserver_test.go @@ -567,3 +567,30 @@ func TestProcessApi(t *testing.T) { Headers: []test.Header{{"apikey", "validkey"}}, }) } + +func TestDisableLogin(t *testing.T) { + test.HttpPageResult(t, test.HttpTestConfig{ + Url: "http://localhost:53843/admin", + RequiredContent: []string{"URL=./login\""}, + IsHtml: true, + Cookies: []test.Cookie{{ + Name: "session_token", + Value: "invalid", + }}, + }) + settings := configuration.GetServerSettings() + settings.DisableLogin = true + configuration.Release() + test.HttpPageResult(t, test.HttpTestConfig{ + Url: "http://localhost:53843/admin", + RequiredContent: []string{"Downloads remaining"}, + IsHtml: true, + Cookies: []test.Cookie{{ + Name: "session_token", + Value: "invalid", + }}, + }) + settings = configuration.GetServerSettings() + settings.DisableLogin = false + configuration.Release() +} diff --git a/internal/webserver/web/templates/html_header.tmpl b/internal/webserver/web/templates/html_header.tmpl index eb6088e..f115f88 100644 --- a/internal/webserver/web/templates/html_header.tmpl +++ b/internal/webserver/web/templates/html_header.tmpl @@ -45,7 +45,7 @@ diff --git a/internal/webserver/web/templates/string_constants.tmpl b/internal/webserver/web/templates/string_constants.tmpl index d3e41b3..8478f1c 100644 --- a/internal/webserver/web/templates/string_constants.tmpl +++ b/internal/webserver/web/templates/string_constants.tmpl @@ -1,2 +1,2 @@ {{define "app_name"}}Gokapi{{end}} -{{define "version"}}1.3.1{{end}} +{{define "version"}}1.3.2{{end}}