Skip to content

Commit c58e5bb

Browse files
committed
Added sample for testing authorized requests (#81)
1 parent 9b1015a commit c58e5bb

File tree

13 files changed

+133
-13
lines changed

13 files changed

+133
-13
lines changed

samples/Books Web API/Books.Api/App_Start/IdentityConfig.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace Books.Api
99
{
1010
using Books.Models;
1111
using Data;
12+
using Infrastructure;
1213

1314
// Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application.
1415

@@ -21,7 +22,9 @@ public ApplicationUserManager(IUserStore<Author> store)
2122

2223
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
2324
{
24-
var manager = new ApplicationUserManager(new UserStore<Author>(context.Get<BooksDbContext>()));
25+
var manager = ObjectFactory.TryGetInstance<ApplicationUserManager>() ??
26+
new ApplicationUserManager(new UserStore<Author>(context.Get<BooksDbContext>()));
27+
2528
// Configure validation logic for usernames
2629
manager.UserValidator = new UserValidator<Author>(manager)
2730
{
@@ -32,10 +35,10 @@ public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUs
3235
manager.PasswordValidator = new PasswordValidator
3336
{
3437
RequiredLength = 6,
35-
RequireNonLetterOrDigit = true,
36-
RequireDigit = true,
37-
RequireLowercase = true,
38-
RequireUppercase = true,
38+
RequireNonLetterOrDigit = false,
39+
RequireDigit = false,
40+
RequireLowercase = false,
41+
RequireUppercase = false,
3942
};
4043
var dataProtectionProvider = options.DataProtectionProvider;
4144
if (dataProtectionProvider != null)

samples/Books Web API/Books.Api/App_Start/NinjectConfig.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ namespace Books.Api
66
using System;
77
using System.Web;
88
using Data;
9+
using Infrastructure;
910
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
1011

1112
using Ninject;
@@ -53,6 +54,7 @@ public static IKernel CreateKernel()
5354
RebindAction(kernel);
5455
}
5556

57+
ObjectFactory.Initialize(kernel);
5658
return kernel;
5759
}
5860
catch

samples/Books Web API/Books.Api/Books.Api.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@
245245
<Compile Include="Global.asax.cs">
246246
<DependentUpon>Global.asax</DependentUpon>
247247
</Compile>
248+
<Compile Include="Infrastructure\ObjectFactory.cs" />
248249
<Compile Include="Mappings\IHaveCustomMappings.cs" />
249250
<Compile Include="Mappings\IMapFrom.cs" />
250251
<Compile Include="Models\AccountBindingModels.cs" />

samples/Books Web API/Books.Api/Controllers/AccountController.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,9 @@ public AccountController()
3232
{
3333
}
3434

35-
public AccountController(ApplicationUserManager userManager,
36-
ISecureDataFormat<AuthenticationTicket> accessTokenFormat)
35+
public AccountController(ApplicationUserManager userManager)
3736
{
3837
UserManager = userManager;
39-
AccessTokenFormat = accessTokenFormat;
4038
}
4139

4240
public ApplicationUserManager UserManager
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
namespace Books.Api.Infrastructure
2+
{
3+
using Ninject;
4+
5+
public static class ObjectFactory
6+
{
7+
public static IKernel standartKernel;
8+
9+
public static void Initialize(IKernel kernel)
10+
{
11+
standartKernel = kernel;
12+
}
13+
14+
public static T TryGetInstance<T>()
15+
{
16+
return standartKernel.TryGet<T>();
17+
}
18+
}
19+
}

samples/Books Web API/Books.Api/Startup.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ public void Configuration(IAppBuilder app)
1616
{
1717
AutoMapperConfig.RegisterMappings(Assembly.GetExecutingAssembly());
1818

19+
app.UseNinjectMiddleware(NinjectConfig.CreateKernel);
20+
1921
ConfigureAuth(app);
2022

2123
var config = new HttpConfiguration();
2224

2325
WebApiConfig.Register(config);
2426

25-
app
26-
.UseNinjectMiddleware(NinjectConfig.CreateKernel)
27-
.UseNinjectWebApi(config);
27+
app.UseNinjectWebApi(config);
2828
}
2929
}
3030
}

