commit
fe2d6f37af
|
|
@ -21,7 +21,10 @@ public interface IBotSharpRepository
|
|||
#region User
|
||||
User? GetUserByEmail(string email) => throw new NotImplementedException();
|
||||
User? GetUserByPhone(string phone) => throw new NotImplementedException();
|
||||
User? GetUserById(string id) => throw new NotImplementedException();
|
||||
User? GetAffiliateUserByPhone(string phone) => throw new NotImplementedException();
|
||||
User? GetUserById(string id) => throw new NotImplementedException();
|
||||
List<User> GetUserByIds(List<string> ids) => throw new NotImplementedException();
|
||||
User? GetUserByAffiliateId(string affiliateId) => throw new NotImplementedException();
|
||||
User? GetUserByUserName(string userName) => throw new NotImplementedException();
|
||||
void CreateUser(User user) => throw new NotImplementedException();
|
||||
void UpdateUserVerified(string userId) => throw new NotImplementedException();
|
||||
|
|
@ -29,6 +32,7 @@ public interface IBotSharpRepository
|
|||
void UpdateUserPassword(string userId, string password) => throw new NotImplementedException();
|
||||
void UpdateUserEmail(string userId, string email)=> throw new NotImplementedException();
|
||||
void UpdateUserPhone(string userId, string Iphone) => throw new NotImplementedException();
|
||||
void UpdateUserIsDisable(string userId, bool isDisable) => throw new NotImplementedException();
|
||||
#endregion
|
||||
|
||||
#region Agent
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BotSharp.Abstraction.Users.Enums
|
||||
{
|
||||
public static class UserSource
|
||||
{
|
||||
public const string Internal = "internal";
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ public interface IUserService
|
|||
Task<User> GetUser(string id);
|
||||
Task<User> CreateUser(User user);
|
||||
Task<Token> ActiveUser(UserActivationModel model);
|
||||
Task<Token?> GetAffiliateToken(string authorization);
|
||||
Task<Token?> GetToken(string authorization);
|
||||
Task<User> GetMyProfile();
|
||||
Task<bool> VerifyUserNameExisting(string userName);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ public class User
|
|||
public string? Phone { get; set; }
|
||||
public string Salt { get; set; } = string.Empty;
|
||||
public string Password { get; set; } = string.Empty;
|
||||
public string Source { get; set; } = "internal";
|
||||
public string Source { get; set; } = UserSource.Internal;
|
||||
public string? ExternalId { get; set; }
|
||||
/// <summary>
|
||||
/// internal, client, affiliate
|
||||
|
|
@ -21,6 +21,8 @@ public class User
|
|||
public string Role { get; set; } = UserRole.User;
|
||||
public string? VerificationCode { get; set; }
|
||||
public bool Verified { get; set; }
|
||||
public string? AffiliateId { get; set; }
|
||||
public bool IsDisabled { get; set; }
|
||||
public DateTime UpdatedTime { get; set; } = DateTime.UtcNow;
|
||||
public DateTime CreatedTime { get; set; } = DateTime.UtcNow;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,11 +16,26 @@ public partial class FileRepository
|
|||
return Users.FirstOrDefault(x => x.Phone == phone);
|
||||
}
|
||||
|
||||
public User? GetAffiliateUserByPhone(string phone)
|
||||
{
|
||||
return Users.FirstOrDefault(x => x.Phone == phone && x.Type == UserType.Affiliate);
|
||||
}
|
||||
|
||||
public User? GetUserById(string id = null)
|
||||
{
|
||||
return Users.FirstOrDefault(x => x.Id == id || (x.ExternalId != null && x.ExternalId == id));
|
||||
}
|
||||
|
||||
public List<User> GetUserByIds(List<string> ids)
|
||||
{
|
||||
return Users.Where(x => ids.Contains(x.Id) || (x.ExternalId != null && ids.Contains(x.ExternalId)))?.ToList() ?? new List<User>();
|
||||
}
|
||||
|
||||
public User? GetUserByAffiliateId(string affiliateId)
|
||||
{
|
||||
return Users.FirstOrDefault(x => x.AffiliateId == affiliateId);
|
||||
}
|
||||
|
||||
public User? GetUserByUserName(string userName = null)
|
||||
{
|
||||
return Users.FirstOrDefault(x => x.UserName == userName.ToLower());
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ using NanoidDotNet;
|
|||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Net;
|
||||
|
||||
namespace BotSharp.Core.Users.Services;
|
||||
|
||||
|
|
@ -106,12 +107,41 @@ public class UserService : IUserService
|
|||
return true;
|
||||
}
|
||||
|
||||
public async Task<Token> GetAffiliateToken(string authorization)
|
||||
{
|
||||
var base64 = Encoding.UTF8.GetString(Convert.FromBase64String(authorization));
|
||||
var (id, password) = base64.SplitAsTuple(":");
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var record = db.GetUserByPhone(id);
|
||||
|
||||
var isCanLoginAffiliateRoleType = record != null && !record.IsDisabled && record.Type != UserType.Client;
|
||||
if (!isCanLoginAffiliateRoleType)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
if (Utilities.HashTextMd5($"{password}{record.Salt}") != record.Password)
|
||||
{
|
||||
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"
|
||||
};
|
||||
return token;
|
||||
}
|
||||
|
||||
public async Task<Token?> GetToken(string authorization)
|
||||
{
|
||||
var base64 = Encoding.UTF8.GetString(Convert.FromBase64String(authorization));
|
||||
var (id, password) = base64.SplitAsTuple(":");
|
||||
|
||||
var hooks = _services.GetServices<IAuthenticationHook>();
|
||||
var db = _services.GetRequiredService<IBotSharpRepository>();
|
||||
var record = id.Contains("@") ? db.GetUserByEmail(id) : db.GetUserByUserName(id);
|
||||
if (record == null)
|
||||
|
|
@ -119,6 +149,12 @@ public class UserService : IUserService
|
|||
record = db.GetUserByUserName(id);
|
||||
}
|
||||
|
||||
if (record != null && record.Type == UserType.Affiliate)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
var hooks = _services.GetServices<IAuthenticationHook>();
|
||||
//verify password is correct or not.
|
||||
if (record != null && !hooks.Any())
|
||||
{
|
||||
|
|
@ -131,7 +167,7 @@ public class UserService : IUserService
|
|||
|
||||
User? user = record;
|
||||
var isAuthenticatedByHook = false;
|
||||
if (record == null || record.Source != "internal")
|
||||
if (record == null || record.Source != UserSource.Internal)
|
||||
{
|
||||
// check 3rd party user
|
||||
foreach (var hook in hooks)
|
||||
|
|
@ -142,7 +178,7 @@ public class UserService : IUserService
|
|||
continue;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(user.Source) || user.Source == "internal")
|
||||
if (string.IsNullOrEmpty(user.Source) || user.Source == UserSource.Internal)
|
||||
{
|
||||
_logger.LogError($"Please set source name in the Authenticate hook.");
|
||||
return null;
|
||||
|
|
@ -244,7 +280,7 @@ public class UserService : IUserService
|
|||
};
|
||||
var tokenHandler = new JwtSecurityTokenHandler();
|
||||
var token = tokenHandler.CreateToken(tokenDescriptor);
|
||||
SaveUserTokenExpiresCache(user.Id,expires).GetAwaiter().GetResult();
|
||||
SaveUserTokenExpiresCache(user.Id, expires).GetAwaiter().GetResult();
|
||||
return tokenHandler.WriteToken(token);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,12 +12,14 @@ public class UserDocument : MongoBase
|
|||
public string? Phone { get; set; }
|
||||
public string Salt { get; set; } = null!;
|
||||
public string Password { get; set; } = null!;
|
||||
public string Source { get; set; } = "internal";
|
||||
public string Source { get; set; } = UserSource.Internal;
|
||||
public string? ExternalId { get; set; }
|
||||
public string Type { get; set; } = UserType.Client;
|
||||
public string Role { get; set; } = null!;
|
||||
public string? VerificationCode { get; set; }
|
||||
public bool Verified { get; set; }
|
||||
public string? AffiliateId { get; set; }
|
||||
public bool IsDisabled { get; set; }
|
||||
public DateTime CreatedTime { get; set; }
|
||||
public DateTime UpdatedTime { get; set; }
|
||||
|
||||
|
|
@ -37,6 +39,8 @@ public class UserDocument : MongoBase
|
|||
ExternalId = ExternalId,
|
||||
Type = Type,
|
||||
Role = Role,
|
||||
AffiliateId = AffiliateId,
|
||||
IsDisabled = IsDisabled,
|
||||
VerificationCode = VerificationCode,
|
||||
Verified = Verified,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using BotSharp.Abstraction.Users.Enums;
|
||||
using BotSharp.Abstraction.Users.Models;
|
||||
|
||||
namespace BotSharp.Plugin.MongoStorage.Repository;
|
||||
|
|
@ -16,6 +17,12 @@ public partial class MongoRepository
|
|||
return user != null ? user.ToUser() : null;
|
||||
}
|
||||
|
||||
public User? GetAffiliateUserByPhone(string phone)
|
||||
{
|
||||
var user = _dc.Users.AsQueryable().FirstOrDefault(x => x.Phone == phone && x.Type == UserType.Affiliate);
|
||||
return user != null ? user.ToUser() : null;
|
||||
}
|
||||
|
||||
public User? GetUserById(string id)
|
||||
{
|
||||
var user = _dc.Users.AsQueryable()
|
||||
|
|
@ -23,6 +30,20 @@ public partial class MongoRepository
|
|||
return user != null ? user.ToUser() : null;
|
||||
}
|
||||
|
||||
public List<User> GetUserByIds(List<string> ids)
|
||||
{
|
||||
var users = _dc.Users.AsQueryable()
|
||||
.Where(x => ids.Contains(x.Id) || (x.ExternalId != null && ids.Contains(x.ExternalId))).ToList();
|
||||
return users?.Any() == true ? users.Select(x => x.ToUser()).ToList() : new List<User>();
|
||||
}
|
||||
|
||||
public User? GetUserByAffiliateId(string affiliateId)
|
||||
{
|
||||
var user = _dc.Users.AsQueryable()
|
||||
.FirstOrDefault(x => x.AffiliateId == affiliateId);
|
||||
return user != null ? user.ToUser() : null;
|
||||
}
|
||||
|
||||
public User? GetUserByUserName(string userName)
|
||||
{
|
||||
var user = _dc.Users.AsQueryable().FirstOrDefault(x => x.UserName == userName.ToLower());
|
||||
|
|
@ -49,6 +70,8 @@ public partial class MongoRepository
|
|||
Type = user.Type,
|
||||
VerificationCode = user.VerificationCode,
|
||||
Verified = user.Verified,
|
||||
AffiliateId = user.AffiliateId,
|
||||
IsDisabled = user.IsDisabled,
|
||||
CreatedTime = DateTime.UtcNow,
|
||||
UpdatedTime = DateTime.UtcNow
|
||||
};
|
||||
|
|
@ -95,4 +118,12 @@ public partial class MongoRepository
|
|||
.Set(x => x.UpdatedTime, DateTime.UtcNow);
|
||||
_dc.Users.UpdateOne(filter, update);
|
||||
}
|
||||
|
||||
public void UpdateUserIsDisable(string userId, bool isDisable)
|
||||
{
|
||||
var filter = Builders<UserDocument>.Filter.Eq(x => x.Id, userId);
|
||||
var update = Builders<UserDocument>.Update.Set(x => x.IsDisabled, isDisable)
|
||||
.Set(x => x.UpdatedTime, DateTime.UtcNow);
|
||||
_dc.Users.UpdateOne(filter, update);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue