DocSpace-buildtools/common/services/ASC.Data.Backup/BackupAjaxHandler.cs
SuhorukovAnton af2295f98a Backup: fix
2020-06-08 13:40:26 +03:00

433 lines
15 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Linq;
using AjaxPro;
using ASC.Common;
using ASC.Common.Caching;
using ASC.Core;
using ASC.Core.Billing;
using ASC.Core.Common.Configuration;
using ASC.Core.Common.Contracts;
using ASC.Core.Users;
using ASC.MessagingSystem;
using ASC.Notify.Cron;
using ASC.Web.Core.PublicResources;
using ASC.Web.Core.Security;
using ASC.Web.Studio.Core;
using ASC.Web.Studio.Utility;
using Microsoft.Extensions.DependencyInjection;
namespace ASC.Data.Backup
{
[AjaxNamespace("AjaxPro.Backup")]
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 BackupHelper BackupHelper { get; }
private ConsumerFactory ConsumerFactory { get; }
private IServiceProvider ServiceProvider { get; }
private BackupServiceClient BackupServiceClient { get; }
#region backup
public BackupAjaxHandler( IServiceProvider serviceProvider, TenantManager tenantManager, MessageService messageService, CoreBaseSettings coreBaseSettings, CoreConfiguration coreConfiguration, PermissionContext permissionContext, SecurityContext securityContext, UserManager userManager, TenantExtra tenantExtra, BackupHelper backupHelper, ConsumerFactory consumerFactory)
{
TenantManager = tenantManager;
MessageService = messageService;
CoreBaseSettings = coreBaseSettings;
CoreConfiguration = coreConfiguration;
PermissionContext = permissionContext;
SecurityContext = securityContext;
UserManager = userManager;
TenantExtra = tenantExtra;
BackupHelper = backupHelper;
ConsumerFactory = consumerFactory;
ServiceProvider = serviceProvider;
BackupServiceClient = new BackupServiceClient();
}
[AjaxMethod]
public BackupProgress StartBackup(BackupStorageType storageType, Dictionary<string, string> storageParams, bool backupMail)
{
DemandPermissionsBackup();
DemandSize();
var backupRequest = new StartBackupRequest
{
TenantId = GetCurrentTenantId(),
UserId = SecurityContext.CurrentAccount.ID.ToString(),
BackupMail = backupMail,
StorageType = (int)storageType
};
backupRequest.StorageParams.Add(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);
BackupServiceClient.СacheStartBackupRequest = ServiceProvider.GetService<ICacheNotify<StartBackupRequest>>();
return BackupServiceClient.StartBackup(backupRequest);
}
[AjaxMethod]
[SecurityPassthrough]
public BackupProgress GetBackupProgress()
{
DemandPermissionsBackup();
return BackupServiceClient.GetBackupProgress(GetCurrentTenantId());
}
[AjaxMethod]
public void DeleteBackup(Guid id)
{
DemandPermissionsBackup();
BackupServiceClient.DeleteBackup(id);
}
[AjaxMethod]
public void DeleteAllBackups()
{
DemandPermissionsBackup();
BackupServiceClient.DeleteAllBackups(GetCurrentTenantId());
}
[AjaxMethod]
public List<BackupHistoryRecord> GetBackupHistory()
{
DemandPermissionsBackup();
return BackupServiceClient.GetBackupHistory(GetCurrentTenantId());
}
[AjaxMethod]
public void CreateSchedule(BackupStorageType storageType, Dictionary<string, string> storageParams, int backupsStored, CronParams cronParams, bool backupMail)
{
DemandPermissionsBackup();
DemandSize();
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 = (int)storageType
};
scheduleRequest.StorageParams.Add(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;
}
BackupServiceClient.CreateSchedule(scheduleRequest);
}
[AjaxMethod]
public Schedule GetSchedule()
{
DemandPermissionsBackup();
ScheduleResponse response;
response = BackupServiceClient.GetSchedule(GetCurrentTenantId());
if (response == null)
{
return null;
}
var schedule = new Schedule
{
StorageType = (BackupStorageType)response.StorageType,
StorageParams = response.StorageParams.ToDictionary(r => r.Key, r => r.Value) ?? new Dictionary<string, string>(),
CronParams = new CronParams(response.Cron),
BackupMail = response.BackupMail,
BackupsStored = response.NumberOfBackupsStored,
LastBackupTime = response.LastBackupTime.ToDateTime()
};
if ((BackupStorageType)response.StorageType == BackupStorageType.CustomCloud)
{
var amazonSettings = CoreConfiguration.GetSection<AmazonS3Settings>();
var consumer = ConsumerFactory.GetByKey<DataStoreConsumer>("S3");//here
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,
Cron = schedule.CronParams.ToString(),
NumberOfBackupsStored = schedule.BackupsStored,
StorageType = (int)schedule.StorageType
};
Schedule.StorageParams.Add(schedule.StorageParams);
BackupServiceClient.CreateSchedule(Schedule);
}
else if ((BackupStorageType)response.StorageType != BackupStorageType.ThirdPartyConsumer)
{
schedule.StorageParams["folderId"] = response.StorageBasePath;
}
return schedule;
}
[AjaxMethod]
public void DeleteSchedule()
{
DemandPermissionsBackup();
BackupServiceClient.DeleteSchedule(GetCurrentTenantId());
}
private void DemandPermissionsBackup()
{
PermissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
if (!SetupInfo.IsVisibleSettings(ManagementType.Backup.ToString()))
throw new BillingException(Resource.ErrorNotAllowedOption, "Backup");
}
#endregion
#region restore
[AjaxMethod]
public BackupProgress StartRestore(string backupId, BackupStorageType storageType, Dictionary<string, string> storageParams, bool notify)
{
DemandPermissionsRestore();
var restoreRequest = new StartRestoreRequest
{
TenantId = GetCurrentTenantId(),
NotifyAfterCompletion = notify
};
restoreRequest.StorageParams.Add(storageParams);
Guid guidBackupId;
if (Guid.TryParse(backupId, out guidBackupId))
{
restoreRequest.BackupId = guidBackupId.ToString();
}
else
{
restoreRequest.StorageType = (int)storageType;
restoreRequest.FilePathOrId = storageParams["filePath"];
}
BackupServiceClient.СacheStartRestoreRequest = ServiceProvider.GetService<ICacheNotify<StartRestoreRequest>>();
return BackupServiceClient.StartRestore(restoreRequest);
}
[AjaxMethod]
[SecurityPassthrough]
public BackupProgress GetRestoreProgress()
{
BackupProgress result;
var tenant = TenantManager.GetCurrentTenant();
result = BackupServiceClient.GetRestoreProgress(tenant.TenantId);
return result;
}
private void DemandPermissionsRestore()
{
PermissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
if (!SetupInfo.IsVisibleSettings("Restore"))
throw new BillingException(Resource.ErrorNotAllowedOption, "Restore");
}
#endregion
#region transfer
[AjaxMethod]
public BackupProgress StartTransfer(string targetRegion, bool notifyUsers, bool transferMail)
{
DemandPermissionsTransfer();
DemandSize();
MessageService.Send(MessageAction.StartTransferSetting);
BackupServiceClient.СacheStartTransferRequest = ServiceProvider.GetService<ICacheNotify<StartTransferRequest>>();
return BackupServiceClient.StartTransfer(
new StartTransferRequest
{
TenantId = GetCurrentTenantId(),
TargetRegion = targetRegion,
BackupMail = transferMail,
NotifyUsers = notifyUsers
});
}
[AjaxMethod]
[SecurityPassthrough]
public BackupProgress GetTransferProgress()
{
return BackupServiceClient.GetTransferProgress(GetCurrentTenantId());
}
private void DemandPermissionsTransfer()
{
PermissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
var currentUser = UserManager.GetUsers(SecurityContext.CurrentAccount.ID);
if (!SetupInfo.IsVisibleSettings(ManagementType.Migration.ToString())
|| !currentUser.IsOwner(TenantManager.GetCurrentTenant())
|| !SetupInfo.IsSecretEmail(currentUser.Email) && !TenantExtra.GetTenantQuota().HasMigration)
throw new InvalidOperationException(Resource.ErrorNotAllowedOption);
}
#endregion
public string GetTmpFolder()
{
return BackupServiceClient.GetTmpFolder();
}
private void DemandSize()
{
if (BackupHelper.ExceedsMaxAvailableSize(TenantManager.GetCurrentTenant().TenantId))
throw new InvalidOperationException(string.Format(UserControlsCommonResource.BackupSpaceExceed,
FileSizeComment.FilesSizeToString(BackupHelper.AvailableZipSize),
"",
""));
}
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()
{
switch (Period)
{
case BackupPeriod.EveryDay:
return string.Format("0 0 {0} ? * *", Hour);
case BackupPeriod.EveryMonth:
return string.Format("0 0 {0} {1} * ?", Hour, Day);
case BackupPeriod.EveryWeek:
return string.Format("0 0 {0} ? * {1}", Hour, Day);
default:
return base.ToString();
}
}
}
public enum BackupPeriod
{
EveryDay = 0,
EveryWeek = 1,
EveryMonth = 2
}
}
public static class BackupAjaxHandlerExtension
{
public static DIHelper AddBackupAjaxHandler(this DIHelper services)
{
services.TryAddScoped<BackupAjaxHandler>();
return services
.AddTenantManagerService()
.AddCoreBaseSettingsService()
.AddMessageServiceService()
.AddCoreSettingsService()
.AddPermissionContextService()
.AddSecurityContextService()
.AddUserManagerService()
.AddTenantExtraService()
.AddConsumerFactoryService()
.AddBackupHelperService()
.AddBackupServiceClient();
}
}
}