Chore: Add org methods to org service and store (#55579)

* Add org methods to org service and store

* Fix name of fake

* Remove unused fake

* Add xorm tags and half of a test

* Add cmment for clarifying missing part of test

* Add some comments about future refactors

* Rename test

* Add test for update org address
This commit is contained in:
idafurjes 2022-09-21 18:00:18 +02:00 committed by GitHub
parent 23afb0c04e
commit 48a8b35ece
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 200 additions and 2 deletions

View File

@ -97,6 +97,24 @@ type GetOrgByNameQuery struct {
Name string
}
type UpdateOrgAddressCommand struct {
OrgID int64 `xorm:"org_id"`
Address
}
type Address struct {
Address1 string `json:"address1"`
Address2 string `json:"address2"`
City string `json:"city"`
ZipCode string `json:"zipCode"`
State string `json:"state"`
Country string `json:"country"`
}
type DeleteOrgCommand struct {
ID int64 `xorm:"id"`
}
func (r RoleType) IsValid() bool {
return r == RoleViewer || r == RoleAdmin || r == RoleEditor
}

View File

@ -14,6 +14,9 @@ type Service interface {
GetByID(context.Context, *GetOrgByIdQuery) (*Org, error)
GetByNameHandler(context.Context, *GetOrgByNameQuery) (*Org, error)
GetByName(string) (*Org, error)
CreateWithMember(name string, userID int64) (*Org, error)
Create(ctx context.Context, cmd *CreateOrgCommand) (*Org, error)
CreateWithMember(string, int64) (*Org, error)
Create(context.Context, *CreateOrgCommand) (*Org, error)
UpdateAddress(context.Context, *UpdateOrgAddressCommand) error
Delete(context.Context, *DeleteOrgCommand) error
GetOrCreate(context.Context, string) (int64, error)
}

View File

@ -243,3 +243,45 @@ func (s *Service) Create(ctx context.Context, cmd *org.CreateOrgCommand) (*org.O
Updated: q.Result.Updated,
}, nil
}
// TODO: refactor service to call store CRUD method
func (s *Service) UpdateAddress(ctx context.Context, cmd *org.UpdateOrgAddressCommand) error {
return s.store.UpdateAddress(ctx, cmd)
}
// TODO: refactor service to call store CRUD method
func (s *Service) Delete(ctx context.Context, cmd *org.DeleteOrgCommand) error {
return s.store.Delete(ctx, cmd)
}
func (s *Service) GetOrCreate(ctx context.Context, orgName string) (int64, error) {
var orga *org.Org
var err error
if s.cfg.AutoAssignOrg {
orga, err = s.store.Get(ctx, int64(s.cfg.AutoAssignOrgId))
if err != nil {
return 0, err
}
if s.cfg.AutoAssignOrgId != 1 {
s.log.Error("Could not create user: organization ID does not exist", "orgID",
s.cfg.AutoAssignOrgId)
return 0, fmt.Errorf("could not create user: organization ID %d does not exist",
s.cfg.AutoAssignOrgId)
}
orga.Name = MainOrgName
orga.ID = int64(s.cfg.AutoAssignOrgId)
} else {
orga.Name = orgName
}
orga.Created = time.Now()
orga.Updated = time.Now()
_, err = s.store.Insert(ctx, orga)
if err != nil {
return 0, err
}
return orga.ID, nil
}

View File

@ -83,3 +83,11 @@ func (f *FakeOrgStore) DeleteUserFromAll(ctx context.Context, userID int64) erro
func (f *FakeOrgStore) Update(ctx context.Context, cmd *org.UpdateOrgCommand) error {
return f.ExpectedError
}
func (f *FakeOrgStore) UpdateAddress(ctx context.Context, cmd *org.UpdateOrgAddressCommand) error {
return f.ExpectedError
}
func (f *FakeOrgStore) Delete(ctx context.Context, cmd *org.DeleteOrgCommand) error {
return f.ExpectedError
}

View File

