├── .gitignore ├── LICENSE ├── README.md ├── doc └── img │ └── iii.png └── src ├── .nuget ├── NuGet.Config ├── NuGet.exe └── NuGet.targets ├── ClientResources ├── Scripts │ ├── InspectInIndexInitializer.js │ └── InspectInIndexView.js ├── Styles │ └── Iiistyles.css └── img │ └── iiiicon.png ├── Constants.cs ├── CopyZipFiles.targets ├── EPiCode.InspectInIndex.csproj ├── EPiCode.InspectInIndex.csproj.user ├── EPiCode.InspectInIndex.sln ├── InspectInIndexStore.cs ├── InspectInIndexViewConfiguration.cs ├── Properties └── AssemblyInfo.cs ├── ServiceCollectionExtensions.cs ├── module.config └── msbuild └── Main.proj /.gitignore: -------------------------------------------------------------------------------- 1 | packages/ 2 | bin/ 3 | obj/ 4 | src/.vs/ 5 | src/modules/ 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2015-2020 BV Network AS 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Inspect In Index # 2 | A quick and easy way to inspect Optimizely content in the Optimizely Search and Navigation index, without having to use the Optimizely Search and Navigation Explore view. 3 | 4 | When installed, you may select a new view called Inspect In Index. This will show the current content's raw form in the EPiServer Find Index, with the options to index, re-index or delete content from the index. 5 | 6 | ![](https://raw.githubusercontent.com/BVNetwork/InspectInIndex/master/doc/img/iii.png) 7 | 8 | ## Installation ## 9 | Run the following command in the NuGet Package Manager Console for your web site: 10 | ``` 11 | install-package EPiCode.InspectInIndex 12 | ``` 13 | You need to add the Optimizely NuGet Feed to Visual Studio (see http://nuget.optimizely.com/en/Feed/) 14 | 15 | ## Configuration ## 16 | 17 | Add the Inspect In Index in the Startup.cs in the ConfigureServices method. Below is an example 18 | 19 | ``` 20 | public void ConfigureServices(IServiceCollection services) 21 | { 22 | ... 23 | 24 | services.AddInspectInIndex(); 25 | 26 | ... 27 | } 28 | ``` 29 | 30 | By default, only users with the "CmsAdmins" or "SearchAdmins" role will have access to the view. You may override this with your own authorization policy: 31 | 32 | ``` 33 | services.AddInspectInIndex(policy => 34 | { 35 | policy.RequireRole("MyRole"); 36 | }); 37 | ``` 38 | 39 | -------------------------------------------------------------------------------- /doc/img/iii.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BVNetwork/InspectInIndex/f893b2505aded4069f8be928391a9ce557fa719f/doc/img/iii.png -------------------------------------------------------------------------------- /src/.nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/.nuget/NuGet.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BVNetwork/InspectInIndex/f893b2505aded4069f8be928391a9ce557fa719f/src/.nuget/NuGet.exe -------------------------------------------------------------------------------- /src/.nuget/NuGet.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildProjectDirectory)\..\ 5 | 6 | 7 | false 8 | 9 | 10 | false 11 | 12 | 13 | true 14 | 15 | 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | $([System.IO.Path]::Combine($(SolutionDir), ".nuget")) 31 | 32 | 33 | 34 | 35 | $(SolutionDir).nuget 36 | 37 | 38 | 39 | $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName.Replace(' ', '_')).config 40 | $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName).config 41 | 42 | 43 | 44 | $(MSBuildProjectDirectory)\packages.config 45 | $(PackagesProjectConfig) 46 | 47 | 48 | 49 | 50 | $(NuGetToolsPath)\NuGet.exe 51 | @(PackageSource) 52 | 53 | "$(NuGetExePath)" 54 | mono --runtime=v4.0.30319 $(NuGetExePath) 55 | 56 | $(TargetDir.Trim('\\')) 57 | 58 | -RequireConsent 59 | -NonInteractive 60 | 61 | "$(SolutionDir) " 62 | "$(SolutionDir)" 63 | 64 | 65 | $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir) 66 | $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols 67 | 68 | 69 | 70 | RestorePackages; 71 | $(BuildDependsOn); 72 | 73 | 74 | 75 | 76 | $(BuildDependsOn); 77 | BuildPackage; 78 | 79 | 80 | 81 | 82 | 83 | 84 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 99 | 100 | 103 | 104 | 105 | 106 | 108 | 109 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 141 | 142 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /src/ClientResources/Scripts/InspectInIndexInitializer.js: -------------------------------------------------------------------------------- 1 | define([ 2 | // Dojo 3 | "dojo", 4 | "dojo/_base/declare", 5 | //CMS 6 | "epi/_Module", 7 | "epi/dependency", 8 | "epi/routes" 9 | ], function ( 10 | // Dojo 11 | dojo, 12 | declare, 13 | //CMS 14 | _Module, 15 | dependency, 16 | routes 17 | ) { 18 | return declare([_Module], { 19 | initialize: function () { 20 | this.inherited(arguments); 21 | 22 | var registry = this.resolveDependency("epi.storeregistry"); 23 | //Register the store 24 | registry.create("inspectinindexstore", this._getRestPath("inspectinindexstore")); 25 | }, 26 | 27 | _getRestPath: function (name) { 28 | return routes.getRestPath({ moduleArea: "EPiCode.InspectInIndex", storeName: name }); 29 | } 30 | }); 31 | }); 32 | 33 | -------------------------------------------------------------------------------- /src/ClientResources/Scripts/InspectInIndexView.js: -------------------------------------------------------------------------------- 1 | define([ 2 | "dojo", 3 | "dojo/parser", 4 | "dojo/_base/declare", 5 | "dojo/json", 6 | 7 | "dijit", 8 | "dijit/_WidgetBase", 9 | "dijit/_TemplatedMixin", 10 | "dijit/form/Button", 11 | 12 | "epi-cms/_ContentContextMixin", 13 | "epi-cms/contentediting/StandardToolbar", 14 | "epi/dependency" 15 | ], 16 | 17 | function ( 18 | dojo, 19 | parser, 20 | declare, 21 | json, 22 | 23 | dijit, 24 | _WidgetBase, 25 | _TemplatedMixin, 26 | Button, 27 | 28 | _ContentContextMixin, 29 | StandardToolbar, 30 | dependency 31 | ) { 32 | 33 | return declare([_WidgetBase, _TemplatedMixin, _ContentContextMixin], { 34 | templateString: '
' + 35 | '
' + 36 | '' + 37 | '' + 38 | '
Loading...
', 39 | store: null, 40 | indexButton: null, 41 | postCreate: function () { 42 | this.inherited(arguments); 43 | this.toolbar = new StandardToolbar(); 44 | this.toolbar.placeAt(this.toolbarArea, "first"); 45 | this.store = dependency.resolve('epi.storeregistry').get('inspectinindexstore'); 46 | }, 47 | id: null, 48 | updateView: function (data, context) { 49 | this.findresult.innerHTML = "Loading..."; 50 | this.id = context.id; 51 | this.toolbar.update({ 52 | currentContext: context, 53 | viewConfigurations: { 54 | availableViews: data.availableViews, 55 | viewName: data.viewName 56 | } 57 | }); 58 | var that = this; 59 | 60 | dojo.when(that.store.get(context.id), function (indexId) { 61 | that._populate(indexId); 62 | }); 63 | Button({ 64 | label: "Delete", 65 | disabled: true, 66 | class: "epi-danger", 67 | iconClass: "epi-iconTrash epi-icon--inverted", 68 | onClick: function () { 69 | dojo.when(that.store.remove(that.id), function () { 70 | that.findresult.innerHTML = 'Deleted from index.'; 71 | dijit.byId("iiiDeleteButton").set("disabled", true); 72 | dijit.byId("iiiIndexButton").set("label", "Index"); 73 | }); 74 | } 75 | }, 76 | "iiiDeleteButton"); 77 | 78 | Button({ 79 | label: "Index", 80 | disabled: true, 81 | class: "epi-primary", 82 | iconClass: "epi-iconReload epi-icon--inverted", 83 | onClick: function () { 84 | that.findresult.innerHTML = "Loading..."; 85 | dojo.when(that.store.put({ 86 | "reference": that.id 87 | }), function (indexId) { 88 | that._populate(indexId); 89 | }); 90 | } 91 | }, 92 | "iiiIndexButton"); 93 | }, 94 | 95 | _populate: function (data) { 96 | var targetNode = this.findresult; 97 | var indexBtn = dijit.byId("iiiIndexButton"); 98 | var xhrArgs = { 99 | url: data.path, 100 | handleAs: "json", 101 | load: function (indexData) { 102 | //// Replace tabs with spaces. 103 | targetNode.innerHTML = json.stringify(indexData._source, null, 4); 104 | dijit.byId("iiiDeleteButton").set("disabled", false); 105 | 106 | indexBtn.set("disabled", false); 107 | indexBtn.set("label", "Reindex"); 108 | }, 109 | error: function (error) { 110 | if (error.status == 404) { 111 | indexBtn.set("disabled", false); 112 | indexBtn.set("label", "Index"); 113 | targetNode.innerHTML = "Content was not found in index."; 114 | } else { 115 | targetNode.innerHTML = "An unexpected error occurred: " + error; 116 | } 117 | } 118 | }; 119 | dojo.xhrGet(xhrArgs); 120 | } 121 | 122 | }); 123 | }); -------------------------------------------------------------------------------- /src/ClientResources/Styles/Iiistyles.css: -------------------------------------------------------------------------------- 1 | .iii-inspectindexview { 2 | height: 100%; 3 | } 4 | 5 | .iii-ButtonRow { 6 | margin-left: auto; 7 | margin-right: auto; 8 | text-align: center; 9 | margin-top: 10px; 10 | } 11 | 12 | .iii-findcontentView { 13 | width: 100%; 14 | height: 80%; 15 | overflow: visible; 16 | } 17 | 18 | .iii-icon { 19 | background: url("../img/iiiicon.png") rgba(0, 0, 0, 0); 20 | height: 24px; 21 | width: 24px; 22 | } 23 | 24 | .iii-findcontentView pre { 25 | margin: 40px; 26 | margin-top: 10px; 27 | word-break: break-word; 28 | font: 1em 'andale mono','lucida console',monospace; 29 | line-height: 1.5; 30 | background-color: #efefef; 31 | border: 1px solid #ccc; 32 | overflow: scroll; 33 | height: 100%; 34 | overflow-x: hidden; 35 | } 36 | -------------------------------------------------------------------------------- /src/ClientResources/img/iiiicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BVNetwork/InspectInIndex/f893b2505aded4069f8be928391a9ce557fa719f/src/ClientResources/img/iiiicon.png -------------------------------------------------------------------------------- /src/Constants.cs: -------------------------------------------------------------------------------- 1 | namespace EPiCode.InspectInIndex 2 | { 3 | public static class Constants 4 | { 5 | public const string PolicyName = "epicode:inspectinindex"; 6 | } 7 | } -------------------------------------------------------------------------------- /src/CopyZipFiles.targets: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /src/EPiCode.InspectInIndex.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | Library 4 | .\ 5 | true 6 | true 7 | 2.0.0.0 8 | 2.0.0 9 | EPiCode.InspectInIndex 10 | Per Magne Skuseth, Haakon Peder Haugsten 11 | BV Network AS 12 | 13 | 14 | net6.0 15 | false 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | false 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/EPiCode.InspectInIndex.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | ShowAllFiles 5 | IIS Express 6 | 7 | -------------------------------------------------------------------------------- /src/EPiCode.InspectInIndex.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.0.32112.339 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EPiCode.InspectInIndex", "EPiCode.InspectInIndex.csproj", "{1EE44FC0-F6A1-443B-B965-D2F924D67E6A}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {1EE44FC0-F6A1-443B-B965-D2F924D67E6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {1EE44FC0-F6A1-443B-B965-D2F924D67E6A}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {1EE44FC0-F6A1-443B-B965-D2F924D67E6A}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {1EE44FC0-F6A1-443B-B965-D2F924D67E6A}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {12FE651F-510A-42D5-82B6-93A2A3A9F4C7} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/InspectInIndexStore.cs: -------------------------------------------------------------------------------- 1 | using EPiServer; 2 | using EPiServer.Core; 3 | using EPiServer.Find.Api; 4 | using EPiServer.Find.Cms; 5 | using EPiServer.Find.UI; 6 | using EPiServer.Find.UI.Helpers; 7 | using EPiServer.Framework; 8 | using EPiServer.Shell.Services.Rest; 9 | using Microsoft.AspNetCore.Mvc; 10 | using Microsoft.Extensions.Options; 11 | 12 | namespace EPiCode.InspectInIndex 13 | { 14 | [RestStore("inspectinindexstore")] 15 | public class InspectInIndexStore : RestControllerBase 16 | { 17 | private readonly IContentLoader _contentLoader; 18 | private readonly IContentIndexer _contentIndexer; 19 | private readonly IPathHelper _pathHelper; 20 | private readonly IOptionsMonitor _findUiOptions; 21 | private readonly LanguageRoutingFactory _languageRoutingFactory; 22 | 23 | public InspectInIndexStore(IContentLoader contentLoader, IContentIndexer contentIndexer, IPathHelper pathHelper, IOptionsMonitor findUiOptions, LanguageRoutingFactory languageRoutingFactory) 24 | { 25 | _contentLoader = contentLoader; 26 | _contentIndexer = contentIndexer; 27 | _pathHelper = pathHelper; 28 | _findUiOptions = findUiOptions; 29 | _languageRoutingFactory = languageRoutingFactory; 30 | } 31 | 32 | [HttpGet] 33 | public ActionResult Get(ContentReference id) 34 | { 35 | var content = _contentLoader.Get(id); 36 | var rest = Rest(new { path = GetIndexContentPath(content) }); 37 | return rest; 38 | } 39 | 40 | [HttpPost] 41 | public ActionResult Post([FromBody] IndexInputModel inputModel) 42 | { 43 | Validator.ThrowIfNull("inputModel", inputModel); 44 | Validator.ThrowIfNull("reference", inputModel.Reference); 45 | 46 | var contentReference = ContentReference.Parse(inputModel.Reference); 47 | 48 | var content = _contentLoader.Get(contentReference); 49 | _contentIndexer.Index(content); 50 | 51 | var rest = Rest(new { path = GetIndexContentPath(content) }); 52 | return rest; 53 | } 54 | 55 | public ActionResult Delete(ContentReference id) 56 | { 57 | var content = _contentLoader.Get(id); 58 | _contentIndexer.Delete(content); 59 | 60 | return Json(""); 61 | } 62 | 63 | private string GetIndexContentPath(IContent content) 64 | { 65 | string findProxyPath = _pathHelper.EnsureTrailingSlash(_pathHelper.GetPathInModule(_findUiOptions.CurrentValue.AdminProxyPath)); 66 | return findProxyPath + GetTypeAndIndexId(content) + GetLanguageRoutingParameter(content); 67 | } 68 | 69 | private string GetTypeAndIndexId(IContent content) 70 | { 71 | var type = content.GetOriginalType().FullName.Replace('.', '_'); 72 | var indexId = content.GetIndexId(); 73 | return type + '/' + indexId; 74 | } 75 | 76 | private string GetLanguageRoutingParameter(IContent content) 77 | { 78 | var languageRouting = GetLanguageRouting(content); 79 | 80 | if (languageRouting != null) 81 | { 82 | return $"?language_routing={languageRouting.FieldSuffix}"; 83 | } 84 | 85 | return string.Empty; 86 | } 87 | 88 | private LanguageRouting GetLanguageRouting(IContent content) 89 | { 90 | var locale = content as ILocale; 91 | 92 | if (locale == null) 93 | { 94 | return null; 95 | } 96 | 97 | return _languageRoutingFactory.CreateLanguageRouting(locale); 98 | } 99 | } 100 | 101 | public class IndexInputModel 102 | { 103 | public string Reference { get; set; } 104 | } 105 | } -------------------------------------------------------------------------------- /src/InspectInIndexViewConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System.Security.Claims; 2 | using EPiServer.Core; 3 | using EPiServer.Security; 4 | using EPiServer.ServiceLocation; 5 | using EPiServer.Shell; 6 | using Microsoft.AspNetCore.Authorization; 7 | 8 | namespace EPiCode.InspectInIndex 9 | { 10 | [ServiceConfiguration(typeof(ViewConfiguration))] 11 | public class InspectInIndexViewConfiguration : ViewConfiguration 12 | { 13 | private readonly IAuthorizationService _authorizationService; 14 | private readonly IPrincipalAccessor _principalAccessor; 15 | 16 | public InspectInIndexViewConfiguration(IAuthorizationService authorizationService, IPrincipalAccessor principalAccessor) : base() 17 | { 18 | _authorizationService = authorizationService; 19 | _principalAccessor = principalAccessor; 20 | 21 | Key = "InspectInIndex"; 22 | Name = "Inspect in index"; 23 | Description = "Show content in Find index"; 24 | IconClass = "iii-icon"; 25 | ControllerType = "inspectinindex/InspectInIndexView"; 26 | } 27 | 28 | public override bool HideFromViewMenu 29 | { 30 | get 31 | { 32 | if(_principalAccessor.Principal is ClaimsPrincipal principal) 33 | { 34 | var result = _authorizationService.AuthorizeAsync(principal, Constants.PolicyName).Result; 35 | return result.Succeeded == false; 36 | } 37 | 38 | return true; 39 | } 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /src/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("EPiCode.InspectInIndex")] 9 | [assembly: AssemblyDescription("Adds a new EPiServer view which will allow you to easily inspect the selected content in the EPiServer Find index")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("BV Network AS")] 12 | [assembly: AssemblyProduct("EPiCode.InspectInIndex")] 13 | [assembly: AssemblyCopyright("Copyright © 2020")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("02540dc3-d438-4c6a-b598-4ed3dd20a70c")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("2.0.0")] 36 | [assembly: AssemblyFileVersion("2.0.0")] 37 | -------------------------------------------------------------------------------- /src/ServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using EPiServer.Shell.Modules; 4 | using Microsoft.AspNetCore.Authorization; 5 | using Microsoft.Extensions.DependencyInjection; 6 | 7 | namespace EPiCode.InspectInIndex 8 | { 9 | public static class ServiceCollectionExtensions 10 | { 11 | private static readonly Action DefaultPolicy = p => p.RequireRole("Administrators","CmsAdmins", "WebAdmins"); 12 | 13 | public static IServiceCollection AddInspectInIndex( 14 | this IServiceCollection services) 15 | { 16 | return services.AddInspectInIndex(DefaultPolicy); 17 | } 18 | 19 | public static IServiceCollection AddInspectInIndex( 20 | this IServiceCollection services, Action configurePolicy) 21 | { 22 | services.Configure( 23 | pm => 24 | { 25 | if (!pm.Items.Any(i => i.Name.Equals("EPiCode.InspectInIndex", StringComparison.OrdinalIgnoreCase))) 26 | { 27 | pm.Items.Add(new ModuleDetails { Name = "EPiCode.InspectInIndex" }); 28 | } 29 | }); 30 | 31 | services.AddAuthorization(options => 32 | { 33 | options.AddPolicy(Constants.PolicyName, configurePolicy); 34 | }); 35 | 36 | return services; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/module.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/msbuild/Main.proj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 21 | 22 | 23 | 24 | 25 | $(MSBuildProjectDirectory)\..\ 26 | $(SolutionDir)\tmp 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | true 59 | content\modules\_protected\$(MSBuildProjectName)\;contentFiles\any\any\modules\_protected\$(MSBuildProjectName)\ 60 | None 61 | true 62 | 63 | 64 | true 65 | build\net5.0\$(MSBuildProjectName).targets 66 | 67 | 68 | --------------------------------------------------------------------------------