Plugins have a base WebViewPage to inherit, this offers integration with various Disco services. Plugins can also add Authorization attributes to their Web Handlers and Controller Methods.
This commit is contained in:
@@ -8,7 +8,7 @@ using System.Web.Mvc;
|
||||
|
||||
namespace Disco.Services.Authorization
|
||||
{
|
||||
public class DiscoAuthorizeAllAttribute : AuthorizeAttribute
|
||||
public class DiscoAuthorizeAllAttribute : DiscoAuthorizeBaseAttribute
|
||||
{
|
||||
string[] authorizedClaims;
|
||||
|
||||
@@ -20,22 +20,17 @@ namespace Disco.Services.Authorization
|
||||
this.authorizedClaims = AuthorisedClaims;
|
||||
}
|
||||
|
||||
protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
|
||||
public override bool IsAuthorized(System.Web.HttpContextBase httpContext)
|
||||
{
|
||||
if (httpContext == null)
|
||||
throw new ArgumentNullException("httpContext");
|
||||
|
||||
var authToken = UserService.CurrentAuthorization;
|
||||
|
||||
if (authToken == null)
|
||||
if (Token == null)
|
||||
return false; // No Current User
|
||||
|
||||
return authToken.HasAll(authorizedClaims);
|
||||
return Token.HasAll(authorizedClaims);
|
||||
}
|
||||
|
||||
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
|
||||
public override string HandleUnauthorizedMessage()
|
||||
{
|
||||
filterContext.Result = new HttpUnauthorizedResult(AuthorizationToken.BuildRequireAllMessage(authorizedClaims));
|
||||
return AuthorizationToken.BuildRequireAllMessage(authorizedClaims);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ using System.Web.Mvc;
|
||||
|
||||
namespace Disco.Services.Authorization
|
||||
{
|
||||
public class DiscoAuthorizeAnyAttribute : AuthorizeAttribute
|
||||
public class DiscoAuthorizeAnyAttribute : DiscoAuthorizeBaseAttribute
|
||||
{
|
||||
string[] authorizedClaims;
|
||||
|
||||
@@ -20,22 +20,17 @@ namespace Disco.Services.Authorization
|
||||
this.authorizedClaims = AuthorisedClaims;
|
||||
}
|
||||
|
||||
protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
|
||||
public override bool IsAuthorized(System.Web.HttpContextBase httpContext)
|
||||
{
|
||||
if (httpContext == null)
|
||||
throw new ArgumentNullException("httpContext");
|
||||
|
||||
var authToken = UserService.CurrentAuthorization;
|
||||
|
||||
if (authToken == null)
|
||||
if (Token == null)
|
||||
return false; // No Current User
|
||||
|
||||
return authToken.HasAny(authorizedClaims);
|
||||
return Token.HasAny(authorizedClaims);
|
||||
}
|
||||
|
||||
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
|
||||
public override string HandleUnauthorizedMessage()
|
||||
{
|
||||
filterContext.Result = new HttpUnauthorizedResult(AuthorizationToken.BuildRequireAnyMessage(authorizedClaims));
|
||||
return AuthorizationToken.BuildRequireAnyMessage(authorizedClaims);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ using System.Web.Mvc;
|
||||
|
||||
namespace Disco.Services.Authorization
|
||||
{
|
||||
public class DiscoAuthorizeAttribute : AuthorizeAttribute
|
||||
public class DiscoAuthorizeAttribute : DiscoAuthorizeBaseAttribute
|
||||
{
|
||||
string authorizedClaim;
|
||||
|
||||
@@ -19,23 +19,18 @@ namespace Disco.Services.Authorization
|
||||
this.authorizedClaim = AuthorisedClaim;
|
||||
}
|
||||
|
||||
protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
|
||||
public override bool IsAuthorized(System.Web.HttpContextBase httpContext)
|
||||
{
|
||||
if (httpContext == null)
|
||||
throw new ArgumentNullException("httpContext");
|
||||
|
||||
var authToken = UserService.CurrentAuthorization;
|
||||
|
||||
if (authToken == null)
|
||||
if (Token == null)
|
||||
return false; // No Current User
|
||||
|
||||
if (authorizedClaim == null)
|
||||
return authToken.RoleTokens.Count > 0; // Just Authenticate - no Authorization (but require at least 1 role)
|
||||
return Token.RoleTokens.Count > 0; // Just Authenticate - no Authorization (but require at least 1 role)
|
||||
else
|
||||
return authToken.Has(authorizedClaim);
|
||||
return Token.Has(authorizedClaim);
|
||||
}
|
||||
|
||||
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
|
||||
public override string HandleUnauthorizedMessage()
|
||||
{
|
||||
string resultMessage;
|
||||
|
||||
@@ -47,7 +42,7 @@ namespace Disco.Services.Authorization
|
||||
else
|
||||
resultMessage = AuthorizationToken.BuildRequireMessage(authorizedClaim);
|
||||
|
||||
filterContext.Result = new HttpUnauthorizedResult(resultMessage);
|
||||
return resultMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
using Disco.Services.Users;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Disco.Services.Authorization
|
||||
{
|
||||
public abstract class DiscoAuthorizeBaseAttribute : AuthorizeAttribute
|
||||
{
|
||||
protected AuthorizationToken Token
|
||||
{
|
||||
get
|
||||
{
|
||||
return UserService.CurrentAuthorization;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract bool IsAuthorized(System.Web.HttpContextBase httpContext);
|
||||
public abstract string HandleUnauthorizedMessage();
|
||||
|
||||
protected sealed override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
|
||||
{
|
||||
if (httpContext == null)
|
||||
throw new ArgumentNullException("httpContext");
|
||||
|
||||
return IsAuthorized(httpContext);
|
||||
}
|
||||
|
||||
protected sealed override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
|
||||
{
|
||||
string resultMessage = HandleUnauthorizedMessage();
|
||||
|
||||
filterContext.Result = new HttpUnauthorizedResult(resultMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,6 +92,7 @@
|
||||
<Compile Include="Authorization\AccessDeniedException.cs" />
|
||||
<Compile Include="Authorization\AuthorizationToken.cs" />
|
||||
<Compile Include="Authorization\ClaimNavigatorItem.cs" />
|
||||
<Compile Include="Authorization\DiscoAuthorizeBaseAttribute.cs" />
|
||||
<Compile Include="Authorization\DiscoAuthorizeAllAttribute.cs" />
|
||||
<Compile Include="Authorization\DiscoAuthorizeAnyAttribute.cs" />
|
||||
<Compile Include="Authorization\DiscoAuthorizeAttribute.cs" />
|
||||
@@ -174,6 +175,8 @@
|
||||
<Compile Include="Plugins\PluginWebHandlerController.cs" />
|
||||
<Compile Include="Plugins\UninstallPluginTask.cs" />
|
||||
<Compile Include="Plugins\UnknownPluginException.cs" />
|
||||
<Compile Include="Plugins\WebHelper.cs" />
|
||||
<Compile Include="Plugins\PluginWebViewPage.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Tasks\ScheduledTask.cs" />
|
||||
<Compile Include="Tasks\ScheduledTasks.cs" />
|
||||
@@ -220,7 +223,7 @@
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties BuildVersion_UseGlobalSettings="False" BuildVersion_DetectChanges="False" BuildVersion_BuildAction="Both" BuildVersion_StartDate="2011/7/1" BuildVersion_BuildVersioningStyle="None.DeltaBaseYear.MonthAndDayStamp.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_UpdateFileVersion="True" />
|
||||
<UserProperties BuildVersion_UpdateFileVersion="True" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.DeltaBaseYear.MonthAndDayStamp.TimeStamp" BuildVersion_StartDate="2011/7/1" BuildVersion_BuildAction="Both" BuildVersion_DetectChanges="False" BuildVersion_UseGlobalSettings="False" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Disco.Services.Plugins.Features.UIExtension.Results
|
||||
{
|
||||
@@ -18,7 +19,7 @@ namespace Disco.Services.Plugins.Features.UIExtension.Results
|
||||
this.results = Results;
|
||||
}
|
||||
|
||||
public override void ExecuteResult<T>(System.Web.Mvc.WebViewPage<T> page)
|
||||
public override void ExecuteResult<T>(WebViewPage<T> page)
|
||||
{
|
||||
foreach (var result in this.results)
|
||||
{
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
using System;
|
||||
using Disco.Services.Web.Bundles;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
|
||||
namespace Disco.Services.Plugins.Features.UIExtension.Results
|
||||
{
|
||||
@@ -16,13 +19,13 @@ namespace Disco.Services.Plugins.Features.UIExtension.Results
|
||||
: base(Source)
|
||||
{
|
||||
this._resource = Resource;
|
||||
this._resourceUrl = HttpContext.Current.Request.RequestContext.DiscoPluginResourceUrl(Resource, false, Source.PluginManifest);
|
||||
this._resourceUrl = new HtmlString(Source.PluginManifest.WebResourceUrl(Resource));
|
||||
|
||||
var deferredBundles = HttpContext.Current.Items["Bundles.UIExtensionCss"] as List<HtmlString>;
|
||||
var deferredBundles = HttpContext.Current.Items[Bundle.UIExtensionCssKey] as List<HtmlString>;
|
||||
if (deferredBundles == null)
|
||||
{
|
||||
deferredBundles = new List<HtmlString>();
|
||||
HttpContext.Current.Items["Bundles.UIExtensionCss"] = deferredBundles;
|
||||
HttpContext.Current.Items[Bundle.UIExtensionCssKey] = deferredBundles;
|
||||
}
|
||||
if (!deferredBundles.Contains(this._resourceUrl))
|
||||
deferredBundles.Add(this._resourceUrl);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Disco.Services.Web.Bundles;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -17,16 +18,16 @@ namespace Disco.Services.Plugins.Features.UIExtension.Results
|
||||
: base(Source)
|
||||
{
|
||||
this._resource = Resource;
|
||||
this._resourceUrl = HttpContext.Current.Request.RequestContext.DiscoPluginResourceUrl(Resource, false, Source.PluginManifest);
|
||||
this._resourceUrl = new HtmlString(Source.PluginManifest.WebResourceUrl(Resource));
|
||||
this._placeInPageHead = PlaceInPageHead;
|
||||
|
||||
if (this._placeInPageHead)
|
||||
{
|
||||
var deferredBundles = HttpContext.Current.Items["Bundles.UIExtensionScripts"] as List<HtmlString>;
|
||||
var deferredBundles = HttpContext.Current.Items[Bundle.UIExtensionScriptsKey] as List<HtmlString>;
|
||||
if (deferredBundles == null)
|
||||
{
|
||||
deferredBundles = new List<HtmlString>();
|
||||
HttpContext.Current.Items["Bundles.UIExtensionScripts"] = deferredBundles;
|
||||
HttpContext.Current.Items[Bundle.UIExtensionScriptsKey] = deferredBundles;
|
||||
}
|
||||
if (!deferredBundles.Contains(this._resourceUrl))
|
||||
deferredBundles.Add(this._resourceUrl);
|
||||
|
||||
@@ -10,6 +10,7 @@ using System.Web.Routing;
|
||||
using System.Web;
|
||||
using System.Web.Mvc.Html;
|
||||
using System.Globalization;
|
||||
using Disco.Services.Web.Bundles;
|
||||
|
||||
namespace Disco.Services.Plugins
|
||||
{
|
||||
@@ -93,34 +94,13 @@ namespace Disco.Services.Plugins
|
||||
#endregion
|
||||
|
||||
#region Virtual Directories
|
||||
//public static string WebHandlerResource(this PluginManifest pluginManifest, string resourcePath, RequestContext requestContext)
|
||||
//{
|
||||
// var rootPath = WebHandlerRootUrl(pluginManifest, requestContext);
|
||||
// return string.Concat(rootPath, resourcePath);
|
||||
//}
|
||||
//public static string WebHandlerRootUrl(this PluginManifest pluginManifest, RequestContext requestContext)
|
||||
//{
|
||||
// var tempPath = pluginManifest.WebHandlerActionUrl(requestContext, "_");
|
||||
// return tempPath.Substring(0, tempPath.LastIndexOf(@"/") + 1);
|
||||
//}
|
||||
//public static string WebHandlerActionUrl(this PluginManifest pluginManifest, RequestContext requestContext, string PluginAction)
|
||||
//{
|
||||
// var routeValues = new RouteValueDictionary(new { PluginId = pluginManifest.Id, PluginAction = PluginAction });
|
||||
// return UrlHelper.GenerateUrl("Plugin", "PluginWebHandler", "Index", routeValues, RouteTable.Routes, requestContext, true);
|
||||
//}
|
||||
//public static string WebHandlerResourceUrl(this PluginManifest pluginManifest, RequestContext requestContext, string PluginAction)
|
||||
//{
|
||||
// var routeValues = new RouteValueDictionary(new { PluginId = pluginManifest.Id, PluginAction = PluginAction });
|
||||
|
||||
|
||||
|
||||
// return UrlHelper.GenerateUrl("Plugin", "PluginWebHandler", "Index", routeValues, RouteTable.Routes, requestContext, true);
|
||||
//}
|
||||
|
||||
[Obsolete("Inherit ViewPages from 'Disco.Services.Plugins.WebViewPage' instead.")]
|
||||
public static HtmlString DiscoPluginResourceUrl<T>(this WebViewPage<T> ViewPage, string Resource)
|
||||
{
|
||||
return ViewPage.DiscoPluginResourceUrl(Resource, false);
|
||||
}
|
||||
[Obsolete("Inherit ViewPages from 'Disco.Services.Plugins.WebViewPage' instead.")]
|
||||
public static HtmlString DiscoPluginResourceUrl<T>(this WebViewPage<T> ViewPage, string Resource, bool Download)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Resource))
|
||||
@@ -133,10 +113,12 @@ namespace Disco.Services.Plugins
|
||||
|
||||
return ViewPage.DiscoPluginResourceUrl(Resource, false, manifest);
|
||||
}
|
||||
[Obsolete("Inherit ViewPages from 'Disco.Services.Plugins.WebViewPage' instead.")]
|
||||
public static HtmlString DiscoPluginResourceUrl<T>(this WebViewPage<T> ViewPage, string Resource, bool Download, PluginManifest manifest)
|
||||
{
|
||||
return ViewPage.ViewContext.RequestContext.DiscoPluginResourceUrl(Resource, Download, manifest);
|
||||
}
|
||||
[Obsolete]
|
||||
public static HtmlString DiscoPluginResourceUrl(this RequestContext RequestContext, string Resource, bool Download, PluginManifest manifest)
|
||||
{
|
||||
var resourcePath = manifest.WebResourcePath(Resource);
|
||||
@@ -151,6 +133,7 @@ namespace Disco.Services.Plugins
|
||||
|
||||
return new HtmlString(pluginActionUrl);
|
||||
}
|
||||
[Obsolete("Inherit ViewPages from 'Disco.Services.Plugins.WebViewPage' instead.")]
|
||||
public static HtmlString DiscoPluginActionUrl<T>(this WebViewPage<T> ViewPage, string PluginAction)
|
||||
{
|
||||
if (string.IsNullOrEmpty(PluginAction))
|
||||
@@ -163,16 +146,19 @@ namespace Disco.Services.Plugins
|
||||
|
||||
return ViewPage.DiscoPluginActionUrl(PluginAction, manifest);
|
||||
}
|
||||
[Obsolete("Inherit ViewPages from 'Disco.Services.Plugins.WebViewPage' instead.")]
|
||||
public static HtmlString DiscoPluginActionUrl<T>(this WebViewPage<T> ViewPage, string PluginAction, PluginManifest manifest)
|
||||
{
|
||||
return ViewPage.ViewContext.RequestContext.DiscoPluginActionUrl(PluginAction, manifest);
|
||||
}
|
||||
[Obsolete("Inherit ViewPages from 'Disco.Services.Plugins.WebViewPage' instead.")]
|
||||
public static HtmlString DiscoPluginActionUrl(this RequestContext RequestContext, string PluginAction, PluginManifest manifest)
|
||||
{
|
||||
var routeValues = new RouteValueDictionary(new { PluginId = manifest.Id, PluginAction = PluginAction });
|
||||
string pluginActionUrl = UrlHelper.GenerateUrl("Plugin", null, null, routeValues, RouteTable.Routes, RequestContext, false);
|
||||
return new HtmlString(pluginActionUrl);
|
||||
}
|
||||
[Obsolete("Inherit ViewPages from 'Disco.Services.Plugins.WebViewPage' instead.")]
|
||||
public static HtmlString DiscoPluginConfigureUrl<T>(this WebViewPage<T> ViewPage)
|
||||
{
|
||||
// Find Plugin
|
||||
@@ -182,16 +168,19 @@ namespace Disco.Services.Plugins
|
||||
|
||||
return ViewPage.DiscoPluginConfigureUrl(manifest);
|
||||
}
|
||||
[Obsolete("Inherit ViewPages from 'Disco.Services.Plugins.WebViewPage' instead.")]
|
||||
public static HtmlString DiscoPluginConfigureUrl<T>(this WebViewPage<T> ViewPage, PluginManifest manifest)
|
||||
{
|
||||
return new HtmlString(ViewPage.ViewContext.RequestContext.DiscoPluginConfigureUrl(manifest));
|
||||
}
|
||||
[Obsolete]
|
||||
public static string DiscoPluginConfigureUrl(this RequestContext RequestContext, PluginManifest manifest)
|
||||
{
|
||||
var routeValues = new RouteValueDictionary(new { PluginId = manifest.Id });
|
||||
string pluginActionUrl = UrlHelper.GenerateUrl("Config_Plugins_Configure", null, null, routeValues, RouteTable.Routes, RequestContext, false);
|
||||
return pluginActionUrl;
|
||||
}
|
||||
[Obsolete("Inherit ViewPages from 'Disco.Services.Plugins.WebViewPage' instead.")]
|
||||
public static MvcForm DiscoPluginActionBeginForm<T>(this WebViewPage<T> ViewPage, string PluginAction, FormMethod method, IDictionary<string, object> htmlAttributes)
|
||||
{
|
||||
if (string.IsNullOrEmpty(PluginAction))
|
||||
@@ -207,19 +196,29 @@ namespace Disco.Services.Plugins
|
||||
|
||||
return ViewPage.FormHelper(pluginActionUrl, method, htmlAttributes);
|
||||
}
|
||||
[Obsolete("Inherit ViewPages from 'Disco.Services.Plugins.WebViewPage' instead.")]
|
||||
public static MvcForm DiscoPluginActionBeginForm<T>(this WebViewPage<T> ViewPage, string PluginAction, FormMethod method)
|
||||
{
|
||||
#pragma warning disable 618
|
||||
return ViewPage.DiscoPluginActionBeginForm(PluginAction, method, null);
|
||||
#pragma warning restore 618
|
||||
}
|
||||
[Obsolete("Inherit ViewPages from 'Disco.Services.Plugins.WebViewPage' instead.")]
|
||||
public static MvcForm DiscoPluginActionBeginForm<T>(this WebViewPage<T> ViewPage, string PluginAction, IDictionary<string, object> htmlAttributes)
|
||||
{
|
||||
#pragma warning disable 618
|
||||
return ViewPage.DiscoPluginActionBeginForm(PluginAction, FormMethod.Post, htmlAttributes);
|
||||
#pragma warning restore 618
|
||||
}
|
||||
[Obsolete("Inherit ViewPages from 'Disco.Services.Plugins.WebViewPage' instead.")]
|
||||
public static MvcForm DiscoPluginActionBeginForm<T>(this WebViewPage<T> ViewPage, string PluginAction)
|
||||
{
|
||||
#pragma warning disable 618
|
||||
return ViewPage.DiscoPluginActionBeginForm(PluginAction, FormMethod.Post, null);
|
||||
#pragma warning restore 618
|
||||
}
|
||||
|
||||
[Obsolete("Inherit ViewPages from 'Disco.Services.Plugins.WebViewPage' instead.")]
|
||||
private static MvcForm FormHelper<T>(this WebViewPage<T> ViewPage, string formAction, FormMethod method, IDictionary<string, object> htmlAttributes)
|
||||
{
|
||||
TagBuilder builder = new TagBuilder("form");
|
||||
@@ -244,7 +243,7 @@ namespace Disco.Services.Plugins
|
||||
return form;
|
||||
}
|
||||
|
||||
|
||||
[Obsolete("Inherit ViewPages from 'Disco.Services.Plugins.WebViewPage' instead.")]
|
||||
public static void DiscoPluginRegisterStylesheet<T>(this WebViewPage<T> ViewPage, string Resource)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Resource))
|
||||
@@ -257,10 +256,12 @@ namespace Disco.Services.Plugins
|
||||
|
||||
ViewPage.DiscoPluginRegisterStylesheet(Resource, manifest);
|
||||
}
|
||||
[Obsolete("Inherit ViewPages from 'Disco.Services.Plugins.WebViewPage' instead.")]
|
||||
public static void DiscoPluginRegisterStylesheet<T>(this WebViewPage<T> ViewPage, string Resource, PluginManifest manifest)
|
||||
{
|
||||
ViewPage.ViewContext.RequestContext.DiscoPluginRegisterStylesheet(Resource, manifest);
|
||||
}
|
||||
[Obsolete]
|
||||
public static void DiscoPluginRegisterStylesheet(this RequestContext RequestContext, string Resource, PluginManifest manifest)
|
||||
{
|
||||
var resourcePath = manifest.WebResourcePath(Resource);
|
||||
@@ -272,11 +273,11 @@ namespace Disco.Services.Plugins
|
||||
|
||||
HtmlString pluginResourceUrlHtml = new HtmlString(pluginResourceUrl);
|
||||
|
||||
var deferredBundles = RequestContext.HttpContext.Items["Bundles.UIExtensionCss"] as List<HtmlString>;
|
||||
var deferredBundles = RequestContext.HttpContext.Items[Bundle.UIExtensionCssKey] as List<HtmlString>;
|
||||
if (deferredBundles == null)
|
||||
{
|
||||
deferredBundles = new List<HtmlString>();
|
||||
HttpContext.Current.Items["Bundles.UIExtensionCss"] = deferredBundles;
|
||||
HttpContext.Current.Items[Bundle.UIExtensionCssKey] = deferredBundles;
|
||||
}
|
||||
if (!deferredBundles.Contains(pluginResourceUrlHtml))
|
||||
deferredBundles.Add(pluginResourceUrlHtml);
|
||||
@@ -285,6 +286,7 @@ namespace Disco.Services.Plugins
|
||||
#endregion
|
||||
|
||||
#region Request Caching
|
||||
[Obsolete]
|
||||
public static void SetCacheability(this PluginWebHandler Handler, TimeSpan CacheDuration)
|
||||
{
|
||||
var cache = Handler.HostController.Response.Cache;
|
||||
@@ -293,6 +295,7 @@ namespace Disco.Services.Plugins
|
||||
cache.SetValidUntilExpires(true);
|
||||
cache.SetCacheability(HttpCacheability.Private);
|
||||
}
|
||||
[Obsolete]
|
||||
public static void SetCacheabilityOff(this PluginWebHandler Handler)
|
||||
{
|
||||
var cache = Handler.HostController.Response.Cache;
|
||||
@@ -302,6 +305,7 @@ namespace Disco.Services.Plugins
|
||||
#endregion
|
||||
|
||||
#region Render Partial Compiled
|
||||
[Obsolete]
|
||||
private static void RenderPartialCompiledInternal(this HtmlHelper htmlHelper, Type viewType, object model, TextWriter writer)
|
||||
{
|
||||
if (writer == null)
|
||||
@@ -315,15 +319,19 @@ namespace Disco.Services.Plugins
|
||||
HttpContextBase httpContext = htmlHelper.ViewContext.HttpContext;
|
||||
page.ExecutePageHierarchy(new WebPageContext(httpContext, null, model), writer, null);
|
||||
}
|
||||
[Obsolete]
|
||||
public static MvcHtmlString PartialCompiled(this HtmlHelper htmlHelper, Type viewType)
|
||||
{
|
||||
return PartialCompiled(htmlHelper, viewType, null);
|
||||
}
|
||||
[Obsolete]
|
||||
public static MvcHtmlString PartialCompiled(this HtmlHelper htmlHelper, Type viewType, object model)
|
||||
{
|
||||
using (StringWriter writer = new StringWriter(CultureInfo.CurrentCulture))
|
||||
{
|
||||
#pragma warning disable 618
|
||||
htmlHelper.RenderPartialCompiledInternal(viewType, model, writer);
|
||||
#pragma warning restore 618
|
||||
return MvcHtmlString.Create(writer.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ using Disco.Data.Repository;
|
||||
using Disco.Services.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Disco.Services.Authorization;
|
||||
using System.Web.Routing;
|
||||
|
||||
namespace Disco.Services.Plugins
|
||||
{
|
||||
@@ -54,6 +56,8 @@ namespace Disco.Services.Plugins
|
||||
private Type ConfigurationHandlerType { get; set; }
|
||||
[JsonIgnore]
|
||||
private Type WebHandlerType { get; set; }
|
||||
[JsonIgnore]
|
||||
private DiscoAuthorizeBaseAttribute[] WebHandlerAuthorizers { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string PluginLocation { get; private set; }
|
||||
@@ -426,6 +430,18 @@ namespace Disco.Services.Plugins
|
||||
if (!typeof(PluginWebHandler).IsAssignableFrom(this.WebHandlerType))
|
||||
throw new ArgumentException("The Plugin WebHandlerType must inherit Disco.Services.Plugins.PluginWebHandler", "WebHandlerType");
|
||||
|
||||
// Determine WebHandler Authorize Attributes
|
||||
if (this.WebHandlerAuthorizers == null)
|
||||
{
|
||||
this.WebHandlerAuthorizers = this.WebHandlerType.GetCustomAttributes<DiscoAuthorizeBaseAttribute>(true).ToArray();
|
||||
}
|
||||
if (this.WebHandlerAuthorizers.Length > 0)
|
||||
{
|
||||
var attributeDenied = this.WebHandlerAuthorizers.FirstOrDefault(a => !a.IsAuthorized(HostController.HttpContext));
|
||||
if (attributeDenied != null)
|
||||
throw new AccessDeniedException(attributeDenied.HandleUnauthorizedMessage());
|
||||
}
|
||||
|
||||
var handler = (PluginWebHandler)Activator.CreateInstance(this.WebHandlerType);
|
||||
|
||||
handler.Manifest = this;
|
||||
@@ -480,6 +496,18 @@ namespace Disco.Services.Plugins
|
||||
|
||||
return new Tuple<string, string>(resourcePath, resourceHash.Item1);
|
||||
}
|
||||
public string WebResourceUrl(string Resource)
|
||||
{
|
||||
var resourcePath = this.WebResourcePath(Resource);
|
||||
|
||||
var url = UrlHelper.GenerateUrl("Plugin_Resources", null, null,
|
||||
new RouteValueDictionary(new Dictionary<string, object>() { { "PluginId", this.Id }, { "res", Resource } }),
|
||||
RouteTable.Routes, HttpContext.Current.Request.RequestContext, false);
|
||||
|
||||
url += string.Format("?v={0}", resourcePath.Item2);
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
public void LogException(Exception PluginException)
|
||||
{
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Disco.Data.Repository;
|
||||
using Disco.Models.Repository;
|
||||
using Disco.Services.Authorization;
|
||||
using Disco.Services.Users;
|
||||
using RazorGenerator.Mvc;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using RazorGenerator.Mvc;
|
||||
|
||||
namespace Disco.Services.Plugins
|
||||
{
|
||||
@@ -14,18 +16,103 @@ namespace Disco.Services.Plugins
|
||||
{
|
||||
public PluginManifest Manifest { get; set; }
|
||||
public Controller HostController { get; set; }
|
||||
protected DiscoDataContext Database;
|
||||
|
||||
public void OnActionExecuting()
|
||||
{
|
||||
this.Database = new DiscoDataContext();
|
||||
this.Database.Configuration.LazyLoadingEnabled = false;
|
||||
}
|
||||
|
||||
public abstract ActionResult ExecuteAction(string ActionName);
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
// Nothing in Base Class
|
||||
if (this.Database != null)
|
||||
{
|
||||
this.Database.Dispose();
|
||||
this.Database = null;
|
||||
}
|
||||
}
|
||||
|
||||
public AuthorizationToken Authorization
|
||||
{
|
||||
get
|
||||
{
|
||||
return UserService.CurrentAuthorization;
|
||||
}
|
||||
}
|
||||
|
||||
public User CurrentUser
|
||||
{
|
||||
get
|
||||
{
|
||||
return UserService.CurrentUser;
|
||||
}
|
||||
}
|
||||
|
||||
#region Caching
|
||||
|
||||
public void SetCacheability(TimeSpan CacheDuration)
|
||||
{
|
||||
var cache = this.HostController.Response.Cache;
|
||||
cache.SetOmitVaryStar(true);
|
||||
cache.SetExpires(DateTime.Now.Add(CacheDuration));
|
||||
cache.SetValidUntilExpires(true);
|
||||
cache.SetCacheability(HttpCacheability.Private);
|
||||
}
|
||||
public void SetCacheabilityOff()
|
||||
{
|
||||
var cache = this.HostController.Response.Cache;
|
||||
cache.SetExpires(DateTime.Now.AddDays(-1));
|
||||
cache.SetCacheability(HttpCacheability.NoCache);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Action Results
|
||||
|
||||
#region Compiled View
|
||||
private static string[] _viewFileNames = new string[] { "cshtml" };
|
||||
|
||||
public ActionResult CompiledView<ViewType>(object Model, bool UseDiscoLayout) where ViewType : WebViewPage
|
||||
{
|
||||
string layoutPath = UseDiscoLayout ? "~/Views/Shared/_Layout.cshtml" : null;
|
||||
|
||||
IView v = new PrecompiledMvcView(this.HostController.Request.Path, layoutPath, typeof(ViewType), false, _viewFileNames);
|
||||
|
||||
if (Model != null)
|
||||
this.HostController.ViewData.Model = Model;
|
||||
|
||||
return new ViewResult { View = v, ViewData = this.HostController.ViewData, TempData = this.HostController.TempData };
|
||||
}
|
||||
public ActionResult CompiledView<ViewType>(bool UseDiscoLayout) where ViewType : WebViewPage
|
||||
{
|
||||
return this.CompiledView<ViewType>(null, UseDiscoLayout);
|
||||
}
|
||||
public ActionResult CompiledView<ViewType>(object Model) where ViewType : WebViewPage
|
||||
{
|
||||
return this.CompiledView<ViewType>(Model, true);
|
||||
}
|
||||
public ActionResult CompiledView<ViewType>() where ViewType : WebViewPage
|
||||
{
|
||||
return this.CompiledView<ViewType>(false, true);
|
||||
}
|
||||
public ActionResult CompiledPartialView<ViewType>(object Model) where ViewType : WebViewPage
|
||||
{
|
||||
IView v = new PrecompiledMvcView(this.HostController.Request.Path, typeof(ViewType), false, _viewFileNames);
|
||||
|
||||
if (Model != null)
|
||||
this.HostController.ViewData.Model = Model;
|
||||
|
||||
return new PartialViewResult { View = v, ViewData = this.HostController.ViewData, TempData = this.HostController.TempData };
|
||||
}
|
||||
public ActionResult CompiledPartialView<ViewType>() where ViewType : WebViewPage
|
||||
{
|
||||
return this.CompiledView<ViewType>();
|
||||
}
|
||||
|
||||
[Obsolete("Use Generic Methods")]
|
||||
public ActionResult CompiledView(Type CompiledViewType, object Model, bool UseDiscoLayout)
|
||||
{
|
||||
string layoutPath = UseDiscoLayout ? "~/Views/Shared/_Layout.cshtml" : null;
|
||||
@@ -37,19 +124,23 @@ namespace Disco.Services.Plugins
|
||||
|
||||
return new ViewResult { View = v, ViewData = this.HostController.ViewData, TempData = this.HostController.TempData };
|
||||
}
|
||||
[Obsolete("Use Generic Methods")]
|
||||
public ActionResult CompiledView(Type CompiledViewType, bool UseDiscoLayout)
|
||||
{
|
||||
return this.CompiledView(CompiledViewType, null, UseDiscoLayout);
|
||||
}
|
||||
[Obsolete("Use Generic Methods")]
|
||||
public ActionResult CompiledView(Type CompiledViewType, object Model)
|
||||
{
|
||||
return this.CompiledView(CompiledViewType, Model, true);
|
||||
}
|
||||
public ActionResult CompiledView(Type CompiledViewType)
|
||||
[Obsolete("Use Generic Methods")]
|
||||
public ActionResult CompiledView(Type CompiledViewType)
|
||||
{
|
||||
return this.CompiledView(CompiledViewType, false, true);
|
||||
}
|
||||
public ActionResult CompiledPartialView(Type PartialCompiledViewType, object Model)
|
||||
[Obsolete("Use Generic Methods")]
|
||||
public ActionResult CompiledPartialView(Type PartialCompiledViewType, object Model)
|
||||
{
|
||||
IView v = new PrecompiledMvcView(this.HostController.Request.Path, PartialCompiledViewType, false, _viewFileNames);
|
||||
|
||||
@@ -58,7 +149,8 @@ namespace Disco.Services.Plugins
|
||||
|
||||
return new PartialViewResult { View = v, ViewData = this.HostController.ViewData, TempData = this.HostController.TempData };
|
||||
}
|
||||
public ActionResult CompiledPartialView(Type PartialCompiledViewType)
|
||||
[Obsolete("Use Generic Methods")]
|
||||
public ActionResult CompiledPartialView(Type PartialCompiledViewType)
|
||||
{
|
||||
return this.CompiledView(PartialCompiledViewType, null);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Disco.Services.Authorization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@@ -19,6 +20,14 @@ namespace Disco.Services.Plugins
|
||||
if (methodDescriptor == null)
|
||||
return this.HttpNotFound("Unknown Plugin Method");
|
||||
|
||||
// Authorize Method
|
||||
if (methodDescriptor.Authorizers.Length > 0)
|
||||
{
|
||||
var attributeDenied = methodDescriptor.Authorizers.FirstOrDefault(a => !a.IsAuthorized(HostController.HttpContext));
|
||||
if (attributeDenied != null)
|
||||
return new HttpUnauthorizedResult(attributeDenied.HandleUnauthorizedMessage());
|
||||
}
|
||||
|
||||
var methodParams = BuildMethodParameters(handlerType, methodDescriptor.MethodInfo, ActionName, this.HostController);
|
||||
|
||||
return (ActionResult)methodDescriptor.MethodInfo.Invoke(this, methodParams);
|
||||
@@ -63,24 +72,6 @@ namespace Disco.Services.Plugins
|
||||
parameterValue = methodParam.DefaultValue;
|
||||
|
||||
result[i] = parameterValue;
|
||||
|
||||
//var paramInstance = Activator.CreateInstance(methodParam.ParameterType);
|
||||
|
||||
//IModelBinder binder = ModelBinders.Binders.GetBinder(methodParam.ParameterType);
|
||||
//ModelBindingContext bindingContext = new ModelBindingContext
|
||||
//{
|
||||
// ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => paramInstance, methodParam.ParameterType),
|
||||
// ModelName = methodParam.Name,
|
||||
// ModelState = HostController.ModelState,
|
||||
// PropertyFilter = (p) => true,
|
||||
// ValueProvider = HostController.ValueProvider
|
||||
//};
|
||||
//binder.BindModel(HostController.ControllerContext, bindingContext);
|
||||
|
||||
//if (methodParam.HasDefaultValue && paramInstance == null)
|
||||
// paramInstance = methodParam.DefaultValue;
|
||||
|
||||
//result[i] = paramInstance;
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -102,7 +93,8 @@ namespace Disco.Services.Plugins
|
||||
var item = new WebHandlerCachedItem()
|
||||
{
|
||||
Method = method.Name,
|
||||
MethodInfo = method
|
||||
MethodInfo = method,
|
||||
Authorizers = method.GetCustomAttributes<DiscoAuthorizeBaseAttribute>().ToArray()
|
||||
};
|
||||
result.Add(item.Method.ToLower(), item);
|
||||
}
|
||||
@@ -115,6 +107,7 @@ namespace Disco.Services.Plugins
|
||||
{
|
||||
public string Method { get; set; }
|
||||
public MethodInfo MethodInfo { get; set; }
|
||||
public DiscoAuthorizeBaseAttribute[] Authorizers { get; set; }
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Disco.Services.Plugins
|
||||
{
|
||||
public abstract class PluginWebViewPage<T> : Disco.Services.Web.WebViewPage<T>
|
||||
{
|
||||
public WebHelper<T> Plugin { get; private set; }
|
||||
|
||||
public PluginWebViewPage()
|
||||
{
|
||||
var self = this.GetType();
|
||||
var manifest = Plugins.GetPlugin(self.Assembly);
|
||||
|
||||
this.Plugin = new WebHelper<T>(this, manifest);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
using Disco.Services.Web.Bundles;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Mvc.Html;
|
||||
using System.Web.Routing;
|
||||
using System.Web.WebPages;
|
||||
|
||||
namespace Disco.Services.Plugins
|
||||
{
|
||||
public class WebHelper<T>
|
||||
{
|
||||
private WebViewPage<T> ViewPage { get; set; }
|
||||
public PluginManifest Manifest { get; private set; }
|
||||
|
||||
public WebHelper(WebViewPage<T> ViewPage, PluginManifest manifest)
|
||||
{
|
||||
this.ViewPage = ViewPage;
|
||||
this.Manifest = manifest;
|
||||
}
|
||||
|
||||
#region Html Helpers
|
||||
|
||||
#region Form Helpers
|
||||
public MvcForm BeginForm(string Action, FormMethod Method, bool MultipartEncoding, IDictionary<string, object> HtmlAttributes)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Action))
|
||||
throw new ArgumentNullException("PluginAction");
|
||||
|
||||
var url = ActionUrl(Action);
|
||||
|
||||
return BeginForm_Helper(url.ToString(), Method, MultipartEncoding, HtmlAttributes);
|
||||
}
|
||||
public MvcForm BeginForm(string Action, FormMethod Method, bool MultipartEncoding)
|
||||
{
|
||||
return BeginForm(Action, Method, MultipartEncoding, null);
|
||||
}
|
||||
public MvcForm BeginForm(string Action, FormMethod Method, IDictionary<string, object> HtmlAttributes)
|
||||
{
|
||||
return BeginForm(Action, Method, false, HtmlAttributes);
|
||||
}
|
||||
public MvcForm BeginForm(string Action, FormMethod Method)
|
||||
{
|
||||
return BeginForm(Action, Method, false, null);
|
||||
}
|
||||
public MvcForm BeginForm(string Action)
|
||||
{
|
||||
return BeginForm(Action, FormMethod.Get, false, null);
|
||||
}
|
||||
private MvcForm BeginForm_Helper(string FormAction, FormMethod Method, bool MultipartEncoding, IDictionary<string, object> HtmlAttributes)
|
||||
{
|
||||
TagBuilder builder = new TagBuilder("form");
|
||||
builder.MergeAttributes(HtmlAttributes);
|
||||
if (MultipartEncoding)
|
||||
builder.MergeAttribute("enctype", "multipart/form-data");
|
||||
builder.MergeAttribute("action", FormAction);
|
||||
builder.MergeAttribute("method", HtmlHelper.GetFormMethodString(Method), true);
|
||||
|
||||
bool useClientValidation = ViewPage.ViewContext.ClientValidationEnabled && !ViewPage.ViewContext.UnobtrusiveJavaScriptEnabled;
|
||||
if (useClientValidation)
|
||||
{
|
||||
object lastFormNumber = ViewPage.ViewContext.HttpContext.Items["DiscoPluginLastFormNum"];
|
||||
int num = (lastFormNumber != null) ? (((int)lastFormNumber) + 1) : 1000;
|
||||
ViewPage.ViewContext.HttpContext.Items["DiscoPluginLastFormNum"] = num;
|
||||
|
||||
builder.GenerateId(string.Format(CultureInfo.InvariantCulture, "form{0}", new object[] { num }));
|
||||
}
|
||||
ViewPage.ViewContext.Writer.Write(builder.ToString(TagRenderMode.StartTag));
|
||||
MvcForm form = new MvcForm(ViewPage.ViewContext);
|
||||
if (useClientValidation)
|
||||
{
|
||||
ViewPage.ViewContext.FormContext.FormId = builder.Attributes["id"];
|
||||
}
|
||||
return form;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void IncludeStyleSheet(string Resource)
|
||||
{
|
||||
var url = ResourceUrl(Resource);
|
||||
|
||||
var deferredBundles = ViewPage.Context.Items[Bundle.UIExtensionCssKey] as List<HtmlString>;
|
||||
if (deferredBundles == null)
|
||||
{
|
||||
deferredBundles = new List<HtmlString>();
|
||||
ViewPage.Context.Items[Bundle.UIExtensionCssKey] = deferredBundles;
|
||||
}
|
||||
if (!deferredBundles.Contains(url))
|
||||
deferredBundles.Add(url);
|
||||
}
|
||||
public void IncludeJavaScript(string Resource)
|
||||
{
|
||||
var url = ResourceUrl(Resource);
|
||||
|
||||
var deferredBundles = ViewPage.Context.Items[Bundle.UIExtensionScriptsKey] as List<HtmlString>;
|
||||
if (deferredBundles == null)
|
||||
{
|
||||
deferredBundles = new List<HtmlString>();
|
||||
ViewPage.Context.Items[Bundle.UIExtensionScriptsKey] = deferredBundles;
|
||||
}
|
||||
if (!deferredBundles.Contains(url))
|
||||
deferredBundles.Add(url);
|
||||
}
|
||||
|
||||
public HtmlString PartialCompiled<ViewType>(object Model) where ViewType : WebViewPage
|
||||
{
|
||||
using (System.IO.StringWriter writer = new StringWriter(CultureInfo.CurrentCulture))
|
||||
{
|
||||
RenderPartialCompiled<ViewType>(writer, Model);
|
||||
|
||||
return new HtmlString(writer.ToString());
|
||||
}
|
||||
}
|
||||
public HtmlString PartialCompiled<ViewType>() where ViewType : WebViewPage
|
||||
{
|
||||
return PartialCompiled<ViewType>(null);
|
||||
}
|
||||
private void RenderPartialCompiled<ViewType>(TextWriter Writer, object Model)
|
||||
{
|
||||
if (Writer == null)
|
||||
throw new ArgumentNullException("Writer");
|
||||
WebViewPage page = Activator.CreateInstance(typeof(ViewType)) as WebViewPage;
|
||||
if (page == null)
|
||||
throw new InvalidOperationException("Invalid View Type");
|
||||
page.ViewContext = ViewPage.ViewContext;
|
||||
page.ViewData = new ViewDataDictionary(Model);
|
||||
page.InitHelpers();
|
||||
HttpContextBase httpContext = ViewPage.ViewContext.HttpContext;
|
||||
page.ExecutePageHierarchy(new WebPageContext(httpContext, null, Model), Writer, null);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Urls
|
||||
|
||||
public HtmlString ConfigurationUrl()
|
||||
{
|
||||
var url = GenerateUrl("Config_Plugins_Configure", new Dictionary<string, object>() { { "PluginId", Manifest.Id } });
|
||||
|
||||
return new HtmlString(url);
|
||||
}
|
||||
|
||||
public HtmlString ActionUrl(string Action)
|
||||
{
|
||||
var url = GenerateUrl("Plugin", new Dictionary<string, object>() { { "PluginId", Manifest.Id }, { "PluginAction", Action } });
|
||||
|
||||
return new HtmlString(url);
|
||||
}
|
||||
|
||||
public HtmlString ResourceUrl(string Resource)
|
||||
{
|
||||
return ResourceUrl(Resource, false);
|
||||
}
|
||||
|
||||
public HtmlString ResourceUrl(string Resource, bool Download)
|
||||
{
|
||||
var url = Manifest.WebResourceUrl(Resource);
|
||||
|
||||
if (Download)
|
||||
url += "&Download=true";
|
||||
|
||||
return new HtmlString(url);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helpers
|
||||
private string GenerateUrl(string RouteName, RouteValueDictionary RouteValues)
|
||||
{
|
||||
return UrlHelper.GenerateUrl(RouteName, null, null, RouteValues, RouteTable.Routes, ViewPage.Request.RequestContext, false);
|
||||
}
|
||||
private string GenerateUrl(string RouteName, IDictionary<string, object> RouteValues)
|
||||
{
|
||||
return GenerateUrl(RouteName, new RouteValueDictionary(RouteValues));
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,10 @@ namespace Disco.Services.Web.Bundles
|
||||
{
|
||||
public class Bundle
|
||||
{
|
||||
public const string DeferredKey = "Bundles.Deferred";
|
||||
public const string UIExtensionScriptsKey = "Bundles.UIExtensionScripts";
|
||||
public const string UIExtensionCssKey = "Bundles.UIExtensionCss";
|
||||
|
||||
private DateTime? _FileLastModified { get; set; }
|
||||
private string _FileHash { get; set; }
|
||||
private string _VersionUrl { get; set; }
|
||||
|
||||
@@ -16,21 +16,21 @@ namespace Disco.Services.Web
|
||||
// Ensure 'App-Relative' Url:
|
||||
BundleUrl = BundleUrl.StartsWith("~/") ? BundleUrl : (BundleUrl.StartsWith("/") ? string.Concat("~", BundleUrl) : string.Concat("~/", BundleUrl));
|
||||
|
||||
var deferredBundles = htmlHelper.ViewContext.HttpContext.Items["Bundles.Deferred"] as List<string>;
|
||||
var deferredBundles = htmlHelper.ViewContext.HttpContext.Items[Bundle.DeferredKey] as List<string>;
|
||||
if (deferredBundles == null)
|
||||
{
|
||||
deferredBundles = new List<string>();
|
||||
htmlHelper.ViewContext.HttpContext.Items["Bundles.Deferred"] = deferredBundles;
|
||||
htmlHelper.ViewContext.HttpContext.Items[Bundle.DeferredKey] = deferredBundles;
|
||||
}
|
||||
if (!deferredBundles.Contains(BundleUrl))
|
||||
deferredBundles.Add(BundleUrl);
|
||||
}
|
||||
public static HtmlString BundleRenderDeferred(this HtmlHelper htmlHelper)
|
||||
{
|
||||
var deferredBundles = htmlHelper.ViewContext.HttpContext.Items["Bundles.Deferred"] as List<string>;
|
||||
var deferredBundles = htmlHelper.ViewContext.HttpContext.Items[Bundle.DeferredKey] as List<string>;
|
||||
|
||||
var uiExtensionScripts = htmlHelper.ViewContext.HttpContext.Items["Bundles.UIExtensionScripts"] as List<HtmlString>;
|
||||
var uiExtensionCss = htmlHelper.ViewContext.HttpContext.Items["Bundles.UIExtensionCss"] as List<HtmlString>;
|
||||
var uiExtensionScripts = htmlHelper.ViewContext.HttpContext.Items[Bundle.UIExtensionScriptsKey] as List<HtmlString>;
|
||||
var uiExtensionCss = htmlHelper.ViewContext.HttpContext.Items[Bundle.UIExtensionCssKey] as List<HtmlString>;
|
||||
|
||||
if (deferredBundles != null || uiExtensionScripts != null || uiExtensionCss != null)
|
||||
{
|
||||
|
||||
@@ -34,16 +34,16 @@ namespace Disco.Web.Extensions
|
||||
{
|
||||
htmlHelper.RenderPartialCompiledInternal(viewType, model, htmlHelper.ViewContext.Writer);
|
||||
}
|
||||
public static MvcHtmlString PartialCompiled(this HtmlHelper htmlHelper, Type viewType)
|
||||
public static HtmlString PartialCompiled(this HtmlHelper htmlHelper, Type viewType)
|
||||
{
|
||||
return PartialCompiled(htmlHelper, viewType, null);
|
||||
}
|
||||
public static MvcHtmlString PartialCompiled(this HtmlHelper htmlHelper, Type viewType, object model)
|
||||
public static HtmlString PartialCompiled(this HtmlHelper htmlHelper, Type viewType, object model)
|
||||
{
|
||||
using (StringWriter writer = new StringWriter(CultureInfo.CurrentCulture))
|
||||
{
|
||||
htmlHelper.RenderPartialCompiledInternal(viewType, model, writer);
|
||||
return MvcHtmlString.Create(writer.ToString());
|
||||
return new HtmlString(writer.ToString());
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -213,6 +213,12 @@
|
||||
#UserDetailTab-Authorization .fancytree-container {
|
||||
border: none;
|
||||
}
|
||||
#UserDetailTab-Authorization span.fancytree-ico-c > span.fancytree-icon {
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACgklEQVQ4y5XSXUhTYRgH8OkItViSri676CIIupC6kIjIrQTNtLbhMEOLmjGsi1CiJoULZmEpW4l5RDehkR/owJNF+3DLliMd6GDWcrFNyNEceAarZZuc7d8xSNQzgx54Lt6v3/vxvBwAnI3Z0NDAJQiifWJiImgwGOIkScasVuuMWq2u3Dp3LTc15HJ5Zk9PzzhFURh79fpTr7avv4voHns/ORkJh8NQqVTX/wmIxWLZW5sNBNGt3tgvrareYzQavVqt9nt5eXnetkCTosk4OkrGWh485G7dqfXR4yvMlSCVSs9sC3z2frFOTU0vp7ur2TJe4XA4oNFoKrcFZl0us9lsodIBk44PpSaTCXa7vSwtoNPpAsxqOJ1OBAIBOhKJ0PF4nE6lUjQzTq+srKR8Ph/m5uaSS0tLLSygsbFx1ev1IhgMwuPxIBQKIRaLIZlM4m+4XC4olUp0dna+YwEKhSLh9/uxuLgIt9v9B4pGo6Bpeh1YOx1TSuj1+nEWcPfe/cSsy4fgtzB8vgX4F34wADbF/Pw81JoOGEgbG3jeVppY9jVD2XwbN+ol+BURwdBfC1ldPaL+ywi5ZTgvuYibshJQ5nNsQFxWmHCTRzHWvR88XjaeKrmgPnJw8AAPFcKdzANkQCrIQn4+H3fEWWyg4MixuOD4IdDTeWiTZyB3Nw+Wrkx4BjOxj5+LW1XZwDAHJw/vAjdnr5kNFBSsSipr0asqwcKbQlyqLkH91bOgZk6DaKlgfuAFzOpOwN5xCnw+37kOFBcX7ygqKrpWU1P7kylPqrXtGdqf6DAwMIjhkZcYGrHAZLbBYrGhT0/ixdBoSiQSfRUKhRKBQJDDSffr/id/A3fSz48XbZuBAAAAAElFTkSuQmCC') /*Images/Actions/locked.png*/;
|
||||
}
|
||||
#UserDetailTab-Authorization span.fancytree-ico-c.fancytree-selected > span.fancytree-icon {
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACWUlEQVQ4y6XRXWiSURgHcJsXa4WNNuuyiy6CoAupixERoXXhmljuxaJiFrVA1i72cVFCOSMt8rNt2YfGO5g5Z1NstWW+c4ZBq4QpqMkEbZDSCObAMprjdf90sIjxsgUdODd/zvmd5zwPCwDrf/aGB7q6utgmk8ngdruzVqt10eVyTWu1Wuk/AXK5vMpoNPpjsRgGbU8/9fbdH/J4PAuRSARKpfLKhoBYLG595nTCaDSZVjPp6TPbHQ5H0mAwfBeJRHXrAp0dna9JcqCguX2H/Xd+S625aLFYQBDE8XWBd+8/TI6Njc+vzcfGX4nLX4FOp5OuC0wGAlS53NzaPPAm2Gi32+H3+5tYJEl+pigKoVAIPp+PnpqaosPhMF1uHB2Px2mv14vya6VgMKhhHGN3d/dSMplENptFIpHA3NwcCoUCSqUSKqvScZVKBbPZHGQEFApFMZ1OI5PJIBqNrkD5fB40Ta8AlcrUajVsNpufEbh+42YxHEkh+/UbUqlZpGd/lAH8WTMzMzDd64d7NMAMDOobi/OpHqh6rqK9jcCvBQncQzK0Xm5DPn0BJ4lz6GgVIkedYAaamxqK0dEDePl4FziczehTsZGLs7BnNwdiwRac4lejvp6La83VzABv/8FF/qG9oD/WQS/fhNptHEw8rEJiuAo7ubXACAtH9m0Fu2YHxQzweEuEVIYnaiFmvQ04f1aItksi5KaP4ZFGjDB5GG/7j4LL5YYYgZYW2c/yiJbv6h/A0EvC4RjGiOsFnK4J+KgABmyjsDufL0skki8CgYCoXOLz+TWrwG+kXMkgQ6yv+QAAAABJRU5ErkJggg==') /*Images/Actions/unlocked.png*/;
|
||||
}
|
||||
#UserDetailTab-Authorization span.fancytree-node.fancytree-selected {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@@ -182,6 +182,14 @@
|
||||
border: none;
|
||||
}
|
||||
|
||||
span.fancytree-ico-c > span.fancytree-icon {
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACgklEQVQ4y5XSXUhTYRgH8OkItViSri676CIIupC6kIjIrQTNtLbhMEOLmjGsi1CiJoULZmEpW4l5RDehkR/owJNF+3DLliMd6GDWcrFNyNEceAarZZuc7d8xSNQzgx54Lt6v3/vxvBwAnI3Z0NDAJQiifWJiImgwGOIkScasVuuMWq2u3Dp3LTc15HJ5Zk9PzzhFURh79fpTr7avv4voHns/ORkJh8NQqVTX/wmIxWLZW5sNBNGt3tgvrareYzQavVqt9nt5eXnetkCTosk4OkrGWh485G7dqfXR4yvMlSCVSs9sC3z2frFOTU0vp7ur2TJe4XA4oNFoKrcFZl0us9lsodIBk44PpSaTCXa7vSwtoNPpAsxqOJ1OBAIBOhKJ0PF4nE6lUjQzTq+srKR8Ph/m5uaSS0tLLSygsbFx1ev1IhgMwuPxIBQKIRaLIZlM4m+4XC4olUp0dna+YwEKhSLh9/uxuLgIt9v9B4pGo6Bpeh1YOx1TSuj1+nEWcPfe/cSsy4fgtzB8vgX4F34wADbF/Pw81JoOGEgbG3jeVppY9jVD2XwbN+ol+BURwdBfC1ldPaL+ywi5ZTgvuYibshJQ5nNsQFxWmHCTRzHWvR88XjaeKrmgPnJw8AAPFcKdzANkQCrIQn4+H3fEWWyg4MixuOD4IdDTeWiTZyB3Nw+Wrkx4BjOxj5+LW1XZwDAHJw/vAjdnr5kNFBSsSipr0asqwcKbQlyqLkH91bOgZk6DaKlgfuAFzOpOwN5xCnw+37kOFBcX7ygqKrpWU1P7kylPqrXtGdqf6DAwMIjhkZcYGrHAZLbBYrGhT0/ixdBoSiQSfRUKhRKBQJDDSffr/id/A3fSz48XbZuBAAAAAElFTkSuQmCC') /*Images/Actions/locked.png*/;
|
||||
}
|
||||
|
||||
span.fancytree-ico-c.fancytree-selected > span.fancytree-icon {
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACWUlEQVQ4y6XRXWiSURgHcJsXa4WNNuuyiy6CoAupixERoXXhmljuxaJiFrVA1i72cVFCOSMt8rNt2YfGO5g5Z1NstWW+c4ZBq4QpqMkEbZDSCObAMprjdf90sIjxsgUdODd/zvmd5zwPCwDrf/aGB7q6utgmk8ngdruzVqt10eVyTWu1Wuk/AXK5vMpoNPpjsRgGbU8/9fbdH/J4PAuRSARKpfLKhoBYLG595nTCaDSZVjPp6TPbHQ5H0mAwfBeJRHXrAp0dna9JcqCguX2H/Xd+S625aLFYQBDE8XWBd+8/TI6Njc+vzcfGX4nLX4FOp5OuC0wGAlS53NzaPPAm2Gi32+H3+5tYJEl+pigKoVAIPp+PnpqaosPhMF1uHB2Px2mv14vya6VgMKhhHGN3d/dSMplENptFIpHA3NwcCoUCSqUSKqvScZVKBbPZHGQEFApFMZ1OI5PJIBqNrkD5fB40Ta8AlcrUajVsNpufEbh+42YxHEkh+/UbUqlZpGd/lAH8WTMzMzDd64d7NMAMDOobi/OpHqh6rqK9jcCvBQncQzK0Xm5DPn0BJ4lz6GgVIkedYAaamxqK0dEDePl4FziczehTsZGLs7BnNwdiwRac4lejvp6La83VzABv/8FF/qG9oD/WQS/fhNptHEw8rEJiuAo7ubXACAtH9m0Fu2YHxQzweEuEVIYnaiFmvQ04f1aItksi5KaP4ZFGjDB5GG/7j4LL5YYYgZYW2c/yiJbv6h/A0EvC4RjGiOsFnK4J+KgABmyjsDufL0skki8CgYCoXOLz+TWrwG+kXMkgQ6yv+QAAAABJRU5ErkJggg==') /*Images/Actions/unlocked.png*/;
|
||||
}
|
||||
|
||||
span.fancytree-node.fancytree-selected {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -11,7 +11,6 @@ namespace Disco.Web.Controllers
|
||||
{
|
||||
public partial class PluginWebHandlerController : Controller
|
||||
{
|
||||
[DiscoAuthorize(Claims.DiscoAdminAccount)]
|
||||
[OutputCache(Duration = 0, Location = System.Web.UI.OutputCacheLocation.None)]
|
||||
public virtual ActionResult Index(string PluginId, string PluginAction)
|
||||
{
|
||||
@@ -19,11 +18,20 @@ namespace Disco.Web.Controllers
|
||||
|
||||
if (manifest.HasWebHandler)
|
||||
{
|
||||
using (var pluginWebHandler = manifest.CreateWebHandler(this))
|
||||
try
|
||||
{
|
||||
return pluginWebHandler.ExecuteAction(PluginAction);
|
||||
using (var pluginWebHandler = manifest.CreateWebHandler(this))
|
||||
{
|
||||
pluginWebHandler.OnActionExecuting();
|
||||
return pluginWebHandler.ExecuteAction(PluginAction);
|
||||
}
|
||||
}
|
||||
catch (AccessDeniedException accessDeniedException)
|
||||
{
|
||||
return new HttpUnauthorizedResult(accessDeniedException.Message);
|
||||
}
|
||||
}
|
||||
|
||||
return HttpNotFound("Plugin has no Web Handler");
|
||||
}
|
||||
|
||||
@@ -42,7 +50,7 @@ namespace Disco.Web.Controllers
|
||||
{
|
||||
return HttpNotFound("Plugin Resource Not Found");
|
||||
}
|
||||
|
||||
|
||||
var pluginResourcePath = pluginResource.Item1;
|
||||
|
||||
var mimeType = Disco.BI.Interop.MimeTypes.ResolveMimeType(pluginResourcePath);
|
||||
|
||||
Reference in New Issue
Block a user