mirror of https://github.com/Squidex/squidex.git
52 changed files with 178 additions and 980 deletions
@ -1,19 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// SquidexClaimTypes.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Core.Identity |
|
||||
{ |
|
||||
public static class SquidexClaimTypes |
|
||||
{ |
|
||||
public static readonly string SquidexDisplayName = "urn:squidex:name"; |
|
||||
|
|
||||
public static readonly string SquidexPictureUrl = "urn:squidex:picture"; |
|
||||
|
|
||||
public static readonly string Prefix = "urn:squidex:"; |
|
||||
} |
|
||||
} |
|
||||
@ -1,21 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// SquidexRoles.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Core.Identity |
|
||||
{ |
|
||||
public static class SquidexRoles |
|
||||
{ |
|
||||
public static readonly string Administrator = "ADMINISTRATOR"; |
|
||||
|
|
||||
public static readonly string AppOwner = "APP-OWNER"; |
|
||||
|
|
||||
public static readonly string AppEditor = "APP-EDITOR"; |
|
||||
|
|
||||
public static readonly string AppDeveloper = "APP-DEVELOPER"; |
|
||||
} |
|
||||
} |
|
||||
@ -1,93 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// MongoRoleStore.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System.Threading; |
|
||||
using System.Threading.Tasks; |
|
||||
using Microsoft.AspNetCore.Identity; |
|
||||
using Microsoft.AspNetCore.Identity.MongoDB; |
|
||||
using MongoDB.Driver; |
|
||||
using Squidex.Domain.Apps.Read.Users; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Read.MongoDb.Users |
|
||||
{ |
|
||||
public sealed class MongoRoleStore : |
|
||||
IRoleStore<IRole>, |
|
||||
IRoleFactory |
|
||||
{ |
|
||||
private readonly RoleStore<WrappedIdentityRole> innerStore; |
|
||||
|
|
||||
public MongoRoleStore(IMongoDatabase database) |
|
||||
{ |
|
||||
var rolesCollection = database.GetCollection<WrappedIdentityRole>("Identity_Roles"); |
|
||||
|
|
||||
IndexChecks.EnsureUniqueIndexOnNormalizedRoleName(rolesCollection); |
|
||||
|
|
||||
innerStore = new RoleStore<WrappedIdentityRole>(rolesCollection); |
|
||||
} |
|
||||
|
|
||||
public void Dispose() |
|
||||
{ |
|
||||
innerStore.Dispose(); |
|
||||
} |
|
||||
|
|
||||
public IRole Create(string name) |
|
||||
{ |
|
||||
return new WrappedIdentityRole { Name = name }; |
|
||||
} |
|
||||
|
|
||||
public async Task<IRole> FindByIdAsync(string roleId, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return await innerStore.FindByIdAsync(roleId, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public async Task<IRole> FindByNameAsync(string normalizedRoleName, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return await innerStore.FindByNameAsync(normalizedRoleName, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<IdentityResult> CreateAsync(IRole role, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.CreateAsync((WrappedIdentityRole)role, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<IdentityResult> UpdateAsync(IRole role, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.UpdateAsync((WrappedIdentityRole)role, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<IdentityResult> DeleteAsync(IRole role, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.DeleteAsync((WrappedIdentityRole)role, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<string> GetRoleIdAsync(IRole role, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.GetRoleIdAsync((WrappedIdentityRole)role, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<string> GetRoleNameAsync(IRole role, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.GetRoleNameAsync((WrappedIdentityRole)role, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task SetRoleNameAsync(IRole role, string roleName, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.SetRoleNameAsync((WrappedIdentityRole)role, roleName, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<string> GetNormalizedRoleNameAsync(IRole role, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.GetNormalizedRoleNameAsync((WrappedIdentityRole)role, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task SetNormalizedRoleNameAsync(IRole role, string normalizedName, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.SetNormalizedRoleNameAsync((WrappedIdentityRole)role, normalizedName, cancellationToken); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,329 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// MongoUserStore.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 System.Threading; |
|
||||
using System.Threading.Tasks; |
|
||||
using Microsoft.AspNetCore.Identity; |
|
||||
using Microsoft.AspNetCore.Identity.MongoDB; |
|
||||
using MongoDB.Driver; |
|
||||
using Squidex.Domain.Apps.Read.Users; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Read.MongoDb.Users |
|
||||
{ |
|
||||
public sealed class MongoUserStore : |
|
||||
IUserPasswordStore<IUser>, |
|
||||
IUserRoleStore<IUser>, |
|
||||
IUserLoginStore<IUser>, |
|
||||
IUserSecurityStampStore<IUser>, |
|
||||
IUserEmailStore<IUser>, |
|
||||
IUserClaimStore<IUser>, |
|
||||
IUserPhoneNumberStore<IUser>, |
|
||||
IUserTwoFactorStore<IUser>, |
|
||||
IUserLockoutStore<IUser>, |
|
||||
IUserAuthenticationTokenStore<IUser>, |
|
||||
IUserFactory, |
|
||||
IUserResolver, |
|
||||
IQueryableUserStore<IUser> |
|
||||
{ |
|
||||
private readonly UserStore<WrappedIdentityUser> innerStore; |
|
||||
|
|
||||
public MongoUserStore(IMongoDatabase database) |
|
||||
{ |
|
||||
var usersCollection = database.GetCollection<WrappedIdentityUser>("Identity_Users"); |
|
||||
|
|
||||
IndexChecks.EnsureUniqueIndexOnNormalizedEmail(usersCollection); |
|
||||
IndexChecks.EnsureUniqueIndexOnNormalizedUserName(usersCollection); |
|
||||
|
|
||||
innerStore = new UserStore<WrappedIdentityUser>(usersCollection); |
|
||||
} |
|
||||
|
|
||||
public void Dispose() |
|
||||
{ |
|
||||
innerStore.Dispose(); |
|
||||
} |
|
||||
|
|
||||
public IQueryable<IUser> Users |
|
||||
{ |
|
||||
get { return innerStore.Users; } |
|
||||
} |
|
||||
|
|
||||
public IUser Create(string email) |
|
||||
{ |
|
||||
return new WrappedIdentityUser { Email = email, UserName = email }; |
|
||||
} |
|
||||
|
|
||||
public async Task<IUser> FindByIdAsync(string userId) |
|
||||
{ |
|
||||
return await innerStore.FindByIdAsync(userId, CancellationToken.None); |
|
||||
} |
|
||||
|
|
||||
public async Task<IUser> FindByIdAsync(string userId, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return await innerStore.FindByIdAsync(userId, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public async Task<IUser> FindByEmailAsync(string normalizedEmail, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return await innerStore.FindByEmailAsync(normalizedEmail, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public async Task<IUser> FindByNameAsync(string normalizedUserName, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return await innerStore.FindByNameAsync(normalizedUserName, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public async Task<IUser> FindByLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return await innerStore.FindByLoginAsync(loginProvider, providerKey, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public async Task<IList<IUser>> GetUsersForClaimAsync(Claim claim, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return (await innerStore.GetUsersForClaimAsync(claim, cancellationToken)).OfType<IUser>().ToList(); |
|
||||
} |
|
||||
|
|
||||
public async Task<IList<IUser>> GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return (await innerStore.GetUsersInRoleAsync(roleName, cancellationToken)).OfType<IUser>().ToList(); |
|
||||
} |
|
||||
|
|
||||
public Task<IdentityResult> CreateAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.CreateAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<IdentityResult> UpdateAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.UpdateAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<IdentityResult> DeleteAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.DeleteAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<string> GetUserIdAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.GetUserIdAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<string> GetUserNameAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.GetUserNameAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task SetUserNameAsync(IUser user, string userName, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.SetUserNameAsync((WrappedIdentityUser)user, userName, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<string> GetNormalizedUserNameAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.GetNormalizedUserNameAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task SetNormalizedUserNameAsync(IUser user, string normalizedName, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.SetNormalizedUserNameAsync((WrappedIdentityUser)user, normalizedName, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<string> GetPasswordHashAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.GetPasswordHashAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task SetPasswordHashAsync(IUser user, string passwordHash, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.SetPasswordHashAsync((WrappedIdentityUser)user, passwordHash, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task AddToRoleAsync(IUser user, string roleName, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.AddToRoleAsync((WrappedIdentityUser)user, roleName, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task RemoveFromRoleAsync(IUser user, string roleName, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.RemoveFromRoleAsync((WrappedIdentityUser)user, roleName, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<IList<string>> GetRolesAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.GetRolesAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<bool> IsInRoleAsync(IUser user, string roleName, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.IsInRoleAsync((WrappedIdentityUser)user, roleName, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task AddLoginAsync(IUser user, UserLoginInfo login, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.AddLoginAsync((WrappedIdentityUser)user, login, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task RemoveLoginAsync(IUser user, string loginProvider, string providerKey, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.RemoveLoginAsync((WrappedIdentityUser)user, loginProvider, providerKey, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<IList<UserLoginInfo>> GetLoginsAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.GetLoginsAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<string> GetSecurityStampAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.GetSecurityStampAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task SetSecurityStampAsync(IUser user, string stamp, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.SetSecurityStampAsync((WrappedIdentityUser)user, stamp, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<string> GetEmailAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.GetEmailAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task SetEmailAsync(IUser user, string email, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.SetEmailAsync((WrappedIdentityUser)user, email, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<bool> GetEmailConfirmedAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.GetEmailConfirmedAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task SetEmailConfirmedAsync(IUser user, bool confirmed, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.SetEmailConfirmedAsync((WrappedIdentityUser)user, confirmed, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<string> GetNormalizedEmailAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.GetNormalizedEmailAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task SetNormalizedEmailAsync(IUser user, string normalizedEmail, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.SetNormalizedEmailAsync((WrappedIdentityUser)user, normalizedEmail, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<IList<Claim>> GetClaimsAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.GetClaimsAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task AddClaimsAsync(IUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.AddClaimsAsync((WrappedIdentityUser)user, claims, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task ReplaceClaimAsync(IUser user, Claim claim, Claim newClaim, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.ReplaceClaimAsync((WrappedIdentityUser)user, claim, newClaim, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task RemoveClaimsAsync(IUser user, IEnumerable<Claim> claims, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.RemoveClaimsAsync((WrappedIdentityUser)user, claims, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<string> GetPhoneNumberAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.GetPhoneNumberAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task SetPhoneNumberAsync(IUser user, string phoneNumber, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.SetPhoneNumberAsync((WrappedIdentityUser)user, phoneNumber, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<bool> GetPhoneNumberConfirmedAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.GetPhoneNumberConfirmedAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task SetPhoneNumberConfirmedAsync(IUser user, bool confirmed, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.SetPhoneNumberConfirmedAsync((WrappedIdentityUser)user, confirmed, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<bool> GetTwoFactorEnabledAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.GetTwoFactorEnabledAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task SetTwoFactorEnabledAsync(IUser user, bool enabled, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.SetTwoFactorEnabledAsync((WrappedIdentityUser)user, enabled, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<DateTimeOffset?> GetLockoutEndDateAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.GetLockoutEndDateAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task SetLockoutEndDateAsync(IUser user, DateTimeOffset? lockoutEnd, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.SetLockoutEndDateAsync((WrappedIdentityUser)user, lockoutEnd, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<int> GetAccessFailedCountAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.GetAccessFailedCountAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<int> IncrementAccessFailedCountAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.IncrementAccessFailedCountAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task ResetAccessFailedCountAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.ResetAccessFailedCountAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<bool> GetLockoutEnabledAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.GetLockoutEnabledAsync((WrappedIdentityUser)user, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task SetLockoutEnabledAsync(IUser user, bool enabled, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.SetLockoutEnabledAsync((WrappedIdentityUser)user, enabled, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task SetTokenAsync(IUser user, string loginProvider, string name, string value, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.SetTokenAsync((WrappedIdentityUser)user, loginProvider, name, value, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task RemoveTokenAsync(IUser user, string loginProvider, string name, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.RemoveTokenAsync((WrappedIdentityUser)user, loginProvider, name, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<string> GetTokenAsync(IUser user, string loginProvider, string name, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return innerStore.GetTokenAsync((WrappedIdentityUser)user, loginProvider, name, cancellationToken); |
|
||||
} |
|
||||
|
|
||||
public Task<bool> HasPasswordAsync(IUser user, CancellationToken cancellationToken) |
|
||||
{ |
|
||||
return Task.FromResult(!string.IsNullOrWhiteSpace(((WrappedIdentityUser)user).PasswordHash)); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,17 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// WrappedIdentityRole.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Microsoft.AspNetCore.Identity.MongoDB; |
|
||||
using Squidex.Domain.Apps.Read.Users; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Read.MongoDb.Users |
|
||||
{ |
|
||||
public sealed class WrappedIdentityRole : IdentityRole, IRole |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
@ -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.Domain.Apps.Read.Users; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Read.MongoDb.Users |
|
||||
{ |
|
||||
public sealed class WrappedIdentityUser : IdentityUser, IUser |
|
||||
{ |
|
||||
public bool IsLocked |
|
||||
{ |
|
||||
get { return LockoutEndDateUtc != null && LockoutEndDateUtc.Value > DateTime.UtcNow; } |
|
||||
} |
|
||||
|
|
||||
IReadOnlyList<Claim> IUser.Claims |
|
||||
{ |
|
||||
get { return Claims.Select(x => new Claim(x.Type, x.Value)).ToList(); } |
|
||||
} |
|
||||
|
|
||||
IReadOnlyList<ExternalLogin> 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 }); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,43 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// AssetUserPictureStore.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System.IO; |
|
||||
using System.Threading.Tasks; |
|
||||
using Squidex.Infrastructure; |
|
||||
using Squidex.Infrastructure.Assets; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Read.Users |
|
||||
{ |
|
||||
public sealed class AssetUserPictureStore : IUserPictureStore |
|
||||
{ |
|
||||
private readonly IAssetStore assetStore; |
|
||||
|
|
||||
public AssetUserPictureStore(IAssetStore assetStore) |
|
||||
{ |
|
||||
Guard.NotNull(assetStore, nameof(assetStore)); |
|
||||
|
|
||||
this.assetStore = assetStore; |
|
||||
} |
|
||||
|
|
||||
public Task UploadAsync(string userId, Stream stream) |
|
||||
{ |
|
||||
return assetStore.UploadAsync(userId, 0, "picture", stream); |
|
||||
} |
|
||||
|
|
||||
public async Task<Stream> DownloadAsync(string userId) |
|
||||
{ |
|
||||
var memoryStream = new MemoryStream(); |
|
||||
|
|
||||
await assetStore.DownloadAsync(userId, 0, "picture", memoryStream); |
|
||||
|
|
||||
memoryStream.Position = 0; |
|
||||
|
|
||||
return memoryStream; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,32 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// ExternalLogin.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Read.Users |
|
||||
{ |
|
||||
public sealed class ExternalLogin |
|
||||
{ |
|
||||
public string LoginProvider { get; } |
|
||||
|
|
||||
public string ProviderKey { get; } |
|
||||
|
|
||||
public string ProviderDisplayName { get; } |
|
||||
|
|
||||
public ExternalLogin(string loginProvider, string providerKey, string providerDisplayName) |
|
||||
{ |
|
||||
LoginProvider = loginProvider; |
|
||||
|
|
||||
ProviderKey = providerKey; |
|
||||
ProviderDisplayName = providerDisplayName; |
|
||||
|
|
||||
if (string.IsNullOrWhiteSpace(ProviderDisplayName)) |
|
||||
{ |
|
||||
ProviderDisplayName = loginProvider; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,15 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// IRole.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Read.Users |
|
||||
{ |
|
||||
public interface IRole |
|
||||
{ |
|
||||
string Name { get; } |
|
||||
} |
|
||||
} |
|
||||
@ -1,15 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// IRoleFactory.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Read.Users |
|
||||
{ |
|
||||
public interface IRoleFactory |
|
||||
{ |
|
||||
IRole Create(string name); |
|
||||
} |
|
||||
} |
|
||||
@ -1,34 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// IUser.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System.Collections.Generic; |
|
||||
using System.Security.Claims; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Read.Users |
|
||||
{ |
|
||||
public interface IUser |
|
||||
{ |
|
||||
bool IsLocked { get; } |
|
||||
|
|
||||
string Id { get; } |
|
||||
|
|
||||
string Email { get; } |
|
||||
|
|
||||
string NormalizedEmail { get; } |
|
||||
|
|
||||
IReadOnlyList<Claim> Claims { get; } |
|
||||
|
|
||||
IReadOnlyList<ExternalLogin> Logins { get; } |
|
||||
|
|
||||
void UpdateEmail(string email); |
|
||||
|
|
||||
void AddClaim(Claim claim); |
|
||||
|
|
||||
void SetClaim(string type, string value); |
|
||||
} |
|
||||
} |
|
||||
@ -1,15 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// IUserFactory.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Read.Users |
|
||||
{ |
|
||||
public interface IUserFactory |
|
||||
{ |
|
||||
IUser Create(string email); |
|
||||
} |
|
||||
} |
|
||||
@ -1,20 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// IUserPictureStore.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System.IO; |
|
||||
using System.Threading.Tasks; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Read.Users |
|
||||
{ |
|
||||
public interface IUserPictureStore |
|
||||
{ |
|
||||
Task UploadAsync(string userId, Stream stream); |
|
||||
|
|
||||
Task<Stream> DownloadAsync(string userId); |
|
||||
} |
|
||||
} |
|
||||
@ -1,17 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// IUserResolver.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System.Threading.Tasks; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Read.Users |
|
||||
{ |
|
||||
public interface IUserResolver |
|
||||
{ |
|
||||
Task<IUser> FindByIdAsync(string id); |
|
||||
} |
|
||||
} |
|
||||
@ -1,74 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// UserExtensions.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System; |
|
||||
using System.Linq; |
|
||||
using Squidex.Domain.Apps.Core.Identity; |
|
||||
using Squidex.Infrastructure; |
|
||||
|
|
||||
// ReSharper disable InvertIf
|
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Read.Users |
|
||||
{ |
|
||||
public static class UserExtensions |
|
||||
{ |
|
||||
public static void UpdateDisplayName(this IUser user, string displayName) |
|
||||
{ |
|
||||
user.SetClaim(SquidexClaimTypes.SquidexDisplayName, displayName); |
|
||||
} |
|
||||
|
|
||||
public static void SetPictureUrl(this IUser user, string pictureUrl) |
|
||||
{ |
|
||||
user.SetClaim(SquidexClaimTypes.SquidexPictureUrl, pictureUrl); |
|
||||
} |
|
||||
|
|
||||
public static void SetPictureUrlToStore(this IUser user) |
|
||||
{ |
|
||||
user.SetClaim(SquidexClaimTypes.SquidexPictureUrl, "store"); |
|
||||
} |
|
||||
|
|
||||
public static void SetPictureUrlFromGravatar(this IUser user, string email) |
|
||||
{ |
|
||||
user.SetClaim(SquidexClaimTypes.SquidexPictureUrl, GravatarHelper.CreatePictureUrl(email)); |
|
||||
} |
|
||||
|
|
||||
public static bool IsPictureUrlStored(this IUser user) |
|
||||
{ |
|
||||
return string.Equals(user.Claims.FirstOrDefault(x => x.Type == SquidexClaimTypes.SquidexPictureUrl)?.Value, "store", StringComparison.OrdinalIgnoreCase); |
|
||||
} |
|
||||
|
|
||||
public static string PictureUrl(this IUser user) |
|
||||
{ |
|
||||
return user.Claims.FirstOrDefault(x => x.Type == SquidexClaimTypes.SquidexPictureUrl)?.Value; |
|
||||
} |
|
||||
|
|
||||
public static string DisplayName(this IUser user) |
|
||||
{ |
|
||||
return user.Claims.FirstOrDefault(x => x.Type == SquidexClaimTypes.SquidexDisplayName)?.Value; |
|
||||
} |
|
||||
|
|
||||
public static string PictureNormalizedUrl(this IUser user) |
|
||||
{ |
|
||||
var url = user.Claims.FirstOrDefault(x => x.Type == SquidexClaimTypes.SquidexPictureUrl)?.Value; |
|
||||
|
|
||||
if (!string.IsNullOrWhiteSpace(url) && Uri.IsWellFormedUriString(url, UriKind.Absolute) && url.Contains("gravatar")) |
|
||||
{ |
|
||||
if (url.Contains("?")) |
|
||||
{ |
|
||||
url += "&d=404"; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
url += "?d=404"; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return url; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,131 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// UserManagerExtensions.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Threading.Tasks; |
|
||||
using Microsoft.AspNetCore.Identity; |
|
||||
using Squidex.Infrastructure; |
|
||||
|
|
||||
// ReSharper disable ImplicitlyCapturedClosure
|
|
||||
// ReSharper disable InvertIf
|
|
||||
// ReSharper disable ReturnTypeCanBeEnumerable.Local
|
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Read.Users |
|
||||
{ |
|
||||
public static class UserManagerExtensions |
|
||||
{ |
|
||||
public static Task<IReadOnlyList<IUser>> QueryByEmailAsync(this UserManager<IUser> userManager, string email = null, int take = 10, int skip = 0) |
|
||||
{ |
|
||||
var users = QueryUsers(userManager, email).Skip(skip).Take(take).ToList(); |
|
||||
|
|
||||
return Task.FromResult<IReadOnlyList<IUser>>(users); |
|
||||
} |
|
||||
|
|
||||
public static Task<long> CountByEmailAsync(this UserManager<IUser> userManager, string email = null) |
|
||||
{ |
|
||||
var count = QueryUsers(userManager, email).LongCount(); |
|
||||
|
|
||||
return Task.FromResult(count); |
|
||||
} |
|
||||
|
|
||||
private static IQueryable<IUser> QueryUsers(UserManager<IUser> userManager, string email = null) |
|
||||
{ |
|
||||
var result = userManager.Users; |
|
||||
|
|
||||
if (!string.IsNullOrWhiteSpace(email)) |
|
||||
{ |
|
||||
var upperEmail = email.ToUpperInvariant(); |
|
||||
|
|
||||
result = result.Where(x => x.NormalizedEmail.Contains(upperEmail)); |
|
||||
} |
|
||||
|
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
public static async Task<IUser> CreateAsync(this UserManager<IUser> userManager, IUserFactory factory, string email, string displayName, string password) |
|
||||
{ |
|
||||
var user = factory.Create(email); |
|
||||
|
|
||||
user.UpdateDisplayName(displayName); |
|
||||
user.SetPictureUrlFromGravatar(email); |
|
||||
|
|
||||
await DoChecked(() => userManager.CreateAsync(user), "Cannot create user."); |
|
||||
|
|
||||
if (!string.IsNullOrWhiteSpace(password)) |
|
||||
{ |
|
||||
await DoChecked(() => userManager.AddPasswordAsync(user, password), "Cannot create user."); |
|
||||
} |
|
||||
|
|
||||
return user; |
|
||||
} |
|
||||
|
|
||||
public static async Task UpdateAsync(this UserManager<IUser> userManager, string id, string email, string displayName, string password) |
|
||||
{ |
|
||||
var user = await userManager.FindByIdAsync(id); |
|
||||
|
|
||||
if (user == null) |
|
||||
{ |
|
||||
throw new DomainObjectNotFoundException(id, typeof(IUser)); |
|
||||
} |
|
||||
|
|
||||
if (!string.IsNullOrWhiteSpace(email)) |
|
||||
{ |
|
||||
user.UpdateEmail(email); |
|
||||
} |
|
||||
|
|
||||
if (!string.IsNullOrWhiteSpace(displayName)) |
|
||||
{ |
|
||||
user.UpdateDisplayName(displayName); |
|
||||
} |
|
||||
|
|
||||
await DoChecked(() => userManager.UpdateAsync(user), "Cannot update user."); |
|
||||
|
|
||||
if (!string.IsNullOrWhiteSpace(password)) |
|
||||
{ |
|
||||
await DoChecked(() => userManager.RemovePasswordAsync(user), "Cannot update user."); |
|
||||
await DoChecked(() => userManager.AddPasswordAsync(user, password), "Cannot update user."); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public static async Task LockAsync(this UserManager<IUser> userManager, string id) |
|
||||
{ |
|
||||
var user = await userManager.FindByIdAsync(id); |
|
||||
|
|
||||
if (user == null) |
|
||||
{ |
|
||||
throw new DomainObjectNotFoundException(id, typeof(IUser)); |
|
||||
} |
|
||||
|
|
||||
await DoChecked(() => userManager.SetLockoutEndDateAsync(user, DateTimeOffset.UtcNow.AddYears(100)), "Cannot lock user."); |
|
||||
} |
|
||||
|
|
||||
public static async Task UnlockAsync(this UserManager<IUser> userManager, string id) |
|
||||
{ |
|
||||
var user = await userManager.FindByIdAsync(id); |
|
||||
|
|
||||
if (user == null) |
|
||||
{ |
|
||||
throw new DomainObjectNotFoundException(id, typeof(IUser)); |
|
||||
} |
|
||||
|
|
||||
await DoChecked(() => userManager.SetLockoutEndDateAsync(user, null), "Cannot unlock user."); |
|
||||
} |
|
||||
|
|
||||
private static async Task DoChecked(Func<Task<IdentityResult>> action, string message) |
|
||||
{ |
|
||||
var result = await action(); |
|
||||
|
|
||||
if (!result.Succeeded) |
|
||||
{ |
|
||||
throw new ValidationException(message, result.Errors.Select(x => new ValidationError(x.Description)).ToArray()); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,28 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
<PropertyGroup> |
||||
|
<OutputType>Exe</OutputType> |
||||
|
<TargetFramework>netcoreapp1.1</TargetFramework> |
||||
|
<PackageTargetFallback>$(PackageTargetFallback);dnxcore50</PackageTargetFallback> |
||||
|
<RootNamespace>Squidex.Domain.Users</RootNamespace> |
||||
|
</PropertyGroup> |
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\..\src\Squidex.Domain.Users.MongoDb\Squidex.Domain.Users.MongoDb.csproj" /> |
||||
|
<ProjectReference Include="..\..\src\Squidex.Domain.Users\Squidex.Domain.Users.csproj" /> |
||||
|
<ProjectReference Include="..\..\src\Squidex.Infrastructure\Squidex.Infrastructure.csproj" /> |
||||
|
<ProjectReference Include="..\..\src\Squidex.Shared\Squidex.Shared.csproj" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="FluentAssertions" Version="4.19.3" /> |
||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" /> |
||||
|
<PackageReference Include="Moq" Version="4.7.63" /> |
||||
|
<PackageReference Include="System.ValueTuple" Version="4.3.1" /> |
||||
|
<PackageReference Include="xunit" Version="2.2.0" /> |
||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="1.0.0-msbuild3-final" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" /> |
||||
|
</ItemGroup> |
||||
|
</Project> |
||||
Loading…
Reference in new issue