From 83c5190c9b5b1fe84692d409c33fb717efdcf9c4 Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 5 Apr 2026 19:48:06 +0200 Subject: [PATCH] feat(user): add BotOwnerID field and IsBot helper --- pkg/user/user.go | 17 ++++++++++++++--- pkg/user/user_test.go | 11 +++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/pkg/user/user.go b/pkg/user/user.go index 2d46341f8..ae2305628 100644 --- a/pkg/user/user.go +++ b/pkg/user/user.go @@ -110,9 +110,12 @@ type User struct { OverdueTasksRemindersEnabled bool `xorm:"bool default true index" json:"-"` OverdueTasksRemindersTime string `xorm:"varchar(5) not null default '09:00'" json:"-"` DefaultProjectID int64 `xorm:"bigint null index" json:"-"` - WeekStart int `xorm:"null" json:"-"` - Language string `xorm:"varchar(50) null" json:"-" valid:"language"` - Timezone string `xorm:"varchar(255) null" json:"-"` + // BotOwnerID is the ID of the owning (human) user if this user is a bot. + // A non-zero value means this user is a bot and cannot authenticate via password. + BotOwnerID int64 `xorm:"bigint null index" json:"bot_owner_id,omitempty"` + WeekStart int `xorm:"null" json:"-"` + Language string `xorm:"varchar(50) null" json:"-" valid:"language"` + Timezone string `xorm:"varchar(255) null" json:"-"` DeletionScheduledAt time.Time `xorm:"datetime null" json:"-"` DeletionLastReminderSent time.Time `xorm:"datetime null" json:"-"` @@ -152,6 +155,9 @@ func (u *User) RouteForDB() int64 { } func (u *User) ShouldNotify(sessions ...*xorm.Session) (bool, error) { + if u.IsBot() { + return false, nil + } var s *xorm.Session if len(sessions) > 0 && sessions[0] != nil { s = sessions[0] @@ -178,6 +184,11 @@ func (u *User) GetID() int64 { return u.ID } +// IsBot reports whether this user is a bot (owned by another user). +func (u *User) IsBot() bool { + return u.BotOwnerID > 0 +} + // TableName returns the table name for users func (*User) TableName() string { return "users" diff --git a/pkg/user/user_test.go b/pkg/user/user_test.go index a5bc263c7..25f9802c3 100644 --- a/pkg/user/user_test.go +++ b/pkg/user/user_test.go @@ -25,6 +25,17 @@ import ( "github.com/stretchr/testify/require" ) +func TestUser_IsBot(t *testing.T) { + t.Run("regular user", func(t *testing.T) { + u := &User{ID: 1} + assert.False(t, u.IsBot()) + }) + t.Run("bot user", func(t *testing.T) { + u := &User{ID: 2, BotOwnerID: 1} + assert.True(t, u.IsBot()) + }) +} + func TestCreateUser(t *testing.T) { // Our dummy user for testing dummyuser := &User{