feat(users): list users via the API now supports `offset`, `limit` or `after` parameter (#21367)
parent
e77481fe52
commit
4becb6d01a
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -328,8 +328,9 @@ func FindUsers(
|
|||
t *testing.T,
|
||||
) {
|
||||
type args struct {
|
||||
ID platform.ID
|
||||
name string
|
||||
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 != "" {
|
||||
|
|
Loading…
Reference in New Issue