Skip to content

Commit

Permalink
feat(users): list users via the API now supports offset, limit or…
Browse files Browse the repository at this point in the history
… `after` parameter (#21367)
  • Loading branch information
bednar authored May 12, 2021
1 parent e77481f commit 4becb6d
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
12 changes: 10 additions & 2 deletions http/user_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down
12 changes: 10 additions & 2 deletions tenant/http_server_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down
16 changes: 15 additions & 1 deletion tenant/storage_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
128 changes: 125 additions & 3 deletions testing/user_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -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 != "" {
Expand Down

0 comments on commit 4becb6d

Please sign in to comment.