Exemple #1
0
        public void Build(QueryEngineBuilder <User> builder)
        {
            builder
            .WithNamedTerm("status", builder => builder
                           .OneCondition((val, query) =>
            {
                if (Enum.TryParse <UsersFilter>(val, true, out var usersStatus))
                {
                    switch (usersStatus)
                    {
                    case UsersFilter.Enabled:
                        query.With <UserIndex>(u => u.IsEnabled);
                        break;

                    case UsersFilter.Disabled:
                        query.With <UserIndex>(u => !u.IsEnabled);
                        break;
                    }
                }

                return(query);
            })
                           .MapTo <UserIndexOptions>((val, model) =>
            {
                if (Enum.TryParse <UsersFilter>(val, true, out var usersFilter))
                {
                    model.Filter = usersFilter;
                }
            })
                           .MapFrom <UserIndexOptions>((model) =>
            {
                switch (model.Filter)
                {
                case UsersFilter.Enabled:
                    return(true, model.Filter.ToString());

                case UsersFilter.Disabled:
                    return(true, model.Filter.ToString());
                }

                return(false, String.Empty);
            })
                           )
            .WithNamedTerm("sort", builder => builder
                           .OneCondition((val, query) =>
            {
                if (Enum.TryParse <UsersOrder>(val, true, out var usersOrder))
                {
                    switch (usersOrder)
                    {
                    case UsersOrder.Name:
                        query.With <UserIndex>().OrderBy(u => u.NormalizedUserName);
                        break;

                    case UsersOrder.Email:
                        query.With <UserIndex>().OrderBy(u => u.NormalizedEmail);
                        break;
                    }
                    ;
                }
                else
                {
                    query.With <UserIndex>().OrderBy(u => u.NormalizedUserName);
                }

                return(query);
            })
                           .MapTo <UserIndexOptions>((val, model) =>
            {
                if (Enum.TryParse <UsersOrder>(val, true, out var order))
                {
                    model.Order = order;
                }
            })
                           .MapFrom <UserIndexOptions>((model) =>
            {
                if (model.Order != UsersOrder.Name)
                {
                    return(true, model.Order.ToString());
                }

                return(false, String.Empty);
            })
                           .AlwaysRun()
                           )
            .WithNamedTerm("role", builder => builder
                           .OneCondition((val, query, ctx) =>
            {
                var context            = (UserQueryContext)ctx;
                var userManager        = context.ServiceProvider.GetRequiredService <UserManager <IUser> >();
                var normalizedRoleName = userManager.NormalizeName(val);
                query.With <UserByRoleNameIndex>(x => x.RoleName == normalizedRoleName);

                return(new ValueTask <IQuery <User> >(query));
            })
                           .MapTo <UserIndexOptions>((val, model) => model.SelectedRole = val)
                           .MapFrom <UserIndexOptions>((model) => (!String.IsNullOrEmpty(model.SelectedRole), model.SelectedRole))
                           )
            .WithDefaultTerm("name", builder => builder
                             .ManyCondition(
                                 (val, query, ctx) =>
            {
                var context            = (UserQueryContext)ctx;
                var userManager        = context.ServiceProvider.GetRequiredService <UserManager <IUser> >();
                var normalizedUserName = userManager.NormalizeName(val);
                query.With <UserIndex>(x => x.NormalizedUserName.Contains(normalizedUserName));

                return(new ValueTask <IQuery <User> >(query));
            },
                                 (val, query, ctx) =>
            {
                var context            = (UserQueryContext)ctx;
                var userManager        = context.ServiceProvider.GetRequiredService <UserManager <IUser> >();
                var normalizedUserName = userManager.NormalizeName(val);
                query.With <UserIndex>(x => x.NormalizedUserName.NotContains(normalizedUserName));

                return(new ValueTask <IQuery <User> >(query));
            }
                                 )
                             )
            .WithNamedTerm("email", builder => builder
                           .ManyCondition(
                               (val, query, ctx) =>
            {
                var context         = (UserQueryContext)ctx;
                var userManager     = context.ServiceProvider.GetRequiredService <UserManager <IUser> >();
                var normalizedEmail = userManager.NormalizeEmail(val);
                query.With <UserIndex>(x => x.NormalizedEmail.Contains(normalizedEmail));

                return(new ValueTask <IQuery <User> >(query));
            },
                               (val, query, ctx) =>
            {
                var context         = (UserQueryContext)ctx;
                var userManager     = context.ServiceProvider.GetRequiredService <UserManager <IUser> >();
                var normalizedEmail = userManager.NormalizeEmail(val);
                query.With <UserIndex>(x => x.NormalizedEmail.NotContains(normalizedEmail));

                return(new ValueTask <IQuery <User> >(query));
            }
                               )
                           );
        }
        public void Build(QueryEngineBuilder <AuditTrailEvent> builder)
        {
            builder
            .WithNamedTerm("id", builder => builder
                           .OneCondition((val, query) =>
            {
                if (!String.IsNullOrEmpty(val))
                {
                    query.With <AuditTrailEventIndex>(x => x.CorrelationId == val);
                }

                return(query);
            })
                           .MapTo <AuditTrailIndexOptions>((val, model) =>
            {
                model.CorrelationId = val;
            })
                           .MapFrom <AuditTrailIndexOptions>((model) =>
            {
                if (!String.IsNullOrEmpty(model.CorrelationId))
                {
                    return(true, model.CorrelationId);
                }
                return(false, String.Empty);
            })
                           )
            .WithNamedTerm("category", builder => builder
                           .OneCondition((val, query) =>
            {
                if (!String.IsNullOrEmpty(val))
                {
                    query.With <AuditTrailEventIndex>(x => x.Category == val);
                }

                return(query);
            })
                           .MapTo <AuditTrailIndexOptions>((val, model) =>
            {
                model.Category = val;
            })
                           .MapFrom <AuditTrailIndexOptions>((model) =>
            {
                if (!String.IsNullOrEmpty(model.Category))
                {
                    return(true, model.Category);
                }
                return(false, String.Empty);
            })
                           )
            .WithNamedTerm("event", builder => builder
                           .OneCondition((val, query) =>
            {
                if (!String.IsNullOrEmpty(val))
                {
                    query.With <AuditTrailEventIndex>(x => x.Name == val);
                }

                return(query);
            })
                           .MapTo <AuditTrailIndexOptions>((val, model) =>
            {
                model.Event = val;
            })
                           .MapFrom <AuditTrailIndexOptions>((model) =>
            {
                if (!String.IsNullOrEmpty(model.Event))
                {
                    return(true, model.Event);
                }
                return(false, String.Empty);
            })
                           )
            .WithNamedTerm("date", builder => builder
                           .OneCondition(async(val, query, ctx) =>
            {
                if (String.IsNullOrEmpty(val))
                {
                    return(query);
                }

                var context      = (AuditTrailQueryContext)ctx;
                var clock        = context.ServiceProvider.GetRequiredService <IClock>();
                var localClock   = context.ServiceProvider.GetRequiredService <ILocalClock>();
                var userTimeZone = await localClock.GetLocalTimeZoneAsync();
                var parseContext = new DateTimeParseContext(CultureInfo.CurrentUICulture, clock, userTimeZone, new Scanner(val));

                if (DateTimeParser.Parser.TryParse(parseContext, out var expression, out var parseError))
                {
                    var utcNow = clock.UtcNow;

                    var param             = Expression.Parameter(typeof(AuditTrailEventIndex));
                    var field             = Expression.Property(param, nameof(AuditTrailEventIndex.CreatedUtc));
                    var expressionContext = new BuildExpressionContext(utcNow, param, field, typeof(Func <AuditTrailEventIndex, bool>));

                    query.With <AuditTrailEventIndex>((Expression <Func <AuditTrailEventIndex, bool> >)expression.BuildExpression(expressionContext));
                }

                return(query);
            })
                           .MapTo <AuditTrailIndexOptions>((val, model) =>
            {
                model.Date = val;
            })
                           .MapFrom <AuditTrailIndexOptions>((model) =>
            {
                if (!String.IsNullOrEmpty(model.Date))
                {
                    return(true, model.Date);
                }
                return(false, String.Empty);
            })
                           )
            .WithNamedTerm("sort", builder => builder
                           .OneCondition((val, query, ctx) =>
            {
                var context = (AuditTrailQueryContext)ctx;
                var options = context.ServiceProvider.GetRequiredService <IOptions <AuditTrailAdminListOptions> >().Value;

                if (options.SortOptions.TryGetValue(val, out var sortOption))
                {
                    return(sortOption.Query(val, query, ctx));
                }

                return(options.DefaultSortOption.Query(val, query, ctx));
            })
                           .MapTo <AuditTrailIndexOptions>((val, model) =>
            {
                // TODO add a context property to the mapping func.
                if (!String.IsNullOrEmpty(val) && _options.Value.SortOptions.TryGetValue(val, out var sortOption))
                {
                    model.Sort = sortOption.Value;
                }
            })
                           .MapFrom <AuditTrailIndexOptions>((model) =>
            {
                // TODO add a context property to the mapping func.
                if (model.Sort != _options.Value.DefaultSortOption.Value)
                {
                    return(true, model.Sort);
                }

                return(false, String.Empty);
            })
                           .AlwaysRun()
                           )
            .WithDefaultTerm("username", builder => builder
                             .ManyCondition(
                                 (val, query, ctx) =>
            {
                var context            = (AuditTrailQueryContext)ctx;
                var lookupNormalizer   = context.ServiceProvider.GetRequiredService <ILookupNormalizer>();
                var normalizedUserName = lookupNormalizer.NormalizeName(val);
                query.With <AuditTrailEventIndex>(x => x.NormalizedUserName.Contains(normalizedUserName));

                return(new ValueTask <IQuery <AuditTrailEvent> >(query));
            },
                                 (val, query, ctx) =>
            {
                var context            = (AuditTrailQueryContext)ctx;
                var lookupNormalizer   = context.ServiceProvider.GetRequiredService <ILookupNormalizer>();
                var normalizedUserName = lookupNormalizer.NormalizeName(val);
                query.With <AuditTrailEventIndex>(x => x.NormalizedUserName.NotContains(normalizedUserName));

                return(new ValueTask <IQuery <AuditTrailEvent> >(query));
            }
                                 )
                             )
            .WithNamedTerm("userid", builder => builder
                           .ManyCondition(
                               (val, query) =>
            {
                query.With <AuditTrailEventIndex>(x => x.UserId.Contains(val));

                return(query);
            },
                               (val, query) =>
            {
                query.With <AuditTrailEventIndex>(x => x.UserId.NotContains(val));

                return(query);
            }
                               )
                           );
        }
