diff --git a/Oqtane.Client/Modules/Admin/Roles/Index.razor b/Oqtane.Client/Modules/Admin/Roles/Index.razor new file mode 100644 index 00000000..c21f185d --- /dev/null +++ b/Oqtane.Client/Modules/Admin/Roles/Index.razor @@ -0,0 +1,40 @@ +@using Oqtane.Services +@using Oqtane.Models +@using Oqtane.Modules +@using Oqtane.Client.Modules.Controls +@inherits ModuleBase +@inject IRoleService RoleService + +@if (Roles == null) +{ +

Loading...

+} +else +{ + + + + + + + + @foreach (var Role in Roles) + { + + + + } + +
Name
@Role.Name
+} + +@code { + public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } + + List Roles; + + protected override async Task OnInitializedAsync() + { + Roles = await RoleService.GetRolesAsync(PageState.Site.SiteId); + } +} \ No newline at end of file diff --git a/Oqtane.Client/Modules/Admin/Users/Index.razor b/Oqtane.Client/Modules/Admin/Users/Index.razor index ea748d40..481e0ae4 100644 --- a/Oqtane.Client/Modules/Admin/Users/Index.razor +++ b/Oqtane.Client/Modules/Admin/Users/Index.razor @@ -30,12 +30,12 @@ else } @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } } + public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } List Users; protected override async Task OnInitializedAsync() { - Users = await UserService.GetUsersAsync(); + Users = await UserService.GetUsersAsync(PageState.Site.SiteId); } } \ No newline at end of file diff --git a/Oqtane.Client/Services/Interfaces/IRoleService.cs b/Oqtane.Client/Services/Interfaces/IRoleService.cs new file mode 100644 index 00000000..d7f26332 --- /dev/null +++ b/Oqtane.Client/Services/Interfaces/IRoleService.cs @@ -0,0 +1,21 @@ +using Oqtane.Models; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Oqtane.Services +{ + public interface IRoleService + { + Task> GetRolesAsync(); + + Task> GetRolesAsync(int SiteId); + + Task GetRoleAsync(int RoleId); + + Task AddRoleAsync(Role Role); + + Task UpdateRoleAsync(Role Role); + + Task DeleteRoleAsync(int RoleId); + } +} diff --git a/Oqtane.Client/Services/Interfaces/IUserRoleService.cs b/Oqtane.Client/Services/Interfaces/IUserRoleService.cs new file mode 100644 index 00000000..9030e2c1 --- /dev/null +++ b/Oqtane.Client/Services/Interfaces/IUserRoleService.cs @@ -0,0 +1,16 @@ +using Oqtane.Models; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Oqtane.Services +{ + public interface IUserRoleService + { + Task> GetUserRolesAsync(); + Task> GetUserRolesAsync(int UserId); + Task GetUserRoleAsync(int UserRoleId); + Task AddUserRoleAsync(UserRole UserRole); + Task UpdateUserRoleAsync(UserRole UserRole); + Task DeleteUserRoleAsync(int UserRoleId); + } +} diff --git a/Oqtane.Client/Services/Interfaces/IUserService.cs b/Oqtane.Client/Services/Interfaces/IUserService.cs index e263d92c..6ffc4991 100644 --- a/Oqtane.Client/Services/Interfaces/IUserService.cs +++ b/Oqtane.Client/Services/Interfaces/IUserService.cs @@ -6,11 +6,11 @@ namespace Oqtane.Services { public interface IUserService { - Task> GetUsersAsync(); + Task> GetUsersAsync(int SiteId); - Task GetUserAsync(int UserId); + Task GetUserAsync(int UserId, int SiteId); - Task GetUserAsync(string Username); + Task GetUserAsync(string Username, int SiteId); Task AddUserAsync(User User); @@ -18,8 +18,6 @@ namespace Oqtane.Services Task DeleteUserAsync(int UserId); - Task GetCurrentUserAsync(); - Task LoginUserAsync(User User); Task LogoutUserAsync(); diff --git a/Oqtane.Client/Services/RoleService.cs b/Oqtane.Client/Services/RoleService.cs new file mode 100644 index 00000000..8f770e78 --- /dev/null +++ b/Oqtane.Client/Services/RoleService.cs @@ -0,0 +1,60 @@ +using Oqtane.Models; +using System.Threading.Tasks; +using System.Net.Http; +using System.Linq; +using Microsoft.AspNetCore.Components; +using System.Collections.Generic; +using Oqtane.Shared; + +namespace Oqtane.Services +{ + public class RoleService : ServiceBase, IRoleService + { + private readonly HttpClient http; + private readonly SiteState sitestate; + private readonly IUriHelper urihelper; + + public RoleService(HttpClient http, SiteState sitestate, IUriHelper urihelper) + { + this.http = http; + this.sitestate = sitestate; + this.urihelper = urihelper; + } + + private string apiurl + { + get { return CreateApiUrl(sitestate.Alias, urihelper.GetAbsoluteUri(), "Role"); } + } + + public async Task> GetRolesAsync() + { + List Roles = await http.GetJsonAsync>(apiurl); + return Roles.OrderBy(item => item.Name).ToList(); + } + + public async Task> GetRolesAsync(int SiteId) + { + List Roles = await http.GetJsonAsync>(apiurl + "?siteid=" + SiteId.ToString()); + return Roles.OrderBy(item => item.Name).ToList(); + } + + public async Task GetRoleAsync(int RoleId) + { + return await http.GetJsonAsync(apiurl + "/" + RoleId.ToString()); + } + + public async Task AddRoleAsync(Role Role) + { + return await http.PostJsonAsync(apiurl, Role); + } + + public async Task UpdateRoleAsync(Role Role) + { + return await http.PutJsonAsync(apiurl + "/" + Role.SiteId.ToString(), Role); + } + public async Task DeleteRoleAsync(int RoleId) + { + await http.DeleteAsync(apiurl + "/" + RoleId.ToString()); + } + } +} diff --git a/Oqtane.Client/Services/UserRoleService.cs b/Oqtane.Client/Services/UserRoleService.cs new file mode 100644 index 00000000..b84a8450 --- /dev/null +++ b/Oqtane.Client/Services/UserRoleService.cs @@ -0,0 +1,59 @@ +using Oqtane.Models; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Components; +using Oqtane.Shared; + +namespace Oqtane.Services +{ + public class UserRoleService : ServiceBase, IUserRoleService + { + private readonly HttpClient http; + private readonly SiteState sitestate; + private readonly IUriHelper urihelper; + + public UserRoleService(HttpClient http, SiteState sitestate, IUriHelper urihelper) + { + this.http = http; + this.sitestate = sitestate; + this.urihelper = urihelper; + } + + private string apiurl + { + get { return CreateApiUrl(sitestate.Alias, urihelper.GetAbsoluteUri(), "UserRole"); } + } + + public async Task> GetUserRolesAsync() + { + return await http.GetJsonAsync>(apiurl); + } + + public async Task> GetUserRolesAsync(int UserId) + { + return await http.GetJsonAsync>(apiurl + "?userid=" + UserId.ToString()); + } + + public async Task GetUserRoleAsync(int UserRoleId) + { + return await http.GetJsonAsync(apiurl + "/" + UserRoleId.ToString()); + } + + public async Task AddUserRoleAsync(UserRole UserRole) + { + return await http.PostJsonAsync(apiurl, UserRole); + } + + public async Task UpdateUserRoleAsync(UserRole UserRole) + { + return await http.PutJsonAsync(apiurl + "/" + UserRole.UserRoleId.ToString(), UserRole); + } + + public async Task DeleteUserRoleAsync(int UserRoleId) + { + await http.DeleteAsync(apiurl + "/" + UserRoleId.ToString()); + } + } +} diff --git a/Oqtane.Client/Services/UserService.cs b/Oqtane.Client/Services/UserService.cs index d9dd281d..333f1cdf 100644 --- a/Oqtane.Client/Services/UserService.cs +++ b/Oqtane.Client/Services/UserService.cs @@ -27,20 +27,20 @@ namespace Oqtane.Services get { return CreateApiUrl(sitestate.Alias, urihelper.GetAbsoluteUri(), "User"); } } - public async Task> GetUsersAsync() + public async Task> GetUsersAsync(int SiteId) { - List users = await http.GetJsonAsync>(apiurl); + List users = await http.GetJsonAsync>(apiurl + "?siteid=" + SiteId.ToString()); return users.OrderBy(item => item.DisplayName).ToList(); } - public async Task GetUserAsync(int UserId) + public async Task GetUserAsync(int UserId, int SiteId) { - return await http.GetJsonAsync(apiurl + "/" + UserId.ToString()); + return await http.GetJsonAsync(apiurl + "/" + UserId.ToString() + "?siteid=" + SiteId.ToString()); } - public async Task GetUserAsync(string Username) + public async Task GetUserAsync(string Username, int SiteId) { - return await http.GetJsonAsync(apiurl + "/name/" + Username); + return await http.GetJsonAsync(apiurl + "/name/" + Username + "?siteid=" + SiteId.ToString()); } public async Task AddUserAsync(User User) @@ -57,11 +57,6 @@ namespace Oqtane.Services await http.DeleteAsync(apiurl + "/" + UserId.ToString()); } - public async Task GetCurrentUserAsync() - { - return await http.GetJsonAsync(apiurl + "/current"); - } - public async Task LoginUserAsync(User User) { return await http.PostJsonAsync(apiurl + "/login", User); @@ -80,7 +75,7 @@ namespace Oqtane.Services if (User != null) { - //super user always has full access + // super user always has full access isAllowed = User.IsSuperUser; } diff --git a/Oqtane.Client/Shared/Installer.razor b/Oqtane.Client/Shared/Installer.razor index f624b89a..72e662e7 100644 --- a/Oqtane.Client/Shared/Installer.razor +++ b/Oqtane.Client/Shared/Installer.razor @@ -169,7 +169,8 @@ user.Password = HostPassword; user.IsSuperUser = true; user.Roles = ""; - await UserService.AddUserAsync(user); + user = await UserService.AddUserAsync(user); + UriHelper.NavigateTo("", true); } else diff --git a/Oqtane.Client/Shared/PaneLayout.razor b/Oqtane.Client/Shared/PaneLayout.razor index 74310b60..9fe4f572 100644 --- a/Oqtane.Client/Shared/PaneLayout.razor +++ b/Oqtane.Client/Shared/PaneLayout.razor @@ -21,8 +21,8 @@ } else { - // layout does not exist with type specified - } + // layout does not exist with type specified + } }; } } \ No newline at end of file diff --git a/Oqtane.Client/Shared/SiteRouter.razor b/Oqtane.Client/Shared/SiteRouter.razor index 8a44e141..995e5b55 100644 --- a/Oqtane.Client/Shared/SiteRouter.razor +++ b/Oqtane.Client/Shared/SiteRouter.razor @@ -195,7 +195,7 @@ var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync(); if (authState.User.Identity.IsAuthenticated) { - user = await UserService.GetUserAsync(authState.User.Identity.Name); + user = await UserService.GetUserAsync(authState.User.Identity.Name, site.SiteId); } } else diff --git a/Oqtane.Client/Shared/Theme.razor b/Oqtane.Client/Shared/Theme.razor index 3f83b411..b9431f4d 100644 --- a/Oqtane.Client/Shared/Theme.razor +++ b/Oqtane.Client/Shared/Theme.razor @@ -20,8 +20,8 @@ } else { - // theme does not exist with type specified - builder.OpenComponent(0, Type.GetType(Constants.ModuleMessageControl)); + // theme does not exist with type specified + builder.OpenComponent(0, Type.GetType(Constants.ModuleMessageControl)); builder.AddAttribute(1, "Type", MessageType.Error); builder.AddAttribute(2, "Message", "Error Loading Page Theme " + PageState.Page.ThemeType); builder.CloseComponent(); diff --git a/Oqtane.Client/Startup.cs b/Oqtane.Client/Startup.cs index 07c3b631..754ca6ad 100644 --- a/Oqtane.Client/Startup.cs +++ b/Oqtane.Client/Startup.cs @@ -46,6 +46,8 @@ namespace Oqtane.Client services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); + services.AddScoped(); services.AddScoped(); // dynamically register module contexts and repository services diff --git a/Oqtane.Client/Themes/Controls/Login.razor b/Oqtane.Client/Themes/Controls/Login.razor index 34492a17..811febd9 100644 --- a/Oqtane.Client/Themes/Controls/Login.razor +++ b/Oqtane.Client/Themes/Controls/Login.razor @@ -1,8 +1,7 @@ @using Oqtane.Themes -@using Oqtane.Services +@using Oqtane.Services @using Oqtane.Providers @using Oqtane.Shared -@using Oqtane.Models @using Microsoft.JSInterop @inherits ThemeObjectBase @inject IUriHelper UriHelper @@ -51,8 +50,8 @@ { // client-side Blazor authstateprovider.NotifyAuthenticationChanged(); - PageState.Reload = Constants.ReloadPage; - UriHelper.NavigateTo(NavigateUrl()); + PageState.Reload = Constants.ReloadSite; + UriHelper.NavigateTo(NavigateUrl(PageState.Page.Path)); } } } diff --git a/Oqtane.Server/Controllers/AliasController.cs b/Oqtane.Server/Controllers/AliasController.cs index facd0453..86ff6a04 100644 --- a/Oqtane.Server/Controllers/AliasController.cs +++ b/Oqtane.Server/Controllers/AliasController.cs @@ -8,25 +8,25 @@ namespace Oqtane.Controllers [Route("{site}/api/[controller]")] public class AliasController : Controller { - private readonly IAliasRepository aliases; + private readonly IAliasRepository Aliases; public AliasController(IAliasRepository Aliases) { - aliases = Aliases; + this.Aliases = Aliases; } // GET: api/ [HttpGet] public IEnumerable Get() { - return aliases.GetAliases(); + return Aliases.GetAliases(); } // GET api//5 [HttpGet("{id}")] public Alias Get(int id) { - return aliases.GetAlias(id); + return Aliases.GetAlias(id); } // POST api/ @@ -35,7 +35,7 @@ namespace Oqtane.Controllers { if (ModelState.IsValid) { - Alias = aliases.AddAlias(Alias); + Alias = Aliases.AddAlias(Alias); } return Alias; } @@ -46,7 +46,7 @@ namespace Oqtane.Controllers { if (ModelState.IsValid) { - Alias = aliases.UpdateAlias(Alias); + Alias = Aliases.UpdateAlias(Alias); } return Alias; } @@ -55,7 +55,7 @@ namespace Oqtane.Controllers [HttpDelete("{id}")] public void Delete(int id) { - aliases.DeleteAlias(id); + Aliases.DeleteAlias(id); } } } diff --git a/Oqtane.Server/Controllers/InstallationController.cs b/Oqtane.Server/Controllers/InstallationController.cs index 06defd92..7390dfd7 100644 --- a/Oqtane.Server/Controllers/InstallationController.cs +++ b/Oqtane.Server/Controllers/InstallationController.cs @@ -18,11 +18,11 @@ namespace Oqtane.Controllers [Route("{site}/api/[controller]")] public class InstallationController : Controller { - private readonly IConfigurationRoot _config; + private readonly IConfigurationRoot Config; - public InstallationController(IConfigurationRoot config) + public InstallationController(IConfigurationRoot Config) { - _config = config; + this.Config = Config; } // POST api/ @@ -139,7 +139,7 @@ namespace Oqtane.Controllers { writer.WriteLine(config); } - _config.Reload(); + Config.Reload(); response.Success = true; } } @@ -160,7 +160,7 @@ namespace Oqtane.Controllers var response = new GenericResponse { Success = false, Message = "" }; string datadirectory = AppDomain.CurrentDomain.GetData("DataDirectory").ToString(); - string connectionString = _config.GetConnectionString("DefaultConnection"); + string connectionString = Config.GetConnectionString("DefaultConnection"); connectionString = connectionString.Replace("|DataDirectory|", datadirectory); SqlConnection connection = new SqlConnection(connectionString); diff --git a/Oqtane.Server/Controllers/ModuleController.cs b/Oqtane.Server/Controllers/ModuleController.cs index 994afbae..ef819edc 100644 --- a/Oqtane.Server/Controllers/ModuleController.cs +++ b/Oqtane.Server/Controllers/ModuleController.cs @@ -8,13 +8,13 @@ namespace Oqtane.Controllers [Route("{site}/api/[controller]")] public class ModuleController : Controller { - private readonly IModuleRepository modules; - private readonly IPageModuleRepository pagemodules; + private readonly IModuleRepository Modules; + private readonly IPageModuleRepository PageModules; public ModuleController(IModuleRepository Modules, IPageModuleRepository PageModules) { - modules = Modules; - pagemodules = PageModules; + this.Modules = Modules; + this.PageModules = PageModules; } // GET: api/?pageid=x @@ -25,7 +25,7 @@ namespace Oqtane.Controllers if (!string.IsNullOrEmpty(pageid)) { List modulelist = new List(); - foreach (PageModule pagemodule in pagemodules.GetPageModules(int.Parse(pageid))) + foreach (PageModule pagemodule in PageModules.GetPageModules(int.Parse(pageid))) { Module module = pagemodule.Module; module.PageModuleId = pagemodule.PageModuleId; @@ -40,7 +40,7 @@ namespace Oqtane.Controllers } else { - return modules.GetModules(int.Parse(siteid), moduledefinitionname); + return Modules.GetModules(int.Parse(siteid), moduledefinitionname); } } @@ -48,7 +48,7 @@ namespace Oqtane.Controllers [HttpGet("{id}")] public Module Get(int id) { - return modules.GetModule(id); + return Modules.GetModule(id); } // POST api/ @@ -57,7 +57,7 @@ namespace Oqtane.Controllers { if (ModelState.IsValid) { - Module = modules.AddModule(Module); + Module = Modules.AddModule(Module); } return Module; } @@ -68,7 +68,7 @@ namespace Oqtane.Controllers { if (ModelState.IsValid) { - Module = modules.UpdateModule(Module); + Module = Modules.UpdateModule(Module); } return Module; } @@ -77,7 +77,7 @@ namespace Oqtane.Controllers [HttpDelete("{id}")] public void Delete(int id) { - modules.DeleteModule(id); + Modules.DeleteModule(id); } } } diff --git a/Oqtane.Server/Controllers/ModuleDefinitionController.cs b/Oqtane.Server/Controllers/ModuleDefinitionController.cs index b523111b..d69275db 100644 --- a/Oqtane.Server/Controllers/ModuleDefinitionController.cs +++ b/Oqtane.Server/Controllers/ModuleDefinitionController.cs @@ -8,18 +8,18 @@ namespace Oqtane.Controllers [Route("{site}/api/[controller]")] public class ModuleDefinitionController : Controller { - private readonly IModuleDefinitionRepository moduledefinitions; + private readonly IModuleDefinitionRepository ModuleDefinitions; public ModuleDefinitionController(IModuleDefinitionRepository ModuleDefinitions) { - moduledefinitions = ModuleDefinitions; + this.ModuleDefinitions = ModuleDefinitions; } // GET: api/ [HttpGet] public IEnumerable Get() { - return moduledefinitions.GetModuleDefinitions(); + return ModuleDefinitions.GetModuleDefinitions(); } } } diff --git a/Oqtane.Server/Controllers/PageController.cs b/Oqtane.Server/Controllers/PageController.cs index 59ac9bdd..96ef61af 100644 --- a/Oqtane.Server/Controllers/PageController.cs +++ b/Oqtane.Server/Controllers/PageController.cs @@ -8,11 +8,11 @@ namespace Oqtane.Controllers [Route("{site}/api/[controller]")] public class PageController : Controller { - private readonly IPageRepository pages; + private readonly IPageRepository Pages; public PageController(IPageRepository Pages) { - pages = Pages; + this.Pages = Pages; } // GET: api/?siteid=x @@ -21,11 +21,11 @@ namespace Oqtane.Controllers { if (siteid == "") { - return pages.GetPages(); + return Pages.GetPages(); } else { - return pages.GetPages(int.Parse(siteid)); + return Pages.GetPages(int.Parse(siteid)); } } @@ -33,7 +33,7 @@ namespace Oqtane.Controllers [HttpGet("{id}")] public Page Get(int id) { - return pages.GetPage(id); + return Pages.GetPage(id); } // POST api/ @@ -42,7 +42,7 @@ namespace Oqtane.Controllers { if (ModelState.IsValid) { - Page = pages.AddPage(Page); + Page = Pages.AddPage(Page); } return Page; } @@ -53,7 +53,7 @@ namespace Oqtane.Controllers { if (ModelState.IsValid) { - Page = pages.UpdatePage(Page); + Page = Pages.UpdatePage(Page); } return Page; } @@ -62,7 +62,7 @@ namespace Oqtane.Controllers [HttpDelete("{id}")] public void Delete(int id) { - pages.DeletePage(id); + Pages.DeletePage(id); } } } diff --git a/Oqtane.Server/Controllers/PageModuleController.cs b/Oqtane.Server/Controllers/PageModuleController.cs index 500825d0..fa99465e 100644 --- a/Oqtane.Server/Controllers/PageModuleController.cs +++ b/Oqtane.Server/Controllers/PageModuleController.cs @@ -8,25 +8,25 @@ namespace Oqtane.Controllers [Route("{site}/api/[controller]")] public class PageModuleController : Controller { - private readonly IPageModuleRepository pagemodules; + private readonly IPageModuleRepository PageModules; public PageModuleController(IPageModuleRepository PageModules) { - pagemodules = PageModules; + this.PageModules = PageModules; } // GET: api/ [HttpGet] public IEnumerable Get() { - return pagemodules.GetPageModules(); + return PageModules.GetPageModules(); } // GET api//5 [HttpGet("{id}")] public PageModule Get(int id) { - return pagemodules.GetPageModule(id); + return PageModules.GetPageModule(id); } // POST api/ @@ -35,7 +35,7 @@ namespace Oqtane.Controllers { if (ModelState.IsValid) { - PageModule = pagemodules.AddPageModule(PageModule); + PageModule = PageModules.AddPageModule(PageModule); } return PageModule; } @@ -46,7 +46,7 @@ namespace Oqtane.Controllers { if (ModelState.IsValid) { - PageModule = pagemodules.UpdatePageModule(PageModule); + PageModule = PageModules.UpdatePageModule(PageModule); } return PageModule; } @@ -55,7 +55,7 @@ namespace Oqtane.Controllers [HttpDelete("{id}")] public void Delete(int id) { - pagemodules.DeletePageModule(id); + PageModules.DeletePageModule(id); } } } diff --git a/Oqtane.Server/Controllers/RoleController.cs b/Oqtane.Server/Controllers/RoleController.cs new file mode 100644 index 00000000..85f32f55 --- /dev/null +++ b/Oqtane.Server/Controllers/RoleController.cs @@ -0,0 +1,68 @@ +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc; +using Oqtane.Repository; +using Oqtane.Models; + +namespace Oqtane.Controllers +{ + [Route("{site}/api/[controller]")] + public class RoleController : Controller + { + private readonly IRoleRepository Roles; + + public RoleController(IRoleRepository Roles) + { + this.Roles = Roles; + } + + // GET: api/?siteid=x + [HttpGet] + public IEnumerable Get(string siteid) + { + if (siteid == "") + { + return Roles.GetRoles(); + } + else + { + return Roles.GetRoles(int.Parse(siteid)); + } + } + + // GET api//5 + [HttpGet("{id}")] + public Role Get(int id) + { + return Roles.GetRole(id); + } + + // POST api/ + [HttpPost] + public Role Post([FromBody] Role Role) + { + if (ModelState.IsValid) + { + Role = Roles.AddRole(Role); + } + return Role; + } + + // PUT api//5 + [HttpPut("{id}")] + public Role Put(int id, [FromBody] Role Role) + { + if (ModelState.IsValid) + { + Role = Roles.UpdateRole(Role); + } + return Role; + } + + // DELETE api//5 + [HttpDelete("{id}")] + public void Delete(int id) + { + Roles.DeleteRole(id); + } + } +} diff --git a/Oqtane.Server/Controllers/SiteController.cs b/Oqtane.Server/Controllers/SiteController.cs index 3d2528f9..b5892ec6 100644 --- a/Oqtane.Server/Controllers/SiteController.cs +++ b/Oqtane.Server/Controllers/SiteController.cs @@ -8,25 +8,25 @@ namespace Oqtane.Controllers [Route("{site}/api/[controller]")] public class SiteController : Controller { - private readonly ISiteRepository sites; + private readonly ISiteRepository Sites; public SiteController(ISiteRepository Sites) { - sites = Sites; + this.Sites = Sites; } // GET: api/ [HttpGet] public IEnumerable Get() { - return sites.GetSites(); + return Sites.GetSites(); } // GET api//5 [HttpGet("{id}")] public Site Get(int id) { - return sites.GetSite(id); + return Sites.GetSite(id); } // POST api/ @@ -35,7 +35,7 @@ namespace Oqtane.Controllers { if (ModelState.IsValid) { - Site = sites.AddSite(Site); + Site = Sites.AddSite(Site); } return Site; } @@ -46,7 +46,7 @@ namespace Oqtane.Controllers { if (ModelState.IsValid) { - Site = sites.UpdateSite(Site); + Site = Sites.UpdateSite(Site); } return Site; } @@ -55,7 +55,7 @@ namespace Oqtane.Controllers [HttpDelete("{id}")] public void Delete(int id) { - sites.DeleteSite(id); + Sites.DeleteSite(id); } } } diff --git a/Oqtane.Server/Controllers/TenantController.cs b/Oqtane.Server/Controllers/TenantController.cs index a5c38ebe..e56d86ee 100644 --- a/Oqtane.Server/Controllers/TenantController.cs +++ b/Oqtane.Server/Controllers/TenantController.cs @@ -8,25 +8,25 @@ namespace Oqtane.Controllers [Route("{site}/api/[controller]")] public class TenantController : Controller { - private readonly ITenantRepository tenants; + private readonly ITenantRepository Tenants; public TenantController(ITenantRepository Tenants) { - tenants = Tenants; + this.Tenants = Tenants; } // GET: api/ [HttpGet] public IEnumerable Get() { - return tenants.GetTenants(); + return Tenants.GetTenants(); } // GET api//5 [HttpGet("{id}")] public Tenant Get(int id) { - return tenants.GetTenant(id); + return Tenants.GetTenant(id); } // POST api/ @@ -35,7 +35,7 @@ namespace Oqtane.Controllers { if (ModelState.IsValid) { - Tenant = tenants.AddTenant(Tenant); + Tenant = Tenants.AddTenant(Tenant); } return Tenant; } @@ -46,7 +46,7 @@ namespace Oqtane.Controllers { if (ModelState.IsValid) { - Tenant = tenants.UpdateTenant(Tenant); + Tenant = Tenants.UpdateTenant(Tenant); } return Tenant; } @@ -55,7 +55,7 @@ namespace Oqtane.Controllers [HttpDelete("{id}")] public void Delete(int id) { - tenants.DeleteTenant(id); + Tenants.DeleteTenant(id); } } } diff --git a/Oqtane.Server/Controllers/ThemeController.cs b/Oqtane.Server/Controllers/ThemeController.cs index 0b22b963..8cb7afe9 100644 --- a/Oqtane.Server/Controllers/ThemeController.cs +++ b/Oqtane.Server/Controllers/ThemeController.cs @@ -8,18 +8,18 @@ namespace Oqtane.Controllers [Route("{site}/api/[controller]")] public class ThemeController : Controller { - private readonly IThemeRepository themes; + private readonly IThemeRepository Themes; public ThemeController(IThemeRepository Themes) { - themes = Themes; + this.Themes = Themes; } // GET: api/ [HttpGet] public IEnumerable Get() { - return themes.GetThemes(); + return Themes.GetThemes(); } } } diff --git a/Oqtane.Server/Controllers/UserController.cs b/Oqtane.Server/Controllers/UserController.cs index 209a90cc..914e23e7 100644 --- a/Oqtane.Server/Controllers/UserController.cs +++ b/Oqtane.Server/Controllers/UserController.cs @@ -11,33 +11,82 @@ namespace Oqtane.Controllers [Route("{site}/api/[controller]")] public class UserController : Controller { - private readonly IUserRepository users; - private readonly ISiteUserRepository siteusers; - private readonly UserManager identityUserManager; - private readonly SignInManager identitySignInManager; + private readonly IUserRepository Users; + private readonly ISiteUserRepository SiteUsers; + private readonly IRoleRepository Roles; + private readonly IUserRoleRepository UserRoles; + private readonly UserManager IdentityUserManager; + private readonly SignInManager IdentitySignInManager; - public UserController(IUserRepository Users, ISiteUserRepository SiteUsers, UserManager IdentityUserManager, SignInManager IdentitySignInManager) + public UserController(IUserRepository Users, ISiteUserRepository SiteUsers, IRoleRepository Roles, IUserRoleRepository UserRoles, UserManager IdentityUserManager, SignInManager IdentitySignInManager) { - users = Users; - siteusers = SiteUsers; - identityUserManager = IdentityUserManager; - identitySignInManager = IdentitySignInManager; + this.Users = Users; + this.SiteUsers = SiteUsers; + this.Roles = Roles; + this.UserRoles = UserRoles; + this.IdentityUserManager = IdentityUserManager; + this.IdentitySignInManager = IdentitySignInManager; } - // GET: api/ + // GET: api/?siteid=x [HttpGet] - public IEnumerable Get() + public IEnumerable Get(string siteid) { - return users.GetUsers(); + List users = new List(); + IEnumerable siteusers = SiteUsers.GetSiteUsers(int.Parse(siteid)); + foreach (SiteUser siteuser in siteusers) + { + User user = siteuser.User; + user.SiteId = siteuser.SiteId; + users.Add(user); + } + return users; } - // GET api//5 + // GET api//5?siteid=x [HttpGet("{id}")] - public User Get(int id) + public User Get(int id, string siteid) { - return users.GetUser(id); + User user = Users.GetUser(id); + if (user != null) + { + user.SiteId = int.Parse(siteid); + if (!user.IsSuperUser) // super users are part of every site by default + { + SiteUser siteuser = SiteUsers.GetSiteUser(user.SiteId, id); + if (siteuser != null) + { + user.Roles = GetUserRoles(user.UserId, user.SiteId); + } + } + } + return user; } - + + // GET api//name/x?siteid=x + [HttpGet("name/{name}")] + public User Get(string name, string siteid) + { + User user = Users.GetUser(name); + if (user != null) + { + user.SiteId = int.Parse(siteid); + if (!user.IsSuperUser) // super users are part of every site by default + { + SiteUser siteuser = SiteUsers.GetSiteUser(user.SiteId, user.UserId); + if (siteuser != null) + { + user.Roles = GetUserRoles(user.UserId, user.SiteId); + } + else + { + user = null; + } + } + } + return user; + } + // POST api/ [HttpPost] public async Task Post([FromBody] User User) @@ -46,21 +95,55 @@ namespace Oqtane.Controllers if (ModelState.IsValid) { - IdentityUser identityuser = await identityUserManager.FindByNameAsync(User.Username); + IdentityUser identityuser = await IdentityUserManager.FindByNameAsync(User.Username); if (identityuser == null) { identityuser = new IdentityUser(); identityuser.UserName = User.Username; identityuser.Email = User.Username; - var result = await identityUserManager.CreateAsync(identityuser, User.Password); + var result = await IdentityUserManager.CreateAsync(identityuser, User.Password); if (result.Succeeded) { - user = users.AddUser(User); - SiteUser SiteUser = new SiteUser(); - SiteUser.SiteId = User.SiteId; - SiteUser.UserId = user.UserId; - SiteUser.IsAuthorized = true; - siteusers.AddSiteUser(SiteUser); + user = Users.AddUser(User); + + SiteUser siteuser = new SiteUser(); + siteuser.SiteId = User.SiteId; + siteuser.UserId = user.UserId; + SiteUsers.AddSiteUser(siteuser); + + List roles = Roles.GetRoles(user.SiteId).Where(item => item.IsAutoAssigned == true).ToList(); + foreach (Role role in roles) + { + UserRole userrole = new UserRole(); + userrole.UserId = user.UserId; + userrole.RoleId = role.RoleId; + userrole.EffectiveDate = null; + userrole.ExpiryDate = null; + UserRoles.AddUserRole(userrole); + } + } + } + else + { + user = Users.GetUser(User.Username); + SiteUser siteuser = SiteUsers.GetSiteUser(User.SiteId, user.UserId); + if (siteuser == null) + { + siteuser = new SiteUser(); + siteuser.SiteId = User.SiteId; + siteuser.UserId = user.UserId; + SiteUsers.AddSiteUser(siteuser); + + List roles = Roles.GetRoles(User.SiteId).Where(item => item.IsAutoAssigned == true).ToList(); + foreach (Role role in roles) + { + UserRole userrole = new UserRole(); + userrole.UserId = user.UserId; + userrole.RoleId = role.RoleId; + userrole.EffectiveDate = null; + userrole.ExpiryDate = null; + UserRoles.AddUserRole(userrole); + } } } } @@ -74,23 +157,20 @@ namespace Oqtane.Controllers { if (ModelState.IsValid) { - User = users.UpdateUser(User); + User = Users.UpdateUser(User); } return User; } - // DELETE api//5 + // DELETE api//5?siteid=x [HttpDelete("{id}")] - public void Delete(int id) + public void Delete(int id, string siteid) { - users.DeleteUser(id); - } - - // GET api//name/x - [HttpGet("name/{name}")] - public User GetByName(string name) - { - return users.GetUser(name); + SiteUser siteuser = SiteUsers.GetSiteUser(id, int.Parse(siteid)); + if (siteuser != null) + { + SiteUsers.DeleteSiteUser(siteuser.SiteUserId); + } } // POST api//login @@ -101,21 +181,31 @@ namespace Oqtane.Controllers if (ModelState.IsValid) { - IdentityUser identityuser = await identityUserManager.FindByNameAsync(User.Username); + IdentityUser identityuser = await IdentityUserManager.FindByNameAsync(User.Username); if (identityuser != null) { - var result = await identitySignInManager.CheckPasswordSignInAsync(identityuser, User.Password, false); + var result = await IdentitySignInManager.CheckPasswordSignInAsync(identityuser, User.Password, false); if (result.Succeeded) { - user = users.GetUser(identityuser.UserName); + user = Users.GetUser(identityuser.UserName); if (user != null) { - SiteUser siteuser = siteusers.GetSiteUsers(User.SiteId, user.UserId).FirstOrDefault(); - if (siteuser.IsAuthorized) + if (!user.IsSuperUser) // super users are part of every site by default + { + SiteUser siteuser = SiteUsers.GetSiteUser(User.SiteId, user.UserId); + if (siteuser != null) + { + user.IsAuthenticated = true; + } + } + else { - await identitySignInManager.SignInAsync(identityuser, User.IsPersistent); user.IsAuthenticated = true; } + if (user.IsAuthenticated) + { + await IdentitySignInManager.SignInAsync(identityuser, User.IsPersistent); + } } } } @@ -128,7 +218,7 @@ namespace Oqtane.Controllers [HttpPost("logout")] public async Task Logout([FromBody] User User) { - await identitySignInManager.SignOutAsync(); + await IdentitySignInManager.SignOutAsync(); } // GET api//current @@ -137,5 +227,20 @@ namespace Oqtane.Controllers { return new User { Username = User.Identity.Name, IsAuthenticated = User.Identity.IsAuthenticated }; } + + private string GetUserRoles(int UserId, int SiteId) + { + string roles = ""; + IEnumerable userroles = UserRoles.GetUserRoles(UserId); + foreach (UserRole userrole in userroles) + { + if (userrole.Role.SiteId == SiteId) + { + roles += userrole.Role.Name + ";"; + } + } + if (roles != "") roles = ";" + roles; + return roles; + } } } diff --git a/Oqtane.Server/Controllers/UserRoleController.cs b/Oqtane.Server/Controllers/UserRoleController.cs new file mode 100644 index 00000000..8865e763 --- /dev/null +++ b/Oqtane.Server/Controllers/UserRoleController.cs @@ -0,0 +1,68 @@ +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc; +using Oqtane.Repository; +using Oqtane.Models; + +namespace Oqtane.Controllers +{ + [Route("{site}/api/[controller]")] + public class UserRoleController : Controller + { + private readonly IUserRoleRepository UserRoles; + + public UserRoleController(IUserRoleRepository UserRoles) + { + this.UserRoles = UserRoles; + } + + // GET: api/?userid=x + [HttpGet] + public IEnumerable Get(string userid) + { + if (userid == "") + { + return UserRoles.GetUserRoles(); + } + else + { + return UserRoles.GetUserRoles(int.Parse(userid)); + } + } + + // GET api//5 + [HttpGet("{id}")] + public UserRole Get(int id) + { + return UserRoles.GetUserRole(id); + } + + // POST api/ + [HttpPost] + public UserRole Post([FromBody] UserRole UserRole) + { + if (ModelState.IsValid) + { + UserRole = UserRoles.AddUserRole(UserRole); + } + return UserRole; + } + + // PUT api//5 + [HttpPut("{id}")] + public UserRole Put(int id, [FromBody] UserRole UserRole) + { + if (ModelState.IsValid) + { + UserRole = UserRoles.UpdateUserRole(UserRole); + } + return UserRole; + } + + // DELETE api//5 + [HttpDelete("{id}")] + public void Delete(int id) + { + UserRoles.DeleteUserRole(id); + } + } +} diff --git a/Oqtane.Server/Pages/Login.cshtml.cs b/Oqtane.Server/Pages/Login.cshtml.cs index eb8399e5..cc1877cc 100644 --- a/Oqtane.Server/Pages/Login.cshtml.cs +++ b/Oqtane.Server/Pages/Login.cshtml.cs @@ -46,12 +46,7 @@ namespace Oqtane.Pages await HttpContext.SignInAsync(IdentityConstants.ApplicationScheme, new ClaimsPrincipal(claimsIdentity), authProperties); } - string url = "~/"; - if (returnurl != "/") - { - url = Url.Content("~/" + returnurl); - } - return LocalRedirect(url); + return LocalRedirect(Url.Content("~" + returnurl)); } } } \ No newline at end of file diff --git a/Oqtane.Server/Pages/Logout.cshtml.cs b/Oqtane.Server/Pages/Logout.cshtml.cs index 95ec1a71..d976f39d 100644 --- a/Oqtane.Server/Pages/Logout.cshtml.cs +++ b/Oqtane.Server/Pages/Logout.cshtml.cs @@ -19,12 +19,7 @@ namespace Oqtane.Pages { await HttpContext.SignOutAsync(IdentityConstants.ApplicationScheme); - string url = "~/"; - if (returnurl != "/") - { - url = Url.Content("~/" + returnurl); - } - return LocalRedirect(url); + return LocalRedirect(Url.Content("~" + returnurl)); } } } \ No newline at end of file diff --git a/Oqtane.Server/Repository/AliasRepository.cs b/Oqtane.Server/Repository/AliasRepository.cs index 8595557c..1ebda180 100644 --- a/Oqtane.Server/Repository/AliasRepository.cs +++ b/Oqtane.Server/Repository/AliasRepository.cs @@ -22,12 +22,11 @@ namespace Oqtane.Repository { try { - IEnumerable aliases = _cache.GetOrCreate("aliases", entry => + return _cache.GetOrCreate("aliases", entry => { entry.SlidingExpiration = TimeSpan.FromMinutes(30); return db.Alias.ToList(); }); - return aliases; } catch { @@ -67,8 +66,7 @@ namespace Oqtane.Repository { try { - Alias alias = db.Alias.Find(AliasId); - return alias; + return db.Alias.Find(AliasId); } catch { diff --git a/Oqtane.Server/Repository/Context/TenantDBContext.cs b/Oqtane.Server/Repository/Context/TenantDBContext.cs index 3e0c1ca7..62c54b0d 100644 --- a/Oqtane.Server/Repository/Context/TenantDBContext.cs +++ b/Oqtane.Server/Repository/Context/TenantDBContext.cs @@ -12,6 +12,8 @@ namespace Oqtane.Repository public virtual DbSet Module { get; set; } public virtual DbSet User { get; set; } public virtual DbSet SiteUser { get; set; } + public virtual DbSet Role { get; set; } + public virtual DbSet UserRole { get; set; } public virtual DbSet Setting { get; set; } public TenantDBContext(ITenantResolver TenantResolver, IHttpContextAccessor accessor) : base(TenantResolver, accessor) diff --git a/Oqtane.Server/Repository/Interfaces/IRoleRepository.cs b/Oqtane.Server/Repository/Interfaces/IRoleRepository.cs new file mode 100644 index 00000000..61541336 --- /dev/null +++ b/Oqtane.Server/Repository/Interfaces/IRoleRepository.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using Oqtane.Models; + +namespace Oqtane.Repository +{ + public interface IRoleRepository + { + IEnumerable GetRoles(); + IEnumerable GetRoles(int SiteId); + Role AddRole(Role Role); + Role UpdateRole(Role Role); + Role GetRole(int RoleId); + void DeleteRole(int RoleId); + } +} diff --git a/Oqtane.Server/Repository/Interfaces/ISiteUserRepository.cs b/Oqtane.Server/Repository/Interfaces/ISiteUserRepository.cs index 747f95e6..67beb7d2 100644 --- a/Oqtane.Server/Repository/Interfaces/ISiteUserRepository.cs +++ b/Oqtane.Server/Repository/Interfaces/ISiteUserRepository.cs @@ -6,10 +6,11 @@ namespace Oqtane.Repository public interface ISiteUserRepository { IEnumerable GetSiteUsers(); - IEnumerable GetSiteUsers(int SiteId, int UserId); + IEnumerable GetSiteUsers(int SiteId); SiteUser AddSiteUser(SiteUser SiteUser); SiteUser UpdateSiteUser(SiteUser SiteUser); SiteUser GetSiteUser(int SiteUserId); + SiteUser GetSiteUser(int SiteId, int UserId); void DeleteSiteUser(int SiteUserId); } } diff --git a/Oqtane.Server/Repository/Interfaces/IUserRoleRepository.cs b/Oqtane.Server/Repository/Interfaces/IUserRoleRepository.cs new file mode 100644 index 00000000..fad2f850 --- /dev/null +++ b/Oqtane.Server/Repository/Interfaces/IUserRoleRepository.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using Oqtane.Models; + +namespace Oqtane.Repository +{ + public interface IUserRoleRepository + { + IEnumerable GetUserRoles(); + IEnumerable GetUserRoles(int UserId); + UserRole AddUserRole(UserRole UserRole); + UserRole UpdateUserRole(UserRole UserRole); + UserRole GetUserRole(int UserRoleId); + void DeleteUserRole(int UserRoleId); + } +} diff --git a/Oqtane.Server/Repository/ModuleDefinitionRepository.cs b/Oqtane.Server/Repository/ModuleDefinitionRepository.cs index ca612fae..d626ead3 100644 --- a/Oqtane.Server/Repository/ModuleDefinitionRepository.cs +++ b/Oqtane.Server/Repository/ModuleDefinitionRepository.cs @@ -10,26 +10,26 @@ namespace Oqtane.Repository { public class ModuleDefinitionRepository : IModuleDefinitionRepository { - private readonly List moduledefinitions; + private readonly List ModuleDefinitions; public ModuleDefinitionRepository() { - moduledefinitions = LoadModuleDefinitions(); + ModuleDefinitions = LoadModuleDefinitions(); } private List LoadModuleDefinitions() { - List moduledefinitions = new List(); + List ModuleDefinitions = new List(); // iterate through Oqtane module assemblies Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies() .Where(item => item.FullName.StartsWith("Oqtane.") || item.FullName.Contains(".Module.")).ToArray(); foreach (Assembly assembly in assemblies) { - moduledefinitions = LoadModuleDefinitionsFromAssembly(moduledefinitions, assembly); + ModuleDefinitions = LoadModuleDefinitionsFromAssembly(ModuleDefinitions, assembly); } - return moduledefinitions; + return ModuleDefinitions; } private List LoadModuleDefinitionsFromAssembly(List moduledefinitions, Assembly assembly) @@ -115,7 +115,7 @@ namespace Oqtane.Repository public IEnumerable GetModuleDefinitions() { - return moduledefinitions; + return ModuleDefinitions; } } diff --git a/Oqtane.Server/Repository/ModuleRepository.cs b/Oqtane.Server/Repository/ModuleRepository.cs index 76c07605..b8248f40 100644 --- a/Oqtane.Server/Repository/ModuleRepository.cs +++ b/Oqtane.Server/Repository/ModuleRepository.cs @@ -73,8 +73,7 @@ namespace Oqtane.Repository { try { - Module Module = db.Module.Find(ModuleId); - return Module; + return db.Module.Find(ModuleId); } catch { diff --git a/Oqtane.Server/Repository/PageModuleRepository.cs b/Oqtane.Server/Repository/PageModuleRepository.cs index 00c0fd0b..f626c472 100644 --- a/Oqtane.Server/Repository/PageModuleRepository.cs +++ b/Oqtane.Server/Repository/PageModuleRepository.cs @@ -29,10 +29,9 @@ namespace Oqtane.Repository { try { - List pagemodules = db.PageModule.Where(item => item.PageId == PageId) - .Include(item => item.Module) + return db.PageModule.Where(item => item.PageId == PageId) + .Include(item => item.Module) // eager load modules .ToList(); - return pagemodules; } catch { @@ -72,8 +71,8 @@ namespace Oqtane.Repository { try { - PageModule PageModule = db.PageModule.Find(PageModuleId); - return PageModule; + return db.PageModule.Include(item => item.Module) // eager load modules + .SingleOrDefault(item => item.PageModuleId == PageModuleId); } catch { diff --git a/Oqtane.Server/Repository/PageRepository.cs b/Oqtane.Server/Repository/PageRepository.cs index 33612112..fcf11a98 100644 --- a/Oqtane.Server/Repository/PageRepository.cs +++ b/Oqtane.Server/Repository/PageRepository.cs @@ -70,8 +70,7 @@ namespace Oqtane.Repository { try { - Page Page = db.Page.Find(PageId); - return Page; + return db.Page.Find(PageId); } catch { diff --git a/Oqtane.Server/Repository/RoleRepository.cs b/Oqtane.Server/Repository/RoleRepository.cs new file mode 100644 index 00000000..afb1fc09 --- /dev/null +++ b/Oqtane.Server/Repository/RoleRepository.cs @@ -0,0 +1,95 @@ +using Microsoft.EntityFrameworkCore; +using System.Collections.Generic; +using System.Linq; +using Oqtane.Models; + +namespace Oqtane.Repository +{ + public class RoleRepository : IRoleRepository + { + private TenantDBContext db; + + public RoleRepository(TenantDBContext context) + { + db = context; + } + + public IEnumerable GetRoles() + { + try + { + return db.Role.ToList(); + } + catch + { + throw; + } + } + + public IEnumerable GetRoles(int SiteId) + { + try + { + return db.Role.Where(item => item.SiteId == SiteId).ToList(); + } + catch + { + throw; + } + } + + public Role AddRole(Role Role) + { + try + { + db.Role.Add(Role); + db.SaveChanges(); + return Role; + } + catch + { + throw; + } + } + + public Role UpdateRole(Role Role) + { + try + { + db.Entry(Role).State = EntityState.Modified; + db.SaveChanges(); + return Role; + } + catch + { + throw; + } + } + + public Role GetRole(int RoleId) + { + try + { + return db.Role.Find(RoleId); + } + catch + { + throw; + } + } + + public void DeleteRole(int RoleId) + { + try + { + Role Role = db.Role.Find(RoleId); + db.Role.Remove(Role); + db.SaveChanges(); + } + catch + { + throw; + } + } + } +} diff --git a/Oqtane.Server/Repository/SettingRepository.cs b/Oqtane.Server/Repository/SettingRepository.cs index b5a17bd5..a12040ec 100644 --- a/Oqtane.Server/Repository/SettingRepository.cs +++ b/Oqtane.Server/Repository/SettingRepository.cs @@ -59,8 +59,7 @@ namespace Oqtane.Repository { try { - Setting Setting = db.Setting.Find(SettingId); - return Setting; + return db.Setting.Find(SettingId); } catch { diff --git a/Oqtane.Server/Repository/SiteRepository.cs b/Oqtane.Server/Repository/SiteRepository.cs index bba65d22..88ec72df 100644 --- a/Oqtane.Server/Repository/SiteRepository.cs +++ b/Oqtane.Server/Repository/SiteRepository.cs @@ -58,8 +58,7 @@ namespace Oqtane.Repository { try { - Site site = db.Site.Find(siteId); - return site; + return db.Site.Find(siteId); } catch { diff --git a/Oqtane.Server/Repository/SiteUserRepository.cs b/Oqtane.Server/Repository/SiteUserRepository.cs index 81fa29f5..f0209b48 100644 --- a/Oqtane.Server/Repository/SiteUserRepository.cs +++ b/Oqtane.Server/Repository/SiteUserRepository.cs @@ -25,16 +25,13 @@ namespace Oqtane.Repository throw; } } - public IEnumerable GetSiteUsers(int SiteId, int UserId) + public IEnumerable GetSiteUsers(int SiteId) { try { - List siteusers = db.SiteUser.Where(item => item.SiteId == SiteId).ToList(); - if (UserId != -1) - { - siteusers = siteusers.Where(item => item.UserId == UserId).ToList(); - } - return siteusers; + return db.SiteUser.Where(item => item.SiteId == SiteId) + .Include(item => item.User) // eager load users + .ToList(); } catch { @@ -74,8 +71,20 @@ namespace Oqtane.Repository { try { - SiteUser SiteUser = db.SiteUser.Find(SiteUserId); - return SiteUser; + return db.SiteUser.Include(item => item.User) // eager load users + .SingleOrDefault(item => item.SiteUserId == SiteUserId); + } + catch + { + throw; + } + } + + public SiteUser GetSiteUser(int SiteId, int UserId) + { + try + { + return db.SiteUser.Where(item => item.SiteId == SiteId).Where(item => item.UserId == UserId).FirstOrDefault(); } catch { diff --git a/Oqtane.Server/Repository/TenantRepository.cs b/Oqtane.Server/Repository/TenantRepository.cs index d21d8f2e..58d7df30 100644 --- a/Oqtane.Server/Repository/TenantRepository.cs +++ b/Oqtane.Server/Repository/TenantRepository.cs @@ -23,12 +23,11 @@ namespace Oqtane.Repository { try { - IEnumerable tenants = _cache.GetOrCreate("tenants", entry => + return _cache.GetOrCreate("tenants", entry => { entry.SlidingExpiration = TimeSpan.FromMinutes(30); return db.Tenant.ToList(); }); - return tenants; } catch { @@ -68,8 +67,7 @@ namespace Oqtane.Repository { try { - Tenant tenant = db.Tenant.Find(TenantId); - return tenant; + return db.Tenant.Find(TenantId); } catch { diff --git a/Oqtane.Server/Repository/ThemeRepository.cs b/Oqtane.Server/Repository/ThemeRepository.cs index 9eb25aa6..1b7ead1e 100644 --- a/Oqtane.Server/Repository/ThemeRepository.cs +++ b/Oqtane.Server/Repository/ThemeRepository.cs @@ -10,26 +10,26 @@ namespace Oqtane.Repository { public class ThemeRepository : IThemeRepository { - private readonly List themes; + private readonly List Themes; public ThemeRepository() { - themes = LoadThemes(); + Themes = LoadThemes(); } private List LoadThemes() { - List themes = new List(); + List Themes = new List(); // iterate through Oqtane theme assemblies Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies() .Where(item => item.FullName.StartsWith("Oqtane.") || item.FullName.Contains(".Theme.")).ToArray(); foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { - themes = LoadThemesFromAssembly(themes, assembly); + Themes = LoadThemesFromAssembly(Themes, assembly); } - return themes; + return Themes; } private List LoadThemesFromAssembly(List themes, Assembly assembly) @@ -120,7 +120,7 @@ namespace Oqtane.Repository public IEnumerable GetThemes() { - return themes; + return Themes; } } } diff --git a/Oqtane.Server/Repository/UserRepository.cs b/Oqtane.Server/Repository/UserRepository.cs index 6b863e37..c31b73d4 100644 --- a/Oqtane.Server/Repository/UserRepository.cs +++ b/Oqtane.Server/Repository/UserRepository.cs @@ -58,8 +58,7 @@ namespace Oqtane.Repository { try { - User user = db.User.Find(userId); - return user; + return db.User.Find(userId); } catch { @@ -71,8 +70,7 @@ namespace Oqtane.Repository { try { - User user = db.User.Where(item => item.Username == Username).FirstOrDefault(); - return user; + return db.User.Where(item => item.Username == Username).FirstOrDefault(); } catch { diff --git a/Oqtane.Server/Repository/UserRoleRepository.cs b/Oqtane.Server/Repository/UserRoleRepository.cs new file mode 100644 index 00000000..8e095ffb --- /dev/null +++ b/Oqtane.Server/Repository/UserRoleRepository.cs @@ -0,0 +1,97 @@ +using Microsoft.EntityFrameworkCore; +using System.Collections.Generic; +using System.Linq; +using Oqtane.Models; + +namespace Oqtane.Repository +{ + public class UserRoleRepository : IUserRoleRepository + { + private TenantDBContext db; + + public UserRoleRepository(TenantDBContext context) + { + db = context; + } + + public IEnumerable GetUserRoles() + { + try + { + return db.UserRole.ToList(); + } + catch + { + throw; + } + } + public IEnumerable GetUserRoles(int UserId) + { + try + { + return db.UserRole.Where(item => item.UserId == UserId) + .Include(item => item.Role) // eager load roles + .ToList(); + } + catch + { + throw; + } + } + + public UserRole AddUserRole(UserRole UserRole) + { + try + { + db.UserRole.Add(UserRole); + db.SaveChanges(); + return UserRole; + } + catch + { + throw; + } + } + + public UserRole UpdateUserRole(UserRole UserRole) + { + try + { + db.Entry(UserRole).State = EntityState.Modified; + db.SaveChanges(); + return UserRole; + } + catch + { + throw; + } + } + + public UserRole GetUserRole(int UserRoleId) + { + try + { + return db.UserRole.Include(item => item.Role) // eager load roles + .SingleOrDefault(item => item.UserRoleId == UserRoleId); + } + catch + { + throw; + } + } + + public void DeleteUserRole(int UserRoleId) + { + try + { + UserRole UserRole = db.UserRole.Find(UserRoleId); + db.UserRole.Remove(UserRole); + db.SaveChanges(); + } + catch + { + throw; + } + } + } +} diff --git a/Oqtane.Server/Scripts/00.00.00.sql b/Oqtane.Server/Scripts/00.00.00.sql index c5d950d8..d047d5f8 100644 --- a/Oqtane.Server/Scripts/00.00.00.sql +++ b/Oqtane.Server/Scripts/00.00.00.sql @@ -99,7 +99,6 @@ CREATE TABLE [dbo].[User]( [UserId] [int] IDENTITY(1,1) NOT NULL, [Username] [nvarchar](256) NOT NULL, [DisplayName] [nvarchar](50) NOT NULL, - [Roles] [nvarchar](50) NOT NULL, [IsSuperUser] [bit] NOT NULL, [CreatedBy] [nvarchar](256) NOT NULL, [CreatedOn] [datetime] NOT NULL, @@ -116,7 +115,6 @@ CREATE TABLE [dbo].[SiteUser]( [SiteUserId] [int] IDENTITY(1,1) NOT NULL, [SiteId] [int] NOT NULL, [UserId] [int] NOT NULL, - [IsAuthorized] [bit] NOT NULL, [CreatedBy] [nvarchar](256) NOT NULL, [CreatedOn] [datetime] NOT NULL, [ModifiedBy] [nvarchar](256) NOT NULL, @@ -128,6 +126,40 @@ CREATE TABLE [dbo].[SiteUser]( ) GO +CREATE TABLE [dbo].[Role]( + [RoleId] [int] IDENTITY(1,1) NOT NULL, + [SiteId] [int] NOT NULL, + [Name] [nvarchar](256) NOT NULL, + [Description] [nvarchar](50) NOT NULL, + [IsAutoAssigned] [bit] NOT NULL, + [CreatedBy] [nvarchar](256) NOT NULL, + [CreatedOn] [datetime] NOT NULL, + [ModifiedBy] [nvarchar](256) NOT NULL, + [ModifiedOn] [datetime] NOT NULL, + CONSTRAINT [PK_Role] PRIMARY KEY CLUSTERED + ( + [RoleId] ASC + ) +) +GO + +CREATE TABLE [dbo].[UserRole]( + [UserRoleId] [int] IDENTITY(1,1) NOT NULL, + [UserId] [int] NOT NULL, + [RoleId] [int] NOT NULL, + [EffectiveDate] [datetime] NULL, + [ExpiryDate] [datetime] NULL, + [CreatedBy] [nvarchar](256) NOT NULL, + [CreatedOn] [datetime] NOT NULL, + [ModifiedBy] [nvarchar](256) NOT NULL, + [ModifiedOn] [datetime] NOT NULL, + CONSTRAINT [PK_UserRole] PRIMARY KEY CLUSTERED + ( + [UserRoleId] ASC + ) +) +GO + CREATE TABLE [dbo].[Setting]( [SettingId] [int] IDENTITY(1,1) NOT NULL, [EntityName] [nvarchar](50) NOT NULL, @@ -260,6 +292,9 @@ GO INSERT [dbo].[Page] ([PageId], [SiteId], [Name], [Path], [ThemeType], [Icon], [Panes], [ViewPermissions], [EditPermissions], [ParentId], [Order], [IsNavigation], [LayoutType], [CreatedBy], [CreatedOn], [ModifiedBy], [ModifiedOn]) VALUES (15, 2, N'Register', N'register', N'Oqtane.Client.Themes.Theme2.Theme2, Oqtane.Client', N'', N'Top;Bottom', N'All Users', N'Administrators', NULL, 1, 0, N'', '', getdate(), '', getdate()) GO +INSERT [dbo].[Page] ([PageId], [SiteId], [Name], [Path], [ThemeType], [Icon], [Panes], [ViewPermissions], [EditPermissions], [ParentId], [Order], [IsNavigation], [LayoutType], [CreatedBy], [CreatedOn], [ModifiedBy], [ModifiedOn]) +VALUES (16, 1, N'Role Management', N'admin/roles', N'Oqtane.Client.Themes.Theme2.Theme2, Oqtane.Client', N'', N'Top;Bottom', N'Administrators', N'Administrators', 4, 5, 1, N'', '', getdate(), '', getdate()) +GO SET IDENTITY_INSERT [dbo].[Page] OFF GO @@ -322,6 +357,9 @@ GO INSERT [dbo].[Module] ([ModuleId], [SiteId], [ModuleDefinitionName], [ViewPermissions], [EditPermissions], [CreatedBy], [CreatedOn], [ModifiedBy], [ModifiedOn]) VALUES (19, 2, N'Oqtane.Client.Modules.Admin.Register, Oqtane.Client', N'All Users', N'Administrators', '', getdate(), '', getdate()) GO +INSERT [dbo].[Module] ([ModuleId], [SiteId], [ModuleDefinitionName], [ViewPermissions], [EditPermissions], [CreatedBy], [CreatedOn], [ModifiedBy], [ModifiedOn]) +VALUES (20, 1, N'Oqtane.Client.Modules.Admin.Roles, Oqtane.Client', N'Administrators', N'Administrators', '', getdate(), '', getdate()) +GO SET IDENTITY_INSERT [dbo].[Module] OFF GO @@ -384,6 +422,9 @@ GO INSERT [dbo].[PageModule] ([PageModuleId], [PageId], [ModuleId], [Title], [Pane], [Order], [ContainerType], [CreatedBy], [CreatedOn], [ModifiedBy], [ModifiedOn]) VALUES (19, 15, 19, N'Register', N'Top', 0, N'Oqtane.Client.Themes.Theme2.Container2, Oqtane.Client', '', getdate(), '', getdate()) GO +INSERT [dbo].[PageModule] ([PageModuleId], [PageId], [ModuleId], [Title], [Pane], [Order], [ContainerType], [CreatedBy], [CreatedOn], [ModifiedBy], [ModifiedOn]) +VALUES (20, 16, 20, N'Role Management', N'Top', 0, N'Oqtane.Client.Themes.Theme2.Container2, Oqtane.Client', '', getdate(), '', getdate()) +GO SET IDENTITY_INSERT [dbo].[PageModule] OFF GO @@ -410,4 +451,20 @@ GO SET IDENTITY_INSERT [dbo].[HtmlText] OFF GO +SET IDENTITY_INSERT [dbo].[Role] ON +GO +INSERT [dbo].[Role] ([RoleId], [SiteId], [Name], [Description], [IsAutoAssigned], [CreatedBy], [CreatedOn], [ModifiedBy], [ModifiedOn]) +VALUES (1, 1, N'Administrators', N'Site Administrators', 0, '', getdate(), '', getdate()) +GO +INSERT [dbo].[Role] ([RoleId], [SiteId], [Name], [Description], [IsAutoAssigned], [CreatedBy], [CreatedOn], [ModifiedBy], [ModifiedOn]) +VALUES (2, 1, N'Registered Users', N'Registered Users', 1, '', getdate(), '', getdate()) +GO +INSERT [dbo].[Role] ([RoleId], [SiteId], [Name], [Description], [IsAutoAssigned], [CreatedBy], [CreatedOn], [ModifiedBy], [ModifiedOn]) +VALUES (3, 2, N'Administrators', N'Site Administrators', 0, '', getdate(), '', getdate()) +GO +INSERT [dbo].[Role] ([RoleId], [SiteId], [Name], [Description], [IsAutoAssigned], [CreatedBy], [CreatedOn], [ModifiedBy], [ModifiedOn]) +VALUES (4, 2, N'Registered Users', N'Registered Users', 1, '', getdate(), '', getdate()) +GO +SET IDENTITY_INSERT [dbo].[Role] OFF +GO diff --git a/Oqtane.Server/Startup.cs b/Oqtane.Server/Startup.cs index 434ec1da..ebf18df8 100644 --- a/Oqtane.Server/Startup.cs +++ b/Oqtane.Server/Startup.cs @@ -79,6 +79,8 @@ namespace Oqtane.Server services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddSingleton(); @@ -157,6 +159,8 @@ namespace Oqtane.Server services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); + services.AddTransient(); services.AddTransient(); // dynamically register module services, contexts, and repository classes @@ -305,6 +309,8 @@ namespace Oqtane.Server services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); + services.AddTransient(); services.AddTransient(); // dynamically register module services, contexts, and repository classes diff --git a/Oqtane.Shared/Models/Role.cs b/Oqtane.Shared/Models/Role.cs new file mode 100644 index 00000000..f892cabc --- /dev/null +++ b/Oqtane.Shared/Models/Role.cs @@ -0,0 +1,18 @@ +using System; + +namespace Oqtane.Models +{ + public class Role : IAuditable + { + public int RoleId { get; set; } + public int SiteId { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public bool IsAutoAssigned { get; set; } + + public string CreatedBy { get; set; } + public DateTime CreatedOn { get; set; } + public string ModifiedBy { get; set; } + public DateTime ModifiedOn { get; set; } + } +} diff --git a/Oqtane.Shared/Models/SiteUser.cs b/Oqtane.Shared/Models/SiteUser.cs index cfae5d2f..15e23c41 100644 --- a/Oqtane.Shared/Models/SiteUser.cs +++ b/Oqtane.Shared/Models/SiteUser.cs @@ -7,11 +7,12 @@ namespace Oqtane.Models public int SiteUserId { get; set; } public int SiteId { get; set; } public int UserId { get; set; } - public bool IsAuthorized { get; set; } public string CreatedBy { get; set; } public DateTime CreatedOn { get; set; } public string ModifiedBy { get; set; } public DateTime ModifiedOn { get; set; } + + public User User { get; set; } } } diff --git a/Oqtane.Shared/Models/User.cs b/Oqtane.Shared/Models/User.cs index 6c759a74..e57f765f 100644 --- a/Oqtane.Shared/Models/User.cs +++ b/Oqtane.Shared/Models/User.cs @@ -8,21 +8,23 @@ namespace Oqtane.Models public int UserId { get; set; } public string Username { get; set; } public string DisplayName { get; set; } - public string Roles { get; set; } public bool IsSuperUser { get; set; } + [NotMapped] + public int SiteId { get; set; } + [NotMapped] + public string Roles { get; set; } public string CreatedBy { get; set; } public DateTime CreatedOn { get; set; } public string ModifiedBy { get; set; } public DateTime ModifiedOn { get; set; } - [NotMapped] - public int SiteId { get; set; } [NotMapped] public string Password { get; set; } [NotMapped] public bool IsAuthenticated { get; set; } [NotMapped] public bool IsPersistent { get; set; } + } } diff --git a/Oqtane.Shared/Models/UserRole.cs b/Oqtane.Shared/Models/UserRole.cs new file mode 100644 index 00000000..3ed423bb --- /dev/null +++ b/Oqtane.Shared/Models/UserRole.cs @@ -0,0 +1,20 @@ +using System; + +namespace Oqtane.Models +{ + public class UserRole : IAuditable + { + public int UserRoleId { get; set; } + public int UserId { get; set; } + public int RoleId { get; set; } + public DateTime? EffectiveDate { get; set; } + public DateTime? ExpiryDate { get; set; } + + public string CreatedBy { get; set; } + public DateTime CreatedOn { get; set; } + public string ModifiedBy { get; set; } + public DateTime ModifiedOn { get; set; } + + public Role Role { get; set; } + } +}