summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.Web.Test
diff options
context:
space:
mode:
Diffstat (limited to 'src/DotNetOpenAuth.Web.Test')
-rw-r--r--src/DotNetOpenAuth.Web.Test/DotNetOpenAuth.Web.Test.csproj87
-rw-r--r--src/DotNetOpenAuth.Web.Test/OAuth2ClientTest.cs142
-rw-r--r--src/DotNetOpenAuth.Web.Test/OAuthAuthenticationTickerHelperTest.cs152
-rw-r--r--src/DotNetOpenAuth.Web.Test/OAuthClientTest.cs142
-rw-r--r--src/DotNetOpenAuth.Web.Test/OAuthWebSecurityTest.cs486
-rw-r--r--src/DotNetOpenAuth.Web.Test/Properties/AssemblyInfo.cs35
-rw-r--r--src/DotNetOpenAuth.Web.Test/UriHelperTest.cs64
7 files changed, 1108 insertions, 0 deletions
diff --git a/src/DotNetOpenAuth.Web.Test/DotNetOpenAuth.Web.Test.csproj b/src/DotNetOpenAuth.Web.Test/DotNetOpenAuth.Web.Test.csproj
new file mode 100644
index 0000000..d02c530
--- /dev/null
+++ b/src/DotNetOpenAuth.Web.Test/DotNetOpenAuth.Web.Test.csproj
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))\EnlistmentInfo.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))' != '' " />
+ <PropertyGroup>
+ <StyleCopEnabled>False</StyleCopEnabled>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{C23B217B-4D35-4A72-A1F7-FAEB4F39CB91}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>DotNetOpenAuth.Web.Test</RootNamespace>
+ <AssemblyName>DotNetOpenAuth.Web.Test</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.props" />
+ <PropertyGroup>
+ <DelaySign>true</DelaySign>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Moq">
+ <HintPath>..\..\lib\Moq.dll</HintPath>
+ </Reference>
+ <Reference Include="nunit.framework">
+ <HintPath>..\..\lib\nunit.framework.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="OAuth2ClientTest.cs" />
+ <Compile Include="OAuthAuthenticationTickerHelperTest.cs" />
+ <Compile Include="OAuthClientTest.cs" />
+ <Compile Include="OAuthWebSecurityTest.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="UriHelperTest.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\DotNetOpenAuth.Messaging\DotNetOpenAuth.Messaging.csproj">
+ <Project>{60426312-6AE5-4835-8667-37EDEA670222}</Project>
+ <Name>DotNetOpenAuth.Messaging</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\DotNetOpenAuth.OAuth\DotNetOpenAuth.OAuth.csproj">
+ <Project>{A288FCC8-6FCF-46DA-A45E-5F9281556361}</Project>
+ <Name>DotNetOpenAuth.OAuth</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\DotNetOpenAuth.WebPages\DotNetOpenAuth.WebPages.csproj">
+ <Project>{AE031B0C-710B-4D5B-BDF5-F21DFC9092D8}</Project>
+ <Name>DotNetOpenAuth.WebPages</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\DotNetOpenAuth.Web\DotNetOpenAuth.Web.csproj">
+ <Project>{51835086-9611-4C53-819B-F2D5C9320873}</Project>
+ <Name>DotNetOpenAuth.Web</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="official-build-key.pfx" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.targets" />
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))\EnlistmentInfo.targets" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))' != '' " />
+</Project> \ No newline at end of file
diff --git a/src/DotNetOpenAuth.Web.Test/OAuth2ClientTest.cs b/src/DotNetOpenAuth.Web.Test/OAuth2ClientTest.cs
new file mode 100644
index 0000000..b090346
--- /dev/null
+++ b/src/DotNetOpenAuth.Web.Test/OAuth2ClientTest.cs
@@ -0,0 +1,142 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using DotNetOpenAuth.Web.Clients;
+using Moq;
+using System.Web;
+using System.Collections.Specialized;
+
+namespace DotNetOpenAuth.Web.Test
+{
+ [TestFixture]
+ public class OAuth2ClientTest
+ {
+ [TestCase]
+ public void TestProviderName()
+ {
+ // Arrange
+ var client = new MockOAuth2Client();
+
+ // Act
+ string providerName = client.ProviderName;
+
+ // Assert
+ Assert.AreEqual("mockprovider", providerName);
+ }
+
+ [TestCase]
+ public void RequestAuthenticationIssueCorrectRedirect()
+ {
+ // Arrange
+ var client = new MockOAuth2Client();
+ var context = new Mock<HttpContextBase>(MockBehavior.Strict);
+ context.Setup(c => c.Response.Redirect("http://live.com/?q=http://return.to.me/", true)).Verifiable();
+
+ // Act
+ client.RequestAuthentication(context.Object, new Uri("http://return.to.me"));
+
+ // Assert
+ context.Verify();
+ }
+
+ [TestCase]
+ public void VerifyAuthenticationThrowsIfContextIsNull()
+ {
+ // Arrange
+ var client = new MockOAuth2Client();
+
+ // Act && Assert
+ Assert.Throws<ArgumentNullException>(() => client.VerifyAuthentication(null));
+ }
+
+ [TestCase]
+ public void VerifyAuthenticationFailsIfCodeIsNotPresent()
+ {
+ // Arrange
+ var client = new MockOAuth2Client();
+ var context = new Mock<HttpContextBase>(MockBehavior.Strict);
+ var queryStrings = new NameValueCollection();
+ context.Setup(c => c.Request.QueryString).Returns(queryStrings);
+
+ // Act
+ AuthenticationResult result = client.VerifyAuthentication(context.Object);
+
+ // Assert
+ Assert.IsFalse(result.IsSuccessful);
+ }
+
+ [TestCase]
+ public void VerifyAuthenticationFailsIfAccessTokenIsNull()
+ {
+ // Arrange
+ var client = new MockOAuth2Client();
+ var context = new Mock<HttpContextBase>(MockBehavior.Strict);
+ var queryStrings = new NameValueCollection();
+ queryStrings.Add("code", "random");
+ context.Setup(c => c.Request.QueryString).Returns(queryStrings);
+
+ // Act
+ AuthenticationResult result = client.VerifyAuthentication(context.Object);
+
+ // Assert
+ Assert.IsFalse(result.IsSuccessful);
+ }
+
+ [TestCase]
+ public void VerifyAuthenticationSucceeds()
+ {
+ // Arrange
+ var client = new MockOAuth2Client();
+ var context = new Mock<HttpContextBase>(MockBehavior.Strict);
+ var queryStrings = new NameValueCollection();
+ queryStrings.Add("code", "secret");
+ context.Setup(c => c.Request.QueryString).Returns(queryStrings);
+
+ // Act
+ AuthenticationResult result = client.VerifyAuthentication(context.Object);
+
+ // Assert
+ Assert.True(result.IsSuccessful);
+ Assert.AreEqual("mockprovider", result.Provider);
+ Assert.AreEqual("12345", result.ProviderUserId);
+ Assert.AreEqual("John Doe", result.UserName);
+ Assert.NotNull(result.ExtraData);
+ Assert.AreEqual("abcde", result.ExtraData["token"]);
+ }
+
+ private class MockOAuth2Client : OAuth2Client
+ {
+ public MockOAuth2Client() : base("mockprovider")
+ {
+ }
+
+ protected override Uri GetServiceLoginUrl(Uri returnUrl)
+ {
+ string url = "http://live.com/?q=" + returnUrl.ToString();
+ return new Uri(url);
+ }
+
+ protected override string QueryAccessToken(Uri returnUrl, string authorizationCode)
+ {
+ return (authorizationCode == "secret") ? "abcde" : null;
+ }
+
+ protected override IDictionary<string, string> GetUserData(string accessToken)
+ {
+ if (accessToken == "abcde")
+ {
+ return new Dictionary<string, string>
+ {
+ {"id", "12345"},
+ {"token", accessToken},
+ {"name", "John Doe"}
+ };
+ }
+
+ return null;
+ }
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.Web.Test/OAuthAuthenticationTickerHelperTest.cs b/src/DotNetOpenAuth.Web.Test/OAuthAuthenticationTickerHelperTest.cs
new file mode 100644
index 0000000..2545bb3
--- /dev/null
+++ b/src/DotNetOpenAuth.Web.Test/OAuthAuthenticationTickerHelperTest.cs
@@ -0,0 +1,152 @@
+using System;
+using System.Web;
+using System.Web.Security;
+using DotNetOpenAuth.Web;
+using Moq;
+using NUnit.Framework;
+
+namespace DotNetOpenAuth.Test.Web
+{
+ [TestFixture]
+ public class OAuthAuthenticationTickerHelperTest
+ {
+ [TestCase]
+ public void SetAuthenticationTicketSetCookieOnHttpResponseWithPersistentSet()
+ {
+ SetAuthenticationTicketSetCookieOnHttpResponse(isPersistent: true);
+ }
+
+ [TestCase]
+ public void SetAuthenticationTicketSetCookieOnHttpResponseWithPersistentNotSet()
+ {
+ SetAuthenticationTicketSetCookieOnHttpResponse(isPersistent: false);
+ }
+
+ [TestCase]
+ public void IsOAuthAuthenticationTicketReturnsTrueIfCookieIsPresent()
+ {
+ // Arrange
+ var ticket = new FormsAuthenticationTicket(
+ 2,
+ "username",
+ DateTime.Now,
+ DateTime.Now.Add(FormsAuthentication.Timeout),
+ false,
+ "OAuth",
+ FormsAuthentication.FormsCookiePath);
+
+ var cookie = new HttpCookie(name: FormsAuthentication.FormsCookieName,
+ value: FormsAuthentication.Encrypt(ticket));
+ var cookies = new HttpCookieCollection {cookie};
+
+ var context = new Mock<HttpContextBase>();
+ context.Setup(c => c.Request.Cookies).Returns(cookies);
+
+ // Act
+ bool result = OAuthAuthenticationTicketHelper.IsOAuthAuthenticationTicket(context.Object);
+
+ // Assert
+ Assert.IsTrue(result);
+ }
+
+ [TestCase]
+ public void IsOAuthAuthenticationTicketReturnsFalseIfCookieIsNotPresent()
+ {
+ // Arrange
+ var context = new Mock<HttpContextBase>();
+ context.Setup(c => c.Request.Cookies).Returns(new HttpCookieCollection());
+
+ // Act
+ bool result = OAuthAuthenticationTicketHelper.IsOAuthAuthenticationTicket(context.Object);
+
+ // Assert
+ Assert.IsFalse(result);
+ }
+
+ [TestCase]
+ public void IsOAuthAuthenticationTicketReturnsFalseIfCookieIsPresentButDoesNotHaveOAuthData()
+ {
+ // Arrange
+ var ticket = new FormsAuthenticationTicket(
+ 2,
+ "username",
+ DateTime.Now,
+ DateTime.Now.Add(FormsAuthentication.Timeout),
+ false,
+ null,
+ FormsAuthentication.FormsCookiePath);
+
+ var cookie = new HttpCookie(name: FormsAuthentication.FormsCookieName,
+ value: FormsAuthentication.Encrypt(ticket));
+ var cookies = new HttpCookieCollection { cookie };
+
+ var context = new Mock<HttpContextBase>();
+ context.Setup(c => c.Request.Cookies).Returns(cookies);
+
+ // Act
+ bool result = OAuthAuthenticationTicketHelper.IsOAuthAuthenticationTicket(context.Object);
+
+ // Assert
+ Assert.IsFalse(result);
+ }
+
+ [TestCase]
+ public void IsOAuthAuthenticationTicketReturnsFalseIfCookieIsPresentButDoesNotHaveCorrectName()
+ {
+ // Arrange
+ var response = new Mock<HttpResponseBase>();
+
+ var ticket = new FormsAuthenticationTicket(
+ 2,
+ "username",
+ DateTime.Now,
+ DateTime.Now.Add(FormsAuthentication.Timeout),
+ false,
+ "OAuth",
+ FormsAuthentication.FormsCookiePath);
+
+ var cookie = new HttpCookie(name: "random cookie name",
+ value: FormsAuthentication.Encrypt(ticket));
+ var cookies = new HttpCookieCollection { cookie };
+
+ var context = new Mock<HttpContextBase>();
+ context.Setup(c => c.Request.Cookies).Returns(cookies);
+
+ // Act
+ bool result = OAuthAuthenticationTicketHelper.IsOAuthAuthenticationTicket(context.Object);
+
+ // Assert
+ Assert.IsFalse(result);
+ }
+
+ private void SetAuthenticationTicketSetCookieOnHttpResponse(bool isPersistent)
+ {
+ // Arrange
+ var cookies = new HttpCookieCollection();
+
+ var context = new Mock<HttpContextBase>();
+ context.Setup(c => c.Request.IsSecureConnection).Returns(true);
+ context.Setup(c => c.Response.Cookies).Returns(cookies);
+
+ // Act
+ OAuthAuthenticationTicketHelper.SetAuthenticationTicket(context.Object, "user", isPersistent);
+
+ // Assert
+ Assert.AreEqual(1, cookies.Count);
+ HttpCookie addedCookie = cookies[0];
+
+ Assert.AreEqual(FormsAuthentication.FormsCookieName, addedCookie.Name);
+ Assert.IsTrue(addedCookie.HttpOnly);
+ Assert.AreEqual("/", addedCookie.Path);
+ Assert.IsFalse(addedCookie.Secure);
+ Assert.IsNotNullOrEmpty(addedCookie.Value);
+
+ FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(addedCookie.Value);
+ Assert.NotNull(ticket);
+ Assert.AreEqual(2, ticket.Version);
+ Assert.AreEqual("user", ticket.Name);
+ Assert.AreEqual("OAuth", ticket.UserData);
+ Assert.AreEqual(isPersistent, ticket.IsPersistent);
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.Web.Test/OAuthClientTest.cs b/src/DotNetOpenAuth.Web.Test/OAuthClientTest.cs
new file mode 100644
index 0000000..8e8cf1e
--- /dev/null
+++ b/src/DotNetOpenAuth.Web.Test/OAuthClientTest.cs
@@ -0,0 +1,142 @@
+using System;
+using System.Web;
+using DotNetOpenAuth.Messaging;
+using DotNetOpenAuth.OAuth.Messages;
+using DotNetOpenAuth.Web.Clients;
+using Moq;
+using NUnit.Framework;
+
+namespace DotNetOpenAuth.Web.Test
+{
+ [TestFixture]
+ public class OAuthClientTest
+ {
+ [TestCase]
+ public void TestProviderNamePropertyIsCorrect()
+ {
+ // Arrange
+ var client = new MockOAuthClient();
+
+ // Act
+ var provider = client.ProviderName;
+
+ // Assert
+ Assert.AreEqual("mockoauth", provider);
+ }
+
+ [TestCase]
+ public void RequestAuthenticationInvokeMethodOnWebWorker()
+ {
+ // Arrange
+ var webWorker = new Mock<IOAuthWebWorker>(MockBehavior.Strict);
+ webWorker.Setup(
+ w => w.RequestAuthentication(
+ It.Is<Uri>(u => u.ToString().Equals("http://live.com/my/path.cshtml?q=one"))))
+ .Verifiable();
+
+ var client = new MockOAuthClient(webWorker.Object);
+ var returnUri = new Uri("http://live.com/my/path.cshtml?q=one");
+ var context = new Mock<HttpContextBase>();
+
+ // Act
+ client.RequestAuthentication(context.Object, returnUri);
+
+ // Assert
+ webWorker.Verify();
+ }
+
+ [TestCase]
+ public void VerifyAuthenticationFailsIfResponseTokenIsNull()
+ {
+ // Arrange
+ var webWorker = new Mock<IOAuthWebWorker>(MockBehavior.Strict);
+ webWorker.Setup(w => w.ProcessUserAuthorization()).Returns((AuthorizedTokenResponse)null);
+
+ var client = new MockOAuthClient(webWorker.Object);
+ var context = new Mock<HttpContextBase>();
+
+ // Act
+ client.VerifyAuthentication(context.Object);
+
+ // Assert
+ webWorker.Verify();
+ }
+
+ [TestCase]
+ public void VerifyAuthenticationFailsIfAccessTokenIsInvalid()
+ {
+ // Arrange
+ var endpoint = new MessageReceivingEndpoint("http://live.com/path/?a=b", HttpDeliveryMethods.GetRequest);
+ var request = new AuthorizedTokenRequest(endpoint, new Version("1.0"));
+ var response = new AuthorizedTokenResponse(request)
+ {
+ AccessToken = "invalid token"
+ };
+
+ var webWorker = new Mock<IOAuthWebWorker>(MockBehavior.Strict);
+ webWorker.Setup(w => w.ProcessUserAuthorization()).Returns(response).Verifiable();
+
+ var client = new MockOAuthClient(webWorker.Object);
+ var context = new Mock<HttpContextBase>();
+
+ // Act
+ AuthenticationResult result = client.VerifyAuthentication(context.Object);
+
+ // Assert
+ webWorker.Verify();
+
+ Assert.False(result.IsSuccessful);
+ }
+
+ [TestCase]
+ public void VerifyAuthenticationSucceeds()
+ {
+ // Arrange
+ var endpoint = new MessageReceivingEndpoint("http://live.com/path/?a=b", HttpDeliveryMethods.GetRequest);
+ var request = new AuthorizedTokenRequest(endpoint, new Version("1.0"));
+ var response = new AuthorizedTokenResponse(request)
+ {
+ AccessToken = "ok"
+ };
+
+ var webWorker = new Mock<IOAuthWebWorker>(MockBehavior.Strict);
+ webWorker.Setup(w => w.ProcessUserAuthorization()).Returns(response).Verifiable();
+
+ var client = new MockOAuthClient(webWorker.Object);
+ var context = new Mock<HttpContextBase>();
+
+ // Act
+ AuthenticationResult result = client.VerifyAuthentication(context.Object);
+
+ // Assert
+ webWorker.Verify();
+
+ Assert.True(result.IsSuccessful);
+ Assert.AreEqual("mockoauth", result.Provider);
+ Assert.AreEqual("12345", result.ProviderUserId);
+ Assert.AreEqual("super", result.UserName);
+ }
+
+ private class MockOAuthClient : OAuthClient
+ {
+ public MockOAuthClient()
+ : this(new Mock<IOAuthWebWorker>().Object)
+ {
+ }
+
+ public MockOAuthClient(IOAuthWebWorker worker) : base("mockoauth", worker)
+ {
+ }
+
+ protected override AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response)
+ {
+ if (response.AccessToken == "ok")
+ {
+ return new AuthenticationResult(true, "mockoauth", "12345", "super", response.ExtraData);
+ }
+
+ return AuthenticationResult.Failed;
+ }
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.Web.Test/OAuthWebSecurityTest.cs b/src/DotNetOpenAuth.Web.Test/OAuthWebSecurityTest.cs
new file mode 100644
index 0000000..2465f0f
--- /dev/null
+++ b/src/DotNetOpenAuth.Web.Test/OAuthWebSecurityTest.cs
@@ -0,0 +1,486 @@
+using System;
+using System.Collections.Specialized;
+using System.Web;
+using System.Web.Security;
+using DotNetOpenAuth.Web.Clients;
+using Moq;
+using NUnit.Framework;
+
+namespace DotNetOpenAuth.Web.Test
+{
+ [TestFixture]
+ public class OAuthWebSecurityTest
+ {
+ [TestCase]
+ public void RegisterDataProviderThrowsOnNullValue()
+ {
+ Assert.Throws(typeof(ArgumentNullException), () => OAuthWebSecurity.RegisterDataProvider(null));
+ }
+
+ [TestCase]
+ public void IsOAuthDataProviderIsFalseIfNotYetRegistered()
+ {
+ Assert.IsFalse(OAuthWebSecurity.IsOAuthDataProviderRegistered);
+ }
+
+ [TestCase]
+ public void IsOAuthDataProviderIsTrueIfRegistered()
+ {
+ // Arrange
+ OAuthWebSecurity.RegisterDataProvider(new Mock<IOAuthDataProvider>().Object);
+
+ // Act & Assert
+ Assert.IsTrue(OAuthWebSecurity.IsOAuthDataProviderRegistered);
+ }
+
+ [TestCase]
+ public void RegisterDataProviderThrowsIfRegisterMoreThanOnce()
+ {
+ // Arrange
+ OAuthWebSecurity.RegisterDataProvider(new Mock<IOAuthDataProvider>().Object);
+
+ // Act & Assert
+ Assert.Throws(
+ typeof(InvalidOperationException),
+ () => OAuthWebSecurity.RegisterDataProvider(new Mock<IOAuthDataProvider>().Object));
+ }
+
+ [TestCase]
+ public void RegisterClientThrowsOnNullValue()
+ {
+ Assert.Throws(typeof(ArgumentNullException), () => OAuthWebSecurity.RegisterClient(null));
+ }
+
+ [TestCase]
+ public void RegisterClientThrowsIfProviderNameIsEmpty()
+ {
+ // Arrange
+ var client = new Mock<IAuthenticationClient>();
+ client.Setup(c => c.ProviderName).Returns((string)null);
+
+ // Act & Assert
+ Assert.Throws(typeof(ArgumentException), () => OAuthWebSecurity.RegisterClient(client.Object), "Invalid provider name.");
+
+ client.Setup(c => c.ProviderName).Returns("");
+
+ // Act & Assert
+ Assert.Throws(typeof(ArgumentException), () => OAuthWebSecurity.RegisterClient(client.Object), "Invalid provider name.");
+ }
+
+ [TestCase]
+ public void RegisterClientThrowsRegisterMoreThanOneClientWithTheSameName()
+ {
+ // Arrange
+ var client1 = new Mock<IAuthenticationClient>();
+ client1.Setup(c => c.ProviderName).Returns("provider");
+
+ var client2 = new Mock<IAuthenticationClient>();
+ client2.Setup(c => c.ProviderName).Returns("provider");
+
+ OAuthWebSecurity.RegisterClient(client1.Object);
+
+ // Act & Assert
+ Assert.Throws(
+ typeof(ArgumentException),
+ () => OAuthWebSecurity.RegisterClient(client2.Object),
+ "Another service provider with the same name has already been registered.");
+ }
+
+ [TestCase]
+ public void RegisterOAuthClient()
+ {
+ // Arrange
+ var clients = new BuiltInOAuthClient[]
+ {
+ BuiltInOAuthClient.Facebook,
+ BuiltInOAuthClient.Twitter,
+ BuiltInOAuthClient.LinkedIn,
+ BuiltInOAuthClient.WindowsLive
+ };
+ var clientNames = new string[]
+ {
+ "Facebook",
+ "Twitter",
+ "LinkedIn",
+ "WindowsLive"
+ };
+
+ for (int i = 0; i < clients.Length; i++)
+ {
+ // Act
+ OAuthWebSecurity.RegisterOAuthClient(clients[i], "key", "secret");
+
+ var client = new Mock<IAuthenticationClient>();
+ client.Setup(c => c.ProviderName).Returns(clientNames[i]);
+
+ // Assert
+ Assert.Throws(
+ typeof(ArgumentException),
+ () => OAuthWebSecurity.RegisterClient(client.Object),
+ "Another service provider with the same name has already been registered.");
+ }
+ }
+
+ [TestCase]
+ public void RegisterOpenIDClient()
+ {
+ // Arrange
+ var clients = new BuiltInOpenIDClient[]
+ {
+ BuiltInOpenIDClient.Google,
+ BuiltInOpenIDClient.Yahoo
+ };
+ var clientNames = new string[]
+ {
+ "Google",
+ "Yahoo"
+ };
+
+ for (int i = 0; i < clients.Length; i++)
+ {
+ // Act
+ OAuthWebSecurity.RegisterOpenIDClient(clients[i]);
+
+ var client = new Mock<IAuthenticationClient>();
+ client.Setup(c => c.ProviderName).Returns(clientNames[i]);
+
+ // Assert
+ Assert.Throws(
+ typeof(ArgumentException),
+ () => OAuthWebSecurity.RegisterClient(client.Object),
+ "Another service provider with the same name has already been registered.");
+ }
+ }
+
+ [TestCase]
+ public void RequestAuthenticationRedirectsToProviderWithNullReturnUrl()
+ {
+ // Arrange
+ var context = new Mock<HttpContextBase>();
+ context.Setup(c => c.Request.ServerVariables).Returns(
+ new NameValueCollection());
+ context.Setup(c => c.Request.Url).Returns(new Uri("http://live.com/login.aspx"));
+ context.Setup(c => c.Request.RawUrl).Returns("/login.aspx");
+
+ var client = new Mock<IAuthenticationClient>();
+ client.Setup(c => c.ProviderName).Returns("windowslive");
+ client.Setup(c => c.RequestAuthentication(
+ context.Object,
+ It.Is<Uri>(u => u.AbsoluteUri.Equals("http://live.com/login.aspx?__provider__=windowslive", StringComparison.OrdinalIgnoreCase))))
+ .Verifiable();
+
+ OAuthWebSecurity.RegisterClient(client.Object);
+
+ // Act
+ OAuthWebSecurity.RequestAuthenticationCore(context.Object, "windowslive", null);
+
+ // Assert
+ client.Verify();
+ }
+
+ [TestCase]
+ public void RequestAuthenticationRedirectsToProviderWithReturnUrl()
+ {
+ // Arrange
+ var context = new Mock<HttpContextBase>();
+ context.Setup(c => c.Request.ServerVariables).Returns(
+ new NameValueCollection());
+ context.Setup(c => c.Request.Url).Returns(new Uri("http://live.com/login.aspx"));
+ context.Setup(c => c.Request.RawUrl).Returns("/login.aspx");
+
+ var client = new Mock<IAuthenticationClient>();
+ client.Setup(c => c.ProviderName).Returns("yahoo");
+ client.Setup(c => c.RequestAuthentication(
+ context.Object,
+ It.Is<Uri>(u => u.AbsoluteUri.Equals("http://yahoo.com/?__provider__=yahoo", StringComparison.OrdinalIgnoreCase))))
+ .Verifiable();
+
+ OAuthWebSecurity.RegisterClient(client.Object);
+
+ // Act
+ OAuthWebSecurity.RequestAuthenticationCore(context.Object, "yahoo", "http://yahoo.com");
+
+ // Assert
+ client.Verify();
+ }
+
+ [TestCase]
+ public void VerifyAuthenticationSucceed()
+ {
+ // Arrange
+ var queryStrings = new NameValueCollection();
+ queryStrings.Add("__provider__", "facebook");
+
+ var context = new Mock<HttpContextBase>();
+ context.Setup(c => c.Request.QueryString).Returns(queryStrings);
+
+ var client = new Mock<IAuthenticationClient>(MockBehavior.Strict);
+ client.Setup(c => c.ProviderName).Returns("facebook");
+ client.Setup(c => c.VerifyAuthentication(context.Object)).Returns(new AuthenticationResult(true, "facebook", "123",
+ "super", null));
+
+ var anotherClient = new Mock<IAuthenticationClient>(MockBehavior.Strict);
+ anotherClient.Setup(c => c.ProviderName).Returns("twitter");
+ anotherClient.Setup(c => c.VerifyAuthentication(context.Object)).Returns(AuthenticationResult.Failed);
+
+ OAuthWebSecurity.RegisterClient(client.Object);
+ OAuthWebSecurity.RegisterClient(anotherClient.Object);
+
+ // Act
+ AuthenticationResult result = OAuthWebSecurity.VerifyAuthenticationCore(context.Object);
+
+ // Assert
+ Assert.True(result.IsSuccessful);
+ Assert.AreEqual("facebook", result.Provider);
+ Assert.AreEqual("123", result.ProviderUserId);
+ Assert.AreEqual("super", result.UserName);
+ Assert.IsNull(result.Error);
+ Assert.IsNull(result.ExtraData);
+ }
+
+ [TestCase]
+ public void VerifyAuthenticationFail()
+ {
+ // Arrange
+ var queryStrings = new NameValueCollection();
+ queryStrings.Add("__provider__", "twitter");
+
+ var context = new Mock<HttpContextBase>();
+ context.Setup(c => c.Request.QueryString).Returns(queryStrings);
+
+ var client = new Mock<IAuthenticationClient>(MockBehavior.Strict);
+ client.Setup(c => c.ProviderName).Returns("facebook");
+ client.Setup(c => c.VerifyAuthentication(context.Object)).Returns(new AuthenticationResult(true, "facebook", "123",
+ "super", null));
+
+ var anotherClient = new Mock<IAuthenticationClient>(MockBehavior.Strict);
+ anotherClient.Setup(c => c.ProviderName).Returns("twitter");
+ anotherClient.Setup(c => c.VerifyAuthentication(context.Object)).Returns(AuthenticationResult.Failed);
+
+ OAuthWebSecurity.RegisterClient(client.Object);
+ OAuthWebSecurity.RegisterClient(anotherClient.Object);
+
+ // Act
+ AuthenticationResult result = OAuthWebSecurity.VerifyAuthenticationCore(context.Object);
+
+ // Assert
+ Assert.False(result.IsSuccessful);
+ Assert.AreEqual("twitter", result.Provider);
+ }
+
+ [TestCase]
+ public void VerifyAuthenticationFailIfNoProviderInQueryString()
+ {
+ // Arrange
+ var context = new Mock<HttpContextBase>();
+ context.Setup(c => c.Request.QueryString).Returns(new NameValueCollection());
+
+ var client = new Mock<IAuthenticationClient>(MockBehavior.Strict);
+ client.Setup(c => c.ProviderName).Returns("facebook");
+
+ var anotherClient = new Mock<IAuthenticationClient>(MockBehavior.Strict);
+ anotherClient.Setup(c => c.ProviderName).Returns("twitter");
+
+ OAuthWebSecurity.RegisterClient(client.Object);
+ OAuthWebSecurity.RegisterClient(anotherClient.Object);
+
+ // Act
+ AuthenticationResult result = OAuthWebSecurity.VerifyAuthenticationCore(context.Object);
+
+ // Assert
+ Assert.False(result.IsSuccessful);
+ Assert.IsNull(result.Provider);
+ }
+
+ [TestCase]
+ public void LoginSetAuthenticationTicketIfSuccessful()
+ {
+ // Arrange
+ var cookies = new HttpCookieCollection();
+ var context = new Mock<HttpContextBase>();
+ context.Setup(c => c.Request.IsSecureConnection).Returns(true);
+ context.Setup(c => c.Response.Cookies).Returns(cookies);
+
+ var dataProvider = new Mock<IOAuthDataProvider>(MockBehavior.Strict);
+ dataProvider.Setup(p => p.GetUserNameFromOAuth("twitter", "12345")).Returns("hola");
+ OAuthWebSecurity.RegisterDataProvider(dataProvider.Object);
+
+ // Act
+ bool successful = OAuthWebSecurity.LoginCore(context.Object, "twitter", "12345", createPersistentCookie: false);
+
+ // Assert
+ Assert.IsTrue(successful);
+
+ Assert.AreEqual(1, cookies.Count);
+ HttpCookie addedCookie = cookies[0];
+
+ Assert.AreEqual(FormsAuthentication.FormsCookieName, addedCookie.Name);
+ Assert.IsTrue(addedCookie.HttpOnly);
+ Assert.AreEqual("/", addedCookie.Path);
+ Assert.IsFalse(addedCookie.Secure);
+ Assert.IsNotNullOrEmpty(addedCookie.Value);
+
+ FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(addedCookie.Value);
+ Assert.NotNull(ticket);
+ Assert.AreEqual(2, ticket.Version);
+ Assert.AreEqual("hola", ticket.Name);
+ Assert.AreEqual("OAuth", ticket.UserData);
+ Assert.IsFalse(ticket.IsPersistent);
+ }
+
+ [TestCase]
+ public void LoginFailIfUserIsNotFound()
+ {
+ // Arrange
+ var context = new Mock<HttpContextBase>();
+
+ var dataProvider = new Mock<IOAuthDataProvider>();
+ OAuthWebSecurity.RegisterDataProvider(dataProvider.Object);
+
+ // Act
+ bool successful = OAuthWebSecurity.LoginCore(context.Object, "twitter", "12345", createPersistentCookie: false);
+
+ // Assert
+ Assert.IsFalse(successful);
+ }
+
+ [TestCase]
+ public void CreateOrUpdateAccountCallsOAuthDataProviderMethod()
+ {
+ // Arrange
+ var dataProvider = new Mock<IOAuthDataProvider>(MockBehavior.Strict);
+ OAuthWebSecurity.RegisterDataProvider(dataProvider.Object);
+ dataProvider.Setup(p => p.CreateOrUpdateOAuthAccount("twitter", "12345", "super")).Verifiable();
+
+ // Act
+ OAuthWebSecurity.CreateOrUpdateAccount("twitter", "12345", "super");
+
+ // Assert
+ dataProvider.Verify();
+ }
+
+ [TestCase]
+ public void GetAccountsFromUserNameCallsOAuthDataProviderMethod()
+ {
+ // Arrange
+ var accounts = new OAuthAccount[]
+ {
+ new OAuthAccount("twitter", "123"),
+ new OAuthAccount("facebook", "abc"),
+ new OAuthAccount("live", "xyz")
+ };
+
+ var dataProvider = new Mock<IOAuthDataProvider>(MockBehavior.Strict);
+ dataProvider.Setup(p => p.GetOAuthAccountsFromUserName("dotnetjunky")).Returns(accounts).Verifiable();
+
+ OAuthWebSecurity.RegisterDataProvider(dataProvider.Object);
+
+ // Act
+ var retrievedAccounts = OAuthWebSecurity.GetAccountsFromUserName("dotnetjunky");
+
+ // Assert
+ CollectionAssert.AreEqual(retrievedAccounts, accounts);
+ }
+
+ [TestCase]
+ public void DeleteAccountCallsOAuthDataProviderMethod()
+ {
+ // Arrange
+ var dataProvider = new Mock<IOAuthDataProvider>(MockBehavior.Strict);
+ OAuthWebSecurity.RegisterDataProvider(dataProvider.Object);
+ dataProvider.Setup(p => p.DeleteOAuthAccount("linkedin", "423432")).Returns(true).Verifiable();
+
+ // Act
+ OAuthWebSecurity.DeleteAccount("linkedin", "423432");
+
+ // Assert
+ dataProvider.Verify();
+ }
+
+ [TestCase]
+ public void GetOAuthClientReturnsTheCorrectClient()
+ {
+ // Arrange
+ var client = new Mock<IAuthenticationClient>();
+ client.Setup(c => c.ProviderName).Returns("facebook");
+ OAuthWebSecurity.RegisterClient(client.Object);
+
+ var anotherClient = new Mock<IAuthenticationClient>();
+ anotherClient.Setup(c => c.ProviderName).Returns("hulu");
+ OAuthWebSecurity.RegisterClient(anotherClient.Object);
+
+ // Act
+ var expectedClient = OAuthWebSecurity.GetOAuthClient("facebook");
+
+ // Assert
+ Assert.AreSame(expectedClient, client.Object);
+ }
+
+ [TestCase]
+ public void GetOAuthClientThrowsIfClientIsNotFound()
+ {
+ // Arrange
+ var client = new Mock<IAuthenticationClient>();
+ client.Setup(c => c.ProviderName).Returns("facebook");
+ OAuthWebSecurity.RegisterClient(client.Object);
+
+ var anotherClient = new Mock<IAuthenticationClient>();
+ anotherClient.Setup(c => c.ProviderName).Returns("hulu");
+ OAuthWebSecurity.RegisterClient(anotherClient.Object);
+
+ // Act & Assert
+ Assert.Throws<ArgumentException>(
+ () => OAuthWebSecurity.GetOAuthClient("live"),
+ "A service provider could not be found by the specified name.");
+ }
+
+ [TestCase]
+ public void TryGetOAuthClientSucceeds()
+ {
+ // Arrange
+ var client = new Mock<IAuthenticationClient>();
+ client.Setup(c => c.ProviderName).Returns("facebook");
+ OAuthWebSecurity.RegisterClient(client.Object);
+
+ var anotherClient = new Mock<IAuthenticationClient>();
+ anotherClient.Setup(c => c.ProviderName).Returns("hulu");
+ OAuthWebSecurity.RegisterClient(anotherClient.Object);
+
+ // Act
+ IAuthenticationClient expectedClient;
+ bool result = OAuthWebSecurity.TryGetOAuthClient("facebook", out expectedClient);
+
+ // Assert
+ Assert.AreSame(expectedClient, client.Object);
+ Assert.IsTrue(result);
+ }
+
+ [TestCase]
+ public void TryGetOAuthClientFail()
+ {
+ // Arrange
+ var client = new Mock<IAuthenticationClient>();
+ client.Setup(c => c.ProviderName).Returns("facebook");
+ OAuthWebSecurity.RegisterClient(client.Object);
+
+ var anotherClient = new Mock<IAuthenticationClient>();
+ anotherClient.Setup(c => c.ProviderName).Returns("hulu");
+ OAuthWebSecurity.RegisterClient(anotherClient.Object);
+
+ // Act
+ IAuthenticationClient expectedClient;
+ bool result = OAuthWebSecurity.TryGetOAuthClient("live", out expectedClient);
+
+ // Assert
+ Assert.IsNull(expectedClient);
+ Assert.IsFalse(result);
+ }
+
+ [TearDown]
+ public void Cleanup()
+ {
+ OAuthWebSecurity.ClearDataProvider();
+ OAuthWebSecurity.ClearProviders();
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.Web.Test/Properties/AssemblyInfo.cs b/src/DotNetOpenAuth.Web.Test/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..2ea59e1
--- /dev/null
+++ b/src/DotNetOpenAuth.Web.Test/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("DotNetOpenAuth.Web.Test")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft IT")]
+[assembly: AssemblyProduct("DotNetOpenAuth.Web.Test")]
+[assembly: AssemblyCopyright("Copyright © Microsoft IT 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("6c32d8f7-1394-40ef-9ec0-b8953adc0a4f")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/DotNetOpenAuth.Web.Test/UriHelperTest.cs b/src/DotNetOpenAuth.Web.Test/UriHelperTest.cs
new file mode 100644
index 0000000..557efae
--- /dev/null
+++ b/src/DotNetOpenAuth.Web.Test/UriHelperTest.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using DotNetOpenAuth.Web.Clients;
+
+namespace DotNetOpenAuth.Web.Test
+{
+ [TestFixture]
+ public class UriHelperTest
+ {
+ [TestCase]
+ public void TestAttachQueryStringParameterMethod()
+ {
+ // Arrange
+ string[] input = new string[]
+ {
+ "http://x.com",
+ "https://xxx.com/one?s=123",
+ "https://yyy.com/?s=6&u=a",
+ "https://zzz.com/default.aspx?name=sd"
+ };
+
+ string[] expectedOutput = new string[]
+ {
+ "http://x.com/?s=awesome",
+ "https://xxx.com/one?s=awesome",
+ "https://yyy.com/?s=awesome&u=a",
+ "https://zzz.com/default.aspx?name=sd&s=awesome"
+ };
+
+ for (int i = 0; i < input.Length; i++)
+ {
+ // Act
+ var inputUrl = new Uri(input[i]);
+ var outputUri = UriHelper.AttachQueryStringParameter(inputUrl, "s", "awesome");
+
+ // Assert
+ Assert.AreEqual(expectedOutput[i], outputUri.ToString());
+ }
+ }
+
+ [TestCase]
+ public void TestAppendQueryArguments()
+ {
+ // Arrange
+ var builder = new UriBuilder("http://www.microsoft.com");
+
+ // Act
+ builder.AppendQueryArguments(
+ new Dictionary<string, string> {{"one", "xxx"}, {"two", "yyy"}});
+
+ // Assert
+ if (builder.Port == 80)
+ {
+ // set port = -1 so that the display string doesn't contain port number
+ builder.Port = -1;
+ }
+ string s = builder.ToString();
+ Assert.AreEqual("http://www.microsoft.com/?one=xxx&two=yyy", s);
+ }
+ }
+}