Esempio n. 1
0
    /// <summary>
    /// Get all statuses the given user is allowed to retrieve.
    /// </summary>
    /// <param name="uid"></param>
    /// <returns></returns>
    public static async Task <UserlistResult> GetUserStatusesAsync(this IUserStatusTracker userStatuses,
                                                                   IGenericSearch searcher, long uid, string contentFields = "*", string userFields = "*", params long[] contentIds)
    {
        //Always allow 0 in there FYI
        var allStatuses = await userStatuses.GetUserStatusesAsync(contentIds);

        var allIds = allStatuses.Keys.ToList();

        //Search content AS THE USER so they only get the content they're allowed to get. Hopefully
        //there will never be an instance where there are over a thousand contents currently being watched
        var allSearch = await searcher.Search(new SearchRequests()
        {
            requests = new List <SearchRequest>()
            {
                new SearchRequest()
                {
                    type   = "content",
                    fields = contentFields,
                    query  = "id in @ids"
                },
                new SearchRequest()
                {
                    type   = "user",
                    fields = userFields,
                    query  = "id in @content.createUserId or id in @userIds"
                }
            },
            values = new Dictionary <string, object>()
            {
                { "ids", allIds },
                { "userIds", allStatuses.SelectMany(x => x.Value.Keys) }
            }
        }, uid);


        //Remove the statuses they can't see, meaning anything that's NOT in the allSearch set
        foreach (var id in allIds.Where(x => x != 0).Except(allSearch.objects["content"].Select(x => (long)x["id"])))
        {
            allStatuses.Remove(id);
        }

        //Don't leak information: remove users that aren't referenced
        var allUsers = allStatuses.SelectMany(x => x.Value.Keys).Union(allSearch.objects["content"].Select(x => (long)x["createUserId"]));

        allSearch.objects["user"] = allSearch.objects["user"].Where(x => allUsers.Contains((long)x["id"]));

        return(new UserlistResult()
        {
            statuses = allStatuses,
            objects = allSearch.objects
        });
    }
    public static async Task <List <T> > SearchSingleType <T>(this IGenericSearch search, long uid, SearchRequest request, Dictionary <string, object>?values = null)
    {
        //Now go get some random-ass module message
        var searchResult = await search.Search(new SearchRequests()
        {
            values   = values ?? new Dictionary <string, object>(),
            requests = new List <SearchRequest> {
                request
            }
        }, uid);

        return(search.ToStronglyTyped <T>(searchResult.objects.First().Value));
    }
    public async void SearchAsync_InMultiList()
    {
        //Write two comments with two users in them. See if chaining to that field works
        var comment1 = GetNewCommentView(AllAccessContentId);

        comment1.text = $"And it's %{NormalUserId}%";
        var comment2 = GetNewCommentView(AllAccessContentId);

        comment2.text = $"And it's also %{SuperUserId}%";

        var writtenComment1 = await writer.WriteAsync(comment1, NormalUserId);

        var writtenComment2 = await writer.WriteAsync(comment2, SuperUserId);

        //Now search specifically for those two comments, but with users chained to the uidsInText field
        var search = new SearchRequests()
        {
            requests = new List <SearchRequest> {
                new SearchRequest()
                {
                    type   = "message",
                    fields = "*",
                    query  = "id in @ids"
                },
                new SearchRequest()
                {
                    type   = "user",
                    fields = "*",
                    query  = "id in @message.uidsInText"
                }
            },
            values = new Dictionary <string, object> {
                { "ids", new[] { writtenComment1.id, writtenComment2.id } }
            }
        };

        var results = await searcher.Search(search, NormalUserId);

        var comments = searcher.ToStronglyTyped <MessageView>(results.objects["message"]);
        var users    = searcher.ToStronglyTyped <UserView>(results.objects["user"]);

        Assert.Equal(2, comments.Count);
        Assert.Equal(2, users.Count);
        Assert.Contains(writtenComment1.id, comments.Select(x => x.id));
        Assert.Contains(writtenComment2.id, comments.Select(x => x.id));
        Assert.Contains(NormalUserId, users.Select(x => x.id));
        Assert.Contains(SuperUserId, users.Select(x => x.id));
    }
Esempio n. 4
0
 /// <summary>
 /// Filters the <paramref name="query"/> results using a cached request object to obtain the search parameters.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="query"></param>
 /// <param name="search"></param>
 /// <returns></returns>
 public static IQueryable <T> Search <T>(this IQueryable <T> query, IGenericSearch search)
 {
     return(search.Search(query));
 }
Esempio n. 5
0
 /// <summary>
 /// Filters the <paramref name="query"/> results using the provided request object to obtain the search parameters.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="query"></param>
 /// <param name="search"></param>
 /// <param name="request"></param>
 /// <returns></returns>
 public static IQueryable <T> Search <T>(this IQueryable <T> query, IGenericSearch search, object request)
 {
     return(search.Search(query, request));
 }