@ -61,6 +61,10 @@ else
|
|||||||
{
|
{
|
||||||
AddModuleMessage(Localizer["The Only Supported Culture That Has Been Defined Is English"], MessageType.Warning);
|
AddModuleMessage(Localizer["The Only Supported Culture That Has Been Defined Is English"], MessageType.Warning);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_supportedCultures = _supportedCultures.Where(c => !c.Name.Equals(Constants.DefaultCulture));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SaveLanguage()
|
private async Task SaveLanguage()
|
||||||
|
@ -58,12 +58,16 @@ else
|
|||||||
<Pager Items="@userroles">
|
<Pager Items="@userroles">
|
||||||
<Header>
|
<Header>
|
||||||
<th>@Localizer["Users"]</th>
|
<th>@Localizer["Users"]</th>
|
||||||
|
<th>@Localizer["Effective"]</th>
|
||||||
|
<th>@Localizer["Expiry"]</th>
|
||||||
<th> </th>
|
<th> </th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td>@context.User.DisplayName</td>
|
<td>@context.User.DisplayName</td>
|
||||||
|
<td>@context.EffectiveDate</td>
|
||||||
|
<td>@context.ExpiryDate</td>
|
||||||
<td>
|
<td>
|
||||||
<button type="button" class="btn btn-danger" @onclick=@(async () => await DeleteUserRole(context.UserRoleId))>@Localizer["Delete"]</button>
|
<ActionDialog Header="Remove User" Message="@Localizer["Are You Sure You Wish To Remove {0} From This Role?", context.User.DisplayName]" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteUserRole(context.UserRoleId))" Disabled="@(context.Role.IsAutoAssigned)" ResourceKey="DeleteUserRole" />
|
||||||
</td>
|
</td>
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
@ -140,9 +144,10 @@ else
|
|||||||
await UserRoleService.AddUserRoleAsync(userrole);
|
await UserRoleService.AddUserRoleAsync(userrole);
|
||||||
}
|
}
|
||||||
|
|
||||||
await GetUserRoles();
|
|
||||||
await logger.LogInformation("User Assigned To Role {UserRole}", userrole);
|
await logger.LogInformation("User Assigned To Role {UserRole}", userrole);
|
||||||
AddModuleMessage(Localizer["User Assigned To Role"], MessageType.Success);
|
AddModuleMessage(Localizer["User Assigned To Role"], MessageType.Success);
|
||||||
|
await GetUserRoles();
|
||||||
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -161,9 +166,10 @@ else
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await UserRoleService.DeleteUserRoleAsync(UserRoleId);
|
await UserRoleService.DeleteUserRoleAsync(UserRoleId);
|
||||||
await GetUserRoles();
|
|
||||||
await logger.LogInformation("User Removed From Role {UserRoleId}", UserRoleId);
|
await logger.LogInformation("User Removed From Role {UserRoleId}", UserRoleId);
|
||||||
AddModuleMessage(Localizer["User Removed From Role"], MessageType.Success);
|
AddModuleMessage(Localizer["User Removed From Role"], MessageType.Success);
|
||||||
|
await GetUserRoles();
|
||||||
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -131,26 +131,34 @@
|
|||||||
{
|
{
|
||||||
if (password == confirm)
|
if (password == confirm)
|
||||||
{
|
{
|
||||||
var user = new User();
|
var user = await UserService.GetUserAsync(username, PageState.Site.SiteId);
|
||||||
user.SiteId = PageState.Site.SiteId;
|
if (user == null)
|
||||||
user.Username = username;
|
|
||||||
user.Password = password;
|
|
||||||
user.Email = email;
|
|
||||||
user.DisplayName = string.IsNullOrWhiteSpace(displayname) ? username : displayname;
|
|
||||||
user.PhotoFileId = null;
|
|
||||||
|
|
||||||
user = await UserService.AddUserAsync(user);
|
|
||||||
|
|
||||||
if (user != null)
|
|
||||||
{
|
{
|
||||||
await SettingService.UpdateUserSettingsAsync(settings, user.UserId);
|
user = new User();
|
||||||
await logger.LogInformation("User Created {User}", user);
|
user.SiteId = PageState.Site.SiteId;
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
user.Username = username;
|
||||||
|
user.Password = password;
|
||||||
|
user.Email = email;
|
||||||
|
user.DisplayName = string.IsNullOrWhiteSpace(displayname) ? username : displayname;
|
||||||
|
user.PhotoFileId = null;
|
||||||
|
|
||||||
|
user = await UserService.AddUserAsync(user);
|
||||||
|
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
await SettingService.UpdateUserSettingsAsync(settings, user.UserId);
|
||||||
|
await logger.LogInformation("User Created {User}", user);
|
||||||
|
NavigationManager.NavigateTo(NavigateUrl());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await logger.LogError("Error Adding User {Username} {Email}", username, email);
|
||||||
|
AddModuleMessage(Localizer["Error Adding User. Please Ensure Password Meets Complexity Requirements And Username And Email Are Not Already In Use."], MessageType.Error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await logger.LogError("Error Adding User {Username} {Email}", username, email);
|
AddModuleMessage(Localizer["Username Already Exists"], MessageType.Warning);
|
||||||
AddModuleMessage(Localizer["Error Adding User. Please Ensure Password Meets Complexity Requirements And Username Is Not Already In Use."], MessageType.Error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -13,10 +13,15 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<ActionLink Action="Add" Text="Add User" ResourceKey="AddUser" />
|
<div class="form-row">
|
||||||
|
<div class="col">
|
||||||
<div class="d-flex p-1">
|
<ActionLink Action="Add" Text="Add User" ResourceKey="AddUser" />
|
||||||
<input class="form-control mr-4" @bind="@_search" /><button class="btn btn-outline-primary ml-1" @onclick="OnSearch">@Localizer["Search"]</button>
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<div class="input-group flex-nowrap">
|
||||||
|
<input class="form-control" @bind="@_search" /> <button class="btn btn-secondary" @onclick="OnSearch">@Localizer["Search"]</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Pager Items="@userroles">
|
<Pager Items="@userroles">
|
||||||
@ -31,7 +36,7 @@ else
|
|||||||
<ActionLink Action="Edit" Parameters="@($"id=" + context.UserId.ToString())" ResourceKey="EditUser" />
|
<ActionLink Action="Edit" Parameters="@($"id=" + context.UserId.ToString())" ResourceKey="EditUser" />
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<ActionDialog Header="Delete User" Message="@Localizer["Are You Sure You Wish To Delete {0}?", context.User.DisplayName]" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteUser(context))" ResourceKey="DeleteUser" />
|
<ActionDialog Header="Delete User" Message="@Localizer["Are You Sure You Wish To Delete {0}?", context.User.DisplayName]" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteUser(context))" Disabled="@(context.Role.Name == RoleNames.Host)" ResourceKey="DeleteUser" />
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<ActionLink Action="Roles" Parameters="@($"id=" + context.UserId.ToString())" ResourceKey="Roles" />
|
<ActionLink Action="Roles" Parameters="@($"id=" + context.UserId.ToString())" ResourceKey="Roles" />
|
||||||
@ -57,19 +62,19 @@ else
|
|||||||
|
|
||||||
private List<UserRole> Search(string search)
|
private List<UserRole> Search(string search)
|
||||||
{
|
{
|
||||||
|
var results = allroles.Where(item => item.Role.Name == RoleNames.Registered || (item.Role.Name == RoleNames.Host && UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)));
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(_search))
|
if (string.IsNullOrEmpty(_search))
|
||||||
{
|
{
|
||||||
return allroles.Where(item => item.Role.Name == RoleNames.Registered).ToList();
|
results = results.Where(item =>
|
||||||
|
(
|
||||||
|
item.User.Username.Contains(search, StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
item.User.Email.Contains(search, StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
item.User.DisplayName.Contains(search, StringComparison.OrdinalIgnoreCase)
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return allroles
|
return results.ToList();
|
||||||
.Where(item => item.Role.Name == RoleNames.Registered &&
|
|
||||||
(
|
|
||||||
item.User.Username.Contains(search, StringComparison.OrdinalIgnoreCase) ||
|
|
||||||
item.User.Email.Contains(search, StringComparison.OrdinalIgnoreCase) ||
|
|
||||||
item.User.DisplayName.Contains(search, StringComparison.OrdinalIgnoreCase)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.ToList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task OnSearch()
|
private async Task OnSearch()
|
||||||
|
@ -59,15 +59,16 @@ else
|
|||||||
<Pager Items="@userroles">
|
<Pager Items="@userroles">
|
||||||
<Header>
|
<Header>
|
||||||
<th>@Localizer["Roles"]</th>
|
<th>@Localizer["Roles"]</th>
|
||||||
|
<th>@Localizer["Effective"]</th>
|
||||||
|
<th>@Localizer["Expiry"]</th>
|
||||||
<th> </th>
|
<th> </th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td>@context.Role.Name</td>
|
<td>@context.Role.Name</td>
|
||||||
|
<td>@context.EffectiveDate</td>
|
||||||
|
<td>@context.ExpiryDate</td>
|
||||||
<td>
|
<td>
|
||||||
@if (context.Role.Name != RoleNames.Registered)
|
<ActionDialog Header="Remove Role" Message="@Localizer["Are You Sure You Wish To Remove This User From The {0} Role?", context.Role.Name]" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteUserRole(context.UserRoleId))" Disabled="@(context.Role.IsAutoAssigned || (context.Role.Name == RoleNames.Host && userid == PageState.User.UserId))" ResourceKey="DeleteUserRole" />
|
||||||
{
|
|
||||||
<button type="button" class="btn btn-danger" @onclick=@(async () => await DeleteUserRole(context.UserRoleId))>@Localizer["Delete"]</button>
|
|
||||||
}
|
|
||||||
</td>
|
</td>
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
@ -92,7 +93,15 @@ else
|
|||||||
userid = Int32.Parse(PageState.QueryString["id"]);
|
userid = Int32.Parse(PageState.QueryString["id"]);
|
||||||
User user = await UserService.GetUserAsync(userid, PageState.Site.SiteId);
|
User user = await UserService.GetUserAsync(userid, PageState.Site.SiteId);
|
||||||
name = user.DisplayName;
|
name = user.DisplayName;
|
||||||
roles = await RoleService.GetRolesAsync(PageState.Site.SiteId);
|
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||||
|
{
|
||||||
|
roles = await RoleService.GetRolesAsync(PageState.Site.SiteId, true);
|
||||||
|
roles = roles.Where(item => item.Name != RoleNames.Everyone).ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
roles = await RoleService.GetRolesAsync(PageState.Site.SiteId);
|
||||||
|
}
|
||||||
await GetUserRoles();
|
await GetUserRoles();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -171,9 +180,10 @@ else
|
|||||||
await UserRoleService.AddUserRoleAsync(userrole);
|
await UserRoleService.AddUserRoleAsync(userrole);
|
||||||
}
|
}
|
||||||
|
|
||||||
await GetUserRoles();
|
|
||||||
await logger.LogInformation("User Assigned To Role {UserRole}", userrole);
|
await logger.LogInformation("User Assigned To Role {UserRole}", userrole);
|
||||||
AddModuleMessage(Localizer["User Assigned To Role"], MessageType.Success);
|
AddModuleMessage(Localizer["User Assigned To Role"], MessageType.Success);
|
||||||
|
await GetUserRoles();
|
||||||
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -192,9 +202,10 @@ else
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await UserRoleService.DeleteUserRoleAsync(UserRoleId);
|
await UserRoleService.DeleteUserRoleAsync(UserRoleId);
|
||||||
await GetUserRoles();
|
|
||||||
await logger.LogInformation("User Removed From Role {UserRoleId}", UserRoleId);
|
await logger.LogInformation("User Removed From Role {UserRoleId}", UserRoleId);
|
||||||
AddModuleMessage(Localizer["User Removed From Role"], MessageType.Success);
|
AddModuleMessage(Localizer["User Removed From Role"], MessageType.Success);
|
||||||
|
await GetUserRoles();
|
||||||
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@ -8,6 +8,8 @@ namespace Oqtane.Services
|
|||||||
{
|
{
|
||||||
Task<List<Role>> GetRolesAsync(int siteId);
|
Task<List<Role>> GetRolesAsync(int siteId);
|
||||||
|
|
||||||
|
Task<List<Role>> GetRolesAsync(int siteId, bool includeGlobalRoles);
|
||||||
|
|
||||||
Task<Role> GetRoleAsync(int roleId);
|
Task<Role> GetRoleAsync(int roleId);
|
||||||
|
|
||||||
Task<Role> AddRoleAsync(Role role);
|
Task<Role> AddRoleAsync(Role role);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -22,7 +22,12 @@ namespace Oqtane.Services
|
|||||||
|
|
||||||
public async Task<List<Role>> GetRolesAsync(int siteId)
|
public async Task<List<Role>> GetRolesAsync(int siteId)
|
||||||
{
|
{
|
||||||
List<Role> roles = await GetJsonAsync<List<Role>>($"{Apiurl}?siteid={siteId}");
|
return await GetRolesAsync(siteId, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<Role>> GetRolesAsync(int siteId, bool includeGlobalRoles)
|
||||||
|
{
|
||||||
|
List<Role> roles = await GetJsonAsync<List<Role>>($"{Apiurl}?siteid={siteId}&global={includeGlobalRoles}");
|
||||||
return roles.OrderBy(item => item.Name).ToList();
|
return roles.OrderBy(item => item.Name).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,10 @@
|
|||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
var languages = await LanguageService.GetLanguagesAsync(PageState.Site.SiteId);
|
var languages = await LanguageService.GetLanguagesAsync(PageState.Site.SiteId);
|
||||||
|
var defaultCulture = CultureInfo.GetCultureInfo(Constants.DefaultCulture);
|
||||||
|
|
||||||
|
languages.Add(new Language { Code = defaultCulture.Name, Name = defaultCulture.DisplayName });
|
||||||
|
|
||||||
_supportedCultures = languages.Select(l => new Culture { Name = l.Code, DisplayName = l.Name });
|
_supportedCultures = languages.Select(l => new Culture { Name = l.Code, DisplayName = l.Name });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,10 +93,14 @@
|
|||||||
<Pane Name="Bottom Full Width" />
|
<Pane Name="Bottom Full Width" />
|
||||||
@if (_footer)
|
@if (_footer)
|
||||||
{
|
{
|
||||||
<div class="bg-primary footer">
|
<div class="bg-primary fixed-bottom footer">
|
||||||
<Pane Name="Footer" />
|
<Pane Name="Footer" />
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<Pane Name="Footer" />
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
@ -7,10 +7,10 @@
|
|||||||
<table class="table table-borderless">
|
<table class="table table-borderless">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<Label For="title" ResourceKey="Title" HelpText="Specify If The Page Footer Should Be Displayed">Display Footer?</Label>
|
<Label For="footer" ResourceKey="Footer" HelpText="Specify If A Footer Should Always Be Displayed In A Fixed Location At The Bottom Of The Browser Window">Display Fixed Footer?</Label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<select id="title" class="form-control" @bind="@_footer">
|
<select id="footer" class="form-control" @bind="@_footer">
|
||||||
<option value="true">Yes</option>
|
<option value="true">Yes</option>
|
||||||
<option value="false">No</option>
|
<option value="false">No</option>
|
||||||
</select>
|
</select>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Oqtane.Enums;
|
using Oqtane.Enums;
|
||||||
@ -21,12 +21,16 @@ namespace Oqtane.Controllers
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET: api/<controller>?siteid=x
|
// GET: api/<controller>?siteid=x&global=true/false
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Authorize(Roles = RoleNames.Registered)]
|
[Authorize(Roles = RoleNames.Registered)]
|
||||||
public IEnumerable<Role> Get(string siteid)
|
public IEnumerable<Role> Get(string siteid, string global)
|
||||||
{
|
{
|
||||||
return _roles.GetRoles(int.Parse(siteid));
|
if (string.IsNullOrEmpty(global))
|
||||||
|
{
|
||||||
|
global = "False";
|
||||||
|
}
|
||||||
|
return _roles.GetRoles(int.Parse(siteid), bool.Parse(global));
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET api/<controller>/5
|
// GET api/<controller>/5
|
||||||
@ -68,8 +72,12 @@ namespace Oqtane.Controllers
|
|||||||
[Authorize(Roles = RoleNames.Admin)]
|
[Authorize(Roles = RoleNames.Admin)]
|
||||||
public void Delete(int id)
|
public void Delete(int id)
|
||||||
{
|
{
|
||||||
_roles.DeleteRole(id);
|
var role = _roles.GetRole(id);
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Role Deleted {RoleId}", id);
|
if (!role.IsSystem)
|
||||||
|
{
|
||||||
|
_roles.DeleteRole(id);
|
||||||
|
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Role Deleted {RoleId}", id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Oqtane.Enums;
|
using Oqtane.Enums;
|
||||||
@ -6,6 +6,7 @@ using Oqtane.Models;
|
|||||||
using Oqtane.Shared;
|
using Oqtane.Shared;
|
||||||
using Oqtane.Infrastructure;
|
using Oqtane.Infrastructure;
|
||||||
using Oqtane.Repository;
|
using Oqtane.Repository;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Oqtane.Controllers
|
namespace Oqtane.Controllers
|
||||||
{
|
{
|
||||||
@ -13,13 +14,15 @@ namespace Oqtane.Controllers
|
|||||||
public class UserRoleController : Controller
|
public class UserRoleController : Controller
|
||||||
{
|
{
|
||||||
private readonly IUserRoleRepository _userRoles;
|
private readonly IUserRoleRepository _userRoles;
|
||||||
|
private readonly IRoleRepository _roles;
|
||||||
private readonly ITenantResolver _tenants;
|
private readonly ITenantResolver _tenants;
|
||||||
private readonly ISyncManager _syncManager;
|
private readonly ISyncManager _syncManager;
|
||||||
private readonly ILogManager _logger;
|
private readonly ILogManager _logger;
|
||||||
|
|
||||||
public UserRoleController(IUserRoleRepository userRoles, ITenantResolver tenants, ISyncManager syncManager, ILogManager logger)
|
public UserRoleController(IUserRoleRepository userRoles, IRoleRepository roles, ITenantResolver tenants, ISyncManager syncManager, ILogManager logger)
|
||||||
{
|
{
|
||||||
_userRoles = userRoles;
|
_userRoles = userRoles;
|
||||||
|
_roles = roles;
|
||||||
_syncManager = syncManager;
|
_syncManager = syncManager;
|
||||||
_tenants = tenants;
|
_tenants = tenants;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
@ -46,11 +49,20 @@ namespace Oqtane.Controllers
|
|||||||
[Authorize(Roles = RoleNames.Admin)]
|
[Authorize(Roles = RoleNames.Admin)]
|
||||||
public UserRole Post([FromBody] UserRole userRole)
|
public UserRole Post([FromBody] UserRole userRole)
|
||||||
{
|
{
|
||||||
if (ModelState.IsValid)
|
var role = _roles.GetRole(userRole.RoleId);
|
||||||
|
if (ModelState.IsValid && (User.IsInRole(RoleNames.Host) || role.Name != RoleNames.Host))
|
||||||
{
|
{
|
||||||
|
if (role.Name == RoleNames.Host)
|
||||||
|
{
|
||||||
|
// host roles can only exist at global level - remove all site specific user roles
|
||||||
|
_userRoles.DeleteUserRoles(userRole.UserId);
|
||||||
|
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "User Roles Deleted For UserId {UserId}", userRole.UserId);
|
||||||
|
}
|
||||||
|
|
||||||
userRole = _userRoles.AddUserRole(userRole);
|
userRole = _userRoles.AddUserRole(userRole);
|
||||||
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.User, userRole.UserId);
|
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "User Role Added {UserRole}", userRole);
|
_logger.Log(LogLevel.Information, this, LogFunction.Create, "User Role Added {UserRole}", userRole);
|
||||||
|
|
||||||
|
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.User, userRole.UserId);
|
||||||
}
|
}
|
||||||
return userRole;
|
return userRole;
|
||||||
}
|
}
|
||||||
@ -60,7 +72,8 @@ namespace Oqtane.Controllers
|
|||||||
[Authorize(Roles = RoleNames.Admin)]
|
[Authorize(Roles = RoleNames.Admin)]
|
||||||
public UserRole Put(int id, [FromBody] UserRole userRole)
|
public UserRole Put(int id, [FromBody] UserRole userRole)
|
||||||
{
|
{
|
||||||
if (ModelState.IsValid)
|
var role = _roles.GetRole(userRole.RoleId);
|
||||||
|
if (ModelState.IsValid && (User.IsInRole(RoleNames.Host) || role.Name != RoleNames.Host))
|
||||||
{
|
{
|
||||||
userRole = _userRoles.UpdateUserRole(userRole);
|
userRole = _userRoles.UpdateUserRole(userRole);
|
||||||
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.User, userRole.UserId);
|
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.User, userRole.UserId);
|
||||||
@ -75,9 +88,24 @@ namespace Oqtane.Controllers
|
|||||||
public void Delete(int id)
|
public void Delete(int id)
|
||||||
{
|
{
|
||||||
UserRole userRole = _userRoles.GetUserRole(id);
|
UserRole userRole = _userRoles.GetUserRole(id);
|
||||||
_userRoles.DeleteUserRole(id);
|
if (User.IsInRole(RoleNames.Host) || userRole.Role.Name != RoleNames.Host)
|
||||||
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.User, userRole.UserId);
|
{
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "User Role Deleted {UserRole}", userRole);
|
_userRoles.DeleteUserRole(id);
|
||||||
|
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "User Role Deleted {UserRole}", userRole);
|
||||||
|
|
||||||
|
if (userRole.Role.Name == RoleNames.Host)
|
||||||
|
{
|
||||||
|
// add site specific user roles to preserve user access
|
||||||
|
var role = _roles.GetRoles(_tenants.GetAlias().SiteId).FirstOrDefault(item => item.Name == RoleNames.Registered);
|
||||||
|
userRole = _userRoles.AddUserRole(new UserRole { UserId = userRole.UserId, RoleId = role.RoleId, EffectiveDate = null, ExpiryDate = null });
|
||||||
|
_logger.Log(LogLevel.Information, this, LogFunction.Create, "User Role Added {UserRole}", userRole);
|
||||||
|
role = _roles.GetRoles(_tenants.GetAlias().SiteId).FirstOrDefault(item => item.Name == RoleNames.Admin);
|
||||||
|
userRole = _userRoles.AddUserRole(new UserRole { UserId = userRole.UserId, RoleId = role.RoleId, EffectiveDate = null, ExpiryDate = null });
|
||||||
|
_logger.Log(LogLevel.Information, this, LogFunction.Create, "User Role Added {UserRole}", userRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.User, userRole.UserId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ namespace Oqtane.Infrastructure
|
|||||||
public static bool InstallPackages(string folders, string webRootPath, string contentRootPath)
|
public static bool InstallPackages(string folders, string webRootPath, string contentRootPath)
|
||||||
{
|
{
|
||||||
bool install = false;
|
bool install = false;
|
||||||
string binFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
|
string binPath = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
|
||||||
|
|
||||||
foreach (string folder in folders.Split(','))
|
foreach (string folder in folders.Split(','))
|
||||||
{
|
{
|
||||||
@ -82,40 +82,37 @@ namespace Oqtane.Infrastructure
|
|||||||
List<string> assets = new List<string>();
|
List<string> assets = new List<string>();
|
||||||
bool manifest = false;
|
bool manifest = false;
|
||||||
|
|
||||||
// module and theme packages must be in form of name.1.0.0.nupkg
|
// packages are in form of name.1.0.0.nupkg or name.culture.1.0.0.nupkg
|
||||||
string name = Path.GetFileNameWithoutExtension(packagename);
|
string name = Path.GetFileNameWithoutExtension(packagename);
|
||||||
string[] segments = name?.Split('.');
|
string[] segments = name?.Split('.');
|
||||||
if (segments != null) name = string.Join('.', segments, 0, segments.Length - 3);
|
if (segments != null) name = string.Join('.', segments, 0, segments.Length - 3); // remove version information
|
||||||
|
|
||||||
// deploy to appropriate locations
|
// deploy to appropriate locations
|
||||||
foreach (ZipArchiveEntry entry in archive.Entries)
|
foreach (ZipArchiveEntry entry in archive.Entries)
|
||||||
{
|
{
|
||||||
string foldername = Path.GetDirectoryName(entry.FullName).Split(Path.DirectorySeparatorChar)[0];
|
string filename = "";
|
||||||
string filename = Path.GetFileName(entry.FullName);
|
|
||||||
|
|
||||||
if (!manifest && filename == "assets.json")
|
// evaluate entry root folder
|
||||||
|
switch (entry.FullName.Split('/')[0])
|
||||||
{
|
{
|
||||||
manifest = true;
|
case "lib": // lib/net5.0/...
|
||||||
|
filename = ExtractFile(entry, binPath, 2);
|
||||||
|
break;
|
||||||
|
case "wwwroot": // wwwroot/...
|
||||||
|
filename = ExtractFile(entry, webRootPath, 1);
|
||||||
|
break;
|
||||||
|
case "runtimes": // runtimes/name/...
|
||||||
|
filename = ExtractFile(entry, binPath, 0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (foldername)
|
if (filename != "")
|
||||||
{
|
{
|
||||||
case "lib":
|
assets.Add(filename.Replace(contentRootPath, ""));
|
||||||
filename = Path.Combine(binFolder, filename);
|
if (!manifest && Path.GetFileName(filename) == "assets.json")
|
||||||
ExtractFile(entry, filename);
|
{
|
||||||
assets.Add(filename.Replace(contentRootPath, ""));
|
manifest = true;
|
||||||
break;
|
}
|
||||||
case "wwwroot":
|
|
||||||
filename = Path.Combine(webRootPath, Utilities.PathCombine(entry.FullName.Replace("wwwroot/", "").Split('/')));
|
|
||||||
ExtractFile(entry, filename);
|
|
||||||
assets.Add(filename.Replace(contentRootPath, ""));
|
|
||||||
break;
|
|
||||||
case "runtimes":
|
|
||||||
var destSubFolder = Path.GetDirectoryName(entry.FullName);
|
|
||||||
filename = Path.Combine(binFolder, destSubFolder, filename);
|
|
||||||
ExtractFile(entry, filename);
|
|
||||||
assets.Add(filename.Replace(contentRootPath, ""));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,21 +142,25 @@ namespace Oqtane.Infrastructure
|
|||||||
return install;
|
return install;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ExtractFile(ZipArchiveEntry entry, string filename)
|
private static string ExtractFile(ZipArchiveEntry entry, string folder, int ignoreLeadingSegments)
|
||||||
{
|
{
|
||||||
if (!Directory.Exists(Path.GetDirectoryName(filename)))
|
string[] segments = entry.FullName.Split('/'); // ZipArchiveEntries always use unix path separator
|
||||||
{
|
string filename = Path.Combine(folder, string.Join(Path.DirectorySeparatorChar, segments, ignoreLeadingSegments, segments.Length - ignoreLeadingSegments));
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(filename));
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (!Directory.Exists(Path.GetDirectoryName(filename)))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(filename));
|
||||||
|
}
|
||||||
entry.ExtractToFile(filename, true);
|
entry.ExtractToFile(filename, true);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
// an error occurred extracting the file
|
// an error occurred extracting the file
|
||||||
|
filename = "";
|
||||||
}
|
}
|
||||||
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpgradeFramework()
|
public void UpgradeFramework()
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
|
|
||||||
namespace Oqtane.Repository
|
namespace Oqtane.Repository
|
||||||
@ -11,5 +11,6 @@ namespace Oqtane.Repository
|
|||||||
UserRole UpdateUserRole(UserRole userRole);
|
UserRole UpdateUserRole(UserRole userRole);
|
||||||
UserRole GetUserRole(int userRoleId);
|
UserRole GetUserRole(int userRoleId);
|
||||||
void DeleteUserRole(int userRoleId);
|
void DeleteUserRole(int userRoleId);
|
||||||
|
void DeleteUserRoles(int userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
@ -16,12 +16,19 @@ namespace Oqtane.Repository
|
|||||||
|
|
||||||
public IEnumerable<Role> GetRoles(int siteId)
|
public IEnumerable<Role> GetRoles(int siteId)
|
||||||
{
|
{
|
||||||
return _db.Role.Where(item => item.SiteId == siteId);
|
return GetRoles(siteId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Role> GetRoles(int siteId, bool includeGlobalRoles)
|
public IEnumerable<Role> GetRoles(int siteId, bool includeGlobalRoles)
|
||||||
{
|
{
|
||||||
return _db.Role.Where(item => item.SiteId == siteId || item.SiteId == null);
|
if (includeGlobalRoles)
|
||||||
|
{
|
||||||
|
return _db.Role.Where(item => item.SiteId == siteId || item.SiteId == null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return _db.Role.Where(item => item.SiteId == siteId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Role AddRole(Role role)
|
public Role AddRole(Role role)
|
||||||
|
@ -649,9 +649,9 @@ namespace Oqtane.Repository
|
|||||||
_roleRepository.AddRole(new Role {SiteId = site.SiteId, Name = RoleNames.Admin, Description = "Site Administrators", IsAutoAssigned = false, IsSystem = true});
|
_roleRepository.AddRole(new Role {SiteId = site.SiteId, Name = RoleNames.Admin, Description = "Site Administrators", IsAutoAssigned = false, IsSystem = true});
|
||||||
|
|
||||||
_profileRepository.AddProfile(new Profile
|
_profileRepository.AddProfile(new Profile
|
||||||
{SiteId = site.SiteId, Name = "FirstName", Title = "First Name", Description = "Your First Or Given Name", Category = "Name", ViewOrder = 1, MaxLength = 50, DefaultValue = "", IsRequired = true, IsPrivate = false});
|
{SiteId = site.SiteId, Name = "FirstName", Title = "First Name", Description = "Your First Or Given Name", Category = "Name", ViewOrder = 1, MaxLength = 50, DefaultValue = "", IsRequired = false, IsPrivate = false});
|
||||||
_profileRepository.AddProfile(new Profile
|
_profileRepository.AddProfile(new Profile
|
||||||
{SiteId = site.SiteId, Name = "LastName", Title = "Last Name", Description = "Your Last Or Family Name", Category = "Name", ViewOrder = 2, MaxLength = 50, DefaultValue = "", IsRequired = true, IsPrivate = false});
|
{SiteId = site.SiteId, Name = "LastName", Title = "Last Name", Description = "Your Last Or Family Name", Category = "Name", ViewOrder = 2, MaxLength = 50, DefaultValue = "", IsRequired = false, IsPrivate = false});
|
||||||
_profileRepository.AddProfile(new Profile
|
_profileRepository.AddProfile(new Profile
|
||||||
{SiteId = site.SiteId, Name = "Street", Title = "Street", Description = "Street Or Building Address", Category = "Address", ViewOrder = 3, MaxLength = 50, DefaultValue = "", IsRequired = false, IsPrivate = false});
|
{SiteId = site.SiteId, Name = "Street", Title = "Street", Description = "Street Or Building Address", Category = "Address", ViewOrder = 3, MaxLength = 50, DefaultValue = "", IsRequired = false, IsPrivate = false});
|
||||||
_profileRepository.AddProfile(
|
_profileRepository.AddProfile(
|
||||||
|
@ -58,5 +58,14 @@ namespace Oqtane.Repository
|
|||||||
_db.UserRole.Remove(userRole);
|
_db.UserRole.Remove(userRole);
|
||||||
_db.SaveChanges();
|
_db.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DeleteUserRoles(int userId)
|
||||||
|
{
|
||||||
|
foreach (UserRole userRole in _db.UserRole.Where(item => item.Role.SiteId != null))
|
||||||
|
{
|
||||||
|
_db.UserRole.Remove(userRole);
|
||||||
|
}
|
||||||
|
_db.SaveChanges();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,7 @@ div.app-moduleactions a.dropdown-toggle, div.app-moduleactions div.dropdown-menu
|
|||||||
min-height: 40px;
|
min-height: 40px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
|
z-index: 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 767px) {
|
@media (max-width: 767px) {
|
||||||
|
Reference in New Issue
Block a user