Merge pull request #8 from oqtane/master

Sync master
This commit is contained in:
Jim Spillane 2020-05-14 12:12:26 -04:00 committed by GitHub
commit def12489e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 81 additions and 59 deletions

View File

@ -2,7 +2,7 @@
@using [Owner].[Module]s.Services
@using [Owner].[Module]s.Models
@namespace [Owner].[Module]s.Modules
@namespace [Owner].[Module]s
@inherits ModuleBase
@inject I[Module]Service [Module]Service
@inject NavigationManager NavigationManager

View File

@ -1,7 +1,7 @@
@using [Owner].[Module]s.Services
@using [Owner].[Module]s.Models
@namespace [Owner].[Module]s.Modules
@namespace [Owner].[Module]s
@inherits ModuleBase
@inject I[Module]Service [Module]Service
@inject NavigationManager NavigationManager

View File

@ -1,7 +1,7 @@
using Oqtane.Models;
using Oqtane.Modules;
namespace [Owner].[Module]s.Modules
namespace [Owner].[Module]s
{
public class ModuleInfo : IModule
{

View File

@ -1,4 +1,4 @@
@namespace [Owner].[Module]s.Modules
@namespace [Owner].[Module]s
@inherits ModuleBase
@inject ISettingService SettingService

View File

@ -15,4 +15,6 @@
@using Oqtane.Services
@using Oqtane.Shared
@using Oqtane.Themes
@using Oqtane.Themes.Controls
@using Oqtane.Themes.Controls
@using Oqtane.UI
@using Oqtane.Enums

View File

@ -2,7 +2,7 @@
@using [Owner].[Module]s.Services
@using [Owner].[Module]s.Models
@namespace [Owner].[Module]s.Modules
@namespace [Owner].[Module]s
@inherits ModuleBase
@inject I[Module]Service [Module]Service
@inject NavigationManager NavigationManager

View File

@ -1,7 +1,7 @@
@using [Owner].[Module]s.Services
@using [Owner].[Module]s.Models
@namespace [Owner].[Module]s.Modules
@namespace [Owner].[Module]s
@inherits ModuleBase
@inject I[Module]Service [Module]Service
@inject NavigationManager NavigationManager

View File

@ -1,7 +1,7 @@
using Oqtane.Models;
using Oqtane.Modules;
namespace [Owner].[Module]s.Modules
namespace [Owner].[Module]s
{
public class ModuleInfo : IModule
{

View File

@ -1,4 +1,4 @@
@namespace [Owner].[Module]s.Modules
@namespace [Owner].[Module]s
@inherits ModuleBase
@inject ISettingService SettingService

View File

@ -32,7 +32,7 @@ namespace Oqtane.Controllers
public IEnumerable<Folder> Get(string siteid)
{
List<Folder> folders = new List<Folder>();
foreach(Folder folder in _folders.GetFolders(int.Parse(siteid)))
foreach (Folder folder in _folders.GetFolders(int.Parse(siteid)))
{
if (_userPermissions.IsAuthorized(User, PermissionNames.Browse, folder.Permissions))
{
@ -84,7 +84,7 @@ namespace Oqtane.Controllers
return null;
}
}
// POST api/<controller>
[HttpPost]
[Authorize(Roles = Constants.RegisteredRole)]
@ -103,7 +103,7 @@ namespace Oqtane.Controllers
new Permission(PermissionNames.Edit, Constants.AdminRole, true),
}.EncodePermissions();
}
if (_userPermissions.IsAuthorized(User,PermissionNames.Edit, permissions))
if (_userPermissions.IsAuthorized(User, PermissionNames.Edit, permissions))
{
if (FolderPathValid(folder))
{
@ -214,8 +214,9 @@ namespace Oqtane.Controllers
private bool FolderPathValid(Folder folder)
{
// prevent folder path traversal and reserved devices
return (folder.Name.IndexOfAny(@"<>:""/\|?*".ToCharArray()) == -1 &&
return (folder.Name.IndexOfAny(Constants.InvalidFileNameChars) == -1 &&
!Constants.InvalidFileNameEndingChars.Any(x => folder.Name.EndsWith(x)) &&
!Constants.ReservedDevices.Split(',').Contains(folder.Name.ToUpper().Split('.')[0]));
}
}
}
}

View File

@ -23,17 +23,19 @@ namespace Oqtane.Controllers
private readonly IModuleDefinitionRepository _moduleDefinitions;
private readonly IModuleRepository _modules;
private readonly ITenantRepository _tenants;
private readonly ISqlRepository _sql;
private readonly IUserPermissions _userPermissions;
private readonly IInstallationManager _installationManager;
private readonly IWebHostEnvironment _environment;
private readonly IServiceProvider _serviceProvider;
private readonly ILogManager _logger;
public ModuleDefinitionController(IModuleDefinitionRepository moduleDefinitions, IModuleRepository modules,ITenantRepository tenants, IUserPermissions userPermissions, IInstallationManager installationManager, IWebHostEnvironment environment, IServiceProvider serviceProvider, ILogManager logger)
public ModuleDefinitionController(IModuleDefinitionRepository moduleDefinitions, IModuleRepository modules,ITenantRepository tenants, ISqlRepository sql, IUserPermissions userPermissions, IInstallationManager installationManager, IWebHostEnvironment environment, IServiceProvider serviceProvider, ILogManager logger)
{
_moduleDefinitions = moduleDefinitions;
_modules = modules;
_tenants = tenants;
_sql = sql;
_userPermissions = userPermissions;
_installationManager = installationManager;
_environment = environment;
@ -99,57 +101,60 @@ namespace Oqtane.Controllers
public void Delete(int id, int siteid)
{
ModuleDefinition moduledefinition = _moduleDefinitions.GetModuleDefinition(id, siteid);
if (moduledefinition != null)
if (moduledefinition != null )
{
if (!string.IsNullOrEmpty(moduledefinition.ServerManagerType))
if (!string.IsNullOrEmpty(moduledefinition.ServerManagerType) && Utilities.GetAssemblyName(moduledefinition.ServerManagerType) != "Oqtane.Server")
{
Type moduletype = Type.GetType(moduledefinition.ServerManagerType);
if (moduletype != null && moduletype.GetInterface("IInstallable") != null)
foreach (Tenant tenant in _tenants.GetTenants())
{
foreach (Tenant tenant in _tenants.GetTenants())
try
{
try
if (moduletype.GetInterface("IInstallable") != null)
{
var moduleobject = ActivatorUtilities.CreateInstance(_serviceProvider, moduletype);
((IInstallable)moduleobject).Uninstall(tenant);
}
catch
else
{
// an error occurred executing the uninstall
_sql.ExecuteScript(tenant, moduletype.Assembly, Utilities.GetTypeName(moduledefinition.ModuleDefinitionName) + ".Uninstall.sql");
}
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "{ModuleDefinitionName} Uninstalled For Tenant {Tenant}", moduledefinition.ModuleDefinitionName, tenant.Name);
}
catch (Exception ex)
{
_logger.Log(LogLevel.Error, this, LogFunction.Delete, "Error Uninstalling {ModuleDefinitionName} For Tenant {Tenant} {Error}", moduledefinition.ModuleDefinitionName, tenant.Name, ex.Message);
}
}
}
// format root assembly name
string assemblyname = Utilities.GetAssemblyName(moduledefinition.ModuleDefinitionName);
if (assemblyname != "Oqtane.Client")
{
assemblyname = assemblyname.Replace(".Client", "");
// clean up module static resource folder
string folder = Path.Combine(_environment.WebRootPath, Path.Combine("Modules",assemblyname));
string folder = Path.Combine(_environment.WebRootPath, Path.Combine("Modules", Utilities.GetTypeName(moduledefinition.ModuleDefinitionName)));
if (Directory.Exists(folder))
{
Directory.Delete(folder, true);
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Static Resources Removed For {AssemblynName}", assemblyname);
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Static Resources Removed For {ModuleDefinitionName}", moduledefinition.ModuleDefinitionName);
}
// remove module assembly from /bin
// get root assembly name ( note that this only works if modules follow a specific naming convention for their assemblies )
string assemblyname = Utilities.GetAssemblyName(moduledefinition.ModuleDefinitionName).ToLower();
assemblyname = assemblyname.Replace(".client", "").Replace(".oqtane", "");
// remove module assemblies from /bin
string binfolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
foreach (string file in Directory.EnumerateFiles(binfolder, assemblyname + "*.*"))
{
System.IO.File.Delete(file);
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Assembly Removed {Filename}", file);
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Assembly {Filename} Removed For {ModuleDefinitionName}", file, moduledefinition.ModuleDefinitionName);
}
// remove module definition
_moduleDefinitions.DeleteModuleDefinition(id, siteid);
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Definition {ModuleDefinitionName} Deleted", moduledefinition.Name);
// restart application
_installationManager.RestartApplication();
}
// remove module definition
_moduleDefinitions.DeleteModuleDefinition(id, siteid);
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Definition Deleted {ModuleDefinitionName}", moduledefinition.Name);
// restart application
_installationManager.RestartApplication();
}
}

View File

@ -54,22 +54,20 @@ namespace Oqtane.Controllers
{
List<Theme> themes = _themes.GetThemes().ToList();
Theme theme = themes.Where(item => item.ThemeName == themename).FirstOrDefault();
if (theme != null)
if (theme != null && Utilities.GetAssemblyName(theme.ThemeName) != "Oqtane.Client")
{
themename = theme.ThemeName.Substring(0, theme.ThemeName.IndexOf(","));
string folder = Path.Combine(_environment.WebRootPath, "Themes" , themename);
// clean up theme static resource folder
string folder = Path.Combine(_environment.WebRootPath, "Themes" , Utilities.GetTypeName(theme.ThemeName));
if (Directory.Exists(folder))
{
Directory.Delete(folder, true);
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Theme Static Resources Removed For {ThemeName}", theme.ThemeName);
}
// remove theme assembly from /bin
string binfolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
foreach (string file in Directory.EnumerateFiles(binfolder, themename + "*.dll"))
{
System.IO.File.Delete(file);
}
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Theme Deleted {ThemeName}", themename);
System.IO.File.Delete(Path.Combine(binfolder, Utilities.GetAssemblyName(theme.ThemeName) + ".dll"));
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Theme Assembly {Filename} Removed For {ThemeName}", Utilities.GetAssemblyName(theme.ThemeName) + ".dll", themename);
_installationManager.RestartApplication();
}

View File

@ -332,10 +332,13 @@ namespace Oqtane.Infrastructure
using (var scope = _serviceScopeFactory.CreateScope())
{
var moduledefinitions = scope.ServiceProvider.GetRequiredService<IModuleDefinitionRepository>();
var sql = scope.ServiceProvider.GetRequiredService<ISqlRepository>();
foreach (var moduledefinition in moduledefinitions.GetModuleDefinitions())
{
if (!string.IsNullOrEmpty(moduledefinition.ServerManagerType) && !string.IsNullOrEmpty(moduledefinition.ReleaseVersions))
if (!string.IsNullOrEmpty(moduledefinition.ReleaseVersions) && !string.IsNullOrEmpty(moduledefinition.ServerManagerType))
{
Type moduletype = Type.GetType(moduledefinition.ServerManagerType);
string[] versions = moduledefinition.ReleaseVersions.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
using (var db = new InstallationContext(NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey))))
{
@ -351,19 +354,22 @@ namespace Oqtane.Infrastructure
if (index == -1) index = 0;
for (int i = index; i < versions.Length; i++)
{
Type moduletype = Type.GetType(moduledefinition.ServerManagerType);
if (moduletype != null && moduletype.GetInterface("IInstallable") != null)
try
{
try
if (moduletype.GetInterface("IInstallable") != null)
{
var moduleobject = ActivatorUtilities.CreateInstance(scope.ServiceProvider, moduletype);
((IInstallable)moduleobject).Install(tenant, versions[i]);
((IInstallable)moduleobject).Install(tenant, versions[i]);
}
catch (Exception ex)
else
{
result.Message = "An Error Occurred Installing " + moduledefinition.Name + " - " + ex.Message.ToString();
sql.ExecuteScript(tenant, moduletype.Assembly, Utilities.GetTypeName(moduledefinition.ModuleDefinitionName) + "." + versions[i] + ".sql");
}
}
catch (Exception ex)
{
result.Message = "An Error Occurred Installing " + moduledefinition.Name + " Version " + versions[i] + " - " + ex.Message.ToString();
}
}
}
}

View File

@ -1,4 +1,6 @@
namespace Oqtane.Shared
using System;
namespace Oqtane.Shared
{
public class Constants
{
@ -43,6 +45,14 @@
public const string ImageFiles = "jpg,jpeg,jpe,gif,bmp,png";
public const string UploadableFiles = "jpg,jpeg,jpe,gif,bmp,png,mov,wmv,avi,mp4,mp3,doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,nupkg";
public const string ReservedDevices = "CON,NUL,PRN,COM1,COM2,COM3,COM4,COM5,COM6,COM7,COM8,COM9,LPT1,LPT2,LPT3,LPT4,LPT5,LPT6,LPT7,LPT8,LPT9,CONIN$,CONOUT$";
public const string ReservedDevices = "CON,NUL,PRN,,COM0,COM1,COM2,COM3,COM4,COM5,COM6,COM7,COM8,COM9,LPT0,LPT1,LPT2,LPT3,LPT4,LPT5,LPT6,LPT7,LPT8,LPT9,CONIN$,CONOUT$";
public static readonly char[] InvalidFileNameChars =
{
'\"', '<', '>', '|', '\0', (Char) 1, (Char) 2, (Char) 3, (Char) 4, (Char) 5, (Char) 6, (Char) 7, (Char) 8,
(Char) 9, (Char) 10, (Char) 11, (Char) 12, (Char) 13, (Char) 14, (Char) 15, (Char) 16, (Char) 17, (Char) 18,
(Char) 19, (Char) 20, (Char) 21, (Char) 22, (Char) 23, (Char) 24, (Char) 25, (Char) 26, (Char) 27,
(Char) 28, (Char) 29, (Char) 30, (Char) 31, ':', '*', '?', '\\', '/'
};
public static readonly string[] InvalidFileNameEndingChars = { ".", " " };
}
}