test(auth): add failing unit tests for OIDC TOTP enforcement

Covers the four states the OIDC TOTP gate must handle: user without
TOTP, TOTP enabled with missing passcode, invalid passcode, and
valid passcode. The helper function under test does not exist yet,
so the package currently fails to compile.

Refs GHSA-8jvc-mcx6-r4cg
This commit is contained in:
kolaente
2026-04-09 13:13:43 +02:00
committed by kolaente
parent 2b980be20d
commit d291e3effe

View File

@@ -18,12 +18,14 @@ package openid
import (
"testing"
"time"
"code.vikunja.io/api/pkg/models"
"code.vikunja.io/api/pkg/db"
"code.vikunja.io/api/pkg/user"
"github.com/coreos/go-oidc/v3/oidc"
"github.com/pquerna/otp/totp"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -420,6 +422,57 @@ func TestMergeClaims(t *testing.T) {
})
}
func TestEnforceTOTPIfRequired(t *testing.T) {
// user 10 has TOTP enabled in pkg/db/fixtures/totp.yml with this secret.
const user10Secret = "JBSWY3DPEHPK3PXP"
t.Run("user without TOTP - no passcode required", func(t *testing.T) {
db.LoadAndAssertFixtures(t)
s := db.NewSession()
defer s.Close()
// user 1 has a totp row but with enabled=false.
u := &user.User{ID: 1}
err := enforceTOTPIfRequired(s, u, "")
require.NoError(t, err)
})
t.Run("TOTP enabled - missing passcode returns ErrInvalidTOTPPasscode", func(t *testing.T) {
db.LoadAndAssertFixtures(t)
s := db.NewSession()
defer s.Close()
u := &user.User{ID: 10}
err := enforceTOTPIfRequired(s, u, "")
require.Error(t, err)
assert.True(t, user.IsErrInvalidTOTPPasscode(err))
})
t.Run("TOTP enabled - invalid passcode returns ErrInvalidTOTPPasscode", func(t *testing.T) {
db.LoadAndAssertFixtures(t)
s := db.NewSession()
defer s.Close()
u := &user.User{ID: 10}
err := enforceTOTPIfRequired(s, u, "000000")
require.Error(t, err)
assert.True(t, user.IsErrInvalidTOTPPasscode(err))
})
t.Run("TOTP enabled - valid passcode succeeds", func(t *testing.T) {
db.LoadAndAssertFixtures(t)
s := db.NewSession()
defer s.Close()
passcode, err := totp.GenerateCode(user10Secret, time.Now())
require.NoError(t, err)
u := &user.User{ID: 10}
err = enforceTOTPIfRequired(s, u, passcode)
require.NoError(t, err)
})
}
func TestSyncUserAvatarFromOpenID(t *testing.T) {
t.Run("empty picture URL resets openid provider to default", func(t *testing.T) {
db.LoadAndAssertFixtures(t)