public void OrderOfDefaultTermShouldNotMatter() { var parser1 = new QueryEngineBuilder <Person>() .WithNamedTerm("age", b => b.OneCondition(PersonOneConditionQuery())) .WithDefaultTerm("name", b => b.ManyCondition(PersonManyMatch(), PersonManyNotMatch())) .Build(); var parser2 = new QueryEngineBuilder <Person>() .WithDefaultTerm("name", b => b.ManyCondition(PersonManyMatch(), PersonManyNotMatch())) .WithNamedTerm("age", b => b.OneCondition(PersonOneConditionQuery())) .Build(); Assert.Equal("steve age:20", parser1.Parse("steve age:20").ToString()); var result = parser1.Parse("steve age:20"); Assert.Equal(2, result.Count()); Assert.Equal("age:20 steve", parser1.Parse("age:20 steve").ToString()); Assert.Equal(2, parser1.Parse("age:20 steve").Count()); Assert.Equal("steve age:20", parser2.Parse("steve age:20").ToString()); Assert.Equal(2, parser2.Parse("steve age:20").Count()); Assert.Equal("age:20 steve", parser2.Parse("age:20 steve").ToString()); Assert.Equal(2, parser2.Parse("age:20 steve").Count()); }
public void ShouldParseDefaultTermAtEndOfStatementWithBuilder() { var parser = new QueryEngineBuilder <Person>() .WithNamedTerm("age", builder => builder .OneCondition((val, query) => { if (Int32.TryParse(val, out var age)) { query.With <PersonByAge>(x => x.Age == age); } return(query); }) ) .WithDefaultTerm("name", builder => builder.OneCondition(PersonOneConditionQuery()) ) .Build(); Assert.Equal("age:20 name:steve", parser.Parse("age:20 name:steve").ToString()); Assert.Equal(2, parser.Parse("age:20 name:steve").Count()); Assert.Equal("age:20 steve", parser.Parse("age:20 steve").ToString()); Assert.Equal(2, parser.Parse("age:20 steve").Count()); }
public void ShouldParseTermWithLocalizedChars() { var parser = new QueryEngineBuilder <Person>() .WithNamedTerm("name", b => b.OneCondition(PersonOneConditionQuery())) .Build(); Assert.Equal("name:账单", parser.Parse("name:账单").ToString()); Assert.Equal("name:账单", parser.Parse("name:账单").ToNormalizedString()); }
public void ShouldParseManyNamedTerms() { var parser = new QueryEngineBuilder <Person>() .WithNamedTerm("name", b => b.OneCondition(PersonOneConditionQuery())) .WithNamedTerm("status", b => b.OneCondition(PersonOneConditionQuery())) .Build(); Assert.Equal("name:steve status:published", parser.Parse("name:steve status:published").ToString()); Assert.Equal("name:steve status:published", parser.Parse("name:steve status:published").ToNormalizedString()); }
public void ShouldIncludeExtraChars(string search) { var parser = new QueryEngineBuilder <Person>() .WithNamedTerm("extrachar", b => b.OneCondition(PersonOneConditionQuery())) .Build(); var result = parser.Parse(search); Assert.Equal(search, result.ToString()); }
public void SelectDefaultWhenNoItemWithHighestScoreFound() { var result = new QueryEngineBuilder().Get(new[] { QueriableItem.Create(new DefaultValueProvider(1),new IFilterCondition[]{new TextMatchCondition("env",null)}), QueriableItem.Create(new DefaultValueProvider(2),new IFilterCondition[]{}), }, false).Query(new Dictionary<string, string>()); Assert.AreEqual(1, result.Length); Assert.AreEqual(2, result.Single().Get()); }
public void ShouldNotIncludeExtraWhitespace(string search) { var parser = new QueryEngineBuilder <Article>() .WithNamedTerm("title", b => b.ManyCondition(ArticleManyMatch(), ArticleManyNotMatch())) .Build(); var result = parser.Parse(search); Assert.Equal(search, result.ToString()); }
public void ShouldIgnoreMultipleNamedTerms() { var parser = new QueryEngineBuilder <Person>() .WithNamedTerm("name", b => b.OneCondition(PersonOneConditionQuery())) .Build(); // By convention the last term is used when single = true; Assert.Equal("name:bill", parser.Parse("name:steve name:bill").ToString()); Assert.Equal("name:bill", parser.Parse("name:steve name:bill").ToNormalizedString()); }
public void Complex(string search, string normalized) { var parser = new QueryEngineBuilder <Article>() .WithNamedTerm("title", b => b.ManyCondition(ArticleManyMatch(), ArticleManyNotMatch())) .Build(); var result = parser.Parse(search); Assert.Equal(normalized, result.ToNormalizedString()); }
public void ShouldParseDefaultTermWithManyConditionWhenLast() { var parser = new QueryEngineBuilder <Person>() .WithNamedTerm("status", b => b.ManyCondition(PersonManyMatch(), PersonManyNotMatch())) .WithDefaultTerm("name", b => b.ManyCondition(PersonManyMatch(), PersonManyNotMatch())) .Build(); Assert.Equal("steve status:published", parser.Parse("steve status:published").ToString()); Assert.Equal("name:steve status:published", parser.Parse("steve status:published").ToNormalizedString()); }
public void ShouldParseDefaultTermWithManyConditionWhenDefaultIsFirst() { // TODO Validation on builder if you have two manys. you cannot have a default. var parser = new QueryEngineBuilder <Person>() .WithDefaultTerm("name", b => b.ManyCondition(PersonManyMatch(), PersonManyNotMatch())) .WithNamedTerm("status", b => b.ManyCondition(PersonManyMatch(), PersonManyNotMatch())) .Build(); Assert.Equal("status:(published OR steve)", parser.Parse("status:published steve").ToNormalizedString()); }
public void ShouldParseNamedTermWhenQuoted() { var parser = new QueryEngineBuilder <Person>() .WithNamedTerm("name", b => b.OneCondition(PersonOneConditionQuery())) .Build(); Assert.Equal("name:\"steve balmer\"", parser.Parse("name:\"steve balmer\"").ToString()); Assert.Equal("name:\"steve balmer\"", parser.Parse("name:\"steve balmer\"").ToNormalizedString()); Assert.Equal("name:'steve balmer'", parser.Parse("name:'steve balmer'").ToString()); Assert.Equal("name:'steve balmer'", parser.Parse("name:'steve balmer'").ToNormalizedString()); }
public void ShouldParseDefaultTerm() { var parser = new QueryEngineBuilder <Person>() .WithNamedTerm("age", b => b.OneCondition(PersonOneConditionQuery())) .WithDefaultTerm("name", b => b.OneCondition(PersonOneConditionQuery())) .Build(); Assert.Equal("name:steve", parser.Parse("name:steve").ToString()); Assert.Equal("steve", parser.Parse("steve").ToString()); Assert.Equal("steve age:20", parser.Parse("steve age:20").ToString()); Assert.Equal("age:20 name:steve", parser.Parse("age:20 name:steve").ToString()); Assert.Equal("age:20 steve", parser.Parse("age:20 steve").ToString()); Assert.Equal(2, parser.Parse("steve age:20").Count()); Assert.Equal("name:steve", parser.Parse("steve").ToNormalizedString()); }
public void EmptyResultWhenSingleMatchingItemIsNegated() { var context = new Dictionary<string, string> { {"A", "2"}, }; var result = new QueryEngineBuilder().Get(new[] { QueriableItem.Create(new DefaultValueProvider(1),new IFilterCondition[]{new TextMatchCondition("A","1",false)}), QueriableItem.Create(new DefaultValueProvider(2),new IFilterCondition[]{new TextMatchCondition("A","2",true)}), QueriableItem.Create(new DefaultValueProvider(3),new IFilterCondition[]{new TextMatchCondition("A","1",false)}), }, true) .Query(context).Select(x => x.Get()).Cast<int>(); Assert.IsFalse(result.Any()); }
public void SelectSingleItemWhenOneItemHasOneSpecificReferenceAndTheOtherHasTwoSpecificReferences() { var context = new Dictionary<string, string> { {"A", "2"}, {"B", "2"}, }; var result = new QueryEngineBuilder().Get(new[] { QueriableItem.Create(new DefaultValueProvider(1),new IFilterCondition[]{new TextMatchCondition("A","2",false)}), QueriableItem.Create(new DefaultValueProvider(2),new IFilterCondition[]{new TextMatchCondition("B","2",false),new TextMatchCondition("A","2",false)}), }, false) .Query(context).Select(x => x.Get()).Cast<int>(); Assert.IsTrue(result.Count() == 1); Assert.IsTrue(result.Single() == 2); }
public void SelectSingleItemWhenOneMatchIsNegatedAndTheOtherWithoutAReference() { var context = new Dictionary<string, string> { {"A", "2"}, }; var result = new QueryEngineBuilder().Get(new[] { QueriableItem.Create(new DefaultValueProvider(1),new IFilterCondition[]{new TextMatchCondition("A","1",false)}), QueriableItem.Create(new DefaultValueProvider(2),new IFilterCondition[]{new TextMatchCondition("A","2",true)}), QueriableItem.Create(new DefaultValueProvider(3),new IFilterCondition[]{}), QueriableItem.Create(new DefaultValueProvider(4),new IFilterCondition[]{new TextMatchCondition("A","1",false)}), }, true) .Query(context).Select(x => x.Get()).Cast<int>(); Assert.IsTrue(result.Count() == 1); Assert.IsTrue(result.Any(x => x == 3)); }
public void when_value_is_negated_and_another_value_with_the_same_subject_is_also_negated() { var context = new Dictionary<string, string> { {"FamilyId", "40"}, {"CustomerId", "100"} }; var result = new QueryEngineBuilder().Get(new[] { QueriableItem.Create(new DefaultValueProvider(1),new IFilterCondition[] { new TextMatchCondition("FamilyId","40",true), new TextMatchCondition("FamilyId","81",true), new TextMatchCondition("FamilyId","80",true), new TextMatchCondition("CustomerId","7",true), new TextMatchCondition("CustomerId","12",true), new TextMatchCondition("CustomerId","19",true)}) }, false) .Query(context); Assert.AreEqual(0, result.Length); }
public void Build(QueryEngineBuilder <ContentItem> builder) { builder .WithNamedTerm("culture", builder => builder .OneCondition <ContentItem>((val, query) => { if (!String.IsNullOrEmpty(val)) { query.With <LocalizedContentItemIndex>(i => (i.Published || i.Latest) && i.Culture == val); } return(query); }) .MapTo <LocalizationContentsAdminFilterViewModel>((val, model) => model.SelectedCulture = val) .MapFrom <LocalizationContentsAdminFilterViewModel>((model) => { if (!String.IsNullOrEmpty(model.SelectedCulture)) { return(true, model.SelectedCulture); } return(false, String.Empty); }) ); }
public void with_two_items_while_one_is_with_one_true_condition_and_the_other_with_one_true_and_the_other_negated_true() { var context = new Dictionary<string, string> { {"subject1", "a"}, {"subject2", "c"} }; var result = new QueryEngineBuilder().Get(new[] { QueriableItem.Create(new DefaultValueProvider(1),new IFilterCondition[]{new TextMatchCondition("subject1","a")}), QueriableItem.Create(new DefaultValueProvider(2),new IFilterCondition[]{new TextMatchCondition("subject1","a"), new TextMatchCondition("subject2","b",true)}), }, false) .Query(context); Assert.AreEqual(1, result.Length); Assert.AreEqual(2, result.Single().Get()); }
public override void ConfigureServices(IServiceCollection services) { services.Configure <UserOptions>(userOptions => { var configuration = ShellScope.Services.GetRequiredService <IShellConfiguration>(); configuration.GetSection("OrchardCore_Users").Bind(userOptions); }); // Add ILookupNormalizer as Singleton because it is needed by UserIndexProvider services.TryAddSingleton <ILookupNormalizer, UpperInvariantLookupNormalizer>(); // Adds the default token providers used to generate tokens for reset passwords, change email // and change telephone number operations, and for two factor authentication token generation. services.AddIdentity <IUser, IRole>(options => { // Specify OrchardCore User requirements. // A user name cannot include an @ symbol, i.e. be an email address // An email address must be provided, and be unique. options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._+"; options.User.RequireUniqueEmail = true; }) .AddDefaultTokenProviders(); // Configure the authentication options to use the application cookie scheme as the default sign-out handler. // This is required for security modules like the OpenID module (that uses SignOutAsync()) to work correctly. services.AddAuthentication(options => options.DefaultSignOutScheme = IdentityConstants.ApplicationScheme); services.TryAddScoped <UserStore>(); services.TryAddScoped <IUserStore <IUser> >(sp => sp.GetRequiredService <UserStore>()); services.TryAddScoped <IUserRoleStore <IUser> >(sp => sp.GetRequiredService <UserStore>()); services.TryAddScoped <IUserPasswordStore <IUser> >(sp => sp.GetRequiredService <UserStore>()); services.TryAddScoped <IUserEmailStore <IUser> >(sp => sp.GetRequiredService <UserStore>()); services.TryAddScoped <IUserSecurityStampStore <IUser> >(sp => sp.GetRequiredService <UserStore>()); services.TryAddScoped <IUserLoginStore <IUser> >(sp => sp.GetRequiredService <UserStore>()); services.TryAddScoped <IUserClaimStore <IUser> >(sp => sp.GetRequiredService <UserStore>()); services.TryAddScoped <IUserAuthenticationTokenStore <IUser> >(sp => sp.GetRequiredService <UserStore>()); services.ConfigureApplicationCookie(options => { var userOptions = ShellScope.Services.GetRequiredService <IOptions <UserOptions> >(); options.Cookie.Name = "orchauth_" + HttpUtility.UrlEncode(_tenantName); // Don't set the cookie builder 'Path' so that it uses the 'IAuthenticationFeature' value // set by the pipeline and comming from the request 'PathBase' which already ends with the // tenant prefix but may also start by a path related e.g to a virtual folder. options.LoginPath = "/" + userOptions.Value.LoginPath; options.LogoutPath = "/" + userOptions.Value.LogoffPath; options.AccessDeniedPath = "/Error/403"; }); services.AddSingleton <IIndexProvider, UserIndexProvider>(); services.AddSingleton <IIndexProvider, UserByRoleNameIndexProvider>(); services.AddSingleton <IIndexProvider, UserByLoginInfoIndexProvider>(); services.AddSingleton <IIndexProvider, UserByClaimIndexProvider>(); services.AddScoped <IDataMigration, Migrations>(); services.AddScoped <IUserService, UserService>(); services.AddScoped <IUserClaimsPrincipalFactory <IUser>, DefaultUserClaimsPrincipalProviderFactory>(); services.AddScoped <IUserClaimsProvider, EmailClaimsProvider>(); services.AddSingleton <IUserIdGenerator, DefaultUserIdGenerator>(); services.AddScoped <IAuthorizationHandler, UserAuthorizationHandler>(); services.AddScoped <IMembershipService, MembershipService>(); services.AddScoped <ISetupEventHandler, SetupEventHandler>(); services.AddScoped <ICommandHandler, UserCommands>(); services.AddScoped <IRoleRemovedEventHandler, UserRoleRemovedEventHandler>(); services.AddScoped <IExternalLoginEventHandler, ScriptExternalLoginEventHandler>(); services.AddScoped <IPermissionProvider, Permissions>(); services.AddScoped <INavigationProvider, AdminMenu>(); services.AddScoped <IDisplayDriver <ISite>, LoginSettingsDisplayDriver>(); services.AddScoped <IDisplayDriver <User>, UserDisplayDriver>(); services.AddScoped <IDisplayDriver <User>, UserRoleDisplayDriver>(); services.AddScoped <IDisplayDriver <User>, UserInformationDisplayDriver>(); services.AddScoped <IDisplayDriver <User>, UserButtonsDisplayDriver>(); services.AddScoped <IThemeSelector, UsersThemeSelector>(); services.AddScoped <IRecipeEnvironmentProvider, RecipeEnvironmentSuperUserProvider>(); services.AddScoped <IUsersAdminListQueryService, DefaultUsersAdminListQueryService>(); services.AddScoped <IDisplayDriver <UserIndexOptions>, UserOptionsDisplayDriver>(); services.AddSingleton <IUsersAdminListFilterParser>(sp => { var filterProviders = sp.GetServices <IUsersAdminListFilterProvider>(); var builder = new QueryEngineBuilder <User>(); foreach (var provider in filterProviders) { provider.Build(builder); } var parser = builder.Build(); return(new DefaultUsersAdminListFilterParser(parser)); }); services.AddTransient <IUsersAdminListFilterProvider, DefaultUsersAdminListFilterProvider>(); services.AddScoped <IUserEventHandler, UserDisabledEventHandler>(); }
public void when_there_are_items_with_conflicting_highest_score_and_a_default_item_could_not_be_determined_throw() { var context = new Dictionary<string, string> { {"B", "3"}, }; var result = new QueryEngineBuilder().Get(new[] { QueriableItem.Create(new DefaultValueProvider(2),new IFilterCondition[]{new TextMatchCondition("A","3",true)}), QueriableItem.Create(new DefaultValueProvider(2),new IFilterCondition[]{new TextMatchCondition("A","5",false)}), }, false) .Query(context).Select(x => x.Get()).Cast<int>(); }
public void when_two_negated_conditions_evaluates_to_true_select_them_over_the_default() { var context = new Dictionary<string, string> { {"B", "2"}, }; var result = new QueryEngineBuilder().Get(new[] { QueriableItem.Create(new DefaultValueProvider(1),new IFilterCondition[]{new TextMatchCondition("B","5",false)}), QueriableItem.Create(new DefaultValueProvider(2),new IFilterCondition[]{new TextMatchCondition("B","3",true),new TextMatchCondition("B","4",true)}), }, false) .Query(context).Select(x => x.Get()).Cast<int>(); Assert.AreEqual(1,result.Count()); Assert.IsTrue(result.Any(x => x == 2)); }
public void SelectTwoItemsWithReferences() { var context = new Dictionary<string, string> { {"A", "2"}, {"B", "2"}, }; var result = new QueryEngineBuilder().Get(new[] { QueriableItem.Create(new DefaultValueProvider(1),new IFilterCondition[]{new TextMatchCondition("A","1",false)}), QueriableItem.Create(new DefaultValueProvider(2),new IFilterCondition[]{new TextMatchCondition("A","2",false)}), QueriableItem.Create(new DefaultValueProvider(3),new IFilterCondition[]{new TextMatchCondition("A","2",false)}), QueriableItem.Create(new DefaultValueProvider(4),new IFilterCondition[]{new TextMatchCondition("A","1",false)}), }, true) .Query(context).Select(x => x.Get()).Cast<int>(); Assert.IsTrue(result.Any(x => x == 2)); Assert.IsTrue(result.Any(x => x == 3)); Assert.IsTrue(result.Count() == 2); }
public void when_an_Item_has_no_references_prefer_it_over_other_items_with_nutral_references() { var context = new Dictionary<string, string> { {"B", "3"}, }; var result = new QueryEngineBuilder().Get(new[] { QueriableItem.Create(new DefaultValueProvider(1),new IFilterCondition[]{}), QueriableItem.Create(new DefaultValueProvider(2),new IFilterCondition[]{new TextMatchCondition("A","3",true)}), QueriableItem.Create(new DefaultValueProvider(2),new IFilterCondition[]{new TextMatchCondition("A","5",false)}), }, false) .Query(context).Select(x => x.Get()).Cast<int>(); Assert.IsTrue(result.Count() == 1); Assert.IsTrue(result.Any(x => x == 1)); }
public void SelectSingleWhenValueHasTwoReferencesToSameSubjectAndOnlyOneMatch2() { var context = new Dictionary<string, string> { {"B", "3"}, }; var result = new QueryEngineBuilder().Get(new[] { QueriableItem.Create(new DefaultValueProvider(1),new IFilterCondition[]{new TextMatchCondition("A","3",false)}), QueriableItem.Create(new DefaultValueProvider(2),new IFilterCondition[]{new TextMatchCondition("B","3",false),new TextMatchCondition("B","4",false)}), }, false) .Query(context).Select(x => x.Get()).Cast<int>(); Assert.AreEqual(1, result.Count()); Assert.IsTrue(result.Single() == 2); }
public void SelectTwoItemsThatHasAMatchingReferenceToASubjectAndOneOfThemHasAlsoAReferenceToTheSameSubjectButWithDifferentValue() { var context = new Dictionary<string, string> { {"A", "2"}, {"B", "2"}, {"C", "2"}, {"D", "2"}, {"E", "2"}, }; var result = new QueryEngineBuilder().Get(new[] { QueriableItem.Create(new DefaultValueProvider(1),new IFilterCondition[]{new TextMatchCondition("A","1",false)}), QueriableItem.Create(new DefaultValueProvider(2),new IFilterCondition[]{new TextMatchCondition("B","2",false), new TextMatchCondition("A","1",false)}), QueriableItem.Create(new DefaultValueProvider(3),new IFilterCondition[]{new TextMatchCondition("A","2",false), new TextMatchCondition("A","1",false)}), }, true) .Query(context).Select(x => x.Get()).Cast<int>(); Assert.AreEqual(1, result.Count()); Assert.IsTrue(result.Any(x => x == 3)); }
public override void ConfigureServices(IServiceCollection services) { // Add ILookupNormalizer as Singleton because it is needed by Users services.TryAddSingleton <ILookupNormalizer, UpperInvariantLookupNormalizer>(); services.AddScoped <IAuditTrailManager, AuditTrailManager>(); services .AddScoped <IDisplayManager <AuditTrailEvent>, DisplayManager <AuditTrailEvent> >() .AddScoped <IDisplayDriver <AuditTrailEvent>, AuditTrailEventDisplayDriver>(); services.AddSingleton <IAuditTrailIdGenerator, AuditTrailIdGenerator>(); services.Configure <StoreCollectionOptions>(o => o.Collections.Add(AuditTrailEvent.Collection)); services.AddScoped <IDataMigration, Migrations>(); services.AddSingleton <IIndexProvider, AuditTrailEventIndexProvider>(); services.AddSingleton <IBackgroundTask, AuditTrailBackgroundTask>(); services.AddScoped <IPermissionProvider, Permissions>(); services.AddScoped <INavigationProvider, AuditTrailAdminMenu>(); services.AddScoped <INavigationProvider, AuditTrailSettingsAdminMenu>(); services.AddScoped <IDisplayDriver <ISite>, AuditTrailSettingsDisplayDriver>(); services.AddScoped <IDisplayDriver <ISite>, AuditTrailTrimmingSettingsDisplayDriver>(); services.AddScoped <IDisplayManager <AuditTrailIndexOptions>, DisplayManager <AuditTrailIndexOptions> >() .AddScoped <IDisplayDriver <AuditTrailIndexOptions>, AuditTrailOptionsDisplayDriver>(); services.AddScoped <IAuditTrailAdminListQueryService, DefaultAuditTrailAdminListQueryService>(); services.AddSingleton <IAuditTrailAdminListFilterParser>(sp => { var filterProviders = sp.GetServices <IAuditTrailAdminListFilterProvider>(); var builder = new QueryEngineBuilder <AuditTrailEvent>(); foreach (var provider in filterProviders) { provider.Build(builder); } var parser = builder.Build(); return(new DefaultAuditTrailAdminListFilterParser(parser)); }); services.AddTransient <IAuditTrailAdminListFilterProvider, DefaultAuditTrailAdminListFilterProvider>(); services.AddOptions <AuditTrailOptions>(); services.Configure <AuditTrailAdminListOptions>(options => { options .ForSort("time-desc", b => b .WithQuery((val, query) => query.With <AuditTrailEventIndex>().OrderByDescending(i => i.CreatedUtc)) .WithSelectListItem <Startup>((S, opt, model) => new SelectListItem(S["Newest"], opt.Value, model.Sort == String.Empty)) .AsDefault()) .ForSort("time-asc", b => b .WithQuery((val, query) => query.With <AuditTrailEventIndex>().OrderBy(i => i.CreatedUtc)) .WithSelectListItem <Startup>((S, opt, model) => new SelectListItem(S["Oldest"], opt.Value, model.Sort == opt.Value))) .ForSort("category-asc-time-desc", b => b .WithQuery((val, query) => query.With <AuditTrailEventIndex>().OrderBy(i => i.Category).ThenByDescending(i => i.CreatedUtc)) .WithSelectListItem <Startup>((S, opt, model) => new SelectListItem(S["Category"], opt.Value, model.Sort == opt.Value))) .ForSort("category-asc-time-asc", b => b .WithQuery((val, query) => query.With <AuditTrailEventIndex>().OrderBy(i => i.Category).ThenBy(i => i.CreatedUtc))) .ForSort("category-desc-time-desc", b => b .WithQuery((val, query) => query.With <AuditTrailEventIndex>().OrderByDescending(i => i.Category).ThenByDescending(i => i.CreatedUtc))) .ForSort("category-desc-time-asc", b => b .WithQuery((val, query) => query.With <AuditTrailEventIndex>().OrderByDescending(i => i.Category).ThenBy(i => i.CreatedUtc))) .ForSort("event-asc-time-desc", b => b .WithQuery((val, query) => query.With <AuditTrailEventIndex>().OrderBy(i => i.Name).ThenByDescending(i => i.CreatedUtc)) .WithSelectListItem <Startup>((S, opt, model) => new SelectListItem(S["Event"], opt.Value, model.Sort == opt.Value))) .ForSort("event-asc-time-asc", b => b .WithQuery((val, query) => query.With <AuditTrailEventIndex>().OrderBy(i => i.Name).ThenBy(i => i.CreatedUtc))) .ForSort("event-desc-time-desc", b => b .WithQuery((val, query) => query.With <AuditTrailEventIndex>().OrderByDescending(i => i.Name).ThenByDescending(i => i.CreatedUtc))) .ForSort("event-desc-time-asc", b => b .WithQuery((val, query) => query.With <AuditTrailEventIndex>().OrderByDescending(i => i.Name).ThenBy(i => i.CreatedUtc))) .ForSort("user-asc-time-asc", b => b .WithQuery((val, query) => query.With <AuditTrailEventIndex>().OrderBy(i => i.NormalizedUserName).ThenBy(i => i.CreatedUtc)) .WithSelectListItem <Startup>((S, opt, model) => new SelectListItem(S["User"], opt.Value, model.Sort == opt.Value))) .ForSort("user-desc-time-desc", b => b .WithQuery((val, query) => query.With <AuditTrailEventIndex>().OrderByDescending(i => i.NormalizedUserName).ThenByDescending(i => i.CreatedUtc))) .ForSort("user-desc-time-asc", b => b .WithQuery((val, query) => query.With <AuditTrailEventIndex>().OrderByDescending(i => i.NormalizedUserName).ThenBy(i => i.CreatedUtc))); }); }
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); } ) ); }
public override void ConfigureServices(IServiceCollection services) { services.AddSingleton <IAnchorTag, ContentAnchorTag>(); services.Configure <LiquidViewOptions>(o => { o.LiquidViewParserConfiguration.Add(parser => parser.RegisterParserTag("contentitem", parser.ArgumentsListParser, ContentItemTag.WriteToAsync)); }); services.Configure <TemplateOptions>(o => { o.MemberAccessStrategy.Register <ContentItem>(); o.MemberAccessStrategy.Register <ContentElement>(); o.MemberAccessStrategy.Register <ShapeViewModel <ContentItem> >(); o.MemberAccessStrategy.Register <ContentTypePartDefinition>(); o.MemberAccessStrategy.Register <ContentPartFieldDefinition>(); o.MemberAccessStrategy.Register <ContentFieldDefinition>(); o.MemberAccessStrategy.Register <ContentPartDefinition>(); o.Filters.AddFilter("display_text", DisplayTextFilter.DisplayText); o.Scope.SetValue("Content", new ObjectValue(new LiquidContentAccessor())); o.MemberAccessStrategy.Register <LiquidContentAccessor, LiquidPropertyAccessor>("ContentItemId", (obj, context) => { var liquidTemplateContext = (LiquidTemplateContext)context; return(new LiquidPropertyAccessor(liquidTemplateContext, async(contentItemId, context) => { var contentManager = context.Services.GetRequiredService <IContentManager>(); return FluidValue.Create(await contentManager.GetAsync(contentItemId), context.Options); })); }); o.MemberAccessStrategy.Register <LiquidContentAccessor, LiquidPropertyAccessor>("ContentItemVersionId", (obj, context) => { var liquidTemplateContext = (LiquidTemplateContext)context; return(new LiquidPropertyAccessor(liquidTemplateContext, async(contentItemVersionId, context) => { var contentManager = context.Services.GetRequiredService <IContentManager>(); return FluidValue.Create(await contentManager.GetVersionAsync(contentItemVersionId), context.Options); })); }); o.MemberAccessStrategy.Register <LiquidContentAccessor, LiquidPropertyAccessor>("Latest", (obj, context) => { var liquidTemplateContext = (LiquidTemplateContext)context; return(new LiquidPropertyAccessor(liquidTemplateContext, (name, context) => { return GetContentByHandleAsync(context, name, true); })); }); o.MemberAccessStrategy.Register <LiquidContentAccessor, FluidValue>((obj, name, context) => GetContentByHandleAsync((LiquidTemplateContext)context, name)); async Task <FluidValue> GetContentByHandleAsync(LiquidTemplateContext context, string handle, bool latest = false) { var contentHandleManager = context.Services.GetRequiredService <IContentHandleManager>(); var contentItemId = await contentHandleManager.GetContentItemIdAsync(handle); if (contentItemId == null) { return(NilValue.Instance); } var contentManager = context.Services.GetRequiredService <IContentManager>(); var contentItem = await contentManager.GetAsync(contentItemId, latest ? VersionOptions.Latest : VersionOptions.Published); return(FluidValue.Create(contentItem, context.Options)); } }) .AddLiquidFilter <DisplayUrlFilter>("display_url") .AddLiquidFilter <BuildDisplayFilter>("shape_build_display") .AddLiquidFilter <ContentItemFilter>("content_item_id") .AddLiquidFilter <FullTextFilter>("full_text"); services.AddContentManagement(); services.AddContentManagementDisplay(); services.AddScoped <IPermissionProvider, Permissions>(); services.AddScoped <IPermissionProvider, ContentTypePermissions>(); services.AddScoped <IAuthorizationHandler, ContentTypeAuthorizationHandler>(); services.AddScoped <IShapeTableProvider, Shapes>(); services.AddScoped <INavigationProvider, AdminMenu>(); services.AddScoped <IContentDisplayDriver, ContentsDriver>(); services.AddScoped <IContentHandler, ContentsHandler>(); services.AddRecipeExecutionStep <ContentStep>(); services.AddScoped <IContentItemIndexHandler, FullTextContentIndexHandler>(); services.AddScoped <IContentItemIndexHandler, AspectsContentIndexHandler>(); services.AddScoped <IContentItemIndexHandler, DefaultContentIndexHandler>(); services.AddScoped <IContentHandleProvider, ContentItemIdHandleProvider>(); services.AddScoped <IContentItemIndexHandler, ContentItemIndexCoordinator>(); services.AddScoped <IDataMigration, Migrations>(); // Common Part services.AddContentPart <CommonPart>() .UseDisplayDriver <DateEditorDriver>() .UseDisplayDriver <OwnerEditorDriver>(); services.AddScoped <IContentTypePartDefinitionDisplayDriver, CommonPartSettingsDisplayDriver>(); // FullTextAspect services.AddScoped <IContentTypeDefinitionDisplayDriver, FullTextAspectSettingsDisplayDriver>(); services.AddScoped <IContentHandler, FullTextAspectContentHandler>(); services.AddTagHelpers <ContentLinkTagHelper>(); services.AddTagHelpers <ContentItemTagHelper>(); services.Configure <AutorouteOptions>(options => { if (options.GlobalRouteValues.Count == 0) { options.GlobalRouteValues = new RouteValueDictionary { { "Area", "OrchardCore.Contents" }, { "Controller", "Item" }, { "Action", "Display" } }; options.ContentItemIdKey = "contentItemId"; options.ContainedContentItemIdKey = "containedContentItemId"; options.JsonPathKey = "jsonPath"; } }); services.AddScoped <IContentsAdminListQueryService, DefaultContentsAdminListQueryService>(); services.AddScoped <IDisplayDriver <ContentOptionsViewModel>, ContentOptionsDisplayDriver>(); services.AddScoped(typeof(IContentItemRecursionHelper <>), typeof(ContentItemRecursionHelper <>)); services.AddSingleton <IContentsAdminListFilterParser>(sp => { var filterProviders = sp.GetServices <IContentsAdminListFilterProvider>(); var builder = new QueryEngineBuilder <ContentItem>(); foreach (var provider in filterProviders) { provider.Build(builder); } var parser = builder.Build(); return(new DefaultContentsAdminListFilterParser(parser)); }); services.AddTransient <IContentsAdminListFilterProvider, DefaultContentsAdminListFilterProvider>(); }
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 <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)))) ) ); }