commit
f636ffcdba
|
@ -139,19 +139,19 @@ else
|
||||||
switch (function)
|
switch (function)
|
||||||
{
|
{
|
||||||
case "Create":
|
case "Create":
|
||||||
classname = "table-primary";
|
classname = "table-success";
|
||||||
break;
|
break;
|
||||||
case "Read":
|
case "Read":
|
||||||
classname = "table-secondary";
|
classname = "table-primary";
|
||||||
break;
|
break;
|
||||||
case "Update":
|
case "Update":
|
||||||
classname = "table-success";
|
classname = "table-warning";
|
||||||
break;
|
break;
|
||||||
case "Delete":
|
case "Delete":
|
||||||
classname = "table-danger";
|
classname = "table-danger";
|
||||||
break;
|
break;
|
||||||
case "Security":
|
case "Security":
|
||||||
classname = "table-warning";
|
classname = "table-secondary";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
classname = "";
|
classname = "";
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace Oqtane.Services
|
||||||
log.Level = Enum.GetName(typeof(LogLevel), level);
|
log.Level = Enum.GetName(typeof(LogLevel), level);
|
||||||
if (exception != null)
|
if (exception != null)
|
||||||
{
|
{
|
||||||
log.Exception = JsonSerializer.Serialize(exception);
|
log.Exception = exception.ToString();
|
||||||
}
|
}
|
||||||
log.Message = message;
|
log.Message = message;
|
||||||
log.MessageTemplate = "";
|
log.MessageTemplate = "";
|
||||||
|
|
92
Oqtane.Server/Infrastructure/HostedServiceBase.cs
Normal file
92
Oqtane.Server/Infrastructure/HostedServiceBase.cs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -62,11 +62,18 @@ namespace Oqtane.Infrastructure
|
||||||
log.Level = Enum.GetName(typeof(LogLevel), Level);
|
log.Level = Enum.GetName(typeof(LogLevel), Level);
|
||||||
if (Exception != null)
|
if (Exception != null)
|
||||||
{
|
{
|
||||||
log.Exception = JsonSerializer.Serialize(Exception.ToString());
|
log.Exception = Exception.ToString();
|
||||||
}
|
}
|
||||||
log.Message = Message;
|
log.Message = Message;
|
||||||
log.MessageTemplate = "";
|
log.MessageTemplate = "";
|
||||||
log.Properties = JsonSerializer.Serialize(Args);
|
try
|
||||||
|
{
|
||||||
|
log.Properties = JsonSerializer.Serialize(Args);
|
||||||
|
}
|
||||||
|
catch // serialization error occurred
|
||||||
|
{
|
||||||
|
log.Properties = "";
|
||||||
|
}
|
||||||
Log(log);
|
Log(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
21
Oqtane.Server/Infrastructure/TestJob.cs
Normal file
21
Oqtane.Server/Infrastructure/TestJob.cs
Normal 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?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,6 +44,10 @@ namespace Oqtane.Repository
|
||||||
moduledef = new ModuleDefinition { ModuleDefinitionName = moduledefinition.ModuleDefinitionName };
|
moduledef = new ModuleDefinition { ModuleDefinitionName = moduledefinition.ModuleDefinitionName };
|
||||||
db.ModuleDefinition.Add(moduledef);
|
db.ModuleDefinition.Add(moduledef);
|
||||||
db.SaveChanges();
|
db.SaveChanges();
|
||||||
|
if (moduledefinition.Permissions != "")
|
||||||
|
{
|
||||||
|
Permissions.UpdatePermissions(SiteId, "ModuleDefinition", moduledef.ModuleDefinitionId, moduledefinition.Permissions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -123,7 +127,8 @@ namespace Oqtane.Repository
|
||||||
ServerAssemblyName = GetProperty(properties, "ServerAssemblyName"),
|
ServerAssemblyName = GetProperty(properties, "ServerAssemblyName"),
|
||||||
ControlTypeTemplate = ModuleType + "." + Constants.ActionToken + ", " + typename[1],
|
ControlTypeTemplate = ModuleType + "." + Constants.ActionToken + ", " + typename[1],
|
||||||
ControlTypeRoutes = "",
|
ControlTypeRoutes = "",
|
||||||
AssemblyName = assembly.FullName.Split(",")[0]
|
AssemblyName = assembly.FullName.Split(",")[0],
|
||||||
|
Permissions = ""
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -144,7 +149,8 @@ namespace Oqtane.Repository
|
||||||
ServerAssemblyName = "",
|
ServerAssemblyName = "",
|
||||||
ControlTypeTemplate = ModuleType + "." + Constants.ActionToken + ", " + typename[1],
|
ControlTypeTemplate = ModuleType + "." + Constants.ActionToken + ", " + typename[1],
|
||||||
ControlTypeRoutes = "",
|
ControlTypeRoutes = "",
|
||||||
AssemblyName = assembly.FullName.Split(",")[0]
|
AssemblyName = assembly.FullName.Split(",")[0],
|
||||||
|
Permissions = ((QualifiedModuleType.StartsWith("Oqtane.Modules.Admin.")) ? "[{\"PermissionName\":\"Utilize\",\"Permissions\":\"Administrators\"}]" : "")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
moduledefinitions.Add(moduledefinition);
|
moduledefinitions.Add(moduledefinition);
|
||||||
|
|
|
@ -52,12 +52,14 @@ GO
|
||||||
|
|
||||||
CREATE TABLE [dbo].[Schedule] (
|
CREATE TABLE [dbo].[Schedule] (
|
||||||
[ScheduleId] [int] IDENTITY(1,1) NOT NULL,
|
[ScheduleId] [int] IDENTITY(1,1) NOT NULL,
|
||||||
[Name] [nvarchar](200) NULL,
|
[Name] [nvarchar](200) NOT NULL,
|
||||||
[JobType] [nvarchar](200) NOT NULL,
|
[JobType] [nvarchar](200) NOT NULL,
|
||||||
[Period] [int] NOT NULL,
|
[Period] [int] NOT NULL,
|
||||||
[Frequency] [char](1) NOT NULL,
|
[Frequency] [char](1) NOT NULL,
|
||||||
[StartDate] [datetime] NULL,
|
[StartDate] [datetime] NULL,
|
||||||
[IsActive] [bit] NOT NULL,
|
[IsActive] [bit] NOT NULL,
|
||||||
|
[IsExecuting] [bit] NOT NULL,
|
||||||
|
[NextExecution] [datetime] NULL,
|
||||||
[RetentionHistory] [int] NOT NULL,
|
[RetentionHistory] [int] NOT NULL,
|
||||||
[CreatedBy] [nvarchar](256) NULL,
|
[CreatedBy] [nvarchar](256) NULL,
|
||||||
[CreatedOn] [datetime] NULL,
|
[CreatedOn] [datetime] NULL,
|
||||||
|
@ -77,7 +79,6 @@ CREATE TABLE [dbo].[ScheduleLog] (
|
||||||
[FinishDate] [datetime] NULL,
|
[FinishDate] [datetime] NULL,
|
||||||
[Succeeded] [bit] NULL,
|
[Succeeded] [bit] NULL,
|
||||||
[Notes] [nvarchar](max) NULL,
|
[Notes] [nvarchar](max) NULL,
|
||||||
[NextExecution] [datetime] NULL,
|
|
||||||
CONSTRAINT [PK_ScheduleLog] PRIMARY KEY CLUSTERED
|
CONSTRAINT [PK_ScheduleLog] PRIMARY KEY CLUSTERED
|
||||||
(
|
(
|
||||||
[ScheduleLogId] ASC
|
[ScheduleLogId] ASC
|
||||||
|
|
|
@ -38,10 +38,17 @@ namespace Oqtane.Security
|
||||||
foreach (UserRole userrole in userroles)
|
foreach (UserRole userrole in userroles)
|
||||||
{
|
{
|
||||||
id.AddClaim(new Claim(options.ClaimsIdentity.RoleClaimType, userrole.Role.Name));
|
id.AddClaim(new Claim(options.ClaimsIdentity.RoleClaimType, userrole.Role.Name));
|
||||||
// host users are admins of every site
|
// host users are members of every site
|
||||||
if (userrole.Role.Name == Constants.HostRole && userroles.Where(item => item.Role.Name == Constants.AdminRole).FirstOrDefault() == null)
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,10 +154,6 @@ namespace Oqtane.Server
|
||||||
services.AddSingleton<IConfigurationRoot>(Configuration);
|
services.AddSingleton<IConfigurationRoot>(Configuration);
|
||||||
services.AddSingleton<IInstallationManager, InstallationManager>();
|
services.AddSingleton<IInstallationManager, InstallationManager>();
|
||||||
|
|
||||||
//ServiceProvider sp = services.BuildServiceProvider();
|
|
||||||
//var InstallationManager = sp.GetRequiredService<IInstallationManager>();
|
|
||||||
//InstallationManager.InstallPackages("Modules,Themes");
|
|
||||||
|
|
||||||
// register transient scoped core services
|
// register transient scoped core services
|
||||||
services.AddTransient<IModuleDefinitionRepository, ModuleDefinitionRepository>();
|
services.AddTransient<IModuleDefinitionRepository, ModuleDefinitionRepository>();
|
||||||
services.AddTransient<IThemeRepository, ThemeRepository>();
|
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 =>
|
services.AddSwaggerGen(c =>
|
||||||
{
|
{
|
||||||
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Oqtane", Version = "v1" });
|
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Oqtane", Version = "v1" });
|
||||||
|
|
|
@ -11,6 +11,8 @@ namespace Oqtane.Models
|
||||||
public string Frequency { get; set; }
|
public string Frequency { get; set; }
|
||||||
public DateTime? StartDate { get; set; }
|
public DateTime? StartDate { get; set; }
|
||||||
public bool IsActive { get; set; }
|
public bool IsActive { get; set; }
|
||||||
|
public bool IsExecuting { get; set; }
|
||||||
|
public DateTime? NextExecution { get; set; }
|
||||||
public int RetentionHistory { get; set; }
|
public int RetentionHistory { get; set; }
|
||||||
|
|
||||||
public string CreatedBy { get; set; }
|
public string CreatedBy { get; set; }
|
||||||
|
|
|
@ -10,6 +10,5 @@ namespace Oqtane.Models
|
||||||
public DateTime? FinishDate { get; set; }
|
public DateTime? FinishDate { get; set; }
|
||||||
public bool? Succeeded { get; set; }
|
public bool? Succeeded { get; set; }
|
||||||
public string Notes { get; set; }
|
public string Notes { get; set; }
|
||||||
public DateTime? NextExecution { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
public static string GetTypeNameLastSegment(string typename, int segment)
|
||||||
{
|
{
|
||||||
if (typename.Contains(","))
|
if (typename.Contains(","))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user