Port v7@2aa0dfb2c5 - WIP
This commit is contained in:
@@ -153,11 +153,13 @@ namespace Umbraco.Core.Migrations.Install
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.UserGroup, "id", false, new UserGroupDto { Id = 2, StartMediaId = -1, StartContentId = -1, Alias = "writer", Name = "Writers", DefaultPermissions = "CAH:F", CreateDate = DateTime.Now, UpdateDate = DateTime.Now, Icon = "icon-edit" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.UserGroup, "id", false, new UserGroupDto { Id = 3, StartMediaId = -1, StartContentId = -1, Alias = "editor", Name = "Editors", DefaultPermissions = "CADMOSKTPUZ:5Fï", CreateDate = DateTime.Now, UpdateDate = DateTime.Now, Icon = "icon-tools" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.UserGroup, "id", false, new UserGroupDto { Id = 4, StartMediaId = -1, StartContentId = -1, Alias = Constants.Security.TranslatorGroupAlias, Name = "Translators", DefaultPermissions = "AF", CreateDate = DateTime.Now, UpdateDate = DateTime.Now, Icon = "icon-globe" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.UserGroup, "id", false, new UserGroupDto { Id = 5, StartMediaId = -1, StartContentId = -1, Alias = Constants.Security.SensitiveDataGroupAlias, Name = "Sensitive data", DefaultPermissions = "", CreateDate = DateTime.Now, UpdateDate = DateTime.Now, Icon = "icon-lock" });
|
||||
}
|
||||
|
||||
private void CreateUser2UserGroupData()
|
||||
{
|
||||
_database.Insert(new User2UserGroupDto { UserGroupId = 1, UserId = Constants.Security.SuperId });
|
||||
_database.Insert(new User2UserGroupDto { UserGroupId = 1, UserId = Constants.Security.SuperId }); // add super to admins
|
||||
_database.Insert(new User2UserGroupDto { UserGroupId = 5, UserId = Constants.Security.SuperId }); // add super to sensitive data
|
||||
}
|
||||
|
||||
private void CreateUserGroup2AppData()
|
||||
|
||||
@@ -28,71 +28,60 @@ namespace Umbraco.Core.Migrations.Install
|
||||
private ISqlSyntaxProvider SqlSyntax => _database.SqlContext.SqlSyntax;
|
||||
|
||||
// all tables, in order
|
||||
public static readonly Dictionary<int, Type> OrderedTables = new Dictionary<int, Type>
|
||||
public static readonly List<Type> OrderedTables = new List<Type>
|
||||
{
|
||||
{0, typeof (NodeDto)},
|
||||
{1, typeof (ContentTypeDto)},
|
||||
{2, typeof (TemplateDto)},
|
||||
{3, typeof (ContentDto)},
|
||||
{4, typeof (ContentVersionDto)},
|
||||
{5, typeof (DocumentDto)},
|
||||
{6, typeof (ContentTypeTemplateDto)},
|
||||
{7, typeof (DataTypeDto)},
|
||||
//removed: {8, typeof (DataTypePreValueDto)},
|
||||
{9, typeof (DictionaryDto)},
|
||||
|
||||
{10, typeof (LanguageDto)},
|
||||
{11, typeof (LanguageTextDto)},
|
||||
{12, typeof (DomainDto)},
|
||||
{13, typeof (LogDto)},
|
||||
{14, typeof (MacroDto)},
|
||||
{15, typeof (MacroPropertyDto)},
|
||||
{16, typeof (MemberTypeDto)},
|
||||
{17, typeof (MemberDto)},
|
||||
{18, typeof (Member2MemberGroupDto)},
|
||||
{19, typeof (ContentXmlDto)},
|
||||
|
||||
{20, typeof (PreviewXmlDto)},
|
||||
{21, typeof (PropertyTypeGroupDto)},
|
||||
{22, typeof (PropertyTypeDto)},
|
||||
{23, typeof (PropertyDataDto)},
|
||||
{24, typeof (RelationTypeDto)},
|
||||
{25, typeof (RelationDto)},
|
||||
//removed: {26...
|
||||
//removed: {27...
|
||||
{28, typeof (TagDto)},
|
||||
{29, typeof (TagRelationshipDto)},
|
||||
|
||||
//removed: {30...
|
||||
//removed in 7.6: {31, typeof (UserTypeDto)},
|
||||
{32, typeof (UserDto)},
|
||||
{33, typeof (TaskTypeDto)},
|
||||
{34, typeof (TaskDto)},
|
||||
{35, typeof (ContentType2ContentTypeDto)},
|
||||
{36, typeof (ContentTypeAllowedContentTypeDto)},
|
||||
//removed in 7.6: {37, typeof (User2AppDto)},
|
||||
{38, typeof (User2NodeNotifyDto)},
|
||||
//removed in 7.6: {39, typeof (User2NodePermissionDto)},
|
||||
|
||||
{40, typeof (ServerRegistrationDto)},
|
||||
{41, typeof (AccessDto)},
|
||||
{42, typeof (AccessRuleDto)},
|
||||
{43, typeof (CacheInstructionDto)},
|
||||
{44, typeof (ExternalLoginDto)},
|
||||
//removed: {45, typeof (MigrationDto)},
|
||||
//removed: {46, typeof (UmbracoDeployChecksumDto)},
|
||||
//removed: {47, typeof (UmbracoDeployDependencyDto)},
|
||||
{48, typeof (RedirectUrlDto) },
|
||||
{49, typeof (LockDto) },
|
||||
|
||||
{50, typeof (UserGroupDto) },
|
||||
{51, typeof (User2UserGroupDto) },
|
||||
{52, typeof (UserGroup2NodePermissionDto) },
|
||||
{53, typeof (UserGroup2AppDto) },
|
||||
{54, typeof (UserStartNodeDto) },
|
||||
{55, typeof (ContentNuDto) },
|
||||
{56, typeof (DocumentVersionDto) },
|
||||
{57, typeof (KeyValueDto) }
|
||||
typeof (NodeDto),
|
||||
typeof (ContentTypeDto),
|
||||
typeof (TemplateDto),
|
||||
typeof (ContentDto),
|
||||
typeof (ContentVersionDto),
|
||||
typeof (MediaVersionDto),
|
||||
typeof (DocumentDto),
|
||||
typeof (ContentTypeTemplateDto),
|
||||
typeof (DataTypeDto),
|
||||
typeof (DictionaryDto),
|
||||
typeof (LanguageDto),
|
||||
typeof (LanguageTextDto),
|
||||
typeof (DomainDto),
|
||||
typeof (LogDto),
|
||||
typeof (MacroDto),
|
||||
typeof (MacroPropertyDto),
|
||||
typeof (MemberTypeDto),
|
||||
typeof (MemberDto),
|
||||
typeof (Member2MemberGroupDto),
|
||||
typeof (ContentXmlDto),
|
||||
typeof (PreviewXmlDto),
|
||||
typeof (PropertyTypeGroupDto),
|
||||
typeof (PropertyTypeDto),
|
||||
typeof (PropertyDataDto),
|
||||
typeof (RelationTypeDto),
|
||||
typeof (RelationDto),
|
||||
typeof (TagDto),
|
||||
typeof (TagRelationshipDto),
|
||||
typeof (UserDto),
|
||||
typeof (TaskTypeDto),
|
||||
typeof (TaskDto),
|
||||
typeof (ContentType2ContentTypeDto),
|
||||
typeof (ContentTypeAllowedContentTypeDto),
|
||||
typeof (User2NodeNotifyDto),
|
||||
typeof (ServerRegistrationDto),
|
||||
typeof (AccessDto),
|
||||
typeof (AccessRuleDto),
|
||||
typeof (CacheInstructionDto),
|
||||
typeof (ExternalLoginDto),
|
||||
typeof (RedirectUrlDto),
|
||||
typeof (LockDto),
|
||||
typeof (UserGroupDto),
|
||||
typeof (User2UserGroupDto),
|
||||
typeof (UserGroup2NodePermissionDto),
|
||||
typeof (UserGroup2AppDto),
|
||||
typeof (UserStartNodeDto),
|
||||
typeof (ContentNuDto),
|
||||
typeof (DocumentVersionDto),
|
||||
typeof (KeyValueDto),
|
||||
typeof (UserLoginDto),
|
||||
typeof (ConsentDto),
|
||||
typeof (AuditEntryDto)
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -102,11 +91,10 @@ namespace Umbraco.Core.Migrations.Install
|
||||
{
|
||||
_logger.Info<DatabaseSchemaCreator>("Start UninstallDatabaseSchema");
|
||||
|
||||
foreach (var item in OrderedTables.OrderByDescending(x => x.Key))
|
||||
foreach (var table in OrderedTables.AsEnumerable().Reverse())
|
||||
{
|
||||
var tableNameAttribute = item.Value.FirstAttribute<TableNameAttribute>();
|
||||
|
||||
var tableName = tableNameAttribute == null ? item.Value.Name : tableNameAttribute.Value;
|
||||
var tableNameAttribute = table.FirstAttribute<TableNameAttribute>();
|
||||
var tableName = tableNameAttribute == null ? table.Name : tableNameAttribute.Value;
|
||||
|
||||
_logger.Info<DatabaseSchemaCreator>("Uninstall" + tableName);
|
||||
|
||||
@@ -135,8 +123,8 @@ namespace Umbraco.Core.Migrations.Install
|
||||
if (e.Cancel == false)
|
||||
{
|
||||
var dataCreation = new DatabaseDataCreator(_database, _logger);
|
||||
foreach (var item in OrderedTables.OrderBy(x => x.Key))
|
||||
CreateTable(false, item.Value, dataCreation);
|
||||
foreach (var table in OrderedTables)
|
||||
CreateTable(false, table, dataCreation);
|
||||
}
|
||||
|
||||
FireAfterCreation(e);
|
||||
@@ -160,8 +148,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
}).ToArray();
|
||||
|
||||
result.TableDefinitions.AddRange(OrderedTables
|
||||
.OrderBy(x => x.Key)
|
||||
.Select(x => DefinitionFactory.GetTableDefinition(x.Value, SqlSyntax)));
|
||||
.Select(x => DefinitionFactory.GetTableDefinition(x, SqlSyntax)));
|
||||
|
||||
ValidateDbTables(result);
|
||||
ValidateDbColumns(result);
|
||||
|
||||
@@ -136,6 +136,18 @@ namespace Umbraco.Core.Migrations.Install
|
||||
return new Version(7, 6, 0);
|
||||
}
|
||||
|
||||
//if the error is for cmsMedia it must be the previous version to 7.8 since that is when it is added
|
||||
if (Errors.Any(x => x.Item1.Equals("Table") && (x.Item2.InvariantEquals("umbracoMedia"))))
|
||||
{
|
||||
return new Version(7, 7, 0);
|
||||
}
|
||||
|
||||
//if the error is for isSensitive column it must be the previous version to 7.9 since that is when it is added
|
||||
if (Errors.Any(x => x.Item1.Equals("Column") && (x.Item2.InvariantEquals("cmsMemberType,isSensitive"))))
|
||||
{
|
||||
return new Version(7, 8, 0);
|
||||
}
|
||||
|
||||
return UmbracoVersion.Current;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,14 @@ namespace Umbraco.Core.Migrations
|
||||
{
|
||||
// provides extra methods for migrations
|
||||
|
||||
protected void AddColumn<T>(string columnName)
|
||||
{
|
||||
var table = DefinitionFactory.GetTableDefinition(typeof(T), SqlSyntax);
|
||||
var column = table.Columns.First(x => x.Name == columnName);
|
||||
var createSql = SqlSyntax.Format(column);
|
||||
Database.Execute(string.Format(SqlSyntax.AddColumn, SqlSyntax.GetQuotedTableName(table.Name), createSql));
|
||||
}
|
||||
|
||||
protected void AddColumn<T>(string tableName, string columnName)
|
||||
{
|
||||
//if (ColumnExists(tableName, columnName))
|
||||
|
||||
@@ -7,6 +7,8 @@ using Umbraco.Core.Migrations.Upgrade.V_7_5_0;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_7_5_5;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_7_6_0;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_7_7_0;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_7_8_0;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_7_9_0;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_8_0_0;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade
|
||||
@@ -36,8 +38,8 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
if (!SemVersion.TryParse(ConfigurationManager.AppSettings["umbracoConfigurationStatus"], out var currentVersion))
|
||||
throw new InvalidOperationException("Could not get current version from web.config umbracoConfigurationStatus appSetting.");
|
||||
|
||||
// must be at least 7.8.0 - fixme adjust when releasing
|
||||
if (currentVersion < new SemVersion(7, 8))
|
||||
// must be at least 7.?.? - fixme adjust when releasing
|
||||
if (currentVersion < new SemVersion(7, 999))
|
||||
throw new InvalidOperationException($"Version {currentVersion} cannot be upgraded to {UmbracoVersion.SemanticVersion}.");
|
||||
|
||||
// cannot go back in time
|
||||
@@ -60,12 +62,6 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
|
||||
private void DefinePlan()
|
||||
{
|
||||
// INSTALL
|
||||
//
|
||||
// when installing, the source state is empty, and the target state should be the final state.
|
||||
|
||||
Add(string.Empty, "{CA7DB949-3EF4-403D-8464-F9BA36A52E87}");
|
||||
|
||||
// UPGRADE FROM 7
|
||||
//
|
||||
// when 8.0.0 is released, on the first upgrade, the state is automatically
|
||||
@@ -74,45 +70,38 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
// then, as more v7 and v8 versions are released, new chains needs to be defined to
|
||||
// support the upgrades (new v7 may backport some migrations and require their own
|
||||
// upgrade paths, etc).
|
||||
// fixme adjust when releasing
|
||||
|
||||
From("{init-7.8.0}")
|
||||
.Chain<V_8_0_0.AddLockObjects>("{7C447271-CA3F-4A6A-A913-5D77015655CB}") // add more lock objects
|
||||
.Chain<AddContentNuTable>("{CBFF58A2-7B50-4F75-8E98-249920DB0F37}")
|
||||
.Chain<RefactorXmlColumns>("{3D18920C-E84D-405C-A06A-B7CEE52FE5DD}")
|
||||
.Chain<VariantsMigration>("{FB0A5429-587E-4BD0-8A67-20F0E7E62FF7}")
|
||||
.Chain<DropMigrationsTable>("{F0C42457-6A3B-4912-A7EA-F27ED85A2092}")
|
||||
.Chain<DataTypeMigration>("{8640C9E4-A1C0-4C59-99BB-609B4E604981}")
|
||||
.Chain<TagsMigration>("{DD1B99AF-8106-4E00-BAC7-A43003EA07F8}")
|
||||
.Chain<SuperZero>("{9DF05B77-11D1-475C-A00A-B656AF7E0908}")
|
||||
.Chain<PropertyEditorsMigration>("{CA7DB949-3EF4-403D-8464-F9BA36A52E87}");;
|
||||
From("{init-7.8.0}");
|
||||
Chain<V_8_0_0.AddLockObjects>("{7C447271-CA3F-4A6A-A913-5D77015655CB}"); // add more lock objects
|
||||
Chain<AddContentNuTable>("{CBFF58A2-7B50-4F75-8E98-249920DB0F37}");
|
||||
Chain<RefactorXmlColumns>("{3D18920C-E84D-405C-A06A-B7CEE52FE5DD}");
|
||||
Chain<VariantsMigration>("{FB0A5429-587E-4BD0-8A67-20F0E7E62FF7}");
|
||||
Chain<DropMigrationsTable>("{F0C42457-6A3B-4912-A7EA-F27ED85A2092}");
|
||||
Chain<DataTypeMigration>("{8640C9E4-A1C0-4C59-99BB-609B4E604981}");
|
||||
Chain<TagsMigration>("{DD1B99AF-8106-4E00-BAC7-A43003EA07F8}");
|
||||
Chain<SuperZero>("{9DF05B77-11D1-475C-A00A-B656AF7E0908}");
|
||||
Chain<PropertyEditorsMigration>("{CA7DB949-3EF4-403D-8464-F9BA36A52E87}");
|
||||
|
||||
// 7.8.1 = same as 7.8.0
|
||||
From("{init-7.8.1}")
|
||||
.Chain("{init-7.8.0}");
|
||||
From("{init-7.8.1}");
|
||||
Chain("{init-7.8.0}");
|
||||
|
||||
// 7.9.0 = requires its own chain
|
||||
From("{init-7.9.0}")
|
||||
// chain...
|
||||
.Chain("{82C4BA1D-7720-46B1-BBD7-07F3F73800E6}");
|
||||
From("{init-7.9.0}");
|
||||
// chain...
|
||||
Chain("{82C4BA1D-7720-46B1-BBD7-07F3F73800E6}");
|
||||
|
||||
|
||||
// UPGRADE 8
|
||||
//
|
||||
// starting from the original 8.0.0 final state, chain migrations to upgrade version 8,
|
||||
// defining new final states as more migrations are added to the chain.
|
||||
|
||||
//From("")
|
||||
// .Chain("")
|
||||
// .Chain("");
|
||||
|
||||
// WIP 8
|
||||
//
|
||||
// before v8 is released, some sites may exist, and these "pre-8" versions require their
|
||||
// own upgrade plan. in other words, this is the plan for sites that were on v8 before
|
||||
// own upgrade plan. in other words, this is also the plan for sites that were on v8 before
|
||||
// v8 was released
|
||||
|
||||
// fixme - this is essentially for ZpqrtBnk website
|
||||
// need to determine which version it is and where it should resume running migrations
|
||||
|
||||
// 8.0.0
|
||||
From("{init-origin}");
|
||||
Chain<V_8_0_0.AddLockTable>("{98347B5E-65BF-4DD7-BB43-A09CB7AF4FCA}");
|
||||
@@ -129,8 +118,6 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
Chain<UpdateAllowedMediaTypesAtRoot>("{44484C32-EEB3-4A12-B1CB-11E02CE22AB2}");
|
||||
|
||||
// 7.6.0
|
||||
//Chain<AddLockTable>("{858B4039-070C-4928-BBEC-DDE8303352DA}");
|
||||
//Chain<AddLockObjects>("{64F587C1-0B28-4D78-B4CC-26B7D87F69C1}");
|
||||
Chain<AddIndexesToUmbracoRelationTables>("{3586E4E9-2922-49EB-8E2A-A530CE6DBDE0}");
|
||||
Chain<AddIndexToCmsMemberLoginName>("{D4A5674F-654D-4CC7-85E5-CFDBC533A318}");
|
||||
Chain<AddIndexToUmbracoNodePath>("{7F828EDD-6622-4A8D-AD80-EEAF46C11680}");
|
||||
@@ -156,6 +143,33 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
Chain<TagsMigration>("{139F26D7-7E08-48E3-81D9-E50A21A72F67}");
|
||||
Chain<SuperZero>("{CC1B1201-1328-443C-954A-E0BBB8CCC1B5}");
|
||||
Chain<PropertyEditorsMigration>("{CA7DB949-3EF4-403D-8464-F9BA36A52E87}");
|
||||
|
||||
// at this point of the chain, people started to work on v8, so whenever we
|
||||
// merge stuff from v7, we have to chain the migrations here so they also
|
||||
// run for v8.
|
||||
|
||||
// mergin from 7.8.0
|
||||
Chain<AddUserLoginTable>("{FDCB727A-EFB6-49F3-89E4-A346503AB849}");
|
||||
Chain<AddTourDataUserColumn>("{2A796A08-4FE4-4783-A1A5-B8A6C8AA4A92}");
|
||||
Chain<AddMediaVersionTable>("{1A46A98B-2AAB-4C8E-870F-A2D55A97FD1F}");
|
||||
Chain<AddInstructionCountColumn>("{0AE053F6-2683-4234-87B2-E963F8CE9498}");
|
||||
Chain<AddIndexToPropertyTypeAliasColumn>("{D454541C-15C5-41CF-8109-937F26A78E71}");
|
||||
|
||||
// merging from 7.9.0
|
||||
Chain<AddIsSensitiveMemberTypeColumn>("{89A728D1-FF4C-4155-A269-62CC09AD2131}");
|
||||
Chain<AddUmbracoAuditTable>("{FD8631BC-0388-425C-A451-5F58574F6F05}");
|
||||
Chain<AddUmbracoConsentTable>("{2821F53E-C58B-4812-B184-9CD240F990D7}");
|
||||
Chain<CreateSensitiveDataUserGroup>("{8918450B-3DA0-4BB7-886A-6FA8B7E4186E}"); // final state
|
||||
|
||||
// BEWARE! whenever changing the final state, update below!
|
||||
|
||||
|
||||
// INSTALL
|
||||
//
|
||||
// when installing, the source state is empty, and the target state should be the final state.
|
||||
// BEWARE! this MUST match the final state above!
|
||||
|
||||
Add(string.Empty, "{8918450B-3DA0-4BB7-886A-6FA8B7E4186E}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_8_0
|
||||
{
|
||||
internal class AddIndexToPropertyTypeAliasColumn : MigrationBase
|
||||
{
|
||||
public AddIndexToPropertyTypeAliasColumn(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(Context.Database);
|
||||
|
||||
//make sure it doesn't already exist
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsPropertyTypeAlias")) == false)
|
||||
{
|
||||
//we can apply the index
|
||||
Create.Index("IX_cmsPropertyTypeAlias").OnTable(Constants.DatabaseSchema.Tables.PropertyType)
|
||||
.OnColumn("Alias")
|
||||
.Ascending().WithOptions().NonClustered()
|
||||
.Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_8_0
|
||||
{
|
||||
internal class AddInstructionCountColumn : MigrationBase
|
||||
{
|
||||
public AddInstructionCountColumn(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals(Constants.DatabaseSchema.Tables.CacheInstruction) && x.ColumnName.InvariantEquals("instructionCount")) == false)
|
||||
AddColumn<CacheInstructionDto>("instructionCount");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.Persistence.Factories;
|
||||
using static Umbraco.Core.Persistence.NPocoSqlExtensions.Statics;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_8_0
|
||||
{
|
||||
internal class AddMediaVersionTable : MigrationBase
|
||||
{
|
||||
public AddMediaVersionTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
|
||||
|
||||
if (tables.InvariantContains(Constants.DatabaseSchema.Tables.MediaVersion)) return;
|
||||
|
||||
Create.Table<MediaVersionDto>().Do();
|
||||
MigrateMediaPaths();
|
||||
}
|
||||
|
||||
private void MigrateMediaPaths()
|
||||
{
|
||||
// this may not be the most efficient way to do it, compared to how it's done in v7, but this
|
||||
// migration should only run for v8 sites that are being developed, before v8 is released, so
|
||||
// no big sites and performances don't matter here - keep it simple
|
||||
|
||||
var sql = Sql()
|
||||
.Select<PropertyDataDto>(x => x.VarcharValue, x => x.TextValue)
|
||||
.AndSelect<ContentVersionDto>(x => Alias(x.Id, "versionId"))
|
||||
.From<PropertyDataDto>()
|
||||
.InnerJoin<PropertyTypeDto>().On<PropertyDataDto, PropertyTypeDto>((left, right) => left.PropertyTypeId == right.Id)
|
||||
.InnerJoin<ContentVersionDto>().On<PropertyDataDto, ContentVersionDto>((left, right) => left.VersionId == right.Id)
|
||||
.InnerJoin<NodeDto>().On<ContentVersionDto, NodeDto>((left, right) => left.NodeId == right.NodeId)
|
||||
.Where<PropertyTypeDto>(x => x.Alias == "umbracoFile")
|
||||
.Where<NodeDto>(x => x.NodeObjectType == Constants.ObjectTypes.Media);
|
||||
|
||||
var paths = new List<MediaVersionDto>();
|
||||
|
||||
//using QUERY = a db cursor, we won't load this all into memory first, just row by row
|
||||
foreach (var row in Database.Query<dynamic>(sql))
|
||||
{
|
||||
// if there's values then ensure there's a media path match and extract it
|
||||
string mediaPath = null;
|
||||
if (
|
||||
(row.varcharValue != null && ContentBaseFactory.TryMatch((string) row.varcharValue, out mediaPath))
|
||||
|| (row.textValue != null && ContentBaseFactory.TryMatch((string) row.textValue, out mediaPath)))
|
||||
{
|
||||
paths.Add(new MediaVersionDto
|
||||
{
|
||||
Id = (int) row.versionId,
|
||||
Path = mediaPath
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// bulk insert
|
||||
Database.BulkInsertRecords(paths);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_8_0
|
||||
{
|
||||
internal class AddTourDataUserColumn : MigrationBase
|
||||
{
|
||||
public AddTourDataUserColumn(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals(Constants.DatabaseSchema.Tables.User) && x.ColumnName.InvariantEquals("tourData")) == false)
|
||||
AddColumn<UserDto>("tourData");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_8_0
|
||||
{
|
||||
internal class AddUserLoginTable : MigrationBase
|
||||
{
|
||||
public AddUserLoginTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
|
||||
|
||||
if (tables.InvariantContains(Constants.DatabaseSchema.Tables.UserLogin) == false)
|
||||
{
|
||||
Create.Table<UserLoginDto>().Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_9_0
|
||||
{
|
||||
internal class AddIsSensitiveMemberTypeColumn : MigrationBase
|
||||
{
|
||||
public AddIsSensitiveMemberTypeColumn(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals(Constants.DatabaseSchema.Tables.MemberType) && x.ColumnName.InvariantEquals("isSensitive")) == false)
|
||||
AddColumn<MemberTypeDto>("isSensitive");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_9_0
|
||||
{
|
||||
internal class AddUmbracoAuditTable : MigrationBase
|
||||
{
|
||||
public AddUmbracoAuditTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
|
||||
|
||||
if (tables.InvariantContains(Constants.DatabaseSchema.Tables.AuditEntry))
|
||||
return;
|
||||
|
||||
Create.Table<AuditEntryDto>().Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_9_0
|
||||
{
|
||||
internal class AddUmbracoConsentTable : MigrationBase
|
||||
{
|
||||
public AddUmbracoConsentTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
|
||||
|
||||
if (tables.InvariantContains(Constants.DatabaseSchema.Tables.Consent))
|
||||
return;
|
||||
|
||||
Create.Table<ConsentDto>().Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_9_0
|
||||
{
|
||||
internal class CreateSensitiveDataUserGroup : MigrationBase
|
||||
{
|
||||
public CreateSensitiveDataUserGroup(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var sql = Sql()
|
||||
.SelectCount()
|
||||
.From<UserGroupDto>()
|
||||
.Where<UserGroupDto>(x => x.Alias == Constants.Security.SensitiveDataGroupAlias);
|
||||
|
||||
var exists = Database.ExecuteScalar<int>(sql) > 0;
|
||||
if (exists) return;
|
||||
|
||||
var groupId = Database.Insert(Constants.DatabaseSchema.Tables.UserGroup, "id", new UserGroupDto { StartMediaId = -1, StartContentId = -1, Alias = Constants.Security.SensitiveDataGroupAlias, Name = "Sensitive data", DefaultPermissions = "", CreateDate = DateTime.Now, UpdateDate = DateTime.Now, Icon = "icon-lock" });
|
||||
Database.Insert(new User2UserGroupDto { UserGroupId = Convert.ToInt32(groupId), UserId = Constants.Security.SuperId }); // add super to sensitive data
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
|
||||
// re-create *all* keys and indexes
|
||||
foreach (var x in DatabaseSchemaCreator.OrderedTables)
|
||||
Create.KeysAndIndexes(x.Value).Do();
|
||||
Create.KeysAndIndexes(x).Do();
|
||||
|
||||
// renames
|
||||
Database.Execute(Sql()
|
||||
|
||||
@@ -52,7 +52,7 @@ HAVING COUNT(v2.id) <> 1").Any())
|
||||
|
||||
// re-create *all* keys and indexes
|
||||
foreach (var x in DatabaseSchemaCreator.OrderedTables)
|
||||
Create.KeysAndIndexes(x.Value).Do();
|
||||
Create.KeysAndIndexes(x).Do();
|
||||
}
|
||||
|
||||
private void MigratePropertyData()
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an audited event.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class AuditEntry : EntityBase, IAuditEntry
|
||||
{
|
||||
private static PropertySelectors _selectors;
|
||||
|
||||
private int _performingUserId;
|
||||
private string _performingDetails;
|
||||
private string _performingIp;
|
||||
private int _affectedUserId;
|
||||
private string _affectedDetails;
|
||||
private string _eventType;
|
||||
private string _eventDetails;
|
||||
|
||||
private static PropertySelectors Selectors => _selectors ?? (_selectors = new PropertySelectors());
|
||||
|
||||
private class PropertySelectors
|
||||
{
|
||||
public readonly PropertyInfo PerformingUserId = ExpressionHelper.GetPropertyInfo<AuditEntry, int>(x => x.PerformingUserId);
|
||||
public readonly PropertyInfo PerformingDetails = ExpressionHelper.GetPropertyInfo<AuditEntry, string>(x => x.PerformingDetails);
|
||||
public readonly PropertyInfo PerformingIp = ExpressionHelper.GetPropertyInfo<AuditEntry, string>(x => x.PerformingIp);
|
||||
public readonly PropertyInfo AffectedUserId = ExpressionHelper.GetPropertyInfo<AuditEntry, int>(x => x.AffectedUserId);
|
||||
public readonly PropertyInfo AffectedDetails = ExpressionHelper.GetPropertyInfo<AuditEntry, string>(x => x.AffectedDetails);
|
||||
public readonly PropertyInfo EventType = ExpressionHelper.GetPropertyInfo<AuditEntry, string>(x => x.EventType);
|
||||
public readonly PropertyInfo EventDetails = ExpressionHelper.GetPropertyInfo<AuditEntry, string>(x => x.EventDetails);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public int PerformingUserId
|
||||
{
|
||||
get => _performingUserId;
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _performingUserId, Selectors.PerformingUserId);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string PerformingDetails
|
||||
{
|
||||
get => _performingDetails;
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _performingDetails, Selectors.PerformingDetails);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string PerformingIp
|
||||
{
|
||||
get => _performingIp;
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _performingIp, Selectors.PerformingIp);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public DateTime EventDateUtc
|
||||
{
|
||||
get => CreateDate;
|
||||
set => CreateDate = value;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public int AffectedUserId
|
||||
{
|
||||
get => _affectedUserId;
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _affectedUserId, Selectors.AffectedUserId);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string AffectedDetails
|
||||
{
|
||||
get => _affectedDetails;
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _affectedDetails, Selectors.AffectedDetails);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string EventType
|
||||
{
|
||||
get => _eventType;
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _eventType, Selectors.EventType);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string EventDetails
|
||||
{
|
||||
get => _eventDetails;
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _eventDetails, Selectors.EventDetails);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,18 +2,29 @@
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
public sealed class AuditItem : EntityBase
|
||||
public sealed class AuditItem : EntityBase, IAuditItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor for creating an item to be created
|
||||
/// </summary>
|
||||
/// <param name="objectId"></param>
|
||||
/// <param name="comment"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="userId"></param>
|
||||
public AuditItem(int objectId, string comment, AuditType type, int userId)
|
||||
{
|
||||
DisableChangeTracking();
|
||||
|
||||
Id = objectId;
|
||||
Comment = comment;
|
||||
AuditType = type;
|
||||
UserId = userId;
|
||||
|
||||
EnableChangeTracking();
|
||||
}
|
||||
|
||||
public string Comment { get; private set; }
|
||||
public AuditType AuditType { get; private set; }
|
||||
public int UserId { get; private set; }
|
||||
public string Comment { get; }
|
||||
public AuditType AuditType { get; }
|
||||
public int UserId { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a consent.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class Consent : EntityBase, IConsent
|
||||
{
|
||||
private static PropertySelectors _selector;
|
||||
|
||||
private bool _current;
|
||||
private string _source;
|
||||
private string _context;
|
||||
private string _action;
|
||||
private ConsentState _state;
|
||||
private string _comment;
|
||||
|
||||
// ReSharper disable once ClassNeverInstantiated.Local
|
||||
private class PropertySelectors
|
||||
{
|
||||
public readonly PropertyInfo Current = ExpressionHelper.GetPropertyInfo<Consent, bool>(x => x.Current);
|
||||
public readonly PropertyInfo Source = ExpressionHelper.GetPropertyInfo<Consent, string>(x => x.Source);
|
||||
public readonly PropertyInfo Context = ExpressionHelper.GetPropertyInfo<Consent, string>(x => x.Context);
|
||||
public readonly PropertyInfo Action = ExpressionHelper.GetPropertyInfo<Consent, string>(x => x.Action);
|
||||
public readonly PropertyInfo State = ExpressionHelper.GetPropertyInfo<Consent, ConsentState>(x => x.State);
|
||||
public readonly PropertyInfo Comment = ExpressionHelper.GetPropertyInfo<Consent, string>(x => x.Comment);
|
||||
}
|
||||
|
||||
private static PropertySelectors Selectors => _selector ?? (_selector = new PropertySelectors());
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Current
|
||||
{
|
||||
get => _current;
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _current, Selectors.Current);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Source
|
||||
{
|
||||
get => _source;
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException(nameof(value));
|
||||
SetPropertyValueAndDetectChanges(value, ref _source, Selectors.Source);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Context
|
||||
{
|
||||
get => _context;
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException(nameof(value));
|
||||
SetPropertyValueAndDetectChanges(value, ref _context, Selectors.Context);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Action
|
||||
{
|
||||
get => _action;
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value)) throw new ArgumentException(nameof(value));
|
||||
SetPropertyValueAndDetectChanges(value, ref _action, Selectors.Action);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ConsentState State
|
||||
{
|
||||
get => _state;
|
||||
// note: we probably should validate the state here, but since the
|
||||
// enum is [Flags] with many combinations, this could be expensive
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _state, Selectors.State);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Comment
|
||||
{
|
||||
get => _comment;
|
||||
set => SetPropertyValueAndDetectChanges(value, ref _comment, Selectors.Comment);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IConsent> History => HistoryInternal;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the previous states of this consent.
|
||||
/// </summary>
|
||||
internal List<IConsent> HistoryInternal { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extension methods for the <see cref="IConsent"/> interface.
|
||||
/// </summary>
|
||||
public static class ConsentExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether the consent is granted.
|
||||
/// </summary>
|
||||
public static bool IsGranted(this IConsent consent) => (consent.State & ConsentState.Granted) > 0;
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the consent is revoked.
|
||||
/// </summary>
|
||||
public static bool IsRevoked(this IConsent consent) => (consent.State & ConsentState.Revoked) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the state of a consent.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum ConsentState // : int
|
||||
{
|
||||
// note - this is a [Flags] enumeration
|
||||
// on can create detailed flags such as:
|
||||
//GrantedOptIn = Granted | 0x0001
|
||||
//GrandedByForce = Granted | 0x0002
|
||||
//
|
||||
// 16 situations for each Pending/Granted/Revoked should be ok
|
||||
|
||||
/// <summary>
|
||||
/// There is no consent.
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Consent is pending and has not been granted yet.
|
||||
/// </summary>
|
||||
Pending = 0x10000,
|
||||
|
||||
/// <summary>
|
||||
/// Consent has been granted.
|
||||
/// </summary>
|
||||
Granted = 0x20000,
|
||||
|
||||
/// <summary>
|
||||
/// Consent has been revoked.
|
||||
/// </summary>
|
||||
Revoked = 0x40000
|
||||
}
|
||||
}
|
||||
@@ -223,9 +223,8 @@ namespace Umbraco.Core.Models
|
||||
|
||||
#region Dirty
|
||||
|
||||
/// <summary>
|
||||
/// Resets dirty properties.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
/// <remarks>Overriden to include user properties.</remarks>
|
||||
public override void ResetDirtyProperties(bool rememberDirty)
|
||||
{
|
||||
base.ResetDirtyProperties(rememberDirty);
|
||||
@@ -235,17 +234,15 @@ namespace Umbraco.Core.Models
|
||||
prop.ResetDirtyProperties(rememberDirty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the current entity is dirty.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
/// <remarks>Overriden to include user properties.</remarks>
|
||||
public override bool IsDirty()
|
||||
{
|
||||
return IsEntityDirty() || this.IsAnyUserPropertyDirty();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the current entity was dirty.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
/// <remarks>Overriden to include user properties.</remarks>
|
||||
public override bool WasDirty()
|
||||
{
|
||||
return WasEntityDirty() || this.WasAnyUserPropertyDirty();
|
||||
@@ -267,9 +264,8 @@ namespace Umbraco.Core.Models
|
||||
return base.WasDirty();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether a user property is dirty.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
/// <remarks>Overriden to include user properties.</remarks>
|
||||
public override bool IsPropertyDirty(string propertyName)
|
||||
{
|
||||
if (base.IsPropertyDirty(propertyName))
|
||||
@@ -278,9 +274,8 @@ namespace Umbraco.Core.Models
|
||||
return Properties.Contains(propertyName) && Properties[propertyName].IsDirty();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether a user property was dirty.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
/// <remarks>Overriden to include user properties.</remarks>
|
||||
public override bool WasPropertyDirty(string propertyName)
|
||||
{
|
||||
if (base.WasPropertyDirty(propertyName))
|
||||
@@ -289,6 +284,24 @@ namespace Umbraco.Core.Models
|
||||
return Properties.Contains(propertyName) && Properties[propertyName].WasDirty();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <remarks>Overriden to include user properties.</remarks>
|
||||
public override IEnumerable<string> GetDirtyProperties()
|
||||
{
|
||||
var instanceProperties = base.GetDirtyProperties();
|
||||
var propertyTypes = Properties.Where(x => x.IsDirty()).Select(x => x.Alias);
|
||||
return instanceProperties.Concat(propertyTypes);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <remarks>Overriden to include user properties.</remarks>
|
||||
public override IEnumerable<string> GetWereDirtyProperties()
|
||||
{
|
||||
var instanceProperties = base.GetWereDirtyProperties();
|
||||
var propertyTypes = Properties.Where(x => x.WasDirty()).Select(x => x.Alias);
|
||||
return instanceProperties.Concat(propertyTypes);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,11 +97,13 @@ namespace Umbraco.Core.Models
|
||||
[DataMember]
|
||||
public IEnumerable<ITemplate> AllowedTemplates
|
||||
{
|
||||
get { return _allowedTemplates; }
|
||||
get => _allowedTemplates;
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(value, ref _allowedTemplates, Ps.Value.AllowedTemplatesSelector,
|
||||
Ps.Value.TemplateComparer);
|
||||
SetPropertyValueAndDetectChanges(value, ref _allowedTemplates, Ps.Value.AllowedTemplatesSelector, Ps.Value.TemplateComparer);
|
||||
|
||||
if (_allowedTemplates.Any(x => x.Id == _defaultTemplate) == false)
|
||||
DefaultTemplateId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an audited event.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>The free-form details properties can be used to capture relevant infos (for example,
|
||||
/// a user email and identifier) at the time of the audited event, even though they may change
|
||||
/// later on - but we want to keep a track of their value at that time.</para>
|
||||
/// <para>Depending on audit loggers, these properties can be purely free-form text, or
|
||||
/// contain json serialized objects.</para>
|
||||
/// </remarks>
|
||||
public interface IAuditEntry : IEntity, IRememberBeingDirty
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the identifier of the user triggering the audited event.
|
||||
/// </summary>
|
||||
int PerformingUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets free-form details about the user triggering the audited event.
|
||||
/// </summary>
|
||||
string PerformingDetails { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the IP address or the request triggering the audited event.
|
||||
/// </summary>
|
||||
string PerformingIp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the date and time of the audited event.
|
||||
/// </summary>
|
||||
DateTime EventDateUtc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the identifier of the user affected by the audited event.
|
||||
/// </summary>
|
||||
/// <remarks>Not used when no single user is affected by the event.</remarks>
|
||||
int AffectedUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets free-form details about the entity affected by the audited event.
|
||||
/// </summary>
|
||||
/// <remarks>The entity affected by the event can be another user, a member...</remarks>
|
||||
string AffectedDetails { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type of the audited event.
|
||||
/// </summary>
|
||||
string EventType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets free-form details about the audited event.
|
||||
/// </summary>
|
||||
string EventDetails { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
public interface IAuditItem : IEntity
|
||||
{
|
||||
string Comment { get; }
|
||||
AuditType AuditType { get; }
|
||||
int UserId { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a consent state.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>A consent is fully identified by a source (whoever is consenting), a context (for
|
||||
/// example, an application), and an action (whatever is consented).</para>
|
||||
/// <para>A consent state registers the state of the consent (granted, revoked...).</para>
|
||||
/// </remarks>
|
||||
public interface IConsent : IEntity, IRememberBeingDirty
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether the consent entity represents the current state.
|
||||
/// </summary>
|
||||
bool Current { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique identifier of whoever is consenting.
|
||||
/// </summary>
|
||||
string Source { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique identifier of the context of the consent.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Represents the domain, application, scope... of the action.</para>
|
||||
/// <para>When the action is a Udi, this should be the Udi type.</para>
|
||||
/// </remarks>
|
||||
string Context { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique identifier of the consented action.
|
||||
/// </summary>
|
||||
string Action { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the state of the consent.
|
||||
/// </summary>
|
||||
ConsentState State { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets some additional free text.
|
||||
/// </summary>
|
||||
string Comment { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the previous states of this consent.
|
||||
/// </summary>
|
||||
IEnumerable<IConsent> History { get; }
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,13 @@
|
||||
/// <returns></returns>
|
||||
bool MemberCanViewProperty(string propertyTypeAlias);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether a Property is marked as storing sensitive values on the Members profile.
|
||||
/// </summary>
|
||||
/// <param name="propertyTypeAlias">PropertyType Alias of the Property to check</param>
|
||||
/// <returns></returns>
|
||||
bool IsSensitiveProperty(string propertyTypeAlias);
|
||||
|
||||
/// <summary>
|
||||
/// Sets a boolean indicating whether a Property is editable by the Member.
|
||||
/// </summary>
|
||||
@@ -32,5 +39,12 @@
|
||||
/// <param name="propertyTypeAlias">PropertyType Alias of the Property to set</param>
|
||||
/// <param name="value">Boolean value, true or false</param>
|
||||
void SetMemberCanViewProperty(string propertyTypeAlias, bool value);
|
||||
|
||||
/// <summary>
|
||||
/// Sets a boolean indicating whether a Property is a sensitive value on the Members profile.
|
||||
/// </summary>
|
||||
/// <param name="propertyTypeAlias">PropertyType Alias of the Property to set</param>
|
||||
/// <param name="value">Boolean value, true or false</param>
|
||||
void SetIsSensitiveProperty(string propertyTypeAlias, bool value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,7 +168,19 @@ namespace Umbraco.Core.Models
|
||||
public string RawPasswordValue
|
||||
{
|
||||
get { return _rawPasswordValue; }
|
||||
set { SetPropertyValueAndDetectChanges(value, ref _rawPasswordValue, Ps.Value.PasswordSelector); }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
//special case, this is used to ensure that the password is not updated when persisting, in this case
|
||||
//we don't want to track changes either
|
||||
_rawPasswordValue = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(value, ref _rawPasswordValue, Ps.Value.PasswordSelector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets a Dictionary of Tuples (MemberCanEdit, VisibleOnProfile) by the PropertyTypes' alias.
|
||||
/// Gets or Sets a Dictionary of Tuples (MemberCanEdit, VisibleOnProfile, IsSensitive) by the PropertyTypes' alias.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
internal IDictionary<string, MemberTypePropertyProfileAccess> MemberTypePropertyTypes { get; private set; }
|
||||
@@ -91,7 +91,7 @@ namespace Umbraco.Core.Models
|
||||
/// <returns></returns>
|
||||
public bool MemberCanEditProperty(string propertyTypeAlias)
|
||||
{
|
||||
return MemberTypePropertyTypes.ContainsKey(propertyTypeAlias) && MemberTypePropertyTypes[propertyTypeAlias].IsEditable;
|
||||
return MemberTypePropertyTypes.TryGetValue(propertyTypeAlias, out var propertyProfile) && propertyProfile.IsEditable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -101,7 +101,16 @@ namespace Umbraco.Core.Models
|
||||
/// <returns></returns>
|
||||
public bool MemberCanViewProperty(string propertyTypeAlias)
|
||||
{
|
||||
return MemberTypePropertyTypes.ContainsKey(propertyTypeAlias) && MemberTypePropertyTypes[propertyTypeAlias].IsVisible;
|
||||
return MemberTypePropertyTypes.TryGetValue(propertyTypeAlias, out var propertyProfile) && propertyProfile.IsVisible;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether a Property is marked as storing sensitive values on the Members profile.
|
||||
/// </summary>
|
||||
/// <param name="propertyTypeAlias">PropertyType Alias of the Property to check</param>
|
||||
/// <returns></returns>
|
||||
public bool IsSensitiveProperty(string propertyTypeAlias)
|
||||
{
|
||||
return MemberTypePropertyTypes.TryGetValue(propertyTypeAlias, out var propertyProfile) && propertyProfile.IsSensitive;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -111,13 +120,13 @@ namespace Umbraco.Core.Models
|
||||
/// <param name="value">Boolean value, true or false</param>
|
||||
public void SetMemberCanEditProperty(string propertyTypeAlias, bool value)
|
||||
{
|
||||
if (MemberTypePropertyTypes.ContainsKey(propertyTypeAlias))
|
||||
if (MemberTypePropertyTypes.TryGetValue(propertyTypeAlias, out var propertyProfile))
|
||||
{
|
||||
MemberTypePropertyTypes[propertyTypeAlias].IsEditable = value;
|
||||
propertyProfile.IsEditable = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
var tuple = new MemberTypePropertyProfileAccess(false, value);
|
||||
var tuple = new MemberTypePropertyProfileAccess(false, value, false);
|
||||
MemberTypePropertyTypes.Add(propertyTypeAlias, tuple);
|
||||
}
|
||||
}
|
||||
@@ -129,13 +138,31 @@ namespace Umbraco.Core.Models
|
||||
/// <param name="value">Boolean value, true or false</param>
|
||||
public void SetMemberCanViewProperty(string propertyTypeAlias, bool value)
|
||||
{
|
||||
if (MemberTypePropertyTypes.ContainsKey(propertyTypeAlias))
|
||||
if (MemberTypePropertyTypes.TryGetValue(propertyTypeAlias, out var propertyProfile))
|
||||
{
|
||||
MemberTypePropertyTypes[propertyTypeAlias].IsVisible = value;
|
||||
propertyProfile.IsVisible = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
var tuple = new MemberTypePropertyProfileAccess(value, false);
|
||||
var tuple = new MemberTypePropertyProfileAccess(value, false, false);
|
||||
MemberTypePropertyTypes.Add(propertyTypeAlias, tuple);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a boolean indicating whether a Property is a sensitive value on the Members profile.
|
||||
/// </summary>
|
||||
/// <param name="propertyTypeAlias">PropertyType Alias of the Property to set</param>
|
||||
/// <param name="value">Boolean value, true or false</param>
|
||||
public void SetIsSensitiveProperty(string propertyTypeAlias, bool value)
|
||||
{
|
||||
if (MemberTypePropertyTypes.TryGetValue(propertyTypeAlias, out var propertyProfile))
|
||||
{
|
||||
propertyProfile.IsSensitive = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
var tuple = new MemberTypePropertyProfileAccess(false, false, true);
|
||||
MemberTypePropertyTypes.Add(propertyTypeAlias, tuple);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,13 +5,15 @@
|
||||
/// </summary>
|
||||
internal class MemberTypePropertyProfileAccess
|
||||
{
|
||||
public MemberTypePropertyProfileAccess(bool isVisible, bool isEditable)
|
||||
public MemberTypePropertyProfileAccess(bool isVisible, bool isEditable, bool isSenstive)
|
||||
{
|
||||
IsVisible = isVisible;
|
||||
IsEditable = isEditable;
|
||||
IsSensitive = isSenstive;
|
||||
}
|
||||
|
||||
public bool IsVisible { get; set; }
|
||||
public bool IsEditable { get; set; }
|
||||
public bool IsSensitive { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,11 +188,11 @@ namespace Umbraco.Core.Models
|
||||
Language,
|
||||
|
||||
/// <summary>
|
||||
/// Document
|
||||
/// Document Blueprint
|
||||
/// </summary>
|
||||
[UmbracoObjectType(Constants.ObjectTypes.Strings.DocumentBlueprint, typeof(IContent))]
|
||||
[FriendlyName("DocumentBlueprint")]
|
||||
[UmbracoUdiType(Constants.UdiEntityType.DocumentBluePrint)]
|
||||
[UmbracoUdiType(Constants.UdiEntityType.DocumentBlueprint)]
|
||||
DocumentBlueprint,
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -48,12 +48,11 @@ namespace Umbraco.Core.Models
|
||||
/// Tries to lookup the user's gravatar to see if the endpoint can be reached, if so it returns the valid URL
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="userService"></param>
|
||||
/// <param name="staticCache"></param>
|
||||
/// <returns>
|
||||
/// A list of 5 different sized avatar URLs
|
||||
/// </returns>
|
||||
internal static string[] GetCurrentUserAvatarUrls(this IUser user, IUserService userService, ICacheProvider staticCache)
|
||||
internal static string[] GetUserAvatarUrls(this IUser user, ICacheProvider staticCache)
|
||||
{
|
||||
//check if the user has explicitly removed all avatars including a gravatar, this will be possible and the value will be "none"
|
||||
if (user.Avatar == "none")
|
||||
@@ -276,6 +275,16 @@ namespace Umbraco.Core.Models
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this user has access to view sensitive data
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
public static bool HasAccessToSensitiveData(this IUser user)
|
||||
{
|
||||
if (user == null) throw new ArgumentNullException("user");
|
||||
return user.Groups != null && user.Groups.Any(x => x.Alias == Constants.Security.SensitiveDataGroupAlias);
|
||||
}
|
||||
|
||||
// calc. start nodes, combining groups' and user's, and excluding what's in the bin
|
||||
public static int[] CalculateContentStartNodeIds(this IUser user, IEntityService entityService)
|
||||
{
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace Umbraco.Core
|
||||
public const string ContentVersion = TableNamePrefix + "ContentVersion";
|
||||
public const string Document = TableNamePrefix + "Document";
|
||||
public const string DocumentVersion = TableNamePrefix + "DocumentVersion";
|
||||
public const string MediaVersion = TableNamePrefix + "MediaVersion";
|
||||
|
||||
public const string PropertyType = /*TableNamePrefix*/ "cms" + "PropertyType";
|
||||
public const string PropertyTypeGroup = /*TableNamePrefix*/ "cms" + "PropertyTypeGroup";
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
using NPoco;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Dtos
|
||||
{
|
||||
// this is a special Dto that does not have a corresponding table
|
||||
// and is only used in our code to represent a media item, similar
|
||||
// to document items.
|
||||
|
||||
internal class MediaDto
|
||||
{
|
||||
public int NodeId { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
[Reference(ReferenceType.OneToOne, ReferenceMemberName = "NodeId")]
|
||||
public ContentDto ContentDto { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
[Reference(ReferenceType.OneToOne)]
|
||||
public MediaVersionDto MediaVersionDto { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using NPoco;
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Dtos
|
||||
{
|
||||
[TableName(Constants.DatabaseSchema.Tables.MediaVersion)]
|
||||
[PrimaryKey("id", AutoIncrement = false)]
|
||||
[ExplicitColumns]
|
||||
internal class MediaVersionDto
|
||||
{
|
||||
[Column("id")]
|
||||
[PrimaryKeyColumn(AutoIncrement = false)]
|
||||
[ForeignKey(typeof(ContentVersionDto))]
|
||||
[Index(IndexTypes.UniqueNonClustered, Name = "IX_" + Constants.DatabaseSchema.Tables.MediaVersion, ForColumns = "id, path")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("path")]
|
||||
[NullSetting(NullSetting = NullSettings.Null)]
|
||||
public string Path { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
[Reference(ReferenceType.OneToOne)]
|
||||
public ContentVersionDto ContentVersionDto { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
internal static class AuditEntryFactory
|
||||
{
|
||||
public static IEnumerable<IAuditEntry> BuildEntities(IEnumerable<AuditEntryDto> dtos)
|
||||
{
|
||||
return dtos.Select(BuildEntity).ToList();
|
||||
}
|
||||
|
||||
public static IAuditEntry BuildEntity(AuditEntryDto dto)
|
||||
{
|
||||
var entity = new AuditEntry
|
||||
{
|
||||
Id = dto.Id,
|
||||
PerformingUserId = dto.PerformingUserId,
|
||||
PerformingDetails = dto.PerformingDetails,
|
||||
PerformingIp = dto.PerformingIp,
|
||||
EventDateUtc = dto.EventDateUtc,
|
||||
AffectedUserId = dto.AffectedUserId,
|
||||
AffectedDetails = dto.AffectedDetails,
|
||||
EventType = dto.EventType,
|
||||
EventDetails = dto.EventDetails
|
||||
};
|
||||
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
entity.ResetDirtyProperties(false);
|
||||
return entity;
|
||||
}
|
||||
|
||||
public static AuditEntryDto BuildDto(IAuditEntry entity)
|
||||
{
|
||||
return new AuditEntryDto
|
||||
{
|
||||
Id = entity.Id,
|
||||
PerformingUserId = entity.PerformingUserId,
|
||||
PerformingDetails = entity.PerformingDetails,
|
||||
PerformingIp = entity.PerformingIp,
|
||||
EventDateUtc = entity.EventDateUtc,
|
||||
AffectedUserId = entity.AffectedUserId,
|
||||
AffectedDetails = entity.AffectedDetails,
|
||||
EventType = entity.EventType,
|
||||
EventDetails = entity.EventDetails
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
internal static class ConsentFactory
|
||||
{
|
||||
public static IEnumerable<IConsent> BuildEntities(IEnumerable<ConsentDto> dtos)
|
||||
{
|
||||
var ix = new Dictionary<string, Consent>();
|
||||
var output = new List<Consent>();
|
||||
|
||||
foreach (var dto in dtos)
|
||||
{
|
||||
var k = dto.Source + "::" + dto.Context + "::" + dto.Action;
|
||||
|
||||
var consent = new Consent
|
||||
{
|
||||
Id = dto.Id,
|
||||
Current = dto.Current,
|
||||
CreateDate = dto.CreateDate,
|
||||
Source = dto.Source,
|
||||
Context = dto.Context,
|
||||
Action = dto.Action,
|
||||
State = (ConsentState) dto.State, // assume value is valid
|
||||
Comment = dto.Comment
|
||||
};
|
||||
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
consent.ResetDirtyProperties(false);
|
||||
|
||||
if (ix.TryGetValue(k, out var current))
|
||||
{
|
||||
if (current.HistoryInternal == null)
|
||||
current.HistoryInternal = new List<IConsent>();
|
||||
current.HistoryInternal.Add(consent);
|
||||
}
|
||||
else
|
||||
{
|
||||
ix[k] = consent;
|
||||
output.Add(consent);
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
public static ConsentDto BuildDto(IConsent entity)
|
||||
{
|
||||
return new ConsentDto
|
||||
{
|
||||
Id = entity.Id,
|
||||
Current = entity.Current,
|
||||
CreateDate = entity.CreateDate,
|
||||
Source = entity.Source,
|
||||
Context = entity.Context,
|
||||
Action = entity.Action,
|
||||
State = (int) entity.State,
|
||||
Comment = entity.Comment
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -6,6 +7,8 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
internal class ContentBaseFactory
|
||||
{
|
||||
private static readonly Regex MediaPathPattern = new Regex(@"(/media/.+?)(?:['""]|$)", RegexOptions.Compiled);
|
||||
|
||||
/// <summary>
|
||||
/// Builds an IContent item from a dto and content type.
|
||||
/// </summary>
|
||||
@@ -177,11 +180,18 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
/// <summary>
|
||||
/// Buils a dto from an IMedia item.
|
||||
/// </summary>
|
||||
public static ContentDto BuildDto(IMedia entity)
|
||||
public static MediaDto BuildDto(IMedia entity)
|
||||
{
|
||||
var contentBase = (Models.Media) entity;
|
||||
var dto = BuildContentDto(contentBase, Constants.ObjectTypes.Media);
|
||||
dto.ContentVersionDto = BuildContentVersionDto(contentBase, dto);
|
||||
var contentDto = BuildContentDto(contentBase, Constants.ObjectTypes.Media);
|
||||
|
||||
var dto = new MediaDto
|
||||
{
|
||||
NodeId = entity.Id,
|
||||
ContentDto = contentDto,
|
||||
MediaVersionDto = BuildMediaVersionDto(contentBase, contentDto)
|
||||
};
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
@@ -273,5 +283,37 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
private static MediaVersionDto BuildMediaVersionDto(Models.Media entity, ContentDto contentDto)
|
||||
{
|
||||
// try to get a path from the string being stored for media
|
||||
// fixme - only considering umbracoFile ?!
|
||||
|
||||
TryMatch(entity.GetValue<string>("umbracoFile"), out var path);
|
||||
|
||||
var dto = new MediaVersionDto
|
||||
{
|
||||
Id = entity.VersionId,
|
||||
Path = path,
|
||||
|
||||
ContentVersionDto = BuildContentVersionDto(entity, contentDto)
|
||||
};
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
// fixme - this should NOT be here?!
|
||||
// more dark magic ;-(
|
||||
internal static bool TryMatch(string text, out string path)
|
||||
{
|
||||
path = null;
|
||||
if (string.IsNullOrWhiteSpace(text)) return false;
|
||||
|
||||
var m = MediaPathPattern.Match(text);
|
||||
if (!m.Success || m.Groups.Count != 2) return false;
|
||||
|
||||
path = m.Groups[1].Value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,8 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
NodeId = entity.Id,
|
||||
PropertyTypeId = x.Id,
|
||||
CanEdit = memberType.MemberCanEditProperty(x.Alias),
|
||||
ViewOnProfile = memberType.MemberCanViewProperty(x.Alias)
|
||||
ViewOnProfile = memberType.MemberCanViewProperty(x.Alias),
|
||||
IsSensitive = memberType.IsSensitiveProperty(x.Alias)
|
||||
}).ToList();
|
||||
return dtos;
|
||||
}
|
||||
|
||||
@@ -57,10 +57,10 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
|
||||
//Add the standard PropertyType to the current list
|
||||
propertyTypes.Add(standardPropertyType.Value);
|
||||
|
||||
//Internal dictionary for adding "MemberCanEdit" and "VisibleOnProfile" properties to each PropertyType
|
||||
|
||||
//Internal dictionary for adding "MemberCanEdit", "VisibleOnProfile", "IsSensitive" properties to each PropertyType
|
||||
memberType.MemberTypePropertyTypes.Add(standardPropertyType.Key,
|
||||
new MemberTypePropertyProfileAccess(false, false));
|
||||
new MemberTypePropertyProfileAccess(false, false, false));
|
||||
}
|
||||
memberType.NoGroupPropertyTypes = propertyTypes;
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
//Internal dictionary for adding "MemberCanEdit" and "VisibleOnProfile" properties to each PropertyType
|
||||
memberType.MemberTypePropertyTypes.Add(typeDto.Alias,
|
||||
new MemberTypePropertyProfileAccess(typeDto.ViewOnProfile, typeDto.CanEdit));
|
||||
new MemberTypePropertyProfileAccess(typeDto.ViewOnProfile, typeDto.CanEdit, typeDto.IsSensitive));
|
||||
|
||||
var tempGroupDto = groupDto;
|
||||
|
||||
@@ -158,7 +158,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
//Internal dictionary for adding "MemberCanEdit" and "VisibleOnProfile" properties to each PropertyType
|
||||
memberType.MemberTypePropertyTypes.Add(typeDto.Alias,
|
||||
new MemberTypePropertyProfileAccess(typeDto.ViewOnProfile, typeDto.CanEdit));
|
||||
new MemberTypePropertyProfileAccess(typeDto.ViewOnProfile, typeDto.CanEdit, typeDto.IsSensitive));
|
||||
|
||||
//ensures that any built-in membership properties have their correct dbtype assigned no matter
|
||||
//what the underlying data type is
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
user.Avatar = dto.Avatar;
|
||||
user.EmailConfirmedDate = dto.EmailConfirmedDate;
|
||||
user.InvitedDate = dto.InvitedDate;
|
||||
user.TourData = dto.TourData;
|
||||
|
||||
// reset dirty initial properties (U4-1946)
|
||||
user.ResetDirtyProperties(false);
|
||||
@@ -68,7 +69,8 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
UpdateDate = entity.UpdateDate,
|
||||
Avatar = entity.Avatar,
|
||||
EmailConfirmedDate = entity.EmailConfirmedDate,
|
||||
InvitedDate = entity.InvitedDate
|
||||
InvitedDate = entity.InvitedDate,
|
||||
TourData = entity.TourData
|
||||
};
|
||||
|
||||
foreach (var startNodeId in entity.StartContentIds)
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a mapper for audit entry entities.
|
||||
/// </summary>
|
||||
[MapperFor(typeof(IAuditEntry))]
|
||||
[MapperFor(typeof(AuditEntry))]
|
||||
public sealed class AuditEntryMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AuditEntryMapper"/> class.
|
||||
/// </summary>
|
||||
public AuditEntryMapper()
|
||||
{
|
||||
// note: why the base ctor does not invoke BuildMap is a mystery to me
|
||||
BuildMap();
|
||||
}
|
||||
|
||||
protected override void BuildMap()
|
||||
{
|
||||
CacheMap<AuditEntry, AuditEntryDto>(entity => entity.Id, dto => dto.Id);
|
||||
CacheMap<AuditEntry, AuditEntryDto>(entity => entity.PerformingUserId, dto => dto.PerformingUserId);
|
||||
CacheMap<AuditEntry, AuditEntryDto>(entity => entity.PerformingDetails, dto => dto.PerformingDetails);
|
||||
CacheMap<AuditEntry, AuditEntryDto>(entity => entity.PerformingIp, dto => dto.PerformingIp);
|
||||
CacheMap<AuditEntry, AuditEntryDto>(entity => entity.EventDateUtc, dto => dto.EventDateUtc);
|
||||
CacheMap<AuditEntry, AuditEntryDto>(entity => entity.AffectedUserId, dto => dto.AffectedUserId);
|
||||
CacheMap<AuditEntry, AuditEntryDto>(entity => entity.AffectedDetails, dto => dto.AffectedDetails);
|
||||
CacheMap<AuditEntry, AuditEntryDto>(entity => entity.EventType, dto => dto.EventType);
|
||||
CacheMap<AuditEntry, AuditEntryDto>(entity => entity.EventDetails, dto => dto.EventDetails);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
[MapperFor(typeof(AuditItem))]
|
||||
[MapperFor(typeof(IAuditItem))]
|
||||
public sealed class AuditMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
public AuditMapper()
|
||||
{
|
||||
BuildMap();
|
||||
}
|
||||
|
||||
protected override void BuildMap()
|
||||
{
|
||||
if (PropertyInfoCache.IsEmpty)
|
||||
{
|
||||
CacheMap<AuditItem, LogDto>(src => src.Id, dto => dto.NodeId);
|
||||
CacheMap<AuditItem, LogDto>(src => src.CreateDate, dto => dto.Datestamp);
|
||||
CacheMap<AuditItem, LogDto>(src => src.UserId, dto => dto.UserId);
|
||||
CacheMap<AuditItem, LogDto>(src => src.AuditType, dto => dto.Header);
|
||||
CacheMap<AuditItem, LogDto>(src => src.Comment, dto => dto.Comment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a mapper for consent entities.
|
||||
/// </summary>
|
||||
[MapperFor(typeof(IConsent))]
|
||||
[MapperFor(typeof(Consent))]
|
||||
public sealed class ConsentMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConsentMapper"/> class.
|
||||
/// </summary>
|
||||
public ConsentMapper()
|
||||
{
|
||||
// note: why the base ctor does not invoke BuildMap is a mystery to me
|
||||
BuildMap();
|
||||
}
|
||||
|
||||
protected override void BuildMap()
|
||||
{
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.Id, dto => dto.Id);
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.Current, dto => dto.Current);
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.Source, dto => dto.Source);
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.Context, dto => dto.Context);
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.Action, dto => dto.Action);
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.State, dto => dto.State);
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.Comment, dto => dto.Comment);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -326,10 +326,23 @@
|
||||
<Compile Include="KeyValuePairExtensions.cs" />
|
||||
<Compile Include="Logging\RollingFileCleanupAppender.cs" />
|
||||
<Compile Include="Migrations\MigrationBase_Extra.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_7_8_0\AddIndexToPropertyTypeAliasColumn.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_7_8_0\AddInstructionCountColumn.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_7_8_0\AddMediaVersionTable.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_7_8_0\AddTourDataUserColumn.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_7_8_0\AddUserLoginTable.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_7_9_0\AddIsSensitiveMemberTypeColumn.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_7_9_0\AddUmbracoAuditTable.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_7_9_0\AddUmbracoConsentTable.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_7_9_0\CreateSensitiveDataUserGroup.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\DataTypeMigration.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\PropertyEditorsMigration.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\SuperZero.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\TagsMigration.cs" />
|
||||
<Compile Include="Models\AuditEntry.cs" />
|
||||
<Compile Include="Models\Consent.cs" />
|
||||
<Compile Include="Models\ConsentExtensions.cs" />
|
||||
<Compile Include="Models\ConsentState.cs" />
|
||||
<Compile Include="Models\ContentTagsExtensions.cs" />
|
||||
<Compile Include="Models\ContentTypeBaseExtensions.cs" />
|
||||
<Compile Include="Models\DataTypeExtensions.cs" />
|
||||
@@ -342,6 +355,9 @@
|
||||
<Compile Include="Models\Entities\IDocumentEntitySlim.cs" />
|
||||
<Compile Include="Models\Entities\ContentEntitySlim.cs" />
|
||||
<Compile Include="Models\Entities\DocumentEntitySlim.cs" />
|
||||
<Compile Include="Models\IAuditEntry.cs" />
|
||||
<Compile Include="Models\IAuditItem.cs" />
|
||||
<Compile Include="Models\IConsent.cs" />
|
||||
<Compile Include="Models\Membership\MemberExportModel.cs" />
|
||||
<Compile Include="Models\Membership\MemberExportProperty.cs" />
|
||||
<Compile Include="Models\PathValidationExtensions.cs" />
|
||||
@@ -349,7 +365,14 @@
|
||||
<Compile Include="Models\PropertyTagsExtensions.cs" />
|
||||
<Compile Include="Persistence\Dtos\AuditEntryDto.cs" />
|
||||
<Compile Include="Persistence\Dtos\ConsentDto.cs" />
|
||||
<Compile Include="Persistence\Dtos\MediaDto.cs" />
|
||||
<Compile Include="Persistence\Dtos\MediaVersionDto.cs" />
|
||||
<Compile Include="Persistence\Dtos\UserLoginDto.cs" />
|
||||
<Compile Include="Persistence\Factories\AuditEntryFactory.cs" />
|
||||
<Compile Include="Persistence\Factories\ConsentFactory.cs" />
|
||||
<Compile Include="Persistence\Mappers\AuditEntryMapper.cs" />
|
||||
<Compile Include="Persistence\Mappers\AuditMapper.cs" />
|
||||
<Compile Include="Persistence\Mappers\ConsentMapper.cs" />
|
||||
<Compile Include="PropertyEditors\ConfigurationEditorOfTConfiguration.cs" />
|
||||
<Compile Include="PropertyEditors\DataEditorAttribute.cs" />
|
||||
<Compile Include="PropertyEditors\ConfigurationEditor.cs" />
|
||||
|
||||
@@ -240,9 +240,9 @@ namespace Umbraco.Tests.Migrations
|
||||
foreach (var x in DatabaseSchemaCreator.OrderedTables)
|
||||
{
|
||||
// ok - for tests, restrict to Node
|
||||
if (x.Value != typeof(NodeDto)) continue;
|
||||
if (x != typeof(NodeDto)) continue;
|
||||
|
||||
Create.KeysAndIndexes(x.Value).Do();
|
||||
Create.KeysAndIndexes(x).Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user