63 changed files with 1502 additions and 307 deletions
@ -0,0 +1,21 @@ |
|||
using Microsoft.Extensions.Logging; |
|||
using Volo.Abp; |
|||
using Volo.Abp.ExceptionHandling; |
|||
using Volo.Abp.Logging; |
|||
|
|||
namespace LINYUN.Abp.Aliyun |
|||
{ |
|||
public class AbpAliyunException : AbpException, IHasErrorCode, IHasLogLevel |
|||
{ |
|||
public LogLevel LogLevel { get; set; } |
|||
|
|||
public string Code { get; } |
|||
|
|||
public AbpAliyunException(string code, string message) |
|||
: base(message) |
|||
{ |
|||
Code = code; |
|||
LogLevel = LogLevel.Warning; |
|||
} |
|||
} |
|||
} |
|||
@ -1,21 +1,25 @@ |
|||
using LINYUN.Abp.Aliyun.Localization; |
|||
using Volo.Abp.Caching; |
|||
using Volo.Abp.Json; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.Settings; |
|||
using Volo.Abp.VirtualFileSystem; |
|||
|
|||
namespace LINGYUN.Abp.Aliyun |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpCachingModule), |
|||
typeof(AbpSettingsModule), |
|||
typeof(AbpJsonModule), |
|||
typeof(AbpLocalizationModule))] |
|||
public class AbpAliyunCloudModule : AbpModule |
|||
public class AbpAliyunModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpVirtualFileSystemOptions>(options => |
|||
{ |
|||
options.FileSets.AddEmbedded<AbpAliyunCloudModule>(); |
|||
options.FileSets.AddEmbedded<AbpAliyunModule>(); |
|||
}); |
|||
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
@ -0,0 +1,32 @@ |
|||
using Aliyun.Acs.Core; |
|||
using Aliyun.Acs.Core.Auth; |
|||
using Aliyun.Acs.Core.Profile; |
|||
using Volo.Abp.Caching; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace LINYUN.Abp.Aliyun |
|||
{ |
|||
public class AcsClientFactory : AliyunClientFactory<IAcsClient>, IAcsClientFactory, ITransientDependency |
|||
{ |
|||
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 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); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
using System; |
|||
|
|||
namespace LINYUN.Abp.Aliyun |
|||
{ |
|||
[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; } |
|||
|
|||
static AliyunBasicSessionCredentialsCacheItem() |
|||
{ |
|||
_cacheKey = Guid.NewGuid().ToString("N"); |
|||
} |
|||
|
|||
public AliyunBasicSessionCredentialsCacheItem() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public AliyunBasicSessionCredentialsCacheItem(string accessKeyId, string accessKeySecret, string securityToken) |
|||
{ |
|||
AccessKeyId = accessKeyId; |
|||
AccessKeySecret = accessKeySecret; |
|||
SecurityToken = securityToken; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,180 @@ |
|||
using Aliyun.Acs.Core; |
|||
using Aliyun.Acs.Core.Auth.Sts; |
|||
using Aliyun.Acs.Core.Http; |
|||
using Aliyun.Acs.Core.Profile; |
|||
using LINYUN.Abp.Aliyun.Settings; |
|||
using Microsoft.Extensions.Caching.Distributed; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Caching; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace LINYUN.Abp.Aliyun |
|||
{ |
|||
/// <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) |
|||
{ |
|||
Cache = cache; |
|||
SettingProvider = settingProvider; |
|||
} |
|||
|
|||
public virtual async 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); |
|||
|
|||
Check.NotNullOrWhiteSpace(regionId, AliyunSettingNames.Authorization.RegionId); |
|||
Check.NotNullOrWhiteSpace(accessKey, AliyunSettingNames.Authorization.AccessKeyId); |
|||
Check.NotNullOrWhiteSpace(accessKeySecret, AliyunSettingNames.Authorization.AccessKeySecret); |
|||
|
|||
if (await SettingProvider.IsTrueAsync(AliyunSettingNames.Authorization.UseSecurityTokenService)) |
|||
{ |
|||
var cacheItem = await GetCacheItemAsync(accessKey, accessKeySecret, regionId); |
|||
|
|||
return GetSecurityTokenClient(regionId, cacheItem.AccessKeyId, cacheItem.AccessKeySecret, cacheItem.SecurityToken); |
|||
} |
|||
|
|||
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 virtual async Task<AliyunBasicSessionCredentialsCacheItem> GetCacheItemAsync(string accessKeyId, string accessKeySecret, string regionId) |
|||
{ |
|||
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 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 |
|||
{ |
|||
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; |
|||
} |
|||
} |
|||
/// <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) |
|||
{ |
|||
Cache = cache; |
|||
SettingProvider = settingProvider; |
|||
} |
|||
|
|||
public virtual async 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); |
|||
|
|||
Check.NotNullOrWhiteSpace(regionId, AliyunSettingNames.Authorization.RegionId); |
|||
Check.NotNullOrWhiteSpace(accessKey, AliyunSettingNames.Authorization.AccessKeyId); |
|||
Check.NotNullOrWhiteSpace(accessKeySecret, AliyunSettingNames.Authorization.AccessKeySecret); |
|||
|
|||
if (await SettingProvider.IsTrueAsync(AliyunSettingNames.Authorization.UseSecurityTokenService)) |
|||
{ |
|||
var cacheItem = await GetCacheItemAsync(accessKey, accessKeySecret, regionId); |
|||
|
|||
return GetSecurityTokenClient(configuration, regionId, cacheItem.AccessKeyId, cacheItem.AccessKeySecret, cacheItem.SecurityToken); |
|||
} |
|||
|
|||
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 virtual async Task<AliyunBasicSessionCredentialsCacheItem> GetCacheItemAsync(string accessKeyId, string accessKeySecret, string regionId) |
|||
{ |
|||
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 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 |
|||
{ |
|||
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; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using Aliyun.Acs.Core; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINYUN.Abp.Aliyun |
|||
{ |
|||
public interface IAcsClientFactory |
|||
{ |
|||
/// <summary>
|
|||
/// 构造一个通用的Acs客户端调用
|
|||
/// 通过CommonRequest调用可以不需要集成其他SDK包
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
Task<IAcsClient> CreateAsync(); |
|||
} |
|||
} |
|||
@ -1,5 +1,23 @@ |
|||
{ |
|||
"culture": "en", |
|||
"texts": { |
|||
"DisplayName:Authorization": "Authorization", |
|||
"Description:Authorization": "Authorization", |
|||
"DisplayName:RegionId": "Region Id", |
|||
"Description:RegionId": "Region Id", |
|||
"DisplayName:AccessKeyId": "AccessKey Id", |
|||
"Description:AccessKeyId": "AccessKey Id", |
|||
"DisplayName:AccessKeySecret": "AccessKey Secret", |
|||
"Description:AccessKeySecret": "AccessKey Secret", |
|||
"DisplayName:UseSecurityTokenService": "Use STS Token", |
|||
"Description:UseSecurityTokenService": "Use STS Token", |
|||
"DisplayName:RamRoleArn": "Ram Role Arn", |
|||
"Description:RamRoleArn": "Ram Role Arn", |
|||
"DisplayName:RoleSessionName": "Role Session Name", |
|||
"Description:RoleSessionName": "Role Session Name", |
|||
"DisplayName:DurationSeconds": "Duration Seconds,in seconds", |
|||
"Description:DurationSeconds": "Duration Seconds,in seconds", |
|||
"DisplayName:Policy": "Policy", |
|||
"Description:Policy": "Policy" |
|||
} |
|||
} |
|||
@ -1,5 +1,23 @@ |
|||
{ |
|||
"culture": "zh-Hans", |
|||
"texts": { |
|||
"DisplayName:Authorization": "阿里云身份认证凭据", |
|||
"Description:Authorization": "阿里云身份认证凭据", |
|||
"DisplayName:RegionId": "地域ID", |
|||
"Description:RegionId": "正在使用的地域ID", |
|||
"DisplayName:AccessKeyId": "AccessKey Id", |
|||
"Description:AccessKeyId": "访问密钥标识", |
|||
"DisplayName:AccessKeySecret": "AccessKey Secret", |
|||
"Description:AccessKeySecret": "访问密钥", |
|||
"DisplayName:UseSecurityTokenService": "使用STS Token访问", |
|||
"Description:UseSecurityTokenService": "使用STS Token访问", |
|||
"DisplayName:RamRoleArn": "角色全局资源描述符", |
|||
"Description:RamRoleArn": "格式:acs:ram::$accountID:role/$roleName/$RoleSessionName,详情见阿里云访问控制API", |
|||
"DisplayName:RoleSessionName": "角色的临时身份", |
|||
"Description:RoleSessionName": "此参数用来区分不同的令牌,可用于用户级别的访问审计", |
|||
"DisplayName:DurationSeconds": "过期时间,单位为秒。", |
|||
"Description:DurationSeconds": "过期时间最小值为900秒,默认3600秒", |
|||
"DisplayName:Policy": "权限策略", |
|||
"Description:Policy": "生成STS Token时可以指定一个额外的权限策略,以进一步限制STS Token的权限" |
|||
} |
|||
} |
|||
@ -0,0 +1,81 @@ |
|||
using LINYUN.Abp.Aliyun.Localization; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace LINYUN.Abp.Aliyun.Settings |
|||
{ |
|||
public class AliyunSettingProvider : SettingDefinitionProvider |
|||
{ |
|||
public override void Define(ISettingDefinitionContext context) |
|||
{ |
|||
context.Add(CreateAliyunSettings()); |
|||
} |
|||
|
|||
private SettingDefinition[] CreateAliyunSettings() |
|||
{ |
|||
return new SettingDefinition[] |
|||
{ |
|||
new SettingDefinition( |
|||
AliyunSettingNames.Authorization.AccessKeyId, |
|||
displayName: L("DisplayName:AccessKeyId"), |
|||
description: L("Description:AccessKeyId"), |
|||
isVisibleToClients: false, |
|||
isEncrypted: true |
|||
), |
|||
new SettingDefinition( |
|||
AliyunSettingNames.Authorization.AccessKeySecret, |
|||
displayName: L("DisplayName:AccessKeySecret"), |
|||
description: L("Description:AccessKeySecret"), |
|||
isVisibleToClients: false, |
|||
isEncrypted: true |
|||
), |
|||
new SettingDefinition( |
|||
AliyunSettingNames.Authorization.DurationSeconds, |
|||
defaultValue: "3000", |
|||
displayName: L("DisplayName:DurationSeconds"), |
|||
description: L("Description:DurationSeconds"), |
|||
isVisibleToClients: false |
|||
), |
|||
new SettingDefinition( |
|||
AliyunSettingNames.Authorization.Policy, |
|||
displayName: L("DisplayName:Policy"), |
|||
description: L("Description:Policy"), |
|||
isVisibleToClients: false, |
|||
isEncrypted: true |
|||
), |
|||
new SettingDefinition( |
|||
AliyunSettingNames.Authorization.RamRoleArn, |
|||
displayName: L("DisplayName:RamRoleArn"), |
|||
description: L("Description:RamRoleArn"), |
|||
isVisibleToClients: false, |
|||
isEncrypted: true |
|||
), |
|||
new SettingDefinition( |
|||
AliyunSettingNames.Authorization.RegionId, |
|||
displayName: L("DisplayName:RegionId"), |
|||
description: L("Description:RegionId"), |
|||
isVisibleToClients: false |
|||
), |
|||
new SettingDefinition( |
|||
AliyunSettingNames.Authorization.RoleSessionName, |
|||
displayName: L("DisplayName:RoleSessionName"), |
|||
description: L("Description:RoleSessionName"), |
|||
isVisibleToClients: false, |
|||
isEncrypted: true |
|||
), |
|||
new SettingDefinition( |
|||
AliyunSettingNames.Authorization.UseSecurityTokenService, |
|||
defaultValue: true.ToString(), |
|||
displayName: L("DisplayName:UseSecurityTokenService"), |
|||
description: L("Description:UseSecurityTokenService"), |
|||
isVisibleToClients: false |
|||
), |
|||
}; |
|||
} |
|||
|
|||
private ILocalizableString L(string name) |
|||
{ |
|||
return LocalizableString.Create<AliyunResource>(name); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
# LINGYUN.Abp.Aliyun |
|||
|
|||
阿里云sdk集成 |
|||
|
|||
参照:https://help.aliyun.com/document_detail/28763.html |
|||
|
|||
## 配置使用 |
|||
|
|||
模块按需引用 |
|||
|
|||
```csharp |
|||
[DependsOn(typeof(AbpAliyunModule))] |
|||
public class YouProjectModule : AbpModule |
|||
{ |
|||
// other |
|||
} |
|||
``` |
|||
## 配置项说明 |
|||
|
|||
* AliyunSettingNames.Authorization.RegionId 可选,区域,默认 default |
|||
* AliyunSettingNames.Authorization.AccessKeyId 必须,阿里云RAM账号的AccessKey ID |
|||
* AliyunSettingNames.Authorization.AccessKeySecret 必须,RAM账号的AccessKey Secret |
|||
* AliyunSettingNames.Authorization.UseSecurityTokenService 可选,建议,使用STS Token访问,按照阿里云文档,建议使用Sts Token访问API,默认false |
|||
* AliyunSettingNames.Authorization.RamRoleArn 可选,启用Sts Token之后必须配置,阿里云RAM角色ARN |
|||
* AliyunSettingNames.Authorization.RoleSessionName 可选,启用Sts Token之后的用户自定义令牌名称,用于访问审计 |
|||
* AliyunSettingNames.Authorization.DurationSeconds 可选,用户令牌的过期时间,单位为秒,默认3000 |
|||
* AliyunSettingNames.Authorization.Policy 可选,权限策略,为json字符串 |
|||
|
|||
## 其他 |
|||
|
|||
网络因素在高并发下可能会出现预期外的异常,考虑使用二级缓存 |
|||
@ -0,0 +1,15 @@ |
|||
using Aliyun.OSS; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.BlobStoring.Aliyun |
|||
{ |
|||
public interface IOssClientFactory |
|||
{ |
|||
/// <summary>
|
|||
/// 通过配置信息构建Oss客户端调用
|
|||
/// </summary>
|
|||
/// <param name="configuration"></param>
|
|||
/// <returns></returns>
|
|||
Task<IOss> CreateAsync(AliyunBlobProviderConfiguration configuration); |
|||
} |
|||
} |
|||
@ -0,0 +1,50 @@ |
|||
using Aliyun.OSS; |
|||
using LINYUN.Abp.Aliyun; |
|||
using Volo.Abp.Caching; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace LINGYUN.Abp.BlobStoring.Aliyun |
|||
{ |
|||
public class OssClientFactory : AliyunClientFactory<IOss, AliyunBlobProviderConfiguration>, IOssClientFactory, ITransientDependency |
|||
{ |
|||
public OssClientFactory( |
|||
ISettingProvider settingProvider, |
|||
IDistributedCache<AliyunBasicSessionCredentialsCacheItem> cache) |
|||
: base(settingProvider, cache) |
|||
{ |
|||
} |
|||
/// <summary>
|
|||
/// 普通方式构建Oss客户端
|
|||
/// </summary>
|
|||
/// <param name="configuration"></param>
|
|||
/// <param name="regionId"></param>
|
|||
/// <param name="accessKeyId"></param>
|
|||
/// <param name="accessKeySecret"></param>
|
|||
/// <returns></returns>
|
|||
protected override IOss GetClient(AliyunBlobProviderConfiguration configuration, string regionId, string accessKeyId, string accessKeySecret) |
|||
{ |
|||
return new OssClient( |
|||
configuration.Endpoint, |
|||
accessKeyId, |
|||
accessKeySecret); |
|||
} |
|||
/// <summary>
|
|||
/// 通过用户安全令牌构建Oss客户端
|
|||
/// </summary>
|
|||
/// <param name="configuration"></param>
|
|||
/// <param name="regionId"></param>
|
|||
/// <param name="accessKeyId"></param>
|
|||
/// <param name="accessKeySecret"></param>
|
|||
/// <param name="securityToken"></param>
|
|||
/// <returns></returns>
|
|||
protected override IOss GetSecurityTokenClient(AliyunBlobProviderConfiguration configuration, string regionId, string accessKeyId, string accessKeySecret, string securityToken) |
|||
{ |
|||
return new OssClient( |
|||
configuration.Endpoint, |
|||
accessKeyId, |
|||
accessKeySecret, |
|||
securityToken); |
|||
} |
|||
} |
|||
} |
|||
@ -1,28 +1,12 @@ |
|||
using Microsoft.Extensions.Logging; |
|||
using Volo.Abp; |
|||
using Volo.Abp.ExceptionHandling; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Logging; |
|||
using LINYUN.Abp.Aliyun; |
|||
|
|||
namespace LINYUN.Abp.Sms.Aliyun |
|||
{ |
|||
public class AliyunSmsException : AbpException, IHasErrorCode, ILocalizeErrorMessage, IHasLogLevel |
|||
public class AliyunSmsException : AbpAliyunException |
|||
{ |
|||
public AliyunSmsException(string code, string message) |
|||
:base(message) |
|||
:base(code, message) |
|||
{ |
|||
Code = code; |
|||
LogLevel = LogLevel.Warning; |
|||
} |
|||
|
|||
public LogLevel LogLevel { get; set; } |
|||
|
|||
public string Code { get; } |
|||
|
|||
public string LocalizeMessage(LocalizationContext context) |
|||
{ |
|||
return AliyunSmsResponse.GetErrorMessage(Code, Message) |
|||
.Localize(context.LocalizerFactory); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -1,38 +0,0 @@ |
|||
namespace LINYUN.Abp.Sms.Aliyun |
|||
{ |
|||
public class AliyunSmsOptions |
|||
{ |
|||
/// <summary>
|
|||
/// 区域Id
|
|||
/// </summary>
|
|||
public string RegionId { get; set; } = "default"; |
|||
/// <summary>
|
|||
/// 阿里云sms服务域名
|
|||
/// </summary>
|
|||
public string Domain { get; set; } = "dysmsapi.aliyuncs.com"; |
|||
/// <summary>
|
|||
/// 调用方法名称
|
|||
/// </summary>
|
|||
public string ActionName { get; set; } = "SendSms"; |
|||
/// <summary>
|
|||
/// 默认版本号
|
|||
/// </summary>
|
|||
public string Version { get; set; } = "2017-05-25"; |
|||
/// <summary>
|
|||
/// 默认签名
|
|||
/// </summary>
|
|||
public string DefaultSignName { get; set; } |
|||
/// <summary>
|
|||
/// 默认短信模板号
|
|||
/// </summary>
|
|||
public string DefaultTemplateCode { get; set; } |
|||
/// <summary>
|
|||
/// 开发人员号码,当应用处于开发模式时,默认所有信息都会发送到此号码
|
|||
/// </summary>
|
|||
public string DeveloperPhoneNumber { get; set; } = "13800138000"; |
|||
/// <summary>
|
|||
/// 展示错误给客户端
|
|||
/// </summary>
|
|||
public bool VisableErrorToClient { get; set; } = false; |
|||
} |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
using LINYUN.Abp.Aliyun.Settings; |
|||
|
|||
namespace LINYUN.Abp.Sms.Aliyun.Settings |
|||
{ |
|||
public static class AliyunSmsSettingNames |
|||
{ |
|||
/// <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"; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,74 @@ |
|||
using LINYUN.Abp.Aliyun.Localization; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace LINYUN.Abp.Sms.Aliyun.Settings |
|||
{ |
|||
public class AliyunSmsSettingProvider : SettingDefinitionProvider |
|||
{ |
|||
public override void Define(ISettingDefinitionContext context) |
|||
{ |
|||
context.Add(CreateAliyunSettings()); |
|||
} |
|||
|
|||
private SettingDefinition[] CreateAliyunSettings() |
|||
{ |
|||
return new SettingDefinition[] |
|||
{ |
|||
new SettingDefinition( |
|||
AliyunSmsSettingNames.Sms.ActionName, |
|||
defaultValue: "SendSms", |
|||
displayName: L("DisplayName:ActionName"), |
|||
description: L("Description:ActionName"), |
|||
isVisibleToClients: false |
|||
), |
|||
new SettingDefinition( |
|||
AliyunSmsSettingNames.Sms.DefaultSignName, |
|||
displayName: L("DisplayName:DefaultSignName"), |
|||
description: L("Description:DefaultSignName"), |
|||
isVisibleToClients: false, |
|||
isEncrypted: true |
|||
), |
|||
new SettingDefinition( |
|||
AliyunSmsSettingNames.Sms.DefaultTemplateCode, |
|||
displayName: L("DisplayName:DefaultTemplateCode"), |
|||
description: L("Description:DefaultTemplateCode"), |
|||
isVisibleToClients: false, |
|||
isEncrypted: true |
|||
), |
|||
new SettingDefinition( |
|||
AliyunSmsSettingNames.Sms.DefaultPhoneNumber, |
|||
displayName: L("DisplayName:DefaultPhoneNumber"), |
|||
description: L("Description:DefaultPhoneNumber"), |
|||
isVisibleToClients: false |
|||
), |
|||
new SettingDefinition( |
|||
AliyunSmsSettingNames.Sms.Domain, |
|||
defaultValue: "dysmsapi.aliyuncs.com", |
|||
displayName: L("DisplayName:Domain"), |
|||
description: L("Description:Domain"), |
|||
isVisibleToClients: false |
|||
), |
|||
new SettingDefinition( |
|||
AliyunSmsSettingNames.Sms.Version, |
|||
defaultValue: "2017-05-25", |
|||
displayName: L("DisplayName:Version"), |
|||
description: L("Description:Version"), |
|||
isVisibleToClients: false |
|||
), |
|||
new SettingDefinition( |
|||
AliyunSmsSettingNames.Sms.VisableErrorToClient, |
|||
defaultValue: false.ToString(), |
|||
displayName: L("DisplayName:VisableErrorToClient"), |
|||
description: L("Description:VisableErrorToClient"), |
|||
isVisibleToClients: false |
|||
) |
|||
}; |
|||
} |
|||
|
|||
private ILocalizableString L(string name) |
|||
{ |
|||
return LocalizableString.Create<AliyunResource>(name); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.Security; |
|||
|
|||
namespace LINGYUN.Abp.Encryption.Console |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpSecurityModule))] |
|||
public class AbpEncryptionConsoleModule : AbpModule |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<OutputType>Exe</OutputType> |
|||
<TargetFramework>netcoreapp3.1</TargetFramework> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Security" Version="4.1.2" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,42 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using System; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Security.Encryption; |
|||
using static System.Console; |
|||
|
|||
namespace LINGYUN.Abp.Encryption.Console |
|||
{ |
|||
class Program |
|||
{ |
|||
static void Main(string[] args) |
|||
{ |
|||
WriteLine("Hello World!"); |
|||
|
|||
var application = AbpApplicationFactory.Create<AbpEncryptionConsoleModule>(); |
|||
|
|||
application.Initialize(); |
|||
|
|||
WriteLine("D:解密 E:加密"); |
|||
|
|||
var opt = ReadLine(); |
|||
bool en = false; |
|||
if ("E".Equals(opt, StringComparison.InvariantCultureIgnoreCase)) |
|||
{ |
|||
en = true; |
|||
WriteLine("请输入需要加密的字符串"); |
|||
} |
|||
else |
|||
{ |
|||
WriteLine("请输入需要解密的字符串"); |
|||
} |
|||
|
|||
var sourceChr = ReadLine(); |
|||
var encryptionService = application.ServiceProvider.GetRequiredService<IStringEncryptionService>(); |
|||
WriteLine(en ? encryptionService.Encrypt(sourceChr) : encryptionService.Decrypt(sourceChr)); |
|||
|
|||
application.Shutdown(); |
|||
|
|||
ReadKey(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net5.0</TargetFramework> |
|||
<RootNamespace /> |
|||
<IsPackable>false</IsPackable> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\modules\cloud-aliyun\LINGYUN.Abp.Aliyun\LINGYUN.Abp.Aliyun.csproj" /> |
|||
<ProjectReference Include="..\LINGYUN.Abp.TestBase\LINGYUN.Abp.TestsBase.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,8 @@ |
|||
using LINGYUN.Abp.Tests; |
|||
|
|||
namespace LINGYUN.Abp.Aliyun |
|||
{ |
|||
public class AbpAliyunTestBase : AbpTestsBase<AbpAliyunTestModule> |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
using LINGYUN.Abp.Tests; |
|||
using Microsoft.Extensions.Configuration; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Aliyun |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpAliyunModule), |
|||
typeof(AbpTestsBaseModule))] |
|||
public class AbpAliyunTestModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var configurationOptions = new AbpConfigurationBuilderOptions |
|||
{ |
|||
BasePath = @"D:\Projects\Development\Abp\Aliyun", |
|||
EnvironmentName = "Development" |
|||
}; |
|||
|
|||
context.Services.ReplaceConfiguration(ConfigurationHelper.BuildConfiguration(configurationOptions)); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
using Microsoft.EntityFrameworkCore; |
|||
using Microsoft.Extensions.Logging; |
|||
using System; |
|||
using System.Diagnostics; |
|||
|
|||
namespace LINGYUN.Abp.EntityFrameworkCore.Tests |
|||
{ |
|||
public class EfCoreLoggerFactory : ILoggerFactory |
|||
{ |
|||
public void AddProvider(ILoggerProvider provider) |
|||
{ |
|||
} |
|||
|
|||
public ILogger CreateLogger(string categoryName) |
|||
{ |
|||
return new EfCoreLogger(categoryName);//创建EFLogger类的实例
|
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
|
|||
} |
|||
} |
|||
|
|||
public class EfCoreLogger : ILogger |
|||
{ |
|||
private readonly string _categoryName; |
|||
|
|||
public EfCoreLogger(string categoryName) => this._categoryName = categoryName; |
|||
|
|||
public bool IsEnabled(LogLevel logLevel) => true; |
|||
|
|||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) |
|||
{ |
|||
var logContent = formatter(state, exception); |
|||
|
|||
Debug.WriteLine(""); |
|||
// Console.ForegroundColor = logLevel == LogLevel.Warning || logLevel == LogLevel.Error ? ConsoleColor.Red : ConsoleColor.Green;
|
|||
Debug.WriteLine(logContent); |
|||
} |
|||
|
|||
public IDisposable BeginScope<TState>(TState state) => null; |
|||
} |
|||
|
|||
public static class EFCoreLoggerExtensions |
|||
{ |
|||
public static DbContextOptionsBuilder UseEFCoreLogger(this DbContextOptionsBuilder builder) |
|||
{ |
|||
return builder.UseLoggerFactory(new EfCoreLoggerFactory()); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net5.0</TargetFramework> |
|||
<RootNamespace /> |
|||
<IsPackable>false</IsPackable> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\modules\common\LINGYUN.Abp.Sms.Aliyun\LINGYUN.Abp.Sms.Aliyun.csproj" /> |
|||
<ProjectReference Include="..\LINGYUN.Abp.Aliyun.Tests\LINGYUN.Abp.Aliyun.Tests.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,8 @@ |
|||
using LINGYUN.Abp.Tests; |
|||
|
|||
namespace LINGYUN.Abp.Sms.Aliyun |
|||
{ |
|||
public class AbpAliyunTestBase : AbpTestsBase<AbpAliyunSmsTestModule> |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using LINGYUN.Abp.Aliyun; |
|||
using LINYUN.Abp.Sms.Aliyun; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.Sms.Aliyun |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpAliyunTestModule), |
|||
typeof(AbpAliyunSmsModule))] |
|||
public class AbpAliyunSmsTestModule : AbpModule |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
using Microsoft.Extensions.Configuration; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Sms; |
|||
using Xunit; |
|||
|
|||
namespace LINGYUN.Abp.Sms.Aliyun |
|||
{ |
|||
public class AliyunSmsSenderTests : AbpAliyunTestBase |
|||
{ |
|||
protected ISmsSender SmsSender { get; } |
|||
protected IConfiguration Configuration { get; } |
|||
|
|||
public AliyunSmsSenderTests() |
|||
{ |
|||
SmsSender = GetRequiredService<ISmsSender>(); |
|||
Configuration = GetRequiredService<IConfiguration>(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 阿里云短信测试
|
|||
/// </summary>
|
|||
/// <param name="code"></param>
|
|||
/// <returns></returns>
|
|||
[Theory] |
|||
[InlineData("123456")] |
|||
public async Task Send_Test(string code) |
|||
{ |
|||
var signName = Configuration["Aliyun:Sms:Sender:SignName"]; |
|||
var phone = Configuration["Aliyun:Sms:Sender:PhoneNumber"]; |
|||
var template = Configuration["Aliyun:Sms:Sender:TemplateCode"]; |
|||
|
|||
await SmsSender.SendAsync( |
|||
signName, |
|||
template, |
|||
phone, |
|||
new Dictionary<string, object> |
|||
{ |
|||
{ "code", code } |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net5.0</TargetFramework> |
|||
<RootNamespace /> |
|||
<IsPackable>false</IsPackable> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" /> |
|||
<PackageReference Include="NSubstitute" Version="4.2.1" /> |
|||
<PackageReference Include="Shouldly" Version="3.0.2" /> |
|||
<PackageReference Include="xunit" Version="2.4.1" /> |
|||
<PackageReference Include="xunit.extensibility.execution" Version="2.4.1" /> |
|||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\modules\platform\LINGYUN.Platform.Domain\LINGYUN.Platform.Domain.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,40 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Data; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.Threading; |
|||
|
|||
namespace LINGYUN.Platform |
|||
{ |
|||
[DependsOn( |
|||
typeof(PlatformDomainModule) |
|||
)] |
|||
public class PlatformDomainTestModule : AbpModule |
|||
{ |
|||
public override void OnApplicationInitialization(ApplicationInitializationContext context) |
|||
{ |
|||
SeedTestData(context); |
|||
} |
|||
|
|||
private static void SeedTestData(ApplicationInitializationContext context) |
|||
{ |
|||
using (var scope = context.ServiceProvider.CreateScope()) |
|||
{ |
|||
var dataSeeder = scope.ServiceProvider.GetRequiredService<IDataSeeder>(); |
|||
AsyncHelper.RunSync(async () => |
|||
{ |
|||
// 预置宿主数据
|
|||
await dataSeeder.SeedAsync(); |
|||
// 预置租户数据
|
|||
await dataSeeder.SeedAsync(PlatformTestsConsts.TenantId); |
|||
}); |
|||
AsyncHelper.RunSync(async () => |
|||
{ |
|||
await scope.ServiceProvider |
|||
.GetRequiredService<PlatformTestsDataBuilder>() |
|||
.BuildAsync(); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System; |
|||
|
|||
namespace LINGYUN.Platform |
|||
{ |
|||
public static class PlatformTestsConsts |
|||
{ |
|||
public static Guid User1Id { get; } = Guid.NewGuid(); |
|||
|
|||
public static Guid User2Id { get; } = Guid.NewGuid(); |
|||
|
|||
public static Guid TenantId { get; } = Guid.NewGuid(); |
|||
|
|||
public static string Role1Name { get; } = "TestRole1"; |
|||
|
|||
public static string Role2Name { get; } = "TestRole2"; |
|||
} |
|||
} |
|||
@ -0,0 +1,65 @@ |
|||
using LINGYUN.Platform.Menus; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Volo.Abp.Uow; |
|||
|
|||
namespace LINGYUN.Platform |
|||
{ |
|||
public class PlatformTestsDataBuilder : ITransientDependency |
|||
{ |
|||
private readonly ICurrentTenant _currentTenant; |
|||
|
|||
private readonly MenuManager _menuManager; |
|||
private readonly IMenuRepository _menuRepository; |
|||
|
|||
public PlatformTestsDataBuilder( |
|||
ICurrentTenant currentTenant, |
|||
MenuManager menuManager, |
|||
IMenuRepository menuRepository) |
|||
{ |
|||
_currentTenant = currentTenant; |
|||
|
|||
_menuManager = menuManager; |
|||
_menuRepository = menuRepository; |
|||
} |
|||
|
|||
[UnitOfWork] |
|||
public async Task BuildAsync() |
|||
{ |
|||
var adminMenu = await _menuRepository.FindByNameAsync("admin"); |
|||
|
|||
var saasMenu = await _menuRepository.FindByNameAsync("saas"); |
|||
await SetRoleMenusAsync(PlatformTestsConsts.Role1Name, new Guid[] { saasMenu.Id }); |
|||
await SetRoleMenusAsync(PlatformTestsConsts.Role2Name, new Guid[] { adminMenu.Id, saasMenu.Id }); |
|||
|
|||
await SetUserMenusAsync(PlatformTestsConsts.User1Id, new Guid[] { saasMenu.Id }); |
|||
|
|||
|
|||
using (_currentTenant.Change(PlatformTestsConsts.TenantId)) |
|||
{ |
|||
var tenantAdminMenu = await _menuRepository.FindByNameAsync("admin"); |
|||
await SetUserMenusAsync(PlatformTestsConsts.User2Id, new Guid[] { tenantAdminMenu.Id }); |
|||
await SetRoleMenusAsync(PlatformTestsConsts.Role1Name, new Guid[] { tenantAdminMenu.Id }); |
|||
} |
|||
} |
|||
|
|||
private async Task SetUserMenusAsync(Guid userId, IEnumerable<Guid> menusIds) |
|||
{ |
|||
await _menuManager |
|||
.SetUserMenusAsync( |
|||
userId, |
|||
menusIds); |
|||
} |
|||
|
|||
private async Task SetRoleMenusAsync(string roleName, IEnumerable<Guid> menusIds) |
|||
{ |
|||
await _menuManager |
|||
.SetRoleMenusAsync( |
|||
roleName, |
|||
menusIds); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net5.0</TargetFramework> |
|||
<RootNamespace /> |
|||
<IsPackable>false</IsPackable> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" /> |
|||
<PackageReference Include="NSubstitute" Version="4.2.1" /> |
|||
<PackageReference Include="Shouldly" Version="3.0.2" /> |
|||
<PackageReference Include="xunit" Version="2.4.1" /> |
|||
<PackageReference Include="xunit.extensibility.execution" Version="2.4.1" /> |
|||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\modules\platform\LINGYUN.Platform.EntityFrameworkCore\LINGYUN.Platform.EntityFrameworkCore.csproj" /> |
|||
<ProjectReference Include="..\LINGYUN.Abp.EntityFrameworkCore.Tests\LINGYUN.Abp.EntityFrameworkCore.Tests.csproj" /> |
|||
<ProjectReference Include="..\LINGYUN.Platform.Domain.Tests\LINGYUN.Platform.Domain.Tests.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,9 @@ |
|||
using LINGYUN.Abp.Tests; |
|||
|
|||
namespace LINGYUN.Platform.EntityFrameworkCore |
|||
{ |
|||
public class PlatformEntityFrameworkCoreTestBase : AbpTestsBase<PlatformEntityFrameworkCoreTestModule> |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using LINGYUN.Abp.EntityFrameworkCore.Tests; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Platform.EntityFrameworkCore |
|||
{ |
|||
[DependsOn( |
|||
typeof(PlatformDomainTestModule), |
|||
typeof(PlatformEntityFrameworkCoreModule), |
|||
typeof(AbpEntityFrameworkCoreTestModule) |
|||
)] |
|||
public class PlatformEntityFrameworkCoreTestModule : AbpModule |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,68 @@ |
|||
using LINGYUN.Platform.EntityFrameworkCore; |
|||
using Shouldly; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.MultiTenancy; |
|||
using Xunit; |
|||
|
|||
namespace LINGYUN.Platform.Menus |
|||
{ |
|||
public class EfCoreUserMenuRepositoryTests : PlatformEntityFrameworkCoreTestBase |
|||
{ |
|||
protected ICurrentTenant CurrentTenant { get; } |
|||
protected IUserMenuRepository Repository { get; } |
|||
protected IMenuRepository MenuRepository { get; } |
|||
protected MenuManager MenuManager { get; } |
|||
|
|||
public EfCoreUserMenuRepositoryTests() |
|||
{ |
|||
MenuManager = GetRequiredService<MenuManager>(); |
|||
Repository = GetRequiredService<IUserMenuRepository>(); |
|||
MenuRepository = GetRequiredService<IMenuRepository>(); |
|||
|
|||
CurrentTenant = GetRequiredService<ICurrentTenant>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task UserHasInMenuAsync_Test() |
|||
{ |
|||
(await Repository.UserHasInMenuAsync(PlatformTestsConsts.User1Id, "saas")).ShouldBeTrue(); |
|||
(await Repository.UserHasInMenuAsync(PlatformTestsConsts.User2Id, "admin")).ShouldBeFalse(); |
|||
|
|||
using (CurrentTenant.Change(PlatformTestsConsts.TenantId)) |
|||
{ |
|||
(await Repository.UserHasInMenuAsync(PlatformTestsConsts.User2Id, "admin")).ShouldBeTrue(); |
|||
} |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task SetMemberMenusAsync_Test() |
|||
{ |
|||
var adminMenu = await MenuRepository.FindByNameAsync("admin"); |
|||
var saasMenu = await MenuRepository.FindByNameAsync("saas"); |
|||
|
|||
await MenuManager.SetUserMenusAsync(PlatformTestsConsts.User1Id, new Guid[] { adminMenu.Id}); |
|||
await MenuManager.SetUserMenusAsync(PlatformTestsConsts.User2Id, new Guid[] { adminMenu.Id, saasMenu.Id }); |
|||
|
|||
(await Repository.UserHasInMenuAsync(PlatformTestsConsts.User1Id, "admin")).ShouldBeTrue(); |
|||
(await Repository.UserHasInMenuAsync(PlatformTestsConsts.User2Id, "admin")).ShouldBeTrue(); |
|||
(await Repository.UserHasInMenuAsync(PlatformTestsConsts.User2Id, "saas")).ShouldBeTrue(); |
|||
|
|||
using (CurrentTenant.Change(PlatformTestsConsts.TenantId)) |
|||
{ |
|||
(await Repository.UserHasInMenuAsync(PlatformTestsConsts.User1Id, "admin")).ShouldBeFalse(); |
|||
|
|||
var tenantSaasMenu = await MenuRepository.FindByNameAsync("saas"); |
|||
|
|||
var ss = await Repository.GetListByUserIdAsync(PlatformTestsConsts.User2Id); |
|||
|
|||
await MenuManager.SetUserMenusAsync(PlatformTestsConsts.User2Id, new Guid[] { tenantSaasMenu.Id }); |
|||
|
|||
var ss1 = await Repository.GetListByUserIdAsync(PlatformTestsConsts.User2Id); |
|||
|
|||
(await Repository.UserHasInMenuAsync(PlatformTestsConsts.User2Id, "admin")).ShouldBeFalse(); |
|||
(await Repository.UserHasInMenuAsync(PlatformTestsConsts.User2Id, "saas")).ShouldBeTrue(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue