diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index 552fe690dd..dd8cb9cc36 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -1,74 +1,55 @@ - - UmbracoCms.Core - 8.0.0 - Umbraco Cms Core Binaries - Umbraco HQ - Umbraco HQ - http://opensource.org/licenses/MIT - http://umbraco.com/ - http://umbraco.com/media/357769/100px_transparent.png - false - Contains the core assemblies needed to run Umbraco Cms. This package only contains assemblies and can be used for package development. Use the UmbracoCms-package to setup Umbraco in Visual Studio as an ASP.NET project. - Contains the core assemblies needed to run Umbraco Cms - en-US - umbraco - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + - - - - - - - - - - + + + + diff --git a/build/NuSpecs/UmbracoCms.Web.nuspec b/build/NuSpecs/UmbracoCms.Web.nuspec index 7a4049fd37..dd13299fd1 100644 --- a/build/NuSpecs/UmbracoCms.Web.nuspec +++ b/build/NuSpecs/UmbracoCms.Web.nuspec @@ -1,74 +1,65 @@ - - UmbracoCms.Web - 8.0.0 - Umbraco Cms Core Binaries - Umbraco HQ - Umbraco HQ - http://opensource.org/licenses/MIT - http://umbraco.com/ - http://umbraco.com/media/357769/100px_transparent.png - false - Contains the core assemblies needed to run Umbraco Cms. This package only contains assemblies and can be used for package development. Use the UmbracoCms-package to setup Umbraco in Visual Studio as an ASP.NET project. - Contains the core assemblies needed to run Umbraco Cms - en-US - umbraco - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + - + + - - - - - - - - + + + + + + + + diff --git a/build/NuSpecs/UmbracoCms.nuspec b/build/NuSpecs/UmbracoCms.nuspec index 30d1a7b6e7..f2024f8fb4 100644 --- a/build/NuSpecs/UmbracoCms.nuspec +++ b/build/NuSpecs/UmbracoCms.nuspec @@ -1,59 +1,60 @@ - - UmbracoCms - 8.0.0 - Umbraco Cms - Umbraco HQ - Umbraco HQ - http://opensource.org/licenses/MIT - http://umbraco.com/ - http://umbraco.com/media/357769/100px_transparent.png - false - Installs Umbraco Cms in your Visual Studio ASP.NET project - Installs Umbraco Cms in your Visual Studio ASP.NET project - en-US - umbraco - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - + + + + - - - - - - - - - - + + + + + + + + + + - - + + diff --git a/src/Umbraco.Core/Auditing/AuditEventsComponent.cs b/src/Umbraco.Core/Components/AuditEventsComponent.cs similarity index 78% rename from src/Umbraco.Core/Auditing/AuditEventsComponent.cs rename to src/Umbraco.Core/Components/AuditEventsComponent.cs index 57457f9241..134aa18414 100644 --- a/src/Umbraco.Core/Auditing/AuditEventsComponent.cs +++ b/src/Umbraco.Core/Components/AuditEventsComponent.cs @@ -3,7 +3,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Web; -using Umbraco.Core.Components; using Umbraco.Core.Events; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; @@ -11,7 +10,7 @@ using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Core.Services.Implement; -namespace Umbraco.Core.Auditing +namespace Umbraco.Core.Components { public sealed class AuditEventsComponent : UmbracoComponentBase, IUmbracoCoreComponent { @@ -53,18 +52,6 @@ namespace Umbraco.Core.Auditing _userService = userService; _entityService = entityService; - //BackOfficeUserManager.AccountLocked += ; - //BackOfficeUserManager.AccountUnlocked += ; - BackOfficeUserManager.ForgotPasswordRequested += OnForgotPasswordRequest; - BackOfficeUserManager.ForgotPasswordChangedSuccess += OnForgotPasswordChange; - BackOfficeUserManager.LoginFailed += OnLoginFailed; - //BackOfficeUserManager.LoginRequiresVerification += ; - BackOfficeUserManager.LoginSuccess += OnLoginSuccess; - BackOfficeUserManager.LogoutSuccess += OnLogoutSuccess; - BackOfficeUserManager.PasswordChanged += OnPasswordChanged; - BackOfficeUserManager.PasswordReset += OnPasswordReset; - //BackOfficeUserManager.ResetAccessFailedCount += ; - UserService.SavedUserGroup += OnSavedUserGroupWithUsers; UserService.SavedUser += OnSavedUser; @@ -255,64 +242,6 @@ namespace Umbraco.Core.Auditing "umbraco/user/delete", "delete user"); } - private void OnLoginSuccess(object sender, EventArgs args) - { - if (args is IdentityAuditEventArgs identityArgs) - { - var performingUser = GetPerformingUser(identityArgs.PerformingUser); - WriteAudit(performingUser, identityArgs.AffectedUser, identityArgs.IpAddress, "umbraco/user/sign-in/login", "login success"); - } - } - - private void OnLogoutSuccess(object sender, EventArgs args) - { - if (args is IdentityAuditEventArgs identityArgs) - { - var performingUser = GetPerformingUser(identityArgs.PerformingUser); - WriteAudit(performingUser, identityArgs.AffectedUser, identityArgs.IpAddress, "umbraco/user/sign-in/logout", "logout success"); - } - } - - private void OnPasswordReset(object sender, EventArgs args) - { - if (args is IdentityAuditEventArgs identityArgs && identityArgs.PerformingUser >= 0) - { - WriteAudit(identityArgs.PerformingUser, identityArgs.AffectedUser, identityArgs.IpAddress, "umbraco/user/password/reset", "password reset"); - } - } - - private void OnPasswordChanged(object sender, EventArgs args) - { - if (args is IdentityAuditEventArgs identityArgs && identityArgs.PerformingUser >= 0) - { - WriteAudit(identityArgs.PerformingUser, identityArgs.AffectedUser, identityArgs.IpAddress, "umbraco/user/password/change", "password change"); - } - } - - private void OnLoginFailed(object sender, EventArgs args) - { - if (args is IdentityAuditEventArgs identityArgs && identityArgs.PerformingUser >= 0) - { - WriteAudit(identityArgs.PerformingUser, 0, identityArgs.IpAddress, "umbraco/user/sign-in/failed", "login failed", affectedDetails: ""); - } - } - - private void OnForgotPasswordChange(object sender, EventArgs args) - { - if (args is IdentityAuditEventArgs identityArgs && identityArgs.PerformingUser >= 0) - { - WriteAudit(identityArgs.PerformingUser, identityArgs.AffectedUser, identityArgs.IpAddress, "umbraco/user/password/forgot/change", "password forgot/change"); - } - } - - private void OnForgotPasswordRequest(object sender, EventArgs args) - { - if (args is IdentityAuditEventArgs identityArgs && identityArgs.PerformingUser >= 0) - { - WriteAudit(identityArgs.PerformingUser, identityArgs.AffectedUser, identityArgs.IpAddress, "umbraco/user/password/forgot/request", "password forgot/request"); - } - } - private void WriteAudit(int performingId, int affectedId, string ipAddress, string eventType, string eventDetails, string affectedDetails = null) { var performingUser = _userService.GetUserById(performingId); diff --git a/src/Umbraco.Core/Strategies/ManifestWatcherComponent.cs b/src/Umbraco.Core/Components/ManifestWatcherComponent.cs similarity index 91% rename from src/Umbraco.Core/Strategies/ManifestWatcherComponent.cs rename to src/Umbraco.Core/Components/ManifestWatcherComponent.cs index da2f3bba32..0a8d9ccd52 100644 --- a/src/Umbraco.Core/Strategies/ManifestWatcherComponent.cs +++ b/src/Umbraco.Core/Components/ManifestWatcherComponent.cs @@ -1,11 +1,9 @@ using System.IO; -using Umbraco.Core.Components; -using Umbraco.Core.Composing; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Manifest; -namespace Umbraco.Core.Strategies +namespace Umbraco.Core.Components { [RuntimeLevel(MinLevel = RuntimeLevel.Run)] public class ManifestWatcherComponent : UmbracoComponentBase, IUmbracoCoreComponent diff --git a/src/Umbraco.Core/Strategies/RelateOnCopyComponent.cs b/src/Umbraco.Core/Components/RelateOnCopyComponent.cs similarity index 93% rename from src/Umbraco.Core/Strategies/RelateOnCopyComponent.cs rename to src/Umbraco.Core/Components/RelateOnCopyComponent.cs index 754fc8dca4..4ebd309e9f 100644 --- a/src/Umbraco.Core/Strategies/RelateOnCopyComponent.cs +++ b/src/Umbraco.Core/Components/RelateOnCopyComponent.cs @@ -1,11 +1,9 @@ -using System; -using Umbraco.Core.Components; -using Umbraco.Core.Composing; +using Umbraco.Core.Composing; using Umbraco.Core.Models; using Umbraco.Core.Services; using Umbraco.Core.Services.Implement; -namespace Umbraco.Core.Strategies +namespace Umbraco.Core.Components { //TODO: This should just exist in the content service/repo! [RuntimeLevel(MinLevel = RuntimeLevel.Run)] diff --git a/src/Umbraco.Core/Strategies/RelateOnTrashComponent.cs b/src/Umbraco.Core/Components/RelateOnTrashComponent.cs similarity index 98% rename from src/Umbraco.Core/Strategies/RelateOnTrashComponent.cs rename to src/Umbraco.Core/Components/RelateOnTrashComponent.cs index 15f0a67a82..fffae85501 100644 --- a/src/Umbraco.Core/Strategies/RelateOnTrashComponent.cs +++ b/src/Umbraco.Core/Components/RelateOnTrashComponent.cs @@ -1,13 +1,11 @@ -using System; -using System.Linq; -using Umbraco.Core.Components; +using System.Linq; using Umbraco.Core.Composing; using Umbraco.Core.Events; using Umbraco.Core.Models; using Umbraco.Core.Services; using Umbraco.Core.Services.Implement; -namespace Umbraco.Core.Strategies +namespace Umbraco.Core.Components { [RuntimeLevel(MinLevel = RuntimeLevel.Run)] public sealed class RelateOnTrashComponent : UmbracoComponentBase, IUmbracoCoreComponent diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings/ContentSectionExtensions.cs b/src/Umbraco.Core/Configuration/UmbracoSettings/ContentSectionExtensions.cs index 519c0e6af1..82cc5928cf 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings/ContentSectionExtensions.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings/ContentSectionExtensions.cs @@ -1,9 +1,24 @@ -using System.Linq; +using System; +using System.Linq; namespace Umbraco.Core.Configuration.UmbracoSettings { public static class ContentSectionExtensions { + /// + /// Gets a value indicating whether the file extension corresponds to an image. + /// + /// The file extension. + /// + /// A value indicating whether the file extension corresponds to an image. + public static bool IsImageFile(this IContentSection contentConfig, string extension) + { + if (contentConfig == null) throw new ArgumentNullException(nameof(contentConfig)); + if (extension == null) return false; + extension = extension.TrimStart('.'); + return contentConfig.ImageFileTypes.InvariantContains(extension); + } + /// /// Determines if file extension is allowed for upload based on (optional) white list and black list /// held in settings. @@ -15,5 +30,17 @@ namespace Umbraco.Core.Configuration.UmbracoSettings (contentSection.AllowedUploadFiles.Any() == false && contentSection.DisallowedUploadFiles.Any(x => x.InvariantEquals(extension)) == false); } + + /// + /// Gets the auto-fill configuration for a specified property alias. + /// + /// + /// The property type alias. + /// The auto-fill configuration for the specified property alias, or null. + public static IImagingAutoFillUploadField GetConfig(this IContentSection contentSection, string propertyTypeAlias) + { + var autoFillConfigs = contentSection.ImageAutoFillProperties; + return autoFillConfigs?.FirstOrDefault(x => x.Alias == propertyTypeAlias); + } } } diff --git a/src/Umbraco.Core/Models/ContentExtensions.cs b/src/Umbraco.Core/ContentExtensions.cs similarity index 92% rename from src/Umbraco.Core/Models/ContentExtensions.cs rename to src/Umbraco.Core/ContentExtensions.cs index d8eb900bb2..a2dd4ff07f 100644 --- a/src/Umbraco.Core/Models/ContentExtensions.cs +++ b/src/Umbraco.Core/ContentExtensions.cs @@ -7,12 +7,13 @@ using System.Web; using System.Xml.Linq; using Umbraco.Core.Composing; using Umbraco.Core.IO; +using Umbraco.Core.Models; using Umbraco.Core.Models.Entities; using Umbraco.Core.Models.Membership; using Umbraco.Core.Services; using Umbraco.Core.Services.Implement; -namespace Umbraco.Core.Models +namespace Umbraco.Core { public static class ContentExtensions { @@ -241,30 +242,6 @@ namespace Umbraco.Core.Models #region SetValue for setting file contents - /// - /// Sets the posted file value of a property. - /// - public static void SetValue(this IContentBase content, string propertyTypeAlias, HttpPostedFileBase value, string culture = null, string segment = null) - { - // ensure we get the filename without the path in IE in intranet mode - // http://stackoverflow.com/questions/382464/httppostedfile-filename-different-from-ie - var filename = value.FileName; - var pos = filename.LastIndexOf(@"\", StringComparison.InvariantCulture); - if (pos > 0) - filename = filename.Substring(pos + 1); - - // strip any directory info - pos = filename.LastIndexOf(IOHelper.DirSepChar); - if (pos > 0) - filename = filename.Substring(pos + 1); - - // get a safe & clean filename - filename = IOHelper.SafeFileName(filename); - if (string.IsNullOrWhiteSpace(filename)) return; - filename = filename.ToLower(); // fixme - er... why? - - MediaFileSystem.SetUploadFile(content, propertyTypeAlias, filename, value.InputStream, culture, segment); - } /// /// Sets the posted file value of a property. @@ -281,7 +258,31 @@ namespace Umbraco.Core.Models if (string.IsNullOrWhiteSpace(filename)) return; filename = filename.ToLower(); // fixme - er... why? - MediaFileSystem.SetUploadFile(content, propertyTypeAlias, filename, filestream, culture, segment); + SetUploadFile(content, propertyTypeAlias, filename, filestream, culture, segment); + } + + private static void SetUploadFile(this IContentBase content, string propertyTypeAlias, string filename, Stream filestream, string culture = null, string segment = null) + { + var property = GetProperty(content, propertyTypeAlias); + var oldpath = property.GetValue(culture, segment) is string svalue ? MediaFileSystem.GetRelativePath(svalue) : null; + var filepath = MediaFileSystem.StoreFile(content, property.PropertyType, filename, filestream, oldpath); + property.SetValue(MediaFileSystem.GetUrl(filepath), culture, segment); + } + + // gets or creates a property for a content item. + private static Property GetProperty(IContentBase content, string propertyTypeAlias) + { + var property = content.Properties.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias)); + if (property != null) return property; + + var propertyType = content.GetContentType().CompositionPropertyTypes + .FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias)); + if (propertyType == null) + throw new Exception("No property type exists with alias " + propertyTypeAlias + "."); + + property = new Property(propertyType); + content.Properties.Add(property); + return property; } /// diff --git a/src/Umbraco.Core/IO/MediaFileSystem.cs b/src/Umbraco.Core/IO/MediaFileSystem.cs index dedad995eb..fd58f573cc 100644 --- a/src/Umbraco.Core/IO/MediaFileSystem.cs +++ b/src/Umbraco.Core/IO/MediaFileSystem.cs @@ -1,20 +1,15 @@ using System; using System.Collections.Generic; -using System.Drawing; -using System.Globalization; using System.IO; using System.Linq; -using System.Threading; using System.Threading.Tasks; using LightInject; -using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Composing; using Umbraco.Core.Exceptions; -using Umbraco.Core.IO.MediaPathSchemes; using Umbraco.Core.Logging; using Umbraco.Core.Media; -using Umbraco.Core.Media.Exif; + using Umbraco.Core.Models; namespace Umbraco.Core.IO @@ -32,8 +27,6 @@ namespace Umbraco.Core.IO // dependencies, so we have to rely on property injection for anything we might need Current.Container.InjectProperties(this); MediaPathScheme.Initialize(this); - - UploadAutoFillProperties = new UploadAutoFillProperties(this, Logger, ContentConfig); } [Inject] @@ -44,9 +37,7 @@ namespace Umbraco.Core.IO [Inject] internal ILogger Logger { get; set; } - - internal UploadAutoFillProperties UploadAutoFillProperties { get; } - + /// /// Deletes all files passed in. /// @@ -213,113 +204,9 @@ namespace Umbraco.Core.IO return filepath; } - // gets or creates a property for a content item. - private static Property GetProperty(IContentBase content, string propertyTypeAlias) - { - var property = content.Properties.FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias)); - if (property != null) return property; - - var propertyType = content.GetContentType().CompositionPropertyTypes - .FirstOrDefault(x => x.Alias.InvariantEquals(propertyTypeAlias)); - if (propertyType == null) - throw new Exception("No property type exists with alias " + propertyTypeAlias + "."); - - property = new Property(propertyType); - content.Properties.Add(property); - return property; - } - - // fixme - what's below belongs to the upload property editor, not the media filesystem! - - public void SetUploadFile(IContentBase content, string propertyTypeAlias, string filename, Stream filestream, string culture = null, string segment = null) - { - var property = GetProperty(content, propertyTypeAlias); - var oldpath = property.GetValue(culture, segment) is string svalue ? GetRelativePath(svalue) : null; - var filepath = StoreFile(content, property.PropertyType, filename, filestream, oldpath); - property.SetValue(GetUrl(filepath), culture, segment); - SetUploadFile(content, property, filepath, filestream, culture, segment); - } - - public void SetUploadFile(IContentBase content, string propertyTypeAlias, string filepath, string culture = null, string segment = null) - { - var property = GetProperty(content, propertyTypeAlias); - // fixme delete? - var oldpath = property.GetValue(culture, segment) is string svalue ? GetRelativePath(svalue) : null; - if (string.IsNullOrWhiteSpace(oldpath) == false && oldpath != filepath) - DeleteFile(oldpath); - property.SetValue(GetUrl(filepath), culture, segment); - using (var filestream = OpenFile(filepath)) - { - SetUploadFile(content, property, filepath, filestream, culture, segment); - } - } - - // sets a file for the FileUpload property editor - // ie generates thumbnails and populates autofill properties - private void SetUploadFile(IContentBase content, Property property, string filepath, Stream filestream, string culture = null, string segment = null) - { - // will use filepath for extension, and filestream for length - UploadAutoFillProperties.Populate(content, property.Alias, filepath, filestream, culture, segment); - } - - #endregion - - #region Image - - /// - /// Gets a value indicating whether the file extension corresponds to an image. - /// - /// The file extension. - /// A value indicating whether the file extension corresponds to an image. - public bool IsImageFile(string extension) - { - if (extension == null) return false; - extension = extension.TrimStart('.'); - return ContentConfig.ImageFileTypes.InvariantContains(extension); - } - - /// - /// Gets the dimensions of an image. - /// - /// A stream containing the image bytes. - /// The dimension of the image. - /// First try with EXIF as it is faster and does not load the entire image - /// in memory. Fallback to GDI which means loading the image in memory and thus - /// use potentially large amounts of memory. - public Size GetDimensions(Stream stream) - { - //Try to load with exif - try - { - var jpgInfo = ImageFile.FromStream(stream); - - if (jpgInfo.Format != ImageFileFormat.Unknown - && jpgInfo.Properties.ContainsKey(ExifTag.PixelYDimension) - && jpgInfo.Properties.ContainsKey(ExifTag.PixelXDimension)) - { - var height = Convert.ToInt32(jpgInfo.Properties[ExifTag.PixelYDimension].Value); - var width = Convert.ToInt32(jpgInfo.Properties[ExifTag.PixelXDimension].Value); - if (height > 0 && width > 0) - { - return new Size(width, height); - } - } - } - catch (Exception) - { - //We will just swallow, just means we can't read exif data, we don't want to log an error either - } - - //we have no choice but to try to read in via GDI - using (var image = Image.FromStream(stream)) - { - - var fileWidth = image.Width; - var fileHeight = image.Height; - return new Size(fileWidth, fileHeight); - } - } + #endregion + } } diff --git a/src/Umbraco.Core/Media/ImageExtensions.cs b/src/Umbraco.Core/Media/ImageExtensions.cs deleted file mode 100644 index c20be13d31..0000000000 --- a/src/Umbraco.Core/Media/ImageExtensions.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Drawing; -using System.Drawing.Imaging; -using System.Linq; - -namespace Umbraco.Core.Media -{ - public static class ImageExtensions - { - /// - /// Gets the MIME type of an image. - /// - /// The image. - /// The MIME type of the image. - public static string GetMimeType(this Image image) - { - var format = image.RawFormat; - var codec = ImageCodecInfo.GetImageDecoders().First(c => c.FormatID == format.Guid); - return codec.MimeType; - } - } -} diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs index d5d9fcfdac..56a31cd76d 100644 --- a/src/Umbraco.Core/Models/ContentBase.cs +++ b/src/Umbraco.Core/Models/ContentBase.cs @@ -280,26 +280,6 @@ namespace Umbraco.Core.Models Properties.Add(property); } - // HttpPostedFileBase is the base class that can be mocked - // HttpPostedFile is what we get in ASP.NET - // HttpPostedFileWrapper wraps sealed HttpPostedFile as HttpPostedFileBase - - /// - /// Sets the posted file value of a property. - /// - public virtual void SetValue(string propertyTypeAlias, HttpPostedFile value, string culture = null, string segment = null) - { - ContentExtensions.SetValue(this, propertyTypeAlias, new HttpPostedFileWrapper(value), culture, segment); - } - - /// - /// Sets the posted file value of a property. - /// - public virtual void SetValue(string propertyTypeAlias, HttpPostedFileBase value, string culture = null, string segment = null) - { - ContentExtensions.SetValue(this, propertyTypeAlias, value, culture, segment); - } - #endregion #region Copy diff --git a/src/Umbraco.Core/Models/Identity/BackOfficeIdentityUser.cs b/src/Umbraco.Core/Models/Identity/BackOfficeIdentityUser.cs index b4d9bb2c8a..23c232324a 100644 --- a/src/Umbraco.Core/Models/Identity/BackOfficeIdentityUser.cs +++ b/src/Umbraco.Core/Models/Identity/BackOfficeIdentityUser.cs @@ -93,14 +93,6 @@ namespace Umbraco.Core.Models.Identity _roles.CollectionChanged += _roles_CollectionChanged; } - public virtual async Task GenerateUserIdentityAsync(BackOfficeUserManager manager) - { - // NOTE the authenticationType must match the umbraco one - // defined in CookieAuthenticationOptions.AuthenticationType - var userIdentity = await manager.CreateIdentityAsync(this, Constants.Security.BackOfficeAuthenticationType); - return userIdentity; - } - /// /// Returns true if an Id has been set on this object this will be false if the object is new and not peristed to the database /// diff --git a/src/Umbraco.Core/Models/Template.cs b/src/Umbraco.Core/Models/Template.cs index 9cdbee1951..b7e67c45ea 100644 --- a/src/Umbraco.Core/Models/Template.cs +++ b/src/Umbraco.Core/Models/Template.cs @@ -1,14 +1,6 @@ using System; -using System.Collections.Generic; -using System.Drawing; -using System.IO; using System.Reflection; using System.Runtime.Serialization; -using System.Text; -using Umbraco.Core.Configuration; -using Umbraco.Core.Configuration.UmbracoSettings; -using Umbraco.Core.IO; -using Umbraco.Core.Services; using Umbraco.Core.Strings; namespace Umbraco.Core.Models diff --git a/src/Umbraco.Core/NetworkHelper.cs b/src/Umbraco.Core/NetworkHelper.cs index e5e153966a..8f310ccf0c 100644 --- a/src/Umbraco.Core/NetworkHelper.cs +++ b/src/Umbraco.Core/NetworkHelper.cs @@ -10,9 +10,6 @@ namespace Umbraco.Core /// /// Returns the machine name that is safe to use in file paths. /// - /// - /// see: https://github.com/Shandem/ClientDependency/issues/4 - /// public static string FileSafeMachineName { get { return MachineName.ReplaceNonAlphanumericChars('-'); } diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 44f170b2df..8c8e474b13 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -38,8 +38,6 @@ - - @@ -58,21 +56,22 @@ - - - - - - - - + + 2.2.2 + + + 5.2.6 + + + 4.0.0 + - + 2.7.1 @@ -110,8 +109,7 @@ - - + @@ -194,7 +192,6 @@ - @@ -567,7 +564,6 @@ - @@ -582,49 +578,17 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -641,7 +605,7 @@ - + @@ -1306,19 +1270,10 @@ - - - - - - - - - @@ -1329,8 +1284,6 @@ - - @@ -1447,9 +1400,9 @@ - - - + + + @@ -1531,6 +1484,8 @@ - + + + \ No newline at end of file diff --git a/src/Umbraco.Examine/Umbraco.Examine.csproj b/src/Umbraco.Examine/Umbraco.Examine.csproj index 1771ca4d2b..678ae124d2 100644 --- a/src/Umbraco.Examine/Umbraco.Examine.csproj +++ b/src/Umbraco.Examine/Umbraco.Examine.csproj @@ -50,7 +50,7 @@ - + diff --git a/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj b/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj index 19236e0163..c53a5571e4 100644 --- a/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj +++ b/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj @@ -68,7 +68,7 @@ - + diff --git a/src/Umbraco.Tests/Macros/MacroParserTests.cs b/src/Umbraco.Tests/Macros/MacroParserTests.cs index 8c03e16f3b..898ae4b20e 100644 --- a/src/Umbraco.Tests/Macros/MacroParserTests.cs +++ b/src/Umbraco.Tests/Macros/MacroParserTests.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using NUnit.Framework; using Umbraco.Core.Macros; +using Umbraco.Web.Macros; namespace Umbraco.Tests.Macros { diff --git a/src/Umbraco.Tests/Models/ContentExtensionsTests.cs b/src/Umbraco.Tests/Models/ContentExtensionsTests.cs index a19d28c295..38a93c0c35 100644 --- a/src/Umbraco.Tests/Models/ContentExtensionsTests.cs +++ b/src/Umbraco.Tests/Models/ContentExtensionsTests.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using NUnit.Framework; +using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Tests.TestHelpers.Entities; using Umbraco.Tests.Testing; diff --git a/src/Umbraco.Tests/Models/ContentTests.cs b/src/Umbraco.Tests/Models/ContentTests.cs index 2b136d2556..661aeb5f87 100644 --- a/src/Umbraco.Tests/Models/ContentTests.cs +++ b/src/Umbraco.Tests/Models/ContentTests.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Web; using Moq; using NUnit.Framework; +using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; diff --git a/src/Umbraco.Tests/Models/MediaXmlTest.cs b/src/Umbraco.Tests/Models/MediaXmlTest.cs index 29c936adb9..492803ce17 100644 --- a/src/Umbraco.Tests/Models/MediaXmlTest.cs +++ b/src/Umbraco.Tests/Models/MediaXmlTest.cs @@ -29,7 +29,7 @@ namespace Umbraco.Tests.Models // reference, so static ctor runs, so event handlers register // and then, this will reset the width, height... because the file does not exist, of course ;-( - var ignored = new FileUploadPropertyEditor(Mock.Of(), new MediaFileSystem(Mock.Of())); + var ignored = new FileUploadPropertyEditor(Mock.Of(), new MediaFileSystem(Mock.Of()), Mock.Of()); var media = MockedMedia.CreateMediaImage(mediaType, -1); media.WriterId = -1; // else it's zero and that's not a user and it breaks the tests diff --git a/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs b/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs index 9b5feb4415..1f6b569a0e 100644 --- a/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs +++ b/src/Umbraco.Tests/PropertyEditors/ImageCropperTest.cs @@ -15,6 +15,7 @@ using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; using Umbraco.Core.PropertyEditors.ValueConverters; +using Umbraco.Core.Services; using Umbraco.Tests.TestHelpers; using Umbraco.Web.Models; using Umbraco.Web; @@ -77,7 +78,7 @@ namespace Umbraco.Tests.PropertyEditors var mediaFileSystem = new MediaFileSystem(Mock.Of()); var dataTypeService = new TestObjects.TestDataTypeService( - new DataType(new ImageCropperPropertyEditor(Mock.Of(), mediaFileSystem, Mock.Of())) { Id = 1 }); + new DataType(new ImageCropperPropertyEditor(Mock.Of(), mediaFileSystem, Mock.Of(), Mock.Of())) { Id = 1 }); var factory = new PublishedContentTypeFactory(Mock.Of(), new PropertyValueConverterCollection(Array.Empty()), dataTypeService); diff --git a/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs b/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs index 11ef8a9411..23e5e472a3 100644 --- a/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs +++ b/src/Umbraco.Tests/Security/BackOfficeCookieManagerTests.cs @@ -14,7 +14,7 @@ using Umbraco.Web; using Umbraco.Web.PublishedCache; using Umbraco.Web.Routing; using Umbraco.Web.Security; -using Umbraco.Web.Security.Identity; + namespace Umbraco.Tests.Security { diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 3a715a9561..08b1cec2d4 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -96,7 +96,7 @@ - + diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 7a6a6bcc19..1faa5dc5a0 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -88,10 +88,10 @@ - + - + diff --git a/src/Umbraco.Web/Components/BackOfficeUserAuditEventsComponent.cs b/src/Umbraco.Web/Components/BackOfficeUserAuditEventsComponent.cs new file mode 100644 index 0000000000..79630ef613 --- /dev/null +++ b/src/Umbraco.Web/Components/BackOfficeUserAuditEventsComponent.cs @@ -0,0 +1,144 @@ +using System; +using Umbraco.Core; +using Umbraco.Core.Components; +using Umbraco.Core.Models; +using Umbraco.Core.Models.Membership; +using Umbraco.Core.Security; +using Umbraco.Core.Services; +using Umbraco.Web.Security; + +namespace Umbraco.Web.Components +{ + public sealed class BackOfficeUserAuditEventsComponent : UmbracoComponentBase, IUmbracoCoreComponent + { + private IAuditService _auditService; + private IUserService _userService; + + private IUser GetPerformingUser(int userId) + { + var found = userId >= 0 ? _userService.GetUserById(userId) : null; + return found ?? new User {Id = 0, Name = "SYSTEM", Email = ""}; + } + + + public void Initialize(IAuditService auditService, IUserService userService) + { + _auditService = auditService; + _userService = userService; + + //BackOfficeUserManager.AccountLocked += ; + //BackOfficeUserManager.AccountUnlocked += ; + BackOfficeUserManager.ForgotPasswordRequested += OnForgotPasswordRequest; + BackOfficeUserManager.ForgotPasswordChangedSuccess += OnForgotPasswordChange; + BackOfficeUserManager.LoginFailed += OnLoginFailed; + //BackOfficeUserManager.LoginRequiresVerification += ; + BackOfficeUserManager.LoginSuccess += OnLoginSuccess; + BackOfficeUserManager.LogoutSuccess += OnLogoutSuccess; + BackOfficeUserManager.PasswordChanged += OnPasswordChanged; + BackOfficeUserManager.PasswordReset += OnPasswordReset; + //BackOfficeUserManager.ResetAccessFailedCount += ; + + } + + private static string FormatEmail(IMembershipUser user) + { + return user == null ? string.Empty : user.Email.IsNullOrWhiteSpace() ? "" : $"<{user.Email}>"; + } + + + private void OnLoginSuccess(object sender, EventArgs args) + { + if (args is IdentityAuditEventArgs identityArgs) + { + var performingUser = GetPerformingUser(identityArgs.PerformingUser); + WriteAudit(performingUser, identityArgs.AffectedUser, identityArgs.IpAddress, "umbraco/user/sign-in/login", "login success"); + } + } + + private void OnLogoutSuccess(object sender, EventArgs args) + { + if (args is IdentityAuditEventArgs identityArgs) + { + var performingUser = GetPerformingUser(identityArgs.PerformingUser); + WriteAudit(performingUser, identityArgs.AffectedUser, identityArgs.IpAddress, "umbraco/user/sign-in/logout", "logout success"); + } + } + + private void OnPasswordReset(object sender, EventArgs args) + { + if (args is IdentityAuditEventArgs identityArgs && identityArgs.PerformingUser >= 0) + { + WriteAudit(identityArgs.PerformingUser, identityArgs.AffectedUser, identityArgs.IpAddress, "umbraco/user/password/reset", "password reset"); + } + } + + private void OnPasswordChanged(object sender, EventArgs args) + { + if (args is IdentityAuditEventArgs identityArgs && identityArgs.PerformingUser >= 0) + { + WriteAudit(identityArgs.PerformingUser, identityArgs.AffectedUser, identityArgs.IpAddress, "umbraco/user/password/change", "password change"); + } + } + + private void OnLoginFailed(object sender, EventArgs args) + { + if (args is IdentityAuditEventArgs identityArgs && identityArgs.PerformingUser >= 0) + { + WriteAudit(identityArgs.PerformingUser, 0, identityArgs.IpAddress, "umbraco/user/sign-in/failed", "login failed", affectedDetails: ""); + } + } + + private void OnForgotPasswordChange(object sender, EventArgs args) + { + if (args is IdentityAuditEventArgs identityArgs && identityArgs.PerformingUser >= 0) + { + WriteAudit(identityArgs.PerformingUser, identityArgs.AffectedUser, identityArgs.IpAddress, "umbraco/user/password/forgot/change", "password forgot/change"); + } + } + + private void OnForgotPasswordRequest(object sender, EventArgs args) + { + if (args is IdentityAuditEventArgs identityArgs && identityArgs.PerformingUser >= 0) + { + WriteAudit(identityArgs.PerformingUser, identityArgs.AffectedUser, identityArgs.IpAddress, "umbraco/user/password/forgot/request", "password forgot/request"); + } + } + + private void WriteAudit(int performingId, int affectedId, string ipAddress, string eventType, string eventDetails, string affectedDetails = null) + { + var performingUser = _userService.GetUserById(performingId); + + var performingDetails = performingUser == null + ? $"User UNKNOWN:{performingId}" + : $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}"; + + WriteAudit(performingId, performingDetails, affectedId, ipAddress, eventType, eventDetails, affectedDetails); + } + + private void WriteAudit(IUser performingUser, int affectedId, string ipAddress, string eventType, string eventDetails) + { + var performingDetails = performingUser == null + ? $"User UNKNOWN" + : $"User \"{performingUser.Name}\" {FormatEmail(performingUser)}"; + + WriteAudit(performingUser?.Id ?? 0, performingDetails, affectedId, ipAddress, eventType, eventDetails); + } + + private void WriteAudit(int performingId, string performingDetails, int affectedId, string ipAddress, string eventType, string eventDetails, string affectedDetails = null) + { + if (affectedDetails == null) + { + var affectedUser = _userService.GetUserById(affectedId); + affectedDetails = affectedUser == null + ? $"User UNKNOWN:{affectedId}" + : $"User \"{affectedUser.Name}\" {FormatEmail(affectedUser)}"; + } + + _auditService.Write(performingId, performingDetails, + ipAddress, + DateTime.UtcNow, + affectedId, affectedDetails, + eventType, eventDetails); + } + } +} diff --git a/src/Umbraco.Web/ContentExtensions.cs b/src/Umbraco.Web/ContentExtensions.cs new file mode 100644 index 0000000000..34ff5da2f6 --- /dev/null +++ b/src/Umbraco.Web/ContentExtensions.cs @@ -0,0 +1,32 @@ +using System; +using System.Web; +using Umbraco.Core.IO; +using Umbraco.Core; +using Umbraco.Core.Models; + +namespace Umbraco.Web +{ + public static class ContentExtensions + { + /// + /// Sets the posted file value of a property. + /// + public static void SetValue(this IContentBase content, string propertyTypeAlias, HttpPostedFileBase value, string culture = null, string segment = null) + { + // ensure we get the filename without the path in IE in intranet mode + // http://stackoverflow.com/questions/382464/httppostedfile-filename-different-from-ie + var filename = value.FileName; + var pos = filename.LastIndexOf(@"\", StringComparison.InvariantCulture); + if (pos > 0) + filename = filename.Substring(pos + 1); + + // strip any directory info + pos = filename.LastIndexOf(IOHelper.DirSepChar); + if (pos > 0) + filename = filename.Substring(pos + 1); + + content.SetValue(propertyTypeAlias, filename, value.InputStream, culture, segment); + } + + } +} diff --git a/src/Umbraco.Web/Editors/AuthenticationController.cs b/src/Umbraco.Web/Editors/AuthenticationController.cs index 3def722738..1f02137caf 100644 --- a/src/Umbraco.Web/Editors/AuthenticationController.cs +++ b/src/Umbraco.Web/Editors/AuthenticationController.cs @@ -21,7 +21,6 @@ using Umbraco.Web.Models; using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Mvc; using Umbraco.Web.Security; -using Umbraco.Web.Security.Identity; using Umbraco.Web.WebApi; using Umbraco.Web.WebApi.Filters; using Umbraco.Core.Configuration; diff --git a/src/Umbraco.Web/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs index c2cf80f296..d201919cef 100644 --- a/src/Umbraco.Web/Editors/BackOfficeController.cs +++ b/src/Umbraco.Web/Editors/BackOfficeController.cs @@ -26,12 +26,13 @@ using Umbraco.Core.Models.Membership; using Umbraco.Core.Security; using Umbraco.Web.Models; using Umbraco.Web.Mvc; -using Umbraco.Web.Security.Identity; + using Umbraco.Web.Trees; using Umbraco.Web.UI.JavaScript; using Umbraco.Core.Services; using Umbraco.Web.Composing; using Umbraco.Web.Features; +using Umbraco.Web.Security; using Action = Umbraco.Web._Legacy.Actions.Action; using Constants = Umbraco.Core.Constants; using JArray = Newtonsoft.Json.Linq.JArray; diff --git a/src/Umbraco.Web/Editors/ImagesController.cs b/src/Umbraco.Web/Editors/ImagesController.cs index a13e7d3a95..e9b89a0ab4 100644 --- a/src/Umbraco.Web/Editors/ImagesController.cs +++ b/src/Umbraco.Web/Editors/ImagesController.cs @@ -2,7 +2,9 @@ using System.IO; using System.Net; using System.Net.Http; +using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; +using Umbraco.Web.Media; using Umbraco.Web.Mvc; using Umbraco.Web.WebApi; using Constants = Umbraco.Core.Constants; @@ -16,10 +18,12 @@ namespace Umbraco.Web.Editors public class ImagesController : UmbracoAuthorizedApiController { private readonly MediaFileSystem _mediaFileSystem; + private readonly IContentSection _contentSection; - public ImagesController(MediaFileSystem mediaFileSystem) + public ImagesController(MediaFileSystem mediaFileSystem, IContentSection contentSection) { _mediaFileSystem = mediaFileSystem; + _contentSection = contentSection; } /// @@ -51,7 +55,7 @@ namespace Umbraco.Web.Editors var ext = Path.GetExtension(imagePath); // we need to check if it is an image by extension - if (_mediaFileSystem.IsImageFile(ext) == false) + if (_contentSection.IsImageFile(ext) == false) return Request.CreateResponse(HttpStatusCode.NotFound); //redirect to ImageProcessor thumbnail with rnd generated from last modified time of original media file diff --git a/src/Umbraco.Web/Editors/PackageInstallController.cs b/src/Umbraco.Web/Editors/PackageInstallController.cs index d2a0df68ba..1c3bddb115 100644 --- a/src/Umbraco.Web/Editors/PackageInstallController.cs +++ b/src/Umbraco.Web/Editors/PackageInstallController.cs @@ -24,6 +24,7 @@ using Umbraco.Web.Models; using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Mvc; using Umbraco.Web.UI; +using Umbraco.Web.UI.JavaScript; using Umbraco.Web.WebApi; using Umbraco.Web.WebApi.Filters; using File = System.IO.File; @@ -582,8 +583,9 @@ namespace Umbraco.Web.Editors ins.LoadConfig(IOHelper.MapPath(model.TemporaryDirectoryPath)); ins.InstallCleanUp(model.Id, IOHelper.MapPath(model.TemporaryDirectoryPath)); - var clientDependencyConfig = new Umbraco.Core.Configuration.ClientDependencyConfiguration(Logger); - var clientDependencyUpdated = clientDependencyConfig.IncreaseVersionNumber(); + var clientDependencyConfig = new ClientDependencyConfiguration(Logger); + var clientDependencyUpdated = clientDependencyConfig.UpdateVersionNumber( + UmbracoVersion.SemanticVersion, DateTime.UtcNow, "yyyyMMdd"); //clear the tree cache - we'll do this here even though the browser will reload, but just in case it doesn't can't hurt. //these bits are super old, but cant find another way to do this currently diff --git a/src/Umbraco.Web/Editors/PasswordChanger.cs b/src/Umbraco.Web/Editors/PasswordChanger.cs index 5034ce1950..69cc28ccb6 100644 --- a/src/Umbraco.Web/Editors/PasswordChanger.cs +++ b/src/Umbraco.Web/Editors/PasswordChanger.cs @@ -11,6 +11,7 @@ using Umbraco.Core.Models.Identity; using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Web.Models; +using Umbraco.Web.Security; using IUser = Umbraco.Core.Models.Membership.IUser; namespace Umbraco.Web.Editors diff --git a/src/Umbraco.Core/Logging/ImageProcessorLogger.cs b/src/Umbraco.Web/ImageProcessorLogger.cs similarity index 97% rename from src/Umbraco.Core/Logging/ImageProcessorLogger.cs rename to src/Umbraco.Web/ImageProcessorLogger.cs index fa1f117e06..75df6bd246 100644 --- a/src/Umbraco.Core/Logging/ImageProcessorLogger.cs +++ b/src/Umbraco.Web/ImageProcessorLogger.cs @@ -2,8 +2,9 @@ using System.Runtime.CompilerServices; using ImageProcessor.Common.Exceptions; using Umbraco.Core.Composing; +using Umbraco.Core.Logging; -namespace Umbraco.Core.Logging +namespace Umbraco.Web { /// diff --git a/src/Umbraco.Web/Install/Controllers/InstallController.cs b/src/Umbraco.Web/Install/Controllers/InstallController.cs index b886c459ab..175e6543ab 100644 --- a/src/Umbraco.Web/Install/Controllers/InstallController.cs +++ b/src/Umbraco.Web/Install/Controllers/InstallController.cs @@ -6,6 +6,7 @@ using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Migrations.Install; using Umbraco.Web.Security; +using Umbraco.Web.UI.JavaScript; namespace Umbraco.Web.Install.Controllers { diff --git a/src/Umbraco.Core/Macros/MacroTagParser.cs b/src/Umbraco.Web/Macros/MacroTagParser.cs similarity index 99% rename from src/Umbraco.Core/Macros/MacroTagParser.cs rename to src/Umbraco.Web/Macros/MacroTagParser.cs index 469b2ed4d0..cbfc1ce0f7 100644 --- a/src/Umbraco.Core/Macros/MacroTagParser.cs +++ b/src/Umbraco.Web/Macros/MacroTagParser.cs @@ -5,7 +5,7 @@ using System.Text.RegularExpressions; using HtmlAgilityPack; using Umbraco.Core.Xml; -namespace Umbraco.Core.Macros +namespace Umbraco.Web.Macros { /// /// Parses the macro syntax in a string and renders out it's contents diff --git a/src/Umbraco.Core/Media/Exif/BitConverterEx.cs b/src/Umbraco.Web/Media/Exif/BitConverterEx.cs similarity index 99% rename from src/Umbraco.Core/Media/Exif/BitConverterEx.cs rename to src/Umbraco.Web/Media/Exif/BitConverterEx.cs index 9447b057b1..9850efa907 100644 --- a/src/Umbraco.Core/Media/Exif/BitConverterEx.cs +++ b/src/Umbraco.Web/Media/Exif/BitConverterEx.cs @@ -1,6 +1,6 @@ using System; -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// An endian-aware converter for converting between base data types diff --git a/src/Umbraco.Core/Media/Exif/ExifBitConverter.cs b/src/Umbraco.Web/Media/Exif/ExifBitConverter.cs similarity index 99% rename from src/Umbraco.Core/Media/Exif/ExifBitConverter.cs rename to src/Umbraco.Web/Media/Exif/ExifBitConverter.cs index 6247929cf6..e116e1994f 100644 --- a/src/Umbraco.Core/Media/Exif/ExifBitConverter.cs +++ b/src/Umbraco.Web/Media/Exif/ExifBitConverter.cs @@ -1,7 +1,7 @@ using System; using System.Text; -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Converts between exif data types and array of bytes. diff --git a/src/Umbraco.Core/Media/Exif/ExifEnums.cs b/src/Umbraco.Web/Media/Exif/ExifEnums.cs similarity index 99% rename from src/Umbraco.Core/Media/Exif/ExifEnums.cs rename to src/Umbraco.Web/Media/Exif/ExifEnums.cs index 2c2f9f798d..5ba5b1d704 100644 --- a/src/Umbraco.Core/Media/Exif/ExifEnums.cs +++ b/src/Umbraco.Web/Media/Exif/ExifEnums.cs @@ -1,6 +1,6 @@ using System; -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { internal enum Compression : ushort { diff --git a/src/Umbraco.Core/Media/Exif/ExifExceptions.cs b/src/Umbraco.Web/Media/Exif/ExifExceptions.cs similarity index 96% rename from src/Umbraco.Core/Media/Exif/ExifExceptions.cs rename to src/Umbraco.Web/Media/Exif/ExifExceptions.cs index b0301e951a..040e84ff99 100644 --- a/src/Umbraco.Core/Media/Exif/ExifExceptions.cs +++ b/src/Umbraco.Web/Media/Exif/ExifExceptions.cs @@ -1,6 +1,6 @@ using System; -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// The exception that is thrown when the format of the JPEG/Exif file diff --git a/src/Umbraco.Core/Media/Exif/ExifExtendedProperty.cs b/src/Umbraco.Web/Media/Exif/ExifExtendedProperty.cs similarity index 99% rename from src/Umbraco.Core/Media/Exif/ExifExtendedProperty.cs rename to src/Umbraco.Web/Media/Exif/ExifExtendedProperty.cs index 2a3ed38928..40ba275fe4 100644 --- a/src/Umbraco.Core/Media/Exif/ExifExtendedProperty.cs +++ b/src/Umbraco.Web/Media/Exif/ExifExtendedProperty.cs @@ -1,7 +1,7 @@ using System; using System.Text; -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Represents an enumerated value. diff --git a/src/Umbraco.Core/Media/Exif/ExifFileTypeDescriptor.cs b/src/Umbraco.Web/Media/Exif/ExifFileTypeDescriptor.cs similarity index 99% rename from src/Umbraco.Core/Media/Exif/ExifFileTypeDescriptor.cs rename to src/Umbraco.Web/Media/Exif/ExifFileTypeDescriptor.cs index 00fd9a11c0..4eba0e5686 100644 --- a/src/Umbraco.Core/Media/Exif/ExifFileTypeDescriptor.cs +++ b/src/Umbraco.Web/Media/Exif/ExifFileTypeDescriptor.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.ComponentModel; -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Provides a custom type descriptor for an ExifFile instance. diff --git a/src/Umbraco.Core/Media/Exif/ExifInterOperability.cs b/src/Umbraco.Web/Media/Exif/ExifInterOperability.cs similarity index 98% rename from src/Umbraco.Core/Media/Exif/ExifInterOperability.cs rename to src/Umbraco.Web/Media/Exif/ExifInterOperability.cs index b43177d49c..e7d8813767 100644 --- a/src/Umbraco.Core/Media/Exif/ExifInterOperability.cs +++ b/src/Umbraco.Web/Media/Exif/ExifInterOperability.cs @@ -1,4 +1,4 @@ -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Represents interoperability data for an exif tag in the platform byte order. diff --git a/src/Umbraco.Core/Media/Exif/ExifProperty.cs b/src/Umbraco.Web/Media/Exif/ExifProperty.cs similarity index 99% rename from src/Umbraco.Core/Media/Exif/ExifProperty.cs rename to src/Umbraco.Web/Media/Exif/ExifProperty.cs index b05d88eb0a..3a6efcab0b 100644 --- a/src/Umbraco.Core/Media/Exif/ExifProperty.cs +++ b/src/Umbraco.Web/Media/Exif/ExifProperty.cs @@ -1,7 +1,7 @@ using System; using System.Text; -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Represents the abstract base class for an Exif property. diff --git a/src/Umbraco.Core/Media/Exif/ExifPropertyCollection.cs b/src/Umbraco.Web/Media/Exif/ExifPropertyCollection.cs similarity index 99% rename from src/Umbraco.Core/Media/Exif/ExifPropertyCollection.cs rename to src/Umbraco.Web/Media/Exif/ExifPropertyCollection.cs index 233fe27a91..7f6258cbca 100644 --- a/src/Umbraco.Core/Media/Exif/ExifPropertyCollection.cs +++ b/src/Umbraco.Web/Media/Exif/ExifPropertyCollection.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Represents a collection of objects. diff --git a/src/Umbraco.Core/Media/Exif/ExifPropertyFactory.cs b/src/Umbraco.Web/Media/Exif/ExifPropertyFactory.cs similarity index 99% rename from src/Umbraco.Core/Media/Exif/ExifPropertyFactory.cs rename to src/Umbraco.Web/Media/Exif/ExifPropertyFactory.cs index 69efb809fc..08d1f40afd 100644 --- a/src/Umbraco.Core/Media/Exif/ExifPropertyFactory.cs +++ b/src/Umbraco.Web/Media/Exif/ExifPropertyFactory.cs @@ -1,7 +1,7 @@ using System; using System.Text; -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Creates exif properties from interoperability parameters. diff --git a/src/Umbraco.Core/Media/Exif/ExifTag.cs b/src/Umbraco.Web/Media/Exif/ExifTag.cs similarity index 99% rename from src/Umbraco.Core/Media/Exif/ExifTag.cs rename to src/Umbraco.Web/Media/Exif/ExifTag.cs index 47facc28b8..a65d75d7c7 100644 --- a/src/Umbraco.Core/Media/Exif/ExifTag.cs +++ b/src/Umbraco.Web/Media/Exif/ExifTag.cs @@ -1,5 +1,5 @@  -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Represents the tags associated with exif fields. diff --git a/src/Umbraco.Core/Media/Exif/ExifTagFactory.cs b/src/Umbraco.Web/Media/Exif/ExifTagFactory.cs similarity index 98% rename from src/Umbraco.Core/Media/Exif/ExifTagFactory.cs rename to src/Umbraco.Web/Media/Exif/ExifTagFactory.cs index 729ce9c345..a9f1896fe7 100644 --- a/src/Umbraco.Core/Media/Exif/ExifTagFactory.cs +++ b/src/Umbraco.Web/Media/Exif/ExifTagFactory.cs @@ -1,6 +1,6 @@ using System; -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { internal static class ExifTagFactory { diff --git a/src/Umbraco.Core/Media/Exif/IFD.cs b/src/Umbraco.Web/Media/Exif/IFD.cs similarity index 90% rename from src/Umbraco.Core/Media/Exif/IFD.cs rename to src/Umbraco.Web/Media/Exif/IFD.cs index 68628e21d8..c73a7ed97a 100644 --- a/src/Umbraco.Core/Media/Exif/IFD.cs +++ b/src/Umbraco.Web/Media/Exif/IFD.cs @@ -1,4 +1,4 @@ -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Represents the IFD section containing tags. diff --git a/src/Umbraco.Core/Media/Exif/ImageFile.cs b/src/Umbraco.Web/Media/Exif/ImageFile.cs similarity index 99% rename from src/Umbraco.Core/Media/Exif/ImageFile.cs rename to src/Umbraco.Web/Media/Exif/ImageFile.cs index 24eb780c9d..da60ea6ffa 100644 --- a/src/Umbraco.Core/Media/Exif/ImageFile.cs +++ b/src/Umbraco.Web/Media/Exif/ImageFile.cs @@ -3,7 +3,7 @@ using System.Drawing; using System.IO; using System.Text; -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Represents the base class for image files. diff --git a/src/Umbraco.Core/Media/Exif/ImageFileDirectory.cs b/src/Umbraco.Web/Media/Exif/ImageFileDirectory.cs similarity index 99% rename from src/Umbraco.Core/Media/Exif/ImageFileDirectory.cs rename to src/Umbraco.Web/Media/Exif/ImageFileDirectory.cs index 898e0fd017..7b2c134f52 100644 --- a/src/Umbraco.Core/Media/Exif/ImageFileDirectory.cs +++ b/src/Umbraco.Web/Media/Exif/ImageFileDirectory.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Represents an image file directory. diff --git a/src/Umbraco.Core/Media/Exif/ImageFileDirectoryEntry.cs b/src/Umbraco.Web/Media/Exif/ImageFileDirectoryEntry.cs similarity index 99% rename from src/Umbraco.Core/Media/Exif/ImageFileDirectoryEntry.cs rename to src/Umbraco.Web/Media/Exif/ImageFileDirectoryEntry.cs index e4be3863f0..2d364c4d0c 100644 --- a/src/Umbraco.Core/Media/Exif/ImageFileDirectoryEntry.cs +++ b/src/Umbraco.Web/Media/Exif/ImageFileDirectoryEntry.cs @@ -1,6 +1,6 @@ using System; -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Represents an entry in the image file directory. diff --git a/src/Umbraco.Core/Media/Exif/ImageFileFormat.cs b/src/Umbraco.Web/Media/Exif/ImageFileFormat.cs similarity index 92% rename from src/Umbraco.Core/Media/Exif/ImageFileFormat.cs rename to src/Umbraco.Web/Media/Exif/ImageFileFormat.cs index 8e1433c947..0e3cb5010f 100644 --- a/src/Umbraco.Core/Media/Exif/ImageFileFormat.cs +++ b/src/Umbraco.Web/Media/Exif/ImageFileFormat.cs @@ -1,4 +1,4 @@ -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Represents the format of the . diff --git a/src/Umbraco.Core/Media/Exif/JFIFEnums.cs b/src/Umbraco.Web/Media/Exif/JFIFEnums.cs similarity index 96% rename from src/Umbraco.Core/Media/Exif/JFIFEnums.cs rename to src/Umbraco.Web/Media/Exif/JFIFEnums.cs index 6cd7089727..d3a55eec79 100644 --- a/src/Umbraco.Core/Media/Exif/JFIFEnums.cs +++ b/src/Umbraco.Web/Media/Exif/JFIFEnums.cs @@ -1,4 +1,4 @@ -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Represents the units for the X and Y densities diff --git a/src/Umbraco.Core/Media/Exif/JFIFExtendedProperty.cs b/src/Umbraco.Web/Media/Exif/JFIFExtendedProperty.cs similarity index 98% rename from src/Umbraco.Core/Media/Exif/JFIFExtendedProperty.cs rename to src/Umbraco.Web/Media/Exif/JFIFExtendedProperty.cs index 573eedf146..94b255f4d1 100644 --- a/src/Umbraco.Core/Media/Exif/JFIFExtendedProperty.cs +++ b/src/Umbraco.Web/Media/Exif/JFIFExtendedProperty.cs @@ -1,6 +1,6 @@ using System; -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Represents the JFIF version as a 16 bit unsigned integer. (EXIF Specification: SHORT) diff --git a/src/Umbraco.Core/Media/Exif/JFIFThumbnail.cs b/src/Umbraco.Web/Media/Exif/JFIFThumbnail.cs similarity index 97% rename from src/Umbraco.Core/Media/Exif/JFIFThumbnail.cs rename to src/Umbraco.Web/Media/Exif/JFIFThumbnail.cs index 95987ea79a..e7fc5fd51a 100644 --- a/src/Umbraco.Core/Media/Exif/JFIFThumbnail.cs +++ b/src/Umbraco.Web/Media/Exif/JFIFThumbnail.cs @@ -1,4 +1,4 @@ -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Represents a JFIF thumbnail. diff --git a/src/Umbraco.Core/Media/Exif/JPEGExceptions.cs b/src/Umbraco.Web/Media/Exif/JPEGExceptions.cs similarity index 98% rename from src/Umbraco.Core/Media/Exif/JPEGExceptions.cs rename to src/Umbraco.Web/Media/Exif/JPEGExceptions.cs index 40b62b25cc..631c3cb1b9 100644 --- a/src/Umbraco.Core/Media/Exif/JPEGExceptions.cs +++ b/src/Umbraco.Web/Media/Exif/JPEGExceptions.cs @@ -1,6 +1,6 @@ using System; -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// diff --git a/src/Umbraco.Core/Media/Exif/JPEGFile.cs b/src/Umbraco.Web/Media/Exif/JPEGFile.cs similarity index 99% rename from src/Umbraco.Core/Media/Exif/JPEGFile.cs rename to src/Umbraco.Web/Media/Exif/JPEGFile.cs index 032668dc0a..d7a5d322dc 100644 --- a/src/Umbraco.Core/Media/Exif/JPEGFile.cs +++ b/src/Umbraco.Web/Media/Exif/JPEGFile.cs @@ -4,7 +4,7 @@ using System.Drawing; using System.IO; using System.Text; -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Represents the binary view of a JPEG compressed file. diff --git a/src/Umbraco.Core/Media/Exif/JPEGMarker.cs b/src/Umbraco.Web/Media/Exif/JPEGMarker.cs similarity index 98% rename from src/Umbraco.Core/Media/Exif/JPEGMarker.cs rename to src/Umbraco.Web/Media/Exif/JPEGMarker.cs index ac65023976..3fb04dff28 100644 --- a/src/Umbraco.Core/Media/Exif/JPEGMarker.cs +++ b/src/Umbraco.Web/Media/Exif/JPEGMarker.cs @@ -1,4 +1,4 @@ -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Represents a JPEG marker byte. diff --git a/src/Umbraco.Core/Media/Exif/JPEGSection.cs b/src/Umbraco.Web/Media/Exif/JPEGSection.cs similarity index 98% rename from src/Umbraco.Core/Media/Exif/JPEGSection.cs rename to src/Umbraco.Web/Media/Exif/JPEGSection.cs index 5062f05491..a1bc420fe4 100644 --- a/src/Umbraco.Core/Media/Exif/JPEGSection.cs +++ b/src/Umbraco.Web/Media/Exif/JPEGSection.cs @@ -1,4 +1,4 @@ -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Represents the memory view of a JPEG section. diff --git a/src/Umbraco.Core/Media/Exif/MathEx.cs b/src/Umbraco.Web/Media/Exif/MathEx.cs similarity index 99% rename from src/Umbraco.Core/Media/Exif/MathEx.cs rename to src/Umbraco.Web/Media/Exif/MathEx.cs index 5364d18d0f..508c5025f7 100644 --- a/src/Umbraco.Core/Media/Exif/MathEx.cs +++ b/src/Umbraco.Web/Media/Exif/MathEx.cs @@ -1,7 +1,7 @@ using System; using System.Text; -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Contains extended Math functions. diff --git a/src/Umbraco.Core/Media/Exif/TIFFFile.cs b/src/Umbraco.Web/Media/Exif/TIFFFile.cs similarity index 99% rename from src/Umbraco.Core/Media/Exif/TIFFFile.cs rename to src/Umbraco.Web/Media/Exif/TIFFFile.cs index 5988a37b18..4f5301d526 100644 --- a/src/Umbraco.Core/Media/Exif/TIFFFile.cs +++ b/src/Umbraco.Web/Media/Exif/TIFFFile.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Drawing; using System.IO; -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Represents the binary view of a TIFF file. diff --git a/src/Umbraco.Core/Media/Exif/TIFFHeader.cs b/src/Umbraco.Web/Media/Exif/TIFFHeader.cs similarity index 98% rename from src/Umbraco.Core/Media/Exif/TIFFHeader.cs rename to src/Umbraco.Web/Media/Exif/TIFFHeader.cs index 89b0c02c2e..339525ef2c 100644 --- a/src/Umbraco.Core/Media/Exif/TIFFHeader.cs +++ b/src/Umbraco.Web/Media/Exif/TIFFHeader.cs @@ -1,4 +1,4 @@ -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Represents a TIFF Header. diff --git a/src/Umbraco.Core/Media/Exif/TIFFStrip.cs b/src/Umbraco.Web/Media/Exif/TIFFStrip.cs similarity index 96% rename from src/Umbraco.Core/Media/Exif/TIFFStrip.cs rename to src/Umbraco.Web/Media/Exif/TIFFStrip.cs index 52ca4e5034..8207eb64e8 100644 --- a/src/Umbraco.Core/Media/Exif/TIFFStrip.cs +++ b/src/Umbraco.Web/Media/Exif/TIFFStrip.cs @@ -1,6 +1,6 @@ using System; -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Represents a strip of compressed image data in a TIFF file. diff --git a/src/Umbraco.Core/Media/Exif/Utility.cs b/src/Umbraco.Web/Media/Exif/Utility.cs similarity index 96% rename from src/Umbraco.Core/Media/Exif/Utility.cs rename to src/Umbraco.Web/Media/Exif/Utility.cs index 2d7a304c3e..d2daa3b632 100644 --- a/src/Umbraco.Core/Media/Exif/Utility.cs +++ b/src/Umbraco.Web/Media/Exif/Utility.cs @@ -1,6 +1,6 @@ using System.IO; -namespace Umbraco.Core.Media.Exif +namespace Umbraco.Web.Media.Exif { /// /// Contains utility functions. diff --git a/src/Umbraco.Web/Media/ImageHelper.cs b/src/Umbraco.Web/Media/ImageHelper.cs new file mode 100644 index 0000000000..90eb3dc848 --- /dev/null +++ b/src/Umbraco.Web/Media/ImageHelper.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Umbraco.Core; +using Umbraco.Core.Configuration; +using Umbraco.Core.Configuration.UmbracoSettings; +using Umbraco.Core.IO; +using Umbraco.Core.Media; +using Umbraco.Core.Models; +using Umbraco.Web.Composing; +using Umbraco.Web.Media.Exif; + +namespace Umbraco.Web.Media +{ + public static class ImageHelper + { + /// + /// Gets the dimensions of an image. + /// + /// A stream containing the image bytes. + /// The dimension of the image. + /// First try with EXIF as it is faster and does not load the entire image + /// in memory. Fallback to GDI which means loading the image in memory and thus + /// use potentially large amounts of memory. + public static Size GetDimensions(Stream stream) + { + //Try to load with exif + try + { + var jpgInfo = ImageFile.FromStream(stream); + + if (jpgInfo.Format != ImageFileFormat.Unknown + && jpgInfo.Properties.ContainsKey(ExifTag.PixelYDimension) + && jpgInfo.Properties.ContainsKey(ExifTag.PixelXDimension)) + { + var height = Convert.ToInt32(jpgInfo.Properties[ExifTag.PixelYDimension].Value); + var width = Convert.ToInt32(jpgInfo.Properties[ExifTag.PixelXDimension].Value); + if (height > 0 && width > 0) + { + return new Size(width, height); + } + } + } + catch (Exception) + { + //We will just swallow, just means we can't read exif data, we don't want to log an error either + } + + //we have no choice but to try to read in via GDI + using (var image = Image.FromStream(stream)) + { + + var fileWidth = image.Width; + var fileHeight = image.Height; + return new Size(fileWidth, fileHeight); + } + } + + + + } +} diff --git a/src/Umbraco.Core/Media/UploadAutoFillProperties.cs b/src/Umbraco.Web/Media/UploadAutoFillProperties.cs similarity index 60% rename from src/Umbraco.Core/Media/UploadAutoFillProperties.cs rename to src/Umbraco.Web/Media/UploadAutoFillProperties.cs index 2045e947ac..6a56dec918 100644 --- a/src/Umbraco.Core/Media/UploadAutoFillProperties.cs +++ b/src/Umbraco.Web/Media/UploadAutoFillProperties.cs @@ -2,58 +2,28 @@ using System.Drawing; using System.IO; using System.Linq; +using Umbraco.Core; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; -namespace Umbraco.Core.Media +namespace Umbraco.Web.Media { /// /// Provides methods to manage auto-fill properties for upload fields. /// internal class UploadAutoFillProperties { - private readonly ILogger _logger; private readonly MediaFileSystem _mediaFileSystem; - private readonly IContentSection _contentSettings; + private readonly ILogger _logger; + private readonly IContentSection _contentSection; - public UploadAutoFillProperties(MediaFileSystem mediaFileSystem, ILogger logger, IContentSection contentSettings) + public UploadAutoFillProperties(MediaFileSystem mediaFileSystem, ILogger logger, IContentSection contentSection) { - _mediaFileSystem = mediaFileSystem; - _logger = logger; - _contentSettings = contentSettings; - } - - /// - /// Gets the auto-fill configuration for a specified property alias. - /// - /// The property type alias. - /// The auto-fill configuration for the specified property alias, or null. - public IImagingAutoFillUploadField GetConfig(string propertyTypeAlias) - { - var autoFillConfigs = _contentSettings.ImageAutoFillProperties; - return autoFillConfigs?.FirstOrDefault(x => x.Alias == propertyTypeAlias); - } - - /// - /// Resets the auto-fill properties of a content item, for a specified property alias. - /// - /// The content item. - /// The property type alias. - /// Variation language. - /// Variation segment. - public void Reset(IContentBase content, string propertyTypeAlias, string culture, string segment) - { - if (content == null) throw new ArgumentNullException(nameof(content)); - if (propertyTypeAlias == null) throw new ArgumentNullException(nameof(propertyTypeAlias)); - - // get the config, no config = nothing to do - var autoFillConfig = GetConfig(propertyTypeAlias); - if (autoFillConfig == null) return; // nothing - - // reset - Reset(content, autoFillConfig, culture, segment); + _mediaFileSystem = mediaFileSystem ?? throw new ArgumentNullException(nameof(mediaFileSystem)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _contentSection = contentSection ?? throw new ArgumentNullException(nameof(contentSection)); } /// @@ -70,56 +40,7 @@ namespace Umbraco.Core.Media ResetProperties(content, autoFillConfig, culture, segment); } - - /// - /// Populates the auto-fill properties of a content item. - /// - /// The content item. - /// The property type alias. - /// The filesystem-relative filepath, or null to clear properties. - /// Variation language. - /// Variation segment. - public void Populate(IContentBase content, string propertyTypeAlias, string filepath, string culture, string segment) - { - if (content == null) throw new ArgumentNullException(nameof(content)); - if (propertyTypeAlias == null) throw new ArgumentNullException(nameof(propertyTypeAlias)); - - // no property = nothing to do - if (content.Properties.Contains(propertyTypeAlias) == false) return; - - // get the config, no config = nothing to do - var autoFillConfig = GetConfig(propertyTypeAlias); - if (autoFillConfig == null) return; // nothing - - // populate - Populate(content, autoFillConfig, filepath, culture, segment); - } - - /// - /// Populates the auto-fill properties of a content item. - /// - /// The content item. - /// The property type alias. - /// The filesystem-relative filepath, or null to clear properties. - /// The stream containing the file data. - /// Variation language. - /// Variation segment. - public void Populate(IContentBase content, string propertyTypeAlias, string filepath, Stream filestream, string culture, string segment) - { - if (content == null) throw new ArgumentNullException(nameof(content)); - if (propertyTypeAlias == null) throw new ArgumentNullException(nameof(propertyTypeAlias)); - - // no property = nothing to do - if (content.Properties.Contains(propertyTypeAlias) == false) return; - - // get the config, no config = nothing to do - var autoFillConfig = GetConfig(propertyTypeAlias); - if (autoFillConfig == null) return; // nothing - - // populate - Populate(content, autoFillConfig, filepath, filestream, culture, segment); - } - + /// /// Populates the auto-fill properties of a content item, for a specified auto-fill configuration. /// @@ -147,7 +68,7 @@ namespace Umbraco.Core.Media using (var filestream = _mediaFileSystem.OpenFile(filepath)) { var extension = (Path.GetExtension(filepath) ?? "").TrimStart('.'); - var size = _mediaFileSystem.IsImageFile(extension) ? (Size?) _mediaFileSystem.GetDimensions(filestream) : null; + var size = _contentSection.IsImageFile(extension) ? (Size?)ImageHelper.GetDimensions(filestream) : null; SetProperties(content, autoFillConfig, size, filestream.Length, extension, culture, segment); } } @@ -181,7 +102,7 @@ namespace Umbraco.Core.Media else { var extension = (Path.GetExtension(filepath) ?? "").TrimStart('.'); - var size = _mediaFileSystem.IsImageFile(extension) ? (Size?)_mediaFileSystem.GetDimensions(filestream) : null; + var size = _contentSection.IsImageFile(extension) ? (Size?)ImageHelper.GetDimensions(filestream) : null; SetProperties(content, autoFillConfig, size, filestream.Length, extension, culture, segment); } } diff --git a/src/Umbraco.Web/Models/Mapping/CreatorResolver.cs b/src/Umbraco.Web/Models/Mapping/CreatorResolver.cs index 44ac768fb4..40ebc801eb 100644 --- a/src/Umbraco.Web/Models/Mapping/CreatorResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/CreatorResolver.cs @@ -1,4 +1,5 @@ using AutoMapper; +using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; using Umbraco.Core.Services; diff --git a/src/Umbraco.Web/Models/Mapping/OwnerResolver.cs b/src/Umbraco.Web/Models/Mapping/OwnerResolver.cs index 68e1a1ff91..671f915e3b 100644 --- a/src/Umbraco.Web/Models/Mapping/OwnerResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/OwnerResolver.cs @@ -1,4 +1,5 @@ using AutoMapper; +using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; using Umbraco.Core.Services; diff --git a/src/Umbraco.Core/Security/OwinExtensions.cs b/src/Umbraco.Web/OwinExtensions.cs similarity index 83% rename from src/Umbraco.Core/Security/OwinExtensions.cs rename to src/Umbraco.Web/OwinExtensions.cs index a4d596855c..e7e1e85b50 100644 --- a/src/Umbraco.Core/Security/OwinExtensions.cs +++ b/src/Umbraco.Web/OwinExtensions.cs @@ -3,12 +3,26 @@ using System.Web; using Microsoft.AspNet.Identity.Owin; using Microsoft.Owin; using Microsoft.Owin.Security; +using Umbraco.Core; using Umbraco.Core.Models.Identity; +using Umbraco.Core.Security; +using Umbraco.Web.Security; -namespace Umbraco.Core.Security +namespace Umbraco.Web { public static class OwinExtensions { + /// + /// Gets the for the Umbraco back office cookie + /// + /// + /// + internal static ISecureDataFormat GetUmbracoAuthTicketDataProtector(this IOwinContext owinContext) + { + var found = owinContext.Get(); + return found?.Protector; + } + public static string GetCurrentRequestIpAddress(this IOwinContext owinContext) { if (owinContext == null) @@ -68,7 +82,6 @@ namespace Umbraco.Core.Security return marker.GetManager(owinContext) ?? throw new NullReferenceException($"Could not resolve an instance of {typeof (BackOfficeUserManager)} from the {typeof (IOwinContext)}."); } - } } diff --git a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs index ac146c3251..412b8c9766 100644 --- a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs @@ -2,11 +2,13 @@ using System.Collections.Generic; using System.Linq; using Umbraco.Core; +using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; +using Umbraco.Web.Media; namespace Umbraco.Web.PropertyEditors { @@ -14,11 +16,15 @@ namespace Umbraco.Web.PropertyEditors public class FileUploadPropertyEditor : DataEditor { private readonly MediaFileSystem _mediaFileSystem; + private readonly IContentSection _contentSection; + private readonly UploadAutoFillProperties _uploadAutoFillProperties; - public FileUploadPropertyEditor(ILogger logger, MediaFileSystem mediaFileSystem) + public FileUploadPropertyEditor(ILogger logger, MediaFileSystem mediaFileSystem, IContentSection contentSection) : base(logger) { _mediaFileSystem = mediaFileSystem ?? throw new ArgumentNullException(nameof(mediaFileSystem)); + _contentSection = contentSection; + _uploadAutoFillProperties = new UploadAutoFillProperties(_mediaFileSystem, logger, contentSection); } /// @@ -148,16 +154,16 @@ namespace Umbraco.Web.PropertyEditors foreach (var property in properties) { - var autoFillConfig = _mediaFileSystem.UploadAutoFillProperties.GetConfig(property.Alias); + var autoFillConfig = _contentSection.GetConfig(property.Alias); if (autoFillConfig == null) continue; foreach (var pvalue in property.Values) { var svalue = property.GetValue(pvalue.Culture, pvalue.Segment) as string; if (string.IsNullOrWhiteSpace(svalue)) - _mediaFileSystem.UploadAutoFillProperties.Reset(model, autoFillConfig, pvalue.Culture, pvalue.Segment); + _uploadAutoFillProperties.Reset(model, autoFillConfig, pvalue.Culture, pvalue.Segment); else - _mediaFileSystem.UploadAutoFillProperties.Populate(model, autoFillConfig, _mediaFileSystem.GetRelativePath(svalue), pvalue.Culture, pvalue.Segment); + _uploadAutoFillProperties.Populate(model, autoFillConfig, _mediaFileSystem.GetRelativePath(svalue), pvalue.Culture, pvalue.Segment); } } } diff --git a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyValueEditor.cs b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyValueEditor.cs index be7b3ff2f8..47711507b2 100644 --- a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyValueEditor.cs @@ -91,6 +91,7 @@ namespace Umbraco.Web.PropertyEditors // update json and return if (editorFile == null) return null; return filepath == null ? string.Empty : _mediaFileSystem.GetUrl(filepath); + } @@ -107,6 +108,9 @@ namespace Umbraco.Web.PropertyEditors using (var filestream = File.OpenRead(file.TempFilePath)) { + //TODO: Here it would make sense to do the auto-fill properties stuff but the API doesn't allow us to do that right + // since we'd need to be able to return values for other properties from these methods + _mediaFileSystem.AddFile(filepath, filestream, true); // must overwrite! } diff --git a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs index 2a74b4f05c..c8a7bfc80c 100644 --- a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyEditor.cs @@ -10,7 +10,9 @@ using Umbraco.Core.Logging; using Umbraco.Core.Media; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; +using Umbraco.Core.PropertyEditors.ValueConverters; using Umbraco.Core.Services; +using Umbraco.Web.Media; namespace Umbraco.Web.PropertyEditors { @@ -21,18 +23,22 @@ namespace Umbraco.Web.PropertyEditors public class ImageCropperPropertyEditor : DataEditor { private readonly MediaFileSystem _mediaFileSystem; + private readonly IContentSection _contentSettings; + private readonly IDataTypeService _dataTypeService; private readonly UploadAutoFillProperties _autoFillProperties; /// /// Initializes a new instance of the class. /// - public ImageCropperPropertyEditor(ILogger logger, MediaFileSystem mediaFileSystem, IContentSection contentSettings) + public ImageCropperPropertyEditor(ILogger logger, MediaFileSystem mediaFileSystem, IContentSection contentSettings, IDataTypeService dataTypeService) : base(logger) { _mediaFileSystem = mediaFileSystem ?? throw new ArgumentNullException(nameof(mediaFileSystem)); - var contentSettings1 = contentSettings ?? throw new ArgumentNullException(nameof(contentSettings)); + _contentSettings = contentSettings ?? throw new ArgumentNullException(nameof(contentSettings)); + _dataTypeService = dataTypeService; - _autoFillProperties = new UploadAutoFillProperties(_mediaFileSystem, Logger, contentSettings1); + //fixme: inject? + _autoFillProperties = new UploadAutoFillProperties(_mediaFileSystem, logger, _contentSettings); } /// @@ -204,7 +210,7 @@ namespace Umbraco.Web.PropertyEditors foreach (var property in properties) { - var autoFillConfig = _autoFillProperties.GetConfig(property.Alias); + var autoFillConfig = _contentSettings.GetConfig(property.Alias); if (autoFillConfig == null) continue; foreach (var pvalue in property.Values) @@ -213,40 +219,40 @@ namespace Umbraco.Web.PropertyEditors if (string.IsNullOrWhiteSpace(svalue)) { _autoFillProperties.Reset(model, autoFillConfig, pvalue.Culture, pvalue.Segment); - continue; - } - - // FIXME VERY TEMP - // we should kill all auto-fill properties - // BUT that being said what would be the right way to do this? - /* - var v = JsonConvert.DeserializeObject() - - var jo = GetJObject(svalue, false); - string src; - if (jo == null) - { - // so we have a non-empty string value that cannot be parsed into a json object - // see http://issues.umbraco.org/issue/U4-4756 - // it can happen when an image is uploaded via the folder browser, in which case - // the property value will be the file source eg '/media/23454/hello.jpg' and we - // are fixing that anomaly here - does not make any sense at all but... bah... - var config = _dataTypeService - .GetPreValuesByDataTypeId(property.PropertyType.DataTypeDefinitionId).FirstOrDefault(); - var crops = string.IsNullOrWhiteSpace(config) ? "[]" : config; - src = svalue; - property.SetValue("{\"src\": \"" + svalue + "\", \"crops\": " + crops + "}"); } else { - src = jo["src"]?.Value(); - } + var jo = GetJObject(svalue, false); + string src; + if (jo == null) + { + // so we have a non-empty string value that cannot be parsed into a json object + // see http://issues.umbraco.org/issue/U4-4756 + // it can happen when an image is uploaded via the folder browser, in which case + // the property value will be the file source eg '/media/23454/hello.jpg' and we + // are fixing that anomaly here - does not make any sense at all but... bah... - if (src == null) - _autoFillProperties.Reset(model, autoFillConfig, pvalue.LanguageId, pvalue.Segment); - else - _autoFillProperties.Populate(model, autoFillConfig, _mediaFileSystem.GetRelativePath(src), pvalue.LanguageId, pvalue.Segment); - */ + var dt = _dataTypeService.GetDataType(property.PropertyType.DataTypeId); + var config = dt?.ConfigurationAs(); + src = svalue; + var json = new + { + src = svalue, + crops = config == null ? Array.Empty() : config.Crops + }; + + property.SetValue(JsonConvert.SerializeObject(json), pvalue.Culture, pvalue.Segment); + } + else + { + src = jo["src"]?.Value(); + } + + if (src == null) + _autoFillProperties.Reset(model, autoFillConfig, pvalue.Culture, pvalue.Segment); + else + _autoFillProperties.Populate(model, autoFillConfig, _mediaFileSystem.GetRelativePath(src), pvalue.Culture, pvalue.Segment); + } } } } diff --git a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs index 98e8346441..4f44352d34 100644 --- a/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ImageCropperPropertyValueEditor.cs @@ -151,6 +151,9 @@ namespace Umbraco.Web.PropertyEditors using (var filestream = File.OpenRead(file.TempFilePath)) { + //TODO: Here it would make sense to do the auto-fill properties stuff but the API doesn't allow us to do that right + // since we'd need to be able to return values for other properties from these methods + _mediaFileSystem.AddFile(filepath, filestream, true); // must overwrite! } diff --git a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs index adb9e1a837..0b091e0d47 100644 --- a/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/RichTextPropertyEditor.cs @@ -6,6 +6,7 @@ using Umbraco.Core.Macros; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; +using Umbraco.Web.Macros; namespace Umbraco.Web.PropertyEditors { diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/MacroContainerValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/MacroContainerValueConverter.cs index 2785f160bf..cd2f4e5384 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/MacroContainerValueConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/MacroContainerValueConverter.cs @@ -8,6 +8,7 @@ using Umbraco.Core.Macros; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; +using Umbraco.Web.Macros; namespace Umbraco.Web.PropertyEditors.ValueConverters { diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs index 32c3ffb2c7..70c4ca0d0b 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs @@ -9,6 +9,7 @@ using System.Linq; using HtmlAgilityPack; using Umbraco.Core.Cache; using Umbraco.Core.Services; +using Umbraco.Web.Macros; namespace Umbraco.Web.PropertyEditors.ValueConverters { diff --git a/src/Umbraco.Core/Security/ActiveDirectoryBackOfficeUserPasswordChecker.cs b/src/Umbraco.Web/Security/ActiveDirectoryBackOfficeUserPasswordChecker.cs similarity index 93% rename from src/Umbraco.Core/Security/ActiveDirectoryBackOfficeUserPasswordChecker.cs rename to src/Umbraco.Web/Security/ActiveDirectoryBackOfficeUserPasswordChecker.cs index 41028e38b3..3ac74bd7c0 100644 --- a/src/Umbraco.Core/Security/ActiveDirectoryBackOfficeUserPasswordChecker.cs +++ b/src/Umbraco.Web/Security/ActiveDirectoryBackOfficeUserPasswordChecker.cs @@ -4,8 +4,9 @@ using System.DirectoryServices.AccountManagement; using System.Threading.Tasks; using Umbraco.Core.Models.Identity; -namespace Umbraco.Core.Security +namespace Umbraco.Web.Security { + //TODO: This relies on an assembly that is not .NET Standard :( public class ActiveDirectoryBackOfficeUserPasswordChecker : IBackOfficeUserPasswordChecker { public virtual string ActiveDirectoryDomain diff --git a/src/Umbraco.Web/Security/Identity/AppBuilderExtensions.cs b/src/Umbraco.Web/Security/AppBuilderExtensions.cs similarity index 99% rename from src/Umbraco.Web/Security/Identity/AppBuilderExtensions.cs rename to src/Umbraco.Web/Security/AppBuilderExtensions.cs index 48b505c80c..ddcf87e9c7 100644 --- a/src/Umbraco.Web/Security/Identity/AppBuilderExtensions.cs +++ b/src/Umbraco.Web/Security/AppBuilderExtensions.cs @@ -2,7 +2,6 @@ using System.Threading; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.Owin; -using Microsoft.AspNet.SignalR; using Microsoft.Owin; using Microsoft.Owin.Extensions; using Microsoft.Owin.Logging; @@ -20,7 +19,7 @@ using Umbraco.Core.Services; using Umbraco.Web.Composing; using Constants = Umbraco.Core.Constants; -namespace Umbraco.Web.Security.Identity +namespace Umbraco.Web.Security { /// /// Provides security/identity extension methods to IAppBuilder. @@ -167,7 +166,7 @@ namespace Umbraco.Web.Security.Identity OnValidateIdentity = SecurityStampValidator .OnValidateIdentity( TimeSpan.FromMinutes(30), - (manager, user) => user.GenerateUserIdentityAsync(manager), + (manager, user) => manager.GenerateUserIdentityAsync(user), identity => identity.GetUserId()), }; diff --git a/src/Umbraco.Web/Security/Identity/AuthenticationManagerExtensions.cs b/src/Umbraco.Web/Security/AuthenticationManagerExtensions.cs similarity index 98% rename from src/Umbraco.Web/Security/Identity/AuthenticationManagerExtensions.cs rename to src/Umbraco.Web/Security/AuthenticationManagerExtensions.cs index 4dfa5a7f5b..5da9c77d6b 100644 --- a/src/Umbraco.Web/Security/Identity/AuthenticationManagerExtensions.cs +++ b/src/Umbraco.Web/Security/AuthenticationManagerExtensions.cs @@ -5,7 +5,7 @@ using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.Owin; using Microsoft.Owin.Security; -namespace Umbraco.Web.Security.Identity +namespace Umbraco.Web.Security { public static class AuthenticationManagerExtensions { diff --git a/src/Umbraco.Web/Security/Identity/AuthenticationOptionsExtensions.cs b/src/Umbraco.Web/Security/AuthenticationOptionsExtensions.cs similarity index 98% rename from src/Umbraco.Web/Security/Identity/AuthenticationOptionsExtensions.cs rename to src/Umbraco.Web/Security/AuthenticationOptionsExtensions.cs index 20f93f44a6..33aabbaf94 100644 --- a/src/Umbraco.Web/Security/Identity/AuthenticationOptionsExtensions.cs +++ b/src/Umbraco.Web/Security/AuthenticationOptionsExtensions.cs @@ -2,11 +2,10 @@ using Microsoft.Owin; using Microsoft.Owin.Security; using Umbraco.Core; -using Umbraco.Core.Logging; using Umbraco.Core.Composing; using Umbraco.Core.Exceptions; -namespace Umbraco.Web.Security.Identity +namespace Umbraco.Web.Security { public static class AuthenticationOptionsExtensions { diff --git a/src/Umbraco.Core/Security/BackOfficeClaimsIdentityFactory.cs b/src/Umbraco.Web/Security/BackOfficeClaimsIdentityFactory.cs similarity index 94% rename from src/Umbraco.Core/Security/BackOfficeClaimsIdentityFactory.cs rename to src/Umbraco.Web/Security/BackOfficeClaimsIdentityFactory.cs index 490e667c17..fbc24d2cd9 100644 --- a/src/Umbraco.Core/Security/BackOfficeClaimsIdentityFactory.cs +++ b/src/Umbraco.Web/Security/BackOfficeClaimsIdentityFactory.cs @@ -4,8 +4,10 @@ using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Identity; using Umbraco.Core.Models.Identity; +using Umbraco.Core.Security; +using Constants = Umbraco.Core.Constants; -namespace Umbraco.Core.Security +namespace Umbraco.Web.Security { public class BackOfficeClaimsIdentityFactory : ClaimsIdentityFactory where T: BackOfficeIdentityUser diff --git a/src/Umbraco.Core/Security/BackOfficeCookieAuthenticationProvider.cs b/src/Umbraco.Web/Security/BackOfficeCookieAuthenticationProvider.cs similarity index 92% rename from src/Umbraco.Core/Security/BackOfficeCookieAuthenticationProvider.cs rename to src/Umbraco.Web/Security/BackOfficeCookieAuthenticationProvider.cs index 4d6a4fdaeb..e12e2ac4f8 100644 --- a/src/Umbraco.Core/Security/BackOfficeCookieAuthenticationProvider.cs +++ b/src/Umbraco.Web/Security/BackOfficeCookieAuthenticationProvider.cs @@ -8,11 +8,13 @@ using System.Threading.Tasks; using Microsoft.AspNet.Identity; using Microsoft.Owin; using Microsoft.Owin.Security.Cookies; +using Umbraco.Core; using Umbraco.Core.Composing; using Umbraco.Core.Configuration; +using Umbraco.Core.Security; using Umbraco.Core.Services; -namespace Umbraco.Core.Security +namespace Umbraco.Web.Security { public class BackOfficeCookieAuthenticationProvider : CookieAuthenticationProvider { @@ -50,7 +52,7 @@ namespace Umbraco.Core.Security if (context?.OwinContext?.Authentication?.User?.Identity != null) { var claimsIdentity = context.OwinContext.Authentication.User.Identity as ClaimsIdentity; - var sessionId = claimsIdentity.FindFirstValue(Constants.Security.SessionIdClaimType); + var sessionId = claimsIdentity.FindFirstValue(Core.Constants.Security.SessionIdClaimType); if (sessionId.IsNullOrWhiteSpace() == false && Guid.TryParse(sessionId, out var guidSession)) { _userService.ClearLoginSession(guidSession); @@ -70,12 +72,12 @@ namespace Umbraco.Core.Security Expires = DateTime.Now.AddYears(-1), Path = "/" }); - context.Response.Cookies.Append(Constants.Web.PreviewCookieName, "", new CookieOptions + context.Response.Cookies.Append(Core.Constants.Web.PreviewCookieName, "", new CookieOptions { Expires = DateTime.Now.AddYears(-1), Path = "/" }); - context.Response.Cookies.Append(Constants.Security.BackOfficeExternalCookieName, "", new CookieOptions + context.Response.Cookies.Append(Core.Constants.Security.BackOfficeExternalCookieName, "", new CookieOptions { Expires = DateTime.Now.AddYears(-1), Path = "/" diff --git a/src/Umbraco.Web/Security/Identity/BackOfficeCookieManager.cs b/src/Umbraco.Web/Security/BackOfficeCookieManager.cs similarity index 99% rename from src/Umbraco.Web/Security/Identity/BackOfficeCookieManager.cs rename to src/Umbraco.Web/Security/BackOfficeCookieManager.cs index 204cd18072..5da86204f3 100644 --- a/src/Umbraco.Web/Security/Identity/BackOfficeCookieManager.cs +++ b/src/Umbraco.Web/Security/BackOfficeCookieManager.cs @@ -8,7 +8,7 @@ using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.Security; -namespace Umbraco.Web.Security.Identity +namespace Umbraco.Web.Security { /// /// A custom cookie manager that is used to read the cookie from the request. diff --git a/src/Umbraco.Core/Security/BackOfficeSignInManager.cs b/src/Umbraco.Web/Security/BackOfficeSignInManager.cs similarity index 98% rename from src/Umbraco.Core/Security/BackOfficeSignInManager.cs rename to src/Umbraco.Web/Security/BackOfficeSignInManager.cs index d156871697..b711fe76cf 100644 --- a/src/Umbraco.Core/Security/BackOfficeSignInManager.cs +++ b/src/Umbraco.Web/Security/BackOfficeSignInManager.cs @@ -9,8 +9,10 @@ using Microsoft.Owin.Logging; using Microsoft.Owin.Security; using Umbraco.Core.Configuration; using Umbraco.Core.Models.Identity; +using Umbraco.Core.Security; +using Constants = Umbraco.Core.Constants; -namespace Umbraco.Core.Security +namespace Umbraco.Web.Security { //TODO: In v8 we need to change this to use an int? nullable TKey instead, see notes against overridden TwoFactorSignInAsync public class BackOfficeSignInManager : SignInManager @@ -32,7 +34,7 @@ namespace Umbraco.Core.Security public override Task CreateUserIdentityAsync(BackOfficeIdentityUser user) { - return user.GenerateUserIdentityAsync((BackOfficeUserManager)UserManager); + return ((BackOfficeUserManager)UserManager).GenerateUserIdentityAsync(user); } public static BackOfficeSignInManager Create(IdentityFactoryOptions options, IOwinContext context, IGlobalSettings globalSettings, ILogger logger) diff --git a/src/Umbraco.Core/Security/BackOfficeUserManager.cs b/src/Umbraco.Web/Security/BackOfficeUserManager.cs similarity index 98% rename from src/Umbraco.Core/Security/BackOfficeUserManager.cs rename to src/Umbraco.Web/Security/BackOfficeUserManager.cs index c4406054e6..828aed588c 100644 --- a/src/Umbraco.Core/Security/BackOfficeUserManager.cs +++ b/src/Umbraco.Web/Security/BackOfficeUserManager.cs @@ -1,23 +1,20 @@ using System; -using System.ComponentModel; -using System.Configuration.Provider; using System.Linq; -using System.Text; +using System.Security.Claims; using System.Threading.Tasks; -using System.Web.Security; using System.Web; +using System.Web.Security; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.Owin; using Microsoft.Owin.Security.DataProtection; -using Umbraco.Core.Composing; -using Umbraco.Core.Auditing; +using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Models.Identity; -using Umbraco.Core.Models.Membership; +using Umbraco.Core.Security; using Umbraco.Core.Services; -namespace Umbraco.Core.Security +namespace Umbraco.Web.Security { /// /// Default back office user manager @@ -154,7 +151,15 @@ namespace Umbraco.Core.Security get { return false; } } #endregion - + + public virtual async Task GenerateUserIdentityAsync(T user) + { + // NOTE the authenticationType must match the umbraco one + // defined in CookieAuthenticationOptions.AuthenticationType + var userIdentity = await CreateIdentityAsync(user, Core.Constants.Security.BackOfficeAuthenticationType); + return userIdentity; + } + /// /// Initializes the user manager with the correct options /// diff --git a/src/Umbraco.Core/Security/BackOfficeUserManagerMarker.cs b/src/Umbraco.Web/Security/BackOfficeUserManagerMarker.cs similarity index 95% rename from src/Umbraco.Core/Security/BackOfficeUserManagerMarker.cs rename to src/Umbraco.Web/Security/BackOfficeUserManagerMarker.cs index 300350072e..2f5a160198 100644 --- a/src/Umbraco.Core/Security/BackOfficeUserManagerMarker.cs +++ b/src/Umbraco.Web/Security/BackOfficeUserManagerMarker.cs @@ -2,8 +2,9 @@ using Microsoft.AspNet.Identity.Owin; using Microsoft.Owin; using Umbraco.Core.Models.Identity; +using Umbraco.Core.Security; -namespace Umbraco.Core.Security +namespace Umbraco.Web.Security { /// /// This class is only here due to the fact that IOwinContext Get / Set only work in generics, if they worked diff --git a/src/Umbraco.Core/Security/BackOfficeUserPasswordCheckerResult.cs b/src/Umbraco.Web/Security/BackOfficeUserPasswordCheckerResult.cs similarity index 88% rename from src/Umbraco.Core/Security/BackOfficeUserPasswordCheckerResult.cs rename to src/Umbraco.Web/Security/BackOfficeUserPasswordCheckerResult.cs index 365a9941b2..5681bb4766 100644 --- a/src/Umbraco.Core/Security/BackOfficeUserPasswordCheckerResult.cs +++ b/src/Umbraco.Web/Security/BackOfficeUserPasswordCheckerResult.cs @@ -1,4 +1,4 @@ -namespace Umbraco.Core.Security +namespace Umbraco.Web.Security { /// /// The result returned from the IBackOfficeUserPasswordChecker diff --git a/src/Umbraco.Web/Security/Identity/ExternalSignInAutoLinkOptions.cs b/src/Umbraco.Web/Security/ExternalSignInAutoLinkOptions.cs similarity index 95% rename from src/Umbraco.Web/Security/Identity/ExternalSignInAutoLinkOptions.cs rename to src/Umbraco.Web/Security/ExternalSignInAutoLinkOptions.cs index fd074b9e96..a143233ff2 100644 --- a/src/Umbraco.Web/Security/Identity/ExternalSignInAutoLinkOptions.cs +++ b/src/Umbraco.Web/Security/ExternalSignInAutoLinkOptions.cs @@ -1,13 +1,9 @@ using System; -using System.ComponentModel; using Microsoft.AspNet.Identity.Owin; -using Microsoft.Owin; -using Umbraco.Core; using Umbraco.Core.Configuration; -using Umbraco.Core.Exceptions; using Umbraco.Core.Models.Identity; -namespace Umbraco.Web.Security.Identity +namespace Umbraco.Web.Security { /// /// Options used to configure auto-linking external OAuth providers diff --git a/src/Umbraco.Web/Security/Identity/FixWindowsAuthMiddlware.cs b/src/Umbraco.Web/Security/FixWindowsAuthMiddlware.cs similarity index 98% rename from src/Umbraco.Web/Security/Identity/FixWindowsAuthMiddlware.cs rename to src/Umbraco.Web/Security/FixWindowsAuthMiddlware.cs index aea1b14ecd..30038e1f31 100644 --- a/src/Umbraco.Web/Security/Identity/FixWindowsAuthMiddlware.cs +++ b/src/Umbraco.Web/Security/FixWindowsAuthMiddlware.cs @@ -6,7 +6,7 @@ using Microsoft.Owin; using Umbraco.Core; using Umbraco.Core.Security; -namespace Umbraco.Web.Security.Identity +namespace Umbraco.Web.Security { /// /// This is used to inspect the request to see if 2 x identities are assigned: A windows one and a back office one. diff --git a/src/Umbraco.Web/Security/Identity/ForceRenewalCookieAuthenticationHandler.cs b/src/Umbraco.Web/Security/ForceRenewalCookieAuthenticationHandler.cs similarity index 98% rename from src/Umbraco.Web/Security/Identity/ForceRenewalCookieAuthenticationHandler.cs rename to src/Umbraco.Web/Security/ForceRenewalCookieAuthenticationHandler.cs index f3c7013701..896a0ca63e 100644 --- a/src/Umbraco.Web/Security/Identity/ForceRenewalCookieAuthenticationHandler.cs +++ b/src/Umbraco.Web/Security/ForceRenewalCookieAuthenticationHandler.cs @@ -1,12 +1,11 @@ -using System; -using Umbraco.Core; -using System.Threading.Tasks; -using Umbraco.Core.Security; +using System.Threading.Tasks; using Microsoft.Owin.Security; using Microsoft.Owin.Security.Cookies; using Microsoft.Owin.Security.Infrastructure; +using Umbraco.Core; +using Umbraco.Core.Security; -namespace Umbraco.Web.Security.Identity +namespace Umbraco.Web.Security { /// /// If a flag is set on the context to force renew the ticket, this will do it diff --git a/src/Umbraco.Web/Security/Identity/ForceRenewalCookieAuthenticationMiddleware.cs b/src/Umbraco.Web/Security/ForceRenewalCookieAuthenticationMiddleware.cs similarity index 96% rename from src/Umbraco.Web/Security/Identity/ForceRenewalCookieAuthenticationMiddleware.cs rename to src/Umbraco.Web/Security/ForceRenewalCookieAuthenticationMiddleware.cs index 02d27eccbb..1b72412f1c 100644 --- a/src/Umbraco.Web/Security/Identity/ForceRenewalCookieAuthenticationMiddleware.cs +++ b/src/Umbraco.Web/Security/ForceRenewalCookieAuthenticationMiddleware.cs @@ -3,7 +3,7 @@ using Microsoft.Owin.Security.Cookies; using Microsoft.Owin.Security.Infrastructure; using Owin; -namespace Umbraco.Web.Security.Identity +namespace Umbraco.Web.Security { /// /// This middleware is used simply to force renew the auth ticket if a flag to do so is found in the request diff --git a/src/Umbraco.Web/Security/Identity/GetUserSecondsMiddleWare.cs b/src/Umbraco.Web/Security/GetUserSecondsMiddleWare.cs similarity index 98% rename from src/Umbraco.Web/Security/Identity/GetUserSecondsMiddleWare.cs rename to src/Umbraco.Web/Security/GetUserSecondsMiddleWare.cs index 25482f17af..dace264996 100644 --- a/src/Umbraco.Web/Security/Identity/GetUserSecondsMiddleWare.cs +++ b/src/Umbraco.Web/Security/GetUserSecondsMiddleWare.cs @@ -3,16 +3,14 @@ using System.Diagnostics; using System.Globalization; using System.Threading.Tasks; using System.Web; -using System.Web.Security; using Microsoft.Owin; using Microsoft.Owin.Logging; -using Microsoft.Owin.Security.Cookies; using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Security; -namespace Umbraco.Web.Security.Identity +namespace Umbraco.Web.Security { /// /// Custom middleware to return the remaining seconds the user has before they are logged out diff --git a/src/Umbraco.Core/Security/IBackOfficeUserManagerMarker.cs b/src/Umbraco.Web/Security/IBackOfficeUserManagerMarker.cs similarity index 94% rename from src/Umbraco.Core/Security/IBackOfficeUserManagerMarker.cs rename to src/Umbraco.Web/Security/IBackOfficeUserManagerMarker.cs index 5d3154ad2a..53e72ef159 100644 --- a/src/Umbraco.Core/Security/IBackOfficeUserManagerMarker.cs +++ b/src/Umbraco.Web/Security/IBackOfficeUserManagerMarker.cs @@ -1,7 +1,7 @@ using Microsoft.Owin; using Umbraco.Core.Models.Identity; -namespace Umbraco.Core.Security +namespace Umbraco.Web.Security { /// /// This interface is only here due to the fact that IOwinContext Get / Set only work in generics, if they worked diff --git a/src/Umbraco.Core/Security/IBackOfficeUserPasswordChecker.cs b/src/Umbraco.Web/Security/IBackOfficeUserPasswordChecker.cs similarity index 97% rename from src/Umbraco.Core/Security/IBackOfficeUserPasswordChecker.cs rename to src/Umbraco.Web/Security/IBackOfficeUserPasswordChecker.cs index 210e3109ab..c3ce15b487 100644 --- a/src/Umbraco.Core/Security/IBackOfficeUserPasswordChecker.cs +++ b/src/Umbraco.Web/Security/IBackOfficeUserPasswordChecker.cs @@ -1,7 +1,7 @@ using System.Threading.Tasks; using Umbraco.Core.Models.Identity; -namespace Umbraco.Core.Security +namespace Umbraco.Web.Security { /// /// Used by the BackOfficeUserManager to check the username/password which allows for developers to more easily diff --git a/src/Umbraco.Web/Security/Identity/IUmbracoBackOfficeTwoFactorOptions.cs b/src/Umbraco.Web/Security/IUmbracoBackOfficeTwoFactorOptions.cs similarity index 90% rename from src/Umbraco.Web/Security/Identity/IUmbracoBackOfficeTwoFactorOptions.cs rename to src/Umbraco.Web/Security/IUmbracoBackOfficeTwoFactorOptions.cs index 8a1ffc4614..acd49ec5e0 100644 --- a/src/Umbraco.Web/Security/Identity/IUmbracoBackOfficeTwoFactorOptions.cs +++ b/src/Umbraco.Web/Security/IUmbracoBackOfficeTwoFactorOptions.cs @@ -1,6 +1,6 @@ using Microsoft.Owin; -namespace Umbraco.Web.Security.Identity +namespace Umbraco.Web.Security { /// /// Used to display a custom view in the back office if developers choose to implement their own custom 2 factor authentication diff --git a/src/Umbraco.Core/Auditing/IdentityAuditEventArgs.cs b/src/Umbraco.Web/Security/IdentityAuditEventArgs.cs similarity index 98% rename from src/Umbraco.Core/Auditing/IdentityAuditEventArgs.cs rename to src/Umbraco.Web/Security/IdentityAuditEventArgs.cs index ff335434ab..4756390d06 100644 --- a/src/Umbraco.Core/Auditing/IdentityAuditEventArgs.cs +++ b/src/Umbraco.Web/Security/IdentityAuditEventArgs.cs @@ -1,10 +1,8 @@ using System; -using System.ComponentModel; using System.Threading; -using System.Web; using Umbraco.Core.Security; -namespace Umbraco.Core.Auditing +namespace Umbraco.Web.Security { /// /// This class is used by events raised from hthe BackofficeUserManager diff --git a/src/Umbraco.Web/Security/OwinExtensions.cs b/src/Umbraco.Web/Security/OwinExtensions.cs deleted file mode 100644 index 80ba0acfa4..0000000000 --- a/src/Umbraco.Web/Security/OwinExtensions.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Web; -using Microsoft.AspNet.Identity.Owin; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Umbraco.Core; -using Umbraco.Core.Models.Identity; -using Umbraco.Core.Security; -using Umbraco.Web.Security.Identity; - -namespace Umbraco.Web.Security -{ - internal static class OwinExtensions - { - /// - /// Gets the for the Umbraco back office cookie - /// - /// - /// - internal static ISecureDataFormat GetUmbracoAuthTicketDataProtector(this IOwinContext owinContext) - { - var found = owinContext.Get(); - return found?.Protector; - } - - } -} diff --git a/src/Umbraco.Web/Security/Identity/PreviewAuthenticationMiddleware.cs b/src/Umbraco.Web/Security/PreviewAuthenticationMiddleware.cs similarity index 85% rename from src/Umbraco.Web/Security/Identity/PreviewAuthenticationMiddleware.cs rename to src/Umbraco.Web/Security/PreviewAuthenticationMiddleware.cs index da3e74ab82..ccb2a81e51 100644 --- a/src/Umbraco.Web/Security/Identity/PreviewAuthenticationMiddleware.cs +++ b/src/Umbraco.Web/Security/PreviewAuthenticationMiddleware.cs @@ -1,28 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Security.Claims; -using System.Threading; +using System.Security.Claims; using System.Threading.Tasks; using System.Web; -using Microsoft.AspNet.Identity; -using Microsoft.AspNet.Identity.Owin; using Microsoft.Owin; -using Microsoft.Owin.Extensions; -using Microsoft.Owin.Logging; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Cookies; -using Owin; using Umbraco.Core; using Umbraco.Core.Configuration; -using Umbraco.Core.IO; -using Umbraco.Core.Logging; -using Umbraco.Core.Models.Identity; using Umbraco.Core.Security; -using Constants = Umbraco.Core.Constants; -namespace Umbraco.Web.Security.Identity +namespace Umbraco.Web.Security { internal class PreviewAuthenticationMiddleware : OwinMiddleware { diff --git a/src/Umbraco.Core/Security/SessionIdValidator.cs b/src/Umbraco.Web/Security/SessionIdValidator.cs similarity index 97% rename from src/Umbraco.Core/Security/SessionIdValidator.cs rename to src/Umbraco.Web/Security/SessionIdValidator.cs index f738ad9c22..e5e1394aea 100644 --- a/src/Umbraco.Core/Security/SessionIdValidator.cs +++ b/src/Umbraco.Web/Security/SessionIdValidator.cs @@ -1,7 +1,5 @@ using System; -using System.Collections.Concurrent; using System.Security.Claims; -using System.Threading; using System.Threading.Tasks; using System.Web; using Microsoft.AspNet.Identity; @@ -9,10 +7,12 @@ using Microsoft.AspNet.Identity.Owin; using Microsoft.Owin; using Microsoft.Owin.Infrastructure; using Microsoft.Owin.Security.Cookies; +using Umbraco.Core; using Umbraco.Core.Configuration; -using Umbraco.Core.Models.Identity; +using Umbraco.Core.Security; +using Constants = Umbraco.Core.Constants; -namespace Umbraco.Core.Security +namespace Umbraco.Web.Security { /// /// Static helper class used to configure a CookieAuthenticationProvider to validate a cookie against a user's session id diff --git a/src/Umbraco.Web/Security/Identity/UmbracoBackOfficeCookieAuthOptions.cs b/src/Umbraco.Web/Security/UmbracoBackOfficeCookieAuthOptions.cs similarity index 97% rename from src/Umbraco.Web/Security/Identity/UmbracoBackOfficeCookieAuthOptions.cs rename to src/Umbraco.Web/Security/UmbracoBackOfficeCookieAuthOptions.cs index a4d3852948..b15be9ec9a 100644 --- a/src/Umbraco.Web/Security/Identity/UmbracoBackOfficeCookieAuthOptions.cs +++ b/src/Umbraco.Web/Security/UmbracoBackOfficeCookieAuthOptions.cs @@ -5,9 +5,8 @@ using Microsoft.Owin.Security.Cookies; using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; -using Umbraco.Web.Composing; -namespace Umbraco.Web.Security.Identity +namespace Umbraco.Web.Security { /// /// Umbraco auth cookie options diff --git a/src/Umbraco.Web/Security/Identity/UmbracoSecureDataFormat.cs b/src/Umbraco.Web/Security/UmbracoSecureDataFormat.cs similarity index 93% rename from src/Umbraco.Web/Security/Identity/UmbracoSecureDataFormat.cs rename to src/Umbraco.Web/Security/UmbracoSecureDataFormat.cs index 2676a5ee25..0dc73f5214 100644 --- a/src/Umbraco.Web/Security/Identity/UmbracoSecureDataFormat.cs +++ b/src/Umbraco.Web/Security/UmbracoSecureDataFormat.cs @@ -1,14 +1,8 @@ using System; -using System.Security.Claims; -using System.Web.Security; -using Microsoft.Owin; using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Cookies; -using Newtonsoft.Json; -using Owin; using Umbraco.Core.Security; -namespace Umbraco.Web.Security.Identity +namespace Umbraco.Web.Security { /// diff --git a/src/Umbraco.Core/Configuration/ClientDependencyConfiguration.cs b/src/Umbraco.Web/UI/JavaScript/ClientDependencyConfiguration.cs similarity index 79% rename from src/Umbraco.Core/Configuration/ClientDependencyConfiguration.cs rename to src/Umbraco.Web/UI/JavaScript/ClientDependencyConfiguration.cs index 61f9023167..f1f57a03a7 100644 --- a/src/Umbraco.Core/Configuration/ClientDependencyConfiguration.cs +++ b/src/Umbraco.Web/UI/JavaScript/ClientDependencyConfiguration.cs @@ -12,7 +12,7 @@ using Semver; using Umbraco.Core.IO; using Umbraco.Core.Logging; -namespace Umbraco.Core.Configuration +namespace Umbraco.Web.UI.JavaScript { /// /// A utility class for working with CDF config and cache files - use sparingly! @@ -91,40 +91,6 @@ namespace Umbraco.Core.Configuration return false; } - /// - /// Changes the version number in ClientDependency.config to a random value to avoid stale caches - /// - /// - [Obsolete("Use the UpdateVersionNumber method specifying the version, date and dateFormat instead")] - public bool IncreaseVersionNumber() - { - try - { - var clientDependencyConfigXml = XDocument.Load(_fileName, LoadOptions.PreserveWhitespace); - if (clientDependencyConfigXml.Root != null) - { - - var versionAttribute = clientDependencyConfigXml.Root.Attribute("version"); - - //Set the new version to the hashcode of now - var oldVersion = versionAttribute.Value; - var newVersion = Math.Abs(DateTime.UtcNow.GetHashCode()); - - versionAttribute.SetValue(newVersion); - clientDependencyConfigXml.Save(_fileName, SaveOptions.DisableFormatting); - - _logger.Info("Updated version number from {OldVersion} to {NewVersion}", oldVersion, newVersion); - return true; - } - } - catch (Exception ex) - { - _logger.Error(ex, "Couldn't update ClientDependency version number"); - } - - return false; - } - /// /// Clears the temporary files stored for the ClientDependency folder /// @@ -141,7 +107,7 @@ namespace Umbraco.Core.Configuration try { - var fullPath = currentHttpContext.Server.MapPath(XmlFileMapper.FileMapVirtualFolder); + var fullPath = currentHttpContext.Server.MapPath(XmlFileMapper.FileMapDefaultFolder); if (fullPath != null) { cdfTempDirectories.Add(fullPath); diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index dd31aed63b..d01eaa0f64 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -43,6 +43,7 @@ + @@ -63,12 +64,15 @@ + + 2.6.2.25 + - + @@ -76,10 +80,9 @@ - - + @@ -107,14 +110,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -430,7 +481,7 @@ - + @@ -558,25 +609,24 @@ - - - - - + + + + + - + - + - @@ -787,11 +837,11 @@ - - - - - + + + + + diff --git a/src/Umbraco.Web/UmbracoDefaultOwinStartup.cs b/src/Umbraco.Web/UmbracoDefaultOwinStartup.cs index 412156acbc..6d8df48adc 100644 --- a/src/Umbraco.Web/UmbracoDefaultOwinStartup.cs +++ b/src/Umbraco.Web/UmbracoDefaultOwinStartup.cs @@ -8,7 +8,8 @@ using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Web; using Umbraco.Web.Composing; -using Umbraco.Web.Security.Identity; +using Umbraco.Web.Security; + [assembly: OwinStartup("UmbracoDefaultOwinStartup", typeof(UmbracoDefaultOwinStartup))] diff --git a/src/Umbraco.Web/WebApi/UmbracoAuthorizedApiController.cs b/src/Umbraco.Web/WebApi/UmbracoAuthorizedApiController.cs index 8e5e784e31..6152503d4e 100644 --- a/src/Umbraco.Web/WebApi/UmbracoAuthorizedApiController.cs +++ b/src/Umbraco.Web/WebApi/UmbracoAuthorizedApiController.cs @@ -1,6 +1,7 @@ using Umbraco.Web.WebApi.Filters; using Umbraco.Core.Models.Identity; using Umbraco.Core.Security; +using Umbraco.Web.Security; namespace Umbraco.Web.WebApi { diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Packages/installer.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Packages/installer.aspx.cs index 2d1f36ce40..52c021fc3c 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Packages/installer.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Packages/installer.aspx.cs @@ -2,9 +2,11 @@ using System.Web.UI; using umbraco.cms.presentation.Trees; using Umbraco.Core; +using Umbraco.Core.Configuration; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Web; +using Umbraco.Web.UI.JavaScript; using Umbraco.Web._Legacy.Controls; using Umbraco.Web.UI.Pages; @@ -83,8 +85,9 @@ namespace umbraco.presentation.developer.packages _installer.InstallCleanUp(packageId, dir); // Update ClientDependency version - var clientDependencyConfig = new Umbraco.Core.Configuration.ClientDependencyConfiguration(Logger); - clientDependencyConfig.IncreaseVersionNumber(); + var clientDependencyConfig = new ClientDependencyConfiguration(Logger); + var clientDependencyUpdated = clientDependencyConfig.UpdateVersionNumber( + UmbracoVersion.SemanticVersion, DateTime.UtcNow, "yyyyMMdd"); //clear the tree cache - we'll do this here even though the browser will reload, but just in case it doesn't can't hurt. ClientTools.ClearClientTreeCache().RefreshTree("packager");