From 1c0ab501aa38e8f79b13abac373703b0ab24d500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mih=C3=A1ly=20Gy=C3=B6ngy=C3=B6si?= Date: Mon, 15 Aug 2022 10:58:58 +0200 Subject: [PATCH] UsersTable: Display Disabled flag in Organizations' Users table (#53656) * Add disabled column to Org's Users table * fix typo * Change column order * Add test for testing whether GetOrgUsers populates the DTO correctly * Remove type assertion --- pkg/models/org_user.go | 1 + pkg/services/sqlstore/org_users.go | 1 + pkg/services/sqlstore/org_users_test.go | 66 +++++++++++++++++++ public/app/features/users/UsersTable.test.tsx | 8 +++ public/app/features/users/UsersTable.tsx | 7 +- .../app/features/users/__mocks__/userMocks.ts | 1 + public/app/types/user.ts | 1 + 7 files changed, 84 insertions(+), 1 deletion(-) diff --git a/pkg/models/org_user.go b/pkg/models/org_user.go index 55e271a3d1e..207a7e96856 100644 --- a/pkg/models/org_user.go +++ b/pkg/models/org_user.go @@ -100,4 +100,5 @@ type OrgUserDTO struct { Created time.Time `json:"-"` LastSeenAtAge string `json:"lastSeenAtAge"` AccessControl map[string]bool `json:"accessControl,omitempty"` + IsDisabled bool `json:"isDisabled"` } diff --git a/pkg/services/sqlstore/org_users.go b/pkg/services/sqlstore/org_users.go index 0a46a90b96f..1e4bfc237c8 100644 --- a/pkg/services/sqlstore/org_users.go +++ b/pkg/services/sqlstore/org_users.go @@ -152,6 +152,7 @@ func (ss *SQLStore) GetOrgUsers(ctx context.Context, query *models.GetOrgUsersQu "user.last_seen_at", "user.created", "user.updated", + "user.is_disabled", ) sess.Asc("user.email", "user.login") diff --git a/pkg/services/sqlstore/org_users_test.go b/pkg/services/sqlstore/org_users_test.go index e87f4f696e8..76c31e0667d 100644 --- a/pkg/services/sqlstore/org_users_test.go +++ b/pkg/services/sqlstore/org_users_test.go @@ -5,6 +5,7 @@ import ( "fmt" "strings" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -83,6 +84,60 @@ func TestSQLStore_GetOrgUsers(t *testing.T) { } } +func TestSQLStore_GetOrgUsers_PopulatesCorrectly(t *testing.T) { + // The millisecond part is not stored in the DB + constNow := time.Now().UTC().Truncate(time.Second) + defer mockTimeNow(constNow)() + + store := InitTestDB(t, InitTestDBOpt{}) + _, err := store.CreateUser(context.Background(), user.CreateUserCommand{ + Login: "Admin", + Email: "admin@localhost", + OrgID: 1, + }) + require.NoError(t, err) + + newUser, err := store.CreateUser(context.Background(), user.CreateUserCommand{ + Login: "Viewer", + Email: "viewer@localhost", + OrgID: 1, + IsDisabled: true, + Name: "Viewer Localhost", + }) + require.NoError(t, err) + + err = store.AddOrgUser(context.Background(), &models.AddOrgUserCommand{ + Role: "Viewer", + OrgId: 1, + UserId: newUser.ID, + }) + require.NoError(t, err) + + query := &models.GetOrgUsersQuery{ + OrgId: 1, + UserID: newUser.ID, + User: &user.SignedInUser{ + OrgID: 1, + Permissions: map[int64]map[string][]string{1: {ac.ActionOrgUsersRead: {ac.ScopeUsersAll}}}, + }, + } + err = store.GetOrgUsers(context.Background(), query) + require.NoError(t, err) + require.Len(t, query.Result, 1) + + actual := query.Result[0] + assert.Equal(t, int64(1), actual.OrgId) + assert.Equal(t, newUser.ID, actual.UserId) + assert.Equal(t, "viewer@localhost", actual.Email) + assert.Equal(t, "Viewer Localhost", actual.Name) + assert.Equal(t, "Viewer", actual.Login) + assert.Equal(t, "Viewer", actual.Role) + assert.Equal(t, constNow.AddDate(-10, 0, 0), actual.LastSeenAt) + assert.Equal(t, constNow, actual.Created) + assert.Equal(t, constNow, actual.Updated) + assert.Equal(t, true, actual.IsDisabled) +} + type searchOrgUsersTestCase struct { desc string query *models.SearchOrgUsersQuery @@ -279,3 +334,14 @@ func hasWildcardScope(user *user.SignedInUser, action string) bool { } return false } + +func mockTimeNow(constTime time.Time) func() { + timeNow = func() time.Time { + return constTime.Truncate(time.Second) + } + return resetTimeNow +} + +func resetTimeNow() { + timeNow = time.Now +} diff --git a/public/app/features/users/UsersTable.test.tsx b/public/app/features/users/UsersTable.test.tsx index c13461dbd6c..44471a5f720 100644 --- a/public/app/features/users/UsersTable.test.tsx +++ b/public/app/features/users/UsersTable.test.tsx @@ -40,6 +40,14 @@ describe('Render', () => { expect(screen.getByText(user.name)).toBeInTheDocument(); }); }); + + it('should render disabled flag when any of the Users are disabled', () => { + const usersData = getMockUsers(5); + usersData[0].isDisabled = true; + setup({ users: usersData }); + + expect(screen.getByText('Disabled')).toBeInTheDocument(); + }); }); describe('Remove modal', () => { diff --git a/public/app/features/users/UsersTable.tsx b/public/app/features/users/UsersTable.tsx index bf4738fd478..327a9282399 100644 --- a/public/app/features/users/UsersTable.tsx +++ b/public/app/features/users/UsersTable.tsx @@ -58,6 +58,7 @@ const UsersTable: FC = (props) => { Seen Role + @@ -108,8 +109,12 @@ const UsersTable: FC = (props) => { )} + + {user.isDisabled && Disabled} + + {contextSrv.hasPermissionInMetadata(AccessControlAction.OrgUsersRemove, user) && ( - +