Skip to content

Commit

Permalink
Improved API for Saml2Scoping
Browse files Browse the repository at this point in the history
- Updated FluentAssertions to get better Xml comparison
- Updated tests and removed test that became redundant.
- Added guard against negative proxy count.
  • Loading branch information
AndersAbel committed Apr 27, 2016
1 parent 6e040b9 commit 6d60f39
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 82 deletions.
9 changes: 5 additions & 4 deletions Kentor.AuthServices.Tests/Kentor.AuthServices.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="FluentAssertions, Version=4.3.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.3.0\lib\net45\FluentAssertions.dll</HintPath>
<Reference Include="FluentAssertions, Version=4.5.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.5.0\lib\net45\FluentAssertions.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="FluentAssertions.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.3.0\lib\net45\FluentAssertions.Core.dll</HintPath>
<Reference Include="FluentAssertions.Core, Version=4.5.0.0, Culture=neutral, PublicKeyToken=33f2691a05b67b6a, processorArchitecture=MSIL">
<HintPath>..\packages\FluentAssertions.4.5.0\lib\net45\FluentAssertions.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
Expand Down Expand Up @@ -131,6 +131,7 @@
<Compile Include="Saml2P\Saml2ArtifactResponseTests.cs" />
<Compile Include="Saml2P\Saml2LogoutRequestTests.cs" />
<Compile Include="Saml2P\Saml2LogoutResponseTests.cs" />
<Compile Include="Saml2P\Saml2ScopingTests.cs" />
<Compile Include="Saml2P\Saml2SoapBindingTests.cs" />
<Compile Include="ServiceCertificateTests.cs" />
<Compile Include="HttpModule\CommandResultHttpTests.cs" />
Expand Down
62 changes: 21 additions & 41 deletions Kentor.AuthServices.Tests/Saml2P/Saml2AuthenticationRequestTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,15 @@ public void Saml2AuthenticationRequest_ToXElement_AddsScoping()
var subject = new Saml2AuthenticationRequest()
{
AssertionConsumerServiceUrl = new Uri("http://destination.example.com"),
Scoping = new Saml2Scoping(new List<Saml2IdPEntry> { new Saml2IdPEntry(location, name, providerId) }, 5, new List<Saml2RequesterId> { new Saml2RequesterId(requesterId) } )
}.ToXElement().Element(Saml2Namespaces.Saml2P + "Scoping");
Scoping = new Saml2Scoping()
{
ProxyCount = 5
}
.With(new Saml2IdpEntry(location, name, providerId))
.With(new Saml2RequesterId(requesterId))
};

var actual = subject.ToXElement().Element(Saml2Namespaces.Saml2P + "Scoping");

var expected = new XElement(Saml2Namespaces.Saml2P + "root",
new XAttribute(XNamespace.Xmlns + "saml2p", Saml2Namespaces.Saml2P),
Expand All @@ -260,66 +267,39 @@ public void Saml2AuthenticationRequest_ToXElement_AddsScoping()
new XElement(Saml2Namespaces.Saml2P + "RequesterID", requesterId.ToString())))
.Elements().Single();

subject.Should().BeEquivalentTo(expected);
actual.Should().BeEquivalentTo(expected);
}

[TestMethod]
public void Saml2AuthenticationRequest_ToXElement_Scoping_NullProxyCount_AttributeNotAdded()
{
var subject = new Saml2AuthenticationRequest()
{
AssertionConsumerServiceUrl = new Uri("http://destination.example.com"),
Scoping = new Saml2Scoping(new List<Saml2IdPEntry>(), null, new List<Saml2RequesterId>())
}.ToXElement().Element(Saml2Namespaces.Saml2P + "Scoping");

var expected = new XElement(Saml2Namespaces.Saml2P + "root",
new XAttribute(XNamespace.Xmlns + "saml2p", Saml2Namespaces.Saml2P),
new XElement(Saml2Namespaces.Saml2P + "Scoping"))
.Elements().Single();

subject.Should().BeEquivalentTo(expected);
}
[TestMethod]
public void Saml2AuthenticationRequest_ToXElement_Scoping_ZeroProxyCount_AttributeAdded()
{
var subject = new Saml2AuthenticationRequest()
{
AssertionConsumerServiceUrl = new Uri("http://destination.example.com"),
Scoping = new Saml2Scoping(new List<Saml2IdPEntry>(), 0, new List<Saml2RequesterId>())
}.ToXElement().Element(Saml2Namespaces.Saml2P + "Scoping");
Scoping = new Saml2Scoping()
{
ProxyCount = 0
}
};

var actual = subject.ToXElement().Element(Saml2Namespaces.Saml2P + "Scoping");

var expected = new XElement(Saml2Namespaces.Saml2P + "root",
new XAttribute(XNamespace.Xmlns + "saml2p", Saml2Namespaces.Saml2P),
new XElement(Saml2Namespaces.Saml2P + "Scoping",
new XAttribute("ProxyCount", "0")))
.Elements().Single();

