Skip to content

Commit

Permalink
Merge pull request #739 from Portkey-Wallet/release/1.23.1
Browse files Browse the repository at this point in the history
Release/1.23.1
  • Loading branch information
Edward-BXS authored Aug 21, 2024
2 parents e0e86b8 + 22b8989 commit bfc74c8
Show file tree
Hide file tree
Showing 13 changed files with 223 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace CAServer.Growth.Dtos;

public class ScoreInfos
{
public List<HamsterScoreDto> GetScoreInfos { get; set; }
public List<HamsterScoreDto> GetScoreInfos { get; set; } = new List<HamsterScoreDto>();

}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.ComponentModel.DataAnnotations;

namespace CAServer.Telegram.Dtos;

public class RegisterTelegramBotDto
{
[Required]
public string Secret { get; set; }

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace CAServer.Telegram.Dtos;

public class TelegramAuthResponseDto<T>
{
public bool Success { get; set; }
public string Message { get; set; }
public T Data { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace CAServer.Telegram.Dtos;

public class TelegramBotInfoDto
{
public string BotId { get; set; }
public string Secret { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using CAServer.Telegram.Dtos;
Expand All @@ -13,4 +12,6 @@ public interface ITelegramAuthService
Task<string> ValidateTelegramHashAndGenerateTokenAsync(TelegramAuthReceiveRequest telegramAuthReceiveRequest);

Task<string> ValidateTelegramHashAndGenerateTokenAsync(IDictionary<string, string> requestParameter);

Task<TelegramAuthResponseDto<TelegramBotInfoDto>> RegisterTelegramBot(RegisterTelegramBotDto request);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Threading.Tasks;

namespace CAServer.Telegram;

public interface ITelegramRateLimiter
{
Task RecordRequestAsync();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace CAServer.Telegram.Options;

public class TelegramVerifierOptions
{
public string Url { get; set; }
public int Timeout { get; set; }
public int BotIdMinimumLength { get; set; } = 9;
public int BotIdMaximumLength { get; set; } = 11;
public int SecretMinimumLength { get; set; } = 34;
public int SecretMaximumLength { get; set; } = 36;

public int ReplenishmentPeriodSeconds { get; set; } = 60;
public int TokenLimit { get; set; } = 5;
public int TokensPerPeriod { get; set; } = 5;
}
1 change: 1 addition & 0 deletions src/CAServer.Application/CAServerApplicationModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ public override void ConfigureServices(ServiceConfigurationContext context)
Configure<ExchangeOptions>(configuration.GetSection("Exchange"));
Configure<RedPackageOptions>(configuration.GetSection("RedPackage"));
Configure<TelegramAuthOptions>(configuration.GetSection("TelegramAuth"));
Configure<TelegramVerifierOptions>(configuration.GetSection("TelegramVerifier"));
// Configure<JwtTokenOptions>(configuration.GetSection("JwtToken"));
Configure<ManagerCountLimitOptions>(configuration.GetSection("ManagerCountLimit"));
Configure<UserGuideInfoOptions>(configuration.GetSection("GuideInfo"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ public async Task<ValidateHamsterScoreResponseDto> ValidateHamsterScoreAsync(str
var hamsterScoreList =
await _growthProvider.GetHamsterScoreListAsync(new List<string> { address }, DateTime.UtcNow.AddDays(-1),
DateTime.UtcNow);
if (hamsterScoreList == null || hamsterScoreList.GetScoreInfos.Count == 0)
if (hamsterScoreList.GetScoreInfos?.Count == 0)
{
return new ValidateHamsterScoreResponseDto()
{
Expand Down
124 changes: 122 additions & 2 deletions src/CAServer.Application/Telegram/TelegramAuthService.cs
Original file line number Diff line number Diff line change
@@ -1,35 +1,48 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.RateLimiting;
using System.Threading.Tasks;
using CAServer.Common;
using CAServer.Commons;
using CAServer.Telegram.Dtos;
using CAServer.Telegram.Options;
using CAServer.Verifier;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Volo.Abp;
using Volo.Abp.Auditing;
using Volo.Abp.ObjectMapping;

namespace CAServer.Telegram;

[RemoteService(false), DisableAuditing]
public class TelegramAuthService : CAServerAppService, ITelegramAuthService
public partial class TelegramAuthService : CAServerAppService, ITelegramAuthService
{
[GeneratedRegex("^\\d+$")]
private static partial Regex DigitRegex();
[GeneratedRegex("^[a-zA-Z0-9_-]+$")]
private static partial Regex DigitLetterDashUnderScoreRegex();
private readonly ILogger<TelegramAuthService> _logger;
private readonly TelegramAuthOptions _telegramAuthOptions;
private readonly IObjectMapper _objectMapper;
private readonly IHttpClientService _httpClientService;
private readonly TelegramVerifierOptions _telegramVerifierOptions;
private readonly ITelegramRateLimiter _telegramRateLimiter;

public TelegramAuthService(ILogger<TelegramAuthService> logger,
IOptionsSnapshot<TelegramAuthOptions> telegramAuthOptions, IObjectMapper objectMapper,
IHttpClientService httpClientService)
IHttpClientService httpClientService, IOptions<TelegramVerifierOptions> telegramVerifierOptions,
ITelegramRateLimiter telegramRateLimiter)
{
_logger = logger;
_telegramAuthOptions = telegramAuthOptions.Value;
_objectMapper = objectMapper;
_httpClientService = httpClientService;
_telegramVerifierOptions = telegramVerifierOptions.Value;
_telegramRateLimiter = telegramRateLimiter;
}

public Task<TelegramBotDto> GetTelegramBotInfoAsync()
Expand Down Expand Up @@ -84,4 +97,111 @@ public async Task<string> ValidateTelegramHashAndGenerateTokenAsync(IDictionary<

return resultDto.Data;
}
private async Task<T> RequestAsync<T>(Func<Task<T>> task)
{
await _telegramRateLimiter.RecordRequestAsync();
return await task();
}

public async Task<TelegramAuthResponseDto<TelegramBotInfoDto>> RegisterTelegramBot(RegisterTelegramBotDto request)
{
return await RequestAsync(async () => await DoRegisterTelegramBot(request));
}

private async Task<TelegramAuthResponseDto<TelegramBotInfoDto>> DoRegisterTelegramBot(RegisterTelegramBotDto request)
{
var checkResult = CheckSecret(request);
if (!checkResult.Success)
{
return checkResult;
}
var url = $"{_telegramVerifierOptions.Url}/api/app/auth/bot/register";
var resultDto = await _httpClientService.PostAsync<ResponseResultDto<TelegramBotInfoDto>>(url, request);
if (resultDto == null)
{
return new TelegramAuthResponseDto<TelegramBotInfoDto>
{
Success = false,
Message = "no result returned"
};
}

if (!resultDto.Success)
{
return new TelegramAuthResponseDto<TelegramBotInfoDto>
{
Success = false,
Message = resultDto.Message
};
}

return new TelegramAuthResponseDto<TelegramBotInfoDto>
{
Success = resultDto.Success,
Message = resultDto.Message,
Data = resultDto.Data
};
}

private TelegramAuthResponseDto<TelegramBotInfoDto> CheckSecret(RegisterTelegramBotDto request)
{
if (request == null || request.Secret.IsNullOrEmpty())
{
return new TelegramAuthResponseDto<TelegramBotInfoDto>
{
Success = false,
Message = "Invalid input, secret needs"
};
}

var secret = request.Secret;
if (!secret.Contains(CommonConstant.Colon))
{
return new TelegramAuthResponseDto<TelegramBotInfoDto>
{
Success = false,
Message = "Secret Format is invalid"
};
}

var secrets = secret.Split(CommonConstant.Colon);
if (secrets.Length != 2)
{
return new TelegramAuthResponseDto<TelegramBotInfoDto>
{
Success = false,
Message = "Secret Format is invalid"
};
}

var botId = secrets[0];
if (botId.IsNullOrEmpty()
|| !DigitRegex().IsMatch(botId)
|| botId.Length <= _telegramVerifierOptions.BotIdMinimumLength
|| botId.Length >= _telegramVerifierOptions.BotIdMaximumLength)
{
return new TelegramAuthResponseDto<TelegramBotInfoDto>
{
Success = false,
Message = "Secret Format is invalid, botId is invalid"
};
}

var token = secrets[1];
if (token.IsNullOrEmpty()
|| !DigitLetterDashUnderScoreRegex().IsMatch(token)
|| token.Length <= _telegramVerifierOptions.SecretMinimumLength
|| token.Length >= _telegramVerifierOptions.SecretMaximumLength)
{
return new TelegramAuthResponseDto<TelegramBotInfoDto>
{
Success = false,
Message = "Secret Content Format is invalid"
};
}
return new TelegramAuthResponseDto<TelegramBotInfoDto>
{
Success = true,
};
}
}
41 changes: 41 additions & 0 deletions src/CAServer.Application/Telegram/TelegramRateLimiter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System;
using System.Threading.RateLimiting;
using System.Threading.Tasks;
using CAServer.Telegram.Options;
using Microsoft.Extensions.Options;
using Volo.Abp;
using Volo.Abp.DependencyInjection;

namespace CAServer.Telegram;

public class TelegramRateLimiter : ITelegramRateLimiter, ISingletonDependency
{
private readonly RateLimiter _rateLimiter;
private readonly IOptionsMonitor<TelegramVerifierOptions> _optionsMonitor;

public TelegramRateLimiter(IOptionsMonitor<TelegramVerifierOptions> optionsMonitor)
{
_optionsMonitor = optionsMonitor;
_rateLimiter = InitializeRateLimiter();
}

private RateLimiter InitializeRateLimiter()
{
return new TokenBucketRateLimiter(new TokenBucketRateLimiterOptions
{
ReplenishmentPeriod = TimeSpan.FromSeconds(_optionsMonitor.CurrentValue.ReplenishmentPeriodSeconds),
TokenLimit = _optionsMonitor.CurrentValue.TokenLimit,
TokensPerPeriod = _optionsMonitor.CurrentValue.TokensPerPeriod
});
}

public Task RecordRequestAsync()
{
var rateLimitLease = _rateLimiter.AttemptAcquire(1);
if (!rateLimitLease.IsAcquired)
{
throw new UserFriendlyException("The request exceeded the limit.");
}
return Task.CompletedTask;
}
}
2 changes: 1 addition & 1 deletion src/CAServer.HttpApi.Host/CAServerHttpApiHostModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public override void ConfigureServices(ServiceConfigurationContext context)
options => { options.Configuration.ChannelPrefix = "CAServer"; });
ConfigAuditing();
}

private void ConfigureCache(IConfiguration configuration)
{
Configure<AbpDistributedCacheOptions>(options => { options.KeyPrefix = "CAServer:"; });
Expand Down
6 changes: 6 additions & 0 deletions src/CAServer.HttpApi/Controllers/TelegramAuthController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,10 @@ public async Task<TelegramAuthTokenResponseDto> TokenAsync()
Token = token
};
}

[HttpPost("bot/register")]
public async Task<TelegramAuthResponseDto<TelegramBotInfoDto>> RegisterTelegramBot([FromBody] RegisterTelegramBotDto registerTelegramBotDto)
{
return await _telegramAuthService.RegisterTelegramBot(registerTelegramBotDto);
}
}

0 comments on commit bfc74c8

Please sign in to comment.