Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .azuredevops/azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ steps:
- 7.0.x
- 8.0.x
- 10.0.x
workingDirectory: "$(System.DefaultWorkingDirectory)"
workingDirectory: "$(System.DefaultWorkingDirectory)"
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Library</OutputType>
<Deterministic>false</Deterministic>
<TargetFrameworks>net6.0;net7.0;net8.0;net10.0</TargetFrameworks>
<Version>1.3.2.0</Version>
<IsPackable>true</IsPackable>
<DebugType>embedded</DebugType>
<Title>Epinova - Environment Synchronizer</Title>
<Authors>Ove Lartelius, Linus Ekström</Authors>
<Owners>Epinova AB</Owners>
<ProjectUrl>https://github.com/Epinova/Addon.Episerver.EnvironmentSynchronizer</ProjectUrl>
<RequireLicenseAcceptance>false</RequireLicenseAcceptance>
<Description>Environment synchronizer helps you to set your environment into a known state after synchronizing databases between environments.</Description>
<Copyright>Copyright © 2021 Epinova AB</Copyright>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0' ">
<PropertyGroup>
<OutputType>Library</OutputType>
<Deterministic>false</Deterministic>
<TargetFrameworks>net6.0;net7.0;net8.0;net10.0</TargetFrameworks>
<Version>1.3.2.0</Version>
<IsPackable>true</IsPackable>
<DebugType>embedded</DebugType>
<Title>Epinova - Environment Synchronizer</Title>
<Authors>Ove Lartelius, Linus Ekström</Authors>
<Owners>Epinova AB</Owners>
<ProjectUrl>https://github.com/Epinova/Addon.Episerver.EnvironmentSynchronizer</ProjectUrl>
<RequireLicenseAcceptance>false</RequireLicenseAcceptance>
<Description>Environment synchronizer helps you to set your environment into a known state after synchronizing databases between environments.</Description>
<Copyright>Copyright © 2021 Epinova AB</Copyright>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<PackageReference Include="EPiServer.CMS.AspNetCore" Version="12.4.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0' ">
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
<PackageReference Include="EPiServer.CMS.AspNetCore" Version="12.11.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0' ">
<PackageReference Include="EPiServer.CMS.AspNetCore" Version="12.11.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net10.0' ">
<PackageReference Include="EPiServer.CMS.AspNetCore" Version="12.11.0" />
</ItemGroup>
<ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="EPiServer.CMS.AspNetCore" Version="12.11.0" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net10.0'">
<PackageReference Include="EPiServer.CMS.AspNetCore" Version="13.0.2" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="Addon.Episerver.EnvironmentSynchronizer.Test" />
</ItemGroup>
</Project>
</Project>
Original file line number Diff line number Diff line change
@@ -1,146 +1,198 @@
using Addon.Episerver.EnvironmentSynchronizer.Models;
using EPiServer.Logging;
using EPiServer.Web;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using Microsoft.Extensions.Options;
using EPiServer.Security;
#if NET10_0_OR_GREATER
using EPiServer.Applications;
#else
using EPiServer.Web;
#endif