samples/Books Web API/Books.Api/Web.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
1010
</configSections>
1111
<connectionStrings>
12-
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-Books.Api-20150901121637.mdf;Initial Catalog=aspnet-Books.Api-20150901121637;Integrated Security=True" providerName="System.Data.SqlClient" />
12+
<add name="DefaultConnection" connectionString="Data Source=.;Initial Catalog=BooksTestingApp;Integrated Security=True" providerName="System.Data.SqlClient" />
1313
</connectionStrings>
1414
<appSettings></appSettings>
1515
<system.web>

samples/Books Web API/Books.Tests/ApiTests/IntegrationTests/BooksControllerIntegrationTests.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,19 @@
66
using Api;
77
using Api.Models.ResponseModels;
88
using Data;
9+
using Microsoft.Owin.Security;
910
using Mocks;
1011
using Models;
1112
using MyTested.WebApi;
1213
using MyTested.WebApi.Builders.Contracts.Servers;
14+
using Newtonsoft.Json.Linq;
1315
using NUnit.Framework;
1416

1517
[TestFixture]
1618
public class BooksControllerIntegrationTests
1719
{
1820
private IServerBuilder server;
21+
private string accessToken;
1922

2023
[TestFixtureSetUp]
2124
public void Init()
@@ -24,10 +27,13 @@ public void Init()
2427
{
2528
kernel.Rebind<IRepository<Book>>().ToConstant(MocksFactory.BooksRepository);
2629
kernel.Rebind<IRepository<Author>>().ToConstant(MocksFactory.AuthorsRepository);
30+
kernel.Rebind<ApplicationUserManager>().ToConstant(MocksFactory.ApplicationUserManager);
2731
};
2832

2933
MyWebApi.Server().Starts<Startup>();
3034
this.server = MyWebApi.Server().Working();
35+
36+
this.GetAccessToken();
3137
}
3238

3339
[Test]
@@ -43,10 +49,38 @@ public void BooksControllerShouldReturnCorrectBooksForUnauthorizedUsers()
4349
.Passing(m => m.Count == 3);
4450
}
4551

52+
[Test]
53+
public void BooksControllerShouldReturnCorrectBooksForAuthorizedUsers()
54+
{
55+
server
56+
.WithHttpRequestMessage(req => req
57+
.WithRequestUri("/api/Books/Get")
58+
.WithMethod(HttpMethod.Get)
59+
.WithHeader("Authorization", "Bearer " + this.accessToken))
60+
.ShouldReturnHttpResponseMessage()
61+
.WithStatusCode(HttpStatusCode.OK)
62+
.WithResponseModelOfType<List<BookResponseModel>>()
63+
.Passing(m => m.Count == 10);
64+
}
65+
4666
[TestFixtureTearDown]
4767
public void TearDown()
4868
{
4969
MyWebApi.Server().Stops();
5070
}
71+
72+
private void GetAccessToken()
73+
{
74+
var message = server
75+
.WithHttpRequestMessage(req => req
76+
.WithRequestUri("/token")
77+
.WithMethod(HttpMethod.Post)
78+
.WithFormUrlEncodedContent("username=TestAuthor@test.com&password=testpass&grant_type=password"))
79+
.ShouldReturnHttpResponseMessage()
80+
.AndProvideTheHttpResponseMessage();
81+
82+
var result = JObject.Parse(message.Content.ReadAsStringAsync().Result);
83+
this.accessToken = (string)result["access_token"];
84+
}
5185
}
5286
}

