Browse Source

Merge pull request #973 from colinin/rel-8.2.0

Rel 8.2.0
pull/988/head
yx lin 1 year ago
committed by GitHub
parent
commit
b49d2a891d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      .github/workflows/publish.yml
  2. 4
      .github/workflows/release.yml
  3. 22
      Directory.Packages.props
  4. 2
      apps/vue/src/api/abp/localization/index.ts
  5. 23
      apps/vue/src/api/account/profiles/index.ts
  6. 5
      apps/vue/src/api/account/profiles/model/index.ts
  7. 2
      apps/vue/src/api/auditing/security-logs/index.ts
  8. 2
      apps/vue/src/api/identity/claims/index.ts
  9. 2
      apps/vue/src/api/identity/organization-units/index.ts
  10. 27
      apps/vue/src/api/identity/sessions/index.ts
  11. 16
      apps/vue/src/api/identity/sessions/model/index.ts
  12. 2
      apps/vue/src/api/localization/languages/index.ts
  13. 2
      apps/vue/src/api/messages/friends/index.ts
  14. 2
      apps/vue/src/api/messages/groups/index.ts
  15. 4
      apps/vue/src/api/multi-tenancy/tenants/index.ts
  16. 208
      apps/vue/src/layouts/default/header/components/notify/NoticeList.vue
  17. 126
      apps/vue/src/layouts/default/header/components/notify/index.vue
  18. 17
      apps/vue/src/layouts/default/header/components/notify/useNotifications.ts
  19. 16
      apps/vue/src/layouts/default/header/components/user-dropdown/index.vue
  20. 61
      apps/vue/src/views/account/security-logs/index.vue
  21. 141
      apps/vue/src/views/account/sessions/index.vue
  22. 150
      apps/vue/src/views/identity/user/components/SessionModal.vue
  23. 13
      apps/vue/src/views/identity/user/components/UserTable.vue
  24. 1
      apps/vue/types/abp.d.ts
  25. 248
      aspnet-core/LINGYUN.MicroService.All.sln
  26. 63
      aspnet-core/LINGYUN.MicroService.SingleProject.sln
  27. 17
      aspnet-core/LINGYUN.MicroService.WebhooksManagement.sln
  28. 16
      aspnet-core/LINGYUN.MicroService.Workflow.sln
  29. 7
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN.Abp.AuditLogging.Elasticsearch.csproj
  30. 23
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/AbpAuditLoggingElasticsearchModule.cs
  31. 21
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/AbpAuditLoggingElasticsearchOptions.cs
  32. 171
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/AuditLogInfoToAuditLogConverter.cs
  33. 633
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/ElasticsearchAuditLogManager.cs
  34. 441
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/ElasticsearchSecurityLogManager.cs
  35. 9
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IAuditLogInfoToAuditLogConverter.cs
  36. 9
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IIndexInitializer.cs
  37. 9
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IIndexNameNormalizer.cs
  38. 155
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IndexInitializer.cs
  39. 23
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IndexInitializerService.cs
  40. 39
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IndexNameNormalizer.cs
  41. 5
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/LINGYUN.Abp.AuditLogging.EntityFrameworkCore.csproj
  42. 31
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/LINGYUN/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingEntityFrameworkCoreModule.cs
  43. 27
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/LINGYUN/Abp/AuditLogging/EntityFrameworkCore/AbpAuditingMapperProfile.cs
  44. 289
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/LINGYUN/Abp/AuditLogging/EntityFrameworkCore/AuditLogManager.cs
  45. 223
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/LINGYUN/Abp/AuditLogging/EntityFrameworkCore/SecurityLogManager.cs
  46. 9
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN.Abp.AuditLogging.csproj
  47. 25
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/AbpAuditLoggingModule.cs
  48. 176
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/AuditLog.cs
  49. 59
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/AuditLogAction.cs
  50. 27
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/AuditingStore.cs
  51. 149
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/DefaultAuditLogManager.cs
  52. 67
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/DefaultEntityChangeStore.cs
  53. 133
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/DefaultSecurityLogManager.cs
  54. 89
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/EntityChange.cs
  55. 11
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/EntityChangeWithUsername.cs
  56. 55
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/EntityPropertyChange.cs
  57. 99
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/IAuditLogManager.cs
  58. 67
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/IEntityChangeStore.cs
  59. 95
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/ISecurityLogManager.cs
  60. 83
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/SecurityLog.cs
  61. 27
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/SecurityLogStore.cs
  62. 5
      aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.QQ/LINGYUN.Abp.Authentication.QQ.csproj
  63. 53
      aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.QQ/LINGYUN/Abp/Authentication/QQ/AbpQQClaimTypes.cs
  64. 279
      aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.QQ/Microsoft/AspNetCore/Authentication/QQ/QQConnectOAuthHandler.cs
  65. 73
      aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.QQ/Microsoft/AspNetCore/Authentication/QQ/QQConnectOAuthOptions.cs
  66. 101
      aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.QQ/Microsoft/AspNetCore/Authentication/QQAuthenticationExtensions.cs
  67. 15
      aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.QQ/System/BytesExtensions.cs
  68. 15
      aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.QQ/System/StringExtensions.cs
  69. 79
      aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.QQ/System/Text/Json/JsonElementExtensions.cs
  70. 5
      aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.WeChat/LINGYUN.Abp.Authentication.WeChat.csproj
  71. 455
      aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialOAuthHandler.cs
  72. 61
      aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialOAuthOptions.cs
  73. 25
      aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialStateCacheItem.cs
  74. 103
      aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.WeChat/Microsoft/AspNetCore/Authentication/WeChatAuthenticationExtensions.cs
  75. 9
      aspnet-core/framework/authorization/LINGYUN.Abp.Authorization.OrganizationUnits/LINGYUN.Abp.Authorization.OrganizationUnits.csproj
  76. 2
      aspnet-core/framework/cli/LINGYUN.Abp.Cli/LINGYUN.Abp.Cli.csproj
  77. 5
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun.SettingManagement/LINGYUN.Abp.Aliyun.SettingManagement.csproj
  78. 49
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun.SettingManagement/LINGYUN/Abp/Aliyun/SettingManagement/AbpAliyunSettingManagementModule.cs
  79. 333
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun.SettingManagement/LINGYUN/Abp/Aliyun/SettingManagement/AliyunSettingAppService.cs
  80. 47
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun.SettingManagement/LINGYUN/Abp/Aliyun/SettingManagement/AliyunSettingController.cs
  81. 27
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun.SettingManagement/LINGYUN/Abp/Aliyun/SettingManagement/AliyunSettingPermissionDefinitionProvider.cs
  82. 11
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun.SettingManagement/LINGYUN/Abp/Aliyun/SettingManagement/AliyunSettingPermissionNames.cs
  83. 7
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun.SettingManagement/LINGYUN/Abp/Aliyun/SettingManagement/IAliyunSettingAppService.cs
  84. 7
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN.Abp.Aliyun.csproj
  85. 21
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AbpAliyunException.cs
  86. 39
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AbpAliyunModule.cs
  87. 39
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AcsClientFactory.cs
  88. 43
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AliyunBasicSessionCredentialsCacheItem.cs
  89. 271
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AliyunClientFactory.cs
  90. 19
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/IAcsClientFactory.cs
  91. 9
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/Localization/AliyunResource.cs
  92. 147
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/Settings/AliyunSettingNames.cs
  93. 399
      aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/Settings/AliyunSettingProvider.cs
  94. 7
      aspnet-core/framework/cloud-tencent/LINGYUN.Abp.BlobStoring.Tencent/LINGYUN.Abp.BlobStoring.Tencent.csproj
  95. 29
      aspnet-core/framework/cloud-tencent/LINGYUN.Abp.BlobStoring.Tencent/LINGYUN/Abp/BlobStoring/Tencent/DefaultTencentBlobNameCalculator.cs
  96. 9
      aspnet-core/framework/cloud-tencent/LINGYUN.Abp.BlobStoring.Tencent/LINGYUN/Abp/BlobStoring/Tencent/ITencentBlobNameCalculator.cs
  97. 29
      aspnet-core/framework/cloud-tencent/LINGYUN.Abp.BlobStoring.Tencent/LINGYUN/Abp/BlobStoring/Tencent/TencentBlobContainerConfigurationExtensions.cs
  98. 99
      aspnet-core/framework/cloud-tencent/LINGYUN.Abp.BlobStoring.Tencent/LINGYUN/Abp/BlobStoring/Tencent/TencentBlobNamingNormalizer.cs
  99. 101
      aspnet-core/framework/cloud-tencent/LINGYUN.Abp.BlobStoring.Tencent/LINGYUN/Abp/BlobStoring/Tencent/TencentBlobProviderConfiguration.cs
  100. 47
      aspnet-core/framework/cloud-tencent/LINGYUN.Abp.BlobStoring.Tencent/LINGYUN/Abp/BlobStoring/Tencent/TencentBlobProviderConfigurationNames.cs

2
.github/workflows/publish.yml

@ -2,7 +2,7 @@ name: "Publish"
on:
push:
branches: [ rel-8.1.3 ]
branches: [ rel-8.2.0 ]
env:
DOTNET_VERSION: "8.0.200"

4
.github/workflows/release.yml

@ -2,7 +2,7 @@ name: "Tagged Release"
on:
push:
branches: [ rel-8.1.3 ]
branches: [ rel-8.2.0 ]
jobs:
tagged-release:
@ -14,4 +14,4 @@ jobs:
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
prerelease: false
automatic_release_tag: "8.1.3"
automatic_release_tag: "8.2.0"

22
Directory.Packages.props

@ -2,17 +2,16 @@
<PropertyGroup>
<DotNetCoreCAPPackageVersion>8.1.1</DotNetCoreCAPPackageVersion>
<ElsaPackageVersion>2.14.1</ElsaPackageVersion>
<VoloAbpPackageVersion>8.1.3</VoloAbpPackageVersion>
<LINGYUNAbpPackageVersion>8.1.3</LINGYUNAbpPackageVersion>
<VoloAbpPackageVersion>8.2.0</VoloAbpPackageVersion>
<LINGYUNAbpPackageVersion>8.2.0</LINGYUNAbpPackageVersion>
<MicrosoftExtensionsPackageVersion>8.0.0</MicrosoftExtensionsPackageVersion>
<MicrosoftAspNetCorePackageVersion>8.0.0</MicrosoftAspNetCorePackageVersion>
<MicrosoftEntityFrameworkCorePackageVersion>8.0.0</MicrosoftEntityFrameworkCorePackageVersion>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<!-- Abp Framework -->
<ItemGroup>
<PackageVersion Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite" Version="3.0.5" />
<PackageVersion Include="Volo.Abp.AspNetCore.Mvc.UI.Theme.LeptonXLite" Version="3.2.0" />
<PackageVersion Include="Volo.Abp.Core" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Account.Application" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Account.Application.Contracts" Version="$(VoloAbpPackageVersion)" />
@ -133,10 +132,9 @@
<PackageVersion Include="Volo.Abp.Users.Domain.Shared" Version="$(VoloAbpPackageVersion)" />
<PackageVersion Include="Volo.Abp.Validation" Version="$(VoloAbpPackageVersion)" />
</ItemGroup>
<!-- .NET -->
<ItemGroup>
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="$(MicrosoftAspNetCorePackageVersion)" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.4" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="$(MicrosoftAspNetCorePackageVersion)" />
<PackageVersion Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="$(MicrosoftAspNetCorePackageVersion)" />
<PackageVersion Include="Microsoft.AspNetCore.SignalR.Protocols.Json" Version="$(MicrosoftAspNetCorePackageVersion)" />
@ -152,9 +150,8 @@
<PackageVersion Include="Microsoft.Extensions.Http" Version="$(MicrosoftExtensionsPackageVersion)" />
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="$(MicrosoftExtensionsPackageVersion)" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="$(MicrosoftExtensionsPackageVersion)" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="$(MicrosoftExtensionsPackageVersion)" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="8.0.2" />
</ItemGroup>
<!-- Elsa -->
<ItemGroup>
<PackageVersion Include="Elsa" Version="$(ElsaPackageVersion)" />
@ -172,7 +169,6 @@
<PackageVersion Include="Elsa.Webhooks.Persistence.EntityFramework.MySql" Version="$(ElsaPackageVersion)" />
<PackageVersion Include="Elsa.WorkflowSettings.Persistence.EntityFramework.MySql" Version="$(ElsaPackageVersion)" />
</ItemGroup>
<!-- DotNetCore.CAP -->
<ItemGroup>
<PackageVersion Include="DotNetCore.CAP" Version="$(DotNetCoreCAPPackageVersion)" />
@ -181,7 +177,6 @@
<PackageVersion Include="DotNetCore.CAP.OpenTelemetry" Version="$(DotNetCoreCAPPackageVersion)" />
<PackageVersion Include="DotNetCore.CAP.RabbitMQ" Version="$(DotNetCoreCAPPackageVersion)" />
</ItemGroup>
<!-- Serilog -->
<ItemGroup>
<PackageVersion Include="Serilog" Version="3.1.1" />
@ -198,7 +193,6 @@
<PackageVersion Include="Serilog.Sinks.Elasticsearch" Version="9.0.3" />
<PackageVersion Include="Serilog.Sinks.File" Version="5.0.0" />
</ItemGroup>
<!-- Test -->
<ItemGroup>
<PackageVersion Include="coverlet.collector" Version="6.0.0" />
@ -210,13 +204,11 @@
<PackageVersion Include="xunit.extensibility.execution" Version="2.6.1" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.3" />
</ItemGroup>
<!-- Fody -->
<ItemGroup>
<PackageVersion Include="ConfigureAwait.Fody" Version="3.3.2" />
<PackageVersion Include="Fody" Version="6.8.0" />
</ItemGroup>
<!-- Other -->
<ItemGroup>
<PackageVersion Include="aliyun-net-sdk-core" Version="1.5.10" />
@ -228,7 +220,7 @@
<PackageVersion Include="DistributedLock.Core" Version="1.0.5" />
<PackageVersion Include="DistributedLock.Redis" Version="1.0.2" />
<PackageVersion Include="Hangfire.MySqlStorage" Version="2.0.3" />
<PackageVersion Include="HangFire.SqlServer" Version="1.8.6" />
<PackageVersion Include="HangFire.SqlServer" Version="1.8.14" />
<PackageVersion Include="IdentityModel" Version="6.2.0" />
<PackageVersion Include="JetBrains.Annotations" Version="2023.3.0" />
<PackageVersion Include="Markdig" Version="0.34.0" />
@ -236,6 +228,8 @@
<PackageVersion Include="NEST" Version="7.15.1" />
<PackageVersion Include="NRules" Version="0.9.2" />
<PackageVersion Include="Ocelot.Provider.Polly" Version="20.0.0" />
<PackageVersion Include="OpenIddict.Server.DataProtection" Version="5.5.0" />
<PackageVersion Include="OpenIddict.Validation.DataProtection" Version="5.5.0" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.8.1" />
<PackageVersion Include="OpenTelemetry.Exporter.Console" Version="1.8.1" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.8.1" />

2
apps/vue/src/api/abp/localization/index.ts

@ -5,7 +5,7 @@ export const GetAsyncByInput = (input: {
onlyDynamics?: boolean;
}) => {
return defHttp.get<ApplicationLocalizationDto>({
url: 'api/abp/application-localization"',
url: '/api/abp/application-localization"',
params: input,
});
};

23
apps/vue/src/api/account/profiles/index.ts

@ -12,7 +12,9 @@ import {
AuthenticatorDto,
VerifyAuthenticatorCodeInput,
AuthenticatorRecoveryCodeDto,
GetUserSessionsInput,
} from './model';
import { IdentitySessionDto } from '../../identity/sessions/model';
export const get = () => {
return defHttp.get<MyProfile>({
@ -92,4 +94,25 @@ export const resetAuthenticator = () => {
return defHttp.post<void>({
url: '/api/account/my-profile/reset-authenticator',
});
}
/**
*
* @param { GetUserSessionsInput } input
* @returns { Promise<PagedResultDto<IdentitySessionDto>> }
*/
export const getSessions = (input?: GetUserSessionsInput): Promise<PagedResultDto<IdentitySessionDto>> => {
return defHttp.get<PagedResultDto<IdentitySessionDto>>({
url: '/api/account/my-profile/sessions',
params: input,
});
};
/**
*
* @param { string } sessionId id
* @returns { Promise<void> }
*/
export const revokeSession = (sessionId: string): Promise<void> => {
return defHttp.delete<void>({
url: `/api/account/my-profile/sessions/${sessionId}/revoke`,
});
}

5
apps/vue/src/api/account/profiles/model/index.ts

@ -60,4 +60,9 @@ interface Profile extends ExtensibleObject, IHasConcurrencyStamp {
export interface VerifyAuthenticatorCodeInput {
authenticatorCode: string;
}
export interface GetUserSessionsInput extends PagedAndSortedResultRequestDto {
device?: string;
clientId?: string;
}

2
apps/vue/src/api/auditing/security-logs/index.ts

@ -15,7 +15,7 @@ export const getById = (id: string) => {
export const getList = (input: GetSecurityLogPagedRequest) => {
return defHttp.get<PagedResultDto<SecurityLog>>({
url: 'api/auditing/security-log',
url: '/api/auditing/security-log',
params: input,
});
};

2
apps/vue/src/api/identity/claims/index.ts

@ -29,7 +29,7 @@ export const update = (id: string, input: UpdateIdentityClaimType) => {
export const getById = (id: string) => {
return defHttp.get<IdentityClaimType>({
url: `'/api/identity/claim-types/${id}'`,
url: `/api/identity/claim-types/${id}'`,
});
};

2
apps/vue/src/api/identity/organization-units/index.ts

@ -88,7 +88,7 @@ export const getAll = () => {
export const move = (id: string, parentId?: string) => {
return defHttp.put<void>({
url: `api/identity/organization-units/${id}/move`,
url: `/api/identity/organization-units/${id}/move`,
data: {
parentId: parentId,
},

27
apps/vue/src/api/identity/sessions/index.ts

@ -0,0 +1,27 @@
import { defHttp } from '/@/utils/http/axios';
import {
IdentitySessionDto,
GetUserSessionsInput
} from './model';
/**
*
* @param { GetUserSessionsInput } input
* @returns { Promise<PagedResultDto<IdentitySessionDto>> }
*/
export const getSessions = (input?: GetUserSessionsInput): Promise<PagedResultDto<IdentitySessionDto>> => {
return defHttp.get<PagedResultDto<IdentitySessionDto>>({
url: '/api/identity/sessions',
params: input,
});
};
/**
*
* @param { string } sessionId id
* @returns { Promise<void> }
*/
export const revokeSession = (sessionId: string): Promise<void> => {
return defHttp.delete<void>({
url: `/api/identity/sessions/${sessionId}/revoke`,
});
}

16
apps/vue/src/api/identity/sessions/model/index.ts

@ -0,0 +1,16 @@
export interface IdentitySessionDto extends EntityDto<string> {
sessionId: string;
device: string;
deviceInfo: string;
userId: string;
clientId?: string;
ipAddresses?: string;
signedIn: Date;
lastAccessed?: Date;
}
export interface GetUserSessionsInput extends PagedAndSortedResultRequestDto {
userId?: string;
device?: string;
clientId?: string;
}

2
apps/vue/src/api/localization/languages/index.ts

@ -16,7 +16,7 @@ export const getByName = (name: string) => {
export const create = (input: LanguageCreate) => {
return defHttp.post<Language>({
url: '/api/abp/localization/languages',
url: '/api/localization/languages',
data: input,
});
};

2
apps/vue/src/api/messages/friends/index.ts

@ -9,7 +9,7 @@ import {
export const create = (input: FriendCreateRequest) => {
return defHttp.post<void>({
url: 'api/im/my-friends',
url: '/api/im/my-friends',
data: input,
});
};

2
apps/vue/src/api/messages/groups/index.ts

@ -10,6 +10,6 @@ export const search = (input: GroupSearchRequest) => {
export const getById = (groupId: string) => {
return defHttp.get<Group>({
url: `'/api/im/groups/${groupId}`,
url: `/api/im/groups/${groupId}`,
});
};

4
apps/vue/src/api/multi-tenancy/tenants/index.ts

@ -3,12 +3,12 @@ import { FindTenantResult } from './model';
export const findTenantByName = (name: string) => {
return defHttp.get<FindTenantResult>({
url: `api/abp/multi-tenancy/tenants/by-name/${name}`
url: `/api/abp/multi-tenancy/tenants/by-name/${name}`
});
};
export const findTenantById = (id: string) => {
return defHttp.get<FindTenantResult>({
url: `api/abp/multi-tenancy/tenants/by-id/${id}`
url: `/api/abp/multi-tenancy/tenants/by-id/${id}`
});
};

208
apps/vue/src/layouts/default/header/components/notify/NoticeList.vue

@ -1,11 +1,11 @@
<template>
<a-list :class="prefixCls" bordered :pagination="getPagination">
<List :class="prefixCls" bordered :pagination="getPagination">
<template v-for="item in getData" :key="item.id">
<a-list-item class="list-item">
<a-list-item-meta>
<ListItem class="list-item">
<ListItemMeta>
<template #title>
<div class="title">
<a-typography-paragraph
<TypographyParagraph
@click="handleTitleClick(item)"
style="width: 100%; margin-bottom: 0 !important"
:style="{ cursor: isTitleClickable ? 'pointer' : '' }"
@ -18,22 +18,22 @@
:content="item.title"
/>
<div class="extra" v-if="item.extra">
<a-tag class="tag" :color="item.color">
<Tag class="tag" :color="item.color">
{{ item.extra }}
</a-tag>
</Tag>
</div>
</div>
</template>
<template #avatar>
<a-avatar v-if="item.avatar" class="avatar" :src="item.avatar" />
<Avatar v-if="item.avatar" class="avatar" :src="item.avatar" />
<span v-else> {{ item.avatar }}</span>
</template>
<template #description>
<div>
<div class="description" v-if="item.description">
<a-typography-paragraph
<TypographyParagraph
@click="handleContentClick(item)"
style="width: 100%; margin-bottom: 0 !important"
:style="{ cursor: isContentClickable ? 'pointer' : '' }"
@ -50,129 +50,109 @@
</div>
</div>
</template>
</a-list-item-meta>
</a-list-item>
</ListItemMeta>
</ListItem>
</template>
<template #footer>
<slot name="footer"></slot>
</template>
</a-list>
</List>
</template>
<script lang="ts">
import { computed, defineComponent, PropType, ref, watch, unref } from 'vue';
<script lang="ts" setup>
import { computed, PropType, ref, watchEffect, unref } from 'vue';
import { ListItem } from './data';
import { useDesign } from '/@/hooks/web/useDesign';
import { List, Avatar, Tag, Typography } from 'ant-design-vue';
import { NotificationContentType } from '/@/api/messages/notifications/model';
import { isNumber } from '/@/utils/is';
export default defineComponent({
components: {
[Avatar.name]: Avatar,
[List.name]: List,
[List.Item.name]: List.Item,
AListItemMeta: List.Item.Meta,
ATypographyParagraph: Typography.Paragraph,
[Tag.name]: Tag,
const TypographyParagraph = Typography.Paragraph;
const ListItem = List.Item;
const ListItemMeta = List.Item.Meta;
const emits = defineEmits(['update:currentPage']);
const props = defineProps({
list: {
type: Array as PropType<ListItem[]>,
default: () => [],
},
props: {
list: {
type: Array as PropType<ListItem[]>,
default: () => [],
},
pageSize: {
type: [Boolean, Number] as PropType<Boolean | Number>,
default: 5,
},
currentPage: {
type: Number,
default: 1,
},
titleRows: {
type: Number,
default: 1,
},
descRows: {
type: Number,
default: 2,
},
onTitleClick: {
type: Function as PropType<(Recordable) => void>,
},
onContentClick: {
type: Function as PropType<(Recordable) => void>,
},
pageSize: {
type: [Boolean, Number] as PropType<Boolean | Number>,
default: 5,
},
emits: ['update:currentPage'],
setup(props, { emit }) {
const { prefixCls } = useDesign('header-notify-list');
const current = ref(props.currentPage || 1);
const getData = computed(() => {
const { pageSize, list } = props;
if (pageSize === false) return [];
let size = isNumber(pageSize) ? pageSize : 10;
return list.slice(size * (unref(current) - 1), size * unref(current));
});
const getContent = computed(() => {
return (item: ListItem) => {
switch (item.contentType) {
default:
case NotificationContentType.Text:
return item.description;
case NotificationContentType.Html:
case NotificationContentType.Json:
case NotificationContentType.Markdown:
return item.title;
}
};
});
watch(
() => props.currentPage,
(v) => {
current.value = v;
},
);
const isTitleClickable = computed(() => !!props.onTitleClick);
const isContentClickable = computed(() => !!props.onContentClick);
const getPagination = computed(() => {
const { list, pageSize } = props;
if (pageSize === false) return false;
const size = isNumber(pageSize) ? pageSize : 5;
if (size > 0 && list && list.length > size) {
return {
total: list.length,
pageSize: size,
//size: 'small',
current: unref(current),
onChange(page) {
current.value = page;
emit('update:currentPage', page);
},
};
} else {
return false;
}
});
function handleTitleClick(item: ListItem) {
props.onTitleClick && props.onTitleClick(item);
}
currentPage: {
type: Number,
default: 1,
},
titleRows: {
type: Number,
default: 1,
},
descRows: {
type: Number,
default: 2,
},
onTitleClick: {
type: Function as PropType<(Recordable) => void>,
},
onContentClick: {
type: Function as PropType<(Recordable) => void>,
}
});
function handleContentClick(item: ListItem) {
props.onContentClick && props.onContentClick(item);
const { prefixCls } = useDesign('header-notify-list');
const current = ref(props.currentPage || 1);
const getData = computed(() => {
const { pageSize, list } = props;
if (pageSize === false) return [];
let size = isNumber(pageSize) ? pageSize : 10;
return list.slice(size * (unref(current) - 1), size * unref(current));
});
const getContent = computed(() => {
return (item: ListItem) => {
switch (item.contentType) {
default:
case NotificationContentType.Text:
return item.description;
case NotificationContentType.Html:
case NotificationContentType.Json:
case NotificationContentType.Markdown:
return item.title;
}
};
});
watchEffect(() => {
current.value = props.currentPage;
});
const isTitleClickable = computed(() => !!props.onTitleClick);
const isContentClickable = computed(() => !!props.onContentClick);
const getPagination = computed(() => {
const { list, pageSize } = props;
if (pageSize === false) return false;
const size = isNumber(pageSize) ? pageSize : 5;
if (size > 0 && list && list.length > size) {
return {
prefixCls,
getPagination,
getData,
getContent,
handleTitleClick,
isTitleClickable,
handleContentClick,
isContentClickable,
total: list.length,
pageSize: size,
//size: 'small',
current: unref(current),
onChange(page) {
current.value = page;
emits('update:currentPage', page);
},
};
},
} else {
return false;
}
});
function handleTitleClick(item: ListItem) {
props.onTitleClick && props.onTitleClick(item);
}
function handleContentClick(item: ListItem) {
props.onContentClick && props.onContentClick(item);
}
</script>
<style lang="less" scoped>
@prefix-cls: ~'@{namespace}-header-notify-list';

126
apps/vue/src/layouts/default/header/components/notify/index.vue

@ -1,6 +1,6 @@
<template>
<div :class="prefixCls">
<Badge :count="count" dot :numberStyle="numberStyle">
<Badge :count="count" dot :numberStyle="{}">
<BellOutlined @click="showDrawer" />
</Badge>
<Drawer
@ -39,44 +39,11 @@
</TabPane>
</Tabs>
</Drawer>
<!-- <Popover title="" trigger="click" :overlayClassName="`${prefixCls}__overlay`">
<Badge :count="count" dot :numberStyle="numberStyle">
<BellOutlined />
</Badge>
<template #content>
<Tabs>
<TabPane :key="notifierRef.key" :tab="notifierRef.name">
<NoticeList :list="notifierRef.list" @title-click="readNotifer" />
</TabPane>
<TabPane :key="messageRef.key" :tab="messageRef.name">
<NoticeList :list="messageRef.list">
<template #footer>
<ButtonGroup style="width: 100%">
<Button
:disabled="messageRef.list.length === 0"
style="width: 50%"
type="link"
@click="clearMessage"
>清空消息</Button
>
<Button style="width: 50%" type="link" @click="handleShowMessages"
>查看更多</Button
>
</ButtonGroup>
</template>
</NoticeList>
</TabPane>
<TabPane :key="tasksRef.key" :tab="tasksRef.name">
<NoticeList :list="tasksRef.list" />
</TabPane>
</Tabs>
</template>
</Popover> -->
</div>
</template>
<script lang="ts">
import { computed, defineComponent, ref } from 'vue';
import { Button, Drawer, Popover, Tabs, Badge } from 'ant-design-vue';
<script lang="ts" setup>
import { computed, ref } from 'vue';
import { Button, Drawer, Tabs, Badge } from 'ant-design-vue';
import { BellOutlined } from '@ant-design/icons-vue';
import NoticeList from './NoticeList.vue';
import { useGo } from '/@/hooks/web/usePage';
@ -85,67 +52,40 @@
import { useMessages } from './useMessages';
import { useNotifications } from './useNotifications';
export default defineComponent({
components: {
Button,
ButtonGroup: Button.Group,
Drawer,
Popover,
BellOutlined,
Tabs,
TabPane: Tabs.TabPane,
Badge,
NoticeList,
},
setup() {
const { prefixCls } = useDesign('header-notify');
const go = useGo();
const open = ref(false);
const { tasksRef } = useTasks();
const { messageRef, clearMessage } = useMessages();
const { notifierRef, readNotifer } = useNotifications();
// const listData = ref(tabListData);
const ButtonGroup = Button.Group;
const TabPane = Tabs.TabPane;
const count = computed(() => {
let count = 0;
count += notifierRef.value.list.length;
count += messageRef.value.list.length;
count += tasksRef.value.list.length;
return count;
});
const { prefixCls } = useDesign('header-notify');
const go = useGo();
const open = ref(false);
const { tasksRef } = useTasks();
const { messageRef, clearMessage } = useMessages();
const { notifierRef, readNotifer } = useNotifications();
// const listData = ref(tabListData);
function handleShowMessages() {
console.log('handleShowMessages');
go('/sys/chat?type=chat-message');
}
const count = computed(() => {
let count = 0;
count += notifierRef.value.list.length;
count += messageRef.value.list.length;
count += tasksRef.value.list.length;
return count;
});
function handleShowNotifications() {
console.log('handleShowNotifications');
open.value = false;
go('/messages/notifications');
}
function handleShowMessages() {
console.log('handleShowMessages');
go('/sys/chat?type=chat-message');
}
function showDrawer() {
console.log('showDrawer');
open.value = true;
}
function handleShowNotifications() {
console.log('handleShowNotifications');
open.value = false;
go('/messages/notifications');
}
return {
prefixCls,
count,
numberStyle: {},
open,
showDrawer,
notifierRef,
readNotifer,
messageRef,
clearMessage,
tasksRef,
handleShowMessages,
handleShowNotifications,
};
},
});
function showDrawer() {
console.log('showDrawer');
open.value = true;
}
</script>
<style lang="less">
@prefix-cls: ~'@{namespace}-header-notify';

17
apps/vue/src/layouts/default/header/components/notify/useNotifications.ts

@ -44,6 +44,10 @@ export function useNotifications() {
});
function onNotifyReceived(notificationInfo: NotificationInfo, notifer?: boolean) {
if (notificationInfo.type === NotificationType.ServiceCallback) {
emitter.emit(NotifyEventEnum.NOTIFICATIONS_SERVICE_CALLBACK, notificationInfo);
return;
}
const { data } = notificationInfo;
let title = data.extraProperties.title;
let message = data.extraProperties.message;
@ -83,16 +87,9 @@ export function useNotifications() {
contentType: notificationInfo.contentType,
};
if (notifer && notificationInfo.type !== NotificationType.ServiceCallback) {
_notification(notifier, notificationInfo.severity);
}
if (notificationInfo.type === NotificationType.ServiceCallback) {
emitter.emit(NotifyEventEnum.NOTIFICATIONS_SERVICE_CALLBACK, notificationInfo);
} else {
emitter.emit(NotifyEventEnum.NOTIFICATIONS_RECEVIED, notificationInfo);
notifierRef.value.list.push(notifier);
}
notifer && _notification(notifier, notificationInfo.severity);
emitter.emit(NotifyEventEnum.NOTIFICATIONS_RECEVIED, notificationInfo);
notifierRef.value.list.push(notifier);
}

16
apps/vue/src/layouts/default/header/components/user-dropdown/index.vue

@ -26,6 +26,11 @@
:text="t('AbpAuditLogging.SecurityLog')"
icon="ant-design:security-scan-outlined"
/>
<MenuItem
key="sessions"
:text="t('AbpIdentity.IdentitySessions')"
icon="carbon:prompt-session"
/>
<MenuDivider />
<MenuItem
v-if="getUseLockPage"
@ -42,6 +47,7 @@
</template>
</Dropdown>
<LockAction @register="register" />
<SessionModal @register="registerSessionModal" />
<SecurityLogsModal @register="registerSecurityLogsModal" />
</template>
<script lang="ts">
@ -67,7 +73,7 @@
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
type MenuEvent = 'logout' | 'doc' | 'lock' | 'setting' | 'center' | 'security-logs';
type MenuEvent = 'logout' | 'doc' | 'lock' | 'setting' | 'center' | 'sessions' | 'security-logs';
export default defineComponent({
name: 'UserDropdown',
@ -77,6 +83,9 @@
MenuItem: createAsyncComponent(() => import('./DropMenuItem.vue')),
MenuDivider: Menu.Divider,
LockAction: createAsyncComponent(() => import('../lock/LockModal.vue')),
SessionModal: createAsyncComponent(
() => import('/@/views/account/sessions/index.vue'),
),
SecurityLogsModal: createAsyncComponent(
() => import('/@/views/account/security-logs/index.vue'),
),
@ -107,6 +116,7 @@
});
const [register, { openModal }] = useModal();
const [registerSessionModal, { openModal: openSessionModal }] = useModal();
const [registerSecurityLogsModal, { openModal: openSecurityLogsModal }] = useModal();
function handleLock() {
@ -140,6 +150,9 @@
case 'center':
go('/account/center');
break;
case 'sessions':
openSessionModal(true, {});
break;
case 'security-logs':
openSecurityLogsModal(true, {});
break;
@ -154,6 +167,7 @@
getShowDoc,
register,
getUseLockPage,
registerSessionModal,
registerSecurityLogsModal,
};
},

61
apps/vue/src/views/account/security-logs/index.vue

@ -9,45 +9,23 @@
:can-fullscreen="false"
:show-ok-btn="false"
>
<Card style="height: 100%">
<div :style="getContentStyle" ref="contentWrapRef">
<ScrollContainer ref="contentScrollRef">
<template v-for="securityLog in securityLogs" :key="securityLog.id">
<CardGrid>
<Form
layout="horizontal"
:colon="false"
:model="securityLog"
:labelCol="{ span: 4 }"
:wrapperCol="{ span: 16 }"
>
<FormItem labelAlign="left" :label="L('ApplicationName')">
<span>{{ securityLog.applicationName }}</span>
</FormItem>
<FormItem labelAlign="left" :label="L('Identity')">
<span>{{ securityLog.identity }}</span>
</FormItem>
<FormItem labelAlign="left" :label="L('Actions')">
<span>{{ securityLog.action }}</span>
</FormItem>
<FormItem labelAlign="left" :label="L('ClientId')">
<span>{{ securityLog.clientId }}</span>
</FormItem>
<FormItem labelAlign="left" :label="L('ClientIpAddress')">
<span>{{ securityLog.clientIpAddress }}</span>
</FormItem>
<FormItem labelAlign="left" :label="L('BrowserInfo')">
<span>{{ securityLog.browserInfo }}</span>
</FormItem>
<FormItem labelAlign="left" :label="L('CreationTime')">
<span>{{ formatToDateTime(securityLog.creationTime) }}</span>
</FormItem>
</Form>
</CardGrid>
</template>
</ScrollContainer>
</div>
</Card>
<div :style="getContentStyle" ref="contentWrapRef">
<ScrollContainer ref="contentScrollRef">
<template v-for="securityLog in securityLogs" :key="securityLog.id">
<Card hoverable style="height: 100%; margin-bottom: 15px;">
<Descriptions bordered size="small" :column="1">
<DescriptionItem :label="L('ApplicationName')">{{ securityLog.applicationName }}</DescriptionItem>
<DescriptionItem :label="L('Identity')">{{ securityLog.identity }}</DescriptionItem>
<DescriptionItem :label="L('Actions')">{{ securityLog.action }}</DescriptionItem>
<DescriptionItem :label="L('ClientId')">{{ securityLog.clientId }}</DescriptionItem>
<DescriptionItem :label="L('ClientIpAddress')">{{ securityLog.clientIpAddress }}</DescriptionItem>
<DescriptionItem :label="L('BrowserInfo')">{{ formatToDateTime(securityLog.browserInfo) }}</DescriptionItem>
<DescriptionItem :label="L('CreationTime')">{{ formatToDateTime(securityLog.creationTime) }}</DescriptionItem>
</Descriptions>
</Card>
</template>
</ScrollContainer>
</div>
<template #footer>
<APagination
ref="paginationRef"
@ -63,7 +41,7 @@
<script lang="ts" setup>
import type { CSSProperties } from 'vue';
import { computed, ref } from 'vue';
import { Card, Form, Pagination } from 'ant-design-vue';
import { Card, Descriptions, Pagination } from 'ant-design-vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { ScrollContainer } from '/@/components/Container';
import { useLocalization } from '/@/hooks/abp/useLocalization';
@ -74,9 +52,8 @@
import { formatPagedRequest } from '/@/utils/http/abp/helper';
import { formatToDateTime } from '/@/utils/dateUtil';
const CardGrid = Card.Grid;
const FormItem = Form.Item;
const APagination = Pagination;
const DescriptionItem = Descriptions.Item;
const props = defineProps({
autoContentHeight: {

141
apps/vue/src/views/account/sessions/index.vue

@ -0,0 +1,141 @@
<template>
<BasicModal
v-bind="$attrs"
@register="registerModal"
:width="800"
:height="500"
:title="L('IdentitySessions')"
:mask-closable="false"
:can-fullscreen="false"
:show-ok-btn="false"
>
<div :style="getContentStyle" ref="contentWrapRef" class="session">
<ScrollContainer ref="contentScrollRef">
<template v-for="identitySession in identitySessions" :key="identitySession.id">
<Card style="height: 100%">
<template #title>
<div class="session__tile">
<span>{{ identitySession.device }}</span>
<div style="padding-left: 5px;">
<Tag
v-if="identitySession.sessionId === abpStore.getApplication.currentUser.sessionId"
color="#87d068"
>{{ L('CurrentSession') }}</Tag>
</div>
</div>
</template>
<Descriptions bordered size="small" :column="1">
<DescriptionItem :label="L('DisplayName:SessionId')">{{ identitySession.sessionId }}</DescriptionItem>
<DescriptionItem :label="L('DisplayName:Device')">{{ identitySession.device }}</DescriptionItem>
<DescriptionItem :label="L('DisplayName:DeviceInfo')">{{ identitySession.deviceInfo }}</DescriptionItem>
<DescriptionItem :label="L('DisplayName:ClientId')">{{ identitySession.clientId }}</DescriptionItem>
<DescriptionItem :label="L('DisplayName:IpAddresses')">{{ identitySession.ipAddresses }}</DescriptionItem>
<DescriptionItem :label="L('DisplayName:SignedIn')">{{ formatToDateTime(identitySession.signedIn) }}</DescriptionItem>
<DescriptionItem v-if="identitySession.lastAccessed" :label="L('DisplayName:LastAccessed')">{{ formatToDateTime(identitySession.lastAccessed) }}</DescriptionItem>
</Descriptions>
<template #extra>
<Button
v-if="identitySession.sessionId !== abpStore.getApplication.currentUser.sessionId"
danger
@click="handleRevokeSession(identitySession)"
>{{ L('RevokeSession') }}</Button>
</template>
</Card>
</template>
</ScrollContainer>
</div>
<template #footer>
<APagination
ref="paginationRef"
:pageSizeOptions="['10', '25', '50', '100']"
:total="identitySessionTotal"
@change="fetchSessions"
@showSizeChange="fetchSessions"
/>
</template>
</BasicModal>
</template>
<script lang="ts" setup>
import type { CSSProperties } from 'vue';
import { computed, ref } from 'vue';
import { Button, Card, Descriptions, Pagination, Tag } from 'ant-design-vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { ScrollContainer } from '/@/components/Container';
import { useMessage } from '/@/hooks/web/useMessage';
import { useLocalization } from '/@/hooks/abp/useLocalization';
import { useContentHeight } from '/@/hooks/web/useContentHeight';
import { useAbpStoreWithOut } from '/@/store/modules/abp';
import { getSessions, revokeSession } from '/@/api/account/profiles';
import { IdentitySessionDto } from '/@/api/identity/sessions/model';
import { formatPagedRequest } from '/@/utils/http/abp/helper';
import { formatToDateTime } from '/@/utils/dateUtil';
const DescriptionItem = Descriptions.Item;
const APagination = Pagination;
const props = defineProps({
autoContentHeight: {
type: Boolean,
default: true,
},
});
const contentWrapRef = ref<any>();
const contentScrollRef = ref<any>();
const paginationRef = ref<any>();
const getContentHeight = computed(() => props.autoContentHeight);
const { contentHeight } = useContentHeight(getContentHeight, contentWrapRef, [paginationRef], []);
const getContentStyle = computed((): CSSProperties => {
return {
width: '100%',
height: `${contentHeight.value}px`,
};
});
const identitySessions = ref<IdentitySessionDto[]>([]);
const identitySessionTotal = ref(0);
const abpStore = useAbpStoreWithOut();
const { createConfirm, createMessage } = useMessage();
const { L } = useLocalization(['AbpIdentity', 'AbpUi']);
const [registerModal] = useModalInner(() => {
fetchSessions();
});
function fetchSessions(page: number = 1, pageSize: number = 10) {
const request = {
skipCount: page,
maxResultCount: pageSize,
};
formatPagedRequest(request);
getSessions({
skipCount: request.skipCount,
maxResultCount: request.maxResultCount,
}).then((res) => {
identitySessions.value = res.items;
identitySessionTotal.value = res.totalCount;
});
}
function handleRevokeSession(session: IdentitySessionDto) {
createConfirm({
iconType: 'warning',
title: L('AreYouSure'),
content: L('SessionWillBeRevokedMessage'),
onOk: async () => {
await revokeSession(session.sessionId);
createMessage.success(L('SuccessfullyRevoked'));
fetchSessions();
},
});
}
</script>
<style lang="less" scoped>
.session {
.session__tile {
display: flex;
flex-direction: row;
}
}
</style>

150
apps/vue/src/views/identity/user/components/SessionModal.vue

@ -0,0 +1,150 @@
<template>
<BasicModal
v-bind="$attrs"
@register="registerModal"
:width="800"
:height="500"
:title="L('IdentitySessions')"
:mask-closable="false"
:can-fullscreen="false"
:show-ok-btn="false"
>
<div v-if="identitySessions.length <= 0">
<Empty />
</div>
<div v-else :style="getContentStyle" ref="contentWrapRef" class="session">
<ScrollContainer ref="contentScrollRef">
<template v-for="identitySession in identitySessions" :key="identitySession.id">
<Card style="height: 100%">
<template #title>
<div class="session__tile">
<span>{{ identitySession.device }}</span>
<div style="padding-left: 5px;">
<Tag
v-if="identitySession.sessionId === abpStore.getApplication.currentUser.sessionId"
color="#87d068"
>{{ L('CurrentSession') }}</Tag>
</div>
</div>
</template>
<Descriptions bordered size="small" :column="1">
<DescriptionItem :label="L('DisplayName:SessionId')">{{ identitySession.sessionId }}</DescriptionItem>
<DescriptionItem :label="L('DisplayName:Device')">{{ identitySession.device }}</DescriptionItem>
<DescriptionItem :label="L('DisplayName:DeviceInfo')">{{ identitySession.deviceInfo }}</DescriptionItem>
<DescriptionItem :label="L('DisplayName:ClientId')">{{ identitySession.clientId }}</DescriptionItem>
<DescriptionItem :label="L('DisplayName:IpAddresses')">{{ identitySession.ipAddresses }}</DescriptionItem>
<DescriptionItem :label="L('DisplayName:SignedIn')">{{ formatToDateTime(identitySession.signedIn) }}</DescriptionItem>
<DescriptionItem v-if="identitySession.lastAccessed" :label="L('DisplayName:LastAccessed')">{{ formatToDateTime(identitySession.lastAccessed) }}</DescriptionItem>
</Descriptions>
<template #extra>
<Button
v-auth="['AbpIdentity.IdentitySessions.Revoke']"
v-if="identitySession.sessionId !== abpStore.getApplication.currentUser.sessionId"
danger
@click="handleRevokeSession(identitySession)"
>{{ L('RevokeSession') }}</Button>
</template>
</Card>
</template>
</ScrollContainer>
</div>
<template #footer>
<APagination
v-if="identitySessions.length > 0"
ref="paginationRef"
:pageSizeOptions="['10', '25', '50', '100']"
:total="identitySessionTotal"
@change="fetchSessions"
@showSizeChange="fetchSessions"
/>
</template>
</BasicModal>
</template>
<script lang="ts" setup>
import type { CSSProperties } from 'vue';
import { computed, ref } from 'vue';
import { Button, Card, Descriptions, Empty, Pagination, Tag } from 'ant-design-vue';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { ScrollContainer } from '/@/components/Container';
import { useMessage } from '/@/hooks/web/useMessage';
import { useLocalization } from '/@/hooks/abp/useLocalization';
import { useContentHeight } from '/@/hooks/web/useContentHeight';
import { useAbpStoreWithOut } from '/@/store/modules/abp';
import { getSessions, revokeSession } from '/@/api/identity/sessions';
import { IdentitySessionDto } from '/@/api/identity/sessions/model';
import { formatPagedRequest } from '/@/utils/http/abp/helper';
import { formatToDateTime } from '/@/utils/dateUtil';
const DescriptionItem = Descriptions.Item;
const APagination = Pagination;
const props = defineProps({
autoContentHeight: {
type: Boolean,
default: true,
},
});
const userId = ref('');
const contentWrapRef = ref<any>();
const contentScrollRef = ref<any>();
const paginationRef = ref<any>();
const getContentHeight = computed(() => props.autoContentHeight);
const { contentHeight } = useContentHeight(getContentHeight, contentWrapRef, [paginationRef], []);
const getContentStyle = computed((): CSSProperties => {
return {
width: '100%',
height: `${contentHeight.value}px`,
};
});
const identitySessions = ref<IdentitySessionDto[]>([]);
const identitySessionTotal = ref(0);
const abpStore = useAbpStoreWithOut();
const { createConfirm, createMessage } = useMessage();
const { L } = useLocalization(['AbpIdentity', 'AbpUi']);
const [registerModal] = useModalInner((data: { userId: string }) => {
userId.value = data.userId;
identitySessions.value = [];
fetchSessions();
});
function fetchSessions(page: number = 1, pageSize: number = 10) {
const request = {
skipCount: page,
maxResultCount: pageSize,
};
formatPagedRequest(request);
getSessions({
userId: userId.value,
skipCount: request.skipCount,
maxResultCount: request.maxResultCount,
}).then((res) => {
identitySessions.value = res.items;
identitySessionTotal.value = res.totalCount;
});
}
function handleRevokeSession(session: IdentitySessionDto) {
createConfirm({
iconType: 'warning',
title: L('AreYouSure'),
content: L('SessionWillBeRevokedMessage'),
onOk: async () => {
await revokeSession(session.sessionId);
createMessage.success(L('SuccessfullyRevoked'));
fetchSessions();
},
});
}
</script>
<style lang="less" scoped>
.session {
.session__tile {
display: flex;
flex-direction: row;
}
}
</style>

13
apps/vue/src/views/identity/user/components/UserTable.vue

@ -57,6 +57,11 @@
ifShow: !lockEnd(record),
onClick: showLockModal.bind(null, record.id),
},
{
auth: 'AbpIdentity.IdentitySessions',
label: L('IdentitySessions'),
onClick: handleShowSessionModal.bind(null, record),
},
{
auth: 'AbpIdentity.Users.Update',
label: L('UnLock'),
@ -90,6 +95,7 @@
</template>
</BasicTable>
<UserModal @register="registerModal" @change="reloadTable" />
<SessionModal @register="registerSessionModal" />
<PermissionModal @register="registerPermissionModal" />
<PasswordModal @register="registerPasswordModal" />
<ClaimModal
@ -129,11 +135,13 @@
updateClaim,
deleteClaim,
} from '/@/api/identity/users';
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
import UserModal from './UserModal.vue';
import PasswordModal from './PasswordModal.vue';
import LockModal from './LockModal.vue';
import MenuModal from '../../components/MenuModal.vue';
import ClaimModal from '../../components/ClaimModal.vue';
const SessionModal = createAsyncComponent(() => import('./SessionModal.vue'));
const emits = defineEmits(['change']);
@ -146,6 +154,7 @@
const { registerLockModal, showLockModal, handleUnLock } = useLock({ emit: emits });
const { registerPasswordModal, showPasswordModal } = usePassword(nullFormElRef);
const [registerClaimModal, { openModal: openClaimModal }] = useModal();
const [registerSessionModal, { openModal: openSessionModal }] = useModal();
const [registerMenuModal, { openModal: openMenuModal, closeModal: closeMenuModal }] = useModal();
const { registerModel: registerPermissionModal, showPermissionModal } = usePermissionModal();
@ -188,4 +197,8 @@
function handleShowClaims(record) {
openClaimModal(true, { id: record.id });
}
function handleShowSessionModal(record) {
openSessionModal(true, { userId: record.id });
}
</script>

1
apps/vue/types/abp.d.ts

@ -110,6 +110,7 @@ declare interface CurrentUser {
phoneNumber?: string;
phoneNumberVerified: boolean;
roles: string[];
sessionId?: string;
}
type SimpleStateCheckerResult<TState extends IHasSimpleStateCheckers<TState>> = Recordable<

248
aspnet-core/LINGYUN.MicroService.All.sln

@ -742,73 +742,21 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.OpenApi.OpenIdd
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.TextTemplating.Scriban", "modules\text-templating\LINGYUN.Abp.TextTemplating.Scriban\LINGYUN.Abp.TextTemplating.Scriban.csproj", "{15482834-9242-4D20-9736-9DA571A9A83A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Claims.Mapping", "framework\security\LINGYUN.Abp.Claims.Mapping\LINGYUN.Abp.Claims.Mapping.csproj", "{8A255A72-50FC-460E-9897-FA53F455580B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Claims.Mapping", "framework\security\LINGYUN.Abp.Claims.Mapping\LINGYUN.Abp.Claims.Mapping.csproj", "{8A255A72-50FC-460E-9897-FA53F455580B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.WeChat.Work.Common", "framework\wechat\LINGYUN.Abp.WeChat.Work.Common\LINGYUN.Abp.WeChat.Work.Common.csproj", "{46038910-8EDD-4822-8768-097B7D276FED}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.WeChat.Work.Common", "framework\wechat\LINGYUN.Abp.WeChat.Work.Common\LINGYUN.Abp.WeChat.Work.Common.csproj", "{CED33625-A034-475B-A4C0-A4E7D1BADD10}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.TaskManagement.Domain.Shared", "modules\task-management\LINGYUN.Abp.TaskManagement.Domain.Shared\LINGYUN.Abp.TaskManagement.Domain.Shared.csproj", "{332F2031-6B67-4199-8BA4-317679D2FFF8}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Session", "modules\identity\LINGYUN.Abp.Identity.Session\LINGYUN.Abp.Identity.Session.csproj", "{E3BA2413-5755-4F61-9A7C-5D49AE9E7016}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.BackgroundTasks", "modules\task-management\LINGYUN.Abp.BackgroundTasks\LINGYUN.Abp.BackgroundTasks.csproj", "{C8138D8C-BF2B-41CB-BEA2-3ACC5E70E306}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Session.AspNetCore", "modules\identity\LINGYUN.Abp.Identity.Session.AspNetCore\LINGYUN.Abp.Identity.Session.AspNetCore.csproj", "{BF85DB7F-70C2-4804-AA57-FACE204981DA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.BackgroundTasks.Quartz", "modules\task-management\LINGYUN.Abp.BackgroundTasks.Quartz\LINGYUN.Abp.BackgroundTasks.Quartz.csproj", "{FF53669D-560C-4791-BE9A-28231C15FA4E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer.Session", "modules\identityServer\LINGYUN.Abp.IdentityServer.Session\LINGYUN.Abp.IdentityServer.Session.csproj", "{893F7376-0913-43DC-AD3D-40AF5B8F9E3B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.BackgroundTasks.DistributedLocking", "modules\task-management\LINGYUN.Abp.BackgroundTasks.DistributedLocking\LINGYUN.Abp.BackgroundTasks.DistributedLocking.csproj", "{2F8BB49E-92E5-4468-8656-BD4BC03FA505}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.AspNetCore.Session", "modules\identity\LINGYUN.Abp.Identity.AspNetCore.Session\LINGYUN.Abp.Identity.AspNetCore.Session.csproj", "{8826831D-8733-473A-B47B-A30C3732B13D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.BackgroundTasks.ExceptionHandling", "modules\task-management\LINGYUN.Abp.BackgroundTasks.ExceptionHandling\LINGYUN.Abp.BackgroundTasks.ExceptionHandling.csproj", "{5CAC42F1-58A4-4716-B8E5-E28042D1B612}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.OpenIddict.AspNetCore.Session", "modules\openIddict\LINGYUN.Abp.OpenIddict.AspNetCore.Session\LINGYUN.Abp.OpenIddict.AspNetCore.Session.csproj", "{D1484DD3-BB0A-45A4-BED5-FFA132DE2E72}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.TaskManagement.EntityFrameworkCore", "modules\task-management\LINGYUN.Abp.TaskManagement.EntityFrameworkCore\LINGYUN.Abp.TaskManagement.EntityFrameworkCore.csproj", "{7D235CB7-EC8E-418F-978A-D2E6EA5F9E9A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.BackgroundTasks.Activities", "modules\task-management\LINGYUN.Abp.BackgroundTasks.Activities\LINGYUN.Abp.BackgroundTasks.Activities.csproj", "{F78B0978-4ECF-4EA3-89A7-9492AE33CB30}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.TaskManagement.Domain", "modules\task-management\LINGYUN.Abp.TaskManagement.Domain\LINGYUN.Abp.TaskManagement.Domain.csproj", "{7C1A3331-D3D0-4CF0-A7D4-9E27F507AB02}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.TaskManagement.Application", "modules\task-management\LINGYUN.Abp.TaskManagement.Application\LINGYUN.Abp.TaskManagement.Application.csproj", "{DC4AB835-76CA-4439-9A14-473B3838F856}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.BackgroundTasks.EventBus", "modules\task-management\LINGYUN.Abp.BackgroundTasks.EventBus\LINGYUN.Abp.BackgroundTasks.EventBus.csproj", "{3310571F-1B30-49A4-AD24-0CF5C91C58F7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.TaskManagement.HttpApi", "modules\task-management\LINGYUN.Abp.TaskManagement.HttpApi\LINGYUN.Abp.TaskManagement.HttpApi.csproj", "{00C8A2BC-361D-4999-AEC3-BA4DD7991A9D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.WebhooksManagement.Application.Contracts", "modules\webhooks\LINGYUN.Abp.WebhooksManagement.Application.Contracts\LINGYUN.Abp.WebhooksManagement.Application.Contracts.csproj", "{D60CF8FB-45BB-4F95-97EB-E1CE54B3105A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.WebhooksManagement.Application", "modules\webhooks\LINGYUN.Abp.WebhooksManagement.Application\LINGYUN.Abp.WebhooksManagement.Application.csproj", "{7D83C686-7BF0-4037-B927-A502D55D01F8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.WebhooksManagement.Domain", "modules\webhooks\LINGYUN.Abp.WebhooksManagement.Domain\LINGYUN.Abp.WebhooksManagement.Domain.csproj", "{C7F7F9E2-F877-4658-BFEC-E47AE27B0139}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.WebhooksManagement.Domain.Shared", "modules\webhooks\LINGYUN.Abp.WebhooksManagement.Domain.Shared\LINGYUN.Abp.WebhooksManagement.Domain.Shared.csproj", "{2BC04B60-6959-47FF-8860-96AB51986584}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore", "modules\webhooks\LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore\LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore.csproj", "{1752BAA2-4305-4655-99B4-6832E2CE6CAF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.WebhooksManagement.HttpApi", "modules\webhooks\LINGYUN.Abp.WebhooksManagement.HttpApi\LINGYUN.Abp.WebhooksManagement.HttpApi.csproj", "{6F2A09CE-183E-4FBA-BB12-DD6105B90B00}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.WebhooksManagement.HttpApi.Client", "modules\webhooks\LINGYUN.Abp.WebhooksManagement.HttpApi.Client\LINGYUN.Abp.WebhooksManagement.HttpApi.Client.csproj", "{5E3E2B57-4BF1-45A7-9BAE-EDA000F27C80}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LY.MicroService.TaskManagement.HttpApi.Host", "services\LY.MicroService.TaskManagement.HttpApi.Host\LY.MicroService.TaskManagement.HttpApi.Host.csproj", "{7D760508-A5A8-44D9-8958-F5AD5F1B7949}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "task", "task", "{C1EFDD32-5524-4DDD-9925-88B6E3530994}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LY.MicroService.WebhooksManagement.HttpApi.Host", "services\LY.MicroService.WebhooksManagement.HttpApi.Host\LY.MicroService.WebhooksManagement.HttpApi.Host.csproj", "{2D3B6C77-465E-4D39-A83D-47E74F14D6D0}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "webhooks", "webhooks", "{0107020D-22E5-4DDF-8A62-5DE850BA6C79}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LY.MicroService.WorkflowManagement.HttpApi.Host", "services\LY.MicroService.WorkflowManagement.HttpApi.Host\LY.MicroService.WorkflowManagement.HttpApi.Host.csproj", "{E8139252-2F6D-437D-97C7-6FB77C705E58}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflow", "workflow", "{74319001-6F4B-41D9-BE32-128EC12AB10B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.BackgroundTasks.Notifications", "modules\task-management\LINGYUN.Abp.BackgroundTasks.Notifications\LINGYUN.Abp.BackgroundTasks.Notifications.csproj", "{40FEF2F7-BB0E-4192-89EE-BDA98B3E4007}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LY.MicroService.TaskManagement.EntityFrameworkCore", "migrations\LY.MicroService.TaskManagement.EntityFrameworkCore\LY.MicroService.TaskManagement.EntityFrameworkCore.csproj", "{CE309DF2-FB96-4917-9DC6-14DC1DED7EED}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "task", "task", "{A922E0EE-5302-4E2B-9D84-0EC681416DA2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Webhooks.Identity", "modules\webhooks\LINGYUN.Abp.Webhooks.Identity\LINGYUN.Abp.Webhooks.Identity.csproj", "{27505FC3-2659-40CC-A9C7-0857FBECE099}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Webhooks.Saas", "modules\webhooks\LINGYUN.Abp.Webhooks.Saas\LINGYUN.Abp.Webhooks.Saas.csproj", "{1E6F9CF8-577C-45A7-A2E0-2BB3C40AFB9D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Webhooks.EventBus", "modules\webhooks\LINGYUN.Abp.Webhooks.EventBus\LINGYUN.Abp.Webhooks.EventBus.csproj", "{65951546-93DB-4415-94C5-2B7B1E232A3E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LY.MicroService.WebhooksManagement.EntityFrameworkCore", "migrations\LY.MicroService.WebhooksManagement.EntityFrameworkCore\LY.MicroService.WebhooksManagement.EntityFrameworkCore.csproj", "{E41F9F32-7A18-485D-BAAE-D858F7EE72E7}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "webhooks", "webhooks", "{E93F5D2E-14FF-47A0-B899-0E34AFDBCCBD}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Notifications", "modules\identity\LINGYUN.Abp.Identity.Notifications\LINGYUN.Abp.Identity.Notifications.csproj", "{54BBA043-317B-4A4F-B583-513D08BC25A7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -1964,118 +1912,34 @@ Global
{8A255A72-50FC-460E-9897-FA53F455580B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8A255A72-50FC-460E-9897-FA53F455580B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8A255A72-50FC-460E-9897-FA53F455580B}.Release|Any CPU.Build.0 = Release|Any CPU
{46038910-8EDD-4822-8768-097B7D276FED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{46038910-8EDD-4822-8768-097B7D276FED}.Debug|Any CPU.Build.0 = Debug|Any CPU
{46038910-8EDD-4822-8768-097B7D276FED}.Release|Any CPU.ActiveCfg = Release|Any CPU
{46038910-8EDD-4822-8768-097B7D276FED}.Release|Any CPU.Build.0 = Release|Any CPU
{332F2031-6B67-4199-8BA4-317679D2FFF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{332F2031-6B67-4199-8BA4-317679D2FFF8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{332F2031-6B67-4199-8BA4-317679D2FFF8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{332F2031-6B67-4199-8BA4-317679D2FFF8}.Release|Any CPU.Build.0 = Release|Any CPU
{C8138D8C-BF2B-41CB-BEA2-3ACC5E70E306}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C8138D8C-BF2B-41CB-BEA2-3ACC5E70E306}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C8138D8C-BF2B-41CB-BEA2-3ACC5E70E306}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C8138D8C-BF2B-41CB-BEA2-3ACC5E70E306}.Release|Any CPU.Build.0 = Release|Any CPU
{FF53669D-560C-4791-BE9A-28231C15FA4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FF53669D-560C-4791-BE9A-28231C15FA4E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FF53669D-560C-4791-BE9A-28231C15FA4E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FF53669D-560C-4791-BE9A-28231C15FA4E}.Release|Any CPU.Build.0 = Release|Any CPU
{2F8BB49E-92E5-4468-8656-BD4BC03FA505}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2F8BB49E-92E5-4468-8656-BD4BC03FA505}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F8BB49E-92E5-4468-8656-BD4BC03FA505}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F8BB49E-92E5-4468-8656-BD4BC03FA505}.Release|Any CPU.Build.0 = Release|Any CPU
{5CAC42F1-58A4-4716-B8E5-E28042D1B612}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5CAC42F1-58A4-4716-B8E5-E28042D1B612}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5CAC42F1-58A4-4716-B8E5-E28042D1B612}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5CAC42F1-58A4-4716-B8E5-E28042D1B612}.Release|Any CPU.Build.0 = Release|Any CPU
{7D235CB7-EC8E-418F-978A-D2E6EA5F9E9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7D235CB7-EC8E-418F-978A-D2E6EA5F9E9A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7D235CB7-EC8E-418F-978A-D2E6EA5F9E9A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7D235CB7-EC8E-418F-978A-D2E6EA5F9E9A}.Release|Any CPU.Build.0 = Release|Any CPU
{F78B0978-4ECF-4EA3-89A7-9492AE33CB30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F78B0978-4ECF-4EA3-89A7-9492AE33CB30}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F78B0978-4ECF-4EA3-89A7-9492AE33CB30}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F78B0978-4ECF-4EA3-89A7-9492AE33CB30}.Release|Any CPU.Build.0 = Release|Any CPU
{7C1A3331-D3D0-4CF0-A7D4-9E27F507AB02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7C1A3331-D3D0-4CF0-A7D4-9E27F507AB02}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7C1A3331-D3D0-4CF0-A7D4-9E27F507AB02}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7C1A3331-D3D0-4CF0-A7D4-9E27F507AB02}.Release|Any CPU.Build.0 = Release|Any CPU
{DC4AB835-76CA-4439-9A14-473B3838F856}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DC4AB835-76CA-4439-9A14-473B3838F856}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DC4AB835-76CA-4439-9A14-473B3838F856}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DC4AB835-76CA-4439-9A14-473B3838F856}.Release|Any CPU.Build.0 = Release|Any CPU
{3310571F-1B30-49A4-AD24-0CF5C91C58F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3310571F-1B30-49A4-AD24-0CF5C91C58F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3310571F-1B30-49A4-AD24-0CF5C91C58F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3310571F-1B30-49A4-AD24-0CF5C91C58F7}.Release|Any CPU.Build.0 = Release|Any CPU
{00C8A2BC-361D-4999-AEC3-BA4DD7991A9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{00C8A2BC-361D-4999-AEC3-BA4DD7991A9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{00C8A2BC-361D-4999-AEC3-BA4DD7991A9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{00C8A2BC-361D-4999-AEC3-BA4DD7991A9D}.Release|Any CPU.Build.0 = Release|Any CPU
{D60CF8FB-45BB-4F95-97EB-E1CE54B3105A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D60CF8FB-45BB-4F95-97EB-E1CE54B3105A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D60CF8FB-45BB-4F95-97EB-E1CE54B3105A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D60CF8FB-45BB-4F95-97EB-E1CE54B3105A}.Release|Any CPU.Build.0 = Release|Any CPU
{7D83C686-7BF0-4037-B927-A502D55D01F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7D83C686-7BF0-4037-B927-A502D55D01F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7D83C686-7BF0-4037-B927-A502D55D01F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7D83C686-7BF0-4037-B927-A502D55D01F8}.Release|Any CPU.Build.0 = Release|Any CPU
{C7F7F9E2-F877-4658-BFEC-E47AE27B0139}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C7F7F9E2-F877-4658-BFEC-E47AE27B0139}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C7F7F9E2-F877-4658-BFEC-E47AE27B0139}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C7F7F9E2-F877-4658-BFEC-E47AE27B0139}.Release|Any CPU.Build.0 = Release|Any CPU
{2BC04B60-6959-47FF-8860-96AB51986584}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2BC04B60-6959-47FF-8860-96AB51986584}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2BC04B60-6959-47FF-8860-96AB51986584}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2BC04B60-6959-47FF-8860-96AB51986584}.Release|Any CPU.Build.0 = Release|Any CPU
{1752BAA2-4305-4655-99B4-6832E2CE6CAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1752BAA2-4305-4655-99B4-6832E2CE6CAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1752BAA2-4305-4655-99B4-6832E2CE6CAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1752BAA2-4305-4655-99B4-6832E2CE6CAF}.Release|Any CPU.Build.0 = Release|Any CPU
{6F2A09CE-183E-4FBA-BB12-DD6105B90B00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6F2A09CE-183E-4FBA-BB12-DD6105B90B00}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6F2A09CE-183E-4FBA-BB12-DD6105B90B00}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6F2A09CE-183E-4FBA-BB12-DD6105B90B00}.Release|Any CPU.Build.0 = Release|Any CPU
{5E3E2B57-4BF1-45A7-9BAE-EDA000F27C80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5E3E2B57-4BF1-45A7-9BAE-EDA000F27C80}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5E3E2B57-4BF1-45A7-9BAE-EDA000F27C80}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5E3E2B57-4BF1-45A7-9BAE-EDA000F27C80}.Release|Any CPU.Build.0 = Release|Any CPU
{7D760508-A5A8-44D9-8958-F5AD5F1B7949}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7D760508-A5A8-44D9-8958-F5AD5F1B7949}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7D760508-A5A8-44D9-8958-F5AD5F1B7949}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7D760508-A5A8-44D9-8958-F5AD5F1B7949}.Release|Any CPU.Build.0 = Release|Any CPU
{2D3B6C77-465E-4D39-A83D-47E74F14D6D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2D3B6C77-465E-4D39-A83D-47E74F14D6D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2D3B6C77-465E-4D39-A83D-47E74F14D6D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2D3B6C77-465E-4D39-A83D-47E74F14D6D0}.Release|Any CPU.Build.0 = Release|Any CPU
{E8139252-2F6D-437D-97C7-6FB77C705E58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E8139252-2F6D-437D-97C7-6FB77C705E58}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E8139252-2F6D-437D-97C7-6FB77C705E58}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E8139252-2F6D-437D-97C7-6FB77C705E58}.Release|Any CPU.Build.0 = Release|Any CPU
{40FEF2F7-BB0E-4192-89EE-BDA98B3E4007}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{40FEF2F7-BB0E-4192-89EE-BDA98B3E4007}.Debug|Any CPU.Build.0 = Debug|Any CPU
{40FEF2F7-BB0E-4192-89EE-BDA98B3E4007}.Release|Any CPU.ActiveCfg = Release|Any CPU
{40FEF2F7-BB0E-4192-89EE-BDA98B3E4007}.Release|Any CPU.Build.0 = Release|Any CPU
{CE309DF2-FB96-4917-9DC6-14DC1DED7EED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CE309DF2-FB96-4917-9DC6-14DC1DED7EED}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CE309DF2-FB96-4917-9DC6-14DC1DED7EED}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CE309DF2-FB96-4917-9DC6-14DC1DED7EED}.Release|Any CPU.Build.0 = Release|Any CPU
{27505FC3-2659-40CC-A9C7-0857FBECE099}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{27505FC3-2659-40CC-A9C7-0857FBECE099}.Debug|Any CPU.Build.0 = Debug|Any CPU
{27505FC3-2659-40CC-A9C7-0857FBECE099}.Release|Any CPU.ActiveCfg = Release|Any CPU
{27505FC3-2659-40CC-A9C7-0857FBECE099}.Release|Any CPU.Build.0 = Release|Any CPU
{1E6F9CF8-577C-45A7-A2E0-2BB3C40AFB9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1E6F9CF8-577C-45A7-A2E0-2BB3C40AFB9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E6F9CF8-577C-45A7-A2E0-2BB3C40AFB9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1E6F9CF8-577C-45A7-A2E0-2BB3C40AFB9D}.Release|Any CPU.Build.0 = Release|Any CPU
{65951546-93DB-4415-94C5-2B7B1E232A3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{65951546-93DB-4415-94C5-2B7B1E232A3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{65951546-93DB-4415-94C5-2B7B1E232A3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{65951546-93DB-4415-94C5-2B7B1E232A3E}.Release|Any CPU.Build.0 = Release|Any CPU
{E41F9F32-7A18-485D-BAAE-D858F7EE72E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E41F9F32-7A18-485D-BAAE-D858F7EE72E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E41F9F32-7A18-485D-BAAE-D858F7EE72E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E41F9F32-7A18-485D-BAAE-D858F7EE72E7}.Release|Any CPU.Build.0 = Release|Any CPU
{CED33625-A034-475B-A4C0-A4E7D1BADD10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CED33625-A034-475B-A4C0-A4E7D1BADD10}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CED33625-A034-475B-A4C0-A4E7D1BADD10}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CED33625-A034-475B-A4C0-A4E7D1BADD10}.Release|Any CPU.Build.0 = Release|Any CPU
{E3BA2413-5755-4F61-9A7C-5D49AE9E7016}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E3BA2413-5755-4F61-9A7C-5D49AE9E7016}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E3BA2413-5755-4F61-9A7C-5D49AE9E7016}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E3BA2413-5755-4F61-9A7C-5D49AE9E7016}.Release|Any CPU.Build.0 = Release|Any CPU
{BF85DB7F-70C2-4804-AA57-FACE204981DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BF85DB7F-70C2-4804-AA57-FACE204981DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF85DB7F-70C2-4804-AA57-FACE204981DA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BF85DB7F-70C2-4804-AA57-FACE204981DA}.Release|Any CPU.Build.0 = Release|Any CPU
{893F7376-0913-43DC-AD3D-40AF5B8F9E3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{893F7376-0913-43DC-AD3D-40AF5B8F9E3B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{893F7376-0913-43DC-AD3D-40AF5B8F9E3B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{893F7376-0913-43DC-AD3D-40AF5B8F9E3B}.Release|Any CPU.Build.0 = Release|Any CPU
{8826831D-8733-473A-B47B-A30C3732B13D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8826831D-8733-473A-B47B-A30C3732B13D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8826831D-8733-473A-B47B-A30C3732B13D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8826831D-8733-473A-B47B-A30C3732B13D}.Release|Any CPU.Build.0 = Release|Any CPU
{D1484DD3-BB0A-45A4-BED5-FFA132DE2E72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D1484DD3-BB0A-45A4-BED5-FFA132DE2E72}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D1484DD3-BB0A-45A4-BED5-FFA132DE2E72}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D1484DD3-BB0A-45A4-BED5-FFA132DE2E72}.Release|Any CPU.Build.0 = Release|Any CPU
{54BBA043-317B-4A4F-B583-513D08BC25A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{54BBA043-317B-4A4F-B583-513D08BC25A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{54BBA043-317B-4A4F-B583-513D08BC25A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{54BBA043-317B-4A4F-B583-513D08BC25A7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -2435,39 +2299,13 @@ Global
{ED3DF100-C5DB-4334-A847-118922B28D95} = {3C7A8246-DE82-4330-8697-24EF1B1C515D}
{15482834-9242-4D20-9736-9DA571A9A83A} = {ABD89F39-62D9-439E-8662-BE4F36BFA04F}
{8A255A72-50FC-460E-9897-FA53F455580B} = {9D1302BE-3886-49F8-B0CD-35D2AC1E5A37}
{46038910-8EDD-4822-8768-097B7D276FED} = {DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21}
{332F2031-6B67-4199-8BA4-317679D2FFF8} = {77ED7922-BF30-4436-8A85-78F812583913}
{C8138D8C-BF2B-41CB-BEA2-3ACC5E70E306} = {77ED7922-BF30-4436-8A85-78F812583913}
{FF53669D-560C-4791-BE9A-28231C15FA4E} = {77ED7922-BF30-4436-8A85-78F812583913}
{2F8BB49E-92E5-4468-8656-BD4BC03FA505} = {77ED7922-BF30-4436-8A85-78F812583913}
{5CAC42F1-58A4-4716-B8E5-E28042D1B612} = {77ED7922-BF30-4436-8A85-78F812583913}
{7D235CB7-EC8E-418F-978A-D2E6EA5F9E9A} = {77ED7922-BF30-4436-8A85-78F812583913}
{F78B0978-4ECF-4EA3-89A7-9492AE33CB30} = {77ED7922-BF30-4436-8A85-78F812583913}
{7C1A3331-D3D0-4CF0-A7D4-9E27F507AB02} = {77ED7922-BF30-4436-8A85-78F812583913}
{DC4AB835-76CA-4439-9A14-473B3838F856} = {77ED7922-BF30-4436-8A85-78F812583913}
{3310571F-1B30-49A4-AD24-0CF5C91C58F7} = {77ED7922-BF30-4436-8A85-78F812583913}
{00C8A2BC-361D-4999-AEC3-BA4DD7991A9D} = {77ED7922-BF30-4436-8A85-78F812583913}
{D60CF8FB-45BB-4F95-97EB-E1CE54B3105A} = {13ACF670-F109-404E-B252-2FA34A4EA061}
{7D83C686-7BF0-4037-B927-A502D55D01F8} = {13ACF670-F109-404E-B252-2FA34A4EA061}
{C7F7F9E2-F877-4658-BFEC-E47AE27B0139} = {13ACF670-F109-404E-B252-2FA34A4EA061}
{2BC04B60-6959-47FF-8860-96AB51986584} = {13ACF670-F109-404E-B252-2FA34A4EA061}
{1752BAA2-4305-4655-99B4-6832E2CE6CAF} = {13ACF670-F109-404E-B252-2FA34A4EA061}
{6F2A09CE-183E-4FBA-BB12-DD6105B90B00} = {13ACF670-F109-404E-B252-2FA34A4EA061}
{5E3E2B57-4BF1-45A7-9BAE-EDA000F27C80} = {13ACF670-F109-404E-B252-2FA34A4EA061}
{C1EFDD32-5524-4DDD-9925-88B6E3530994} = {672E1170-7B18-474B-85C7-1961BF2A48AE}
{7D760508-A5A8-44D9-8958-F5AD5F1B7949} = {C1EFDD32-5524-4DDD-9925-88B6E3530994}
{0107020D-22E5-4DDF-8A62-5DE850BA6C79} = {672E1170-7B18-474B-85C7-1961BF2A48AE}
{74319001-6F4B-41D9-BE32-128EC12AB10B} = {672E1170-7B18-474B-85C7-1961BF2A48AE}
{2D3B6C77-465E-4D39-A83D-47E74F14D6D0} = {0107020D-22E5-4DDF-8A62-5DE850BA6C79}
{E8139252-2F6D-437D-97C7-6FB77C705E58} = {74319001-6F4B-41D9-BE32-128EC12AB10B}
{40FEF2F7-BB0E-4192-89EE-BDA98B3E4007} = {77ED7922-BF30-4436-8A85-78F812583913}
{A922E0EE-5302-4E2B-9D84-0EC681416DA2} = {C90A505F-000E-4AE4-8CCD-AB5FE5092B5C}
{CE309DF2-FB96-4917-9DC6-14DC1DED7EED} = {A922E0EE-5302-4E2B-9D84-0EC681416DA2}
{27505FC3-2659-40CC-A9C7-0857FBECE099} = {13ACF670-F109-404E-B252-2FA34A4EA061}
{1E6F9CF8-577C-45A7-A2E0-2BB3C40AFB9D} = {13ACF670-F109-404E-B252-2FA34A4EA061}
{65951546-93DB-4415-94C5-2B7B1E232A3E} = {13ACF670-F109-404E-B252-2FA34A4EA061}
{E93F5D2E-14FF-47A0-B899-0E34AFDBCCBD} = {C90A505F-000E-4AE4-8CCD-AB5FE5092B5C}
{E41F9F32-7A18-485D-BAAE-D858F7EE72E7} = {E93F5D2E-14FF-47A0-B899-0E34AFDBCCBD}
{CED33625-A034-475B-A4C0-A4E7D1BADD10} = {DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21}
{E3BA2413-5755-4F61-9A7C-5D49AE9E7016} = {52B5D4F7-237B-4E0A-A167-68442164F70A}
{BF85DB7F-70C2-4804-AA57-FACE204981DA} = {52B5D4F7-237B-4E0A-A167-68442164F70A}
{893F7376-0913-43DC-AD3D-40AF5B8F9E3B} = {0439B173-F41E-4CE0-A44A-CCB70328F272}
{8826831D-8733-473A-B47B-A30C3732B13D} = {52B5D4F7-237B-4E0A-A167-68442164F70A}
{D1484DD3-BB0A-45A4-BED5-FFA132DE2E72} = {83E698F6-F8CD-4604-AB80-01A203389501}
{54BBA043-317B-4A4F-B583-513D08BC25A7} = {52B5D4F7-237B-4E0A-A167-68442164F70A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718}

63
aspnet-core/LINGYUN.MicroService.SingleProject.sln

@ -515,6 +515,24 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.BackgroundTasks
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Saas.Jobs", "modules\saas\LINGYUN.Abp.Saas.Jobs\LINGYUN.Abp.Saas.Jobs.csproj", "{8FA3ED81-19AB-4E0C-B36A-DF49131A2AB3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer.SmsValidator", "modules\identityServer\LINGYUN.Abp.IdentityServer.SmsValidator\LINGYUN.Abp.IdentityServer.SmsValidator.csproj", "{7C1A8FF7-9FD1-41FC-856D-7A2DC6F7CE6F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer.Portal", "modules\identityServer\LINGYUN.Abp.IdentityServer.Portal\LINGYUN.Abp.IdentityServer.Portal.csproj", "{986B92F6-A758-4D1F-8BC7-BFD13FF38591}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer.WeChat.Work", "modules\identityServer\LINGYUN.Abp.IdentityServer.WeChat.Work\LINGYUN.Abp.IdentityServer.WeChat.Work.csproj", "{62D72C3E-5C57-439D-B7F7-5C55CC384A7A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Session", "modules\identity\LINGYUN.Abp.Identity.Session\LINGYUN.Abp.Identity.Session.csproj", "{74156CFF-C236-4DED-B810-FAD8948F51CA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Session.AspNetCore", "modules\identity\LINGYUN.Abp.Identity.Session.AspNetCore\LINGYUN.Abp.Identity.Session.AspNetCore.csproj", "{63D08153-B43C-4884-8818-4AB42E1FEE75}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.AspNetCore.Session", "modules\identity\LINGYUN.Abp.Identity.AspNetCore.Session\LINGYUN.Abp.Identity.AspNetCore.Session.csproj", "{AF02868C-283E-4CB2-8866-3B0CAD1BB2DE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.IdentityServer.Session", "modules\identityServer\LINGYUN.Abp.IdentityServer.Session\LINGYUN.Abp.IdentityServer.Session.csproj", "{F7459720-873C-4741-A991-A671CF03A6AF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.OpenIddict.AspNetCore.Session", "modules\openIddict\LINGYUN.Abp.OpenIddict.AspNetCore.Session\LINGYUN.Abp.OpenIddict.AspNetCore.Session.csproj", "{382CAC43-EE1F-4DA3-B433-E23C3F58F44A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Notifications", "modules\identity\LINGYUN.Abp.Identity.Notifications\LINGYUN.Abp.Identity.Notifications.csproj", "{4634B421-36E6-4169-AA1A-11050902495F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -1349,6 +1367,42 @@ Global
{8FA3ED81-19AB-4E0C-B36A-DF49131A2AB3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8FA3ED81-19AB-4E0C-B36A-DF49131A2AB3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8FA3ED81-19AB-4E0C-B36A-DF49131A2AB3}.Release|Any CPU.Build.0 = Release|Any CPU
{7C1A8FF7-9FD1-41FC-856D-7A2DC6F7CE6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7C1A8FF7-9FD1-41FC-856D-7A2DC6F7CE6F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7C1A8FF7-9FD1-41FC-856D-7A2DC6F7CE6F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7C1A8FF7-9FD1-41FC-856D-7A2DC6F7CE6F}.Release|Any CPU.Build.0 = Release|Any CPU
{986B92F6-A758-4D1F-8BC7-BFD13FF38591}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{986B92F6-A758-4D1F-8BC7-BFD13FF38591}.Debug|Any CPU.Build.0 = Debug|Any CPU
{986B92F6-A758-4D1F-8BC7-BFD13FF38591}.Release|Any CPU.ActiveCfg = Release|Any CPU
{986B92F6-A758-4D1F-8BC7-BFD13FF38591}.Release|Any CPU.Build.0 = Release|Any CPU
{62D72C3E-5C57-439D-B7F7-5C55CC384A7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{62D72C3E-5C57-439D-B7F7-5C55CC384A7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{62D72C3E-5C57-439D-B7F7-5C55CC384A7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{62D72C3E-5C57-439D-B7F7-5C55CC384A7A}.Release|Any CPU.Build.0 = Release|Any CPU
{74156CFF-C236-4DED-B810-FAD8948F51CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{74156CFF-C236-4DED-B810-FAD8948F51CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{74156CFF-C236-4DED-B810-FAD8948F51CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{74156CFF-C236-4DED-B810-FAD8948F51CA}.Release|Any CPU.Build.0 = Release|Any CPU
{63D08153-B43C-4884-8818-4AB42E1FEE75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{63D08153-B43C-4884-8818-4AB42E1FEE75}.Debug|Any CPU.Build.0 = Debug|Any CPU
{63D08153-B43C-4884-8818-4AB42E1FEE75}.Release|Any CPU.ActiveCfg = Release|Any CPU
{63D08153-B43C-4884-8818-4AB42E1FEE75}.Release|Any CPU.Build.0 = Release|Any CPU
{AF02868C-283E-4CB2-8866-3B0CAD1BB2DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AF02868C-283E-4CB2-8866-3B0CAD1BB2DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AF02868C-283E-4CB2-8866-3B0CAD1BB2DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AF02868C-283E-4CB2-8866-3B0CAD1BB2DE}.Release|Any CPU.Build.0 = Release|Any CPU
{F7459720-873C-4741-A991-A671CF03A6AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F7459720-873C-4741-A991-A671CF03A6AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F7459720-873C-4741-A991-A671CF03A6AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F7459720-873C-4741-A991-A671CF03A6AF}.Release|Any CPU.Build.0 = Release|Any CPU
{382CAC43-EE1F-4DA3-B433-E23C3F58F44A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{382CAC43-EE1F-4DA3-B433-E23C3F58F44A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{382CAC43-EE1F-4DA3-B433-E23C3F58F44A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{382CAC43-EE1F-4DA3-B433-E23C3F58F44A}.Release|Any CPU.Build.0 = Release|Any CPU
{4634B421-36E6-4169-AA1A-11050902495F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4634B421-36E6-4169-AA1A-11050902495F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4634B421-36E6-4169-AA1A-11050902495F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4634B421-36E6-4169-AA1A-11050902495F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -1600,6 +1654,15 @@ Global
{66A6E78D-E547-4DD7-9844-087FAB3D03C2} = {C22741F9-FC56-4AE3-B543-9F15C779D345}
{A99F5406-37DC-4677-9166-9BDE90C26CA6} = {D9C65C9D-8591-46DA-A3EE-419393E607AB}
{8FA3ED81-19AB-4E0C-B36A-DF49131A2AB3} = {0DF5AD76-AEEA-4052-A6CA-A44C24879F11}
{7C1A8FF7-9FD1-41FC-856D-7A2DC6F7CE6F} = {A3B6DFC3-5D27-496E-9AD6-C1035213F1DC}
{986B92F6-A758-4D1F-8BC7-BFD13FF38591} = {A3B6DFC3-5D27-496E-9AD6-C1035213F1DC}
{62D72C3E-5C57-439D-B7F7-5C55CC384A7A} = {A3B6DFC3-5D27-496E-9AD6-C1035213F1DC}
{74156CFF-C236-4DED-B810-FAD8948F51CA} = {D94D6AFE-20BD-4F21-8708-03F5E34F49FC}
{63D08153-B43C-4884-8818-4AB42E1FEE75} = {D94D6AFE-20BD-4F21-8708-03F5E34F49FC}
{AF02868C-283E-4CB2-8866-3B0CAD1BB2DE} = {D94D6AFE-20BD-4F21-8708-03F5E34F49FC}
{F7459720-873C-4741-A991-A671CF03A6AF} = {A3B6DFC3-5D27-496E-9AD6-C1035213F1DC}
{382CAC43-EE1F-4DA3-B433-E23C3F58F44A} = {7C714185-D3D9-4D94-B5CB-D857A0091F04}
{4634B421-36E6-4169-AA1A-11050902495F} = {D94D6AFE-20BD-4F21-8708-03F5E34F49FC}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {711A43C0-A2F8-4E5C-9B9F-F2551E4B3FF1}

17
aspnet-core/LINGYUN.MicroService.WebhooksManagement.sln

@ -147,6 +147,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Security", "fra
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Claims.Mapping", "framework\security\LINGYUN.Abp.Claims.Mapping\LINGYUN.Abp.Claims.Mapping.csproj", "{047F892F-F8D2-4952-A1E9-93AA2B030F76}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "identity", "identity", "{23E99204-F7C1-47BA-84CD-3C9D05210F4F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Session", "modules\identity\LINGYUN.Abp.Identity.Session\LINGYUN.Abp.Identity.Session.csproj", "{BF298DF5-BC1D-4DDD-A51E-8E9020D2C5F1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Session.AspNetCore", "modules\identity\LINGYUN.Abp.Identity.Session.AspNetCore\LINGYUN.Abp.Identity.Session.AspNetCore.csproj", "{BE58649C-EA57-4DFC-8D25-54FDCB1943A1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -381,6 +387,14 @@ Global
{047F892F-F8D2-4952-A1E9-93AA2B030F76}.Debug|Any CPU.Build.0 = Debug|Any CPU
{047F892F-F8D2-4952-A1E9-93AA2B030F76}.Release|Any CPU.ActiveCfg = Release|Any CPU
{047F892F-F8D2-4952-A1E9-93AA2B030F76}.Release|Any CPU.Build.0 = Release|Any CPU
{BF298DF5-BC1D-4DDD-A51E-8E9020D2C5F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BF298DF5-BC1D-4DDD-A51E-8E9020D2C5F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF298DF5-BC1D-4DDD-A51E-8E9020D2C5F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BF298DF5-BC1D-4DDD-A51E-8E9020D2C5F1}.Release|Any CPU.Build.0 = Release|Any CPU
{BE58649C-EA57-4DFC-8D25-54FDCB1943A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BE58649C-EA57-4DFC-8D25-54FDCB1943A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BE58649C-EA57-4DFC-8D25-54FDCB1943A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BE58649C-EA57-4DFC-8D25-54FDCB1943A1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -454,6 +468,9 @@ Global
{0DFDAC71-BCB9-44CF-A44A-E8288E75246F} = {FB7A9794-06D2-42CF-939E-4626497B97BD}
{8F11DADB-557A-4ECF-BEBB-19AFA71998A1} = {FB7A9794-06D2-42CF-939E-4626497B97BD}
{047F892F-F8D2-4952-A1E9-93AA2B030F76} = {FB7A9794-06D2-42CF-939E-4626497B97BD}
{23E99204-F7C1-47BA-84CD-3C9D05210F4F} = {03B4B0AA-83CE-4E4B-9CE2-47369BF88B97}
{BF298DF5-BC1D-4DDD-A51E-8E9020D2C5F1} = {23E99204-F7C1-47BA-84CD-3C9D05210F4F}
{BE58649C-EA57-4DFC-8D25-54FDCB1943A1} = {23E99204-F7C1-47BA-84CD-3C9D05210F4F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {80ED12A5-C899-459F-A181-ADCC9D680DE5}

16
aspnet-core/LINGYUN.MicroService.Workflow.sln

@ -165,6 +165,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Security", "fra
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Claims.Mapping", "framework\security\LINGYUN.Abp.Claims.Mapping\LINGYUN.Abp.Claims.Mapping.csproj", "{1859E205-88DC-4E08-A0BD-55A045DCC495}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "identity", "identity", "{9C73D4E6-4408-4717-B51C-63C20321D4DA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Session", "modules\identity\LINGYUN.Abp.Identity.Session\LINGYUN.Abp.Identity.Session.csproj", "{6ECF678D-6F3A-4084-8538-A86C1D67C703}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Session.AspNetCore", "modules\identity\LINGYUN.Abp.Identity.Session.AspNetCore\LINGYUN.Abp.Identity.Session.AspNetCore.csproj", "{9FB5E943-7F6F-4281-9C00-E76284B4F1F3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -443,6 +449,14 @@ Global
{1859E205-88DC-4E08-A0BD-55A045DCC495}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1859E205-88DC-4E08-A0BD-55A045DCC495}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1859E205-88DC-4E08-A0BD-55A045DCC495}.Release|Any CPU.Build.0 = Release|Any CPU
{6ECF678D-6F3A-4084-8538-A86C1D67C703}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6ECF678D-6F3A-4084-8538-A86C1D67C703}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6ECF678D-6F3A-4084-8538-A86C1D67C703}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6ECF678D-6F3A-4084-8538-A86C1D67C703}.Release|Any CPU.Build.0 = Release|Any CPU
{9FB5E943-7F6F-4281-9C00-E76284B4F1F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9FB5E943-7F6F-4281-9C00-E76284B4F1F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9FB5E943-7F6F-4281-9C00-E76284B4F1F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9FB5E943-7F6F-4281-9C00-E76284B4F1F3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -518,6 +532,8 @@ Global
{4D055853-DE80-4145-BB2F-33EB6B379F5E} = {6DA78E72-BA55-4ECF-97DB-6258174D3E2A}
{E4783690-052A-4AB0-837E-BDBC77CC7EEC} = {6DA78E72-BA55-4ECF-97DB-6258174D3E2A}
{1859E205-88DC-4E08-A0BD-55A045DCC495} = {6DA78E72-BA55-4ECF-97DB-6258174D3E2A}
{6ECF678D-6F3A-4084-8538-A86C1D67C703} = {9C73D4E6-4408-4717-B51C-63C20321D4DA}
{9FB5E943-7F6F-4281-9C00-E76284B4F1F3} = {9C73D4E6-4408-4717-B51C-63C20321D4DA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6BB7A5DE-DA12-44DC-BC9B-0F6CA524346F}

7
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN.Abp.AuditLogging.Elasticsearch.csproj

@ -4,7 +4,12 @@
<Import Project="..\..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0</TargetFrameworks>
<AssemblyName>LINGYUN.Abp.AuditLogging.Elasticsearch</AssemblyName>
<PackageId>LINGYUN.Abp.AuditLogging.Elasticsearch</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>

23
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/AbpAuditLoggingElasticsearchModule.cs

@ -3,20 +3,19 @@ using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Json;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.AuditLogging.Elasticsearch
namespace LINGYUN.Abp.AuditLogging.Elasticsearch;
[DependsOn(
typeof(AbpAuditLoggingModule),
typeof(AbpElasticsearchModule),
typeof(AbpJsonModule))]
public class AbpAuditLoggingElasticsearchModule : AbpModule
{
[DependsOn(
typeof(AbpAuditLoggingModule),
typeof(AbpElasticsearchModule),
typeof(AbpJsonModule))]
public class AbpAuditLoggingElasticsearchModule : AbpModule
public override void ConfigureServices(ServiceConfigurationContext context)
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
Configure<AbpAuditLoggingElasticsearchOptions>(configuration.GetSection("AuditLogging:Elasticsearch"));
var configuration = context.Services.GetConfiguration();
Configure<AbpAuditLoggingElasticsearchOptions>(configuration.GetSection("AuditLogging:Elasticsearch"));
context.Services.AddHostedService<IndexInitializerService>();
}
context.Services.AddHostedService<IndexInitializerService>();
}
}

21
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/AbpAuditLoggingElasticsearchOptions.cs

@ -1,17 +1,16 @@
using Nest;
namespace LINGYUN.Abp.AuditLogging.Elasticsearch
namespace LINGYUN.Abp.AuditLogging.Elasticsearch;
public class AbpAuditLoggingElasticsearchOptions
{
public class AbpAuditLoggingElasticsearchOptions
{
public const string DefaultIndexPrefix = "auditlogging";
public string IndexPrefix { get; set; }
public IIndexSettings IndexSettings { get; set; }
public const string DefaultIndexPrefix = "auditlogging";
public string IndexPrefix { get; set; }
public IIndexSettings IndexSettings { get; set; }
public AbpAuditLoggingElasticsearchOptions()
{
IndexPrefix = DefaultIndexPrefix;
IndexSettings = new IndexSettings();
}
public AbpAuditLoggingElasticsearchOptions()
{
IndexPrefix = DefaultIndexPrefix;
IndexSettings = new IndexSettings();
}
}

171
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/AuditLogInfoToAuditLogConverter.cs

@ -11,105 +11,104 @@ using Volo.Abp.Guids;
using Volo.Abp.Http;
using Volo.Abp.Json;
namespace LINGYUN.Abp.AuditLogging
namespace LINGYUN.Abp.AuditLogging;
public class AuditLogInfoToAuditLogConverter : IAuditLogInfoToAuditLogConverter, ITransientDependency
{
public class AuditLogInfoToAuditLogConverter : IAuditLogInfoToAuditLogConverter, ITransientDependency
protected IGuidGenerator GuidGenerator { get; }
protected AbpExceptionHandlingOptions ExceptionHandlingOptions { get; }
protected IExceptionToErrorInfoConverter ExceptionToErrorInfoConverter { get; }
protected IJsonSerializer JsonSerializer { get; }
public AuditLogInfoToAuditLogConverter(
IGuidGenerator guidGenerator,
IOptions<AbpExceptionHandlingOptions> exceptionHandlingOptions,
IExceptionToErrorInfoConverter exceptionToErrorInfoConverter,
IJsonSerializer jsonSerializer)
{
protected IGuidGenerator GuidGenerator { get; }
protected AbpExceptionHandlingOptions ExceptionHandlingOptions { get; }
protected IExceptionToErrorInfoConverter ExceptionToErrorInfoConverter { get; }
protected IJsonSerializer JsonSerializer { get; }
GuidGenerator = guidGenerator;
ExceptionHandlingOptions = exceptionHandlingOptions.Value;
ExceptionToErrorInfoConverter = exceptionToErrorInfoConverter;
JsonSerializer = jsonSerializer;
}
public AuditLogInfoToAuditLogConverter(
IGuidGenerator guidGenerator,
IOptions<AbpExceptionHandlingOptions> exceptionHandlingOptions,
IExceptionToErrorInfoConverter exceptionToErrorInfoConverter,
IJsonSerializer jsonSerializer)
{
GuidGenerator = guidGenerator;
ExceptionHandlingOptions = exceptionHandlingOptions.Value;
ExceptionToErrorInfoConverter = exceptionToErrorInfoConverter;
JsonSerializer = jsonSerializer;
}
public virtual Task<AuditLog> ConvertAsync(AuditLogInfo auditLogInfo)
{
var auditLogId = GuidGenerator.Create();
public virtual Task<AuditLog> ConvertAsync(AuditLogInfo auditLogInfo)
var extraProperties = new ExtraPropertyDictionary();
if (auditLogInfo.ExtraProperties != null)
{
var auditLogId = GuidGenerator.Create();
var extraProperties = new ExtraPropertyDictionary();
if (auditLogInfo.ExtraProperties != null)
foreach (var pair in auditLogInfo.ExtraProperties)
{
foreach (var pair in auditLogInfo.ExtraProperties)
{
extraProperties.Add(pair.Key, pair.Value);
}
extraProperties.Add(pair.Key, pair.Value);
}
}
var entityChanges = auditLogInfo
.EntityChanges?
.Select(entityChangeInfo => new EntityChange(
GuidGenerator,
auditLogId,
entityChangeInfo,
tenantId: auditLogInfo.TenantId,
entityTenantId: entityChangeInfo.EntityTenantId))
.ToList()
?? new List<EntityChange>();
var entityChanges = auditLogInfo
.EntityChanges?
.Select(entityChangeInfo => new EntityChange(
GuidGenerator,
auditLogId,
entityChangeInfo,
tenantId: auditLogInfo.TenantId,
entityTenantId: entityChangeInfo.EntityTenantId))
.ToList()
?? new List<EntityChange>();
var actions = auditLogInfo
.Actions?
.Select(auditLogActionInfo => new AuditLogAction(
GuidGenerator.Create(),
auditLogId,
auditLogActionInfo,
tenantId: auditLogInfo.TenantId))
.ToList()
?? new List<AuditLogAction>();
var actions = auditLogInfo
.Actions?
.Select(auditLogActionInfo => new AuditLogAction(
GuidGenerator.Create(),
auditLogId,
auditLogActionInfo,
tenantId: auditLogInfo.TenantId))
.ToList()
?? new List<AuditLogAction>();
var remoteServiceErrorInfos = auditLogInfo.Exceptions?.Select(exception =>
ExceptionToErrorInfoConverter.Convert(exception, options =>
{
options.SendExceptionsDetailsToClients = ExceptionHandlingOptions.SendExceptionsDetailsToClients;
options.SendStackTraceToClients = ExceptionHandlingOptions.SendStackTraceToClients;
})) ?? new List<RemoteServiceErrorInfo>();
var remoteServiceErrorInfos = auditLogInfo.Exceptions?.Select(exception =>
ExceptionToErrorInfoConverter.Convert(exception, options =>
{
options.SendExceptionsDetailsToClients = ExceptionHandlingOptions.SendExceptionsDetailsToClients;
options.SendStackTraceToClients = ExceptionHandlingOptions.SendStackTraceToClients;
})) ?? new List<RemoteServiceErrorInfo>();
var exceptions = remoteServiceErrorInfos.Any()
? JsonSerializer.Serialize(remoteServiceErrorInfos, indented: true)
: null;
var exceptions = remoteServiceErrorInfos.Any()
? JsonSerializer.Serialize(remoteServiceErrorInfos, indented: true)
: null;
var comments = auditLogInfo
.Comments?
.JoinAsString(Environment.NewLine);
var comments = auditLogInfo
.Comments?
.JoinAsString(Environment.NewLine);
var auditLog = new AuditLog(
auditLogId,
auditLogInfo.ApplicationName,
auditLogInfo.TenantId,
auditLogInfo.TenantName,
auditLogInfo.UserId,
auditLogInfo.UserName,
auditLogInfo.ExecutionTime,
auditLogInfo.ExecutionDuration,
auditLogInfo.ClientIpAddress,
auditLogInfo.ClientName,
auditLogInfo.ClientId,
auditLogInfo.CorrelationId,
auditLogInfo.BrowserInfo,
auditLogInfo.HttpMethod,
auditLogInfo.Url,
auditLogInfo.HttpStatusCode,
auditLogInfo.ImpersonatorUserId,
auditLogInfo.ImpersonatorUserName,
auditLogInfo.ImpersonatorTenantId,
auditLogInfo.ImpersonatorTenantName,
extraProperties,
entityChanges,
actions,
exceptions,
comments
);
var auditLog = new AuditLog(
auditLogId,
auditLogInfo.ApplicationName,
auditLogInfo.TenantId,
auditLogInfo.TenantName,
auditLogInfo.UserId,
auditLogInfo.UserName,
auditLogInfo.ExecutionTime,
auditLogInfo.ExecutionDuration,
auditLogInfo.ClientIpAddress,
auditLogInfo.ClientName,
auditLogInfo.ClientId,
auditLogInfo.CorrelationId,
auditLogInfo.BrowserInfo,
auditLogInfo.HttpMethod,
auditLogInfo.Url,
auditLogInfo.HttpStatusCode,
auditLogInfo.ImpersonatorUserId,
auditLogInfo.ImpersonatorUserName,
auditLogInfo.ImpersonatorTenantId,
auditLogInfo.ImpersonatorTenantName,
extraProperties,
entityChanges,
actions,
exceptions,
comments
);
return Task.FromResult(auditLog);
}
return Task.FromResult(auditLog);
}
}

633
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/ElasticsearchAuditLogManager.cs

@ -13,361 +13,360 @@ using Volo.Abp.Auditing;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Timing;
namespace LINGYUN.Abp.AuditLogging.Elasticsearch
namespace LINGYUN.Abp.AuditLogging.Elasticsearch;
[Dependency(ReplaceServices = true)]
public class ElasticsearchAuditLogManager : IAuditLogManager, ITransientDependency
{
[Dependency(ReplaceServices = true)]
public class ElasticsearchAuditLogManager : IAuditLogManager, ITransientDependency
private readonly AbpAuditingOptions _auditingOptions;
private readonly AbpElasticsearchOptions _elasticsearchOptions;
private readonly IIndexNameNormalizer _indexNameNormalizer;
private readonly IElasticsearchClientFactory _clientFactory;
private readonly IAuditLogInfoToAuditLogConverter _converter;
private readonly IClock _clock;
public ILogger<ElasticsearchAuditLogManager> Logger { protected get; set; }
public ElasticsearchAuditLogManager(
IClock clock,
IIndexNameNormalizer indexNameNormalizer,
IOptions<AbpElasticsearchOptions> elasticsearchOptions,
IElasticsearchClientFactory clientFactory,
IOptions<AbpAuditingOptions> auditingOptions,
IAuditLogInfoToAuditLogConverter converter)
{
private readonly AbpAuditingOptions _auditingOptions;
private readonly AbpElasticsearchOptions _elasticsearchOptions;
private readonly IIndexNameNormalizer _indexNameNormalizer;
private readonly IElasticsearchClientFactory _clientFactory;
private readonly IAuditLogInfoToAuditLogConverter _converter;
private readonly IClock _clock;
public ILogger<ElasticsearchAuditLogManager> Logger { protected get; set; }
public ElasticsearchAuditLogManager(
IClock clock,
IIndexNameNormalizer indexNameNormalizer,
IOptions<AbpElasticsearchOptions> elasticsearchOptions,
IElasticsearchClientFactory clientFactory,
IOptions<AbpAuditingOptions> auditingOptions,
IAuditLogInfoToAuditLogConverter converter)
{
_clock = clock;
_converter = converter;
_clientFactory = clientFactory;
_auditingOptions = auditingOptions.Value;
_elasticsearchOptions = elasticsearchOptions.Value;
_indexNameNormalizer = indexNameNormalizer;
Logger = NullLogger<ElasticsearchAuditLogManager>.Instance;
}
_clock = clock;
_converter = converter;
_clientFactory = clientFactory;
_auditingOptions = auditingOptions.Value;
_elasticsearchOptions = elasticsearchOptions.Value;
_indexNameNormalizer = indexNameNormalizer;
Logger = NullLogger<ElasticsearchAuditLogManager>.Instance;
}
public async virtual Task<long> GetCountAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string correlationId = null,
string clientId = null,
string clientIpAddress = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
CancellationToken cancellationToken = default(CancellationToken))
{
var client = _clientFactory.Create();
var querys = BuildQueryDescriptor(
startTime,
endTime,
httpMethod,
url,
userId,
userName,
applicationName,
correlationId,
clientId,
clientIpAddress,
maxExecutionDuration,
minExecutionDuration,
hasException,
httpStatusCode);
var response = await client.CountAsync<AuditLog>(dsl =>
dsl.Index(CreateIndex())
.Query(log => log.Bool(b => b.Must(querys.ToArray()))),
cancellationToken);
return response.Count;
}
public async virtual Task<long> GetCountAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string correlationId = null,
string clientId = null,
string clientIpAddress = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
CancellationToken cancellationToken = default)
{
var client = _clientFactory.Create();
var querys = BuildQueryDescriptor(
startTime,
endTime,
httpMethod,
url,
userId,
userName,
applicationName,
correlationId,
clientId,
clientIpAddress,
maxExecutionDuration,
minExecutionDuration,
hasException,
httpStatusCode);
var response = await client.CountAsync<AuditLog>(dsl =>
dsl.Index(CreateIndex())
.Query(log => log.Bool(b => b.Must(querys.ToArray()))),
cancellationToken);
return response.Count;
}
public async virtual Task<List<AuditLog>> GetListAsync(
string sorting = null,
int maxResultCount = 50,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string correlationId = null,
string clientId = null,
string clientIpAddress = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
bool includeDetails = false,
CancellationToken cancellationToken = default(CancellationToken))
public async virtual Task<List<AuditLog>> GetListAsync(
string sorting = null,
int maxResultCount = 50,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string correlationId = null,
string clientId = null,
string clientIpAddress = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var client = _clientFactory.Create();
var sortOrder = !sorting.IsNullOrWhiteSpace() && sorting.EndsWith("asc", StringComparison.InvariantCultureIgnoreCase)
? SortOrder.Ascending : SortOrder.Descending;
sorting = !sorting.IsNullOrWhiteSpace()
? sorting.Split()[0]
: nameof(AuditLog.ExecutionTime);
var querys = BuildQueryDescriptor(
startTime,
endTime,
httpMethod,
url,
userId,
userName,
applicationName,
correlationId,
clientId,
clientIpAddress,
maxExecutionDuration,
minExecutionDuration,
hasException,
httpStatusCode);
SourceFilterDescriptor<AuditLog> SourceFilter(SourceFilterDescriptor<AuditLog> selector)
{
var client = _clientFactory.Create();
var sortOrder = !sorting.IsNullOrWhiteSpace() && sorting.EndsWith("asc", StringComparison.InvariantCultureIgnoreCase)
? SortOrder.Ascending : SortOrder.Descending;
sorting = !sorting.IsNullOrWhiteSpace()
? sorting.Split()[0]
: nameof(AuditLog.ExecutionTime);
var querys = BuildQueryDescriptor(
startTime,
endTime,
httpMethod,
url,
userId,
userName,
applicationName,
correlationId,
clientId,
clientIpAddress,
maxExecutionDuration,
minExecutionDuration,
hasException,
httpStatusCode);
SourceFilterDescriptor<AuditLog> SourceFilter(SourceFilterDescriptor<AuditLog> selector)
selector.IncludeAll();
if (!includeDetails)
{
selector.IncludeAll();
if (!includeDetails)
{
selector.Excludes(field =>
field.Field(f => f.Actions)
.Field(f => f.Comments)
.Field(f => f.Exceptions)
.Field(f => f.EntityChanges));
}
return selector;
selector.Excludes(field =>
field.Field(f => f.Actions)
.Field(f => f.Comments)
.Field(f => f.Exceptions)
.Field(f => f.EntityChanges));
}
var response = await client.SearchAsync<AuditLog>(dsl =>
dsl.Index(CreateIndex())
.Query(log => log.Bool(b => b.Must(querys.ToArray())))
.Source(SourceFilter)
.Sort(log => log.Field(GetField(sorting), sortOrder))
.From(skipCount)
.Size(maxResultCount),
cancellationToken);
return response.Documents.ToList();
return selector;
}
public async virtual Task<AuditLog> GetAsync(
Guid id,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var client = _clientFactory.Create();
var response = await client.SearchAsync<AuditLog>(dsl =>
dsl.Index(CreateIndex())
.Query(log => log.Bool(b => b.Must(querys.ToArray())))
.Source(SourceFilter)
.Sort(log => log.Field(GetField(sorting), sortOrder))
.From(skipCount)
.Size(maxResultCount),
cancellationToken);
var response = await client.GetAsync<AuditLog>(
id,
dsl =>
dsl.Index(CreateIndex()),
cancellationToken);
return response.Documents.ToList();
}
return response.Source;
}
public async virtual Task<AuditLog> GetAsync(
Guid id,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var client = _clientFactory.Create();
public async virtual Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
{
var client = _clientFactory.Create();
var response = await client.GetAsync<AuditLog>(
id,
dsl =>
dsl.Index(CreateIndex()),
cancellationToken);
await client.DeleteAsync<AuditLog>(
id,
dsl =>
dsl.Index(CreateIndex()),
cancellationToken);
}
return response.Source;
}
public async virtual Task<string> SaveAsync(
AuditLogInfo auditInfo,
CancellationToken cancellationToken = default(CancellationToken))
{
if (!_auditingOptions.HideErrors)
{
return await SaveLogAsync(auditInfo, cancellationToken);
}
public async virtual Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
{
var client = _clientFactory.Create();
try
{
return await SaveLogAsync(auditInfo, cancellationToken);
}
catch (Exception ex)
{
Logger.LogWarning("Could not save the audit log object: " + Environment.NewLine + auditInfo.ToString());
Logger.LogException(ex, Microsoft.Extensions.Logging.LogLevel.Error);
}
return "";
await client.DeleteAsync<AuditLog>(
id,
dsl =>
dsl.Index(CreateIndex()),
cancellationToken);
}
public async virtual Task<string> SaveAsync(
AuditLogInfo auditInfo,
CancellationToken cancellationToken = default)
{
if (!_auditingOptions.HideErrors)
{
return await SaveLogAsync(auditInfo, cancellationToken);
}
protected async virtual Task<string> SaveLogAsync(
AuditLogInfo auditLogInfo,
CancellationToken cancellationToken = default(CancellationToken))
try
{
var client = _clientFactory.Create();
return await SaveLogAsync(auditInfo, cancellationToken);
}
catch (Exception ex)
{
Logger.LogWarning("Could not save the audit log object: " + Environment.NewLine + auditInfo.ToString());
Logger.LogException(ex, Microsoft.Extensions.Logging.LogLevel.Error);
}
return "";
}
var auditLog = await _converter.ConvertAsync(auditLogInfo);
protected async virtual Task<string> SaveLogAsync(
AuditLogInfo auditLogInfo,
CancellationToken cancellationToken = default)
{
var client = _clientFactory.Create();
//var response = await client.IndexAsync(
// auditLog,
// (x) => x.Index(CreateIndex())
// .Id(auditLog.Id),
// cancellationToken);
var auditLog = await _converter.ConvertAsync(auditLogInfo);
// 使用 Bulk 命令传输可能存在参数庞大的日志结构
var response = await client.BulkAsync(
dsl => dsl.Index(CreateIndex())
.Create<AuditLog>(ct =>
ct.Id(auditLog.Id)
.Document(auditLog)));
//var response = await client.IndexAsync(
// auditLog,
// (x) => x.Index(CreateIndex())
// .Id(auditLog.Id),
// cancellationToken);
return response.Items?.FirstOrDefault()?.Id;
}
// 使用 Bulk 命令传输可能存在参数庞大的日志结构
var response = await client.BulkAsync(
dsl => dsl.Index(CreateIndex())
.Create<AuditLog>(ct =>
ct.Id(auditLog.Id)
.Document(auditLog)));
protected virtual List<Func<QueryContainerDescriptor<AuditLog>, QueryContainer>> BuildQueryDescriptor(
DateTime? startTime = null,
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string correlationId = null,
string clientId = null,
string clientIpAddress = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null)
{
var querys = new List<Func<QueryContainerDescriptor<AuditLog>, QueryContainer>>();
return response.Items?.FirstOrDefault()?.Id;
}
if (startTime.HasValue)
{
querys.Add((log) => log.DateRange((q) => q.Field(GetField(nameof(AuditLog.ExecutionTime))).GreaterThanOrEquals(_clock.Normalize(startTime.Value))));
}
if (endTime.HasValue)
{
querys.Add((log) => log.DateRange((q) => q.Field(GetField(nameof(AuditLog.ExecutionTime))).LessThanOrEquals(_clock.Normalize(endTime.Value))));
}
if (!httpMethod.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.HttpMethod))).Value(httpMethod)));
}
if (!url.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Wildcard((q) => q.Field(GetField(nameof(AuditLog.Url))).Value($"*{url}*")));
}
if (userId.HasValue)
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.UserId))).Value(userId)));
}
if (!userName.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.UserName))).Value(userName)));
}
if (!applicationName.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.ApplicationName))).Value(applicationName)));
}
if (!correlationId.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.CorrelationId))).Value(correlationId)));
}
if (!clientId.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.ClientId))).Value(clientId)));
}
if (!clientIpAddress.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.ClientIpAddress))).Value(clientIpAddress)));
}
if (maxExecutionDuration.HasValue)
{
querys.Add((log) => log.Range((q) => q.Field(GetField(nameof(AuditLog.ExecutionDuration))).LessThanOrEquals(maxExecutionDuration)));
}
if (minExecutionDuration.HasValue)
{
querys.Add((log) => log.Range((q) => q.Field(GetField(nameof(AuditLog.ExecutionDuration))).GreaterThanOrEquals(minExecutionDuration)));
}
protected virtual List<Func<QueryContainerDescriptor<AuditLog>, QueryContainer>> BuildQueryDescriptor(
DateTime? startTime = null,
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string correlationId = null,
string clientId = null,
string clientIpAddress = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null)
{
var querys = new List<Func<QueryContainerDescriptor<AuditLog>, QueryContainer>>();
if (startTime.HasValue)
{
querys.Add((log) => log.DateRange((q) => q.Field(GetField(nameof(AuditLog.ExecutionTime))).GreaterThanOrEquals(_clock.Normalize(startTime.Value))));
}
if (endTime.HasValue)
{
querys.Add((log) => log.DateRange((q) => q.Field(GetField(nameof(AuditLog.ExecutionTime))).LessThanOrEquals(_clock.Normalize(endTime.Value))));
}
if (!httpMethod.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.HttpMethod))).Value(httpMethod)));
}
if (!url.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Wildcard((q) => q.Field(GetField(nameof(AuditLog.Url))).Value($"*{url}*")));
}
if (userId.HasValue)
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.UserId))).Value(userId)));
}
if (!userName.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.UserName))).Value(userName)));
}
if (!applicationName.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.ApplicationName))).Value(applicationName)));
}
if (!correlationId.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.CorrelationId))).Value(correlationId)));
}
if (!clientId.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.ClientId))).Value(clientId)));
}
if (!clientIpAddress.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.ClientIpAddress))).Value(clientIpAddress)));
}
if (maxExecutionDuration.HasValue)
{
querys.Add((log) => log.Range((q) => q.Field(GetField(nameof(AuditLog.ExecutionDuration))).LessThanOrEquals(maxExecutionDuration)));
}
if (minExecutionDuration.HasValue)
{
querys.Add((log) => log.Range((q) => q.Field(GetField(nameof(AuditLog.ExecutionDuration))).GreaterThanOrEquals(minExecutionDuration)));
}
if (hasException.HasValue)
if (hasException.HasValue)
{
if (hasException.Value)
{
if (hasException.Value)
{
querys.Add(
(q) => q.Bool(
(b) => b.Must(
(m) => m.Exists(
(e) => e.Field((f) => f.Exceptions)))
)
);
}
else
{
querys.Add(
(q) => q.Bool(
(b) => b.MustNot(
(mn) => mn.Exists(
(e) => e.Field(
(f) => f.Exceptions)))
)
);
}
querys.Add(
(q) => q.Bool(
(b) => b.Must(
(m) => m.Exists(
(e) => e.Field((f) => f.Exceptions)))
)
);
}
if (httpStatusCode.HasValue)
else
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.HttpStatusCode))).Value(httpStatusCode)));
querys.Add(
(q) => q.Bool(
(b) => b.MustNot(
(mn) => mn.Exists(
(e) => e.Field(
(f) => f.Exceptions)))
)
);
}
return querys;
}
protected virtual string CreateIndex()
if (httpStatusCode.HasValue)
{
return _indexNameNormalizer.NormalizeIndex("audit-log");
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(AuditLog.HttpStatusCode))).Value(httpStatusCode)));
}
private readonly static IDictionary<string, string> _fieldMaps = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase)
{
{ "Id", "Id.keyword" },
{ "ApplicationName", "ApplicationName.keyword" },
{ "UserId", "UserId.keyword" },
{ "UserName", "UserName.keyword" },
{ "TenantId", "TenantId.keyword" },
{ "TenantName", "TenantName.keyword" },
{ "ImpersonatorUserId", "ImpersonatorUserId.keyword" },
{ "ImpersonatorTenantId", "ImpersonatorTenantId.keyword" },
{ "ClientName", "ClientName.keyword" },
{ "ClientIpAddress", "ClientIpAddress.keyword" },
{ "ClientId", "ClientId.keyword" },
{ "CorrelationId", "CorrelationId.keyword" },
{ "BrowserInfo", "BrowserInfo.keyword" },
{ "HttpMethod", "HttpMethod.keyword" },
{ "Url", "Url.keyword" },
{ "ExecutionDuration", "ExecutionDuration" },
{ "ExecutionTime", "ExecutionTime" },
{ "HttpStatusCode", "HttpStatusCode" },
};
protected virtual string GetField(string field)
{
if (_fieldMaps.TryGetValue(field, out string mapField))
{
return _elasticsearchOptions.FieldCamelCase ? mapField.ToCamelCase() : mapField.ToPascalCase();
}
return querys;
}
protected virtual string CreateIndex()
{
return _indexNameNormalizer.NormalizeIndex("audit-log");
}
return _elasticsearchOptions.FieldCamelCase ? field.ToCamelCase() : field.ToPascalCase();
private readonly static IDictionary<string, string> _fieldMaps = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase)
{
{ "Id", "Id.keyword" },
{ "ApplicationName", "ApplicationName.keyword" },
{ "UserId", "UserId.keyword" },
{ "UserName", "UserName.keyword" },
{ "TenantId", "TenantId.keyword" },
{ "TenantName", "TenantName.keyword" },
{ "ImpersonatorUserId", "ImpersonatorUserId.keyword" },
{ "ImpersonatorTenantId", "ImpersonatorTenantId.keyword" },
{ "ClientName", "ClientName.keyword" },
{ "ClientIpAddress", "ClientIpAddress.keyword" },
{ "ClientId", "ClientId.keyword" },
{ "CorrelationId", "CorrelationId.keyword" },
{ "BrowserInfo", "BrowserInfo.keyword" },
{ "HttpMethod", "HttpMethod.keyword" },
{ "Url", "Url.keyword" },
{ "ExecutionDuration", "ExecutionDuration" },
{ "ExecutionTime", "ExecutionTime" },
{ "HttpStatusCode", "HttpStatusCode" },
};
protected virtual string GetField(string field)
{
if (_fieldMaps.TryGetValue(field, out string mapField))
{
return _elasticsearchOptions.FieldCamelCase ? mapField.ToCamelCase() : mapField.ToPascalCase();
}
return _elasticsearchOptions.FieldCamelCase ? field.ToCamelCase() : field.ToPascalCase();
}
}

441
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/ElasticsearchSecurityLogManager.cs

@ -13,260 +13,259 @@ using Volo.Abp.Guids;
using Volo.Abp.SecurityLog;
using Volo.Abp.Timing;
namespace LINGYUN.Abp.AuditLogging.Elasticsearch
namespace LINGYUN.Abp.AuditLogging.Elasticsearch;
[Dependency(ReplaceServices = true)]
public class ElasticsearchSecurityLogManager : ISecurityLogManager, ITransientDependency
{
[Dependency(ReplaceServices = true)]
public class ElasticsearchSecurityLogManager : ISecurityLogManager, ITransientDependency
private readonly AbpSecurityLogOptions _securityLogOptions;
private readonly AbpElasticsearchOptions _elasticsearchOptions;
private readonly IIndexNameNormalizer _indexNameNormalizer;
private readonly IGuidGenerator _guidGenerator;
private readonly IElasticsearchClientFactory _clientFactory;
private readonly IClock _clock;
public ILogger<ElasticsearchSecurityLogManager> Logger { protected get; set; }
public ElasticsearchSecurityLogManager(
IClock clock,
IGuidGenerator guidGenerator,
IIndexNameNormalizer indexNameNormalizer,
IOptions<AbpSecurityLogOptions> securityLogOptions,
IOptions<AbpElasticsearchOptions> elasticsearchOptions,
IElasticsearchClientFactory clientFactory)
{
private readonly AbpSecurityLogOptions _securityLogOptions;
private readonly AbpElasticsearchOptions _elasticsearchOptions;
private readonly IIndexNameNormalizer _indexNameNormalizer;
private readonly IGuidGenerator _guidGenerator;
private readonly IElasticsearchClientFactory _clientFactory;
private readonly IClock _clock;
_clock = clock;
_guidGenerator = guidGenerator;
_clientFactory = clientFactory;
_indexNameNormalizer = indexNameNormalizer;
_securityLogOptions = securityLogOptions.Value;
_elasticsearchOptions = elasticsearchOptions.Value;
public ILogger<ElasticsearchSecurityLogManager> Logger { protected get; set; }
Logger = NullLogger<ElasticsearchSecurityLogManager>.Instance;
}
public ElasticsearchSecurityLogManager(
IClock clock,
IGuidGenerator guidGenerator,
IIndexNameNormalizer indexNameNormalizer,
IOptions<AbpSecurityLogOptions> securityLogOptions,
IOptions<AbpElasticsearchOptions> elasticsearchOptions,
IElasticsearchClientFactory clientFactory)
public async virtual Task SaveAsync(
SecurityLogInfo securityLogInfo,
CancellationToken cancellationToken = default)
{
// TODO: 框架不把这玩意儿放在 ISecurityLogManager?
if (!_securityLogOptions.IsEnabled)
{
_clock = clock;
_guidGenerator = guidGenerator;
_clientFactory = clientFactory;
_indexNameNormalizer = indexNameNormalizer;
_securityLogOptions = securityLogOptions.Value;
_elasticsearchOptions = elasticsearchOptions.Value;
Logger = NullLogger<ElasticsearchSecurityLogManager>.Instance;
return;
}
public async virtual Task SaveAsync(
SecurityLogInfo securityLogInfo,
CancellationToken cancellationToken = default(CancellationToken))
{
// TODO: 框架不把这玩意儿放在 ISecurityLogManager?
if (!_securityLogOptions.IsEnabled)
{
return;
}
var client = _clientFactory.Create();
var client = _clientFactory.Create();
var securityLog = new SecurityLog(
_guidGenerator.Create(),
securityLogInfo);
var securityLog = new SecurityLog(
_guidGenerator.Create(),
securityLogInfo);
await client.IndexAsync(
securityLog,
(x) => x.Index(CreateIndex())
.Id(securityLog.Id),
cancellationToken);
}
await client.IndexAsync(
securityLog,
(x) => x.Index(CreateIndex())
.Id(securityLog.Id),
cancellationToken);
}
public async virtual Task<SecurityLog> GetAsync(
Guid id,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var client = _clientFactory.Create();
public async virtual Task<SecurityLog> GetAsync(
Guid id,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var client = _clientFactory.Create();
var response = await client.GetAsync<SecurityLog>(
id,
dsl =>
dsl.Index(CreateIndex()),
cancellationToken);
var response = await client.GetAsync<SecurityLog>(
id,
dsl =>
dsl.Index(CreateIndex()),
cancellationToken);
return response.Source;
}
return response.Source;
}
public async virtual Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
{
var client = _clientFactory.Create();
public async virtual Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
{
var client = _clientFactory.Create();
await client.DeleteAsync<SecurityLog>(
id,
dsl =>
dsl.Index(CreateIndex()),
cancellationToken);
}
await client.DeleteAsync<SecurityLog>(
id,
dsl =>
dsl.Index(CreateIndex()),
cancellationToken);
}
public async virtual Task<List<SecurityLog>> GetListAsync(
string sorting = null,
int maxResultCount = 50,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string clientIpAddress = null,
string correlationId = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var client = _clientFactory.Create();
public async virtual Task<List<SecurityLog>> GetListAsync(
string sorting = null,
int maxResultCount = 50,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string clientIpAddress = null,
string correlationId = null,
bool includeDetails = false,
CancellationToken cancellationToken = default(CancellationToken))
{
var client = _clientFactory.Create();
var sortOrder = !sorting.IsNullOrWhiteSpace() && sorting.EndsWith("asc", StringComparison.InvariantCultureIgnoreCase)
? SortOrder.Ascending : SortOrder.Descending;
sorting = !sorting.IsNullOrWhiteSpace()
? sorting.Split()[0]
: nameof(SecurityLog.CreationTime);
var sortOrder = !sorting.IsNullOrWhiteSpace() && sorting.EndsWith("asc", StringComparison.InvariantCultureIgnoreCase)
? SortOrder.Ascending : SortOrder.Descending;
sorting = !sorting.IsNullOrWhiteSpace()
? sorting.Split()[0]
: nameof(SecurityLog.CreationTime);
var querys = BuildQueryDescriptor(
startTime,
endTime,
applicationName,
identity,
action,
userId,
userName,
clientId,
clientIpAddress,
correlationId);
var querys = BuildQueryDescriptor(
startTime,
endTime,
applicationName,
identity,
action,
userId,
userName,
clientId,
clientIpAddress,
correlationId);
var response = await client.SearchAsync<SecurityLog>(dsl =>
dsl.Index(CreateIndex())
.Query(log => log.Bool(b => b.Must(querys.ToArray())))
.Source(log => log.IncludeAll())
.Sort(log => log.Field(GetField(sorting), sortOrder))
.From(skipCount)
.Size(maxResultCount),
cancellationToken);
var response = await client.SearchAsync<SecurityLog>(dsl =>
dsl.Index(CreateIndex())
.Query(log => log.Bool(b => b.Must(querys.ToArray())))
.Source(log => log.IncludeAll())
.Sort(log => log.Field(GetField(sorting), sortOrder))
.From(skipCount)
.Size(maxResultCount),
cancellationToken);
return response.Documents.ToList();
}
return response.Documents.ToList();
}
public async virtual Task<long> GetCountAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string clientIpAddress = null,
string correlationId = null,
CancellationToken cancellationToken = default)
{
var client = _clientFactory.Create();
public async virtual Task<long> GetCountAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string clientIpAddress = null,
string correlationId = null,
CancellationToken cancellationToken = default(CancellationToken))
{
var client = _clientFactory.Create();
var querys = BuildQueryDescriptor(
startTime,
endTime,
applicationName,
identity,
action,
userId,
userName,
clientId,
clientIpAddress,
correlationId);
var querys = BuildQueryDescriptor(
startTime,
endTime,
applicationName,
identity,
action,
userId,
userName,
clientId,
clientIpAddress,
correlationId);
var response = await client.CountAsync<SecurityLog>(dsl =>
dsl.Index(CreateIndex())
.Query(log => log.Bool(b => b.Must(querys.ToArray()))),
cancellationToken);
var response = await client.CountAsync<SecurityLog>(dsl =>
dsl.Index(CreateIndex())
.Query(log => log.Bool(b => b.Must(querys.ToArray()))),
cancellationToken);
return response.Count;
}
return response.Count;
}
protected virtual List<Func<QueryContainerDescriptor<SecurityLog>, QueryContainer>> BuildQueryDescriptor(
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string clientIpAddress = null,
string correlationId = null)
{
var querys = new List<Func<QueryContainerDescriptor<SecurityLog>, QueryContainer>>();
protected virtual List<Func<QueryContainerDescriptor<SecurityLog>, QueryContainer>> BuildQueryDescriptor(
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string clientIpAddress = null,
string correlationId = null)
if (startTime.HasValue)
{
var querys = new List<Func<QueryContainerDescriptor<SecurityLog>, QueryContainer>>();
if (startTime.HasValue)
{
querys.Add((log) => log.DateRange((q) => q.Field(GetField(nameof(SecurityLog.CreationTime))).GreaterThanOrEquals(_clock.Normalize(startTime.Value))));
}
if (endTime.HasValue)
{
querys.Add((log) => log.DateRange((q) => q.Field(GetField(nameof(SecurityLog.CreationTime))).LessThanOrEquals(_clock.Normalize(endTime.Value))));
}
if (!applicationName.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.ApplicationName))).Value(applicationName)));
}
if (!identity.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.Identity))).Value(identity)));
}
if (!action.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.Action))).Value(action)));
}
if (userId.HasValue)
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.UserId))).Value(userId)));
}
if (!userName.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.UserName))).Value(userName)));
}
if (!clientId.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.ClientId))).Value(clientId)));
}
if (!clientIpAddress.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.ClientIpAddress))).Value(clientIpAddress)));
}
if (!correlationId.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.CorrelationId))).Value(correlationId)));
}
return querys;
querys.Add((log) => log.DateRange((q) => q.Field(GetField(nameof(SecurityLog.CreationTime))).GreaterThanOrEquals(_clock.Normalize(startTime.Value))));
}
protected virtual string CreateIndex()
if (endTime.HasValue)
{
return _indexNameNormalizer.NormalizeIndex("security-log");
querys.Add((log) => log.DateRange((q) => q.Field(GetField(nameof(SecurityLog.CreationTime))).LessThanOrEquals(_clock.Normalize(endTime.Value))));
}
private readonly static IDictionary<string, string> _fieldMaps = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase)
if (!applicationName.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.ApplicationName))).Value(applicationName)));
}
if (!identity.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.Identity))).Value(identity)));
}
if (!action.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.Action))).Value(action)));
}
if (userId.HasValue)
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.UserId))).Value(userId)));
}
if (!userName.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.UserName))).Value(userName)));
}
if (!clientId.IsNullOrWhiteSpace())
{
{ "Id", "Id.keyword" },
{ "ApplicationName", "ApplicationName.keyword" },
{ "UserId", "UserId.keyword" },
{ "UserName", "UserName.keyword" },
{ "TenantId", "TenantId.keyword" },
{ "TenantName", "TenantName.keyword" },
{ "Identity", "Identity.keyword" },
{ "Action", "Action.keyword" },
{ "BrowserInfo", "BrowserInfo.keyword" },
{ "ClientIpAddress", "ClientIpAddress.keyword" },
{ "ClientId", "ClientId.keyword" },
{ "CorrelationId", "CorrelationId.keyword" },
{ "CreationTime", "CreationTime" },
};
protected virtual string GetField(string field)
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.ClientId))).Value(clientId)));
}
if (!clientIpAddress.IsNullOrWhiteSpace())
{
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.ClientIpAddress))).Value(clientIpAddress)));
}
if (!correlationId.IsNullOrWhiteSpace())
{
if (_fieldMaps.TryGetValue(field, out string mapField))
{
return _elasticsearchOptions.FieldCamelCase ? mapField.ToCamelCase() : mapField.ToPascalCase();
}
querys.Add((log) => log.Term((q) => q.Field(GetField(nameof(SecurityLog.CorrelationId))).Value(correlationId)));
}
return _elasticsearchOptions.FieldCamelCase ? field.ToCamelCase() : field.ToPascalCase();
return querys;
}
protected virtual string CreateIndex()
{
return _indexNameNormalizer.NormalizeIndex("security-log");
}
private readonly static IDictionary<string, string> _fieldMaps = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase)
{
{ "Id", "Id.keyword" },
{ "ApplicationName", "ApplicationName.keyword" },
{ "UserId", "UserId.keyword" },
{ "UserName", "UserName.keyword" },
{ "TenantId", "TenantId.keyword" },
{ "TenantName", "TenantName.keyword" },
{ "Identity", "Identity.keyword" },
{ "Action", "Action.keyword" },
{ "BrowserInfo", "BrowserInfo.keyword" },
{ "ClientIpAddress", "ClientIpAddress.keyword" },
{ "ClientId", "ClientId.keyword" },
{ "CorrelationId", "CorrelationId.keyword" },
{ "CreationTime", "CreationTime" },
};
protected virtual string GetField(string field)
{
if (_fieldMaps.TryGetValue(field, out string mapField))
{
return _elasticsearchOptions.FieldCamelCase ? mapField.ToCamelCase() : mapField.ToPascalCase();
}
return _elasticsearchOptions.FieldCamelCase ? field.ToCamelCase() : field.ToPascalCase();
}
}

9
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IAuditLogInfoToAuditLogConverter.cs

@ -1,10 +1,9 @@
using System.Threading.Tasks;
using Volo.Abp.Auditing;
namespace LINGYUN.Abp.AuditLogging
namespace LINGYUN.Abp.AuditLogging;
public interface IAuditLogInfoToAuditLogConverter
{
public interface IAuditLogInfoToAuditLogConverter
{
Task<AuditLog> ConvertAsync(AuditLogInfo auditLogInfo);
}
Task<AuditLog> ConvertAsync(AuditLogInfo auditLogInfo);
}

9
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IIndexInitializer.cs

@ -1,9 +1,8 @@
using System.Threading.Tasks;
namespace LINGYUN.Abp.AuditLogging.Elasticsearch
namespace LINGYUN.Abp.AuditLogging.Elasticsearch;
public interface IIndexInitializer
{
public interface IIndexInitializer
{
Task InitializeAsync();
}
Task InitializeAsync();
}

9
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IIndexNameNormalizer.cs

@ -1,7 +1,6 @@
namespace LINGYUN.Abp.AuditLogging.Elasticsearch
namespace LINGYUN.Abp.AuditLogging.Elasticsearch;
public interface IIndexNameNormalizer
{
public interface IIndexNameNormalizer
{
string NormalizeIndex(string index);
}
string NormalizeIndex(string index);
}

155
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IndexInitializer.cs

@ -9,98 +9,97 @@ using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Json;
namespace LINGYUN.Abp.AuditLogging.Elasticsearch
namespace LINGYUN.Abp.AuditLogging.Elasticsearch;
public class IndexInitializer : IIndexInitializer, ISingletonDependency
{
public class IndexInitializer : IIndexInitializer, ISingletonDependency
{
private readonly AbpJsonOptions _jsonOptions;
private readonly AbpAuditLoggingElasticsearchOptions _elasticsearchOptions;
private readonly IIndexNameNormalizer _nameNormalizer;
private readonly IElasticsearchClientFactory _clientFactory;
private readonly AbpJsonOptions _jsonOptions;
private readonly AbpAuditLoggingElasticsearchOptions _elasticsearchOptions;
private readonly IIndexNameNormalizer _nameNormalizer;
private readonly IElasticsearchClientFactory _clientFactory;
public ILogger<IndexInitializer> Logger { protected get; set; }
public ILogger<IndexInitializer> Logger { protected get; set; }
public IndexInitializer(
IOptions<AbpJsonOptions> jsonOptions,
IOptions<AbpAuditLoggingElasticsearchOptions> elasticsearchOptions,
IIndexNameNormalizer nameNormalizer,
IElasticsearchClientFactory clientFactory)
{
_jsonOptions = jsonOptions.Value;
_elasticsearchOptions = elasticsearchOptions.Value;
_nameNormalizer = nameNormalizer;
_clientFactory = clientFactory;
public IndexInitializer(
IOptions<AbpJsonOptions> jsonOptions,
IOptions<AbpAuditLoggingElasticsearchOptions> elasticsearchOptions,
IIndexNameNormalizer nameNormalizer,
IElasticsearchClientFactory clientFactory)
{
_jsonOptions = jsonOptions.Value;
_elasticsearchOptions = elasticsearchOptions.Value;
_nameNormalizer = nameNormalizer;
_clientFactory = clientFactory;
Logger = NullLogger<IndexInitializer>.Instance;
}
Logger = NullLogger<IndexInitializer>.Instance;
}
public async virtual Task InitializeAsync()
public async virtual Task InitializeAsync()
{
var client = _clientFactory.Create();
var dateTimeFormat = !_jsonOptions.OutputDateTimeFormat.IsNullOrWhiteSpace()
? $"{_jsonOptions.OutputDateTimeFormat}||strict_date_optional_time||epoch_millis"
: "strict_date_optional_time||epoch_millis";
var indexState = new IndexState
{
var client = _clientFactory.Create();
var dateTimeFormat = !_jsonOptions.OutputDateTimeFormat.IsNullOrWhiteSpace()
? $"{_jsonOptions.OutputDateTimeFormat}||strict_date_optional_time||epoch_millis"
: "strict_date_optional_time||epoch_millis";
var indexState = new IndexState
{
Settings = _elasticsearchOptions.IndexSettings,
};
await InitlizeAuditLogIndex(client, indexState, dateTimeFormat);
await InitlizeSecurityLogIndex(client, indexState, dateTimeFormat);
}
Settings = _elasticsearchOptions.IndexSettings,
};
await InitlizeAuditLogIndex(client, indexState, dateTimeFormat);
await InitlizeSecurityLogIndex(client, indexState, dateTimeFormat);
}
protected async virtual Task InitlizeAuditLogIndex(IElasticClient client, IIndexState indexState, string dateTimeFormat)
protected async virtual Task InitlizeAuditLogIndex(IElasticClient client, IIndexState indexState, string dateTimeFormat)
{
var indexName = _nameNormalizer.NormalizeIndex("audit-log");
var indexExists = await client.Indices.ExistsAsync(indexName);
if (!indexExists.Exists)
{
var indexName = _nameNormalizer.NormalizeIndex("audit-log");
var indexExists = await client.Indices.ExistsAsync(indexName);
if (!indexExists.Exists)
var indexCreateResponse = await client.Indices.CreateAsync(
indexName,
dsl => dsl.InitializeUsing(indexState)
.Map<AuditLog>(map =>
map.AutoMap()
.Properties(mp =>
mp.Date(p => p.Name(n => n.ExecutionTime).Format(dateTimeFormat))
.Object<ExtraPropertyDictionary>(p => p.Name(n => n.ExtraProperties))
.Nested<EntityChange>(n =>
n.AutoMap()
.Name(nameof(AuditLog.EntityChanges))
.Properties(np =>
np.Object<ExtraPropertyDictionary>(p => p.Name(n => n.ExtraProperties))
.Date(p => p.Name(n => n.ChangeTime).Format(dateTimeFormat))
.Nested<EntityPropertyChange>(npn => npn.Name(nameof(EntityChange.PropertyChanges)))))
.Nested<AuditLogAction>(n => n.Name(nameof(AuditLog.Actions))
.AutoMap()
.Properties((np =>
np.Object<ExtraPropertyDictionary>(p => p.Name(n => n.ExtraProperties))
.Date(p => p.Name(n => n.ExecutionTime).Format(dateTimeFormat))))))));
if (!indexCreateResponse.IsValid)
{
var indexCreateResponse = await client.Indices.CreateAsync(
indexName,
dsl => dsl.InitializeUsing(indexState)
.Map<AuditLog>(map =>
map.AutoMap()
.Properties(mp =>
mp.Date(p => p.Name(n => n.ExecutionTime).Format(dateTimeFormat))
.Object<ExtraPropertyDictionary>(p => p.Name(n => n.ExtraProperties))
.Nested<EntityChange>(n =>
n.AutoMap()
.Name(nameof(AuditLog.EntityChanges))
.Properties(np =>
np.Object<ExtraPropertyDictionary>(p => p.Name(n => n.ExtraProperties))
.Date(p => p.Name(n => n.ChangeTime).Format(dateTimeFormat))
.Nested<EntityPropertyChange>(npn => npn.Name(nameof(EntityChange.PropertyChanges)))))
.Nested<AuditLogAction>(n => n.Name(nameof(AuditLog.Actions))
.AutoMap()
.Properties((np =>
np.Object<ExtraPropertyDictionary>(p => p.Name(n => n.ExtraProperties))
.Date(p => p.Name(n => n.ExecutionTime).Format(dateTimeFormat))))))));
if (!indexCreateResponse.IsValid)
{
Logger.LogWarning("Failed to initialize index and audit log may not be retrieved.");
Logger.LogWarning(indexCreateResponse.OriginalException.ToString());
}
Logger.LogWarning("Failed to initialize index and audit log may not be retrieved.");
Logger.LogWarning(indexCreateResponse.OriginalException.ToString());
}
}
}
protected async virtual Task InitlizeSecurityLogIndex(IElasticClient client, IIndexState indexState, string dateTimeFormat)
protected async virtual Task InitlizeSecurityLogIndex(IElasticClient client, IIndexState indexState, string dateTimeFormat)
{
var indexName = _nameNormalizer.NormalizeIndex("security-log");
var indexExists = await client.Indices.ExistsAsync(indexName);
if (!indexExists.Exists)
{
var indexName = _nameNormalizer.NormalizeIndex("security-log");
var indexExists = await client.Indices.ExistsAsync(indexName);
if (!indexExists.Exists)
var indexCreateResponse = await client.Indices.CreateAsync(
indexName,
dsl => dsl.InitializeUsing(indexState)
.Map<SecurityLog>(map =>
map.AutoMap()
.Properties(mp =>
mp.Object<ExtraPropertyDictionary>(p => p.Name(n => n.ExtraProperties))
.Date(p => p.Name(n => n.CreationTime).Format(dateTimeFormat)))));
if (!indexCreateResponse.IsValid)
{
var indexCreateResponse = await client.Indices.CreateAsync(
indexName,
dsl => dsl.InitializeUsing(indexState)
.Map<SecurityLog>(map =>
map.AutoMap()
.Properties(mp =>
mp.Object<ExtraPropertyDictionary>(p => p.Name(n => n.ExtraProperties))
.Date(p => p.Name(n => n.CreationTime).Format(dateTimeFormat)))));
if (!indexCreateResponse.IsValid)
{
Logger.LogWarning("Failed to initialize index and security log may not be retrieved.");
Logger.LogWarning(indexCreateResponse.OriginalException.ToString());
}
Logger.LogWarning("Failed to initialize index and security log may not be retrieved.");
Logger.LogWarning(indexCreateResponse.OriginalException.ToString());
}
}
}

23
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IndexInitializerService.cs

@ -2,20 +2,19 @@
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.AuditLogging.Elasticsearch
namespace LINGYUN.Abp.AuditLogging.Elasticsearch;
public class IndexInitializerService : BackgroundService
{
public class IndexInitializerService : BackgroundService
{
private readonly IIndexInitializer _indexInitializer;
private readonly IIndexInitializer _indexInitializer;
public IndexInitializerService(IIndexInitializer indexInitializer)
{
_indexInitializer = indexInitializer;
}
public IndexInitializerService(IIndexInitializer indexInitializer)
{
_indexInitializer = indexInitializer;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await _indexInitializer.InitializeAsync();
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await _indexInitializer.InitializeAsync();
}
}

39
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.Elasticsearch/LINGYUN/Abp/AuditLogging/Elasticsearch/IndexNameNormalizer.cs

@ -3,30 +3,29 @@ using System;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.AuditLogging.Elasticsearch
namespace LINGYUN.Abp.AuditLogging.Elasticsearch;
public class IndexNameNormalizer : IIndexNameNormalizer, ISingletonDependency
{
public class IndexNameNormalizer : IIndexNameNormalizer, ISingletonDependency
{
private readonly ICurrentTenant _currentTenant;
private readonly AbpAuditLoggingElasticsearchOptions _options;
private readonly ICurrentTenant _currentTenant;
private readonly AbpAuditLoggingElasticsearchOptions _options;
public IndexNameNormalizer(
ICurrentTenant currentTenant,
IOptions<AbpAuditLoggingElasticsearchOptions> options)
{
_currentTenant = currentTenant;
_options = options.Value;
}
public IndexNameNormalizer(
ICurrentTenant currentTenant,
IOptions<AbpAuditLoggingElasticsearchOptions> options)
{
_currentTenant = currentTenant;
_options = options.Value;
}
public string NormalizeIndex(string index)
public string NormalizeIndex(string index)
{
if (_currentTenant.IsAvailable)
{
if (_currentTenant.IsAvailable)
{
return $"{_options.IndexPrefix}-{index}-{_currentTenant.Id:N}";
}
return _options.IndexPrefix.IsNullOrWhiteSpace()
? index
: $"{_options.IndexPrefix}-{index}";
return $"{_options.IndexPrefix}-{index}-{_currentTenant.Id:N}";
}
return _options.IndexPrefix.IsNullOrWhiteSpace()
? index
: $"{_options.IndexPrefix}-{index}";
}
}

5
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/LINGYUN.Abp.AuditLogging.EntityFrameworkCore.csproj

@ -5,6 +5,11 @@
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AssemblyName>LINGYUN.Abp.AuditLogging.EntityFrameworkCore</AssemblyName>
<PackageId>LINGYUN.Abp.AuditLogging.EntityFrameworkCore</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>

31
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/LINGYUN/Abp/AuditLogging/EntityFrameworkCore/AbpAuditLoggingEntityFrameworkCoreModule.cs

@ -2,24 +2,23 @@
using Volo.Abp.AutoMapper;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.AuditLogging.EntityFrameworkCore
namespace LINGYUN.Abp.AuditLogging.EntityFrameworkCore;
[DependsOn(
typeof(Volo.Abp.Identity.EntityFrameworkCore.AbpIdentityEntityFrameworkCoreModule),
typeof(Volo.Abp.AuditLogging.EntityFrameworkCore.AbpAuditLoggingEntityFrameworkCoreModule))]
[DependsOn(
typeof(AbpAuditLoggingModule),
typeof(AbpAutoMapperModule))]
public class AbpAuditLoggingEntityFrameworkCoreModule : AbpModule
{
[DependsOn(
typeof(Volo.Abp.Identity.EntityFrameworkCore.AbpIdentityEntityFrameworkCoreModule),
typeof(Volo.Abp.AuditLogging.EntityFrameworkCore.AbpAuditLoggingEntityFrameworkCoreModule))]
[DependsOn(
typeof(AbpAuditLoggingModule),
typeof(AbpAutoMapperModule))]
public class AbpAuditLoggingEntityFrameworkCoreModule : AbpModule
public override void ConfigureServices(ServiceConfigurationContext context)
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAutoMapperObjectMapper<AbpAuditLoggingEntityFrameworkCoreModule>();
context.Services.AddAutoMapperObjectMapper<AbpAuditLoggingEntityFrameworkCoreModule>();
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<AbpAuditingMapperProfile>(validate: true);
});
}
Configure<AbpAutoMapperOptions>(options =>
{
options.AddProfile<AbpAuditingMapperProfile>(validate: true);
});
}
}

27
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/LINGYUN/Abp/AuditLogging/EntityFrameworkCore/AbpAuditingMapperProfile.cs

@ -1,21 +1,20 @@
using AutoMapper;
namespace LINGYUN.Abp.AuditLogging.EntityFrameworkCore
namespace LINGYUN.Abp.AuditLogging.EntityFrameworkCore;
public class AbpAuditingMapperProfile : Profile
{
public class AbpAuditingMapperProfile : Profile
public AbpAuditingMapperProfile()
{
public AbpAuditingMapperProfile()
{
CreateMap<Volo.Abp.AuditLogging.AuditLogAction, LINGYUN.Abp.AuditLogging.AuditLogAction>()
.MapExtraProperties();
CreateMap<Volo.Abp.AuditLogging.EntityPropertyChange, LINGYUN.Abp.AuditLogging.EntityPropertyChange>();
CreateMap<Volo.Abp.AuditLogging.EntityChange, LINGYUN.Abp.AuditLogging.EntityChange>()
.MapExtraProperties();
CreateMap<Volo.Abp.AuditLogging.AuditLog, LINGYUN.Abp.AuditLogging.AuditLog>()
.MapExtraProperties();
CreateMap<Volo.Abp.AuditLogging.AuditLogAction, LINGYUN.Abp.AuditLogging.AuditLogAction>()
.MapExtraProperties();
CreateMap<Volo.Abp.AuditLogging.EntityPropertyChange, LINGYUN.Abp.AuditLogging.EntityPropertyChange>();
CreateMap<Volo.Abp.AuditLogging.EntityChange, LINGYUN.Abp.AuditLogging.EntityChange>()
.MapExtraProperties();
CreateMap<Volo.Abp.AuditLogging.AuditLog, LINGYUN.Abp.AuditLogging.AuditLog>()
.MapExtraProperties();
CreateMap<Volo.Abp.Identity.IdentitySecurityLog, LINGYUN.Abp.AuditLogging.SecurityLog>()
.MapExtraProperties();
}
CreateMap<Volo.Abp.Identity.IdentitySecurityLog, LINGYUN.Abp.AuditLogging.SecurityLog>()
.MapExtraProperties();
}
}

289
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/LINGYUN/Abp/AuditLogging/EntityFrameworkCore/AuditLogManager.cs

@ -12,168 +12,169 @@ using Volo.Abp.DependencyInjection;
using Volo.Abp.ObjectMapping;
using Volo.Abp.Uow;
namespace LINGYUN.Abp.AuditLogging.EntityFrameworkCore
namespace LINGYUN.Abp.AuditLogging.EntityFrameworkCore;
[Dependency(ReplaceServices = true)]
public class AuditLogManager : IAuditLogManager, ITransientDependency
{
[Dependency(ReplaceServices = true)]
public class AuditLogManager : IAuditLogManager, ITransientDependency
protected IObjectMapper ObjectMapper { get; }
protected IAuditLogRepository AuditLogRepository { get; }
protected IUnitOfWorkManager UnitOfWorkManager { get; }
protected AbpAuditingOptions Options { get; }
protected IAuditLogInfoToAuditLogConverter Converter { get; }
public ILogger<AuditLogManager> Logger { protected get; set; }
public AuditLogManager(
IObjectMapper objectMapper,
IAuditLogRepository auditLogRepository,
IUnitOfWorkManager unitOfWorkManager,
IOptions<AbpAuditingOptions> options,
IAuditLogInfoToAuditLogConverter converter)
{
protected IObjectMapper ObjectMapper { get; }
protected IAuditLogRepository AuditLogRepository { get; }
protected IUnitOfWorkManager UnitOfWorkManager { get; }
protected AbpAuditingOptions Options { get; }
protected IAuditLogInfoToAuditLogConverter Converter { get; }
public ILogger<AuditLogManager> Logger { protected get; set; }
public AuditLogManager(
IObjectMapper objectMapper,
IAuditLogRepository auditLogRepository,
IUnitOfWorkManager unitOfWorkManager,
IOptions<AbpAuditingOptions> options,
IAuditLogInfoToAuditLogConverter converter)
{
ObjectMapper = objectMapper;
AuditLogRepository = auditLogRepository;
UnitOfWorkManager = unitOfWorkManager;
Converter = converter;
Options = options.Value;
ObjectMapper = objectMapper;
AuditLogRepository = auditLogRepository;
UnitOfWorkManager = unitOfWorkManager;
Converter = converter;
Options = options.Value;
Logger = NullLogger<AuditLogManager>.Instance;
}
Logger = NullLogger<AuditLogManager>.Instance;
}
public async virtual Task<long> GetCountAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string correlationId = null,
string clientId = null,
string clientIpAddress = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
CancellationToken cancellationToken = default(CancellationToken))
{
return await AuditLogRepository.GetCountAsync(
startTime,
endTime,
httpMethod,
url,
userId,
userName,
applicationName,
clientIpAddress,
correlationId,
maxExecutionDuration,
minExecutionDuration,
hasException,
httpStatusCode,
cancellationToken);
}
public async virtual Task<long> GetCountAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string correlationId = null,
string clientId = null,
string clientIpAddress = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
CancellationToken cancellationToken = default)
{
return await AuditLogRepository.GetCountAsync(
startTime,
endTime,
httpMethod,
url,
clientId,
userId,
userName,
applicationName,
clientIpAddress,
correlationId,
maxExecutionDuration,
minExecutionDuration,
hasException,
httpStatusCode,
cancellationToken);
}
public async virtual Task<List<AuditLog>> GetListAsync(
string sorting = null,
int maxResultCount = 50,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string correlationId = null,
string clientId = null,
string clientIpAddress = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
bool includeDetails = false,
CancellationToken cancellationToken = default(CancellationToken))
{
var auditLogs = await AuditLogRepository.GetListAsync(
sorting,
maxResultCount,
skipCount,
startTime,
endTime,
httpMethod,
url,
userId,
userName,
applicationName,
clientIpAddress,
correlationId,
maxExecutionDuration,
minExecutionDuration,
hasException,
httpStatusCode,
includeDetails,
cancellationToken);
public async virtual Task<List<AuditLog>> GetListAsync(
string sorting = null,
int maxResultCount = 50,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string correlationId = null,
string clientId = null,
string clientIpAddress = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var auditLogs = await AuditLogRepository.GetListAsync(
sorting,
maxResultCount,
skipCount,
startTime,
endTime,
httpMethod,
url,
clientId,
userId,
userName,
applicationName,
clientIpAddress,
correlationId,
maxExecutionDuration,
minExecutionDuration,
hasException,
httpStatusCode,
includeDetails,
cancellationToken);
return ObjectMapper.Map<List<Volo.Abp.AuditLogging.AuditLog>, List<AuditLog>>(auditLogs);
}
return ObjectMapper.Map<List<Volo.Abp.AuditLogging.AuditLog>, List<AuditLog>>(auditLogs);
}
public async virtual Task<AuditLog> GetAsync(
Guid id,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var auditLog = await AuditLogRepository.GetAsync(id, includeDetails, cancellationToken);
public async virtual Task<AuditLog> GetAsync(
Guid id,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var auditLog = await AuditLogRepository.GetAsync(id, includeDetails, cancellationToken);
return ObjectMapper.Map<Volo.Abp.AuditLogging.AuditLog, AuditLog>(auditLog);
}
return ObjectMapper.Map<Volo.Abp.AuditLogging.AuditLog, AuditLog>(auditLog);
public async virtual Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
{
using (var uow = UnitOfWorkManager.Begin(true))
{
await AuditLogRepository.DeleteAsync(id);
await uow.CompleteAsync();
}
}
public async virtual Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
public async virtual Task<string> SaveAsync(
AuditLogInfo auditInfo,
CancellationToken cancellationToken = default)
{
if (!Options.HideErrors)
{
using (var uow = UnitOfWorkManager.Begin(true))
{
await AuditLogRepository.DeleteAsync(id);
await uow.CompleteAsync();
}
return await SaveLogAsync(auditInfo, cancellationToken);
}
public async virtual Task<string> SaveAsync(
AuditLogInfo auditInfo,
CancellationToken cancellationToken = default(CancellationToken))
try
{
return await SaveLogAsync(auditInfo, cancellationToken);
}
catch (Exception ex)
{
if (!Options.HideErrors)
{
return await SaveLogAsync(auditInfo, cancellationToken);
}
try
{
return await SaveLogAsync(auditInfo, cancellationToken);
}
catch (Exception ex)
{
Logger.LogWarning("Could not save the audit log object: " + Environment.NewLine + auditInfo.ToString());
Logger.LogException(ex, LogLevel.Error);
}
return "";
Logger.LogWarning("Could not save the audit log object: " + Environment.NewLine + auditInfo.ToString());
Logger.LogException(ex, LogLevel.Error);
}
return "";
}
protected async virtual Task<string> SaveLogAsync(
AuditLogInfo auditInfo,
CancellationToken cancellationToken = default(CancellationToken))
protected async virtual Task<string> SaveLogAsync(
AuditLogInfo auditInfo,
CancellationToken cancellationToken = default)
{
using (var uow = UnitOfWorkManager.Begin(true))
{
using (var uow = UnitOfWorkManager.Begin(true))
{
var auditLog = await AuditLogRepository.InsertAsync(
await Converter.ConvertAsync(auditInfo),
false,
cancellationToken);
await uow.CompleteAsync();
return auditLog.Id.ToString();
}
var auditLog = await AuditLogRepository.InsertAsync(
await Converter.ConvertAsync(auditInfo),
false,
cancellationToken);
await uow.CompleteAsync();
return auditLog.Id.ToString();
}
}
}

223
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/LINGYUN/Abp/AuditLogging/EntityFrameworkCore/SecurityLogManager.cs

@ -11,134 +11,133 @@ using Volo.Abp.ObjectMapping;
using Volo.Abp.SecurityLog;
using Volo.Abp.Uow;
namespace LINGYUN.Abp.AuditLogging.EntityFrameworkCore
namespace LINGYUN.Abp.AuditLogging.EntityFrameworkCore;
[Dependency(ReplaceServices = true)]
public class SecurityLogManager : ISecurityLogManager, ITransientDependency
{
[Dependency(ReplaceServices = true)]
public class SecurityLogManager : ISecurityLogManager, ITransientDependency
{
public ILogger<SecurityLogManager> Logger { get; set; }
public ILogger<SecurityLogManager> Logger { get; set; }
protected IObjectMapper ObjectMapper { get; }
protected AbpSecurityLogOptions SecurityLogOptions { get; }
protected IIdentitySecurityLogRepository IdentitySecurityLogRepository { get; }
protected IGuidGenerator GuidGenerator { get; }
protected IUnitOfWorkManager UnitOfWorkManager { get; }
protected IObjectMapper ObjectMapper { get; }
protected AbpSecurityLogOptions SecurityLogOptions { get; }
protected IIdentitySecurityLogRepository IdentitySecurityLogRepository { get; }
protected IGuidGenerator GuidGenerator { get; }
protected IUnitOfWorkManager UnitOfWorkManager { get; }
public SecurityLogManager(
IObjectMapper objectMapper,
ILogger<SecurityLogManager> logger,
IOptions<AbpSecurityLogOptions> securityLogOptions,
IIdentitySecurityLogRepository identitySecurityLogRepository,
IGuidGenerator guidGenerator,
IUnitOfWorkManager unitOfWorkManager)
{
Logger = logger;
ObjectMapper = objectMapper;
SecurityLogOptions = securityLogOptions.Value;
IdentitySecurityLogRepository = identitySecurityLogRepository;
GuidGenerator = guidGenerator;
UnitOfWorkManager = unitOfWorkManager;
}
public SecurityLogManager(
IObjectMapper objectMapper,
ILogger<SecurityLogManager> logger,
IOptions<AbpSecurityLogOptions> securityLogOptions,
IIdentitySecurityLogRepository identitySecurityLogRepository,
IGuidGenerator guidGenerator,
IUnitOfWorkManager unitOfWorkManager)
public async virtual Task SaveAsync(
SecurityLogInfo securityLogInfo,
CancellationToken cancellationToken = default)
{
if (!SecurityLogOptions.IsEnabled)
{
Logger = logger;
ObjectMapper = objectMapper;
SecurityLogOptions = securityLogOptions.Value;
IdentitySecurityLogRepository = identitySecurityLogRepository;
GuidGenerator = guidGenerator;
UnitOfWorkManager = unitOfWorkManager;
return;
}
public async virtual Task SaveAsync(
SecurityLogInfo securityLogInfo,
CancellationToken cancellationToken = default(CancellationToken))
using (var uow = UnitOfWorkManager.Begin(requiresNew: true))
{
if (!SecurityLogOptions.IsEnabled)
{
return;
}
using (var uow = UnitOfWorkManager.Begin(requiresNew: true))
{
await IdentitySecurityLogRepository.InsertAsync(
new IdentitySecurityLog(GuidGenerator, securityLogInfo),
false,
cancellationToken);
await uow.CompleteAsync();
}
await IdentitySecurityLogRepository.InsertAsync(
new IdentitySecurityLog(GuidGenerator, securityLogInfo),
false,
cancellationToken);
await uow.CompleteAsync();
}
}
public async virtual Task<SecurityLog> GetAsync(
Guid id,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var securityLog = await IdentitySecurityLogRepository.GetAsync(id, includeDetails, cancellationToken);
public async virtual Task<SecurityLog> GetAsync(
Guid id,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var securityLog = await IdentitySecurityLogRepository.GetAsync(id, includeDetails, cancellationToken);
return ObjectMapper.Map<IdentitySecurityLog, SecurityLog>(securityLog);
}
return ObjectMapper.Map<IdentitySecurityLog, SecurityLog>(securityLog);
}
public async virtual Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
public async virtual Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
{
using (var uow = UnitOfWorkManager.Begin(true))
{
using (var uow = UnitOfWorkManager.Begin(true))
{
await IdentitySecurityLogRepository.DeleteAsync(id);
await uow.CompleteAsync();
}
await IdentitySecurityLogRepository.DeleteAsync(id);
await uow.CompleteAsync();
}
}
public async virtual Task<List<SecurityLog>> GetListAsync(
string sorting = null,
int maxResultCount = 50,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string clientIpAddress = null,
string correlationId = null,
bool includeDetails = false,
CancellationToken cancellationToken = default(CancellationToken))
{
var securityLogs = await IdentitySecurityLogRepository.GetListAsync(
sorting,
maxResultCount,
skipCount,
startTime,
endTime,
applicationName,
identity,
action,
userId,
userName,
clientId,
correlationId,
includeDetails,
cancellationToken);
public async virtual Task<List<SecurityLog>> GetListAsync(
string sorting = null,
int maxResultCount = 50,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string clientIpAddress = null,
string correlationId = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
var securityLogs = await IdentitySecurityLogRepository.GetListAsync(
sorting,
maxResultCount,
skipCount,
startTime,
endTime,
applicationName,
identity,
action,
userId,
userName,
clientId,
correlationId,
includeDetails,
cancellationToken);
return ObjectMapper.Map<List<IdentitySecurityLog>, List<SecurityLog>>(securityLogs);
}
return ObjectMapper.Map<List<IdentitySecurityLog>, List<SecurityLog>>(securityLogs);
}
public async virtual Task<long> GetCountAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string clientIpAddress = null,
string correlationId = null,
CancellationToken cancellationToken = default(CancellationToken))
{
return await IdentitySecurityLogRepository.GetCountAsync(
startTime,
endTime,
applicationName,
identity,
action,
userId,
userName,
clientId,
correlationId,
cancellationToken);
}
public async virtual Task<long> GetCountAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string clientIpAddress = null,
string correlationId = null,
CancellationToken cancellationToken = default)
{
return await IdentitySecurityLogRepository.GetCountAsync(
startTime,
endTime,
applicationName,
identity,
action,
userId,
userName,
clientId,
correlationId,
cancellationToken);
}
}

9
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN.Abp.AuditLogging.csproj

@ -4,7 +4,14 @@
<Import Project="..\..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0</TargetFrameworks>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<AssemblyName>LINGYUN.Abp.AuditLogging</AssemblyName>
<PackageId>LINGYUN.Abp.AuditLogging</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>

25
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/AbpAuditLoggingModule.cs

@ -5,21 +5,20 @@ using Volo.Abp.ExceptionHandling;
using Volo.Abp.Guids;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.AuditLogging
namespace LINGYUN.Abp.AuditLogging;
[DependsOn(
typeof(AbpAuditingModule),
typeof(AbpGuidsModule),
typeof(AbpExceptionHandlingModule))]
public class AbpAuditLoggingModule : AbpModule
{
[DependsOn(
typeof(AbpAuditingModule),
typeof(AbpGuidsModule),
typeof(AbpExceptionHandlingModule))]
public class AbpAuditLoggingModule : AbpModule
public override void ConfigureServices(ServiceConfigurationContext context)
{
public override void ConfigureServices(ServiceConfigurationContext context)
Configure<AbpAuditingOptions>(options =>
{
Configure<AbpAuditingOptions>(options =>
{
options.IgnoredTypes.AddIfNotContains(typeof(CancellationToken));
options.IgnoredTypes.AddIfNotContains(typeof(CancellationTokenSource));
});
}
options.IgnoredTypes.AddIfNotContains(typeof(CancellationToken));
options.IgnoredTypes.AddIfNotContains(typeof(CancellationTokenSource));
});
}
}

176
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/AuditLog.cs

@ -1,122 +1,120 @@
using System;
using System.Collections.Generic;
using Volo.Abp.Auditing;
using Volo.Abp.Data;
namespace LINGYUN.Abp.AuditLogging
namespace LINGYUN.Abp.AuditLogging;
public class AuditLog : IHasExtraProperties
{
public class AuditLog : IHasExtraProperties
{
public Guid Id { get; set; }
public Guid Id { get; set; }
public string ApplicationName { get; set; }
public string? ApplicationName { get; set; }
public Guid? UserId { get; set; }
public Guid? UserId { get; set; }
public string UserName { get; set; }
public string? UserName { get; set; }
public Guid? TenantId { get; set; }
public Guid? TenantId { get; set; }
public string TenantName { get; set; }
public string? TenantName { get; set; }
public Guid? ImpersonatorUserId { get; set; }
public Guid? ImpersonatorUserId { get; set; }
public string ImpersonatorUserName { get; set; }
public string? ImpersonatorUserName { get; set; }
public Guid? ImpersonatorTenantId { get; set; }
public Guid? ImpersonatorTenantId { get; set; }
public string ImpersonatorTenantName { get; set; }
public string? ImpersonatorTenantName { get; set; }
public DateTime ExecutionTime { get; set; }
public DateTime ExecutionTime { get; set; }
public int ExecutionDuration { get; set; }
public int ExecutionDuration { get; set; }
public string ClientIpAddress { get; set; }
public string? ClientIpAddress { get; set; }
public string ClientName { get; set; }
public string? ClientName { get; set; }
public string ClientId { get; set; }
public string? ClientId { get; set; }
public string CorrelationId { get; set; }
public string? CorrelationId { get; set; }
public string BrowserInfo { get; set; }
public string? BrowserInfo { get; set; }
public string HttpMethod { get; set; }
public string? HttpMethod { get; set; }
public string Url { get; set; }
public string? Url { get; set; }
public string Exceptions { get; set; }
public string? Exceptions { get; set; }
public string Comments { get; set; }
public string? Comments { get; set; }
public int? HttpStatusCode { get; set; }
public int? HttpStatusCode { get; set; }
public List<EntityChange> EntityChanges { get; set; }
public List<EntityChange> EntityChanges { get; set; }
public List<AuditLogAction> Actions { get; set; }
public List<AuditLogAction> Actions { get; set; }
public ExtraPropertyDictionary ExtraProperties { get; set; }
public ExtraPropertyDictionary ExtraProperties { get; set; }
public AuditLog()
{
Actions = new List<AuditLogAction>();
EntityChanges = new List<EntityChange>();
ExtraProperties = new ExtraPropertyDictionary();
}
public AuditLog()
{
Actions = new List<AuditLogAction>();
EntityChanges = new List<EntityChange>();
ExtraProperties = new ExtraPropertyDictionary();
}
public AuditLog(
Guid id,
string applicationName,
Guid? tenantId,
string tenantName,
Guid? userId,
string userName,
DateTime executionTime,
int executionDuration,
string clientIpAddress,
string clientName,
string clientId,
string correlationId,
string browserInfo,
string httpMethod,
string url,
int? httpStatusCode,
Guid? impersonatorUserId,
string impersonatorUserName,
Guid? impersonatorTenantId,
string impersonatorTenantName,
ExtraPropertyDictionary extraPropertyDictionary,
List<EntityChange> entityChanges,
List<AuditLogAction> actions,
string exceptions,
string comments)
{
Id = id;
ApplicationName = applicationName;
TenantId = tenantId;
TenantName = tenantName;
UserId = userId;
UserName = userName;
ExecutionTime = executionTime;
ExecutionDuration = executionDuration;
ClientIpAddress = clientIpAddress;
ClientName = clientName;
ClientId = clientId;
CorrelationId = correlationId;
BrowserInfo = browserInfo;
HttpMethod = httpMethod;
Url = url;
HttpStatusCode = httpStatusCode;
ImpersonatorUserId = impersonatorUserId;
ImpersonatorUserName = impersonatorUserName;
ImpersonatorTenantId = impersonatorTenantId;
ImpersonatorTenantName = impersonatorTenantName;
ExtraProperties = extraPropertyDictionary;
EntityChanges = entityChanges;
Actions = actions;
Exceptions = exceptions;
Comments = comments;
}
public AuditLog(
Guid id,
string? applicationName,
Guid? tenantId,
string? tenantName,
Guid? userId,
string? userName,
DateTime executionTime,
int executionDuration,
string? clientIpAddress,
string? clientName,
string? clientId,
string? correlationId,
string? browserInfo,
string? httpMethod,
string? url,
int? httpStatusCode,
Guid? impersonatorUserId,
string? impersonatorUserName,
Guid? impersonatorTenantId,
string? impersonatorTenantName,
ExtraPropertyDictionary extraPropertyDictionary,
List<EntityChange> entityChanges,
List<AuditLogAction> actions,
string? exceptions,
string? comments)
{
Id = id;
ApplicationName = applicationName;
TenantId = tenantId;
TenantName = tenantName;
UserId = userId;
UserName = userName;
ExecutionTime = executionTime;
ExecutionDuration = executionDuration;
ClientIpAddress = clientIpAddress;
ClientName = clientName;
ClientId = clientId;
CorrelationId = correlationId;
BrowserInfo = browserInfo;
HttpMethod = httpMethod;
Url = url;
HttpStatusCode = httpStatusCode;
ImpersonatorUserId = impersonatorUserId;
ImpersonatorUserName = impersonatorUserName;
ImpersonatorTenantId = impersonatorTenantId;
ImpersonatorTenantName = impersonatorTenantName;
ExtraProperties = extraPropertyDictionary;
EntityChanges = entityChanges;
Actions = actions;
Exceptions = exceptions;
Comments = comments;
}
}

59
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/AuditLogAction.cs

@ -2,47 +2,46 @@
using Volo.Abp.Auditing;
using Volo.Abp.Data;
namespace LINGYUN.Abp.AuditLogging
namespace LINGYUN.Abp.AuditLogging;
[DisableAuditing]
public class AuditLogAction : IHasExtraProperties
{
[DisableAuditing]
public class AuditLogAction : IHasExtraProperties
{
public Guid Id { get; set; }
public Guid Id { get; set; }
public Guid? TenantId { get; set; }
public Guid? TenantId { get; set; }
public Guid AuditLogId { get; set; }
public Guid AuditLogId { get; set; }
public string ServiceName { get; set; }
public string ServiceName { get; set; }
public string MethodName { get; set; }
public string MethodName { get; set; }
public string Parameters { get; set; }
public string Parameters { get; set; }
public DateTime ExecutionTime { get; set; }
public DateTime ExecutionTime { get; set; }
public int ExecutionDuration { get; set; }
public int ExecutionDuration { get; set; }
public ExtraPropertyDictionary ExtraProperties { get; set; }
public ExtraPropertyDictionary ExtraProperties { get; set; }
public AuditLogAction()
{
ExtraProperties = new ExtraPropertyDictionary();
}
public AuditLogAction()
{
ExtraProperties = new ExtraPropertyDictionary();
}
public AuditLogAction(Guid id, Guid auditLogId, AuditLogActionInfo actionInfo, Guid? tenantId = null)
{
public AuditLogAction(Guid id, Guid auditLogId, AuditLogActionInfo actionInfo, Guid? tenantId = null)
{
Id = id;
TenantId = tenantId;
AuditLogId = auditLogId;
ExecutionTime = actionInfo.ExecutionTime;
ExecutionDuration = actionInfo.ExecutionDuration;
ExtraProperties = new ExtraPropertyDictionary(actionInfo.ExtraProperties);
ServiceName = actionInfo.ServiceName;
MethodName = actionInfo.MethodName;
Parameters = actionInfo.Parameters;
// Parameters = actionInfo.Parameters.Length > 2000 ? "" : actionInfo.Parameters;
}
Id = id;
TenantId = tenantId;
AuditLogId = auditLogId;
ExecutionTime = actionInfo.ExecutionTime;
ExecutionDuration = actionInfo.ExecutionDuration;
ExtraProperties = new ExtraPropertyDictionary(actionInfo.ExtraProperties);
ServiceName = actionInfo.ServiceName;
MethodName = actionInfo.MethodName;
Parameters = actionInfo.Parameters;
// Parameters = actionInfo.Parameters.Length > 2000 ? "" : actionInfo.Parameters;
}
}

27
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/AuditingStore.cs

@ -2,22 +2,21 @@
using Volo.Abp.Auditing;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.AuditLogging
namespace LINGYUN.Abp.AuditLogging;
[Dependency(ReplaceServices = true)]
public class AuditingStore : IAuditingStore, ITransientDependency
{
[Dependency(ReplaceServices = true)]
public class AuditingStore : IAuditingStore, ITransientDependency
{
private readonly IAuditLogManager _manager;
private readonly IAuditLogManager _manager;
public AuditingStore(
IAuditLogManager manager)
{
_manager = manager;
}
public AuditingStore(
IAuditLogManager manager)
{
_manager = manager;
}
public async virtual Task SaveAsync(AuditLogInfo auditInfo)
{
await _manager.SaveAsync(auditInfo);
}
public async virtual Task SaveAsync(AuditLogInfo auditInfo)
{
await _manager.SaveAsync(auditInfo);
}
}

149
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/DefaultAuditLogManager.cs

@ -8,89 +8,88 @@ using System.Threading.Tasks;
using Volo.Abp.Auditing;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.AuditLogging
namespace LINGYUN.Abp.AuditLogging;
[Dependency(TryRegister = true)]
public class DefaultAuditLogManager : IAuditLogManager, ISingletonDependency
{
[Dependency(TryRegister = true)]
public class DefaultAuditLogManager : IAuditLogManager, ISingletonDependency
{
public ILogger<DefaultAuditLogManager> Logger { protected get; set; }
public ILogger<DefaultAuditLogManager> Logger { protected get; set; }
public DefaultAuditLogManager()
{
Logger = NullLogger<DefaultAuditLogManager>.Instance;
}
public DefaultAuditLogManager()
{
Logger = NullLogger<DefaultAuditLogManager>.Instance;
}
public virtual Task<long> GetCountAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string correlationId = null,
string clientId = null,
string clientIpAddress = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
CancellationToken cancellationToken = default(CancellationToken))
{
Logger.LogDebug("No audit log manager is available!");
return Task.FromResult(0L);
}
public virtual Task<long> GetCountAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string? httpMethod = null,
string? url = null,
Guid? userId = null,
string? userName = null,
string? applicationName = null,
string? correlationId = null,
string? clientId = null,
string? clientIpAddress = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
CancellationToken cancellationToken = default)
{
Logger.LogDebug("No audit log manager is available!");
return Task.FromResult(0L);
}
public virtual Task<List<AuditLog>> GetListAsync(
string sorting = null,
int maxResultCount = 50,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string correlationId = null,
string clientId = null,
string clientIpAddress = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
bool includeDetails = false,
CancellationToken cancellationToken = default(CancellationToken))
{
Logger.LogDebug("No audit log manager is available!");
return Task.FromResult(new List<AuditLog>());
}
public virtual Task<List<AuditLog>> GetListAsync(
string? sorting = null,
int maxResultCount = 50,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string? httpMethod = null,
string? url = null,
Guid? userId = null,
string? userName = null,
string? applicationName = null,
string? correlationId = null,
string? clientId = null,
string? clientIpAddress = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
Logger.LogDebug("No audit log manager is available!");
return Task.FromResult(new List<AuditLog>());
}
public virtual Task<string> SaveAsync(
AuditLogInfo auditInfo,
CancellationToken cancellationToken = default)
{
Logger.LogDebug("No audit log manager is available and is written to the local log by default");
Logger.LogInformation(auditInfo.ToString());
public virtual Task<string> SaveAsync(
AuditLogInfo auditInfo,
CancellationToken cancellationToken = default)
{
Logger.LogDebug("No audit log manager is available and is written to the local log by default");
Logger.LogInformation(auditInfo.ToString());
return Task.FromResult("");
}
return Task.FromResult("");
}
public virtual Task<AuditLog> GetAsync(
Guid id,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
Logger.LogDebug("No audit log manager is available!");
public virtual Task<AuditLog> GetAsync(
Guid id,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
Logger.LogDebug("No audit log manager is available!");
AuditLog auditLog = null;
return Task.FromResult(auditLog);
}
AuditLog? auditLog = null;
return Task.FromResult(auditLog!);
}
public virtual Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
{
Logger.LogDebug("No audit log manager is available!");
return Task.CompletedTask;
}
public virtual Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
{
Logger.LogDebug("No audit log manager is available!");
return Task.CompletedTask;
}
}

67
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/DefaultEntityChangeStore.cs

@ -5,36 +5,53 @@ using System.Threading.Tasks;
using Volo.Abp.Auditing;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.AuditLogging
namespace LINGYUN.Abp.AuditLogging;
[Dependency(TryRegister = true)]
public class DefaultEntityChangeStore : IEntityChangeStore, ISingletonDependency
{
[Dependency(TryRegister = true)]
public class DefaultEntityChangeStore : IEntityChangeStore, ISingletonDependency
public Task<EntityChange?> GetAsync(Guid entityChangeId, CancellationToken cancellationToken = default)
{
public Task<EntityChange> GetAsync(Guid entityChangeId, CancellationToken cancellationToken = default)
{
EntityChange entityChange = null;
return Task.FromResult(entityChange);
}
EntityChange? entityChange = null;
return Task.FromResult(entityChange);
}
public Task<long> GetCountAsync(Guid? auditLogId = null, DateTime? startTime = null, DateTime? endTime = null, EntityChangeType? changeType = null, string entityId = null, string entityTypeFullName = null, CancellationToken cancellationToken = default)
{
return Task.FromResult(0L);
}
public Task<long> GetCountAsync(
Guid? auditLogId = null,
DateTime? startTime = null,
DateTime? endTime = null,
EntityChangeType? changeType = null,
string? entityId = null,
string? entityTypeFullName = null,
CancellationToken cancellationToken = default)
{
return Task.FromResult(0L);
}
public Task<List<EntityChange>> GetListAsync(string sorting = null, int maxResultCount = 50, int skipCount = 0, Guid? auditLogId = null, DateTime? startTime = null, DateTime? endTime = null, EntityChangeType? changeType = null, string entityId = null, string entityTypeFullName = null, bool includeDetails = false, CancellationToken cancellationToken = default)
{
return Task.FromResult(new List<EntityChange>());
}
public Task<List<EntityChange>> GetListAsync(
string? sorting = null,
int maxResultCount = 50,
int skipCount = 0,
Guid? auditLogId = null,
DateTime? startTime = null,
DateTime? endTime = null,
EntityChangeType? changeType = null,
string? entityId = null,
string? entityTypeFullName = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
return Task.FromResult(new List<EntityChange>());
}
public Task<EntityChangeWithUsername> GetWithUsernameAsync(Guid entityChangeId, CancellationToken cancellationToken = default)
{
EntityChangeWithUsername entityChange = null;
return Task.FromResult(entityChange);
}
public Task<EntityChangeWithUsername> GetWithUsernameAsync(Guid entityChangeId, CancellationToken cancellationToken = default)
{
EntityChangeWithUsername? entityChange = null;
return Task.FromResult(entityChange!);
}
public Task<List<EntityChangeWithUsername>> GetWithUsernameAsync(string entityId, string entityTypeFullName, CancellationToken cancellationToken = default)
{
return Task.FromResult(new List<EntityChangeWithUsername>());
}
public Task<List<EntityChangeWithUsername>> GetWithUsernameAsync(string entityId, string entityTypeFullName, CancellationToken cancellationToken = default)
{
return Task.FromResult(new List<EntityChangeWithUsername>());
}
}

133
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/DefaultSecurityLogManager.cs

@ -7,81 +7,80 @@ using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.SecurityLog;
namespace LINGYUN.Abp.AuditLogging
namespace LINGYUN.Abp.AuditLogging;
[Dependency(TryRegister = true)]
public class DefaultSecurityLogManager : ISecurityLogManager, ISingletonDependency
{
[Dependency(TryRegister = true)]
public class DefaultSecurityLogManager : ISecurityLogManager, ISingletonDependency
{
public ILogger<DefaultSecurityLogManager> Logger { protected get; set; }
public ILogger<DefaultSecurityLogManager> Logger { protected get; set; }
public DefaultSecurityLogManager()
{
Logger = NullLogger<DefaultSecurityLogManager>.Instance;
}
public DefaultSecurityLogManager()
{
Logger = NullLogger<DefaultSecurityLogManager>.Instance;
}
public Task<long> GetCountAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string clientIpAddress = null,
string correlationId = null,
CancellationToken cancellationToken = default(CancellationToken))
{
Logger.LogDebug("No security log manager is available!");
return Task.FromResult(0L);
}
public Task<long> GetCountAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string? applicationName = null,
string? identity = null,
string? action = null,
Guid? userId = null,
string? userName = null,
string? clientId = null,
string? clientIpAddress = null,
string? correlationId = null,
CancellationToken cancellationToken = default)
{
Logger.LogDebug("No security log manager is available!");
return Task.FromResult(0L);
}
public Task<List<SecurityLog>> GetListAsync(
string sorting = null,
int maxResultCount = 50,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string clientIpAddress = null,
string correlationId = null,
bool includeDetails = false,
CancellationToken cancellationToken = default(CancellationToken))
{
Logger.LogDebug("No security log manager is available!");
return Task.FromResult(new List<SecurityLog>());
}
public Task<List<SecurityLog>> GetListAsync(
string? sorting = null,
int maxResultCount = 50,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string? applicationName = null,
string? identity = null,
string? action = null,
Guid? userId = null,
string? userName = null,
string? clientId = null,
string? clientIpAddress = null,
string? correlationId = null,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
Logger.LogDebug("No security log manager is available!");
return Task.FromResult(new List<SecurityLog>());
}
public Task SaveAsync(
SecurityLogInfo securityLogInfo,
CancellationToken cancellationToken = default(CancellationToken))
{
Logger.LogDebug("No security log manager is available and is written to the local log by default");
Logger.LogInformation(securityLogInfo.ToString());
public Task SaveAsync(
SecurityLogInfo securityLogInfo,
CancellationToken cancellationToken = default)
{
Logger.LogDebug("No security log manager is available and is written to the local log by default");
Logger.LogInformation(securityLogInfo.ToString());
return Task.CompletedTask;
}
return Task.CompletedTask;
}
public virtual Task<SecurityLog> GetAsync(
Guid id,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
Logger.LogDebug("No security log manager is available!");
public virtual Task<SecurityLog> GetAsync(
Guid id,
bool includeDetails = false,
CancellationToken cancellationToken = default)
{
Logger.LogDebug("No security log manager is available!");
SecurityLog securityLog = null;
return Task.FromResult(securityLog);
}
SecurityLog? securityLog = null;
return Task.FromResult(securityLog!);
}
public virtual Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
{
Logger.LogDebug("No security log manager is available!");
return Task.CompletedTask;
}
public virtual Task DeleteAsync(Guid id, CancellationToken cancellationToken = default)
{
Logger.LogDebug("No security log manager is available!");
return Task.CompletedTask;
}
}

89
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/EntityChange.cs

@ -5,66 +5,65 @@ using Volo.Abp.Auditing;
using Volo.Abp.Data;
using Volo.Abp.Guids;
namespace LINGYUN.Abp.AuditLogging
namespace LINGYUN.Abp.AuditLogging;
[DisableAuditing]
public class EntityChange : IHasExtraProperties
{
[DisableAuditing]
public class EntityChange : IHasExtraProperties
{
public Guid Id { get; set; }
public Guid Id { get; set; }
public Guid AuditLogId { get; set; }
public Guid AuditLogId { get; set; }
public Guid? TenantId { get; set; }
public Guid? TenantId { get; set; }
public DateTime ChangeTime { get; set; }
public DateTime ChangeTime { get; set; }
public EntityChangeType ChangeType { get; set; }
public EntityChangeType ChangeType { get; set; }
public Guid? EntityTenantId { get; set; }
public Guid? EntityTenantId { get; set; }
public string EntityId { get; set; }
public string? EntityId { get; set; }
public string EntityTypeFullName { get; set; }
public string? EntityTypeFullName { get; set; }
public List<EntityPropertyChange> PropertyChanges { get; set; }
public List<EntityPropertyChange> PropertyChanges { get; set; }
public ExtraPropertyDictionary ExtraProperties { get; set; }
public ExtraPropertyDictionary ExtraProperties { get; set; }
public EntityChange()
{
PropertyChanges = new List<EntityPropertyChange>();
ExtraProperties = new ExtraPropertyDictionary();
}
public EntityChange()
{
PropertyChanges = new List<EntityPropertyChange>();
ExtraProperties = new ExtraPropertyDictionary();
}
public EntityChange(
IGuidGenerator guidGenerator,
Guid auditLogId,
EntityChangeInfo entityChangeInfo,
Guid? tenantId = null,
Guid? entityTenantId = null)
{
Id = guidGenerator.Create();
AuditLogId = auditLogId;
TenantId = tenantId;
EntityTenantId = entityTenantId;
ChangeTime = entityChangeInfo.ChangeTime;
ChangeType = entityChangeInfo.ChangeType;
EntityId = entityChangeInfo.EntityId;
EntityTypeFullName = entityChangeInfo.EntityTypeFullName;
public EntityChange(
IGuidGenerator guidGenerator,
Guid auditLogId,
EntityChangeInfo entityChangeInfo,
Guid? tenantId = null,
Guid? entityTenantId = null)
{
Id = guidGenerator.Create();
AuditLogId = auditLogId;
TenantId = tenantId;
EntityTenantId = entityTenantId;
ChangeTime = entityChangeInfo.ChangeTime;
ChangeType = entityChangeInfo.ChangeType;
EntityId = entityChangeInfo.EntityId;
EntityTypeFullName = entityChangeInfo.EntityTypeFullName;
PropertyChanges = entityChangeInfo
.PropertyChanges?
.Select(p => new EntityPropertyChange(guidGenerator, Id, p, tenantId))
.ToList()
?? new List<EntityPropertyChange>();
PropertyChanges = entityChangeInfo
.PropertyChanges?
.Select(p => new EntityPropertyChange(guidGenerator, Id, p, tenantId))
.ToList()
?? new List<EntityPropertyChange>();
ExtraProperties = new ExtraPropertyDictionary();
if (entityChangeInfo.ExtraProperties != null)
ExtraProperties = new ExtraPropertyDictionary();
if (entityChangeInfo.ExtraProperties != null)
{
foreach (var pair in entityChangeInfo.ExtraProperties)
{
foreach (var pair in entityChangeInfo.ExtraProperties)
{
ExtraProperties.Add(pair.Key, pair.Value);
}
ExtraProperties.Add(pair.Key, pair.Value);
}
}
}

11
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/EntityChangeWithUsername.cs

@ -1,9 +1,8 @@
namespace LINGYUN.Abp.AuditLogging
namespace LINGYUN.Abp.AuditLogging;
public class EntityChangeWithUsername
{
public class EntityChangeWithUsername
{
public EntityChange EntityChange { get; set; }
public EntityChange EntityChange { get; set; }
public string UserName { get; set; }
}
public string UserName { get; set; }
}

55
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/EntityPropertyChange.cs

@ -2,42 +2,41 @@
using Volo.Abp.Auditing;
using Volo.Abp.Guids;
namespace LINGYUN.Abp.AuditLogging
namespace LINGYUN.Abp.AuditLogging;
[DisableAuditing]
public class EntityPropertyChange
{
[DisableAuditing]
public class EntityPropertyChange
{
public Guid Id { get; set; }
public Guid Id { get; set; }
public Guid? TenantId { get; set; }
public Guid? TenantId { get; set; }
public Guid EntityChangeId { get; set; }
public Guid EntityChangeId { get; set; }
public string NewValue { get; set; }
public string? NewValue { get; set; }
public string OriginalValue { get; set; }
public string? OriginalValue { get; set; }
public string PropertyName { get; set; }
public string PropertyName { get; set; }
public string PropertyTypeFullName { get; set; }
public string PropertyTypeFullName { get; set; }
public EntityPropertyChange()
{
}
public EntityPropertyChange()
{
}
public EntityPropertyChange(
IGuidGenerator guidGenerator,
Guid entityChangeId,
EntityPropertyChangeInfo entityChangeInfo,
Guid? tenantId = null)
{
Id = guidGenerator.Create();
TenantId = tenantId;
EntityChangeId = entityChangeId;
NewValue = entityChangeInfo.NewValue;
OriginalValue = entityChangeInfo.OriginalValue;
PropertyName = entityChangeInfo.PropertyName;
PropertyTypeFullName = entityChangeInfo.PropertyTypeFullName;
}
public EntityPropertyChange(
IGuidGenerator guidGenerator,
Guid entityChangeId,
EntityPropertyChangeInfo entityChangeInfo,
Guid? tenantId = null)
{
Id = guidGenerator.Create();
TenantId = tenantId;
EntityChangeId = entityChangeId;
NewValue = entityChangeInfo.NewValue;
OriginalValue = entityChangeInfo.OriginalValue;
PropertyName = entityChangeInfo.PropertyName;
PropertyTypeFullName = entityChangeInfo.PropertyTypeFullName;
}
}

99
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/IAuditLogManager.cs

@ -5,60 +5,59 @@ using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Auditing;
namespace LINGYUN.Abp.AuditLogging
namespace LINGYUN.Abp.AuditLogging;
public interface IAuditLogManager
{
public interface IAuditLogManager
{
Task<AuditLog> GetAsync(
Guid id,
bool includeDetails = false,
CancellationToken cancellationToken = default(CancellationToken));
Task<AuditLog> GetAsync(
Guid id,
bool includeDetails = false,
CancellationToken cancellationToken = default);
Task DeleteAsync(
Guid id,
CancellationToken cancellationToken = default(CancellationToken));
Task DeleteAsync(
Guid id,
CancellationToken cancellationToken = default);
Task<string> SaveAsync(
AuditLogInfo auditInfo,
CancellationToken cancellationToken = default(CancellationToken));
Task<string> SaveAsync(
AuditLogInfo auditInfo,
CancellationToken cancellationToken = default);
Task<long> GetCountAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string correlationId = null,
string clientId = null,
string clientIpAddress = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
CancellationToken cancellationToken = default(CancellationToken));
Task<long> GetCountAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string? httpMethod = null,
string? url = null,
Guid? userId = null,
string? userName = null,
string? applicationName = null,
string? correlationId = null,
string? clientId = null,
string? clientIpAddress = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
CancellationToken cancellationToken = default);
Task<List<AuditLog>> GetListAsync(
string sorting = null,
int maxResultCount = 50,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string httpMethod = null,
string url = null,
Guid? userId = null,
string userName = null,
string applicationName = null,
string correlationId = null,
string clientId = null,
string clientIpAddress = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
bool includeDetails = false,
CancellationToken cancellationToken = default(CancellationToken));
Task<List<AuditLog>> GetListAsync(
string? sorting = null,
int maxResultCount = 50,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string? httpMethod = null,
string? url = null,
Guid? userId = null,
string? userName = null,
string? applicationName = null,
string? correlationId = null,
string? clientId = null,
string? clientIpAddress = null,
int? maxExecutionDuration = null,
int? minExecutionDuration = null,
bool? hasException = null,
HttpStatusCode? httpStatusCode = null,
bool includeDetails = false,
CancellationToken cancellationToken = default);
}
}

67
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/IEntityChangeStore.cs

@ -4,43 +4,42 @@ using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Auditing;
namespace LINGYUN.Abp.AuditLogging
namespace LINGYUN.Abp.AuditLogging;
public interface IEntityChangeStore
{
public interface IEntityChangeStore
{
Task<EntityChange> GetAsync(
Guid entityChangeId,
CancellationToken cancellationToken = default);
Task<EntityChange?> GetAsync(
Guid entityChangeId,
CancellationToken cancellationToken = default);
Task<long> GetCountAsync(
Guid? auditLogId = null,
DateTime? startTime = null,
DateTime? endTime = null,
EntityChangeType? changeType = null,
string entityId = null,
string entityTypeFullName = null,
CancellationToken cancellationToken = default);
Task<long> GetCountAsync(
Guid? auditLogId = null,
DateTime? startTime = null,
DateTime? endTime = null,
EntityChangeType? changeType = null,
string? entityId = null,
string? entityTypeFullName = null,
CancellationToken cancellationToken = default);
Task<List<EntityChange>> GetListAsync(
string sorting = null,
int maxResultCount = 50,
int skipCount = 0,
Guid? auditLogId = null,
DateTime? startTime = null,
DateTime? endTime = null,
EntityChangeType? changeType = null,
string entityId = null,
string entityTypeFullName = null,
bool includeDetails = false,
CancellationToken cancellationToken = default);
Task<List<EntityChange>> GetListAsync(
string? sorting = null,
int maxResultCount = 50,
int skipCount = 0,
Guid? auditLogId = null,
DateTime? startTime = null,
DateTime? endTime = null,
EntityChangeType? changeType = null,
string? entityId = null,
string? entityTypeFullName = null,
bool includeDetails = false,
CancellationToken cancellationToken = default);
Task<EntityChangeWithUsername> GetWithUsernameAsync(
Guid entityChangeId,
CancellationToken cancellationToken = default);
Task<EntityChangeWithUsername> GetWithUsernameAsync(
Guid entityChangeId,
CancellationToken cancellationToken = default);
Task<List<EntityChangeWithUsername>> GetWithUsernameAsync(
string entityId,
string entityTypeFullName,
CancellationToken cancellationToken = default);
}
Task<List<EntityChangeWithUsername>> GetWithUsernameAsync(
string entityId,
string entityTypeFullName,
CancellationToken cancellationToken = default);
}

95
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/ISecurityLogManager.cs

@ -4,53 +4,52 @@ using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.SecurityLog;
namespace LINGYUN.Abp.AuditLogging
namespace LINGYUN.Abp.AuditLogging;
public interface ISecurityLogManager
{
public interface ISecurityLogManager
{
Task<SecurityLog> GetAsync(
Guid id,
bool includeDetails = false,
CancellationToken cancellationToken = default(CancellationToken));
Task DeleteAsync(
Guid id,
CancellationToken cancellationToken = default(CancellationToken));
Task SaveAsync(
SecurityLogInfo securityLogInfo,
CancellationToken cancellationToken = default(CancellationToken));
Task<List<SecurityLog>> GetListAsync(
string sorting = null,
int maxResultCount = 50,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string clientIpAddress = null,
string correlationId = null,
bool includeDetails = false,
CancellationToken cancellationToken = default(CancellationToken));
Task<long> GetCountAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string applicationName = null,
string identity = null,
string action = null,
Guid? userId = null,
string userName = null,
string clientId = null,
string clientIpAddress = null,
string correlationId = null,
CancellationToken cancellationToken = default(CancellationToken));
}
Task<SecurityLog> GetAsync(
Guid id,
bool includeDetails = false,
CancellationToken cancellationToken = default);
Task DeleteAsync(
Guid id,
CancellationToken cancellationToken = default);
Task SaveAsync(
SecurityLogInfo securityLogInfo,
CancellationToken cancellationToken = default);
Task<List<SecurityLog>> GetListAsync(
string? sorting = null,
int maxResultCount = 50,
int skipCount = 0,
DateTime? startTime = null,
DateTime? endTime = null,
string? applicationName = null,
string? identity = null,
string? action = null,
Guid? userId = null,
string? userName = null,
string? clientId = null,
string? clientIpAddress = null,
string? correlationId = null,
bool includeDetails = false,
CancellationToken cancellationToken = default);
Task<long> GetCountAsync(
DateTime? startTime = null,
DateTime? endTime = null,
string? applicationName = null,
string? identity = null,
string? action = null,
Guid? userId = null,
string? userName = null,
string? clientId = null,
string? clientIpAddress = null,
string? correlationId = null,
CancellationToken cancellationToken = default);
}

83
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/SecurityLog.cs

@ -2,70 +2,69 @@
using Volo.Abp.Data;
using Volo.Abp.SecurityLog;
namespace LINGYUN.Abp.AuditLogging
namespace LINGYUN.Abp.AuditLogging;
public class SecurityLog : IHasExtraProperties
{
public class SecurityLog : IHasExtraProperties
{
public Guid Id { get; set; }
public Guid Id { get; set; }
public Guid? TenantId { get; set; }
public Guid? TenantId { get; set; }
public string ApplicationName { get; set; }
public string? ApplicationName { get; set; }
public string Identity { get; set; }
public string? Identity { get; set; }
public string Action { get; set; }
public string? Action { get; set; }
public Guid? UserId { get; set; }
public Guid? UserId { get; set; }
public string UserName { get; set; }
public string? UserName { get; set; }
public string TenantName { get; set; }
public string? TenantName { get; set; }
public string ClientId { get; set; }
public string? ClientId { get; set; }
public string CorrelationId { get; set; }
public string? CorrelationId { get; set; }
public string ClientIpAddress { get; set; }
public string? ClientIpAddress { get; set; }
public string BrowserInfo { get; set; }
public string? BrowserInfo { get; set; }
public DateTime CreationTime { get; set; }
public DateTime CreationTime { get; set; }
public ExtraPropertyDictionary ExtraProperties { get; set; }
public ExtraPropertyDictionary ExtraProperties { get; set; }
public SecurityLog()
{
ExtraProperties = new ExtraPropertyDictionary();
}
public SecurityLog()
{
ExtraProperties = new ExtraPropertyDictionary();
}
public SecurityLog(Guid id, SecurityLogInfo securityLogInfo)
{
Id = id;
TenantId = securityLogInfo.TenantId;
TenantName = securityLogInfo.TenantName;
public SecurityLog(Guid id, SecurityLogInfo securityLogInfo)
{
Id = id;
TenantId = securityLogInfo.TenantId;
TenantName = securityLogInfo.TenantName;
ApplicationName = securityLogInfo.ApplicationName;
Identity = securityLogInfo.Identity;
Action = securityLogInfo.Action;
ApplicationName = securityLogInfo.ApplicationName;
Identity = securityLogInfo.Identity;
Action = securityLogInfo.Action;
UserId = securityLogInfo.UserId;
UserName = securityLogInfo.UserName;
UserId = securityLogInfo.UserId;
UserName = securityLogInfo.UserName;
CreationTime = securityLogInfo.CreationTime;
CreationTime = securityLogInfo.CreationTime;
ClientIpAddress = securityLogInfo.ClientIpAddress;
ClientId = securityLogInfo.ClientId;
CorrelationId = securityLogInfo.CorrelationId;
BrowserInfo = securityLogInfo.BrowserInfo;
ClientIpAddress = securityLogInfo.ClientIpAddress;
ClientId = securityLogInfo.ClientId;
CorrelationId = securityLogInfo.CorrelationId;
BrowserInfo = securityLogInfo.BrowserInfo;
ExtraProperties = new ExtraPropertyDictionary();
if (securityLogInfo.ExtraProperties != null)
ExtraProperties = new ExtraPropertyDictionary();
if (securityLogInfo.ExtraProperties != null)
{
foreach (var pair in securityLogInfo.ExtraProperties)
{
foreach (var pair in securityLogInfo.ExtraProperties)
{
ExtraProperties.Add(pair.Key, pair.Value);
}
ExtraProperties.Add(pair.Key, pair.Value);
}
}
}

27
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging/LINGYUN/Abp/AuditLogging/SecurityLogStore.cs

@ -2,22 +2,21 @@
using Volo.Abp.DependencyInjection;
using Volo.Abp.SecurityLog;
namespace LINGYUN.Abp.AuditLogging
namespace LINGYUN.Abp.AuditLogging;
[Dependency(ReplaceServices = true)]
public class SecurityLogStore : ISecurityLogStore, ITransientDependency
{
[Dependency(ReplaceServices = true)]
public class SecurityLogStore : ISecurityLogStore, ITransientDependency
{
private readonly ISecurityLogManager _manager;
private readonly ISecurityLogManager _manager;
public SecurityLogStore(
ISecurityLogManager manager)
{
_manager = manager;
}
public SecurityLogStore(
ISecurityLogManager manager)
{
_manager = manager;
}
public async virtual Task SaveAsync(SecurityLogInfo securityLogInfo)
{
await _manager.SaveAsync(securityLogInfo);
}
public async virtual Task SaveAsync(SecurityLogInfo securityLogInfo)
{
await _manager.SaveAsync(securityLogInfo);
}
}

5
aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.QQ/LINGYUN.Abp.Authentication.QQ.csproj

@ -5,6 +5,11 @@
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AssemblyName>LINGYUN.Abp.Authentication.QQ</AssemblyName>
<PackageId>LINGYUN.Abp.Authentication.QQ</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>

53
aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.QQ/LINGYUN/Abp/Authentication/QQ/AbpQQClaimTypes.cs

@ -1,31 +1,30 @@
namespace LINGYUN.Abp.Authentication.QQ
namespace LINGYUN.Abp.Authentication.QQ;
/// <summary>
/// QQ互联身份类型,可以像 <see cref="Volo.Abp.Security.Claims.AbpClaimTypes"/> 自行配置
/// <br />
/// See: <see cref="https://wiki.connect.qq.com/get_user_info"/>
/// </summary>
public class AbpQQClaimTypes
{
/// <summary>
/// QQ互联身份类型,可以像 <see cref="Volo.Abp.Security.Claims.AbpClaimTypes"/> 自行配置
/// <br />
/// See: <see cref="https://wiki.connect.qq.com/get_user_info"/>
/// 用户的唯一标识
/// </summary>
public class AbpQQClaimTypes
{
/// <summary>
/// 用户的唯一标识
/// </summary>
public static string OpenId { get; set; } = "qq-openid"; // 可变更
/// <summary>
/// 用户昵称
/// </summary>
public static string NickName { get; set; } = "nickname";
/// <summary>
/// 性别。 如果获取不到则默认返回"男"
/// </summary>
public static string Gender { get; set; } = "gender";
/// <summary>
/// 用户头像, 取自字段: figureurl_qq_1
/// </summary>
/// <remarks>
/// 根据QQ互联文档, 40x40的头像是一定会存在的, 只取40x40的头像
/// see: https://wiki.connect.qq.com/get_user_info
/// </remarks>
public static string AvatarUrl { get; set; } = "avatar";
}
public static string OpenId { get; set; } = "qq-openid"; // 可变更
/// <summary>
/// 用户昵称
/// </summary>
public static string NickName { get; set; } = "nickname";
/// <summary>
/// 性别。 如果获取不到则默认返回"男"
/// </summary>
public static string Gender { get; set; } = "gender";
/// <summary>
/// 用户头像, 取自字段: figureurl_qq_1
/// </summary>
/// <remarks>
/// 根据QQ互联文档, 40x40的头像是一定会存在的, 只取40x40的头像
/// see: https://wiki.connect.qq.com/get_user_info
/// </remarks>
public static string AvatarUrl { get; set; } = "avatar";
}

279
aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.QQ/Microsoft/AspNetCore/Authentication/QQ/QQConnectOAuthHandler.cs

@ -12,165 +12,164 @@ using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Authentication.QQ
namespace Microsoft.AspNetCore.Authentication.QQ;
/// <summary>
/// QQ互联实现
/// </summary>
public class QQConnectOAuthHandler : OAuthHandler<QQConnectOAuthOptions>
{
protected AbpTencentQQOptionsFactory TencentQQOptionsFactory { get; }
public QQConnectOAuthHandler(
IOptionsMonitor<QQConnectOAuthOptions> options,
AbpTencentQQOptionsFactory tencentQQOptionsFactory,
ILoggerFactory logger,
UrlEncoder encoder)
: base(options, logger, encoder)
{
TencentQQOptionsFactory = tencentQQOptionsFactory;
}
protected override async Task InitializeHandlerAsync()
{
var options = await TencentQQOptionsFactory.CreateAsync();
// 用配置项重写
Options.ClientId = options.AppId;
Options.ClientSecret = options.AppKey;
Options.IsMobile = options.IsMobile;
Options.TimeProvider ??= TimeProvider.System;
await base.InitializeHandlerAsync();
}
/// <summary>
/// QQ互联实现
/// </summary>
public class QQConnectOAuthHandler : OAuthHandler<QQConnectOAuthOptions>
/// 构建用户授权地址
/// </summary>
protected override string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri)
{
protected AbpTencentQQOptionsFactory TencentQQOptionsFactory { get; }
public QQConnectOAuthHandler(
IOptionsMonitor<QQConnectOAuthOptions> options,
AbpTencentQQOptionsFactory tencentQQOptionsFactory,
ILoggerFactory logger,
UrlEncoder encoder)
: base(options, logger, encoder)
var challengeUrl = base.BuildChallengeUrl(properties, redirectUri);
if (Options.IsMobile)
{
TencentQQOptionsFactory = tencentQQOptionsFactory;
challengeUrl += "&display=mobile";
}
return challengeUrl;
protected override async Task InitializeHandlerAsync()
}
/// <summary>
/// code换取access_token
/// </summary>
protected override async Task<OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
{
var address = QueryHelpers.AddQueryString(Options.TokenEndpoint, new Dictionary<string, string>()
{
var options = await TencentQQOptionsFactory.CreateAsync();
{ "client_id", Options.ClientId },
{ "redirect_uri", context.RedirectUri },
{ "client_secret", Options.ClientSecret},
{ "code", context.Code},
{ "grant_type","authorization_code"}
});
var response = await Backchannel.GetAsync(address);
if (!response.IsSuccessStatusCode)
{
Logger.LogError("An error occurred while retrieving an access token: the remote server " +
"returned a {Status} response with the following payload: {Headers} {Body}.",
/* Status: */ response.StatusCode,
/* Headers: */ response.Headers.ToString(),
/* Body: */ await response.Content.ReadAsStringAsync());
return OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token."));
}
// 用配置项重写
Options.ClientId = options.AppId;
Options.ClientSecret = options.AppKey;
Options.IsMobile = options.IsMobile;
Options.TimeProvider ??= TimeProvider.System;
var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
if (!string.IsNullOrEmpty(payload.GetRootString("errcode")))
{
Logger.LogError("An error occurred while retrieving an access token: the remote server " +
"returned a {Status} response with the following payload: {Headers} {Body}.",
/* Status: */ response.StatusCode,
/* Headers: */ response.Headers.ToString(),
/* Body: */ await response.Content.ReadAsStringAsync());
await base.InitializeHandlerAsync();
return OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token."));
}
return OAuthTokenResponse.Success(payload);
}
protected override async Task<AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens)
{
var openIdEndpoint = Options.OpenIdEndpoint + "?access_token=" + tokens.AccessToken + "&fmt=json";
var openIdResponse = await Backchannel.GetAsync(openIdEndpoint, Context.RequestAborted);
openIdResponse.EnsureSuccessStatusCode();
var openIdPayload = JsonDocument.Parse(await openIdResponse.Content.ReadAsStringAsync());
var openId = openIdPayload.GetRootString("openid");
/// <summary>
/// 构建用户授权地址
/// </summary>
protected override string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri)
identity.AddClaim(new Claim(AbpQQClaimTypes.OpenId, openId, ClaimValueTypes.String, Options.ClaimsIssuer));
var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary<string, string>
{
{"oauth_consumer_key", Options.ClientId},
{"access_token", tokens.AccessToken},
{"openid", openId}
});
var response = await Backchannel.GetAsync(address);
if (!response.IsSuccessStatusCode)
{
var challengeUrl = base.BuildChallengeUrl(properties, redirectUri);
if (Options.IsMobile)
{
challengeUrl += "&display=mobile";
}
return challengeUrl;
Logger.LogError("An error occurred while retrieving the user profile: the remote server " +
"returned a {Status} response with the following payload: {Headers} {Body}.",
/* Status: */ response.StatusCode,
/* Headers: */ response.Headers.ToString(),
/* Body: */ await response.Content.ReadAsStringAsync());
throw new HttpRequestException("An error occurred while retrieving user information.");
}
/// <summary>
/// code换取access_token
/// </summary>
protected override async Task<OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
var userInfoPayload = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
var errorCode = userInfoPayload.GetRootString("ret");
if (!"0".Equals(errorCode))
{
var address = QueryHelpers.AddQueryString(Options.TokenEndpoint, new Dictionary<string, string>()
{
{ "client_id", Options.ClientId },
{ "redirect_uri", context.RedirectUri },
{ "client_secret", Options.ClientSecret},
{ "code", context.Code},
{ "grant_type","authorization_code"}
});
var response = await Backchannel.GetAsync(address);
if (!response.IsSuccessStatusCode)
{
Logger.LogError("An error occurred while retrieving an access token: the remote server " +
"returned a {Status} response with the following payload: {Headers} {Body}.",
/* Status: */ response.StatusCode,
/* Headers: */ response.Headers.ToString(),
/* Body: */ await response.Content.ReadAsStringAsync());
return OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token."));
}
var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
if (!string.IsNullOrEmpty(payload.GetRootString("errcode")))
{
Logger.LogError("An error occurred while retrieving an access token: the remote server " +
"returned a {Status} response with the following payload: {Headers} {Body}.",
/* Status: */ response.StatusCode,
/* Headers: */ response.Headers.ToString(),
/* Body: */ await response.Content.ReadAsStringAsync());
return OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token."));
}
return OAuthTokenResponse.Success(payload);
// See: https://wiki.connect.qq.com/%e5%85%ac%e5%85%b1%e8%bf%94%e5%9b%9e%e7%a0%81%e8%af%b4%e6%98%8e
Logger.LogError("An error occurred while retrieving the user profile: the remote server " +
"returned code {Code} response with message: {Message}.",
errorCode,
userInfoPayload.GetRootString("msg"));
throw new HttpRequestException("An error occurred while retrieving user information.");
}
protected override async Task<AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens)
var nickName = userInfoPayload.GetRootString("nickname");
if (!nickName.IsNullOrWhiteSpace())
{
var openIdEndpoint = Options.OpenIdEndpoint + "?access_token=" + tokens.AccessToken + "&fmt=json";
var openIdResponse = await Backchannel.GetAsync(openIdEndpoint, Context.RequestAborted);
openIdResponse.EnsureSuccessStatusCode();
var openIdPayload = JsonDocument.Parse(await openIdResponse.Content.ReadAsStringAsync());
var openId = openIdPayload.GetRootString("openid");
identity.AddClaim(new Claim(AbpQQClaimTypes.OpenId, openId, ClaimValueTypes.String, Options.ClaimsIssuer));
var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary<string, string>
{
{"oauth_consumer_key", Options.ClientId},
{"access_token", tokens.AccessToken},
{"openid", openId}
});
var response = await Backchannel.GetAsync(address);
if (!response.IsSuccessStatusCode)
{
Logger.LogError("An error occurred while retrieving the user profile: the remote server " +
"returned a {Status} response with the following payload: {Headers} {Body}.",
/* Status: */ response.StatusCode,
/* Headers: */ response.Headers.ToString(),
/* Body: */ await response.Content.ReadAsStringAsync());
throw new HttpRequestException("An error occurred while retrieving user information.");
}
var userInfoPayload = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
var errorCode = userInfoPayload.GetRootString("ret");
if (!"0".Equals(errorCode))
{
// See: https://wiki.connect.qq.com/%e5%85%ac%e5%85%b1%e8%bf%94%e5%9b%9e%e7%a0%81%e8%af%b4%e6%98%8e
Logger.LogError("An error occurred while retrieving the user profile: the remote server " +
"returned code {Code} response with message: {Message}.",
errorCode,
userInfoPayload.GetRootString("msg"));
throw new HttpRequestException("An error occurred while retrieving user information.");
}
var nickName = userInfoPayload.GetRootString("nickname");
if (!nickName.IsNullOrWhiteSpace())
{
identity.AddClaim(new Claim(AbpQQClaimTypes.NickName, nickName, ClaimValueTypes.String, Options.ClaimsIssuer));
}
var gender = userInfoPayload.GetRootString("gender");
if (!gender.IsNullOrWhiteSpace())
{
identity.AddClaim(new Claim(AbpQQClaimTypes.Gender, gender, ClaimValueTypes.String, Options.ClaimsIssuer));
}
var avatarUrl = userInfoPayload.GetRootString("figureurl_qq_1");
if (!avatarUrl.IsNullOrWhiteSpace())
{
identity.AddClaim(new Claim(AbpQQClaimTypes.AvatarUrl, avatarUrl, ClaimValueTypes.String, Options.ClaimsIssuer));
}
var context = new OAuthCreatingTicketContext(
new ClaimsPrincipal(identity),
properties,
Context,
Scheme,
Options,
Backchannel,
tokens,
userInfoPayload.RootElement);
context.RunClaimActions();
await Events.CreatingTicket(context);
return new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name);
identity.AddClaim(new Claim(AbpQQClaimTypes.NickName, nickName, ClaimValueTypes.String, Options.ClaimsIssuer));
}
var gender = userInfoPayload.GetRootString("gender");
if (!gender.IsNullOrWhiteSpace())
{
identity.AddClaim(new Claim(AbpQQClaimTypes.Gender, gender, ClaimValueTypes.String, Options.ClaimsIssuer));
}
var avatarUrl = userInfoPayload.GetRootString("figureurl_qq_1");
if (!avatarUrl.IsNullOrWhiteSpace())
{
identity.AddClaim(new Claim(AbpQQClaimTypes.AvatarUrl, avatarUrl, ClaimValueTypes.String, Options.ClaimsIssuer));
}
var context = new OAuthCreatingTicketContext(
new ClaimsPrincipal(identity),
properties,
Context,
Scheme,
Options,
Backchannel,
tokens,
userInfoPayload.RootElement);
context.RunClaimActions();
await Events.CreatingTicket(context);
return new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name);
}
}

73
aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.QQ/Microsoft/AspNetCore/Authentication/QQ/QQConnectOAuthOptions.cs

@ -3,44 +3,43 @@ using Microsoft.AspNetCore.Authentication.OAuth;
using Microsoft.AspNetCore.Http;
using System.Security.Claims;
namespace Microsoft.AspNetCore.Authentication.QQ
namespace Microsoft.AspNetCore.Authentication.QQ;
public class QQConnectOAuthOptions : OAuthOptions
{
public class QQConnectOAuthOptions : OAuthOptions
/// <summary>
/// 是否移动端样式
/// </summary>
public bool IsMobile { get; set; }
/// <summary>
/// 获取用户OpenID_OAuth2.0
/// </summary>
public string OpenIdEndpoint { get; set; }
public QQConnectOAuthOptions()
{
/// <summary>
/// 是否移动端样式
/// </summary>
public bool IsMobile { get; set; }
/// <summary>
/// 获取用户OpenID_OAuth2.0
/// </summary>
public string OpenIdEndpoint { get; set; }
public QQConnectOAuthOptions()
{
// 用于防止初始化错误,会在OAuthHandler.InitializeHandlerAsync中进行重写
ClientId = "QQConnect";
ClientSecret = "QQConnect";
ClaimsIssuer = "connect.qq.com";
CallbackPath = new PathString(AbpAuthenticationQQConsts.CallbackPath);
AuthorizationEndpoint = "https://graph.qq.com/oauth2.0/authorize";
TokenEndpoint = "https://graph.qq.com/oauth2.0/token";
OpenIdEndpoint = "https://graph.qq.com/oauth2.0/me";
UserInformationEndpoint = "https://graph.qq.com/user/get_user_info";
Scope.Add("get_user_info");
// 这个原始的属性一定要写进去,框架关联判断是否绑定QQ
ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "openid");
ClaimActions.MapJsonKey(ClaimTypes.Name, "nickname");
// 把自定义的身份标识写进令牌
ClaimActions.MapJsonKey(AbpQQClaimTypes.OpenId, "openid");
ClaimActions.MapJsonKey(AbpQQClaimTypes.NickName, "nickname");
ClaimActions.MapJsonKey(AbpQQClaimTypes.Gender, "gender");
ClaimActions.MapJsonKey(AbpQQClaimTypes.AvatarUrl, "figureurl_qq_1");
}
// 用于防止初始化错误,会在OAuthHandler.InitializeHandlerAsync中进行重写
ClientId = "QQConnect";
ClientSecret = "QQConnect";
ClaimsIssuer = "connect.qq.com";
CallbackPath = new PathString(AbpAuthenticationQQConsts.CallbackPath);
AuthorizationEndpoint = "https://graph.qq.com/oauth2.0/authorize";
TokenEndpoint = "https://graph.qq.com/oauth2.0/token";
OpenIdEndpoint = "https://graph.qq.com/oauth2.0/me";
UserInformationEndpoint = "https://graph.qq.com/user/get_user_info";
Scope.Add("get_user_info");
// 这个原始的属性一定要写进去,框架关联判断是否绑定QQ
ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "openid");
ClaimActions.MapJsonKey(ClaimTypes.Name, "nickname");
// 把自定义的身份标识写进令牌
ClaimActions.MapJsonKey(AbpQQClaimTypes.OpenId, "openid");
ClaimActions.MapJsonKey(AbpQQClaimTypes.NickName, "nickname");
ClaimActions.MapJsonKey(AbpQQClaimTypes.Gender, "gender");
ClaimActions.MapJsonKey(AbpQQClaimTypes.AvatarUrl, "figureurl_qq_1");
}
}

101
aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.QQ/Microsoft/AspNetCore/Authentication/QQAuthenticationExtensions.cs

@ -3,61 +3,60 @@ using Microsoft.AspNetCore.Authentication.QQ;
using Microsoft.Extensions.DependencyInjection;
using System;
namespace Microsoft.AspNetCore.Authentication
namespace Microsoft.AspNetCore.Authentication;
public static class QQAuthenticationExtensions
{
public static class QQAuthenticationExtensions
/// <summary>
/// </summary>
public static AuthenticationBuilder AddQQConnect(
this AuthenticationBuilder builder)
{
/// <summary>
/// </summary>
public static AuthenticationBuilder AddQQConnect(
this AuthenticationBuilder builder)
{
return builder
.AddQQConnect(
AbpAuthenticationQQConsts.AuthenticationScheme,
AbpAuthenticationQQConsts.DisplayName,
options => { });
}
return builder
.AddQQConnect(
AbpAuthenticationQQConsts.AuthenticationScheme,
AbpAuthenticationQQConsts.DisplayName,
options => { });
}
/// <summary>
/// </summary>
public static AuthenticationBuilder AddQQConnect(
this AuthenticationBuilder builder,
Action<QQConnectOAuthOptions> configureOptions)
{
return builder
.AddQQConnect(
AbpAuthenticationQQConsts.AuthenticationScheme,
configureOptions);
}
/// <summary>
/// </summary>
public static AuthenticationBuilder AddQQConnect(
this AuthenticationBuilder builder,
Action<QQConnectOAuthOptions> configureOptions)
{
return builder
.AddQQConnect(
AbpAuthenticationQQConsts.AuthenticationScheme,
configureOptions);
}
/// <summary>
/// </summary>
public static AuthenticationBuilder AddQQConnect(
this AuthenticationBuilder builder,
string authenticationScheme,
Action<QQConnectOAuthOptions> configureOptions)
{
return builder
.AddQQConnect(
authenticationScheme,
AbpAuthenticationQQConsts.DisplayName,
configureOptions);
}
/// <summary>
/// </summary>
public static AuthenticationBuilder AddQQConnect(
this AuthenticationBuilder builder,
string authenticationScheme,
Action<QQConnectOAuthOptions> configureOptions)
{
return builder
.AddQQConnect(
authenticationScheme,
AbpAuthenticationQQConsts.DisplayName,
configureOptions);
}
/// <summary>
/// </summary>
public static AuthenticationBuilder AddQQConnect(
this AuthenticationBuilder builder,
string authenticationScheme,
string displayName,
Action<QQConnectOAuthOptions> configureOptions)
{
return builder
.AddOAuth<QQConnectOAuthOptions, QQConnectOAuthHandler>(
authenticationScheme,
displayName,
configureOptions);
}
/// <summary>
/// </summary>
public static AuthenticationBuilder AddQQConnect(
this AuthenticationBuilder builder,
string authenticationScheme,
string displayName,
Action<QQConnectOAuthOptions> configureOptions)
{
return builder
.AddOAuth<QQConnectOAuthOptions, QQConnectOAuthHandler>(
authenticationScheme,
displayName,
configureOptions);
}
}

15
aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.QQ/System/BytesExtensions.cs

@ -1,16 +1,15 @@
using System.Security.Cryptography;
namespace System
namespace System;
internal static class BytesExtensions
{
internal static class BytesExtensions
public static byte[] Sha1(this byte[] data)
{
public static byte[] Sha1(this byte[] data)
using (var sha = SHA1.Create())
{
using (var sha = SHA1.Create())
{
var hashBytes = sha.ComputeHash(data);
return hashBytes;
}
var hashBytes = sha.ComputeHash(data);
return hashBytes;
}
}
}

15
aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.QQ/System/StringExtensions.cs

@ -1,17 +1,16 @@
using System.Security.Cryptography;
using System.Text;
namespace System
namespace System;
internal static class StringExtensions
{
internal static class StringExtensions
public static byte[] Sha1(this string str)
{
public static byte[] Sha1(this string str)
using (var sha = SHA1.Create())
{
using (var sha = SHA1.Create())
{
var hashBytes = sha.ComputeHash(Encoding.ASCII.GetBytes(str));
return hashBytes;
}
var hashBytes = sha.ComputeHash(Encoding.ASCII.GetBytes(str));
return hashBytes;
}
}
}

79
aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.QQ/System/Text/Json/JsonElementExtensions.cs

@ -1,63 +1,62 @@
using System.Collections.Generic;
namespace System.Text.Json
namespace System.Text.Json;
internal static class JsonElementExtensions
{
internal static class JsonElementExtensions
public static IEnumerable<string> GetRootStrings(this JsonDocument json, string key)
{
public static IEnumerable<string> GetRootStrings(this JsonDocument json, string key)
{
return json.RootElement.GetStrings(key);
}
return json.RootElement.GetStrings(key);
}
public static IEnumerable<string> GetStrings(this JsonElement json, string key)
{
var result = new List<string>();
public static IEnumerable<string> GetStrings(this JsonElement json, string key)
{
var result = new List<string>();
if (json.TryGetProperty(key, out JsonElement property) && property.ValueKind == JsonValueKind.Array)
if (json.TryGetProperty(key, out JsonElement property) && property.ValueKind == JsonValueKind.Array)
{
foreach (var jsonProp in property.EnumerateArray())
{
foreach (var jsonProp in property.EnumerateArray())
{
result.Add(jsonProp.GetString());
}
result.Add(jsonProp.GetString());
}
return result;
}
public static string GetRootString(this JsonDocument json, string key, string defaultValue = "")
return result;
}
public static string GetRootString(this JsonDocument json, string key, string defaultValue = "")
{
if (json.RootElement.TryGetProperty(key, out JsonElement property))
{
if (json.RootElement.TryGetProperty(key, out JsonElement property))
{
return property.GetString();
}
return defaultValue;
return property.GetString();
}
return defaultValue;
}
public static string GetString(this JsonElement json, string key, string defaultValue = "")
public static string GetString(this JsonElement json, string key, string defaultValue = "")
{
if (json.TryGetProperty(key, out JsonElement property))
{
if (json.TryGetProperty(key, out JsonElement property))
{
return property.GetString();
}
return defaultValue;
return property.GetString();
}
return defaultValue;
}
public static int GetRootInt32(this JsonDocument json, string key, int defaultValue = 0)
public static int GetRootInt32(this JsonDocument json, string key, int defaultValue = 0)
{
if (json.RootElement.TryGetProperty(key, out JsonElement property) && property.TryGetInt32(out int value))
{
if (json.RootElement.TryGetProperty(key, out JsonElement property) && property.TryGetInt32(out int value))
{
return value;
}
return defaultValue;
return value;
}
return defaultValue;
}
public static int GetInt32(this JsonElement json, string key, int defaultValue = 0)
public static int GetInt32(this JsonElement json, string key, int defaultValue = 0)
{
if (json.TryGetProperty(key, out JsonElement property) && property.TryGetInt32(out int value))
{
if (json.TryGetProperty(key, out JsonElement property) && property.TryGetInt32(out int value))
{
return value;
}
return defaultValue;
return value;
}
return defaultValue;
}
}

5
aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.WeChat/LINGYUN.Abp.Authentication.WeChat.csproj

@ -5,6 +5,11 @@
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AssemblyName>LINGYUN.Abp.Authentication.WeChat</AssemblyName>
<PackageId>LINGYUN.Abp.Authentication.WeChat</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>

455
aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialOAuthHandler.cs

@ -16,299 +16,298 @@ using System.Text.Encodings.Web;
using System.Text.Json;
using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Authentication.WeChat.Official
namespace Microsoft.AspNetCore.Authentication.WeChat.Official;
/// <summary>
/// 网页授权只有公众平台的实现
/// </summary>
public class WeChatOfficialOAuthHandler : OAuthHandler<WeChatOfficialOAuthOptions>
{
protected AbpWeChatOfficialOptionsFactory WeChatOfficialOptionsFactory { get; }
public WeChatOfficialOAuthHandler(
IOptionsMonitor<WeChatOfficialOAuthOptions> options,
AbpWeChatOfficialOptionsFactory weChatOfficialOptionsFactory,
ILoggerFactory logger,
UrlEncoder encoder)
: base(options, logger, encoder)
{
WeChatOfficialOptionsFactory = weChatOfficialOptionsFactory;
}
protected override async Task InitializeHandlerAsync()
{
var weChatOfficialOptions = await WeChatOfficialOptionsFactory.CreateAsync();
// 用配置项重写
Options.ClientId = weChatOfficialOptions.AppId;
Options.ClientSecret = weChatOfficialOptions.AppSecret;
Options.TimeProvider ??= TimeProvider.System;
await base.InitializeHandlerAsync();
}
/// <summary>
/// 网页授权只有公众平台的实现
/// </summary>
public class WeChatOfficialOAuthHandler : OAuthHandler<WeChatOfficialOAuthOptions>
/// 第一步:构建用户授权地址
/// </summary>
protected override string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri)
{
protected AbpWeChatOfficialOptionsFactory WeChatOfficialOptionsFactory { get; }
public WeChatOfficialOAuthHandler(
IOptionsMonitor<WeChatOfficialOAuthOptions> options,
AbpWeChatOfficialOptionsFactory weChatOfficialOptionsFactory,
ILoggerFactory logger,
UrlEncoder encoder)
: base(options, logger, encoder)
{
WeChatOfficialOptionsFactory = weChatOfficialOptionsFactory;
}
var isWeChatBrewserRequest = IsWeChatBrowser();
protected override async Task InitializeHandlerAsync()
{
var weChatOfficialOptions = await WeChatOfficialOptionsFactory.CreateAsync();
var scope = isWeChatBrewserRequest
? AbpAuthenticationWeChatConsts.UserInfoScope
: AbpAuthenticationWeChatConsts.LoginScope;
// 用配置项重写
Options.ClientId = weChatOfficialOptions.AppId;
Options.ClientSecret = weChatOfficialOptions.AppSecret;
Options.TimeProvider ??= TimeProvider.System;
var endPoint = isWeChatBrewserRequest
? Options.AuthorizationEndpoint
: AbpAuthenticationWeChatConsts.QrConnectEndpoint;
await base.InitializeHandlerAsync();
}
/// <summary>
/// 第一步:构建用户授权地址
/// </summary>
protected override string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri)
redirectUri += $"?protected={Options.StateDataFormat.Protect(properties)}";
var parameters = new Dictionary<string, string>
{
var isWeChatBrewserRequest = IsWeChatBrowser();
{ "appid", Options.ClientId },
{ "redirect_uri", redirectUri },
{ "response_type", "code" },
{ "scope", scope },
{ "state", Guid.NewGuid().ToString("N") },
};
return $"{QueryHelpers.AddQueryString(endPoint, parameters)}#wechat_redirect";
}
var scope = isWeChatBrewserRequest
? AbpAuthenticationWeChatConsts.UserInfoScope
: AbpAuthenticationWeChatConsts.LoginScope;
/// <summary>
/// 第二步:code换取access_token
/// </summary>
protected async override Task<OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
{
var parameters = new Dictionary<string, string>()
{
{ "appid", Options.ClientId },
{ "secret", Options.ClientSecret },
{ "code", context.Code },
{ "grant_type", "authorization_code" },
};
var endPoint = isWeChatBrewserRequest
? Options.AuthorizationEndpoint
: AbpAuthenticationWeChatConsts.QrConnectEndpoint;
var address = QueryHelpers.AddQueryString(Options.TokenEndpoint, parameters);
redirectUri += $"?protected={Options.StateDataFormat.Protect(properties)}";
var response = await Backchannel.GetAsync(address);
if (!response.IsSuccessStatusCode)
{
Logger.LogError("An error occurred while retrieving an access token: the remote server " +
"returned a {Status} response with the following payload: {Headers} {Body}.",
/* Status: */ response.StatusCode,
/* Headers: */ response.Headers.ToString(),
/* Body: */ await response.Content.ReadAsStringAsync());
var parameters = new Dictionary<string, string>
{
{ "appid", Options.ClientId },
{ "redirect_uri", redirectUri },
{ "response_type", "code" },
{ "scope", scope },
{ "state", Guid.NewGuid().ToString("N") },
};
return $"{QueryHelpers.AddQueryString(endPoint, parameters)}#wechat_redirect";
return OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token."));
}
/// <summary>
/// 第二步:code换取access_token
/// </summary>
protected async override Task<OAuthTokenResponse> ExchangeCodeAsync(OAuthCodeExchangeContext context)
var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
if (!string.IsNullOrEmpty(payload.GetRootString("errcode")))
{
var parameters = new Dictionary<string, string>()
{
{ "appid", Options.ClientId },
{ "secret", Options.ClientSecret },
{ "code", context.Code },
{ "grant_type", "authorization_code" },
};
Logger.LogError("An error occurred while retrieving an access token: the remote server " +
"returned a {Status} response with the following payload: {Headers} {Body}.",
/* Status: */ response.StatusCode,
/* Headers: */ response.Headers.ToString(),
/* Body: */ await response.Content.ReadAsStringAsync());
var address = QueryHelpers.AddQueryString(Options.TokenEndpoint, parameters);
var response = await Backchannel.GetAsync(address);
if (!response.IsSuccessStatusCode)
{
Logger.LogError("An error occurred while retrieving an access token: the remote server " +
"returned a {Status} response with the following payload: {Headers} {Body}.",
/* Status: */ response.StatusCode,
/* Headers: */ response.Headers.ToString(),
/* Body: */ await response.Content.ReadAsStringAsync());
return OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token."));
}
return OAuthTokenResponse.Success(payload);
}
return OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token."));
}
/// <summary>
/// 第三步:构建用户票据
/// </summary>
/// <param name="identity"></param>
/// <param name="properties"></param>
/// <param name="tokens"></param>
/// <returns></returns>
/// <exception cref="HttpRequestException"></exception>
protected async override Task<AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens)
{
var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary<string, string>
{
["access_token"] = tokens.AccessToken,
["openid"] = tokens.Response.GetRootString("openid")
});
var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
if (!string.IsNullOrEmpty(payload.GetRootString("errcode")))
{
Logger.LogError("An error occurred while retrieving an access token: the remote server " +
"returned a {Status} response with the following payload: {Headers} {Body}.",
/* Status: */ response.StatusCode,
/* Headers: */ response.Headers.ToString(),
/* Body: */ await response.Content.ReadAsStringAsync());
var response = await Backchannel.GetAsync(address);
if (!response.IsSuccessStatusCode)
{
Logger.LogError("An error occurred while retrieving the user profile: the remote server " +
"returned a {Status} response with the following payload: {Headers} {Body}.",
/* Status: */ response.StatusCode,
/* Headers: */ response.Headers.ToString(),
/* Body: */ await response.Content.ReadAsStringAsync());
return OAuthTokenResponse.Failed(new Exception("An error occurred while retrieving an access token."));
}
return OAuthTokenResponse.Success(payload);
throw new HttpRequestException("An error occurred while retrieving user information.");
}
/// <summary>
/// 第三步:构建用户票据
/// </summary>
/// <param name="identity"></param>
/// <param name="properties"></param>
/// <param name="tokens"></param>
/// <returns></returns>
/// <exception cref="HttpRequestException"></exception>
protected async override Task<AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity, AuthenticationProperties properties, OAuthTokenResponse tokens)
var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
if (!string.IsNullOrEmpty(payload.GetRootString("errcode")))
{
var address = QueryHelpers.AddQueryString(Options.UserInformationEndpoint, new Dictionary<string, string>
{
["access_token"] = tokens.AccessToken,
["openid"] = tokens.Response.GetRootString("openid")
});
Logger.LogError("An error occurred while retrieving the user profile: the remote server " +
"returned a {Status} response with the following payload: {Headers} {Body}.",
/* Status: */ response.StatusCode,
/* Headers: */ response.Headers.ToString(),
/* Body: */ await response.Content.ReadAsStringAsync());
var response = await Backchannel.GetAsync(address);
if (!response.IsSuccessStatusCode)
{
Logger.LogError("An error occurred while retrieving the user profile: the remote server " +
"returned a {Status} response with the following payload: {Headers} {Body}.",
/* Status: */ response.StatusCode,
/* Headers: */ response.Headers.ToString(),
/* Body: */ await response.Content.ReadAsStringAsync());
throw new HttpRequestException("An error occurred while retrieving user information.");
}
throw new HttpRequestException("An error occurred while retrieving user information.");
}
var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, payload.RootElement);
context.RunClaimActions();
var payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
if (!string.IsNullOrEmpty(payload.GetRootString("errcode")))
{
Logger.LogError("An error occurred while retrieving the user profile: the remote server " +
"returned a {Status} response with the following payload: {Headers} {Body}.",
/* Status: */ response.StatusCode,
/* Headers: */ response.Headers.ToString(),
/* Body: */ await response.Content.ReadAsStringAsync());
await Events.CreatingTicket(context);
throw new HttpRequestException("An error occurred while retrieving user information.");
}
return new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name);
}
public override Task<bool> HandleRequestAsync()
{
return base.HandleRequestAsync();
}
var context = new OAuthCreatingTicketContext(new ClaimsPrincipal(identity), properties, Context, Scheme, Options, Backchannel, tokens, payload.RootElement);
context.RunClaimActions();
protected async override Task<HandleRequestResult> HandleRemoteAuthenticateAsync()
{
var query = Request.Query;
await Events.CreatingTicket(context);
// TODO: 此处借用唯一的 CorrelationId, 将 properties生成的State缓存取出,进行解密
var state = query["protected"];
return new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name);
}
var properties = Options.StateDataFormat.Unprotect(state);
public override Task<bool> HandleRequestAsync()
if (properties == null)
{
return base.HandleRequestAsync();
return HandleRequestResult.Fail("The oauth state was missing or invalid.");
}
protected async override Task<HandleRequestResult> HandleRemoteAuthenticateAsync()
// OAuth2 10.12 CSRF
if (!ValidateCorrelationId(properties))
{
var query = Request.Query;
return HandleRequestResult.Fail("Correlation failed.", properties);
}
// TODO: 此处借用唯一的 CorrelationId, 将 properties生成的State缓存取出,进行解密
var state = query["protected"];
var error = query["error"];
if (!StringValues.IsNullOrEmpty(error))
{
// Note: access_denied errors are special protocol errors indicating the user didn't
// approve the authorization demand requested by the remote authorization server.
// Since it's a frequent scenario (that is not caused by incorrect configuration),
// denied errors are handled differently using HandleAccessDeniedErrorAsync().
// Visit https://tools.ietf.org/html/rfc6749#section-4.1.2.1 for more information.
var errorDescription = query["error_description"];
var errorUri = query["error_uri"];
if (StringValues.Equals(error, "access_denied"))
{
var result = await HandleAccessDeniedErrorAsync(properties);
if (!result.None)
{
return result;
}
var deniedEx = new Exception("Access was denied by the resource owner or by the remote server.");
deniedEx.Data["error"] = error.ToString();
deniedEx.Data["error_description"] = errorDescription.ToString();
deniedEx.Data["error_uri"] = errorUri.ToString();
var properties = Options.StateDataFormat.Unprotect(state);
return HandleRequestResult.Fail(deniedEx, properties);
}
if (properties == null)
var failureMessage = new StringBuilder();
failureMessage.Append(error);
if (!StringValues.IsNullOrEmpty(errorDescription))
{
return HandleRequestResult.Fail("The oauth state was missing or invalid.");
failureMessage.Append(";Description=").Append(errorDescription);
}
// OAuth2 10.12 CSRF
if (!ValidateCorrelationId(properties))
if (!StringValues.IsNullOrEmpty(errorUri))
{
return HandleRequestResult.Fail("Correlation failed.", properties);
failureMessage.Append(";Uri=").Append(errorUri);
}
var error = query["error"];
if (!StringValues.IsNullOrEmpty(error))
{
// Note: access_denied errors are special protocol errors indicating the user didn't
// approve the authorization demand requested by the remote authorization server.
// Since it's a frequent scenario (that is not caused by incorrect configuration),
// denied errors are handled differently using HandleAccessDeniedErrorAsync().
// Visit https://tools.ietf.org/html/rfc6749#section-4.1.2.1 for more information.
var errorDescription = query["error_description"];
var errorUri = query["error_uri"];
if (StringValues.Equals(error, "access_denied"))
{
var result = await HandleAccessDeniedErrorAsync(properties);
if (!result.None)
{
return result;
}
var deniedEx = new Exception("Access was denied by the resource owner or by the remote server.");
deniedEx.Data["error"] = error.ToString();
deniedEx.Data["error_description"] = errorDescription.ToString();
deniedEx.Data["error_uri"] = errorUri.ToString();
return HandleRequestResult.Fail(deniedEx, properties);
}
var ex = new Exception(failureMessage.ToString());
ex.Data["error"] = error.ToString();
ex.Data["error_description"] = errorDescription.ToString();
ex.Data["error_uri"] = errorUri.ToString();
var failureMessage = new StringBuilder();
failureMessage.Append(error);
if (!StringValues.IsNullOrEmpty(errorDescription))
{
failureMessage.Append(";Description=").Append(errorDescription);
}
if (!StringValues.IsNullOrEmpty(errorUri))
{
failureMessage.Append(";Uri=").Append(errorUri);
}
return HandleRequestResult.Fail(ex, properties);
}
var ex = new Exception(failureMessage.ToString());
ex.Data["error"] = error.ToString();
ex.Data["error_description"] = errorDescription.ToString();
ex.Data["error_uri"] = errorUri.ToString();
var code = query["code"];
return HandleRequestResult.Fail(ex, properties);
}
if (StringValues.IsNullOrEmpty(code))
{
return HandleRequestResult.Fail("Code was not found.", properties);
}
var code = query["code"];
var codeExchangeContext = new OAuthCodeExchangeContext(properties, code, BuildRedirectUri(Options.CallbackPath));
using var tokens = await ExchangeCodeAsync(codeExchangeContext);
if (StringValues.IsNullOrEmpty(code))
{
return HandleRequestResult.Fail("Code was not found.", properties);
}
if (tokens.Error != null)
{
return HandleRequestResult.Fail(tokens.Error, properties);
}
if (string.IsNullOrEmpty(tokens.AccessToken))
{
return HandleRequestResult.Fail("Failed to retrieve access token.", properties);
}
var codeExchangeContext = new OAuthCodeExchangeContext(properties, code, BuildRedirectUri(Options.CallbackPath));
using var tokens = await ExchangeCodeAsync(codeExchangeContext);
var identity = new ClaimsIdentity(ClaimsIssuer);
if (tokens.Error != null)
if (Options.SaveTokens)
{
var authTokens = new List<AuthenticationToken>();
authTokens.Add(new AuthenticationToken { Name = "access_token", Value = tokens.AccessToken });
if (!string.IsNullOrEmpty(tokens.RefreshToken))
{
return HandleRequestResult.Fail(tokens.Error, properties);
authTokens.Add(new AuthenticationToken { Name = "refresh_token", Value = tokens.RefreshToken });
}
if (string.IsNullOrEmpty(tokens.AccessToken))
if (!string.IsNullOrEmpty(tokens.TokenType))
{
return HandleRequestResult.Fail("Failed to retrieve access token.", properties);
authTokens.Add(new AuthenticationToken { Name = "token_type", Value = tokens.TokenType });
}
var identity = new ClaimsIdentity(ClaimsIssuer);
if (Options.SaveTokens)
if (!string.IsNullOrEmpty(tokens.ExpiresIn))
{
var authTokens = new List<AuthenticationToken>();
authTokens.Add(new AuthenticationToken { Name = "access_token", Value = tokens.AccessToken });
if (!string.IsNullOrEmpty(tokens.RefreshToken))
{
authTokens.Add(new AuthenticationToken { Name = "refresh_token", Value = tokens.RefreshToken });
}
if (!string.IsNullOrEmpty(tokens.TokenType))
int value;
if (int.TryParse(tokens.ExpiresIn, NumberStyles.Integer, CultureInfo.InvariantCulture, out value))
{
authTokens.Add(new AuthenticationToken { Name = "token_type", Value = tokens.TokenType });
}
if (!string.IsNullOrEmpty(tokens.ExpiresIn))
{
int value;
if (int.TryParse(tokens.ExpiresIn, NumberStyles.Integer, CultureInfo.InvariantCulture, out value))
// https://www.w3.org/TR/xmlschema-2/#dateTime
// https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx
var expiresAt = Options.TimeProvider.GetUtcNow() + TimeSpan.FromSeconds(value);
authTokens.Add(new AuthenticationToken
{
// https://www.w3.org/TR/xmlschema-2/#dateTime
// https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx
var expiresAt = Options.TimeProvider.GetUtcNow() + TimeSpan.FromSeconds(value);
authTokens.Add(new AuthenticationToken
{
Name = "expires_at",
Value = expiresAt.ToString("o", CultureInfo.InvariantCulture)
});
}
Name = "expires_at",
Value = expiresAt.ToString("o", CultureInfo.InvariantCulture)
});
}
properties.StoreTokens(authTokens);
}
var ticket = await CreateTicketAsync(identity, properties, tokens);
if (ticket != null)
{
return HandleRequestResult.Success(ticket);
}
else
{
return HandleRequestResult.Fail("Failed to retrieve user information from remote server.", properties);
}
properties.StoreTokens(authTokens);
}
protected override string FormatScope()
var ticket = await CreateTicketAsync(identity, properties, tokens);
if (ticket != null)
{
return string.Join(",", Options.Scope);
return HandleRequestResult.Success(ticket);
}
protected virtual bool IsWeChatBrowser()
else
{
var userAgent = Request.Headers[HeaderNames.UserAgent].ToString();
return userAgent.Contains("micromessenger", StringComparison.InvariantCultureIgnoreCase);
return HandleRequestResult.Fail("Failed to retrieve user information from remote server.", properties);
}
}
protected override string FormatScope()
{
return string.Join(",", Options.Scope);
}
protected virtual bool IsWeChatBrowser()
{
var userAgent = Request.Headers[HeaderNames.UserAgent].ToString();
return userAgent.Contains("micromessenger", StringComparison.InvariantCultureIgnoreCase);
}
}

61
aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialOAuthOptions.cs

@ -5,43 +5,42 @@ using Microsoft.AspNetCore.Http;
using System.Security.Claims;
using System.Text.Json;
namespace Microsoft.AspNetCore.Authentication.WeChat.Official
namespace Microsoft.AspNetCore.Authentication.WeChat.Official;
public class WeChatOfficialOAuthOptions : OAuthOptions
{
public class WeChatOfficialOAuthOptions : OAuthOptions
public WeChatOfficialOAuthOptions()
{
public WeChatOfficialOAuthOptions()
{
// 用于防止初始化错误,会在OAuthHandler.InitializeHandlerAsync中进行重写
ClientId = "WeChatOfficial";
ClientSecret = "WeChatOfficial";
// 用于防止初始化错误,会在OAuthHandler.InitializeHandlerAsync中进行重写
ClientId = "WeChatOfficial";
ClientSecret = "WeChatOfficial";
ClaimsIssuer = AbpAuthenticationWeChatConsts.ProviderKey;
CallbackPath = new PathString(AbpAuthenticationWeChatConsts.CallbackPath);
ClaimsIssuer = AbpAuthenticationWeChatConsts.ProviderKey;
CallbackPath = new PathString(AbpAuthenticationWeChatConsts.CallbackPath);
AuthorizationEndpoint = AbpAuthenticationWeChatConsts.AuthorizationEndpoint;
TokenEndpoint = AbpAuthenticationWeChatConsts.TokenEndpoint;
UserInformationEndpoint = AbpAuthenticationWeChatConsts.UserInformationEndpoint;
AuthorizationEndpoint = AbpAuthenticationWeChatConsts.AuthorizationEndpoint;
TokenEndpoint = AbpAuthenticationWeChatConsts.TokenEndpoint;
UserInformationEndpoint = AbpAuthenticationWeChatConsts.UserInformationEndpoint;
Scope.Add(AbpAuthenticationWeChatConsts.LoginScope);
Scope.Add(AbpAuthenticationWeChatConsts.UserInfoScope);
Scope.Add(AbpAuthenticationWeChatConsts.LoginScope);
Scope.Add(AbpAuthenticationWeChatConsts.UserInfoScope);
// 这个原始的属性一定要写进去,框架与UserLogin.ProviderKey进行关联判断是否绑定微信
ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "openid");
ClaimActions.MapJsonKey(ClaimTypes.Name, "nickname");
// 这个原始的属性一定要写进去,框架与UserLogin.ProviderKey进行关联判断是否绑定微信
ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "openid");
ClaimActions.MapJsonKey(ClaimTypes.Name, "nickname");
// 把自定义的身份标识写进令牌
ClaimActions.MapJsonKey(AbpWeChatClaimTypes.OpenId, "openid");
ClaimActions.MapJsonKey(AbpWeChatClaimTypes.UnionId, "unionid");// 公众号如果与小程序关联,这个可以用上
ClaimActions.MapJsonKey(AbpWeChatClaimTypes.NickName, "nickname");
ClaimActions.MapJsonKey(AbpWeChatClaimTypes.Sex, "sex", ClaimValueTypes.Integer);
ClaimActions.MapJsonKey(AbpWeChatClaimTypes.Country, "country");
ClaimActions.MapJsonKey(AbpWeChatClaimTypes.Province, "province");
ClaimActions.MapJsonKey(AbpWeChatClaimTypes.City, "city");
ClaimActions.MapJsonKey(AbpWeChatClaimTypes.AvatarUrl, "headimgurl");
ClaimActions.MapCustomJson(AbpWeChatClaimTypes.Privilege, user =>
{
return string.Join(",", user.GetStrings("privilege"));
});
}
// 把自定义的身份标识写进令牌
ClaimActions.MapJsonKey(AbpWeChatClaimTypes.OpenId, "openid");
ClaimActions.MapJsonKey(AbpWeChatClaimTypes.UnionId, "unionid");// 公众号如果与小程序关联,这个可以用上
ClaimActions.MapJsonKey(AbpWeChatClaimTypes.NickName, "nickname");
ClaimActions.MapJsonKey(AbpWeChatClaimTypes.Sex, "sex", ClaimValueTypes.Integer);
ClaimActions.MapJsonKey(AbpWeChatClaimTypes.Country, "country");
ClaimActions.MapJsonKey(AbpWeChatClaimTypes.Province, "province");
ClaimActions.MapJsonKey(AbpWeChatClaimTypes.City, "city");
ClaimActions.MapJsonKey(AbpWeChatClaimTypes.AvatarUrl, "headimgurl");
ClaimActions.MapCustomJson(AbpWeChatClaimTypes.Privilege, user =>
{
return string.Join(",", user.GetStrings("privilege"));
});
}
}

25
aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.WeChat/Microsoft/AspNetCore/Authentication/WeChat/Official/WeChatOfficialStateCacheItem.cs

@ -1,18 +1,17 @@
namespace Microsoft.AspNetCore.Authentication.WeChat.Official
namespace Microsoft.AspNetCore.Authentication.WeChat.Official;
public class WeChatOfficialStateCacheItem
{
public class WeChatOfficialStateCacheItem
{
public string State { get; set; }
public string State { get; set; }
public WeChatOfficialStateCacheItem() { }
public WeChatOfficialStateCacheItem(string state)
{
State = state;
}
public WeChatOfficialStateCacheItem() { }
public WeChatOfficialStateCacheItem(string state)
{
State = state;
}
public static string CalculateCacheKey(string correlationId, string purpose)
{
return $"ci:{correlationId};p:{purpose ?? "null"}";
}
public static string CalculateCacheKey(string correlationId, string purpose)
{
return $"ci:{correlationId};p:{purpose ?? "null"}";
}
}

103
aspnet-core/framework/authentication/LINGYUN.Abp.Authentication.WeChat/Microsoft/AspNetCore/Authentication/WeChatAuthenticationExtensions.cs

@ -4,62 +4,61 @@ using Microsoft.AspNetCore.Authentication.WeChat.Official;
using Microsoft.Extensions.DependencyInjection;
using System;
namespace Microsoft.AspNetCore.Authentication
namespace Microsoft.AspNetCore.Authentication;
public static class WeChatAuthenticationExtensions
{
public static class WeChatAuthenticationExtensions
/// <summary>
/// </summary>
public static AuthenticationBuilder AddWeChat(
this AuthenticationBuilder builder)
{
/// <summary>
/// </summary>
public static AuthenticationBuilder AddWeChat(
this AuthenticationBuilder builder)
{
return builder
.AddWeChat(
AbpWeChatGlobalConsts.AuthenticationScheme,
AbpWeChatGlobalConsts.DisplayName,
options => { });
}
return builder
.AddWeChat(
AbpWeChatGlobalConsts.AuthenticationScheme,
AbpWeChatGlobalConsts.DisplayName,
options => { });
}
/// <summary>
/// </summary>
public static AuthenticationBuilder AddWeChat(
this AuthenticationBuilder builder,
Action<WeChatOfficialOAuthOptions> configureOptions)
{
return builder
.AddWeChat(
AbpWeChatGlobalConsts.AuthenticationScheme,
AbpWeChatGlobalConsts.DisplayName,
configureOptions);
}
/// <summary>
/// </summary>
public static AuthenticationBuilder AddWeChat(
this AuthenticationBuilder builder,
Action<WeChatOfficialOAuthOptions> configureOptions)
{
return builder
.AddWeChat(
AbpWeChatGlobalConsts.AuthenticationScheme,
AbpWeChatGlobalConsts.DisplayName,
configureOptions);
}
/// <summary>
/// </summary>
public static AuthenticationBuilder AddWeChat(
this AuthenticationBuilder builder,
string authenticationScheme,
Action<WeChatOfficialOAuthOptions> configureOptions)
{
return builder
.AddWeChat(
authenticationScheme,
AbpAuthenticationWeChatConsts.DisplayName,
configureOptions);
}
/// <summary>
/// </summary>
public static AuthenticationBuilder AddWeChat(
this AuthenticationBuilder builder,
string authenticationScheme,
Action<WeChatOfficialOAuthOptions> configureOptions)
{
return builder
.AddWeChat(
authenticationScheme,
AbpAuthenticationWeChatConsts.DisplayName,
configureOptions);
}
/// <summary>
/// </summary>
public static AuthenticationBuilder AddWeChat(
this AuthenticationBuilder builder,
string authenticationScheme,
string displayName,
Action<WeChatOfficialOAuthOptions> configureOptions)
{
return builder
.AddOAuth<WeChatOfficialOAuthOptions, WeChatOfficialOAuthHandler>(
authenticationScheme,
displayName,
configureOptions);
}
/// <summary>
/// </summary>
public static AuthenticationBuilder AddWeChat(
this AuthenticationBuilder builder,
string authenticationScheme,
string displayName,
Action<WeChatOfficialOAuthOptions> configureOptions)
{
return builder
.AddOAuth<WeChatOfficialOAuthOptions, WeChatOfficialOAuthHandler>(
authenticationScheme,
displayName,
configureOptions);
}
}

9
aspnet-core/framework/authorization/LINGYUN.Abp.Authorization.OrganizationUnits/LINGYUN.Abp.Authorization.OrganizationUnits.csproj

@ -4,7 +4,14 @@
<Import Project="..\..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0</TargetFrameworks>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<AssemblyName>LINGYUN.Abp.Authorization.OrganizationUnits</AssemblyName>
<PackageId>LINGYUN.Abp.Authorization.OrganizationUnits</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>

2
aspnet-core/framework/cli/LINGYUN.Abp.Cli/LINGYUN.Abp.Cli.csproj

@ -5,7 +5,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<Version>8.1.1</Version>
<Version>8.2.0</Version>
<Copyright>colin</Copyright>
<Description>Use LINGYUN.MicroService.Templates command line</Description>
<PackAsTool>true</PackAsTool>

5
aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun.SettingManagement/LINGYUN.Abp.Aliyun.SettingManagement.csproj

@ -5,6 +5,11 @@
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AssemblyName>LINGYUN.Abp.Aliyun.SettingManagement</AssemblyName>
<PackageId>LINGYUN.Abp.Aliyun.SettingManagement</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
</PropertyGroup>

49
aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun.SettingManagement/LINGYUN/Abp/Aliyun/SettingManagement/AbpAliyunSettingManagementModule.cs

@ -7,36 +7,35 @@ using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.Aliyun.SettingManagement
namespace LINGYUN.Abp.Aliyun.SettingManagement;
[DependsOn(
typeof(AbpAliyunModule),
typeof(AbpAliyunSmsModule),
typeof(AbpAspNetCoreMvcModule))]
public class AbpAliyunSettingManagementModule : AbpModule
{
[DependsOn(
typeof(AbpAliyunModule),
typeof(AbpAliyunSmsModule),
typeof(AbpAspNetCoreMvcModule))]
public class AbpAliyunSettingManagementModule : AbpModule
public override void PreConfigureServices(ServiceConfigurationContext context)
{
public override void PreConfigureServices(ServiceConfigurationContext context)
PreConfigure<IMvcBuilder>(mvcBuilder =>
{
PreConfigure<IMvcBuilder>(mvcBuilder =>
{
mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpAliyunSettingManagementModule).Assembly);
});
}
mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpAliyunSettingManagementModule).Assembly);
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpAliyunSettingManagementModule>();
});
options.FileSets.AddEmbedded<AbpAliyunSettingManagementModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<AliyunResource>()
.AddBaseTypes(typeof(AbpUiResource))
.AddVirtualJson("/LINGYUN/Abp/Aliyun/SettingManagement/Localization/Resources");
});
}
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<AliyunResource>()
.AddBaseTypes(typeof(AbpUiResource))
.AddVirtualJson("/LINGYUN/Abp/Aliyun/SettingManagement/Localization/Resources");
});
}
}

333
aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun.SettingManagement/LINGYUN/Abp/Aliyun/SettingManagement/AliyunSettingAppService.cs

@ -11,192 +11,191 @@ using Volo.Abp.SettingManagement;
using Volo.Abp.Settings;
using ValueType = LINGYUN.Abp.SettingManagement.ValueType;
namespace LINGYUN.Abp.Aliyun.SettingManagement
namespace LINGYUN.Abp.Aliyun.SettingManagement;
public class AliyunSettingAppService : ApplicationService, IAliyunSettingAppService
{
public class AliyunSettingAppService : ApplicationService, IAliyunSettingAppService
protected ISettingManager SettingManager { get; }
protected IPermissionChecker PermissionChecker { get; }
protected ISettingDefinitionManager SettingDefinitionManager { get; }
public AliyunSettingAppService(
ISettingManager settingManager,
IPermissionChecker permissionChecker,
ISettingDefinitionManager settingDefinitionManager)
{
protected ISettingManager SettingManager { get; }
protected IPermissionChecker PermissionChecker { get; }
protected ISettingDefinitionManager SettingDefinitionManager { get; }
public AliyunSettingAppService(
ISettingManager settingManager,
IPermissionChecker permissionChecker,
ISettingDefinitionManager settingDefinitionManager)
{
SettingManager = settingManager;
PermissionChecker = permissionChecker;
SettingDefinitionManager = settingDefinitionManager;
LocalizationResource = typeof(AliyunResource);
}
SettingManager = settingManager;
PermissionChecker = permissionChecker;
SettingDefinitionManager = settingDefinitionManager;
LocalizationResource = typeof(AliyunResource);
}
public async virtual Task<SettingGroupResult> GetAllForCurrentTenantAsync()
{
return await GetAllForProviderAsync(TenantSettingValueProvider.ProviderName, CurrentTenant.GetId().ToString());
}
public async virtual Task<SettingGroupResult> GetAllForCurrentTenantAsync()
{
return await GetAllForProviderAsync(TenantSettingValueProvider.ProviderName, CurrentTenant.GetId().ToString());
}
public async virtual Task<SettingGroupResult> GetAllForGlobalAsync()
{
return await GetAllForProviderAsync(GlobalSettingValueProvider.ProviderName, null);
}
public async virtual Task<SettingGroupResult> GetAllForGlobalAsync()
{
return await GetAllForProviderAsync(GlobalSettingValueProvider.ProviderName, null);
}
protected async virtual Task<SettingGroupResult> GetAllForProviderAsync(string providerName, string providerKey)
protected async virtual Task<SettingGroupResult> GetAllForProviderAsync(string providerName, string providerKey)
{
var settingGroups = new SettingGroupResult();
// 无权限返回空结果,直接报错的话,网关聚合会抛出异常
if (await FeatureChecker.IsEnabledAsync(AliyunFeatureNames.Enable) &&
await PermissionChecker.IsGrantedAsync(AliyunSettingPermissionNames.Settings))
{
var settingGroups = new SettingGroupResult();
var aliyunSettingGroup = new SettingGroupDto(L["DisplayName:Aliyun"], L["Description:Aliyun"]);
#region 访问控制
var ramSetting = aliyunSettingGroup.AddSetting(L["DisplayName:Aliyun.RAM"], L["Description:Aliyun.RAM"]);
ramSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Authorization.RegionId),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Authorization.RegionId, providerName, providerKey),
ValueType.Option,
providerName)
.AddOptions(GetAvailableRegionOptions());
ramSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Authorization.AccessKeyId),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Authorization.AccessKeyId, providerName, providerKey),
ValueType.String,
providerName);
ramSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Authorization.AccessKeySecret),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Authorization.AccessKeySecret, providerName, providerKey),
ValueType.String,
providerName);
ramSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Authorization.RamRoleArn),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Authorization.RamRoleArn, providerName, providerKey),
ValueType.String,
providerName);
ramSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Authorization.RoleSessionName),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Authorization.RoleSessionName, providerName, providerKey),
ValueType.String,
providerName);
ramSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Authorization.Policy),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Authorization.Policy, providerName, providerKey),
ValueType.String,
providerName);
ramSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Authorization.UseSecurityTokenService),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Authorization.UseSecurityTokenService, providerName, providerKey),
ValueType.Boolean,
providerName);
ramSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Authorization.DurationSeconds),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Authorization.DurationSeconds, providerName, providerKey),
ValueType.Number,
providerName);
// 无权限返回空结果,直接报错的话,网关聚合会抛出异常
if (await FeatureChecker.IsEnabledAsync(AliyunFeatureNames.Enable) &&
await PermissionChecker.IsGrantedAsync(AliyunSettingPermissionNames.Settings))
#endregion
#region 短信
if (await FeatureChecker.IsEnabledAsync(AliyunFeatureNames.Sms.Enable))
{
var aliyunSettingGroup = new SettingGroupDto(L["DisplayName:Aliyun"], L["Description:Aliyun"]);
#region 访问控制
var ramSetting = aliyunSettingGroup.AddSetting(L["DisplayName:Aliyun.RAM"], L["Description:Aliyun.RAM"]);
ramSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Authorization.RegionId),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Authorization.RegionId, providerName, providerKey),
ValueType.Option,
providerName)
.AddOptions(GetAvailableRegionOptions());
ramSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Authorization.AccessKeyId),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Authorization.AccessKeyId, providerName, providerKey),
ValueType.String,
var smsSetting = aliyunSettingGroup.AddSetting(L["DisplayName:Aliyun.Sms"], L["Description:Aliyun.Sms"]);
smsSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Sms.Domain),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Sms.Domain, providerName, providerKey),
ValueType.String,
providerName);
ramSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Authorization.AccessKeySecret),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Authorization.AccessKeySecret, providerName, providerKey),
ValueType.String,
smsSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Sms.Version),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Sms.Version, providerName, providerKey),
ValueType.String,
providerName);
ramSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Authorization.RamRoleArn),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Authorization.RamRoleArn, providerName, providerKey),
ValueType.String,
smsSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Sms.ActionName),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Sms.ActionName, providerName, providerKey),
ValueType.String,
providerName);
ramSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Authorization.RoleSessionName),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Authorization.RoleSessionName, providerName, providerKey),
ValueType.String,
smsSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Sms.DefaultPhoneNumber),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Sms.DefaultPhoneNumber, providerName, providerKey),
ValueType.String,
providerName);
ramSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Authorization.Policy),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Authorization.Policy, providerName, providerKey),
ValueType.String,
smsSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Sms.DefaultSignName),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Sms.DefaultSignName, providerName, providerKey),
ValueType.String,
providerName);
ramSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Authorization.UseSecurityTokenService),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Authorization.UseSecurityTokenService, providerName, providerKey),
ValueType.Boolean,
smsSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Sms.DefaultTemplateCode),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Sms.DefaultTemplateCode, providerName, providerKey),
ValueType.String,
providerName);
ramSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Authorization.DurationSeconds),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Authorization.DurationSeconds, providerName, providerKey),
ValueType.Number,
smsSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Sms.VisableErrorToClient),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Sms.VisableErrorToClient, providerName, providerKey),
ValueType.Boolean,
providerName);
#endregion
#region 短信
if (await FeatureChecker.IsEnabledAsync(AliyunFeatureNames.Sms.Enable))
{
var smsSetting = aliyunSettingGroup.AddSetting(L["DisplayName:Aliyun.Sms"], L["Description:Aliyun.Sms"]);
smsSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Sms.Domain),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Sms.Domain, providerName, providerKey),
ValueType.String,
providerName);
smsSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Sms.Version),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Sms.Version, providerName, providerKey),
ValueType.String,
providerName);
smsSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Sms.ActionName),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Sms.ActionName, providerName, providerKey),
ValueType.String,
providerName);
smsSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Sms.DefaultPhoneNumber),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Sms.DefaultPhoneNumber, providerName, providerKey),
ValueType.String,
providerName);
smsSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Sms.DefaultSignName),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Sms.DefaultSignName, providerName, providerKey),
ValueType.String,
providerName);
smsSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Sms.DefaultTemplateCode),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Sms.DefaultTemplateCode, providerName, providerKey),
ValueType.String,
providerName);
smsSetting.AddDetail(
await SettingDefinitionManager.GetAsync(AliyunSettingNames.Sms.VisableErrorToClient),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(AliyunSettingNames.Sms.VisableErrorToClient, providerName, providerKey),
ValueType.Boolean,
providerName);
}
#endregion
settingGroups.AddGroup(aliyunSettingGroup);
}
return settingGroups;
#endregion
settingGroups.AddGroup(aliyunSettingGroup);
}
protected virtual IEnumerable<OptionDto> GetAvailableRegionOptions()
return settingGroups;
}
protected virtual IEnumerable<OptionDto> GetAvailableRegionOptions()
{
return new OptionDto[]
{
return new OptionDto[]
{
new OptionDto(L["Region:HangZhou"], "oss-cn-hangzhou"),
new OptionDto(L["Region:ShangHai"], "oss-cn-shanghai"),
new OptionDto(L["Region:NanJing"], "oss-cn-nanjing"),
new OptionDto(L["Region:FuZhou"], "oss-cn-fuzhou"),
new OptionDto(L["Region:WuHan"], "oss-cn-wuhan"),
new OptionDto(L["Region:QingDao"], "oss-cn-qingdao"),
new OptionDto(L["Region:BeiJing"], "oss-cn-beijing"),
new OptionDto(L["Region:ZhangJiaKou"], "oss-cn-zhangjiakou"),
new OptionDto(L["Region:HuHeHaoTe"], "oss-cn-huhehaote"),
new OptionDto(L["Region:WuLanChaBu"], "oss-cn-wulanchabu"),
new OptionDto(L["Region:ShenZhen"], "oss-cn-shenzhen"),
new OptionDto(L["Region:HeYuan"], "oss-cn-heyuan"),
new OptionDto(L["Region:GuangZhou"], "oss-cn-guangzhou"),
new OptionDto(L["Region:ChengDu"], "oss-cn-chengdu"),
new OptionDto(L["Region:HongKong"], "oss-cn-hongkong"),
new OptionDto(L["Region:SiliconValley"], "oss-us-west-1"),
new OptionDto(L["Region:Virginia"], "oss-us-east-1"),
new OptionDto(L["Region:Tokoyo"], "oss-ap-northeast-1"),
new OptionDto(L["Region:Seoul"], "oss-ap-northeast-2"),
new OptionDto(L["Region:Singapore"], "oss-ap-southeast-1"),
new OptionDto(L["Region:Sydney"], "oss-ap-southeast-2"),
new OptionDto(L["Region:KualaLumpur"], "oss-ap-southeast-3"),
new OptionDto(L["Region:Jakarta"], "oss-ap-southeast-5"),
new OptionDto(L["Region:Manila"], "oss-ap-southeast-6"),
new OptionDto(L["Region:Bangkok"], "oss-ap-southeast-7"),
new OptionDto(L["Region:Bombay"], "oss-ap-south-1"),
new OptionDto(L["Region:Frankfurt"], "oss-eu-central-1"),
new OptionDto(L["Region:London"], "oss-eu-west-1"),
new OptionDto(L["Region:Dubai"], "oss-me-east-1"),
new OptionDto(L["Region:MainLand"], "oss-rg-china-mainland"),
};
}
new OptionDto(L["Region:HangZhou"], "oss-cn-hangzhou"),
new OptionDto(L["Region:ShangHai"], "oss-cn-shanghai"),
new OptionDto(L["Region:NanJing"], "oss-cn-nanjing"),
new OptionDto(L["Region:FuZhou"], "oss-cn-fuzhou"),
new OptionDto(L["Region:WuHan"], "oss-cn-wuhan"),
new OptionDto(L["Region:QingDao"], "oss-cn-qingdao"),
new OptionDto(L["Region:BeiJing"], "oss-cn-beijing"),
new OptionDto(L["Region:ZhangJiaKou"], "oss-cn-zhangjiakou"),
new OptionDto(L["Region:HuHeHaoTe"], "oss-cn-huhehaote"),
new OptionDto(L["Region:WuLanChaBu"], "oss-cn-wulanchabu"),
new OptionDto(L["Region:ShenZhen"], "oss-cn-shenzhen"),
new OptionDto(L["Region:HeYuan"], "oss-cn-heyuan"),
new OptionDto(L["Region:GuangZhou"], "oss-cn-guangzhou"),
new OptionDto(L["Region:ChengDu"], "oss-cn-chengdu"),
new OptionDto(L["Region:HongKong"], "oss-cn-hongkong"),
new OptionDto(L["Region:SiliconValley"], "oss-us-west-1"),
new OptionDto(L["Region:Virginia"], "oss-us-east-1"),
new OptionDto(L["Region:Tokoyo"], "oss-ap-northeast-1"),
new OptionDto(L["Region:Seoul"], "oss-ap-northeast-2"),
new OptionDto(L["Region:Singapore"], "oss-ap-southeast-1"),
new OptionDto(L["Region:Sydney"], "oss-ap-southeast-2"),
new OptionDto(L["Region:KualaLumpur"], "oss-ap-southeast-3"),
new OptionDto(L["Region:Jakarta"], "oss-ap-southeast-5"),
new OptionDto(L["Region:Manila"], "oss-ap-southeast-6"),
new OptionDto(L["Region:Bangkok"], "oss-ap-southeast-7"),
new OptionDto(L["Region:Bombay"], "oss-ap-south-1"),
new OptionDto(L["Region:Frankfurt"], "oss-eu-central-1"),
new OptionDto(L["Region:London"], "oss-eu-west-1"),
new OptionDto(L["Region:Dubai"], "oss-me-east-1"),
new OptionDto(L["Region:MainLand"], "oss-rg-china-mainland"),
};
}
}

47
aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun.SettingManagement/LINGYUN/Abp/Aliyun/SettingManagement/AliyunSettingController.cs

@ -4,33 +4,32 @@ using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
namespace LINGYUN.Abp.Aliyun.SettingManagement
namespace LINGYUN.Abp.Aliyun.SettingManagement;
[RemoteService(Name = AbpSettingManagementRemoteServiceConsts.RemoteServiceName)]
[Area("settingManagement")]
[Route("api/setting-management/aliyun")]
public class AliyunSettingController : AbpControllerBase, IAliyunSettingAppService
{
[RemoteService(Name = AbpSettingManagementRemoteServiceConsts.RemoteServiceName)]
[Area("settingManagement")]
[Route("api/setting-management/aliyun")]
public class AliyunSettingController : AbpControllerBase, IAliyunSettingAppService
{
protected IAliyunSettingAppService AppService { get; }
protected IAliyunSettingAppService AppService { get; }
public AliyunSettingController(
IAliyunSettingAppService appService)
{
AppService = appService;
}
public AliyunSettingController(
IAliyunSettingAppService appService)
{
AppService = appService;
}
[HttpGet]
[Route("by-current-tenant")]
public async virtual Task<SettingGroupResult> GetAllForCurrentTenantAsync()
{
return await AppService.GetAllForCurrentTenantAsync();
}
[HttpGet]
[Route("by-current-tenant")]
public async virtual Task<SettingGroupResult> GetAllForCurrentTenantAsync()
{
return await AppService.GetAllForCurrentTenantAsync();
}
[HttpGet]
[Route("by-global")]
public async virtual Task<SettingGroupResult> GetAllForGlobalAsync()
{
return await AppService.GetAllForGlobalAsync();
}
[HttpGet]
[Route("by-global")]
public async virtual Task<SettingGroupResult> GetAllForGlobalAsync()
{
return await AppService.GetAllForGlobalAsync();
}
}

27
aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun.SettingManagement/LINGYUN/Abp/Aliyun/SettingManagement/AliyunSettingPermissionDefinitionProvider.cs

@ -2,23 +2,22 @@
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Localization;
namespace LINGYUN.Abp.Aliyun.SettingManagement
namespace LINGYUN.Abp.Aliyun.SettingManagement;
public class AliyunSettingPermissionDefinitionProvider : PermissionDefinitionProvider
{
public class AliyunSettingPermissionDefinitionProvider : PermissionDefinitionProvider
public override void Define(IPermissionDefinitionContext context)
{
public override void Define(IPermissionDefinitionContext context)
{
var wechatGroup = context.AddGroup(
AliyunSettingPermissionNames.GroupName,
L("Permission:Aliyun"));
var wechatGroup = context.AddGroup(
AliyunSettingPermissionNames.GroupName,
L("Permission:Aliyun"));
wechatGroup.AddPermission(
AliyunSettingPermissionNames.Settings, L("Permission:Aliyun.Settings"));
}
wechatGroup.AddPermission(
AliyunSettingPermissionNames.Settings, L("Permission:Aliyun.Settings"));
}
protected LocalizableString L(string name)
{
return LocalizableString.Create<AliyunResource>(name);
}
protected LocalizableString L(string name)
{
return LocalizableString.Create<AliyunResource>(name);
}
}

11
aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun.SettingManagement/LINGYUN/Abp/Aliyun/SettingManagement/AliyunSettingPermissionNames.cs

@ -1,9 +1,8 @@
namespace LINGYUN.Abp.Aliyun.SettingManagement
namespace LINGYUN.Abp.Aliyun.SettingManagement;
public class AliyunSettingPermissionNames
{
public class AliyunSettingPermissionNames
{
public const string GroupName = "Abp.Aliyun";
public const string GroupName = "Abp.Aliyun";
public const string Settings = GroupName + ".Settings";
}
public const string Settings = GroupName + ".Settings";
}

7
aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun.SettingManagement/LINGYUN/Abp/Aliyun/SettingManagement/IAliyunSettingAppService.cs

@ -1,8 +1,7 @@
using LINGYUN.Abp.SettingManagement;
namespace LINGYUN.Abp.Aliyun.SettingManagement
namespace LINGYUN.Abp.Aliyun.SettingManagement;
public interface IAliyunSettingAppService : IReadonlySettingAppService
{
public interface IAliyunSettingAppService : IReadonlySettingAppService
{
}
}

7
aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN.Abp.Aliyun.csproj

@ -4,7 +4,12 @@
<Import Project="..\..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0</TargetFrameworks>
<AssemblyName>LINGYUN.Abp.Aliyun</AssemblyName>
<PackageId>LINGYUN.Abp.Aliyun</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
<Description>阿里云SDK基础框架</Description>
</PropertyGroup>

21
aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AbpAliyunException.cs

@ -3,19 +3,18 @@ using Volo.Abp;
using Volo.Abp.ExceptionHandling;
using Volo.Abp.Logging;
namespace LINGYUN.Abp.Aliyun
namespace LINGYUN.Abp.Aliyun;
public class AbpAliyunException : AbpException, IHasErrorCode, IHasLogLevel
{
public class AbpAliyunException : AbpException, IHasErrorCode, IHasLogLevel
{
public LogLevel LogLevel { get; set; }
public LogLevel LogLevel { get; set; }
public string Code { get; }
public string Code { get; }
public AbpAliyunException(string code, string message)
: base(message)
{
Code = code;
LogLevel = LogLevel.Warning;
}
public AbpAliyunException(string code, string message)
: base(message)
{
Code = code;
LogLevel = LogLevel.Warning;
}
}

39
aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AbpAliyunModule.cs

@ -7,29 +7,28 @@ using Volo.Abp.Modularity;
using Volo.Abp.Settings;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.Aliyun
namespace LINGYUN.Abp.Aliyun;
[DependsOn(
typeof(AbpCachingModule),
typeof(AbpSettingsModule),
typeof(AbpJsonModule),
typeof(AbpLocalizationModule),
typeof(AbpFeaturesLimitValidationModule))]
public class AbpAliyunModule : AbpModule
{
[DependsOn(
typeof(AbpCachingModule),
typeof(AbpSettingsModule),
typeof(AbpJsonModule),
typeof(AbpLocalizationModule),
typeof(AbpFeaturesLimitValidationModule))]
public class AbpAliyunModule : AbpModule
public override void ConfigureServices(ServiceConfigurationContext context)
{
public override void ConfigureServices(ServiceConfigurationContext context)
Configure<AbpVirtualFileSystemOptions>(options =>
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpAliyunModule>();
});
options.FileSets.AddEmbedded<AbpAliyunModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<AliyunResource>("zh-Hans") // 中国区云服务,默认使用简体中文
.AddVirtualJson("/LINGYUN/Abp/Aliyun/Localization/Resources");
});
}
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<AliyunResource>("zh-Hans") // 中国区云服务,默认使用简体中文
.AddVirtualJson("/LINGYUN/Abp/Aliyun/Localization/Resources");
});
}
}

39
aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AcsClientFactory.cs

@ -7,29 +7,28 @@ using Volo.Abp.DependencyInjection;
using Volo.Abp.Features;
using Volo.Abp.Settings;
namespace LINGYUN.Abp.Aliyun
namespace LINGYUN.Abp.Aliyun;
[RequiresFeature(AliyunFeatureNames.Enable)]
public class AcsClientFactory : AliyunClientFactory<IAcsClient>, IAcsClientFactory, ITransientDependency
{
[RequiresFeature(AliyunFeatureNames.Enable)]
public class AcsClientFactory : AliyunClientFactory<IAcsClient>, IAcsClientFactory, ITransientDependency
public AcsClientFactory(
ISettingProvider settingProvider,
IDistributedCache<AliyunBasicSessionCredentialsCacheItem> cache)
: base(settingProvider, cache)
{
public AcsClientFactory(
ISettingProvider settingProvider,
IDistributedCache<AliyunBasicSessionCredentialsCacheItem> cache)
: base(settingProvider, cache)
{
}
}
protected override IAcsClient GetClient(string regionId, string accessKeyId, string accessKeySecret)
{
return new DefaultAcsClient(
DefaultProfile.GetProfile(regionId, accessKeyId, accessKeySecret));
}
protected override IAcsClient GetClient(string regionId, string accessKeyId, string accessKeySecret)
{
return new DefaultAcsClient(
DefaultProfile.GetProfile(regionId, accessKeyId, accessKeySecret));
}
protected override IAcsClient GetSecurityTokenClient(string regionId, string accessKeyId, string accessKeySecret, string securityToken)
{
var profile = DefaultProfile.GetProfile(regionId);
var credentials = new BasicSessionCredentials(accessKeyId, accessKeySecret, securityToken);
return new DefaultAcsClient(profile, credentials);
}
protected override IAcsClient GetSecurityTokenClient(string regionId, string accessKeyId, string accessKeySecret, string securityToken)
{
var profile = DefaultProfile.GetProfile(regionId);
var credentials = new BasicSessionCredentials(accessKeyId, accessKeySecret, securityToken);
return new DefaultAcsClient(profile, credentials);
}
}

43
aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AliyunBasicSessionCredentialsCacheItem.cs

@ -1,31 +1,30 @@
using System;
namespace LINGYUN.Abp.Aliyun
namespace LINGYUN.Abp.Aliyun;
[Serializable]
public class AliyunBasicSessionCredentialsCacheItem
{
[Serializable]
public class AliyunBasicSessionCredentialsCacheItem
{
private readonly static string _cacheKey;
public static string CacheKey => _cacheKey;
public string AccessKeyId { get; set; }
public string AccessKeySecret { get; set; }
public string SecurityToken { get; set; }
private readonly static string _cacheKey;
public static string CacheKey => _cacheKey;
public string AccessKeyId { get; set; }
public string AccessKeySecret { get; set; }
public string SecurityToken { get; set; }
static AliyunBasicSessionCredentialsCacheItem()
{
_cacheKey = Guid.NewGuid().ToString("N");
}
static AliyunBasicSessionCredentialsCacheItem()
{
_cacheKey = Guid.NewGuid().ToString("N");
}
public AliyunBasicSessionCredentialsCacheItem()
{
public AliyunBasicSessionCredentialsCacheItem()
{
}
}
public AliyunBasicSessionCredentialsCacheItem(string accessKeyId, string accessKeySecret, string securityToken)
{
AccessKeyId = accessKeyId;
AccessKeySecret = accessKeySecret;
SecurityToken = securityToken;
}
public AliyunBasicSessionCredentialsCacheItem(string accessKeyId, string accessKeySecret, string securityToken)
{
AccessKeyId = accessKeyId;
AccessKeySecret = accessKeySecret;
SecurityToken = securityToken;
}
}

271
aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/AliyunClientFactory.cs

@ -10,171 +10,170 @@ using Volo.Abp;
using Volo.Abp.Caching;
using Volo.Abp.Settings;
namespace LINGYUN.Abp.Aliyun
namespace LINGYUN.Abp.Aliyun;
/// <summary>
/// 阿里云通用客户端构建工厂
/// </summary>
/// <typeparam name="TClient"></typeparam>
public abstract class AliyunClientFactory<TClient>
{
/// <summary>
/// 阿里云通用客户端构建工厂
/// </summary>
/// <typeparam name="TClient"></typeparam>
public abstract class AliyunClientFactory<TClient>
protected ISettingProvider SettingProvider { get; }
protected IDistributedCache<AliyunBasicSessionCredentialsCacheItem> Cache { get; }
public AliyunClientFactory(
ISettingProvider settingProvider,
IDistributedCache<AliyunBasicSessionCredentialsCacheItem> cache)
{
protected ISettingProvider SettingProvider { get; }
protected IDistributedCache<AliyunBasicSessionCredentialsCacheItem> Cache { get; }
public AliyunClientFactory(
ISettingProvider settingProvider,
IDistributedCache<AliyunBasicSessionCredentialsCacheItem> cache)
{
Cache = cache;
SettingProvider = settingProvider;
}
public async virtual Task<TClient> CreateAsync()
{
var regionId = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.RegionId);
var accessKey = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.AccessKeyId);
var accessKeySecret = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.AccessKeySecret);
Cache = cache;
SettingProvider = settingProvider;
}
Check.NotNullOrWhiteSpace(regionId, AliyunSettingNames.Authorization.RegionId);
Check.NotNullOrWhiteSpace(accessKey, AliyunSettingNames.Authorization.AccessKeyId);
Check.NotNullOrWhiteSpace(accessKeySecret, AliyunSettingNames.Authorization.AccessKeySecret);
public async virtual Task<TClient> CreateAsync()
{
var regionId = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.RegionId);
var accessKey = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.AccessKeyId);
var accessKeySecret = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.AccessKeySecret);
if (await SettingProvider.IsTrueAsync(AliyunSettingNames.Authorization.UseSecurityTokenService))
{
var cacheItem = await GetCacheItemAsync(accessKey, accessKeySecret, regionId);
Check.NotNullOrWhiteSpace(regionId, AliyunSettingNames.Authorization.RegionId);
Check.NotNullOrWhiteSpace(accessKey, AliyunSettingNames.Authorization.AccessKeyId);
Check.NotNullOrWhiteSpace(accessKeySecret, AliyunSettingNames.Authorization.AccessKeySecret);
return GetSecurityTokenClient(regionId, cacheItem.AccessKeyId, cacheItem.AccessKeySecret, cacheItem.SecurityToken);
}
if (await SettingProvider.IsTrueAsync(AliyunSettingNames.Authorization.UseSecurityTokenService))
{
var cacheItem = await GetCacheItemAsync(accessKey, accessKeySecret, regionId);
return GetClient(regionId, accessKey, accessKeySecret);
return GetSecurityTokenClient(regionId, cacheItem.AccessKeyId, cacheItem.AccessKeySecret, cacheItem.SecurityToken);
}
protected abstract TClient GetClient(string regionId, string accessKeyId, string accessKeySecret);
return GetClient(regionId, accessKey, accessKeySecret);
}
protected abstract TClient GetClient(string regionId, string accessKeyId, string accessKeySecret);
protected abstract TClient GetSecurityTokenClient(string regionId, string accessKeyId, string accessKeySecret, string securityToken);
protected abstract TClient GetSecurityTokenClient(string regionId, string accessKeyId, string accessKeySecret, string securityToken);
protected async virtual Task<AliyunBasicSessionCredentialsCacheItem> GetCacheItemAsync(string accessKeyId, string accessKeySecret, string regionId)
protected async virtual Task<AliyunBasicSessionCredentialsCacheItem> GetCacheItemAsync(string accessKeyId, string accessKeySecret, string regionId)
{
var cacheItem = await Cache.GetAsync(AliyunBasicSessionCredentialsCacheItem.CacheKey);
if (cacheItem == null)
{
var cacheItem = await Cache.GetAsync(AliyunBasicSessionCredentialsCacheItem.CacheKey);
if (cacheItem == null)
{
var roleArn = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.RamRoleArn);
var roleSession = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.RoleSessionName);
Check.NotNullOrWhiteSpace(roleArn, AliyunSettingNames.Authorization.RamRoleArn);
var roleArn = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.RamRoleArn);
var roleSession = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.RoleSessionName);
Check.NotNullOrWhiteSpace(roleArn, AliyunSettingNames.Authorization.RamRoleArn);
var policy = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.Policy);
var durationSeconds = await SettingProvider.GetAsync(AliyunSettingNames.Authorization.DurationSeconds, 3000);
var policy = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.Policy);
var durationSeconds = await SettingProvider.GetAsync(AliyunSettingNames.Authorization.DurationSeconds, 3000);
var profile = DefaultProfile.GetProfile(regionId, accessKeyId, accessKeySecret);
var request = new AssumeRoleRequest
var profile = DefaultProfile.GetProfile(regionId, accessKeyId, accessKeySecret);
var request = new AssumeRoleRequest
{
AcceptFormat = FormatType.JSON,
RoleArn = roleArn,
RoleSessionName = roleSession,
DurationSeconds = durationSeconds,
Policy = policy.IsNullOrWhiteSpace() ? null : policy
};
var client = new DefaultAcsClient(profile);
var response = client.GetAcsResponse(request);
cacheItem = new AliyunBasicSessionCredentialsCacheItem(
response.Credentials.AccessKeyId,
response.Credentials.AccessKeySecret,
response.Credentials.SecurityToken);
await Cache.SetAsync(
AliyunBasicSessionCredentialsCacheItem.CacheKey,
cacheItem,
new DistributedCacheEntryOptions
{
AcceptFormat = FormatType.JSON,
RoleArn = roleArn,
RoleSessionName = roleSession,
DurationSeconds = durationSeconds,
Policy = policy.IsNullOrWhiteSpace() ? null : policy
};
var client = new DefaultAcsClient(profile);
var response = client.GetAcsResponse(request);
cacheItem = new AliyunBasicSessionCredentialsCacheItem(
response.Credentials.AccessKeyId,
response.Credentials.AccessKeySecret,
response.Credentials.SecurityToken);
await Cache.SetAsync(
AliyunBasicSessionCredentialsCacheItem.CacheKey,
cacheItem,
new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(durationSeconds - 10)
});
}
return cacheItem;
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(durationSeconds - 10)
});
}
return cacheItem;
}
/// <summary>
/// 阿里云通用客户端构建工厂
/// </summary>
/// <typeparam name="TClient">客户端类型</typeparam>
/// <typeparam name="TConfiguration">客户端参数类型</typeparam>
public abstract class AliyunClientFactory<TClient, TConfiguration>
}
/// <summary>
/// 阿里云通用客户端构建工厂
/// </summary>
/// <typeparam name="TClient">客户端类型</typeparam>
/// <typeparam name="TConfiguration">客户端参数类型</typeparam>
public abstract class AliyunClientFactory<TClient, TConfiguration>
{
protected ISettingProvider SettingProvider { get; }
protected IDistributedCache<AliyunBasicSessionCredentialsCacheItem> Cache { get; }
public AliyunClientFactory(
ISettingProvider settingProvider,
IDistributedCache<AliyunBasicSessionCredentialsCacheItem> cache)
{
protected ISettingProvider SettingProvider { get; }
protected IDistributedCache<AliyunBasicSessionCredentialsCacheItem> Cache { get; }
public AliyunClientFactory(
ISettingProvider settingProvider,
IDistributedCache<AliyunBasicSessionCredentialsCacheItem> cache)
{
Cache = cache;
SettingProvider = settingProvider;
}
public async virtual Task<TClient> CreateAsync(TConfiguration configuration)
{
var regionId = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.RegionId);
var accessKey = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.AccessKeyId);
var accessKeySecret = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.AccessKeySecret);
Cache = cache;
SettingProvider = settingProvider;
}
Check.NotNullOrWhiteSpace(regionId, AliyunSettingNames.Authorization.RegionId);
Check.NotNullOrWhiteSpace(accessKey, AliyunSettingNames.Authorization.AccessKeyId);
Check.NotNullOrWhiteSpace(accessKeySecret, AliyunSettingNames.Authorization.AccessKeySecret);
public async virtual Task<TClient> CreateAsync(TConfiguration configuration)
{
var regionId = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.RegionId);
var accessKey = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.AccessKeyId);
var accessKeySecret = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.AccessKeySecret);
if (await SettingProvider.IsTrueAsync(AliyunSettingNames.Authorization.UseSecurityTokenService))
{
var cacheItem = await GetCacheItemAsync(accessKey, accessKeySecret, regionId);
Check.NotNullOrWhiteSpace(regionId, AliyunSettingNames.Authorization.RegionId);
Check.NotNullOrWhiteSpace(accessKey, AliyunSettingNames.Authorization.AccessKeyId);
Check.NotNullOrWhiteSpace(accessKeySecret, AliyunSettingNames.Authorization.AccessKeySecret);
return GetSecurityTokenClient(configuration, regionId, cacheItem.AccessKeyId, cacheItem.AccessKeySecret, cacheItem.SecurityToken);
}
if (await SettingProvider.IsTrueAsync(AliyunSettingNames.Authorization.UseSecurityTokenService))
{
var cacheItem = await GetCacheItemAsync(accessKey, accessKeySecret, regionId);
return GetClient(configuration, regionId, accessKey, accessKeySecret);
return GetSecurityTokenClient(configuration, regionId, cacheItem.AccessKeyId, cacheItem.AccessKeySecret, cacheItem.SecurityToken);
}
protected abstract TClient GetClient(TConfiguration configuration, string regionId, string accessKeyId, string accessKeySecret);
return GetClient(configuration, regionId, accessKey, accessKeySecret);
}
protected abstract TClient GetClient(TConfiguration configuration, string regionId, string accessKeyId, string accessKeySecret);
protected abstract TClient GetSecurityTokenClient(TConfiguration configuration, string regionId, string accessKeyId, string accessKeySecret, string securityToken);
protected abstract TClient GetSecurityTokenClient(TConfiguration configuration, string regionId, string accessKeyId, string accessKeySecret, string securityToken);
protected async virtual Task<AliyunBasicSessionCredentialsCacheItem> GetCacheItemAsync(string accessKeyId, string accessKeySecret, string regionId)
protected async virtual Task<AliyunBasicSessionCredentialsCacheItem> GetCacheItemAsync(string accessKeyId, string accessKeySecret, string regionId)
{
var cacheItem = await Cache.GetAsync(AliyunBasicSessionCredentialsCacheItem.CacheKey);
if (cacheItem == null)
{
var cacheItem = await Cache.GetAsync(AliyunBasicSessionCredentialsCacheItem.CacheKey);
if (cacheItem == null)
{
var roleArn = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.RamRoleArn);
var roleSession = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.RoleSessionName);
Check.NotNullOrWhiteSpace(roleArn, AliyunSettingNames.Authorization.RamRoleArn);
var roleArn = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.RamRoleArn);
var roleSession = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.RoleSessionName);
Check.NotNullOrWhiteSpace(roleArn, AliyunSettingNames.Authorization.RamRoleArn);
var policy = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.Policy);
var durationSeconds = await SettingProvider.GetAsync(AliyunSettingNames.Authorization.DurationSeconds, 3000);
var policy = await SettingProvider.GetOrNullAsync(AliyunSettingNames.Authorization.Policy);
var durationSeconds = await SettingProvider.GetAsync(AliyunSettingNames.Authorization.DurationSeconds, 3000);
var profile = DefaultProfile.GetProfile(regionId, accessKeyId, accessKeySecret);
var request = new AssumeRoleRequest
var profile = DefaultProfile.GetProfile(regionId, accessKeyId, accessKeySecret);
var request = new AssumeRoleRequest
{
AcceptFormat = FormatType.JSON,
RoleArn = roleArn,
RoleSessionName = roleSession,
DurationSeconds = durationSeconds,
Policy = policy.IsNullOrWhiteSpace() ? null : policy
};
var client = new DefaultAcsClient(profile);
var response = client.GetAcsResponse(request);
cacheItem = new AliyunBasicSessionCredentialsCacheItem(
response.Credentials.AccessKeyId,
response.Credentials.AccessKeySecret,
response.Credentials.SecurityToken);
await Cache.SetAsync(
AliyunBasicSessionCredentialsCacheItem.CacheKey,
cacheItem,
new DistributedCacheEntryOptions
{
AcceptFormat = FormatType.JSON,
RoleArn = roleArn,
RoleSessionName = roleSession,
DurationSeconds = durationSeconds,
Policy = policy.IsNullOrWhiteSpace() ? null : policy
};
var client = new DefaultAcsClient(profile);
var response = client.GetAcsResponse(request);
cacheItem = new AliyunBasicSessionCredentialsCacheItem(
response.Credentials.AccessKeyId,
response.Credentials.AccessKeySecret,
response.Credentials.SecurityToken);
await Cache.SetAsync(
AliyunBasicSessionCredentialsCacheItem.CacheKey,
cacheItem,
new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(durationSeconds - 10)
});
}
return cacheItem;
AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(durationSeconds - 10)
});
}
return cacheItem;
}
}

19
aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/IAcsClientFactory.cs

@ -1,15 +1,14 @@
using Aliyun.Acs.Core;
using System.Threading.Tasks;
namespace LINGYUN.Abp.Aliyun
namespace LINGYUN.Abp.Aliyun;
public interface IAcsClientFactory
{
public interface IAcsClientFactory
{
/// <summary>
/// 构造一个通用的Acs客户端调用
/// 通过CommonRequest调用可以不需要集成其他SDK包
/// </summary>
/// <returns></returns>
Task<IAcsClient> CreateAsync();
}
/// <summary>
/// 构造一个通用的Acs客户端调用
/// 通过CommonRequest调用可以不需要集成其他SDK包
/// </summary>
/// <returns></returns>
Task<IAcsClient> CreateAsync();
}

9
aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/Localization/AliyunResource.cs

@ -1,9 +1,8 @@
using Volo.Abp.Localization;
namespace LINGYUN.Abp.Aliyun.Localization
namespace LINGYUN.Abp.Aliyun.Localization;
[LocalizationResourceName("Aliyun")]
public class AliyunResource
{
[LocalizationResourceName("Aliyun")]
public class AliyunResource
{
}
}

147
aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/Settings/AliyunSettingNames.cs

@ -1,83 +1,82 @@
namespace LINGYUN.Abp.Aliyun.Settings
namespace LINGYUN.Abp.Aliyun.Settings;
public static class AliyunSettingNames
{
public static class AliyunSettingNames
{
public const string Prefix = "Abp.Aliyun";
public const string Prefix = "Abp.Aliyun";
/// <summary>
/// 认证方式
/// </summary>
public class Authorization
{
public const string Prefix = AliyunSettingNames.Prefix + ".Authorization";
/// <summary>
/// 地域ID
/// </summary>
public const string RegionId = Prefix + ".RegionId";
/// <summary>
/// RAM账号的AccessKey ID
/// </summary>
public const string AccessKeyId = Prefix + ".AccessKeyId";
/// <summary>
/// RAM账号的AccessKey Secret
/// </summary>
public const string AccessKeySecret = Prefix + ".AccessKeySecret";
/// <summary>
/// 使用STS Token访问
/// </summary>
public const string UseSecurityTokenService = Prefix + ".UseSecurityTokenService";
/// <summary>
/// 使用RAM子账号的AssumeRole方式访问
/// </summary>
public const string RamRoleArn = Prefix + ".RamRoleArn";
/// <summary>
/// 用户自定义参数。此参数用来区分不同的令牌,可用于用户级别的访问审计
/// </summary>
public const string RoleSessionName = Prefix + ".RoleSessionName";
/// <summary>
/// 认证方式
/// 过期时间,单位为秒。
/// </summary>
public class Authorization
{
public const string Prefix = AliyunSettingNames.Prefix + ".Authorization";
/// <summary>
/// 地域ID
/// </summary>
public const string RegionId = Prefix + ".RegionId";
/// <summary>
/// RAM账号的AccessKey ID
/// </summary>
public const string AccessKeyId = Prefix + ".AccessKeyId";
/// <summary>
/// RAM账号的AccessKey Secret
/// </summary>
public const string AccessKeySecret = Prefix + ".AccessKeySecret";
/// <summary>
/// 使用STS Token访问
/// </summary>
public const string UseSecurityTokenService = Prefix + ".UseSecurityTokenService";
/// <summary>
/// 使用RAM子账号的AssumeRole方式访问
/// </summary>
public const string RamRoleArn = Prefix + ".RamRoleArn";
/// <summary>
/// 用户自定义参数。此参数用来区分不同的令牌,可用于用户级别的访问审计
/// </summary>
public const string RoleSessionName = Prefix + ".RoleSessionName";
/// <summary>
/// 过期时间,单位为秒。
/// </summary>
public const string DurationSeconds = Prefix + ".DurationSeconds";
/// <summary>
/// 权限策略。
/// </summary>
public const string Policy = Prefix + ".Policy";
}
public const string DurationSeconds = Prefix + ".DurationSeconds";
/// <summary>
/// 权限策略。
/// </summary>
public const string Policy = Prefix + ".Policy";
}
/// <summary>
/// 短信服务
/// </summary>
public class Sms
{
public const string Prefix = AliyunSettingNames.Prefix + ".Sms";
/// <summary>
/// 阿里云sms服务域名
/// </summary>
public const string Domain = Prefix + ".Domain";
/// <summary>
/// 调用方法名称
/// </summary>
public const string ActionName = Prefix + ".ActionName";
/// <summary>
/// 默认版本号
/// </summary>
public const string Version = Prefix + ".Version";
/// <summary>
/// 默认签名
/// </summary>
public const string DefaultSignName = Prefix + ".DefaultSignName";
/// <summary>
/// 默认短信模板号
/// </summary>
public const string DefaultTemplateCode = Prefix + ".DefaultTemplateCode";
/// <summary>
/// 默认号码
/// </summary>
public const string DefaultPhoneNumber = Prefix + ".DefaultPhoneNumber";
/// <summary>
/// 短信服务
/// 展示错误给客户端
/// </summary>
public class Sms
{
public const string Prefix = AliyunSettingNames.Prefix + ".Sms";
/// <summary>
/// 阿里云sms服务域名
/// </summary>
public const string Domain = Prefix + ".Domain";
/// <summary>
/// 调用方法名称
/// </summary>
public const string ActionName = Prefix + ".ActionName";
/// <summary>
/// 默认版本号
/// </summary>
public const string Version = Prefix + ".Version";
/// <summary>
/// 默认签名
/// </summary>
public const string DefaultSignName = Prefix + ".DefaultSignName";
/// <summary>
/// 默认短信模板号
/// </summary>
public const string DefaultTemplateCode = Prefix + ".DefaultTemplateCode";
/// <summary>
/// 默认号码
/// </summary>
public const string DefaultPhoneNumber = Prefix + ".DefaultPhoneNumber";
/// <summary>
/// 展示错误给客户端
/// </summary>
public const string VisableErrorToClient = Prefix + ".VisableErrorToClient";
}
public const string VisableErrorToClient = Prefix + ".VisableErrorToClient";
}
}

399
aspnet-core/framework/cloud-aliyun/LINGYUN.Abp.Aliyun/LINGYUN/Abp/Aliyun/Settings/AliyunSettingProvider.cs

@ -2,211 +2,210 @@
using Volo.Abp.Localization;
using Volo.Abp.Settings;
namespace LINGYUN.Abp.Aliyun.Settings
namespace LINGYUN.Abp.Aliyun.Settings;
public class AliyunSettingProvider : SettingDefinitionProvider
{
public class AliyunSettingProvider : SettingDefinitionProvider
public override void Define(ISettingDefinitionContext context)
{
public override void Define(ISettingDefinitionContext context)
{
context.Add(GetAuthorizationSettings());
context.Add(GetSmsSettings());
}
context.Add(GetAuthorizationSettings());
context.Add(GetSmsSettings());
}
private SettingDefinition[] GetAuthorizationSettings()
private SettingDefinition[] GetAuthorizationSettings()
{
return new SettingDefinition[]
{
return new SettingDefinition[]
{
new SettingDefinition(
AliyunSettingNames.Authorization.AccessKeyId,
displayName: L("DisplayName:AccessKeyId"),
description: L("Description:AccessKeyId"),
isVisibleToClients: false,
isEncrypted: true
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Authorization.AccessKeySecret,
displayName: L("DisplayName:AccessKeySecret"),
description: L("Description:AccessKeySecret"),
isVisibleToClients: false,
isEncrypted: true
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Authorization.DurationSeconds,
defaultValue: "3600",
displayName: L("DisplayName:DurationSeconds"),
description: L("Description:DurationSeconds"),
isVisibleToClients: false
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Authorization.Policy,
displayName: L("DisplayName:Policy"),
description: L("Description:Policy"),
isVisibleToClients: false,
isEncrypted: true
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Authorization.RamRoleArn,
displayName: L("DisplayName:RamRoleArn"),
description: L("Description:RamRoleArn"),
isVisibleToClients: false,
isEncrypted: true
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Authorization.RegionId,
defaultValue: "oss-cn-hangzhou",
displayName: L("DisplayName:RegionId"),
description: L("Description:RegionId"),
isVisibleToClients: false
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Authorization.RoleSessionName,
displayName: L("DisplayName:RoleSessionName"),
description: L("Description:RoleSessionName"),
isVisibleToClients: false,
isEncrypted: true
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Authorization.UseSecurityTokenService,
defaultValue: true.ToString(),
displayName: L("DisplayName:UseSecurityTokenService"),
description: L("Description:UseSecurityTokenService"),
isVisibleToClients: false
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
};
}
new SettingDefinition(
AliyunSettingNames.Authorization.AccessKeyId,
displayName: L("DisplayName:AccessKeyId"),
description: L("Description:AccessKeyId"),
isVisibleToClients: false,
isEncrypted: true
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Authorization.AccessKeySecret,
displayName: L("DisplayName:AccessKeySecret"),
description: L("Description:AccessKeySecret"),
isVisibleToClients: false,
isEncrypted: true
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Authorization.DurationSeconds,
defaultValue: "3600",
displayName: L("DisplayName:DurationSeconds"),
description: L("Description:DurationSeconds"),
isVisibleToClients: false
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Authorization.Policy,
displayName: L("DisplayName:Policy"),
description: L("Description:Policy"),
isVisibleToClients: false,
isEncrypted: true
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Authorization.RamRoleArn,
displayName: L("DisplayName:RamRoleArn"),
description: L("Description:RamRoleArn"),
isVisibleToClients: false,
isEncrypted: true
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Authorization.RegionId,
defaultValue: "oss-cn-hangzhou",
displayName: L("DisplayName:RegionId"),
description: L("Description:RegionId"),
isVisibleToClients: false
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Authorization.RoleSessionName,
displayName: L("DisplayName:RoleSessionName"),
description: L("Description:RoleSessionName"),
isVisibleToClients: false,
isEncrypted: true
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Authorization.UseSecurityTokenService,
defaultValue: true.ToString(),
displayName: L("DisplayName:UseSecurityTokenService"),
description: L("Description:UseSecurityTokenService"),
isVisibleToClients: false
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
};
}
private SettingDefinition[] GetSmsSettings()
{
return new SettingDefinition[]
{
new SettingDefinition(
AliyunSettingNames.Sms.ActionName,
defaultValue: "SendSms",
displayName: L("DisplayName:ActionName"),
description: L("Description:ActionName"),
isVisibleToClients: false
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Sms.DefaultSignName,
displayName: L("DisplayName:DefaultSignName"),
description: L("Description:DefaultSignName"),
isVisibleToClients: false,
isEncrypted: true
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Sms.DefaultTemplateCode,
displayName: L("DisplayName:DefaultTemplateCode"),
description: L("Description:DefaultTemplateCode"),
isVisibleToClients: false,
isEncrypted: true
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Sms.DefaultPhoneNumber,
displayName: L("DisplayName:DefaultPhoneNumber"),
description: L("Description:DefaultPhoneNumber"),
isVisibleToClients: false
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Sms.Domain,
defaultValue: "dysmsapi.aliyuncs.com",
displayName: L("DisplayName:Domain"),
description: L("Description:Domain"),
isVisibleToClients: false
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Sms.Version,
defaultValue: "2017-05-25",
displayName: L("DisplayName:Version"),
description: L("Description:Version"),
isVisibleToClients: false
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Sms.VisableErrorToClient,
defaultValue: false.ToString(),
displayName: L("DisplayName:VisableErrorToClient"),
description: L("Description:VisableErrorToClient"),
isVisibleToClients: false
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName)
};
}
private ILocalizableString L(string name)
private SettingDefinition[] GetSmsSettings()
{
return new SettingDefinition[]
{
return LocalizableString.Create<AliyunResource>(name);
}
new SettingDefinition(
AliyunSettingNames.Sms.ActionName,
defaultValue: "SendSms",
displayName: L("DisplayName:ActionName"),
description: L("Description:ActionName"),
isVisibleToClients: false
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Sms.DefaultSignName,
displayName: L("DisplayName:DefaultSignName"),
description: L("Description:DefaultSignName"),
isVisibleToClients: false,
isEncrypted: true
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Sms.DefaultTemplateCode,
displayName: L("DisplayName:DefaultTemplateCode"),
description: L("Description:DefaultTemplateCode"),
isVisibleToClients: false,
isEncrypted: true
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Sms.DefaultPhoneNumber,
displayName: L("DisplayName:DefaultPhoneNumber"),
description: L("Description:DefaultPhoneNumber"),
isVisibleToClients: false
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Sms.Domain,
defaultValue: "dysmsapi.aliyuncs.com",
displayName: L("DisplayName:Domain"),
description: L("Description:Domain"),
isVisibleToClients: false
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Sms.Version,
defaultValue: "2017-05-25",
displayName: L("DisplayName:Version"),
description: L("Description:Version"),
isVisibleToClients: false
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
new SettingDefinition(
AliyunSettingNames.Sms.VisableErrorToClient,
defaultValue: false.ToString(),
displayName: L("DisplayName:VisableErrorToClient"),
description: L("Description:VisableErrorToClient"),
isVisibleToClients: false
)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName)
};
}
private ILocalizableString L(string name)
{
return LocalizableString.Create<AliyunResource>(name);
}
}

7
aspnet-core/framework/cloud-tencent/LINGYUN.Abp.BlobStoring.Tencent/LINGYUN.Abp.BlobStoring.Tencent.csproj

@ -4,7 +4,12 @@
<Import Project="..\..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0</TargetFrameworks>
<AssemblyName>LINGYUN.Abp.BlobStoring.Tencent</AssemblyName>
<PackageId>LINGYUN.Abp.BlobStoring.Tencent</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<RootNamespace />
<Description>腾讯云Oss对象存储Abp集成</Description>
</PropertyGroup>

29
aspnet-core/framework/cloud-tencent/LINGYUN.Abp.BlobStoring.Tencent/LINGYUN/Abp/BlobStoring/Tencent/DefaultTencentBlobNameCalculator.cs

@ -2,23 +2,22 @@
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
namespace LINGYUN.Abp.BlobStoring.Tencent
namespace LINGYUN.Abp.BlobStoring.Tencent;
public class DefaultTencentBlobNameCalculator : ITencentBlobNameCalculator, ITransientDependency
{
public class DefaultTencentBlobNameCalculator : ITencentBlobNameCalculator, ITransientDependency
{
protected ICurrentTenant CurrentTenant { get; }
protected ICurrentTenant CurrentTenant { get; }
public DefaultTencentBlobNameCalculator(
ICurrentTenant currentTenant)
{
CurrentTenant = currentTenant;
}
public DefaultTencentBlobNameCalculator(
ICurrentTenant currentTenant)
{
CurrentTenant = currentTenant;
}
public string Calculate(BlobProviderArgs args)
{
return CurrentTenant.Id == null
? $"host/{args.BlobName}"
: $"tenants/{CurrentTenant.Id.Value:D}/{args.BlobName}";
}
public string Calculate(BlobProviderArgs args)
{
return CurrentTenant.Id == null
? $"host/{args.BlobName}"
: $"tenants/{CurrentTenant.Id.Value:D}/{args.BlobName}";
}
}

9
aspnet-core/framework/cloud-tencent/LINGYUN.Abp.BlobStoring.Tencent/LINGYUN/Abp/BlobStoring/Tencent/ITencentBlobNameCalculator.cs

@ -1,9 +1,8 @@
using Volo.Abp.BlobStoring;
namespace LINGYUN.Abp.BlobStoring.Tencent
namespace LINGYUN.Abp.BlobStoring.Tencent;
public interface ITencentBlobNameCalculator
{
public interface ITencentBlobNameCalculator
{
string Calculate(BlobProviderArgs args);
}
string Calculate(BlobProviderArgs args);
}

29
aspnet-core/framework/cloud-tencent/LINGYUN.Abp.BlobStoring.Tencent/LINGYUN/Abp/BlobStoring/Tencent/TencentBlobContainerConfigurationExtensions.cs

@ -1,25 +1,24 @@
using System;
using Volo.Abp.BlobStoring;
namespace LINGYUN.Abp.BlobStoring.Tencent
namespace LINGYUN.Abp.BlobStoring.Tencent;
public static class TencentBlobContainerConfigurationExtensions
{
public static class TencentBlobContainerConfigurationExtensions
public static TencentBlobProviderConfiguration GetTencentConfiguration(
this BlobContainerConfiguration containerConfiguration)
{
public static TencentBlobProviderConfiguration GetTencentConfiguration(
this BlobContainerConfiguration containerConfiguration)
{
return new TencentBlobProviderConfiguration(containerConfiguration);
}
return new TencentBlobProviderConfiguration(containerConfiguration);
}
public static BlobContainerConfiguration UseTencentCloud(
this BlobContainerConfiguration containerConfiguration,
Action<TencentBlobProviderConfiguration> aliyunConfigureAction)
{
containerConfiguration.ProviderType = typeof(TencentCloudBlobProvider);
public static BlobContainerConfiguration UseTencentCloud(
this BlobContainerConfiguration containerConfiguration,
Action<TencentBlobProviderConfiguration> aliyunConfigureAction)
{
containerConfiguration.ProviderType = typeof(TencentCloudBlobProvider);
aliyunConfigureAction(new TencentBlobProviderConfiguration(containerConfiguration));
aliyunConfigureAction(new TencentBlobProviderConfiguration(containerConfiguration));
return containerConfiguration;
}
return containerConfiguration;
}
}

99
aspnet-core/framework/cloud-tencent/LINGYUN.Abp.BlobStoring.Tencent/LINGYUN/Abp/BlobStoring/Tencent/TencentBlobNamingNormalizer.cs

@ -2,60 +2,59 @@
using Volo.Abp.BlobStoring;
using Volo.Abp.DependencyInjection;
namespace LINGYUN.Abp.BlobStoring.Tencent
namespace LINGYUN.Abp.BlobStoring.Tencent;
public class TencentBlobNamingNormalizer : IBlobNamingNormalizer, ITransientDependency
{
public class TencentBlobNamingNormalizer : IBlobNamingNormalizer, ITransientDependency
/// <summary>
/// 腾讯云对象命名规范
/// https://cloud.tencent.com/document/product/436/13324
/// </summary>
/// <param name="blobName"></param>
/// <returns></returns>
public virtual string NormalizeBlobName(string blobName)
{
/// <summary>
/// 腾讯云对象命名规范
/// https://cloud.tencent.com/document/product/436/13324
/// </summary>
/// <param name="blobName"></param>
/// <returns></returns>
public virtual string NormalizeBlobName(string blobName)
{
// 不允许以正斜线/或者反斜线\开头。
blobName = Regex.Replace(blobName, "^/", string.Empty);
blobName = blobName.StartsWith("\\") ? blobName.Substring(1) : blobName;
// 对象键中不支持 ASCII 控制字符中的
// 字符上(↑),字符下(↓),字符右(→),字符左(←),
// 分别对应 CAN(24),EM(25),SUB(26),ESC(27)。
blobName = blobName.Replace("↑", "");
blobName = blobName.Replace("↓", "");
blobName = blobName.Replace("←", "");
blobName = blobName.Replace("→", "");
// TODO: 要求还真多...其他暂时不写了
return blobName;
}
// 不允许以正斜线/或者反斜线\开头。
blobName = Regex.Replace(blobName, "^/", string.Empty);
blobName = blobName.StartsWith("\\") ? blobName.Substring(1) : blobName;
// 对象键中不支持 ASCII 控制字符中的
// 字符上(↑),字符下(↓),字符右(→),字符左(←),
// 分别对应 CAN(24),EM(25),SUB(26),ESC(27)。
blobName = blobName.Replace("↑", "");
blobName = blobName.Replace("↓", "");
blobName = blobName.Replace("←", "");
blobName = blobName.Replace("→", "");
// TODO: 要求还真多...其他暂时不写了
return blobName;
}
/// <summary>
/// 腾讯云BucketName命名规范
/// https://cloud.tencent.com/document/product/436/13312
/// </summary>
/// <param name="containerName"></param>
/// <returns></returns>
public virtual string NormalizeContainerName(string containerName)
{
// 仅支持小写英文字母和数字,即[a-z,0-9]、中划线“-”及其组合。
containerName = containerName.ToLower();
containerName = Regex.Replace(containerName, "[^a-z0-9-]", string.Empty);
/// <summary>
/// 腾讯云BucketName命名规范
/// https://cloud.tencent.com/document/product/436/13312
/// </summary>
/// <param name="containerName"></param>
/// <returns></returns>
public virtual string NormalizeContainerName(string containerName)
// 不能以短划线(-)开头
containerName = Regex.Replace(containerName, "^-", string.Empty);
// 不能以短划线(-)结尾
containerName = Regex.Replace(containerName, "-$", string.Empty);
// 存储桶名称的最大允许字符受到 地域简称 和 APPID 的字符数影响,组成的完整请求域名字符数总计最多60个字符。
// 例如请求域名123456789012345678901-1250000000.cos.ap-beijing.myqcloud.com总和为60个字符。
if (containerName.Length > 60)
{
// 仅支持小写英文字母和数字,即[a-z,0-9]、中划线“-”及其组合。
containerName = containerName.ToLower();
containerName = Regex.Replace(containerName, "[^a-z0-9-]", string.Empty);
// 不能以短划线(-)开头
containerName = Regex.Replace(containerName, "^-", string.Empty);
// 不能以短划线(-)结尾
containerName = Regex.Replace(containerName, "-$", string.Empty);
// 存储桶名称的最大允许字符受到 地域简称 和 APPID 的字符数影响,组成的完整请求域名字符数总计最多60个字符。
// 例如请求域名123456789012345678901-1250000000.cos.ap-beijing.myqcloud.com总和为60个字符。
if (containerName.Length > 60)
{
containerName = containerName.Substring(0, 60);
}
return containerName;
containerName = containerName.Substring(0, 60);
}
return containerName;
}
}

101
aspnet-core/framework/cloud-tencent/LINGYUN.Abp.BlobStoring.Tencent/LINGYUN/Abp/BlobStoring/Tencent/TencentBlobProviderConfiguration.cs

@ -2,62 +2,61 @@
using Volo.Abp;
using Volo.Abp.BlobStoring;
namespace LINGYUN.Abp.BlobStoring.Tencent
namespace LINGYUN.Abp.BlobStoring.Tencent;
public class TencentBlobProviderConfiguration
{
public class TencentBlobProviderConfiguration
/// <summary>
/// AppId
/// </summary>
public string AppId {
get => _containerConfiguration.GetConfiguration<string>(TencentBlobProviderConfigurationNames.AppId);
set => _containerConfiguration.SetConfiguration(TencentBlobProviderConfigurationNames.AppId, Check.NotNullOrWhiteSpace(value, nameof(value)));
}
/// <summary>
/// 区域
/// </summary>
public string Region {
get => _containerConfiguration.GetConfiguration<string>(TencentBlobProviderConfigurationNames.Region);
set => _containerConfiguration.SetConfiguration(TencentBlobProviderConfigurationNames.Region, value);
}
/// <summary>
/// 命名空间
/// </summary>
public string BucketName
{
/// <summary>
/// AppId
/// </summary>
public string AppId {
get => _containerConfiguration.GetConfiguration<string>(TencentBlobProviderConfigurationNames.AppId);
set => _containerConfiguration.SetConfiguration(TencentBlobProviderConfigurationNames.AppId, Check.NotNullOrWhiteSpace(value, nameof(value)));
}
/// <summary>
/// 区域
/// </summary>
public string Region {
get => _containerConfiguration.GetConfiguration<string>(TencentBlobProviderConfigurationNames.Region);
set => _containerConfiguration.SetConfiguration(TencentBlobProviderConfigurationNames.Region, value);
}
/// <summary>
/// 命名空间
/// </summary>
public string BucketName
{
get => _containerConfiguration.GetConfiguration<string>(TencentBlobProviderConfigurationNames.BucketName);
set => _containerConfiguration.SetConfiguration(TencentBlobProviderConfigurationNames.BucketName, Check.NotNullOrWhiteSpace(value, nameof(value)));
}
/// <summary>
/// 命名空间不存在是否创建
/// </summary>
public bool CreateBucketIfNotExists
{
get => _containerConfiguration.GetConfigurationOrDefault(TencentBlobProviderConfigurationNames.CreateBucketIfNotExists, false);
set => _containerConfiguration.SetConfiguration(TencentBlobProviderConfigurationNames.CreateBucketIfNotExists, value);
}
/// <summary>
/// 创建命名空间时防盗链列表
/// </summary>
public List<string> CreateBucketReferer {
get => _containerConfiguration.GetConfiguration<List<string>>(TencentBlobProviderConfigurationNames.CreateBucketReferer);
set {
if (value == null)
{
_containerConfiguration.SetConfiguration(TencentBlobProviderConfigurationNames.CreateBucketReferer, new List<string>());
}
else
{
_containerConfiguration.SetConfiguration(TencentBlobProviderConfigurationNames.CreateBucketReferer, value);
}
get => _containerConfiguration.GetConfiguration<string>(TencentBlobProviderConfigurationNames.BucketName);
set => _containerConfiguration.SetConfiguration(TencentBlobProviderConfigurationNames.BucketName, Check.NotNullOrWhiteSpace(value, nameof(value)));
}
/// <summary>
/// 命名空间不存在是否创建
/// </summary>
public bool CreateBucketIfNotExists
{
get => _containerConfiguration.GetConfigurationOrDefault(TencentBlobProviderConfigurationNames.CreateBucketIfNotExists, false);
set => _containerConfiguration.SetConfiguration(TencentBlobProviderConfigurationNames.CreateBucketIfNotExists, value);
}
/// <summary>
/// 创建命名空间时防盗链列表
/// </summary>
public List<string> CreateBucketReferer {
get => _containerConfiguration.GetConfiguration<List<string>>(TencentBlobProviderConfigurationNames.CreateBucketReferer);
set {
if (value == null)
{
_containerConfiguration.SetConfiguration(TencentBlobProviderConfigurationNames.CreateBucketReferer, new List<string>());
}
else
{
_containerConfiguration.SetConfiguration(TencentBlobProviderConfigurationNames.CreateBucketReferer, value);
}
}
}
private readonly BlobContainerConfiguration _containerConfiguration;
private readonly BlobContainerConfiguration _containerConfiguration;
public TencentBlobProviderConfiguration(BlobContainerConfiguration containerConfiguration)
{
_containerConfiguration = containerConfiguration;
}
public TencentBlobProviderConfiguration(BlobContainerConfiguration containerConfiguration)
{
_containerConfiguration = containerConfiguration;
}
}

47
aspnet-core/framework/cloud-tencent/LINGYUN.Abp.BlobStoring.Tencent/LINGYUN/Abp/BlobStoring/Tencent/TencentBlobProviderConfigurationNames.cs

@ -1,26 +1,25 @@
namespace LINGYUN.Abp.BlobStoring.Tencent
namespace LINGYUN.Abp.BlobStoring.Tencent;
public static class TencentBlobProviderConfigurationNames
{
public static class TencentBlobProviderConfigurationNames
{
/// <summary>
/// AppId
/// </summary>
public const string AppId = "Tencent:OSS:AppId";
/// <summary>
/// 区域
/// </summary>
public const string Region = "Tencent:OSS:Region";
/// <summary>
/// 命名空间
/// </summary>
public const string BucketName = "Tencent:OSS:BucketName";
/// <summary>
/// 命名空间不存在是否创建
/// </summary>
public const string CreateBucketIfNotExists = "Tencent:OSS:CreateBucketIfNotExists";
/// <summary>
/// 创建命名空间时防盗链列表
/// </summary>
public const string CreateBucketReferer = "Tencent:OSS:CreateBucketReferer";
}
/// <summary>
/// AppId
/// </summary>
public const string AppId = "Tencent:OSS:AppId";
/// <summary>
/// 区域
/// </summary>
public const string Region = "Tencent:OSS:Region";
/// <summary>
/// 命名空间
/// </summary>
public const string BucketName = "Tencent:OSS:BucketName";
/// <summary>
/// 命名空间不存在是否创建
/// </summary>
public const string CreateBucketIfNotExists = "Tencent:OSS:CreateBucketIfNotExists";
/// <summary>
/// 创建命名空间时防盗链列表
/// </summary>
public const string CreateBucketReferer = "Tencent:OSS:CreateBucketReferer";
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save