DocSpace-client/common/ASC.Data.Backup.Core/BackupAjaxHandler.cs
pavelbannov 320a1f2250 Merge branch 'develop' into feature/backend-refactor
# Conflicts:
#	common/ASC.Api.Core/Core/BaseStartup.cs
#	common/ASC.Common/Caching/AscCache.cs
#	common/ASC.Common/Data/StreamExtension.cs
#	common/ASC.Common/Utils/RandomString.cs
#	common/ASC.Core.Common/Billing/CouponManager.cs
#	common/ASC.Core.Common/Billing/License/LicenseReader.cs
#	common/ASC.Core.Common/Core/UserGroupRef.cs
#	common/ASC.Core.Common/Data/DbTenantService.cs
#	common/ASC.Core.Common/Notify/Jabber/JabberServiceClientWcf.cs
#	common/ASC.Core.Common/Notify/Telegram/Dao/CachedTelegramDao.cs
#	common/ASC.Data.Backup.Core/Core/DbHelper.cs
#	common/ASC.Data.Backup.Core/Storage/BackupRepository.cs
#	common/ASC.Data.Backup.Core/Tasks/Data/TableInfo.cs
#	common/ASC.Data.Storage/BaseStorage.cs
#	common/ASC.Data.Storage/DiscStorage/DiscDataStore.cs
#	common/ASC.Data.Storage/GoogleCloud/GoogleCloudStorage.cs
#	common/ASC.Data.Storage/RackspaceCloud/RackspaceCloudStorage.cs
#	common/ASC.Data.Storage/S3/S3Storage.cs
#	common/ASC.Notify.Textile/JabberStyler.cs
#	common/ASC.Textile/Blocks/GlyphBlockModifier.cs
#	common/ASC.Textile/States/TableRowFormatterState.cs
#	common/services/ASC.ApiSystem/Classes/CommonMethods.cs
#	common/services/ASC.ApiSystem/Controllers/PortalController.cs
#	common/services/ASC.ClearEvents/Program.cs
#	common/services/ASC.TelegramService/Startup.cs
#	common/services/ASC.UrlShortener.Svc/Program.cs
#	products/ASC.Files/Core/Core/Entries/File.cs
#	products/ASC.Files/Core/Core/Entries/FileEntry.cs
#	products/ASC.Files/Core/Core/Entries/FileHelper.cs
#	products/ASC.Files/Core/Core/Entries/Folder.cs
#	products/ASC.Files/Core/Core/FileStorageService.cs
#	products/ASC.Files/Core/Core/Thirdparty/ProviderDao/ProviderDaoBase.cs
#	products/ASC.Files/Core/Helpers/ThirdpartyConfiguration.cs
#	products/ASC.Files/Core/HttpHandlers/FileHandler.ashx.cs
#	products/ASC.Files/Core/Services/DocumentService/Configuration.cs
#	products/ASC.Files/Core/Services/DocumentService/DocumentServiceConnector.cs
#	products/ASC.Files/Core/Services/DocumentService/DocumentServiceTracker.cs
#	products/ASC.Files/Core/Services/WCFService/FileOperations/FileDownloadOperation.cs
#	products/ASC.Files/Core/Services/WCFService/FileOperations/FileMoveCopyOperation.cs
#	products/ASC.Files/Core/Utils/EntryManager.cs
#	products/ASC.Files/Server/Helpers/FilesControllerHelper.cs
#	products/ASC.Files/Server/Startup.cs
#	products/ASC.Files/Service/Thumbnail/Builder.cs
#	products/ASC.Files/Service/Thumbnail/FileDataProvider.cs
#	products/ASC.People/Server/Startup.cs
#	web/ASC.Web.Core/Files/DocumentService.cs
#	web/ASC.Web.Core/Files/DocumentServiceLicense.cs
#	web/ASC.Web.Core/QuotaSync.cs
#	web/ASC.Web.Core/Sms/SmsKeyStorage.cs
#	web/ASC.Web.Core/Users/UserManagerWrapper.cs
#	web/ASC.Web.HealthChecks.UI/Program.cs
#	web/ASC.Web.Studio/Startup.cs
2022-02-10 13:16:33 +03:00

386 lines
13 KiB
C#

