Skip to content

Commit 6bbd082

Browse files
committed
Implement IUserLoginStore
- update nuspec for deploy 1.0.1
1 parent 4947a14 commit 6bbd082

File tree

7 files changed

+173
-6
lines changed

7 files changed

+173
-6
lines changed

src/AspNet.Identity.MongoDB/AspNet.Identity.MongoDB.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
<Compile Include="UserStore.cs" />
5858
</ItemGroup>
5959
<ItemGroup>
60+
<None Include="AspNet.Identity.MongoDB.nuspec" />
6061
<None Include="packages.config" />
6162
</ItemGroup>
6263
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

src/AspNet.Identity.MongoDB/AspNet.Identity.MongoDB.nuspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
<package >
33
<metadata>
44
<id>AspNet.Identity.MongoDB</id>
5-
<version>1.0.0-alpha1</version>
5+
<version>1.0.1-alpha1</version>
66
<authors>Wes McClure</authors>
77
<owners>Wes McClure</owners>
88
<licenseUrl>https://github.com/g0t4/aspnet-identity-mongo/blob/master/LICENSE</licenseUrl>
99
<projectUrl>https://github.com/g0t4/aspnet-identity-mongo</projectUrl>
1010
<iconUrl>https://github.com/g0t4/aspnet-identity-mongo</iconUrl>
1111
<requireLicenseAcceptance>false</requireLicenseAcceptance>
1212
<description>A mongodb provider for the new ASP.NET Identity framework. My aim is to ensure this project is well tested and configurable.</description>
13-
<releaseNotes>Initial release</releaseNotes>
13+
<releaseNotes>Adding IUserLoginStore, IUserRoleStore and IUserPasswordStore interfaces.</releaseNotes>
1414
<copyright>MIT</copyright>
1515
<tags>mongo mongodb aspnet identity</tags>
1616
</metadata>

