diff --git a/internal/daemon/controller/handlers/list_token.go b/internal/daemon/controller/handlers/list_token.go index a8ea10497..e41a00e74 100644 --- a/internal/daemon/controller/handlers/list_token.go +++ b/internal/daemon/controller/handlers/list_token.go @@ -11,13 +11,19 @@ import ( "github.com/hashicorp/boundary/internal/listtoken" "github.com/hashicorp/boundary/internal/types/resource" "github.com/mr-tron/base58" + "google.golang.org/grpc/codes" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" ) // ParseListToken parses a list token from the input, returning // an error if the parsing fails. -func ParseListToken(ctx context.Context, token string) (*pbs.ListToken, error) { +func ParseListToken( + ctx context.Context, + token string, + expectedResourceType resource.Type, + expectedGrantsHash []byte, +) (*listtoken.Token, error) { const op = "handlers.ParseListToken" marshaled, err := base58.Decode(token) if err != nil { @@ -27,7 +33,54 @@ func ParseListToken(ctx context.Context, token string) (*pbs.ListToken, error) { if err := proto.Unmarshal(marshaled, &tok); err != nil { return nil, errors.Wrap(ctx, err, op) } - return &tok, nil + var listToken *listtoken.Token + switch st := tok.Token.(type) { + case *pbs.ListToken_PaginationToken: + listToken, err = listtoken.NewPagination( + ctx, + tok.CreateTime.AsTime(), + ListTokenResourceToResource(tok.ResourceType), + tok.GrantsHash, + st.PaginationToken.LastItemId, + st.PaginationToken.LastItemCreateTime.AsTime(), + ) + if err != nil { + return nil, err + } + case *pbs.ListToken_StartRefreshToken: + listToken, err = listtoken.NewStartRefresh( + ctx, + tok.CreateTime.AsTime(), + ListTokenResourceToResource(tok.ResourceType), + tok.GrantsHash, + st.StartRefreshToken.PreviousDeletedIdsTime.AsTime(), + st.StartRefreshToken.PreviousPhaseUpperBound.AsTime(), + ) + if err != nil { + return nil, err + } + case *pbs.ListToken_RefreshToken: + listToken, err = listtoken.NewRefresh( + ctx, + tok.CreateTime.AsTime(), + ListTokenResourceToResource(tok.ResourceType), + tok.GrantsHash, + st.RefreshToken.PreviousDeletedIdsTime.AsTime(), + st.RefreshToken.PhaseUpperBound.AsTime(), + st.RefreshToken.PhaseLowerBound.AsTime(), + st.RefreshToken.LastItemId, + st.RefreshToken.LastItemUpdateTime.AsTime(), + ) + if err != nil { + return nil, err + } + default: + return nil, ApiErrorWithCodeAndMessage(codes.InvalidArgument, "unexpected list token subtype: %T", st) + } + if err := listToken.Validate(ctx, expectedResourceType, expectedGrantsHash); err != nil { + return nil, err + } + return listToken, nil } // MarshalListToken assembles and marshals a list token to its string representation. diff --git a/internal/daemon/controller/handlers/list_token_test.go b/internal/daemon/controller/handlers/list_token_test.go index c4c72dfb7..5fadd2e48 100644 --- a/internal/daemon/controller/handlers/list_token_test.go +++ b/internal/daemon/controller/handlers/list_token_test.go @@ -22,102 +22,167 @@ import ( func Test_ParseListToken(t *testing.T) { t.Parallel() - pagToken := &pbs.ListToken{ - CreateTime: timestamppb.New(time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)), - ResourceType: pbs.ResourceType_RESOURCE_TYPE_TARGET, - GrantsHash: []byte("some hash"), - Token: &pbs.ListToken_PaginationToken{ - PaginationToken: &pbs.PaginationToken{ - LastItemId: "ttcp_1234567890", - LastItemCreateTime: timestamppb.New(time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)), - }, - }, - } - pagBytes, err := proto.Marshal(pagToken) - require.NoError(t, err) - pagString := base58.Encode(pagBytes) + fiveDaysAgo := time.Now().AddDate(0, 0, -5) + tokenCreateTime := fiveDaysAgo + lastItemCreateTime := fiveDaysAgo.Add(time.Hour) + lastItemUpdateTime := fiveDaysAgo.Add(2 * time.Hour) + previousPhaseUpperBoundTime := fiveDaysAgo.Add(3 * time.Hour) + previousDeletedIdsTime := fiveDaysAgo.Add(4 * time.Hour) + phaseLowerBound := fiveDaysAgo.Add(5 * time.Hour) + phaseUpperBound := fiveDaysAgo.Add(6 * time.Hour) - srToken := &pbs.ListToken{ - CreateTime: timestamppb.New(time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)), - ResourceType: pbs.ResourceType_RESOURCE_TYPE_TARGET, - GrantsHash: []byte("some hash"), - Token: &pbs.ListToken_StartRefreshToken{ - StartRefreshToken: &pbs.StartRefreshToken{ - PreviousPhaseUpperBound: timestamppb.New(time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)), - PreviousDeletedIdsTime: timestamppb.New(time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)), + t.Run("valid pagination", func(t *testing.T) { + t.Parallel() + pagToken := &pbs.ListToken{ + CreateTime: timestamppb.New(tokenCreateTime), + ResourceType: pbs.ResourceType_RESOURCE_TYPE_TARGET, + GrantsHash: []byte("some hash"), + Token: &pbs.ListToken_PaginationToken{ + PaginationToken: &pbs.PaginationToken{ + LastItemId: "ttcp_1234567890", + LastItemCreateTime: timestamppb.New(lastItemCreateTime), + }, }, - }, - } - srBytes, err := proto.Marshal(srToken) - require.NoError(t, err) - srString := base58.Encode(srBytes) + } + pagBytes, err := proto.Marshal(pagToken) + require.NoError(t, err) + pagString := base58.Encode(pagBytes) - rToken := &pbs.ListToken{ - CreateTime: timestamppb.New(time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)), - ResourceType: pbs.ResourceType_RESOURCE_TYPE_TARGET, - GrantsHash: []byte("some hash"), - Token: &pbs.ListToken_RefreshToken{ - RefreshToken: &pbs.RefreshToken{ - PhaseUpperBound: timestamppb.New(time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)), - PhaseLowerBound: timestamppb.New(time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)), - PreviousDeletedIdsTime: timestamppb.New(time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)), - LastItemId: "ttcp_1234567890", - LastItemUpdateTime: timestamppb.New(time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)), + domainPagToken, err := listtoken.NewPagination( + context.Background(), + pagToken.CreateTime.AsTime(), + handlers.ListTokenResourceToResource(pagToken.ResourceType), + pagToken.GrantsHash, + pagToken.GetPaginationToken().LastItemId, + pagToken.GetPaginationToken().LastItemCreateTime.AsTime(), + ) + require.NoError(t, err) + + got, err := handlers.ParseListToken(context.Background(), pagString, resource.Target, []byte("some hash")) + require.NoError(t, err) + require.Empty(t, cmp.Diff(got, domainPagToken, protocmp.Transform())) + }) + t.Run("valid start-refresh", func(t *testing.T) { + t.Parallel() + srToken := &pbs.ListToken{ + CreateTime: timestamppb.New(tokenCreateTime), + ResourceType: pbs.ResourceType_RESOURCE_TYPE_TARGET, + GrantsHash: []byte("some hash"), + Token: &pbs.ListToken_StartRefreshToken{ + StartRefreshToken: &pbs.StartRefreshToken{ + PreviousPhaseUpperBound: timestamppb.New(previousPhaseUpperBoundTime), + PreviousDeletedIdsTime: timestamppb.New(previousDeletedIdsTime), + }, }, - }, - } - rBytes, err := proto.Marshal(rToken) - require.NoError(t, err) - rString := base58.Encode(rBytes) + } + srBytes, err := proto.Marshal(srToken) + require.NoError(t, err) + srString := base58.Encode(srBytes) + domainSrToken, err := listtoken.NewStartRefresh( + context.Background(), + srToken.CreateTime.AsTime(), + handlers.ListTokenResourceToResource(srToken.ResourceType), + srToken.GrantsHash, + srToken.GetStartRefreshToken().PreviousDeletedIdsTime.AsTime(), + srToken.GetStartRefreshToken().PreviousPhaseUpperBound.AsTime(), + ) + require.NoError(t, err) - tests := []struct { - name string - token string - want *pbs.ListToken - wantErr bool - }{ - { - name: "valid pagination", - token: pagString, - want: pagToken, - }, - { - name: "valid start-refresh", - token: srString, - want: srToken, - }, - { - name: "valid refresh", - token: rString, - want: rToken, - }, - { - name: "empty token", - token: "", - wantErr: true, - }, - { - name: "invalid base58", - token: "not a token", - wantErr: true, - }, - { - name: "invalid proto", - token: base58.Encode([]byte("not a token")), - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := handlers.ParseListToken(context.Background(), tt.token) - if tt.wantErr { - require.Error(t, err) - return - } - require.NoError(t, err) - require.Empty(t, cmp.Diff(got, tt.want, protocmp.Transform())) - }) - } + got, err := handlers.ParseListToken(context.Background(), srString, resource.Target, []byte("some hash")) + require.NoError(t, err) + require.Empty(t, cmp.Diff(got, domainSrToken, protocmp.Transform())) + }) + t.Run("valid refresh", func(t *testing.T) { + t.Parallel() + rToken := &pbs.ListToken{ + CreateTime: timestamppb.New(tokenCreateTime), + ResourceType: pbs.ResourceType_RESOURCE_TYPE_TARGET, + GrantsHash: []byte("some hash"), + Token: &pbs.ListToken_RefreshToken{ + RefreshToken: &pbs.RefreshToken{ + PhaseUpperBound: timestamppb.New(phaseUpperBound), + PhaseLowerBound: timestamppb.New(phaseLowerBound), + PreviousDeletedIdsTime: timestamppb.New(previousDeletedIdsTime), + LastItemId: "ttcp_1234567890", + LastItemUpdateTime: timestamppb.New(lastItemUpdateTime), + }, + }, + } + rBytes, err := proto.Marshal(rToken) + require.NoError(t, err) + rString := base58.Encode(rBytes) + domainRToken, err := listtoken.NewRefresh( + context.Background(), + tokenCreateTime, + handlers.ListTokenResourceToResource(rToken.ResourceType), + rToken.GrantsHash, + rToken.GetRefreshToken().PreviousDeletedIdsTime.AsTime(), + rToken.GetRefreshToken().PhaseUpperBound.AsTime(), + rToken.GetRefreshToken().PhaseLowerBound.AsTime(), + rToken.GetRefreshToken().LastItemId, + rToken.GetRefreshToken().LastItemUpdateTime.AsTime(), + ) + require.NoError(t, err) + + got, err := handlers.ParseListToken(context.Background(), rString, resource.Target, []byte("some hash")) + require.NoError(t, err) + require.Empty(t, cmp.Diff(got, domainRToken, protocmp.Transform())) + }) + t.Run("empty token", func(t *testing.T) { + t.Parallel() + _, err := handlers.ParseListToken(context.Background(), "", resource.Target, []byte("some hash")) + require.Error(t, err) + }) + t.Run("invalid base58", func(t *testing.T) { + t.Parallel() + _, err := handlers.ParseListToken(context.Background(), "not a token", resource.Target, []byte("some hash")) + require.Error(t, err) + }) + t.Run("invalid proto", func(t *testing.T) { + t.Parallel() + _, err := handlers.ParseListToken(context.Background(), base58.Encode([]byte("not a token")), resource.Target, []byte("some hash")) + require.Error(t, err) + }) + t.Run("resource type mismatch", func(t *testing.T) { + t.Parallel() + pagToken := &pbs.ListToken{ + CreateTime: timestamppb.New(tokenCreateTime), + ResourceType: pbs.ResourceType_RESOURCE_TYPE_TARGET, + GrantsHash: []byte("some hash"), + Token: &pbs.ListToken_PaginationToken{ + PaginationToken: &pbs.PaginationToken{ + LastItemId: "ttcp_1234567890", + LastItemCreateTime: timestamppb.New(lastItemCreateTime), + }, + }, + } + pagBytes, err := proto.Marshal(pagToken) + require.NoError(t, err) + pagString := base58.Encode(pagBytes) + + _, err = handlers.ParseListToken(context.Background(), pagString, resource.Session, []byte("some hash")) + require.Error(t, err) + }) + t.Run("grants hash mismatch", func(t *testing.T) { + t.Parallel() + pagToken := &pbs.ListToken{ + CreateTime: timestamppb.New(tokenCreateTime), + ResourceType: pbs.ResourceType_RESOURCE_TYPE_TARGET, + GrantsHash: []byte("some hash"), + Token: &pbs.ListToken_PaginationToken{ + PaginationToken: &pbs.PaginationToken{ + LastItemId: "ttcp_1234567890", + LastItemCreateTime: timestamppb.New(lastItemCreateTime), + }, + }, + } + pagBytes, err := proto.Marshal(pagToken) + require.NoError(t, err) + pagString := base58.Encode(pagBytes) + + _, err = handlers.ParseListToken(context.Background(), pagString, resource.Target, []byte("some other hash")) + require.Error(t, err) + }) } func Test_MarshalListToken(t *testing.T) { @@ -132,6 +197,7 @@ func Test_MarshalListToken(t *testing.T) { phaseUpperBound := fiveDaysAgo.Add(6 * time.Hour) t.Run("valid pagination", func(t *testing.T) { + t.Parallel() pagToken := &pbs.ListToken{ CreateTime: timestamppb.New(tokenCreateTime), ResourceType: pbs.ResourceType_RESOURCE_TYPE_TARGET, @@ -161,6 +227,7 @@ func Test_MarshalListToken(t *testing.T) { require.Empty(t, cmp.Diff(got, pagString, protocmp.Transform())) }) t.Run("valid start-refresh", func(t *testing.T) { + t.Parallel() srToken := &pbs.ListToken{ CreateTime: timestamppb.New(tokenCreateTime), ResourceType: pbs.ResourceType_RESOURCE_TYPE_TARGET, @@ -190,6 +257,7 @@ func Test_MarshalListToken(t *testing.T) { require.Empty(t, cmp.Diff(got, srString, protocmp.Transform())) }) t.Run("valid refresh", func(t *testing.T) { + t.Parallel() rToken := &pbs.ListToken{ CreateTime: timestamppb.New(tokenCreateTime), ResourceType: pbs.ResourceType_RESOURCE_TYPE_TARGET, @@ -225,10 +293,12 @@ func Test_MarshalListToken(t *testing.T) { require.Empty(t, cmp.Diff(got, rString, protocmp.Transform())) }) t.Run("nil token", func(t *testing.T) { + t.Parallel() _, err := handlers.MarshalListToken(context.Background(), nil, pbs.ResourceType_RESOURCE_TYPE_TARGET) require.Error(t, err) }) t.Run("invalid token resource type", func(t *testing.T) { + t.Parallel() domainPagToken, err := listtoken.NewPagination( context.Background(), tokenCreateTime, @@ -242,6 +312,7 @@ func Test_MarshalListToken(t *testing.T) { require.Error(t, err) }) t.Run("token resource type mismatch", func(t *testing.T) { + t.Parallel() domainPagToken, err := listtoken.NewPagination( context.Background(), tokenCreateTime, @@ -255,6 +326,7 @@ func Test_MarshalListToken(t *testing.T) { require.Error(t, err) }) t.Run("invalid token subtype", func(t *testing.T) { + t.Parallel() invalidToken := &listtoken.Token{ CreateTime: tokenCreateTime, ResourceType: resource.Target, diff --git a/internal/daemon/controller/handlers/targets/target_service.go b/internal/daemon/controller/handlers/targets/target_service.go index bea9a42d1..2143d4ff7 100644 --- a/internal/daemon/controller/handlers/targets/target_service.go +++ b/internal/daemon/controller/handlers/targets/target_service.go @@ -289,70 +289,25 @@ func (s Service) ListTargets(ctx context.Context, req *pbs.ListTargetsRequest) ( return nil, err } } else { - pt, err := handlers.ParseListToken(ctx, req.GetListToken()) + listToken, err := handlers.ParseListToken(ctx, req.GetListToken(), resource.Target, grantsHash) if err != nil { return nil, err } - switch st := pt.Token.(type) { - case *pbs.ListToken_PaginationToken: + switch st := listToken.Subtype.(type) { + case *listtoken.PaginationToken: sortBy = "created_time" - listToken, err := listtoken.NewPagination( - ctx, - pt.CreateTime.AsTime(), - handlers.ListTokenResourceToResource(pt.ResourceType), - pt.GrantsHash, - st.PaginationToken.LastItemId, - st.PaginationToken.LastItemCreateTime.AsTime(), - ) - if err != nil { - return nil, err - } - if err := listToken.Validate(ctx, resource.Target, grantsHash); err != nil { - return nil, err - } listResp, err = target.ListPage(ctx, grantsHash, pageSize, filterItemFn, listToken, repo) if err != nil { return nil, err } - case *pbs.ListToken_StartRefreshToken: + case *listtoken.StartRefreshToken: sortBy = "updated_time" - listToken, err := listtoken.NewStartRefresh( - ctx, - pt.CreateTime.AsTime(), - handlers.ListTokenResourceToResource(pt.ResourceType), - pt.GrantsHash, - st.StartRefreshToken.PreviousDeletedIdsTime.AsTime(), - st.StartRefreshToken.PreviousPhaseUpperBound.AsTime(), - ) - if err != nil { - return nil, err - } - if err := listToken.Validate(ctx, resource.Target, grantsHash); err != nil { - return nil, err - } listResp, err = target.ListRefresh(ctx, grantsHash, pageSize, filterItemFn, listToken, repo) if err != nil { return nil, err } - case *pbs.ListToken_RefreshToken: + case *listtoken.RefreshToken: sortBy = "updated_time" - listToken, err := listtoken.NewRefresh( - ctx, - pt.CreateTime.AsTime(), - handlers.ListTokenResourceToResource(pt.ResourceType), - pt.GrantsHash, - st.RefreshToken.PreviousDeletedIdsTime.AsTime(), - st.RefreshToken.PhaseUpperBound.AsTime(), - st.RefreshToken.PhaseLowerBound.AsTime(), - st.RefreshToken.LastItemId, - st.RefreshToken.LastItemUpdateTime.AsTime(), - ) - if err != nil { - return nil, err - } - if err := listToken.Validate(ctx, resource.Target, grantsHash); err != nil { - return nil, err - } listResp, err = target.ListRefreshPage(ctx, grantsHash, pageSize, filterItemFn, listToken, repo) if err != nil { return nil, err diff --git a/internal/target/service_list_ext_test.go b/internal/target/service_list_ext_test.go index 5416cf5ea..8768dabae 100644 --- a/internal/target/service_list_ext_test.go +++ b/internal/target/service_list_ext_test.go @@ -193,7 +193,7 @@ func TestService_List(t *testing.T) { } tok, err := listtoken.NewStartRefresh(ctx, fiveDaysAgo, resource.Target, []byte("some hash"), fiveDaysAgo, fiveDaysAgo) require.NoError(t, err) - _, err = target.ListPage(ctx, nil, 1, filterFunc, tok, repo) + _, err = target.ListRefresh(ctx, nil, 1, filterFunc, tok, repo) require.ErrorContains(t, err, "missing grants hash") }) t.Run("zero page size", func(t *testing.T) { @@ -203,7 +203,7 @@ func TestService_List(t *testing.T) { } tok, err := listtoken.NewStartRefresh(ctx, fiveDaysAgo, resource.Target, []byte("some hash"), fiveDaysAgo, fiveDaysAgo) require.NoError(t, err) - _, err = target.ListPage(ctx, []byte("some hash"), 0, filterFunc, tok, repo) + _, err = target.ListRefresh(ctx, []byte("some hash"), 0, filterFunc, tok, repo) require.ErrorContains(t, err, "page size must be at least 1") }) t.Run("negative page size", func(t *testing.T) { @@ -213,14 +213,14 @@ func TestService_List(t *testing.T) { } tok, err := listtoken.NewStartRefresh(ctx, fiveDaysAgo, resource.Target, []byte("some hash"), fiveDaysAgo, fiveDaysAgo) require.NoError(t, err) - _, err = target.ListPage(ctx, []byte("some hash"), -1, filterFunc, tok, repo) + _, err = target.ListRefresh(ctx, []byte("some hash"), -1, filterFunc, tok, repo) require.ErrorContains(t, err, "page size must be at least 1") }) t.Run("nil filter func", func(t *testing.T) { t.Parallel() tok, err := listtoken.NewStartRefresh(ctx, fiveDaysAgo, resource.Target, []byte("some hash"), fiveDaysAgo, fiveDaysAgo) require.NoError(t, err) - _, err = target.ListPage(ctx, []byte("some hash"), 1, nil, tok, repo) + _, err = target.ListRefresh(ctx, []byte("some hash"), 1, nil, tok, repo) require.ErrorContains(t, err, "missing filter item callback") }) t.Run("nil token", func(t *testing.T) { @@ -228,7 +228,7 @@ func TestService_List(t *testing.T) { filterFunc := func(_ context.Context, t target.Target) (bool, error) { return true, nil } - _, err = target.ListPage(ctx, []byte("some hash"), 1, filterFunc, nil, repo) + _, err = target.ListRefresh(ctx, []byte("some hash"), 1, filterFunc, nil, repo) require.ErrorContains(t, err, "missing token") }) t.Run("wrong token type", func(t *testing.T) { @@ -248,143 +248,7 @@ func TestService_List(t *testing.T) { } tok, err := listtoken.NewStartRefresh(ctx, fiveDaysAgo, resource.Target, []byte("some hash"), fiveDaysAgo, fiveDaysAgo) require.NoError(t, err) - _, err = target.ListPage(ctx, []byte("some hash"), 1, filterFunc, tok, nil) - require.ErrorContains(t, err, "missing repo") - }) - }) - t.Run("ListRefresh validation", func(t *testing.T) { - t.Parallel() - t.Run("missing grants hash", func(t *testing.T) { - t.Parallel() - filterFunc := func(_ context.Context, t target.Target) (bool, error) { - return true, nil - } - tok, err := listtoken.NewStartRefresh(ctx, fiveDaysAgo, resource.Target, []byte("some hash"), fiveDaysAgo, fiveDaysAgo) - require.NoError(t, err) - _, err = target.ListPage(ctx, nil, 1, filterFunc, tok, repo) - require.ErrorContains(t, err, "missing grants hash") - }) - t.Run("zero page size", func(t *testing.T) { - t.Parallel() - filterFunc := func(_ context.Context, t target.Target) (bool, error) { - return true, nil - } - tok, err := listtoken.NewStartRefresh(ctx, fiveDaysAgo, resource.Target, []byte("some hash"), fiveDaysAgo, fiveDaysAgo) - require.NoError(t, err) - _, err = target.ListPage(ctx, []byte("some hash"), 0, filterFunc, tok, repo) - require.ErrorContains(t, err, "page size must be at least 1") - }) - t.Run("negative page size", func(t *testing.T) { - t.Parallel() - filterFunc := func(_ context.Context, t target.Target) (bool, error) { - return true, nil - } - tok, err := listtoken.NewStartRefresh(ctx, fiveDaysAgo, resource.Target, []byte("some hash"), fiveDaysAgo, fiveDaysAgo) - require.NoError(t, err) - _, err = target.ListPage(ctx, []byte("some hash"), -1, filterFunc, tok, repo) - require.ErrorContains(t, err, "page size must be at least 1") - }) - t.Run("nil filter func", func(t *testing.T) { - t.Parallel() - tok, err := listtoken.NewStartRefresh(ctx, fiveDaysAgo, resource.Target, []byte("some hash"), fiveDaysAgo, fiveDaysAgo) - require.NoError(t, err) - _, err = target.ListPage(ctx, []byte("some hash"), 1, nil, tok, repo) - require.ErrorContains(t, err, "missing filter item callback") - }) - t.Run("nil token", func(t *testing.T) { - t.Parallel() - filterFunc := func(_ context.Context, t target.Target) (bool, error) { - return true, nil - } - _, err = target.ListPage(ctx, []byte("some hash"), 1, filterFunc, nil, repo) - require.ErrorContains(t, err, "missing token") - }) - t.Run("wrong token type", func(t *testing.T) { - t.Parallel() - filterFunc := func(_ context.Context, t target.Target) (bool, error) { - return true, nil - } - tok, err := listtoken.NewPagination(ctx, fiveDaysAgo, resource.Target, []byte("some hash"), "some-id", fiveDaysAgo) - require.NoError(t, err) - _, err = target.ListRefresh(ctx, []byte("some hash"), 1, filterFunc, tok, repo) - require.ErrorContains(t, err, "token did not have a start-refresh token component") - }) - t.Run("nil repo", func(t *testing.T) { - t.Parallel() - filterFunc := func(_ context.Context, t target.Target) (bool, error) { - return true, nil - } - tok, err := listtoken.NewStartRefresh(ctx, fiveDaysAgo, resource.Target, []byte("some hash"), fiveDaysAgo, fiveDaysAgo) - require.NoError(t, err) - _, err = target.ListPage(ctx, []byte("some hash"), 1, filterFunc, tok, nil) - require.ErrorContains(t, err, "missing repo") - }) - }) - t.Run("ListRefreshPage validation", func(t *testing.T) { - t.Parallel() - t.Run("missing grants hash", func(t *testing.T) { - t.Parallel() - filterFunc := func(_ context.Context, t target.Target) (bool, error) { - return true, nil - } - tok, err := listtoken.NewRefresh(ctx, fiveDaysAgo, resource.Target, []byte("some hash"), fiveDaysAgo, fiveDaysAgo, fiveDaysAgo, "some other id", fiveDaysAgo) - require.NoError(t, err) - _, err = target.ListRefreshPage(ctx, nil, 1, filterFunc, tok, repo) - require.ErrorContains(t, err, "missing grants hash") - }) - t.Run("zero page size", func(t *testing.T) { - t.Parallel() - filterFunc := func(_ context.Context, t target.Target) (bool, error) { - return true, nil - } - tok, err := listtoken.NewRefresh(ctx, fiveDaysAgo, resource.Target, []byte("some hash"), fiveDaysAgo, fiveDaysAgo, fiveDaysAgo, "some other id", fiveDaysAgo) - require.NoError(t, err) - _, err = target.ListRefreshPage(ctx, []byte("some hash"), 0, filterFunc, tok, repo) - require.ErrorContains(t, err, "page size must be at least 1") - }) - t.Run("negative page size", func(t *testing.T) { - t.Parallel() - filterFunc := func(_ context.Context, t target.Target) (bool, error) { - return true, nil - } - tok, err := listtoken.NewRefresh(ctx, fiveDaysAgo, resource.Target, []byte("some hash"), fiveDaysAgo, fiveDaysAgo, fiveDaysAgo, "some other id", fiveDaysAgo) - require.NoError(t, err) - _, err = target.ListRefreshPage(ctx, []byte("some hash"), -1, filterFunc, tok, repo) - require.ErrorContains(t, err, "page size must be at least 1") - }) - t.Run("nil filter func", func(t *testing.T) { - t.Parallel() - tok, err := listtoken.NewRefresh(ctx, fiveDaysAgo, resource.Target, []byte("some hash"), fiveDaysAgo, fiveDaysAgo, fiveDaysAgo, "some other id", fiveDaysAgo) - require.NoError(t, err) - _, err = target.ListRefreshPage(ctx, []byte("some hash"), 1, nil, tok, repo) - require.ErrorContains(t, err, "missing filter item callback") - }) - t.Run("nil token", func(t *testing.T) { - t.Parallel() - filterFunc := func(_ context.Context, t target.Target) (bool, error) { - return true, nil - } - _, err = target.ListRefreshPage(ctx, []byte("some hash"), 1, filterFunc, nil, repo) - require.ErrorContains(t, err, "missing token") - }) - t.Run("wrong token type", func(t *testing.T) { - t.Parallel() - filterFunc := func(_ context.Context, t target.Target) (bool, error) { - return true, nil - } - tok, err := listtoken.NewPagination(ctx, fiveDaysAgo, resource.Target, []byte("some hash"), "some-id", fiveDaysAgo) - require.NoError(t, err) - _, err = target.ListRefreshPage(ctx, []byte("some hash"), 1, filterFunc, tok, repo) - require.ErrorContains(t, err, "token did not have a refresh token component") - }) - t.Run("nil repo", func(t *testing.T) { - t.Parallel() - filterFunc := func(_ context.Context, t target.Target) (bool, error) { - return true, nil - } - tok, err := listtoken.NewRefresh(ctx, fiveDaysAgo, resource.Target, []byte("some hash"), fiveDaysAgo, fiveDaysAgo, fiveDaysAgo, "some other id", fiveDaysAgo) - require.NoError(t, err) - _, err = target.ListRefreshPage(ctx, []byte("some hash"), 1, filterFunc, tok, nil) + _, err = target.ListRefresh(ctx, []byte("some hash"), 1, filterFunc, tok, nil) require.ErrorContains(t, err, "missing repo") }) })