Merge pull request #6 from oqtane/master

11-14-2019 changes
This commit is contained in:
ADefWebserver 2019-11-14 05:27:19 -08:00 committed by GitHub
commit f636ffcdba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 177 additions and 19 deletions

View File

@ -139,19 +139,19 @@ else
switch (function)
{
case "Create":
classname = "table-primary";
classname = "table-success";
break;
case "Read":
classname = "table-secondary";
classname = "table-primary";
break;
case "Update":
classname = "table-success";
classname = "table-warning";
break;
case "Delete":
classname = "table-danger";
break;
case "Security":
classname = "table-warning";
classname = "table-secondary";
break;
default:
classname = "";

View File

@ -51,7 +51,7 @@ namespace Oqtane.Services
log.Level = Enum.GetName(typeof(LogLevel), level);
if (exception != null)
{
log.Exception = JsonSerializer.Serialize(exception);
log.Exception = exception.ToString();
}
log.Message = message;
log.MessageTemplate = "";

View File

@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Oqtane.Models;
using Oqtane.Repository;
using Oqtane.Shared;
namespace Oqtane.Infrastructure
{
public abstract class HostedServiceBase : IHostedService, IDisposable
{
private Task ExecutingTask;
private readonly CancellationTokenSource CancellationTokenSource = new CancellationTokenSource();
private readonly IServiceScopeFactory ServiceScopeFactory;
public HostedServiceBase(IServiceScopeFactory ServiceScopeFactory)
{
this.ServiceScopeFactory = ServiceScopeFactory;
}
// abstract method must be overridden by job
public abstract void ExecuteJob(IServiceProvider provider);
protected async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
while (!stoppingToken.IsCancellationRequested)
{
// allows consumption of scoped services
using (var scope = ServiceScopeFactory.CreateScope())
{
string JobType = Utilities.GetFullTypeName(this.GetType().AssemblyQualifiedName);
IScheduleRepository ScheduleRepository = scope.ServiceProvider.GetRequiredService<IScheduleRepository>();
List<Schedule> schedules = ScheduleRepository.GetSchedules().ToList();
Schedule schedule = schedules.Where(item => item.JobType == JobType).FirstOrDefault();
if (schedule != null && schedule.IsActive)
{
ExecuteJob(scope.ServiceProvider);
}
}
await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
}
}
catch
{
// can occur during the initial installation as there is no DBContext
}
}
public Task StartAsync(CancellationToken cancellationToken)
{
ExecutingTask = ExecuteAsync(CancellationTokenSource.Token);
if (ExecutingTask.IsCompleted)
{
return ExecutingTask;
}
return Task.CompletedTask;
}
public async Task StopAsync(CancellationToken CancellationToken)
{
if (ExecutingTask == null)
{
return;
}
try
{
CancellationTokenSource.Cancel();
}
finally
{
await Task.WhenAny(ExecutingTask, Task.Delay(Timeout.Infinite, CancellationToken));
}
}
public void Dispose()
{
CancellationTokenSource.Cancel();
}
}
}

View File

@ -62,11 +62,18 @@ namespace Oqtane.Infrastructure
log.Level = Enum.GetName(typeof(LogLevel), Level);
if (Exception != null)
{
log.Exception = JsonSerializer.Serialize(Exception.ToString());
log.Exception = Exception.ToString();
}
log.Message = Message;
log.MessageTemplate = "";
log.Properties = JsonSerializer.Serialize(Args);
try
{
log.Properties = JsonSerializer.Serialize(Args);
}
catch // serialization error occurred
{
log.Properties = "";
}
Log(log);
}

View File

@ -0,0 +1,21 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Oqtane.Models;
using Oqtane.Repository;
namespace Oqtane.Infrastructure
{
public class TestJob : HostedServiceBase
{
public TestJob(IServiceScopeFactory ServiceScopeFactory) : base(ServiceScopeFactory) {}
public override void ExecuteJob(IServiceProvider provider)
{
var Tenants = provider.GetRequiredService<ITenantRepository>();
foreach(Tenant tenant in Tenants.GetTenants())
{
// is it possible to set the HttpContext so that DbContextBase will resolve properly for tenants?
}
}
}
}

View File

@ -44,6 +44,10 @@ namespace Oqtane.Repository
moduledef = new ModuleDefinition { ModuleDefinitionName = moduledefinition.ModuleDefinitionName };
db.ModuleDefinition.Add(moduledef);
db.SaveChanges();
if (moduledefinition.Permissions != "")
{
Permissions.UpdatePermissions(SiteId, "ModuleDefinition", moduledef.ModuleDefinitionId, moduledefinition.Permissions);
}
}
else
{
@ -123,7 +127,8 @@ namespace Oqtane.Repository
ServerAssemblyName = GetProperty(properties, "ServerAssemblyName"),
ControlTypeTemplate = ModuleType + "." + Constants.ActionToken + ", " + typename[1],
ControlTypeRoutes = "",
AssemblyName = assembly.FullName.Split(",")[0]
AssemblyName = assembly.FullName.Split(",")[0],
Permissions = ""
};
}
else
@ -144,7 +149,8 @@ namespace Oqtane.Repository
ServerAssemblyName = "",
ControlTypeTemplate = ModuleType + "." + Constants.ActionToken + ", " + typename[1],
ControlTypeRoutes = "",
AssemblyName = assembly.FullName.Split(",")[0]
AssemblyName = assembly.FullName.Split(",")[0],
Permissions = ((QualifiedModuleType.StartsWith("Oqtane.Modules.Admin.")) ? "[{\"PermissionName\":\"Utilize\",\"Permissions\":\"Administrators\"}]" : "")
};
}
moduledefinitions.Add(moduledefinition);

