diff --git a/pkg/models/project.go b/pkg/models/project.go index de688348f..623a02811 100644 --- a/pkg/models/project.go +++ b/pkg/models/project.go @@ -1046,8 +1046,17 @@ func CreateProject(s *xorm.Session, project *Project, auth web.Auth, createBackl } project.ID = 0 - project.OwnerID = doer.ID - project.Owner = doer + if doer.IsBot() { + project.OwnerID = doer.BotOwnerID + owner, err := user.GetUserByID(s, doer.BotOwnerID) + if err != nil { + return err + } + project.Owner = owner + } else { + project.OwnerID = doer.ID + project.Owner = doer + } err = checkProjectBeforeUpdateOrDelete(s, project) if err != nil { @@ -1061,6 +1070,18 @@ func CreateProject(s *xorm.Session, project *Project, auth web.Auth, createBackl return } + // Give the bot continued access to the project it created. + if doer.IsBot() { + pu := &ProjectUser{ + ProjectID: project.ID, + Username: doer.Username, + Permission: PermissionAdmin, + } + if err = pu.Create(s, auth); err != nil { + return err + } + } + project.Position = calculateDefaultPosition(project.ID, project.Position) _, err = s.Where("id = ?", project.ID).Update(project) if err != nil { diff --git a/pkg/models/project_test.go b/pkg/models/project_test.go index 47c95cb9b..798c8c4cf 100644 --- a/pkg/models/project_test.go +++ b/pkg/models/project_test.go @@ -79,6 +79,29 @@ func TestProject_CreateOrUpdate(t *testing.T) { "project_view_id": kanbanView.ID, }, false) }) + t.Run("bot project owned by bot owner", func(t *testing.T) { + db.LoadAndAssertFixtures(t) + s := db.NewSession() + defer s.Close() + + bot := &user.User{ID: 23, Username: "bot-owner-a-assistant", BotOwnerID: 21} + project := Project{Title: "bot-created"} + err := project.Create(s, bot) + require.NoError(t, err) + require.NoError(t, s.Commit()) + + // The bot's owner should own the project. + db.AssertExists(t, "projects", map[string]interface{}{ + "id": project.ID, + "owner_id": 21, + }, false) + // The bot should retain access via a share. + db.AssertExists(t, "users_projects", map[string]interface{}{ + "user_id": 23, + "project_id": project.ID, + "permission": PermissionAdmin, + }, false) + }) t.Run("kanban view creates To-Do, doing, done buckets", func(t *testing.T) { db.LoadAndAssertFixtures(t) s := db.NewSession()