From 029eff1f8a611737623338424cd938480303c072 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 29 Aug 2018 01:15:46 +1000 Subject: [PATCH] Some refactoring to decouple web based assemblies from Umbraco.Core and move whatever we can to Umbraco.Web where web based assemblies are used. Decouples System.Drawing entirely from Umbraco.Core and removes the Active Directory dependency from Umbraco.core. --- build/NuSpecs/UmbracoCms.Core.nuspec | 111 ++++++-------- build/NuSpecs/UmbracoCms.Web.nuspec | 119 +++++++-------- build/NuSpecs/UmbracoCms.nuspec | 99 ++++++------ .../AuditEventsComponent.cs | 73 +-------- .../ManifestWatcherComponent.cs | 4 +- .../RelateOnCopyComponent.cs | 6 +- .../RelateOnTrashComponent.cs | 6 +- .../ContentSectionExtensions.cs | 29 +++- .../{Models => }/ContentExtensions.cs | 53 +++---- src/Umbraco.Core/IO/MediaFileSystem.cs | 121 +-------------- src/Umbraco.Core/Media/ImageExtensions.cs | 21 --- src/Umbraco.Core/Models/ContentBase.cs | 20 --- .../Models/Identity/BackOfficeIdentityUser.cs | 8 - src/Umbraco.Core/Models/Template.cs | 8 - src/Umbraco.Core/NetworkHelper.cs | 3 - src/Umbraco.Core/Umbraco.Core.csproj | 81 +++------- src/Umbraco.Examine/Umbraco.Examine.csproj | 2 +- .../Umbraco.Tests.Benchmarks.csproj | 2 +- src/Umbraco.Tests/Macros/MacroParserTests.cs | 1 + .../Models/ContentExtensionsTests.cs | 1 + src/Umbraco.Tests/Models/ContentTests.cs | 1 + src/Umbraco.Tests/Models/MediaXmlTest.cs | 2 +- .../PropertyEditors/ImageCropperTest.cs | 3 +- .../Security/BackOfficeCookieManagerTests.cs | 2 +- src/Umbraco.Tests/Umbraco.Tests.csproj | 2 +- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 4 +- .../BackOfficeUserAuditEventsComponent.cs | 144 ++++++++++++++++++ src/Umbraco.Web/ContentExtensions.cs | 32 ++++ .../Editors/AuthenticationController.cs | 1 - .../Editors/BackOfficeController.cs | 3 +- src/Umbraco.Web/Editors/ImagesController.cs | 8 +- .../Editors/PackageInstallController.cs | 6 +- src/Umbraco.Web/Editors/PasswordChanger.cs | 1 + .../ImageProcessorLogger.cs | 3 +- .../Install/Controllers/InstallController.cs | 1 + .../Macros/MacroTagParser.cs | 2 +- .../Media/Exif/BitConverterEx.cs | 2 +- .../Media/Exif/ExifBitConverter.cs | 2 +- .../Media/Exif/ExifEnums.cs | 2 +- .../Media/Exif/ExifExceptions.cs | 2 +- .../Media/Exif/ExifExtendedProperty.cs | 2 +- .../Media/Exif/ExifFileTypeDescriptor.cs | 2 +- .../Media/Exif/ExifInterOperability.cs | 2 +- .../Media/Exif/ExifProperty.cs | 2 +- .../Media/Exif/ExifPropertyCollection.cs | 2 +- .../Media/Exif/ExifPropertyFactory.cs | 2 +- .../Media/Exif/ExifTag.cs | 2 +- .../Media/Exif/ExifTagFactory.cs | 2 +- .../Media/Exif/IFD.cs | 2 +- .../Media/Exif/ImageFile.cs | 2 +- .../Media/Exif/ImageFileDirectory.cs | 2 +- .../Media/Exif/ImageFileDirectoryEntry.cs | 2 +- .../Media/Exif/ImageFileFormat.cs | 2 +- .../Media/Exif/JFIFEnums.cs | 2 +- .../Media/Exif/JFIFExtendedProperty.cs | 2 +- .../Media/Exif/JFIFThumbnail.cs | 2 +- .../Media/Exif/JPEGExceptions.cs | 2 +- .../Media/Exif/JPEGFile.cs | 2 +- .../Media/Exif/JPEGMarker.cs | 2 +- .../Media/Exif/JPEGSection.cs | 2 +- .../Media/Exif/MathEx.cs | 2 +- .../Media/Exif/TIFFFile.cs | 2 +- .../Media/Exif/TIFFHeader.cs | 2 +- .../Media/Exif/TIFFStrip.cs | 2 +- .../Media/Exif/Utility.cs | 2 +- src/Umbraco.Web/Media/ImageHelper.cs | 66 ++++++++ .../Media/UploadAutoFillProperties.cs | 101 ++---------- .../Models/Mapping/CreatorResolver.cs | 1 + .../Models/Mapping/OwnerResolver.cs | 1 + .../OwinExtensions.cs | 17 ++- .../FileUploadPropertyEditor.cs | 14 +- .../FileUploadPropertyValueEditor.cs | 4 + .../ImageCropperPropertyEditor.cs | 74 ++++----- .../ImageCropperPropertyValueEditor.cs | 3 + .../PropertyEditors/RichTextPropertyEditor.cs | 1 + .../MacroContainerValueConverter.cs | 1 + .../RteMacroRenderingValueConverter.cs | 1 + ...eDirectoryBackOfficeUserPasswordChecker.cs | 3 +- .../{Identity => }/AppBuilderExtensions.cs | 5 +- .../AuthenticationManagerExtensions.cs | 2 +- .../AuthenticationOptionsExtensions.cs | 3 +- .../BackOfficeClaimsIdentityFactory.cs | 4 +- .../BackOfficeCookieAuthenticationProvider.cs | 10 +- .../{Identity => }/BackOfficeCookieManager.cs | 2 +- .../Security/BackOfficeSignInManager.cs | 6 +- .../Security/BackOfficeUserManager.cs | 23 +-- .../Security/BackOfficeUserManagerMarker.cs | 3 +- .../BackOfficeUserPasswordCheckerResult.cs | 2 +- .../ExternalSignInAutoLinkOptions.cs | 6 +- .../{Identity => }/FixWindowsAuthMiddlware.cs | 2 +- ...ForceRenewalCookieAuthenticationHandler.cs | 9 +- ...ceRenewalCookieAuthenticationMiddleware.cs | 2 +- .../GetUserSecondsMiddleWare.cs | 4 +- .../Security/IBackOfficeUserManagerMarker.cs | 2 +- .../IBackOfficeUserPasswordChecker.cs | 2 +- .../IUmbracoBackOfficeTwoFactorOptions.cs | 2 +- .../Security}/IdentityAuditEventArgs.cs | 4 +- src/Umbraco.Web/Security/OwinExtensions.cs | 26 ---- .../PreviewAuthenticationMiddleware.cs | 20 +-- .../Security/SessionIdValidator.cs | 8 +- .../UmbracoBackOfficeCookieAuthOptions.cs | 3 +- .../{Identity => }/UmbracoSecureDataFormat.cs | 8 +- .../ClientDependencyConfiguration.cs | 38 +---- src/Umbraco.Web/Umbraco.Web.csproj | 84 +++++++--- src/Umbraco.Web/UmbracoDefaultOwinStartup.cs | 3 +- .../WebApi/UmbracoAuthorizedApiController.cs | 1 + .../developer/Packages/installer.aspx.cs | 7 +- 107 files changed, 756 insertions(+), 863 deletions(-) rename src/Umbraco.Core/{Auditing => Components}/AuditEventsComponent.cs (78%) rename src/Umbraco.Core/{Strategies => Components}/ManifestWatcherComponent.cs (91%) rename src/Umbraco.Core/{Strategies => Components}/RelateOnCopyComponent.cs (93%) rename src/Umbraco.Core/{Strategies => Components}/RelateOnTrashComponent.cs (98%) rename src/Umbraco.Core/{Models => }/ContentExtensions.cs (92%) delete mode 100644 src/Umbraco.Core/Media/ImageExtensions.cs create mode 100644 src/Umbraco.Web/Components/BackOfficeUserAuditEventsComponent.cs create mode 100644 src/Umbraco.Web/ContentExtensions.cs rename src/{Umbraco.Core/Logging => Umbraco.Web}/ImageProcessorLogger.cs (97%) rename src/{Umbraco.Core => Umbraco.Web}/Macros/MacroTagParser.cs (99%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/BitConverterEx.cs (99%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/ExifBitConverter.cs (99%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/ExifEnums.cs (99%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/ExifExceptions.cs (96%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/ExifExtendedProperty.cs (99%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/ExifFileTypeDescriptor.cs (99%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/ExifInterOperability.cs (98%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/ExifProperty.cs (99%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/ExifPropertyCollection.cs (99%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/ExifPropertyFactory.cs (99%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/ExifTag.cs (99%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/ExifTagFactory.cs (98%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/IFD.cs (90%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/ImageFile.cs (99%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/ImageFileDirectory.cs (99%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/ImageFileDirectoryEntry.cs (99%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/ImageFileFormat.cs (92%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/JFIFEnums.cs (96%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/JFIFExtendedProperty.cs (98%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/JFIFThumbnail.cs (97%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/JPEGExceptions.cs (98%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/JPEGFile.cs (99%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/JPEGMarker.cs (98%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/JPEGSection.cs (98%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/MathEx.cs (99%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/TIFFFile.cs (99%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/TIFFHeader.cs (98%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/TIFFStrip.cs (96%) rename src/{Umbraco.Core => Umbraco.Web}/Media/Exif/Utility.cs (96%) create mode 100644 src/Umbraco.Web/Media/ImageHelper.cs rename src/{Umbraco.Core => Umbraco.Web}/Media/UploadAutoFillProperties.cs (60%) rename src/{Umbraco.Core/Security => Umbraco.Web}/OwinExtensions.cs (83%) rename src/{Umbraco.Core => Umbraco.Web}/Security/ActiveDirectoryBackOfficeUserPasswordChecker.cs (93%) rename src/Umbraco.Web/Security/{Identity => }/AppBuilderExtensions.cs (99%) rename src/Umbraco.Web/Security/{Identity => }/AuthenticationManagerExtensions.cs (98%) rename src/Umbraco.Web/Security/{Identity => }/AuthenticationOptionsExtensions.cs (98%) rename src/{Umbraco.Core => Umbraco.Web}/Security/BackOfficeClaimsIdentityFactory.cs (94%) rename src/{Umbraco.Core => Umbraco.Web}/Security/BackOfficeCookieAuthenticationProvider.cs (92%) rename src/Umbraco.Web/Security/{Identity => }/BackOfficeCookieManager.cs (99%) rename src/{Umbraco.Core => Umbraco.Web}/Security/BackOfficeSignInManager.cs (98%) rename src/{Umbraco.Core => Umbraco.Web}/Security/BackOfficeUserManager.cs (98%) rename src/{Umbraco.Core => Umbraco.Web}/Security/BackOfficeUserManagerMarker.cs (95%) rename src/{Umbraco.Core => Umbraco.Web}/Security/BackOfficeUserPasswordCheckerResult.cs (88%) rename src/Umbraco.Web/Security/{Identity => }/ExternalSignInAutoLinkOptions.cs (95%) rename src/Umbraco.Web/Security/{Identity => }/FixWindowsAuthMiddlware.cs (98%) rename src/Umbraco.Web/Security/{Identity => }/ForceRenewalCookieAuthenticationHandler.cs (98%) rename src/Umbraco.Web/Security/{Identity => }/ForceRenewalCookieAuthenticationMiddleware.cs (96%) rename src/Umbraco.Web/Security/{Identity => }/GetUserSecondsMiddleWare.cs (98%) rename src/{Umbraco.Core => Umbraco.Web}/Security/IBackOfficeUserManagerMarker.cs (94%) rename src/{Umbraco.Core => Umbraco.Web}/Security/IBackOfficeUserPasswordChecker.cs (97%) rename src/Umbraco.Web/Security/{Identity => }/IUmbracoBackOfficeTwoFactorOptions.cs (90%) rename src/{Umbraco.Core/Auditing => Umbraco.Web/Security}/IdentityAuditEventArgs.cs (98%) delete mode 100644 src/Umbraco.Web/Security/OwinExtensions.cs rename src/Umbraco.Web/Security/{Identity => }/PreviewAuthenticationMiddleware.cs (85%) rename src/{Umbraco.Core => Umbraco.Web}/Security/SessionIdValidator.cs (97%) rename src/Umbraco.Web/Security/{Identity => }/UmbracoBackOfficeCookieAuthOptions.cs (97%) rename src/Umbraco.Web/Security/{Identity => }/UmbracoSecureDataFormat.cs (93%) rename src/{Umbraco.Core/Configuration => Umbraco.Web/UI/JavaScript}/ClientDependencyConfiguration.cs (79%) 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");