@ -20,6 +20,10 @@ type store interface {
InsertOrgUser(context.Context, *org.OrgUser) (int64, error)
DeleteUserFromAll(context.Context, int64) error
Update(ctx context.Context, cmd *org.UpdateOrgCommand) error
// TO BE REFACTORED - move logic to service methods and leave CRUD methods for store
UpdateAddress(context.Context, *org.UpdateOrgAddressCommand) error
Delete(context.Context, *org.DeleteOrgCommand) error
}
type sqlStore struct {
@ -143,3 +147,73 @@ func isOrgNameTaken(name string, existingId int64, sess *sqlstore.DBSession) (bo
return false, nil
}
// TODO: refactor move logic to service method
func (ss *sqlStore) UpdateAddress(ctx context.Context, cmd *org.UpdateOrgAddressCommand) error {
return ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
org := models.Org{
Address1: cmd.Address1,
Address2: cmd.Address2,
City: cmd.City,
ZipCode: cmd.ZipCode,
State: cmd.State,
Country: cmd.Country,
Updated: time.Now(),
}
if _, err := sess.ID(cmd.OrgID).Update(&org); err != nil {
return err
}
sess.PublishAfterCommit(&events.OrgUpdated{
Timestamp: org.Updated,
Id: org.Id,
Name: org.Name,
})
return nil
})
}
// TODO: refactor move logic to service method
func (ss *sqlStore) Delete(ctx context.Context, cmd *org.DeleteOrgCommand) error {
return ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
if res, err := sess.Query("SELECT 1 from org WHERE id=?", cmd.ID); err != nil {
return err
} else if len(res) != 1 {
return models.ErrOrgNotFound
}
deletes := []string{
"DELETE FROM star WHERE EXISTS (SELECT 1 FROM dashboard WHERE org_id = ? AND star.dashboard_id = dashboard.id)",
"DELETE FROM dashboard_tag WHERE EXISTS (SELECT 1 FROM dashboard WHERE org_id = ? AND dashboard_tag.dashboard_id = dashboard.id)",
"DELETE FROM dashboard WHERE org_id = ?",
"DELETE FROM api_key WHERE org_id = ?",
"DELETE FROM data_source WHERE org_id = ?",
"DELETE FROM org_user WHERE org_id = ?",
"DELETE FROM org WHERE id = ?",
"DELETE FROM temp_user WHERE org_id = ?",
"DELETE FROM ngalert_configuration WHERE org_id = ?",
"DELETE FROM alert_configuration WHERE org_id = ?",
"DELETE FROM alert_instance WHERE rule_org_id = ?",
"DELETE FROM alert_notification WHERE org_id = ?",
"DELETE FROM alert_notification_state WHERE org_id = ?",
"DELETE FROM alert_rule WHERE org_id = ?",
"DELETE FROM alert_rule_tag WHERE EXISTS (SELECT 1 FROM alert WHERE alert.org_id = ? AND alert.id = alert_rule_tag.alert_id)",
"DELETE FROM alert_rule_version WHERE rule_org_id = ?",
"DELETE FROM alert WHERE org_id = ?",
"DELETE FROM annotation WHERE org_id = ?",
"DELETE FROM kv_store WHERE org_id = ?",
}
for _, sql := range deletes {
_, err := sess.Exec(sql, cmd.ID)
if err != nil {
return err
}
}
return nil
})
}

View File

@ -53,6 +53,47 @@ func TestIntegrationOrgDataAccess(t *testing.T) {
err := orgStore.DeleteUserFromAll(context.Background(), 1)
require.NoError(t, err)
})
t.Run("Update org address", func(t *testing.T) {
// make sure ac2 has no org
ac2 := &org.Org{ID: 21, Name: "name", Version: 1, Created: time.Now(), Updated: time.Now()}
_, err := orgStore.Insert(context.Background(), ac2)
require.NoError(t, err)
err = orgStore.UpdateAddress(context.Background(), &org.UpdateOrgAddressCommand{
OrgID: ac2.ID,
Address: org.Address{
Address1: "address1",
Address2: "address2",
City: "city",
ZipCode: "zip",
State: "state",
Country: "country"},
})
require.NoError(t, err)
orga, err := orgStore.Get(context.Background(), ac2.ID)
require.NoError(t, err)
require.Equal(t, "address1", orga.Address1)
})
t.Run("Removing org", func(t *testing.T) {
// make sure ac2 has no org
ac2 := &org.Org{ID: 22, Name: "ac2", Version: 1, Created: time.Now(), Updated: time.Now()}
_, err := orgStore.Insert(context.Background(), ac2)
require.NoError(t, err)
err = orgStore.Delete(context.Background(), &org.DeleteOrgCommand{ID: ac2.ID})
require.NoError(t, err)
// TODO: this part of the test will be added when we move RemoveOrgUser to org store
// "Removing user from org should delete user completely if in no other org"
// // remove ac2 user from ac1 org
// remCmd := models.RemoveOrgUserCommand{OrgId: ac1.OrgID, UserId: ac2.ID, ShouldDeleteOrphanedUser: true}
// err = orgStore.RemoveOrgUser(context.Background(), &remCmd)
// require.NoError(t, err)
// require.True(t, remCmd.UserWasDeleted)
// err = orgStore.GetSignedInUser(context.Background(), &models.GetSignedInUserQuery{UserId: ac2.ID})
// require.Equal(t, err, user.ErrUserNotFound)
})
}
func TestIntegrationOrgUserDataAccess(t *testing.T) {

View File

@ -64,3 +64,15 @@ func (f *FakeOrgService) CreateWithMember(name string, userID int64) (*org.Org,
func (f *FakeOrgService) Create(ctx context.Context, cmd *org.CreateOrgCommand) (*org.Org, error) {
return f.ExpectedOrg, f.ExpectedError
}
func (f *FakeOrgService) UpdateAddress(ctx context.Context, cmd *org.UpdateOrgAddressCommand) error {
return f.ExpectedError
}
func (f *FakeOrgService) Delete(ctx context.Context, cmd *org.DeleteOrgCommand) error {
return f.ExpectedError
}
func (f *FakeOrgService) GetOrCreate(ctx context.Context, orgName string) (int64, error) {
return 0, f.ExpectedError
}