mirror of
https://github.com/OpenListTeam/OpenList.git
synced 2026-11-10 12:43:54 +08:00
fix(auth): match SQLite username constraint errors (#3295)
- Match the UNIQUE constraint text anywhere in the SQLite error message. - Add regression tests for the SSO auto-registration username retry. - Verify the fix with targeted SSO tests and go vet. Co-authored-by: LunelleEverdawn <lunelle+suyunmeng@oplist.org>
This commit is contained in:
1 parent
05d3fea069
commit
e7b6fac89c
2 files changed
+59
-1
No files matched your search
@@ -296,7 +296,7 @@ func autoRegister(username, userID string, err error) (*model.User, error) {
|
||||
SsoID: userID,
|
||||
}
|
||||
if err = db.CreateUser(user); err != nil {
|
||||
if strings.HasPrefix(err.Error(), "UNIQUE constraint failed") && strings.HasSuffix(err.Error(), "username") {
|
||||
if strings.Contains(err.Error(), "UNIQUE constraint failed") && strings.Contains(err.Error(), "username") {
|
||||
user.Username = user.Username + "_" + userID
|
||||
if err = db.CreateUser(user); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package handles
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/conf"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/db"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/model"
|
||||
"github.com/OpenListTeam/OpenList/v4/internal/op"
|
||||
"github.com/glebarez/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func setupAutoRegisterTest(t *testing.T) {
|
||||
t.Helper()
|
||||
database, err := gorm.Open(sqlite.Open("file:"+t.Name()+"?mode=memory&cache=shared"), &gorm.Config{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
conf.Conf = conf.DefaultConfig(t.TempDir())
|
||||
db.Init(database)
|
||||
for key, value := range map[string]string{
|
||||
conf.SSOAutoRegister: "true",
|
||||
conf.SSODefaultPermission: "0",
|
||||
conf.SSODefaultDir: "/",
|
||||
} {
|
||||
op.Cache.SetSetting(key, &model.SettingItem{Key: key, Value: value})
|
||||
}
|
||||
t.Cleanup(op.Cache.ClearAll)
|
||||
}
|
||||
|
||||
// Re-login after unbinding SSO: the username is still taken by the unbound
|
||||
// user, so registration must retry with the SSO ID suffix instead of failing.
|
||||
func TestAutoRegisterRetriesOnUsernameConflict(t *testing.T) {
|
||||
setupAutoRegisterTest(t)
|
||||
if err := db.CreateUser(&model.User{Username: "alice"}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
user, err := autoRegister("alice", "sso-1", gorm.ErrRecordNotFound)
|
||||
if err != nil {
|
||||
t.Fatalf("expected retry to succeed, got: %v", err)
|
||||
}
|
||||
if user.Username != "alice_sso-1" || user.SsoID != "sso-1" {
|
||||
t.Fatalf("unexpected user: username=%q sso_id=%q", user.Username, user.SsoID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAutoRegisterReturnsUnrelatedErrors(t *testing.T) {
|
||||
setupAutoRegisterTest(t)
|
||||
want := errors.New("unrelated")
|
||||
|
||||
user, err := autoRegister("alice", "sso-1", want)
|
||||
if user != nil || !errors.Is(err, want) {
|
||||
t.Fatalf("expected original error, got user=%v err=%v", user, err)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user