-
-
- settings;
+ if (_scope == "site")
+ {
+ settings = PageState.Site.Settings;
+ _login = SettingService.GetSetting(settings, GetType().Namespace + ":Login", "true");
+ _register = SettingService.GetSetting(settings, GetType().Namespace + ":Register", "true");
+ _footer = SettingService.GetSetting(settings, GetType().Namespace + ":Footer", "false");
+ }
+ else
+ {
+ settings = SettingService.MergeSettings(PageState.Site.Settings, PageState.Page.Settings);
+ _login = SettingService.GetSetting(settings, GetType().Namespace + ":Login", "-");
+ _register = SettingService.GetSetting(settings, GetType().Namespace + ":Register", "-");
+ _footer = SettingService.GetSetting(settings, GetType().Namespace + ":Footer", "-");
+ }
+ }
+
+ private async Task ScopeChanged(ChangeEventArgs eventArgs)
+ {
+ try
+ {
+ _scope = (string)eventArgs.Value;
+ await LoadSettings();
+ StateHasChanged();
+ }
+ catch (Exception ex)
+ {
+ await logger.LogError(ex, "Error Loading Settings {Error}", ex.Message);
+ AddModuleMessage("Error Loading Settings", MessageType.Error);
+ }
+ }
+
+ public async Task UpdateSettings()
+ {
+ try
+ {
+ Dictionary settings;
+ if (_scope == "site")
+ {
+ settings = PageState.Site.Settings;
+ }
+ else
+ {
+ settings = PageState.Page.Settings;
+ }
+
+ if (_login != "-")
+ {
+ settings = SettingService.SetSetting(settings, GetType().Namespace + ":Login", _login, true);
+ }
+ if (_register != "-")
+ {
+ settings = SettingService.SetSetting(settings, GetType().Namespace + ":Register", _register, true);
+ }
+ if (_footer != "-")
+ {
+ settings = SettingService.SetSetting(settings, GetType().Namespace + ":Footer", _footer, true);
+ }
+
+ if (_scope == "site")
+ {
+ await SettingService.UpdateSiteSettingsAsync(settings, PageState.Site.SiteId);
+ }
+ else
+ {
+ await SettingService.UpdatePageSettingsAsync(settings, PageState.Page.PageId);
+ }
+ }
+ catch (Exception ex)
+ {
+ await logger.LogError(ex, "Error Saving Settings {Error}", ex.Message);
+ AddModuleMessage("Error Saving Settings", MessageType.Error);
+ }
+ }
+}
diff --git a/Oqtane.Client/Themes/ThemeBase.cs b/Oqtane.Client/Themes/ThemeBase.cs
index 2ab10f7b..6dbece0b 100644
--- a/Oqtane.Client/Themes/ThemeBase.cs
+++ b/Oqtane.Client/Themes/ThemeBase.cs
@@ -104,9 +104,9 @@ namespace Oqtane.Themes
return Utilities.ContentUrl(PageState.Alias, fileid, asAttachment);
}
- public string ImageUrl(int fileid, string size, string mode)
+ public string ImageUrl(int fileid, int width, int height, string mode)
{
- return Utilities.ImageUrl(PageState.Alias, fileid, size, mode);
+ return Utilities.ImageUrl(PageState.Alias, fileid, width, height, mode);
}
}
}
diff --git a/Oqtane.Server/Controllers/FileController.cs b/Oqtane.Server/Controllers/FileController.cs
index efccfa95..57ffb98f 100644
--- a/Oqtane.Server/Controllers/FileController.cs
+++ b/Oqtane.Server/Controllers/FileController.cs
@@ -188,9 +188,9 @@ namespace Oqtane.Controllers
}
}
- // GET api//upload?url=x&folderid=y
+ // GET api//upload?url=x&folderid=y&name=z
[HttpGet("upload")]
- public Models.File UploadFile(string url, string folderid)
+ public Models.File UploadFile(string url, string folderid, string name)
{
Models.File file = null;
@@ -206,16 +206,19 @@ namespace Oqtane.Controllers
string folderPath = _folders.GetFolderPath(folder);
CreateDirectory(folderPath);
- string filename = url.Substring(url.LastIndexOf("/", StringComparison.Ordinal) + 1);
+ if (string.IsNullOrEmpty(name))
+ {
+ name = url.Substring(url.LastIndexOf("/", StringComparison.Ordinal) + 1);
+ }
// check for allowable file extensions
- if (!Constants.UploadableFiles.Split(',').Contains(Path.GetExtension(filename).ToLower().Replace(".", "")))
+ if (!Constants.UploadableFiles.Split(',').Contains(Path.GetExtension(name).ToLower().Replace(".", "")))
{
_logger.Log(LogLevel.Error, this, LogFunction.Create, "File Could Not Be Downloaded From Url Due To Its File Extension {Url}", url);
HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict;
return file;
}
- if (!filename.IsPathOrFileValid())
+ if (!name.IsPathOrFileValid())
{
_logger.Log(LogLevel.Error, this, LogFunction.Create, $"File Could Not Be Downloaded From Url Due To Its File Name Not Allowed {url}");
HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict;
@@ -225,7 +228,7 @@ namespace Oqtane.Controllers
try
{
var client = new WebClient();
- string targetPath = Path.Combine(folderPath, filename);
+ string targetPath = Path.Combine(folderPath, name);
// remove file if it already exists
if (System.IO.File.Exists(targetPath))
{
@@ -233,15 +236,15 @@ namespace Oqtane.Controllers
}
client.DownloadFile(url, targetPath);
- file = CreateFile(filename, folder.FolderId, targetPath);
+ file = CreateFile(name, folder.FolderId, targetPath);
if (file != null)
{
file = _files.AddFile(file);
}
}
- catch
+ catch (Exception ex)
{
- _logger.Log(LogLevel.Error, this, LogFunction.Create, "File Could Not Be Downloaded From Url {Url}", url);
+ _logger.Log(LogLevel.Error, this, LogFunction.Create, "File Could Not Be Downloaded From Url {Url} {Error}", url, ex.Message);
}
}
else
@@ -494,8 +497,8 @@ namespace Oqtane.Controllers
return System.IO.File.Exists(errorPath) ? PhysicalFile(errorPath, MimeUtilities.GetMimeType(errorPath)) : null;
}
- [HttpGet("image/{id}/{size}/{mode?}")]
- public IActionResult GetImage(int id, string size, string mode)
+ [HttpGet("image/{id}/{width}/{height}/{mode?}")]
+ public IActionResult GetImage(int id, int width, int height, string mode)
{
var file = _files.GetFile(id);
if (file != null && file.Folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.Permissions))
@@ -505,27 +508,31 @@ namespace Oqtane.Controllers
var filepath = _files.GetFilePath(file);
if (System.IO.File.Exists(filepath))
{
- size = size.ToLower();
mode = (string.IsNullOrEmpty(mode)) ? "crop" : mode;
- if ((_userPermissions.IsAuthorized(User, PermissionNames.Edit, file.Folder.Permissions) ||
- size.Contains("x") && !string.IsNullOrEmpty(file.Folder.ImageSizes) && file.Folder.ImageSizes.ToLower().Split(",").Contains(size))
- && Enum.TryParse(mode, true, out ResizeMode resizemode))
+
+ string imagepath = filepath.Replace(Path.GetExtension(filepath), "." + width.ToString() + "x" + height.ToString() + "." + mode.ToLower() + ".png");
+ if (!System.IO.File.Exists(imagepath))
{
- var imagepath = CreateImage(filepath, size, resizemode.ToString());
- if (!string.IsNullOrEmpty(imagepath))
+ if ((_userPermissions.IsAuthorized(User, PermissionNames.Edit, file.Folder.Permissions) ||
+ !string.IsNullOrEmpty(file.Folder.ImageSizes) && file.Folder.ImageSizes.ToLower().Split(",").Contains(width.ToString() + "x" + height.ToString()))
+ && Enum.TryParse(mode, true, out ResizeMode resizemode))
{
- return PhysicalFile(imagepath, file.GetMimeType());
+ imagepath = CreateImage(filepath, width, height, resizemode.ToString(), imagepath);
}
else
{
- _logger.Log(LogLevel.Error, this, LogFunction.Create, "Error Creating Image For File {File} {Size}", file, size);
- HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
+ _logger.Log(LogLevel.Error, this, LogFunction.Security, "Invalid Image Size For Folder Or Invalid Mode Specification {Folder} {Width} {Height} {Mode}", file.Folder, width, height, mode);
+ HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
}
}
+ if (!string.IsNullOrEmpty(imagepath))
+ {
+ return PhysicalFile(imagepath, file.GetMimeType());
+ }
else
{
- _logger.Log(LogLevel.Error, this, LogFunction.Security, "Invalid Image Size For Folder Or Invalid Mode Specification {Folder} {Size} {Mode}", file.Folder, size, mode);
- HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
+ _logger.Log(LogLevel.Error, this, LogFunction.Create, "Error Displaying Image For File {File} {Width} {Height}", file, width, height);
+ HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
}
}
else
@@ -550,38 +557,31 @@ namespace Oqtane.Controllers
return System.IO.File.Exists(errorPath) ? PhysicalFile(errorPath, MimeUtilities.GetMimeType(errorPath)) : null;
}
- private string CreateImage(string filepath, string size, string mode)
+ private string CreateImage(string filepath, int width, int height, string mode, string imagepath)
{
- string imagepath = filepath.Replace(Path.GetExtension(filepath), "." + size + "." + mode.ToLower() + ".png");
-
- if (!System.IO.File.Exists(imagepath))
+ try
{
- try
+ FileStream stream = new FileStream(filepath, FileMode.Open, FileAccess.Read);
+ using (Image image = Image.Load(stream))
{
- FileStream stream = new FileStream(filepath, FileMode.Open, FileAccess.Read);
- using (Image image = Image.Load(stream))
- {
- var parts = size.Split('x');
- int width = (!string.IsNullOrEmpty(parts[0])) ? int.Parse(parts[0]) : 0;
- int height = (!string.IsNullOrEmpty(parts[1])) ? int.Parse(parts[1]) : 0;
- Enum.TryParse(mode, true, out ResizeMode resizemode);
+ Enum.TryParse(mode, true, out ResizeMode resizemode);
- image.Mutate(x =>
- x.Resize(new ResizeOptions
- {
- Size = new Size(width, height),
- Mode = resizemode
- })
- .BackgroundColor(new Rgba32(255, 255, 255, 0)));
+ image.Mutate(x =>
+ x.Resize(new ResizeOptions
+ {
+ Size = new Size(width, height),
+ Mode = resizemode
+ })
+ .BackgroundColor(new Rgba32(255, 255, 255, 0)));
- image.Save(imagepath, new PngEncoder());
- }
- stream.Close();
- }
- catch // error creating image
- {
- imagepath = "";
+ image.Save(imagepath, new PngEncoder());
}
+ stream.Close();
+ }
+ catch (Exception ex)
+ {
+ _logger.Log(LogLevel.Error, this, LogFunction.Security, "Error Creating Image For File {FilePath} {Width} {Height} {Mode} {Error}", filepath, width, height, mode, ex.Message);
+ imagepath = "";
}
return imagepath;
diff --git a/Oqtane.Server/Controllers/SettingController.cs b/Oqtane.Server/Controllers/SettingController.cs
index 32d0573b..b305686e 100644
--- a/Oqtane.Server/Controllers/SettingController.cs
+++ b/Oqtane.Server/Controllers/SettingController.cs
@@ -39,6 +39,10 @@ namespace Oqtane.Controllers
if (IsAuthorized(entityname, entityid, PermissionNames.View))
{
settings = _settings.GetSettings(entityname, entityid).ToList();
+ if (entityname == EntityNames.Site && !User.IsInRole(RoleNames.Admin))
+ {
+ settings = settings.Where(item => item.IsPublic).ToList();
+ }
}
else
{
@@ -55,6 +59,10 @@ namespace Oqtane.Controllers
Setting setting = _settings.GetSetting(id);
if (IsAuthorized(setting.EntityName, setting.EntityId, PermissionNames.View))
{
+ if (setting.EntityName == EntityNames.Site && !User.IsInRole(RoleNames.Admin) && !setting.IsPublic)
+ {
+ setting = null;
+ }
return setting;
}
else
@@ -72,10 +80,7 @@ namespace Oqtane.Controllers
if (ModelState.IsValid && IsAuthorized(setting.EntityName, setting.EntityId, PermissionNames.Edit))
{
setting = _settings.AddSetting(setting);
- if (setting.EntityName == EntityNames.Module)
- {
- _syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, _alias.SiteId);
- }
+ AddSyncEvent(setting.EntityName);
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Setting Added {Setting}", setting);
}
else
@@ -94,10 +99,7 @@ namespace Oqtane.Controllers
if (ModelState.IsValid && IsAuthorized(setting.EntityName, setting.EntityId, PermissionNames.Edit))
{
setting = _settings.UpdateSetting(setting);
- if (setting.EntityName == EntityNames.Module)
- {
- _syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, _alias.SiteId);
- }
+ AddSyncEvent(setting.EntityName);
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Setting Updated {Setting}", setting);
}
else
@@ -117,10 +119,7 @@ namespace Oqtane.Controllers
if (IsAuthorized(setting.EntityName, setting.EntityId, PermissionNames.Edit))
{
_settings.DeleteSetting(id);
- if (setting.EntityName == EntityNames.Module)
- {
- _syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, _alias.SiteId);
- }
+ AddSyncEvent(setting.EntityName);
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Setting Deleted {Setting}", setting);
}
else
@@ -144,7 +143,14 @@ namespace Oqtane.Controllers
authorized = User.IsInRole(RoleNames.Host);
break;
case EntityNames.Site:
- authorized = User.IsInRole(RoleNames.Admin);
+ if (permissionName == PermissionNames.Edit)
+ {
+ authorized = User.IsInRole(RoleNames.Admin);
+ }
+ else
+ {
+ authorized = true;
+ }
break;
case EntityNames.Page:
case EntityNames.Module:
@@ -161,5 +167,17 @@ namespace Oqtane.Controllers
}
return authorized;
}
+
+ private void AddSyncEvent(string EntityName)
+ {
+ switch (EntityName)
+ {
+ case EntityNames.Module:
+ case EntityNames.Page:
+ case EntityNames.Site:
+ _syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, _alias.SiteId);
+ break;
+ }
+ }
}
}
diff --git a/Oqtane.Server/Controllers/SiteController.cs b/Oqtane.Server/Controllers/SiteController.cs
index 78715eaa..b67cc126 100644
--- a/Oqtane.Server/Controllers/SiteController.cs
+++ b/Oqtane.Server/Controllers/SiteController.cs
@@ -15,13 +15,15 @@ namespace Oqtane.Controllers
public class SiteController : Controller
{
private readonly ISiteRepository _sites;
+ private readonly ISettingRepository _settings;
private readonly ISyncManager _syncManager;
private readonly ILogManager _logger;
private readonly Alias _alias;
- public SiteController(ISiteRepository sites, ITenantManager tenantManager, ISyncManager syncManager, ILogManager logger)
+ public SiteController(ISiteRepository sites, ISettingRepository settings, ITenantManager tenantManager, ISyncManager syncManager, ILogManager logger)
{
_sites = sites;
+ _settings = settings;
_syncManager = syncManager;
_logger = logger;
_alias = tenantManager.GetAlias();
@@ -42,6 +44,12 @@ namespace Oqtane.Controllers
var site = _sites.GetSite(id);
if (site.SiteId == _alias.SiteId)
{
+ var settings = _settings.GetSettings(EntityNames.Site, site.SiteId);
+ if (!User.IsInRole(RoleNames.Admin))
+ {
+ settings = settings.Where(item => item.IsPublic);
+ }
+ site.Settings = settings.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
return site;
}
else
diff --git a/Oqtane.Server/Migrations/Tenant/02030002_AddSettingIsPublic.cs b/Oqtane.Server/Migrations/Tenant/02030002_AddSettingIsPublic.cs
new file mode 100644
index 00000000..74d1e18a
--- /dev/null
+++ b/Oqtane.Server/Migrations/Tenant/02030002_AddSettingIsPublic.cs
@@ -0,0 +1,31 @@
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Oqtane.Databases.Interfaces;
+using Oqtane.Migrations.EntityBuilders;
+using Oqtane.Repository;
+using Oqtane.Shared;
+
+namespace Oqtane.Migrations.Tenant
+{
+ [DbContext(typeof(TenantDBContext))]
+ [Migration("Tenant.02.03.00.02")]
+ public class AddSettingIsPublic : MultiDatabaseMigration
+ {
+ public AddSettingIsPublic(IDatabase database) : base(database)
+ {
+ }
+
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ var settingEntityBuilder = new SettingEntityBuilder(migrationBuilder, ActiveDatabase);
+ settingEntityBuilder.AddBooleanColumn("IsPublic", true);
+ settingEntityBuilder.UpdateColumn("IsPublic", "0");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ var settingEntityBuilder = new SettingEntityBuilder(migrationBuilder, ActiveDatabase);
+ settingEntityBuilder.DropColumn("IsPublic");
+ }
+ }
+}
diff --git a/Oqtane.Shared/Models/Page.cs b/Oqtane.Shared/Models/Page.cs
index 0ceb2dbb..e11661f1 100644
--- a/Oqtane.Shared/Models/Page.cs
+++ b/Oqtane.Shared/Models/Page.cs
@@ -104,10 +104,13 @@ namespace Oqtane.Models
///
[NotMapped]
public List Resources { get; set; }
+
[NotMapped]
public string Permissions { get; set; }
+
[NotMapped]
public Dictionary Settings { get; set; }
+
[NotMapped]
public int Level { get; set; }
diff --git a/Oqtane.Shared/Models/Setting.cs b/Oqtane.Shared/Models/Setting.cs
index 5619415d..37d72dbe 100644
--- a/Oqtane.Shared/Models/Setting.cs
+++ b/Oqtane.Shared/Models/Setting.cs
@@ -32,6 +32,11 @@ namespace Oqtane.Models
///
public string SettingValue { get; set; }
+ ///
+ /// Indicates if this setting is publicly available - only applicable to Site Settings as other entities have more granular permissions
+ ///
+ public bool IsPublic { get; set; }
+
#region IAuditable Properties
///
diff --git a/Oqtane.Shared/Models/Site.cs b/Oqtane.Shared/Models/Site.cs
index 86492571..82a7fc62 100644
--- a/Oqtane.Shared/Models/Site.cs
+++ b/Oqtane.Shared/Models/Site.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace Oqtane.Models
@@ -81,6 +82,9 @@ namespace Oqtane.Models
[NotMapped]
public string SiteTemplateType { get; set; }
+ [NotMapped]
+ public Dictionary Settings { get; set; }
+
[NotMapped]
[Obsolete("This property is deprecated.", false)]
public string DefaultLayoutType { get; set; }
diff --git a/Oqtane.Shared/Shared/Utilities.cs b/Oqtane.Shared/Shared/Utilities.cs
index aad5849a..aee8b568 100644
--- a/Oqtane.Shared/Shared/Utilities.cs
+++ b/Oqtane.Shared/Shared/Utilities.cs
@@ -112,10 +112,10 @@ namespace Oqtane.Shared
return $"{aliasUrl}{Constants.ContentUrl}{fileId}{method}";
}
- public static string ImageUrl(Alias alias, int fileId, string size, string mode)
+ public static string ImageUrl(Alias alias, int fileId, int width, int height, string mode)
{
var aliasUrl = (alias != null && !string.IsNullOrEmpty(alias.Path)) ? "/" + alias.Path : "";
- return $"{aliasUrl}{Constants.ImageUrl}{fileId}/{size}/{mode}";
+ return $"{aliasUrl}{Constants.ImageUrl}{fileId}/{width}/{height}/{mode}";
}
public static string TenantUrl(Alias alias, string url)
-
-
+
+
+@code {
+ private string _scope = "page";
+ private string _login = "-";
+ private string _register = "-";
+ private string _footer = "-";
- @code {
- private string _footer = "false";
-
- protected override void OnInitialized()
+ protected override async Task OnInitializedAsync()
+ {
+ try
{
- try
- {
- _footer = SettingService.GetSetting(PageState.Page.Settings, GetType().Namespace + ":Footer", "false");
- }
- catch (Exception ex)
- {
- ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error);
- }
+ await LoadSettings();
}
-
- public async Task UpdateSettings()
+ catch (Exception ex)
{
- try
- {
- var settings = PageState.Page.Settings;
- settings = SettingService.SetSetting(settings, GetType().Namespace + ":Footer", _footer);
- await SettingService.UpdatePageSettingsAsync(settings, PageState.Page.PageId);
- }
- catch (Exception ex)
- {
- ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error);
- }
+ await logger.LogError(ex, "Error Loading Settings {Error}", ex.Message);
+ AddModuleMessage("Error Loading Settings", MessageType.Error);
}
}
+
+ private async Task LoadSettings()
+ {
+ await Task.Yield();
+ Dictionary
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+