From 82e3d9d514876998145228fd8964a3339fa72ad2 Mon Sep 17 00:00:00 2001 From: Marc Ole Bulling Date: Sat, 11 Jan 2025 17:09:53 +0100 Subject: [PATCH] Added tests --- .../configuration/database/Database_test.go | 10 --- .../configuration/setup/templates/setup.tmpl | 4 +- .../testconfiguration/TestConfiguration.go | 15 ++++ .../authentication/Authentication.go | 7 +- .../authentication/Authentication_test.go | 76 ++++++++++++++++++- .../sessionmanager/SessionManager.go | 3 +- .../sessionmanager/SessionManager_test.go | 22 +++++- .../webserver/fileupload/FileUpload_test.go | 18 ++++- 8 files changed, 135 insertions(+), 20 deletions(-) diff --git a/internal/configuration/database/Database_test.go b/internal/configuration/database/Database_test.go index 4151eb1..5a77cea 100644 --- a/internal/configuration/database/Database_test.go +++ b/internal/configuration/database/Database_test.go @@ -1,7 +1,6 @@ package database import ( - "fmt" "github.com/alicebob/miniredis/v2" "github.com/forceu/gokapi/internal/configuration/database/dbabstraction" "github.com/forceu/gokapi/internal/models" @@ -282,15 +281,6 @@ func TestUsers(t *testing.T) { SaveUser(user, true) } -func printDbName(db dbabstraction.Database) { - switch db.GetType() { - case dbabstraction.TypeSqlite: - fmt.Println("Testing SQLite") - case dbabstraction.TypeRedis: - fmt.Println("Testing Redis") - } -} - func TestUpgrade(t *testing.T) { runAllTypesNoOutput(t, func() { test.IsEqualBool(t, db.GetDbVersion() != 1, true) }) runAllTypesNoOutput(t, func() { db.SetDbVersion(1) }) diff --git a/internal/configuration/setup/templates/setup.tmpl b/internal/configuration/setup/templates/setup.tmpl index 1a07242..cab961e 100644 --- a/internal/configuration/setup/templates/setup.tmpl +++ b/internal/configuration/setup/templates/setup.tmpl @@ -299,7 +299,7 @@
- +
Recheck identity every @@ -363,7 +363,7 @@

- +


diff --git a/internal/test/testconfiguration/TestConfiguration.go b/internal/test/testconfiguration/TestConfiguration.go index 268fa76..cdb17c8 100644 --- a/internal/test/testconfiguration/TestConfiguration.go +++ b/internal/test/testconfiguration/TestConfiguration.go @@ -213,6 +213,11 @@ func writeTestSessions() { ValidUntil: 2147483646, UserId: 7, }) + database.SaveSession("logoutsession2", models.Session{ + RenewAt: 2147483645, + ValidUntil: 2147483646, + UserId: 7, + }) database.SaveSession("needsRenewal", models.Session{ RenewAt: 0, ValidUntil: 2147483646, @@ -223,6 +228,16 @@ func writeTestSessions() { ValidUntil: 0, UserId: 7, }) + database.SaveSession("validSessionInvalidUser", models.Session{ + RenewAt: 2147483645, + ValidUntil: 2147483645, + UserId: 5000, + }) + database.SaveSession("validSessionInvalidUser", models.Session{ + RenewAt: 2147483645, + ValidUntil: 2147483645, + UserId: 5000, + }) } func writeTestUploadStatus() { pstatusdb.Set(models.UploadStatus{ diff --git a/internal/webserver/authentication/Authentication.go b/internal/webserver/authentication/Authentication.go index e0b8306..ba4c7aa 100644 --- a/internal/webserver/authentication/Authentication.go +++ b/internal/webserver/authentication/Authentication.go @@ -13,6 +13,7 @@ import ( "io" "log" "net/http" + "os" "regexp" "strings" ) @@ -27,11 +28,15 @@ func Init(config models.AuthenticationConfig) { valid, err := isValid(config) if !valid { log.Println("Error while initiating authentication method:") - log.Fatal(err) + log.Println(err) + osExit(3) + return } authSettings = config } +var osExit = os.Exit + // isValid checks if the config is actually valid, and returns true or returns false and an error func isValid(config models.AuthenticationConfig) (bool, error) { switch config.Method { diff --git a/internal/webserver/authentication/Authentication_test.go b/internal/webserver/authentication/Authentication_test.go index b1e0872..fb6ca2b 100644 --- a/internal/webserver/authentication/Authentication_test.go +++ b/internal/webserver/authentication/Authentication_test.go @@ -1,14 +1,18 @@ package authentication import ( + "context" "encoding/json" "errors" "fmt" "github.com/forceu/gokapi/internal/configuration" + "github.com/forceu/gokapi/internal/configuration/database" "github.com/forceu/gokapi/internal/models" "github.com/forceu/gokapi/internal/test" "github.com/forceu/gokapi/internal/test/testconfiguration" + "github.com/forceu/gokapi/internal/webserver/authentication/sessionmanager" "io" + "net/http" "net/http/httptest" "os" "strings" @@ -41,6 +45,8 @@ func TestIsCorrectUsernameAndPassword(t *testing.T) { test.IsEqualInt(t, user.Id, 7) _, ok = IsCorrectUsernameAndPassword("test", "wrong") test.IsEqualBool(t, ok, false) + _, ok = IsCorrectUsernameAndPassword("invalid", "adminadmin") + test.IsEqualBool(t, ok, false) } func TestIsAuthenticated(t *testing.T) { @@ -54,6 +60,12 @@ func TestIsAuthenticated(t *testing.T) { } func testAuthSession(t *testing.T) { + + exitCode := 0 + osExit = func(code int) { + exitCode = code + } + w, r := test.GetRecorder("GET", "/", nil, nil, nil) Init(modelUserPW) _, ok := IsAuthenticated(w, r) @@ -69,6 +81,13 @@ func testAuthSession(t *testing.T) { user, ok := IsAuthenticated(w, r) test.IsEqualBool(t, ok, true) test.IsEqualInt(t, user.Id, 7) + test.IsEqualInt(t, exitCode, 0) + + Init(models.AuthenticationConfig{ + Method: 10, + }) + test.IsEqualInt(t, exitCode, 3) + } func testAuthHeader(t *testing.T) { @@ -132,6 +151,32 @@ func TestRedirect(t *testing.T) { test.IsEqualString(t, string(output), "") } +func TestGetUserFromRequest(t *testing.T) { + _, r := test.GetRecorder("GET", "/", nil, nil, nil) + _, err := GetUserFromRequest(r) + test.IsNotNil(t, err) + c := context.WithValue(r.Context(), "user", "invalid") + rInvalid := r.WithContext(c) + _, err = GetUserFromRequest(rInvalid) + test.IsNotNil(t, err) + + user := models.User{ + Id: 1, + Name: "test", + Permissions: 1, + UserLevel: 2, + LastOnline: 3, + Password: "12345", + ResetPassword: true, + } + + c = context.WithValue(r.Context(), "user", user) + rValid := r.WithContext(c) + retrievedUser, err := GetUserFromRequest(rValid) + test.IsNil(t, err) + test.IsEqual(t, retrievedUser, user) +} + func TestIsValidOauthUser(t *testing.T) { Init(modelOauth) info := OAuthUserInfo{Email: "", Subject: "randomid"} @@ -223,10 +268,39 @@ func TestWildcardMatch(t *testing.T) { } } +func getRecorder(cookies []test.Cookie) (*httptest.ResponseRecorder, *http.Request, bool, int) { + w, r := test.GetRecorder("GET", "/", cookies, nil, nil) + return w, r, false, 1 +} + func TestLogout(t *testing.T) { Init(modelUserPW) - w, r := test.GetRecorder("GET", "/", nil, nil, nil) + w, r, _, _ := getRecorder([]test.Cookie{{ + Name: "session_token", + Value: "logoutsession"}, + }) + _, ok := sessionmanager.IsValidSession(w, r, false, 0) + test.IsEqualBool(t, ok, true) + Logout(w, r) + _, ok = database.GetSession("logoutsession") + test.IsEqualBool(t, ok, false) + _, ok = sessionmanager.IsValidSession(w, r, false, 0) + test.IsEqualBool(t, ok, false) + test.ResponseBodyContains(t, w, "") + + Init(modelOauth) + w, r, _, _ = getRecorder([]test.Cookie{{ + Name: "session_token", + Value: "logoutsession2"}, + }) + _, ok = sessionmanager.IsValidSession(w, r, false, 0) + test.IsEqualBool(t, ok, true) Logout(w, r) + _, ok = database.GetSession("logoutsession") + test.IsEqualBool(t, ok, false) + _, ok = sessionmanager.IsValidSession(w, r, false, 0) + test.IsEqualBool(t, ok, false) + test.ResponseBodyContains(t, w, "") } type testInfo struct { diff --git a/internal/webserver/authentication/sessionmanager/SessionManager.go b/internal/webserver/authentication/sessionmanager/SessionManager.go index 401e5ab..57e33dc 100644 --- a/internal/webserver/authentication/sessionmanager/SessionManager.go +++ b/internal/webserver/authentication/sessionmanager/SessionManager.go @@ -14,6 +14,7 @@ import ( // If no login occurred during this time, the admin session will be deleted. Default 30 days const cookieLifeAdmin = 30 * 24 * time.Hour +const lengthSessionId = 60 // IsValidSession checks if the user is submitting a valid session token // If valid session is found, useSession will be called @@ -61,7 +62,7 @@ func CreateSession(w http.ResponseWriter, isOauth bool, OAuthRecheckInterval int timeExpiry = time.Now().Add(time.Duration(OAuthRecheckInterval) * time.Hour) } - sessionString := helper.GenerateRandomString(60) + sessionString := helper.GenerateRandomString(lengthSessionId) database.SaveSession(sessionString, models.Session{ RenewAt: time.Now().Add(12 * time.Hour).Unix(), ValidUntil: timeExpiry.Unix(), diff --git a/internal/webserver/authentication/sessionmanager/SessionManager_test.go b/internal/webserver/authentication/sessionmanager/SessionManager_test.go index 1b17fb1..eb47662 100644 --- a/internal/webserver/authentication/sessionmanager/SessionManager_test.go +++ b/internal/webserver/authentication/sessionmanager/SessionManager_test.go @@ -2,12 +2,15 @@ package sessionmanager import ( "github.com/forceu/gokapi/internal/configuration" + "github.com/forceu/gokapi/internal/configuration/database" + "github.com/forceu/gokapi/internal/models" "github.com/forceu/gokapi/internal/test" "github.com/forceu/gokapi/internal/test/testconfiguration" "net/http" "net/http/httptest" "os" "testing" + "time" ) var newSession string @@ -49,14 +52,17 @@ func TestIsValidSession(t *testing.T) { Value: "validsession"}, })) test.IsEqualBool(t, ok, true) + _, ok = IsValidSession(getRecorder([]test.Cookie{{ + Name: "session_token", + Value: "validSessionInvalidUser"}, + })) + test.IsEqualBool(t, ok, false) test.IsEqualInt(t, user.Id, 7) w, r, _, _ := getRecorder([]test.Cookie{{ Name: "session_token", Value: "needsRenewal"}, }) user, ok = IsValidSession(w, r, false, 1) - test.IsEqualBool(t, ok, true) - test.IsEqualInt(t, user.Id, 7) cookies := w.Result().Cookies() test.IsEqualInt(t, len(cookies), 1) test.IsEqualString(t, cookies[0].Name, "session_token") @@ -80,6 +86,18 @@ func TestCreateSession(t *testing.T) { })) test.IsEqualBool(t, ok, true) test.IsEqualInt(t, user.Id, 5) + + w, _, _, _ = getRecorder(nil) + CreateSession(w, true, 20, 50) + cookies = w.Result().Cookies() + newOauthSession := cookies[0].Value + + var session models.Session + session, ok = database.GetSession(newOauthSession) + test.IsEqualBool(t, ok, true) + isEqual := time.Now().Add(20*time.Hour).Unix()-session.ValidUntil < 10 && + time.Now().Add(20*time.Hour).Unix()-session.ValidUntil > -1 + test.IsEqualBool(t, isEqual, true) } func TestLogoutSession(t *testing.T) { diff --git a/internal/webserver/fileupload/FileUpload_test.go b/internal/webserver/fileupload/FileUpload_test.go index 113b912..3d58a98 100644 --- a/internal/webserver/fileupload/FileUpload_test.go +++ b/internal/webserver/fileupload/FileUpload_test.go @@ -116,16 +116,28 @@ func TestProcessNewChunk(t *testing.T) { } func TestCompleteChunk(t *testing.T) { - w, r := test.GetRecorder("POST", "/uploadComplete", nil, nil, strings.NewReader("invalid§$%&%§")) + body := strings.NewReader("%") + r := httptest.NewRequest(http.MethodPost, "/upload", body) + r.Header.Set("Content-Type", "application/x-www-form-urlencoded") + _, _, _, err := ParseFileHeader(r) test.IsNotNil(t, err) - w = httptest.NewRecorder() + w := httptest.NewRecorder() r = getFileUploadRecorder(false) _, _, _, err = ParseFileHeader(r) test.IsNotNil(t, err) data := url.Values{} + data.Set("isE2E", "true") + data.Set("realSize", "none") + w, r = test.GetRecorder("POST", "/uploadComplete", nil, nil, strings.NewReader(data.Encode())) + r.Header.Set("Content-type", "application/x-www-form-urlencoded") + chunkId, header, config, err := ParseFileHeader(r) + test.IsNotNil(t, err) + + data.Del("isE2E") + data.Del("realSize") data.Set("allowedDownloads", "9") data.Set("expiryDays", "5") data.Set("password", "123") @@ -134,7 +146,7 @@ func TestCompleteChunk(t *testing.T) { data.Set("filesize", "13") w, r = test.GetRecorder("POST", "/uploadComplete", nil, nil, strings.NewReader(data.Encode())) r.Header.Set("Content-type", "application/x-www-form-urlencoded") - chunkId, header, config, err := ParseFileHeader(r) + chunkId, header, config, err = ParseFileHeader(r) test.IsNil(t, err) file, err := CompleteChunk(chunkId, header, 9, config) test.IsNil(t, err)