28 changed files with 1152 additions and 1410 deletions
@ -1,75 +0,0 @@ |
|||
using LINGYUN.Abp.OssManagement.Localization; |
|||
using Volo.Abp.Features; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Validation.StringValues; |
|||
|
|||
namespace LINGYUN.Abp.OssManagement.Features |
|||
{ |
|||
public class AbpOssManagementFeatureDefinitionProvider : FeatureDefinitionProvider |
|||
{ |
|||
public override void Define(IFeatureDefinitionContext context) |
|||
{ |
|||
var featureGroup = context.AddGroup( |
|||
name: AbpOssManagementFeatureNames.GroupName, |
|||
displayName: L("Features:OssManagement")); |
|||
|
|||
var ossFeature = featureGroup.AddFeature( |
|||
name: AbpOssManagementFeatureNames.OssObject.Default, |
|||
defaultValue: true.ToString(), |
|||
displayName: L("Features:DisplayName:OssObject"), |
|||
description: L("Features:Description:OssObject"), |
|||
valueType: new ToggleStringValueType(new BooleanValueValidator())); |
|||
|
|||
ossFeature.CreateChild( |
|||
name: AbpOssManagementFeatureNames.OssObject.DownloadFile, |
|||
defaultValue: false.ToString(), |
|||
displayName: L("Features:DisplayName:DownloadFile"), |
|||
description: L("Features:Description:DownloadFile"), |
|||
valueType: new ToggleStringValueType(new BooleanValueValidator())); |
|||
ossFeature.CreateChild( |
|||
name: AbpOssManagementFeatureNames.OssObject.DownloadLimit, |
|||
defaultValue: "1000", |
|||
displayName: L("Features:DisplayName:DownloadLimit"), |
|||
description: L("Features:Description:DownloadLimit"), |
|||
valueType: new FreeTextStringValueType(new NumericValueValidator(0, 100_0000))); // 上限100万次调用
|
|||
ossFeature.CreateChild( |
|||
name: AbpOssManagementFeatureNames.OssObject.DownloadInterval, |
|||
defaultValue: "1", |
|||
displayName: L("Features:DisplayName:DownloadInterval"), |
|||
description: L("Features:Description:DownloadInterval"), |
|||
valueType: new FreeTextStringValueType(new NumericValueValidator(1, 12))); // 上限12月
|
|||
|
|||
ossFeature.CreateChild( |
|||
name: AbpOssManagementFeatureNames.OssObject.UploadFile, |
|||
defaultValue: true.ToString(), |
|||
displayName: L("Features:DisplayName:UploadFile"), |
|||
description: L("Features:Description:UploadFile"), |
|||
valueType: new ToggleStringValueType(new BooleanValueValidator())); |
|||
ossFeature.CreateChild( |
|||
name: AbpOssManagementFeatureNames.OssObject.UploadLimit, |
|||
defaultValue: "1000", |
|||
displayName: L("Features:DisplayName:UploadLimit"), |
|||
description: L("Features:Description:UploadLimit"), |
|||
valueType: new FreeTextStringValueType(new NumericValueValidator(0, 100_0000))); // 上限100万次调用
|
|||
ossFeature.CreateChild( |
|||
name: AbpOssManagementFeatureNames.OssObject.UploadInterval, |
|||
defaultValue: "1", |
|||
displayName: L("Features:DisplayName:UploadInterval"), |
|||
description: L("Features:Description:UploadInterval"), |
|||
valueType: new FreeTextStringValueType(new NumericValueValidator(1, 12))); // 上限12月
|
|||
|
|||
// TODO: 此功能需要控制器协同,暂时不实现
|
|||
//fileSystemFeature.CreateChild(
|
|||
// name: AbpOssManagementFeatureNames.OssObject.MaxUploadFileCount,
|
|||
// defaultValue: 1.ToString(),
|
|||
// displayName: L("Features:DisplayName:MaxUploadFileCount"),
|
|||
// description: L("Features:Description:MaxUploadFileCount"),
|
|||
// valueType: new FreeTextStringValueType(new NumericValueValidator(1, 10)));
|
|||
} |
|||
|
|||
protected ILocalizableString L(string name) |
|||
{ |
|||
return LocalizableString.Create<AbpOssManagementResource>(name); |
|||
} |
|||
} |
|||
} |
|||
@ -1,41 +0,0 @@ |
|||
namespace LINGYUN.Abp.OssManagement.Features |
|||
{ |
|||
public class AbpOssManagementFeatureNames |
|||
{ |
|||
public const string GroupName = "AbpOssManagement"; |
|||
|
|||
|
|||
public class OssObject |
|||
{ |
|||
public const string Default = GroupName + ".OssObject"; |
|||
/// <summary>
|
|||
/// 下载文件功能
|
|||
/// </summary>
|
|||
public const string DownloadFile = Default + ".DownloadFile"; |
|||
/// <summary>
|
|||
/// 下载文件功能限制次数
|
|||
/// </summary>
|
|||
public const string DownloadLimit = Default + ".DownloadLimit"; |
|||
/// <summary>
|
|||
/// 下载文件功能限制次数周期
|
|||
/// </summary>
|
|||
public const string DownloadInterval = Default + ".DownloadInterval"; |
|||
/// <summary>
|
|||
/// 上传文件功能
|
|||
/// </summary>
|
|||
public const string UploadFile = Default + ".UploadFile"; |
|||
/// <summary>
|
|||
/// 上传文件功能限制次数
|
|||
/// </summary>
|
|||
public const string UploadLimit = Default + ".UploadLimit"; |
|||
/// <summary>
|
|||
/// 上传文件功能限制次数周期
|
|||
/// </summary>
|
|||
public const string UploadInterval = Default + ".UploadInterval"; |
|||
/// <summary>
|
|||
/// 最大上传文件
|
|||
/// </summary>
|
|||
public const string MaxUploadFileCount = Default + ".MaxUploadFileCount"; |
|||
} |
|||
} |
|||
} |
|||
@ -1,89 +1,16 @@ |
|||
using LINGYUN.Abp.Features.LimitValidation; |
|||
using LINGYUN.Abp.OssManagement.Features; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using System.IO; |
|||
using System.Threading.Tasks; |
|||
using System.Web; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Features; |
|||
using Volo.Abp.Users; |
|||
|
|||
namespace LINGYUN.Abp.OssManagement |
|||
namespace LINGYUN.Abp.OssManagement |
|||
{ |
|||
/// <summary>
|
|||
/// 所有登录用户公开访问文件服务接口
|
|||
/// bucket限制在users
|
|||
/// path限制在用户id
|
|||
/// </summary>
|
|||
[Authorize] |
|||
// 不对外公开,仅通过控制器调用
|
|||
[RemoteService(IsEnabled = false, IsMetadataEnabled = false)] |
|||
public class PublicFileAppService : OssManagementApplicationServiceBase, IPublicFileAppService |
|||
public class PublicFileAppService : FileAppServiceBase, IPublicFileAppService |
|||
{ |
|||
private readonly IFileValidater _fileValidater; |
|||
private readonly IOssContainerFactory _ossContainerFactory; |
|||
|
|||
public PublicFileAppService( |
|||
IFileValidater fileValidater, |
|||
IOssContainerFactory ossContainerFactory) |
|||
: base(fileValidater, ossContainerFactory) |
|||
{ |
|||
_fileValidater = fileValidater; |
|||
_ossContainerFactory = ossContainerFactory; |
|||
} |
|||
|
|||
[RequiresFeature(AbpOssManagementFeatureNames.OssObject.UploadFile)] |
|||
[RequiresLimitFeature( |
|||
AbpOssManagementFeatureNames.OssObject.UploadLimit, |
|||
AbpOssManagementFeatureNames.OssObject.UploadInterval, |
|||
LimitPolicy.Month)] |
|||
public virtual async Task<OssObjectDto> UploadAsync(UploadPublicFileInput input) |
|||
protected override string GetCurrentBucket() |
|||
{ |
|||
await _fileValidater.ValidationAsync(new UploadFile |
|||
{ |
|||
TotalSize = input.Content.Length, |
|||
FileName = input.Object |
|||
}); |
|||
|
|||
var oss = _ossContainerFactory.Create(); |
|||
|
|||
var createOssObjectRequest = new CreateOssObjectRequest( |
|||
"users", |
|||
HttpUtility.UrlDecode(input.Object), |
|||
input.Content, |
|||
GetCurrentUserPath(HttpUtility.UrlDecode(input.Path))) |
|||
{ |
|||
Overwrite = input.Overwrite |
|||
}; |
|||
|
|||
var ossObject = await oss.CreateObjectAsync(createOssObjectRequest); |
|||
|
|||
return ObjectMapper.Map<OssObject, OssObjectDto>(ossObject); |
|||
} |
|||
|
|||
[RequiresFeature(AbpOssManagementFeatureNames.OssObject.DownloadFile)] |
|||
[RequiresLimitFeature( |
|||
AbpOssManagementFeatureNames.OssObject.DownloadLimit, |
|||
AbpOssManagementFeatureNames.OssObject.DownloadInterval, |
|||
LimitPolicy.Month)] |
|||
public virtual async Task<Stream> GetAsync(GetPublicFileInput input) |
|||
{ |
|||
var ossObjectRequest = new GetOssObjectRequest( |
|||
"users", // 需要处理特殊字符
|
|||
HttpUtility.UrlDecode(input.Name), |
|||
GetCurrentUserPath(HttpUtility.UrlDecode(input.Path)), |
|||
HttpUtility.UrlDecode(input.Process)); |
|||
|
|||
var ossContainer = _ossContainerFactory.Create(); |
|||
var ossObject = await ossContainer.GetObjectAsync(ossObjectRequest); |
|||
|
|||
return ossObject.Content; |
|||
} |
|||
|
|||
private string GetCurrentUserPath(string path) |
|||
{ |
|||
path = path.StartsWith("/") ? path.Substring(1) : path; |
|||
var userId = CurrentUser.GetId().ToString(); |
|||
return path.StartsWith(userId) ? path : $"{userId}/{path}"; |
|||
return "public"; |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -1,96 +0,0 @@ |
|||
using LINGYUN.Abp.OssManagement.Localization; |
|||
using LINGYUN.Abp.OssManagement.Settings; |
|||
using Microsoft.Extensions.Caching.Memory; |
|||
using Microsoft.Extensions.Localization; |
|||
using System; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.IO; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace LINGYUN.Abp.OssManagement |
|||
{ |
|||
public class FileValidater : IFileValidater, ISingletonDependency |
|||
{ |
|||
private readonly IMemoryCache _cache; |
|||
private readonly ISettingProvider _settingProvider; |
|||
private readonly IServiceProvider _serviceProvider; |
|||
private readonly IStringLocalizer _stringLocalizer; |
|||
|
|||
public FileValidater( |
|||
IMemoryCache cache, |
|||
ISettingProvider settingProvider, |
|||
IServiceProvider serviceProvider, |
|||
IStringLocalizer<AbpOssManagementResource> stringLocalizer) |
|||
{ |
|||
_cache = cache; |
|||
_settingProvider = settingProvider; |
|||
_serviceProvider = serviceProvider; |
|||
_stringLocalizer = stringLocalizer; |
|||
} |
|||
|
|||
public virtual async Task ValidationAsync(UploadOssObjectInput input) |
|||
{ |
|||
var validation = await GetByCacheItemAsync(); |
|||
if (validation.SizeLimit * 1024 * 1024 < input.TotalSize) |
|||
{ |
|||
throw new UserFriendlyException(_stringLocalizer["UploadFileSizeBeyondLimit", validation.SizeLimit]); |
|||
} |
|||
var fileExtensionName = FileHelper.GetExtension(input.FileName); |
|||
if (!validation.AllowedExtensions |
|||
.Any(fe => fe.Equals(fileExtensionName, StringComparison.CurrentCultureIgnoreCase))) |
|||
{ |
|||
throw new UserFriendlyException(_stringLocalizer["NotAllowedFileExtensionName", fileExtensionName]); |
|||
} |
|||
} |
|||
|
|||
protected virtual async Task<FileValidation> GetByCacheItemAsync() |
|||
{ |
|||
var fileValidation = _cache.Get<FileValidation>(FileValidation.CacheKey); |
|||
if (fileValidation == null) |
|||
{ |
|||
fileValidation = await GetBySettingAsync(); |
|||
_cache.Set(FileValidation.CacheKey, |
|||
fileValidation, |
|||
new MemoryCacheEntryOptions |
|||
{ |
|||
AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(2) |
|||
}); |
|||
} |
|||
return fileValidation; |
|||
} |
|||
|
|||
protected virtual async Task<FileValidation> GetBySettingAsync() |
|||
{ |
|||
var fileSizeLimited = await _settingProvider |
|||
.GetAsync( |
|||
AbpOssManagementSettingNames.FileLimitLength, |
|||
AbpOssManagementSettingNames.DefaultFileLimitLength); |
|||
var fileAllowExtension = await _settingProvider |
|||
.GetOrDefaultAsync(AbpOssManagementSettingNames.AllowFileExtensions, _serviceProvider); |
|||
|
|||
return new FileValidation(fileSizeLimited, fileAllowExtension.Split(',')); |
|||
} |
|||
} |
|||
|
|||
public class FileValidation |
|||
{ |
|||
public const string CacheKey = "Abp.OssManagement.FileValidation"; |
|||
public long SizeLimit { get; set; } |
|||
public string[] AllowedExtensions { get; set; } |
|||
public FileValidation() |
|||
{ |
|||
|
|||
} |
|||
|
|||
public FileValidation( |
|||
long sizeLimit, |
|||
string[] allowedExtensions) |
|||
{ |
|||
SizeLimit = sizeLimit; |
|||
AllowedExtensions = allowedExtensions; |
|||
} |
|||
} |
|||
} |
|||
@ -1,9 +0,0 @@ |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.OssManagement |
|||
{ |
|||
public interface IFileValidater |
|||
{ |
|||
Task ValidationAsync(UploadOssObjectInput input); |
|||
} |
|||
} |
|||
@ -1,20 +0,0 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.OssManagement.SettingManagement |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpOssManagementApplicationContractsModule), |
|||
typeof(AbpAspNetCoreMvcModule))] |
|||
public class AbpOssManagementSettingManagementModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
PreConfigure<IMvcBuilder>(mvcBuilder => |
|||
{ |
|||
mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpOssManagementSettingManagementModule).Assembly); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue