From 061d42c2c276eea55d97a66f4f465445d8bb9fcb Mon Sep 17 00:00:00 2001 From: Jonathan Sheely Date: Thu, 13 Feb 2014 23:47:30 -0500 Subject: [PATCH 1/7] Updated the UserStore and Entities to v2. Need to address how to handle the TKey for Bson ObjectId --- IdentityRole.cs | 42 +++++++++++ IdentityUser.cs | 87 +++++++++++++--------- IdentityUserClaim.cs | 46 ++++++++++++ IdentityUserLogin.cs | 34 +++++++++ IdentityUserRole.cs | 30 ++++++++ MongoDB.AspNet.Identity.csproj | 5 +- UserStore.cs | 128 ++++++++++++++++++++++++++++++++- packages.config | 2 +- 8 files changed, 336 insertions(+), 38 deletions(-) create mode 100644 IdentityRole.cs create mode 100644 IdentityUserClaim.cs create mode 100644 IdentityUserLogin.cs create mode 100644 IdentityUserRole.cs diff --git a/IdentityRole.cs b/IdentityRole.cs new file mode 100644 index 0000000..3a6494c --- /dev/null +++ b/IdentityRole.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Microsoft.AspNet.Identity; + +namespace MongoDB.AspNet.Identity +{ + public class IdentityRole : IdentityRole + { + public IdentityRole() + { + base.Id = Guid.NewGuid().ToString(); + } + + public IdentityRole(string roleName) + : this() + { + base.Name = roleName; + } + } + + + public class IdentityRole : IRole + where TUserRole : IdentityUserRole + { + public TKey Id { get; set; } + public string Name { get; set; } + + public ICollection Users { get; set; } + + public virtual ICollection GetUsers() + { + return Users; + } + + public IdentityRole() + { + Users = new List(); + } + + } +} \ No newline at end of file diff --git a/IdentityUser.cs b/IdentityUser.cs index aa31b8c..f8b5cb7 100644 --- a/IdentityUser.cs +++ b/IdentityUser.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Microsoft.AspNet.Identity; using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; @@ -6,10 +7,30 @@ namespace MongoDB.AspNet.Identity { + + public class IdentityUser : IdentityUser, IUser, IUser + { + public IdentityUser() + { + this.Id = Guid.NewGuid().ToString(); + } + + public IdentityUser(string userName) + : this() + { + this.UserName = userName; + } + } + + + /// /// Class IdentityUser. /// - public class IdentityUser : IUser + public class IdentityUser : IUser + where TLogin : IdentityUserLogin + where TRole : IdentityUserRole + where TClaim : IdentityUserClaim { /// /// Unique key for the user @@ -18,7 +39,7 @@ public class IdentityUser : IUser /// The unique key for the user [BsonId] [BsonRepresentation(BsonType.ObjectId)] - public virtual string Id { get; set; } + public virtual TKey Id { get; set; } /// /// Gets or sets the name of the user. /// @@ -50,6 +71,36 @@ public class IdentityUser : IUser /// The logins. public virtual List Logins { get; private set; } + /// + /// Gets or sets a value indicating whether [two factor enabled]. + /// + /// true if [two factor enabled]; otherwise, false. + public virtual bool TwoFactorEnabled { get; set; } + + /// + /// Gets or sets the phone number. + /// + /// The phone number. + public virtual string PhoneNumber { get; set; } + + /// + /// Gets or sets a value indicating whether [phone number confirmed]. + /// + /// true if [phone number confirmed]; otherwise, false. + public virtual bool PhoneNumberConfirmed { get; set; } + + /// + /// Gets or sets the email. + /// + /// The email. + public virtual string Email { get; set; } + + /// + /// Gets or sets a value indicating whether [email confirmed]. + /// + /// true if [email confirmed]; otherwise, false. + public virtual bool EmailConfirmed { get; set; } + /// /// Initializes a new instance of the class. /// @@ -70,33 +121,5 @@ public IdentityUser(string userName) : this() } } - /// - /// Class IdentityUserClaim. - /// - public class IdentityUserClaim - { - /// - /// Gets or sets the identifier. - /// - /// The identifier. - [BsonId] - [BsonRepresentation(BsonType.ObjectId)] - public virtual string Id { get; set; } - /// - /// Gets or sets the user identifier. - /// - /// The user identifier. - public virtual string UserId { get; set; } - /// - /// Gets or sets the type of the claim. - /// - /// The type of the claim. - public virtual string ClaimType { get; set; } - /// - /// Gets or sets the claim value. - /// - /// The claim value. - public virtual string ClaimValue { get; set; } - - } + } diff --git a/IdentityUserClaim.cs b/IdentityUserClaim.cs new file mode 100644 index 0000000..af08fc3 --- /dev/null +++ b/IdentityUserClaim.cs @@ -0,0 +1,46 @@ +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; + +namespace MongoDB.AspNet.Identity +{ + + + /// + /// Class IdentityUserClaim. + /// + public class IdentityUserClaim : IdentityUserClaim + { + + } + + /// + /// Class IdentityUserClaim. + /// + public class IdentityUserClaim + { + /// + /// Gets or sets the identifier. + /// + /// The identifier. + [BsonId] + [BsonRepresentation(BsonType.ObjectId)] + public virtual string Id { get; set; } + /// + /// Gets or sets the user identifier. + /// + /// The user identifier. + public virtual string UserId { get; set; } + /// + /// Gets or sets the type of the claim. + /// + /// The type of the claim. + public virtual string ClaimType { get; set; } + /// + /// Gets or sets the claim value. + /// + /// The claim value. + public virtual string ClaimValue { get; set; } + + + } +} \ No newline at end of file diff --git a/IdentityUserLogin.cs b/IdentityUserLogin.cs new file mode 100644 index 0000000..043b8b2 --- /dev/null +++ b/IdentityUserLogin.cs @@ -0,0 +1,34 @@ +namespace MongoDB.AspNet.Identity +{ + public class IdentityUserLogin : IdentityUserLogin + { + public IdentityUserLogin() + { + } + } + + public class IdentityUserLogin + { + public virtual string LoginProvider + { + get; + set; + } + + public virtual string ProviderKey + { + get; + set; + } + + public virtual TKey UserId + { + get; + set; + } + + public IdentityUserLogin() + { + } + } +} \ No newline at end of file diff --git a/IdentityUserRole.cs b/IdentityUserRole.cs new file mode 100644 index 0000000..905a2f8 --- /dev/null +++ b/IdentityUserRole.cs @@ -0,0 +1,30 @@ +namespace MongoDB.AspNet.Identity +{ + + + public class IdentityUserRole : IdentityUserRole + { + public IdentityUserRole() + { + } + } + + public class IdentityUserRole + { + public virtual TKey RoleId + { + get; + set; + } + + public virtual TKey UserId + { + get; + set; + } + + public IdentityUserRole() + { + } + } +} \ No newline at end of file diff --git a/MongoDB.AspNet.Identity.csproj b/MongoDB.AspNet.Identity.csproj index ba38609..8b1b46a 100644 --- a/MongoDB.AspNet.Identity.csproj +++ b/MongoDB.AspNet.Identity.csproj @@ -41,8 +41,9 @@ bin\MongoDB.AspNet.Identity.XML - - packages\Microsoft.AspNet.Identity.Core.1.0.0\lib\net45\Microsoft.AspNet.Identity.Core.dll + + False + packages\Microsoft.AspNet.Identity.Core.2.0.0-beta1\lib\net45\Microsoft.AspNet.Identity.Core.dll False diff --git a/UserStore.cs b/UserStore.cs index 93613eb..6b1b488 100644 --- a/UserStore.cs +++ b/UserStore.cs @@ -15,9 +15,13 @@ namespace MongoDB.AspNet.Identity /// Class UserStore. /// /// The type of the t user. - public class UserStore : IUserLoginStore, IUserClaimStore, IUserRoleStore, - IUserPasswordStore, IUserSecurityStampStore - where TUser : IdentityUser + public class UserStore : IUserLoginStore, IUserClaimStore, IUserRoleStore, IUserPasswordStore, IUserSecurityStampStore, IQueryableUserStore, IUserEmailStore, IUserPhoneNumberStore, IUserTwoFactorStore, IUserStore, IDisposable + where TUser : IdentityUser + where TRole : IdentityRole + where TKey : IEquatable + where TUserLogin : IdentityUserLogin, new() + where TUserRole : IdentityUserRole, new() + where TUserClaim : IdentityUserClaim, new() { #region Private Methods & Variables @@ -267,6 +271,13 @@ public Task DeleteAsync(TUser user) return Task.FromResult(true); } + public Task FindByIdAsync(TKey userId) + { + ThrowIfDisposed(); + TUser user = db.GetCollection(collectionName).FindOne((Query.EQ("_id", ObjectId.Parse(userId)))); + return Task.FromResult(user); + } + /// /// Finds the by identifier asynchronous. /// @@ -292,6 +303,50 @@ public Task FindByNameAsync(string userName) return Task.FromResult(user); } + public Task SetEmailConfirmedAsync(TUser user, bool confirmed) + { + throw new NotImplementedException(); + } + + /// + /// Finds the by email asynchronous. + /// + /// The email. + /// Task{`0}. + public Task FindByEmailAsync(string email) + { + ThrowIfDisposed(); + + TUser user = db.GetCollection(collectionName).FindOne((Query.EQ("Email", email))); + return Task.FromResult(user); + } + + public Task SetEmailAsync(TUser user, string email) + { + throw new NotImplementedException(); + } + + /// + /// Gets the email asynchronous. + /// + /// The user. + /// Task{System.String}. + /// user + public Task GetEmailAsync(TUser user) + { + ThrowIfDisposed(); + if (user == null) + { + throw new ArgumentException("user"); + } + return Task.FromResult(user.Email); + } + + public Task GetEmailConfirmedAsync(TUser user) + { + throw new NotImplementedException(); + } + /// /// Updates the user asynchronous. /// @@ -544,6 +599,73 @@ private void ThrowIfDisposed() } #endregion + + public IQueryable Users { get; private set; } + + public Task SetPhoneNumberAsync(TUser user, string phoneNumber) + { + ThrowIfDisposed(); + if (user == null) + { + throw new ArgumentException("user"); + } + + user.PhoneNumber = phoneNumber; + return Task.FromResult(0); + } + + public Task GetPhoneNumberAsync(TUser user) + { + ThrowIfDisposed(); + if (user == null) + { + throw new ArgumentNullException("user"); + } + + return Task.FromResult(user.PhoneNumber); + } + + public Task GetPhoneNumberConfirmedAsync(TUser user) + { + ThrowIfDisposed(); + if (user == null) + { + throw new ArgumentNullException("user"); + } + return Task.FromResult(user.PhoneNumberConfirmed); + } + + public Task SetPhoneNumberConfirmedAsync(TUser user, bool confirmed) + { + ThrowIfDisposed(); + if (user == null) + { + throw new ArgumentNullException("user"); + } + user.PhoneNumberConfirmed = confirmed; + return Task.FromResult(0); + } + + public Task SetTwoFactorEnabledAsync(TUser user, bool enabled) + { + ThrowIfDisposed(); + if (user == null) + { + throw new ArgumentNullException("user"); + } + user.TwoFactorEnabled = enabled; + return Task.FromResult(0); + } + + public Task GetTwoFactorEnabledAsync(TUser user) + { + ThrowIfDisposed(); + if (user == null) + { + throw new ArgumentNullException("user"); + } + return Task.FromResult(user.TwoFactorEnabled); + } } } \ No newline at end of file diff --git a/packages.config b/packages.config index 0e77e46..db6a3c2 100644 --- a/packages.config +++ b/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file From c9b9809d01ccc64542ba8b25909fc80040ad506f Mon Sep 17 00:00:00 2001 From: Jonathan Sheely Date: Mon, 7 Apr 2014 01:30:22 -0400 Subject: [PATCH 2/7] Added additioanl IdentityUser properties not in beta. userId must be a string and can't be of variable type because of ObjectId.Parse() requiring a type string. Will look into an alternative way of handling this. --- IdentityUser.cs | 29 +++++++++++++++++++++++++++-- IdentityUserClaim.cs | 2 +- MongoDB.AspNet.Identity.csproj | 12 ++++++++---- UserStore.cs | 7 +++---- packages.config | 2 +- 5 files changed, 40 insertions(+), 12 deletions(-) diff --git a/IdentityUser.cs b/IdentityUser.cs index f8b5cb7..c277d6d 100644 --- a/IdentityUser.cs +++ b/IdentityUser.cs @@ -33,7 +33,7 @@ public class IdentityUser : IUser where TClaim : IdentityUserClaim { /// - /// Unique key for the user + /// Unique key for the user. TKey must be a string. /// /// The identifier. /// The unique key for the user @@ -56,10 +56,17 @@ public class IdentityUser : IUser /// The security stamp. public virtual string SecurityStamp { get; set; } /// - /// Gets the roles. + /// Gets the roles. Extended from the AspNet IdentityUser entity to add a Role array to the users to follow a more Mongo document model style. /// /// The roles. public virtual List Roles { get; private set; } + + /// + /// Gets or sets the roles. Matches the AspNet IdentityUser entity signature. + /// + /// The roles. + //public virtual ICollection Roles { get; set; } + /// /// Gets the claims. /// @@ -100,6 +107,24 @@ public class IdentityUser : IUser /// /// true if [email confirmed]; otherwise, false. public virtual bool EmailConfirmed { get; set; } + + /// + /// Gets or sets the access failed count. + /// + /// The access failed count. + public virtual int AccessFailedCount { get; set; } + + /// + /// Gets or sets a value indicating whether [lockout enabled]. + /// + /// true if [lockout enabled]; otherwise, false. + public virtual bool LockoutEnabled { get; set; } + + /// + /// Gets or sets the lockout end date UTC. + /// + /// The lockout end date UTC. + public virtual DateTime? LockoutEndDateUtc { get; set; } /// /// Initializes a new instance of the class. diff --git a/IdentityUserClaim.cs b/IdentityUserClaim.cs index af08fc3..7b55c7a 100644 --- a/IdentityUserClaim.cs +++ b/IdentityUserClaim.cs @@ -29,7 +29,7 @@ public class IdentityUserClaim /// Gets or sets the user identifier. /// /// The user identifier. - public virtual string UserId { get; set; } + public virtual TKey UserId { get; set; } /// /// Gets or sets the type of the claim. /// diff --git a/MongoDB.AspNet.Identity.csproj b/MongoDB.AspNet.Identity.csproj index 8b1b46a..9d06a7e 100644 --- a/MongoDB.AspNet.Identity.csproj +++ b/MongoDB.AspNet.Identity.csproj @@ -45,13 +45,13 @@ False packages\Microsoft.AspNet.Identity.Core.2.0.0-beta1\lib\net45\Microsoft.AspNet.Identity.Core.dll - + False - packages\mongocsharpdriver.1.8.3\lib\net35\MongoDB.Bson.dll + packages\mongocsharpdriver.1.9.0\lib\net35\MongoDB.Bson.dll - + False - packages\mongocsharpdriver.1.8.3\lib\net35\MongoDB.Driver.dll + packages\mongocsharpdriver.1.9.0\lib\net35\MongoDB.Driver.dll @@ -65,7 +65,11 @@ + + + + diff --git a/UserStore.cs b/UserStore.cs index 6b1b488..e203f28 100644 --- a/UserStore.cs +++ b/UserStore.cs @@ -267,14 +267,14 @@ public Task DeleteAsync(TUser user) if (user == null) throw new ArgumentNullException("user"); - db.GetCollection(collectionName).Remove((Query.EQ("_id", ObjectId.Parse(user.Id)))); + db.GetCollection(collectionName).Remove((Query.EQ("_id", ObjectId.Parse(user.Id.ToString())))); return Task.FromResult(true); } public Task FindByIdAsync(TKey userId) { ThrowIfDisposed(); - TUser user = db.GetCollection(collectionName).FindOne((Query.EQ("_id", ObjectId.Parse(userId)))); + TUser user = db.GetCollection(collectionName).FindOne((Query.EQ("_id", ObjectId.Parse(userId.ToString())))); return Task.FromResult(user); } @@ -359,8 +359,7 @@ public Task UpdateAsync(TUser user) if (user == null) throw new ArgumentNullException("user"); - db.GetCollection(collectionName) - .Update(Query.EQ("_id", ObjectId.Parse(user.Id)), Update.Replace(user), UpdateFlags.Upsert); + db.GetCollection(collectionName).Update(Query.EQ("_id", ObjectId.Parse(user.Id.ToString())), Update.Replace(user), UpdateFlags.Upsert); return Task.FromResult(user); } diff --git a/packages.config b/packages.config index db6a3c2..bae2be2 100644 --- a/packages.config +++ b/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file From 9419fa9f380fa40b459631397fb55483d8bd2600 Mon Sep 17 00:00:00 2001 From: Jonathan Sheely Date: Mon, 7 Apr 2014 01:48:52 -0400 Subject: [PATCH 3/7] Updated comments --- UserStore.cs | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/UserStore.cs b/UserStore.cs index e203f28..006950e 100644 --- a/UserStore.cs +++ b/UserStore.cs @@ -12,9 +12,14 @@ namespace MongoDB.AspNet.Identity { /// - /// Class UserStore. + /// Class UserStore. /// /// The type of the t user. + /// The type of the t role. + /// The type of the t key. + /// The type of the t user login. + /// The type of the t user role. + /// The type of the t user claim. public class UserStore : IUserLoginStore, IUserClaimStore, IUserRoleStore, IUserPasswordStore, IUserSecurityStampStore, IQueryableUserStore, IUserEmailStore, IUserPhoneNumberStore, IUserTwoFactorStore, IUserStore, IDisposable where TUser : IdentityUser where TRole : IdentityRole @@ -271,6 +276,11 @@ public Task DeleteAsync(TUser user) return Task.FromResult(true); } + /// + /// Finds the by identifier asynchronous. + /// + /// The user identifier. + /// Task{`0}. public Task FindByIdAsync(TKey userId) { ThrowIfDisposed(); @@ -303,6 +313,13 @@ public Task FindByNameAsync(string userName) return Task.FromResult(user); } + /// + /// Sets the email confirmed asynchronous. + /// + /// The user. + /// if set to true [confirmed]. + /// Task. + /// public Task SetEmailConfirmedAsync(TUser user, bool confirmed) { throw new NotImplementedException(); @@ -321,6 +338,13 @@ public Task FindByEmailAsync(string email) return Task.FromResult(user); } + /// + /// Sets the email asynchronous. + /// + /// The user. + /// The email. + /// Task. + /// public Task SetEmailAsync(TUser user, string email) { throw new NotImplementedException(); @@ -342,6 +366,12 @@ public Task GetEmailAsync(TUser user) return Task.FromResult(user.Email); } + /// + /// Gets the email confirmed asynchronous. + /// + /// The user. + /// Task{System.Boolean}. + /// public Task GetEmailConfirmedAsync(TUser user) { throw new NotImplementedException(); @@ -599,8 +629,19 @@ private void ThrowIfDisposed() #endregion + /// + /// Gets the users. + /// + /// The users. public IQueryable Users { get; private set; } + /// + /// Sets the phone number asynchronous. + /// + /// The user. + /// The phone number. + /// Task. + /// user public Task SetPhoneNumberAsync(TUser user, string phoneNumber) { ThrowIfDisposed(); @@ -613,6 +654,12 @@ public Task SetPhoneNumberAsync(TUser user, string phoneNumber) return Task.FromResult(0); } + /// + /// Gets the phone number asynchronous. + /// + /// The user. + /// Task{System.String}. + /// user public Task GetPhoneNumberAsync(TUser user) { ThrowIfDisposed(); @@ -624,6 +671,12 @@ public Task GetPhoneNumberAsync(TUser user) return Task.FromResult(user.PhoneNumber); } + /// + /// Gets the phone number confirmed asynchronous. + /// + /// The user. + /// Task{System.Boolean}. + /// user public Task GetPhoneNumberConfirmedAsync(TUser user) { ThrowIfDisposed(); @@ -634,6 +687,13 @@ public Task GetPhoneNumberConfirmedAsync(TUser user) return Task.FromResult(user.PhoneNumberConfirmed); } + /// + /// Sets the phone number confirmed asynchronous. + /// + /// The user. + /// if set to true [confirmed]. + /// Task. + /// user public Task SetPhoneNumberConfirmedAsync(TUser user, bool confirmed) { ThrowIfDisposed(); @@ -645,6 +705,13 @@ public Task SetPhoneNumberConfirmedAsync(TUser user, bool confirmed) return Task.FromResult(0); } + /// + /// Sets the two factor enabled asynchronous. + /// + /// The user. + /// if set to true [enabled]. + /// Task. + /// user public Task SetTwoFactorEnabledAsync(TUser user, bool enabled) { ThrowIfDisposed(); @@ -656,6 +723,12 @@ public Task SetTwoFactorEnabledAsync(TUser user, bool enabled) return Task.FromResult(0); } + /// + /// Gets the two factor enabled asynchronous. + /// + /// The user. + /// Task{System.Boolean}. + /// user public Task GetTwoFactorEnabledAsync(TUser user) { ThrowIfDisposed(); From 1c09d6e00bf85828543a3d74a99323e053951f2f Mon Sep 17 00:00:00 2001 From: Jonathan Sheely Date: Mon, 26 May 2014 12:21:58 -0400 Subject: [PATCH 4/7] Removed the auto creation of the ID field. Updated to 1.9.1 of the mongo driver. Refactored the UserStore to implement my customized base store. --- IdentityUser.cs | 61 +++++++++++++++++----------------- MongoDB.AspNet.Identity.csproj | 12 +++---- UserStore.cs | 15 +++++++++ packages.config | 4 +-- 4 files changed, 54 insertions(+), 38 deletions(-) diff --git a/IdentityUser.cs b/IdentityUser.cs index c277d6d..1e863f1 100644 --- a/IdentityUser.cs +++ b/IdentityUser.cs @@ -8,13 +8,20 @@ namespace MongoDB.AspNet.Identity { + /// + /// Class IdentityUser. + /// public class IdentityUser : IdentityUser, IUser, IUser { - public IdentityUser() - { - this.Id = Guid.NewGuid().ToString(); - } + /// + /// Initializes a new instance of the class. + /// + public IdentityUser() {} + /// + /// Initializes a new instance of the class. + /// + /// Name of the user. public IdentityUser(string userName) : this() { @@ -22,8 +29,6 @@ public IdentityUser(string userName) } } - - /// /// Class IdentityUser. /// @@ -39,27 +44,31 @@ public class IdentityUser : IUser /// The unique key for the user [BsonId] [BsonRepresentation(BsonType.ObjectId)] - public virtual TKey Id { get; set; } + public virtual TKey Id { get; set; } + /// /// Gets or sets the name of the user. /// /// The name of the user. - public virtual string UserName { get; set; } + public virtual string UserName { get; set; } + /// /// Gets or sets the password hash. /// /// The password hash. - public virtual string PasswordHash { get; set; } + public virtual string PasswordHash { get; set; } + /// /// Gets or sets the security stamp. /// /// The security stamp. - public virtual string SecurityStamp { get; set; } + public virtual string SecurityStamp { get; set; } + /// /// Gets the roles. Extended from the AspNet IdentityUser entity to add a Role array to the users to follow a more Mongo document model style. /// /// The roles. - public virtual List Roles { get; private set; } + public virtual List Roles { get; private set; } /// /// Gets or sets the roles. Matches the AspNet IdentityUser entity signature. @@ -71,12 +80,13 @@ public class IdentityUser : IUser /// Gets the claims. /// /// The claims. - public virtual List Claims { get; private set; } + public virtual List Claims { get; private set; } + /// /// Gets the logins. /// /// The logins. - public virtual List Logins { get; private set; } + public virtual List Logins { get; private set; } /// /// Gets or sets a value indicating whether [two factor enabled]. @@ -125,26 +135,17 @@ public class IdentityUser : IUser /// /// The lockout end date UTC. public virtual DateTime? LockoutEndDateUtc { get; set; } - - /// - /// Initializes a new instance of the class. - /// - public IdentityUser() - { - this.Claims = new List(); - this.Roles = new List(); - this.Logins = new List(); - } /// /// Initializes a new instance of the class. /// - /// Name of the user. - public IdentityUser(string userName) : this() - { - this.UserName = userName; - } - } + public IdentityUser() + { + //this.Id = Guid.NewGuid().ToString(); + this.Claims = new List(); + this.Roles = new List(); + this.Logins = new List(); + } + } - } diff --git a/MongoDB.AspNet.Identity.csproj b/MongoDB.AspNet.Identity.csproj index 9d06a7e..6fbe6fe 100644 --- a/MongoDB.AspNet.Identity.csproj +++ b/MongoDB.AspNet.Identity.csproj @@ -41,17 +41,17 @@ bin\MongoDB.AspNet.Identity.XML - + False - packages\Microsoft.AspNet.Identity.Core.2.0.0-beta1\lib\net45\Microsoft.AspNet.Identity.Core.dll + ..\Test.MongoDB.AspNet.Identity\packages\Microsoft.AspNet.Identity.Core.2.0.1\lib\net45\Microsoft.AspNet.Identity.Core.dll - + False - packages\mongocsharpdriver.1.9.0\lib\net35\MongoDB.Bson.dll + ..\Test.MongoDB.AspNet.Identity\packages\mongocsharpdriver.1.9.1\lib\net35\MongoDB.Bson.dll - + False - packages\mongocsharpdriver.1.9.0\lib\net35\MongoDB.Driver.dll + ..\Test.MongoDB.AspNet.Identity\packages\mongocsharpdriver.1.9.1\lib\net35\MongoDB.Driver.dll diff --git a/UserStore.cs b/UserStore.cs index 006950e..4d704ac 100644 --- a/UserStore.cs +++ b/UserStore.cs @@ -5,12 +5,27 @@ using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Identity; +using MongoDB.AspNet.Identity; using MongoDB.Bson; using MongoDB.Driver; using MongoDB.Driver.Builders; namespace MongoDB.AspNet.Identity { + + public class UserStore : UserStore, IUserStore, IUserStore, IDisposable + where TUser : IdentityUser + { + public UserStore() : base() {} + public UserStore(string connectionNameOrUrl) : base(connectionNameOrUrl) {} + public UserStore(string connectionNameOrUrl, string dbName) : base(connectionNameOrUrl,dbName) {} + public UserStore(MongoDatabase mongoDatabase) : base(mongoDatabase) { } + [Obsolete("Use UserStore(connectionNameOrUrl)")] + public UserStore(string connectionName, bool useMongoUrlFormat) : base(connectionName, useMongoUrlFormat) { } + } + + + /// /// Class UserStore. /// diff --git a/packages.config b/packages.config index bae2be2..a0f639e 100644 --- a/packages.config +++ b/packages.config @@ -1,5 +1,5 @@  - - + + \ No newline at end of file From 2eedee9a4d830d20ae0ab271508a1ec2c80218df Mon Sep 17 00:00:00 2001 From: Jonathan Sheely Date: Mon, 26 May 2014 12:48:02 -0400 Subject: [PATCH 5/7] Implemented RoleStore --- MongoDB.AspNet.Identity.csproj | 1 + RoleStore.cs | 118 +++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 RoleStore.cs diff --git a/MongoDB.AspNet.Identity.csproj b/MongoDB.AspNet.Identity.csproj index 6fbe6fe..be7f29a 100644 --- a/MongoDB.AspNet.Identity.csproj +++ b/MongoDB.AspNet.Identity.csproj @@ -71,6 +71,7 @@ + diff --git a/RoleStore.cs b/RoleStore.cs new file mode 100644 index 0000000..26f2fbc --- /dev/null +++ b/RoleStore.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Threading.Tasks; +using System.Web; +using Microsoft.AspNet.Identity; +using MongoDB.Bson; +using MongoDB.Driver; +using MongoDB.Driver.Builders; + +namespace MongoDB.AspNet.Identity +{ + + + public class RoleStore : RoleStore, IQueryableRoleStore, IQueryableRoleStore, IRoleStore, IDisposable + where TRole : IdentityRole, new() + { + public RoleStore() + + { + + } + + + } + + public class RoleStore : IQueryableRoleStore, IRoleStore, IDisposable + where TRole : IdentityRole, new() + where TUserRole : IdentityUserRole, new() + { + private bool _disposed; + + private readonly MongoDatabase db; + private const string collectionName = "AspNetRoles"; + public bool DisposeContext + { + get; + set; + } + + public IQueryable Roles + { + get { return db.GetCollection(collectionName).FindAll().AsQueryable(); } + } + + + public virtual async Task CreateAsync(TRole role) + { + this.ThrowIfDisposed(); + if (role == null) + { + throw new ArgumentNullException("role"); + } + + db.GetCollection(collectionName).Insert(role); + + } + + public virtual async Task DeleteAsync(TRole role) + { + this.ThrowIfDisposed(); + if (role == null) + { + throw new ArgumentNullException("role"); + } + + db.GetCollection(collectionName).Remove((Query.EQ("_id", ObjectId.Parse(role.Id.ToString())))); + } + + public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) + { + _disposed = true; + } + + public Task FindByIdAsync(TKey roleId) + { + this.ThrowIfDisposed(); + TRole role = db.GetCollection(collectionName).FindOne((Query.EQ("_id", ObjectId.Parse(roleId.ToString())))); + return Task.FromResult(role); + } + + public Task FindByNameAsync(string roleName) + { + this.ThrowIfDisposed(); + TRole role = db.GetCollection(collectionName).FindOne((Query.EQ("Name", roleName))); + return Task.FromResult(role); + } + + private void ThrowIfDisposed() + { + if (this._disposed) + { + throw new ObjectDisposedException(this.GetType().Name); + } + } + + public virtual async Task UpdateAsync(TRole role) + { + this.ThrowIfDisposed(); + if (role == null) + { + throw new ArgumentNullException("role"); + } + + db.GetCollection(collectionName).Update(Query.EQ("_id", ObjectId.Parse(role.Id.ToString())), Update.Replace(role), UpdateFlags.Upsert); + + + } + } +} \ No newline at end of file From 52d3bde195e94756966a955cec5b1391a4d64be0 Mon Sep 17 00:00:00 2001 From: Jonathan Sheely Date: Tue, 27 May 2014 02:02:54 -0400 Subject: [PATCH 6/7] Refactored the Stores to use the same signature style as the Entity framework. Need to solve the public db property that is bubbling up to IdentityConfig because I can't figure out how to instantiate IdentityDbContext as a MongoDatabase --- IdentityDbContext.cs | 126 ++++++++++++++++++++++++++++++ MongoDB.AspNet.Identity.csproj | 4 + RoleStore.cs | 19 ++--- UserStore.cs | 139 ++------------------------------- Utils.cs | 5 +- 5 files changed, 151 insertions(+), 142 deletions(-) create mode 100644 IdentityDbContext.cs diff --git a/IdentityDbContext.cs b/IdentityDbContext.cs new file mode 100644 index 0000000..c1753d5 --- /dev/null +++ b/IdentityDbContext.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data.Common; +using System.Globalization; +using System.Linq; +using MongoDB.Driver; + +namespace MongoDB.AspNet.Identity +{ + public class IdentityDbContext : IdentityDbContext + where TUser : IdentityUser + { + public IdentityDbContext() : this("DefaultConnection") { } + public IdentityDbContext(string nameOrConnectionString) : base(nameOrConnectionString) { } + } + + public class IdentityDbContext : IdentityDbContext + { + public IdentityDbContext() : this("DefaultConnection") { } + public IdentityDbContext(string nameOrConnectionString) : base(nameOrConnectionString) { } + } + + public class IdentityDbContext : IDisposable + where TUser : IdentityUser + where TRole : IdentityRole + where TUserLogin : IdentityUserLogin + where TUserRole : IdentityUserRole + where TUserClaim : IdentityUserClaim + { + + public readonly MongoDatabase db; + + + /// + /// Gets the database from connection string. + /// + /// The connection string. + /// MongoDatabase. + /// No database name specified in connection string + private MongoDatabase GetDatabaseFromSqlStyle(string connectionString) + { + var conString = new MongoConnectionStringBuilder(connectionString); + MongoClientSettings settings = MongoClientSettings.FromConnectionStringBuilder(conString); + MongoServer server = new MongoClient(settings).GetServer(); + if (conString.DatabaseName == null) + { + throw new Exception("No database name specified in connection string"); + } + return server.GetDatabase(conString.DatabaseName); + } + + /// + /// Gets the database from URL. + /// + /// The URL. + /// MongoDatabase. + private MongoDatabase GetDatabaseFromUrl(MongoUrl url) + { + var client = new MongoClient(url); + MongoServer server = client.GetServer(); + if (url.DatabaseName == null) + { + throw new Exception("No database name specified in connection string"); + } + return server.GetDatabase(url.DatabaseName); // WriteConcern defaulted to Acknowledged + } + + /// + /// Uses connectionString to connect to server and then uses databae name specified. + /// + /// The connection string. + /// Name of the database. + /// MongoDatabase. + private MongoDatabase GetDatabase(string connectionString, string dbName) + { + var client = new MongoClient(connectionString); + MongoServer server = client.GetServer(); + return server.GetDatabase(dbName); + } + + public bool RequireUniqueEmail + { + get; + set; + } + + public virtual IQueryable Roles + { + get; + set; + } + + public virtual IQueryable Users + { + get; + set; + } + + public IdentityDbContext() : this("DefaultConnection") { } + public IdentityDbContext(string nameOrConnectionString) + { + if (nameOrConnectionString.ToLower().StartsWith("mongodb://")) + { + db = GetDatabaseFromUrl(new MongoUrl(nameOrConnectionString)); + } + else + { + string connStringFromManager = + ConfigurationManager.ConnectionStrings[nameOrConnectionString].ConnectionString; + if (connStringFromManager.ToLower().StartsWith("mongodb://")) + { + db = GetDatabaseFromUrl(new MongoUrl(connStringFromManager)); + } + else + { + db = GetDatabaseFromSqlStyle(connStringFromManager); + } + } + } + + public void Dispose() + { + } + } +} \ No newline at end of file diff --git a/MongoDB.AspNet.Identity.csproj b/MongoDB.AspNet.Identity.csproj index be7f29a..edb1700 100644 --- a/MongoDB.AspNet.Identity.csproj +++ b/MongoDB.AspNet.Identity.csproj @@ -65,6 +65,7 @@ + @@ -78,6 +79,9 @@ + + + 10.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) diff --git a/RoleStore.cs b/RoleStore.cs index 26f2fbc..74f75aa 100644 --- a/RoleStore.cs +++ b/RoleStore.cs @@ -17,13 +17,7 @@ namespace MongoDB.AspNet.Identity public class RoleStore : RoleStore, IQueryableRoleStore, IQueryableRoleStore, IRoleStore, IDisposable where TRole : IdentityRole, new() { - public RoleStore() - - { - - } - - + public RoleStore() : base(new IdentityDbContext().db) { } } public class RoleStore : IQueryableRoleStore, IRoleStore, IDisposable @@ -31,9 +25,16 @@ public class RoleStore : IQueryableRoleStore, new() { private bool _disposed; - + private readonly MongoDatabase db; private const string collectionName = "AspNetRoles"; + + + public RoleStore(MongoDatabase context) + { + db = context; + } + public bool DisposeContext { get; @@ -44,7 +45,7 @@ public IQueryable Roles { get { return db.GetCollection(collectionName).FindAll().AsQueryable(); } } - + public virtual async Task CreateAsync(TRole role) { diff --git a/UserStore.cs b/UserStore.cs index 4d704ac..bab2486 100644 --- a/UserStore.cs +++ b/UserStore.cs @@ -1,11 +1,9 @@ using System; using System.Collections.Generic; -using System.Configuration; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Identity; -using MongoDB.AspNet.Identity; using MongoDB.Bson; using MongoDB.Driver; using MongoDB.Driver.Builders; @@ -16,12 +14,8 @@ namespace MongoDB.AspNet.Identity public class UserStore : UserStore, IUserStore, IUserStore, IDisposable where TUser : IdentityUser { - public UserStore() : base() {} - public UserStore(string connectionNameOrUrl) : base(connectionNameOrUrl) {} - public UserStore(string connectionNameOrUrl, string dbName) : base(connectionNameOrUrl,dbName) {} - public UserStore(MongoDatabase mongoDatabase) : base(mongoDatabase) { } - [Obsolete("Use UserStore(connectionNameOrUrl)")] - public UserStore(string connectionName, bool useMongoUrlFormat) : base(connectionName, useMongoUrlFormat) { } + public UserStore(IdentityDbContext context) : base(context.db) { } + public UserStore(MongoDatabase db) : base(db) { } } @@ -45,6 +39,8 @@ public class UserStore : { #region Private Methods & Variables + + /// /// The database /// @@ -60,140 +56,19 @@ public class UserStore : /// private const string collectionName = "AspNetUsers"; - /// - /// Gets the database from connection string. - /// - /// The connection string. - /// MongoDatabase. - /// No database name specified in connection string - private MongoDatabase GetDatabaseFromSqlStyle(string connectionString) - { - var conString = new MongoConnectionStringBuilder(connectionString); - MongoClientSettings settings = MongoClientSettings.FromConnectionStringBuilder(conString); - MongoServer server = new MongoClient(settings).GetServer(); - if (conString.DatabaseName == null) - { - throw new Exception("No database name specified in connection string"); - } - return server.GetDatabase(conString.DatabaseName); - } - - /// - /// Gets the database from URL. - /// - /// The URL. - /// MongoDatabase. - private MongoDatabase GetDatabaseFromUrl(MongoUrl url) - { - var client = new MongoClient(url); - MongoServer server = client.GetServer(); - if (url.DatabaseName == null) - { - throw new Exception("No database name specified in connection string"); - } - return server.GetDatabase(url.DatabaseName); // WriteConcern defaulted to Acknowledged - } - - /// - /// Uses connectionString to connect to server and then uses databae name specified. - /// - /// The connection string. - /// Name of the database. - /// MongoDatabase. - private MongoDatabase GetDatabase(string connectionString, string dbName) - { - var client = new MongoClient(connectionString); - MongoServer server = client.GetServer(); - return server.GetDatabase(dbName); - } #endregion #region Constructors - - /// - /// Initializes a new instance of the class. Uses DefaultConnection name if none was - /// specified. - /// - public UserStore() : this("DefaultConnection") - { - } - /// - /// Initializes a new instance of the class. Uses name from ConfigurationManager or a - /// mongodb:// Url. - /// - /// The connection name or URL. - public UserStore(string connectionNameOrUrl) - { - if (connectionNameOrUrl.ToLower().StartsWith("mongodb://")) - { - db = GetDatabaseFromUrl(new MongoUrl(connectionNameOrUrl)); - } - else - { - string connStringFromManager = - ConfigurationManager.ConnectionStrings[connectionNameOrUrl].ConnectionString; - if (connStringFromManager.ToLower().StartsWith("mongodb://")) - { - db = GetDatabaseFromUrl(new MongoUrl(connStringFromManager)); - } - else - { - db = GetDatabaseFromSqlStyle(connStringFromManager); - } - } - } - - /// - /// Initializes a new instance of the class. Uses name from ConfigurationManager or a - /// mongodb:// Url. - /// Database can be specified separately from connection server. - /// - /// The connection name or URL. - /// Name of the database. - public UserStore(string connectionNameOrUrl, string dbName) - { - if (connectionNameOrUrl.ToLower().StartsWith("mongodb://")) - { - db = GetDatabase(connectionNameOrUrl, dbName); - } - else - { - db = GetDatabase(ConfigurationManager.ConnectionStrings[connectionNameOrUrl].ConnectionString, dbName); - } - } + public UserStore(): this(new IdentityDbContext().db) {} - /// - /// Initializes a new instance of the class using a already initialized Mongo Database. - /// - /// The mongo database. - public UserStore(MongoDatabase mongoDatabase) + public UserStore(MongoDatabase context) { - db = mongoDatabase; + db = context; } - /// - /// Initializes a new instance of the class. - /// - /// Name of the connection from ConfigurationManager.ConnectionStrings[]. - /// if set to true [use mongo URL format]. - [Obsolete("Use UserStore(connectionNameOrUrl)")] - public UserStore(string connectionName, bool useMongoUrlFormat) - { - string connectionString = ConfigurationManager.ConnectionStrings[connectionName].ConnectionString; - if (useMongoUrlFormat) - { - var url = new MongoUrl(connectionString); - db = GetDatabaseFromUrl(url); - } - else - { - db = GetDatabaseFromSqlStyle(connectionString); - } - } - #endregion #region Methods diff --git a/Utils.cs b/Utils.cs index addfa5a..6601cee 100644 --- a/Utils.cs +++ b/Utils.cs @@ -1,5 +1,7 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; +using MongoDB.Driver; namespace MongoDB.AspNet.Identity { @@ -15,5 +17,6 @@ internal static IList ToIList(this IEnumerable enumerable) { return enumerable.ToList(); } + } } \ No newline at end of file From cae016c1a34d5af1ab3c045f3e137b8ba9abba30 Mon Sep 17 00:00:00 2001 From: Jonathan Sheely Date: Tue, 27 May 2014 02:24:53 -0400 Subject: [PATCH 7/7] Cleaning up new classes. Adding documentation --- IdentityDbContext.cs | 7 +++---- IdentityUser.cs | 3 +-- MongoDB.AspNet.Identity.csproj | 3 --- UserStore.cs | 19 +++++++++++++++++++ 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/IdentityDbContext.cs b/IdentityDbContext.cs index c1753d5..9100274 100644 --- a/IdentityDbContext.cs +++ b/IdentityDbContext.cs @@ -1,8 +1,5 @@ using System; -using System.Collections.Generic; using System.Configuration; -using System.Data.Common; -using System.Globalization; using System.Linq; using MongoDB.Driver; @@ -29,7 +26,9 @@ public class IdentityDbContext { - public readonly MongoDatabase db; + internal readonly MongoDatabase db; + + public MongoDatabase Context { get { return db; } } /// diff --git a/IdentityUser.cs b/IdentityUser.cs index 1e863f1..71ba170 100644 --- a/IdentityUser.cs +++ b/IdentityUser.cs @@ -22,8 +22,7 @@ public IdentityUser() {} /// Initializes a new instance of the class. /// /// Name of the user. - public IdentityUser(string userName) - : this() + public IdentityUser(string userName) : this() { this.UserName = userName; } diff --git a/MongoDB.AspNet.Identity.csproj b/MongoDB.AspNet.Identity.csproj index edb1700..f933717 100644 --- a/MongoDB.AspNet.Identity.csproj +++ b/MongoDB.AspNet.Identity.csproj @@ -79,9 +79,6 @@ - - - 10.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) diff --git a/UserStore.cs b/UserStore.cs index bab2486..bd5dded 100644 --- a/UserStore.cs +++ b/UserStore.cs @@ -11,10 +11,22 @@ namespace MongoDB.AspNet.Identity { + /// + /// Class UserStore. + /// + /// The type of the t user. public class UserStore : UserStore, IUserStore, IUserStore, IDisposable where TUser : IdentityUser { + /// + /// Initializes a new instance of the class. + /// + /// The context. public UserStore(IdentityDbContext context) : base(context.db) { } + /// + /// Initializes a new instance of the class. + /// + /// The database. public UserStore(MongoDatabase db) : base(db) { } } @@ -61,8 +73,15 @@ public class UserStore : #region Constructors + /// + /// Initializes a new instance of the class. + /// public UserStore(): this(new IdentityDbContext().db) {} + /// + /// Initializes a new instance of the class. + /// + /// The context. public UserStore(MongoDatabase context) { db = context;