diff --git a/pkg/db/fixtures/api_tokens.yml b/pkg/db/fixtures/api_tokens.yml index cad2dbe9b..b7a225616 100644 --- a/pkg/db/fixtures/api_tokens.yml +++ b/pkg/db/fixtures/api_tokens.yml @@ -38,3 +38,13 @@ owner_id: 17 created: 2023-09-01 07:00:00 # token in plaintext is tk_disabled_user_test_token_000000001234abcd +- id: 5 + title: 'locked user token' + token_salt: xK9mPr2sNq + token_hash: ee3fb2381e42ec87430519de0b59ce5fbe6ad7e0f0be40948ac28100167ed6f26fc6999f53958f589536d6291418c9419aef + token_last_eight: 12345678 + permissions: '{"tasks":["read_all"]}' + expires_at: 2099-01-01 00:00:00 + owner_id: 18 + created: 2023-09-01 07:00:00 + # token in plaintext is tk_locked_user_test_token_0000000012345678 diff --git a/pkg/db/fixtures/users.yml b/pkg/db/fixtures/users.yml index 9bbee147e..e3f23c58d 100644 --- a/pkg/db/fixtures/users.yml +++ b/pkg/db/fixtures/users.yml @@ -136,3 +136,12 @@ issuer: local updated: 2018-12-02 15:13:12 created: 2018-12-01 15:13:12 +# Locked user for security tests +- id: 18 + username: 'user18' + password: '$2a$04$X4aRMEt0ytgPwMIgv36cI..7X9.nhY/.tYwxpqSi0ykRHx2CwQ0S6' # 12345678 + email: 'user18@example.com' + status: 3 + issuer: local + updated: 2018-12-02 15:13:12 + created: 2018-12-01 15:13:12 diff --git a/pkg/user/user_test.go b/pkg/user/user_test.go index fb75dae7c..a5bc263c7 100644 --- a/pkg/user/user_test.go +++ b/pkg/user/user_test.go @@ -329,6 +329,16 @@ func TestCheckUserCredentials(t *testing.T) { require.Error(t, err) assert.True(t, IsErrAccountDisabled(err)) }) + t.Run("locked user", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + + // user18 is locked (status=3), password is "12345678" + _, err := CheckUserCredentials(s, &Login{Username: "user18", Password: "12345678"}) + require.Error(t, err) + assert.True(t, IsErrAccountLocked(err)) + }) } func TestUpdateUser(t *testing.T) { diff --git a/pkg/webtests/api_tokens_test.go b/pkg/webtests/api_tokens_test.go index e47f53a16..8434cd488 100644 --- a/pkg/webtests/api_tokens_test.go +++ b/pkg/webtests/api_tokens_test.go @@ -112,6 +112,21 @@ func TestAPIToken(t *testing.T) { assert.Equal(t, http.StatusUnauthorized, res.Code) assert.Contains(t, res.Body.String(), `"code":11`) }) + t.Run("locked user token rejected", func(t *testing.T) { + e, err := setupTestEnv() + require.NoError(t, err) + req := httptest.NewRequest(http.MethodGet, "/api/v1/tasks", nil) + res := httptest.NewRecorder() + c := e.NewContext(req, res) + h := routes.SetupTokenMiddleware()(func(c *echo.Context) error { + return c.String(http.StatusOK, "test") + }) + + req.Header.Set(echo.HeaderAuthorization, "Bearer tk_locked_user_test_token_0000000012345678") // Token 5 (locked user 18) + require.NoError(t, h(c)) + assert.Equal(t, http.StatusUnauthorized, res.Code) + assert.Contains(t, res.Body.String(), `"code":11`) + }) t.Run("jwt", func(t *testing.T) { e, err := setupTestEnv() require.NoError(t, err) diff --git a/pkg/webtests/caldav_test.go b/pkg/webtests/caldav_test.go index 2ef0b3f7b..f0aa461d6 100644 --- a/pkg/webtests/caldav_test.go +++ b/pkg/webtests/caldav_test.go @@ -770,4 +770,13 @@ func TestCaldavDisabledUserRejected(t *testing.T) { require.NoError(t, err) assert.False(t, result, "disabled user should not be able to authenticate via CalDAV") }) + t.Run("locked user cannot authenticate via CalDAV", func(t *testing.T) { + e, _ := setupTestEnv() + c, _ := createRequest(e, http.MethodGet, "", nil, nil) + + // user18 is locked (status=3), password is "12345678" + result, err := caldav.BasicAuth(c, "user18", "12345678") + require.NoError(t, err) + assert.False(t, result, "locked user should not be able to authenticate via CalDAV") + }) }