diff --git a/api/v2/memo_service.go b/api/v2/memo_service.go index 10665f58..b1f6004d 100644 --- a/api/v2/memo_service.go +++ b/api/v2/memo_service.go @@ -96,9 +96,6 @@ func (s *APIV2Service) ListMemos(ctx context.Context, request *apiv2pb.ListMemos if err := unmarshalPageToken(request.PageToken, &pageToken); err != nil { return nil, status.Errorf(codes.InvalidArgument, "invalid page token: %v", err) } - if pageToken.Limit < 0 { - return nil, status.Errorf(codes.InvalidArgument, "page size cannot be negative") - } limit = int(pageToken.Limit) offset = int(pageToken.Offset) } else { @@ -108,11 +105,11 @@ func (s *APIV2Service) ListMemos(ctx context.Context, request *apiv2pb.ListMemos limit = DefaultPageSize } limitPlusOne := limit + 1 - memoFind.Offset = &offset memoFind.Limit = &limitPlusOne + memoFind.Offset = &offset memos, err := s.Store.ListMemos(ctx, memoFind) if err != nil { - return nil, err + return nil, status.Errorf(codes.Internal, "failed to list memos") } memoMessages := []*apiv2pb.Memo{} @@ -613,6 +610,90 @@ func convertVisibilityToStore(visibility apiv2pb.Visibility) store.Visibility { } } +func (s *APIV2Service) buildMemoFindWithFilter(ctx context.Context, find *store.FindMemo, filter string) error { + user, _ := getCurrentUser(ctx, s.Store) + if find == nil { + find = &store.FindMemo{} + } + if filter != "" { + filter, err := parseListMemosFilter(filter) + if err != nil { + return status.Errorf(codes.InvalidArgument, "invalid filter: %v", err) + } + if len(filter.ContentSearch) > 0 { + find.ContentSearch = filter.ContentSearch + } + if len(filter.Visibilities) > 0 { + find.VisibilityList = filter.Visibilities + } + if filter.OrderByPinned { + find.OrderByPinned = filter.OrderByPinned + } + if filter.DisplayTimeAfter != nil { + displayWithUpdatedTs, err := s.getMemoDisplayWithUpdatedTsSettingValue(ctx) + if err != nil { + return status.Errorf(codes.Internal, "failed to get memo display with updated ts setting value") + } + if displayWithUpdatedTs { + find.UpdatedTsAfter = filter.DisplayTimeAfter + } else { + find.CreatedTsAfter = filter.DisplayTimeAfter + } + } + if filter.DisplayTimeBefore != nil { + displayWithUpdatedTs, err := s.getMemoDisplayWithUpdatedTsSettingValue(ctx) + if err != nil { + return status.Errorf(codes.Internal, "failed to get memo display with updated ts setting value") + } + if displayWithUpdatedTs { + find.UpdatedTsBefore = filter.DisplayTimeBefore + } else { + find.CreatedTsBefore = filter.DisplayTimeBefore + } + } + if filter.Creator != nil { + username, err := ExtractUsernameFromName(*filter.Creator) + if err != nil { + return status.Errorf(codes.InvalidArgument, "invalid creator name") + } + user, err := s.Store.GetUser(ctx, &store.FindUser{ + Username: &username, + }) + if err != nil { + return status.Errorf(codes.Internal, "failed to get user") + } + if user == nil { + return status.Errorf(codes.NotFound, "user not found") + } + find.CreatorID = &user.ID + } + if filter.RowStatus != nil { + find.RowStatus = filter.RowStatus + } + } + + // If the user is not authenticated, only public memos are visible. + if user == nil { + if filter == "" { + // If no filter is provided, return an error. + return status.Errorf(codes.InvalidArgument, "filter is required") + } + + find.VisibilityList = []store.Visibility{store.Public} + } else if find.CreatorID != nil && *find.CreatorID != user.ID { + find.VisibilityList = []store.Visibility{store.Public, store.Protected} + } + + displayWithUpdatedTs, err := s.getMemoDisplayWithUpdatedTsSettingValue(ctx) + if err != nil { + return status.Errorf(codes.Internal, "failed to get memo display with updated ts setting value") + } + if displayWithUpdatedTs { + find.OrderByUpdatedTs = true + } + return nil +} + // ListMemosFilterCELAttributes are the CEL attributes for ListMemosFilter. var ListMemosFilterCELAttributes = []cel.EnvOption{ cel.Variable("content_search", cel.ListType(cel.StringType)), @@ -733,90 +814,6 @@ func (s *APIV2Service) dispatchMemoRelatedWebhook(ctx context.Context, memo *api return nil } -func (s *APIV2Service) buildMemoFindWithFilter(ctx context.Context, find *store.FindMemo, filter string) error { - user, _ := getCurrentUser(ctx, s.Store) - if find == nil { - find = &store.FindMemo{} - } - if filter != "" { - filter, err := parseListMemosFilter(filter) - if err != nil { - return status.Errorf(codes.InvalidArgument, "invalid filter: %v", err) - } - if len(filter.ContentSearch) > 0 { - find.ContentSearch = filter.ContentSearch - } - if len(filter.Visibilities) > 0 { - find.VisibilityList = filter.Visibilities - } - if filter.OrderByPinned { - find.OrderByPinned = filter.OrderByPinned - } - if filter.DisplayTimeAfter != nil { - displayWithUpdatedTs, err := s.getMemoDisplayWithUpdatedTsSettingValue(ctx) - if err != nil { - return status.Errorf(codes.Internal, "failed to get memo display with updated ts setting value") - } - if displayWithUpdatedTs { - find.UpdatedTsAfter = filter.DisplayTimeAfter - } else { - find.CreatedTsAfter = filter.DisplayTimeAfter - } - } - if filter.DisplayTimeBefore != nil { - displayWithUpdatedTs, err := s.getMemoDisplayWithUpdatedTsSettingValue(ctx) - if err != nil { - return status.Errorf(codes.Internal, "failed to get memo display with updated ts setting value") - } - if displayWithUpdatedTs { - find.UpdatedTsBefore = filter.DisplayTimeBefore - } else { - find.CreatedTsBefore = filter.DisplayTimeBefore - } - } - if filter.Creator != nil { - username, err := ExtractUsernameFromName(*filter.Creator) - if err != nil { - return status.Errorf(codes.InvalidArgument, "invalid creator name") - } - user, err := s.Store.GetUser(ctx, &store.FindUser{ - Username: &username, - }) - if err != nil { - return status.Errorf(codes.Internal, "failed to get user") - } - if user == nil { - return status.Errorf(codes.NotFound, "user not found") - } - find.CreatorID = &user.ID - } - if filter.RowStatus != nil { - find.RowStatus = filter.RowStatus - } - } else if user == nil { - // If no filter is provided, check if the user is authenticated. - return status.Errorf(codes.InvalidArgument, "filter is required") - } - - // If the user is not authenticated, only public memos are visible. - if user == nil { - find.VisibilityList = []store.Visibility{store.Public} - } - if user != nil && find.CreatorID != nil && *find.CreatorID != user.ID { - find.VisibilityList = []store.Visibility{store.Public, store.Protected} - } - - displayWithUpdatedTs, err := s.getMemoDisplayWithUpdatedTsSettingValue(ctx) - if err != nil { - return status.Errorf(codes.Internal, "failed to get memo display with updated ts setting value") - } - if displayWithUpdatedTs { - find.OrderByUpdatedTs = true - } - - return nil -} - func convertMemoToWebhookPayload(memo *apiv2pb.Memo) *webhook.WebhookPayload { return &webhook.WebhookPayload{ CreatorID: memo.CreatorId,