added API Management for managing site level entity permissions
This commit is contained in:
		
							
								
								
									
										120
									
								
								Oqtane.Server/Controllers/ApiController.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								Oqtane.Server/Controllers/ApiController.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,120 @@ | ||||
| using Microsoft.AspNetCore.Mvc; | ||||
| using Microsoft.AspNetCore.Authorization; | ||||
| using System.Collections.Generic; | ||||
| using Oqtane.Shared; | ||||
| using Oqtane.Models; | ||||
| using Oqtane.Infrastructure; | ||||
| using Oqtane.Enums; | ||||
| using System.Net; | ||||
| using Oqtane.Repository; | ||||
| using Oqtane.Extensions; | ||||
| using System.Reflection; | ||||
| using System; | ||||
| using System.Linq; | ||||
|  | ||||
| namespace Oqtane.Controllers | ||||
| { | ||||
|     [Route(ControllerRoutes.ApiRoute)] | ||||
|     public class ApiController : Controller | ||||
|     { | ||||
|         private readonly IPermissionRepository _permissions; | ||||
|         private readonly ILogManager _logger; | ||||
|         private readonly Alias _alias; | ||||
|  | ||||
|         public ApiController(IPermissionRepository permissions, ILogManager logger, ITenantManager tenantManager) | ||||
|         { | ||||
|             _permissions = permissions; | ||||
|             _logger = logger; | ||||
|             _alias = tenantManager.GetAlias(); | ||||
|         } | ||||
|  | ||||
|         // GET: api/<controller>?siteid=x | ||||
|         [HttpGet] | ||||
|         [Authorize(Roles = RoleNames.Admin)] | ||||
|         public List<Api> Get(string siteid) | ||||
|         { | ||||
|             int SiteId; | ||||
|             if (int.TryParse(siteid, out SiteId) && SiteId == _alias.SiteId) | ||||
|             { | ||||
|                 var apis = new List<Api>(); | ||||
|  | ||||
|                 var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies(); | ||||
|                 foreach (var assembly in assemblies) | ||||
|                 { | ||||
|                     // iterate controllers | ||||
|                     foreach (var type in assembly.GetTypes().Where(type => typeof(Controller).IsAssignableFrom(type))) | ||||
|                     { | ||||
|                         // iterate controller methods with authorize attribute | ||||
|                         var actions = type.GetMethods(BindingFlags.Public | BindingFlags.Instance) | ||||
|                             .Where(m => m.GetCustomAttributes<AuthorizeAttribute>().Any()); | ||||
|                         foreach(var action in actions) | ||||
|                         { | ||||
|                             // get policy | ||||
|                             var policy = action.GetCustomAttribute<AuthorizeAttribute>().Policy; | ||||
|                             if (!string.IsNullOrEmpty(policy) && policy.Contains(":") && !policy.Contains(Constants.RequireEntityId)) | ||||
|                             { | ||||
|                                 // parse policy | ||||
|                                 var segments = policy.Split(':'); | ||||
|                                 if (!apis.Any(item => item.EntityName == segments[0])) | ||||
|                                 { | ||||
|                                     apis.Add(new Api { SiteId = SiteId, EntityName = segments[0], Permissions = segments[1] }); | ||||
|                                 } | ||||
|                                 else | ||||
|                                 { | ||||
|                                     // concatenate permissions | ||||
|                                     var permissions = apis.SingleOrDefault(item => item.EntityName == segments[0]).Permissions; | ||||
|                                     if (!permissions.Split(',').Contains(segments[1])) | ||||
|                                     { | ||||
|                                         apis.SingleOrDefault(item => item.EntityName == segments[0]).Permissions += "," + segments[1]; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 return apis; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Api Get Attempt {SiteId}", siteid); | ||||
|                 HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden; | ||||
|                 return null; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // GET: api/<controller>/1/user | ||||
|         [HttpGet("{siteid}/{entityname}")] | ||||
|         [Authorize(Roles = RoleNames.Admin)] | ||||
|         public Api Get(int siteid, string entityname) | ||||
|         { | ||||
|             if (siteid == _alias.SiteId) | ||||
|             { | ||||
|                 return new Api { SiteId = siteid, EntityName = entityname, Permissions = _permissions.GetPermissions(siteid, entityname).EncodePermissions() }; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Api Get Attempt {SiteId} {EntityName}", siteid, entityname); | ||||
|                 HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden; | ||||
|                 return null; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // POST: api/<controller> | ||||
|         [HttpPost] | ||||
|         [Authorize(Roles = RoleNames.Admin)] | ||||
|         public void Post([FromBody] Api api) | ||||
|         { | ||||
|             if (ModelState.IsValid && api.SiteId == _alias.SiteId) | ||||
|             { | ||||
|                 _permissions.UpdatePermissions(api.SiteId, api.EntityName, -1, api.Permissions); | ||||
|                 _logger.Log(LogLevel.Information, this, LogFunction.Update, "Api Updated {Api}", api); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Api Post Attempt {Api}", api); | ||||
|                 HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -24,10 +24,11 @@ namespace Oqtane.Controllers | ||||
|             _syncManager = syncManager; | ||||
|             _logger = logger; | ||||
|             _alias = tenantManager.GetAlias(); | ||||
|     } | ||||
|         } | ||||
|  | ||||
|     // GET: api/<controller>?siteid=x | ||||
|     [HttpGet] | ||||
|         // GET: api/<controller>?siteid=x | ||||
|         [HttpGet] | ||||
|         [Authorize(Policy = $"{EntityNames.Profile}:{PermissionNames.Read}:{RoleNames.Registered}")] | ||||
|         public IEnumerable<Profile> Get(string siteid) | ||||
|         { | ||||
|             int SiteId; | ||||
| @ -45,6 +46,7 @@ namespace Oqtane.Controllers | ||||
|  | ||||
|         // GET api/<controller>/5 | ||||
|         [HttpGet("{id}")] | ||||
|         [Authorize(Policy = $"{EntityNames.Profile}:{PermissionNames.Read}:{RoleNames.Registered}")] | ||||
|         public Profile Get(int id) | ||||
|         { | ||||
|             var profile = _profiles.GetProfile(id); | ||||
| @ -62,7 +64,7 @@ namespace Oqtane.Controllers | ||||
|  | ||||
|         // POST api/<controller> | ||||
|         [HttpPost] | ||||
|         [Authorize(Roles = RoleNames.Admin)] | ||||
|         [Authorize(Policy = $"{EntityNames.Profile}:{PermissionNames.Write}:{RoleNames.Admin}")] | ||||
|         public Profile Post([FromBody] Profile profile) | ||||
|         { | ||||
|             if (ModelState.IsValid && profile.SiteId == _alias.SiteId) | ||||
| @ -82,7 +84,7 @@ namespace Oqtane.Controllers | ||||
|  | ||||
|         // PUT api/<controller>/5 | ||||
|         [HttpPut("{id}")] | ||||
|         [Authorize(Roles = RoleNames.Admin)] | ||||
|         [Authorize(Policy = $"{EntityNames.Profile}:{PermissionNames.Write}:{RoleNames.Admin}")] | ||||
|         public Profile Put(int id, [FromBody] Profile profile) | ||||
|         { | ||||
|             if (ModelState.IsValid && profile.SiteId == _alias.SiteId && _profiles.GetProfile(profile.ProfileId, false) != null) | ||||
| @ -102,7 +104,7 @@ namespace Oqtane.Controllers | ||||
|  | ||||
|         // DELETE api/<controller>/5 | ||||
|         [HttpDelete("{id}")] | ||||
|         [Authorize(Roles = RoleNames.Admin)] | ||||
|         [Authorize(Policy = $"{EntityNames.Profile}:{PermissionNames.Write}:{RoleNames.Admin}")] | ||||
|         public void Delete(int id) | ||||
|         { | ||||
|             var profile = _profiles.GetProfile(id); | ||||
|  | ||||
| @ -60,6 +60,9 @@ namespace Oqtane.Infrastructure | ||||
|                     case "3.2.1": | ||||
|                         Upgrade_3_2_1(tenant, scope); | ||||
|                         break; | ||||
|                     case "3.3.0": | ||||
|                         Upgrade_3_3_0(tenant, scope); | ||||
|                         break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @ -303,5 +306,46 @@ namespace Oqtane.Infrastructure | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private void Upgrade_3_3_0(Tenant tenant, IServiceScope scope) | ||||
|         { | ||||
|             var pageTemplates = new List<PageTemplate>(); | ||||
|  | ||||
|             pageTemplates.Add(new PageTemplate | ||||
|             { | ||||
|                 Name = "API Management", | ||||
|                 Parent = "Admin", | ||||
|                 Order = 35, | ||||
|                 Path = "admin/apis", | ||||
|                 Icon = Icons.CloudDownload,  | ||||
|                 IsNavigation = true, | ||||
|                 IsPersonalizable = false, | ||||
|                 PagePermissions = new List<Permission> | ||||
|                 { | ||||
|                     new Permission(PermissionNames.View, RoleNames.Admin, true), | ||||
|                     new Permission(PermissionNames.Edit, RoleNames.Admin, true) | ||||
|                 }.EncodePermissions(), | ||||
|                 PageTemplateModules = new List<PageTemplateModule> | ||||
|                 { | ||||
|                     new PageTemplateModule | ||||
|                     { | ||||
|                         ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Visitors.Index).ToModuleDefinitionName(), Title = "Visitor Management", Pane = PaneNames.Default, | ||||
|                         ModulePermissions = new List<Permission> | ||||
|                         { | ||||
|                             new Permission(PermissionNames.View, RoleNames.Admin, true), | ||||
|                             new Permission(PermissionNames.Edit, RoleNames.Admin, true) | ||||
|                         }.EncodePermissions(), | ||||
|                         Content = "" | ||||
|                     } | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             var pages = scope.ServiceProvider.GetRequiredService<IPageRepository>(); | ||||
|  | ||||
|             var sites = scope.ServiceProvider.GetRequiredService<ISiteRepository>(); | ||||
|             foreach (Site site in sites.GetSites().ToList()) | ||||
|             { | ||||
|                 sites.CreatePages(site, pageTemplates); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Shaun Walker
					Shaun Walker