src/AspNet.Identity.MongoDB/IdentityUser.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace AspNet.Identity.MongoDB
22
{
33
using System.Collections.Generic;
4+
using System.Linq;
45
using global::MongoDB.Bson;
56
using global::MongoDB.Bson.Serialization.Attributes;
67
using Microsoft.AspNet.Identity;
@@ -11,6 +12,7 @@ public IdentityUser()
1112
{
1213
Id = ObjectId.GenerateNewId().ToString();
1314
Roles = new List<string>();
15+
Logins = new List<UserLoginInfo>();
1416
}
1517

1618
[BsonRepresentation(BsonType.ObjectId)]
@@ -34,6 +36,23 @@ public virtual void RemoveRole(string role)
3436
[BsonIgnoreIfNull]
3537
public virtual string PasswordHash { get; set; }
3638

39+
[BsonIgnoreIfNull]
40+
public List<UserLoginInfo> Logins { get; set; }
41+
42+
public virtual void AddLogin(UserLoginInfo login)
43+
{
44+
Logins.Add(login);
45+
}
46+
47+
public virtual void RemoveLogin(UserLoginInfo login)
48+
{
49+
var loginsToRemove = Logins
50+
.Where(l => l.LoginProvider == login.LoginProvider)
51+
.Where(l => l.ProviderKey == login.ProviderKey);
52+
53+
Logins = Logins.Except(loginsToRemove).ToList();
54+
}
55+
3756
public virtual bool HasPassword()
3857
{
3958
return false;

src/AspNet.Identity.MongoDB/UserStore.cs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
namespace AspNet.Identity.MongoDB
22
{
33
using System.Collections.Generic;
4+
using System.Linq;
45
using System.Threading.Tasks;
56
using global::MongoDB.Bson;
67
using global::MongoDB.Driver.Builders;
8+
using global::MongoDB.Driver.Linq;
79
using Microsoft.AspNet.Identity;
810

9-
public class UserStore<TUser> : IUserStore<TUser>, IUserPasswordStore<TUser>, IUserRoleStore<TUser>
11+
public class UserStore<TUser> : IUserStore<TUser>, IUserPasswordStore<TUser>, IUserRoleStore<TUser>, IUserLoginStore<TUser>
1012
where TUser : IdentityUser
1113
{
1214
private readonly IdentityContext _Context;
@@ -86,5 +88,30 @@ public Task<bool> IsInRoleAsync(TUser user, string roleName)
8688
{
8789
return Task.FromResult(user.Roles.Contains(roleName));
8890
}
91+
92+
public Task AddLoginAsync(TUser user, UserLoginInfo login)
93+
{
94+
user.AddLogin(login);
95+
return Task.FromResult(0);
96+
}
97+
98+
public Task RemoveLoginAsync(TUser user, UserLoginInfo login)
99+
{
100+
user.RemoveLogin(login);
101+
return Task.FromResult(0);
102+
}
103+
104+
public Task<IList<UserLoginInfo>> GetLoginsAsync(TUser user)
105+
{
106+
return Task.FromResult((IList<UserLoginInfo>) user.Logins);
107+
}
108+
109+
public Task<TUser> FindAsync(UserLoginInfo login)
110+
{
111+
return Task.Factory
112+
.StartNew(() => _Context.Users.AsQueryable<TUser>()
113+
.FirstOrDefault(u => u.Logins
114+
.Any(l => l.LoginProvider == login.LoginProvider && l.ProviderKey == login.ProviderKey)));
115+
}
89116
}
90117
}

src/IntegrationTests/IntegrationTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
<Compile Include="IdentityUserTests.cs" />
6262
<Compile Include="Properties\AssemblyInfo.cs" />
6363
<Compile Include="UserIntegrationTestsBase.cs" />
64+
<Compile Include="UserLoginStoreTests.cs" />
6465
<Compile Include="UserPasswordStoreTests.cs" />
6566
<Compile Include="UserRoleStoreTests.cs" />
6667
<Compile Include="UserStoreTests.cs" />
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
namespace IntegrationTests
2+
{
3+
using System.Linq;
4+
using AspNet.Identity.MongoDB;
5+
using Microsoft.AspNet.Identity;
6+
using NUnit.Framework;
7+
8+
[TestFixture]
9+
public class UserLoginStoreTests : UserIntegrationTestsBase
10+
{
11+
[Test]
12+
public void AddLogin_NewLogin_Adds()
13+
{
14+
var manager = GetUserManager();
15+
var login = new UserLoginInfo("provider", "key");
16+
var user = new IdentityUser {UserName = "bob"};
17+
manager.Create(user);
18+
19+
manager.AddLogin(user.Id, login);
20+
21+
var savedLogin = Users.FindAll().Single().Logins.Single();
22+
Expect(savedLogin.LoginProvider, Is.EqualTo("provider"));
23+
Expect(savedLogin.ProviderKey, Is.EqualTo("key"));
24+
}
25+
26+
27+
[Test]
28+
public void RemoveLogin_NewLogin_Removes()
29+
{
30+
var manager = GetUserManager();
31+
var login = new UserLoginInfo("provider", "key");
32+
var user = new IdentityUser {UserName = "bob"};
33+
manager.Create(user);
34+
manager.AddLogin(user.Id, login);
35+
36+
manager.RemoveLogin(user.Id, login);
37+
38+
var savedUser = Users.FindAll().Single();
39+
Expect(savedUser.Logins, Is.Empty);
40+
}
41+
42+
[Test]
43+
public void GetLogins_OneLogin_ReturnsLogin()
44+
{
45+
var manager = GetUserManager();
46+
var login = new UserLoginInfo("provider", "key");
47+
var user = new IdentityUser {UserName = "bob"};
48+
manager.Create(user);
49+
manager.AddLogin(user.Id, login);
50+
51+
var logins = manager.GetLogins(user.Id);
52+
53+
var savedLogin = logins.Single();
54+
Expect(savedLogin.LoginProvider, Is.EqualTo("provider"));
55+
Expect(savedLogin.ProviderKey, Is.EqualTo("key"));
56+
}
57+
58+
[Test]
59+
public void Find_UserWithLogin_FindsUser()
60+
{
61+
var manager = GetUserManager();
62+
var login = new UserLoginInfo("provider", "key");
63+
var user = new IdentityUser {UserName = "bob"};
64+
manager.Create(user);
65+
manager.AddLogin(user.Id, login);
66+
67+
var findUser = manager.Find(login);
68+
69+
Expect(findUser, Is.Not.Null);
70+
}
71+
72+
[Test]
73+
public void Find_UserWithDifferentKey_DoesNotFindUser()
74+
{
75+
var manager = GetUserManager();
76+
var login = new UserLoginInfo("provider", "key");
77+
var user = new IdentityUser {UserName = "bob"};
78+
manager.Create(user);
79+
manager.AddLogin(user.Id, login);
80+
81+
var findUser = manager.Find(new UserLoginInfo("provider", "otherkey"));
82+
83+
Expect(findUser, Is.Null);
84+
}
85+
86+
[Test]
87+
public void Find_UserWithDifferentProvider_DoesNotFindUser()
88+
{
89+
var manager = GetUserManager();
90+
var login = new UserLoginInfo("provider", "key");
91+
var user = new IdentityUser {UserName = "bob"};
92+
manager.Create(user);
93+
manager.AddLogin(user.Id, login);
94+
95+
var findUser = manager.Find(new UserLoginInfo("otherprovider", "key"));
96+
97+
Expect(findUser, Is.Null);
98+
}
99+
}
100+
}

src/Tests/IdentityUserTests.cs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
namespace Tests
22
{
3-
using System.Collections.Generic;
43
using AspNet.Identity.MongoDB;
54
using MongoDB.Bson;
65
using NUnit.Framework;
@@ -60,7 +59,27 @@ public void Create_NullRoles_DoesNotSerializeRoles()
6059

6160
Expect(document.Contains("Roles"), Is.False);
6261
}
63-
64-
// todo consider if we want to not serialize the empty Roles array
62+
63+
// todo consider if we want to not serialize the empty Roles array, also empty Logins array
64+
65+
[Test]
66+
public void Create_NewIdentityUser_LoginsNotNull()
67+
{
68+
var user = new IdentityUser();
69+
70+
Expect(user.Logins, Is.Not.Null);
71+
}
72+
73+
[Test]
74+
public void Create_NullLogins_DoesNotSerializeLogins()
75+
{
76+
// serialized nulls can cause havoc in deserialization, overwriting the constructor's initial empty list
77+
var user = new IdentityUser();
78+
user.Logins = null;
79+
80+
var document = user.ToBsonDocument();
81+
82+
Expect(document.Contains("Logins"), Is.False);
83+
}
6584
}
6685
}

0 commit comments

Comments
 (0)