diff --git a/server/store/datastore/org.go b/server/store/datastore/org.go index eb18ac8df0d..59fa18f804a 100644 --- a/server/store/datastore/org.go +++ b/server/store/datastore/org.go @@ -77,9 +77,15 @@ func (s storage) orgDelete(sess *xorm.Session, id int64) error { func (s storage) OrgFindByName(name string) (*model.Org, error) { // sanitize name = strings.ToLower(name) - // find org := new(model.Org) - return org, wrapGet(s.engine.Where("name = ?", name).Get(org)) + has, err := s.engine.Where("name = ?", name).Get(org) + if err != nil { + return nil, fmt.Errorf("failed to check if org exists: %w", err) + } + if !has { + return nil, nil + } + return org, nil } func (s storage) OrgRepoList(org *model.Org, p *model.ListOptions) ([]*model.Repo, error) { diff --git a/server/store/datastore/user.go b/server/store/datastore/user.go index aa3d35f7d70..deeddf54275 100644 --- a/server/store/datastore/user.go +++ b/server/store/datastore/user.go @@ -15,6 +15,8 @@ package datastore import ( + "fmt" + "xorm.io/xorm" "go.woodpecker-ci.org/woodpecker/v3/server/model" @@ -59,9 +61,24 @@ func (s storage) CreateUser(user *model.User) error { Name: user.Login, IsUser: true, } - err := s.orgCreate(org, sess) + + existingOrg, err := s.OrgFindByName(org.Name) if err != nil { - return err + return fmt.Errorf("failed to check if org exists: %w", err) + } + + if existingOrg != nil { + if existingOrg.Name == user.Login { + err = s.OrgUpdate(org) + if err != nil { + return fmt.Errorf("failed to update existing org: %w", err) + } + } + } else { + err = s.orgCreate(org, sess) + if err != nil { + return fmt.Errorf("failed to create new org: %w", err) + } } user.OrgID = org.ID // only Insert set auto created ID back to object diff --git a/server/store/datastore/users_test.go b/server/store/datastore/users_test.go index 0189e9f49bb..410daa36fca 100644 --- a/server/store/datastore/users_test.go +++ b/server/store/datastore/users_test.go @@ -94,3 +94,42 @@ func TestUsers(t *testing.T) { _, err3 := store.GetUser(getUser.ID) assert.Error(t, err3) } + +func TestCreateUserWithExistingOrg(t *testing.T) { + store, closer := newTestStore(t, new(model.User), new(model.Org), new(model.Perm)) + defer closer() + + existingOrg := &model.Org{ + ForgeID: 1, + IsUser: true, + Name: "existingorg", + Private: false, + } + + err := store.OrgCreate(existingOrg) + assert.NoError(t, err) + assert.EqualValues(t, "existingorg", existingOrg.Name) + + // Create a new user with the same name as the existing organization + newUser := &model.User{ + Login: "existingOrg", + Hash: "A", + } + err = store.CreateUser(newUser) + assert.NoError(t, err) + + updatedOrg, err := store.OrgGet(existingOrg.ID) + assert.NoError(t, err) + assert.Equal(t, "existingorg", updatedOrg.Name) + + newUser2 := &model.User{ + Login: "new-user", + Hash: "B", + } + err = store.CreateUser(newUser2) + assert.NoError(t, err) + + newOrg, err := store.OrgFindByName("new-user") + assert.NoError(t, err) + assert.Equal(t, "new-user", newOrg.Name) +}