DocSpace-client/common/services/ASC.Data.Backup/BackupAjaxHandler.cs

431 lines
15 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Linq;
using AjaxPro;
using ASC.Common;
2020-06-08 10:40:26 +00:00
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;
2020-06-08 10:40:26 +00:00
using Microsoft.Extensions.DependencyInjection;
namespace ASC.Data.Backup
{
[AjaxNamespace("AjaxPro.Backup")]
public class BackupAjaxHandler
{
2020-06-03 09:15:05 +00:00
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; }
2020-06-08 10:40:26 +00:00
private IServiceProvider ServiceProvider { get; }
2020-06-04 10:47:22 +00:00
private BackupServiceClient BackupServiceClient { get; }
#region backup
2020-06-10 12:35:10 +00:00
public BackupAjaxHandler(BackupServiceClient backupServiceClient, IServiceProvider serviceProvider, TenantManager tenantManager, MessageService messageService, CoreBaseSettings coreBaseSettings, CoreConfiguration coreConfiguration, PermissionContext permissionContext, SecurityContext securityContext, UserManager userManager, TenantExtra tenantExtra, BackupHelper backupHelper, ConsumerFactory consumerFactory)
{
2020-06-04 10:47:22 +00:00
TenantManager = tenantManager;
MessageService = messageService;
CoreBaseSettings = coreBaseSettings;
CoreConfiguration = coreConfiguration;
PermissionContext = permissionContext;
SecurityContext = securityContext;
UserManager = userManager;
TenantExtra = tenantExtra;
BackupHelper = backupHelper;
ConsumerFactory = consumerFactory;
2020-06-08 10:40:26 +00:00
ServiceProvider = serviceProvider;
2020-06-10 12:35:10 +00:00
BackupServiceClient = backupServiceClient;
}
[AjaxMethod]
public BackupProgress StartBackup(BackupStorageType storageType, Dictionary<string, string> storageParams, bool backupMail)
{
DemandPermissionsBackup();
DemandSize();
var backupRequest = new StartBackupRequest
{
TenantId = GetCurrentTenantId(),
2020-06-08 10:40:26 +00:00
UserId = SecurityContext.CurrentAccount.ID.ToString(),
BackupMail = backupMail,
2020-06-08 10:40:26 +00:00
StorageType = (int)storageType
};
2020-06-08 10:40:26 +00:00
backupRequest.StorageParams.Add(storageParams);
switch (storageType)
{
case BackupStorageType.ThridpartyDocuments:
case BackupStorageType.Documents:
backupRequest.StorageBasePath = storageParams["folderId"];
break;
case BackupStorageType.Local:
2020-06-03 09:15:05 +00:00
if (!CoreBaseSettings.Standalone) throw new Exception("Access denied");
backupRequest.StorageBasePath = storageParams["filePath"];
break;
}
2020-06-03 09:15:05 +00:00
MessageService.Send(MessageAction.StartBackupSetting);
2020-06-10 12:35:10 +00:00
2020-06-08 10:40:26 +00:00
return BackupServiceClient.StartBackup(backupRequest);
}
[AjaxMethod]
[SecurityPassthrough]
public BackupProgress GetBackupProgress()
{
DemandPermissionsBackup();
2020-06-04 10:47:22 +00:00
return BackupServiceClient.GetBackupProgress(GetCurrentTenantId());
}
[AjaxMethod]
public void DeleteBackup(Guid id)
{
DemandPermissionsBackup();
2020-06-04 10:47:22 +00:00
BackupServiceClient.DeleteBackup(id);
}
[AjaxMethod]
public void DeleteAllBackups()
{
DemandPermissionsBackup();
2020-06-04 10:47:22 +00:00
BackupServiceClient.DeleteAllBackups(GetCurrentTenantId());
}
[AjaxMethod]
public List<BackupHistoryRecord> GetBackupHistory()
{
DemandPermissionsBackup();
2020-06-04 10:47:22 +00:00
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
{
2020-06-03 09:15:05 +00:00
TenantId = TenantManager.GetCurrentTenant().TenantId,
BackupMail = backupMail,
Cron = cronParams.ToString(),
NumberOfBackupsStored = backupsStored,
2020-06-08 10:40:26 +00:00
StorageType = (int)storageType
};
2020-06-08 10:40:26 +00:00
scheduleRequest.StorageParams.Add(storageParams);
switch (storageType)
{
case BackupStorageType.ThridpartyDocuments:
case BackupStorageType.Documents:
scheduleRequest.StorageBasePath = storageParams["folderId"];
break;
case BackupStorageType.Local:
2020-06-03 09:15:05 +00:00
if (!CoreBaseSettings.Standalone) throw new Exception("Access denied");
scheduleRequest.StorageBasePath = storageParams["filePath"];
break;
}
2020-06-04 10:47:22 +00:00
BackupServiceClient.CreateSchedule(scheduleRequest);
}
[AjaxMethod]
public Schedule GetSchedule()
{
DemandPermissionsBackup();
ScheduleResponse response;
2020-06-04 10:47:22 +00:00
response = BackupServiceClient.GetSchedule(GetCurrentTenantId());
if (response == null)
{
2020-06-04 10:47:22 +00:00
return null;
}
var schedule = new Schedule
{
2020-06-08 10:40:26 +00:00
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,
2020-06-08 10:40:26 +00:00
LastBackupTime = response.LastBackupTime.ToDateTime()
};
2020-06-08 10:40:26 +00:00
if ((BackupStorageType)response.StorageType == BackupStorageType.CustomCloud)
{
2020-06-03 09:15:05 +00:00
var amazonSettings = CoreConfiguration.GetSection<AmazonS3Settings>();
2020-06-10 12:35:10 +00:00
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");
2020-06-08 10:40:26 +00:00
var Schedule = new CreateScheduleRequest
{
2020-06-04 10:47:22 +00:00
TenantId = TenantManager.GetCurrentTenant().TenantId,
BackupMail = schedule.BackupMail,
Cron = schedule.CronParams.ToString(),
NumberOfBackupsStored = schedule.BackupsStored,
2020-06-08 10:40:26 +00:00
StorageType = (int)schedule.StorageType
};
Schedule.StorageParams.Add(schedule.StorageParams);
BackupServiceClient.CreateSchedule(Schedule);
}
2020-06-08 10:40:26 +00:00
else if ((BackupStorageType)response.StorageType != BackupStorageType.ThirdPartyConsumer)
{
schedule.StorageParams["folderId"] = response.StorageBasePath;
}
return schedule;
}
[AjaxMethod]
public void DeleteSchedule()
{
DemandPermissionsBackup();
2020-06-04 10:47:22 +00:00
BackupServiceClient.DeleteSchedule(GetCurrentTenantId());
}
private void DemandPermissionsBackup()
{
2020-06-03 09:15:05 +00:00
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(),
2020-06-08 10:40:26 +00:00
NotifyAfterCompletion = notify
};
2020-06-08 10:40:26 +00:00
restoreRequest.StorageParams.Add(storageParams);
Guid guidBackupId;
if (Guid.TryParse(backupId, out guidBackupId))
{
2020-06-08 10:40:26 +00:00
restoreRequest.BackupId = guidBackupId.ToString();
}
else
{
2020-06-08 10:40:26 +00:00
restoreRequest.StorageType = (int)storageType;
restoreRequest.FilePathOrId = storageParams["filePath"];
}
2020-06-08 10:40:26 +00:00
return BackupServiceClient.StartRestore(restoreRequest);
}
[AjaxMethod]
[SecurityPassthrough]
public BackupProgress GetRestoreProgress()
{
BackupProgress result;
2020-06-03 09:15:05 +00:00
var tenant = TenantManager.GetCurrentTenant();
2020-06-08 10:40:26 +00:00
result = BackupServiceClient.GetRestoreProgress(tenant.TenantId);
return result;
}
private void DemandPermissionsRestore()
{
2020-06-03 09:15:05 +00:00
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();
2020-06-03 09:15:05 +00:00
MessageService.Send(MessageAction.StartTransferSetting);
2020-06-04 10:47:22 +00:00
return BackupServiceClient.StartTransfer(
new StartTransferRequest
{
TenantId = GetCurrentTenantId(),
TargetRegion = targetRegion,
BackupMail = transferMail,
NotifyUsers = notifyUsers
});
}
[AjaxMethod]
[SecurityPassthrough]
public BackupProgress GetTransferProgress()
{
2020-06-04 10:47:22 +00:00
return BackupServiceClient.GetTransferProgress(GetCurrentTenantId());
}
private void DemandPermissionsTransfer()
{
2020-06-03 09:15:05 +00:00
PermissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
2020-06-03 09:15:05 +00:00
var currentUser = UserManager.GetUsers(SecurityContext.CurrentAccount.ID);
if (!SetupInfo.IsVisibleSettings(ManagementType.Migration.ToString())
2020-06-04 10:47:22 +00:00
|| !currentUser.IsOwner(TenantManager.GetCurrentTenant())
2020-06-03 09:15:05 +00:00
|| !SetupInfo.IsSecretEmail(currentUser.Email) && !TenantExtra.GetTenantQuota().HasMigration)
throw new InvalidOperationException(Resource.ErrorNotAllowedOption);
}
#endregion
public string GetTmpFolder()
{
2020-06-04 10:47:22 +00:00
return BackupServiceClient.GetTmpFolder();
}
private void DemandSize()
{
2020-06-04 10:47:22 +00:00
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()
{
2020-06-03 09:15:05 +00:00
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()
2020-06-03 09:15:05 +00:00
.AddConsumerFactoryService()
2020-06-04 10:47:22 +00:00
.AddBackupHelperService()
.AddBackupServiceClient();
}
}
}