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. [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. [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
|
### Bug Fixes
|
||||||
|
|
||||||
|
|
|
@ -388,7 +388,7 @@ func (h *UserHandler) handleGetUsers(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
users, _, err := h.UserService.FindUsers(ctx, req.filter)
|
users, _, err := h.UserService.FindUsers(ctx, req.filter, req.opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.HandleHTTPError(ctx, err, w)
|
h.HandleHTTPError(ctx, err, w)
|
||||||
return
|
return
|
||||||
|
@ -404,11 +404,19 @@ func (h *UserHandler) handleGetUsers(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
type getUsersRequest struct {
|
type getUsersRequest struct {
|
||||||
filter influxdb.UserFilter
|
filter influxdb.UserFilter
|
||||||
|
opts influxdb.FindOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeGetUsersRequest(ctx context.Context, r *http.Request) (*getUsersRequest, error) {
|
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()
|
qp := r.URL.Query()
|
||||||
req := &getUsersRequest{}
|
req := &getUsersRequest{
|
||||||
|
opts: *opts,
|
||||||
|
}
|
||||||
|
|
||||||
if userID := qp.Get("id"); userID != "" {
|
if userID := qp.Get("id"); userID != "" {
|
||||||
id, err := platform.IDFromString(userID)
|
id, err := platform.IDFromString(userID)
|
||||||
|
|
|
@ -409,7 +409,7 @@ func (h *UserHandler) handleGetUsers(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
users, _, err := h.userSvc.FindUsers(ctx, req.filter)
|
users, _, err := h.userSvc.FindUsers(ctx, req.filter, req.opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.api.Err(w, r, err)
|
h.api.Err(w, r, err)
|
||||||
return
|
return
|
||||||
|
@ -421,11 +421,19 @@ func (h *UserHandler) handleGetUsers(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
type getUsersRequest struct {
|
type getUsersRequest struct {
|
||||||
filter influxdb.UserFilter
|
filter influxdb.UserFilter
|
||||||
|
opts influxdb.FindOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeGetUsersRequest(ctx context.Context, r *http.Request) (*getUsersRequest, error) {
|
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()
|
qp := r.URL.Query()
|
||||||
req := &getUsersRequest{}
|
req := &getUsersRequest{
|
||||||
|
opts: *opts,
|
||||||
|
}
|
||||||
|
|
||||||
if userID := qp.Get("id"); userID != "" {
|
if userID := qp.Get("id"); userID != "" {
|
||||||
id, err := platform.IDFromString(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
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -330,6 +330,7 @@ func FindUsers(
|
||||||
type args struct {
|
type args struct {
|
||||||
ID platform.ID
|
ID platform.ID
|
||||||
name string
|
name string
|
||||||
|
findOptions influxdb.FindOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
type wants struct {
|
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 {
|
for _, tt := range tests {
|
||||||
|
@ -498,7 +620,7 @@ func FindUsers(
|
||||||
filter.Name = &tt.args.name
|
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)
|
diffPlatformErrors(tt.name, err, tt.wants.err, opPrefix, t)
|
||||||
|
|
||||||
if diff := cmp.Diff(users, tt.wants.users, userCmpOptions...); diff != "" {
|
if diff := cmp.Diff(users, tt.wants.users, userCmpOptions...); diff != "" {
|
||||||
|
|
Loading…
Reference in New Issue