subject.Should().BeEquivalentTo(expected);
}
[TestMethod]
public void Saml2AuthenticationRequest_ToXElement_Scoping_NegativeProxyCount_AttributeNotAdded()
{
var subject = new Saml2AuthenticationRequest()
{
AssertionConsumerServiceUrl = new Uri("http://destination.example.com"),
Scoping = new Saml2Scoping(new List<Saml2IdPEntry>(), -1, new List<Saml2RequesterId>())
}.ToXElement().Element(Saml2Namespaces.Saml2P + "Scoping");

var expected = new XElement(Saml2Namespaces.Saml2P + "root",
new XAttribute(XNamespace.Xmlns + "saml2p", Saml2Namespaces.Saml2P),
new XElement(Saml2Namespaces.Saml2P + "Scoping"))
.Elements().Single();

subject.Should().BeEquivalentTo(expected);
actual.Should().BeEquivalentTo(expected);
}

[TestMethod]
public void Saml2AuthenticationRequest_ToXElement_Scoping_NullInput_EmptyScoping()
public void Saml2AuthenticationRequest_ToXElement_Scoping_NullContents_EmptyScoping()
{
var subject = new Saml2AuthenticationRequest()
{
AssertionConsumerServiceUrl = new Uri("http://destination.example.com"),
Scoping = new Saml2Scoping(null, -1, null)
Scoping = new Saml2Scoping()
}.ToXElement().Element(Saml2Namespaces.Saml2P + "Scoping");

var expected = new XElement(Saml2Namespaces.Saml2P + "root",
Expand Down Expand Up @@ -355,7 +335,7 @@ public void Saml2AuthenticationRequest_ToXElement_AddsRequestedAuthnContext_Comp
}

[TestMethod]
public void Saml2AuthenticateRequest_ToXElement_OmitsRequestedAuthnContext_OnNullClassRef()
public void Saml2AuthenticationRequest_ToXElement_OmitsRequestedAuthnContext_OnNullClassRef()
{
var subject = new Saml2AuthenticationRequest()
{
Expand Down
20 changes: 20 additions & 0 deletions Kentor.AuthServices.Tests/Saml2P/Saml2ScopingTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using FluentAssertions;
using Kentor.AuthServices.Saml2P;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;

namespace Kentor.AuthServices.Tests.Saml2P
{
[TestClass]
public class Saml2ScopingTests
{
[TestMethod]
public void Saml2Scoping_Ctor_ThrowsOnNegativeProxyCount()
{
Action a = () => new Saml2Scoping().ProxyCount = -1;

a.ShouldThrow<ArgumentException>()
.WithMessage("*negative*");
}
}
}
2 changes: 1 addition & 1 deletion Kentor.AuthServices.Tests/packages.config
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="FluentAssertions" version="4.3.0" targetFramework="net45" />
<package id="FluentAssertions" version="4.5.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="5.2.2" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="3.2.2" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.2.2" targetFramework="net45" />
Expand Down
2 changes: 1 addition & 1 deletion Kentor.AuthServices/Kentor.AuthServices.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
<Compile Include="Configuration\ServiceCertificateCollection.cs" />
<Compile Include="Saml2P\AuthnContextComparisonType.cs" />
<Compile Include="Configuration\NameIdPolicyElement.cs" />
<Compile Include="Saml2P\Saml2IdPEntry.cs" />
<Compile Include="Saml2P\Saml2IdpEntry.cs" />
<Compile Include="Saml2P\Saml2LogoutResponse.cs" />
<Compile Include="Saml2P\Saml2RequestedAuthnContext.cs" />
<Compile Include="Configuration\RequestedAuthnContextElement.cs" />
Expand Down
6 changes: 3 additions & 3 deletions Kentor.AuthServices/SAML2P/Saml2IdPEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ namespace Kentor.AuthServices.Saml2P
/// <summary>
/// The Saml2IdPEntry specifies a single identity provider trusted by the requester to authenticate the presenter
/// </summary>
public class Saml2IdPEntry
public class Saml2IdpEntry
{
/// <summary>
/// Initializes a new instance of the <see cref="Saml2IdPEntry"/> class.
/// Initializes a new instance of the <see cref="Saml2IdpEntry"/> class.
/// </summary>
/// <param name="location">The location.</param>
/// <param name="name">The name.</param>
/// <param name="providerId">The provider identifier.</param>
public Saml2IdPEntry(string location, string name, string providerId)
public Saml2IdpEntry(string location, string name, string providerId)
{
Location = location;
Name = name;
Expand Down
88 changes: 61 additions & 27 deletions Kentor.AuthServices/SAML2P/Saml2Scoping.cs
Original file line number Diff line number Diff line change
@@ -1,48 +1,80 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Xml.Linq;

namespace Kentor.AuthServices.Saml2P
{
/// <summary>
/// Saml2Scoping specifies a set of identity providers trusted by the requester to authenticate the presenter, as well as
/// limitations and context related to proxying of the authentication request message to subsequent identity
/// providers by the responder.
/// Saml2Scoping specifies a set of identity providers trusted by the
/// requester to authenticate the presenter, as well as limitations and
/// context related to proxying of the authentication request message to
/// subsequent identity providers by the responder.
/// </summary>
public class Saml2Scoping
{
/// <summary>
/// Initializes a new instance of the <see cref="Saml2Scoping"/> class.
/// Gets advisory list of identity providers and associated information
/// that the requester deems acceptable to respond to the request.
/// </summary>
/// <param name="idPEntries">The advisory list of identity providers.</param>
/// <param name="proxyCount">The proxy count.</param>
/// <param name="requesterIds">The requester ids.</param>
public Saml2Scoping(IList<Saml2IdPEntry> idPEntries, int? proxyCount, IList<Saml2RequesterId> requesterIds)
public IList<Saml2IdpEntry> IdPEntries { get; } = new List<Saml2IdpEntry>();

/// <summary>
/// Fluent config helper that adds a <see cref="Saml2IdpEntry"/> to the
/// <see cref="Saml2Scoping"/>
/// </summary>
/// <param name="idpEntry">Idp entry to add</param>
/// <returns>this</returns>
public Saml2Scoping With(Saml2IdpEntry idpEntry)
{
IdPEntries = idPEntries;
ProxyCount = proxyCount;
RequesterIds = requesterIds;
IdPEntries.Add(idpEntry);
return this;
}

private int? proxyCount;

/// <summary>
/// Gets or sets advisory list of identity providers and associated information that
/// the requester deems acceptable to respond to the request.
/// Specifies the number of proxying indirections permissible between
/// the identity provider that receives the authentication request and
/// the identity provider who ultimately authenticates the principal.
/// A count of zero permits no proxying, while omitting (null) this
/// attribute expresses no such restriction.
/// </summary>
/// <value>The idp entries.</value>
public IList<Saml2IdPEntry> IdPEntries { get; }
public int? ProxyCount
{
get
{
return proxyCount;
}
set
{
if(value < 0)
{
throw new ArgumentException("ProxyCount cannot be negative.");
}
proxyCount = value;
}
}

/// <summary>
/// Specifies the number of proxying indirections permissible between the identity provider that receives
/// the authentication request and the identity provider who ultimately authenticates the principal.
/// A count of zero permits no proxying, while omitting (null) this attribute expresses no such restriction.
/// Gets or sets the set of requesting entities on whose behalf the
/// requester is acting. Used to communicate the chain of requesters
/// when proxying occurs.
/// </summary>
/// <value>The proxy count.</value>
public int? ProxyCount { get; }
public IList<Saml2RequesterId> RequesterIds { get; } = new List<Saml2RequesterId>();

/// <summary>
/// Gets or sets the set of requesting entities on whose behalf the requester is acting.
/// Used to communicate the chain of requesters when proxying occurs.
/// Fluent config helper that adds a <see cref="Saml2RequesterId"/> to the
/// <see cref="Saml2Scoping"/>
/// </summary>
/// <value>The requester ids.</value>
public IList<Saml2RequesterId> RequesterIds { get; }
/// <param name="requesterId">Requester Id to add</param>
/// <returns>this</returns>
public Saml2Scoping With(Saml2RequesterId requesterId)
{
RequesterIds.Add(requesterId);
return this;
}

/// <summary>
/// Create XElement for the Saml2Scoping.
Expand All @@ -53,12 +85,14 @@ public XElement ToXElement()

if (ProxyCount.HasValue && ProxyCount.Value >= 0)
{
scopingElement.AddAttributeIfNotNullOrEmpty("ProxyCount", ProxyCount.Value.ToString(CultureInfo.InvariantCulture));
scopingElement.AddAttributeIfNotNullOrEmpty("ProxyCount", ProxyCount);
}

if (IdPEntries != null && IdPEntries.Count > 0)
{
scopingElement.Add(new XElement(Saml2Namespaces.Saml2P + "IDPList", IdPEntries.Select(x => x.ToXElement())));
scopingElement.Add(new XElement(
Saml2Namespaces.Saml2P + "IDPList",
IdPEntries.Select(x => x.ToXElement())));
}

if (RequesterIds != null && RequesterIds.Count > 0)
Expand Down
5 changes: 0 additions & 5 deletions Kentor.AuthServices/WebSSO/SignInCommand.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
using Kentor.AuthServices.Configuration;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.IdentityModel.Metadata;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Kentor.AuthServices.Saml2P;

namespace Kentor.AuthServices.WebSso
{
Expand Down

0 comments on commit 6d60f39

Please sign in to comment.