From def6fe218c0bead424621718e83475b545d11acd Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Sat, 2 Sep 2017 12:11:12 +0200 Subject: [PATCH 1/3] Temp --- .../Squidex.Domain.Apps.Core.csproj | 2 +- .../Squidex.Domain.Apps.Read.MongoDb.csproj | 2 +- src/Squidex.Domain.Users.MongoDb/MongoRole.cs | 28 ++ .../MongoRoleStore.cs | 67 +++-- src/Squidex.Domain.Users.MongoDb/MongoUser.cs | 199 +++++++++++++ .../MongoUserClaim.cs | 34 +++ .../MongoUserLogin.cs | 43 +++ .../MongoUserStore.cs | 279 +++++++++++------- .../MongoUserToken.cs | 27 ++ .../Squidex.Domain.Users.MongoDb.csproj | 1 - .../WrappedIdentityRole.cs | 16 - .../WrappedIdentityUser.cs | 46 --- .../UserManagerExtensions.cs | 3 +- .../CollectionExtensions.cs | 8 + src/Squidex/Squidex.csproj | 3 +- 15 files changed, 559 insertions(+), 199 deletions(-) create mode 100644 src/Squidex.Domain.Users.MongoDb/MongoRole.cs create mode 100644 src/Squidex.Domain.Users.MongoDb/MongoUser.cs create mode 100644 src/Squidex.Domain.Users.MongoDb/MongoUserClaim.cs create mode 100644 src/Squidex.Domain.Users.MongoDb/MongoUserLogin.cs create mode 100644 src/Squidex.Domain.Users.MongoDb/MongoUserToken.cs delete mode 100644 src/Squidex.Domain.Users.MongoDb/WrappedIdentityRole.cs delete mode 100644 src/Squidex.Domain.Users.MongoDb/WrappedIdentityUser.cs diff --git a/src/Squidex.Domain.Apps.Core/Squidex.Domain.Apps.Core.csproj b/src/Squidex.Domain.Apps.Core/Squidex.Domain.Apps.Core.csproj index dff5093fa..fbae8f950 100644 --- a/src/Squidex.Domain.Apps.Core/Squidex.Domain.Apps.Core.csproj +++ b/src/Squidex.Domain.Apps.Core/Squidex.Domain.Apps.Core.csproj @@ -10,7 +10,7 @@ - + diff --git a/src/Squidex.Domain.Apps.Read.MongoDb/Squidex.Domain.Apps.Read.MongoDb.csproj b/src/Squidex.Domain.Apps.Read.MongoDb/Squidex.Domain.Apps.Read.MongoDb.csproj index 62570d28e..8f024eb56 100644 --- a/src/Squidex.Domain.Apps.Read.MongoDb/Squidex.Domain.Apps.Read.MongoDb.csproj +++ b/src/Squidex.Domain.Apps.Read.MongoDb/Squidex.Domain.Apps.Read.MongoDb.csproj @@ -14,7 +14,7 @@ - + diff --git a/src/Squidex.Domain.Users.MongoDb/MongoRole.cs b/src/Squidex.Domain.Users.MongoDb/MongoRole.cs new file mode 100644 index 000000000..682ef8b9c --- /dev/null +++ b/src/Squidex.Domain.Users.MongoDb/MongoRole.cs @@ -0,0 +1,28 @@ +// ========================================================================== +// MongoRole.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; + +namespace Squidex.Domain.Users.MongoDb +{ + public sealed class MongoRole : IRole + { + [BsonRepresentation(BsonType.ObjectId)] + [BsonElement] + public string Id { get; set; } + + [BsonRequired] + [BsonElement] + public string Name { get; set; } + + [BsonRequired] + [BsonElement] + public string NormalizedName { get; set; } + } +} diff --git a/src/Squidex.Domain.Users.MongoDb/MongoRoleStore.cs b/src/Squidex.Domain.Users.MongoDb/MongoRoleStore.cs index 2ff23c1fc..c7340d010 100644 --- a/src/Squidex.Domain.Users.MongoDb/MongoRoleStore.cs +++ b/src/Squidex.Domain.Users.MongoDb/MongoRoleStore.cs @@ -9,82 +9,101 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Identity; -using Microsoft.AspNetCore.Identity.MongoDB; using MongoDB.Driver; +using Squidex.Infrastructure.MongoDb; +using Squidex.Infrastructure.Tasks; namespace Squidex.Domain.Users.MongoDb { - public sealed class MongoRoleStore : IRoleStore, IRoleFactory + public sealed class MongoRoleStore : MongoRepositoryBase, IRoleStore, IRoleFactory { - private readonly RoleStore innerStore; - public MongoRoleStore(IMongoDatabase database) + : base(database) { - var rolesCollection = database.GetCollection("Identity_Roles"); + } - IndexChecks.EnsureUniqueIndexOnNormalizedRoleName(rolesCollection); + protected override string CollectionName() + { + return "Identity_Roles"; + } - innerStore = new RoleStore(rolesCollection); + protected override Task SetupCollectionAsync(IMongoCollection collection) + { + return collection.Indexes.CreateOneAsync(Index.Ascending(x => x.NormalizedName), new CreateIndexOptions { Unique = true }); + } + + protected override MongoCollectionSettings CollectionSettings() + { + return new MongoCollectionSettings { WriteConcern = WriteConcern.WMajority }; } public void Dispose() { - innerStore.Dispose(); } public IRole Create(string name) { - return new WrappedIdentityRole { Name = name }; + return new MongoRole { Name = name }; } public async Task FindByIdAsync(string roleId, CancellationToken cancellationToken) { - return await innerStore.FindByIdAsync(roleId, cancellationToken); + return await Collection.Find(x => x.Id == roleId).FirstOrDefaultAsync(cancellationToken); } public async Task FindByNameAsync(string normalizedRoleName, CancellationToken cancellationToken) { - return await innerStore.FindByNameAsync(normalizedRoleName, cancellationToken); + return await Collection.Find(x => x.NormalizedName == normalizedRoleName).FirstOrDefaultAsync(cancellationToken); } - public Task CreateAsync(IRole role, CancellationToken cancellationToken) + public async Task CreateAsync(IRole role, CancellationToken cancellationToken) { - return innerStore.CreateAsync((WrappedIdentityRole)role, cancellationToken); + await Collection.InsertOneAsync((MongoRole)role, null, cancellationToken); + + return IdentityResult.Success; } - public Task UpdateAsync(IRole role, CancellationToken cancellationToken) + public async Task UpdateAsync(IRole role, CancellationToken cancellationToken) { - return innerStore.UpdateAsync((WrappedIdentityRole)role, cancellationToken); + await Collection.ReplaceOneAsync(x => x.Id == ((MongoRole)role).Id, (MongoRole)role, null, cancellationToken); + + return IdentityResult.Success; } - public Task DeleteAsync(IRole role, CancellationToken cancellationToken) + public async Task DeleteAsync(IRole role, CancellationToken cancellationToken) { - return innerStore.DeleteAsync((WrappedIdentityRole)role, cancellationToken); + await Collection.DeleteOneAsync(x => x.Id == ((MongoRole)role).Id, null, cancellationToken); + + return IdentityResult.Success; } public Task GetRoleIdAsync(IRole role, CancellationToken cancellationToken) { - return innerStore.GetRoleIdAsync((WrappedIdentityRole)role, cancellationToken); + return Task.FromResult(((MongoRole)role).Id); } public Task GetRoleNameAsync(IRole role, CancellationToken cancellationToken) { - return innerStore.GetRoleNameAsync((WrappedIdentityRole)role, cancellationToken); + return Task.FromResult(((MongoRole)role).Name); } - public Task SetRoleNameAsync(IRole role, string roleName, CancellationToken cancellationToken) + public Task GetNormalizedRoleNameAsync(IRole role, CancellationToken cancellationToken) { - return innerStore.SetRoleNameAsync((WrappedIdentityRole)role, roleName, cancellationToken); + return Task.FromResult(((MongoRole)role).NormalizedName); } - public Task GetNormalizedRoleNameAsync(IRole role, CancellationToken cancellationToken) + public Task SetRoleNameAsync(IRole role, string roleName, CancellationToken cancellationToken) { - return innerStore.GetNormalizedRoleNameAsync((WrappedIdentityRole)role, cancellationToken); + ((MongoRole)role).Name = roleName; + + return TaskHelper.Done; } public Task SetNormalizedRoleNameAsync(IRole role, string normalizedName, CancellationToken cancellationToken) { - return innerStore.SetNormalizedRoleNameAsync((WrappedIdentityRole)role, normalizedName, cancellationToken); + ((MongoRole)role).NormalizedName = normalizedName; + + return TaskHelper.Done; } } } diff --git a/src/Squidex.Domain.Users.MongoDb/MongoUser.cs b/src/Squidex.Domain.Users.MongoDb/MongoUser.cs new file mode 100644 index 000000000..191a66016 --- /dev/null +++ b/src/Squidex.Domain.Users.MongoDb/MongoUser.cs @@ -0,0 +1,199 @@ +// ========================================================================== +// MongoUser.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using Microsoft.AspNetCore.Identity; +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; +using Squidex.Infrastructure; +using Squidex.Shared.Users; + +namespace Squidex.Domain.Users.MongoDb +{ + public sealed class MongoUser : IUser + { + [BsonRepresentation(BsonType.ObjectId)] + [BsonElement] + public string Id { get; set; } + + [BsonIgnoreIfNull] + [BsonElement] + public string SecurityStamp { get; set; } + + [BsonRequired] + [BsonElement] + public string UserName { get; set; } + + [BsonRequired] + [BsonElement] + public string NormalizedUserName { get; set; } + + [BsonRequired] + [BsonElement] + public string Email { get; set; } + + [BsonRequired] + [BsonElement] + public string NormalizedEmail { get; set; } + + [BsonIgnoreIfNull] + [BsonElement] + public string PhoneNumber { get; set; } + + [BsonIgnoreIfNull] + [BsonElement] + public string PasswordHash { get; set; } + + [BsonRequired] + [BsonElement] + public bool EmailConfirmed { get; set; } + + [BsonIgnoreIfDefault] + [BsonElement] + public bool PhoneNumberConfirmed { get; set; } + + [BsonIgnoreIfDefault] + [BsonElement] + public bool TwoFactorEnabled { get; set; } + + [BsonIgnoreIfDefault] + [BsonElement] + public bool LockoutEnabled { get; set; } + + [BsonIgnoreIfNull] + [BsonElement] + public DateTime? LockoutEndDateUtc { get; set; } + + [BsonIgnoreIfDefault] + [BsonElement] + public int AccessFailedCount { get; set; } + + [BsonRequired] + [BsonElement] + public List Roles { get; set; } = new List(); + + [BsonRequired] + [BsonElement] + public List Claims { get; set; } = new List(); + + [BsonRequired] + [BsonElement] + public List Tokens { get; set; } = new List(); + + [BsonRequired] + [BsonElement] + public List Logins { get; set; } = new List(); + + public bool IsLocked + { + get { return LockoutEndDateUtc != null && LockoutEndDateUtc.Value > DateTime.UtcNow; } + } + + IReadOnlyList IUser.Claims + { + get { return Claims.Select(x => new Claim(x.Type, x.Value)).ToList(); } + } + + IReadOnlyList IUser.Logins + { + get { return Logins.Select(x => new ExternalLogin(x.LoginProvider, x.ProviderKey, x.ProviderDisplayName)).ToList(); } + } + + public MongoUser() + { + Id = ObjectId.GenerateNewId().ToString(); + } + + public void UpdateEmail(string email) + { + Email = UserName = email; + } + + public void AddRole(string role) + { + Roles.Add(role); + } + + public void RemoveRole(string role) + { + Roles.Remove(role); + } + + public void AddLogin(UserLoginInfo login) + { + Logins.Add(login); + } + + public void RemoveLogin(string loginProvider, string providerKey) + { + Logins.RemoveAll(l => l.LoginProvider == loginProvider && l.ProviderKey == providerKey); + } + + public void AddClaim(Claim claim) + { + Claims.Add(claim); + } + + public void AddClaims(IEnumerable claims) + { + claims.Foreach(AddClaim); + } + + public void RemoveClaim(Claim claim) + { + Claims.RemoveAll(c => c.Type == claim.Type && c.Value == claim.Value); + } + + public void RemoveClaims(IEnumerable claims) + { + claims.Foreach(RemoveClaim); + } + + public void SetClaim(string type, string value) + { + SetClaim(new Claim(type, value)); + } + + public void SetClaim(Claim claim) + { + ReplaceClaim(claim, claim); + } + + public string GetToken(string loginProider, string name) + { + return Tokens.FirstOrDefault(t => t.LoginProvider == loginProider && t.Name == name)?.Value; + } + + public void AddToken(string loginProvider, string name, string value) + { + Tokens.Add(new MongoUserToken { LoginProvider = loginProvider, Name = name, Value = value }); + } + + public void RemoveToken(string loginProvider, string name) + { + Tokens.RemoveAll(t => t.LoginProvider == loginProvider && t.Name == name); + } + + public void ReplaceClaim(Claim existingClaim, Claim newClaim) + { + RemoveClaim(existingClaim); + + AddClaim(newClaim); + } + + public void SetToken(string loginProider, string name, string value) + { + RemoveToken(loginProider, name); + + AddToken(loginProider, name, value); + } + } +} diff --git a/src/Squidex.Domain.Users.MongoDb/MongoUserClaim.cs b/src/Squidex.Domain.Users.MongoDb/MongoUserClaim.cs new file mode 100644 index 000000000..d9632e439 --- /dev/null +++ b/src/Squidex.Domain.Users.MongoDb/MongoUserClaim.cs @@ -0,0 +1,34 @@ +// ========================================================================== +// MongoUserClaim.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System.Security.Claims; +using MongoDB.Bson.Serialization.Attributes; + +namespace Squidex.Domain.Users.MongoDb +{ + public sealed class MongoUserClaim + { + [BsonRequired] + [BsonElement] + public string Type { get; set; } + + [BsonRequired] + [BsonElement] + public string Value { get; set; } + + public static implicit operator MongoUserClaim(Claim claim) + { + return new MongoUserClaim { Type = claim.Type, Value = claim.Value }; + } + + public static implicit operator Claim(MongoUserClaim userClaim) + { + return new Claim(userClaim.Type, userClaim.Value); + } + } +} diff --git a/src/Squidex.Domain.Users.MongoDb/MongoUserLogin.cs b/src/Squidex.Domain.Users.MongoDb/MongoUserLogin.cs new file mode 100644 index 000000000..899c0daea --- /dev/null +++ b/src/Squidex.Domain.Users.MongoDb/MongoUserLogin.cs @@ -0,0 +1,43 @@ +// ========================================================================== +// MongoUserLogin.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using Microsoft.AspNetCore.Identity; +using MongoDB.Bson.Serialization.Attributes; + +namespace Squidex.Domain.Users.MongoDb +{ + public sealed class MongoUserLogin + { + [BsonRequired] + [BsonElement] + public string LoginProvider { get; set; } + + [BsonRequired] + [BsonElement] + public string ProviderDisplayName { get; set; } + + [BsonRequired] + [BsonElement] + public string ProviderKey { get; set; } + + public static implicit operator MongoUserLogin(UserLoginInfo login) + { + return new MongoUserLogin + { + LoginProvider = login.LoginProvider, + ProviderKey = login.ProviderKey, + ProviderDisplayName = login.ProviderDisplayName + }; + } + + public static implicit operator UserLoginInfo(MongoUserLogin userLogin) + { + return new UserLoginInfo(userLogin.LoginProvider, userLogin.ProviderKey, userLogin.ProviderDisplayName); + } + } +} diff --git a/src/Squidex.Domain.Users.MongoDb/MongoUserStore.cs b/src/Squidex.Domain.Users.MongoDb/MongoUserStore.cs index 23ca128be..964e9a990 100644 --- a/src/Squidex.Domain.Users.MongoDb/MongoUserStore.cs +++ b/src/Squidex.Domain.Users.MongoDb/MongoUserStore.cs @@ -13,13 +13,15 @@ using System.Security.Claims; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Identity; -using Microsoft.AspNetCore.Identity.MongoDB; using MongoDB.Driver; +using Squidex.Infrastructure.MongoDb; +using Squidex.Infrastructure.Tasks; using Squidex.Shared.Users; namespace Squidex.Domain.Users.MongoDb { public sealed class MongoUserStore : + MongoRepositoryBase, IUserPasswordStore, IUserRoleStore, IUserLoginStore, @@ -34,296 +36,357 @@ namespace Squidex.Domain.Users.MongoDb IUserResolver, IQueryableUserStore { - private readonly UserStore innerStore; - public MongoUserStore(IMongoDatabase database) + : base(database) + { + } + + protected override string CollectionName() { - var usersCollection = database.GetCollection("Identity_Users"); + return "Identity_Users"; + } - IndexChecks.EnsureUniqueIndexOnNormalizedEmail(usersCollection); - IndexChecks.EnsureUniqueIndexOnNormalizedUserName(usersCollection); + protected override Task SetupCollectionAsync(IMongoCollection collection) + { + return Task.WhenAll( + collection.Indexes.CreateOneAsync(Index.Ascending(x => x.NormalizedUserName), new CreateIndexOptions { Unique = true }), + collection.Indexes.CreateOneAsync(Index.Ascending(x => x.NormalizedEmail), new CreateIndexOptions { Unique = true })); + } - innerStore = new UserStore(usersCollection); + protected override MongoCollectionSettings CollectionSettings() + { + return new MongoCollectionSettings { WriteConcern = WriteConcern.WMajority }; } public void Dispose() { - innerStore.Dispose(); } public IQueryable Users { - get { return innerStore.Users; } + get { return Collection.AsQueryable(); } } public IUser Create(string email) { - return new WrappedIdentityUser { Email = email, UserName = email }; + return new MongoUser { Email = email, UserName = email }; } - public async Task FindByIdAsync(string userId) + public async Task FindByIdAsync(string id) { - return await innerStore.FindByIdAsync(userId, CancellationToken.None); + return await Collection.Find(x => x.Id == id).FirstOrDefaultAsync(); } public async Task FindByIdAsync(string userId, CancellationToken cancellationToken) { - return await innerStore.FindByIdAsync(userId, cancellationToken); + return await Collection.Find(x => x.Id == userId).FirstOrDefaultAsync(cancellationToken); } public async Task FindByEmailAsync(string normalizedEmail, CancellationToken cancellationToken) { - return await innerStore.FindByEmailAsync(normalizedEmail, cancellationToken); + return await Collection.Find(x => x.NormalizedEmail == normalizedEmail).FirstOrDefaultAsync(cancellationToken); } public async Task FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken) { - return await innerStore.FindByNameAsync(normalizedUserName, cancellationToken); + return await Collection.Find(x => x.NormalizedEmail == normalizedUserName).FirstOrDefaultAsync(cancellationToken); } public async Task FindByLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken) { - return await innerStore.FindByLoginAsync(loginProvider, providerKey, cancellationToken); + return await Collection.Find(x => x.Logins.Any(y => y.LoginProvider == loginProvider && y.ProviderKey == providerKey)).FirstOrDefaultAsync(cancellationToken); } public async Task> GetUsersForClaimAsync(Claim claim, CancellationToken cancellationToken) { - return (await innerStore.GetUsersForClaimAsync(claim, cancellationToken)).OfType().ToList(); + return (await Collection.Find(x => x.Claims.Any(y => y.Type == claim.Type && y.Value == claim.Value)).ToListAsync(cancellationToken)).OfType().ToList(); } public async Task> GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken) { - return (await innerStore.GetUsersInRoleAsync(roleName, cancellationToken)).OfType().ToList(); + return (await Collection.Find(x => x.Roles.Contains(roleName)).ToListAsync(cancellationToken)).OfType().ToList(); } - public Task CreateAsync(IUser user, CancellationToken cancellationToken) + public async Task CreateAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.CreateAsync((WrappedIdentityUser)user, cancellationToken); + await Collection.InsertOneAsync((MongoUser)user, null, cancellationToken); + + return IdentityResult.Success; } - public Task UpdateAsync(IUser user, CancellationToken cancellationToken) + public async Task UpdateAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.UpdateAsync((WrappedIdentityUser)user, cancellationToken); + await Collection.ReplaceOneAsync(x => x.Id == user.Id, (MongoUser)user, null, cancellationToken); + + return IdentityResult.Success; } - public Task DeleteAsync(IUser user, CancellationToken cancellationToken) + public async Task DeleteAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.DeleteAsync((WrappedIdentityUser)user, cancellationToken); + await Collection.DeleteOneAsync(x => x.Id == user.Id, null, cancellationToken); + + return IdentityResult.Success; } public Task GetUserIdAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.GetUserIdAsync((WrappedIdentityUser)user, cancellationToken); + return Task.FromResult(((MongoUser)user).Id); } public Task GetUserNameAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.GetUserNameAsync((WrappedIdentityUser)user, cancellationToken); + return Task.FromResult(((MongoUser)user).UserName); } - public Task SetUserNameAsync(IUser user, string userName, CancellationToken cancellationToken) + public Task GetNormalizedUserNameAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.SetUserNameAsync((WrappedIdentityUser)user, userName, cancellationToken); + return Task.FromResult(((MongoUser)user).NormalizedUserName); } - public Task GetNormalizedUserNameAsync(IUser user, CancellationToken cancellationToken) + public Task GetPasswordHashAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.GetNormalizedUserNameAsync((WrappedIdentityUser)user, cancellationToken); + return Task.FromResult(((MongoUser)user).PasswordHash); } - public Task SetNormalizedUserNameAsync(IUser user, string normalizedName, CancellationToken cancellationToken) + public Task> GetRolesAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.SetNormalizedUserNameAsync((WrappedIdentityUser)user, normalizedName, cancellationToken); + return Task.FromResult>(((MongoUser)user).Roles); } - public Task GetPasswordHashAsync(IUser user, CancellationToken cancellationToken) + public Task IsInRoleAsync(IUser user, string roleName, CancellationToken cancellationToken) { - return innerStore.GetPasswordHashAsync((WrappedIdentityUser)user, cancellationToken); + return Task.FromResult(((MongoUser)user).Roles.Contains(roleName)); } - public Task SetPasswordHashAsync(IUser user, string passwordHash, CancellationToken cancellationToken) + public Task> GetLoginsAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.SetPasswordHashAsync((WrappedIdentityUser)user, passwordHash, cancellationToken); + return Task.FromResult>(((MongoUser)user).Logins.Select(x => (UserLoginInfo)x).ToList()); } - public Task AddToRoleAsync(IUser user, string roleName, CancellationToken cancellationToken) + public Task GetSecurityStampAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.AddToRoleAsync((WrappedIdentityUser)user, roleName, cancellationToken); + return Task.FromResult(((MongoUser)user).SecurityStamp); } - public Task RemoveFromRoleAsync(IUser user, string roleName, CancellationToken cancellationToken) + public Task GetEmailAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.RemoveFromRoleAsync((WrappedIdentityUser)user, roleName, cancellationToken); + return Task.FromResult(((MongoUser)user).Email); } - public Task> GetRolesAsync(IUser user, CancellationToken cancellationToken) + public Task GetEmailConfirmedAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.GetRolesAsync((WrappedIdentityUser)user, cancellationToken); + return Task.FromResult(((MongoUser)user).EmailConfirmed); } - public Task IsInRoleAsync(IUser user, string roleName, CancellationToken cancellationToken) + public Task GetNormalizedEmailAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.IsInRoleAsync((WrappedIdentityUser)user, roleName, cancellationToken); + return Task.FromResult(((MongoUser)user).NormalizedEmail); } - public Task AddLoginAsync(IUser user, UserLoginInfo login, CancellationToken cancellationToken) + public Task> GetClaimsAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.AddLoginAsync((WrappedIdentityUser)user, login, cancellationToken); + return Task.FromResult>(((MongoUser)user).Claims.Select(x => (Claim)x).ToList()); } - public Task RemoveLoginAsync(IUser user, string loginProvider, string providerKey, CancellationToken cancellationToken) + public Task GetPhoneNumberAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.RemoveLoginAsync((WrappedIdentityUser)user, loginProvider, providerKey, cancellationToken); + return Task.FromResult(((MongoUser)user).PhoneNumber); } - public Task> GetLoginsAsync(IUser user, CancellationToken cancellationToken) + public Task GetPhoneNumberConfirmedAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.GetLoginsAsync((WrappedIdentityUser)user, cancellationToken); + return Task.FromResult(((MongoUser)user).PhoneNumberConfirmed); } - public Task GetSecurityStampAsync(IUser user, CancellationToken cancellationToken) + public Task GetTwoFactorEnabledAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.GetSecurityStampAsync((WrappedIdentityUser)user, cancellationToken); + return Task.FromResult(((MongoUser)user).TwoFactorEnabled); } - public Task SetSecurityStampAsync(IUser user, string stamp, CancellationToken cancellationToken) + public Task GetLockoutEndDateAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.SetSecurityStampAsync((WrappedIdentityUser)user, stamp, cancellationToken); + return Task.FromResult(((MongoUser)user).LockoutEndDateUtc); } - public Task GetEmailAsync(IUser user, CancellationToken cancellationToken) + public Task GetAccessFailedCountAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.GetEmailAsync((WrappedIdentityUser)user, cancellationToken); + return Task.FromResult(((MongoUser)user).AccessFailedCount); } - public Task SetEmailAsync(IUser user, string email, CancellationToken cancellationToken) + public Task GetLockoutEnabledAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.SetEmailAsync((WrappedIdentityUser)user, email, cancellationToken); + return Task.FromResult(((MongoUser)user).LockoutEnabled); } - public Task GetEmailConfirmedAsync(IUser user, CancellationToken cancellationToken) + public Task GetTokenAsync(IUser user, string loginProvider, string name, CancellationToken cancellationToken) { - return innerStore.GetEmailConfirmedAsync((WrappedIdentityUser)user, cancellationToken); + return Task.FromResult(((MongoUser)user).GetToken(loginProvider, name)); } - public Task SetEmailConfirmedAsync(IUser user, bool confirmed, CancellationToken cancellationToken) + public Task HasPasswordAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.SetEmailConfirmedAsync((WrappedIdentityUser)user, confirmed, cancellationToken); + return Task.FromResult(!string.IsNullOrWhiteSpace(((MongoUser)user).PasswordHash)); } - public Task GetNormalizedEmailAsync(IUser user, CancellationToken cancellationToken) + public Task SetUserNameAsync(IUser user, string userName, CancellationToken cancellationToken) { - return innerStore.GetNormalizedEmailAsync((WrappedIdentityUser)user, cancellationToken); + ((MongoUser)user).UserName = userName; + + return TaskHelper.Done; } - public Task SetNormalizedEmailAsync(IUser user, string normalizedEmail, CancellationToken cancellationToken) + public Task SetNormalizedUserNameAsync(IUser user, string normalizedName, CancellationToken cancellationToken) { - return innerStore.SetNormalizedEmailAsync((WrappedIdentityUser)user, normalizedEmail, cancellationToken); + ((MongoUser)user).NormalizedUserName = normalizedName; + + return TaskHelper.Done; } - public Task> GetClaimsAsync(IUser user, CancellationToken cancellationToken) + public Task SetPasswordHashAsync(IUser user, string passwordHash, CancellationToken cancellationToken) { - return innerStore.GetClaimsAsync((WrappedIdentityUser)user, cancellationToken); + ((MongoUser)user).PasswordHash = passwordHash; + + return TaskHelper.Done; } - public Task AddClaimsAsync(IUser user, IEnumerable claims, CancellationToken cancellationToken) + public Task AddToRoleAsync(IUser user, string roleName, CancellationToken cancellationToken) { - return innerStore.AddClaimsAsync((WrappedIdentityUser)user, claims, cancellationToken); + ((MongoUser)user).AddRole(roleName); + + return TaskHelper.Done; } - public Task ReplaceClaimAsync(IUser user, Claim claim, Claim newClaim, CancellationToken cancellationToken) + public Task RemoveFromRoleAsync(IUser user, string roleName, CancellationToken cancellationToken) { - return innerStore.ReplaceClaimAsync((WrappedIdentityUser)user, claim, newClaim, cancellationToken); + ((MongoUser)user).RemoveRole(roleName); + + return TaskHelper.Done; } - public Task RemoveClaimsAsync(IUser user, IEnumerable claims, CancellationToken cancellationToken) + public Task AddLoginAsync(IUser user, UserLoginInfo login, CancellationToken cancellationToken) { - return innerStore.RemoveClaimsAsync((WrappedIdentityUser)user, claims, cancellationToken); + ((MongoUser)user).AddLogin(login); + + return TaskHelper.Done; } - public Task GetPhoneNumberAsync(IUser user, CancellationToken cancellationToken) + public Task RemoveLoginAsync(IUser user, string loginProvider, string providerKey, CancellationToken cancellationToken) { - return innerStore.GetPhoneNumberAsync((WrappedIdentityUser)user, cancellationToken); + ((MongoUser)user).RemoveLogin(loginProvider, providerKey); + + return TaskHelper.Done; } - public Task SetPhoneNumberAsync(IUser user, string phoneNumber, CancellationToken cancellationToken) + public Task SetSecurityStampAsync(IUser user, string stamp, CancellationToken cancellationToken) { - return innerStore.SetPhoneNumberAsync((WrappedIdentityUser)user, phoneNumber, cancellationToken); + ((MongoUser)user).SecurityStamp = stamp; + + return TaskHelper.Done; } - public Task GetPhoneNumberConfirmedAsync(IUser user, CancellationToken cancellationToken) + public Task SetEmailAsync(IUser user, string email, CancellationToken cancellationToken) { - return innerStore.GetPhoneNumberConfirmedAsync((WrappedIdentityUser)user, cancellationToken); + ((MongoUser)user).Email = email; + + return TaskHelper.Done; } - public Task SetPhoneNumberConfirmedAsync(IUser user, bool confirmed, CancellationToken cancellationToken) + public Task SetEmailConfirmedAsync(IUser user, bool confirmed, CancellationToken cancellationToken) { - return innerStore.SetPhoneNumberConfirmedAsync((WrappedIdentityUser)user, confirmed, cancellationToken); + ((MongoUser)user).EmailConfirmed = confirmed; + + return TaskHelper.Done; } - public Task GetTwoFactorEnabledAsync(IUser user, CancellationToken cancellationToken) + public Task SetNormalizedEmailAsync(IUser user, string normalizedEmail, CancellationToken cancellationToken) { - return innerStore.GetTwoFactorEnabledAsync((WrappedIdentityUser)user, cancellationToken); + ((MongoUser)user).NormalizedEmail = normalizedEmail; + + return TaskHelper.Done; } - public Task SetTwoFactorEnabledAsync(IUser user, bool enabled, CancellationToken cancellationToken) + public Task AddClaimsAsync(IUser user, IEnumerable claims, CancellationToken cancellationToken) { - return innerStore.SetTwoFactorEnabledAsync((WrappedIdentityUser)user, enabled, cancellationToken); + ((MongoUser)user).AddClaims(claims); + + return TaskHelper.Done; } - public Task GetLockoutEndDateAsync(IUser user, CancellationToken cancellationToken) + public Task ReplaceClaimAsync(IUser user, Claim claim, Claim newClaim, CancellationToken cancellationToken) { - return innerStore.GetLockoutEndDateAsync((WrappedIdentityUser)user, cancellationToken); + ((MongoUser)user).ReplaceClaim(claim, newClaim); + + return TaskHelper.Done; } - public Task SetLockoutEndDateAsync(IUser user, DateTimeOffset? lockoutEnd, CancellationToken cancellationToken) + public Task RemoveClaimsAsync(IUser user, IEnumerable claims, CancellationToken cancellationToken) { - return innerStore.SetLockoutEndDateAsync((WrappedIdentityUser)user, lockoutEnd, cancellationToken); + ((MongoUser)user).RemoveClaims(claims); + + return TaskHelper.Done; } - public Task GetAccessFailedCountAsync(IUser user, CancellationToken cancellationToken) + public Task SetPhoneNumberAsync(IUser user, string phoneNumber, CancellationToken cancellationToken) { - return innerStore.GetAccessFailedCountAsync((WrappedIdentityUser)user, cancellationToken); + ((MongoUser)user).PhoneNumber = phoneNumber; + + return TaskHelper.Done; } - public Task IncrementAccessFailedCountAsync(IUser user, CancellationToken cancellationToken) + public Task SetPhoneNumberConfirmedAsync(IUser user, bool confirmed, CancellationToken cancellationToken) { - return innerStore.IncrementAccessFailedCountAsync((WrappedIdentityUser)user, cancellationToken); + ((MongoUser)user).PhoneNumberConfirmed = confirmed; + + return TaskHelper.Done; } - public Task ResetAccessFailedCountAsync(IUser user, CancellationToken cancellationToken) + public Task SetTwoFactorEnabledAsync(IUser user, bool enabled, CancellationToken cancellationToken) { - return innerStore.ResetAccessFailedCountAsync((WrappedIdentityUser)user, cancellationToken); + ((MongoUser)user).TwoFactorEnabled = enabled; + + return TaskHelper.Done; } - public Task GetLockoutEnabledAsync(IUser user, CancellationToken cancellationToken) + public Task SetLockoutEndDateAsync(IUser user, DateTimeOffset? lockoutEnd, CancellationToken cancellationToken) { - return innerStore.GetLockoutEnabledAsync((WrappedIdentityUser)user, cancellationToken); + ((MongoUser)user).LockoutEndDateUtc = lockoutEnd?.UtcDateTime; + + return TaskHelper.Done; } - public Task SetLockoutEnabledAsync(IUser user, bool enabled, CancellationToken cancellationToken) + public Task IncrementAccessFailedCountAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.SetLockoutEnabledAsync((WrappedIdentityUser)user, enabled, cancellationToken); + ((MongoUser)user).AccessFailedCount++; + + return Task.FromResult(((MongoUser)user).AccessFailedCount); } - public Task SetTokenAsync(IUser user, string loginProvider, string name, string value, CancellationToken cancellationToken) + public Task ResetAccessFailedCountAsync(IUser user, CancellationToken cancellationToken) { - return innerStore.SetTokenAsync((WrappedIdentityUser)user, loginProvider, name, value, cancellationToken); + ((MongoUser)user).AccessFailedCount = 0; + + return TaskHelper.Done; } - public Task RemoveTokenAsync(IUser user, string loginProvider, string name, CancellationToken cancellationToken) + public Task SetLockoutEnabledAsync(IUser user, bool enabled, CancellationToken cancellationToken) { - return innerStore.RemoveTokenAsync((WrappedIdentityUser)user, loginProvider, name, cancellationToken); + ((MongoUser)user).LockoutEnabled = enabled; + + return TaskHelper.Done; } - public Task GetTokenAsync(IUser user, string loginProvider, string name, CancellationToken cancellationToken) + public Task SetTokenAsync(IUser user, string loginProvider, string name, string value, CancellationToken cancellationToken) { - return innerStore.GetTokenAsync((WrappedIdentityUser)user, loginProvider, name, cancellationToken); + ((MongoUser)user).SetToken(loginProvider, name, value); + + return TaskHelper.Done; } - public Task HasPasswordAsync(IUser user, CancellationToken cancellationToken) + public Task RemoveTokenAsync(IUser user, string loginProvider, string name, CancellationToken cancellationToken) { - return Task.FromResult(!string.IsNullOrWhiteSpace(((WrappedIdentityUser)user).PasswordHash)); + ((MongoUser)user).RemoveToken(loginProvider, name); + + return TaskHelper.Done; } } } diff --git a/src/Squidex.Domain.Users.MongoDb/MongoUserToken.cs b/src/Squidex.Domain.Users.MongoDb/MongoUserToken.cs new file mode 100644 index 000000000..e162116a8 --- /dev/null +++ b/src/Squidex.Domain.Users.MongoDb/MongoUserToken.cs @@ -0,0 +1,27 @@ +// ========================================================================== +// MongoUserToken.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using MongoDB.Bson.Serialization.Attributes; + +namespace Squidex.Domain.Users.MongoDb +{ + public sealed class MongoUserToken + { + [BsonRequired] + [BsonElement] + public string LoginProvider { get; set; } + + [BsonIgnoreIfDefault] + [BsonElement] + public string Name { get; set; } + + [BsonRequired] + [BsonElement] + public string Value { get; set; } + } +} diff --git a/src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj b/src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj index c118300b3..31704faa2 100644 --- a/src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj +++ b/src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj @@ -15,7 +15,6 @@ - diff --git a/src/Squidex.Domain.Users.MongoDb/WrappedIdentityRole.cs b/src/Squidex.Domain.Users.MongoDb/WrappedIdentityRole.cs deleted file mode 100644 index fee399a23..000000000 --- a/src/Squidex.Domain.Users.MongoDb/WrappedIdentityRole.cs +++ /dev/null @@ -1,16 +0,0 @@ -// ========================================================================== -// WrappedIdentityRole.cs -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex Group -// All rights reserved. -// ========================================================================== - -using Microsoft.AspNetCore.Identity.MongoDB; - -namespace Squidex.Domain.Users.MongoDb -{ - public sealed class WrappedIdentityRole : IdentityRole, IRole - { - } -} diff --git a/src/Squidex.Domain.Users.MongoDb/WrappedIdentityUser.cs b/src/Squidex.Domain.Users.MongoDb/WrappedIdentityUser.cs deleted file mode 100644 index abbce010a..000000000 --- a/src/Squidex.Domain.Users.MongoDb/WrappedIdentityUser.cs +++ /dev/null @@ -1,46 +0,0 @@ -// ========================================================================== -// WrappedIdentityUser.cs -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex Group -// All rights reserved. -// ========================================================================== - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Claims; -using Microsoft.AspNetCore.Identity.MongoDB; -using Squidex.Shared.Users; - -namespace Squidex.Domain.Users.MongoDb -{ - public sealed class WrappedIdentityUser : IdentityUser, IUser - { - public bool IsLocked - { - get { return LockoutEndDateUtc != null && LockoutEndDateUtc.Value > DateTime.UtcNow; } - } - - IReadOnlyList IUser.Claims - { - get { return Claims.Select(x => new Claim(x.Type, x.Value)).ToList(); } - } - - IReadOnlyList IUser.Logins - { - get { return Logins.Select(x => new ExternalLogin(x.LoginProvider, x.ProviderKey, x.ProviderDisplayName)).ToList(); } - } - - public void UpdateEmail(string email) - { - Email = UserName = email; - } - - public void SetClaim(string type, string value) - { - Claims.RemoveAll(x => string.Equals(x.Type, type, StringComparison.OrdinalIgnoreCase)); - Claims.Add(new IdentityUserClaim { Type = type, Value = value }); - } - } -} diff --git a/src/Squidex.Domain.Users/UserManagerExtensions.cs b/src/Squidex.Domain.Users/UserManagerExtensions.cs index c207d6c7e..799b9a2ee 100644 --- a/src/Squidex.Domain.Users/UserManagerExtensions.cs +++ b/src/Squidex.Domain.Users/UserManagerExtensions.cs @@ -87,7 +87,8 @@ namespace Squidex.Domain.Users if (!string.IsNullOrWhiteSpace(email)) { - user.UpdateEmail(email); + await DoChecked(() => userManager.SetEmailAsync(user, email), "Cannot update email."); + await DoChecked(() => userManager.SetUserNameAsync(user, email), "Cannot update email."); } if (!string.IsNullOrWhiteSpace(displayName)) diff --git a/src/Squidex.Infrastructure/CollectionExtensions.cs b/src/Squidex.Infrastructure/CollectionExtensions.cs index 0b177c816..b26ef92bb 100644 --- a/src/Squidex.Infrastructure/CollectionExtensions.cs +++ b/src/Squidex.Infrastructure/CollectionExtensions.cs @@ -128,5 +128,13 @@ namespace Squidex.Infrastructure return result; } + + public static void Foreach(this IEnumerable collection, Action action) + { + foreach (var item in collection) + { + action(item); + } + } } } \ No newline at end of file diff --git a/src/Squidex/Squidex.csproj b/src/Squidex/Squidex.csproj index f6a54444f..83d110efc 100644 --- a/src/Squidex/Squidex.csproj +++ b/src/Squidex/Squidex.csproj @@ -8,6 +8,7 @@ Squidex true netcoreapp2.0 + Latest true @@ -68,7 +69,7 @@ - + From daa2eb42e5b35bb9619e0c7edb0603bdde87f6ae Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Sat, 2 Sep 2017 15:03:08 +0200 Subject: [PATCH 2/3] Test --- .../Config/Identity/MicrosoftIdentityUsage.cs | 1 + src/Squidex/Config/Web/WebDependencies.cs | 14 ++++- src/Squidex/Pipeline/Foo.cs | 52 +++++++++++++++++++ src/Squidex/Squidex.csproj | 5 +- .../Squidex.Infrastructure.Tests.csproj | 4 +- 5 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 src/Squidex/Pipeline/Foo.cs diff --git a/src/Squidex/Config/Identity/MicrosoftIdentityUsage.cs b/src/Squidex/Config/Identity/MicrosoftIdentityUsage.cs index 40088d10b..60690d3f7 100644 --- a/src/Squidex/Config/Identity/MicrosoftIdentityUsage.cs +++ b/src/Squidex/Config/Identity/MicrosoftIdentityUsage.cs @@ -6,6 +6,7 @@ // All rights reserved. // ========================================================================== +using Microsoft.AspNetCore.Authentication.MicrosoftAccount; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; diff --git a/src/Squidex/Config/Web/WebDependencies.cs b/src/Squidex/Config/Web/WebDependencies.cs index 019def3c5..c515a3e2b 100644 --- a/src/Squidex/Config/Web/WebDependencies.cs +++ b/src/Squidex/Config/Web/WebDependencies.cs @@ -6,8 +6,11 @@ // All rights reserved. // ========================================================================== +using System.Linq; +using Microsoft.AspNetCore.Mvc.Razor.Compilation; using Microsoft.Extensions.DependencyInjection; using Squidex.Config.Domain; +using Squidex.Pipeline; namespace Squidex.Config.Web { @@ -15,7 +18,16 @@ namespace Squidex.Config.Web { public static void AddMyMvc(this IServiceCollection services) { - services.AddMvc().AddMySerializers(); + services + .AddMvc() + .AddMySerializers() + .ConfigureApplicationPartManager(manager => + { + var oldMetadataReferenceFeatureProvider = manager.FeatureProviders.First(f => f is MetadataReferenceFeatureProvider); + + manager.FeatureProviders.Remove(oldMetadataReferenceFeatureProvider); + manager.FeatureProviders.Add(new ReferencesMetadataReferenceFeatureProvider()); + }); } } } diff --git a/src/Squidex/Pipeline/Foo.cs b/src/Squidex/Pipeline/Foo.cs new file mode 100644 index 000000000..4190260a5 --- /dev/null +++ b/src/Squidex/Pipeline/Foo.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection.PortableExecutable; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.ApplicationParts; +using Microsoft.AspNetCore.Mvc.Razor.Compilation; +using Microsoft.CodeAnalysis; +using Microsoft.Extensions.DependencyModel; + +namespace Squidex.Pipeline +{ + public class ReferencesMetadataReferenceFeatureProvider : IApplicationFeatureProvider + { + public void PopulateFeature(IEnumerable parts, MetadataReferenceFeature feature) + { + var libraryPaths = new HashSet(StringComparer.OrdinalIgnoreCase); + foreach (var providerPart in parts.OfType()) + { + try + { + var referencePaths = providerPart.GetReferencePaths(); + foreach (var path in referencePaths) + { + if (libraryPaths.Add(path)) + { + var metadataReference = CreateMetadataReference(path); + feature.MetadataReferences.Add(metadataReference); + } + } + } + catch (InvalidOperationException) + { + Debug.WriteLine("FOO"); + } + } + } + + private static MetadataReference CreateMetadataReference(string path) + { + using (var stream = File.OpenRead(path)) + { + var moduleMetadata = ModuleMetadata.CreateFromStream(stream, PEStreamOptions.PrefetchMetadata); + var assemblyMetadata = AssemblyMetadata.Create(moduleMetadata); + + return assemblyMetadata.GetReference(filePath: path); + } + } + } +} diff --git a/src/Squidex/Squidex.csproj b/src/Squidex/Squidex.csproj index 83d110efc..0b13fbdd4 100644 --- a/src/Squidex/Squidex.csproj +++ b/src/Squidex/Squidex.csproj @@ -1,10 +1,9 @@  - Squidex true + true $(NoWarn);CS1591;1591;1573;1572 - Exe Squidex true netcoreapp2.0 @@ -63,12 +62,14 @@ + + diff --git a/tests/Squidex.Infrastructure.Tests/Squidex.Infrastructure.Tests.csproj b/tests/Squidex.Infrastructure.Tests/Squidex.Infrastructure.Tests.csproj index d99b3ad5f..a41525658 100644 --- a/tests/Squidex.Infrastructure.Tests/Squidex.Infrastructure.Tests.csproj +++ b/tests/Squidex.Infrastructure.Tests/Squidex.Infrastructure.Tests.csproj @@ -13,8 +13,8 @@ - - + + From 8714b3f871e1bb44daf95fb9d4cfeca052ff465a Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Sat, 2 Sep 2017 16:20:25 +0200 Subject: [PATCH 3/3] Cleanup --- global.json | 5 +++ src/Squidex/Config/Web/WebDependencies.cs | 14 +----- src/Squidex/Pipeline/Foo.cs | 52 ----------------------- src/Squidex/Squidex.csproj | 1 + 4 files changed, 7 insertions(+), 65 deletions(-) create mode 100644 global.json delete mode 100644 src/Squidex/Pipeline/Foo.cs diff --git a/global.json b/global.json new file mode 100644 index 000000000..110af6027 --- /dev/null +++ b/global.json @@ -0,0 +1,5 @@ +{ + "sdk": { + "version": "2.0.0" + } +} diff --git a/src/Squidex/Config/Web/WebDependencies.cs b/src/Squidex/Config/Web/WebDependencies.cs index c515a3e2b..019def3c5 100644 --- a/src/Squidex/Config/Web/WebDependencies.cs +++ b/src/Squidex/Config/Web/WebDependencies.cs @@ -6,11 +6,8 @@ // All rights reserved. // ========================================================================== -using System.Linq; -using Microsoft.AspNetCore.Mvc.Razor.Compilation; using Microsoft.Extensions.DependencyInjection; using Squidex.Config.Domain; -using Squidex.Pipeline; namespace Squidex.Config.Web { @@ -18,16 +15,7 @@ namespace Squidex.Config.Web { public static void AddMyMvc(this IServiceCollection services) { - services - .AddMvc() - .AddMySerializers() - .ConfigureApplicationPartManager(manager => - { - var oldMetadataReferenceFeatureProvider = manager.FeatureProviders.First(f => f is MetadataReferenceFeatureProvider); - - manager.FeatureProviders.Remove(oldMetadataReferenceFeatureProvider); - manager.FeatureProviders.Add(new ReferencesMetadataReferenceFeatureProvider()); - }); + services.AddMvc().AddMySerializers(); } } } diff --git a/src/Squidex/Pipeline/Foo.cs b/src/Squidex/Pipeline/Foo.cs deleted file mode 100644 index 4190260a5..000000000 --- a/src/Squidex/Pipeline/Foo.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Reflection.PortableExecutable; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc.ApplicationParts; -using Microsoft.AspNetCore.Mvc.Razor.Compilation; -using Microsoft.CodeAnalysis; -using Microsoft.Extensions.DependencyModel; - -namespace Squidex.Pipeline -{ - public class ReferencesMetadataReferenceFeatureProvider : IApplicationFeatureProvider - { - public void PopulateFeature(IEnumerable parts, MetadataReferenceFeature feature) - { - var libraryPaths = new HashSet(StringComparer.OrdinalIgnoreCase); - foreach (var providerPart in parts.OfType()) - { - try - { - var referencePaths = providerPart.GetReferencePaths(); - foreach (var path in referencePaths) - { - if (libraryPaths.Add(path)) - { - var metadataReference = CreateMetadataReference(path); - feature.MetadataReferences.Add(metadataReference); - } - } - } - catch (InvalidOperationException) - { - Debug.WriteLine("FOO"); - } - } - } - - private static MetadataReference CreateMetadataReference(string path) - { - using (var stream = File.OpenRead(path)) - { - var moduleMetadata = ModuleMetadata.CreateFromStream(stream, PEStreamOptions.PrefetchMetadata); - var assemblyMetadata = AssemblyMetadata.Create(moduleMetadata); - - return assemblyMetadata.GetReference(filePath: path); - } - } - } -} diff --git a/src/Squidex/Squidex.csproj b/src/Squidex/Squidex.csproj index 0b13fbdd4..ac910196a 100644 --- a/src/Squidex/Squidex.csproj +++ b/src/Squidex/Squidex.csproj @@ -65,6 +65,7 @@ +