Exemple #3
0
        public void Build(QueryEngineBuilder <ContentItem> builder)
        {
            builder
            .WithNamedTerm("status", builder => builder
                           .OneCondition <ContentItem>((val, query, ctx) =>
            {
                var context = (ContentQueryContext)ctx;
                if (Enum.TryParse <ContentsStatus>(val, true, out var contentsStatus))
                {
                    switch (contentsStatus)
                    {
                    case ContentsStatus.Draft:
                        query.With <ContentItemIndex>(x => x.Latest && !x.Published);
                        break;

                    case ContentsStatus.Published:
                        query.With <ContentItemIndex>(x => x.Published);
                        break;

                    case ContentsStatus.Owner:
                        var httpContextAccessor = context.ServiceProvider.GetRequiredService <IHttpContextAccessor>();
                        var userNameIdentifier  = httpContextAccessor.HttpContext.User?.FindFirstValue(ClaimTypes.NameIdentifier);
                        query.With <ContentItemIndex>(x => x.Owner == userNameIdentifier && x.Latest);
                        break;

                    case ContentsStatus.AllVersions:
                        query.With <ContentItemIndex>(x => x.Latest);
                        break;

                    default:
                        query.With <ContentItemIndex>(x => x.Latest);
                        break;
                    }
                }
                else
                {
                    // Draft is the default value.
                    query.With <ContentItemIndex>(x => x.Latest);
                }

                return(new ValueTask <IQuery <ContentItem> >(query));
            })
                           .MapTo <ContentOptionsViewModel>((val, model) =>
            {
                if (Enum.TryParse <ContentsStatus>(val, true, out var contentsStatus))
                {
                    model.ContentsStatus = contentsStatus;
                }
            })
                           .MapFrom <ContentOptionsViewModel>((model) =>
            {
                if (model.ContentsStatus != ContentsStatus.Latest)
                {
                    return(true, model.ContentsStatus.ToString());
                }

                return(false, String.Empty);
            })
                           .AlwaysRun()
                           )
            .WithNamedTerm("sort", builder => builder
                           .OneCondition <ContentItem>((val, query) =>
            {
                if (Enum.TryParse <ContentsOrder>(val, true, out var contentsOrder))
                {
                    switch (contentsOrder)
                    {
                    case ContentsOrder.Modified:
                        query.With <ContentItemIndex>().OrderByDescending(x => x.ModifiedUtc);
                        break;

                    case ContentsOrder.Published:
                        query.With <ContentItemIndex>().OrderByDescending(cr => cr.PublishedUtc);
                        break;

                    case ContentsOrder.Created:
                        query.With <ContentItemIndex>().OrderByDescending(cr => cr.CreatedUtc);
                        break;

                    case ContentsOrder.Title:
                        query.With <ContentItemIndex>().OrderBy(cr => cr.DisplayText);
                        break;
                    }
                    ;
                }
                else
                {
                    // Modified is a default value and applied when there is no filter.
                    query.With <ContentItemIndex>().OrderByDescending(x => x.ModifiedUtc);
                }

                return(query);
            })
                           .MapTo <ContentOptionsViewModel>((val, model) =>
            {
                if (Enum.TryParse <ContentsOrder>(val, true, out var contentsOrder))
                {
                    model.OrderBy = contentsOrder;
                }
            })
                           .MapFrom <ContentOptionsViewModel>((model) =>
            {
                if (model.OrderBy != ContentsOrder.Modified)
                {
                    return(true, model.OrderBy.ToString());
                }

                return(false, String.Empty);
            })
                           .AlwaysRun()
                           )
            .WithNamedTerm("type", builder => builder
                           .OneCondition <ContentItem>(async(contentType, query, ctx) =>
            {
                var context                  = (ContentQueryContext)ctx;
                var httpContextAccessor      = context.ServiceProvider.GetRequiredService <IHttpContextAccessor>();
                var authorizationService     = context.ServiceProvider.GetRequiredService <IAuthorizationService>();
                var contentManager           = context.ServiceProvider.GetRequiredService <IContentManager>();
                var contentDefinitionManager = context.ServiceProvider.GetRequiredService <IContentDefinitionManager>();
                var user = httpContextAccessor.HttpContext.User;
                var userNameIdentifier = user?.FindFirstValue(ClaimTypes.NameIdentifier);

                var canListAllContent = await authorizationService.AuthorizeAsync(user, Permissions.ListContent);

                // Filter for a specific type.
                if (!string.IsNullOrEmpty(contentType))
                {
                    var contentTypeDefinition = contentDefinitionManager.GetTypeDefinition(contentType);
                    if (contentTypeDefinition != null)
                    {
                        // We display a specific type even if it's not listable so that admin pages
                        // can reuse the Content list page for specific types.
                        var contentItem   = await contentManager.NewAsync(contentTypeDefinition.Name);
                        contentItem.Owner = userNameIdentifier;

                        var hasContentListPermission = await authorizationService.AuthorizeAsync(user, ContentTypePermissionsHelper.CreateDynamicPermission(ContentTypePermissionsHelper.PermissionTemplates[CommonPermissions.ListContent.Name], contentTypeDefinition), contentItem);
                        if (hasContentListPermission)
                        {
                            query.With <ContentItemIndex>(x => x.ContentType == contentType);
                        }
                        else
                        {
                            query.With <ContentItemIndex>(x => x.ContentType == contentType && x.Owner == userNameIdentifier);
                        }
                    }
                }
                else
                {
                    var listableTypes            = new List <ContentTypeDefinition>();
                    var authorizedContentTypes   = new List <ContentTypeDefinition>();
                    var unauthorizedContentTypes = new List <ContentTypeDefinition>();

                    foreach (var ctd in contentDefinitionManager.ListTypeDefinitions())
                    {
                        if (ctd.GetSettings <ContentTypeSettings>().Listable)
                        {
                            // We want to list the content item if the user can edit their own items at least.
                            // It might display content items the user won't be able to edit though.
                            var contentItem   = await contentManager.NewAsync(ctd.Name);
                            contentItem.Owner = userNameIdentifier;

                            var hasEditPermission = await authorizationService.AuthorizeAsync(user, CommonPermissions.EditContent, contentItem);
                            if (hasEditPermission)
                            {
                                listableTypes.Add(ctd);
                            }

                            if (!canListAllContent)
                            {
                                var hasContentListPermission = await authorizationService.AuthorizeAsync(user, ContentTypePermissionsHelper.CreateDynamicPermission(ContentTypePermissionsHelper.PermissionTemplates[CommonPermissions.ListContent.Name], ctd), contentItem);
                                if (hasContentListPermission)
                                {
                                    authorizedContentTypes.Add(ctd);
                                }
                                else
                                {
                                    unauthorizedContentTypes.Add(ctd);
                                }
                            }
                        }
                    }

                    if (authorizedContentTypes.Any() && !canListAllContent)
                    {
                        query.With <ContentItemIndex>().Where(x => (x.ContentType.IsIn(authorizedContentTypes.Select(t => t.Name).ToArray())) || (x.ContentType.IsIn(unauthorizedContentTypes.Select(t => t.Name).ToArray()) && x.Owner == userNameIdentifier));
                    }
                    else
                    {
                        query.With <ContentItemIndex>(x => x.ContentType.IsIn(listableTypes.Select(t => t.Name).ToArray()));

                        // If we set the ListContent permission
                        // to false we can only view our own content and
                        // we bypass and force the corresponding ContentsStatus by owned content filtering
                        if (!canListAllContent)
                        {
                            query.With <ContentItemIndex>(x => x.Owner == userNameIdentifier);
                        }
                    }
                }

                return(query);
            })
                           .MapTo <ContentOptionsViewModel>((val, model) =>
            {
                if (!String.IsNullOrEmpty(val))
                {
                    model.SelectedContentType = val;
                }
            })
                           .MapFrom <ContentOptionsViewModel>((model) =>
            {
                if (!String.IsNullOrEmpty(model.SelectedContentType))
                {
                    return(true, model.SelectedContentType);
                }

                return(false, String.Empty);
            })
                           .AlwaysRun()
                           )
            .WithDefaultTerm("text", builder => builder
                             .ManyCondition <ContentItem>(
                                 ((val, query) => query.With <ContentItemIndex>(x => x.DisplayText.Contains(val))),
                                 ((val, query) => query.With <ContentItemIndex>(x => x.DisplayText.IsNotIn <ContentItemIndex>(s => s.DisplayText, w => w.DisplayText.Contains(val))))
                                 )
                             );
        }