shiori/internal/http/handlers/api/v1/auth_test.go
Felipe Martin 514df1e8ab
fix: auth validation on existing sessions, rely on token only (#1069)
* chore: use http.NoBody

* fix: remove cookie token on logout

* fix: remove token cookie on middleware and redirect

* fix: frontend sets cookie token if authenticated

* refactor: remove session-id, rely on token only

* docs: make swagger

* fix: redirect

* fix: archive route handler

* fix: properly unset cookie
2025-02-28 20:30:07 +01:00

206 lines
6.7 KiB
Go

package api_v1
import (
"context"
"net/http"
"testing"
"github.com/go-shiori/shiori/internal/model"
"github.com/go-shiori/shiori/internal/testutil"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
)
func TestHandleLogin(t *testing.T) {
logger := logrus.New()
// _, deps := testutil.GetTestConfigurationAndDependencies(t, context.Background(), logger)
t.Run("invalid json payload", func(t *testing.T) {
ctx := context.Background()
_, deps := testutil.GetTestConfigurationAndDependencies(t, ctx, logger)
body := `{"username":}`
w := testutil.PerformRequest(deps, HandleLogin, "POST", "/login", testutil.WithBody(body))
require.Equal(t, http.StatusBadRequest, w.Code)
})
t.Run("missing username", func(t *testing.T) {
ctx := context.Background()
_, deps := testutil.GetTestConfigurationAndDependencies(t, ctx, logger)
body := `{"password": "test"}`
w := testutil.PerformRequest(deps, HandleLogin, "POST", "/login", testutil.WithBody(body))
require.Equal(t, http.StatusBadRequest, w.Code)
})
t.Run("missing password", func(t *testing.T) {
ctx := context.Background()
_, deps := testutil.GetTestConfigurationAndDependencies(t, ctx, logger)
body := `{"username": "test"}`
w := testutil.PerformRequest(deps, HandleLogin, "POST", "/login", testutil.WithBody(body))
require.Equal(t, http.StatusBadRequest, w.Code)
})
t.Run("invalid credentials", func(t *testing.T) {
ctx := context.Background()
_, deps := testutil.GetTestConfigurationAndDependencies(t, ctx, logger)
body := `{"username": "test", "password": "wrong"}`
w := testutil.PerformRequest(deps, HandleLogin, "POST", "/login", testutil.WithBody(body))
require.Equal(t, http.StatusBadRequest, w.Code)
})
t.Run("successful login", func(t *testing.T) {
ctx := context.Background()
_, deps := testutil.GetTestConfigurationAndDependencies(t, ctx, logger)
account := testutil.GetValidAccount().ToDTO()
account.Password = "test"
_, err := deps.Domains().Accounts().CreateAccount(context.Background(), account)
require.NoError(t, err)
body := `{
"username": "test",
"password": "test",
"remember_me": true
}`
w := testutil.PerformRequest(deps, HandleLogin, "POST", "/login", testutil.WithBody(body))
require.Equal(t, http.StatusOK, w.Code)
response, err := testutil.NewTestResponseFromReader(w.Body)
require.NoError(t, err)
response.AssertOk(t)
response.AssertMessageContains(t, "token")
response.AssertMessageContains(t, "expires")
})
}
func TestHandleRefreshToken(t *testing.T) {
logger := logrus.New()
_, deps := testutil.GetTestConfigurationAndDependencies(t, context.Background(), logger)
t.Run("requires authentication", func(t *testing.T) {
w := testutil.PerformRequest(deps, HandleRefreshToken, "POST", "/refresh")
require.Equal(t, http.StatusUnauthorized, w.Code)
})
t.Run("successful refresh", func(t *testing.T) {
account := testutil.GetValidAccount().ToDTO()
account.Password = "test"
_, err := deps.Domains().Accounts().CreateAccount(context.Background(), account)
require.NoError(t, err)
w := testutil.PerformRequest(deps, HandleRefreshToken, "POST", "/refresh", testutil.WithAccount(&account))
require.Equal(t, http.StatusAccepted, w.Code)
response, err := testutil.NewTestResponseFromReader(w.Body)
require.NoError(t, err)
response.AssertOk(t)
response.AssertMessageContains(t, "token")
})
}
func TestHandleGetMe(t *testing.T) {
logger := logrus.New()
_, deps := testutil.GetTestConfigurationAndDependencies(t, context.Background(), logger)
t.Run("requires authentication", func(t *testing.T) {
c, w := testutil.NewTestWebContext()
HandleGetMe(deps, c)
require.Equal(t, http.StatusUnauthorized, w.Code)
})
t.Run("returns user info", func(t *testing.T) {
c, w := testutil.NewTestWebContext()
testutil.SetFakeUser(c)
HandleGetMe(deps, c)
require.Equal(t, http.StatusOK, w.Code)
response, err := testutil.NewTestResponseFromReader(w.Body)
require.NoError(t, err)
response.AssertOk(t)
response.AssertMessageContains(t, "username")
})
}
func TestHandleUpdateLoggedAccount(t *testing.T) {
logger := logrus.New()
_, deps := testutil.GetTestConfigurationAndDependencies(t, context.Background(), logger)
account, err := deps.Domains().Accounts().CreateAccount(context.Background(), model.AccountDTO{
Username: "shiori",
Password: "gopher",
Owner: model.Ptr(true),
Config: model.Ptr(model.UserConfig{
ShowId: true,
ListMode: true,
HideThumbnail: true,
HideExcerpt: true,
KeepMetadata: true,
UseArchive: true,
CreateEbook: true,
MakePublic: true,
}),
})
require.NoError(t, err)
t.Run("requires authentication", func(t *testing.T) {
c, w := testutil.NewTestWebContext()
HandleUpdateLoggedAccount(deps, c)
require.Equal(t, http.StatusUnauthorized, w.Code)
})
t.Run("invalid json payload", func(t *testing.T) {
body := `invalid json`
w := testutil.PerformRequest(deps, HandleUpdateLoggedAccount, "PATCH", "/account", testutil.WithBody(body), testutil.WithAccount(account))
require.Equal(t, http.StatusInternalServerError, w.Code)
})
t.Run("missing old password", func(t *testing.T) {
body := `{"new_password": "newpass"}`
w := testutil.PerformRequest(deps, HandleUpdateLoggedAccount, "PATCH", "/account", testutil.WithBody(body), testutil.WithAccount(account))
require.Equal(t, http.StatusBadRequest, w.Code)
})
t.Run("incorrect old password", func(t *testing.T) {
body := `{
"old_password": "wrong",
"new_password": "newpass"
}`
w := testutil.PerformRequest(deps, HandleUpdateLoggedAccount, "PATCH", "/account", testutil.WithBody(body), testutil.WithAccount(account))
require.Equal(t, http.StatusBadRequest, w.Code)
})
t.Run("successful update", func(t *testing.T) {
body := `{
"old_password": "gopher",
"new_password": "newpass",
"config": {
"show_id": true,
"list_mode": true
}
}`
w := testutil.PerformRequest(deps, HandleUpdateLoggedAccount, "PATCH", "/account", testutil.WithBody(body), testutil.WithAccount(account))
require.Equal(t, http.StatusOK, w.Code)
response, err := testutil.NewTestResponseFromReader(w.Body)
require.NoError(t, err)
response.AssertOk(t)
response.AssertMessageContains(t, "config")
})
}
func TestHandleLogout(t *testing.T) {
logger := logrus.New()
_, deps := testutil.GetTestConfigurationAndDependencies(t, context.Background(), logger)
t.Run("requires authentication", func(t *testing.T) {
c, w := testutil.NewTestWebContext()
HandleLogout(deps, c)
require.Equal(t, http.StatusUnauthorized, w.Code)
})
t.Run("successful logout", func(t *testing.T) {
c, w := testutil.NewTestWebContext()
testutil.SetFakeUser(c)
HandleLogout(deps, c)
require.Equal(t, http.StatusOK, w.Code)
})
}