add affiliate token api

This commit is contained in:
jason.wang 2024-09-21 15:12:08 +08:00
parent 47520736ba
commit d85e16dc81
10 changed files with 98 additions and 17 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

@ -33,4 +33,5 @@ public class UserRole
/// AI Assistant
/// </summary>
public const string Assistant = "assistant";
public const string Affiliate = "affiliate";
}

View file

@ -0,0 +1,14 @@
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";
public const string Affiliate = "affiliate";
}
}

View file

@ -9,7 +9,7 @@ public interface IUserService
Task<User> CreateUser(User user);
Task<Token> ActiveUser(UserActivationModel model);
Task<Token?> GetAffiliateToken(string authorization);
Task<Token?> GetClientToken(string authorization);
Task<Token?> GetToken(string authorization);
Task<User> GetMyProfile();
Task<bool> VerifyUserNameExisting(string userName);
Task<bool> VerifyEmailExisting(string email);

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 IsDisable { 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;
@ -113,16 +114,30 @@ public class UserService : IUserService
var db = _services.GetRequiredService<IBotSharpRepository>();
var record = db.GetUserByPhone(id);
var isCanLoginAffiliateRoleType = record == null && record.Type != UserType.Client;
if (isCanLoginAffiliateRoleType)
var isCanLoginAffiliateRoleType = record != null && !record.IsDisable && record.Type != UserType.Client;
if (!isCanLoginAffiliateRoleType)
{
return await GetToken(record, id, password);
return default;
}
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> GetClientToken(string authorization)
public async Task<Token?> GetToken(string authorization)
{
var base64 = Encoding.UTF8.GetString(Convert.FromBase64String(authorization));
var (id, password) = base64.SplitAsTuple(":");
@ -139,11 +154,6 @@ public class UserService : IUserService
return default;
}
return await GetToken(record, id, password);
}
private async Task<Token?> GetToken(User record, string id, string password)
{
var hooks = _services.GetServices<IAuthenticationHook>();
//verify password is correct or not.
if (record != null && !hooks.Any())
@ -157,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)
@ -168,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;

View file

@ -25,7 +25,7 @@ public class UserController : ControllerBase
authcode = authcode.Split(' ')[1];
}
var token = await _userService.GetClientToken(authcode);
var token = await _userService.GetToken(authcode);
if (token == null)
{

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 IsDisable { 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,
IsDisable = IsDisable,
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,
IsDisable = user.IsDisable,
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.IsDisable, isDisable)
.Set(x => x.UpdatedTime, DateTime.UtcNow);
_dc.Users.UpdateOne(filter, update);
}
}