namespace ASC.Data.Backup
{
[Scope]
public class BackupAjaxHandler
{
private TenantManager TenantManager { get; }
private MessageService MessageService { get; }
private CoreBaseSettings CoreBaseSettings { get; }
private CoreConfiguration CoreConfiguration { get; }
private PermissionContext PermissionContext { get; }
private SecurityContext SecurityContext { get; }
private UserManager UserManager { get; }
private TenantExtra TenantExtra { get; }
private ConsumerFactory ConsumerFactory { get; }
private BackupFileUploadHandler BackupFileUploadHandler { get; }
private BackupService BackupService { get; }
#region backup
public BackupAjaxHandler(
BackupService backupService,
TenantManager tenantManager,
MessageService messageService,
CoreBaseSettings coreBaseSettings,
CoreConfiguration coreConfiguration,
PermissionContext permissionContext,
SecurityContext securityContext,
UserManager userManager,
TenantExtra tenantExtra,
ConsumerFactory consumerFactory,
BackupFileUploadHandler backupFileUploadHandler)
{
TenantManager = tenantManager;
MessageService = messageService;
CoreBaseSettings = coreBaseSettings;
CoreConfiguration = coreConfiguration;
PermissionContext = permissionContext;
SecurityContext = securityContext;
UserManager = userManager;
TenantExtra = tenantExtra;
ConsumerFactory = consumerFactory;
BackupFileUploadHandler = backupFileUploadHandler;
BackupService = backupService;
}
public void StartBackup(BackupStorageType storageType, Dictionary<string, string> storageParams, bool backupMail)
{
DemandPermissionsBackup();
var backupRequest = new StartBackupRequest
{
TenantId = GetCurrentTenantId(),
UserId = SecurityContext.CurrentAccount.ID,
BackupMail = backupMail,
StorageType = storageType,
StorageParams = storageParams
};
switch (storageType)
{
case BackupStorageType.ThridpartyDocuments:
case BackupStorageType.Documents:
backupRequest.StorageBasePath = storageParams["folderId"];
break;
case BackupStorageType.Local:
if (!CoreBaseSettings.Standalone) throw new Exception("Access denied");
backupRequest.StorageBasePath = storageParams["filePath"];
break;
}
MessageService.Send(MessageAction.StartBackupSetting);
BackupService.StartBackup(backupRequest);
}
public BackupProgress GetBackupProgress()
{
DemandPermissionsBackup();
return BackupService.GetBackupProgress(GetCurrentTenantId());
}
public BackupProgress GetBackupProgress(int tenantId)
{
DemandPermissionsBackup();
return BackupService.GetBackupProgress(tenantId);
}
public void DeleteBackup(Guid id)
{
DemandPermissionsBackup();
BackupService.DeleteBackup(id);
}
public void DeleteAllBackups()
{
DemandPermissionsBackup();
BackupService.DeleteAllBackups(GetCurrentTenantId());
}
public List<BackupHistoryRecord> GetBackupHistory()
{
DemandPermissionsBackup();
return BackupService.GetBackupHistory(GetCurrentTenantId());
}
public void CreateSchedule(BackupStorageType storageType, Dictionary<string, string> storageParams, int backupsStored, CronParams cronParams, bool backupMail)
{
DemandPermissionsBackup();
if (!SetupInfo.IsVisibleSettings("AutoBackup"))
throw new InvalidOperationException(Resource.ErrorNotAllowedOption);
ValidateCronSettings(cronParams);
var scheduleRequest = new CreateScheduleRequest
{
TenantId = TenantManager.GetCurrentTenant().TenantId,
BackupMail = backupMail,
Cron = cronParams.ToString(),
NumberOfBackupsStored = backupsStored,
StorageType = storageType,
StorageParams = storageParams
};
switch (storageType)
{
case BackupStorageType.ThridpartyDocuments:
case BackupStorageType.Documents:
scheduleRequest.StorageBasePath = storageParams["folderId"];
break;
case BackupStorageType.Local:
if (!CoreBaseSettings.Standalone) throw new Exception("Access denied");
scheduleRequest.StorageBasePath = storageParams["filePath"];
break;
}
BackupService.CreateSchedule(scheduleRequest);
}
public Schedule GetSchedule()
{
DemandPermissionsBackup();
ScheduleResponse response;
response = BackupService.GetSchedule(GetCurrentTenantId());
if (response == null)
{
return null;
}
var schedule = new Schedule
{
StorageType = response.StorageType,
StorageParams = response.StorageParams.ToDictionary(r => r.Key, r => r.Value) ?? new Dictionary<string, string>(),
CronParams = new CronParams(response.Cron),
BackupMail = response.BackupMail.NullIfDefault(),
BackupsStored = response.NumberOfBackupsStored.NullIfDefault(),
LastBackupTime = response.LastBackupTime
};
if (response.StorageType == BackupStorageType.CustomCloud)
{
var amazonSettings = CoreConfiguration.GetSection<AmazonS3Settings>();
var consumer = ConsumerFactory.GetByKey<DataStoreConsumer>("s3");
if (!consumer.IsSet)
{
consumer["acesskey"] = amazonSettings.AccessKeyId;
consumer["secretaccesskey"] = amazonSettings.SecretAccessKey;
consumer["bucket"] = amazonSettings.Bucket;
consumer["region"] = amazonSettings.Region;
}
schedule.StorageType = BackupStorageType.ThirdPartyConsumer;
schedule.StorageParams = consumer.AdditionalKeys.ToDictionary(r => r, r => consumer[r]);
schedule.StorageParams.Add("module", "S3");
var Schedule = new CreateScheduleRequest
{
TenantId = TenantManager.GetCurrentTenant().TenantId,
BackupMail = schedule.BackupMail != null && (bool)schedule.BackupMail,
Cron = schedule.CronParams.ToString(),
NumberOfBackupsStored = schedule.BackupsStored == null ? 0 : (int)schedule.BackupsStored,
StorageType = schedule.StorageType,
StorageParams = schedule.StorageParams
};
BackupService.CreateSchedule(Schedule);
}
else if (response.StorageType != BackupStorageType.ThirdPartyConsumer)
{
schedule.StorageParams["folderId"] = response.StorageBasePath;
}
return schedule;
}
public void DeleteSchedule()
{
DemandPermissionsBackup();
BackupService.DeleteSchedule(GetCurrentTenantId());
}
private void DemandPermissionsBackup()
{
PermissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
if (!SetupInfo.IsVisibleSettings(nameof(ManagementType.Backup)))
throw new BillingException(Resource.ErrorNotAllowedOption, "Backup");
}
#endregion
#region restore
public void StartRestore(string backupId, BackupStorageType storageType, Dictionary<string, string> storageParams, bool notify)
{
DemandPermissionsRestore();
var restoreRequest = new StartRestoreRequest
{
TenantId = GetCurrentTenantId(),
NotifyAfterCompletion = notify,
StorageParams = storageParams
};
if (Guid.TryParse(backupId, out var guidBackupId))
{
restoreRequest.BackupId = guidBackupId;
}
else
{
restoreRequest.StorageType = storageType;
restoreRequest.FilePathOrId = storageParams["filePath"];
if (restoreRequest.StorageType == BackupStorageType.Local && !CoreBaseSettings.Standalone)
{
restoreRequest.FilePathOrId = BackupFileUploadHandler.GetFilePath();
}
}
BackupService.StartRestore(restoreRequest);
}
public BackupProgress GetRestoreProgress()
{
BackupProgress result;
var tenant = TenantManager.GetCurrentTenant();
result = BackupService.GetRestoreProgress(tenant.TenantId);
return result;
}
private void DemandPermissionsRestore()
{
PermissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
if (!SetupInfo.IsVisibleSettings("Restore") ||
(!CoreBaseSettings.Standalone && !TenantManager.GetTenantQuota(TenantManager.GetCurrentTenant().TenantId).Restore))
throw new BillingException(Resource.ErrorNotAllowedOption, "Restore");
}
#endregion
#region transfer
public void StartTransfer(string targetRegion, bool notifyUsers, bool transferMail)
{
DemandPermissionsTransfer();
MessageService.Send(MessageAction.StartTransferSetting);
BackupService.StartTransfer(
new StartTransferRequest
{
TenantId = GetCurrentTenantId(),
TargetRegion = targetRegion,
BackupMail = transferMail,
NotifyUsers = notifyUsers
});
}
public BackupProgress GetTransferProgress()
{
return BackupService.GetTransferProgress(GetCurrentTenantId());
}
private void DemandPermissionsTransfer()
{
PermissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
var currentUser = UserManager.GetUsers(SecurityContext.CurrentAccount.ID);
if (!SetupInfo.IsVisibleSettings(nameof(ManagementType.Migration))
|| !currentUser.IsOwner(TenantManager.GetCurrentTenant())
|| !SetupInfo.IsSecretEmail(currentUser.Email) && !TenantExtra.GetTenantQuota().HasMigration)
throw new InvalidOperationException(Resource.ErrorNotAllowedOption);
}
#endregion
public string GetTmpFolder()
{
return BackupService.GetTmpFolder();
}
private static void ValidateCronSettings(CronParams cronParams)
{
new CronExpression(cronParams.ToString());
}
private int GetCurrentTenantId()
{
return TenantManager.GetCurrentTenant().TenantId;
}
public class Schedule
{
public BackupStorageType StorageType { get; set; }
public Dictionary<string, string> StorageParams { get; set; }
public CronParams CronParams { get; set; }
public bool? BackupMail { get; set; }
public int? BackupsStored { get; set; }
public DateTime LastBackupTime { get; set; }
}
public class CronParams
{
public BackupPeriod Period { get; set; }
public int Hour { get; set; }
public int Day { get; set; }
public CronParams()
{
}
public CronParams(string cronString)
{
var tokens = cronString.Split(' ');
Hour = Convert.ToInt32(tokens[2]);
if (tokens[3] != "?")
{
Period = BackupPeriod.EveryMonth;
Day = Convert.ToInt32(tokens[3]);
}
else if (tokens[5] != "*")
{
Period = BackupPeriod.EveryWeek;
Day = Convert.ToInt32(tokens[5]);
}
else
{
Period = BackupPeriod.EveryDay;
}
}
public override string ToString()
{
return Period switch
{
BackupPeriod.EveryDay => string.Format("0 0 {0} ? * *", Hour),
BackupPeriod.EveryMonth => string.Format("0 0 {0} {1} * ?", Hour, Day),
BackupPeriod.EveryWeek => string.Format("0 0 {0} ? * {1}", Hour, Day),
_ => base.ToString(),
};
}
}
public enum BackupPeriod
{
EveryDay = 0,
EveryWeek = 1,
EveryMonth = 2
}
}
}