package legacy import ( "testing" "text/template" "time" "github.com/grafana/grafana/pkg/registry/apis/iam/common" "github.com/grafana/grafana/pkg/services/team" "github.com/grafana/grafana/pkg/storage/legacysql" "github.com/grafana/grafana/pkg/storage/unified/sql/sqltemplate" "github.com/grafana/grafana/pkg/storage/unified/sql/sqltemplate/mocks" ) func TestIdentityQueries(t *testing.T) { // prefix tables with grafana nodb := &legacysql.LegacyDatabaseHelper{ Table: func(n string) string { return "grafana." + n }, } getDisplay := func(q *ListDisplayQuery) sqltemplate.SQLTemplate { v := newListDisplay(nodb, q) v.SQLTemplate = mocks.NewTestingSQLTemplate() return &v } listUsers := func(q *ListUserQuery) sqltemplate.SQLTemplate { v := newListUser(nodb, q) v.SQLTemplate = mocks.NewTestingSQLTemplate() return &v } deleteUser := func(q *DeleteUserCommand) sqltemplate.SQLTemplate { v := newDeleteUser(nodb, q) v.SQLTemplate = mocks.NewTestingSQLTemplate() return &v } deleteOrgUser := func(userID int64) sqltemplate.SQLTemplate { v := newDeleteOrgUser(nodb, userID) return &v } createOrgUser := func(cmd *CreateOrgUserCommand) sqltemplate.SQLTemplate { v := newCreateOrgUser(nodb, cmd) v.SQLTemplate = mocks.NewTestingSQLTemplate() return &v } createUser := func(cmd *CreateUserCommand) sqltemplate.SQLTemplate { v := newCreateUser(nodb, cmd) v.SQLTemplate = mocks.NewTestingSQLTemplate() return &v } createTeam := func(cmd *CreateTeamCommand) sqltemplate.SQLTemplate { v := newCreateTeam(nodb, cmd) v.SQLTemplate = mocks.NewTestingSQLTemplate() return &v } updateTeam := func(cmd *UpdateTeamCommand) sqltemplate.SQLTemplate { v := newUpdateTeam(nodb, cmd) v.SQLTemplate = mocks.NewTestingSQLTemplate() return &v } listTeams := func(q *ListTeamQuery) sqltemplate.SQLTemplate { v := newListTeams(nodb, q) v.SQLTemplate = mocks.NewTestingSQLTemplate() return &v } createTeamMember := func(cmd *CreateTeamMemberCommand) sqltemplate.SQLTemplate { v := newCreateTeamMember(nodb, cmd) v.SQLTemplate = mocks.NewTestingSQLTemplate() return &v } listTeamBindings := func(q *ListTeamBindingsQuery) sqltemplate.SQLTemplate { v := newListTeamBindings(nodb, q) v.SQLTemplate = mocks.NewTestingSQLTemplate() return &v } updateTeamMember := func(cmd *UpdateTeamMemberCommand) sqltemplate.SQLTemplate { v := newUpdateTeamMember(nodb, cmd) v.SQLTemplate = mocks.NewTestingSQLTemplate() return &v } listTeamMembers := func(q *ListTeamMembersQuery) sqltemplate.SQLTemplate { v := newListTeamMembers(nodb, q) v.SQLTemplate = mocks.NewTestingSQLTemplate() return &v } deleteTeamMember := func(q *DeleteTeamMemberCommand) sqltemplate.SQLTemplate { v := newDeleteTeamMember(nodb, q) v.SQLTemplate = mocks.NewTestingSQLTemplate() return &v } deleteTeam := func(q *DeleteTeamCommand) sqltemplate.SQLTemplate { v := newDeleteTeam(nodb, q) v.SQLTemplate = mocks.NewTestingSQLTemplate() return &v } listUserTeams := func(q *ListUserTeamsQuery) sqltemplate.SQLTemplate { v := newListUserTeams(nodb, q) v.SQLTemplate = mocks.NewTestingSQLTemplate() return &v } listServiceAccounts := func(q *ListServiceAccountsQuery) sqltemplate.SQLTemplate { v := newListServiceAccounts(nodb, q) v.SQLTemplate = mocks.NewTestingSQLTemplate() return &v } createServiceAccounts := func(cmd *CreateServiceAccountCommand) sqltemplate.SQLTemplate { v := newCreateServiceAccount(nodb, cmd) v.SQLTemplate = mocks.NewTestingSQLTemplate() return &v } listServiceAccountTokens := func(q *ListServiceAccountTokenQuery) sqltemplate.SQLTemplate { v := newListServiceAccountTokens(nodb, q) v.SQLTemplate = mocks.NewTestingSQLTemplate() return &v } updateUser := func(cmd *UpdateUserCommand) sqltemplate.SQLTemplate { v := newUpdateUser(nodb, cmd) v.SQLTemplate = mocks.NewTestingSQLTemplate() return &v } updateOrgUser := func(cmd *UpdateOrgUserCommand) sqltemplate.SQLTemplate { v := newUpdateOrgUser(nodb, cmd) v.SQLTemplate = mocks.NewTestingSQLTemplate() return &v } mocks.CheckQuerySnapshots(t, mocks.TemplateTestSetup{ RootDir: "testdata", SQLTemplatesFS: sqlTemplatesFS, Templates: map[*template.Template][]mocks.TemplateTestCase{ sqlQueryTeamsTemplate: { { Name: "teams_uid", Data: listTeams(&ListTeamQuery{ UID: "abc", Pagination: common.Pagination{Limit: 1}, }), }, { Name: "teams_page_1", Data: listTeams(&ListTeamQuery{ Pagination: common.Pagination{Limit: 5}, }), }, { Name: "teams_page_2", Data: listTeams(&ListTeamQuery{ Pagination: common.Pagination{ Limit: 1, Continue: 2, }, }), }, }, sqlQueryUsersTemplate: { { Name: "users_uid", Data: listUsers(&ListUserQuery{ UID: "abc", Pagination: common.Pagination{Limit: 1}, }), }, { Name: "users_page_1", Data: listUsers(&ListUserQuery{ Pagination: common.Pagination{Limit: 5}, }), }, { Name: "users_page_2", Data: listUsers(&ListUserQuery{ Pagination: common.Pagination{ Limit: 1, Continue: 2, }, }), }, }, sqlQueryDisplayTemplate: { { Name: "display_uids", Data: getDisplay(&ListDisplayQuery{ OrgID: 2, UIDs: []string{"a", "b"}, }), }, { Name: "display_ids", Data: getDisplay(&ListDisplayQuery{ OrgID: 2, IDs: []int64{1, 2}, }), }, { Name: "display_ids_uids", Data: getDisplay(&ListDisplayQuery{ OrgID: 2, UIDs: []string{"a", "b"}, IDs: []int64{1, 2}, }), }, }, sqlCreateTeamMemberQuery: { { Name: "create_team_member", Data: createTeamMember(&CreateTeamMemberCommand{ TeamID: 1, UserID: 1, Created: legacysql.NewDBTime(time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC)), Updated: legacysql.NewDBTime(time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC)), External: false, Permission: team.PermissionTypeMember, }), }, { Name: "create_team_member_admin", Data: createTeamMember(&CreateTeamMemberCommand{ TeamID: 1, UserID: 1, Created: legacysql.NewDBTime(time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC)), Updated: legacysql.NewDBTime(time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC)), External: false, Permission: team.PermissionTypeAdmin, }), }, }, sqlQueryTeamBindingsTemplate: { { Name: "team_bindings_uid", Data: listTeamBindings(&ListTeamBindingsQuery{ OrgID: 1, UID: "tm-1", Pagination: common.Pagination{Limit: 1}, }), }, { Name: "team_bindings_page_1", Data: listTeamBindings(&ListTeamBindingsQuery{ OrgID: 1, Pagination: common.Pagination{Limit: 5}, }), }, { Name: "team_bindings_page_2", Data: listTeamBindings(&ListTeamBindingsQuery{ OrgID: 1, Pagination: common.Pagination{ Limit: 1, Continue: 2, }, }), }, }, sqlUpdateTeamMemberQuery: { { Name: "update_team_member_basic", Data: updateTeamMember(&UpdateTeamMemberCommand{ UID: "team-member-1", Permission: team.PermissionTypeAdmin, Updated: legacysql.NewDBTime(time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC)), }), }, }, sqlQueryTeamMembersTemplate: { { Name: "team_1_members_page_1", Data: listTeamMembers(&ListTeamMembersQuery{ UID: "team-1", OrgID: 1, Pagination: common.Pagination{Limit: 1}, }), }, { Name: "team_1_members_page_2", Data: listTeamMembers(&ListTeamMembersQuery{ UID: "team-1", OrgID: 1, Pagination: common.Pagination{Limit: 1, Continue: 2}, }), }, }, sqlDeleteTeamMemberQuery: { { Name: "delete_team_member_basic", Data: deleteTeamMember(&DeleteTeamMemberCommand{ UID: "team-member-1", }), }, }, sqlQueryUserTeamsTemplate: { { Name: "team_1_members_page_1", Data: listUserTeams(&ListUserTeamsQuery{ UserUID: "user-1", OrgID: 1, Pagination: common.Pagination{Limit: 1}, }), }, { Name: "team_1_members_page_2", Data: listUserTeams(&ListUserTeamsQuery{ UserUID: "user-1", OrgID: 1, Pagination: common.Pagination{Limit: 1, Continue: 2}, }), }, }, sqlQueryUserInternalIDTemplate: { { Name: "user_internal_id", Data: &getUserInternalIDQuery{ SQLTemplate: mocks.NewTestingSQLTemplate(), UserTable: nodb.Table("user"), OrgUserTable: nodb.Table("org_user"), Query: &GetUserInternalIDQuery{ UID: "user-1", OrgID: 1, }, }, }, }, sqlQueryTeamInternalIDTemplate: { { Name: "team_internal_id", Data: &getTeamInternalIDQuery{ SQLTemplate: mocks.NewTestingSQLTemplate(), TeamTable: nodb.Table("team"), Query: &GetTeamInternalIDQuery{ UID: "team-1", OrgID: 1, }, }, }, }, sqlQueryServiceAccountInternalIDTemplate: { { Name: "basic", Data: &getServiceAccountInternalIDQuery{ SQLTemplate: mocks.NewTestingSQLTemplate(), UserTable: nodb.Table("user"), OrgUserTable: nodb.Table("org_user"), Query: &GetServiceAccountInternalIDQuery{ OrgID: 1, UID: "sa-1", }, }, }, }, sqlQueryServiceAccountsTemplate: { { Name: "service_accounts", Data: listServiceAccounts(&ListServiceAccountsQuery{ UID: "sa-1", OrgID: 1, Pagination: common.Pagination{Limit: 1}, }), }, { Name: "service_accounts_page_1", Data: listServiceAccounts(&ListServiceAccountsQuery{ OrgID: 1, Pagination: common.Pagination{Limit: 5}, }), }, { Name: "service_accounts_page_2", Data: listServiceAccounts(&ListServiceAccountsQuery{ OrgID: 1, Pagination: common.Pagination{ Limit: 1, Continue: 2, }, }), }, }, sqlQueryServiceAccountTokensTemplate: { { Name: "service_account_tokens", Data: listServiceAccountTokens(&ListServiceAccountTokenQuery{ UID: "sa-1", OrgID: 1, Pagination: common.Pagination{Limit: 1}, }), }, { Name: "service_account_tokens_page_1", Data: listServiceAccountTokens(&ListServiceAccountTokenQuery{ OrgID: 1, Pagination: common.Pagination{Limit: 5}, }), }, { Name: "service_accounts_tokens_page_2", Data: listServiceAccountTokens(&ListServiceAccountTokenQuery{ OrgID: 1, Pagination: common.Pagination{ Limit: 1, Continue: 2, }, }), }, }, sqlDeleteUserTemplate: { { Name: "delete_user_basic", Data: deleteUser(&DeleteUserCommand{ UID: "user-1", }), }, { Name: "delete_user_different_org", Data: deleteUser(&DeleteUserCommand{ UID: "user-abc", }), }, }, sqlDeleteOrgUserTemplate: { { Name: "delete_org_user_basic", Data: deleteOrgUser(123), }, { Name: "delete_org_user_different_id", Data: deleteOrgUser(456), }, }, sqlCreateTeamTemplate: { { Name: "create_team_non_provisioned", Data: createTeam(&CreateTeamCommand{ UID: "team-1", Name: "Team 1", Email: "team1@example.com", IsProvisioned: false, OrgID: 1, Created: legacysql.NewDBTime(time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC)), Updated: legacysql.NewDBTime(time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC)), }), }, { Name: "create_team_provisioned", Data: createTeam(&CreateTeamCommand{ UID: "team-2", Name: "Team 2", Email: "team2@example.com", IsProvisioned: true, ExternalUID: "team-2-uid", OrgID: 1, Created: legacysql.NewDBTime(time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC)), Updated: legacysql.NewDBTime(time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC)), }), }, }, sqlUpdateTeamTemplate: { { Name: "update_team_basic", Data: updateTeam(&UpdateTeamCommand{ UID: "team-1", Name: "Team 1", Email: "team1@example.com", IsProvisioned: true, ExternalUID: "team-1-uid", Updated: legacysql.NewDBTime(time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC)), }), }, }, sqlDeleteTeamTemplate: { { Name: "delete_team_basic", Data: deleteTeam(&DeleteTeamCommand{ UID: "team-1", }), }, }, sqlCreateOrgUserTemplate: { { Name: "create_org_user_basic", Data: createOrgUser(&CreateOrgUserCommand{ OrgID: 1, UserID: 123, Role: "Viewer", Created: legacysql.NewDBTime(time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC)), Updated: legacysql.NewDBTime(time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC)), }), }, { Name: "create_org_user_admin", Data: createOrgUser(&CreateOrgUserCommand{ OrgID: 2, UserID: 456, Role: "Admin", Created: legacysql.NewDBTime(time.Date(2023, 2, 1, 10, 30, 0, 0, time.UTC)), Updated: legacysql.NewDBTime(time.Date(2023, 2, 1, 10, 30, 0, 0, time.UTC)), }), }, }, sqlCreateUserTemplate: { { Name: "create_user_basic", Data: createUser(&CreateUserCommand{ UID: "user-1", Email: "user1@example.com", Login: "user1", Name: "User One", OrgID: 1, IsAdmin: false, IsDisabled: false, EmailVerified: true, IsProvisioned: false, Salt: "randomsalt", Rands: "randomrands", Created: legacysql.NewDBTime(time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC)), Updated: legacysql.NewDBTime(time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC)), LastSeenAt: legacysql.NewDBTime(time.Date(2013, 1, 1, 12, 0, 0, 0, time.UTC)), Role: "Viewer", }), }, { Name: "create_user_admin", Data: createUser(&CreateUserCommand{ UID: "admin-1", Email: "admin@example.com", Login: "admin", Name: "Admin User", OrgID: 2, IsAdmin: true, IsDisabled: false, EmailVerified: true, IsProvisioned: true, Salt: "adminsalt", Rands: "adminrands", Created: legacysql.NewDBTime(time.Date(2023, 2, 1, 10, 30, 0, 0, time.UTC)), Updated: legacysql.NewDBTime(time.Date(2023, 2, 1, 10, 30, 0, 0, time.UTC)), LastSeenAt: legacysql.NewDBTime(time.Date(2013, 2, 1, 10, 30, 0, 0, time.UTC)), Role: "Admin", }), }, }, sqlCreateServiceAccountTemplate: { { Name: "create_service_account_basic", Data: createServiceAccounts(&CreateServiceAccountCommand{ UID: "abcdef", Name: "Service Account 1", Email: "sa-1-service-account-1", Login: "sa-1-service-account-1", IsDisabled: false, OrgID: 1, Created: legacysql.NewDBTime(time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC)), Updated: legacysql.NewDBTime(time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC)), LastSeenAt: time.Date(2013, 1, 1, 12, 0, 0, 0, time.UTC), }), }, { Name: "create_service_account_disabled", Data: createServiceAccounts(&CreateServiceAccountCommand{ UID: "abcdef", Name: "Disabled Service Account", Email: "sa-2-disabled-service-account", Login: "sa-2-disabled-service-account", IsDisabled: true, OrgID: 2, Created: legacysql.NewDBTime(time.Date(2023, 2, 1, 10, 30, 0, 0, time.UTC)), Updated: legacysql.NewDBTime(time.Date(2023, 2, 1, 10, 30, 0, 0, time.UTC)), LastSeenAt: time.Date(2013, 2, 1, 10, 30, 0, 0, time.UTC), }), }, }, sqlUpdateUserTemplate: { { Name: "update_user_basic", Data: updateUser(&UpdateUserCommand{ UID: "user-1", Login: "newuser1", Email: "newuser1@example.com", Name: "New User One", IsAdmin: true, IsDisabled: true, EmailVerified: false, Role: "Editor", Updated: legacysql.NewDBTime(time.Date(2023, 1, 1, 13, 0, 0, 0, time.UTC)), }), }, }, sqlUpdateOrgUserTemplate: { { Name: "update_org_user_basic", Data: updateOrgUser(&UpdateOrgUserCommand{ OrgID: 1, UserID: 123, Role: "Admin", Updated: legacysql.NewDBTime(time.Date(2023, 1, 1, 14, 0, 0, 0, time.UTC)), }), }, }, }, }) }