Filter from all users list if we have don't have filters

This commit is contained in:
Abin Simon
2022-04-06 13:58:05 +05:30
parent 5306d6a2c6
commit 66c7cc7f10
3 changed files with 33 additions and 16 deletions

View File

@@ -71,7 +71,6 @@ type userProjectnamesaceRole struct {
Project *string `bun:"project,type:string"`
}
// TODO: find a better name for the function
func GetQueryFilteredUsers(ctx context.Context, db bun.IDB, partner, org, group, role uuid.UUID, projects []uuid.UUID) ([]uuid.UUID, error) {
p := []models.AccountPermission{}
q := db.NewSelect().Model(&p).ColumnExpr("DISTINCT account_id")
@@ -100,7 +99,10 @@ func GetQueryFilteredUsers(ctx context.Context, db bun.IDB, partner, org, group,
// ListFilteredUsers will return the list of users fileterd by query
func ListFilteredUsers(ctx context.Context, db bun.IDB, users *[]models.KratosIdentities, fusers []uuid.UUID, query string, orderBy string, order string, limit int, offset int) (*[]models.KratosIdentities, error) {
q := db.NewSelect().Model(users)
q.Where("id IN (?)", bun.In(fusers))
if len(fusers) > 0 {
// filter with precomputed users if we have any
q.Where("id IN (?)", bun.In(fusers))
}
if query != "" {
q.Where("traits ->> 'email' ILIKE ?", "%"+query+"%") // XXX: ILIKE is not-standard
q.WhereOr("traits ->> 'first_name' ILIKE ?", "%"+query+"%")

View File

@@ -707,21 +707,36 @@ func (s *userService) List(ctx context.Context, opts ...query.Option) (*userv3.U
}
}
uids, err := dao.GetQueryFilteredUsers(ctx, s.db, partnerId, orgId, groupId, roleId, projectIds)
if err != nil {
return &userv3.UserList{}, err
}
var usrs *[]models.KratosIdentities
var accs []models.KratosIdentities
if len(projectIds) != 0 || groupId != uuid.Nil || roleId != uuid.Nil {
uids, err := dao.GetQueryFilteredUsers(ctx, s.db, partnerId, orgId, groupId, roleId, projectIds)
if err != nil {
return &userv3.UserList{}, err
}
if len(uids) != 0 {
var accs []models.KratosIdentities
// TODO: maybe merge this with the previous one into single sql
usrs, err := dao.ListFilteredUsers(ctx, s.db, &accs,
uids, queryOptions.Q,
if len(uids) != 0 {
// TODO: maybe merge this with the previous one into single sql
usrs, err = dao.ListFilteredUsers(ctx, s.db, &accs,
uids, queryOptions.Q,
queryOptions.OrderBy, queryOptions.Order,
int(queryOptions.Limit), int(queryOptions.Offset))
if err != nil {
return userList, err
}
}
} else {
// If no filters are available we have to list just using identities table
usrs, err = dao.ListFilteredUsers(ctx, s.db, &accs,
[]uuid.UUID{}, queryOptions.Q,
queryOptions.OrderBy, queryOptions.Order,
int(queryOptions.Limit), int(queryOptions.Offset))
if err != nil {
return userList, err
}
}
if usrs != nil {
for _, usr := range *usrs {
user := &userv3.User{}
user, err := s.identitiesModelToUser(ctx, s.db, user, &usr)

View File

@@ -429,9 +429,7 @@ func TestUserList(t *testing.T) {
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(puuid))
mock.ExpectQuery(`SELECT "organization"."id" FROM "authsrv_organization" AS "organization"`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(ouuid))
mock.ExpectQuery(`SELECT DISTINCT account_id FROM "sentry_account_permission" AS "sap" WHERE .partner_id = '` + puuid + `'. AND .organization_id = '` + ouuid + `'`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"account_id"}).AddRow(uuuid1).AddRow(uuuid2))
mock.ExpectQuery(`SELECT "identities"."id", .*WHERE .id IN .'` + uuuid1 + `', '` + uuuid2 + `'.. LIMIT 10`).
mock.ExpectQuery(`SELECT "identities"."id", .*FROM "identities" LIMIT 10`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "traits"}).
AddRow(uuuid1, []byte(`{"email":"johndoe@provider.com", "first_name": "John", "last_name": "Doe", "organization_id": "`+ouuid+`", "partner_id": "`+puuid+`", "description": "My awesome user"}`)).
AddRow(uuuid2, []byte(`{"email":"johndoe@provider.com", "first_name": "John", "last_name": "Doe", "organization_id": "`+ouuid+`", "partner_id": "`+puuid+`", "description": "My awesome user"}`)))
@@ -492,7 +490,7 @@ func TestUserList(t *testing.T) {
performBasicAuthProviderChecks(t, *ap, 0, 0, 0, 0)
}
func TestUserFiletered(t *testing.T) {
func TestUserFiltered(t *testing.T) {
db, mock := getDB(t)
defer db.Close()
@@ -512,6 +510,8 @@ func TestUserFiletered(t *testing.T) {
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(puuid))
mock.ExpectQuery(`SELECT "organization"."id" FROM "authsrv_organization" AS "organization"`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(ouuid))
mock.ExpectQuery(`SELECT "group"."id" FROM "authsrv_group" AS "group" WHERE .name = 'group-name'. AND .trash = FALSE.`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(guuid))
mock.ExpectQuery(`SELECT DISTINCT account_id FROM "sentry_account_permission" AS "sap" WHERE .partner_id = '` + puuid + `'. AND .organization_id = '` + ouuid + `'`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"account_id"}).AddRow(uuuid1).AddRow(uuuid2))
mock.ExpectQuery(`SELECT "identities"."id", .*WHERE .id IN .'` + uuuid1 + `', '` + uuuid2 + `'.. AND .traits ->> 'email' ILIKE '%filter-query%'. OR .traits ->> 'first_name' ILIKE '%filter-query%'. OR .traits ->> 'last_name' ILIKE '%filter-query%'. ORDER BY "traits ->> 'email' asc" LIMIT 50 OFFSET 20`).
@@ -563,7 +563,7 @@ func TestUserFiletered(t *testing.T) {
mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role, authsrv_project.name as project, namespace_id as namespace FROM "authsrv_projectaccountnamespacerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectaccountnamespacerole.role_id JOIN authsrv_project ON authsrv_project.id=authsrv_projectaccountnamespacerole.project_id WHERE .authsrv_projectaccountnamespacerole.account_id = '` + uuuid2 + `'`).
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project", "namespace"}).AddRow("role-"+ruuid, "project-"+pruuid, 9))
qo := &commonv3.QueryOptions{Q: "filter-query", Limit: 50, Offset: 20, OrderBy: "email", Order: "asc", Organization: ouuid, Partner: puuid}
qo := &commonv3.QueryOptions{Q: "filter-query", Limit: 50, Offset: 20, OrderBy: "email", Order: "asc", Organization: ouuid, Partner: puuid, Group: "group-name"}
userlist, err := us.List(context.Background(), query.WithOptions(qo))
if err != nil {
t.Fatal("could not list users:", err)