Files
Umbraco-CMS/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ScriptRepository.cs

140 lines
4.4 KiB
C#
Raw Normal View History

2017-12-07 16:45:25 +01:00
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Persistence.Repositories;
using Umbraco.Extensions;
2017-12-07 16:45:25 +01:00
namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
2017-12-07 16:45:25 +01:00
{
/// <summary>
/// Represents the Script Repository
/// </summary>
internal class ScriptRepository : FileRepository<string, IScript>, IScriptRepository
2017-12-07 16:45:25 +01:00
{
private readonly IIOHelper _ioHelper;
private readonly GlobalSettings _globalSettings;
2017-12-07 16:45:25 +01:00
Netcore: File systems rework (#10181) * Allow IMediaFileSystem to be replace in the DI, or registered with inner filesystem * Remove GetFileSystem from Filesystems It was only used by tests. * Make MediaFileSystem inherit from PhysicalFileSystem directly * Remove FileSystemWrapper * Remove inner filesystem from MediaFileSystem * Add MediaFileManager and bare minimum to make it testable * Remove MediaFileSystem * Fix unit tests using MediaFileManager * Remove IFileSystem and rely only on FileSystem * Hide dangerous methods in FileSystems and do some cleaning * Apply stylecop warnings to MediaFileManager * Add FilesystemsCreator to Tests.Common This allows you to create an instance if FileSystems with your own specified IFileSystem for testing purposes outside our own test suite. * Allow the stylesheet filesystem to be replaced. * Fix tests * Don't save stylesheetWrapper in a temporary var * refactor(FileSystems): change how stylesheet filesystem is registered * fix(FileSystems): unable to overwrite media filesystem SetMediaFileSystem added the MediaManager as a Singleton instead of replacing the existing instance. * fix(FileSystems): calling AddFileSystems replaces MediaManager When calling AddFileSystems after SetMediaFileSystem the MediaManager gets replaced by the default PhysicalFileSystem, so instead of calling SetMediaFileSystem in AddFileSystems we now call TrySetMediaFileSystem instead. This method will not replace any existing instance of the MediaManager if there's already a MediaManager registered. * Use SetMediaFileSystem instead of TrySet, and rename AddFilesystems to ConfigureFileSystems Also don't call AddFileSystems again in ConfigureFilesystems * Don't wrap CSS filesystem twice * Add CreateShadowWrapperInternal to avoid casting * Throw UnauthorizedAccessException isntead of InvalidOperationException * Remove ResetShadowId Co-authored-by: Rasmus John Pedersen <mail@rjp.dk>
2021-04-27 09:52:17 +02:00
public ScriptRepository(FileSystems fileSystems, IIOHelper ioHelper, IOptions<GlobalSettings> globalSettings)
2018-07-20 09:49:05 +02:00
: base(fileSystems.ScriptsFileSystem)
2017-12-07 16:45:25 +01:00
{
_ioHelper = ioHelper ?? throw new ArgumentNullException(nameof(ioHelper));
_globalSettings = globalSettings.Value;
2017-12-07 16:45:25 +01:00
}
#region Implementation of IRepository<string,Script>
public override IScript Get(string id)
2017-12-07 16:45:25 +01:00
{
// get the relative path within the filesystem
// (though... id should be relative already)
var path = FileSystem.GetRelativePath(id);
if (FileSystem.FileExists(path) == false)
return null;
// content will be lazy-loaded when required
var created = FileSystem.GetCreated(path).UtcDateTime;
var updated = FileSystem.GetLastModified(path).UtcDateTime;
//var content = GetFileContent(path);
var script = new Script(path, file => GetFileContent(file.OriginalPath))
{
//id can be the hash
Id = path.GetHashCode(),
Key = path.EncodeAsGuid(),
//Content = content,
CreateDate = created,
UpdateDate = updated,
VirtualPath = FileSystem.GetUrl(path)
};
// reset dirty initial properties (U4-1946)
script.ResetDirtyProperties(false);
return script;
}
public override void Save(IScript entity)
2017-12-07 16:45:25 +01:00
{
// TODO: Casting :/ Review GetFileContent and it's usages, need to look into it later
var script = (Script) entity;
base.Save(script);
2017-12-07 16:45:25 +01:00
// ensure that from now on, content is lazy-loaded
if (script.GetFileContent == null)
script.GetFileContent = file => GetFileContent(file.OriginalPath);
2017-12-07 16:45:25 +01:00
}
public override IEnumerable<IScript> GetMany(params string[] ids)
2017-12-07 16:45:25 +01:00
{
//ensure they are de-duplicated, easy win if people don't do this as this can cause many excess queries
ids = ids.Distinct().ToArray();
if (ids.Any())
{
foreach (var id in ids)
{
yield return Get(id);
}
}
else
{
var files = FindAllFiles("", "*.*");
foreach (var file in files)
{
yield return Get(file);
}
}
}
public bool ValidateScript(IScript script)
2017-12-07 16:45:25 +01:00
{
// get full path
string fullPath;
try
{
// may throw for security reasons
fullPath = FileSystem.GetFullPath(script.Path);
}
catch
{
return false;
}
// validate path & extension
var validDir = _globalSettings.UmbracoScriptsPath;
var isValidPath = _ioHelper.VerifyEditPath(fullPath, validDir);
var validExts = new[] {"js"};
var isValidExtension = _ioHelper.VerifyFileExtension(script.Path, validExts);
2017-12-07 16:45:25 +01:00
return isValidPath && isValidExtension;
}
public Stream GetFileContentStream(string filepath)
{
if (FileSystem.FileExists(filepath) == false) return null;
try
{
return FileSystem.OpenFile(filepath);
}
catch
{
return null; // deal with race conds
}
}
public void SetFileContent(string filepath, Stream content)
{
FileSystem.AddFile(filepath, content, true);
}
#endregion
}
}