Merge pull request #13 from Qtoss-AI/jason_dev

Jason dev
This commit is contained in:
Haiping 2024-09-21 15:48:31 -05:00 committed by GitHub
commit fe2d6f37af
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 113 additions and 7 deletions

View file

@ -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

View file

@ -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";
}
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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());

View file

@ -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);
}

View file

@ -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,
};

View file

@ -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);
}
}