feat(users): list users via the API now supports `offset`, `limit` or `after` parameter (#21367)

pull/21353/head^2
Jakub Bednář 2021-05-12 14:09:52 +02:00 committed by GitHub
parent e77481fe52
commit 4becb6d01a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 161 additions and 8 deletions

View File

@ -4,6 +4,7 @@
1. [19811](https://github.com/influxdata/influxdb/pull/19811): Add Geo graph type to be able to store in Dashboard cells.
1. [21218](https://github.com/influxdata/influxdb/pull/21218): Add the properties of a static legend for line graphs and band plots.
1. [21367](https://github.com/influxdata/influxdb/pull/21367): List users via the API now supports pagination
### Bug Fixes

View File

@ -388,7 +388,7 @@ func (h *UserHandler) handleGetUsers(w http.ResponseWriter, r *http.Request) {
return
}
users, _, err := h.UserService.FindUsers(ctx, req.filter)
users, _, err := h.UserService.FindUsers(ctx, req.filter, req.opts)
if err != nil {
h.HandleHTTPError(ctx, err, w)
return
@ -404,11 +404,19 @@ func (h *UserHandler) handleGetUsers(w http.ResponseWriter, r *http.Request) {
type getUsersRequest struct {
filter influxdb.UserFilter
opts influxdb.FindOptions
}
func decodeGetUsersRequest(ctx context.Context, r *http.Request) (*getUsersRequest, error) {
opts, err := influxdb.DecodeFindOptions(r)
if err != nil {
return nil, err
}
qp := r.URL.Query()
req := &getUsersRequest{}
req := &getUsersRequest{
opts: *opts,
}
if userID := qp.Get("id"); userID != "" {
id, err := platform.IDFromString(userID)

View File

@ -409,7 +409,7 @@ func (h *UserHandler) handleGetUsers(w http.ResponseWriter, r *http.Request) {
return
}
users, _, err := h.userSvc.FindUsers(ctx, req.filter)
users, _, err := h.userSvc.FindUsers(ctx, req.filter, req.opts)
if err != nil {
h.api.Err(w, r, err)
return
@ -421,11 +421,19 @@ func (h *UserHandler) handleGetUsers(w http.ResponseWriter, r *http.Request) {
type getUsersRequest struct {
filter influxdb.UserFilter
opts influxdb.FindOptions
}
func decodeGetUsersRequest(ctx context.Context, r *http.Request) (*getUsersRequest, error) {
opts, err := influxdb.DecodeFindOptions(r)
if err != nil {
return nil, err
}
qp := r.URL.Query()
req := &getUsersRequest{}
req := &getUsersRequest{
opts: *opts,
}
if userID := qp.Get("id"); userID != "" {
id, err := platform.IDFromString(userID)

View File

@ -119,7 +119,21 @@ func (s *Store) ListUsers(ctx context.Context, tx kv.Tx, opt ...influxdb.FindOpt
return nil, err
}
cursor, err := b.ForwardCursor(nil)
var opts []kv.CursorOption
if o.Descending {
opts = append(opts, kv.WithCursorDirection(kv.CursorDescending))
}
var seek []byte
if o.After != nil {
after := (*o.After) + 1
seek, err = after.Encode()
if err != nil {
return nil, err
}
}
cursor, err := b.ForwardCursor(seek, opts...)
if err != nil {
return nil, err
}

View File

@ -330,6 +330,7 @@ func FindUsers(
type args struct {
ID platform.ID
name string
findOptions influxdb.FindOptions
}
type wants struct {
@ -482,6 +483,127 @@ func FindUsers(
},
},
},
{
name: "find all users by offset and limit",
fields: UserFields{
Users: []*influxdb.User{
{
ID: MustIDBase16(userOneID),
Name: "abc",
Status: influxdb.Active,
},
{
ID: MustIDBase16(userTwoID),
Name: "def",
Status: influxdb.Active,
},
{
ID: MustIDBase16(userThreeID),
Name: "xyz",
Status: influxdb.Active,
},
},
},
args: args{
findOptions: influxdb.FindOptions{
Offset: 1,
Limit: 1,
},
},
wants: wants{
users: []*influxdb.User{
{
ID: MustIDBase16(userTwoID),
Name: "def",
Status: influxdb.Active,
},
},
},
},
{
name: "find all users by after and limit",
fields: UserFields{
Users: []*influxdb.User{
{
ID: MustIDBase16(userOneID),
Name: "abc",
Status: influxdb.Active,
},
{
ID: MustIDBase16(userTwoID),
Name: "def",
Status: influxdb.Active,
},
{
ID: MustIDBase16(userThreeID),
Name: "xyz",
Status: influxdb.Active,
},
},
},
args: args{
findOptions: influxdb.FindOptions{
After: MustIDBase16Ptr(userOneID),
Limit: 2,
},
},
wants: wants{
users: []*influxdb.User{
{
ID: MustIDBase16(userTwoID),
Name: "def",
Status: influxdb.Active,
},
{
ID: MustIDBase16(userThreeID),
Name: "xyz",
Status: influxdb.Active,
},
},
},
},
{
name: "find all users by descending",
fields: UserFields{
Users: []*influxdb.User{
{
ID: MustIDBase16(userOneID),
Name: "abc",
Status: influxdb.Active,
},
{
ID: MustIDBase16(userTwoID),
Name: "def",
Status: influxdb.Active,
},
{
ID: MustIDBase16(userThreeID),
Name: "xyz",
Status: influxdb.Active,
},
},
},
args: args{
findOptions: influxdb.FindOptions{
Offset: 1,
Descending: true,
},
},
wants: wants{
users: []*influxdb.User{
{
ID: MustIDBase16(userTwoID),
Name: "def",
Status: influxdb.Active,
},
{
ID: MustIDBase16(userOneID),
Name: "abc",
Status: influxdb.Active,
},
},
},
},
}
for _, tt := range tests {
@ -498,7 +620,7 @@ func FindUsers(
filter.Name = &tt.args.name
}
users, _, err := s.FindUsers(ctx, filter)
users, _, err := s.FindUsers(ctx, filter, tt.args.findOptions)
diffPlatformErrors(tt.name, err, tt.wants.err, opPrefix, t)
if diff := cmp.Diff(users, tt.wants.users, userCmpOptions...); diff != "" {