mirror of https://github.com/abpframework/abp.git
486 changed files with 68715 additions and 21303 deletions
@ -0,0 +1,25 @@ |
|||
using JetBrains.Annotations; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
|
|||
namespace Volo.Abp.Authorization |
|||
{ |
|||
public class PermissionsRequirement : IAuthorizationRequirement |
|||
{ |
|||
public string[] PermissionNames { get; } |
|||
|
|||
public bool RequiresAll { get; } |
|||
|
|||
public PermissionsRequirement([NotNull]string[] permissionNames, bool requiresAll) |
|||
{ |
|||
Check.NotNull(permissionNames, nameof(permissionNames)); |
|||
|
|||
PermissionNames = permissionNames; |
|||
RequiresAll = requiresAll; |
|||
} |
|||
|
|||
public override string ToString() |
|||
{ |
|||
return $"PermissionsRequirement: {string.Join(", ", PermissionNames)}"; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Volo.Abp.Authorization.Permissions; |
|||
|
|||
namespace Volo.Abp.Authorization |
|||
{ |
|||
public class PermissionsRequirementHandler : AuthorizationHandler<PermissionsRequirement> |
|||
{ |
|||
private readonly IPermissionChecker _permissionChecker; |
|||
|
|||
public PermissionsRequirementHandler(IPermissionChecker permissionChecker) |
|||
{ |
|||
_permissionChecker = permissionChecker; |
|||
} |
|||
|
|||
protected override async Task HandleRequirementAsync( |
|||
AuthorizationHandlerContext context, |
|||
PermissionsRequirement requirement) |
|||
{ |
|||
var multiplePermissionGrantResult = await _permissionChecker.IsGrantedAsync(context.User, requirement.PermissionNames); |
|||
|
|||
if (requirement.RequiresAll ? |
|||
multiplePermissionGrantResult.AllGranted : |
|||
multiplePermissionGrantResult.Result.Any(x => x.Value == PermissionGrantResult.Granted)) |
|||
{ |
|||
context.Succeed(requirement); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
|
|||
namespace Volo.Abp.Cli.ProjectModification |
|||
{ |
|||
public class AddModuleInfoOutput |
|||
{ |
|||
public string Name { get; set; } |
|||
|
|||
public string DisplayName { get; set; } |
|||
|
|||
public string DocumentationLinks { get; set; } |
|||
|
|||
public string InstallationCompleteMessage { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,25 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|||
|
|||
<Import Project="..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net6.0</TargetFramework> |
|||
<AssemblyName>Volo.Abp.Http.Client.Web</AssemblyName> |
|||
<PackageId>Volo.Abp.Http.Client.Web</PackageId> |
|||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<IsPackable>true</IsPackable> |
|||
<OutputType>Library</OutputType> |
|||
<NoDefaultLaunchSettingsFile>true</NoDefaultLaunchSettingsFile> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc\Volo.Abp.AspNetCore.Mvc.csproj" /> |
|||
<ProjectReference Include="..\Volo.Abp.Http.Client\Volo.Abp.Http.Client.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,42 @@ |
|||
using System.Linq; |
|||
using Microsoft.AspNetCore.Mvc.ApplicationParts; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc.Conventions; |
|||
using Volo.Abp.Http.Client.Web.Conventions; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Volo.Abp.Http.Client.Web |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpAspNetCoreMvcModule), |
|||
typeof(AbpHttpClientModule) |
|||
)] |
|||
public class AbpHttpClientWebModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.Replace(ServiceDescriptor.Transient<IAbpServiceConvention, AbpHttpClientProxyServiceConvention>()); |
|||
context.Services.AddTransient<AbpHttpClientProxyServiceConvention>(); |
|||
|
|||
var partManager = context.Services.GetSingletonInstance<ApplicationPartManager>(); |
|||
partManager.FeatureProviders.Add(new AbpHttpClientProxyControllerFeatureProvider()); |
|||
} |
|||
|
|||
public override void OnApplicationInitialization(ApplicationInitializationContext context) |
|||
{ |
|||
var partManager = context.ServiceProvider.GetRequiredService<ApplicationPartManager>(); |
|||
foreach (var moduleAssembly in context |
|||
.ServiceProvider |
|||
.GetRequiredService<IModuleContainer>() |
|||
.Modules |
|||
.Select(m => m.Type.Assembly) |
|||
.Where(a => a.GetTypes().Any(AbpHttpClientProxyHelper.IsClientProxyService)) |
|||
.Distinct()) |
|||
{ |
|||
partManager.ApplicationParts.AddIfNotContains(moduleAssembly); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System.Reflection; |
|||
using Microsoft.AspNetCore.Mvc.Controllers; |
|||
|
|||
namespace Volo.Abp.Http.Client.Web.Conventions |
|||
{ |
|||
public class AbpHttpClientProxyControllerFeatureProvider : ControllerFeatureProvider |
|||
{ |
|||
protected override bool IsController(TypeInfo typeInfo) |
|||
{ |
|||
return AbpHttpClientProxyHelper.IsClientProxyService(typeInfo); |
|||
} |
|||
} |
|||
} |
|||
@ -1,6 +1,6 @@ |
|||
using System; |
|||
|
|||
namespace Volo.Abp.Http.Client.Proxying |
|||
namespace Volo.Abp.Http.Client.ClientProxying |
|||
{ |
|||
public class ApiVersionInfo //TODO: Rename to not conflict with api versioning apis
|
|||
{ |
|||
@ -0,0 +1,31 @@ |
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Volo.Abp.Http.Client.ClientProxying |
|||
{ |
|||
public class ClientProxyRequestTypeValue : IEnumerable<KeyValuePair<Type, object>> |
|||
{ |
|||
public List<KeyValuePair<Type, object>> Values { get; private set; } |
|||
|
|||
public ClientProxyRequestTypeValue() |
|||
{ |
|||
Values = new List<KeyValuePair<Type, object>>(); |
|||
} |
|||
|
|||
public void Add(Type type, object value) |
|||
{ |
|||
Values.Add(new KeyValuePair<Type, object>(type, value)); |
|||
} |
|||
|
|||
public IEnumerator<KeyValuePair<Type, object>> GetEnumerator() |
|||
{ |
|||
return Values.GetEnumerator(); |
|||
} |
|||
|
|||
IEnumerator IEnumerable.GetEnumerator() |
|||
{ |
|||
return GetEnumerator(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
using System.Net.Http; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Http.Client.ClientProxying; |
|||
|
|||
namespace Volo.Abp.Http.Client.DynamicProxying |
|||
{ |
|||
public class DynamicHttpProxyInterceptorClientProxy<TService> : ClientProxyBase<TService> |
|||
{ |
|||
public virtual async Task<T> CallRequestAsync<T>(ClientProxyRequestContext requestContext) |
|||
{ |
|||
return await base.RequestAsync<T>(requestContext); |
|||
} |
|||
|
|||
public virtual async Task<HttpContent> CallRequestAsync(ClientProxyRequestContext requestContext) |
|||
{ |
|||
return await base.RequestAsync(requestContext); |
|||
} |
|||
} |
|||
} |
|||
@ -1,267 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Globalization; |
|||
using System.Linq; |
|||
using System.Net.Http; |
|||
using System.Net.Http.Headers; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.Options; |
|||
using Microsoft.Extensions.Primitives; |
|||
using Volo.Abp.Content; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Http.Client.Authentication; |
|||
using Volo.Abp.Http.Modeling; |
|||
using Volo.Abp.Http.ProxyScripting.Generators; |
|||
using Volo.Abp.Json; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.Threading; |
|||
using Volo.Abp.Tracing; |
|||
|
|||
namespace Volo.Abp.Http.Client.Proxying |
|||
{ |
|||
public class HttpProxyExecuter : IHttpProxyExecuter, ITransientDependency |
|||
{ |
|||
protected ICancellationTokenProvider CancellationTokenProvider { get; } |
|||
protected ICorrelationIdProvider CorrelationIdProvider { get; } |
|||
protected ICurrentTenant CurrentTenant { get; } |
|||
protected AbpCorrelationIdOptions AbpCorrelationIdOptions { get; } |
|||
protected IProxyHttpClientFactory HttpClientFactory { get; } |
|||
protected IRemoteServiceConfigurationProvider RemoteServiceConfigurationProvider { get; } |
|||
protected AbpHttpClientOptions ClientOptions { get; } |
|||
protected IJsonSerializer JsonSerializer { get; } |
|||
protected IRemoteServiceHttpClientAuthenticator ClientAuthenticator { get; } |
|||
|
|||
public HttpProxyExecuter( |
|||
ICancellationTokenProvider cancellationTokenProvider, |
|||
ICorrelationIdProvider correlationIdProvider, |
|||
ICurrentTenant currentTenant, |
|||
IOptions<AbpCorrelationIdOptions> abpCorrelationIdOptions, |
|||
IProxyHttpClientFactory httpClientFactory, |
|||
IRemoteServiceConfigurationProvider remoteServiceConfigurationProvider, |
|||
IOptions<AbpHttpClientOptions> clientOptions, |
|||
IRemoteServiceHttpClientAuthenticator clientAuthenticator, |
|||
IJsonSerializer jsonSerializer) |
|||
{ |
|||
CancellationTokenProvider = cancellationTokenProvider; |
|||
CorrelationIdProvider = correlationIdProvider; |
|||
CurrentTenant = currentTenant; |
|||
AbpCorrelationIdOptions = abpCorrelationIdOptions.Value; |
|||
HttpClientFactory = httpClientFactory; |
|||
RemoteServiceConfigurationProvider = remoteServiceConfigurationProvider; |
|||
ClientOptions = clientOptions.Value; |
|||
ClientAuthenticator = clientAuthenticator; |
|||
JsonSerializer = jsonSerializer; |
|||
} |
|||
|
|||
public virtual async Task<T> MakeRequestAndGetResultAsync<T>(HttpProxyExecuterContext context) |
|||
{ |
|||
var responseContent = await MakeRequestAsync(context); |
|||
|
|||
if (typeof(T) == typeof(IRemoteStreamContent) || |
|||
typeof(T) == typeof(RemoteStreamContent)) |
|||
{ |
|||
/* returning a class that holds a reference to response |
|||
* content just to be sure that GC does not dispose of |
|||
* it before we finish doing our work with the stream */ |
|||
return (T) (object) new RemoteStreamContent( |
|||
await responseContent.ReadAsStreamAsync(), |
|||
responseContent.Headers?.ContentDisposition?.FileNameStar ?? RemoveQuotes(responseContent.Headers?.ContentDisposition?.FileName).ToString(), |
|||
responseContent.Headers?.ContentType?.ToString(), |
|||
responseContent.Headers?.ContentLength); |
|||
} |
|||
|
|||
var stringContent = await responseContent.ReadAsStringAsync(); |
|||
if (typeof(T) == typeof(string)) |
|||
{ |
|||
return (T)(object)stringContent; |
|||
} |
|||
|
|||
if (stringContent.IsNullOrWhiteSpace()) |
|||
{ |
|||
return default; |
|||
} |
|||
|
|||
return JsonSerializer.Deserialize<T>(stringContent); |
|||
} |
|||
|
|||
public virtual async Task<HttpContent> MakeRequestAsync(HttpProxyExecuterContext context) |
|||
{ |
|||
var clientConfig = ClientOptions.HttpClientProxies.GetOrDefault(context.ServiceType) ?? throw new AbpException($"Could not get HttpClientProxyConfig for {context.ServiceType.FullName}."); |
|||
var remoteServiceConfig = await RemoteServiceConfigurationProvider.GetConfigurationOrDefaultAsync(clientConfig.RemoteServiceName); |
|||
|
|||
var client = HttpClientFactory.Create(clientConfig.RemoteServiceName); |
|||
|
|||
var apiVersion = await GetApiVersionInfoAsync(context); |
|||
var url = remoteServiceConfig.BaseUrl.EnsureEndsWith('/') + UrlBuilder.GenerateUrlWithParameters(context.Action, context.Arguments, apiVersion); |
|||
|
|||
var requestMessage = new HttpRequestMessage(context.Action.GetHttpMethod(), url) |
|||
{ |
|||
Content = RequestPayloadBuilder.BuildContent(context.Action, context.Arguments, JsonSerializer, apiVersion) |
|||
}; |
|||
|
|||
AddHeaders(context.Arguments, context.Action, requestMessage, apiVersion); |
|||
|
|||
if (context.Action.AllowAnonymous != true) |
|||
{ |
|||
await ClientAuthenticator.Authenticate( |
|||
new RemoteServiceHttpClientAuthenticateContext( |
|||
client, |
|||
requestMessage, |
|||
remoteServiceConfig, |
|||
clientConfig.RemoteServiceName |
|||
) |
|||
); |
|||
} |
|||
|
|||
var response = await client.SendAsync( |
|||
requestMessage, |
|||
HttpCompletionOption.ResponseHeadersRead /*this will buffer only the headers, the content will be used as a stream*/, |
|||
GetCancellationToken(context.Arguments) |
|||
); |
|||
|
|||
if (!response.IsSuccessStatusCode) |
|||
{ |
|||
await ThrowExceptionForResponseAsync(response); |
|||
} |
|||
|
|||
return response.Content; |
|||
} |
|||
|
|||
private async Task<ApiVersionInfo> GetApiVersionInfoAsync(HttpProxyExecuterContext context) |
|||
{ |
|||
var apiVersion = await FindBestApiVersionAsync(context); |
|||
|
|||
//TODO: Make names configurable?
|
|||
var versionParam = context.Action.Parameters.FirstOrDefault(p => p.Name == "apiVersion" && p.BindingSourceId == ParameterBindingSources.Path) ?? |
|||
context.Action.Parameters.FirstOrDefault(p => p.Name == "api-version" && p.BindingSourceId == ParameterBindingSources.Query); |
|||
|
|||
return new ApiVersionInfo(versionParam?.BindingSourceId, apiVersion); |
|||
} |
|||
|
|||
private async Task<string> FindBestApiVersionAsync(HttpProxyExecuterContext context) |
|||
{ |
|||
var configuredVersion = await GetConfiguredApiVersionAsync(context); |
|||
|
|||
if (context.Action.SupportedVersions.IsNullOrEmpty()) |
|||
{ |
|||
return configuredVersion ?? "1.0"; |
|||
} |
|||
|
|||
if (context.Action.SupportedVersions.Contains(configuredVersion)) |
|||
{ |
|||
return configuredVersion; |
|||
} |
|||
|
|||
return context.Action.SupportedVersions.Last(); //TODO: Ensure to get the latest version!
|
|||
} |
|||
|
|||
private async Task<string> GetConfiguredApiVersionAsync(HttpProxyExecuterContext context) |
|||
{ |
|||
var clientConfig = ClientOptions.HttpClientProxies.GetOrDefault(context.ServiceType) |
|||
?? throw new AbpException($"Could not get DynamicHttpClientProxyConfig for {context.ServiceType.FullName}."); |
|||
|
|||
return (await RemoteServiceConfigurationProvider |
|||
.GetConfigurationOrDefaultOrNullAsync(clientConfig.RemoteServiceName))?.Version; |
|||
} |
|||
|
|||
private async Task ThrowExceptionForResponseAsync(HttpResponseMessage response) |
|||
{ |
|||
if (response.Headers.Contains(AbpHttpConsts.AbpErrorFormat)) |
|||
{ |
|||
var errorResponse = JsonSerializer.Deserialize<RemoteServiceErrorResponse>( |
|||
await response.Content.ReadAsStringAsync() |
|||
); |
|||
|
|||
throw new AbpRemoteCallException(errorResponse.Error) |
|||
{ |
|||
HttpStatusCode = (int) response.StatusCode |
|||
}; |
|||
} |
|||
|
|||
throw new AbpRemoteCallException( |
|||
new RemoteServiceErrorInfo |
|||
{ |
|||
Message = response.ReasonPhrase, |
|||
Code = response.StatusCode.ToString() |
|||
} |
|||
) |
|||
{ |
|||
HttpStatusCode = (int) response.StatusCode |
|||
}; |
|||
} |
|||
|
|||
protected virtual void AddHeaders( |
|||
IReadOnlyDictionary<string, object> argumentsDictionary, |
|||
ActionApiDescriptionModel action, |
|||
HttpRequestMessage requestMessage, |
|||
ApiVersionInfo apiVersion) |
|||
{ |
|||
//API Version
|
|||
if (!apiVersion.Version.IsNullOrEmpty()) |
|||
{ |
|||
//TODO: What about other media types?
|
|||
requestMessage.Headers.Add("accept", $"{MimeTypes.Text.Plain}; v={apiVersion.Version}"); |
|||
requestMessage.Headers.Add("accept", $"{MimeTypes.Application.Json}; v={apiVersion.Version}"); |
|||
requestMessage.Headers.Add("api-version", apiVersion.Version); |
|||
} |
|||
|
|||
//Header parameters
|
|||
var headers = action.Parameters.Where(p => p.BindingSourceId == ParameterBindingSources.Header).ToArray(); |
|||
foreach (var headerParameter in headers) |
|||
{ |
|||
var value = HttpActionParameterHelper.FindParameterValue(argumentsDictionary, headerParameter); |
|||
if (value != null) |
|||
{ |
|||
requestMessage.Headers.Add(headerParameter.Name, value.ToString()); |
|||
} |
|||
} |
|||
|
|||
//CorrelationId
|
|||
requestMessage.Headers.Add(AbpCorrelationIdOptions.HttpHeaderName, CorrelationIdProvider.Get()); |
|||
|
|||
//TenantId
|
|||
if (CurrentTenant.Id.HasValue) |
|||
{ |
|||
//TODO: Use AbpAspNetCoreMultiTenancyOptions to get the key
|
|||
requestMessage.Headers.Add(TenantResolverConsts.DefaultTenantKey, CurrentTenant.Id.Value.ToString()); |
|||
} |
|||
|
|||
//Culture
|
|||
//TODO: Is that the way we want? Couldn't send the culture (not ui culture)
|
|||
var currentCulture = CultureInfo.CurrentUICulture.Name ?? CultureInfo.CurrentCulture.Name; |
|||
if (!currentCulture.IsNullOrEmpty()) |
|||
{ |
|||
requestMessage.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(currentCulture)); |
|||
} |
|||
|
|||
//X-Requested-With
|
|||
requestMessage.Headers.Add("X-Requested-With", "XMLHttpRequest"); |
|||
} |
|||
|
|||
protected virtual StringSegment RemoveQuotes(StringSegment input) |
|||
{ |
|||
if (!StringSegment.IsNullOrEmpty(input) && input.Length >= 2 && input[0] == '"' && input[input.Length - 1] == '"') |
|||
{ |
|||
input = input.Subsegment(1, input.Length - 2); |
|||
} |
|||
|
|||
return input; |
|||
} |
|||
|
|||
protected virtual CancellationToken GetCancellationToken(IReadOnlyDictionary<string, object> arguments) |
|||
{ |
|||
var cancellationTokenArg = arguments.LastOrDefault(); |
|||
|
|||
if (cancellationTokenArg.Value is CancellationToken cancellationToken) |
|||
{ |
|||
if (cancellationToken != default) |
|||
{ |
|||
return cancellationToken; |
|||
} |
|||
} |
|||
|
|||
return CancellationTokenProvider.Token; |
|||
} |
|||
} |
|||
} |
|||
@ -1,12 +0,0 @@ |
|||
using System.Net.Http; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Volo.Abp.Http.Client.Proxying |
|||
{ |
|||
public interface IHttpProxyExecuter |
|||
{ |
|||
Task<HttpContent> MakeRequestAsync(HttpProxyExecuterContext context); |
|||
|
|||
Task<T> MakeRequestAndGetResultAsync<T>(HttpProxyExecuterContext context); |
|||
} |
|||
} |
|||
@ -1,13 +0,0 @@ |
|||
using System.Reflection; |
|||
using Microsoft.AspNetCore.Mvc.Controllers; |
|||
|
|||
namespace Volo.Abp.Swashbuckle.Conventions |
|||
{ |
|||
public class AbpSwaggerClientProxyControllerFeatureProvider : ControllerFeatureProvider |
|||
{ |
|||
protected override bool IsController(TypeInfo typeInfo) |
|||
{ |
|||
return AbpSwaggerClientProxyHelper.IsClientProxyService(typeInfo); |
|||
} |
|||
} |
|||
} |
|||
@ -1,12 +0,0 @@ |
|||
namespace Volo.Abp.Swashbuckle.Conventions |
|||
{ |
|||
public class AbpSwaggerClientProxyOptions |
|||
{ |
|||
public bool IsEnabled { get; set; } |
|||
|
|||
public AbpSwaggerClientProxyOptions() |
|||
{ |
|||
IsEnabled = true; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System; |
|||
using Volo.Abp.Domain.Entities; |
|||
|
|||
namespace Volo.Abp.Auditing.App.Entities |
|||
{ |
|||
public class AppEntityWithSoftDelete : AggregateRoot<Guid>, IHasDeletionTime |
|||
{ |
|||
public AppEntityWithSoftDelete(Guid id, string name) |
|||
: base(id) |
|||
{ |
|||
Name = name; |
|||
} |
|||
|
|||
public string Name { get; set; } |
|||
|
|||
public bool IsDeleted { get; set; } |
|||
|
|||
public DateTime? DeletionTime { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.test.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net6.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" /> |
|||
<ProjectReference Include="..\..\src\Volo.Abp.IdentityModel\Volo.Abp.IdentityModel.csproj" /> |
|||
<ProjectReference Include="..\AbpTestBase\AbpTestBase.csproj" /> |
|||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<None Remove="appsettings.json" /> |
|||
<Content Include="appsettings.json"> |
|||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
|||
</Content> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,51 @@ |
|||
using System; |
|||
using Microsoft.Extensions.Options; |
|||
using Shouldly; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Xunit; |
|||
|
|||
namespace Volo.Abp.IdentityModel |
|||
{ |
|||
public class AbpIdentityClientOptions_Tests : AbpIdentityModelTestBase |
|||
{ |
|||
private readonly ICurrentTenant _currentTenant; |
|||
private readonly AbpIdentityClientOptions _identityClientOptions; |
|||
|
|||
public AbpIdentityClientOptions_Tests() |
|||
{ |
|||
_currentTenant = GetRequiredService<ICurrentTenant>(); |
|||
_identityClientOptions = GetRequiredService<IOptions<AbpIdentityClientOptions>>().Value; |
|||
} |
|||
|
|||
[Fact] |
|||
public void GetClientConfiguration_Test() |
|||
{ |
|||
var hostDefaultConfiguration = _identityClientOptions.GetClientConfiguration(_currentTenant); |
|||
hostDefaultConfiguration.UserName.ShouldBe("host_default_admin"); |
|||
|
|||
var hostIdentityConfiguration = _identityClientOptions.GetClientConfiguration(_currentTenant, "Identity"); |
|||
hostIdentityConfiguration.UserName.ShouldBe("host_identity_admin"); |
|||
|
|||
using (_currentTenant.Change(Guid.Parse("f72a344f-651e-49f0-85f6-be260a10e4df"), "Test_Tenant1")) |
|||
{ |
|||
var tenantDefaultConfiguration = _identityClientOptions.GetClientConfiguration(_currentTenant); |
|||
tenantDefaultConfiguration.UserName.ShouldBe("tenant_default_admin"); |
|||
} |
|||
|
|||
using (_currentTenant.Change(Guid.Parse("f72a344f-651e-49f0-85f6-be260a10e4df"))) |
|||
{ |
|||
var tenantIdentityConfiguration = _identityClientOptions.GetClientConfiguration(_currentTenant, "Identity"); |
|||
tenantIdentityConfiguration.UserName.ShouldBe("tenant_identity_admin"); |
|||
} |
|||
|
|||
using (_currentTenant.Change(Guid.NewGuid())) |
|||
{ |
|||
var configuration = _identityClientOptions.GetClientConfiguration(_currentTenant); |
|||
configuration.UserName.ShouldBe("host_default_admin"); |
|||
|
|||
configuration = _identityClientOptions.GetClientConfiguration(_currentTenant, "Identity"); |
|||
configuration.UserName.ShouldBe("host_identity_admin"); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using Volo.Abp.Testing; |
|||
|
|||
namespace Volo.Abp.IdentityModel |
|||
{ |
|||
public abstract class AbpIdentityModelTestBase : AbpIntegratedTest<AbpIdentityModelTestModule> |
|||
{ |
|||
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) |
|||
{ |
|||
options.UseAutofac(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Volo.Abp.IdentityModel |
|||
{ |
|||
[DependsOn(typeof(AbpIdentityModelModule))] |
|||
public class AbpIdentityModelTestModule : AbpModule |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,40 @@ |
|||
{ |
|||
"IdentityClients": { |
|||
"Default": { |
|||
"GrantType": "password", |
|||
"ClientId": "Test_App", |
|||
"ClientSecret": "1q2w3e*", |
|||
"UserName": "host_default_admin", |
|||
"UserPassword": "1q2w3E*", |
|||
"Authority": "https://localhost:44395", |
|||
"Scope": "Test_Scope" |
|||
}, |
|||
"Default.Test_Tenant1": { |
|||
"GrantType": "password", |
|||
"ClientId": "Test_App", |
|||
"ClientSecret": "1q2w3e*", |
|||
"UserName": "tenant_default_admin", |
|||
"UserPassword": "1q2w3E*", |
|||
"Authority": "https://localhost:44395", |
|||
"Scope": "Test_Scope" |
|||
}, |
|||
"Identity": { |
|||
"GrantType": "password", |
|||
"ClientId": "Test_App", |
|||
"ClientSecret": "1q2w3e*", |
|||
"UserName": "host_identity_admin", |
|||
"UserPassword": "1q2w3E*", |
|||
"Authority": "https://localhost:44395", |
|||
"Scope": "Test_Scope" |
|||
}, |
|||
"Identity.f72a344f-651e-49f0-85f6-be260a10e4df": { |
|||
"GrantType": "password", |
|||
"ClientId": "Test_App", |
|||
"ClientSecret": "1q2w3e*", |
|||
"UserName": "tenant_identity_admin", |
|||
"UserPassword": "1q2w3E*", |
|||
"Authority": "https://localhost:44395", |
|||
"Scope": "Test_Scope" |
|||
} |
|||
} |
|||
} |
|||
@ -1,18 +0,0 @@ |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.EntityFrameworkCore.Modeling; |
|||
|
|||
namespace Volo.Abp.Identity.EntityFrameworkCore |
|||
{ |
|||
public class AbpAuditLoggingModelBuilderConfigurationOptions : AbpModelBuilderConfigurationOptions |
|||
{ |
|||
public AbpAuditLoggingModelBuilderConfigurationOptions( |
|||
[NotNull] string tablePrefix, |
|||
[CanBeNull] string schema) |
|||
: base( |
|||
tablePrefix, |
|||
schema) |
|||
{ |
|||
|
|||
} |
|||
} |
|||
} |
|||
@ -1,14 +0,0 @@ |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.MongoDB; |
|||
|
|||
namespace Volo.Abp.AuditLogging.MongoDB |
|||
{ |
|||
public class AuditLoggingMongoModelBuilderConfigurationOptions : AbpMongoModelBuilderConfigurationOptions |
|||
{ |
|||
public AuditLoggingMongoModelBuilderConfigurationOptions( |
|||
[NotNull] string collectionPrefix = "") |
|||
: base(collectionPrefix) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -1,18 +0,0 @@ |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.EntityFrameworkCore.Modeling; |
|||
|
|||
namespace Volo.Abp.BackgroundJobs.EntityFrameworkCore |
|||
{ |
|||
public class BackgroundJobsModelBuilderConfigurationOptions : AbpModelBuilderConfigurationOptions |
|||
{ |
|||
public BackgroundJobsModelBuilderConfigurationOptions( |
|||
[NotNull] string tablePrefix = "", |
|||
[CanBeNull] string schema = null) |
|||
: base( |
|||
tablePrefix, |
|||
schema) |
|||
{ |
|||
|
|||
} |
|||
} |
|||
} |
|||
@ -1,26 +1,18 @@ |
|||
using System; |
|||
using Volo.Abp.MongoDB; |
|||
using Volo.Abp.MongoDB; |
|||
|
|||
namespace Volo.Abp.BackgroundJobs.MongoDB |
|||
{ |
|||
public static class BackgroundJobsMongoDbContextExtensions |
|||
{ |
|||
public static void ConfigureBackgroundJobs( |
|||
this IMongoModelBuilder builder, |
|||
Action<AbpMongoModelBuilderConfigurationOptions> optionsAction = null) |
|||
this IMongoModelBuilder builder) |
|||
{ |
|||
Check.NotNull(builder, nameof(builder)); |
|||
|
|||
var options = new BackgroundJobsMongoModelBuilderConfigurationOptions( |
|||
BackgroundJobsDbProperties.DbTablePrefix |
|||
); |
|||
|
|||
optionsAction?.Invoke(options); |
|||
|
|||
builder.Entity<BackgroundJobRecord>(b => |
|||
{ |
|||
b.CollectionName = options.CollectionPrefix + "BackgroundJobs"; |
|||
b.CollectionName = BackgroundJobsDbProperties.DbTablePrefix + "BackgroundJobs"; |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -1,14 +0,0 @@ |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.MongoDB; |
|||
|
|||
namespace Volo.Abp.BackgroundJobs.MongoDB |
|||
{ |
|||
public class BackgroundJobsMongoModelBuilderConfigurationOptions : AbpMongoModelBuilderConfigurationOptions |
|||
{ |
|||
public BackgroundJobsMongoModelBuilderConfigurationOptions( |
|||
[NotNull] string collectionPrefix = "") |
|||
: base(collectionPrefix) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -1,18 +0,0 @@ |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.EntityFrameworkCore.Modeling; |
|||
|
|||
namespace Volo.Abp.BlobStoring.Database.EntityFrameworkCore |
|||
{ |
|||
public class BlobStoringModelBuilderConfigurationOptions : AbpModelBuilderConfigurationOptions |
|||
{ |
|||
public BlobStoringModelBuilderConfigurationOptions( |
|||
[NotNull] string tablePrefix = "", |
|||
[CanBeNull] string schema = null) |
|||
: base( |
|||
tablePrefix, |
|||
schema) |
|||
{ |
|||
|
|||
} |
|||
} |
|||
} |
|||
@ -1,31 +1,23 @@ |
|||
using System; |
|||
using Volo.Abp.MongoDB; |
|||
using Volo.Abp.MongoDB; |
|||
|
|||
namespace Volo.Abp.BlobStoring.Database.MongoDB |
|||
{ |
|||
public static class BlobStoringMongoDbContextExtensions |
|||
{ |
|||
public static void ConfigureBlobStoring( |
|||
this IMongoModelBuilder builder, |
|||
Action<AbpMongoModelBuilderConfigurationOptions> optionsAction = null) |
|||
this IMongoModelBuilder builder) |
|||
{ |
|||
Check.NotNull(builder, nameof(builder)); |
|||
|
|||
var options = new BlobStoringMongoModelBuilderConfigurationOptions( |
|||
BlobStoringDatabaseDbProperties.DbTablePrefix |
|||
); |
|||
|
|||
optionsAction?.Invoke(options); |
|||
|
|||
builder.Entity<DatabaseBlobContainer>(b => |
|||
{ |
|||
b.CollectionName = options.CollectionPrefix + "BlobContainers"; |
|||
b.CollectionName = BlobStoringDatabaseDbProperties.DbTablePrefix + "BlobContainers"; |
|||
}); |
|||
|
|||
builder.Entity<DatabaseBlob>(b => |
|||
{ |
|||
b.CollectionName = options.CollectionPrefix + "Blobs"; |
|||
b.CollectionName = BlobStoringDatabaseDbProperties.DbTablePrefix + "Blobs"; |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -1,14 +0,0 @@ |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.MongoDB; |
|||
|
|||
namespace Volo.Abp.BlobStoring.Database.MongoDB |
|||
{ |
|||
public class BlobStoringMongoModelBuilderConfigurationOptions : AbpMongoModelBuilderConfigurationOptions |
|||
{ |
|||
public BlobStoringMongoModelBuilderConfigurationOptions( |
|||
[NotNull] string collectionPrefix = "") |
|||
: base(collectionPrefix) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
File diff suppressed because it is too large
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue