Update: SignalR 2.0.3 Migration; Noticeboards

Migrate all SignalR 1.x Persistent Connections to SignalR 2.x Hubs.
Abstracts ScheduledTaskStatus with core interface and adds a Mock for
optional status reporting. Noticeboards rewritten (with new theme) to be
more resilient and accurate.
This commit is contained in:
Gary Sharp
2014-06-01 23:27:07 +10:00
parent f6fae26bc7
commit 4cd57f4a90
116 changed files with 9874 additions and 6462 deletions
@@ -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[Bundle.DeferredKey] as List<string>;
var deferredBundles = htmlHelper.ViewContext.HttpContext.Items[BundleTable.DeferredKey] as List<string>;
if (deferredBundles == null)
{
deferredBundles = new List<string>();
htmlHelper.ViewContext.HttpContext.Items[Bundle.DeferredKey] = deferredBundles;
htmlHelper.ViewContext.HttpContext.Items[BundleTable.DeferredKey] = deferredBundles;
}
if (!deferredBundles.Contains(BundleUrl))
deferredBundles.Add(BundleUrl);
}
public static HtmlString BundleRenderDeferred(this HtmlHelper htmlHelper)
{
var deferredBundles = htmlHelper.ViewContext.HttpContext.Items[Bundle.DeferredKey] as List<string>;
var deferredBundles = htmlHelper.ViewContext.HttpContext.Items[BundleTable.DeferredKey] as List<string>;
var uiExtensionScripts = htmlHelper.ViewContext.HttpContext.Items[Bundle.UIExtensionScriptsKey] as List<string>;
var uiExtensionCss = htmlHelper.ViewContext.HttpContext.Items[Bundle.UIExtensionCssKey] as List<string>;
var uiExtensionScripts = htmlHelper.ViewContext.HttpContext.Items[BundleTable.UIExtensionScriptsKey] as List<string>;
var uiExtensionCss = htmlHelper.ViewContext.HttpContext.Items[BundleTable.UIExtensionCssKey] as List<string>;
if (deferredBundles != null || uiExtensionScripts != null || uiExtensionCss != null)
{
+2 -2
View File
@@ -9,10 +9,10 @@ namespace Disco.Services.Web.Bundles
{
internal sealed class BundleHandler : IHttpHandler
{
public Bundle RequestBundle { get; private set; }
public IBundle RequestBundle { get; private set; }
public string BundleVirtualPath { get; private set; }
public BundleHandler(Bundle requestBundle, string bundleVirtualPath)
public BundleHandler(IBundle requestBundle, string bundleVirtualPath)
{
this.RequestBundle = requestBundle;
this.BundleVirtualPath = bundleVirtualPath;
+8 -4
View File
@@ -9,14 +9,18 @@ namespace Disco.Services.Web.Bundles
{
public static class BundleTable
{
private static Dictionary<string, Bundle> _bundles;
public const string DeferredKey = "Bundles.Deferred";
public const string UIExtensionScriptsKey = "Bundles.UIExtensionScripts";
public const string UIExtensionCssKey = "Bundles.UIExtensionCss";
private static Dictionary<string, IBundle> _bundles;
static BundleTable()
{
_bundles = new Dictionary<string, Bundle>();
_bundles = new Dictionary<string, IBundle>();
}
public static void Add(Bundle Bundle)
public static void Add(IBundle Bundle)
{
_bundles[Bundle.Url] = Bundle;
}
@@ -29,7 +33,7 @@ namespace Disco.Services.Web.Bundles
}
}
internal static Bundle GetBundleFor(string Url)
internal static IBundle GetBundleFor(string Url)
{
if (_bundles.ContainsKey(Url))
{
@@ -9,16 +9,13 @@ using System.Web;
namespace Disco.Services.Web.Bundles
{
public class Bundle
public class FileBundle : IBundle
{
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; }
public bool RemapRequest { get { return true; } }
public string Url { get; private set; }
public string File { get; private set; }
public string FileHash
@@ -44,7 +41,7 @@ namespace Disco.Services.Web.Bundles
}
}
public Bundle(string Url, string File)
public FileBundle(string Url, string File)
{
if (string.IsNullOrWhiteSpace(Url))
throw new ArgumentNullException("Url");
@@ -117,7 +114,7 @@ namespace Disco.Services.Web.Bundles
this._FileHash = string.Empty;
}
internal void ProcessRequest(HttpContext context)
public void ProcessRequest(HttpContext context)
{
// Write Content Type
context.Response.ContentType = this.ContentType;
+23
View File
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace Disco.Services.Web.Bundles
{
public interface IBundle
{
bool RemapRequest { get; }
string Url { get; }
string VersionUrl { get; }
string ContentType { get; }
void ProcessRequest(HttpContext context);
}
}
+32
View File
@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Disco.Services.Web.Bundles
{
public class UrlBundle : IBundle
{
public bool RemapRequest { get { return false; } }
public string Url { get; private set; }
public string VersionUrl { get; private set; }
public string ContentType { get; private set; }
public void ProcessRequest(System.Web.HttpContext context)
{
// Not needed for Url Bundle
throw new NotImplementedException();
}
public UrlBundle(string Url, string ContentType)
{
this.Url = Url;
this.VersionUrl = Url;
this.ContentType = ContentType;
}
}
}
@@ -0,0 +1,35 @@
using Disco.Services.Users;
using Microsoft.AspNet.SignalR;
using System;
using System.Security.Principal;
namespace Disco.Services.Web.Signalling
{
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class DiscoHubAuthorizeAllAttribute : AuthorizeAttribute
{
string[] authorizedClaims;
public DiscoHubAuthorizeAllAttribute(params string[] AuthorisedClaims)
{
if (AuthorisedClaims == null || AuthorisedClaims.Length == 0)
throw new ArgumentNullException("AuthorisedClaims");
this.authorizedClaims = AuthorisedClaims;
}
protected override bool UserAuthorized(IPrincipal user)
{
if (user == null || !user.Identity.IsAuthenticated)
return false;
var username = user.Identity.Name;
var userToken = UserService.GetAuthorization(username);
if (userToken == null)
return false; // No User
return userToken.HasAll(authorizedClaims);
}
}
}
@@ -0,0 +1,35 @@
using Disco.Services.Users;
using Microsoft.AspNet.SignalR;
using System;
using System.Security.Principal;
namespace Disco.Services.Web.Signalling
{
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class DiscoHubAuthorizeAnyAttribute : AuthorizeAttribute
{
string[] authorizedClaims;
public DiscoHubAuthorizeAnyAttribute(params string[] AuthorisedClaims)
{
if (AuthorisedClaims == null || AuthorisedClaims.Length == 0)
throw new ArgumentNullException("AuthorisedClaims");
this.authorizedClaims = AuthorisedClaims;
}
protected override bool UserAuthorized(IPrincipal user)
{
if (user == null || !user.Identity.IsAuthenticated)
return false;
var username = user.Identity.Name;
var userToken = UserService.GetAuthorization(username);
if (userToken == null)
return false; // No User
return userToken.HasAny(authorizedClaims);
}
}
}
@@ -0,0 +1,37 @@
using Disco.Services.Users;
using Microsoft.AspNet.SignalR;
using System;
using System.Security.Principal;
namespace Disco.Services.Web.Signalling
{
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class DiscoHubAuthorizeAttribute : AuthorizeAttribute
{
string authorizedClaim;
public DiscoHubAuthorizeAttribute() { }
public DiscoHubAuthorizeAttribute(string AuthorisedClaim)
{
this.authorizedClaim = AuthorisedClaim;
}
protected override bool UserAuthorized(IPrincipal user)
{
if (user == null || !user.Identity.IsAuthenticated)
return false;
var username = user.Identity.Name;
var userToken = UserService.GetAuthorization(username);
if (userToken == null)
return false; // No User
if (authorizedClaim == null)
return userToken.RoleTokens.Count > 0; // Just Authenticate - no Authorization (but require at least 1 role)
else
return userToken.Has(authorizedClaim);
}
}
}