Files
Umbraco-CMS/src/Umbraco.Web/Editors/TourController.cs
Shannon c46d4e9e43 Merge remote-tracking branch 'origin/dev-v7' into dev-v8
# Conflicts:
#	src/SolutionInfo.cs
#	src/Umbraco.Core/Configuration/UmbracoVersion.cs
#	src/Umbraco.Core/Persistence/Migrations/MigrationRunner.cs
#	src/Umbraco.Core/Persistence/PetaPoco.cs
#	src/Umbraco.Core/Scoping/NoScope.cs
#	src/Umbraco.Core/Scoping/ScopeProvider.cs
#	src/Umbraco.Core/Services/ContentService.cs
#	src/Umbraco.Core/Services/IContentService.cs
#	src/Umbraco.Tests/Persistence/Migrations/MigrationStartupHandlerTests.cs
#	src/Umbraco.Tests/UI/LegacyDialogTests.cs
#	src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js
#	src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js
#	src/Umbraco.Web.UI/umbraco/config/create/UI.xml
#	src/Umbraco.Web.UI/umbraco/config/lang/zh.xml
#	src/Umbraco.Web/BatchedDatabaseServerMessenger.cs
#	src/Umbraco.Web/Editors/ContentController.cs
#	src/Umbraco.Web/Editors/MediaTypeController.cs
#	src/Umbraco.Web/HealthCheck/Checks/Security/ClickJackingCheck.cs
#	src/Umbraco.Web/HealthCheck/Checks/Security/ExcessiveHeadersCheck.cs
#	src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs
#	src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs
#	src/Umbraco.Web/Models/Mapping/ContentPropertyDisplayConverter.cs
#	src/Umbraco.Web/Models/Mapping/ContentPropertyDtoConverter.cs
#	src/Umbraco.Web/Models/Mapping/ContentPropertyModelMapper.cs
#	src/Umbraco.Web/PropertyEditors/NestedContentPropertyEditor.cs
#	src/Umbraco.Web/PropertyEditors/ParameterEditors/MultipleContentPickerParameterEditor.cs
#	src/Umbraco.Web/Trees/ContentTreeControllerBase.cs
#	src/Umbraco.Web/umbraco.presentation/umbraco/create/MemberGroupTasks.cs
2018-04-19 23:41:35 +10:00

153 lines
6.5 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using LightInject;
using Newtonsoft.Json;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Web.Models;
using Umbraco.Web.Mvc;
using Umbraco.Web.Tour;
namespace Umbraco.Web.Editors
{
[PluginController("UmbracoApi")]
public class TourController : UmbracoAuthorizedJsonController
{
public IEnumerable<BackOfficeTourFile> GetTours()
{
var result = new List<BackOfficeTourFile>();
if (UmbracoConfig.For.UmbracoSettings().BackOffice.Tours.EnableTours == false)
return result;
var filters = Current.Container.GetInstance<TourFilterCollection>().ToList(); // fixme inject
//get all filters that will be applied to all tour aliases
var aliasOnlyFilters = filters.Where(x => x.PluginName == null && x.TourFileName == null).ToList();
//don't pass in any filters for core tours that have a plugin name assigned
var nonPluginFilters = filters.Where(x => x.PluginName == null).ToList();
//add core tour files
var coreToursPath = Path.Combine(IOHelper.MapPath(SystemDirectories.Config), "BackOfficeTours");
if (Directory.Exists(coreToursPath))
{
foreach (var tourFile in Directory.EnumerateFiles(coreToursPath, "*.json"))
{
TryParseTourFile(tourFile, result, nonPluginFilters, aliasOnlyFilters);
}
}
//collect all tour files in packages
foreach (var plugin in Directory.EnumerateDirectories(IOHelper.MapPath(SystemDirectories.AppPlugins)))
{
var pluginName = Path.GetFileName(plugin.TrimEnd('\\'));
var pluginFilters = filters.Where(x => x.PluginName != null && x.PluginName.IsMatch(pluginName)).ToList();
//If there is any filter applied to match the plugin only (no file or tour alias) then ignore the plugin entirely
var isPluginFiltered = pluginFilters.Any(x => x.TourFileName == null && x.TourAlias == null);
if (isPluginFiltered) continue;
//combine matched package filters with filters not specific to a package
var combinedFilters = nonPluginFilters.Concat(pluginFilters).ToList();
foreach (var backofficeDir in Directory.EnumerateDirectories(plugin, "backoffice"))
{
foreach (var tourDir in Directory.EnumerateDirectories(backofficeDir, "tours"))
{
foreach (var tourFile in Directory.EnumerateFiles(tourDir, "*.json"))
{
TryParseTourFile(tourFile, result, combinedFilters, aliasOnlyFilters, pluginName);
}
}
}
}
//Get all allowed sections for the current user
var allowedSections = UmbracoContext.Current.Security.CurrentUser.AllowedSections.ToList();
var toursToBeRemoved = new List<BackOfficeTourFile>();
//Checking to see if the user has access to the required tour sections, else we remove the tour
foreach (var backOfficeTourFile in result)
{
if (backOfficeTourFile.Tours != null)
{
foreach (var tour in backOfficeTourFile.Tours)
{
if (tour.RequiredSections != null)
{
foreach (var toursRequiredSection in tour.RequiredSections)
{
if (allowedSections.Contains(toursRequiredSection) == false)
{
toursToBeRemoved.Add(backOfficeTourFile);
break;
}
}
}
}
}
}
return result.Except(toursToBeRemoved).OrderBy(x => x.FileName, StringComparer.InvariantCultureIgnoreCase);
}
private void TryParseTourFile(string tourFile,
ICollection<BackOfficeTourFile> result,
List<BackOfficeTourFilter> filters,
List<BackOfficeTourFilter> aliasOnlyFilters,
string pluginName = null)
{
var fileName = Path.GetFileNameWithoutExtension(tourFile);
if (fileName == null) return;
//get the filters specific to this file
var fileFilters = filters.Where(x => x.TourFileName != null && x.TourFileName.IsMatch(fileName)).ToList();
//If there is any filter applied to match the file only (no tour alias) then ignore the file entirely
var isFileFiltered = fileFilters.Any(x => x.TourAlias == null);
if (isFileFiltered) return;
//now combine all aliases to filter below
var aliasFilters = aliasOnlyFilters.Concat(filters.Where(x => x.TourAlias != null))
.Select(x => x.TourAlias)
.ToList();
try
{
var contents = File.ReadAllText(tourFile);
var tours = JsonConvert.DeserializeObject<BackOfficeTour[]>(contents);
var backOfficeTours = tours.Where(x =>
aliasFilters.Count == 0 || aliasFilters.All(filter => filter.IsMatch(x.Alias)) == false);
var localizedTours = backOfficeTours.Where(x =>
string.IsNullOrWhiteSpace(x.Culture) || x.Culture.Equals(Security.CurrentUser.Language,
StringComparison.InvariantCultureIgnoreCase)).ToList();
var tour = new BackOfficeTourFile
{
FileName = Path.GetFileNameWithoutExtension(tourFile),
PluginName = pluginName,
Tours = localizedTours
};
//don't add if all of the tours are filtered
if (tour.Tours.Any())
result.Add(tour);
}
catch (IOException e)
{
throw new IOException("Error while trying to read file: " + tourFile, e);
}
catch (JsonReaderException e)
{
throw new JsonReaderException("Error while trying to parse content as tour data: " + tourFile, e);
}
}
}
}