* tests for user provider
* username is no longer required * added ip address property to user
This commit is contained in:
parent
7e042d3b93
commit
9a1f0347c0
@ -1,7 +1,14 @@
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace VideoGameQuotes.Api {
|
||||
/// <summary>
|
||||
/// Provides an interface for identifying the current user
|
||||
/// </summary>
|
||||
public interface ICurrentUserProvider {
|
||||
/// <summary>
|
||||
/// Returns the user currently performing actions on the site, or <c>null</c>
|
||||
/// if the user cannot be identified
|
||||
/// </summary>
|
||||
[CanBeNull]
|
||||
User CurrentUser { get; }
|
||||
}
|
||||
|
@ -6,7 +6,8 @@
|
||||
<generator class="identity" />
|
||||
</id>
|
||||
|
||||
<property name="Username" column="username" not-null="true" type="string" length="50" unique="true"/>
|
||||
<property name="Username" column="username" not-null="false" type="string" length="50"/>
|
||||
<property name="IpAddress" column="ip_address" not-null="false" type="string" length="40"/>
|
||||
<property name="Created" column="created" not-null="true" type="DateTime" />
|
||||
<property name="Group" column="user_group" not-null="true" />
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
</id>
|
||||
|
||||
<property name="Created" column="created" not-null="true" />
|
||||
<property name="Value" column="point_value" not-null="true" />
|
||||
<property name="Direction" column="direction" not-null="true" type="int" length="1" />
|
||||
|
||||
<many-to-one name="Voter" column="voter_id" not-null="true" foreign-key="fk_vote_user"/>
|
||||
<many-to-one name="Quote" column="quote_id" not-null="true" foreign-key="fk_vote_quote" />
|
||||
|
@ -1,11 +1,17 @@
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using NHibernate;
|
||||
using Portoa.NHibernate;
|
||||
using Portoa.Persistence;
|
||||
|
||||
namespace VideoGameQuotes.Api.Persistence {
|
||||
public interface IUserRepository : IRepository<User> {
|
||||
[CanBeNull]
|
||||
User FindByUsername(string name);
|
||||
|
||||
[CanBeNull]
|
||||
User FindByIpAddress(string ipAddress);
|
||||
}
|
||||
|
||||
public class UserRepository : NHibernateRepository<User>, IUserRepository {
|
||||
@ -14,5 +20,9 @@ namespace VideoGameQuotes.Api.Persistence {
|
||||
public User FindByUsername(string name) {
|
||||
return Records.FirstOrDefault(user => user.Username == name);
|
||||
}
|
||||
|
||||
public User FindByIpAddress(string ipAddress) {
|
||||
return Records.FirstOrDefault(user => user.IpAddress == ipAddress);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +1,12 @@
|
||||
using Portoa.Persistence;
|
||||
using System;
|
||||
using Portoa.Persistence;
|
||||
|
||||
namespace VideoGameQuotes.Api.Persistence {
|
||||
|
||||
public interface IUserService {
|
||||
User Save(User user);
|
||||
User FindByUsername(string name);
|
||||
User FindByIpAddress(string ipAddress);
|
||||
}
|
||||
|
||||
public class UserService : IUserService {
|
||||
@ -23,5 +25,10 @@ namespace VideoGameQuotes.Api.Persistence {
|
||||
public User FindByUsername(string name) {
|
||||
return repository.FindByUsername(name);
|
||||
}
|
||||
|
||||
[UnitOfWork]
|
||||
public User FindByIpAddress(string ipAddress) {
|
||||
return repository.FindByIpAddress(ipAddress);
|
||||
}
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ namespace VideoGameQuotes.Api {
|
||||
|
||||
public virtual DateTime Created { get; set; }
|
||||
public virtual string Username { get; set; }
|
||||
public virtual string IpAddress { get; set; }
|
||||
public virtual UserGroup Group { get; set; }
|
||||
|
||||
public virtual void ChangePassword([DoNotLog]string newPassword) {
|
||||
|
@ -18,7 +18,7 @@ namespace VideoGameQuotes.Web {
|
||||
|
||||
Container
|
||||
.AddNewExtension<LogAllMethodCalls>()
|
||||
.RegisterType<ICurrentUserProvider, UserProvider>()
|
||||
.RegisterType<ICurrentUserProvider, SessionBasedUserProvider>()
|
||||
.RegisterType<IUserService, UserService>()
|
||||
.RegisterType<IUserRepository, UserRepository>();
|
||||
}
|
||||
|
@ -4,12 +4,12 @@ using VideoGameQuotes.Api;
|
||||
using VideoGameQuotes.Api.Persistence;
|
||||
|
||||
namespace VideoGameQuotes.Web.Security {
|
||||
public class UserProvider : ICurrentUserProvider {
|
||||
public class SessionBasedUserProvider : ICurrentUserProvider {
|
||||
private readonly IUserService userService;
|
||||
private readonly ISessionStore sessionStore;
|
||||
private readonly HttpContextBase httpContext;
|
||||
|
||||
public UserProvider(IUserService userService, ISessionStore sessionStore, HttpContextBase httpContext) {
|
||||
public SessionBasedUserProvider(IUserService userService, ISessionStore sessionStore, HttpContextBase httpContext) {
|
||||
this.userService = userService;
|
||||
this.sessionStore = sessionStore;
|
||||
this.httpContext = httpContext;
|
||||
@ -21,15 +21,15 @@ namespace VideoGameQuotes.Web.Security {
|
||||
|
||||
if (user == null) {
|
||||
//identify user by IP address
|
||||
var username = httpContext.Request.UserHostAddress;
|
||||
if (string.IsNullOrEmpty(username)) {
|
||||
var ipAddress = httpContext.Request.UserHostAddress;
|
||||
if (string.IsNullOrEmpty(ipAddress)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
user = userService.FindByUsername(username);
|
||||
user = userService.FindByIpAddress(ipAddress);
|
||||
if (user == null) {
|
||||
user = new User {
|
||||
Username = username,
|
||||
IpAddress = ipAddress,
|
||||
Group = UserGroup.User
|
||||
};
|
||||
|
@ -86,7 +86,7 @@
|
||||
<DependentUpon>Default.aspx</DependentUpon>
|
||||
<SubType>ASPXCodeBehind</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Security\UserProvider.cs" />
|
||||
<Compile Include="Security\SessionBasedUserProvider.cs" />
|
||||
<Compile Include="Global.asax.cs">
|
||||
<DependentUpon>Global.asax</DependentUpon>
|
||||
</Compile>
|
||||
|
@ -34,6 +34,9 @@
|
||||
<Reference Include="log4net">
|
||||
<HintPath>..\..\Lib\log4net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Moq">
|
||||
<HintPath>..\..\Lib\Moq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MySql.Data">
|
||||
<HintPath>..\..\Lib\MySql.Data.dll</HintPath>
|
||||
</Reference>
|
||||
|
36
Tests/VideoGameQuotes.Web.Tests/Properties/AssemblyInfo.cs
Normal file
36
Tests/VideoGameQuotes.Web.Tests/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
||||
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("VideoGameQuotes.Web.Tests")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("VideoGameQuotes.Web.Tests")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft 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("2e52aa26-c170-44ad-801f-3ee9d6aa3fcd")]
|
||||
|
||||
// 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: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
48
Tests/VideoGameQuotes.Web.Tests/UserProviderTests.cs
Normal file
48
Tests/VideoGameQuotes.Web.Tests/UserProviderTests.cs
Normal file
@ -0,0 +1,48 @@
|
||||
using System.Web;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Portoa.Web.Session;
|
||||
using VideoGameQuotes.Api;
|
||||
using VideoGameQuotes.Api.Persistence;
|
||||
using VideoGameQuotes.Web.Security;
|
||||
|
||||
namespace VideoGameQuotes.Web.Tests {
|
||||
[TestFixture]
|
||||
public class UserProviderTests {
|
||||
[Test]
|
||||
public void Should_use_user_in_session_store() {
|
||||
var session = new Mock<ISessionStore>();
|
||||
var user = new User();
|
||||
session.SetupGet(s => s["user"]).Returns(user).Verifiable();
|
||||
|
||||
var userProvider = new SessionBasedUserProvider(new Mock<IUserService>().Object, session.Object, new Mock<HttpContextBase>().Object);
|
||||
|
||||
Assert.That(userProvider.CurrentUser, Is.EqualTo(user));
|
||||
session.VerifyAll();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Should_identify_user_using_ip_address() {
|
||||
var session = new Mock<ISessionStore>();
|
||||
session.SetupGet(s => s["user"]).Returns(null);
|
||||
|
||||
var httpContext = new Mock<HttpContextBase>();
|
||||
var httpRequest = new Mock<HttpRequestBase>();
|
||||
httpRequest.SetupGet(req => req.UserHostAddress).Returns("10.4.60.120");
|
||||
httpContext.SetupGet(ctx => ctx.Request).Returns(httpRequest.Object);
|
||||
|
||||
|
||||
var userService = new Mock<IUserService>();
|
||||
userService.Setup(service => service.Save(It.IsAny<User>())).Callback<User>(user => {
|
||||
Assert.That(user, Is.Not.Null);
|
||||
Assert.That(user.Username, Is.Null);
|
||||
Assert.That(user.IpAddress, Is.EqualTo("10.4.60.120"));
|
||||
Assert.That(user.Group, Is.EqualTo(UserGroup.User));
|
||||
}).Returns(new User { Id = 1 });
|
||||
|
||||
var userProvider = new SessionBasedUserProvider(userService.Object, session.Object, httpContext.Object);
|
||||
|
||||
Assert.That(userProvider.CurrentUser, Is.EqualTo(new User { Id = 1 }));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{5787E8CA-072D-4231-B34A-B4C92BEEA3E7}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>VideoGameQuotes.Web.Tests</RootNamespace>
|
||||
<AssemblyName>VideoGameQuotes.Web.Tests</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>
|
||||
<ItemGroup>
|
||||
<Reference Include="Moq">
|
||||
<HintPath>..\..\Lib\Moq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="nunit.framework">
|
||||
<HintPath>..\..\Lib\nunit.framework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Portoa">
|
||||
<HintPath>..\..\Lib\Portoa.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Portoa.Web">
|
||||
<HintPath>..\..\Lib\Portoa.Web.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="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="UserProviderTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Src\VideoGameQuotes.Api\VideoGameQuotes.Api.csproj">
|
||||
<Project>{329FAB1F-A18D-4B7B-9E3C-A0C157E55503}</Project>
|
||||
<Name>VideoGameQuotes.Api</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\Src\VideoGameQuotes.Web\VideoGameQuotes.Web.csproj">
|
||||
<Project>{5D576303-EEB3-409B-80E2-FC221C23D7BF}</Project>
|
||||
<Name>VideoGameQuotes.Web</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VideoGameQuotes.Api.Tests",
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VideoGameQuotes.Web", "Src\VideoGameQuotes.Web\VideoGameQuotes.Web.csproj", "{5D576303-EEB3-409B-80E2-FC221C23D7BF}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VideoGameQuotes.Web.Tests", "Tests\VideoGameQuotes.Web.Tests\VideoGameQuotes.Web.Tests.csproj", "{5787E8CA-072D-4231-B34A-B4C92BEEA3E7}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -25,6 +27,10 @@ Global
|
||||
{5D576303-EEB3-409B-80E2-FC221C23D7BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5D576303-EEB3-409B-80E2-FC221C23D7BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5D576303-EEB3-409B-80E2-FC221C23D7BF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5787E8CA-072D-4231-B34A-B4C92BEEA3E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5787E8CA-072D-4231-B34A-B4C92BEEA3E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5787E8CA-072D-4231-B34A-B4C92BEEA3E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5787E8CA-072D-4231-B34A-B4C92BEEA3E7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
Loading…
Reference in New Issue
Block a user