namespace Addon.Episerver.EnvironmentSynchronizer.Configuration
{
public class ConfigurationReader : IConfigurationReader
{
private static readonly ILogger Logger = LogManager.GetLogger();
public class ConfigurationReader : IConfigurationReader
{
private static readonly ILogger Logger = LogManager.GetLogger();

private readonly EnvironmentSynchronizerOptions _configuration;
private readonly EnvironmentSynchronizerOptions _configuration;

public ConfigurationReader(IOptions<EnvironmentSynchronizerOptions> synchronizerConfiguration)
public ConfigurationReader(IOptions<EnvironmentSynchronizerOptions> synchronizerConfiguration)
{
_configuration = synchronizerConfiguration.Value;
_configuration = synchronizerConfiguration.Value;
}

public SynchronizationData ReadConfiguration()
{
var syncData = new SynchronizationData();
public SynchronizationData ReadConfiguration()
{
var syncData = new SynchronizationData();

if(_configuration == null)
if (_configuration == null)
{
return syncData;
return syncData;
}

try
{
syncData.RunAsInitializationModule = _configuration.RunAsInitializationModule;
syncData.RunInitializationModuleEveryStartup = _configuration.RunInitializationModuleEveryStartup;

if (_configuration.SiteDefinitions != null && _configuration.SiteDefinitions.Count > 0)
{
syncData.SiteDefinitions = new List<EnvironmentSynchronizerSiteDefinition>();
foreach (var options in _configuration.SiteDefinitions)
{
var siteDefinition = CreateEnvironmentSynchronizerSiteDefinition(options);
if (!string.IsNullOrEmpty(siteDefinition.Name) && siteDefinition.SiteUrl != null)
{
syncData.SiteDefinitions.Add(siteDefinition);
}
}
}
else
{
Logger.Information($"Found no site definitions to handle. Missing Name/SiteUrl?");
}

if (_configuration.ScheduledJobs != null && _configuration.ScheduledJobs.Count > 0)
{
syncData.ScheduledJobs = new List<ScheduledJobDefinition>();
foreach (var options in _configuration.ScheduledJobs)
{
var job = new ScheduledJobDefinition
{
Id = options.Id,
Name = options.Name,
IsEnabled = options.IsEnabled,
AutoRun = options.AutoRun
};
syncData.ScheduledJobs.Add(job);
}
}
else
{
Logger.Information($"Found no schedule jobs to handle.");
}
}
catch (ArgumentException argEx)
{
if (argEx.Message.Contains("is not a valid host name"))
{
Logger.Error($"EnvironmentSynchronizer configuration found in the appSettings.json but there are hostnames that is not valid.", argEx);
} else
{
Logger.Error($"EnvironmentSynchronizer configuration found in the appSettings.json but some arguments is not correct.", argEx);
}

}
catch (Exception ex)
{
Logger.Error($"No configuration found in the appSettings.json. Missing EnvironmentSynchronizer section.", ex);
}

return syncData;
}

private EnvironmentSynchronizerSiteDefinition CreateEnvironmentSynchronizerSiteDefinition(SiteDefinitionOptions options)
{
var siteDefinition = new EnvironmentSynchronizerSiteDefinition()
{
Id = string.IsNullOrEmpty(options.Id) ? Guid.Empty : new Guid(options.Id),
Name = string.IsNullOrEmpty(options.Name) ? string.Empty : options.Name,
SiteUrl = string.IsNullOrEmpty(options.SiteUrl) ? null : new Uri(options.SiteUrl),
Hosts = ToHostDefinitions(options.Hosts),
ForceLogin = options.ForceLogin,
SetRoles = options.SetRoles != null ? ToSetRoleDefinitions(options.SetRoles) : new List<SetRoleDefinition>(),
RemoveRoles = options.RemoveRoles != null ? ToRemoveRoleDefinitions(options.RemoveRoles) : new List<RemoveRoleDefinition>()
};

return siteDefinition;
}

private List<HostDefinition> ToHostDefinitions(IList<HostOptions> hosts)
{
return hosts.Select(hostOptions => {
return new HostDefinition
{
Name = hostOptions.Name,
Type = hostOptions.Type != HostDefinitionType.Undefined ? hostOptions.Type : HostDefinitionType.Undefined,
UseSecureConnection = hostOptions.UseSecureConnection,
Language = string.IsNullOrEmpty(hostOptions.Language) ? null : new CultureInfo(hostOptions.Language)
};
}).ToList();
}

private List<SetRoleDefinition> ToSetRoleDefinitions(IList<SetRoleOptions> setRoles)
{
return setRoles.Select(setRoleOptions =>
{
return new SetRoleDefinition
{
Name = setRoleOptions.Name,
Access = setRoleOptions.Access != null ? AccessLevelConverter.ConvertToAccessLevel(setRoleOptions.Access) : AccessLevel.NoAccess,
};
}).ToList();
}

private List<RemoveRoleDefinition> ToRemoveRoleDefinitions(IList<string> removeRoles)
{
return removeRoles.Select(removeRoleOptions =>
{
return new RemoveRoleDefinition
{
Name = removeRoleOptions
};
}).ToList();
}
}
try
{
syncData.RunAsInitializationModule = _configuration.RunAsInitializationModule;
syncData.RunInitializationModuleEveryStartup = _configuration.RunInitializationModuleEveryStartup;

if (_configuration.SiteDefinitions != null && _configuration.SiteDefinitions.Count > 0)
{
syncData.SiteDefinitions = new List<EnvironmentSynchronizerSiteDefinition>();
foreach (var options in _configuration.SiteDefinitions)
{
var siteDefinition = CreateEnvironmentSynchronizerSiteDefinition(options);
#if NET10_0_OR_GREATER
if (!string.IsNullOrEmpty(siteDefinition.Name))
#else
if (!string.IsNullOrEmpty(siteDefinition.Name) && siteDefinition.SiteUrl != null)
#endif
{
syncData.SiteDefinitions.Add(siteDefinition);
}
}
}
else
{
#if NET10_0_OR_GREATER
Logger.Information($"Found no site definitions to handle. Missing Name?");
#else
Logger.Information($"Found no site definitions to handle. Missing Name/SiteUrl?");
#endif
}

if (_configuration.ScheduledJobs != null && _configuration.ScheduledJobs.Count > 0)
{
syncData.ScheduledJobs = new List<ScheduledJobDefinition>();
foreach (var options in _configuration.ScheduledJobs)
{
var job = new ScheduledJobDefinition
{
Id = options.Id,
Name = options.Name,
IsEnabled = options.IsEnabled,
AutoRun = options.AutoRun
};
syncData.ScheduledJobs.Add(job);
}
}
else
{
Logger.Information($"Found no schedule jobs to handle.");
}
}
catch (ArgumentException argEx)
{
if (argEx.Message.Contains("is not a valid host name"))
{
Logger.Error($"EnvironmentSynchronizer configuration found in the appSettings.json but there are hostnames that is not valid.", argEx);
}
else
{
Logger.Error($"EnvironmentSynchronizer configuration found in the appSettings.json but some arguments is not correct.", argEx);
}

}
catch (Exception ex)
{
Logger.Error($"No configuration found in the appSettings.json. Missing EnvironmentSynchronizer section.", ex);
}

return syncData;
}

private EnvironmentSynchronizerSiteDefinition CreateEnvironmentSynchronizerSiteDefinition(SiteDefinitionOptions options)
{
var siteDefinition = new EnvironmentSynchronizerSiteDefinition()
{
#if NET10_0_OR_GREATER
Id = string.IsNullOrEmpty(options.Id) ? string.Empty : options.Id,
#else
Id = string.IsNullOrEmpty(options.Id) ? Guid.Empty : new Guid(options.Id),
SiteUrl = string.IsNullOrEmpty(options.SiteUrl) ? null : new Uri(options.SiteUrl),
#endif
Name = string.IsNullOrEmpty(options.Name) ? string.Empty : options.Name,
Hosts = ToHostDefinitions(options.Hosts),
#if NET10_0_OR_GREATER
IsDefault = options.IsDefault,
#endif
ForceLogin = options.ForceLogin,
SetRoles = options.SetRoles != null ? ToSetRoleDefinitions(options.SetRoles) : new List<SetRoleDefinition>(),
RemoveRoles = options.RemoveRoles != null ? ToRemoveRoleDefinitions(options.RemoveRoles) : new List<RemoveRoleDefinition>()
};

return siteDefinition;
}

#if NET10_0_OR_GREATER
private List<ApplicationHost> ToHostDefinitions(IList<HostOptions> hosts)
{
return hosts
.Select(hostOptions => new ApplicationHost(hostOptions.Name)
{
Type = hostOptions.Type,
PreferredUrlScheme = hostOptions.UseSecureConnection ? UrlScheme.Https : UrlScheme.Http,
Locale = GetApplicationHostLocale(hostOptions)
})
.ToList();
}

private static CultureInfo GetApplicationHostLocale(HostOptions hostOptions)
{
if (string.IsNullOrEmpty(hostOptions.Language) || !SupportsLocale(hostOptions.Type))
{
return null;
}

return new CultureInfo(hostOptions.Language);
}

private static bool SupportsLocale(ApplicationHostType hostType)
{
return hostType == ApplicationHostType.Primary ||
hostType == ApplicationHostType.Default ||
hostType == ApplicationHostType.RedirectPermanent ||
hostType == ApplicationHostType.RedirectTemporary;
}
#else
private List<HostDefinition> ToHostDefinitions(IList<HostOptions> hosts)
{
return hosts.Select(hostOptions => {
return new HostDefinition
{
Name = hostOptions.Name,
Type = hostOptions.Type != HostDefinitionType.Undefined ? hostOptions.Type : HostDefinitionType.Undefined,
UseSecureConnection = hostOptions.UseSecureConnection,
Language = string.IsNullOrEmpty(hostOptions.Language) ? null : new CultureInfo(hostOptions.Language)
};
}).ToList();
}
#endif

private List<SetRoleDefinition> ToSetRoleDefinitions(IList<SetRoleOptions> setRoles)
{
return setRoles.Select(setRoleOptions =>
{
return new SetRoleDefinition
{
Name = setRoleOptions.Name,
Access = setRoleOptions.Access != null ? AccessLevelConverter.ConvertToAccessLevel(setRoleOptions.Access) : AccessLevel.NoAccess,
};
}).ToList();
}

private List<RemoveRoleDefinition> ToRemoveRoleDefinitions(IList<string> removeRoles)
{
return removeRoles.Select(removeRoleOptions =>
{
return new RemoveRoleDefinition
{
Name = removeRoleOptions
};
}).ToList();
}
}
}
Loading