samples/Books Web API/Books.Tests/Books.Tests.csproj

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@
4646
<HintPath>..\packages\Microsoft.AspNet.Identity.EntityFramework.2.2.1\lib\net45\Microsoft.AspNet.Identity.EntityFramework.dll</HintPath>
4747
<Private>True</Private>
4848
</Reference>
49+
<Reference Include="Microsoft.AspNet.Identity.Owin, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
50+
<HintPath>..\packages\Microsoft.AspNet.Identity.Owin.2.2.1\lib\net45\Microsoft.AspNet.Identity.Owin.dll</HintPath>
51+
<Private>True</Private>
52+
</Reference>
4953
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
5054
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
5155
<Private>True</Private>
@@ -58,6 +62,18 @@
5862
<HintPath>..\packages\Microsoft.Owin.Hosting.3.0.1\lib\net45\Microsoft.Owin.Hosting.dll</HintPath>
5963
<Private>True</Private>
6064
</Reference>
65+
<Reference Include="Microsoft.Owin.Security, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
66+
<HintPath>..\packages\Microsoft.Owin.Security.3.0.1\lib\net45\Microsoft.Owin.Security.dll</HintPath>
67+
<Private>True</Private>
68+
</Reference>
69+
<Reference Include="Microsoft.Owin.Security.Cookies, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
70+
<HintPath>..\packages\Microsoft.Owin.Security.Cookies.3.0.1\lib\net45\Microsoft.Owin.Security.Cookies.dll</HintPath>
71+
<Private>True</Private>
72+
</Reference>
73+
<Reference Include="Microsoft.Owin.Security.OAuth, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
74+
<HintPath>..\packages\Microsoft.Owin.Security.OAuth.3.0.1\lib\net45\Microsoft.Owin.Security.OAuth.dll</HintPath>
75+
<Private>True</Private>
76+
</Reference>
6177
<Reference Include="Microsoft.Owin.Testing, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
6278
<HintPath>..\packages\Microsoft.Owin.Testing.3.0.1\lib\net45\Microsoft.Owin.Testing.dll</HintPath>
6379
<Private>True</Private>
@@ -108,6 +124,7 @@
108124
<Compile Include="ApiTests\ControllerTests\BooksControllerTests.cs" />
109125
<Compile Include="ApiTests\IntegrationTests\BooksControllerIntegrationTests.cs" />
110126
<Compile Include="ApiTests\RouteTests\BookControllerRouteTests.cs" />
127+
<Compile Include="Mocks\Identity\ApplicationUserManagerMock.cs" />
111128
<Compile Include="Mocks\MocksFactory.cs" />
112129
<Compile Include="Mocks\Repositories\AuthorsRepositoryMock.cs" />
113130
<Compile Include="Mocks\Repositories\BooksRepositoryMock.cs" />
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
namespace Books.Tests.Mocks.Identity
2+
{
3+
using System.Security.Claims;
4+
using System.Threading.Tasks;
5+
using Api;
6+
using Microsoft.AspNet.Identity;
7+
using Models;
8+
using Moq;
9+
10+
public class ApplicationUserManagerMock
11+
{
12+
public static ApplicationUserManager Create()
13+
{
14+
// create our mocked user
15+
var user = new Author { UserName = "TestAuthor", Email = "TestAuthor@test.com" };
16+
17+
// mock the application user manager with mocked user store
18+
var mockedUserStore = new Mock<IUserStore<Author>>();
19+
var applicationUserManager = new Mock<ApplicationUserManager>(mockedUserStore.Object);
20+
21+
// mock the application user manager to always return our user object with any username and password
22+
applicationUserManager.Setup(x => x.FindAsync(It.IsAny<string>(), It.IsAny<string>()))
23+
.Returns(Task.FromResult(user));
24+
25+
// mock the application user manager create identity in order to generate valid access token when requested
26+
applicationUserManager.Setup(x => x.CreateIdentityAsync(It.IsAny<Author>(), It.IsAny<string>()))
27+
.Returns<Author, string>(
28+
(author, password) =>
29+
Task.FromResult(new ClaimsIdentity(new[] {new Claim(ClaimTypes.Name, author.UserName)},
30+
DefaultAuthenticationTypes.ApplicationCookie)));
31+
32+
return applicationUserManager.Object;
33+
}
34+
}
35+
}

0 commit comments

Comments
 (0)