From 394922cd9b08bae5465373ec5d1d7ca01ab88987 Mon Sep 17 00:00:00 2001 From: Worthaboutapig Date: Thu, 8 Jan 2015 11:25:27 +0000 Subject: [PATCH 1/2] Added guard to FormsAuthentication login/out methods to ensure that 'Enable' has been called. Added tests- a bit hacky, as FormsAuthentication is static. --- .../FormsAuthenticationFixture.cs | 67 ++++++++++++++++++- .../FormsAuthentication.cs | 46 ++++++++++--- src/Nancy.sln.DotSettings | 2 + src/SharedAssemblyInfo.cs | 1 + 4 files changed, 103 insertions(+), 13 deletions(-) diff --git a/src/Nancy.Authentication.Forms.Tests/FormsAuthenticationFixture.cs b/src/Nancy.Authentication.Forms.Tests/FormsAuthenticationFixture.cs index 89a6edcc29..c423ac58ae 100644 --- a/src/Nancy.Authentication.Forms.Tests/FormsAuthenticationFixture.cs +++ b/src/Nancy.Authentication.Forms.Tests/FormsAuthenticationFixture.cs @@ -8,7 +8,6 @@ namespace Nancy.Authentication.Forms.Tests using FakeItEasy; using Fakes; using Helpers; - using Nancy.Security; using Nancy.Tests; using Nancy.Tests.Fakes; using Xunit; @@ -162,7 +161,71 @@ public void Should_return_ok_response_when_user_logs_in_without_redirect() result.StatusCode.ShouldEqual(HttpStatusCode.OK); } - [Fact] + #region Throw helpful exception when the configuration is not enabled + + [Fact] + public void Should_throw_helpful_exception_message_when_user_logs_in_without_redirect_and_forms_authentication_not_enabled() + { + // Given + const string expectedMessage = "The internal FormsAuthenticationConfiguration has not been set. Ensure that FormsAuthentication has been enabled in the bootstrapper"; + FormsAuthentication.Disable(); + + // When + var result = Record.Exception(() => FormsAuthentication.UserLoggedInResponse(userGuid)); + + // Then + result.ShouldBeOfType(typeof(InvalidOperationException)); + result.Message.ShouldBeSameAs(expectedMessage); + } + + [Fact] + public void Should_throw_helpful_exception_message_when_user_logs_in_with_redirect_and_forms_authentication_not_enabled() + { + // Given + const string expectedMessage = "The internal FormsAuthenticationConfiguration has not been set. Ensure that FormsAuthentication has been enabled in the bootstrapper"; + FormsAuthentication.Disable(); + + // When + var result = Record.Exception(() => FormsAuthentication.UserLoggedInRedirectResponse(context, userGuid)); + + // Then + result.ShouldBeOfType(typeof(InvalidOperationException)); + result.Message.ShouldBeSameAs(expectedMessage); + } + + [Fact] + public void Should_throw_helpful_exception_message_when_user_logs_out_with_redirect_and_forms_authentication_not_enabled() + { + // Given + const string expectedMessage = "The internal FormsAuthenticationConfiguration has not been set. Ensure that FormsAuthentication has been enabled in the bootstrapper"; + FormsAuthentication.Disable(); + + // When + var result = Record.Exception(() => FormsAuthentication.LogOutAndRedirectResponse(context, "/")); + + // Then + result.ShouldBeOfType(typeof(InvalidOperationException)); + result.Message.ShouldBeSameAs(expectedMessage); + } + + [Fact] + public void Should_throw_helpful_exception_message_when_user_logs_out_without_redirect_and_forms_authentication_not_enabled() + { + // Given + const string expectedMessage = "The internal FormsAuthenticationConfiguration has not been set. Ensure that FormsAuthentication has been enabled in the bootstrapper"; + FormsAuthentication.Disable(); + + // When + var result = Record.Exception(() => FormsAuthentication.LogOutResponse()); + + // Then + result.ShouldBeOfType(typeof(InvalidOperationException)); + result.Message.ShouldBeSameAs(expectedMessage); + } + + #endregion + + [Fact] public void Should_have_authentication_cookie_in_login_response_when_logging_in_with_redirect() { FormsAuthentication.Enable(A.Fake(), this.config); diff --git a/src/Nancy.Authentication.Forms/FormsAuthentication.cs b/src/Nancy.Authentication.Forms/FormsAuthentication.cs index f185e55e20..7a3d8a4609 100644 --- a/src/Nancy.Authentication.Forms/FormsAuthentication.cs +++ b/src/Nancy.Authentication.Forms/FormsAuthentication.cs @@ -34,7 +34,15 @@ public static string FormsAuthenticationCookieName } } - /// + /// + /// To support testing, necessary as everying is static, but not ideal + /// + internal static void Disable() + { + currentConfiguration = null; + } + + /// /// Enables forms authentication for the application /// /// Pipelines to add handlers to (usually "this") @@ -110,7 +118,12 @@ public static void Enable(INancyModule module, FormsAuthenticationConfiguration /// Nancy response with redirect. public static Response UserLoggedInRedirectResponse(NancyContext context, Guid userIdentifier, DateTime? cookieExpiry = null, string fallbackRedirectUrl = null) { - var redirectUrl = fallbackRedirectUrl; + if (currentConfiguration == null) + { + throw new InvalidOperationException("The internal FormsAuthenticationConfiguration has not been set. Ensure that FormsAuthentication has been enabled in the bootstrapper"); + } + + var redirectUrl = fallbackRedirectUrl; if (string.IsNullOrEmpty(redirectUrl)) { @@ -149,11 +162,14 @@ public static Response UserLoggedInRedirectResponse(NancyContext context, Guid u /// Nancy response with status public static Response UserLoggedInResponse(Guid userIdentifier, DateTime? cookieExpiry = null) { - var response = - (Response)HttpStatusCode.OK; + if (currentConfiguration == null) + { + throw new InvalidOperationException("The internal FormsAuthenticationConfiguration has not been set. Ensure that FormsAuthentication has been enabled in the bootstrapper"); + } + + var response = (Response)HttpStatusCode.OK; - var authenticationCookie = - BuildCookie(userIdentifier, cookieExpiry, currentConfiguration); + var authenticationCookie = BuildCookie(userIdentifier, cookieExpiry, currentConfiguration); response.AddCookie(authenticationCookie); @@ -168,7 +184,12 @@ public static Response UserLoggedInResponse(Guid userIdentifier, DateTime? cooki /// Nancy response public static Response LogOutAndRedirectResponse(NancyContext context, string redirectUrl) { - var response = context.GetRedirect(redirectUrl); + if (currentConfiguration == null) + { + throw new InvalidOperationException("The internal FormsAuthenticationConfiguration has not been set. Ensure that FormsAuthentication has been enabled in the bootstrapper"); + } + + var response = context.GetRedirect(redirectUrl); var authenticationCookie = BuildLogoutCookie(currentConfiguration); response.AddCookie(authenticationCookie); @@ -181,11 +202,14 @@ public static Response LogOutAndRedirectResponse(NancyContext context, string re /// Nancy response public static Response LogOutResponse() { - var response = - (Response)HttpStatusCode.OK; + if (currentConfiguration == null) + { + throw new InvalidOperationException("The internal FormsAuthenticationConfiguration has not been set. Ensure that FormsAuthentication has been enabled in the bootstrapper"); + } + + var response = (Response)HttpStatusCode.OK; - var authenticationCookie = - BuildLogoutCookie(currentConfiguration); + var authenticationCookie = BuildLogoutCookie(currentConfiguration); response.AddCookie(authenticationCookie); diff --git a/src/Nancy.sln.DotSettings b/src/Nancy.sln.DotSettings index 6e2e1bf350..ceefa60019 100644 --- a/src/Nancy.sln.DotSettings +++ b/src/Nancy.sln.DotSettings @@ -1,5 +1,6 @@  <?xml version="1.0" encoding="utf-16"?><Profile name="NancyStandard"><CSUseVar><BehavourStyle>CAN_CHANGE_TO_IMPLICIT</BehavourStyle><LocalVariableStyle>ALWAYS_IMPLICIT</LocalVariableStyle><ForeachVariableStyle>ALWAYS_IMPLICIT</ForeachVariableStyle></CSUseVar><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><CSShortenReferences>True</CSShortenReferences><CSReorderTypeMembers>True</CSReorderTypeMembers><CSMakeFieldReadonly>True</CSMakeFieldReadonly></Profile> + All NEXT_LINE 1 NEXT_LINE @@ -10,5 +11,6 @@ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="" Suffix="" Style="Aa_bb" /></Policy> <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> True + True <data><IncludeFilters /><ExcludeFilters /></data> <data /> \ No newline at end of file diff --git a/src/SharedAssemblyInfo.cs b/src/SharedAssemblyInfo.cs index fbeab6a5ff..00058d070a 100644 --- a/src/SharedAssemblyInfo.cs +++ b/src/SharedAssemblyInfo.cs @@ -11,3 +11,4 @@ [assembly: AssemblyInformationalVersion("0.23.2")] [assembly: InternalsVisibleTo("Nancy.Tests")] +[assembly: InternalsVisibleTo("Nancy.Authentication.Forms.Tests")] From e21534e5e1cc1ca426baba51f3242117a437d3c6 Mon Sep 17 00:00:00 2001 From: Worthaboutapig Date: Fri, 6 Feb 2015 15:30:43 +0000 Subject: [PATCH 2/2] Support for runtime view errors --- src/Nancy.Testing/Nancy.Testing.csproj | 8 +- src/Nancy.Testing/packages.config | 2 +- ...cy.ViewEngines.Razor.BuildProviders.csproj | 4 +- src/Nancy.ViewEngines.Razor/HtmlHelpers.cs | 30 +++++-- .../Nancy.ViewEngines.Razor.csproj | 2 +- .../NancyRazorViewBase.cs | 15 ++-- .../RazorViewEngine.cs | 82 ++++++++++++++----- src/Nancy/Responses/MaterialisingResponse.cs | 2 +- 8 files changed, 102 insertions(+), 43 deletions(-) diff --git a/src/Nancy.Testing/Nancy.Testing.csproj b/src/Nancy.Testing/Nancy.Testing.csproj index 12756859d2..22b9d7f6d6 100644 --- a/src/Nancy.Testing/Nancy.Testing.csproj +++ b/src/Nancy.Testing/Nancy.Testing.csproj @@ -85,9 +85,9 @@ bin\MonoRelease\Nancy.Testing.XML - + False - ..\packages\CsQuery.1.3.3\lib\net40\CsQuery.dll + ..\..\..\..\savetrees\code\references\packages\CsQuery.1.3.4\lib\net40\CsQuery.dll @@ -171,7 +171,6 @@ - @@ -180,6 +179,9 @@ Resources.Designer.cs + + +