|
|
@ -12,6 +12,7 @@ import ( |
|
|
|
|
|
|
|
|
|
|
|
"github.com/grafana/grafana/pkg/apimachinery/identity" |
|
|
|
"github.com/grafana/grafana/pkg/apimachinery/identity" |
|
|
|
"github.com/grafana/grafana/pkg/infra/db" |
|
|
|
"github.com/grafana/grafana/pkg/infra/db" |
|
|
|
|
|
|
|
"github.com/grafana/grafana/pkg/infra/log" |
|
|
|
"github.com/grafana/grafana/pkg/infra/tracing" |
|
|
|
"github.com/grafana/grafana/pkg/infra/tracing" |
|
|
|
"github.com/grafana/grafana/pkg/services/accesscontrol" |
|
|
|
"github.com/grafana/grafana/pkg/services/accesscontrol" |
|
|
|
"github.com/grafana/grafana/pkg/services/org" |
|
|
|
"github.com/grafana/grafana/pkg/services/org" |
|
|
@ -38,6 +39,7 @@ func TestIntegrationOrgDataAccess(t *testing.T) { |
|
|
|
orgStore := sqlStore{ |
|
|
|
orgStore := sqlStore{ |
|
|
|
db: ss, |
|
|
|
db: ss, |
|
|
|
dialect: ss.GetDialect(), |
|
|
|
dialect: ss.GetDialect(), |
|
|
|
|
|
|
|
log: log.NewNopLogger(), |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
t.Run("org not found", func(t *testing.T) { |
|
|
|
t.Run("org not found", func(t *testing.T) { |
|
|
@ -258,6 +260,7 @@ func TestIntegrationOrgUserDataAccess(t *testing.T) { |
|
|
|
orgUserStore := sqlStore{ |
|
|
|
orgUserStore := sqlStore{ |
|
|
|
db: ss, |
|
|
|
db: ss, |
|
|
|
dialect: ss.GetDialect(), |
|
|
|
dialect: ss.GetDialect(), |
|
|
|
|
|
|
|
log: log.NewNopLogger(), |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
t.Run("org user inserted", func(t *testing.T) { |
|
|
|
t.Run("org user inserted", func(t *testing.T) { |
|
|
@ -333,7 +336,7 @@ func TestIntegrationOrgUserDataAccess(t *testing.T) { |
|
|
|
ss, cfg := db.InitTestDBWithCfg(t) |
|
|
|
ss, cfg := db.InitTestDBWithCfg(t) |
|
|
|
_, usrSvc := createOrgAndUserSvc(t, ss, cfg) |
|
|
|
_, usrSvc := createOrgAndUserSvc(t, ss, cfg) |
|
|
|
ac1cmd := &user.CreateUserCommand{Login: "ac1", Email: "ac1@test.com", Name: "ac1 name"} |
|
|
|
ac1cmd := &user.CreateUserCommand{Login: "ac1", Email: "ac1@test.com", Name: "ac1 name"} |
|
|
|
ac2cmd := &user.CreateUserCommand{Login: "ac2", Email: "ac2@test.com", Name: "ac2 name", IsAdmin: true} |
|
|
|
ac2cmd := &user.CreateUserCommand{Login: "ac2", Email: "ac2@test.com", Name: "ac2 name"} |
|
|
|
ac1, err := usrSvc.Create(context.Background(), ac1cmd) |
|
|
|
ac1, err := usrSvc.Create(context.Background(), ac1cmd) |
|
|
|
require.NoError(t, err) |
|
|
|
require.NoError(t, err) |
|
|
|
ac2, err := usrSvc.Create(context.Background(), ac2cmd) |
|
|
|
ac2, err := usrSvc.Create(context.Background(), ac2cmd) |
|
|
@ -460,6 +463,15 @@ func TestIntegrationOrgUserDataAccess(t *testing.T) { |
|
|
|
err := orgUserStore.Delete(context.Background(), &org.DeleteOrgCommand{ID: ac2.OrgID}) |
|
|
|
err := orgUserStore.Delete(context.Background(), &org.DeleteOrgCommand{ID: ac2.OrgID}) |
|
|
|
require.NoError(t, err) |
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// make sure ac2 is in ac1 org
|
|
|
|
|
|
|
|
cmd := org.AddOrgUserCommand{ |
|
|
|
|
|
|
|
OrgID: ac1.OrgID, |
|
|
|
|
|
|
|
UserID: ac2.ID, |
|
|
|
|
|
|
|
Role: org.RoleViewer, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
err = orgUserStore.AddOrgUser(context.Background(), &cmd) |
|
|
|
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
|
|
// remove ac2 user from ac1 org
|
|
|
|
// remove ac2 user from ac1 org
|
|
|
|
remCmd := org.RemoveOrgUserCommand{OrgID: ac1.OrgID, UserID: ac2.ID, ShouldDeleteOrphanedUser: true} |
|
|
|
remCmd := org.RemoveOrgUserCommand{OrgID: ac1.OrgID, UserID: ac2.ID, ShouldDeleteOrphanedUser: true} |
|
|
|
err = orgUserStore.RemoveOrgUser(context.Background(), &remCmd) |
|
|
|
err = orgUserStore.RemoveOrgUser(context.Background(), &remCmd) |
|
|
@ -545,6 +557,7 @@ func TestIntegrationSQLStore_AddOrgUser(t *testing.T) { |
|
|
|
orgUserStore := sqlStore{ |
|
|
|
orgUserStore := sqlStore{ |
|
|
|
db: store, |
|
|
|
db: store, |
|
|
|
dialect: store.GetDialect(), |
|
|
|
dialect: store.GetDialect(), |
|
|
|
|
|
|
|
log: log.NewNopLogger(), |
|
|
|
} |
|
|
|
} |
|
|
|
orgSvc, usrSvc := createOrgAndUserSvc(t, store, cfg) |
|
|
|
orgSvc, usrSvc := createOrgAndUserSvc(t, store, cfg) |
|
|
|
|
|
|
|
|
|
|
@ -610,6 +623,7 @@ func TestIntegration_SQLStore_GetOrgUsers(t *testing.T) { |
|
|
|
orgUserStore := sqlStore{ |
|
|
|
orgUserStore := sqlStore{ |
|
|
|
db: store, |
|
|
|
db: store, |
|
|
|
dialect: store.GetDialect(), |
|
|
|
dialect: store.GetDialect(), |
|
|
|
|
|
|
|
log: log.NewNopLogger(), |
|
|
|
} |
|
|
|
} |
|
|
|
cfg.IsEnterprise = true |
|
|
|
cfg.IsEnterprise = true |
|
|
|
defer func() { |
|
|
|
defer func() { |
|
|
@ -728,6 +742,7 @@ func TestIntegration_SQLStore_GetOrgUsers_PopulatesCorrectly(t *testing.T) { |
|
|
|
orgUserStore := sqlStore{ |
|
|
|
orgUserStore := sqlStore{ |
|
|
|
db: store, |
|
|
|
db: store, |
|
|
|
dialect: store.GetDialect(), |
|
|
|
dialect: store.GetDialect(), |
|
|
|
|
|
|
|
log: log.NewNopLogger(), |
|
|
|
} |
|
|
|
} |
|
|
|
_, usrSvc := createOrgAndUserSvc(t, store, cfg) |
|
|
|
_, usrSvc := createOrgAndUserSvc(t, store, cfg) |
|
|
|
|
|
|
|
|
|
|
@ -789,6 +804,7 @@ func TestIntegration_SQLStore_SearchOrgUsers(t *testing.T) { |
|
|
|
orgUserStore := sqlStore{ |
|
|
|
orgUserStore := sqlStore{ |
|
|
|
db: store, |
|
|
|
db: store, |
|
|
|
dialect: store.GetDialect(), |
|
|
|
dialect: store.GetDialect(), |
|
|
|
|
|
|
|
log: log.NewNopLogger(), |
|
|
|
} |
|
|
|
} |
|
|
|
// orgUserStore.cfg.Skip
|
|
|
|
// orgUserStore.cfg.Skip
|
|
|
|
orgSvc, userSvc := createOrgAndUserSvc(t, store, cfg) |
|
|
|
orgSvc, userSvc := createOrgAndUserSvc(t, store, cfg) |
|
|
@ -865,12 +881,18 @@ func TestIntegration_SQLStore_RemoveOrgUser(t *testing.T) { |
|
|
|
orgUserStore := sqlStore{ |
|
|
|
orgUserStore := sqlStore{ |
|
|
|
db: store, |
|
|
|
db: store, |
|
|
|
dialect: store.GetDialect(), |
|
|
|
dialect: store.GetDialect(), |
|
|
|
|
|
|
|
log: log.NewNopLogger(), |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
orgSvc, usrSvc := createOrgAndUserSvc(t, store, cfg) |
|
|
|
orgSvc, usrSvc := createOrgAndUserSvc(t, store, cfg) |
|
|
|
|
|
|
|
|
|
|
|
o, err := orgSvc.CreateWithMember(context.Background(), &org.CreateOrgCommand{Name: MainOrgName}) |
|
|
|
o, err := orgSvc.CreateWithMember(context.Background(), &org.CreateOrgCommand{Name: MainOrgName}) |
|
|
|
require.NoError(t, err) |
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// create 2nd org
|
|
|
|
|
|
|
|
o2, err := orgSvc.CreateWithMember(context.Background(), &org.CreateOrgCommand{Name: "test org 2"}) |
|
|
|
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
|
|
// create org and admin
|
|
|
|
// create org and admin
|
|
|
|
_, err = usrSvc.Create(context.Background(), &user.CreateUserCommand{ |
|
|
|
_, err = usrSvc.Create(context.Background(), &user.CreateUserCommand{ |
|
|
|
Login: "admin", |
|
|
|
Login: "admin", |
|
|
@ -879,28 +901,116 @@ func TestIntegration_SQLStore_RemoveOrgUser(t *testing.T) { |
|
|
|
require.NoError(t, err) |
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
|
|
// create a user with no org
|
|
|
|
// create a user with no org
|
|
|
|
_, err = usrSvc.Create(context.Background(), &user.CreateUserCommand{ |
|
|
|
viewer, err := usrSvc.Create(context.Background(), &user.CreateUserCommand{ |
|
|
|
Login: "user", |
|
|
|
Login: "viewer", |
|
|
|
OrgID: 1, |
|
|
|
|
|
|
|
SkipOrgSetup: true, |
|
|
|
SkipOrgSetup: true, |
|
|
|
}) |
|
|
|
}) |
|
|
|
require.NoError(t, err) |
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// create a user with no org
|
|
|
|
|
|
|
|
viewer2, err := usrSvc.Create(context.Background(), &user.CreateUserCommand{ |
|
|
|
|
|
|
|
Login: "viewer2", |
|
|
|
|
|
|
|
SkipOrgSetup: true, |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// create a user with no org
|
|
|
|
|
|
|
|
viewer3, err := usrSvc.Create(context.Background(), &user.CreateUserCommand{ |
|
|
|
|
|
|
|
Login: "viewer3", |
|
|
|
|
|
|
|
SkipOrgSetup: true, |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// create an admin user with no org
|
|
|
|
|
|
|
|
admin, err := usrSvc.Create(context.Background(), &user.CreateUserCommand{ |
|
|
|
|
|
|
|
Login: "serverAdmin", |
|
|
|
|
|
|
|
SkipOrgSetup: true, |
|
|
|
|
|
|
|
IsAdmin: true, |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
|
|
// assign the user to the org
|
|
|
|
// assign the user to the org
|
|
|
|
err = orgUserStore.AddOrgUser(context.Background(), &org.AddOrgUserCommand{ |
|
|
|
err = orgUserStore.AddOrgUser(context.Background(), &org.AddOrgUserCommand{ |
|
|
|
Role: "Viewer", |
|
|
|
Role: "Viewer", |
|
|
|
OrgID: 1, |
|
|
|
OrgID: o.ID, |
|
|
|
UserID: 2, |
|
|
|
UserID: viewer.ID, |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// assign the admin user to the org
|
|
|
|
|
|
|
|
err = orgUserStore.AddOrgUser(context.Background(), &org.AddOrgUserCommand{ |
|
|
|
|
|
|
|
Role: "Admin", |
|
|
|
|
|
|
|
OrgID: o.ID, |
|
|
|
|
|
|
|
UserID: admin.ID, |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// assign the viewer3 user to the 2nd org
|
|
|
|
|
|
|
|
err = orgUserStore.AddOrgUser(context.Background(), &org.AddOrgUserCommand{ |
|
|
|
|
|
|
|
Role: "Viewer", |
|
|
|
|
|
|
|
OrgID: o2.ID, |
|
|
|
|
|
|
|
UserID: viewer3.ID, |
|
|
|
}) |
|
|
|
}) |
|
|
|
require.NoError(t, err) |
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
|
|
// remove the user org
|
|
|
|
// remove the user org
|
|
|
|
err = orgUserStore.RemoveOrgUser(context.Background(), &org.RemoveOrgUserCommand{ |
|
|
|
err = orgUserStore.RemoveOrgUser(context.Background(), &org.RemoveOrgUserCommand{ |
|
|
|
UserID: 2, |
|
|
|
UserID: viewer.ID, |
|
|
|
OrgID: 1, |
|
|
|
OrgID: o.ID, |
|
|
|
ShouldDeleteOrphanedUser: false, |
|
|
|
ShouldDeleteOrphanedUser: true, |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// remove the admin user
|
|
|
|
|
|
|
|
err = orgUserStore.RemoveOrgUser(context.Background(), &org.RemoveOrgUserCommand{ |
|
|
|
|
|
|
|
UserID: admin.ID, |
|
|
|
|
|
|
|
OrgID: o.ID, |
|
|
|
|
|
|
|
ShouldDeleteOrphanedUser: true, |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// remove the viewer3 user from first org they don't belong to
|
|
|
|
|
|
|
|
err = orgUserStore.RemoveOrgUser(context.Background(), &org.RemoveOrgUserCommand{ |
|
|
|
|
|
|
|
UserID: viewer3.ID, |
|
|
|
|
|
|
|
OrgID: o.ID, |
|
|
|
|
|
|
|
ShouldDeleteOrphanedUser: true, |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// remove the viewer2 user from first org they don't belong to
|
|
|
|
|
|
|
|
err = orgUserStore.RemoveOrgUser(context.Background(), &org.RemoveOrgUserCommand{ |
|
|
|
|
|
|
|
UserID: viewer2.ID, |
|
|
|
|
|
|
|
OrgID: o.ID, |
|
|
|
|
|
|
|
ShouldDeleteOrphanedUser: true, |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// verify the user is deleted
|
|
|
|
|
|
|
|
_, err = usrSvc.GetByID(context.Background(), &user.GetUserByIDQuery{ |
|
|
|
|
|
|
|
ID: viewer.ID, |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
require.ErrorIs(t, err, user.ErrUserNotFound) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// verify the admin user is not deleted
|
|
|
|
|
|
|
|
usr, err := usrSvc.GetByID(context.Background(), &user.GetUserByIDQuery{ |
|
|
|
|
|
|
|
ID: admin.ID, |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
assert.NotNil(t, usr) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// verify the viewer2 user is not deleted
|
|
|
|
|
|
|
|
_, err = usrSvc.GetByID(context.Background(), &user.GetUserByIDQuery{ |
|
|
|
|
|
|
|
ID: viewer2.ID, |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
assert.NotNil(t, usr) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// verify the viewer3 user is not deleted
|
|
|
|
|
|
|
|
_, err = usrSvc.GetByID(context.Background(), &user.GetUserByIDQuery{ |
|
|
|
|
|
|
|
ID: viewer3.ID, |
|
|
|
}) |
|
|
|
}) |
|
|
|
require.NoError(t, err) |
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
assert.NotNil(t, usr) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func createOrgAndUserSvc(t *testing.T, store db.DB, cfg *setting.Cfg) (org.Service, user.Service) { |
|
|
|
func createOrgAndUserSvc(t *testing.T, store db.DB, cfg *setting.Cfg) (org.Service, user.Service) { |
|
|
|