diff --git a/.gitignore b/.gitignore index f5e5847ac..c4ead1401 100644 --- a/.gitignore +++ b/.gitignore @@ -275,6 +275,9 @@ grpc_csharp_plugin launchSettings.json +# dev settings +*/**/appsettings.Development.json + yarn.lock results/coverage.json diff --git a/CAServer.sln b/CAServer.sln index 53922b918..aed8b0360 100644 --- a/CAServer.sln +++ b/CAServer.sln @@ -65,6 +65,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CAServer.EntityEventHandler EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CAServer.HttpApi.Tests", "test\CAServer.HttpApi.Tests\CAServer.HttpApi.Tests.csproj", "{A79C3A46-D7FA-435F-BFB0-6C41B27C33EE}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CAServer.Signature.HttpApi", "src\CAServer.Signature.HttpApi\CAServer.Signature.HttpApi.csproj", "{E591184A-51BB-4B30-9613-3D71B0A37827}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CAServer.Signature.HttpApi.Host", "src\CAServer.Signature.HttpApi.Host\CAServer.Signature.HttpApi.Host.csproj", "{13DC2010-60D4-4925-BE24-996A0516F0B6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CAServer.Signature.HttpApi.Tests", "test\CAServer.Signature.HttpApi.Tests\CAServer.Signature.HttpApi.Tests.csproj", "{B0079C9F-368D-4CDB-B097-27A6250BD402}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CAServer.Signature", "src\CAServer.Signature\CAServer.Signature.csproj", "{EC87414A-45DA-4FEB-9A25-874C5A852B91}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -187,6 +195,22 @@ Global {A79C3A46-D7FA-435F-BFB0-6C41B27C33EE}.Debug|Any CPU.Build.0 = Debug|Any CPU {A79C3A46-D7FA-435F-BFB0-6C41B27C33EE}.Release|Any CPU.ActiveCfg = Release|Any CPU {A79C3A46-D7FA-435F-BFB0-6C41B27C33EE}.Release|Any CPU.Build.0 = Release|Any CPU + {E591184A-51BB-4B30-9613-3D71B0A37827}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E591184A-51BB-4B30-9613-3D71B0A37827}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E591184A-51BB-4B30-9613-3D71B0A37827}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E591184A-51BB-4B30-9613-3D71B0A37827}.Release|Any CPU.Build.0 = Release|Any CPU + {13DC2010-60D4-4925-BE24-996A0516F0B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {13DC2010-60D4-4925-BE24-996A0516F0B6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {13DC2010-60D4-4925-BE24-996A0516F0B6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {13DC2010-60D4-4925-BE24-996A0516F0B6}.Release|Any CPU.Build.0 = Release|Any CPU + {B0079C9F-368D-4CDB-B097-27A6250BD402}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B0079C9F-368D-4CDB-B097-27A6250BD402}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B0079C9F-368D-4CDB-B097-27A6250BD402}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B0079C9F-368D-4CDB-B097-27A6250BD402}.Release|Any CPU.Build.0 = Release|Any CPU + {EC87414A-45DA-4FEB-9A25-874C5A852B91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EC87414A-45DA-4FEB-9A25-874C5A852B91}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EC87414A-45DA-4FEB-9A25-874C5A852B91}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EC87414A-45DA-4FEB-9A25-874C5A852B91}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -221,6 +245,10 @@ Global {1B1FA09C-98AC-4893-9D76-EC34071E55C5} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} {484F985C-3BCC-484D-B2D4-5A366388C249} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} {A79C3A46-D7FA-435F-BFB0-6C41B27C33EE} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} + {E591184A-51BB-4B30-9613-3D71B0A37827} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + {13DC2010-60D4-4925-BE24-996A0516F0B6} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + {B0079C9F-368D-4CDB-B097-27A6250BD402} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} + {EC87414A-45DA-4FEB-9A25-874C5A852B91} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F} diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 890574268..a88fbc9b3 100755 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -31,8 +31,8 @@ jobs: # - script: PowerShell.exe -file build.ps1 --target=Upload-Coverage-Azure # displayName: 'Upload data to Codecov' # All tasks on Linux - - job: build_all_linux - displayName: Build all tasks (Linux) +# - job: build_all_linux +# displayName: Build all tasks (Linux) # timeoutInMinutes: 120 # pool: # vmImage: ubuntu-latest @@ -60,13 +60,11 @@ jobs: # - script: bash build.sh --target=Upload-Coverage-Azure # displayName: 'Upload data to Codecov' #All tasks on macOS -# - job: build_all_darwin -# displayName: Build all tasks (macOS) + - job: build_all_darwin + displayName: Build all tasks (macOS) timeoutInMinutes: 120 pool: - name: Default - demands: - - Agent.OS -equals Linux + vmImage: macos-latest variables: CI_TEST: true steps: @@ -74,7 +72,7 @@ jobs: displayName: 'Install .NET Core SDK' inputs: version: 7.0.x - - script: cd scripts && bash elasticsearch-linux.sh + - script: cd scripts && bash elasticsearch-macOS.sh displayName: 'Start an elasticsearch' - script: bash build.sh --target=Test-with-Codecov displayName: 'Build and Test' diff --git a/src/CAServer.Application.Contracts/AppleAuth/AppleAuthOptions.cs b/src/CAServer.Application.Contracts/AppleAuth/AppleAuthOptions.cs index 216c3228e..e55594df1 100644 --- a/src/CAServer.Application.Contracts/AppleAuth/AppleAuthOptions.cs +++ b/src/CAServer.Application.Contracts/AppleAuth/AppleAuthOptions.cs @@ -7,6 +7,7 @@ public class AppleAuthOptions public List Audiences { get; set; } public string RedirectUrl { get; set; } public string BingoRedirectUrl { get; set; } + public string UnifyRedirectUrl { get; set; } public ExtensionConfig ExtensionConfig { get; set; } } diff --git a/src/CAServer.Application.Contracts/CAAccount/Dtos/QueryRecoveryResponse.cs b/src/CAServer.Application.Contracts/CAAccount/Dtos/QueryRecoveryResponse.cs deleted file mode 100644 index 1d139f13c..000000000 --- a/src/CAServer.Application.Contracts/CAAccount/Dtos/QueryRecoveryResponse.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -namespace CAServer.Dtos -{ - public class QueryRecoveryResponse - { - - public string RecoveryStatus { get; set; } - public string RecoveryMessage { get; set; } - public string CaHash { get; set; } - public string CaAddress { get; set; } - - } -} - diff --git a/src/CAServer.Application.Contracts/CAActivity/ActivityConstants.cs b/src/CAServer.Application.Contracts/CAActivity/ActivityConstants.cs index 595bbb7af..303cad85c 100644 --- a/src/CAServer.Application.Contracts/CAActivity/ActivityConstants.cs +++ b/src/CAServer.Application.Contracts/CAActivity/ActivityConstants.cs @@ -4,6 +4,27 @@ namespace CAServer.CAActivity; public static class ActivityConstants { + public static readonly Dictionary TypeMap = new() + { + { "Transfer", "Transfer" }, + { "CrossChainTransfer", "CrossChain Transfer" }, + { "SocialRecovery", "Social Recovery" }, + { "RemoveManagerInfo", "Exit Wallet" }, + { "AddManagerInfo", "Scan code login" }, + { "CreateCAHolder", "Create CA address" }, + { "AddGuardian", "Add guardian" }, + { "RemoveGuardian", "Remove guardian" }, + { "UpdateGuardian", "Edit guardian" }, + { "SetGuardianForLogin", "Set login account" }, + { "UnsetGuardianForLogin", "Unset login account" }, + { "RemoveOtherManagerInfo", "Remove device" }, + { "ClaimToken", "Transfer" }, + { "Register", "Register" }, + { "Approve", "Approve" }, + { "Bingo", "Bingo" }, + { "Play", "Play" } + }; + public static readonly List DefaultTypes = new() { "Transfer", "SocialRecovery", "RemoveManagerInfo", "AddManagerInfo" @@ -13,7 +34,7 @@ public static class ActivityConstants { "Transfer", "CrossChainTransfer", "CrossChainReceiveToken", "SocialRecovery", "RemoveManagerInfo", "AddManagerInfo", "CreateCAHolder", "AddGuardian", "RemoveGuardian", "UpdateGuardian", "SetGuardianForLogin", - "UnsetGuardianForLogin", "RemoveOtherManagerInfo", "ClaimToken", "Approve", "Bingo", "Play" + "UnsetGuardianForLogin", "RemoveOtherManagerInfo", "ClaimToken", "Register", "Approve", "Bingo", "Play" }; public static readonly List TransferTypes = new() @@ -24,7 +45,9 @@ public static class ActivityConstants public static readonly List ContractTypes = new() { "SocialRecovery", "RemoveManagerInfo", "AddManagerInfo", "CreateCAHolder", "AddGuardian", "RemoveGuardian", - "UpdateGuardian", "SetGuardianForLogin", "UnsetGuardianForLogin", "RemoveOtherManagerInfo", "Approve", "Bingo", "Play" + "UpdateGuardian", "SetGuardianForLogin", "UnsetGuardianForLogin", "RemoveOtherManagerInfo", "Register", + "Approve", "Bingo", + "Play" }; public static readonly List ShowPriceTypes = new() @@ -34,5 +57,15 @@ public static class ActivityConstants "UnsetGuardianForLogin", "RemoveOtherManagerInfo", "ClaimToken", "Approve", "Bingo", "Play" }; + public static readonly List ShowNftTypes = new() + { + "Transfer", "CrossChainTransfer" + }; + + public static readonly List RecentTypes = new() + { + "Transfer", "CrossChainTransfer", "ClaimToken" + }; + public static readonly string Zero = "0"; } \ No newline at end of file diff --git a/src/CAServer.Application.Contracts/CAActivity/Dtos/ActivityBase.cs b/src/CAServer.Application.Contracts/CAActivity/Dtos/ActivityBase.cs index 879f7a4a3..4790ab438 100644 --- a/src/CAServer.Application.Contracts/CAActivity/Dtos/ActivityBase.cs +++ b/src/CAServer.Application.Contracts/CAActivity/Dtos/ActivityBase.cs @@ -7,6 +7,7 @@ public class ActivityBase public string TransactionId { get; set; } public string BlockHash { get; set; } public string TransactionType { get; set; } + public string TransactionName { get; set; } public string Amount { get; set; } public string Symbol { get; set; } public string Decimals { get; set; } diff --git a/src/CAServer.Application.Contracts/CAActivity/Dtos/GetTwoCaTransactionRequestDto.cs b/src/CAServer.Application.Contracts/CAActivity/Dtos/GetTwoCaTransactionRequestDto.cs new file mode 100644 index 000000000..86b575bd1 --- /dev/null +++ b/src/CAServer.Application.Contracts/CAActivity/Dtos/GetTwoCaTransactionRequestDto.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using CAServer.UserAssets; +using Volo.Abp.Application.Dtos; + +namespace CAServer.CAActivity.Dtos; + +public class GetTwoCaTransactionRequestDto : PagedResultRequestDto +{ + public List TargetAddressInfos { get; set; } + + public List CaAddressInfos { get; set; } + public string ChainId { get; set; } + public string Symbol { get; set; } + + public int Width { get; set; } + + public int Height { get; set; } +} \ No newline at end of file diff --git a/src/CAServer.Application.Contracts/CAActivity/Dtos/IndexerTransactions.cs b/src/CAServer.Application.Contracts/CAActivity/Dtos/IndexerTransactions.cs index 8f4e9af40..7a96db2e0 100644 --- a/src/CAServer.Application.Contracts/CAActivity/Dtos/IndexerTransactions.cs +++ b/src/CAServer.Application.Contracts/CAActivity/Dtos/IndexerTransactions.cs @@ -8,6 +8,11 @@ public class IndexerTransactions public CaHolderTransaction CaHolderTransaction { get; set; } } +public class TransactionsDto +{ + public CaHolderTransaction TwoCaHolderTransaction { get; set; } +} + public class CaHolderTransaction { public List Data { get; set; } diff --git a/src/CAServer.Application.Contracts/CAActivity/IUserActivityService.cs b/src/CAServer.Application.Contracts/CAActivity/IUserActivityService.cs index 693b5009c..c847aade6 100644 --- a/src/CAServer.Application.Contracts/CAActivity/IUserActivityService.cs +++ b/src/CAServer.Application.Contracts/CAActivity/IUserActivityService.cs @@ -8,6 +8,7 @@ namespace CAServer.CAActivity; public interface IUserActivityAppService:IApplicationService { + Task GetTwoCaTransactionsAsync(GetTwoCaTransactionRequestDto request); Task GetActivitiesAsync(GetActivitiesRequestDto request); Task GetActivityAsync(GetActivityRequestDto request); } \ No newline at end of file diff --git a/src/CAServer.Application.Contracts/CAServer.Application.Contracts.csproj b/src/CAServer.Application.Contracts/CAServer.Application.Contracts.csproj index d36d26b21..276fff158 100644 --- a/src/CAServer.Application.Contracts/CAServer.Application.Contracts.csproj +++ b/src/CAServer.Application.Contracts/CAServer.Application.Contracts.csproj @@ -34,4 +34,9 @@ + + + + + diff --git a/src/CAServer.Application.Contracts/Commons/ContractServiceConstant.cs b/src/CAServer.Application.Contracts/Commons/ContractServiceConstant.cs new file mode 100644 index 000000000..3ca38fd16 --- /dev/null +++ b/src/CAServer.Application.Contracts/Commons/ContractServiceConstant.cs @@ -0,0 +1,10 @@ +namespace CAServer.Commons; + +public static class AElfContractMethodName +{ + public const string GetHolderInfo = "GetHolderInfo"; + public const string GetVerifierServers = "GetVerifierServers"; + public const string GetBalance = "GetBalance"; + public const string ClaimToken = "ClaimToken"; + public const string Transfer = "Transfer"; +} \ No newline at end of file diff --git a/src/CAServer.Application.Contracts/Contacts/Dtos/GetContractsInput.cs b/src/CAServer.Application.Contracts/Contacts/Dtos/GetContractsInput.cs deleted file mode 100644 index ca7358284..000000000 --- a/src/CAServer.Application.Contracts/Contacts/Dtos/GetContractsInput.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Volo.Abp.Application.Dtos; - -namespace CAServer.Contacts; - -public class GetContractsDto : PagedAndSortedResultRequestDto -{ - public bool ContainDeleted { get; set; } - public long MinModificationTime { get; set; } -} \ No newline at end of file diff --git a/src/CAServer.Application.Contracts/Notify/Dtos/CmsNotifyDto.cs b/src/CAServer.Application.Contracts/Notify/Dtos/CmsNotifyDto.cs new file mode 100644 index 000000000..f81be91ce --- /dev/null +++ b/src/CAServer.Application.Contracts/Notify/Dtos/CmsNotifyDto.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace CAServer.Notify.Dtos; + +public class CmsNotifyDto +{ + public List Data { get; set; } +} + +public class CmsNotify +{ + public int Id { get; set; } + public string Title { get; set; } + public string Content { get; set; } + public string AppId { get; set; } + public CmsTargetVersion TargetVersion { get; set; } + public List AppVersions { get; set; } + public string DownloadUrl { get; set; } + [JsonProperty("date_created")] public DateTime ReleaseTime { get; set; } + public List DeviceTypes { get; set; } + public List DeviceBrands { get; set; } + public List OperatingSystemVersions { get; set; } + public List Countries { get; set; } + public CmsStyleType StyleType { get; set; } + public bool IsForceUpdate { get; set; } + public bool IsApproved { get; set; } +} + +public class CmsAppVersion +{ + [JsonProperty("appVersion_id")] public CmsValue AppVersion { get; set; } +} + +public class CmsCountry +{ + [JsonProperty("country_id")] public CmsValue Country { get; set; } +} + +public class CmsDeviceBrand +{ + [JsonProperty("deviceBrand_id")] public CmsValue DeviceBrand { get; set; } +} + +public class CmsDeviceType +{ + [JsonProperty("deviceType_id")] public CmsValue DeviceType { get; set; } +} + +public class CmsTargetVersion +{ + public string Value { get; set; } +} + +public class CmsStyleType +{ + public int Value { get; set; } +} + +public class CmsOperatingSystemVersion +{ + [JsonProperty("operatingSystemVersion_id")] public CmsValue OperatingSystemVersion { get; set; } +} + +public class CmsValue +{ + public T Value { get; set; } +} \ No newline at end of file diff --git a/src/CAServer.Application.Contracts/Notify/Dtos/NotifyBaseDto.cs b/src/CAServer.Application.Contracts/Notify/Dtos/NotifyBaseDto.cs index 91c2d7900..5e2aa5a94 100644 --- a/src/CAServer.Application.Contracts/Notify/Dtos/NotifyBaseDto.cs +++ b/src/CAServer.Application.Contracts/Notify/Dtos/NotifyBaseDto.cs @@ -17,5 +17,6 @@ public class NotifyBaseDto public string[] OperatingSystemVersions { get; set; } public NotifySendType[] SendTypes { get; set; } [Required] public bool IsForceUpdate { get; set; } + public int NotifyId { get; set; } public bool IsApproved { get; set; } } \ No newline at end of file diff --git a/src/CAServer.Application.Contracts/Notify/Dtos/PullNotifyDto.cs b/src/CAServer.Application.Contracts/Notify/Dtos/PullNotifyDto.cs index b99788432..e20cc5459 100644 --- a/src/CAServer.Application.Contracts/Notify/Dtos/PullNotifyDto.cs +++ b/src/CAServer.Application.Contracts/Notify/Dtos/PullNotifyDto.cs @@ -10,5 +10,4 @@ public class PullNotifyDto public string DeviceBrand { get; set; } public string OperatingSystemVersion { get; set; } [Required] public string AppId { get; set; } - public bool IsColdBoot { get; set; } } \ No newline at end of file diff --git a/src/CAServer.Application.Contracts/Notify/Dtos/PullNotifyResultDto.cs b/src/CAServer.Application.Contracts/Notify/Dtos/PullNotifyResultDto.cs index 253de1628..492b7670f 100644 --- a/src/CAServer.Application.Contracts/Notify/Dtos/PullNotifyResultDto.cs +++ b/src/CAServer.Application.Contracts/Notify/Dtos/PullNotifyResultDto.cs @@ -7,4 +7,5 @@ public class PullNotifyResultDto public string TargetVersion { get; set; } public string DownloadUrl { get; set; } public bool IsForceUpdate { get; set; } + public StyleType StyleType { get; set; } } \ No newline at end of file diff --git a/src/CAServer.Application.Contracts/Notify/INotifyAppService.cs b/src/CAServer.Application.Contracts/Notify/INotifyAppService.cs index 0c789c5bd..228f423ca 100644 --- a/src/CAServer.Application.Contracts/Notify/INotifyAppService.cs +++ b/src/CAServer.Application.Contracts/Notify/INotifyAppService.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Threading.Tasks; using CAServer.Notify.Dtos; @@ -10,4 +11,7 @@ public interface INotifyAppService Task CreateAsync(CreateNotifyDto notifyDto); Task UpdateAsync(Guid id, UpdateNotifyDto notifyDto); Task DeleteAsync(Guid id); + + Task> CreateFromCmsAsync(string version); + Task UpdateFromCmsAsync(Guid id); } \ No newline at end of file diff --git a/src/CAServer.Application.Contracts/Notify/NotifyBase.cs b/src/CAServer.Application.Contracts/Notify/NotifyBase.cs index 6134dee17..a6e6da164 100644 --- a/src/CAServer.Application.Contracts/Notify/NotifyBase.cs +++ b/src/CAServer.Application.Contracts/Notify/NotifyBase.cs @@ -11,4 +11,5 @@ public class NotifyBase public string DownloadUrl { get; set; } public DateTime ReleaseTime { get; set; } public bool IsForceUpdate { get; set; } + public StyleType StyleType { get; set; } } \ No newline at end of file diff --git a/src/CAServer.Application.Contracts/Notify/NotifyRulesBase.cs b/src/CAServer.Application.Contracts/Notify/NotifyRulesBase.cs index 84932b226..78446731e 100644 --- a/src/CAServer.Application.Contracts/Notify/NotifyRulesBase.cs +++ b/src/CAServer.Application.Contracts/Notify/NotifyRulesBase.cs @@ -2,11 +2,13 @@ namespace CAServer.Notify; public class NotifyRulesBase { + public int NotifyId { get; set; } public string AppId { get; set; } public string[] AppVersions { get; set; } public string[] DeviceTypes { get; set; } public string[] DeviceBrands { get; set; } public string[] OperatingSystemVersions { get; set; } + public string[] Countries { get; set; } public NotifySendType[] SendTypes { get; set; } public bool IsApproved { get; set; } } \ No newline at end of file diff --git a/src/CAServer.Application.Contracts/Phone/Dtos/PhoneDto.cs b/src/CAServer.Application.Contracts/Phone/Dtos/PhoneDto.cs index 9b1fa6bd7..d1f8eb676 100644 --- a/src/CAServer.Application.Contracts/Phone/Dtos/PhoneDto.cs +++ b/src/CAServer.Application.Contracts/Phone/Dtos/PhoneDto.cs @@ -6,6 +6,9 @@ namespace CAServer.Phone.Dtos; public class PhoneInfoListDto { + + public Dictionary LocateData { get; set; } + public List> Data { get; set; } } diff --git a/src/CAServer.Application.Contracts/Phone/IPhoneAppService.cs b/src/CAServer.Application.Contracts/Phone/IPhoneAppService.cs index 1f0ab549e..f5d1ffb64 100644 --- a/src/CAServer.Application.Contracts/Phone/IPhoneAppService.cs +++ b/src/CAServer.Application.Contracts/Phone/IPhoneAppService.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using System.Threading.Tasks; using CAServer.Phone.Dtos; @@ -6,5 +5,5 @@ namespace CAServer.Phone; public interface IPhoneAppService { - Task GetPhoneInfo(); + Task GetPhoneInfoAsync(); } \ No newline at end of file diff --git a/src/CAServer.Application.Contracts/Sample/ISampleAppService.cs b/src/CAServer.Application.Contracts/Sample/ISampleAppService.cs deleted file mode 100644 index 68c23fe64..000000000 --- a/src/CAServer.Application.Contracts/Sample/ISampleAppService.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Threading.Tasks; - -namespace CAServer.Sample; - -public interface ISampleAppService -{ - Task Hello(string from, string to); -} \ No newline at end of file diff --git a/src/CAServer.Application.Contracts/Sample/TestDto.cs b/src/CAServer.Application.Contracts/Sample/TestDto.cs deleted file mode 100644 index ba1422d3d..000000000 --- a/src/CAServer.Application.Contracts/Sample/TestDto.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace CAServer.Sample; - -public class TestDto -{ - public string From { get; set; } - public string To { get; set; } - public string Message { get; set; } -} \ No newline at end of file diff --git a/src/CAServer.Application.Contracts/Verifier/IVerifierAppService.cs b/src/CAServer.Application.Contracts/Verifier/IVerifierAppService.cs index c94d135a3..d436d63e7 100644 --- a/src/CAServer.Application.Contracts/Verifier/IVerifierAppService.cs +++ b/src/CAServer.Application.Contracts/Verifier/IVerifierAppService.cs @@ -12,4 +12,5 @@ public interface IVerifierAppService public Task VerifyGoogleTokenAsync(VerifyTokenRequestDto requestDto); public Task VerifyAppleTokenAsync(VerifyTokenRequestDto requestDto); public Task CountVerifyCodeInterfaceRequestAsync(string userIpAddress); + public Task GuardianExistsAsync(string guardianIdentifier); } \ No newline at end of file diff --git a/src/CAServer.Application.Contracts/Verifier/OperationType.cs b/src/CAServer.Application.Contracts/Verifier/OperationType.cs new file mode 100644 index 000000000..7faf7cd8e --- /dev/null +++ b/src/CAServer.Application.Contracts/Verifier/OperationType.cs @@ -0,0 +1,8 @@ +namespace CAServer.Verifier; + +public enum OperationType +{ + Register = 0, + Recovery = 1, + GuardianOperations = 2, +} \ No newline at end of file diff --git a/src/CAServer.Application.Contracts/Verifier/VerifierServerInput.cs b/src/CAServer.Application.Contracts/Verifier/VerifierServerInput.cs index e827e7b09..6e7de58a5 100644 --- a/src/CAServer.Application.Contracts/Verifier/VerifierServerInput.cs +++ b/src/CAServer.Application.Contracts/Verifier/VerifierServerInput.cs @@ -7,6 +7,9 @@ namespace CAServer.Verifier; public class VerifierServerInput : VerifierServerBase , IValidatableObject { [Required] public string ChainId { get; set; } + + [Required] public OperationType OperationType { get; set; } + public IEnumerable Validate(ValidationContext validationContext) { if (Type == "Email"&& !VerifyHelper.VerifyEmail(GuardianIdentifier)) diff --git a/src/CAServer.Application.Contracts/Verifier/VerifierSignatureInput.cs b/src/CAServer.Application.Contracts/Verifier/VerifierSignatureInput.cs deleted file mode 100644 index 6a3b29b1b..000000000 --- a/src/CAServer.Application.Contracts/Verifier/VerifierSignatureInput.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace CAServer.Dtos -{ - public class VerifierSignatureInput - { - [Range(0, 1)] public int Type { get; set; } = -1; - [Required] public string LoginGuardianType { get; set; } - [Required] public string ManagerUniqueId { get; set; } - [Required] public string VerifierName { get; set; } - [Required] public string VerificationDoc { get; set; } - [Required] public string VerifierSignature { get; set; } - } -} \ No newline at end of file diff --git a/src/CAServer.Application/CAAccount/CAAccountAppService.cs b/src/CAServer.Application/CAAccount/CAAccountAppService.cs index 1edfb1545..9ac20dcfe 100644 --- a/src/CAServer.Application/CAAccount/CAAccountAppService.cs +++ b/src/CAServer.Application/CAAccount/CAAccountAppService.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using AElf.Types; using CAServer.Common; +using CAServer.Commons; using CAServer.Device; using CAServer.Dtos; using CAServer.Etos; @@ -29,16 +30,19 @@ public class CAAccountAppService : CAServerAppService, ICAAccountAppService private readonly ILogger _logger; private readonly IDeviceAppService _deviceAppService; private readonly ChainOptions _chainOptions; + private readonly IContractProvider _contractProvider; public CAAccountAppService(IClusterClient clusterClient, IDistributedEventBus distributedEventBus, - ILogger logger, IDeviceAppService deviceAppService, IOptions chainOptions) + ILogger logger, IDeviceAppService deviceAppService, IOptions chainOptions, + IContractProvider contractProvider) { _clusterClient = clusterClient; _distributedEventBus = distributedEventBus; _logger = logger; _deviceAppService = deviceAppService; _chainOptions = chainOptions.Value; + _contractProvider = contractProvider; } public async Task RegisterRequestAsync(RegisterRequestDto input) @@ -51,8 +55,9 @@ public async Task RegisterRequestAsync(RegisterRequestDto inpu var grainId = GrainIdHelper.GenerateGrainId(guardianGrainDto.IdentifierHash, input.VerifierId, input.ChainId, input.Manager); - - registerDto.ManagerInfo.ExtraData = await _deviceAppService.EncryptExtraDataAsync(registerDto.ManagerInfo.ExtraData, grainId); + + registerDto.ManagerInfo.ExtraData = + await _deviceAppService.EncryptExtraDataAsync(registerDto.ManagerInfo.ExtraData, grainId); var grain = _clusterClient.GetGrain(grainId); var result = await grain.RequestAsync(ObjectMapper.Map(registerDto)); @@ -119,26 +124,23 @@ public async Task RecoverRequestAsync(RecoveryRequestDto input } var caHash = await GetCAHashAsync(input.ChainId, guardianGrainDto.IdentifierHash); - + if (caHash != null) { - result.Data.ManagerInfo.ExtraData = await _deviceAppService.EncryptExtraDataAsync(result.Data.ManagerInfo.ExtraData, caHash); - + result.Data.ManagerInfo.ExtraData = + await _deviceAppService.EncryptExtraDataAsync(result.Data.ManagerInfo.ExtraData, caHash); } - + await _distributedEventBus.PublishAsync( ObjectMapper.Map(result.Data)); return new AccountResultDto(recoveryDto.Id.ToString()); } - + private async Task GetCAHashAsync(string chainId, string loginGuardianIdentifierHash) { - var chainInfo = _chainOptions.ChainInfos[chainId]; - var output = await ContractHelper.CallTransactionAsync(MethodName.GetHolderInfo, new GetHolderInfoInput - { - LoginGuardianIdentifierHash = Hash.LoadFromHex(loginGuardianIdentifierHash) - }, false, chainInfo); + var output = + await _contractProvider.GetHolderInfoAsync(null, Hash.LoadFromHex(loginGuardianIdentifierHash), chainId); return output?.CaHash?.ToHex(); } diff --git a/src/CAServer.Application/CAActivity/Provider/ActivityProvider.cs b/src/CAServer.Application/CAActivity/Provider/ActivityProvider.cs index cfd1df1a2..73ff5354d 100644 --- a/src/CAServer.Application/CAActivity/Provider/ActivityProvider.cs +++ b/src/CAServer.Application/CAActivity/Provider/ActivityProvider.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using AElf.Indexing.Elasticsearch; +using CAServer.CAActivity.Dtos; using CAServer.Common; using CAServer.Entities.Es; using CAServer.Grains.Grain.ApplicationHandler; @@ -28,6 +29,26 @@ public ActivityProvider(IGraphQLHelper graphQlHelper, INESTRepository GetTwoCaTransactionsAsync(List twoCaAddresses, string symbolOpt, + List inputTransactionTypes, int inputSkipCount, int inputMaxResultCount) + { + return await _graphQlHelper.QueryAsync(new GraphQLRequest + { + Query = @" + query ($chainId:String,$symbol:String,$caAddressInfos:[CAAddressInfo]!,$methodNames:[String],$startBlockHeight:Long!,$endBlockHeight:Long!,$skipCount:Int!,$maxResultCount:Int!){ + twoCaHolderTransaction(dto: {chainId:$chainId,symbol:$symbol,caAddressInfos:$caAddressInfos,methodNames:$methodNames,startBlockHeight:$startBlockHeight,endBlockHeight:$endBlockHeight,skipCount:$skipCount,maxResultCount:$maxResultCount}){ + data{id,chainId,blockHash,blockHeight,previousBlockHash,transactionId,methodName,tokenInfo{symbol,tokenContractAddress,decimals,totalSupply,tokenName},status,timestamp,nftInfo{symbol,totalSupply,imageUrl,decimals,tokenName},transferInfo{fromAddress,toAddress,amount,toChainId,fromChainId,fromCAAddress},fromAddress,transactionFees{symbol,amount}},totalRecordCount} + }", + Variables = new + { + caAddressInfos = twoCaAddresses, symbol = symbolOpt, + methodNames = inputTransactionTypes, skipCount = inputSkipCount, maxResultCount = inputMaxResultCount, + startBlockHeight = 0, endBlockHeight = 0 + } + }); + } + public async Task GetActivitiesAsync(List caAddressInfos, string inputChainId, string symbolOpt, List inputTransactionTypes, int inputSkipCount, int inputMaxResultCount) { diff --git a/src/CAServer.Application/CAActivity/Provider/IActivityProvider.cs b/src/CAServer.Application/CAActivity/Provider/IActivityProvider.cs index 86fb0c2cc..49332557d 100644 --- a/src/CAServer.Application/CAActivity/Provider/IActivityProvider.cs +++ b/src/CAServer.Application/CAActivity/Provider/IActivityProvider.cs @@ -8,9 +8,12 @@ namespace CAServer.CAActivity.Provider; public interface IActivityProvider { - Task GetActivitiesAsync(List addressInfos, string inputChainId, string symbolOpt, + Task GetTwoCaTransactionsAsync(List twoCaAddresses, string symbolOpt, List inputTransactionTypes, int inputSkipCount, int inputMaxResultCount); + Task GetActivitiesAsync(List addressInfos, string inputChainId, + string symbolOpt, List inputTransactionTypes, int inputSkipCount, int inputMaxResultCount); + Task GetActivityAsync(string inputTransactionId, string inputBlockHash); Task GetCaHolderNickName(Guid userId); diff --git a/src/CAServer.Application/CAActivity/UserActivityAppService.cs b/src/CAServer.Application/CAActivity/UserActivityAppService.cs index df87dd9bb..976e4c06c 100644 --- a/src/CAServer.Application/CAActivity/UserActivityAppService.cs +++ b/src/CAServer.Application/CAActivity/UserActivityAppService.cs @@ -45,6 +45,40 @@ public UserActivityAppService(ILogger logger, ITokenAppS _imageProcessProvider = imageProcessProvider; } + + public async Task GetTwoCaTransactionsAsync(GetTwoCaTransactionRequestDto request) + { + // addresses of current user + var caAddresses = request.CaAddressInfos.IsNullOrEmpty() + ? new List() + : request.CaAddressInfos.Select(info => info.CaAddress).ToList(); + try + { + if (request.CaAddressInfos.IsNullOrEmpty() || request.TargetAddressInfos.IsNullOrEmpty()) + { + throw new UserFriendlyException("Parameters “CaAddressInfos” “TargetAddressInfos” must be non-empty"); + } + + var twoCaAddress = new List() { request.CaAddressInfos[0], request.TargetAddressInfos[0] }; + var transactionsDto = await _activityProvider.GetTwoCaTransactionsAsync(twoCaAddress, + request.Symbol, ActivityConstants.RecentTypes, request.SkipCount, request.MaxResultCount); + + var transactions = ObjectMapper.Map(transactionsDto); + return await IndexerTransaction2Dto(caAddresses, transactions, request.ChainId, request.Width, + request.Height, needMap: true); + } + catch (UserFriendlyException e) + { + throw e; + } + catch (Exception e) + { + _logger.LogError(e, "GetTwoCaTransactionsAsync error, addresses={addresses}", + string.Join(",", caAddresses)); + throw new UserFriendlyException("Internal service error, place try again later."); + } + } + public async Task GetActivitiesAsync(GetActivitiesRequestDto request) { try @@ -60,7 +94,7 @@ public async Task GetActivitiesAsync(GetActivitiesRequestDto r var transactions = await _activityProvider.GetActivitiesAsync(caAddressInfos, request.ChainId, request.Symbol, filterTypes, request.SkipCount, request.MaxResultCount); return await IndexerTransaction2Dto(request.CaAddresses, transactions, request.ChainId, request.Width, - request.Height); + request.Height, needMap: true); } catch (Exception e) { @@ -71,9 +105,9 @@ public async Task GetActivitiesAsync(GetActivitiesRequestDto r private List FilterTypes(IEnumerable reqList) { - if (reqList == null) + if (reqList == null || reqList.Count() == 0) { - return ActivityConstants.DefaultTypes; + return ActivityConstants.TypeMap.Keys.ToList(); } var ans = reqList.Where(e => ActivityConstants.AllSupportTypes.Contains(e)).ToList(); @@ -88,7 +122,8 @@ public async Task GetActivityAsync(GetActivityRequestDto request { var indexerTransactions = await _activityProvider.GetActivityAsync(request.TransactionId, request.BlockHash); - var activitiesDto = await IndexerTransaction2Dto(request.CaAddresses, indexerTransactions, null, 0, 0); + var activitiesDto = + await IndexerTransaction2Dto(request.CaAddresses, indexerTransactions, null, 0, 0, true); if (activitiesDto == null || activitiesDto.TotalRecordCount == 0) { return new GetActivityDto(); @@ -160,7 +195,8 @@ await _userContactProvider.BatchGetUserNameAsync(new List { anotherAddre } private async Task IndexerTransaction2Dto(List caAddresses, - IndexerTransactions indexerTransactions, [CanBeNull] string chainId, int weidth, int height) + IndexerTransactions indexerTransactions, [CanBeNull] string chainId, int weidth, int height, + bool needMap = false) { var result = new GetActivitiesDto { @@ -256,7 +292,16 @@ private async Task IndexerTransaction2Dto(List caAddre { dto.IsDelegated = true; } - + + if (needMap) + { + var typeName = ActivityConstants.TypeMap.GetValueOrDefault(dto.TransactionType, dto.TransactionType); + dto.TransactionName = dto.NftInfo != null && !string.IsNullOrWhiteSpace(dto.NftInfo.NftId) && + ActivityConstants.ShowNftTypes.Contains(dto.TransactionType) + ? typeName + " NFT" + : typeName; + } + getActivitiesDto.Add(dto); } diff --git a/src/CAServer.Application/CAServer.Application.csproj b/src/CAServer.Application/CAServer.Application.csproj index 8a6ab050f..16227547b 100644 --- a/src/CAServer.Application/CAServer.Application.csproj +++ b/src/CAServer.Application/CAServer.Application.csproj @@ -12,6 +12,7 @@ + diff --git a/src/CAServer.Application/CAServerApplicationAutoMapperProfile.cs b/src/CAServer.Application/CAServerApplicationAutoMapperProfile.cs index f3741ba44..a4fc97093 100644 --- a/src/CAServer.Application/CAServerApplicationAutoMapperProfile.cs +++ b/src/CAServer.Application/CAServerApplicationAutoMapperProfile.cs @@ -41,6 +41,7 @@ using CAServer.Verifier.Etos; using MongoDB.Bson.Serialization.IdGenerators; using Portkey.Contracts.CA; +using Volo.Abp.AutoMapper; using ContactAddress = CAServer.Grains.Grain.Contacts.ContactAddress; using GuardianInfo = CAServer.Account.GuardianInfo; using GuardianType = CAServer.Account.GuardianType; @@ -273,8 +274,33 @@ public CAServerApplicationAutoMapperProfile() CreateMap(); CreateMap(); CreateMap().BeforeMap((src, dest) => { dest.Message = "Login Successful"; }); - + CreateMap(); CreateMap(); + CreateMap() + .ForMember(t => t.CaHolderTransaction, m => m.MapFrom(f => f.TwoCaHolderTransaction)); + + CreateMap() + .Ignore(t => t.Id) + .ForMember(t => t.NotifyId, m => m.MapFrom(f => f.Id)) + .ForMember(t => t.AppVersions, + m => m.MapFrom(f => f.AppVersions == null ? null : f.AppVersions.Select(t => t.AppVersion.Value))) + .ForMember(t => t.TargetVersion, m => m.MapFrom(f => f.TargetVersion == null ? "" : f.TargetVersion.Value)) + .ForMember(t => t.Countries, + m => m.MapFrom(f => f.Countries == null ? null : f.Countries.Select(t => t.Country.Value))) + .ForMember(t => t.DeviceBrands, + m => m.MapFrom(f => f.DeviceBrands == null ? null : f.DeviceBrands.Select(t => t.DeviceBrand.Value))) + .ForMember(t => t.OperatingSystemVersions, + m => m.MapFrom(f => + f.OperatingSystemVersions == null + ? null + : f.OperatingSystemVersions.Select(t => t.OperatingSystemVersion.Value))) + .ForMember(t => t.DeviceTypes, + m => m.MapFrom(f => + f.DeviceTypes == null + ? null + : f.DeviceTypes.Select(t => ((DeviceType)t.DeviceType.Value).ToString()))) + .ForMember(t => t.StyleType, m => m.MapFrom(f => (StyleType)f.StyleType.Value)); + //.ForMember() } } \ No newline at end of file diff --git a/src/CAServer.Application/CAServerApplicationModule.cs b/src/CAServer.Application/CAServerApplicationModule.cs index 731ba033e..35430fa3d 100644 --- a/src/CAServer.Application/CAServerApplicationModule.cs +++ b/src/CAServer.Application/CAServerApplicationModule.cs @@ -7,6 +7,7 @@ using CAServer.Options; using CAServer.Search; using CAServer.Settings; +using CAServer.Signature; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Account; @@ -29,7 +30,8 @@ namespace CAServer; typeof(AbpTenantManagementApplicationModule), typeof(AbpFeatureManagementApplicationModule), typeof(AbpSettingManagementApplicationModule), - typeof(CAServerGrainsModule) + typeof(CAServerGrainsModule), + typeof(CAServerSignatureModule) )] public class CAServerApplicationModule : AbpModule { @@ -70,6 +72,8 @@ public override void ConfigureServices(ServiceConfigurationContext context) Configure(configuration.GetSection("PhoneInfoOptions")); Configure(configuration.GetSection("ClaimTokenWhiteListAddresses")); Configure(configuration.GetSection("ClaimTokenInfo")); + Configure(configuration.GetSection("CmsConfig")); + Configure(configuration.GetSection("ContractOptions")); context.Services.AddHttpClient(); context.Services.AddScoped(); context.Services.AddScoped(); diff --git a/src/CAServer.Application/ClaimToken/ClaimTokenAppService.cs b/src/CAServer.Application/ClaimToken/ClaimTokenAppService.cs index 76e3dc550..59e2711ec 100644 --- a/src/CAServer.Application/ClaimToken/ClaimTokenAppService.cs +++ b/src/CAServer.Application/ClaimToken/ClaimTokenAppService.cs @@ -49,13 +49,18 @@ public async Task GetClaimTokenAsync(ClaimTokenRequestDto } var chainId = _claimTokenInfoOption.ChainId; - var getBalanceOutput = await _contractProvider.GetBalanceAsync(chainId, address, claimTokenRequestDto.Symbol); + + var getBalanceOutput = await _contractProvider.GetBalanceAsync(claimTokenRequestDto.Symbol, address, chainId); + if (getBalanceOutput.Balance < _claimTokenInfoOption.ClaimTokenAmount) { - await _contractProvider.ClaimTokenAsync(chainId, claimTokenRequestDto.Symbol); + await _contractProvider.ClaimTokenAsync(claimTokenRequestDto.Symbol, + _claimTokenInfoOption.ClaimTokenAddress, chainId); } - var result = await _contractProvider.TransferAsync(chainId, claimTokenRequestDto); + var result = await _contractProvider.SendTransferAsync(claimTokenRequestDto.Symbol, claimTokenRequestDto.Amount, + claimTokenRequestDto.Address, chainId); + await _cacheProvider.Increase(GetClaimTokenAddressCacheKey + claimTokenRequestDto.Address, 1, TimeSpan.FromHours(_claimTokenInfoOption.ExpireTime)); return new ClaimTokenResponseDto diff --git a/src/CAServer.Application/Common/ContractHelper.cs b/src/CAServer.Application/Common/ContractHelper.cs deleted file mode 100644 index ca183b681..000000000 --- a/src/CAServer.Application/Common/ContractHelper.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Threading.Tasks; -using AElf; -using AElf.Client.Dto; -using AElf.Client.Service; -using CAServer.Grains.Grain.ApplicationHandler; -using Google.Protobuf; - -namespace CAServer.Common; - -public static class ContractHelper -{ - public static async Task CallTransactionAsync(string methodName, IMessage param, - bool isTokenContract, ChainInfo chainInfo) where T : class, IMessage, new() - { - var client = new AElfClient(chainInfo.BaseUrl); - await client.IsConnectedAsync(); - var ownAddress = client.GetAddressFromPrivateKey(chainInfo.PrivateKey); - var contractAddress = isTokenContract ? chainInfo.TokenContractAddress : chainInfo.ContractAddress; - - var transaction = - await client.GenerateTransactionAsync(ownAddress, contractAddress, - methodName, param); - var txWithSign = client.SignTransaction(chainInfo.PrivateKey, transaction); - - var result = await client.ExecuteTransactionAsync(new ExecuteTransactionDto - { - RawTransaction = txWithSign.ToByteArray().ToHex() - }); - - var value = new T(); - value.MergeFrom(ByteArrayHelper.HexStringToByteArray(result)); - - return value; - } -} \ No newline at end of file diff --git a/src/CAServer.Application/Common/ContractProvider.cs b/src/CAServer.Application/Common/ContractProvider.cs index 5aad648f8..6c25c90bd 100644 --- a/src/CAServer.Application/Common/ContractProvider.cs +++ b/src/CAServer.Application/Common/ContractProvider.cs @@ -1,11 +1,12 @@ using System.Threading.Tasks; using AElf; using AElf.Client.Dto; -using AElf.Client.MultiToken; +using AElf.Contracts.MultiToken; using AElf.Client.Service; using AElf.Types; -using CAServer.ClaimToken.Dtos; +using CAServer.Commons; using CAServer.Options; +using CAServer.Signature; using Google.Protobuf; using Google.Protobuf.WellKnownTypes; using Microsoft.Extensions.Logging; @@ -13,17 +14,17 @@ using Portkey.Contracts.CA; using Portkey.Contracts.TokenClaim; using Volo.Abp.DependencyInjection; -using GetBalanceInput = AElf.Contracts.MultiToken.GetBalanceInput; -using TransferInput = AElf.Contracts.MultiToken.TransferInput; +using ChainOptions = CAServer.Grains.Grain.ApplicationHandler.ChainOptions; namespace CAServer.Common; public interface IContractProvider { + public Task GetHolderInfoAsync(Hash caHash, Hash loginGuardianIdentifierHash, string chainId); public Task GetVerifierServersListAsync(string chainId); - public Task GetBalanceAsync(string chainId, string address, string symbol); - public Task TransferAsync(string chainId, ClaimTokenRequestDto claimTokenRequestDto); - public Task ClaimTokenAsync(string chainId,string symbol); + public Task GetBalanceAsync(string symbol, string address, string chainId); + public Task ClaimTokenAsync(string symbol, string address, string chainId); + public Task SendTransferAsync(string symbol, string amount, string address, string chainId); } public class ContractProvider : IContractProvider, ISingletonDependency @@ -31,126 +32,140 @@ public class ContractProvider : IContractProvider, ISingletonDependency private readonly ChainOptions _chainOptions; private readonly ILogger _logger; private readonly ClaimTokenInfoOptions _claimTokenInfoOption; + private readonly ISignatureProvider _signatureProvider; + private readonly ContractOptions _contractOptions; public ContractProvider(IOptions chainOptions, ILogger logger, - IOptionsSnapshot claimTokenInfoOption) + ISignatureProvider signatureProvider, IOptionsSnapshot claimTokenInfoOption, + IOptionsSnapshot contractOptions) { _chainOptions = chainOptions.Value; _logger = logger; _claimTokenInfoOption = claimTokenInfoOption.Value; + _signatureProvider = signatureProvider; + _contractOptions = contractOptions.Value; } - public async Task GetVerifierServersListAsync(string chainId) + private async Task CallTransactionAsync(string methodName, IMessage param, string contractAddress, + string chainId) where T : class, IMessage, new() { - if (!_chainOptions.ChainInfos.TryGetValue(chainId, out var chainOption)) + if (!_chainOptions.ChainInfos.TryGetValue(chainId, out var chainInfo)) { return null; } - var client = new AElfClient(chainOption.BaseUrl); + var client = new AElfClient(chainInfo.BaseUrl); await client.IsConnectedAsync(); - var ownAddress = client.GetAddressFromPrivateKey(chainOption.PrivateKey); - const string methodName = "GetVerifierServers"; - var param = new Empty(); - var transaction = await client.GenerateTransactionAsync(ownAddress, - chainOption.ContractAddress, methodName, param); + string addressFromPrivateKey = client.GetAddressFromPrivateKey(_contractOptions.CommonPrivateKeyForCallTx); + + var transaction = + await client.GenerateTransactionAsync(addressFromPrivateKey, contractAddress, methodName, param); - _logger.LogDebug("param is: {transaction}, privateKey is:{privateKey} ", transaction, chainOption.PrivateKey); + _logger.LogDebug("Call tx methodName is: {methodName} param is: {transaction}", methodName, transaction); - var txWithSign = client.SignTransaction(chainOption.PrivateKey, transaction); + var txWithSign = client.SignTransaction(_contractOptions.CommonPrivateKeyForCallTx, transaction); var result = await client.ExecuteTransactionAsync(new ExecuteTransactionDto { RawTransaction = txWithSign.ToByteArray().ToHex() }); - return GetVerifierServersOutput.Parser.ParseFrom(ByteArrayHelper.HexStringToByteArray(result)); + + var value = new T(); + value.MergeFrom(ByteArrayHelper.HexStringToByteArray(result)); + + return value; } - public async Task GetBalanceAsync(string chainId, string address, string symbol) + private async Task SendTransactionAsync(string methodName, IMessage param, + string senderPubKey, string contractAddress, string chainId) + where T : class, IMessage, new() { - if (!_chainOptions.ChainInfos.TryGetValue(chainId, out var chainOption)) + if (!_chainOptions.ChainInfos.TryGetValue(chainId, out var chainInfo)) { return null; } - var client = new AElfClient(chainOption.BaseUrl); + var client = new AElfClient(chainInfo.BaseUrl); await client.IsConnectedAsync(); - var ownAddress = client.GetAddressFromPrivateKey(chainOption.PrivateKey); - const string methodName = "GetBalance"; - var param = new GetBalanceInput - { - Symbol = symbol, - Owner = Address.FromBase58(address) - }; - var transaction = await client.GenerateTransactionAsync(ownAddress, - chainOption.TokenContractAddress, methodName, param); + var ownAddress = client.GetAddressFromPubKey(senderPubKey); - _logger.LogDebug("param is: {transaction}, privateKey is:{privateKey} ", transaction, chainOption.PrivateKey); + var transaction = await client.GenerateTransactionAsync(ownAddress, contractAddress, methodName, param); - var txWithSign = client.SignTransaction(chainOption.PrivateKey, transaction); - var result = await client.ExecuteTransactionAsync(new ExecuteTransactionDto + _logger.LogDebug("Send tx methodName is: {methodName} param is: {transaction}, publicKey is:{publicKey} ", + methodName, transaction, _claimTokenInfoOption.PublicKey); + + var txWithSign = await _signatureProvider.SignTxMsg(ownAddress, transaction.ToByteArray().ToHex()); + + var result = await client.SendTransactionAsync(new SendTransactionInput() { - RawTransaction = txWithSign.ToByteArray().ToHex() + RawTransaction = txWithSign }); - return GetBalanceOutput.Parser.ParseFrom(ByteArrayHelper.HexStringToByteArray(result)); + + return result; } + public async Task GetHolderInfoAsync(Hash caHash, Hash loginGuardianIdentifierHash, + string chainId) + { + var param = new GetHolderInfoInput(); + param.CaHash = caHash; + param.LoginGuardianIdentifierHash = loginGuardianIdentifierHash; + var output = await CallTransactionAsync(AElfContractMethodName.GetHolderInfo, param, + _chainOptions.ChainInfos[chainId].ContractAddress, chainId); + return output; + } - public async Task TransferAsync(string chainId, ClaimTokenRequestDto claimTokenRequestDto) + public async Task GetVerifierServersListAsync(string chainId) { - if (!_chainOptions.ChainInfos.TryGetValue(chainId, out var chainOption)) + if (!_chainOptions.ChainInfos.TryGetValue(chainId, out _)) { - return new SendTransactionOutput(); + return null; } + + return await CallTransactionAsync(AElfContractMethodName.GetVerifierServers, + new Empty(), _chainOptions.ChainInfos[chainId].ContractAddress, chainId); + } - var client = new AElfClient(chainOption.BaseUrl); - await client.IsConnectedAsync(); - var ownAddress = client.GetAddressFromPrivateKey(_claimTokenInfoOption.PrivateKey); - const string methodName = "Transfer"; - var param = new TransferInput + public async Task GetBalanceAsync(string symbol, string address, string chainId) + { + if (!_chainOptions.ChainInfos.TryGetValue(chainId, out _)) { - Symbol = claimTokenRequestDto.Symbol, - Amount = long.Parse(claimTokenRequestDto.Amount), - To = Address.FromBase58(claimTokenRequestDto.Address) - }; - var transaction = await client.GenerateTransactionAsync(ownAddress, - chainOption.TokenContractAddress, methodName, param); - - _logger.LogDebug("param is: {transaction}, privateKey is:{privateKey} ", transaction, _claimTokenInfoOption.PrivateKey); + return null; + } - var txWithSign = client.SignTransaction(_claimTokenInfoOption.PrivateKey, transaction); - var result = await client.SendTransactionAsync(new SendTransactionInput() + var getBalanceParam = new GetBalanceInput { - RawTransaction = txWithSign.ToByteArray().ToHex() - }); - return result; + Symbol = symbol, + Owner = Address.FromBase58(address) + }; + + return await CallTransactionAsync(AElfContractMethodName.GetBalance, getBalanceParam, + _chainOptions.ChainInfos[chainId].TokenContractAddress, chainId); } - public async Task ClaimTokenAsync(string chainId,string symbol) + public async Task ClaimTokenAsync(string symbol, string address, string chainId) { - if (!_chainOptions.ChainInfos.TryGetValue(chainId, out var chainOption)) - { - return ; - } - var client = new AElfClient(chainOption.BaseUrl); - await client.IsConnectedAsync(); - var ownAddress = client.GetAddressFromPrivateKey(_claimTokenInfoOption.PrivateKey); - const string methodName = "ClaimToken"; - var param = new ClaimTokenInput + var claimTokenParam = new ClaimTokenInput { Symbol = symbol, Amount = _claimTokenInfoOption.ClaimTokenAmount }; - var transaction = await client.GenerateTransactionAsync(ownAddress, - _claimTokenInfoOption.ClaimTokenAddress, methodName, param); - - _logger.LogDebug("param is: {transaction}, privateKey is:{privateKey} ", transaction, _claimTokenInfoOption.PrivateKey); + await SendTransactionAsync(AElfContractMethodName.ClaimToken, claimTokenParam, + _claimTokenInfoOption.PublicKey, address, chainId); + } - var txWithSign = client.SignTransaction(_claimTokenInfoOption.PrivateKey, transaction); - await client.SendTransactionAsync(new SendTransactionInput() + public async Task SendTransferAsync(string symbol, string amount, string address, + string chainId) + { + var transferParam = new TransferInput { - RawTransaction = txWithSign.ToByteArray().ToHex() - }); + Symbol = symbol, + Amount = long.Parse(amount), + To = Address.FromBase58(address) + }; + + return await SendTransactionAsync(AElfContractMethodName.Transfer, transferParam, + _claimTokenInfoOption.PublicKey, _chainOptions.ChainInfos[chainId].TokenContractAddress, chainId); } } \ No newline at end of file diff --git a/src/CAServer.Application/Common/GetVerifierServerProvider.cs b/src/CAServer.Application/Common/GetVerifierServerProvider.cs index d8f448e54..9fa632f89 100644 --- a/src/CAServer.Application/Common/GetVerifierServerProvider.cs +++ b/src/CAServer.Application/Common/GetVerifierServerProvider.cs @@ -2,8 +2,10 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using CAServer.Commons; using CAServer.Settings; using CAServer.Verifier; +using Google.Protobuf.WellKnownTypes; using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -31,7 +33,8 @@ public class GetVerifierServerProvider : IGetVerifierServerProvider, ISingletonD public GetVerifierServerProvider( IDistributedCache distributedCache, - IOptions adaptableVariableOptions, ILogger logger, IContractProvider contractProvider) + IOptionsSnapshot adaptableVariableOptions, ILogger logger, + IContractProvider contractProvider) { _adaptableVariableOptions = adaptableVariableOptions.Value; _distributedCache = distributedCache; @@ -71,6 +74,7 @@ private int GetRandomNum(int t) private async Task GetVerifierServerListAsync(string chainId) { var result = await _contractProvider.GetVerifierServersListAsync(chainId); + if (null == result) { return null; diff --git a/src/CAServer.Application/Google/GoogleAppService.cs b/src/CAServer.Application/Google/GoogleAppService.cs index c08158068..4d1d66656 100644 --- a/src/CAServer.Application/Google/GoogleAppService.cs +++ b/src/CAServer.Application/Google/GoogleAppService.cs @@ -39,7 +39,7 @@ public async Task IsGoogleRecaptchaOpenAsync(string userIpAddress) await _cacheProvider.Get(SendVerifierCodeInterfaceRequestCountCacheKey + ":" + userIpAddress); if (cacheCount.IsNullOrEmpty) { - return false; + cacheCount = 0; } _logger.LogDebug("cacheItem is {item}, limit is {limit}", JsonConvert.SerializeObject(cacheCount), _sendVerifierCodeRequestLimitOptions.Limit); diff --git a/src/CAServer.Application/Guardian/GuardianAppService.cs b/src/CAServer.Application/Guardian/GuardianAppService.cs index 24b22c5c9..846b73e33 100644 --- a/src/CAServer.Application/Guardian/GuardianAppService.cs +++ b/src/CAServer.Application/Guardian/GuardianAppService.cs @@ -36,13 +36,9 @@ public class GuardianAppService : CAServerAppService, IGuardianAppService private readonly IAppleUserProvider _appleUserProvider; public GuardianAppService( - INESTRepository guardianRepository, - INESTRepository userExtraInfoRepository, - ILogger logger, - IOptions chainOptions, - IGuardianProvider guardianProvider, - IClusterClient clusterClient, - IAppleUserProvider appleUserProvider) + INESTRepository guardianRepository, IAppleUserProvider appleUserProvider, + INESTRepository userExtraInfoRepository, ILogger logger, + IOptions chainOptions, IGuardianProvider guardianProvider, IClusterClient clusterClient) { _guardianRepository = guardianRepository; _userExtraInfoRepository = userExtraInfoRepository; @@ -116,13 +112,13 @@ private string GetHash(string guardianIdentifier) private async Task GetOriginChainIdAsync(string guardianIdentifierHash, string caHash) { - foreach (var chainInfo in _chainOptions.ChainInfos) + foreach (var (chainId, chainInfo) in _chainOptions.ChainInfos) { try { - //var holderInfo = await GetHolderInfoFromContractAsync(guardianIdentifierHash, caHash, chainInfo.Value); - var holderInfo = await _guardianProvider.GetHolderInfoFromContractAsync(guardianIdentifierHash, caHash, chainInfo.Value); - if (holderInfo?.GuardianList?.Guardians?.Count > 0) return chainInfo.Key; + var holderInfo = + await _guardianProvider.GetHolderInfoFromContractAsync(guardianIdentifierHash, caHash, chainId); + if (holderInfo?.GuardianList?.Guardians?.Count > 0) return chainId; } catch (Exception e) { @@ -186,9 +182,7 @@ private async Task GetHolderInfosAsync(string guardianIdent { try { - var chainInfo = _chainOptions.ChainInfos[chainId]; - //return await GetHolderInfoFromContractAsync(guardianIdentifierHash, caHash, chainInfo); - return await _guardianProvider.GetHolderInfoFromContractAsync(guardianIdentifierHash, caHash, chainInfo); + return await _guardianProvider.GetHolderInfoFromContractAsync(guardianIdentifierHash, caHash, chainId); } catch (Exception ex) { @@ -210,31 +204,6 @@ private async Task GetHolderInfosAsync(string guardianIdent } } - private async Task GetHolderInfoFromContractAsync( - string guardianIdentifierHash, - string caHash, - ChainInfo chainInfo) - { - var param = new GetHolderInfoInput(); - - if (!string.IsNullOrWhiteSpace(caHash)) - { - param.CaHash = Hash.LoadFromHex(caHash); - param.LoginGuardianIdentifierHash = null; - } - else - { - param.LoginGuardianIdentifierHash = AElf.Types.Hash.LoadFromHex(guardianIdentifierHash); - param.CaHash = null; - } - - var output = - await ContractHelper.CallTransactionAsync(MethodName.GetHolderInfo, param, false, - chainInfo); - - return output; - } - private async Task> GetIdentifiersAsync(List identifierHashList) { var mustQuery = new List, QueryContainer>>() { }; @@ -269,7 +238,7 @@ QueryContainer Filter(QueryContainerDescriptor f) => } catch (Exception ex) { - _logger.LogError(ex,"in GetUserExtraInfoAsync"); + _logger.LogError(ex, "in GetUserExtraInfoAsync"); } return new List(); diff --git a/src/CAServer.Application/Guardian/Provider/GuardianProvider.cs b/src/CAServer.Application/Guardian/Provider/GuardianProvider.cs index b02465f0f..33cf6c9ca 100644 --- a/src/CAServer.Application/Guardian/Provider/GuardianProvider.cs +++ b/src/CAServer.Application/Guardian/Provider/GuardianProvider.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using AElf.Types; using CAServer.Common; +using CAServer.Commons; using CAServer.Grains.Grain.ApplicationHandler; using CAServer.UserAssets.Dtos; using CAServer.UserAssets.Provider; @@ -15,10 +16,13 @@ namespace CAServer.Guardian.Provider; public class GuardianProvider : IGuardianProvider, ITransientDependency { private readonly IGraphQLHelper _graphQlHelper; + private readonly IContractProvider _contractProvider; - public GuardianProvider(IGraphQLHelper graphQlHelper) + + public GuardianProvider(IGraphQLHelper graphQlHelper, IContractProvider contractProvider) { _graphQlHelper = graphQlHelper; + _contractProvider = contractProvider; } public async Task GetGuardiansAsync(string loginGuardianIdentifierHash, string caHash) @@ -42,28 +46,14 @@ private async Task GetGuardianListByScanAsync(string loginGuardian }); } - public async Task GetHolderInfoFromContractAsync( - string guardianIdentifierHash, - string caHash, - ChainInfo chainInfo) + public async Task GetHolderInfoFromContractAsync(string guardianIdentifierHash, string caHash, + string chainId) { - var param = new GetHolderInfoInput(); - if (!string.IsNullOrWhiteSpace(caHash)) { - param.CaHash = Hash.LoadFromHex(caHash); - param.LoginGuardianIdentifierHash = null; + return await _contractProvider.GetHolderInfoAsync(Hash.LoadFromHex(caHash), null, chainId); } - else - { - param.LoginGuardianIdentifierHash = Hash.LoadFromHex(guardianIdentifierHash); - param.CaHash = null; - } - - var output = - await ContractHelper.CallTransactionAsync(MethodName.GetHolderInfo, param, false, - chainInfo); - return output; + return await _contractProvider.GetHolderInfoAsync(null, Hash.LoadFromHex(guardianIdentifierHash), chainId); } } \ No newline at end of file diff --git a/src/CAServer.Application/Guardian/Provider/IGuardianProvider.cs b/src/CAServer.Application/Guardian/Provider/IGuardianProvider.cs index 6e8c613f9..93e0d4aa6 100644 --- a/src/CAServer.Application/Guardian/Provider/IGuardianProvider.cs +++ b/src/CAServer.Application/Guardian/Provider/IGuardianProvider.cs @@ -8,8 +8,6 @@ public interface IGuardianProvider { Task GetGuardiansAsync(string loginGuardianIdentifierHash, string caHash); - Task GetHolderInfoFromContractAsync( - string guardianIdentifierHash, - string caHash, - ChainInfo chainInfo); + Task GetHolderInfoFromContractAsync(string guardianIdentifierHash, string caHash, + string chainId); } \ No newline at end of file diff --git a/src/CAServer.Application/IpInfo/IpInfoClient.cs b/src/CAServer.Application/IpInfo/IpInfoClient.cs index 9ab061817..a1f8e6658 100644 --- a/src/CAServer.Application/IpInfo/IpInfoClient.cs +++ b/src/CAServer.Application/IpInfo/IpInfoClient.cs @@ -25,7 +25,6 @@ public IpInfoClient(IHttpClientFactory httpClientFactory, public async Task GetIpInfoAsync(string ip) { - _logger.LogError($"#### ip is {ip}"); var requestUrl = $"{_ipServiceSetting.BaseUrl.TrimEnd('/')}/{ip}"; requestUrl += $"?access_key={_ipServiceSetting.AccessKey}&language={_ipServiceSetting.Language}"; diff --git a/src/CAServer.Application/Notify/NotifyAppService.cs b/src/CAServer.Application/Notify/NotifyAppService.cs index 65696d314..97b8094d2 100644 --- a/src/CAServer.Application/Notify/NotifyAppService.cs +++ b/src/CAServer.Application/Notify/NotifyAppService.cs @@ -5,9 +5,13 @@ using AElf.Indexing.Elasticsearch; using CAServer.Entities.Es; using CAServer.Grains.Grain.Notify; +using CAServer.IpInfo; using CAServer.Notify.Dtos; using CAServer.Notify.Etos; +using CAServer.Notify.Provider; +using Microsoft.Extensions.Logging; using Nest; +using Newtonsoft.Json; using Orleans; using Volo.Abp; using Volo.Abp.Auditing; @@ -21,35 +25,52 @@ public class NotifyAppService : CAServerAppService, INotifyAppService private readonly IClusterClient _clusterClient; private readonly IDistributedEventBus _distributedEventBus; private readonly INESTRepository _notifyRulesRepository; + private readonly INotifyProvider _notifyProvider; + private readonly IIpInfoAppService _ipInfoAppService; public NotifyAppService(IDistributedEventBus distributedEventBus, IClusterClient clusterClient, - INESTRepository notifyRulesRepository) + INESTRepository notifyRulesRepository, + INotifyProvider notifyProvider, + IIpInfoAppService ipInfoAppService) { _clusterClient = clusterClient; _distributedEventBus = distributedEventBus; _notifyRulesRepository = notifyRulesRepository; + _notifyProvider = notifyProvider; + _ipInfoAppService = ipInfoAppService; } public async Task PullNotifyAsync(PullNotifyDto input) { var mustQuery = new List, QueryContainer>>(); + //mustQuery.Add(q => q.Term(i => i.Field(f => f.AppId).Value(input.AppId))); mustQuery.Add(q => q.Terms(i => i.Field(f => f.DeviceTypes).Terms(input.DeviceType.ToString()))); mustQuery.Add(q => q.Terms(i => i.Field(f => f.AppVersions).Terms(input.AppVersion))); + mustQuery.Add(q => q.Terms(i => i.Field(f => f.DeviceBrands).Terms(input.DeviceBrand))); + mustQuery.Add(q => q.Terms(i => i.Field(f => f.OperatingSystemVersions).Terms(input.OperatingSystemVersion))); QueryContainer Filter(QueryContainerDescriptor f) => f.Bool(b => b.Must(mustQuery)); - IPromise> Sort(SortDescriptor s) => s.Descending(a => a.AppId); + IPromise> Sort(SortDescriptor s) => s.Descending(t => t.NotifyId); var (totalCount, notifyRulesIndices) = await _notifyRulesRepository.GetSortListAsync(Filter, sortFunc: Sort); - if (totalCount <= 0) { return null; } + var ipInfo = await _ipInfoAppService.GetIpInfoAsync(); var notifyRules = notifyRulesIndices.First(); - var grain = _clusterClient.GetGrain(notifyRules.Id); + if (notifyRules.Countries is { Length: > 0 }) + { + notifyRules = notifyRulesIndices?.Where(t => t.Countries.Contains(ipInfo.Code)).FirstOrDefault(); + if (notifyRules == null) + { + return null; + } + } + var grain = _clusterClient.GetGrain(notifyRules.Id); var resultDto = await grain.GetNotifyAsync(); if (!resultDto.Success) { @@ -104,7 +125,78 @@ public async Task DeleteAsync(Guid id) throw new UserFriendlyException(resultDto.Message); } - await _distributedEventBus.PublishAsync( - ObjectMapper.Map(resultDto.Data)); + await _distributedEventBus.PublishAsync(ObjectMapper.Map(resultDto.Data)); + } + + public async Task> CreateFromCmsAsync(string version) + { + //get data from cms + var condition = + "/items/upgradePush?fields=*,countries.country_id.value,deviceBrands.deviceBrand_id.value,deviceTypes.deviceType_id.value,targetVersion.value," + + $"appVersions.appVersion_id.value,styleType.value,targetVersion.value&filter[targetVersion][value][_eq]={version}&filter[status][_eq]=published"; + + Logger.LogDebug("before get data from cms."); + var notifyDto = await GetDataAsync(condition); + + var result = new List(); + + foreach (var notify in notifyDto.Data) + { + var grainId = GuidGenerator.Create(); + var grain = _clusterClient.GetGrain(grainId); + + var resultDto = await grain.AddNotifyAsync(ObjectMapper.Map(notify)); + if (!resultDto.Success) + { + throw new UserFriendlyException(resultDto.Message); + } + + await _distributedEventBus.PublishAsync(ObjectMapper.Map(resultDto.Data), false, + false); + result.Add(ObjectMapper.Map(resultDto.Data)); + } + + return result; + } + + public async Task UpdateFromCmsAsync(Guid id) + { + var grain = _clusterClient.GetGrain(id); + var getResultDto = await grain.GetNotifyAsync(); + if (!getResultDto.Success) + { + throw new UserFriendlyException(getResultDto.Message); + } + + var condition = + "/items/upgradePush?fields=*,countries.country_id.value,deviceBrands.deviceBrand_id.value,deviceTypes.deviceType_id.value," + + $"targetVersion.value,appVersions.appVersion_id.value,styleType.value,targetVersion.value&filter[id][_eq]={getResultDto.Data.NotifyId}"; + var notifyDto = await GetDataAsync(condition); + + var cmsNotify = notifyDto.Data.First(); + var resultDto = await grain.UpdateNotifyAsync(ObjectMapper.Map(cmsNotify)); + + if (!resultDto.Success) + { + throw new UserFriendlyException(resultDto.Message); + } + + await _distributedEventBus.PublishAsync(ObjectMapper.Map(resultDto.Data), false, + false); + return ObjectMapper.Map(resultDto.Data); + } + + private async Task GetDataAsync(string condition) + { + var notifyDto = await _notifyProvider.GetDataFromCms(condition); + + if (notifyDto?.Data == null || notifyDto.Data.Count == 0) + { + throw new UserFriendlyException($"Get data from cms fail: {condition}"); + } + + Logger.LogDebug("Get data from cms: {data}", JsonConvert.SerializeObject(notifyDto)); + + return notifyDto; } } \ No newline at end of file diff --git a/src/CAServer.Application/Notify/Provider/INotifyProvider.cs b/src/CAServer.Application/Notify/Provider/INotifyProvider.cs new file mode 100644 index 000000000..1e9810da6 --- /dev/null +++ b/src/CAServer.Application/Notify/Provider/INotifyProvider.cs @@ -0,0 +1,8 @@ +using System.Threading.Tasks; + +namespace CAServer.Notify.Provider; + +public interface INotifyProvider +{ + Task GetDataFromCms(string condition); +} \ No newline at end of file diff --git a/src/CAServer.Application/Notify/Provider/NotifyProvider.cs b/src/CAServer.Application/Notify/Provider/NotifyProvider.cs new file mode 100644 index 000000000..bd9d3cbd1 --- /dev/null +++ b/src/CAServer.Application/Notify/Provider/NotifyProvider.cs @@ -0,0 +1,26 @@ +using System.Threading.Tasks; +using CAServer.Common; +using CAServer.Options; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace CAServer.Notify.Provider; + +public class NotifyProvider : INotifyProvider, ISingletonDependency +{ + private readonly IHttpClientService _httpClientService; + private readonly CmsConfigOptions _cmsConfigOptions; + + public NotifyProvider(IHttpClientService httpClientService, + IOptionsSnapshot cmsConfigOptions) + { + _httpClientService = httpClientService; + _cmsConfigOptions = cmsConfigOptions.Value; + } + + public async Task GetDataFromCms(string condition) + { + var url = $"{_cmsConfigOptions.Uri}{condition}&access_token={_cmsConfigOptions.AccessToken}"; + return await _httpClientService.GetAsync(url); + } +} \ No newline at end of file diff --git a/src/CAServer.Application/Options/ClaimTokenInfoOptions.cs b/src/CAServer.Application/Options/ClaimTokenInfoOptions.cs index 327f718c4..89992b9e4 100644 --- a/src/CAServer.Application/Options/ClaimTokenInfoOptions.cs +++ b/src/CAServer.Application/Options/ClaimTokenInfoOptions.cs @@ -3,7 +3,7 @@ namespace CAServer.Options; public class ClaimTokenInfoOptions { public string ChainId { get; set; } - public string PrivateKey { get; set; } + public string PublicKey { get; set; } public string ClaimTokenAddress { get; set; } public int ExpireTime { get; set; } public long ClaimTokenAmount { get; set; } diff --git a/src/CAServer.Application/Options/CmsConfigOptions.cs b/src/CAServer.Application/Options/CmsConfigOptions.cs new file mode 100644 index 000000000..2b1c2d000 --- /dev/null +++ b/src/CAServer.Application/Options/CmsConfigOptions.cs @@ -0,0 +1,7 @@ +namespace CAServer.Options; + +public class CmsConfigOptions +{ + public string Uri { get; set; } + public string AccessToken { get; set; } +} \ No newline at end of file diff --git a/src/CAServer.Application/Options/ContractOptions.cs b/src/CAServer.Application/Options/ContractOptions.cs new file mode 100644 index 000000000..aecef4df4 --- /dev/null +++ b/src/CAServer.Application/Options/ContractOptions.cs @@ -0,0 +1,6 @@ +namespace CAServer.Options; + +public class ContractOptions +{ + public string CommonPrivateKeyForCallTx { get; set; } +} \ No newline at end of file diff --git a/src/CAServer.Application/Options/PhoneInfoOptions.cs b/src/CAServer.Application/Options/PhoneInfoOptions.cs index ef39a5181..39f7f7fab 100644 --- a/src/CAServer.Application/Options/PhoneInfoOptions.cs +++ b/src/CAServer.Application/Options/PhoneInfoOptions.cs @@ -5,6 +5,9 @@ namespace CAServer.Options; public class PhoneInfoOptions { + + public PhoneInfoItem Default { get; set; } + public List PhoneInfo { get; set; } } diff --git a/src/CAServer.Application/Phone/PhoneAppService.cs b/src/CAServer.Application/Phone/PhoneAppService.cs index 0d490c179..fe90d4f99 100644 --- a/src/CAServer.Application/Phone/PhoneAppService.cs +++ b/src/CAServer.Application/Phone/PhoneAppService.cs @@ -6,6 +6,7 @@ using CAServer.Grains; using CAServer.Grains.Grain.Contacts; using CAServer.Grains.Grain.Device; +using CAServer.IpInfo; using CAServer.Options; using Microsoft.AspNetCore.Routing.Matching; using Microsoft.Extensions.Logging; @@ -14,6 +15,7 @@ using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using Orleans; +using Orleans.Runtime; using Volo.Abp; using Volo.Abp.Auditing; using Volo.Abp.Users; @@ -29,31 +31,62 @@ public class PhoneAppService : CAServerAppService, IPhoneAppService private readonly PhoneInfoOptions _phoneInfoOptions; - public PhoneAppService(IClusterClient clusterClient, ILogger logger, + private readonly IIpInfoAppService _ipInfoAppService; + + public PhoneAppService(IIpInfoAppService ipInfoAppService, IClusterClient clusterClient, + ILogger logger, IOptions phoneInfoOptions) { + _ipInfoAppService = ipInfoAppService; _clusterClient = clusterClient; _logger = logger; _phoneInfoOptions = phoneInfoOptions.Value; } - public async Task GetPhoneInfo() + public async Task GetPhoneInfoAsync() { var phoneInfo = new List>(); + var allPhoneCode = new Dictionary(); for (int i = 0; i < _phoneInfoOptions.PhoneInfo.Count; i++) { var phoneInfoDict = new Dictionary(); - phoneInfoDict.Add("country",_phoneInfoOptions.PhoneInfo[i].Country); - phoneInfoDict.Add("code",_phoneInfoOptions.PhoneInfo[i].Code); - phoneInfoDict.Add("iso",_phoneInfoOptions.PhoneInfo[i].Iso); - phoneInfo.Add(phoneInfoDict); - } - + phoneInfoDict.Add("country", _phoneInfoOptions.PhoneInfo[i].Country); + phoneInfoDict.Add("code", _phoneInfoOptions.PhoneInfo[i].Code); + phoneInfoDict.Add("iso", _phoneInfoOptions.PhoneInfo[i].Iso); + phoneInfo.Add(phoneInfoDict); + + allPhoneCode.Add(_phoneInfoOptions.PhoneInfo[i].Code, _phoneInfoOptions.PhoneInfo[i].Iso); + } + + // default value + Dictionary locate = new Dictionary(); + + locate.Add("country", _phoneInfoOptions.Default.Country); + locate.Add("code", _phoneInfoOptions.Default.Code); + locate.Add("iso", _phoneInfoOptions.Default.Iso); + try + { + // NOTE! The [code] and [iso] attributes are DIFFERENT in [IpInfoResultDto] and [PhoneInfoListDto]. + IpInfoResultDto ipLocate = await _ipInfoAppService.GetIpInfoAsync(); + if (ipLocate != null && allPhoneCode.ContainsKey(ipLocate.Iso)) + { + locate = new Dictionary(); + locate.Add("country", ipLocate.Country); + locate.Add("code", ipLocate.Iso); + locate.Add("iso", ipLocate.Code); + } + } + catch (Exception e) + { + Logger.LogError(e, "GetIpInfoAsync error {}", e.Message); + } var phoneInfoList = new PhoneInfoListDto { - Data = phoneInfo + Data = phoneInfo, + LocateData = locate }; - + return phoneInfoList; } + } \ No newline at end of file diff --git a/src/CAServer.Application/Sample/SampleAppService.cs b/src/CAServer.Application/Sample/SampleAppService.cs deleted file mode 100644 index ada5a3df3..000000000 --- a/src/CAServer.Application/Sample/SampleAppService.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Threading.Tasks; -using CAServer.Grains.Grain; -using Newtonsoft.Json; -using Orleans; -using Volo.Abp; -using Volo.Abp.Auditing; - -namespace CAServer.Sample; - -[RemoteService(IsEnabled = false)] -[DisableAuditing] -public class SampleAppService : CAServerAppService, ISampleAppService -{ - private readonly IClusterClient _clusterClient; - - public SampleAppService(IClusterClient clusterClient) - { - _clusterClient = clusterClient; - } - - public async Task Hello(string from, string to) - { - var grain = _clusterClient.GetGrain(0); - string message = await grain.SayHello(from, to); - - var me = await grain.GetLastMessage(); - Console.WriteLine("### " + JsonConvert.SerializeObject(me)); - return message; - } -} \ No newline at end of file diff --git a/src/CAServer.Application/UserAssets/Provider/ImageProcessProvider.cs b/src/CAServer.Application/UserAssets/Provider/ImageProcessProvider.cs index ba927e2fc..a17a8ea03 100644 --- a/src/CAServer.Application/UserAssets/Provider/ImageProcessProvider.cs +++ b/src/CAServer.Application/UserAssets/Provider/ImageProcessProvider.cs @@ -32,7 +32,7 @@ public class ImageProcessProvider : IImageProcessProvider, ISingletonDependency private HttpClient? Client { get; set; } public ImageProcessProvider(ILogger logger, - IOptions adaptableVariableOptions, IHttpClientFactory httpClientFactory) + IOptionsSnapshot adaptableVariableOptions, IHttpClientFactory httpClientFactory) { _logger = logger; _httpClientFactory = httpClientFactory; @@ -76,7 +76,8 @@ public string getResizeUrl(string imageUrl, int width, int height, bool replaceD { if (replaceDomain) { - string[] urlSplit = imageUrl.Split(new string[] { UserAssetsServiceConstant.AwsDomain }, StringSplitOptions.RemoveEmptyEntries); + string[] urlSplit = imageUrl.Split(new string[] { UserAssetsServiceConstant.AwsDomain }, + StringSplitOptions.RemoveEmptyEntries); imageUrl = UserAssetsServiceConstant.NewAwsDomain + urlSplit[1]; } diff --git a/src/CAServer.Application/Verifier/HttpService.cs b/src/CAServer.Application/Verifier/HttpService.cs index 594b4c803..598a8eff0 100644 --- a/src/CAServer.Application/Verifier/HttpService.cs +++ b/src/CAServer.Application/Verifier/HttpService.cs @@ -13,22 +13,9 @@ namespace CAServer.Verifier; public interface IHttpService { - - Task GetResponseAsync(string url, string? version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK); - Task PostResponseAsync(string url, Dictionary parameters, string? version = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK, AuthenticationHeaderValue? authenticationHeaderValue = null); - - Task DeleteResponseAsObjectAsync(string url, string? version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK, - AuthenticationHeaderValue? authenticationHeaderValue = null); - - Task PostVerifyCodeResponseAsync(string url, Dictionary parameters, - string? version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK, - AuthenticationHeaderValue? authenticationHeaderValue = null); } public class HttpService : IHttpService @@ -45,20 +32,6 @@ public HttpService(int timeoutSeconds, IHttpClientFactory httpClientFactory, boo _httpClientFactory = httpClientFactory; } - public async Task GetResponseAsync(string url, string? version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK) - { - var response = await GetResponseAsync(url, version, expectedStatusCode); - var stream = await response.Content.ReadAsStreamAsync(); - var jsonSerializerOptions = _useCamelCase - ? new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.CamelCase - } - : new JsonSerializerOptions(); - return await JsonSerializer.DeserializeAsync(stream, jsonSerializerOptions); - } - public async Task PostResponseAsync(string url, Dictionary parameters, string? version = null, HttpStatusCode expectedStatusCode = HttpStatusCode.OK, @@ -76,46 +49,6 @@ public HttpService(int timeoutSeconds, IHttpClientFactory httpClientFactory, boo return await JsonSerializer.DeserializeAsync(stream, jsonSerializerOptions); } - public async Task DeleteResponseAsObjectAsync(string url, string? version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK, - AuthenticationHeaderValue? authenticationHeaderValue = null) - { - var response = await DeleteResponseAsync(url, version, expectedStatusCode, authenticationHeaderValue); - var stream = await response.Content.ReadAsStreamAsync(); - var jsonSerializerOptions = _useCamelCase - ? new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.CamelCase - } - : new JsonSerializerOptions(); - return await JsonSerializer.DeserializeAsync(stream, jsonSerializerOptions); - } - - public async Task PostVerifyCodeResponseAsync(string url, Dictionary parameters, string version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK, AuthenticationHeaderValue authenticationHeaderValue = null) - { - var response = await PostResponseAsync(url, parameters, version, true, expectedStatusCode, - authenticationHeaderValue); - return await response.Content.ReadAsStringAsync(); - } - - private async Task GetResponseAsync(string url, string? version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK) - { - version = !string.IsNullOrWhiteSpace(version) ? $";v={version}" : string.Empty; - - var client = GetHttpClient(version); - try - { - var response = await client.GetAsync(url); - return response; - } - catch (Exception ex) - { - throw new Exception(ex.Message); - } - } - private HttpClient GetHttpClient(string? version = null) { if (Client != null) @@ -173,30 +106,5 @@ private async Task PostResponseAsync(string url, } } - - private async Task DeleteResponseAsync(string url, string? version = null, - HttpStatusCode expectedStatusCode = HttpStatusCode.OK, - AuthenticationHeaderValue? authenticationHeaderValue = null) - { - version = !string.IsNullOrWhiteSpace(version) ? $";v={version}" : string.Empty; - var client = GetHttpClient(version); - - if (authenticationHeaderValue != null) - { - client.DefaultRequestHeaders.Authorization = authenticationHeaderValue; - } - - try - { - var response = await client.DeleteAsync(url); - return response; - } - catch (Exception ex) - { - throw new Exception(ex.Message); - } - } - - } diff --git a/src/CAServer.Application/Verifier/VerifierAppService.cs b/src/CAServer.Application/Verifier/VerifierAppService.cs index 94c2ec7b5..9061e6c16 100644 --- a/src/CAServer.Application/Verifier/VerifierAppService.cs +++ b/src/CAServer.Application/Verifier/VerifierAppService.cs @@ -25,6 +25,7 @@ using Volo.Abp.Auditing; using Volo.Abp.EventBus.Distributed; using Volo.Abp.ObjectMapping; +using Volo.Abp.Users; namespace CAServer.Verifier; @@ -232,10 +233,31 @@ await AddUserInfoAsync( public async Task CountVerifyCodeInterfaceRequestAsync(string userIpAddress) { var expire = TimeSpan.FromHours(_sendVerifierCodeRequestLimitOption.ExpireHours); + var countCacheItem = await _cacheProvider.Get(SendVerifierCodeInterfaceRequestCountCacheKey + ":" + userIpAddress); + if (countCacheItem.HasValue) + { + return await _cacheProvider.Increase(SendVerifierCodeInterfaceRequestCountCacheKey + ":" + userIpAddress, 1, + null); + } + return await _cacheProvider.Increase(SendVerifierCodeInterfaceRequestCountCacheKey + ":" + userIpAddress, 1, expire); } + public async Task GuardianExistsAsync(string guardianIdentifier) + { + try + { + var resultDto = GetGuardian(guardianIdentifier); + return resultDto.Success; + } + catch (Exception e) + { + _logger.LogError(e, "{Message}", e.Message); + throw new UserFriendlyException(e.Message); + } + } + private async Task AddUserInfoAsync(Dtos.UserExtraInfo userExtraInfo) { var userExtraInfoGrainId = @@ -394,4 +416,4 @@ private string GetAppleUserId(string identityToken) throw new Exception("Invalid token"); } } -} \ No newline at end of file +} diff --git a/src/CAServer.Application/Verifier/VerifierServerClient.cs b/src/CAServer.Application/Verifier/VerifierServerClient.cs index 99a0e7a64..8aa69aa9b 100644 --- a/src/CAServer.Application/Verifier/VerifierServerClient.cs +++ b/src/CAServer.Application/Verifier/VerifierServerClient.cs @@ -23,7 +23,7 @@ public class VerifierServerClient : IDisposable, IVerifierServerClient, ISinglet private readonly ILogger _logger; private readonly IHttpClientFactory _httpClientFactory; - public VerifierServerClient(IOptions adaptableVariableOptions, + public VerifierServerClient(IOptionsSnapshot adaptableVariableOptions, IGetVerifierServerProvider getVerifierServerProvider, ILogger logger, IHttpClientFactory httpClientFactory) diff --git a/src/CAServer.AuthServer/CAServer.AuthServer.csproj b/src/CAServer.AuthServer/CAServer.AuthServer.csproj index 6e53e7796..93868efde 100644 --- a/src/CAServer.AuthServer/CAServer.AuthServer.csproj +++ b/src/CAServer.AuthServer/CAServer.AuthServer.csproj @@ -22,6 +22,7 @@ + @@ -67,6 +68,7 @@ + diff --git a/src/CAServer.AuthServer/CAServerAuthServerModule.cs b/src/CAServer.AuthServer/CAServerAuthServerModule.cs index 57af0310c..fa839c87b 100644 --- a/src/CAServer.AuthServer/CAServerAuthServerModule.cs +++ b/src/CAServer.AuthServer/CAServerAuthServerModule.cs @@ -14,6 +14,7 @@ using CAServer.Localization; using CAServer.Model; using CAServer.MultiTenancy; +using CAServer.Signature; using StackExchange.Redis; using Volo.Abp; using Volo.Abp.Account; @@ -51,7 +52,8 @@ namespace CAServer; typeof(CAServerDomainModule), typeof(CAServerApplicationContractsModule), typeof(AbpAspNetCoreSerilogModule), - typeof(AbpEventBusRabbitMqModule) + typeof(AbpEventBusRabbitMqModule), + typeof(CAServerSignatureModule) )] public class CAServerAuthServerModule : AbpModule { @@ -90,7 +92,7 @@ public override void ConfigureServices(ServiceConfigurationContext context) { var hostingEnvironment = context.Services.GetHostingEnvironment(); var configuration = context.Services.GetConfiguration(); - + Configure(options => { options.TransactionBehavior = UnitOfWorkTransactionBehavior.Disabled; @@ -148,7 +150,7 @@ public override void ConfigureServices(ServiceConfigurationContext context) Configure(options => { - options.IsEnabled = false; + options.IsEnabled = false; //options.IsEnabledForGetRequests = true; //options.ApplicationName = "AuthServer"; }); diff --git a/src/CAServer.AuthServer/Contract/ChainInfo.cs b/src/CAServer.AuthServer/Contract/ChainInfo.cs index 740db7f41..2a554c8b3 100644 --- a/src/CAServer.AuthServer/Contract/ChainInfo.cs +++ b/src/CAServer.AuthServer/Contract/ChainInfo.cs @@ -5,6 +5,6 @@ public class ChainInfo public string ChainId { get; set; } public string BaseUrl { get; set; } public string ContractAddress { get; set; } - public string PrivateKey { get; set; } + public string PublicKey { get; set; } public bool IsMainChain { get; set; } } \ No newline at end of file diff --git a/src/CAServer.AuthServer/SignatureGrantHandler.cs b/src/CAServer.AuthServer/SignatureGrantHandler.cs index f9dd10820..3c827e8b9 100644 --- a/src/CAServer.AuthServer/SignatureGrantHandler.cs +++ b/src/CAServer.AuthServer/SignatureGrantHandler.cs @@ -12,6 +12,7 @@ using CAServer.Dto; using CAServer.Etos; using CAServer.Model; +using CAServer.Signature; using Google.Protobuf; using GraphQL; using GraphQL.Client.Http; @@ -41,6 +42,7 @@ public class SignatureGrantHandler : ITokenExtensionGrant private ILogger _logger; private IAbpDistributedLock _distributedLock; private readonly string _lockKeyPrefix = "CAServer:Auth:SignatureGrantHandler:"; + private ISignatureProvider _signatureProvider; public async Task HandleAsync(ExtensionGrantContext context) { @@ -82,6 +84,7 @@ public async Task HandleAsync(ExtensionGrantContext context) //Find manager by caHash var graphqlConfig = context.HttpContext.RequestServices.GetRequiredService>().Value; var chainOptions = context.HttpContext.RequestServices.GetRequiredService>().Value; + _signatureProvider = context.HttpContext.RequestServices.GetRequiredService(); var managerCheck = await CheckAddressAsync(chainId, graphqlConfig.Url, caHash, address, chainOptions); if (!managerCheck.HasValue || !managerCheck.Value) @@ -259,7 +262,7 @@ private async Task CallTransactionAsync(string chainId, string methodName, var client = new AElfClient(chainInfo.BaseUrl); await client.IsConnectedAsync(); - var ownAddress = client.GetAddressFromPrivateKey(chainInfo.PrivateKey); + var ownAddress = client.GetAddressFromPubKey(chainInfo.PublicKey); var contractAddress = isCrossChain ? (await client.GetContractAddressByNameAsync(HashHelper.ComputeFrom(ContractName.CrossChain))) .ToBase58() @@ -268,11 +271,11 @@ private async Task CallTransactionAsync(string chainId, string methodName, var transaction = await client.GenerateTransactionAsync(ownAddress, contractAddress, methodName, param); - var txWithSign = client.SignTransaction(chainInfo.PrivateKey, transaction); + var txWithSign = await _signatureProvider.SignTxMsg(ownAddress, transaction.ToByteArray().ToHex()); var result = await client.ExecuteTransactionAsync(new ExecuteTransactionDto { - RawTransaction = txWithSign.ToByteArray().ToHex() + RawTransaction = txWithSign }); var value = new T(); diff --git a/src/CAServer.AuthServer/appsettings.json b/src/CAServer.AuthServer/appsettings.json index 4a130d840..b4c2c81cb 100644 --- a/src/CAServer.AuthServer/appsettings.json +++ b/src/CAServer.AuthServer/appsettings.json @@ -85,5 +85,8 @@ } } ] + }, + "SignatureServer": { + "BaseUrl": "http://localhost:5000/api/app/signature" } } \ No newline at end of file diff --git a/src/CAServer.ContractEventHandler.Core/Application/CrossChainTransferAppService.cs b/src/CAServer.ContractEventHandler.Core/Application/CrossChainTransferAppService.cs index ae7e9b29a..c9a1a01aa 100644 --- a/src/CAServer.ContractEventHandler.Core/Application/CrossChainTransferAppService.cs +++ b/src/CAServer.ContractEventHandler.Core/Application/CrossChainTransferAppService.cs @@ -11,6 +11,7 @@ using AElf.Types; using CAServer.Grains.Grain.CrossChain; using CAServer.Grains.State.CrossChain; +using CAServer.Signature; using Google.Protobuf; using Google.Protobuf.WellKnownTypes; using Microsoft.Extensions.Logging; @@ -35,6 +36,8 @@ public class CrossChainTransferAppService : ICrossChainTransferAppService, ITran private readonly IClusterClient _clusterClient; private readonly CrossChainOptions _crossChainOptions; private readonly ILogger _logger; + private readonly ISignatureProvider _signatureProvider; + private const int MaxTransferQueryCount = 100; private const int MaxRetryTimes = 5; @@ -42,7 +45,7 @@ public class CrossChainTransferAppService : ICrossChainTransferAppService, ITran public CrossChainTransferAppService(IContractProvider contractProvider, IOptionsSnapshot chainOptions, ILogger logger, IGraphQLProvider graphQlProvider, IClusterClient clusterClient, IOptions indexOptions, - IOptions crossChainOptions) + IOptionsSnapshot crossChainOptions, ISignatureProvider signatureProvider) { _contractProvider = contractProvider; _chainOptions = chainOptions.Value; @@ -51,6 +54,7 @@ public CrossChainTransferAppService(IContractProvider contractProvider, IOptions _clusterClient = clusterClient; _indexOptions = indexOptions.Value; _crossChainOptions = crossChainOptions.Value; + _signatureProvider = signatureProvider; } public async Task AutoReceiveAsync() @@ -85,28 +89,19 @@ private async Task> GetToReceiveTransactionsAsync(st if (transfers.Count < MaxTransferQueryCount) { - var lastEndHeight = (await grain.GetLastedProcessedHeightAsync()).Data; - - if (lastEndHeight == 0) + var latestProcessedHeight = (await grain.GetLastedProcessedHeightAsync()).Data; + if (latestProcessedHeight == 0) { - lastEndHeight = _crossChainOptions.AutoReceiveStartHeight[chainId] - 1; + latestProcessedHeight = _crossChainOptions.AutoReceiveStartHeight[chainId] - 1; } - var currentIndexHeight = await _graphQlProvider.GetIndexBlockHeightAsync(chainId); - - var targetIndexHeight = currentIndexHeight + _indexOptions.IndexAfter; - - var startHeight = lastEndHeight - _indexOptions.IndexBefore; - - var endIndexHeight = lastEndHeight + _indexOptions.IndexBefore; - - endIndexHeight = endIndexHeight < targetIndexHeight ? endIndexHeight : targetIndexHeight; + var indexedHeight = await _graphQlProvider.GetIndexBlockHeightAsync(chainId); + var startHeight = latestProcessedHeight + 1; + var endHeight = Math.Min(startHeight + MaxTransferQueryCount - 1, indexedHeight - _indexOptions.IndexSafe); - _logger.LogDebug("startHeight is {startHeight},endHeight is {endHeight}", startHeight, endIndexHeight); - - while (endIndexHeight <= targetIndexHeight) + while (true) { - var list = await _graphQlProvider.GetToReceiveTransactionsAsync(chainId, startHeight, endIndexHeight); + var list = await _graphQlProvider.GetToReceiveTransactionsAsync(chainId, startHeight, endHeight); var queryTransfers = list.CaHolderTransactionInfo.Data.Select(tx => new CrossChainTransferDto { Id = tx.TransactionId, @@ -117,34 +112,25 @@ private async Task> GetToReceiveTransactionsAsync(st TransferTransactionBlockHash = tx.BlockHash, Status = CrossChainStatus.Indexing }).ToList(); - var transactionDic = await grain.GetTransactionDicAsync(); - if (transactionDic != null) - { - queryTransfers = queryTransfers.Where(o => !transactionDic.ContainsValue(o.TransferTransactionId)) - .ToList(); - } - var dic = queryTransfers.ToDictionary(o => o.TransferTransactionHeight, o => o.TransferTransactionId); - - await grain.UpdateTransfersDicAsync(startHeight, dic); - await grain.AddTransfersAsync(endIndexHeight, queryTransfers); + await grain.AddTransfersAsync(endHeight, queryTransfers); transfers.AddRange(queryTransfers); - _logger.LogDebug($"Processed height: {chainId}, {endIndexHeight}"); + _logger.LogDebug($"Processed height: {chainId}, {endHeight}"); - if (transfers.Count > MaxTransferQueryCount || endIndexHeight == targetIndexHeight) + if (transfers.Count > MaxTransferQueryCount || endHeight == indexedHeight - _indexOptions.IndexSafe) { break; } - startHeight = endIndexHeight; - endIndexHeight += _indexOptions.IndexInterval; - endIndexHeight = endIndexHeight < targetIndexHeight ? endIndexHeight : targetIndexHeight; + startHeight = endHeight + 1; + endHeight = Math.Min(startHeight + MaxTransferQueryCount - 1, indexedHeight - _indexOptions.IndexSafe); } } return transfers; } + private async Task HandleTransferTransactionsAsync(List transfers) { foreach (var transfer in transfers) @@ -389,19 +375,20 @@ private async Task GetBoundParentChainHeightAndMer { var chainInfo = _chainOptions.ChainInfos[chainId]; var client = new AElfClient(chainInfo.BaseUrl); + var ownAddress = client.GetAddressFromPubKey(chainInfo.PublicKey); var param = new Int64Value { Value = height }; var transaction = - await client.GenerateTransactionAsync(client.GetAddressFromPrivateKey(chainInfo.PrivateKey), + await client.GenerateTransactionAsync(client.GetAddressFromPubKey(chainInfo.PublicKey), chainInfo.CrossChainContractAddress, "GetBoundParentChainHeightAndMerklePathByHeight", param); - var txWithSign = client.SignTransaction(chainInfo.PrivateKey, transaction); + var txWithSign = await _signatureProvider.SignTxMsg(ownAddress, transaction.ToByteArray().ToHex()); var transactionResult = await client.ExecuteTransactionAsync(new ExecuteTransactionDto { - RawTransaction = txWithSign.ToByteArray().ToHex() + RawTransaction = txWithSign }); var result = CrossChainMerkleProofContext.Parser.ParseFrom(ByteArrayHelper.HexStringToByteArray(transactionResult)); @@ -414,6 +401,7 @@ private async Task SendCrossChainReceiveTokenAsync(string chainId, strin { var chainInfo = _chainOptions.ChainInfos[chainId]; var client = new AElfClient(chainInfo.BaseUrl); + var ownAddress = client.GetAddressFromPubKey(chainInfo.PublicKey); var param = new CrossChainReceiveTokenInput { @@ -422,14 +410,13 @@ private async Task SendCrossChainReceiveTokenAsync(string chainId, strin ParentChainHeight = parentChainHeight, TransferTransactionBytes = ByteString.CopyFrom(ByteArrayHelper.HexStringToByteArray(transferTransaction)), }; - var fromAddress = client.GetAddressFromPrivateKey(chainInfo.PrivateKey); + var fromAddress = client.GetAddressFromPubKey(chainInfo.PublicKey); var transaction = await client.GenerateTransactionAsync(fromAddress, chainInfo.TokenContractAddress, "CrossChainReceiveToken", param); - var txWithSign = client.SignTransaction(chainInfo.PrivateKey, transaction); - + var txWithSign = await _signatureProvider.SignTxMsg(ownAddress, transaction.ToByteArray().ToHex()); var result = await client.SendTransactionAsync(new SendTransactionInput { - RawTransaction = txWithSign.ToByteArray().ToHex() + RawTransaction = txWithSign }); return result.TransactionId; diff --git a/src/CAServer.ContractEventHandler.Core/Application/IContractAppService.cs b/src/CAServer.ContractEventHandler.Core/Application/IContractAppService.cs index 7a8ef552d..4668cde2d 100644 --- a/src/CAServer.ContractEventHandler.Core/Application/IContractAppService.cs +++ b/src/CAServer.ContractEventHandler.Core/Application/IContractAppService.cs @@ -232,7 +232,7 @@ private async Task ValidateTransactionAndSyncAsync(string chainId, GetHold var validateHeight = transactionDto.TransactionResultDto.BlockNumber; SyncHolderInfoInput syncHolderInfoInput; - + var syncSucceed = true; if (chainInfo.IsMainChain) @@ -241,7 +241,7 @@ private async Task ValidateTransactionAndSyncAsync(string chainId, GetHold !c.IsMainChain && c.ChainId != optionChainId)) { await _contractProvider.SideChainCheckMainChainBlockIndexAsync(sideChain.ChainId, validateHeight); - + syncHolderInfoInput = await _contractProvider.GetSyncHolderInfoInputAsync(chainId, new TransactionInfo { @@ -262,7 +262,7 @@ private async Task ValidateTransactionAndSyncAsync(string chainId, GetHold else { await _contractProvider.MainChainCheckSideChainBlockIndexAsync(chainId, validateHeight); - + syncHolderInfoInput = await _contractProvider.GetSyncHolderInfoInputAsync(chainId, new TransactionInfo { @@ -270,12 +270,12 @@ private async Task ValidateTransactionAndSyncAsync(string chainId, GetHold BlockNumber = transactionDto.TransactionResultDto.BlockNumber, Transaction = transactionDto.Transaction.ToByteArray() }); - + if (syncHolderInfoInput.VerificationTransactionInfo == null) { return false; } - + var syncResult = await _contractProvider.SyncTransactionAsync(ContractAppServiceConstant.MainChainId, syncHolderInfoInput); @@ -336,6 +336,19 @@ private async Task QueryEventsAndSyncAsync(string chainId) await SyncQueryEventsAsync(chainId); } + private long GetEndBlockHeight(long lastEndHeight, long interval, long currentIndexHeight) + { + if (lastEndHeight + 1 >= currentIndexHeight - _indexOptions.IndexSafe) + { + return ContractAppServiceConstant.LongError; + } + + var nextQueryHeight = lastEndHeight + 1 + interval; + var currentSafeIndexHeight = currentIndexHeight - _indexOptions.IndexSafe; + + return nextQueryHeight < currentSafeIndexHeight ? nextQueryHeight : currentSafeIndexHeight; + } + private async Task SyncQueryEventsAsync(string chainId) { _logger.LogInformation("SyncQueryEvents on chain: {id} starts", chainId); @@ -411,7 +424,7 @@ record = records.FirstOrDefault(r => r.ValidateHeight < indexHeight); while (indexMainChainBlock <= mainHeight && retryTimes < _indexOptions.IndexTimes) { - await Task.Delay(1000); + await Task.Delay(_indexOptions.IndexDelay); indexMainChainBlock = await _contractProvider.GetIndexHeightFromSideChainAsync(chainId); retryTimes++; } @@ -465,12 +478,10 @@ private async Task QueryEventsAsync(string chainId) try { var lastEndHeight = await _graphQLProvider.GetLastEndHeightAsync(chainId, QueryType.QueryRecord); - var currentIndexHeight = await _graphQLProvider.GetIndexBlockHeightAsync(chainId); + var endBlockHeight = GetEndBlockHeight(lastEndHeight, _indexOptions.IndexInterval, currentIndexHeight); - var targetIndexHeight = currentIndexHeight + _indexOptions.IndexAfter; - - if (currentIndexHeight <= 0 || lastEndHeight >= targetIndexHeight) + if (endBlockHeight == ContractAppServiceConstant.LongError) { _logger.LogWarning( "QueryEventsAsync on chain: {id}. Index Height is not enough. Skipped querying this time. \nLastEndHeight: {last}, CurrentIndexHeight: {index}", @@ -478,56 +489,35 @@ private async Task QueryEventsAsync(string chainId) return; } - var startIndexHeight = lastEndHeight - _indexOptions.IndexBefore; - var endIndexHeight = lastEndHeight + _indexOptions.IndexInterval; - endIndexHeight = endIndexHeight < targetIndexHeight ? endIndexHeight : targetIndexHeight; + var queryEvents = await _graphQLProvider.GetLoginGuardianTransactionInfosAsync( + chainId, lastEndHeight + 1, endBlockHeight); + queryEvents.AddRange(await _graphQLProvider.GetManagerTransactionInfosAsync( + chainId, lastEndHeight + 1, endBlockHeight)); - List queryEvents = new List(); - - while (endIndexHeight <= targetIndexHeight) - { - _logger.LogInformation("Query on chain: {id}, from {start} to {end}", chainId, startIndexHeight, - endIndexHeight); - - queryEvents.AddRange(await _graphQLProvider.GetLoginGuardianTransactionInfosAsync( - chainId, startIndexHeight, endIndexHeight)); - queryEvents.AddRange(await _graphQLProvider.GetManagerTransactionInfosAsync( - chainId, startIndexHeight, endIndexHeight)); - - if (endIndexHeight == targetIndexHeight) - { - break; - } - - startIndexHeight = endIndexHeight; - - endIndexHeight += _indexOptions.IndexInterval; - endIndexHeight = endIndexHeight < targetIndexHeight ? endIndexHeight : targetIndexHeight; - } + var nextIndexHeight = endBlockHeight < currentIndexHeight + ? endBlockHeight + 1 + : currentIndexHeight - _indexOptions.IndexSafe; if (queryEvents.IsNullOrEmpty()) { _logger.LogInformation( "Found no events on chain: {id}. Next index block height: {height}", chainId, - currentIndexHeight); + nextIndexHeight); } else { _logger.LogInformation( - "Found {num} events on chain: {id}. Next index block height: {height}", queryEvents.Count, chainId, - currentIndexHeight); + "Found {num} events on chain: {id}", queryEvents.Count, chainId); queryEvents = queryEvents.Where(e => e.ChangeType != QueryLoginGuardianType.LoginGuardianRemoved) .ToList(); var list = OptimizeQueryEvents(queryEvents); - list = RemoveDuplicateQueryEvents(await _recordsBucketContainer.GetValidatedRecords(chainId), list); - await _recordsBucketContainer.AddToBeValidatedRecordsAsync(chainId, list); } - await _graphQLProvider.SetLastEndHeightAsync(chainId, QueryType.QueryRecord, currentIndexHeight); + await _graphQLProvider.SetLastEndHeightAsync(chainId, QueryType.QueryRecord, nextIndexHeight); } catch (Exception e) { diff --git a/src/CAServer.ContractEventHandler.Core/Application/IContractProvider.cs b/src/CAServer.ContractEventHandler.Core/Application/IContractProvider.cs index fc1cfc403..6001eadc8 100644 --- a/src/CAServer.ContractEventHandler.Core/Application/IContractProvider.cs +++ b/src/CAServer.ContractEventHandler.Core/Application/IContractProvider.cs @@ -6,6 +6,7 @@ using AElf.Types; using CAServer.Grains.Grain.ApplicationHandler; using CAServer.Grains.State.ApplicationHandler; +using CAServer.Signature; using Google.Protobuf; using Google.Protobuf.Collections; using Google.Protobuf.WellKnownTypes; @@ -53,14 +54,16 @@ public class ContractProvider : IContractProvider private readonly IClusterClient _clusterClient; private readonly ChainOptions _chainOptions; private readonly IndexOptions _indexOptions; + private readonly ISignatureProvider _signatureProvider; public ContractProvider(ILogger logger, IOptionsSnapshot chainOptions, - IOptionsSnapshot indexOptions, IClusterClient clusterClient) + IOptionsSnapshot indexOptions, IClusterClient clusterClient, ISignatureProvider signatureProvider) { _logger = logger; _chainOptions = chainOptions.Value; _indexOptions = indexOptions.Value; _clusterClient = clusterClient; + _signatureProvider = signatureProvider; } private async Task CallTransactionAsync(string chainId, string methodName, IMessage param, @@ -72,17 +75,16 @@ private async Task CallTransactionAsync(string chainId, string methodName, var client = new AElfClient(chainInfo.BaseUrl); await client.IsConnectedAsync(); - var ownAddress = client.GetAddressFromPrivateKey(chainInfo.PrivateKey); + var ownAddress = client.GetAddressFromPubKey(chainInfo.PublicKey); var contractAddress = isCrossChain ? chainInfo.CrossChainContractAddress : chainInfo.ContractAddress; var transaction = await client.GenerateTransactionAsync(ownAddress, contractAddress, methodName, param); - var txWithSign = client.SignTransaction(chainInfo.PrivateKey, transaction); - + var txWithSign = await _signatureProvider.SignTxMsg(ownAddress, transaction.ToByteArray().ToHex()); var result = await client.ExecuteTransactionAsync(new ExecuteTransactionDto { - RawTransaction = txWithSign.ToByteArray().ToHex() + RawTransaction = txWithSign }); var value = new T(); diff --git a/src/CAServer.ContractEventHandler.Core/Application/IGraphQLProvider.cs b/src/CAServer.ContractEventHandler.Core/Application/IGraphQLProvider.cs index f905c98eb..8219850b0 100644 --- a/src/CAServer.ContractEventHandler.Core/Application/IGraphQLProvider.cs +++ b/src/CAServer.ContractEventHandler.Core/Application/IGraphQLProvider.cs @@ -109,7 +109,7 @@ public async Task> GetLoginGuardianTransactionInfosAsync( Query = @" query($chainId:String,$startBlockHeight:Long!,$endBlockHeight:Long!) { loginGuardianChangeRecordInfo(dto: {chainId:$chainId,startBlockHeight:$startBlockHeight,endBlockHeight:$endBlockHeight}){ - id, caHash, caAddress, changeType, manager, loginGuardian{identifierHash}, blockHeight, blockHash} + id, caHash, caAddress, changeType, loginGuardian{identifierHash}, blockHeight} }", Variables = new { @@ -129,11 +129,9 @@ public async Task> GetLoginGuardianTransactionInfosAsync( { result.Add(new QueryEventDto { + BlockHeight = record.BlockHeight, CaHash = record.CaHash, ChangeType = record.ChangeType, - Manager = record.Manager, - BlockHeight = record.BlockHeight, - BlockHash = record.BlockHash, NotLoginGuardian = record.ChangeType == QueryLoginGuardianType.LoginGuardianUnbound ? record.LoginGuardian.IdentifierHash : null @@ -157,7 +155,7 @@ public async Task> GetManagerTransactionInfosAsync(string ch Query = @" query($chainId:String,$startBlockHeight:Long!,$endBlockHeight:Long!) { caHolderManagerChangeRecordInfo(dto: {chainId:$chainId,startBlockHeight:$startBlockHeight,endBlockHeight:$endBlockHeight}){ - caAddress, caHash, manager, changeType, blockHeight, blockHash} + caAddress, caHash, manager, changeType, blockHeight} }", Variables = new { @@ -177,11 +175,9 @@ public async Task> GetManagerTransactionInfosAsync(string ch { result.Add(new QueryEventDto { - CaHash = record.CaHash, - ChangeType = record.ChangeType, - Manager = record.Manager, BlockHeight = record.BlockHeight, - BlockHash = record.BlockHash + CaHash = record.CaHash, + ChangeType = record.ChangeType }); } diff --git a/src/CAServer.ContractEventHandler.Core/Application/Options.cs b/src/CAServer.ContractEventHandler.Core/Application/Options.cs index 5347c3dec..67d798835 100644 --- a/src/CAServer.ContractEventHandler.Core/Application/Options.cs +++ b/src/CAServer.ContractEventHandler.Core/Application/Options.cs @@ -14,7 +14,7 @@ public class ChainInfo public string ContractAddress { get; set; } public string TokenContractAddress { get; set; } public string CrossChainContractAddress { get; set; } - public string PrivateKey { get; set; } + public string PublicKey { get; set; } public bool IsMainChain { get; set; } } @@ -23,12 +23,14 @@ public class IndexOptions public int IndexDelay { get; set; } public long IndexInterval { get; set; } public long IndexSafe { get; set; } - public long IndexBefore { get; set; } - public long IndexAfter { get; set; } public long IndexTimes { get; set; } public int MaxRetryTimes { get; set; } public int MaxBucket { get; set; } - public Dictionary AutoSyncStartHeight { get; set; } + public Dictionary AutoSyncStartHeight { get; set; } = new() + { + { "AELF", 146928049 }, + { "tDVV", 139522008 } + }; } public class GraphQLOptions diff --git a/src/CAServer.ContractEventHandler.Core/CAServer.ContractEventHandler.Core.csproj b/src/CAServer.ContractEventHandler.Core/CAServer.ContractEventHandler.Core.csproj index d4526afba..03f80d026 100644 --- a/src/CAServer.ContractEventHandler.Core/CAServer.ContractEventHandler.Core.csproj +++ b/src/CAServer.ContractEventHandler.Core/CAServer.ContractEventHandler.Core.csproj @@ -16,5 +16,6 @@ + \ No newline at end of file diff --git a/src/CAServer.ContractEventHandler.Core/CAServerContractEventHandlerCoreModule.cs b/src/CAServer.ContractEventHandler.Core/CAServerContractEventHandlerCoreModule.cs index d8a20b81f..2120a1370 100644 --- a/src/CAServer.ContractEventHandler.Core/CAServerContractEventHandlerCoreModule.cs +++ b/src/CAServer.ContractEventHandler.Core/CAServerContractEventHandlerCoreModule.cs @@ -1,4 +1,5 @@ using CAServer.ContractEventHandler.Core.Application; +using CAServer.Signature; using Microsoft.Extensions.DependencyInjection; using Volo.Abp; using Volo.Abp.AutoMapper; @@ -7,7 +8,7 @@ namespace CAServer.ContractEventHandler.Core; -[DependsOn(typeof(AbpAutoMapperModule))] +[DependsOn(typeof(AbpAutoMapperModule), typeof(CAServerSignatureModule))] public class CAServerContractEventHandlerCoreModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) diff --git a/src/CAServer.ContractEventHandler/CAServerContractEventHandlerModule.cs b/src/CAServer.ContractEventHandler/CAServerContractEventHandlerModule.cs index 5c7221019..c4db02df1 100644 --- a/src/CAServer.ContractEventHandler/CAServerContractEventHandlerModule.cs +++ b/src/CAServer.ContractEventHandler/CAServerContractEventHandlerModule.cs @@ -3,6 +3,7 @@ using CAServer.ContractEventHandler.Core.Application; using CAServer.ContractEventHandler.Core.Worker; using CAServer.Grains; +using CAServer.Signature; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; @@ -57,12 +58,12 @@ public override void ConfigureServices(ServiceConfigurationContext context) ConfigureCache(configuration); ConfigureDataProtection(context, configuration, hostingEnvironment); } - + private void ConfigureCache(IConfiguration configuration) { Configure(options => { options.KeyPrefix = "CAServer:"; }); } - + private void ConfigureDataProtection( ServiceConfigurationContext context, IConfiguration configuration, @@ -111,8 +112,7 @@ private static void ConfigureOrleans(ServiceConfigurationContext context, IConfi .Build(); }); } - - + private static void StartOrleans(IServiceProvider serviceProvider) { diff --git a/src/CAServer.ContractEventHandler/appsettings.json b/src/CAServer.ContractEventHandler/appsettings.json index 402c2e866..3ed2c9253 100644 --- a/src/CAServer.ContractEventHandler/appsettings.json +++ b/src/CAServer.ContractEventHandler/appsettings.json @@ -55,17 +55,11 @@ }, "Index": { "IndexDelay": 5000, - "IndexInterval": 800, + "IndexInterval": 10000, "IndexSafe": 100, "IndexTimes": 60, "MaxRetryTimes": 10, - "MaxBucket": 1, - "IndexBefore": 200, - "indexAfter": 400, - "AutoSyncStartHeight": { - "AELF": 5743, - "tDVV": 3295 - } + "MaxBucket": 1 }, "GraphQL": { "GraphQLConnection": "http://127.0.0.1:8083/Indexer_DApp/PortKeyIndexerCASchema/graphql" diff --git a/src/CAServer.Domain.Shared/EnumType/StyleType.cs b/src/CAServer.Domain.Shared/EnumType/StyleType.cs new file mode 100644 index 000000000..b90ac253c --- /dev/null +++ b/src/CAServer.Domain.Shared/EnumType/StyleType.cs @@ -0,0 +1,6 @@ +namespace CAServer; + +public enum StyleType +{ + Default = 1 +} \ No newline at end of file diff --git a/src/CAServer.Domain/Entities/Es/NotifyRulesIndex.cs b/src/CAServer.Domain/Entities/Es/NotifyRulesIndex.cs index 31c4c7c1b..6d2efee4e 100644 --- a/src/CAServer.Domain/Entities/Es/NotifyRulesIndex.cs +++ b/src/CAServer.Domain/Entities/Es/NotifyRulesIndex.cs @@ -7,11 +7,13 @@ namespace CAServer.Entities.Es; public class NotifyRulesIndex : CAServerEsEntity, IIndexBuild { [Keyword] public override Guid Id { get; set; } + public int NotifyId { get; set; } [Keyword] public string AppId { get; set; } [Keyword] public string[] AppVersions { get; set; } [Keyword] public string[] DeviceTypes { get; set; } [Keyword] public string[] DeviceBrands { get; set; } [Keyword] public string[] OperatingSystemVersions { get; set; } public NotifySendType[] SendTypes { get; set; } + [Keyword] public string[] Countries { get; set; } public bool IsApproved { get; set; } } \ No newline at end of file diff --git a/src/CAServer.Grains/CAServer.Grains.csproj b/src/CAServer.Grains/CAServer.Grains.csproj index b997825e8..90636606a 100644 --- a/src/CAServer.Grains/CAServer.Grains.csproj +++ b/src/CAServer.Grains/CAServer.Grains.csproj @@ -8,6 +8,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -29,6 +30,7 @@ + diff --git a/src/CAServer.Grains/CAServerGrainsModule.cs b/src/CAServer.Grains/CAServerGrainsModule.cs index bd2fcd9ba..326044ff4 100644 --- a/src/CAServer.Grains/CAServerGrainsModule.cs +++ b/src/CAServer.Grains/CAServerGrainsModule.cs @@ -1,13 +1,16 @@ using CAServer.Grains.Grain.Account; using CAServer.Grains.Grain.Tokens.TokenPrice; using CAServer.Options; +using CAServer.Signature; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AutoMapper; using Volo.Abp.Modularity; namespace CAServer.Grains; -[DependsOn(typeof(CAServerApplicationContractsModule), typeof(AbpAutoMapperModule))] +[DependsOn(typeof(CAServerApplicationContractsModule), + typeof(AbpAutoMapperModule), + typeof(CAServerSignatureModule))] public class CAServerGrainsModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) diff --git a/src/CAServer.Grains/Grain/ApplicationHandler/ContractServiceBase.cs b/src/CAServer.Grains/Grain/ApplicationHandler/ContractServiceBase.cs index bdf1ee115..8ca0bfd22 100644 --- a/src/CAServer.Grains/Grain/ApplicationHandler/ContractServiceBase.cs +++ b/src/CAServer.Grains/Grain/ApplicationHandler/ContractServiceBase.cs @@ -18,7 +18,7 @@ public class ChainInfo public string ContractAddress { get; set; } public string TokenContractAddress { get; set; } public string CrossChainContractAddress { get; set; } - public string PrivateKey { get; set; } + public string PublicKey { get; set; } public bool IsMainChain { get; set; } } diff --git a/src/CAServer.Grains/Grain/ApplicationHandler/ContractServiceGrain.cs b/src/CAServer.Grains/Grain/ApplicationHandler/ContractServiceGrain.cs index eb742e169..bd6c801f6 100644 --- a/src/CAServer.Grains/Grain/ApplicationHandler/ContractServiceGrain.cs +++ b/src/CAServer.Grains/Grain/ApplicationHandler/ContractServiceGrain.cs @@ -4,6 +4,7 @@ using AElf.Standards.ACS7; using AElf.Types; using CAServer.Grains.State.ApplicationHandler; +using CAServer.Signature; using Google.Protobuf; using Google.Protobuf.Collections; using Google.Protobuf.WellKnownTypes; @@ -23,14 +24,18 @@ public class ContractServiceGrain : Orleans.Grain, IContractServiceGrain private readonly ChainOptions _chainOptions; private readonly IObjectMapper _objectMapper; private readonly ILogger _logger; + private readonly ISignatureProvider _signatureProvider; public ContractServiceGrain(IOptions chainOptions, IOptions grainOptions, - IObjectMapper objectMapper, ILogger logger) + IObjectMapper objectMapper, + ISignatureProvider signatureProvider, + ILogger logger) { _objectMapper = objectMapper; _logger = logger; _grainOptions = grainOptions.Value; _chainOptions = chainOptions.Value; + _signatureProvider = signatureProvider; } private async Task SendTransactionToChainAsync(string chainId, IMessage param, @@ -41,8 +46,8 @@ private async Task SendTransactionToChainAsync(string chainI var chainInfo = _chainOptions.ChainInfos[chainId]; var client = new AElfClient(chainInfo.BaseUrl); await client.IsConnectedAsync(); - var ownAddress = client.GetAddressFromPrivateKey(chainInfo.PrivateKey); - + var ownAddress = client.GetAddressFromPubKey(chainInfo.PublicKey); + var transaction = await client.GenerateTransactionAsync(ownAddress, chainInfo.ContractAddress, methodName, param); @@ -50,7 +55,7 @@ await client.GenerateTransactionAsync(ownAddress, chainInfo.ContractAddress, met var refBlockNumber = transaction.RefBlockNumber; refBlockNumber -= _grainOptions.SafeBlockHeight; - + if (refBlockNumber < 0) { refBlockNumber = 0; @@ -60,12 +65,13 @@ await client.GenerateTransactionAsync(ownAddress, chainInfo.ContractAddress, met transaction.RefBlockNumber = refBlockNumber; transaction.RefBlockPrefix = BlockHelper.GetRefBlockPrefix(Hash.LoadFromHex(blockDto.BlockHash)); - - var txWithSign = client.SignTransaction(chainInfo.PrivateKey, transaction); - var result = await client.SendTransactionAsync(new SendTransactionInput + var txWithSign = await _signatureProvider.SignTxMsg(ownAddress, + transaction.ToByteArray().ToHex()); + + var result = await client.SendTransactionAsync(new SendTransactionInput() { - RawTransaction = txWithSign.ToByteArray().ToHex() + RawTransaction = txWithSign }); await Task.Delay(_grainOptions.Delay); @@ -183,7 +189,7 @@ private async Task UpdateMerkleTreeAsync(string chainId, AE { var chainInfo = _chainOptions.ChainInfos[chainId]; - var ownAddress = client.GetAddressFromPrivateKey(chainInfo.PrivateKey); + var ownAddress = client.GetAddressFromPubKey(chainInfo.PublicKey); var transaction = await client.GenerateTransactionAsync(ownAddress, chainInfo.CrossChainContractAddress, MethodName.UpdateMerkleTree, @@ -191,11 +197,11 @@ private async Task UpdateMerkleTreeAsync(string chainId, AE { Value = syncHolderInfoInput.VerificationTransactionInfo.ParentChainHeight }); - var txWithSign = client.SignTransaction(chainInfo.PrivateKey, transaction); - + var txWithSign = await _signatureProvider.SignTxMsg(ownAddress, + transaction.ToByteArray().ToHex()); var result = await client.ExecuteTransactionAsync(new ExecuteTransactionDto { - RawTransaction = txWithSign.ToByteArray().ToHex() + RawTransaction = txWithSign }); var context = CrossChainMerkleProofContext.Parser.ParseFrom(ByteArrayHelper.HexStringToByteArray(result)); diff --git a/src/CAServer.Grains/Grain/ISampleGrain.cs b/src/CAServer.Grains/Grain/ISampleGrain.cs deleted file mode 100644 index 7e0862363..000000000 --- a/src/CAServer.Grains/Grain/ISampleGrain.cs +++ /dev/null @@ -1,11 +0,0 @@ -using CAServer.Sample; -using Orleans; - -namespace CAServer.Grains.Grain; - -public interface ISampleGrain:IGrainWithIntegerKey -{ - Task SayHello(string from, string to); - - Task GetLastMessage(); -} \ No newline at end of file diff --git a/src/CAServer.Grains/Grain/Notify/NotifyGrain.cs b/src/CAServer.Grains/Grain/Notify/NotifyGrain.cs index 19e503220..2b7089409 100644 --- a/src/CAServer.Grains/Grain/Notify/NotifyGrain.cs +++ b/src/CAServer.Grains/Grain/Notify/NotifyGrain.cs @@ -63,6 +63,7 @@ public async Task> AddNotifyAsync(NotifyGrainDto notifyData.OperatingSystemVersions = rules.OperatingSystemVersions; notifyData.SendTypes = rules.SendTypes; notifyData.IsApproved = rules.IsApproved; + notifyData.Countries = rules.Countries; result.Success = true; result.Data = notifyData; @@ -92,6 +93,7 @@ public async Task> UpdateNotifyAsync(NotifyGrainD notifyData.OperatingSystemVersions = rules.OperatingSystemVersions; notifyData.SendTypes = rules.SendTypes; notifyData.IsApproved = rules.IsApproved; + notifyData.Countries = rules.Countries; result.Success = true; result.Data = notifyData; diff --git a/src/CAServer.Grains/Grain/Notify/NotifyGrainDto.cs b/src/CAServer.Grains/Grain/Notify/NotifyGrainDto.cs index 1671e1160..384566675 100644 --- a/src/CAServer.Grains/Grain/Notify/NotifyGrainDto.cs +++ b/src/CAServer.Grains/Grain/Notify/NotifyGrainDto.cs @@ -6,11 +6,12 @@ namespace CAServer.Grains.Grain.Notify; public class NotifyGrainDto : NotifyRulesBase { public Guid Id { get; set; } - + public int NotifyId { get; set; } public string Title { get; set; } public string Content { get; set; } public string TargetVersion { get; set; } public string DownloadUrl { get; set; } + public StyleType StyleType { get; set; } public DateTime ReleaseTime { get; set; } public bool IsForceUpdate { get; set; } } \ No newline at end of file diff --git a/src/CAServer.Grains/Grain/SampleGrain.cs b/src/CAServer.Grains/Grain/SampleGrain.cs deleted file mode 100644 index 961195d19..000000000 --- a/src/CAServer.Grains/Grain/SampleGrain.cs +++ /dev/null @@ -1,47 +0,0 @@ -using CAServer.Grains.State; -using CAServer.Sample; -using Orleans.Providers; -using Orleans; -using Volo.Abp.ObjectMapping; - -namespace CAServer.Grains.Grain; - -[StorageProvider(ProviderName = "Default")] -public class SampleGrain : Grain, ISampleGrain -{ - private IObjectMapper _objectMapper; - - public SampleGrain(IObjectMapper objectMapper) - { - _objectMapper = objectMapper; - } - - public override Task OnActivateAsync() - { - ReadStateAsync(); - return base.OnActivateAsync(); - } - - public override Task OnDeactivateAsync() - { - WriteStateAsync(); - return base.OnDeactivateAsync(); - } - - public async Task SayHello(string from, string to) - { - this.State.From = from; - this.State.To = to; - string message = $"{from} say hello to {to}"; - this.State.Message = message; - - await WriteStateAsync(); - - return message; - } - - public Task GetLastMessage() - { - return Task.FromResult(_objectMapper.Map(State)); - } -} \ No newline at end of file diff --git a/src/CAServer.Grains/State/Notify/NotifyState.cs b/src/CAServer.Grains/State/Notify/NotifyState.cs index 5e48730a8..fff06f0a8 100644 --- a/src/CAServer.Grains/State/Notify/NotifyState.cs +++ b/src/CAServer.Grains/State/Notify/NotifyState.cs @@ -6,5 +6,6 @@ public class NotifyState : NotifyBase { public Guid Id { get; set; } public Guid RulesId { get; set; } + public int NotifyId { get; set; } public bool IsDeleted { get; set; } } \ No newline at end of file diff --git a/src/CAServer.Grains/appsettings.json b/src/CAServer.Grains/appsettings.json index 02ab08b5c..ce32fc5e5 100644 --- a/src/CAServer.Grains/appsettings.json +++ b/src/CAServer.Grains/appsettings.json @@ -1,5 +1,8 @@ { "GraphQL": { "Configuration": "http://127.0.0.1:8083/Indexer_DApp/PortKeyIndexerCASchema/graphql" + }, + "SignatureServer": { + "BaseUrl": "http://localhost:5000/api/app/signature" } } \ No newline at end of file diff --git a/src/CAServer.HttpApi.Host/CAServer.HttpApi.Host.csproj b/src/CAServer.HttpApi.Host/CAServer.HttpApi.Host.csproj index 6e49b51fa..cefc10de7 100644 --- a/src/CAServer.HttpApi.Host/CAServer.HttpApi.Host.csproj +++ b/src/CAServer.HttpApi.Host/CAServer.HttpApi.Host.csproj @@ -37,6 +37,7 @@ + diff --git a/src/CAServer.HttpApi.Host/CAServerHttpApiHostModule.cs b/src/CAServer.HttpApi.Host/CAServerHttpApiHostModule.cs index e94aebc60..e9185bd1b 100644 --- a/src/CAServer.HttpApi.Host/CAServerHttpApiHostModule.cs +++ b/src/CAServer.HttpApi.Host/CAServerHttpApiHostModule.cs @@ -7,6 +7,7 @@ using CAServer.MultiTenancy; using CAServer.Options; using CAServer.Redis; +using CAServer.Signature; using GraphQL.Client.Abstractions; using GraphQL.Client.Http; using GraphQL.Client.Serializer.Newtonsoft; @@ -310,7 +311,7 @@ public override void OnApplicationInitialization(ApplicationInitializationContex app.UseAuthorization(); - if (env.IsDevelopment()) + //if (env.IsDevelopment()) { app.UseSwagger(); app.UseAbpSwaggerUI(options => @@ -322,7 +323,7 @@ public override void OnApplicationInitialization(ApplicationInitializationContex // options.OAuthScopes("CAServer"); }); } - + app.UseAuditing(); app.UseAbpSerilogEnrichers(); app.UseUnitOfWork(); diff --git a/src/CAServer.HttpApi.Host/appsettings.Development.json b/src/CAServer.HttpApi.Host/appsettings.Development.json deleted file mode 100644 index 2c63c0851..000000000 --- a/src/CAServer.HttpApi.Host/appsettings.Development.json +++ /dev/null @@ -1,2 +0,0 @@ -{ -} diff --git a/src/CAServer.HttpApi.Host/appsettings.json b/src/CAServer.HttpApi.Host/appsettings.json index b0b38dc7d..e104a30d0 100644 --- a/src/CAServer.HttpApi.Host/appsettings.json +++ b/src/CAServer.HttpApi.Host/appsettings.json @@ -175,5 +175,11 @@ "ExpireTime": 24, "ClaimTokenAmount": 10000000000, "GetClaimTokenLimit": 1 + }, + "SignatureServer": { + "BaseUrl": "http://localhost:5000/api/app/signature" + }, + "ContractOptions": { + "CommonPrivateKeyForCallTx": "" } } diff --git a/src/CAServer.HttpApi.Host/phone.json b/src/CAServer.HttpApi.Host/phone.json index b0a099856..205fb795c 100644 --- a/src/CAServer.HttpApi.Host/phone.json +++ b/src/CAServer.HttpApi.Host/phone.json @@ -1,5 +1,10 @@ { "PhoneInfoOptions":{ + "Default" : { + "Country": "Singapore", + "Code": "65", + "Iso": "SG" + }, "PhoneInfo": [ { "Country": "China", diff --git a/src/CAServer.HttpApi/CAServer.HttpApi.csproj b/src/CAServer.HttpApi/CAServer.HttpApi.csproj index 6d69a1756..d447859bd 100644 --- a/src/CAServer.HttpApi/CAServer.HttpApi.csproj +++ b/src/CAServer.HttpApi/CAServer.HttpApi.csproj @@ -17,7 +17,6 @@ - diff --git a/src/CAServer.HttpApi/Controllers/AppleAuthController.cs b/src/CAServer.HttpApi/Controllers/AppleAuthController.cs index 5a274d49b..e44b96b84 100644 --- a/src/CAServer.HttpApi/Controllers/AppleAuthController.cs +++ b/src/CAServer.HttpApi/Controllers/AppleAuthController.cs @@ -36,4 +36,11 @@ public async Task BingoReceiveAsync([FromForm] AppleAuthDto apple await _appleAuthAppService.ReceiveAsync(appleAuthDto); return Redirect($"{_appleAuthOptions.BingoRedirectUrl}?id_token={appleAuthDto.Id_token}"); } + + [HttpPost("unifyReceive")] + public async Task UnifyReceiveAsync([FromForm] AppleAuthDto appleAuthDto) + { + await _appleAuthAppService.ReceiveAsync(appleAuthDto); + return Redirect($"{_appleAuthOptions.UnifyRedirectUrl}?id_token={appleAuthDto.Id_token}"); + } } \ No newline at end of file diff --git a/src/CAServer.HttpApi/Controllers/CAVerifierController.cs b/src/CAServer.HttpApi/Controllers/CAVerifierController.cs index c93d12350..fb1cb352d 100644 --- a/src/CAServer.HttpApi/Controllers/CAVerifierController.cs +++ b/src/CAServer.HttpApi/Controllers/CAVerifierController.cs @@ -5,11 +5,13 @@ using CAServer.Switch; using CAServer.Verifier; using CAServer.Verifier.Dtos; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using Volo.Abp; using Volo.Abp.ObjectMapping; +using Volo.Abp.Users; namespace CAServer.Controllers; @@ -26,15 +28,18 @@ public class CAVerifierController : CAServerController private readonly IGoogleAppService _googleAppService; private const string GoogleRecaptcha = "GoogleRecaptcha"; private const string XForwardedFor = "X-Forwarded-For"; + private readonly ICurrentUser _currentUser; public CAVerifierController(IVerifierAppService verifierAppService, IObjectMapper objectMapper, - ILogger logger, ISwitchAppService switchAppService, IGoogleAppService googleAppService) + ILogger logger, ISwitchAppService switchAppService, IGoogleAppService googleAppService, + ICurrentUser currentUser) { _verifierAppService = verifierAppService; _objectMapper = objectMapper; _logger = logger; _switchAppService = switchAppService; _googleAppService = googleAppService; + _currentUser = currentUser; } [HttpPost("sendVerificationRequest")] @@ -51,9 +56,41 @@ public async Task SendVerificationRequest([FromHeader] s return null; } + var type = verifierServerInput.OperationType; + return type switch + { + OperationType.Register => await RegisterSendVerificationRequestAsync(recaptchatoken, + sendVerificationRequestInput), + OperationType.Recovery => await RecoverySendVerificationRequestAsync(recaptchatoken, + sendVerificationRequestInput), + OperationType.GuardianOperations => await GuardianOperationsSendVerificationRequestAsync(recaptchatoken, + sendVerificationRequestInput), + _ => throw new ArgumentOutOfRangeException() + }; + } + + private async Task GuardianOperationsSendVerificationRequestAsync(string recaptchaToken, + SendVerificationRequestInput sendVerificationRequestInput) + { + var isAuthenticated = _currentUser.IsAuthenticated; + if (!isAuthenticated) + { + return null; + } + return await GoogleRecaptchaAndSendVerifyCodeAsync(recaptchaToken, sendVerificationRequestInput); + } + + private async Task GoogleRecaptchaAndSendVerifyCodeAsync(string recaptchaToken, + SendVerificationRequestInput sendVerificationRequestInput) + { + var userIpAddress = UserIpAddress(HttpContext); + if (string.IsNullOrWhiteSpace(userIpAddress)) + { + return null; + } + _logger.LogDebug("userIp is {userIp}", userIpAddress); var switchStatus = _switchAppService.GetSwitchStatus(GoogleRecaptcha); - var googleRecaptchaOpen = await _googleAppService.IsGoogleRecaptchaOpenAsync(userIpAddress); await _verifierAppService.CountVerifyCodeInterfaceRequestAsync(userIpAddress); if (!switchStatus.IsOpen || !googleRecaptchaOpen) @@ -64,7 +101,43 @@ public async Task SendVerificationRequest([FromHeader] s var googleRecaptchaTokenSuccess = false; try { - googleRecaptchaTokenSuccess = await _googleAppService.IsGoogleRecaptchaTokenValidAsync(recaptchatoken); + googleRecaptchaTokenSuccess = await _googleAppService.IsGoogleRecaptchaTokenValidAsync(recaptchaToken); + } + catch (Exception e) + { + _logger.LogError("GoogleRecaptchaTokenAsync error: {errorMessage}", e.Message); + return null; + } + + if (googleRecaptchaTokenSuccess) + { + return await _verifierAppService.SendVerificationRequestAsync(sendVerificationRequestInput); + } + + return null; + } + + private async Task RecoverySendVerificationRequestAsync(string recaptchaToken, + SendVerificationRequestInput sendVerificationRequestInput) + { + //check guardian isExists; + var guardianExists = + await _verifierAppService.GuardianExistsAsync(sendVerificationRequestInput.GuardianIdentifier); + if (!guardianExists) + { + return null; + } + + return await GoogleRecaptchaAndSendVerifyCodeAsync(recaptchaToken, sendVerificationRequestInput); + } + + private async Task RegisterSendVerificationRequestAsync(string recaptchaToken, + SendVerificationRequestInput sendVerificationRequestInput) + { + var googleRecaptchaTokenSuccess = false; + try + { + googleRecaptchaTokenSuccess = await _googleAppService.IsGoogleRecaptchaTokenValidAsync(recaptchaToken); } catch (Exception e) { diff --git a/src/CAServer.HttpApi/Controllers/ClaimTokenController.cs b/src/CAServer.HttpApi/Controllers/ClaimTokenController.cs index 3a2a9871f..712e66c8e 100644 --- a/src/CAServer.HttpApi/Controllers/ClaimTokenController.cs +++ b/src/CAServer.HttpApi/Controllers/ClaimTokenController.cs @@ -11,7 +11,7 @@ namespace CAServer.Controllers; [RemoteService] [Area("app")] [ControllerName("ClaimToken")] -[Route("api/app/claimToken")] +[Route("api/app/claim_token")] public class ClaimTokenController : CAServerController { private readonly IClaimTokenAppService _claimTokenAppService; diff --git a/src/CAServer.HttpApi/Controllers/NotifyController.cs b/src/CAServer.HttpApi/Controllers/NotifyController.cs index 7ed72e3c0..e6178d376 100644 --- a/src/CAServer.HttpApi/Controllers/NotifyController.cs +++ b/src/CAServer.HttpApi/Controllers/NotifyController.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Threading.Tasks; using CAServer.Notify; using CAServer.Notify.Dtos; @@ -28,6 +29,13 @@ public async Task CreateAsync(CreateNotifyDto notifyDto) return await _notifyAppService.CreateAsync(notifyDto); } + [HttpPost("createFromCms")] + [Authorize(Roles = "admin")] + public async Task> CreateFromCmsAsync([FromForm] string version) + { + return await _notifyAppService.CreateFromCmsAsync(version); + } + [HttpPut("{id}")] [Authorize(Roles = "admin")] public async Task UpdateAsync(Guid id, UpdateNotifyDto notifyDto) @@ -35,6 +43,13 @@ public async Task UpdateAsync(Guid id, UpdateNotifyDto notifyDt return await _notifyAppService.UpdateAsync(id, notifyDto); } + [HttpPut("updateFromCms/{id}")] + [Authorize(Roles = "admin")] + public async Task UpdateFromCmsAsync(Guid id) + { + return await _notifyAppService.UpdateFromCmsAsync(id); + } + [HttpDelete("{id}")] [Authorize(Roles = "admin")] public async Task DeleteAsync(Guid id) diff --git a/src/CAServer.HttpApi/Controllers/PhoneControllers.cs b/src/CAServer.HttpApi/Controllers/PhoneControllers.cs index efb80bc44..5d01d157e 100644 --- a/src/CAServer.HttpApi/Controllers/PhoneControllers.cs +++ b/src/CAServer.HttpApi/Controllers/PhoneControllers.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using System.Threading.Tasks; using CAServer.Phone; using CAServer.Phone.Dtos; @@ -19,8 +18,8 @@ public PhoneController(IPhoneAppService phoneAppService) } [HttpGet("info")] - public Task PhoneInfoAsyncs() + public Task PhoneInfoAsync() { - return _phoneAppService.GetPhoneInfo(); + return _phoneAppService.GetPhoneInfoAsync(); } } diff --git a/src/CAServer.HttpApi/Controllers/SampleController.cs b/src/CAServer.HttpApi/Controllers/SampleController.cs deleted file mode 100644 index 31901a98c..000000000 --- a/src/CAServer.HttpApi/Controllers/SampleController.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Threading.Tasks; -using CAServer.Sample; -using Microsoft.AspNetCore.Mvc; -using Volo.Abp; -using Volo.Abp.AspNetCore.Mvc; - -namespace CAServer.Controllers; - -[RemoteService] -[ControllerName("Sample")] -[Route("api/app/sample")] -public class SampleController : CAServerController -{ - private readonly ISampleAppService _sampleAppService; - - public SampleController(ISampleAppService sampleAppService) - { - _sampleAppService = sampleAppService; - } - - [HttpGet] - [Route("hello")] - //[Authorize] - public virtual Task Hello(string from, string to) - { - return _sampleAppService.Hello(from, to); - } -} \ No newline at end of file diff --git a/src/CAServer.HttpApi/Controllers/UserActivityController.cs b/src/CAServer.HttpApi/Controllers/UserActivityController.cs index a80f2e2af..44d820df7 100644 --- a/src/CAServer.HttpApi/Controllers/UserActivityController.cs +++ b/src/CAServer.HttpApi/Controllers/UserActivityController.cs @@ -22,6 +22,12 @@ public UserActivityController(IUserActivityAppService userActivityAppService) _userActivityAppService = userActivityAppService; } + [HttpPost("transactions")] + public async Task GetTransactionsAsync(GetTwoCaTransactionRequestDto requestDto) + { + return await _userActivityAppService.GetTwoCaTransactionsAsync(requestDto); + } + [HttpPost("activities")] public async Task GetActivitiesAsync(GetActivitiesRequestDto requestDto) { @@ -33,4 +39,4 @@ public async Task GetActivityAsync(GetActivityRequestDto request { return await _userActivityAppService.GetActivityAsync(requestDto); } -} \ No newline at end of file +} \ No newline at end of file diff --git a/src/CAServer.HttpApi/Models/BookCreateInput.cs b/src/CAServer.HttpApi/Models/BookCreateInput.cs deleted file mode 100644 index 9fb8aab32..000000000 --- a/src/CAServer.HttpApi/Models/BookCreateInput.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace CAServer.Models; - -public class BookCreateInput -{ - public string Name { get; set; } - public int Amount { get; set; } -} \ No newline at end of file diff --git a/src/CAServer.Redis/RedisCacheProvider.cs b/src/CAServer.Redis/RedisCacheProvider.cs index 6cc8325ba..bed40a2bb 100644 --- a/src/CAServer.Redis/RedisCacheProvider.cs +++ b/src/CAServer.Redis/RedisCacheProvider.cs @@ -66,12 +66,14 @@ public async Task> BatchGet(List keys) return realAns; } - public async Task Increase(string key, int increase,TimeSpan? expire) + public async Task Increase(string key, int increase, TimeSpan? expire) { - var count = await _database.StringIncrementAsync(key, increase); - _database.KeyExpire(key, expire); - return count; - + var count = await _database.StringIncrementAsync(key, increase); + if (expire != null) + { + _database.KeyExpire(key, expire); + } + return count; } } \ No newline at end of file diff --git a/src/CAServer.Signature.HttpApi.Host/CAServer.Signature.HttpApi.Host.csproj b/src/CAServer.Signature.HttpApi.Host/CAServer.Signature.HttpApi.Host.csproj new file mode 100644 index 000000000..84255a7b9 --- /dev/null +++ b/src/CAServer.Signature.HttpApi.Host/CAServer.Signature.HttpApi.Host.csproj @@ -0,0 +1,36 @@ + + + + + + net7.0 + SignatureServer + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/CAServer.Signature.HttpApi.Host/CAServerSignatureHttpApiHostModule.cs b/src/CAServer.Signature.HttpApi.Host/CAServerSignatureHttpApiHostModule.cs new file mode 100644 index 000000000..33cc047a3 --- /dev/null +++ b/src/CAServer.Signature.HttpApi.Host/CAServerSignatureHttpApiHostModule.cs @@ -0,0 +1,166 @@ +using System; +using System.Linq; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Cors; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.OpenApi.Models; +using Volo.Abp; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Serilog; +using Volo.Abp.Autofac; +using Volo.Abp.Localization; +using Volo.Abp.Modularity; +using Volo.Abp.Swashbuckle; + +namespace CAServer.Signature; + +[DependsOn( + typeof(CAServerSignatureHttpApiModule), + typeof(AbpAutofacModule), + typeof(AbpAspNetCoreSerilogModule), + typeof(AbpSwashbuckleModule) +)] +public class SignatureServerHttpApiHostModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + var hostingEnvironment = context.Services.GetHostingEnvironment(); + var configuration = context.Services.GetConfiguration(); + ConfigureConventionalControllers(); + ConfigureLocalization(); + ConfigureCors(context, configuration); + ConfigureSwaggerServices(context, configuration); + } + + private void ConfigureConventionalControllers() + { + Configure(options => + { + options.ConventionalControllers.Create(typeof(CAServerSignatureHttpApiModule).Assembly); + }); + } + + + private void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration) + { + context.Services.AddCors(options => + { + options.AddDefaultPolicy(builder => + { + builder + .WithOrigins( + configuration["App:CorsOrigins"] + .Split(",", StringSplitOptions.RemoveEmptyEntries) + .Select(o => o.RemovePostFix("/")) + .ToArray() + ) + .WithAbpExposedHeaders() + .SetIsOriginAllowedToAllowWildcardSubdomains() + .AllowAnyHeader() + .AllowAnyMethod() + .AllowCredentials(); + }); + }); + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + var app = context.GetApplicationBuilder(); + var env = context.GetEnvironment(); + + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + else + { + app.UseHsts(); + } + + app.UseHttpsRedirection(); + app.UseCorrelationId(); + app.UseStaticFiles(); + app.UseRouting(); + app.UseCors(); + app.UseAuthentication(); + + app.UseAbpRequestLocalization(); + app.UseAuthorization(); + + if (env.IsDevelopment()) + { + app.UseSwagger(); + app.UseAbpSwaggerUI(options => + { + options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support APP API"); + + // var configuration = context.GetConfiguration(); + // options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]); + // options.OAuthScopes("SignatureServer"); + }); + } + + app.UseAuditing(); + app.UseAbpSerilogEnrichers(); + app.UseConfiguredEndpoints(); + } + + private void ConfigureLocalization() + { + Configure(options => + { + options.Languages.Add(new LanguageInfo("ar", "ar", "العربية")); + options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština")); + options.Languages.Add(new LanguageInfo("en", "en", "English")); + options.Languages.Add(new LanguageInfo("en-GB", "en-GB", "English (UK)")); + options.Languages.Add(new LanguageInfo("fi", "fi", "Finnish")); + options.Languages.Add(new LanguageInfo("fr", "fr", "Français")); + options.Languages.Add(new LanguageInfo("hi", "hi", "Hindi", "in")); + options.Languages.Add(new LanguageInfo("is", "is", "Icelandic", "is")); + options.Languages.Add(new LanguageInfo("it", "it", "Italiano", "it")); + options.Languages.Add(new LanguageInfo("ro-RO", "ro-RO", "Română")); + options.Languages.Add(new LanguageInfo("hu", "hu", "Magyar")); + options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português")); + options.Languages.Add(new LanguageInfo("ru", "ru", "Русский")); + options.Languages.Add(new LanguageInfo("sk", "sk", "Slovak")); + options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe")); + options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文")); + options.Languages.Add(new LanguageInfo("zh-Hant", "zh-Hant", "繁體中文")); + options.Languages.Add(new LanguageInfo("de-DE", "de-DE", "Deutsch", "de")); + options.Languages.Add(new LanguageInfo("es", "es", "Español", "es")); + options.Languages.Add(new LanguageInfo("el", "el", "Ελληνικά")); + }); + } + + private static void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration) + { + context.Services.AddAbpSwaggerGen(options => + { + options.SwaggerDoc("v1", new OpenApiInfo { Title = "SignServer API", Version = "v1" }); + options.DocInclusionPredicate((docName, description) => true); + options.CustomSchemaIds(type => type.FullName); + options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme() + { + Name = "Authorization", + Scheme = "bearer", + Description = "Specify the authorization token.", + In = ParameterLocation.Header, + Type = SecuritySchemeType.Http, + }); + + options.AddSecurityRequirement(new OpenApiSecurityRequirement() + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } + }, + new string[] { } + } + }); + } + ); + } +} \ No newline at end of file diff --git a/src/CAServer.Signature.HttpApi.Host/Controllers/HomeController.cs b/src/CAServer.Signature.HttpApi.Host/Controllers/HomeController.cs new file mode 100644 index 000000000..3ceb7babf --- /dev/null +++ b/src/CAServer.Signature.HttpApi.Host/Controllers/HomeController.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; + +namespace SignatureServer.Controllers; + +public class HomeController : AbpController +{ + public ActionResult Index() + { + return Redirect("~/swagger"); + } +} diff --git a/src/CAServer.Signature.HttpApi.Host/Program.cs b/src/CAServer.Signature.HttpApi.Host/Program.cs new file mode 100644 index 000000000..08908f13b --- /dev/null +++ b/src/CAServer.Signature.HttpApi.Host/Program.cs @@ -0,0 +1,62 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Serilog; +using Serilog.Events; + +namespace CAServer.Signature; + +public class Program +{ + public async static Task Main(string[] args) + { + var configuration = new ConfigurationBuilder() + .AddJsonFile("appsettings.json") + .Build(); + Log.Logger = new LoggerConfiguration() +#if DEBUG + .MinimumLevel.Debug() +#else + .MinimumLevel.Information() +#endif + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .Enrich.FromLogContext() + .ReadFrom.Configuration(configuration) + +#if DEBUG + .WriteTo.Async(c => c.Console()) +#endif + .CreateLogger(); + + try + { + Log.Information("Starting web host."); + var builder = WebApplication.CreateBuilder(args); + builder.Host.AddAppSettingsSecretsJson() + .UseAutofac() + .UseSerilog(); + await builder.AddApplicationAsync(); + var app = builder.Build(); + await app.InitializeApplicationAsync(); + await app.RunAsync(); + return 0; + } + catch (Exception ex) + { + if (ex is HostAbortedException) + { + throw; + } + + Log.Fatal(ex, "Host terminated unexpectedly!"); + return 1; + } + finally + { + Log.CloseAndFlush(); + } + } +} \ No newline at end of file diff --git a/src/CAServer.Signature.HttpApi.Host/appsettings.json b/src/CAServer.Signature.HttpApi.Host/appsettings.json new file mode 100644 index 000000000..9b36ebb47 --- /dev/null +++ b/src/CAServer.Signature.HttpApi.Host/appsettings.json @@ -0,0 +1,22 @@ +{ + "App": { + "CorsOrigins": "https://*.SignatureServer.com,http://localhost:4200" + }, + "AuthServer": { + "Authority": "https://localhost:44323/", + "RequireHttpsMetadata": "false", + "SwaggerClientId": "SignatureServer_Swagger", + "SwaggerClientSecret": "*" + }, + "Kestrel": { + "EndPoints": { + "Http": { + "Url": "http://*:18080" + } + } + }, + "KeyPairInfo": { + "PrivateKeyDictionary":{ + } + } +} diff --git a/src/CAServer.AuthServer/appsettings.Development.json b/src/CAServer.Signature.HttpApi.Host/appsettings.secrets.json similarity index 50% rename from src/CAServer.AuthServer/appsettings.Development.json rename to src/CAServer.Signature.HttpApi.Host/appsettings.secrets.json index 2c63c0851..7a73a41bf 100644 --- a/src/CAServer.AuthServer/appsettings.Development.json +++ b/src/CAServer.Signature.HttpApi.Host/appsettings.secrets.json @@ -1,2 +1,2 @@ { -} +} \ No newline at end of file diff --git a/src/CAServer.Signature.HttpApi/CAServer.Signature.HttpApi.csproj b/src/CAServer.Signature.HttpApi/CAServer.Signature.HttpApi.csproj new file mode 100644 index 000000000..49f937eb3 --- /dev/null +++ b/src/CAServer.Signature.HttpApi/CAServer.Signature.HttpApi.csproj @@ -0,0 +1,18 @@ + + + + + + net7.0 + enable + SignatureServer + + + + + + + + + + diff --git a/src/CAServer.Signature.HttpApi/CAServerSignatureController.cs b/src/CAServer.Signature.HttpApi/CAServerSignatureController.cs new file mode 100644 index 000000000..7bc501c85 --- /dev/null +++ b/src/CAServer.Signature.HttpApi/CAServerSignatureController.cs @@ -0,0 +1,11 @@ +using Volo.Abp.AspNetCore.Mvc; + +namespace CAServer.Signature; + +public abstract class CAServerSignatureController : AbpControllerBase +{ + protected CAServerSignatureController() + { + LocalizationResource = typeof(CAServerSignatureResource); + } +} \ No newline at end of file diff --git a/src/CAServer.Signature.HttpApi/CAServerSignatureHttpApiModule.cs b/src/CAServer.Signature.HttpApi/CAServerSignatureHttpApiModule.cs new file mode 100644 index 000000000..3ee649dde --- /dev/null +++ b/src/CAServer.Signature.HttpApi/CAServerSignatureHttpApiModule.cs @@ -0,0 +1,18 @@ +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.Modularity; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AutoMapper; + +namespace CAServer.Signature; + +[DependsOn( + typeof(AbpAspNetCoreMvcModule))] +public class CAServerSignatureHttpApiModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => { options.AddMaps(); }); + var configuration = context.Services.GetConfiguration(); + Configure(configuration.GetSection("KeyPairInfo")); + } +} \ No newline at end of file diff --git a/src/CAServer.Signature.HttpApi/CAServerSignatureResource.cs b/src/CAServer.Signature.HttpApi/CAServerSignatureResource.cs new file mode 100644 index 000000000..59cc26274 --- /dev/null +++ b/src/CAServer.Signature.HttpApi/CAServerSignatureResource.cs @@ -0,0 +1,8 @@ +using Volo.Abp.Localization; + +namespace CAServer.Signature; + +[LocalizationResourceName("CAServer")] +public class CAServerSignatureResource +{ +} \ No newline at end of file diff --git a/src/CAServer.Signature.HttpApi/Dtos/SignatureDto.cs b/src/CAServer.Signature.HttpApi/Dtos/SignatureDto.cs new file mode 100644 index 000000000..71714cfb4 --- /dev/null +++ b/src/CAServer.Signature.HttpApi/Dtos/SignatureDto.cs @@ -0,0 +1,14 @@ +using System.ComponentModel.DataAnnotations; + +namespace CAServer.Signature.Dtos; + +public class SignResponseDto +{ + public string Signature { get; set; } +} + +public class SendSignatureDto +{ + [Required] public string PublicKey { get; set; } + [Required] public string HexMsg { get; set; } +} \ No newline at end of file diff --git a/src/CAServer.Signature.HttpApi/KeyPairInfoOptions.cs b/src/CAServer.Signature.HttpApi/KeyPairInfoOptions.cs new file mode 100644 index 000000000..d6baa1a3f --- /dev/null +++ b/src/CAServer.Signature.HttpApi/KeyPairInfoOptions.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace CAServer.Signature; + +public class KeyPairInfoOptions +{ + public Dictionary PrivateKeyDictionary { get; set; } +} diff --git a/src/CAServer.Signature.HttpApi/SignatureController.cs b/src/CAServer.Signature.HttpApi/SignatureController.cs new file mode 100644 index 000000000..ee21fd70d --- /dev/null +++ b/src/CAServer.Signature.HttpApi/SignatureController.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using AElf; +using AElf.Cryptography; +using CAServer.Signature.Dtos; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Volo.Abp; + +namespace CAServer.Signature; + +[RemoteService] +[Route("api/app/signature")] +public class SignatureController : CAServerSignatureController +{ + private readonly ILogger _logger; + private readonly KeyPairInfoOptions _keyPairInfoOptions; + + + public SignatureController(ILogger logger, + IOptionsSnapshot signatureOptions) + { + _logger = logger; + _keyPairInfoOptions = signatureOptions.Value; + } + + [HttpPost] + public async Task SendSignAsync( + SendSignatureDto input) + { + try + { + var privateKey = GetPrivateKeyByPublicKey(input.PublicKey); + var msgHashBytes = ByteStringHelper.FromHexString(input.HexMsg); + var recoverableInfo = CryptoHelper.SignWithPrivateKey(privateKey, msgHashBytes.ToByteArray()); + return new SignResponseDto + { + Signature = recoverableInfo.ToHex(), + }; + } + catch (Exception e) + { + _logger.LogError("Signature failed, error msg is {errorMsg}", e); + throw new UserFriendlyException(e.Message); + } + } + + private byte[] GetPrivateKeyByPublicKey(string publicKey) + { + if (_keyPairInfoOptions.PrivateKeyDictionary.TryGetValue(publicKey, out string _)) + { + return Encoding.UTF8.GetBytes(_keyPairInfoOptions.PrivateKeyDictionary[publicKey]); + } + + _logger.LogError("Publish key {publishKey} not exist!", publicKey); + throw new KeyNotFoundException("Publish key not exist!"); + } +} \ No newline at end of file diff --git a/src/CAServer.Signature/CAServer.Signature.csproj b/src/CAServer.Signature/CAServer.Signature.csproj new file mode 100644 index 000000000..f53fc25b7 --- /dev/null +++ b/src/CAServer.Signature/CAServer.Signature.csproj @@ -0,0 +1,18 @@ + + + + net7.0 + enable + enable + + false + + + + + + + + + + diff --git a/src/CAServer.Signature/CAServerSignatureModule.cs b/src/CAServer.Signature/CAServerSignatureModule.cs new file mode 100644 index 000000000..45b1e176a --- /dev/null +++ b/src/CAServer.Signature/CAServerSignatureModule.cs @@ -0,0 +1,13 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AutoMapper; +using Volo.Abp.Modularity; + +namespace CAServer.Signature; + +public class CAServerSignatureModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(context.Services.GetConfiguration().GetSection("SignatureServer")); + } +} \ No newline at end of file diff --git a/src/CAServer.Signature/SignatureProvider.cs b/src/CAServer.Signature/SignatureProvider.cs new file mode 100644 index 000000000..e2db79a92 --- /dev/null +++ b/src/CAServer.Signature/SignatureProvider.cs @@ -0,0 +1,58 @@ +using System.Net; +using System.Text; +using Microsoft.Extensions.Options; +using Newtonsoft.Json; +using Volo.Abp.DependencyInjection; + +namespace CAServer.Signature; + +public interface ISignatureProvider +{ + Task SignTxMsg(string publicKey, string hexMsg); +} + +public class SignatureProvider : ISignatureProvider, ISingletonDependency +{ + private readonly SignatureServerOptions _signatureServerOptions; + private readonly IHttpClientFactory _httpClientFactory; + + public SignatureProvider(IOptionsSnapshot signatureOptions, + IHttpClientFactory httpClientFactory) + { + _httpClientFactory = httpClientFactory; + _signatureServerOptions = signatureOptions.Value; + } + + public async Task SignTxMsg(string publicKey, string hexMsg) + { + var signatureSend = new SendSignatureDto + { + PublicKey = publicKey, + HexMsg = hexMsg, + }; + var httpResult = await _httpClientFactory.CreateClient().SendAsync(new HttpRequestMessage() + { + Method = HttpMethod.Post, + RequestUri = new Uri(_signatureServerOptions.BaseUrl), + Content = new StringContent(JsonConvert.SerializeObject(signatureSend), Encoding.UTF8, "application/json") + }); + if (httpResult.StatusCode == HttpStatusCode.OK) + { + return JsonConvert.DeserializeObject(await httpResult.Content.ReadAsStringAsync()) + .Signature; + } + + return ""; + } +} + +public class SendSignatureDto +{ + public string PublicKey { get; set; } + public string HexMsg { get; set; } +} + +public class SignResponseDto +{ + public string Signature { get; set; } +} \ No newline at end of file diff --git a/src/CAServer.Signature/SignatureServerOptions.cs b/src/CAServer.Signature/SignatureServerOptions.cs new file mode 100644 index 000000000..3ce19d212 --- /dev/null +++ b/src/CAServer.Signature/SignatureServerOptions.cs @@ -0,0 +1,6 @@ +namespace CAServer.Signature; + +public class SignatureServerOptions +{ + public string BaseUrl { get; set; } +} \ No newline at end of file diff --git a/test/CAServer.Application.Tests/AppleAuth/AppleAuthTest.cs b/test/CAServer.Application.Tests/AppleAuth/AppleAuthTest.cs index 5d6b7c1ba..7b3b03835 100644 --- a/test/CAServer.Application.Tests/AppleAuth/AppleAuthTest.cs +++ b/test/CAServer.Application.Tests/AppleAuth/AppleAuthTest.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Security.Principal; @@ -9,6 +10,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.IdentityModel.Tokens; using Moq; +using Newtonsoft.Json; using Shouldly; using Xunit; @@ -40,7 +42,15 @@ await _appleAuthAppService.ReceiveAsync(new AppleAuthDto() Code = "", Id_token = "eyJraWQiOiJXNldjT0tCIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiYXVkIjoiY29tLnBvcnRrZXkuZGlkIiwiZXhwIjoxNjc5NDcyMjg1LCJpYXQiOjE2NzkzODU4ODUsInN1YiI6IjAwMDMwMy5jZDgxN2I2OTgzMDc0ZDhjOGZiNzkyNDk2ZjI3N2ViYy4wMjU3IiwiY19oYXNoIjoicFBSeFFTSWNWY19BTEExSE9vdmJ5QSIsImVtYWlsIjoicHQ2eXhtOXptbUBwcml2YXRlcmVsYXkuYXBwbGVpZC5jb20iLCJlbWFpbF92ZXJpZmllZCI6InRydWUiLCJpc19wcml2YXRlX2VtYWlsIjoidHJ1ZSIsImF1dGhfdGltZSI6MTY3OTM4NTg4NSwibm9uY2Vfc3VwcG9ydGVkIjp0cnVlfQ.wXHXNbQVqvRxK_a6dq3WjBbJe_KaGsRVgSz_i3E01JyKW8rxGRRgDqjYNiTxB6iOqBMfvXfjtjgPl1N-de_Q4OflzG7gKK_17c-sY2uXUbOWVtAFI9WEXksYhZdV66eJDiUKJ8KE94S6NCT8UdkRqtxHtCnjuq82taYPbqcb-NO3Xcu23hfKsYQM_73yHJfnFd7jUYCoLHcxlVUeRGR7D7L3Yo9FdbocHZwei_x_jwb_7gYjTqGKg6rYt4MRT5ElSTj4xajXrRLZZzCFTVPjytvUsGvU038SEj4sIK6eoDAQy90ne2_XritzViMfKcWid6cdgh-Zz3PzfRx9LEyIPg", - User = string.Empty + User = JsonConvert.SerializeObject(new AppleExtraInfo + { + Name = new AppleNameInfo() + { + FirstName = "Li", + LastName = "Ning" + }, + Email = "test@qq.com" + }) }); } catch (Exception e) @@ -48,7 +58,39 @@ await _appleAuthAppService.ReceiveAsync(new AppleAuthDto() e.ShouldNotBeNull(); } } - //todo mock client and get token + + [Fact] + public async Task Receive_Invalid_Params_Test() + { + try + { + var options = new AppleAuthOptions + { + Audiences = new List(), + RedirectUrl = string.Empty, + BingoRedirectUrl = string.Empty, + UnifyRedirectUrl = string.Empty, + ExtensionConfig = new ExtensionConfig + { + PrivateKey = string.Empty, + TeamId = string.Empty, + ClientId = string.Empty, + KeyId = string.Empty + } + }; + + await _appleAuthAppService.ReceiveAsync(new AppleAuthDto() + { + Code = string.Empty, + Id_token = string.Empty + }); + } + catch (Exception e) + { + e.ShouldNotBeNull(); + e.Message.ShouldContain("valid"); + } + } private JwtSecurityTokenHandler GetJwtSecurityTokenHandlerMock() { @@ -72,7 +114,8 @@ private JwtSecurityTokenHandler GetJwtSecurityTokenHandlerMock() private static ClaimsPrincipal SelectClaimsPrincipal() { IPrincipal currentPrincipal = Thread.CurrentPrincipal; - return currentPrincipal is ClaimsPrincipal claimsPrincipal ? claimsPrincipal : (currentPrincipal == null ? (ClaimsPrincipal)null : new ClaimsPrincipal(currentPrincipal)); + return currentPrincipal is ClaimsPrincipal claimsPrincipal + ? claimsPrincipal + : (currentPrincipal == null ? (ClaimsPrincipal)null : new ClaimsPrincipal(currentPrincipal)); } - -} \ No newline at end of file +} \ No newline at end of file diff --git a/test/CAServer.Application.Tests/CAAccount/RecoveryServiceTests.cs b/test/CAServer.Application.Tests/CAAccount/RecoveryServiceTests.cs index 671d8d7d5..7220dc78c 100644 --- a/test/CAServer.Application.Tests/CAAccount/RecoveryServiceTests.cs +++ b/test/CAServer.Application.Tests/CAAccount/RecoveryServiceTests.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using CAServer.Account; using CAServer.CAAccount.Dtos; using CAServer.Dtos; using CAServer.Grain.Tests; @@ -44,7 +45,7 @@ public async Task RecoverRequestAsync_Test() var grain = _cluster.Client.GetGrain("Guardian-" + identifier); await grain.AddGuardianAsync(identifier, salt, identifierHash); - + var list = new List(); list.Add(new RecoveryGuardian { @@ -73,9 +74,8 @@ await _caAccountAppService.RecoverRequestAsync(new RecoveryRequestDto { Assert.True(e != null); } - } - + [Fact] public async Task RecoverRequestAsync_LoginGuardianIdentifier_Is_NullOrEmpty_Test() { @@ -85,6 +85,41 @@ public async Task RecoverRequestAsync_LoginGuardianIdentifier_Is_NullOrEmpty_Tes list.Add(new RecoveryGuardian { Type = GuardianIdentifierType.Email, + Identifier = "", + VerifierId = DefaultVerifierId, + VerificationDoc = DefaultVerificationDoc, + Signature = DefaultVerifierSignature + }); + + await _caAccountAppService.RecoverRequestAsync(new RecoveryRequestDto + { + LoginGuardianIdentifier = DefaultEmailAddress, + Manager = DefaultManager, + ExtraData = DefaultExtraData, + ChainId = DefaultChainId, + GuardiansApproved = list, + Context = new HubRequestContextDto + { + ClientId = DefaultClientId, + RequestId = DefaultRequestId + } + }); + } + catch (Exception ex) + { + Assert.True(ex is AbpValidationException); + } + } + + [Fact] + public async Task RecoverRequestAsync_Type_Is_Invalid_Test() + { + try + { + var list = new List(); + list.Add(new RecoveryGuardian + { + Type = (GuardianIdentifierType)10, Identifier = DefaultEmailAddress, VerifierId = DefaultVerifierId, VerificationDoc = DefaultVerificationDoc, @@ -110,5 +145,28 @@ await _caAccountAppService.RecoverRequestAsync(new RecoveryRequestDto Assert.True(ex is AbpValidationException); } } - + + [Fact] + public async Task RecoverRequestAsync_Dto_Test() + { + var guardian = new GuardianAccountInfoDto + { + Type = GuardianType.GUARDIAN_TYPE_OF_APPLE, + Value = string.Empty, + VerificationInfo = new VerificationInfoDto + { + Id = string.Empty, + Signature = string.Empty, + VerificationDoc = string.Empty + } + }; + + var message = new RecoveryCompletedMessageDto + { + RecoveryStatus = "PASS", + RecoveryMessage = string.Empty + }; + + + } } \ No newline at end of file diff --git a/test/CAServer.Application.Tests/CAAccount/RegisterServiceTests.cs b/test/CAServer.Application.Tests/CAAccount/RegisterServiceTests.cs index 44e814807..3248fb205 100644 --- a/test/CAServer.Application.Tests/CAAccount/RegisterServiceTests.cs +++ b/test/CAServer.Application.Tests/CAAccount/RegisterServiceTests.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using CAServer.Account; using CAServer.CAAccount.Dtos; using CAServer.Dtos; using CAServer.Grain.Tests; @@ -63,12 +64,69 @@ public async Task RegisterRequestAsync_Register_Success_Test() result.ShouldNotBeNull(); result.SessionId.ShouldNotBeEmpty(); } + + [Fact] + public async Task RegisterRequestAsync_Type_Not_Exist_Test() + { + try + { + var result = await _caAccountAppService.RegisterRequestAsync(new RegisterRequestDto + { + Type = (GuardianIdentifierType)8, + LoginGuardianIdentifier = DefaultEmailAddress, + Manager = DefaultManager, + ExtraData = DefaultExtraData, + ChainId = DefaultChainId, + VerifierId = DefaultVerifierId, + VerificationDoc = DefaultVerificationDoc, + Signature = DefaultVerifierSignature, + Context = new HubRequestContextDto + { + ClientId = DefaultClientId, + RequestId = DefaultRequestId + } + }); + } + catch (Exception e) + { + Assert.True(e is AbpValidationException); + } + } [Fact] public async Task RegisterRequestAsync_Register_LoginGuardianIdentifier_Is_NullOrEmpty_Test() { try { + var message = new AccountCompletedMessageBase + { + CaAddress = string.Empty, + CaHash = string.Empty + }; + + var header = new ActivityHeader + { + PubKey = string.Empty + }; + + var info = new GuardianAccountInfoDto + { + Type = GuardianType.GUARDIAN_TYPE_OF_APPLE, + Value = string.Empty, + VerificationInfo = new VerificationInfoDto + { + VerificationDoc = string.Empty, + Id = string.Empty, + Signature = string.Empty + } + }; + + var registerMessage = new RegisterCompletedMessageDto + { + RegisterStatus = "PASS", + RegisterMessage = string.Empty + }; + await _caAccountAppService.RegisterRequestAsync(new RegisterRequestDto { Type = GuardianIdentifierType.Email, diff --git a/test/CAServer.Application.Tests/CAActivity/UserActivityAppServiceTests.cs b/test/CAServer.Application.Tests/CAActivity/UserActivityAppServiceTests.cs index 95b8a22e5..aab644ea3 100644 --- a/test/CAServer.Application.Tests/CAActivity/UserActivityAppServiceTests.cs +++ b/test/CAServer.Application.Tests/CAActivity/UserActivityAppServiceTests.cs @@ -4,12 +4,14 @@ using System.Threading.Tasks; using CAServer.CAActivity.Dto; using CAServer.CAActivity.Dtos; +using CAServer.CAActivity.Provider; using CAServer.UserAssets; using Microsoft.Extensions.DependencyInjection; using Microsoft.VisualBasic; using NSubstitute; using Shouldly; using Volo.Abp.Users; +using Volo.Abp.Validation; using Xunit; namespace CAServer.CAActivity; @@ -24,17 +26,17 @@ public UserActivityAppServiceTests() { _userActivityAppService = GetRequiredService(); } - + protected override void AfterAddApplication(IServiceCollection services) { _currentUser = Substitute.For(); services.AddSingleton(_currentUser); services.AddSingleton(GetMockTokenAppService()); services.AddSingleton(GetUserContactProvider()); - services.AddSingleton(GetActivitiesIcon()); + services.AddSingleton(GetActivitiesIcon()); services.AddSingleton(GetMockActivityProvider()); } - + private void Login(Guid userId) { _currentUser.Id.Returns(userId); @@ -58,6 +60,135 @@ public async Task GetActivityTest() result.TransactionFees.First().Decimals.ShouldBe("8"); } + [Fact] + public async Task GetActivity_TransactionId_NullTest() + { + Login(Guid.NewGuid()); + + var token = new TokenDto + { + Symbol = string.Empty, + Address = string.Empty + }; + + try + { + var param = new GetActivityRequestDto + { + BlockHash = "blockHash", + TransactionId = "", + CaAddresses = new List { "c1pPpwKdVaYjEsS5VLMTkiXf76wxW9YY2qaDBPowpa8zX2oEo" } + }; + + await _userActivityAppService.GetActivityAsync(param); + } + catch (Exception e) + { + Assert.True(e is AbpValidationException); + } + } + + [Fact] + public async Task GetActivity_BlockHash_Null_Test() + { + Login(Guid.NewGuid()); + try + { + var param = new GetActivityRequestDto + { + BlockHash = "", + TransactionId = "TransactionId", + CaAddresses = new List { "c1pPpwKdVaYjEsS5VLMTkiXf76wxW9YY2qaDBPowpa8zX2oEo" } + }; + + await _userActivityAppService.GetActivityAsync(param); + } + catch (Exception e) + { + Assert.True(e is AbpValidationException); + } + } + + [Fact] + public async Task GetActivity_CaAddresses_Null_Test() + { + Login(Guid.NewGuid()); + try + { + var param = new GetActivityRequestDto + { + BlockHash = "BlockHash", + TransactionId = "TransactionId", + CaAddresses = null + }; + + await _userActivityAppService.GetActivityAsync(param); + } + catch (Exception e) + { + Assert.True(e is AbpValidationException); + } + } + + [Fact] + public async Task GetTwoCaTransactionsTest() + { + Login(Guid.NewGuid()); + var param = new GetTwoCaTransactionRequestDto + { + TargetAddressInfos = new List() + { + new CAAddressInfo() + { + ChainId = "test", + CaAddress = "CaAddress" + } + }, + CaAddressInfos = new List() + { + new CAAddressInfo() + { + ChainId = "test", + CaAddress = "CaAddress" + } + } + }; + + var result = await _userActivityAppService.GetTwoCaTransactionsAsync(param); + result.ShouldNotBeNull(); + result.TotalRecordCount.ShouldBe(1); + } + + [Fact] + public async Task GetTwoCaTransactions_Param_Empty_Test() + { + Login(Guid.NewGuid()); + var param = new GetTwoCaTransactionRequestDto(); + var info = new TransferInfo + { + FromAddress = string.Empty, + ToAddress = string.Empty, + ToChainId = string.Empty, + FromChainId = string.Empty, + FromCAAddress = string.Empty + }; + + try + { + var detail = new NftDetail + { + ImageUrl = string.Empty, + Alias = string.Empty, + NftId = string.Empty + }; + var result = await _userActivityAppService.GetTwoCaTransactionsAsync(param); + } + catch (Exception e) + { + e.Message.ShouldContain("must be non-empty"); + } + } + [Fact] public async Task GetActivitiesTest() { diff --git a/test/CAServer.Application.Tests/CAActivity/UserActivityAppServiceTestsMock.cs b/test/CAServer.Application.Tests/CAActivity/UserActivityAppServiceTestsMock.cs index a6848cd2c..7ebf3cfdb 100644 --- a/test/CAServer.Application.Tests/CAActivity/UserActivityAppServiceTestsMock.cs +++ b/test/CAServer.Application.Tests/CAActivity/UserActivityAppServiceTestsMock.cs @@ -96,6 +96,16 @@ private IActivityProvider GetMockActivityProvider() } }); + mockActivityProvider.Setup(m => m.GetTwoCaTransactionsAsync(It.IsAny>(), It.IsAny(), + It.IsAny>(), It.IsAny(), It.IsAny())).ReturnsAsync(new TransactionsDto() + { + TwoCaHolderTransaction = new CaHolderTransaction() + { + Data = new List(), + TotalRecordCount = 1 + } + }); + return mockActivityProvider.Object; } diff --git a/test/CAServer.Application.Tests/CAServer.Application.Tests.csproj b/test/CAServer.Application.Tests/CAServer.Application.Tests.csproj index eefc120c3..0235b58b0 100644 --- a/test/CAServer.Application.Tests/CAServer.Application.Tests.csproj +++ b/test/CAServer.Application.Tests/CAServer.Application.Tests.csproj @@ -27,6 +27,12 @@ + + + PreserveNewest + + + diff --git a/test/CAServer.Application.Tests/CAServerApplicationCollection.cs b/test/CAServer.Application.Tests/CAServerApplicationCollection.cs index 6337320e4..b5eaad331 100644 --- a/test/CAServer.Application.Tests/CAServerApplicationCollection.cs +++ b/test/CAServer.Application.Tests/CAServerApplicationCollection.cs @@ -4,7 +4,7 @@ namespace CAServer; [CollectionDefinition(CAServerTestConsts.CollectionDefinitionName)] -public class CAServerApplicationCollection : CAServerMongoDbCollectionFixtureBase +public class CAServerApplicationCollection { public const string CollectionDefinitionName = "CAServer collection"; } diff --git a/test/CAServer.Application.Tests/CAServerApplicationTestModule.cs b/test/CAServer.Application.Tests/CAServerApplicationTestModule.cs index 6e07c2e82..686f68557 100644 --- a/test/CAServer.Application.Tests/CAServerApplicationTestModule.cs +++ b/test/CAServer.Application.Tests/CAServerApplicationTestModule.cs @@ -1,10 +1,14 @@ +using System; using System.Collections.Generic; +using System.Configuration; using CAServer.Grain.Tests; using CAServer.Hub; using CAServer.IpInfo; using CAServer.Options; using CAServer.Search; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using NSubstitute.Extensions; using Volo.Abp.AutoMapper; using Volo.Abp.EventBus; using Volo.Abp.Modularity; @@ -21,6 +25,16 @@ public class CAServerApplicationTestModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { + // load config from [appsettings.Development.json] + var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Development"; + + var builder = new ConfigurationBuilder() + .SetBasePath(AppContext.BaseDirectory) + .AddJsonFile($"appsettings.{environmentName}.json", optional: true) + .AddEnvironmentVariables(); + + var configuration = builder.Build(); + // context.Services.AddSingleton(sp => sp.GetService().Cluster.Client); context.Services.AddSingleton(); context.Services.AddSingleton(); @@ -56,13 +70,15 @@ public override void ConfigureServices(ServiceConfigurationContext context) tokenList.Add(token1); tokenList.Add(token2); context.Services.Configure(o => { o.UserToken = tokenList; }); - context.Services.Configure(o => - { - o.ExpirationDays = 1; - o.BaseUrl = "http://127.0.0.1:6889"; - o.Language = "zh"; - o.AccessKey = ""; - }); + // context.Services.Configure(o => + // { + // o.ExpirationDays = 1; + // o.BaseUrl = "http://127.0.0.1:6889"; + // o.Language = "zh"; + // o.AccessKey = ""; + // }); + context.Services.Configure(o => o.ExpirationDays = 1); + // context.Services.AddTransient>(sp => // sp.GetService()); @@ -71,6 +87,27 @@ public override void ConfigureServices(ServiceConfigurationContext context) option.ChainInfos = new Dictionary { { "TEST", new CAServer.Grains.Grain.ApplicationHandler.ChainInfo() } }; }); + + context.Services.Configure(option => + { + option.ChainInfos = new Dictionary + { + { + "TEST", new CAServer.Options.ChainInfo() + { + BaseUrl = "http://127.0.0.1:6889", + ChainId = "TEST", + PrivateKey = "28d2520e2c480ef6f42c2803dcf4348807491237fd294c0f0a3d7c8f9ab8fb91" + } + } + }; + }); + + context.Services.Configure(option => + { + option.ChainId = "TEST"; + option.PublicKey = "28d2520e2c480ef6f42c2803dcf4348807491237fd294c0f0a3d7c8f9ab8fb91"; + }); base.ConfigureServices(context); } } \ No newline at end of file diff --git a/test/CAServer.Application.Tests/ClaimToken/ClaimTokenMockTests.cs b/test/CAServer.Application.Tests/ClaimToken/ClaimTokenMockTests.cs new file mode 100644 index 000000000..6137c5605 --- /dev/null +++ b/test/CAServer.Application.Tests/ClaimToken/ClaimTokenMockTests.cs @@ -0,0 +1,72 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using AElf; +using AElf.Client.Dto; +using AElf.Client.MultiToken; +using AElf.Contracts.MultiToken; +using CAServer.Cache; +using CAServer.ClaimToken.Dtos; +using CAServer.Common; +using CAServer.Hub; +using CAServer.Options; +using Microsoft.Extensions.Options; +using Moq; +using Portkey.Contracts.CA; +using GetBalanceOutput = AElf.Contracts.MultiToken.GetBalanceOutput; + +namespace CAServer.ClaimToken; + +public partial class ClaimTokenTests +{ + private ICacheProvider GetMockCacheProvider() + { + return new MockCacheProvider(); + } + + private IOptionsSnapshot GetClaimTokenInfoOptions() + { + var mockOptionsSnapshot = new Mock>(); + mockOptionsSnapshot.Setup(o => o.Value).Returns( + new ClaimTokenInfoOptions + { + ChainId = "mockChainId", + PublicKey = "mockPrivateKey", + ClaimTokenAddress = "mockClaimTokenAddress", + ClaimTokenAmount = 100, + GetClaimTokenLimit = 0 + }); + return mockOptionsSnapshot.Object; + } + + private IOptionsSnapshot GetClaimTokenWhiteListAddressesOptions() + { + var mockOptionsSnapshot = new Mock>(); + mockOptionsSnapshot.Setup(o => o.Value).Returns( + new ClaimTokenWhiteListAddressesOptions + { + WhiteListAddresses = new List + { + "MockAddress" + } + }); + return mockOptionsSnapshot.Object; + } + + private IContractProvider GetMockContractProvider() + { + var mockContractProvider = new Mock(); + mockContractProvider.Setup(o => o.GetBalanceAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync((string chainId, string address, string symbol) => chainId == "mockChainId" + ? new GetBalanceOutput() { Balance = 80 } + : new GetBalanceOutput() { Balance = 120 }); + + mockContractProvider.Setup(o => o.ClaimTokenAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .Returns(Task.CompletedTask); + + mockContractProvider.Setup(o => + o.SendTransferAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync(new SendTransactionOutput() { TransactionId = "" }); + + return mockContractProvider.Object; + } +} \ No newline at end of file diff --git a/test/CAServer.Application.Tests/ClaimToken/ClaimTokenTests.cs b/test/CAServer.Application.Tests/ClaimToken/ClaimTokenTests.cs new file mode 100644 index 000000000..bedb7147c --- /dev/null +++ b/test/CAServer.Application.Tests/ClaimToken/ClaimTokenTests.cs @@ -0,0 +1,43 @@ +using System.Threading.Tasks; +using CAServer.ClaimToken.Dtos; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Xunit; + +namespace CAServer.ClaimToken; + +[Collection(CAServerTestConsts.CollectionDefinitionName)] + +public partial class ClaimTokenTests : CAServerApplicationTestBase +{ + + private readonly IClaimTokenAppService _claimTokenAppService; + + public ClaimTokenTests() + { + _claimTokenAppService = GetRequiredService(); + } + + protected override void AfterAddApplication(IServiceCollection services) + { + services.AddSingleton(GetClaimTokenInfoOptions()); + services.AddSingleton(GetMockCacheProvider()); + services.AddSingleton(GetClaimTokenWhiteListAddressesOptions()); + services.AddSingleton(GetMockContractProvider()); + } + + + [Fact] + public async Task GetClaimTokenAsyncTest() + { + var requestDto = new ClaimTokenRequestDto() + { + Symbol = "MockSymbol", + Amount = "100", + Address = "MockAddress" + }; + var result = await _claimTokenAppService.GetClaimTokenAsync(requestDto); + result.ShouldNotBe(null); + } + +} \ No newline at end of file diff --git a/test/CAServer.Application.Tests/Common/ContractProviderTest.cs b/test/CAServer.Application.Tests/Common/ContractProviderTest.cs new file mode 100644 index 000000000..ff02ffcd4 --- /dev/null +++ b/test/CAServer.Application.Tests/Common/ContractProviderTest.cs @@ -0,0 +1,81 @@ +using System; +using System.Threading.Tasks; +using AElf.Contracts.MultiToken; +using AElf.Types; +using CAServer.ClaimToken.Dtos; +using Nethereum.Hex.HexConvertors.Extensions; +using Shouldly; +using Xunit; + +namespace CAServer.Common; + +[Collection(CAServerTestConsts.CollectionDefinitionName)] +public class ContractProviderTest : CAServerApplicationTestBase +{ + private readonly IContractProvider _contractProvider; + + public ContractProviderTest() + { + _contractProvider = GetRequiredService(); + } + + [Fact] + public async Task GetVerifierServersListAsyncTest() + { + try + { + var outPutNull = await _contractProvider.GetVerifierServersListAsync("TEST"); + } + catch (Exception e) + { + e.ShouldNotBeNull(); + } + } + + [Fact] + public async Task GetVerifierServersListAsync_ChainId_NotFount_Test() + { + var result = await _contractProvider.GetVerifierServersListAsync("TEST1"); + result.ShouldBeNull(); + } + + [Fact] + public async Task GetBalanceAsyncTest() + { + try + { + var outPutNull = await _contractProvider.GetBalanceAsync("TEST", "address", "CPU"); + } + catch (Exception e) + { + e.ShouldNotBeNull(); + } + } + + [Fact] + public async Task GetBalanceAsync_ChainId_NotFount_Test() + { + var result = await _contractProvider.GetBalanceAsync("TEST1", + Address.FromPublicKey("AAA".HexToByteArray()).ToBase58(), "CPU"); + result.ShouldBeNull(); + } + + [Fact] + public async Task ClaimTokenAsync() + { + try + { + await _contractProvider.ClaimTokenAsync("TEST", "CPU", "AELF"); + } + catch (Exception e) + { + e.ShouldNotBeNull(); + } + } + + [Fact] + public async Task ClaimTokenAsync_ChainId_NotFount_Test() + { + await _contractProvider.ClaimTokenAsync("TEST1", "CPU", "AELF"); + } +} \ No newline at end of file diff --git a/test/CAServer.Application.Tests/Common/ModelTest.cs b/test/CAServer.Application.Tests/Common/ModelTest.cs new file mode 100644 index 000000000..7d0f23031 --- /dev/null +++ b/test/CAServer.Application.Tests/Common/ModelTest.cs @@ -0,0 +1,199 @@ +using System.Collections.Generic; +using CAServer.Guardian; +using CAServer.Hubs; +using CAServer.IpInfo; +using CAServer.ThirdPart.Dtos; +using CAServer.Verifier; +using Shouldly; +using Xunit; + +namespace CAServer.Common; + +public class ModelTest +{ + [Fact] + public void GuardianDtoTest() + { + var dto = new ManagerInfoDBase + { + Address = string.Empty, + ExtraData = string.Empty, + }; + + var list = new GuardianBaseListDto + { + Guardians = new List() + }; + + var guardian = new GuardianDto + { + ThirdPartyEmail = string.Empty, + IsPrivate = false, + FirstName = string.Empty, + LastName = string.Empty + }; + + var baseList = new GuardianBaseListDto + { + Guardians = new List() + }; + + dto.ShouldNotBeNull(); + } + + [Fact] + public void HubRequestTest() + { + var hub = new HubRequestBase + { + Context = new HubRequestContext() + { + ClientId = "test", + RequestId = "test" + } + }; + + var info = hub.ToString(); + info.ShouldNotBeNull(); + } + + [Fact] + public void IpInfoTest() + { + var dto = new IpInfoDto + { + Ip = string.Empty, + Type = string.Empty, + ContinentCode = string.Empty, + ContinentName = string.Empty, + CountryCode = string.Empty, + CountryName = string.Empty, + RegionCode = string.Empty, + RegionName = string.Empty, + City = string.Empty, + Zip = string.Empty, + Latitude = 0, + Longitude = 0, + Location = new LocationInfo() + { + GeonameId = 1, + Capital = string.Empty, + Languages = new List() + { + new LanguageInfo() + { + Code = string.Empty, + Name = string.Empty, + Native = string.Empty + } + }, + CountryFlag = string.Empty, + CountryFlagEmoji = string.Empty, + CountryFlagEmojiUnicode = string.Empty, + CallingCode = string.Empty, + IsEu = false + } + }; + + dto.ShouldNotBeNull(); + } + + [Fact] + public void ACHDtoTest() + { + var requestDto = new GetAlchemyOrderQuoteDto + { + Crypto = string.Empty, + Network = string.Empty, + Fiat = string.Empty, + Country = string.Empty, + Amount = string.Empty, + Side = string.Empty, + PayWayCode = string.Empty, + Type = string.Empty + }; + + var responseDto = new AlchemyOrderQuoteResultDto + { + Data = new AlchemyOrderQuoteDataDto() + { + Crypto = string.Empty, + CryptoPrice = string.Empty, + Fiat = string.Empty, + CryptoQuantity = string.Empty, + RampFee = string.Empty, + NetworkFee = string.Empty, + PayWayCode = string.Empty + } + }; + + var dtos = new AlchemyCryptoListDto + { + Data = new List() + { + new AlchemyCryptoDto() + { + Crypto = string.Empty, + Network = string.Empty, + BuyEnable = string.Empty, + SellEnable = string.Empty, + MinPurchaseAmount = string.Empty, + MaxPurchaseAmount = string.Empty, + Address = string.Empty, + Icon = string.Empty, + MinSellAmount = string.Empty, + MaxSellAmount = string.Empty + } + } + }; + + var fiatListDto = new AlchemyFiatListDto + { + Data = new List() + { + new AlchemyFiatDto() + { + Currency = string.Empty, + Country = string.Empty, + PayWayName = string.Empty, + FixedFee = string.Empty, + RateFee = string.Empty, + PayMin = string.Empty, + PayMax = string.Empty, + PayWayCode = string.Empty + } + } + }; + + var tokenDto = new AlchemyTokenDto + { + Data = new AlchemyTokenDataDto() + { + Email = string.Empty, + AccessToken = string.Empty + } + }; + + requestDto.ShouldNotBeNull(); + } + + [Fact] + public void VerifierDtoTest() + { + var serverInfo = new GuardianVerifierServer + { + Name = string.Empty, + VerifierAddress = null, + ImageUrl = string.Empty, + EndPoints = null + }; + + var verifierServerInfo = new VerifierServerInfo + { + EndPoints = new List(), + Id = string.Empty + }; + + serverInfo.ShouldNotBeNull(); + } +} \ No newline at end of file diff --git a/test/CAServer.Application.Tests/Common/TimeStampHelperTest.cs b/test/CAServer.Application.Tests/Common/TimeStampHelperTest.cs new file mode 100644 index 000000000..e9dc9e1e5 --- /dev/null +++ b/test/CAServer.Application.Tests/Common/TimeStampHelperTest.cs @@ -0,0 +1,23 @@ +using System; +using Shouldly; +using Xunit; + +namespace CAServer.Common; + +public class TimeStampHelperTest +{ + [Fact] + public void GetTimeStampTest() + { + var millisecondsStr = TimeStampHelper.GetTimeStampInMilliseconds(); + var secondsStr = TimeStampHelper.GetTimeStampInSeconds(); + millisecondsStr.ShouldNotBeNull(); + secondsStr.ShouldNotBeNull(); + + var milliseconds = Convert.ToUInt64(millisecondsStr); + var seconds = Convert.ToUInt64(secondsStr); + + Assert.True(milliseconds > 0); + Assert.True(seconds > 0); + } +} \ No newline at end of file diff --git a/test/CAServer.Application.Tests/Common/VerifyHelperTest.cs b/test/CAServer.Application.Tests/Common/VerifyHelperTest.cs new file mode 100644 index 000000000..4f677d9a4 --- /dev/null +++ b/test/CAServer.Application.Tests/Common/VerifyHelperTest.cs @@ -0,0 +1,22 @@ +using CAServer.Commons; +using Shouldly; +using Xunit; + +namespace CAServer.Common; + +public class VerifyHelperTest +{ + [Fact] + public void TestPhone() + { + var result = VerifyHelper.VerifyPhone("12345678901"); + result.ShouldBeTrue(); + } + + [Fact] + public void TestErrorMessage() + { + var dic = CAServerError.Message; + dic[400].ShouldBe("Invalid input params."); + } +} \ No newline at end of file diff --git a/test/CAServer.Application.Tests/Google/GoogleRecapthaTests.cs b/test/CAServer.Application.Tests/Google/GoogleRecapthaTests.cs index 3264681de..56d44f064 100644 --- a/test/CAServer.Application.Tests/Google/GoogleRecapthaTests.cs +++ b/test/CAServer.Application.Tests/Google/GoogleRecapthaTests.cs @@ -5,11 +5,12 @@ namespace CAServer.Google; -public partial class GoogleRecapthaTests : CAServerApplicationTestBase +[Collection(CAServerTestConsts.CollectionDefinitionName)] +public partial class GoogleRecaptchaTests : CAServerApplicationTestBase { private readonly IGoogleAppService _googleAppService; - public GoogleRecapthaTests() + public GoogleRecaptchaTests() { _googleAppService = GetRequiredService(); } @@ -19,7 +20,6 @@ protected override void AfterAddApplication(IServiceCollection services) services.AddSingleton(GetMockHttpClientFactory()); services.AddSingleton(GetGoogleRecaptchaOptions()); services.AddSingleton(GetMockCacheProvider()); - base.AfterAddApplication(services); } @@ -44,9 +44,6 @@ public async Task IsGoogleRecaptchaOpen_Test() { var userIpAddress = "127.0.0.1"; var result = await _googleAppService.IsGoogleRecaptchaOpenAsync(userIpAddress); - result.ShouldBeFalse(); + result.ShouldBeTrue(); } - - - } \ No newline at end of file diff --git a/test/CAServer.Application.Tests/Google/GoogleReptchaMockTests.cs b/test/CAServer.Application.Tests/Google/GoogleReptchaMockTests.cs index b2e065c60..76bd5da10 100644 --- a/test/CAServer.Application.Tests/Google/GoogleReptchaMockTests.cs +++ b/test/CAServer.Application.Tests/Google/GoogleReptchaMockTests.cs @@ -11,7 +11,7 @@ namespace CAServer.Google; -public partial class GoogleRecapthaTests +public partial class GoogleRecaptchaTests { private IHttpClientFactory GetMockHttpClientFactory() { diff --git a/test/CAServer.Application.Tests/Guardian/GuardianProviderMock.cs b/test/CAServer.Application.Tests/Guardian/GuardianProviderMock.cs index 482cb8aba..3c30eb389 100644 --- a/test/CAServer.Application.Tests/Guardian/GuardianProviderMock.cs +++ b/test/CAServer.Application.Tests/Guardian/GuardianProviderMock.cs @@ -15,24 +15,24 @@ public IGuardianProvider GetGuardianProviderMock() provider.Setup(t => t.GetGuardiansAsync(It.IsAny(), It.IsAny())) .ReturnsAsync(new GuardiansDto() { - CaHolderInfo = new List() - { - new Provider.GuardianDto() - { - OriginChainId = "TEST", - CaAddress = "", - CaHash = "", - GuardianList = new GuardianBaseListDto() - { - Guardians = new List - { new GuardianDto { IdentifierHash = _identifierHash } } - } - } - } + // CaHolderInfo = new List() + // { + // new Provider.GuardianDto() + // { + // OriginChainId = "TEST", + // CaAddress = "", + // CaHash = "", + // GuardianList = new GuardianBaseListDto() + // { + // Guardians = new List + // { new GuardianDto { IdentifierHash = _identifierHash } } + // } + // } + // } }); - provider.Setup(t => t.GetHolderInfoFromContractAsync(It.IsAny(), It.IsAny(), - It.IsAny())).ReturnsAsync(new GetHolderInfoOutput() + provider.Setup(t => t.GetHolderInfoFromContractAsync(It.IsAny(), + It.IsAny(), It.IsAny())).ReturnsAsync(new GetHolderInfoOutput() { GuardianList = new GuardianList() { diff --git a/test/CAServer.Application.Tests/Guardian/GuardianProviderTest.cs b/test/CAServer.Application.Tests/Guardian/GuardianProviderTest.cs index 7bd0e4f29..1bdcfdf8a 100644 --- a/test/CAServer.Application.Tests/Guardian/GuardianProviderTest.cs +++ b/test/CAServer.Application.Tests/Guardian/GuardianProviderTest.cs @@ -24,8 +24,10 @@ protected override void BeforeAddApplication(IServiceCollection services) { var graphQlHelper = Substitute.For(); var graphQlClient = Substitute.For(); + // var contractProvider = Substitute.For(); services.AddSingleton(graphQlClient); services.AddSingleton(graphQlHelper); + // services.AddSingleton(contractProvider); } [Fact] @@ -46,8 +48,7 @@ public async Task GetHolderInfoFromContractTest() { try { - await _guardianProvider.GetHolderInfoFromContractAsync("test", string.Empty, - new Grains.Grain.ApplicationHandler.ChainInfo()); + await _guardianProvider.GetHolderInfoFromContractAsync("test", string.Empty, "AELF"); } catch (Exception e) { diff --git a/test/CAServer.Application.Tests/Guardian/GuardianTest.cs b/test/CAServer.Application.Tests/Guardian/GuardianTest.cs index 80cfd1f6c..d12314212 100644 --- a/test/CAServer.Application.Tests/Guardian/GuardianTest.cs +++ b/test/CAServer.Application.Tests/Guardian/GuardianTest.cs @@ -8,6 +8,7 @@ using CAServer.Grain.Tests; using CAServer.Grains.Grain.ApplicationHandler; using CAServer.Grains.Grain.Guardian; +using CAServer.Guardian.Provider; using Microsoft.CodeAnalysis; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -83,6 +84,23 @@ await _guardianAppService.GetGuardianIdentifiersAsync(new GuardianIdentifierDto } } + [Fact] + public async Task GetGuardianIdentifiers_Invalid_Params_Test() + { + try + { + await _guardianAppService.GetGuardianIdentifiersAsync(new GuardianIdentifierDto + { + GuardianIdentifier = "", + ChainId = "TEST" + }); + } + catch (Exception e) + { + Assert.True(e is AbpValidationException); + } + } + [Fact] public async Task GetRegisterInfo_Invalid_Params_Test() { @@ -121,6 +139,14 @@ public async Task GetRegisterInfo_Guardian_Not_Exist_Test() { try { + var info = new GuardianInfo { CaHolderInfo = new List() }; + var guardianDto = new CAServer.Guardian.Provider.GuardianDto + { + OriginChainId = string.Empty, + GuardianList = new GuardianBaseListDto(), + ManagerInfos = new List() + }; + await _guardianAppService.GetRegisterInfoAsync(new RegisterInfoDto() { LoginGuardianIdentifier = _identifier, @@ -133,6 +159,19 @@ await _guardianAppService.GetRegisterInfoAsync(new RegisterInfoDto() } } + [Fact] + public async Task GetRegisterInfo_Params_Error_Test() + { + try + { + await _guardianAppService.GetRegisterInfoAsync(new RegisterInfoDto()); + } + catch (Exception e) + { + e.Message.ShouldContain("valid"); + } + } + private IOptions GetChainOptions() { return new OptionsWrapper( diff --git a/test/CAServer.Application.Tests/IpInfo/IpInfoClientTest.cs b/test/CAServer.Application.Tests/IpInfo/IpInfoClientTest.cs index 7b4c85658..0db5560d1 100644 --- a/test/CAServer.Application.Tests/IpInfo/IpInfoClientTest.cs +++ b/test/CAServer.Application.Tests/IpInfo/IpInfoClientTest.cs @@ -20,8 +20,9 @@ public async Task GetIpInfoTest() { try { - var ip = "127.0.0.1"; + var ip = "20.246.106.227"; var result = await _infoClient.GetIpInfoAsync(ip); + result.CountryCode.ShouldBe("US"); } catch (Exception e) { diff --git a/test/CAServer.Application.Tests/IpInfo/IpInfoServiceTest.cs b/test/CAServer.Application.Tests/IpInfo/IpInfoServiceTest.cs index a101e714e..3fd5fdfc4 100644 --- a/test/CAServer.Application.Tests/IpInfo/IpInfoServiceTest.cs +++ b/test/CAServer.Application.Tests/IpInfo/IpInfoServiceTest.cs @@ -28,6 +28,7 @@ protected override void AfterAddApplication(IServiceCollection services) [Fact] public async Task TestGetIpInfo() { + var ipInfoDto = new IpInfoDto(); var ipInfo = await _ipInfoAppService.GetIpInfoAsync(); ipInfo.ShouldNotBeNull(); ipInfo.Country.ShouldBe("Singapore"); diff --git a/test/CAServer.Application.Tests/Notify/IpInfoServiceMock.cs b/test/CAServer.Application.Tests/Notify/IpInfoServiceMock.cs new file mode 100644 index 000000000..ea7360300 --- /dev/null +++ b/test/CAServer.Application.Tests/Notify/IpInfoServiceMock.cs @@ -0,0 +1,19 @@ +using CAServer.IpInfo; +using Moq; + +namespace CAServer.Notify; + +public partial class NotifyTest +{ + private IIpInfoAppService GetIpInfo() + { + var ipInfoService = new Mock(); + ipInfoService.Setup(m => m.GetIpInfoAsync()).ReturnsAsync(new IpInfoResultDto() + { + Country = "Singapore", + Code = "SG" + }); + + return ipInfoService.Object; + } +} \ No newline at end of file diff --git a/test/CAServer.Application.Tests/Notify/NotifyProviderMock.cs b/test/CAServer.Application.Tests/Notify/NotifyProviderMock.cs new file mode 100644 index 000000000..b2fc3cbbb --- /dev/null +++ b/test/CAServer.Application.Tests/Notify/NotifyProviderMock.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using CAServer.Notify.Dtos; +using CAServer.Notify.Provider; +using Moq; + +namespace CAServer.Notify; + +public partial class NotifyTest +{ + private INotifyProvider GetNotifyProvider() + { + var ipInfoService = new Mock(); + ipInfoService.Setup(m => m.GetDataFromCms(It.IsAny())).ReturnsAsync(new CmsNotifyDto() + { + Data = new List() + { + new CmsNotify + { + Id = 1, + Title = "test", + TargetVersion = new CmsTargetVersion + { + Value = "1.2.2" + }, + AppVersions = new List + { + new CmsAppVersion + { + AppVersion = new CmsValue + { + Value = "1.2.1" + } + } + } + } + } + }); + + return ipInfoService.Object; + } +} \ No newline at end of file diff --git a/test/CAServer.Application.Tests/Notify/NotifyTest.cs b/test/CAServer.Application.Tests/Notify/NotifyTest.cs index 0f3e0f76f..de31629ec 100644 --- a/test/CAServer.Application.Tests/Notify/NotifyTest.cs +++ b/test/CAServer.Application.Tests/Notify/NotifyTest.cs @@ -1,16 +1,18 @@ using System; +using System.Linq; using System.Threading.Tasks; using AElf.Indexing.Elasticsearch; using CAServer.Entities.Es; using CAServer.Grains.Grain.Notify; using CAServer.Notify.Dtos; +using Microsoft.Extensions.DependencyInjection; using Shouldly; using Xunit; namespace CAServer.Notify; [Collection(CAServerTestConsts.CollectionDefinitionName)] -public class NotifyTest : CAServerApplicationTestBase +public partial class NotifyTest : CAServerApplicationTestBase { private readonly INotifyAppService _notifyAppService; private readonly INESTRepository _notifyRulesRepository; @@ -21,6 +23,12 @@ public NotifyTest() _notifyRulesRepository = GetRequiredService>(); } + protected override void AfterAddApplication(IServiceCollection services) + { + services.AddSingleton(GetIpInfo()); + services.AddSingleton(GetNotifyProvider()); + } + [Fact] public async Task Create_Test() { @@ -64,6 +72,24 @@ public async Task Create_Test() updateResult.Title.ShouldBe(newTitle); } + [Fact] + public async Task CreateFromCms_Test() + { + var result = await _notifyAppService.CreateFromCmsAsync(""); + result.ShouldNotBeNull(); + result.Count.ShouldBe(1); + } + + [Fact] + public async Task UpdateFromCms_Test() + { + var resultDto = await _notifyAppService.CreateFromCmsAsync(""); + var notify = resultDto.First(); + + var result = await _notifyAppService.UpdateFromCmsAsync(notify.Id); + result.ShouldNotBeNull(); + } + [Fact] public async Task Delete_Test() { @@ -85,7 +111,7 @@ public async Task Delete_Test() var createDto = await _notifyAppService.CreateAsync(dto); await _notifyAppService.DeleteAsync(createDto.Id); } - + [Fact] public async Task Pull_Test() { @@ -101,7 +127,8 @@ public async Task Pull_Test() ReleaseTime = DateTime.UtcNow, DownloadUrl = "http://127.0.0.1", IsForceUpdate = true, - IsApproved = true + IsApproved = true, + NotifyId = 1 }; var createDto = await _notifyAppService.CreateAsync(dto); @@ -113,7 +140,8 @@ await _notifyRulesRepository.AddOrUpdateAsync(new NotifyRulesIndex DeviceTypes = new[] { "Android" }, SendTypes = new[] { NotifySendType.None }, IsApproved = true, - Id = createDto.Id + Id = createDto.Id, + NotifyId = 1 }); var result = await _notifyAppService.PullNotifyAsync(new PullNotifyDto() @@ -126,5 +154,4 @@ await _notifyRulesRepository.AddOrUpdateAsync(new NotifyRulesIndex result.Title.ShouldBe("Update Portkey"); } - } \ No newline at end of file diff --git a/test/CAServer.Application.Tests/Phone/PhoneAppServiceTests.cs b/test/CAServer.Application.Tests/Phone/PhoneAppServiceTests.cs index e869abfa7..96a876b8b 100644 --- a/test/CAServer.Application.Tests/Phone/PhoneAppServiceTests.cs +++ b/test/CAServer.Application.Tests/Phone/PhoneAppServiceTests.cs @@ -36,9 +36,9 @@ protected override void AfterAddApplication(IServiceCollection services) [Fact] public async void PhoneInfoSuccessTest() { - var res = await _phoneAppService.GetPhoneInfo(); - res.Data[0]["Country"].ShouldBe("12345678901234567890123456789012"); - res.Data[0]["Code"].ShouldBe("sssss"); - res.Data[0]["Iso"].ShouldBe("123"); + var res = await _phoneAppService.GetPhoneInfoAsync(); + res.Data[0]["country"].ShouldBe("12345678901234567890123456789012"); + res.Data[0]["code"].ShouldBe("sssss"); + res.Data[0]["iso"].ShouldBe("123"); } } diff --git a/test/CAServer.Application.Tests/Phone/PhoneInfoServiceTestsMock.cs b/test/CAServer.Application.Tests/Phone/PhoneInfoServiceTestsMock.cs index fc4895ad0..9219e3200 100644 --- a/test/CAServer.Application.Tests/Phone/PhoneInfoServiceTestsMock.cs +++ b/test/CAServer.Application.Tests/Phone/PhoneInfoServiceTestsMock.cs @@ -18,6 +18,12 @@ private IOptions GetPhoneInfoOptions() var phoneInfo = new List(); phoneInfo.Add(phoneInfoItem); phoneInfoOptions.PhoneInfo = phoneInfo; + phoneInfoOptions.Default = new PhoneInfoItem + { + Country = "Singapore", + Code = "65", + Iso = "SG" + }; return new OptionsWrapper( phoneInfoOptions); } diff --git a/test/CAServer.Application.Tests/Samples/SampleAppServiceTests.cs b/test/CAServer.Application.Tests/Samples/SampleAppServiceTests.cs deleted file mode 100644 index a5916f437..000000000 --- a/test/CAServer.Application.Tests/Samples/SampleAppServiceTests.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Shouldly; -using System.Threading.Tasks; -using CAServer.CAAccount; -using CAServer.Dtos; -using Volo.Abp.Identity; -using Xunit; - -namespace CAServer.Samples; - -/* This is just an example test class. - * Normally, you don't test code of the modules you are using - * (like IIdentityUserAppService here). - * Only test your own application services. - */ -[Collection(CAServerTestConsts.CollectionDefinitionName)] -public class SampleAppServiceTests : CAServerApplicationTestBase -{ - private readonly IIdentityUserAppService _userAppService; - - public SampleAppServiceTests() - { - _userAppService = GetRequiredService(); - } - - [Fact] - public async Task Initial_Data_Should_Contain_Admin_User() - { - //Act - var result = await _userAppService.GetListAsync(new GetIdentityUsersInput()); - - //Assert - result.TotalCount.ShouldBeGreaterThan(0); - result.Items.ShouldContain(u => u.UserName == "admin"); - } - [Fact] - public async Task Initial_Data() - { - //Act - // await _registerService.ManagerAddressAsync(new ManagerAddressInput - // { - // - // }); - - } -} diff --git a/test/CAServer.Application.Tests/Tokens/TokenAppServiceHistoryTest.cs b/test/CAServer.Application.Tests/Tokens/TokenAppServiceHistoryTest.cs index 5a10193e6..52b7725d0 100644 --- a/test/CAServer.Application.Tests/Tokens/TokenAppServiceHistoryTest.cs +++ b/test/CAServer.Application.Tests/Tokens/TokenAppServiceHistoryTest.cs @@ -9,9 +9,6 @@ using CAServer.Security; using CAServer.Tokens.Dtos; using Microsoft.Extensions.DependencyInjection; -using Mongo2Go; -using Moq; -using Orleans; using Orleans.TestingHost; using Shouldly; using Volo.Abp.Users; diff --git a/test/CAServer.Application.Tests/Tokens/TokenAppServiceTest.cs b/test/CAServer.Application.Tests/Tokens/TokenAppServiceTest.cs index 0b5d1b6a4..43966826d 100644 --- a/test/CAServer.Application.Tests/Tokens/TokenAppServiceTest.cs +++ b/test/CAServer.Application.Tests/Tokens/TokenAppServiceTest.cs @@ -9,9 +9,6 @@ using CAServer.Security; using CAServer.Tokens.Dtos; using Microsoft.Extensions.DependencyInjection; -using Mongo2Go; -using Moq; -using Orleans; using Orleans.TestingHost; using Shouldly; using Volo.Abp.Users; diff --git a/test/CAServer.Application.Tests/UserAssets/UserAssetsTests.cs b/test/CAServer.Application.Tests/UserAssets/UserAssetsTests.cs index 015521050..daa31689e 100644 --- a/test/CAServer.Application.Tests/UserAssets/UserAssetsTests.cs +++ b/test/CAServer.Application.Tests/UserAssets/UserAssetsTests.cs @@ -51,7 +51,7 @@ public async Task GetTokenTest() var result = await _userAssetsAppService.GetTokenAsync(param); - result.TotalRecordCount.ShouldBe(1); + result.TotalRecordCount.ShouldBe(3); var data = result.Data.First(); data.Balance.ShouldBe(1000.ToString()); diff --git a/test/CAServer.Application.Tests/UserAssets/UserAssetsTestsMock.cs b/test/CAServer.Application.Tests/UserAssets/UserAssetsTestsMock.cs index 6bb6c2eef..f37c3bb51 100644 --- a/test/CAServer.Application.Tests/UserAssets/UserAssetsTestsMock.cs +++ b/test/CAServer.Application.Tests/UserAssets/UserAssetsTestsMock.cs @@ -29,17 +29,22 @@ private IUserAssetsProvider GetMockUserAssetsProvider() new() { ChainId = "AELF" + }, + new() + { + ChainId = "tDVV" } } }); mockUserAssetsProvider.Setup(m => - m.GetUserTokenInfoAsync(It.IsAny>(), It.IsAny(), It.IsAny(), It.IsAny())) + m.GetUserTokenInfoAsync(It.IsAny>(), It.IsAny(), It.IsAny(), + It.IsAny())) .ReturnsAsync(new IndexerTokenInfos { CaHolderTokenBalanceInfo = new CaHolderTokenBalanceInfo { - totalRecordCount = 1, + totalRecordCount = 2, Data = new List { new() @@ -56,39 +61,56 @@ private IUserAssetsProvider GetMockUserAssetsProvider() TokenName = "Token", TotalSupply = 10000 } + }, + new() + { + CaAddress = "c1pPpwKdVaYjEsS5VLMTkiXf76wxW9YY2qaDBPowpa8zX2oEo", + ChainId = "AELF", + Balance = 1000, + TokenIds = new List { 1 }, + TokenInfo = new TokenInfo + { + Symbol = "CPU", + Decimals = 8, + TokenContractAddress = "c1pPpwKdVaYjEsS5VLMTkiXf76wxW9YY2qaDBPowpa8zX2oEo", + TokenName = "Token", + TotalSupply = 10000 + } } } } }); mockUserAssetsProvider.Setup(m => - m.GetUserNftCollectionInfoAsync(It.IsAny>(), It.IsAny(), It.IsAny())).ReturnsAsync( - new IndexerNftCollectionInfos - { - CaHolderNFTCollectionBalanceInfo = new CaHolderNFTCollectionBalanceInfo + m.GetUserNftCollectionInfoAsync(It.IsAny>(), It.IsAny(), It.IsAny())) + .ReturnsAsync( + new IndexerNftCollectionInfos { - TotalRecordCount = 1, - Data = new List + CaHolderNFTCollectionBalanceInfo = new CaHolderNFTCollectionBalanceInfo { - new() + TotalRecordCount = 1, + Data = new List { - CaAddress = "c1pPpwKdVaYjEsS5VLMTkiXf76wxW9YY2qaDBPowpa8zX2oEo", - ChainId = "AELF", - TokenIds = new List { 1 }, - NftCollectionInfo = new NftCollectionInfo + new() { - Symbol = "TEST-0", - TokenName = "TEST", - TotalSupply = 1000, - Decimals = 1 + CaAddress = "c1pPpwKdVaYjEsS5VLMTkiXf76wxW9YY2qaDBPowpa8zX2oEo", + ChainId = "AELF", + TokenIds = new List { 1 }, + NftCollectionInfo = new NftCollectionInfo + { + Symbol = "TEST-0", + TokenName = "TEST", + TotalSupply = 1000, + Decimals = 1 + } } } } - } - }); + }); mockUserAssetsProvider.Setup(m => - m.GetUserNftInfoAsync(It.IsAny>(), It.IsAny(), It.IsAny(), It.IsAny())) + m.GetUserNftInfoAsync(It.IsAny>(), It.IsAny(), It.IsAny(), + It.IsAny())) .ReturnsAsync( new IndexerNftInfos { @@ -131,32 +153,50 @@ private IUserAssetsProvider GetMockUserAssetsProvider() Symbol = "ELF", Decimals = 8 } + }, + new() + { + Id = Guid.Empty, + UserId = Guid.Empty, + IsDefault = true, + IsDisplay = true, + SortWeight = 100, + Token = new Token + { + Id = Guid.Empty, + Address = "c1pPpwKdVaYjEsS5VLMTkiXf76wxW9YY2qaDBPowpa8zX2oEo", + ChainId = "tDVV", + Symbol = "UF", + Decimals = 8 + } } }); mockUserAssetsProvider.Setup(m => - m.GetRecentTransactionUsersAsync(It.IsAny>(), It.IsAny(), It.IsAny())).ReturnsAsync( - new IndexerRecentTransactionUsers - { - CaHolderTransactionAddressInfo = new CaHolderTransactionAddressInfo + m.GetRecentTransactionUsersAsync(It.IsAny>(), It.IsAny(), It.IsAny())) + .ReturnsAsync( + new IndexerRecentTransactionUsers { - TotalRecordCount = 1, - Data = new List + CaHolderTransactionAddressInfo = new CaHolderTransactionAddressInfo { - new() + TotalRecordCount = 1, + Data = new List { - Address = "c1pPpwKdVaYjEsS5VLMTkiXf76wxW9YY2qaDBPowpa8zX2oEo", - AddressChainId = "AELF", - CaAddress = "c1pPpwKdVaYjEsS5VLMTkiXf76wxW9YY2qaDBPowpa8zX2oEo", - ChainId = "AELF", - TransactionTime = 1000 + new() + { + Address = "c1pPpwKdVaYjEsS5VLMTkiXf76wxW9YY2qaDBPowpa8zX2oEo", + AddressChainId = "AELF", + CaAddress = "c1pPpwKdVaYjEsS5VLMTkiXf76wxW9YY2qaDBPowpa8zX2oEo", + ChainId = "AELF", + TransactionTime = 1000 + } } } - } - }); - + }); + mockUserAssetsProvider.Setup(m => - m.SearchUserAssetsAsync(It.IsAny>(), It.IsAny(), It.IsAny(), It.IsAny())).ReturnsAsync( + m.SearchUserAssetsAsync(It.IsAny>(), It.IsAny(), It.IsAny(), + It.IsAny())).ReturnsAsync( new IndexerSearchTokenNfts { CaHolderSearchTokenNFT = new CaHolderSearchTokenNFT @@ -164,7 +204,7 @@ private IUserAssetsProvider GetMockUserAssetsProvider() TotalRecordCount = 1, Data = new List { - new () + new() { ChainId = "AELF", CaAddress = "c1pPpwKdVaYjEsS5VLMTkiXf76wxW9YY2qaDBPowpa8zX2oEo", @@ -177,6 +217,10 @@ private IUserAssetsProvider GetMockUserAssetsProvider() TokenContractAddress = "address", TokenName = "tokenName", TotalSupply = 1000 + }, + NftInfo = new NftInfo + { + Symbol = "ELF-NFT" } } } @@ -208,7 +252,7 @@ private ITokenAppService GetMockTokenAppService() } } }); - + mockTokenAppService.Setup(m => m.GetTokenPriceListAsync(It.IsAny>())) .ReturnsAsync( new ListResultDto diff --git a/test/CAServer.Application.Tests/VerifierCode/VerifierServerClientMockTest.cs b/test/CAServer.Application.Tests/VerifierCode/VerifierServerClientMockTest.cs index 83bf462ef..c87ac6f72 100644 --- a/test/CAServer.Application.Tests/VerifierCode/VerifierServerClientMockTest.cs +++ b/test/CAServer.Application.Tests/VerifierCode/VerifierServerClientMockTest.cs @@ -24,7 +24,6 @@ private IGetVerifierServerProvider GetVerifierServerProvider() } - private IHttpClientFactory GetMockHttpClientFactory() { var clientHandlerStub = new DelegatingHandlerStub(); @@ -37,14 +36,16 @@ private IHttpClientFactory GetMockHttpClientFactory() return factory; } - private IOptions GetAdaptableVariableOptions() + private IOptionsSnapshot GetAdaptableVariableOptions() { - return new OptionsWrapper( + var mockOptionsSnapshot = new Mock>(); + mockOptionsSnapshot.Setup(o => o.Value).Returns( new AdaptableVariableOptions { HttpConnectTimeOut = 5, VerifierServerExpireTime = 1000 }); + return mockOptionsSnapshot.Object; } } @@ -54,14 +55,18 @@ public class DelegatingHandlerStub : DelegatingHandler public DelegatingHandlerStub() { - _handlerFunc = (request, cancellationToken) => Task.FromResult(new HttpResponseMessage { StatusCode = HttpStatusCode.OK,Content = new StringContent(JsonConvert.SerializeObject(new GoogleUserInfoDto + _handlerFunc = (request, cancellationToken) => Task.FromResult(new HttpResponseMessage { - Id="123456789", - Email="MockEmail", - Picture="MockPicture", - VerifiedEmail=true, - FullName= "MockGivenName" - }))}); + StatusCode = HttpStatusCode.OK, Content = new StringContent(JsonConvert.SerializeObject( + new GoogleUserInfoDto + { + Id = "123456789", + Email = "MockEmail", + Picture = "MockPicture", + VerifiedEmail = true, + FullName = "MockGivenName" + })) + }); } public DelegatingHandlerStub(Func> handlerFunc) @@ -69,7 +74,8 @@ public DelegatingHandlerStub(Func SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + protected override Task SendAsync(HttpRequestMessage request, + CancellationToken cancellationToken) { return _handlerFunc(request, cancellationToken); } diff --git a/test/CAServer.Application.Tests/VerifierServer/VerifierServerProviderMockTests.cs b/test/CAServer.Application.Tests/VerifierServer/VerifierServerProviderMockTests.cs index 7fd2ebda4..619d61947 100644 --- a/test/CAServer.Application.Tests/VerifierServer/VerifierServerProviderMockTests.cs +++ b/test/CAServer.Application.Tests/VerifierServer/VerifierServerProviderMockTests.cs @@ -8,23 +8,23 @@ namespace CAServer.VerifierServer; public partial class GetVerifierServerProviderTest { - private IOptions GetAdaptableVariableOptions() + private IOptionsSnapshot GetAdaptableVariableOptions() { - return new OptionsWrapper( + var mockOptionsSnapshot = new Mock>(); + mockOptionsSnapshot.Setup(o => o.Value).Returns( new AdaptableVariableOptions { HttpConnectTimeOut = 5, VerifierServerExpireTime = 1000 }); + return mockOptionsSnapshot.Object; } private IContractProvider GetMockContractProvider() { var mockContractProvider = new Mock(); - mockContractProvider.Setup(o => o.GetVerifierServersListAsync(It.IsAny())) - .ReturnsAsync((string chainId) => chainId == DefaultChainId ? new GetVerifierServersOutput() : null); + // mockContractProvider.Setup(o => o.GetVerifierServersListAsync(It.IsAny())) + // .ReturnsAsync((string chainId) => chainId == DefaultChainId ? new GetVerifierServersOutput() : null); return mockContractProvider.Object; } - - } \ No newline at end of file diff --git a/test/CAServer.Domain.Tests/CAServerDomainCollection.cs b/test/CAServer.Domain.Tests/CAServerDomainCollection.cs index b2f1a9afc..e91a5a140 100644 --- a/test/CAServer.Domain.Tests/CAServerDomainCollection.cs +++ b/test/CAServer.Domain.Tests/CAServerDomainCollection.cs @@ -4,7 +4,7 @@ namespace CAServer; [CollectionDefinition(CAServerTestConsts.CollectionDefinitionName)] -public class CAServerDomainCollection : CAServerMongoDbCollectionFixtureBase +public class CAServerDomainCollection { } diff --git a/test/CAServer.Domain.Tests/Samples/SampleDomainTests.cs b/test/CAServer.Domain.Tests/Samples/SampleDomainTests.cs deleted file mode 100644 index fcb08b3e3..000000000 --- a/test/CAServer.Domain.Tests/Samples/SampleDomainTests.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.IO; -using System.Text.Json; -using System.Text.Json.Serialization; -using System.Threading.Tasks; -using Shouldly; -using Volo.Abp.Identity; -using Xunit; - -namespace CAServer.Samples; - -/* This is just an example test class. - * Normally, you don't test code of the modules you are using - * (like IdentityUserManager here). - * Only test your own domain services. - */ -[Collection(CAServerTestConsts.CollectionDefinitionName)] -public class SampleDomainTests : CAServerDomainTestBase -{ - private readonly IIdentityUserRepository _identityUserRepository; - private readonly IdentityUserManager _identityUserManager; - - public SampleDomainTests() - { - _identityUserRepository = GetRequiredService(); - _identityUserManager = GetRequiredService(); - } - - public class ResponseResultDto - { - public bool Success { get; set; } - public string Message { get; set; } - public T Data { get; set; } - } - public class VerifierServerResponse - { - //VerifierSessionId - public Guid VerifierSessionId { get; set;} - - } - [Fact] - public async Task Should_Set_Email_Of_A_User() - { - var str = - "{\"success\":true,\"message\":null,\"data\":{\"verifierSessionId\":\"88aaa8cc-071c-4fe5-b2d9-e16752641b9f\"}}"; - var memory = new MemoryStream(System.Text.Encoding.Default.GetBytes(str)); - var jsonSerializerOptions = new JsonSerializerOptions(new JsonSerializerOptions - { - PropertyNamingPolicy = JsonNamingPolicy.CamelCase - } ); - var a = await JsonSerializer.DeserializeAsync>(memory, jsonSerializerOptions); - - IdentityUser adminUser; - - /* Need to manually start Unit Of Work because - * FirstOrDefaultAsync should be executed while db connection / context is available. - */ - await WithUnitOfWorkAsync(async () => - { - adminUser = await _identityUserRepository - .FindByNormalizedUserNameAsync("ADMIN"); - - await _identityUserManager.SetEmailAsync(adminUser, "newemail@abp.io"); - await _identityUserRepository.UpdateAsync(adminUser); - }); - - adminUser = await _identityUserRepository.FindByNormalizedUserNameAsync("ADMIN"); - adminUser.Email.ShouldBe("newemail@abp.io"); - } -} diff --git a/test/CAServer.EntityEventHandler.Core.Tests/CAAccount/AccountGrainMock.cs b/test/CAServer.EntityEventHandler.Core.Tests/CAAccount/AccountGrainMock.cs new file mode 100644 index 000000000..42f4e6679 --- /dev/null +++ b/test/CAServer.EntityEventHandler.Core.Tests/CAAccount/AccountGrainMock.cs @@ -0,0 +1,56 @@ +using CAServer.Grains.Grain; +using CAServer.Grains.Grain.Account; +using CAServer.Grains.Grain.Device; +using Moq; +using Orleans; + +namespace CAServer.EntityEventHandler.Tests.CAAccount; + +public partial class AccountHandlerTests +{ + private IClusterClient GetClusterClient() + { + var client = new Mock(); + var register = new Mock(); + var device = new Mock(); + var recovery = new Mock(); + + register.Setup(t => t.UpdateRegisterResultAsync(It.IsAny())).ReturnsAsync( + (CreateHolderResultGrainDto dto) => + new GrainResultDto() + { + Success = true, + Data = new RegisterGrainDto() + { + Id = dto.Id, + GrainId = dto.GrainId, + CaAddress = dto.CaAddress, + CaHash = dto.CaHash, + RegisterSuccess = dto.RegisterSuccess, + RegisterMessage = dto.RegisterMessage, + RegisteredTime = dto.RegisteredTime + } + }); + + recovery.Setup(t => t.UpdateRecoveryResultAsync(It.IsAny())).ReturnsAsync( + (SocialRecoveryResultGrainDto dto) => new GrainResultDto() + { + Success = true, + Data = new RecoveryGrainDto() + { + Id = dto.Id, + GrainId = dto.GrainId, + CaAddress = dto.CaAddress, + CaHash = dto.CaHash, + RecoverySuccess = dto.RecoverySuccess, + RecoveryMessage = dto.RecoveryMessage, + RecoveryTime = dto.RecoveryTime + } + }); + + client.Setup(t => t.GetGrain(It.IsAny(), null)).Returns(register.Object); + client.Setup(t => t.GetGrain(It.IsAny(), null)).Returns(device.Object); + client.Setup(t => t.GetGrain(It.IsAny(), null)).Returns(recovery.Object); + return client.Object; + } +} \ No newline at end of file diff --git a/test/CAServer.EntityEventHandler.Core.Tests/CAAccount/AccountHandlerTests.cs b/test/CAServer.EntityEventHandler.Core.Tests/CAAccount/AccountHandlerTests.cs index 651fdaab8..11248fa46 100644 --- a/test/CAServer.EntityEventHandler.Core.Tests/CAAccount/AccountHandlerTests.cs +++ b/test/CAServer.EntityEventHandler.Core.Tests/CAAccount/AccountHandlerTests.cs @@ -1,9 +1,13 @@ using CAServer.Account; +using CAServer.ContractEventHandler; using CAServer.Entities.Es; using CAServer.Etos; using CAServer.Hubs; +using CAServer.Orleans.TestBase; using CAServer.Search; +using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; +using Orleans.TestingHost; using Shouldly; using Volo.Abp.Application.Dtos; using Volo.Abp.EventBus.Distributed; @@ -11,15 +15,23 @@ namespace CAServer.EntityEventHandler.Tests.CAAccount; -public class AccountHandlerTests : CAServerEntityEventHandlerTestBase +public partial class AccountHandlerTests : CAServerEntityEventHandlerTestBase { private readonly ISearchAppService _searchAppService; + private readonly IDistributedEventBus _eventBus; + //private readonly TestCluster _cluster; public AccountHandlerTests() { _searchAppService = GetRequiredService(); _eventBus = GetRequiredService(); + // _cluster = GetRequiredService().Cluster; + } + + protected override void AfterAddApplication(IServiceCollection services) + { + services.AddSingleton(GetClusterClient()); } [Fact] @@ -34,7 +46,6 @@ public async Task HandlerEvent_AccountRegisterCreate() RegisterMessage = "test", RegisterStatus = "", Context = new HubRequestContext() - }; await _eventBus.PublishAsync(chain); @@ -48,7 +59,7 @@ public async Task HandlerEvent_AccountRegisterCreate() extra.ShouldNotBeNull(); extra.Items[0].RegisterMessage.ShouldBe("test"); } - + [Fact] public async Task HandlerEvent_AccountRecoverCreate() { @@ -74,5 +85,82 @@ public async Task HandlerEvent_AccountRecoverCreate() extra.ShouldNotBeNull(); extra.Items[0].RecoveryMessage.ShouldBe("test"); } - + + [Fact] + public async Task HandlerEvent_CreateHolder_Test() + { + var id = Guid.NewGuid(); + var register = new AccountRegisterCreateEto + { + Id = id, + GrainId = "registerTest", + GuardianInfo = new GuardianInfo(), + RegisteredTime = new DateTime(), + RegisterSuccess = false, + RegisterMessage = "test", + RegisterStatus = "", + Context = new HubRequestContext() + }; + await _eventBus.PublishAsync(register); + + var eto = new CreateHolderEto + { + Id = id, + GrainId = "registerTest", + RegisterSuccess = true, + RegisterMessage = "test", + Context = new HubRequestContext() + }; + await _eventBus.PublishAsync(eto); + + var result = await _searchAppService.GetListByLucenceAsync("accountregisterindex", new GetListInput() + { + MaxResultCount = 1 + }); + + result.ShouldNotBeNull(); + var extra = JsonConvert.DeserializeObject>(result); + extra.ShouldNotBeNull(); + extra.Items[0].RegisterSuccess.ShouldBe(true); + } + + [Fact] + public async Task HandlerEvent_AccountRecoverUpdate_Test() + { + var id = Guid.NewGuid(); + var recovery = new AccountRecoverCreateEto + { + Id = id, + GrainId = "recovery_test", + RecoverySuccess = false, + RecoveryMessage = "test", + RecoveryTime = new DateTime(), + LoginGuardianIdentifierHash = "test", + Context = new HubRequestContext() + }; + await _eventBus.PublishAsync(recovery); + + var eto = new SocialRecoveryEto + { + Id = id, + GrainId = "recovery_test", + RecoverySuccess = true, + RecoveryMessage = "test", + RecoveryTime = new DateTime(), + CaAddress = "address", + CaHash = "hash", + Context = new HubRequestContext() + }; + await _eventBus.PublishAsync(eto); + + var result = await _searchAppService.GetListByLucenceAsync("accountrecoverindex", new GetListInput() + { + MaxResultCount = 1 + }); + + result.ShouldNotBeNull(); + var extra = JsonConvert.DeserializeObject>(result); + extra.ShouldNotBeNull(); + extra.Items[0].RecoverySuccess.ShouldBe(true); + } } \ No newline at end of file diff --git a/test/CAServer.EntityEventHandler.Core.Tests/CAHolder/CaHolderHandlerTests.cs b/test/CAServer.EntityEventHandler.Core.Tests/CAHolder/CaHolderHandlerTests.cs index c2ba34d84..c804e28c4 100644 --- a/test/CAServer.EntityEventHandler.Core.Tests/CAHolder/CaHolderHandlerTests.cs +++ b/test/CAServer.EntityEventHandler.Core.Tests/CAHolder/CaHolderHandlerTests.cs @@ -22,25 +22,62 @@ public CaHolderHandlerTests() } [Fact] - public async Task HandlerEvent_NewNotity() + public async Task CaHolder_Create_Test() { - var user = new CreateUserEto + try { - CaHash = HashHelper.ComputeFrom("a23322344aa").ToString(), - Id = Guid.NewGuid(), - Nickname = "test333", - UserId = Guid.NewGuid() - }; - // await _eventBus.PublishAsync(user); - // - // var result = await _searchAppService.GetListByLucenceAsync("caholderindex", new GetListInput() - // { - // MaxResultCount = 1 - // }); - // - // result.ShouldNotBeNull(); - // var extra = JsonConvert.DeserializeObject>(result); - // extra.ShouldNotBeNull(); - // extra.Items[0].NickName.ShouldBe("test333"); + var user = new CreateUserEto + { + CaHash = HashHelper.ComputeFrom("a23322344aa").ToString(), + Id = Guid.NewGuid(), + Nickname = "Wallet 01", + UserId = Guid.NewGuid() + }; + await _eventBus.PublishAsync(user); + + var result = await _searchAppService.GetListByLucenceAsync("caholderindex", new GetListInput() + { + MaxResultCount = 1 + }); + + result.ShouldNotBeNull(); + var extra = JsonConvert.DeserializeObject>(result); + extra.ShouldNotBeNull(); + extra.Items[0].NickName.ShouldBe("Wallet 01"); + } + catch (Exception e) + { + e.ShouldNotBeNull(); + } + } + + [Fact] + public async Task CaHolder_Update_Test() + { + try + { + var user = new UpdateCAHolderEto() + { + CaHash = HashHelper.ComputeFrom("a23322344aa").ToString(), + Id = Guid.NewGuid(), + Nickname = "Wallet 01", + UserId = Guid.NewGuid() + }; + await _eventBus.PublishAsync(user); + + var result = await _searchAppService.GetListByLucenceAsync("caholderindex", new GetListInput() + { + MaxResultCount = 1 + }); + + result.ShouldNotBeNull(); + var extra = JsonConvert.DeserializeObject>(result); + extra.ShouldNotBeNull(); + extra.Items[0].NickName.ShouldBe("Wallet 01"); + } + catch (Exception e) + { + e.ShouldNotBeNull(); + } } } \ No newline at end of file diff --git a/test/CAServer.EntityEventHandler.Core.Tests/CAServer.EntityEventHandler.Core.Tests.csproj b/test/CAServer.EntityEventHandler.Core.Tests/CAServer.EntityEventHandler.Core.Tests.csproj index d59a10539..d999a4bb3 100644 --- a/test/CAServer.EntityEventHandler.Core.Tests/CAServer.EntityEventHandler.Core.Tests.csproj +++ b/test/CAServer.EntityEventHandler.Core.Tests/CAServer.EntityEventHandler.Core.Tests.csproj @@ -8,6 +8,7 @@ + diff --git a/test/CAServer.EntityEventHandler.Core.Tests/CAVerifier/CaVerifierHandlerTests.cs b/test/CAServer.EntityEventHandler.Core.Tests/CAVerifier/CaVerifierHandlerTests.cs index f5f5609ae..51a3a94f7 100644 --- a/test/CAServer.EntityEventHandler.Core.Tests/CAVerifier/CaVerifierHandlerTests.cs +++ b/test/CAServer.EntityEventHandler.Core.Tests/CAVerifier/CaVerifierHandlerTests.cs @@ -1,6 +1,7 @@ using CAServer.Entities.Es; using CAServer.Search; using CAServer.Verifier.Etos; +using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using Shouldly; using Volo.Abp.Application.Dtos; @@ -9,7 +10,7 @@ namespace CAServer.EntityEventHandler.Tests.CAVerifier; -public class CaVerifierHandlerTests : CAServerEntityEventHandlerTestBase +public partial class CaVerifierHandlerTests : CAServerEntityEventHandlerTestBase { private readonly ISearchAppService _searchAppService; private readonly IDistributedEventBus _eventBus; @@ -19,29 +20,22 @@ public CaVerifierHandlerTests() _searchAppService = GetRequiredService(); _eventBus = GetRequiredService(); } - + protected override void AfterAddApplication(IServiceCollection services) + { + services.AddSingleton(GetClient()); + } + [Fact] public async Task HandlerEvent_NewNotity() { var verifer = new VerifierCodeEto { VerifierSessionId = Guid.NewGuid(), - Type ="1" , - GuardianAccount ="test00001" , - VerifierId ="test0000322342" , - ChainId ="test0032351" , + Type = "1", + GuardianAccount = "test", + VerifierId = "test0000322342", + ChainId = "test0032351", }; - // await _eventBus.PublishAsync(verifer); - // - // var result = await _searchAppService.GetListByLucenceAsync("guardianindex", new GetListInput() - // { - // MaxResultCount = 1 - // }); - // - // result.ShouldNotBeNull(); - // var info = JsonConvert.DeserializeObject>(result); - // info.ShouldNotBeNull(); - // info.Items[0].Identifier.ShouldBe("test"); - + await _eventBus.PublishAsync(verifer); } } \ No newline at end of file diff --git a/test/CAServer.EntityEventHandler.Core.Tests/CAVerifier/MockCaVerifierHandler.cs b/test/CAServer.EntityEventHandler.Core.Tests/CAVerifier/MockCaVerifierHandler.cs deleted file mode 100644 index ec14d4f80..000000000 --- a/test/CAServer.EntityEventHandler.Core.Tests/CAVerifier/MockCaVerifierHandler.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Volo.Abp.ObjectMapping; -using CAServer.Verifier; -using CAServer.Verifier.Dtos; -using CAServer.Verifier.Etos; -using Volo.Abp.DependencyInjection; -using Volo.Abp.EventBus.Distributed; - -namespace CAServer.EntityEventHandler.Tests.CAVerifier; -public class MockCaVerifierHandler: IDistributedEventHandler, ITransientDependency -{ - private readonly IVerifierServerClient _verifierServerClient; - - private readonly IObjectMapper _objectMapper; - - public MockCaVerifierHandler(IVerifierServerClient verifierServerClient, IObjectMapper objectMapper) - { - _verifierServerClient = verifierServerClient; - _objectMapper = objectMapper; - } - - public async Task HandleEventAsync(VerifierCodeEto eventData) - { - //var dto = _objectMapper.Map(eventData); - //await _verifierServerClient.SendVerificationRequestAsync(dto); - - } -} \ No newline at end of file diff --git a/test/CAServer.EntityEventHandler.Core.Tests/CAVerifier/VerifierServerClientMock.cs b/test/CAServer.EntityEventHandler.Core.Tests/CAVerifier/VerifierServerClientMock.cs new file mode 100644 index 000000000..2c834fed3 --- /dev/null +++ b/test/CAServer.EntityEventHandler.Core.Tests/CAVerifier/VerifierServerClientMock.cs @@ -0,0 +1,19 @@ +using CAServer.Dtos; +using CAServer.Verifier; +using CAServer.Verifier.Dtos; +using Moq; + +namespace CAServer.EntityEventHandler.Tests.CAVerifier; + +public partial class CaVerifierHandlerTests +{ + private IVerifierServerClient GetClient() + { + var verifierServerClient = new Mock(); + + verifierServerClient.Setup(m => m.SendVerificationRequestAsync(It.IsAny())) + .ReturnsAsync(new ResponseResultDto()); + + return verifierServerClient.Object; + } +} \ No newline at end of file diff --git a/test/CAServer.Grain.Tests/CAServerGrainTestModule.cs b/test/CAServer.Grain.Tests/CAServerGrainTestModule.cs index 4371562f4..2bccb1d42 100644 --- a/test/CAServer.Grain.Tests/CAServerGrainTestModule.cs +++ b/test/CAServer.Grain.Tests/CAServerGrainTestModule.cs @@ -2,6 +2,7 @@ using CAServer.Grains; using CAServer.Grains.Grain.Account; using CAServer.Grains.Grain.ApplicationHandler; +using CAServer.Signature; using Microsoft.Extensions.DependencyInjection; using Orleans; using Volo.Abp.AutoMapper; @@ -18,7 +19,8 @@ namespace CAServer.Grain.Tests; typeof(CAServerCoinGeckoApiModule), typeof(AbpCachingModule), typeof(AbpAutoMapperModule), - typeof(AbpObjectMappingModule) + typeof(AbpObjectMappingModule), + typeof(CAServerSignatureModule) )] public class CAServerGrainTestModule : AbpModule { @@ -32,5 +34,4 @@ public override void ConfigureServices(ServiceConfigurationContext context) o.CAAccountRequestInfoExpirationTime = 1; }); } - } \ No newline at end of file diff --git a/test/CAServer.Grain.Tests/ClusterFixture.cs b/test/CAServer.Grain.Tests/ClusterFixture.cs index 55c6854f8..b131060b5 100644 --- a/test/CAServer.Grain.Tests/ClusterFixture.cs +++ b/test/CAServer.Grain.Tests/ClusterFixture.cs @@ -6,12 +6,14 @@ using CAServer.Grains.Grain.Account; using CAServer.Grains.Grain.ApplicationHandler; using CAServer.Grains.Grain.Tokens.TokenPrice; +using CAServer.Signature; using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; +using Moq; using Nethereum.Hex.HexConvertors.Extensions; using Orleans; using Orleans.Hosting; @@ -55,6 +57,10 @@ public void Configure(ISiloHostBuilder hostBuilder) { hostBuilder.ConfigureServices(services => { + var mockSignatureProvider = new Mock(); + mockSignatureProvider.Setup(o => o.SignTxMsg(It.IsAny(), It.IsAny())) + .ReturnsAsync("123"); + services.AddSingleton(mockSignatureProvider.Object); services.AddSingleton(); services.AddSingleton(); services.Configure(o => @@ -68,8 +74,9 @@ public void Configure(ISiloHostBuilder hostBuilder) BaseUrl = "url", ContractAddress = Address.FromPublicKey("AAA".HexToByteArray()).ToBase58(), TokenContractAddress = Address.FromPublicKey("AAA".HexToByteArray()).ToBase58(), - CrossChainContractAddress = Address.FromPublicKey("AAA".HexToByteArray()).ToBase58(), - PrivateKey = HashHelper.ComputeFrom("private").ToHex(), + CrossChainContractAddress = + Address.FromPublicKey("AAA".HexToByteArray()).ToBase58(), + PublicKey = HashHelper.ComputeFrom("private").ToHex(), IsMainChain = true } }, @@ -80,8 +87,9 @@ public void Configure(ISiloHostBuilder hostBuilder) BaseUrl = "url", ContractAddress = Address.FromPublicKey("AAA".HexToByteArray()).ToBase58(), TokenContractAddress = Address.FromPublicKey("AAA".HexToByteArray()).ToBase58(), - CrossChainContractAddress = Address.FromPublicKey("AAA".HexToByteArray()).ToBase58(), - PrivateKey = "private", + CrossChainContractAddress = + Address.FromPublicKey("AAA".HexToByteArray()).ToBase58(), + PublicKey = "private", IsMainChain = false } } @@ -98,7 +106,7 @@ public void Configure(ISiloHostBuilder hostBuilder) { o.CoinIdMapping = new Dictionary { - {"ELF","aelf"} + { "ELF", "aelf" } }; }); services.Configure(o => @@ -173,8 +181,6 @@ public void Configure(ISiloHostBuilder hostBuilder) Mapper = sp.GetRequiredService() }); services.AddTransient(provider => provider.GetRequiredService()); - - }) .AddSimpleMessageStreamProvider(CAServerApplicationConsts.MessageStreamName) .AddMemoryGrainStorage("PubSubStore") @@ -368,6 +374,7 @@ public DistributedCache( SetDefaultOptions(); } + protected virtual void SetDefaultOptions() { CacheName = CacheNameAttribute.GetCacheName(typeof(TCacheItem)); @@ -378,6 +385,7 @@ protected virtual void SetDefaultOptions() //Configure default cache entry options DefaultCacheOptions = GetDefaultCacheEntryOptions(); } + protected virtual DistributedCacheEntryOptions GetDefaultCacheEntryOptions() { foreach (var configure in _distributedCacheOption.CacheConfigurators) @@ -391,6 +399,7 @@ protected virtual DistributedCacheEntryOptions GetDefaultCacheEntryOptions() return _distributedCacheOption.GlobalCacheEntryOptions; } + public TCacheItem Get(TCacheKey key, bool? hideErrors = null, bool considerUow = false) { throw new NotImplementedException(); @@ -504,11 +513,12 @@ public virtual async Task GetOrAddAsync( return value; } + protected virtual bool ShouldConsiderUow(bool considerUow) { return considerUow && UnitOfWorkManager.Current != null; } - + protected virtual Dictionary> GetUnitOfWorkCache() { if (UnitOfWorkManager.Current == null) @@ -519,7 +529,7 @@ protected virtual Dictionary> GetUnit return UnitOfWorkManager.Current.GetOrAddItem(GetUnitOfWorkCacheKey(), key => new Dictionary>()); } - + protected virtual string GetUnitOfWorkCacheKey() { return UowCacheName + CacheName; @@ -612,6 +622,7 @@ protected virtual string NormalizeKey(TCacheKey key) ) ); } + protected virtual async Task HandleExceptionAsync(Exception ex) { Logger.LogException(ex, LogLevel.Warning); @@ -623,6 +634,7 @@ await scope.ServiceProvider .NotifyAsync(new ExceptionNotificationContext(ex, LogLevel.Warning)); } } + public void SetMany(IEnumerable> items, DistributedCacheEntryOptions options = null, bool? hideErrors = null, bool considerUow = false) @@ -682,11 +694,12 @@ public Task RemoveManyAsync(IEnumerable keys, bool? hideErrors = null } } - public class AsyncLocalCurrentTenantAccessor : ICurrentTenantAccessor,ISingletonDependency + public class AsyncLocalCurrentTenantAccessor : ICurrentTenantAccessor, ISingletonDependency { public static AsyncLocalCurrentTenantAccessor Instance { get; } = new(); - public BasicTenantInfo Current { + public BasicTenantInfo Current + { get => _currentScope.Value; set => _currentScope.Value = value; } @@ -698,6 +711,7 @@ public AsyncLocalCurrentTenantAccessor() _currentScope = new AsyncLocal(); } } + private class TestClientBuilderConfigurator : IClientBuilderConfigurator { public void Configure(IConfiguration configuration, IClientBuilder clientBuilder) => clientBuilder diff --git a/test/CAServer.Grain.Tests/ContractService/ContractServiceGrainTests.cs b/test/CAServer.Grain.Tests/ContractService/ContractServiceGrainTests.cs index 93cdf78e7..d09319880 100644 --- a/test/CAServer.Grain.Tests/ContractService/ContractServiceGrainTests.cs +++ b/test/CAServer.Grain.Tests/ContractService/ContractServiceGrainTests.cs @@ -14,7 +14,7 @@ namespace CAServer.Grain.Tests.ContractService; -public class ContractServiceGrainTests : CAServerGrainTestBase +public partial class ContractServiceGrainTests : CAServerGrainTestBase { [Fact] public async Task CreateHolderInfoAsyncTests() @@ -89,7 +89,7 @@ public async Task ValidateTransactionAsyncTests() await grain.ValidateTransactionAsync("AELF", output, unsetList); } - + [Fact] public async Task GetSyncHolderInfoInputAsyncTests() { @@ -98,18 +98,18 @@ public async Task GetSyncHolderInfoInputAsyncTests() var input = await grain.GetSyncHolderInfoInputAsync("AELF", new TransactionInfo { TransactionId = HashHelper.ComputeFrom("txId").ToHex(), - Transaction = new byte[] {1, 2, 3}, + Transaction = new byte[] { 1, 2, 3 }, BlockNumber = 1000 }); return input; } - + [Fact] public async Task SyncTransactionAsyncTests() { var input = await GetSyncHolderInfoInputAsyncTests(); - + var grain = Cluster.Client.GetGrain(Guid.NewGuid()); await grain.SyncTransactionAsync("AELF", input); diff --git a/test/CAServer.MongoDB.Tests/MongoDb/CAServerMongoDbFixture.cs b/test/CAServer.MongoDB.Tests/MongoDb/CAServerMongoDbFixture.cs index 79b59c5fd..d0c1e0c97 100644 --- a/test/CAServer.MongoDB.Tests/MongoDb/CAServerMongoDbFixture.cs +++ b/test/CAServer.MongoDB.Tests/MongoDb/CAServerMongoDbFixture.cs @@ -5,17 +5,17 @@ namespace CAServer.MongoDB; public class CAServerMongoDbFixture : IDisposable { - private static readonly MongoDbRunner MongoDbRunner; - public static readonly string ConnectionString; - - static CAServerMongoDbFixture() - { - MongoDbRunner = MongoDbRunner.Start(singleNodeReplSet: true, singleNodeReplSetWaitTimeout: 10); - ConnectionString = MongoDbRunner.ConnectionString; - } + // private static readonly MongoDbRunner MongoDbRunner; + // public static readonly string ConnectionString; + // + // static CAServerMongoDbFixture() + // { + // MongoDbRunner = MongoDbRunner.Start(singleNodeReplSet: true, singleNodeReplSetWaitTimeout: 10); + // ConnectionString = MongoDbRunner.ConnectionString; + // } public void Dispose() { - MongoDbRunner?.Dispose(); + //MongoDbRunner?.Dispose(); } } diff --git a/test/CAServer.MongoDB.Tests/MongoDb/CAServerMongoDbTestModule.cs b/test/CAServer.MongoDB.Tests/MongoDb/CAServerMongoDbTestModule.cs index 51448ddc5..073d29e40 100644 --- a/test/CAServer.MongoDB.Tests/MongoDb/CAServerMongoDbTestModule.cs +++ b/test/CAServer.MongoDB.Tests/MongoDb/CAServerMongoDbTestModule.cs @@ -12,14 +12,14 @@ public class CAServerMongoDbTestModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { - var stringArray = CAServerMongoDbFixture.ConnectionString.Split('?'); - var connectionString = stringArray[0].EnsureEndsWith('/') + - "Db_" + - Guid.NewGuid().ToString("N") + "/?" + stringArray[1]; - - Configure(options => - { - options.ConnectionStrings.Default = connectionString; - }); + // var stringArray = CAServerMongoDbFixture.ConnectionString.Split('?'); + // var connectionString = stringArray[0].EnsureEndsWith('/') + + // "Db_" + + // Guid.NewGuid().ToString("N") + "/?" + stringArray[1]; + // + // Configure(options => + // { + // options.ConnectionStrings.Default = connectionString; + // }); } } diff --git a/test/CAServer.MongoDB.Tests/MongoDb/Samples/SampleRepositoryTests.cs b/test/CAServer.MongoDB.Tests/MongoDb/Samples/SampleRepositoryTests.cs deleted file mode 100644 index c70f8ad01..000000000 --- a/test/CAServer.MongoDB.Tests/MongoDb/Samples/SampleRepositoryTests.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Threading.Tasks; -using MongoDB.Driver.Linq; -using Shouldly; -using Volo.Abp.Domain.Repositories; -using Volo.Abp.Identity; -using Xunit; - -namespace CAServer.MongoDB.Samples; - -/* This is just an example test class. - * Normally, you don't test ABP framework code - * (like default AppUser repository IRepository here). - * Only test your custom repository methods. - */ -[Collection(CAServerTestConsts.CollectionDefinitionName)] -public class SampleRepositoryTests : CAServerMongoDbTestBase -{ - private readonly IRepository _appUserRepository; - - public SampleRepositoryTests() - { - _appUserRepository = GetRequiredService>(); - } - - [Fact] - public async Task Should_Query_AppUser() - { - /* Need to manually start Unit Of Work because - * FirstOrDefaultAsync should be executed while db connection / context is available. - */ - await WithUnitOfWorkAsync(async () => - { - //Act - var adminUser = await (await _appUserRepository.GetMongoQueryableAsync()) - .FirstOrDefaultAsync(u => u.UserName == "admin"); - - //Assert - adminUser.ShouldNotBeNull(); - }); - } -} diff --git a/test/CAServer.Signature.HttpApi.Tests/CAServer.Signature.HttpApi.Tests.csproj b/test/CAServer.Signature.HttpApi.Tests/CAServer.Signature.HttpApi.Tests.csproj new file mode 100644 index 000000000..96f8baad4 --- /dev/null +++ b/test/CAServer.Signature.HttpApi.Tests/CAServer.Signature.HttpApi.Tests.csproj @@ -0,0 +1,19 @@ + + + + net7.0 + CAServer.Signature.Test + + + + + + + + + + + + + + diff --git a/test/CAServer.Signature.HttpApi.Tests/CAServerSignatureHttpApiTestModule.cs b/test/CAServer.Signature.HttpApi.Tests/CAServerSignatureHttpApiTestModule.cs new file mode 100644 index 000000000..26d16e3dc --- /dev/null +++ b/test/CAServer.Signature.HttpApi.Tests/CAServerSignatureHttpApiTestModule.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq.Dynamic.Core.Tokenizer; +using System.Security.Cryptography; +using System.Text; +using AElf; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.AutoMapper; +using Volo.Abp.Modularity; + +namespace CAServer.Signature.Test; + +[DependsOn( + typeof(CAServerSignatureHttpApiModule), + typeof(CAServerSignatureHttpApiModule) +)] +public class CAServerSignatureHttpApiTestModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + // Configure(options => { options.AddMaps(); }); + byte[] privateKeyBytes = Encoding.UTF8.GetBytes("test.1234567890.key"); + context.Services.Configure(option => + { + option.PrivateKeyDictionary = new Dictionary + { + { "test-key", privateKeyBytes.ToHex() } + }; + }); + base.ConfigureServices(context); + } +} \ No newline at end of file diff --git a/test/CAServer.Signature.HttpApi.Tests/CAServerSignatureServiceTest.cs b/test/CAServer.Signature.HttpApi.Tests/CAServerSignatureServiceTest.cs new file mode 100644 index 000000000..5aa630ef8 --- /dev/null +++ b/test/CAServer.Signature.HttpApi.Tests/CAServerSignatureServiceTest.cs @@ -0,0 +1,64 @@ +using System.Threading.Tasks; +using CAServer.Signature.Dtos; +using System; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using AElf; +using CAServer.Security; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Volo.Abp.Users; +using Xunit; + +namespace CAServer.Signature.Test; + +[Collection(CAServerTestConsts.CollectionDefinitionName)] +public class CAServerSignatureServiceTest : CAServerSignatureHttpApiTestBase +{ + private readonly SignatureController _signatureController; + + public CAServerSignatureServiceTest() + { + _signatureController = GetRequiredService(); + } + + + [Fact] + public async Task GetSignatureByPublicKeySucceedAsyncTest() + { + var result = await _signatureController.SendSignAsync(new SendSignatureDto() + { + HexMsg = TestHexMsgGenerator(), + PublicKey = "test-key" + }); + result.Signature.ShouldBe( + "d71f1ada7df0aa23f2cfe27234f63c6811ebd39d6b5a56878ec366abf94b73a63c9e56d2f1c4608047325a2c1c859536beaeb70fb4736476583552197e86a41900"); + } + + [Fact] + public async Task GetSignatureByPublicKeyNotExistAsyncTest() + { + try + { + var result = await _signatureController.SendSignAsync(new SendSignatureDto() + { + HexMsg = TestHexMsgGenerator("Public key not exist."), + PublicKey = "not-exist-key" + }); + } + catch (Exception e) + { + e.Message.ShouldBe("Publish key not exist!"); + } + } + + private static string TestHexMsgGenerator(string message = "CAServer.Signature.TestString") + { + byte[] hashBytes = SHA256.Create() + .ComputeHash(Encoding.UTF8.GetBytes(message)); + + return hashBytes.ToHex(); + } +} \ No newline at end of file diff --git a/test/CAServer.Signature.HttpApi.Tests/CAServerSignatureTestBase.cs b/test/CAServer.Signature.HttpApi.Tests/CAServerSignatureTestBase.cs new file mode 100644 index 000000000..f72a8fefd --- /dev/null +++ b/test/CAServer.Signature.HttpApi.Tests/CAServerSignatureTestBase.cs @@ -0,0 +1,5 @@ +namespace CAServer.Signature.Test; + +public class CAServerSignatureHttpApiTestBase : CAServerTestBase +{ +} \ No newline at end of file diff --git a/test/CAServer.TestBase/CAServerTestBaseModule.cs b/test/CAServer.TestBase/CAServerTestBaseModule.cs index 13ff4ffb6..f76ab4862 100644 --- a/test/CAServer.TestBase/CAServerTestBaseModule.cs +++ b/test/CAServer.TestBase/CAServerTestBaseModule.cs @@ -34,7 +34,7 @@ public override void ConfigureServices(ServiceConfigurationContext context) public override void OnApplicationInitialization(ApplicationInitializationContext context) { - SeedTestData(context); + // SeedTestData(context); } private static void SeedTestData(ApplicationInitializationContext context)