From 6cffa6751853de42d27deca5074e5e330337de48 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Thu, 25 Apr 2013 21:09:07 -1000 Subject: [PATCH] Fixes merge issues and WebSecurity with the correct encryption (from failed merge along time ago). Fixes ContentType to ensure that ALL property type values get reset, not just ones assigned to a group. Fixes logic in ContentTypeService to ensure that xml is re-generated when a property type alias is changed too. --- src/Umbraco.Core/Models/ContentType.cs | 12 +++- .../Initial/DatabaseSchemaCreation.cs | 24 +------ .../Services/ContentTypeService.cs | 36 +++++++---- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 1 + src/Umbraco.Web/Security/WebSecurity.cs | 47 +++++--------- .../controls/ContentTypeControlNew.ascx.cs | 63 ++++++++++--------- 6 files changed, 86 insertions(+), 97 deletions(-) diff --git a/src/Umbraco.Core/Models/ContentType.cs b/src/Umbraco.Core/Models/ContentType.cs index d675b966ba..4577046b17 100644 --- a/src/Umbraco.Core/Models/ContentType.cs +++ b/src/Umbraco.Core/Models/ContentType.cs @@ -161,14 +161,24 @@ namespace Umbraco.Core.Models { base.ResetDirtyProperties(); + //loop through each property group to reset the property types + var propertiesReset = new List(); + foreach (var propertyGroup in PropertyGroups) { propertyGroup.ResetDirtyProperties(); foreach (var propertyType in propertyGroup.PropertyTypes) - { + { propertyType.ResetDirtyProperties(); + propertiesReset.Add(propertyType.Id); } } + //then loop through our property type collection since some might not exist on a property group + //but don't re-reset ones we've already done. + foreach (var propertyType in PropertyTypes.Where(x => propertiesReset.Contains(x.Id) == false)) + { + propertyType.ResetDirtyProperties(); + } } /// diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs index e53c7719ae..df0cf13052 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs @@ -62,6 +62,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial {41, typeof (ServerRegistrationDto)} }; #endregion + /// /// Drops all Umbraco tables in the db /// @@ -90,29 +91,6 @@ namespace Umbraco.Core.Persistence.Migrations.Initial } } - /// - /// Drops all Umbraco tables in the db - /// - internal void UninstallDatabaseSchema() - { - foreach (var item in OrderedTables.OrderByDescending(x => x.Key)) - { - var tableNameAttribute = item.Value.FirstAttribute(); - string tableName = tableNameAttribute == null ? item.Value.Name : tableNameAttribute.Value; - - try - { - _database.DropTable(tableName); - } - catch (Exception ex) - { - //swallow this for now, not sure how best to handle this with diff databases... though this is internal - // and only used for unit tests. If this fails its because the table doesn't exist... generally! - LogHelper.Error("Could not drop table " + tableName, ex); - } - } - } - public DatabaseSchemaCreation(Database database) { _database = database; diff --git a/src/Umbraco.Core/Services/ContentTypeService.cs b/src/Umbraco.Core/Services/ContentTypeService.cs index f037d25bc2..1c764d88cf 100644 --- a/src/Umbraco.Core/Services/ContentTypeService.cs +++ b/src/Umbraco.Core/Services/ContentTypeService.cs @@ -152,29 +152,41 @@ namespace Umbraco.Core.Services foreach (var contentType in contentTypes) { //we need to determine if we need to refresh the xml content in the database. This is to be done when: - // - the item is not new (already existed in the db) - // - a content type changes it's alias - // - if a content type has it's property removed + // - the item is not new (already existed in the db) AND + // - a content type changes it's alias OR + // - if a content type has it's property removed OR + // - if a content type has a property whose alias has changed //here we need to check if the alias of the content type changed or if one of the properties was removed. var dirty = contentType as IRememberBeingDirty; - if (dirty != null - && !dirty.WasPropertyDirty("HasIdentity") //ensure it's now 'new' - && (dirty.WasPropertyDirty("Alias") || dirty.WasPropertyDirty("HasPropertyTypeBeenRemoved"))) + if (dirty == null) continue; + + //check if any property types have changed their aliases (and not new property types) + var hasAnyPropertiesChangedAlias = contentType.PropertyTypes.Any(propType => + { + var dirtyProperty = propType as IRememberBeingDirty; + if (dirtyProperty == null) return false; + return dirtyProperty.WasPropertyDirty("HasIdentity") == false //ensure it's not 'new' + && dirtyProperty.WasPropertyDirty("Alias"); //alias has changed + }); + + if (dirty.WasPropertyDirty("HasIdentity") == false //ensure it's not 'new' + && (dirty.WasPropertyDirty("Alias") || dirty.WasPropertyDirty("HasPropertyTypeBeenRemoved") || hasAnyPropertiesChangedAlias)) { - //if the alias was changed then we only need to update the xml structures for content of the current content type. - //if a property was deleted then we need to update the xml structures for any content of the current content type - // and any of the content type's child content types. - if (dirty.WasPropertyDirty("Alias") && !dirty.WasPropertyDirty("HasPropertyTypeBeenRemoved")) + //If the alias was changed then we only need to update the xml structures for content of the current content type. + //If a property was deleted or a property alias was changed then we need to update the xml structures for any + // content of the current content type and any of the content type's child content types. + if (dirty.WasPropertyDirty("Alias") + && dirty.WasPropertyDirty("HasPropertyTypeBeenRemoved") == false && hasAnyPropertiesChangedAlias == false) { //if only the alias changed then only update the current content type toUpdate.Add(contentType); } else { - //if a property was deleted (and maybe the alias changed too), then update all content of the current content type + //if a property was deleted or alias changed, then update all content of the current content type // and all of it's desscendant doc types. toUpdate.AddRange(contentType.DescendantsAndSelf()); - } + } } } diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 5bf656e8a4..6bb9dbcb9d 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -389,6 +389,7 @@ ContentTypeControlNew.ascx + ASPXCodeBehind ContentTypeControlNew.ascx diff --git a/src/Umbraco.Web/Security/WebSecurity.cs b/src/Umbraco.Web/Security/WebSecurity.cs index e800550949..e7551ae2ea 100644 --- a/src/Umbraco.Web/Security/WebSecurity.cs +++ b/src/Umbraco.Web/Security/WebSecurity.cs @@ -366,34 +366,23 @@ namespace Umbraco.Web.Security /// /// The umbraco user context ID. public string UmbracoUserContextId - { - - //TODO: Clean this up!! We also have extension methods in StringExtensions for decrypting/encrypting in med trust - // ... though an existing cookie may fail decryption, in that case they'd just get logged out. no problems. - + { get { - // zb-00004 #29956 : refactor cookies names & handling if (StateHelper.Cookies.HasCookies && StateHelper.Cookies.UserContext.HasValue) - return StateHelper.Cookies.UserContext.GetValue(); - try { - var encTicket = StateHelper.Cookies.UserContext.GetValue(); - if (string.IsNullOrEmpty(encTicket) == false) + try { - var formsAuthenticationTicket = FormsAuthentication.Decrypt(encTicket); - if (formsAuthenticationTicket != null) - return formsAuthenticationTicket.UserData; + var encTicket = StateHelper.Cookies.UserContext.GetValue(); + if (string.IsNullOrEmpty(encTicket) == false) + { + return encTicket.DecryptWithMachineKey(); + } + } + catch (HttpException ex) + { + // we swallow this type of exception as it happens if a legacy (pre 4.8.1) cookie is set } - } - catch (HttpException) - { - // we swallow this type of exception as it happens if a legacy (pre 4.8.1) cookie is set - } - catch (ArgumentException ex) - { - // we swallow this one because it's 99.99% certaincy is legacy based. We'll still log it, though - LogHelper.Error(typeof(WebSecurity), "An error occurred reading auth cookie value", ex); } return ""; } @@ -408,19 +397,11 @@ namespace Umbraco.Web.Security if (string.IsNullOrEmpty(value) == false) { - var ticket = new FormsAuthenticationTicket(1, - value, - DateTime.Now, - DateTime.Now.AddDays(1), - false, - value, - FormsAuthentication.FormsCookiePath); + // Encrypt the value + var encTicket = value.EncryptWithMachineKey(); - // Encrypt the ticket. - FormsAuthentication.Encrypt(ticket); - // Create new cookie. - StateHelper.Cookies.UserContext.SetValue(value, 1); + StateHelper.Cookies.UserContext.SetValue(encTicket, 1); } else { diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs index 8c69de4c8f..4d7dcc48ea 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs @@ -91,13 +91,13 @@ namespace umbraco.controls protected void Page_Load(object sender, EventArgs e) { - pp_newTab.Text = ui.Text("newtab", CurrentUser); - pp_alias.Text = ui.Text("alias", CurrentUser); - pp_name.Text = ui.Text("name", CurrentUser); - pp_allowedChildren.Text = ui.Text("allowedchildnodetypes", CurrentUser); - pp_description.Text = ui.Text("editcontenttype", "description", CurrentUser); - pp_icon.Text = ui.Text("icon", CurrentUser); - pp_thumbnail.Text = ui.Text("editcontenttype", "thumbnail", CurrentUser); + pp_newTab.Text = ui.Text("newtab", Security.CurrentUser); + pp_alias.Text = ui.Text("alias", Security.CurrentUser); + pp_name.Text = ui.Text("name", Security.CurrentUser); + pp_allowedChildren.Text = ui.Text("allowedchildnodetypes", Security.CurrentUser); + pp_description.Text = ui.Text("editcontenttype", "description", Security.CurrentUser); + pp_icon.Text = ui.Text("icon", Security.CurrentUser); + pp_thumbnail.Text = ui.Text("editcontenttype", "thumbnail", Security.CurrentUser); // we'll disable this... @@ -334,6 +334,13 @@ namespace umbraco.controls _contentType.AllowAtRoot = allowAtRoot.Checked; _contentType.Save(); + + // Only if the doctype alias changed, cause a regeneration of the xml cache file since + // the xml element names will need to be updated to reflect the new alias + if (asyncState.HasAliasChanged() || asyncState.HasAnyPropertyAliasChanged(_contentType)) + { + _contentType.RebuildXmlStructuresForContent(); + } } Trace.Write("ContentTypeControlNew", "task completing"); @@ -1056,35 +1063,35 @@ jQuery(document).ready(function() {{ refreshDropDowns(); }}); protected void gpw_Delete(object sender, EventArgs e) { //Add the async operation to the page - Page.RegisterAsyncTask(new PageAsyncTask(BeginAsyncDeleteOperation, EndAsyncDeleteOperation, HandleAsyncSaveTimeout, (GenericPropertyWrapper)sender)); + Page.RegisterAsyncTask(new PageAsyncTask(BeginAsyncDeleteOperation, EndAsyncDeleteOperation, HandleAsyncSaveTimeout, (GenericPropertyWrapper) sender)); //create the save task to be executed async _asyncDeleteTask = genericPropertyWrapper => - { - Trace.Write("ContentTypeControlNew", "executing task"); + { + Trace.Write("ContentTypeControlNew", "executing task"); + + if (_contentType.ContentTypeItem is IContentType || _contentType.ContentTypeItem is IMediaType) + { + _contentType.ContentTypeItem.RemovePropertyType(genericPropertyWrapper.PropertyType.Alias); + _contentType.Save(); + } + else + { + //if it is not a document type or a media type, then continue to call the legacy delete() method. + //the new API for document type and media type's will ensure that the data is removed correctly and that + //the cache is flushed correctly (using events). If it is not one of these types, we'll rever to the + //legacy operation (... like for members i suppose ?) + genericPropertyWrapper.GenricPropertyControl.PropertyType.delete(); + + } + + Trace.Write("ContentTypeControlNew", "task completing"); + }; - if (_contentType.ContentTypeItem is IContentType || _contentType.ContentTypeItem is IMediaType) - { - _contentType.ContentTypeItem.RemovePropertyType(gpw.PropertyType.Alias); - _contentType.Save(); - } - else - { - //if it is not a document type or a media type, then continue to call the legacy delete() method. - //the new API for document type and media type's will ensure that the data is removed correctly and that - //the cache is flushed correctly (using events). If it is not one of these types, we'll rever to the - //legacy operation (... like for members i suppose ?) - gpw.GenricPropertyControl.PropertyType.delete(); - - }; - Trace.Write("ContentTypeControlNew", "task completing"); - //execute the async tasks Page.ExecuteRegisteredAsyncTasks(); - } - #endregion #region "Tab" Pane