Add permissions for downloading LeafInput

This commit is contained in:
2020-08-08 21:43:12 -04:00
parent 2716b9bfb4
commit 5dfc65a83a
9 changed files with 109 additions and 51 deletions
+36 -10
View File
@@ -5,6 +5,7 @@ using LeafWeb.Core.Entities;
using LeafWeb.Core.Utility; using LeafWeb.Core.Utility;
using LeafWeb.WebCms.Models; using LeafWeb.WebCms.Models;
using LeafWeb.WebCms.Utility; using LeafWeb.WebCms.Utility;
using Microsoft.Ajax.Utilities;
using Umbraco.Web.Mvc; using Umbraco.Web.Mvc;
namespace LeafWeb.WebCms.Controllers namespace LeafWeb.WebCms.Controllers
@@ -29,13 +30,31 @@ namespace LeafWeb.WebCms.Controllers
[MemberAuthorize(AllowGroup = "Authenticated,Administrator")] [MemberAuthorize(AllowGroup = "Authenticated,Administrator")]
public ActionResult Input(int id) public ActionResult Input(int id)
{ {
return GetInputZip(id); var leafInput = DataService.GetLeafInput(id);
// check leafinput email matches current user
if (!Permissions.IsCurrentUserAdministrator() &&
!leafInput.DoesBelongToUser(HttpContext.User.Identity.Name))
{
return View("PermissionDenied");
}
return GetInputZip(leafInput);
} }
[MemberAuthorize(AllowGroup = "Authenticated,Administrator")] [MemberAuthorize(AllowGroup = "Authenticated,Administrator")]
public ActionResult OutputToUser(int id) public ActionResult OutputToUser(int id)
{ {
return GetOutputZip(id, LeafOutputFileType.ToUser); var leafInput = DataService.GetLeafInput(id);
// check leafinput email matches current user
if (!Permissions.IsCurrentUserAdministrator() &&
!leafInput.DoesBelongToUser(HttpContext.User.Identity.Name))
{
return View("PermissionDenied");
}
return GetOutputZip(leafInput, LeafOutputFileType.ToUser);
} }
[MemberAuthorize(AllowGroup = "Administrator")] [MemberAuthorize(AllowGroup = "Administrator")]
@@ -44,42 +63,49 @@ namespace LeafWeb.WebCms.Controllers
return GetOutputZip(id, LeafOutputFileType.NotToUser); return GetOutputZip(id, LeafOutputFileType.NotToUser);
} }
[MemberAuthorize(AllowGroup = "Authenticated,Administrator")] [MemberAuthorize(AllowGroup = "Administrator")]
public ActionResult OutputCleanedInput(int id) public ActionResult OutputCleanedInput(int id)
{ {
return GetOutputZip(id, LeafOutputFileType.CleanedInput); return GetOutputZip(id, LeafOutputFileType.CleanedInput);
} }
[MemberAuthorize(AllowGroup = "Authenticated,Administrator")] [MemberAuthorize(AllowGroup = "Administrator")]
public ActionResult ResultsInputZip(LeafDataQuery query) public ActionResult ResultsInputZip(LeafDataQuery query)
{ {
return GetResults(query, LeafInput.GetInputFilesZip, $"LeafWeb_{DateTime.Now:yyyy-dd-MM--HH-mm-ss}_Input.zip"); return GetResults(query, LeafInput.GetInputFilesZip, $"LeafWeb_{DateTime.Now:yyyy-dd-MM--HH-mm-ss}_Input.zip");
} }
[MemberAuthorize(AllowGroup = "Authenticated,Administrator")] [MemberAuthorize(AllowGroup = "Administrator")]
public ActionResult ResultsOutputZip(LeafDataQuery query) public ActionResult ResultsOutputZip(LeafDataQuery query)
{ {
return GetResults(query, LeafInput.GetOutputFilesZip_ToUser, $"LeafWeb_{DateTime.Now:yyyy-dd-MM--HH-mm-ss}_Output.zip"); return GetResults(query, LeafInput.GetOutputFilesZip_ToUser, $"LeafWeb_{DateTime.Now:yyyy-dd-MM--HH-mm-ss}_Output.zip");
} }
private ActionResult GetOutputZip(int id, LeafOutputFileType type) private ActionResult GetOutputZip(int id, LeafOutputFileType type)
{ => GetOutputZip(DataService.GetLeafInput(id), type);
var leafInput = DataService.GetLeafInput(id);
private ActionResult GetOutputZip(LeafInput leafInput, LeafOutputFileType type)
{
if (leafInput == null) if (leafInput == null)
return View("DownloadNotFound"); return View("DownloadNotFound");
var zip = leafInput.GetOutputFileZip(type); var zip = leafInput.GetOutputFileZip(type);
var filename = $"{leafInput.Identifier.FilterValidFilename()}_{type}.zip"; var suffix =
type == LeafOutputFileType.ToUser
? "_Output"
: $"_Output_{type}";
var filename = $"{leafInput.Identifier.FilterValidFilename()}{suffix}.zip";
return new FileContentResult(zip, "application/zip") { FileDownloadName = filename }; return new FileContentResult(zip, "application/zip") { FileDownloadName = filename };
} }
private ActionResult GetInputZip(int id) private ActionResult GetInputZip(int id)
{ => GetInputZip(DataService.GetLeafInput(id));
var leafInput = DataService.GetLeafInput(id);
private ActionResult GetInputZip(LeafInput leafInput)
{
if (leafInput == null) if (leafInput == null)
return View("DownloadNotFound"); return View("DownloadNotFound");
-1
View File
@@ -59,7 +59,6 @@ namespace LeafWeb.WebCms.Controllers
return View(viewModel); return View(viewModel);
} }
public ActionResult Recent() public ActionResult Recent()
{ {
var dateThreshold = DateTime.Today.Subtract(TimeSpan.FromDays(90)); var dateThreshold = DateTime.Today.Subtract(TimeSpan.FromDays(90));
+20
View File
@@ -0,0 +1,20 @@
using System;
using LeafWeb.Core.Entities;
using Umbraco.Web.Security;
namespace LeafWeb.WebCms.Utility
{
public static class Permissions
{
public static bool IsCurrentUserAdministrator()
{
var memberShipHelper = new MembershipHelper(Umbraco.Web.UmbracoContext.Current);
return memberShipHelper.IsMemberAuthorized(allowGroups: new[] {"Administrator"});
}
public static bool DoesBelongToUser(this LeafInput leafInput, string username)
{
return string.Equals(leafInput.Email, username, StringComparison.OrdinalIgnoreCase);
}
}
}
@@ -40,7 +40,7 @@ else
null, null,
new {id="register-member"})) new {id="register-member"}))
{ {
@Html.ValidationSummary(true) @Html.ValidationSummary(false)
<ul class="d-none"> <ul class="d-none">
@foreach (var ms in ViewData.ModelState) @foreach (var ms in ViewData.ModelState)
{ {
+7 -13
View File
@@ -1,5 +1,8 @@
@using LeafWeb.WebCms.Utility @using LeafWeb.WebCms.Utility
@model LeafInputDetails @model LeafInputDetails
@{
var username = HttpContext.Current.User.Identity.Name;
}
<div class="row pb-3"> <div class="row pb-3">
@@ -10,6 +13,8 @@
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="fa fa-download"></span> Download <span class="fa fa-download"></span> Download
</button> </button>
@if (string.Equals(Model.Email, username, StringComparison.OrdinalIgnoreCase))
{
<div class="dropdown-menu" aria-labelledby="downloadButton"> <div class="dropdown-menu" aria-labelledby="downloadButton">
<a href="@Url.Action("Input", "Download", new {id = Model.LeafInputId})" <a href="@Url.Action("Input", "Download", new {id = Model.LeafInputId})"
class="dropdown-item"> class="dropdown-item">
@@ -17,9 +22,10 @@
</a> </a>
<a href="@Url.Action("OutputToUser", "Download", new {id = Model.LeafInputId})" <a href="@Url.Action("OutputToUser", "Download", new {id = Model.LeafInputId})"
class="dropdown-item @if (!Model.HasOutputFiles) {<text> disabled</text>}"> class="dropdown-item @if (!Model.HasOutputFiles) {<text> disabled</text>}">
ToUser Output
</a> </a>
</div> </div>
}
</div> </div>
</div> </div>
@@ -40,15 +46,3 @@
} }
@Html.Partial("DisplayTemplates/_ChartLink", (int)item.LeafInputId, cssClass) @Html.Partial("DisplayTemplates/_ChartLink", (int)item.LeafInputId, cssClass)
} }
@helper CancelLink(LeafInputDetails_Admin item)
{
var cssClass
= CssClassUtil.CreateCssClassDataDictionary("btn", "btn-outline-secondary");
if (!item.IsCancellable)
{
cssClass.SetCssDisabled();
}
@Html.Partial("DisplayTemplates/_CancelForm", Tuple.Create(item.LeafInputId, item.Identifier), cssClass)
}
+2 -2
View File
@@ -35,10 +35,10 @@
</div> </div>
<div class="row justify-content-end"> <div class="row justify-content-end">
<div class="col-sm">@grid.PagerList()</div> <div class="col-sm">@grid.PagerList()</div>
<div class="col-sm col-lg-5 pl-4 pt-3 pt-sm-0"> @*<div class="col-sm col-lg-5 pl-4 pt-3 pt-sm-0">
<span class="pr-2">Download Results</span> <span class="pr-2">Download Results</span>
@DownloadResults() @DownloadResults()
</div> </div>*@
</div> </div>
} }
else else
@@ -0,0 +1,10 @@
@{
ViewBag.Title = "Permission Denied";
}
<h1>
@ViewBag.Title
</h1>
<p>Permission denied for requested resource. If you believe this to be in error please contact administrator, referencing the following url:</p>
<code>@Html.Raw(Request.Url)</code>
+17 -10
View File
@@ -1,8 +1,10 @@
@using LeafWeb.Core.Entities @using LeafWeb.Core.Entities
@using LeafWeb.WebCms.Utility @using LeafWeb.WebCms.Utility
@model LeafInput @model LeafInput
@{ @{
var admin = ViewData.ContainsKey("admin"); var admin = ViewData.ContainsKey("admin");
var username = HttpContext.Current.User.Identity.Name;
} }
<div class="btn-group text-nowrap" role="group"> <div class="btn-group text-nowrap" role="group">
@@ -15,13 +17,8 @@
@if (admin) @if (admin)
{ {
@Details_AdminLink(Model) @Details_AdminLink(Model)
}
else
{
@Details_ResultsLink(Model)
}
@ChartLink(Model) @ChartLink(Model)
@if (admin && Model.IsPending) if (Model.IsPending)
{ {
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
<h6 class="dropdown-header">Priority</h6> <h6 class="dropdown-header">Priority</h6>
@@ -29,7 +26,7 @@
<button class="dropdown-item @DisableItem(Model.PendingPriority == Priority.Normal)">@PriorityForm(Model, Priority.Normal)</button> <button class="dropdown-item @DisableItem(Model.PendingPriority == Priority.Normal)">@PriorityForm(Model, Priority.Normal)</button>
<button class="dropdown-item @DisableItem(Model.PendingPriority == Priority.Low)">@PriorityForm(Model, Priority.Low)</button> <button class="dropdown-item @DisableItem(Model.PendingPriority == Priority.Low)">@PriorityForm(Model, Priority.Low)</button>
} }
@if (admin && Model.IsCancellable) if (Model.IsCancellable)
{ {
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
@CancelLink(Model) @CancelLink(Model)
@@ -38,11 +35,21 @@
<h6 class="dropdown-header">Download</h6> <h6 class="dropdown-header">Download</h6>
@DownloadInput(Model) @DownloadInput(Model)
@DownloadOutputToUser(Model) @DownloadOutputToUser(Model)
@if (admin)
{
<div class="dropdown-divider"></div> <div class="dropdown-divider"></div>
@DeleteLink(Model) @DeleteLink(Model)
} }
else
{
@Details_ResultsLink(Model)
@ChartLink(Model)
if (string.Equals(Model.Email, username, StringComparison.OrdinalIgnoreCase))
{
<div class="dropdown-divider"></div>
<h6 class="dropdown-header">Download</h6>
@DownloadInput(Model)
@DownloadOutputToUser(Model)
}
}
</div> </div>
</div> </div>
</div> </div>
@@ -81,7 +88,7 @@
@helper DownloadOutputToUser(dynamic item) @helper DownloadOutputToUser(dynamic item)
{ {
<a href="@Url.Action("OutputToUser", "Download", new {id = item.Id})" class="dropdown-item @DisableItem(!item.HasOutputFiles)"> <a href="@Url.Action("OutputToUser", "Download", new {id = item.Id})" class="dropdown-item @DisableItem(!item.HasOutputFiles)">
<span class="fa fa-download"></span> ToUser <span class="fa fa-download"></span> Output
</a> </a>
} }
@helper DeleteLink(LeafInput item) @helper DeleteLink(LeafInput item)
+2
View File
@@ -1077,6 +1077,7 @@
<Content Include="Views\MacroPartials\ResultsDetails.cshtml" /> <Content Include="Views\MacroPartials\ResultsDetails.cshtml" />
<Content Include="Views\Shared\Boolean.cshtml" /> <Content Include="Views\Shared\Boolean.cshtml" />
<Content Include="Views\Shared\EditorTemplates\Checkbox.cshtml" /> <Content Include="Views\Shared\EditorTemplates\Checkbox.cshtml" />
<Content Include="Views\Shared\PermissionDenied.cshtml" />
<None Include="Web.Debug.config"> <None Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon> <DependentUpon>Web.config</DependentUpon>
</None> </None>
@@ -1143,6 +1144,7 @@
<Compile Include="Services\PiscalQueue\PiscalService.cs" /> <Compile Include="Services\PiscalQueue\PiscalService.cs" />
<Compile Include="Services\PiscalQueue\StartPending.cs" /> <Compile Include="Services\PiscalQueue\StartPending.cs" />
<Compile Include="Utility\NameValueCollectionUtil.cs" /> <Compile Include="Utility\NameValueCollectionUtil.cs" />
<Compile Include="Utility\Permissions.cs" />
<Compile Include="Utility\QueryFilter.cs" /> <Compile Include="Utility\QueryFilter.cs" />
<Compile Include="Utility\RequireRequestValueAttribute.cs" /> <Compile Include="Utility\RequireRequestValueAttribute.cs" />
<Compile Include="Utility\Validation.cs" /> <Compile Include="Utility\Validation.cs" />