diff --git a/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs index 1471093b..4ef68d88 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Repositories/IBotSharpRepository.cs @@ -24,7 +24,7 @@ public interface IBotSharpRepository User? GetAffiliateUserByPhone(string phone) => throw new NotImplementedException(); User? GetUserById(string id) => throw new NotImplementedException(); List GetUserByIds(List ids) => throw new NotImplementedException(); - User? GetUserByAffiliateId(string affiliateId) => throw new NotImplementedException(); + List GetUsersByAffiliateId(string affiliateId) => throw new NotImplementedException(); User? GetUserByUserName(string userName) => throw new NotImplementedException(); void CreateUser(User user) => throw new NotImplementedException(); void UpdateExistUser(string userId, User user) => throw new NotImplementedException(); diff --git a/src/Infrastructure/BotSharp.Abstraction/Users/IUserIdentity.cs b/src/Infrastructure/BotSharp.Abstraction/Users/IUserIdentity.cs index 2eb1ec9d..47e70e42 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Users/IUserIdentity.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Users/IUserIdentity.cs @@ -14,4 +14,7 @@ public interface IUserIdentity string UserLanguage { get; } string? Phone { get; } string? AffiliateId { get; } + string? EmployeeId { get; } + string Type { get; } + string Role { get; } } diff --git a/src/Infrastructure/BotSharp.Abstraction/Users/IUserService.cs b/src/Infrastructure/BotSharp.Abstraction/Users/IUserService.cs index 421e217b..d5547051 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Users/IUserService.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Users/IUserService.cs @@ -9,6 +9,7 @@ public interface IUserService Task CreateUser(User user); Task ActiveUser(UserActivationModel model); Task GetAffiliateToken(string authorization); + Task GetAdminToken(string authorization); Task GetToken(string authorization); Task GetMyProfile(); Task VerifyUserNameExisting(string userName); diff --git a/src/Infrastructure/BotSharp.Abstraction/Users/Models/User.cs b/src/Infrastructure/BotSharp.Abstraction/Users/Models/User.cs index cb48701f..69e41eca 100644 --- a/src/Infrastructure/BotSharp.Abstraction/Users/Models/User.cs +++ b/src/Infrastructure/BotSharp.Abstraction/Users/Models/User.cs @@ -22,6 +22,7 @@ public class User public string? VerificationCode { get; set; } public bool Verified { get; set; } public string? AffiliateId { get; set; } + public string? EmployeeId { get; set; } public bool IsDisabled { get; set; } public DateTime UpdatedTime { get; set; } = DateTime.UtcNow; public DateTime CreatedTime { get; set; } = DateTime.UtcNow; diff --git a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.User.cs b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.User.cs index 465ae961..b7c8aae6 100644 --- a/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.User.cs +++ b/src/Infrastructure/BotSharp.Core/Repository/FileRepository/FileRepository.User.cs @@ -31,9 +31,9 @@ public partial class FileRepository return Users.Where(x => ids.Contains(x.Id) || (x.ExternalId != null && ids.Contains(x.ExternalId)))?.ToList() ?? new List(); } - public User? GetUserByAffiliateId(string affiliateId) + public List GetUsersByAffiliateId(string affiliateId) { - return Users.FirstOrDefault(x => x.AffiliateId == affiliateId); + return Users.Where(x => x.AffiliateId == affiliateId).ToList(); } public User? GetUserByUserName(string userName = null) diff --git a/src/Infrastructure/BotSharp.Core/Users/Services/UserIdentity.cs b/src/Infrastructure/BotSharp.Core/Users/Services/UserIdentity.cs index 14f09c0e..6ddeae03 100644 --- a/src/Infrastructure/BotSharp.Core/Users/Services/UserIdentity.cs +++ b/src/Infrastructure/BotSharp.Core/Users/Services/UserIdentity.cs @@ -72,4 +72,13 @@ public class UserIdentity : IUserIdentity [JsonPropertyName("affiliateId")] public string? AffiliateId => _claims?.FirstOrDefault(x => x.Type == "affiliateId")?.Value; + + [JsonPropertyName("employeeId")] + public string? EmployeeId => _claims?.FirstOrDefault(x => x.Type == "employeeId")?.Value; + + [JsonPropertyName("type")] + public string? Type => _claims?.FirstOrDefault(x => x.Type == "type")?.Value; + + [JsonPropertyName("role")] + public string? Role => _claims?.FirstOrDefault(x => x.Type == ClaimTypes.Role)?.Value; } diff --git a/src/Infrastructure/BotSharp.Core/Users/Services/UserService.cs b/src/Infrastructure/BotSharp.Core/Users/Services/UserService.cs index 5d08c51f..9c1c8723 100644 --- a/src/Infrastructure/BotSharp.Core/Users/Services/UserService.cs +++ b/src/Infrastructure/BotSharp.Core/Users/Services/UserService.cs @@ -144,19 +144,14 @@ public class UserService : IUserService return true; } - public async Task GetAffiliateToken(string authorization) + public async Task GetAffiliateToken(string authorization) { var base64 = Encoding.UTF8.GetString(Convert.FromBase64String(authorization)); var (id, password) = base64.SplitAsTuple(":"); var db = _services.GetRequiredService(); var record = db.GetAffiliateUserByPhone(id); - if (record == null) - { - record = db.GetUserByPhone(id); - } - - var isCanLoginAffiliateRoleType = record != null && !record.IsDisabled && record.Type != UserType.Client; - if (!isCanLoginAffiliateRoleType) + var isCanLogin = record != null && !record.IsDisabled && record.Type == UserType.Affiliate; + if (!isCanLogin) { return default; } @@ -166,6 +161,35 @@ public class UserService : IUserService return default; } + return await Task.FromResult(BuildToken(record)); + } + + public async Task GetAdminToken(string authorization) + { + var base64 = Encoding.UTF8.GetString(Convert.FromBase64String(authorization)); + var (id, password) = base64.SplitAsTuple(":"); + var db = _services.GetRequiredService(); + var record = db.GetUserByPhone(id); + var isCanLogin = record != null && !record.IsDisabled + && record.Type == UserType.Internal && new List + { + UserRole.Root,UserRole.Admin + }.Contains(record.Role); + if (!isCanLogin) + { + return default; + } + + if (Utilities.HashTextMd5($"{password}{record.Salt}") != record.Password) + { + return default; + } + + return await Task.FromResult(BuildToken(record)); + } + + private Token BuildToken(User record) + { var accessToken = GenerateJwtToken(record); var jwt = new JwtSecurityTokenHandler().ReadJwtToken(accessToken); var token = new Token @@ -263,16 +287,7 @@ public class UserService : IUserService return default; } - var accessToken = GenerateJwtToken(record); - var jwt = new JwtSecurityTokenHandler().ReadJwtToken(accessToken); - var token = new Token - { - AccessToken = accessToken, - ExpireTime = jwt.Payload.Exp.Value, - TokenType = "Bearer", - Scope = "api" - }; - + var token = BuildToken(record); foreach (var hook in hooks) { hook.UserAuthenticated(jwt); @@ -296,7 +311,8 @@ public class UserService : IUserService new Claim("role", user.Role ?? UserRole.User), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), new Claim("phone", user.Phone ?? string.Empty), - new Claim("affiliateId", user.AffiliateId ?? string.Empty) + new Claim("affiliateId", user.AffiliateId ?? string.Empty), + new Claim("employeeId", user.EmployeeId ?? string.Empty) }; var validators = _services.GetServices(); diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/UserDocument.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/UserDocument.cs index ffcd71a2..a3d84e7d 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/UserDocument.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Collections/UserDocument.cs @@ -19,6 +19,7 @@ public class UserDocument : MongoBase public string? VerificationCode { get; set; } public bool Verified { get; set; } public string? AffiliateId { get; set; } + public string? EmployeeId { get; set; } public bool IsDisabled { get; set; } public DateTime CreatedTime { get; set; } public DateTime UpdatedTime { get; set; } @@ -40,6 +41,7 @@ public class UserDocument : MongoBase Type = Type, Role = Role, AffiliateId = AffiliateId, + EmployeeId = EmployeeId, IsDisabled = IsDisabled, VerificationCode = VerificationCode, Verified = Verified, diff --git a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.User.cs b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.User.cs index c064856c..3281eed0 100644 --- a/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.User.cs +++ b/src/Plugins/BotSharp.Plugin.MongoStorage/Repository/MongoRepository.User.cs @@ -37,11 +37,11 @@ public partial class MongoRepository return users?.Any() == true ? users.Select(x => x.ToUser()).ToList() : new List(); } - public User? GetUserByAffiliateId(string affiliateId) + public List GetUsersByAffiliateId(string affiliateId) { - var user = _dc.Users.AsQueryable() - .FirstOrDefault(x => x.AffiliateId == affiliateId); - return user != null ? user.ToUser() : null; + var users = _dc.Users.AsQueryable() + .Where(x => x.AffiliateId == affiliateId).ToList(); + return users?.Any() == true ? users.Select(x => x.ToUser()).ToList() : new List(); } public User? GetUserByUserName(string userName) @@ -71,6 +71,7 @@ public partial class MongoRepository VerificationCode = user.VerificationCode, Verified = user.Verified, AffiliateId = user.AffiliateId, + EmployeeId = user.EmployeeId, IsDisabled = user.IsDisabled, CreatedTime = DateTime.UtcNow, UpdatedTime = DateTime.UtcNow