oqtane.framework/Oqtane.Server/Controllers/SettingController.cs
2022-03-19 13:42:19 -04:00

267 lines
10 KiB
C#

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Oqtane.Models;
using Oqtane.Shared;
using Oqtane.Security;
using System.Linq;
using Oqtane.Enums;
using Oqtane.Infrastructure;
using Oqtane.Repository;
using System.Net;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authorization;
namespace Oqtane.Controllers
{
[Route(ControllerRoutes.ApiRoute)]
public class SettingController : Controller
{
private readonly ISettingRepository _settings;
private readonly IPageModuleRepository _pageModules;
private readonly IUserPermissions _userPermissions;
private readonly ISyncManager _syncManager;
private readonly ILogManager _logger;
private readonly Alias _alias;
private readonly IOptionsMonitorCache<OpenIdConnectOptions> _optionsMonitorCache;
private readonly string _visitorCookie;
public SettingController(ISettingRepository settings, IPageModuleRepository pageModules, IUserPermissions userPermissions, ITenantManager tenantManager, ISyncManager syncManager, IOptionsMonitorCache<OpenIdConnectOptions> optionsMonitorCache, ILogManager logger)
{
_settings = settings;
_pageModules = pageModules;
_userPermissions = userPermissions;
_syncManager = syncManager;
_optionsMonitorCache = optionsMonitorCache;
_logger = logger;
_alias = tenantManager.GetAlias();
_visitorCookie = "APP_VISITOR_" + _alias.SiteId.ToString();
}
// GET: api/<controller>
[HttpGet]
public IEnumerable<Setting> Get(string entityName, int entityId)
{
List<Setting> settings = new List<Setting>();
if (IsAuthorized(entityName, entityId, PermissionNames.View))
{
settings = _settings.GetSettings(entityName, entityId).ToList();
if (FilterPrivate(entityName, entityId))
{
settings = settings.Where(item => !item.IsPrivate).ToList();
}
}
else
{
_logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access Settings {EntityName} {EntityId}", entityName, entityId);
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
}
return settings;
}
// GET api/<controller>/5/xxx
[HttpGet("{id}/{entityName}")]
public Setting Get(int id, string entityName)
{
Setting setting = _settings.GetSetting(entityName, id);
if (IsAuthorized(setting.EntityName, setting.EntityId, PermissionNames.View))
{
if (FilterPrivate(entityName, id) && setting.IsPrivate)
{
setting = null;
}
return setting;
}
else
{
_logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access Setting {EntityName} {SettingId}", entityName, id);
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
return null;
}
}
// POST api/<controller>
[HttpPost]
public Setting Post([FromBody] Setting setting)
{
if (ModelState.IsValid && IsAuthorized(setting.EntityName, setting.EntityId, PermissionNames.Edit))
{
setting = _settings.AddSetting(setting);
AddSyncEvent(setting.EntityName);
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Setting Added {Setting}", setting);
}
else
{
_logger.Log(LogLevel.Error, this, LogFunction.Create, "User Not Authorized To Add Setting {Setting}", setting);
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
setting = null;
}
return setting;
}
// PUT api/<controller>/5
[HttpPut("{id}")]
public Setting Put(int id, [FromBody] Setting setting)
{
if (ModelState.IsValid && IsAuthorized(setting.EntityName, setting.EntityId, PermissionNames.Edit))
{
setting = _settings.UpdateSetting(setting);
AddSyncEvent(setting.EntityName);
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Setting Updated {Setting}", setting);
}
else
{
_logger.Log(LogLevel.Error, this, LogFunction.Update, "User Not Authorized To Update Setting {Setting}", setting);
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
setting = null;
}
return setting;
}
// DELETE api/<controller>/5/xxx
[HttpDelete("{id}/{entityName}")]
public void Delete(string entityName, int id)
{
Setting setting = _settings.GetSetting(entityName, id);
if (IsAuthorized(setting.EntityName, setting.EntityId, PermissionNames.Edit))
{
_settings.DeleteSetting(setting.EntityName, id);
AddSyncEvent(setting.EntityName);
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Setting Deleted {Setting}", setting);
}
else
{
_logger.Log(LogLevel.Error, this, LogFunction.Delete, "User Not Authorized To Delete Setting {Setting}", setting);
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
}
}
// DELETE api/<controller>/clear
[HttpDelete("clear/{id}")]
[Authorize(Roles = RoleNames.Admin)]
public void Clear(int id)
{
_optionsMonitorCache.Clear();
_logger.Log(LogLevel.Information, this, LogFunction.Other, "Site Options Cache Cleared");
}
private bool IsAuthorized(string entityName, int entityId, string permissionName)
{
bool authorized = false;
if (entityName == EntityNames.PageModule)
{
entityName = EntityNames.Module;
entityId = _pageModules.GetPageModule(entityId).ModuleId;
}
switch (entityName)
{
case EntityNames.Tenant:
case EntityNames.ModuleDefinition:
case EntityNames.Host:
if (permissionName == PermissionNames.Edit)
{
authorized = User.IsInRole(RoleNames.Host);
}
else
{
authorized = true;
}
break;
case EntityNames.Site:
if (permissionName == PermissionNames.Edit)
{
authorized = User.IsInRole(RoleNames.Admin);
}
else
{
authorized = true;
}
break;
case EntityNames.Page:
case EntityNames.Module:
case EntityNames.Folder:
authorized = _userPermissions.IsAuthorized(User, entityName, entityId, permissionName);
break;
case EntityNames.User:
authorized = true;
if (permissionName == PermissionNames.Edit)
{
authorized = User.IsInRole(RoleNames.Admin) || (_userPermissions.GetUser(User).UserId == entityId);
}
break;
case EntityNames.Visitor:
authorized = User.IsInRole(RoleNames.Admin);
if (!authorized)
{
if (int.TryParse(Request.Cookies[_visitorCookie], out int visitorId))
{
authorized = (visitorId == entityId);
}
}
break;
default: // custom entity
if (permissionName == PermissionNames.Edit)
{
authorized = User.IsInRole(RoleNames.Admin) || _userPermissions.IsAuthorized(User, entityName, entityId, permissionName);
}
else
{
authorized = true;
}
break;
}
return authorized;
}
private bool FilterPrivate(string entityName, int entityId)
{
bool filter = false;
switch (entityName)
{
case EntityNames.Tenant:
case EntityNames.ModuleDefinition:
case EntityNames.Host:
filter = !User.IsInRole(RoleNames.Host);
break;
case EntityNames.Site:
filter = !User.IsInRole(RoleNames.Admin);
break;
case EntityNames.Page:
case EntityNames.Module:
case EntityNames.Folder:
filter = !_userPermissions.IsAuthorized(User, entityName, entityId, PermissionNames.Edit);
break;
case EntityNames.User:
filter = !User.IsInRole(RoleNames.Admin) && _userPermissions.GetUser(User).UserId != entityId;
break;
case EntityNames.Visitor:
if (!User.IsInRole(RoleNames.Admin))
{
filter = true;
if (int.TryParse(Request.Cookies[_visitorCookie], out int visitorId))
{
filter = (visitorId != entityId);
}
}
break;
default: // custom entity
filter = !User.IsInRole(RoleNames.Admin) && !_userPermissions.IsAuthorized(User, entityName, entityId, PermissionNames.Edit);
break;
}
return filter;
}
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;
}
}
}
}