View File

@ -52,12 +52,14 @@ GO
CREATE TABLE [dbo].[Schedule] (
[ScheduleId] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](200) NULL,
[Name] [nvarchar](200) NOT NULL,
[JobType] [nvarchar](200) NOT NULL,
[Period] [int] NOT NULL,
[Frequency] [char](1) NOT NULL,
[StartDate] [datetime] NULL,
[IsActive] [bit] NOT NULL,
[IsExecuting] [bit] NOT NULL,
[NextExecution] [datetime] NULL,
[RetentionHistory] [int] NOT NULL,
[CreatedBy] [nvarchar](256) NULL,
[CreatedOn] [datetime] NULL,
@ -77,7 +79,6 @@ CREATE TABLE [dbo].[ScheduleLog] (
[FinishDate] [datetime] NULL,
[Succeeded] [bit] NULL,
[Notes] [nvarchar](max) NULL,
[NextExecution] [datetime] NULL,
CONSTRAINT [PK_ScheduleLog] PRIMARY KEY CLUSTERED
(
[ScheduleLogId] ASC

View File

@ -38,10 +38,17 @@ namespace Oqtane.Security
foreach (UserRole userrole in userroles)
{
id.AddClaim(new Claim(options.ClaimsIdentity.RoleClaimType, userrole.Role.Name));
// host users are admins of every site
if (userrole.Role.Name == Constants.HostRole && userroles.Where(item => item.Role.Name == Constants.AdminRole).FirstOrDefault() == null)
// host users are members of every site
if (userrole.Role.Name == Constants.HostRole)
{
id.AddClaim(new Claim(options.ClaimsIdentity.RoleClaimType, Constants.AdminRole));
if (userroles.Where(item => item.Role.Name == Constants.RegisteredRole).FirstOrDefault() == null)
{
id.AddClaim(new Claim(options.ClaimsIdentity.RoleClaimType, Constants.RegisteredRole));
}
if (userroles.Where(item => item.Role.Name == Constants.AdminRole).FirstOrDefault() == null)
{
id.AddClaim(new Claim(options.ClaimsIdentity.RoleClaimType, Constants.AdminRole));
}
}
}
}

View File

@ -154,10 +154,6 @@ namespace Oqtane.Server
services.AddSingleton<IConfigurationRoot>(Configuration);
services.AddSingleton<IInstallationManager, InstallationManager>();
//ServiceProvider sp = services.BuildServiceProvider();
//var InstallationManager = sp.GetRequiredService<IInstallationManager>();
//InstallationManager.InstallPackages("Modules,Themes");
// register transient scoped core services
services.AddTransient<IModuleDefinitionRepository, ModuleDefinitionRepository>();
services.AddTransient<IThemeRepository, ThemeRepository>();
@ -235,6 +231,21 @@ namespace Oqtane.Server
}
}
// dynamically register hosted services
foreach (Assembly assembly in assemblies)
{
Type[] servicetypes = assembly.GetTypes()
.Where(item => item.GetInterfaces().Contains(typeof(IHostedService)))
.ToArray();
foreach (Type servicetype in servicetypes)
{
if (servicetype.Name != "HostedServiceBase")
{
services.AddSingleton(typeof(IHostedService), servicetype);
}
}
}
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Oqtane", Version = "v1" });

View File

@ -11,6 +11,8 @@ namespace Oqtane.Models
public string Frequency { get; set; }
public DateTime? StartDate { get; set; }
public bool IsActive { get; set; }
public bool IsExecuting { get; set; }
public DateTime? NextExecution { get; set; }
public int RetentionHistory { get; set; }
public string CreatedBy { get; set; }

View File

@ -10,6 +10,5 @@ namespace Oqtane.Models
public DateTime? FinishDate { get; set; }
public bool? Succeeded { get; set; }
public string Notes { get; set; }
public DateTime? NextExecution { get; set; }
}
}

View File

@ -70,6 +70,18 @@ namespace Oqtane.Shared
}
}
public static string GetFullTypeName(string fullyqualifiedtypename)
{
if (fullyqualifiedtypename.Contains(", Version="))
{
return fullyqualifiedtypename.Substring(0, fullyqualifiedtypename.IndexOf(", Version="));
}
else
{
return fullyqualifiedtypename;
}
}
public static string GetTypeNameLastSegment(string typename, int segment)
{
if (typename.Contains(","))