Merge branch 'develop' into feature/branding
This commit is contained in:
commit
b58422cfee
@ -47,7 +47,8 @@ global using ASC.Api.Core.Core;
|
||||
global using ASC.Api.Core.Extensions;
|
||||
global using ASC.Api.Core.Log;
|
||||
global using ASC.Api.Core.Middleware;
|
||||
global using ASC.Api.Core.Routing;
|
||||
global using ASC.Api.Core.Routing;
|
||||
global using ASC.Api.Core.Security;
|
||||
global using ASC.Common;
|
||||
global using ASC.Common.Caching;
|
||||
global using ASC.Common.DependencyInjection;
|
||||
@ -67,7 +68,10 @@ global using ASC.Core.Users;
|
||||
global using ASC.EventBus;
|
||||
global using ASC.EventBus.Abstractions;
|
||||
global using ASC.EventBus.RabbitMQ;
|
||||
global using ASC.IPSecurity;
|
||||
global using ASC.IPSecurity;
|
||||
global using ASC.MessagingSystem.Data;
|
||||
global using ASC.MessagingSystem.Core;
|
||||
global using ASC.MessagingSystem.Models;
|
||||
global using ASC.Security.Cryptography;
|
||||
global using ASC.Web.Api.Routing;
|
||||
global using ASC.Web.Core;
|
||||
@ -100,7 +104,8 @@ global using Microsoft.AspNetCore.Mvc.Routing;
|
||||
global using Microsoft.AspNetCore.Routing;
|
||||
global using Microsoft.AspNetCore.Routing.Constraints;
|
||||
global using Microsoft.AspNetCore.Routing.Patterns;
|
||||
global using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
global using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
global using Microsoft.AspNetCore.WebUtilities;
|
||||
global using Microsoft.Extensions.Configuration;
|
||||
global using Microsoft.Extensions.DependencyInjection;
|
||||
global using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||
@ -116,7 +121,9 @@ global using NLog;
|
||||
global using NLog.Config;
|
||||
global using NLog.Extensions.Logging;
|
||||
|
||||
global using RabbitMQ.Client;
|
||||
global using RabbitMQ.Client;
|
||||
|
||||
global using AutoMapper;
|
||||
|
||||
global using StackExchange.Redis.Extensions.Core.Configuration;
|
||||
global using StackExchange.Redis.Extensions.Newtonsoft;
|
||||
|
175
common/ASC.Api.Core/Security/EmailValidationKeyModelHelper.cs
Normal file
175
common/ASC.Api.Core/Security/EmailValidationKeyModelHelper.cs
Normal file
@ -0,0 +1,175 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
using static ASC.Security.Cryptography.EmailValidationKeyProvider;
|
||||
|
||||
namespace ASC.Api.Core.Security;
|
||||
|
||||
[Transient]
|
||||
public class EmailValidationKeyModelHelper
|
||||
{
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly EmailValidationKeyProvider _provider;
|
||||
private readonly AuthContext _authContext;
|
||||
private readonly UserManager _userManager;
|
||||
private readonly AuthManager _authentication;
|
||||
private readonly RoomInvitationLinksService _roomLinksService;
|
||||
|
||||
public EmailValidationKeyModelHelper(
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
EmailValidationKeyProvider provider,
|
||||
AuthContext authContext,
|
||||
UserManager userManager,
|
||||
AuthManager authentication,
|
||||
RoomInvitationLinksService roomLinksService)
|
||||
{
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_provider = provider;
|
||||
_authContext = authContext;
|
||||
_userManager = userManager;
|
||||
_authentication = authentication;
|
||||
_roomLinksService = roomLinksService;
|
||||
}
|
||||
|
||||
public EmailValidationKeyModel GetModel()
|
||||
{
|
||||
var request = QueryHelpers.ParseQuery(_httpContextAccessor.HttpContext.Request.Headers["confirm"]);
|
||||
|
||||
request.TryGetValue("type", out var type);
|
||||
|
||||
ConfirmType? cType = null;
|
||||
if (Enum.TryParse<ConfirmType>(type, out var confirmType))
|
||||
{
|
||||
cType = confirmType;
|
||||
}
|
||||
|
||||
request.TryGetValue("key", out var key);
|
||||
|
||||
request.TryGetValue("emplType", out var emplType);
|
||||
Enum.TryParse<EmployeeType>(emplType, out var employeeType);
|
||||
|
||||
request.TryGetValue("email", out var _email);
|
||||
|
||||
request.TryGetValue("uid", out var userIdKey);
|
||||
Guid.TryParse(userIdKey, out var userId);
|
||||
|
||||
request.TryGetValue("access", out var fileShareRaw);
|
||||
int.TryParse(fileShareRaw, out var fileShare);
|
||||
|
||||
request.TryGetValue("roomId", out var roomId);
|
||||
|
||||
return new EmailValidationKeyModel
|
||||
{
|
||||
Email = _email,
|
||||
EmplType = employeeType,
|
||||
Key = key,
|
||||
Type = cType,
|
||||
UiD = userId,
|
||||
RoomAccess = fileShare,
|
||||
RoomId = roomId
|
||||
};
|
||||
}
|
||||
|
||||
public ValidationResult Validate(EmailValidationKeyModel inDto)
|
||||
{
|
||||
var (key, emplType, email, uiD, type, fileShare, roomId) = inDto;
|
||||
|
||||
ValidationResult checkKeyResult;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ConfirmType.EmpInvite:
|
||||
checkKeyResult = _provider.ValidateEmailKey(email + type + (int)emplType, key, _provider.ValidEmailKeyInterval);
|
||||
break;
|
||||
|
||||
case ConfirmType.LinkInvite:
|
||||
if (fileShare != default && !string.IsNullOrEmpty(roomId))
|
||||
{
|
||||
checkKeyResult = _provider.ValidateEmailKey(email + type + ((int)emplType + (int)fileShare + roomId), key, _provider.ValidEmailKeyInterval);
|
||||
if (checkKeyResult == ValidationResult.Ok &&
|
||||
!_roomLinksService.VisitProcess(roomId, email, key, _provider.ValidVisitLinkInterval))
|
||||
{
|
||||
checkKeyResult = ValidationResult.Expired;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
checkKeyResult = _provider.ValidateEmailKey(type.ToString() + (int)emplType, key, _provider.ValidEmailKeyInterval);
|
||||
break;
|
||||
|
||||
case ConfirmType.PortalOwnerChange:
|
||||
checkKeyResult = _provider.ValidateEmailKey(email + type + uiD.HasValue, key, _provider.ValidEmailKeyInterval);
|
||||
break;
|
||||
|
||||
case ConfirmType.EmailChange:
|
||||
checkKeyResult = _provider.ValidateEmailKey(email + type + _authContext.CurrentAccount.ID, key, _provider.ValidEmailKeyInterval);
|
||||
break;
|
||||
case ConfirmType.PasswordChange:
|
||||
|
||||
var hash = _authentication.GetUserPasswordStamp(_userManager.GetUserByEmail(email).Id).ToString("s");
|
||||
|
||||
checkKeyResult = _provider.ValidateEmailKey(email + type + hash, key, _provider.ValidEmailKeyInterval);
|
||||
break;
|
||||
|
||||
case ConfirmType.Activation:
|
||||
checkKeyResult = _provider.ValidateEmailKey(email + type + uiD, key, _provider.ValidEmailKeyInterval);
|
||||
break;
|
||||
|
||||
case ConfirmType.ProfileRemove:
|
||||
// validate UiD
|
||||
var user = _userManager.GetUsers(uiD.GetValueOrDefault());
|
||||
if (user == null || user.Status == EmployeeStatus.Terminated || _authContext.IsAuthenticated && _authContext.CurrentAccount.ID != uiD)
|
||||
{
|
||||
return ValidationResult.Invalid;
|
||||
}
|
||||
|
||||
checkKeyResult = _provider.ValidateEmailKey(email + type + uiD, key, _provider.ValidEmailKeyInterval);
|
||||
break;
|
||||
|
||||
case ConfirmType.Wizard:
|
||||
checkKeyResult = _provider.ValidateEmailKey("" + type, key, _provider.ValidEmailKeyInterval);
|
||||
break;
|
||||
|
||||
case ConfirmType.PhoneActivation:
|
||||
case ConfirmType.PhoneAuth:
|
||||
case ConfirmType.TfaActivation:
|
||||
case ConfirmType.TfaAuth:
|
||||
case ConfirmType.Auth:
|
||||
checkKeyResult = _provider.ValidateEmailKey(email + type, key, _provider.ValidAuthKeyInterval);
|
||||
break;
|
||||
|
||||
case ConfirmType.PortalContinue:
|
||||
checkKeyResult = _provider.ValidateEmailKey(email + type, key);
|
||||
break;
|
||||
|
||||
default:
|
||||
checkKeyResult = _provider.ValidateEmailKey(email + type, key, _provider.ValidEmailKeyInterval);
|
||||
break;
|
||||
}
|
||||
|
||||
return checkKeyResult;
|
||||
}
|
||||
}
|
124
common/ASC.Api.Core/Security/RoomInvitationLinksService.cs
Normal file
124
common/ASC.Api.Core/Security/RoomInvitationLinksService.cs
Normal file
@ -0,0 +1,124 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Api.Core.Security;
|
||||
|
||||
[Scope]
|
||||
public class RoomInvitationLinksService
|
||||
{
|
||||
private readonly CommonLinkUtility _commonLinkUtility;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly MessageTarget _messageTarget;
|
||||
private readonly UserManager _userManager;
|
||||
private readonly Lazy<MessagesContext> _messagesContext;
|
||||
private readonly MessageService _messageService;
|
||||
|
||||
public RoomInvitationLinksService(
|
||||
CommonLinkUtility commonLinkUtility,
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
MessageTarget messageTarget,
|
||||
UserManager userManager,
|
||||
DbContextManager<MessagesContext> dbContextManager,
|
||||
MessageService messageService)
|
||||
{
|
||||
_commonLinkUtility = commonLinkUtility;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_messageTarget = messageTarget;
|
||||
_userManager = userManager;
|
||||
_messagesContext = new Lazy<MessagesContext>(() => dbContextManager.Value);
|
||||
_messageService = messageService;
|
||||
}
|
||||
|
||||
public string GenerateLink<T>(T id, int fileShare, EmployeeType employeeType, Guid guid)
|
||||
{
|
||||
return GenerateLink(id, string.Empty, fileShare, employeeType, guid);
|
||||
}
|
||||
|
||||
public string GenerateLink<T>(T id, string email, int fileShare, EmployeeType employeeType, Guid guid)
|
||||
{
|
||||
var user = _userManager.GetUserByEmail(email);
|
||||
|
||||
if (user != ASC.Core.Users.Constants.LostUser)
|
||||
{
|
||||
throw new Exception("The user with this email already exists");
|
||||
}
|
||||
|
||||
var postifx = (int)employeeType + fileShare + id.ToString();
|
||||
|
||||
var link = _commonLinkUtility.GetConfirmationUrl(email, ConfirmType.LinkInvite, postifx, guid)
|
||||
+ $"&emplType={employeeType:d}&roomId={id}&access={fileShare}";
|
||||
|
||||
return link;
|
||||
}
|
||||
|
||||
public bool VisitProcess(string id, string email, string key, TimeSpan interval)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(email))
|
||||
{
|
||||
var user = _userManager.GetUserByEmail(email);
|
||||
|
||||
if (user != ASC.Core.Users.Constants.LostUser)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var message = GetLinkInfo(id, email, key);
|
||||
|
||||
if (message == null)
|
||||
{
|
||||
SaveVisitLinkInfo(id, email, key);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return message.Date + interval > DateTime.UtcNow;
|
||||
}
|
||||
|
||||
private void SaveVisitLinkInfo(string id, string email, string key)
|
||||
{
|
||||
var headers = _httpContextAccessor?.HttpContext?.Request?.Headers;
|
||||
var target = _messageTarget.CreateFromGroupValues(email != null ? new[] { id, email } : new[] { id });
|
||||
|
||||
_messageService.Send(headers, MessageAction.RoomInviteLinkUsed, target, key);
|
||||
}
|
||||
|
||||
private AuditEvent GetLinkInfo(string id, string email, string key)
|
||||
{
|
||||
var context = _messagesContext.Value;
|
||||
var target = _messageTarget.CreateFromGroupValues(email != null ? new[] { id, email } : new[] { id });
|
||||
var description = JsonConvert.SerializeObject(new[] { key },
|
||||
new JsonSerializerSettings
|
||||
{
|
||||
DateTimeZoneHandling = DateTimeZoneHandling.Utc
|
||||
});
|
||||
|
||||
var message = context.AuditEvents.Where(a => a.Target == target.ToString() &&
|
||||
a.DescriptionRaw == description).FirstOrDefault();
|
||||
|
||||
return message;
|
||||
}
|
||||
}
|
@ -33,6 +33,7 @@ public class CoreBaseSettings
|
||||
private string _basedomain;
|
||||
private bool? _personal;
|
||||
private bool? _customMode;
|
||||
private bool? _disableDocSpace;
|
||||
|
||||
private IConfiguration Configuration { get; }
|
||||
|
||||
@ -61,6 +62,8 @@ public class CoreBaseSettings
|
||||
_personal ?? (bool)(_personal = string.Equals(Configuration["core:personal"], "true", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
public bool CustomMode => _customMode ?? (bool)(_customMode = string.Equals(Configuration["core:custom-mode"], "true", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
public bool DisableDocSpace => _disableDocSpace ?? (bool)(_disableDocSpace = string.Equals(Configuration["core:disableDocspace"], "true", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
class ConfigureCoreSettings : IConfigureNamedOptions<CoreSettings>
|
||||
|
@ -718,6 +718,11 @@ public class UserManager
|
||||
group = ToGroup(Constants.BuildinGroups.FirstOrDefault(r => r.ID == groupID) ?? Constants.LostGroupInfo);
|
||||
}
|
||||
|
||||
if (group == null)
|
||||
{
|
||||
return Constants.LostGroupInfo;
|
||||
}
|
||||
|
||||
return new GroupInfo
|
||||
{
|
||||
ID = group.Id,
|
||||
|
@ -32,17 +32,26 @@ public class RegisterInstanceWorkerService<T> : BackgroundService where T : IHos
|
||||
private readonly ILogger _logger;
|
||||
private readonly IHostApplicationLifetime _applicationLifetime;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly int _intervalCheckRegisterInstanceInSeconds;
|
||||
public static readonly string InstanceId =
|
||||
$"{typeof(T).GetFormattedName()}_{DateTime.UtcNow.Ticks}";
|
||||
|
||||
public RegisterInstanceWorkerService(
|
||||
ILogger<RegisterInstanceWorkerService<T>> logger,
|
||||
IServiceProvider serviceProvider,
|
||||
IHostApplicationLifetime applicationLifetime)
|
||||
IHostApplicationLifetime applicationLifetime,
|
||||
IConfiguration configuration)
|
||||
{
|
||||
_logger = logger;
|
||||
_serviceProvider = serviceProvider;
|
||||
_applicationLifetime = applicationLifetime;
|
||||
_applicationLifetime = applicationLifetime;
|
||||
|
||||
if (!int.TryParse(configuration["core:hosting:intervalCheckRegisterInstanceInSeconds"], out _intervalCheckRegisterInstanceInSeconds))
|
||||
{
|
||||
_intervalCheckRegisterInstanceInSeconds = 1;
|
||||
}
|
||||
|
||||
_intervalCheckRegisterInstanceInSeconds = _intervalCheckRegisterInstanceInSeconds*1000;
|
||||
}
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
@ -50,7 +59,7 @@ public class RegisterInstanceWorkerService<T> : BackgroundService where T : IHos
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
{
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
|
||||
var registerInstanceService = scope.ServiceProvider.GetService<IRegisterInstanceManager<T>>();
|
||||
@ -60,7 +69,7 @@ public class RegisterInstanceWorkerService<T> : BackgroundService where T : IHos
|
||||
|
||||
_logger.TraceWorkingRunnging(DateTimeOffset.Now);
|
||||
|
||||
await Task.Delay(1000, stoppingToken);
|
||||
await Task.Delay(_intervalCheckRegisterInstanceInSeconds, stoppingToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -33,6 +33,7 @@ public class AuditEvent : MessageEvent, IMapFrom<EventMessage>
|
||||
|
||||
public void Mapping(Profile profile)
|
||||
{
|
||||
profile.CreateMap<MessageEvent, AuditEvent>();
|
||||
profile.CreateMap<EventMessage, AuditEvent>()
|
||||
.ConvertUsing<EventTypeConverter>();
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -53,7 +53,7 @@ public class MessageTarget
|
||||
};
|
||||
}
|
||||
|
||||
public MessageTarget Create(IEnumerable<string> value)
|
||||
public MessageTarget CreateFromGroupValues(IEnumerable<string> value)
|
||||
{
|
||||
var res = new MessageTarget(_option)
|
||||
{
|
||||
|
@ -35,11 +35,13 @@ public class EmailValidationKeyProvider
|
||||
Invalid,
|
||||
Expired
|
||||
}
|
||||
|
||||
public TimeSpan ValidEmailKeyInterval { get; }
|
||||
public TimeSpan ValidAuthKeyInterval { get; }
|
||||
public TimeSpan ValidVisitLinkInterval { get; }
|
||||
|
||||
private readonly ILogger<EmailValidationKeyProvider> _logger;
|
||||
private static readonly DateTime _from = new DateTime(2010, 01, 01, 0, 0, 0, DateTimeKind.Utc);
|
||||
internal readonly TimeSpan _validEmailKeyInterval;
|
||||
internal readonly TimeSpan _validAuthKeyInterval;
|
||||
private readonly MachinePseudoKeys _machinePseudoKeys;
|
||||
private readonly TenantManager _tenantManager;
|
||||
|
||||
@ -55,9 +57,13 @@ public class EmailValidationKeyProvider
|
||||
{
|
||||
authValidInterval = TimeSpan.FromHours(1);
|
||||
}
|
||||
|
||||
_validEmailKeyInterval = validInterval;
|
||||
_validAuthKeyInterval = authValidInterval;
|
||||
if (!TimeSpan.TryParse(configuration["visit:validinterval"], out var validVisitLinkInterval))
|
||||
{
|
||||
ValidVisitLinkInterval = TimeSpan.FromMinutes(15);
|
||||
}
|
||||
|
||||
ValidEmailKeyInterval = validInterval;
|
||||
ValidAuthKeyInterval = authValidInterval;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@ -162,133 +168,11 @@ public class EmailValidationKeyModel
|
||||
public string Email { get; set; }
|
||||
public Guid? UiD { get; set; }
|
||||
public ConfirmType? Type { get; set; }
|
||||
public int RoomAccess { get; set; }
|
||||
public string RoomId { get; set; }
|
||||
|
||||
public void Deconstruct(out string key, out EmployeeType? emplType, out string email, out Guid? uiD, out ConfirmType? type)
|
||||
public void Deconstruct(out string key, out EmployeeType? emplType, out string email, out Guid? uiD, out ConfirmType? type, out int roomAccess, out string roomId)
|
||||
{
|
||||
(key, emplType, email, uiD, type) = (Key, EmplType, Email, UiD, Type);
|
||||
(key, emplType, email, uiD, type, roomAccess, roomId) = (Key, EmplType, Email, UiD, Type, RoomAccess, RoomId);
|
||||
}
|
||||
}
|
||||
|
||||
[Transient]
|
||||
public class EmailValidationKeyModelHelper
|
||||
{
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly EmailValidationKeyProvider _provider;
|
||||
private readonly AuthContext _authContext;
|
||||
private readonly UserManager _userManager;
|
||||
private readonly AuthManager _authentication;
|
||||
|
||||
public EmailValidationKeyModelHelper(
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
EmailValidationKeyProvider provider,
|
||||
AuthContext authContext,
|
||||
UserManager userManager,
|
||||
AuthManager authentication)
|
||||
{
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_provider = provider;
|
||||
_authContext = authContext;
|
||||
_userManager = userManager;
|
||||
_authentication = authentication;
|
||||
}
|
||||
|
||||
public EmailValidationKeyModel GetModel()
|
||||
{
|
||||
var request = QueryHelpers.ParseQuery(_httpContextAccessor.HttpContext.Request.Headers["confirm"]);
|
||||
|
||||
request.TryGetValue("type", out var type);
|
||||
|
||||
ConfirmType? cType = null;
|
||||
if (Enum.TryParse<ConfirmType>(type, out var confirmType))
|
||||
{
|
||||
cType = confirmType;
|
||||
}
|
||||
|
||||
request.TryGetValue("key", out var key);
|
||||
|
||||
request.TryGetValue("emplType", out var emplType);
|
||||
Enum.TryParse<EmployeeType>(emplType, out var employeeType);
|
||||
|
||||
request.TryGetValue("email", out var _email);
|
||||
request.TryGetValue("uid", out var userIdKey);
|
||||
Guid.TryParse(userIdKey, out var userId);
|
||||
|
||||
return new EmailValidationKeyModel
|
||||
{
|
||||
Email = _email,
|
||||
EmplType = employeeType,
|
||||
Key = key,
|
||||
Type = cType,
|
||||
UiD = userId
|
||||
};
|
||||
}
|
||||
|
||||
public ValidationResult Validate(EmailValidationKeyModel inDto)
|
||||
{
|
||||
var (key, emplType, email, uiD, type) = inDto;
|
||||
|
||||
ValidationResult checkKeyResult;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ConfirmType.EmpInvite:
|
||||
checkKeyResult = _provider.ValidateEmailKey(email + type + (int)emplType, key, _provider._validEmailKeyInterval);
|
||||
break;
|
||||
|
||||
case ConfirmType.LinkInvite:
|
||||
checkKeyResult = _provider.ValidateEmailKey(type.ToString() + (int)emplType, key, _provider._validEmailKeyInterval);
|
||||
break;
|
||||
|
||||
case ConfirmType.PortalOwnerChange:
|
||||
checkKeyResult = _provider.ValidateEmailKey(email + type + uiD.HasValue, key, _provider._validEmailKeyInterval);
|
||||
break;
|
||||
|
||||
case ConfirmType.EmailChange:
|
||||
checkKeyResult = _provider.ValidateEmailKey(email + type + _authContext.CurrentAccount.ID, key, _provider._validEmailKeyInterval);
|
||||
break;
|
||||
case ConfirmType.PasswordChange:
|
||||
|
||||
var hash = _authentication.GetUserPasswordStamp(_userManager.GetUserByEmail(email).Id).ToString("s");
|
||||
|
||||
checkKeyResult = _provider.ValidateEmailKey(email + type + hash, key, _provider._validEmailKeyInterval);
|
||||
break;
|
||||
|
||||
case ConfirmType.Activation:
|
||||
checkKeyResult = _provider.ValidateEmailKey(email + type + uiD, key, _provider._validEmailKeyInterval);
|
||||
break;
|
||||
|
||||
case ConfirmType.ProfileRemove:
|
||||
// validate UiD
|
||||
var user = _userManager.GetUsers(uiD.GetValueOrDefault());
|
||||
if (user == null || user.Status == EmployeeStatus.Terminated || _authContext.IsAuthenticated && _authContext.CurrentAccount.ID != uiD)
|
||||
{
|
||||
return ValidationResult.Invalid;
|
||||
}
|
||||
|
||||
checkKeyResult = _provider.ValidateEmailKey(email + type + uiD, key, _provider._validEmailKeyInterval);
|
||||
break;
|
||||
|
||||
case ConfirmType.Wizard:
|
||||
checkKeyResult = _provider.ValidateEmailKey("" + type, key, _provider._validEmailKeyInterval);
|
||||
break;
|
||||
|
||||
case ConfirmType.PhoneActivation:
|
||||
case ConfirmType.PhoneAuth:
|
||||
case ConfirmType.TfaActivation:
|
||||
case ConfirmType.TfaAuth:
|
||||
case ConfirmType.Auth:
|
||||
checkKeyResult = _provider.ValidateEmailKey(email + type, key, _provider._validAuthKeyInterval);
|
||||
break;
|
||||
|
||||
case ConfirmType.PortalContinue:
|
||||
checkKeyResult = _provider.ValidateEmailKey(email + type, key);
|
||||
break;
|
||||
|
||||
default:
|
||||
checkKeyResult = _provider.ValidateEmailKey(email + type, key, _provider._validEmailKeyInterval);
|
||||
break;
|
||||
}
|
||||
|
||||
return checkKeyResult;
|
||||
}
|
||||
}
|
||||
}
|
@ -54,5 +54,5 @@ public enum ConfirmType
|
||||
Auth,
|
||||
TfaActivation,
|
||||
TfaAuth,
|
||||
Wizard
|
||||
Wizard,
|
||||
}
|
||||
|
@ -24,22 +24,6 @@
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2021
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ASC.FederatedLogin.LoginProviders;
|
||||
|
||||
[Scope]
|
||||
@ -130,23 +114,25 @@ public class AppleIdLoginProvider : BaseLoginProvider<AppleIdLoginProvider>
|
||||
}
|
||||
|
||||
private string GenerateSecret()
|
||||
{
|
||||
using (var cngKey = CngKey.Import(Convert.FromBase64String(PrivateKey), CngKeyBlobFormat.Pkcs8PrivateBlob))
|
||||
{
|
||||
var handler = new JwtSecurityTokenHandler();
|
||||
var token = handler.CreateJwtSecurityToken(
|
||||
issuer: TeamId,
|
||||
audience: "https://appleid.apple.com",
|
||||
subject: new ClaimsIdentity(new List<Claim> { new Claim("sub", ClientID) }),
|
||||
issuedAt: DateTime.UtcNow,
|
||||
notBefore: DateTime.UtcNow,
|
||||
expires: DateTime.UtcNow.AddMinutes(5),
|
||||
signingCredentials: new SigningCredentials(new ECDsaSecurityKey(new ECDsaCng(cngKey)), SecurityAlgorithms.EcdsaSha256)
|
||||
);
|
||||
token.Header.Add("kid", KeyId);
|
||||
|
||||
return handler.WriteToken(token);
|
||||
}
|
||||
{
|
||||
using var ecdsa = ECDsa.Create();
|
||||
|
||||
ecdsa.ImportPkcs8PrivateKey(Convert.FromBase64String(PrivateKey), out _);
|
||||
|
||||
var handler = new JwtSecurityTokenHandler();
|
||||
var token = handler.CreateJwtSecurityToken(
|
||||
issuer: TeamId,
|
||||
audience: "https://appleid.apple.com",
|
||||
subject: new ClaimsIdentity(new List<Claim> { new Claim("sub", ClientID) }),
|
||||
issuedAt: DateTime.UtcNow,
|
||||
notBefore: DateTime.UtcNow,
|
||||
expires: DateTime.UtcNow.AddMinutes(5),
|
||||
signingCredentials: new SigningCredentials(new ECDsaSecurityKey(ecdsa), SecurityAlgorithms.EcdsaSha256)
|
||||
);
|
||||
|
||||
token.Header.Add("kid", KeyId);
|
||||
|
||||
return handler.WriteToken(token);
|
||||
}
|
||||
|
||||
private ClaimsPrincipal ValidateIdToken(string idToken)
|
||||
|
@ -88,9 +88,11 @@ public class GosUslugiLoginProvider : BaseLoginProvider<GosUslugiLoginProvider>
|
||||
|
||||
public override LoginProfile GetLoginProfile(string accessToken)
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
var tokenPayloadString = JwtBuilder.Create()
|
||||
.WithAlgorithm(new HMACSHA256Algorithm())
|
||||
.Decode(accessToken);
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
var tokenPayload = JObject.Parse(tokenPayloadString);
|
||||
if (tokenPayload == null)
|
||||
{
|
||||
|
@ -24,22 +24,6 @@
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2021
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ASC.FederatedLogin.LoginProviders;
|
||||
|
||||
public class MicrosoftLoginProvider : BaseLoginProvider<MicrosoftLoginProvider>
|
||||
|
@ -38,8 +38,10 @@ public class MessagesRepository : IDisposable
|
||||
private readonly IServiceScopeFactory _serviceScopeFactory;
|
||||
private readonly IMapper _mapper;
|
||||
private readonly ILogger<MessagesRepository> _logger;
|
||||
private readonly Timer _timer;
|
||||
private readonly Timer _timer;
|
||||
private readonly int _cacheLimit;
|
||||
private readonly HashSet<MessageAction> _forceSaveAuditActions = new HashSet<MessageAction>
|
||||
{ MessageAction.RoomInviteLinkUsed, MessageAction.UserSentPasswordChangeInstructions };
|
||||
|
||||
public MessagesRepository(IServiceScopeFactory serviceScopeFactory, ILogger<MessagesRepository> logger, IMapper mapper, IConfiguration configuration)
|
||||
{
|
||||
@ -52,28 +54,29 @@ public class MessagesRepository : IDisposable
|
||||
|
||||
_timer = new Timer(FlushCache);
|
||||
|
||||
_mapper = mapper;
|
||||
_mapper = mapper;
|
||||
|
||||
var minutes = configuration["messaging:CacheTimeFromMinutes"];
|
||||
var limit = configuration["messaging:CacheLimit"];
|
||||
|
||||
_cacheTime = int.TryParse(minutes, out var cacheTime) ? TimeSpan.FromMinutes(cacheTime) : TimeSpan.FromMinutes(1);
|
||||
_cacheLimit = int.TryParse(limit, out var cacheLimit) ? cacheLimit : 100;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
~MessagesRepository()
|
||||
{
|
||||
{
|
||||
FlushCache(true);
|
||||
}
|
||||
|
||||
private bool ForseSave(EventMessage message)
|
||||
{
|
||||
// messages with action code < 2000 are related to login-history
|
||||
if ((int)message.Action < 2000)
|
||||
{
|
||||
// messages with action code < 2000 are related to login-history
|
||||
if ((int)message.Action < 2000)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return message.Action == MessageAction.UserSentPasswordChangeInstructions;
|
||||
return _forceSaveAuditActions.Contains(message.Action);
|
||||
}
|
||||
|
||||
public int Add(EventMessage message)
|
||||
@ -94,8 +97,8 @@ public class MessagesRepository : IDisposable
|
||||
}
|
||||
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
using var ef = scope.ServiceProvider.GetService<DbContextManager<MessagesContext>>().Get("messages");
|
||||
|
||||
using var ef = scope.ServiceProvider.GetService<DbContextManager<MessagesContext>>().Get("messages");
|
||||
|
||||
if ((int)message.Action < 2000)
|
||||
{
|
||||
id = AddLoginEvent(message, ef);
|
||||
@ -125,12 +128,12 @@ public class MessagesRepository : IDisposable
|
||||
private void FlushCache(object state)
|
||||
{
|
||||
FlushCache(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void FlushCache(bool isDisposed = false)
|
||||
{
|
||||
List<EventMessage> events = null;
|
||||
|
||||
|
||||
if (DateTime.UtcNow > _lastSave.Add(_cacheTime) || _cache.Count > _cacheLimit || isDisposed)
|
||||
{
|
||||
lock (_cache)
|
||||
@ -149,15 +152,15 @@ public class MessagesRepository : IDisposable
|
||||
return;
|
||||
}
|
||||
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
using var ef = scope.ServiceProvider.GetService<DbContextManager<MessagesContext>>().Get("messages");
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
using var ef = scope.ServiceProvider.GetService<DbContextManager<MessagesContext>>().Get("messages");
|
||||
var strategy = ef.Database.CreateExecutionStrategy();
|
||||
|
||||
strategy.Execute(() =>
|
||||
{
|
||||
using var tx = ef.Database.BeginTransaction(IsolationLevel.ReadUncommitted);
|
||||
var dict = new Dictionary<string, ClientInfo>();
|
||||
|
||||
|
||||
foreach (var message in events)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(message.UAHeader))
|
||||
@ -183,9 +186,9 @@ public class MessagesRepository : IDisposable
|
||||
{
|
||||
AddAuditEvent(message, ef);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tx.Commit();
|
||||
});
|
||||
}
|
||||
@ -195,7 +198,7 @@ public class MessagesRepository : IDisposable
|
||||
var loginEvent = _mapper.Map<EventMessage, LoginEvent>(message);
|
||||
|
||||
dbContext.LoginEvents.Add(loginEvent);
|
||||
dbContext.SaveChanges();
|
||||
dbContext.SaveChanges();
|
||||
|
||||
return loginEvent.Id;
|
||||
}
|
||||
@ -205,8 +208,8 @@ public class MessagesRepository : IDisposable
|
||||
var auditEvent = _mapper.Map<EventMessage, AuditEvent>(message);
|
||||
|
||||
dbContext.AuditEvents.Add(auditEvent);
|
||||
dbContext.SaveChanges();
|
||||
|
||||
dbContext.SaveChanges();
|
||||
|
||||
return auditEvent.Id;
|
||||
}
|
||||
|
||||
|
@ -24,22 +24,6 @@
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2021
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ASC.Notify.Textile;
|
||||
|
||||
public class MarkDownStyler : IPatternStyler
|
||||
|
@ -24,22 +24,6 @@
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2021
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ASC.AuditTrail.Mappers;
|
||||
|
||||
internal class LoginActionsMapper : IProductActionMapper
|
||||
|
@ -24,22 +24,6 @@
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2021
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ASC.AuditTrail.Mappers;
|
||||
|
||||
internal class OthersActionsMapper : IProductActionMapper
|
||||
|
@ -24,22 +24,6 @@
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2021
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ASC.AuditTrail.Mappers;
|
||||
|
||||
internal class SettingsActionsMapper : IProductActionMapper
|
||||
|
@ -25,11 +25,16 @@
|
||||
"test": true
|
||||
},
|
||||
"personal": false,
|
||||
"disableDocspace": false,
|
||||
"products": {
|
||||
"folder": "../../products",
|
||||
"subfolder": "Server"
|
||||
},
|
||||
"search-by-content": false
|
||||
"search-by-content": false,
|
||||
"hosting": {
|
||||
"intervalCheckRegisterInstanceInSeconds": "1",
|
||||
"timeUntilUnregisterInSeconds": "15"
|
||||
}
|
||||
},
|
||||
"license": {
|
||||
"file": {
|
||||
@ -42,7 +47,7 @@
|
||||
"server-mailbox-limit-per-user": 2
|
||||
},
|
||||
"messaging": {
|
||||
"enabled": "enabled"
|
||||
"enabled": "true"
|
||||
},
|
||||
"version": {
|
||||
"number": "11.5.0",
|
||||
|
@ -180,14 +180,13 @@ server {
|
||||
proxy_pass http://localhost:5034;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
}
|
||||
|
||||
location ~* /sso {
|
||||
rewrite api/2.0/sso/(.*) /$1 break;
|
||||
proxy_pass http://localhost:9834;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
}
|
||||
}
|
||||
|
||||
location /sso {
|
||||
rewrite sso/(.*) /$1 break;
|
||||
proxy_pass http://localhost:9834;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
}
|
||||
location ~* /(ssologin.ashx|login.ashx|storage) {
|
||||
proxy_pass http://localhost:5003;
|
||||
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
|
||||
|
@ -68,6 +68,21 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "room_logos",
|
||||
"data": "00000000-0000-0000-0000-000000000000",
|
||||
"type": "disc",
|
||||
"path": "$STORAGE_ROOT\\Products\\Files\\logos\\{0}",
|
||||
"domain": [
|
||||
{
|
||||
"name": "logos_temp",
|
||||
"data": "00000000-0000-0000-0000-000000000000",
|
||||
"type": "disc",
|
||||
"path": "$STORAGE_ROOT\\Products\\Files\\logos\\{0}\\temp",
|
||||
"expires": "0:10:0"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "files_template",
|
||||
"visible": false,
|
||||
|
@ -32,6 +32,7 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\common\ASC.Api.Core\ASC.Api.Core.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\services\ASC.ElasticSearch\ASC.ElasticSearch.csproj" />
|
||||
<ProjectReference Include="..\..\..\web\ASC.Web.Core\ASC.Web.Core.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Protobuf Include="proto\box_cache_item.proto" />
|
||||
|
@ -0,0 +1,32 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Files.Core.ApiModels.RequestDto;
|
||||
|
||||
public class BatchTagsRequestDto
|
||||
{
|
||||
public IEnumerable<string> Names { get; set; }
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Files.Core.ApiModels.RequestDto;
|
||||
|
||||
public enum RoomType
|
||||
{
|
||||
FillingFormsRoom = 1,
|
||||
EditingRoom = 2,
|
||||
ReviewRoom = 3,
|
||||
ReadOnlyRoom = 4,
|
||||
CustomRoom = 5
|
||||
}
|
||||
|
||||
public class CreateRoomRequestDto
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public RoomType RoomType { get; set; }
|
||||
}
|
32
products/ASC.Files/Core/ApiModels/RequestDto/CreateTag.cs
Normal file
32
products/ASC.Files/Core/ApiModels/RequestDto/CreateTag.cs
Normal file
@ -0,0 +1,32 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Files.Core.ApiModels.RequestDto;
|
||||
|
||||
public class CreateTagRequestDto
|
||||
{
|
||||
public string Name { get; set; }
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Files.Core.ApiModels.RequestDto;
|
||||
|
||||
public class InviteLinkDto
|
||||
{
|
||||
public FileShare Access { get; set; }
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Files.Core.ApiModels.RequestDto;
|
||||
|
||||
public class InviteUsersByEmailRequestDto
|
||||
{
|
||||
public IEnumerable<string> Emails { get; set; }
|
||||
public EmployeeType EmployeeType { get; set; }
|
||||
public FileShare Access { get; set; }
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Files.Core.ApiModels.RequestDto;
|
||||
|
||||
public class LogoRequestDto
|
||||
{
|
||||
public string TmpFile { get; set; }
|
||||
public int X { get; set; }
|
||||
public int Y { get; set; }
|
||||
public int Width { get; set; }
|
||||
public int Height { get; set; }
|
||||
}
|
@ -31,4 +31,6 @@ public class SecurityInfoRequestDto : BaseBatchRequestDto
|
||||
public IEnumerable<FileShareParams> Share { get; set; }
|
||||
public bool Notify { get; set; }
|
||||
public string SharingMessage { get; set; }
|
||||
public FileShare Access { get; set; }
|
||||
public string Key { get; set; }
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ public class ThirdPartyRequestDto
|
||||
public string Password { get; set; }
|
||||
public string Token { get; set; }
|
||||
public bool IsCorporate { get; set; }
|
||||
public bool IsRoomsStorage { get; set; }
|
||||
public string CustomerTitle { get; set; }
|
||||
public string ProviderKey { get; set; }
|
||||
public string ProviderId { get; set; }
|
||||
|
@ -0,0 +1,32 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Files.Core.ApiModels.RequestDto;
|
||||
|
||||
public class UpdateRoomRequestDto
|
||||
{
|
||||
public string Title { get; set; }
|
||||
}
|
@ -103,6 +103,7 @@ public class FolderContentDtoHelper
|
||||
}
|
||||
|
||||
var folderEntries = folderItems.Entries.Where(r => r.FileEntryType == FileEntryType.Folder);
|
||||
|
||||
foreach (var r in folderEntries)
|
||||
{
|
||||
FileEntryDto wrapper = null;
|
||||
|
@ -34,6 +34,9 @@ public class FolderDto<T> : FileEntryDto<T>
|
||||
public bool? IsShareable { get; set; }
|
||||
public bool? IsFavorite { get; set; }
|
||||
public int New { get; set; }
|
||||
public IEnumerable<string> Tags { get; set; }
|
||||
public Logo Logo { get; set; }
|
||||
public bool Pinned { get; set; }
|
||||
|
||||
public FolderDto() { }
|
||||
|
||||
@ -65,6 +68,7 @@ public class FolderDtoHelper : FileEntryDtoHelper
|
||||
private readonly AuthContext _authContext;
|
||||
private readonly IDaoFactory _daoFactory;
|
||||
private readonly GlobalFolderHelper _globalFolderHelper;
|
||||
private readonly RoomLogoManager _roomLogoManager;
|
||||
|
||||
public FolderDtoHelper(
|
||||
ApiDateTimeHelper apiDateTimeHelper,
|
||||
@ -73,12 +77,14 @@ public class FolderDtoHelper : FileEntryDtoHelper
|
||||
IDaoFactory daoFactory,
|
||||
FileSecurity fileSecurity,
|
||||
GlobalFolderHelper globalFolderHelper,
|
||||
FileSharingHelper fileSharingHelper)
|
||||
FileSharingHelper fileSharingHelper,
|
||||
RoomLogoManager roomLogoManager)
|
||||
: base(apiDateTimeHelper, employeeWrapperHelper, fileSharingHelper, fileSecurity)
|
||||
{
|
||||
_authContext = authContext;
|
||||
_daoFactory = daoFactory;
|
||||
_globalFolderHelper = globalFolderHelper;
|
||||
_roomLogoManager = roomLogoManager;
|
||||
}
|
||||
|
||||
public async Task<FolderDto<T>> GetAsync<T>(Folder<T> folder, List<Tuple<FileEntry<T>, bool>> folders = null)
|
||||
@ -87,6 +93,24 @@ public class FolderDtoHelper : FileEntryDtoHelper
|
||||
|
||||
result.ParentId = folder.ParentId;
|
||||
|
||||
if (DocSpaceHelper.IsRoom(folder.FolderType))
|
||||
{
|
||||
if (folder.Tags == null)
|
||||
{
|
||||
var tagDao = _daoFactory.GetTagDao<T>();
|
||||
|
||||
var tags = await tagDao.GetTagsAsync(TagType.Custom, new[] { folder }).ToListAsync();
|
||||
|
||||
result.Tags = tags.Select(t => t.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Tags = folder.Tags.Select(t => t.Name);
|
||||
}
|
||||
|
||||
result.Logo = await _roomLogoManager.GetLogo(folder.Id);
|
||||
}
|
||||
|
||||
if (folder.RootFolderType == FolderType.USER
|
||||
&& !Equals(folder.RootCreateBy, _authContext.CurrentAccount.ID))
|
||||
{
|
||||
@ -125,6 +149,7 @@ public class FolderDtoHelper : FileEntryDtoHelper
|
||||
result.IsShareable = folder.Shareable.NullIfDefault();
|
||||
result.IsFavorite = folder.IsFavorite.NullIfDefault();
|
||||
result.New = folder.NewForMe;
|
||||
result.Pinned = folder.Pinned;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -0,0 +1,34 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Files.Core.ApiModels.ResponseDto;
|
||||
|
||||
public class InviteResultDto
|
||||
{
|
||||
public string Email { get; set; }
|
||||
public bool Success { get; set; }
|
||||
public string Message { get; set; }
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Files.Core.ApiModels.ResponseDto;
|
||||
|
||||
public class UploadResultDto
|
||||
{
|
||||
public bool Success { get; set; }
|
||||
public object Data { get; set; }
|
||||
public string Message { get; set; }
|
||||
}
|
@ -62,18 +62,50 @@ public interface IFolderDao<T>
|
||||
/// </summary>
|
||||
/// <param name="parentId"></param>
|
||||
IAsyncEnumerable<Folder<T>> GetFoldersAsync(T parentId);
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of folders.
|
||||
/// </summary>
|
||||
/// <param name="parentId"></param>
|
||||
/// <param name="orderBy"></param>
|
||||
/// <param name="filterType"></param>
|
||||
/// <param name="subjectGroup"></param>
|
||||
/// <param name="subjectID"></param>
|
||||
/// <param name="searchText"></param>
|
||||
/// <param name="withSubfolders"></param>
|
||||
/// <param name="tagIds"></param>
|
||||
/// <returns></returns>
|
||||
IAsyncEnumerable<Folder<T>> GetFoldersAsync(T parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false,
|
||||
IEnumerable<string> tagNames = null);
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of folders.
|
||||
/// </summary>
|
||||
/// <param name="parentId"></param>
|
||||
/// <param name="orderBy"></param>
|
||||
/// <param name="filterType"></param>
|
||||
/// <param name="filterTypes"></param>
|
||||
/// <param name="subjectGroup"></param>
|
||||
/// <param name="subjectID"></param>
|
||||
/// <param name="searchText"></param>
|
||||
/// <param name="withSubfolders"></param>
|
||||
/// <returns></returns>
|
||||
IAsyncEnumerable<Folder<T>> GetFoldersAsync(T parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false);
|
||||
IAsyncEnumerable<Folder<T>> GetFoldersAsync(T parentId, OrderBy orderBy, IEnumerable<FilterType> filterTypes, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false,
|
||||
IEnumerable<string> tagNames = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the folder (s) by ID (s)
|
||||
/// </summary>
|
||||
/// <param name="folderIds"></param>
|
||||
/// <param name="filterTypes"></param>
|
||||
/// <param name="subjectGroup"></param>
|
||||
/// <param name="subjectID"></param>
|
||||
/// <param name="searchText"></param>
|
||||
/// <param name="searchSubfolders"></param>
|
||||
/// <param name="checkShare"></param>
|
||||
/// <param name="tagIds"></param>
|
||||
/// <returns></returns>
|
||||
IAsyncEnumerable<Folder<T>> GetFoldersAsync(IEnumerable<T> folderIds, FilterType filterTypes = FilterType.None, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true,
|
||||
IEnumerable<string> tagNames = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the folder (s) by ID (s)
|
||||
@ -86,7 +118,8 @@ public interface IFolderDao<T>
|
||||
/// <param name="searchSubfolders"></param>
|
||||
/// <param name="checkShare"></param>
|
||||
/// <returns></returns>
|
||||
IAsyncEnumerable<Folder<T>> GetFoldersAsync(IEnumerable<T> folderIds, FilterType filterType = FilterType.None, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true);
|
||||
IAsyncEnumerable<Folder<T>> GetFoldersAsync(IEnumerable<T> folderIds, IEnumerable<FilterType> filterTypes, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true,
|
||||
IEnumerable<string> tagNames = null);
|
||||
|
||||
/// <summary>
|
||||
/// Get folder, contains folder with id
|
||||
@ -301,6 +334,21 @@ public interface IFolderDao<T>
|
||||
/// <returns></returns>
|
||||
Task<T> GetFolderIDProjectsAsync(bool createIfNotExists);
|
||||
|
||||
/// <summary>
|
||||
/// Returns id folder "VirtualRooms"
|
||||
/// Only in TMFolderDao
|
||||
/// </summary>
|
||||
/// <param name="createIfNotExists"></param>
|
||||
/// <returns></returns>
|
||||
Task<T> GetFolderIDVirtualRooms(bool createIfNotExists);
|
||||
|
||||
/// <summary>
|
||||
/// Returns id folder "Archive"
|
||||
/// Only in TMFolderDao
|
||||
/// </summary>
|
||||
/// <param name="createIfNotExists"></param>
|
||||
/// <returns></returns>
|
||||
Task<T> GetFolderIDArchive(bool createIfNotExists);
|
||||
|
||||
/// <summary>
|
||||
/// Return id of related object
|
||||
|
@ -34,6 +34,8 @@ public interface IProviderDao
|
||||
IAsyncEnumerable<IProviderInfo> GetProvidersInfoAsync(FolderType folderType, string searchText = null);
|
||||
IAsyncEnumerable<IProviderInfo> GetProvidersInfoAsync(Guid userId);
|
||||
Task<int> SaveProviderInfoAsync(string providerKey, string customerTitle, AuthData authData, FolderType folderType);
|
||||
Task<bool> UpdateProviderInfoAsync(int linkId, FolderType rootFolderType);
|
||||
Task<bool> UpdateProviderInfoAsync(int linkId, string folderId, FolderType folderType);
|
||||
Task<int> UpdateProviderInfoAsync(int linkId, string customerTitle, AuthData authData, FolderType folderType, Guid? userId = null);
|
||||
Task RemoveProviderInfoAsync(int linkId);
|
||||
}
|
||||
|
@ -32,9 +32,11 @@ public interface IProviderInfo : IDisposable
|
||||
string ProviderKey { get; }
|
||||
Guid Owner { get; }
|
||||
FolderType RootFolderType { get; }
|
||||
FolderType FolderType { get; }
|
||||
DateTime CreateOn { get; }
|
||||
string CustomerTitle { get; }
|
||||
string RootFolderId { get; }
|
||||
string FolderId { get; }
|
||||
|
||||
Task<bool> CheckAccessAsync();
|
||||
Task InvalidateStorageAsync();
|
||||
|
@ -39,10 +39,15 @@ public interface ITagDao<T>
|
||||
IAsyncEnumerable<Tag> GetTagsAsync(Guid owner, TagType tagType);
|
||||
IAsyncEnumerable<Tag> GetTagsAsync(string name, TagType tagType);
|
||||
IAsyncEnumerable<Tag> GetTagsAsync(string[] names, TagType tagType);
|
||||
IAsyncEnumerable<TagInfo> GetTagsInfoAsync(string searchText, TagType tagType, bool byName, int from = 0, int count = 0);
|
||||
IAsyncEnumerable<TagInfo> GetTagsInfoAsync(IEnumerable<string> names);
|
||||
IEnumerable<Tag> SaveTags(IEnumerable<Tag> tag);
|
||||
IEnumerable<Tag> SaveTags(Tag tag);
|
||||
Task<TagInfo> SaveTagInfoAsync(TagInfo tagInfo);
|
||||
void UpdateNewTags(IEnumerable<Tag> tag);
|
||||
void UpdateNewTags(Tag tag);
|
||||
Task RemoveTagsAsync(IEnumerable<int> tagsIds);
|
||||
Task RemoveTagsAsync(FileEntry<T> entry, IEnumerable<int> tagsIds);
|
||||
void RemoveTags(IEnumerable<Tag> tag);
|
||||
void RemoveTags(Tag tag);
|
||||
}
|
||||
|
@ -38,6 +38,8 @@ internal class FolderDao : AbstractDao, IFolderDao<int>
|
||||
private const string Privacy = "privacy";
|
||||
private const string Trash = "trash";
|
||||
private const string Projects = "projects";
|
||||
private const string VirtualRooms = "virtualrooms";
|
||||
private const string Archive = "archive";
|
||||
|
||||
private readonly FactoryIndexerFolder _factoryIndexer;
|
||||
private readonly GlobalSpace _globalSpace;
|
||||
@ -46,6 +48,10 @@ internal class FolderDao : AbstractDao, IFolderDao<int>
|
||||
private readonly CrossDao _crossDao;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
private static readonly List<FilterType> _constraintFolderFilters =
|
||||
new List<FilterType> { FilterType.FilesOnly, FilterType.ByExtension, FilterType.DocumentsOnly, FilterType.ImagesOnly,
|
||||
FilterType.PresentationsOnly, FilterType.SpreadsheetsOnly, FilterType.ArchiveOnly, FilterType.MediaOnly };
|
||||
|
||||
public FolderDao(
|
||||
FactoryIndexerFolder factoryIndexer,
|
||||
UserManager userManager,
|
||||
@ -154,15 +160,19 @@ internal class FolderDao : AbstractDao, IFolderDao<int>
|
||||
|
||||
public IAsyncEnumerable<Folder<int>> GetFoldersAsync(int parentId)
|
||||
{
|
||||
return GetFoldersAsync(parentId, default, default, false, default, string.Empty);
|
||||
return GetFoldersAsync(parentId, default, FilterType.None, false, default, string.Empty);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<int>> GetFoldersAsync(int parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false)
|
||||
public IAsyncEnumerable<Folder<int>> GetFoldersAsync(int parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (filterType == FilterType.FilesOnly || filterType == FilterType.ByExtension
|
||||
|| filterType == FilterType.DocumentsOnly || filterType == FilterType.ImagesOnly
|
||||
|| filterType == FilterType.PresentationsOnly || filterType == FilterType.SpreadsheetsOnly
|
||||
|| filterType == FilterType.ArchiveOnly || filterType == FilterType.MediaOnly)
|
||||
return GetFoldersAsync(parentId, orderBy, new[] { filterType }, subjectGroup, subjectID, searchText, withSubfolders, tagNames);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<int>> GetFoldersAsync(int parentId, OrderBy orderBy, IEnumerable<FilterType> filterTypes, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (!CheckForInvalidFilters(filterTypes))
|
||||
{
|
||||
return AsyncEnumerable.Empty<Folder<int>>();
|
||||
}
|
||||
@ -174,6 +184,8 @@ internal class FolderDao : AbstractDao, IFolderDao<int>
|
||||
|
||||
var q = GetFolderQuery(r => r.ParentId == parentId).AsNoTracking();
|
||||
|
||||
q = SetFilterByTypes(q, filterTypes);
|
||||
|
||||
if (withSubfolders)
|
||||
{
|
||||
q = GetFolderQuery().AsNoTracking()
|
||||
@ -215,23 +227,37 @@ internal class FolderDao : AbstractDao, IFolderDao<int>
|
||||
}
|
||||
}
|
||||
|
||||
if (tagNames != null && tagNames.Any())
|
||||
{
|
||||
q = q.Join(FilesDbContext.TagLink, f => f.Id.ToString(), t => t.EntryId, (folder, tag) => new { folder, tag.TagId })
|
||||
.Join(FilesDbContext.Tag, r => r.TagId, t => t.Id, (result, tagInfo) => new { result.folder, result.TagId, tagInfo.Name })
|
||||
.Where(r => tagNames.Contains(r.Name))
|
||||
.Select(r => r.folder).Distinct();
|
||||
}
|
||||
|
||||
var dbFolders = FromQueryWithShared(q).AsAsyncEnumerable();
|
||||
|
||||
return dbFolders.Select(_mapper.Map<DbFolderQuery, Folder<int>>);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<int>> GetFoldersAsync(IEnumerable<int> folderIds, FilterType filterType = FilterType.None, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true)
|
||||
public IAsyncEnumerable<Folder<int>> GetFoldersAsync(IEnumerable<int> folderIds, FilterType filterType = FilterType.None, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (filterType == FilterType.FilesOnly || filterType == FilterType.ByExtension
|
||||
|| filterType == FilterType.DocumentsOnly || filterType == FilterType.ImagesOnly
|
||||
|| filterType == FilterType.PresentationsOnly || filterType == FilterType.SpreadsheetsOnly
|
||||
|| filterType == FilterType.ArchiveOnly || filterType == FilterType.MediaOnly)
|
||||
return GetFoldersAsync(folderIds, new[] { filterType }, subjectGroup, subjectID, searchText, searchSubfolders, checkShare, tagNames);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<int>> GetFoldersAsync(IEnumerable<int> folderIds, IEnumerable<FilterType> filterTypes, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (!CheckForInvalidFilters(filterTypes))
|
||||
{
|
||||
return AsyncEnumerable.Empty<Folder<int>>();
|
||||
}
|
||||
|
||||
var q = GetFolderQuery(r => folderIds.Contains(r.Id)).AsNoTracking();
|
||||
|
||||
q = SetFilterByTypes(q, filterTypes);
|
||||
|
||||
if (searchSubfolders)
|
||||
{
|
||||
q = GetFolderQuery()
|
||||
@ -271,6 +297,14 @@ internal class FolderDao : AbstractDao, IFolderDao<int>
|
||||
}
|
||||
}
|
||||
|
||||
if (tagNames != null && tagNames.Any())
|
||||
{
|
||||
q = q.Join(FilesDbContext.TagLink, f => f.Id.ToString(), t => t.EntryId, (folder, tag) => new { folder, tag.TagId })
|
||||
.Join(FilesDbContext.Tag, r => r.TagId, t => t.Id, (result, tagInfo) => new { result.folder, result.TagId, tagInfo.Name })
|
||||
.Where(r => tagNames.Contains(r.Name))
|
||||
.Select(r => r.folder).Distinct();
|
||||
}
|
||||
|
||||
var dbFolders = (checkShare ? FromQueryWithShared(q) : FromQuery(q)).AsAsyncEnumerable();
|
||||
|
||||
return dbFolders.Select(_mapper.Map<DbFolderQuery, Folder<int>>).Distinct();
|
||||
@ -543,7 +577,7 @@ internal class FolderDao : AbstractDao, IFolderDao<int>
|
||||
{
|
||||
var folder = await GetFolderAsync(folderId).ConfigureAwait(false);
|
||||
|
||||
if (folder.FolderType != FolderType.DEFAULT)
|
||||
if (folder.FolderType != FolderType.DEFAULT && !DocSpaceHelper.IsRoom(folder.FolderType))
|
||||
{
|
||||
throw new ArgumentException("It is forbidden to move the System folder.", nameof(folderId));
|
||||
}
|
||||
@ -990,6 +1024,14 @@ internal class FolderDao : AbstractDao, IFolderDao<int>
|
||||
folder.FolderType = FolderType.Projects;
|
||||
folder.Title = Projects;
|
||||
break;
|
||||
case VirtualRooms:
|
||||
folder.FolderType = FolderType.VirtualRooms;
|
||||
folder.Title = VirtualRooms;
|
||||
break;
|
||||
case Archive:
|
||||
folder.FolderType = FolderType.Archive;
|
||||
folder.Title = Archive;
|
||||
break;
|
||||
default:
|
||||
folder.FolderType = FolderType.BUNCH;
|
||||
folder.Title = key;
|
||||
@ -1092,6 +1134,14 @@ internal class FolderDao : AbstractDao, IFolderDao<int>
|
||||
folder.FolderType = FolderType.Projects;
|
||||
folder.Title = Projects;
|
||||
break;
|
||||
case VirtualRooms:
|
||||
folder.FolderType = FolderType.VirtualRooms;
|
||||
folder.Title = VirtualRooms;
|
||||
break;
|
||||
case Archive:
|
||||
folder.FolderType = FolderType.Archive;
|
||||
folder.Title = Archive;
|
||||
break;
|
||||
default:
|
||||
folder.FolderType = FolderType.BUNCH;
|
||||
folder.Title = key;
|
||||
@ -1166,6 +1216,16 @@ internal class FolderDao : AbstractDao, IFolderDao<int>
|
||||
return (this as IFolderDao<int>).GetFolderIDAsync(FileConstant.ModuleId, Privacy, (userId ?? _authContext.CurrentAccount.ID).ToString(), createIfNotExists);
|
||||
}
|
||||
|
||||
public Task<int> GetFolderIDVirtualRooms(bool createIfNotExists)
|
||||
{
|
||||
return (this as IFolderDao<int>).GetFolderIDAsync(FileConstant.ModuleId, VirtualRooms, null, createIfNotExists);
|
||||
}
|
||||
|
||||
public Task<int> GetFolderIDArchive(bool createIfNotExists)
|
||||
{
|
||||
return (this as IFolderDao<int>).GetFolderIDAsync(FileConstant.ModuleId, Archive, null, createIfNotExists);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
protected internal IQueryable<DbFolder> GetFolderQuery(Expression<Func<DbFolder, bool>> where = null)
|
||||
@ -1296,6 +1356,33 @@ internal class FolderDao : AbstractDao, IFolderDao<int>
|
||||
return q1.Union(q2);
|
||||
}
|
||||
|
||||
private bool CheckForInvalidFilters(IEnumerable<FilterType> filterTypes)
|
||||
{
|
||||
var intersection = filterTypes.Intersect(_constraintFolderFilters);
|
||||
|
||||
return !intersection.Any();
|
||||
}
|
||||
|
||||
private IQueryable<DbFolder> SetFilterByTypes(IQueryable<DbFolder> q, IEnumerable<FilterType> filterTypes)
|
||||
{
|
||||
if (filterTypes.Any() && !filterTypes.Contains(FilterType.None))
|
||||
{
|
||||
var filter = filterTypes.Select(f => f switch
|
||||
{
|
||||
FilterType.FillingFormsRooms => FolderType.FillingFormsRoom,
|
||||
FilterType.EditingRooms => FolderType.EditingRoom,
|
||||
FilterType.ReviewRooms => FolderType.ReviewRoom,
|
||||
FilterType.ReadOnlyRooms => FolderType.ReadOnlyRoom,
|
||||
FilterType.CustomRooms => FolderType.CustomRoom,
|
||||
_ => FolderType.CustomRoom
|
||||
}).ToHashSet();
|
||||
|
||||
q = q.Where(r => filter.Contains(r.FolderType));
|
||||
}
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
private string GetProjectTitle(object folderID)
|
||||
{
|
||||
return "";
|
||||
|
@ -215,6 +215,54 @@ internal class TagDao<T> : AbstractDao, ITagDao<T>
|
||||
}
|
||||
}
|
||||
|
||||
public async IAsyncEnumerable<TagInfo> GetTagsInfoAsync(string searchText, TagType tagType, bool byName, int from = 0, int count = 0)
|
||||
{
|
||||
var q = Query(FilesDbContext.Tag).AsNoTracking().Where(r => r.Type == tagType);
|
||||
|
||||
if (byName)
|
||||
{
|
||||
q = q.Where(r => r.Name == searchText);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(searchText))
|
||||
{
|
||||
var lowerText = searchText.ToLower().Trim().Replace("%", "\\%").Replace("_", "\\_");
|
||||
q = q.Where(r => r.Name.ToLower().Contains(lowerText));
|
||||
}
|
||||
|
||||
if (count != 0)
|
||||
{
|
||||
q = q.Take(count);
|
||||
}
|
||||
|
||||
q = q.Skip(from);
|
||||
|
||||
await foreach (var tag in FromQueryAsync(q).ConfigureAwait(false))
|
||||
{
|
||||
yield return tag;
|
||||
}
|
||||
}
|
||||
|
||||
public async IAsyncEnumerable<TagInfo> GetTagsInfoAsync(IEnumerable<string> names)
|
||||
{
|
||||
var q = Query(FilesDbContext.Tag).AsNoTracking().Where(r => names.Contains(r.Name));
|
||||
|
||||
await foreach (var tag in FromQueryAsync(q).ConfigureAwait(false))
|
||||
{
|
||||
yield return tag;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<TagInfo> SaveTagInfoAsync(TagInfo tagInfo)
|
||||
{
|
||||
var tagDb = _mapper.Map<TagInfo, DbFilesTag>(tagInfo);
|
||||
tagDb.TenantId = TenantID;
|
||||
|
||||
var tag = await FilesDbContext.Tag.AddAsync(tagDb).ConfigureAwait(false);
|
||||
await FilesDbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||
|
||||
return _mapper.Map<DbFilesTag, TagInfo>(tag.Entity);
|
||||
}
|
||||
|
||||
public IEnumerable<Tag> SaveTags(IEnumerable<Tag> tags)
|
||||
{
|
||||
var result = new List<Tag>();
|
||||
@ -485,6 +533,40 @@ internal class TagDao<T> : AbstractDao, ITagDao<T>
|
||||
}
|
||||
}
|
||||
|
||||
public async Task RemoveTagsAsync(FileEntry<T> entry, IEnumerable<int> tagsIds)
|
||||
{
|
||||
var entryId = (await MappingIDAsync(entry.Id).ConfigureAwait(false)).ToString();
|
||||
|
||||
var toDelete = await Query(FilesDbContext.TagLink)
|
||||
.Where(r => tagsIds.Contains(r.TagId) && r.EntryId == entryId && r.EntryType == entry.FileEntryType)
|
||||
.ToListAsync().ConfigureAwait(false);
|
||||
|
||||
FilesDbContext.TagLink.RemoveRange(toDelete);
|
||||
await FilesDbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task RemoveTagsAsync(IEnumerable<int> tagsIds)
|
||||
{
|
||||
var toDeleteTags = await Query(FilesDbContext.Tag)
|
||||
.Where(r => tagsIds.Contains(r.Id)).ToListAsync().ConfigureAwait(false);
|
||||
var toDeleteLinks = await Query(FilesDbContext.TagLink)
|
||||
.Where(r => toDeleteTags.Select(t => t.Id).Contains(r.TagId)).ToListAsync().ConfigureAwait(false);
|
||||
|
||||
var strategy = FilesDbContext.Database.CreateExecutionStrategy();
|
||||
|
||||
await strategy.ExecuteAsync(async () =>
|
||||
{
|
||||
using var tx = await FilesDbContext.Database.BeginTransactionAsync().ConfigureAwait(false);
|
||||
|
||||
FilesDbContext.RemoveRange(toDeleteTags);
|
||||
FilesDbContext.RemoveRange(toDeleteLinks);
|
||||
|
||||
await FilesDbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||
|
||||
await tx.CommitAsync().ConfigureAwait(false);
|
||||
});
|
||||
}
|
||||
|
||||
private Task RemoveTagInDbAsync(Tag tag)
|
||||
{
|
||||
if (tag == null)
|
||||
@ -703,6 +785,26 @@ internal class TagDao<T> : AbstractDao, ITagDao<T>
|
||||
.Distinct()
|
||||
);
|
||||
|
||||
static readonly Func<FilesDbContext, int, Guid, IAsyncEnumerable<TagLinkData>> _newTagsThirdpartyRoomsQuery =
|
||||
Microsoft.EntityFrameworkCore.EF.CompileAsyncQuery((FilesDbContext ctx, int tenantId, Guid subject) =>
|
||||
ctx.Tag
|
||||
.AsNoTracking()
|
||||
.Where(r => r.TenantId == tenantId)
|
||||
.Where(r => subject == Guid.Empty || r.Owner == subject)
|
||||
.Where(r => r.Type == TagType.New)
|
||||
.Join(ctx.TagLink, r => r.Id, l => l.TagId, (tag, link) => new TagLinkData
|
||||
{
|
||||
Tag = tag,
|
||||
Link = link
|
||||
})
|
||||
.Where(r => r.Link.TenantId == r.Tag.TenantId)
|
||||
.Join(ctx.ThirdpartyIdMapping, r => r.Link.EntryId, r => r.HashId, (tagLink, mapping) => new { tagLink, mapping })
|
||||
.Where(r => r.mapping.TenantId == tenantId && r.tagLink.Tag.Owner == subject && r.tagLink.Link.EntryType == FileEntryType.Folder)
|
||||
.Join(ctx.ThirdpartyAccount, r => r.mapping.Id, r => r.FolderId, (tagLinkData, account) => new { tagLinkData, account })
|
||||
.Where(r => r.tagLinkData.mapping.Id == r.account.FolderId && r.account.FolderType == FolderType.VirtualRooms)
|
||||
.Select(r => r.tagLinkData.tagLink).Distinct()
|
||||
);
|
||||
|
||||
static readonly Func<FilesDbContext, List<int>, bool, IAsyncEnumerable<int>> _getFolderQuery = Microsoft.EntityFrameworkCore.EF.CompileAsyncQuery((FilesDbContext ctx, List<int> monitorFolderIdsInt, bool deepSearch) =>
|
||||
ctx.Tree
|
||||
.AsNoTracking()
|
||||
@ -853,6 +955,10 @@ internal class TagDao<T> : AbstractDao, ITagDao<T>
|
||||
result = result.Concat(FromQueryAsync(_newTagsForSBoxQuery(FilesDbContext, tenantId, subject, thirdpartyFolderIds)));
|
||||
}
|
||||
}
|
||||
if (parentFolder.FolderType == FolderType.VirtualRooms)
|
||||
{
|
||||
result = result.Concat(FromQueryAsync(_newTagsThirdpartyRoomsQuery(FilesDbContext, tenantId, subject)));
|
||||
}
|
||||
|
||||
await foreach (var e in result)
|
||||
{
|
||||
@ -872,6 +978,18 @@ internal class TagDao<T> : AbstractDao, ITagDao<T>
|
||||
}
|
||||
}
|
||||
|
||||
protected async IAsyncEnumerable<TagInfo> FromQueryAsync(IQueryable<DbFilesTag> dbFilesTags)
|
||||
{
|
||||
var tags = await dbFilesTags
|
||||
.ToListAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
foreach (var tag in tags)
|
||||
{
|
||||
yield return _mapper.Map<DbFilesTag, TagInfo>(tag);
|
||||
}
|
||||
}
|
||||
|
||||
protected async IAsyncEnumerable<Tag> FromQueryAsync(IAsyncEnumerable<TagLinkData> dbFilesTags)
|
||||
{
|
||||
var files = await dbFilesTags
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
namespace ASC.Files.Core.EF;
|
||||
|
||||
public class DbFilesTag : IDbFile
|
||||
public class DbFilesTag : IDbFile, IMapFrom<TagInfo>
|
||||
{
|
||||
public int TenantId { get; set; }
|
||||
public int Id { get; set; }
|
||||
|
@ -36,9 +36,11 @@ public class DbFilesThirdpartyAccount : BaseEntity, IDbFile, IDbSearch
|
||||
public string Token { get; set; }
|
||||
public Guid UserId { get; set; }
|
||||
public FolderType FolderType { get; set; }
|
||||
public FolderType RoomType { get; set; }
|
||||
public DateTime CreateOn { get; set; }
|
||||
public string Url { get; set; }
|
||||
public int TenantId { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
|
||||
public override object[] GetKeys()
|
||||
{
|
||||
@ -79,6 +81,7 @@ public static class DbFilesThirdpartyAccountExtension
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.FolderType).HasColumnName("folder_type");
|
||||
entity.Property(e => e.RoomType).HasColumnName("room_type");
|
||||
|
||||
entity.Property(e => e.Password)
|
||||
.IsRequired()
|
||||
@ -122,6 +125,12 @@ public static class DbFilesThirdpartyAccountExtension
|
||||
.HasColumnType("varchar(100)")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.FolderId)
|
||||
.HasColumnName("folder_id")
|
||||
.HasColumnType("text")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
});
|
||||
}
|
||||
public static void PgSqlAddDbFilesThirdpartyAccount(this ModelBuilder modelBuilder)
|
||||
@ -141,7 +150,8 @@ public static class DbFilesThirdpartyAccountExtension
|
||||
.HasColumnName("customer_title")
|
||||
.HasMaxLength(400);
|
||||
|
||||
entity.Property(e => e.FolderType).HasColumnName("folder_type");
|
||||
entity.Property(e => e.FolderType).HasColumnName("root_folder_type");
|
||||
entity.Property(e => e.RoomType).HasColumnType("folder_type");
|
||||
|
||||
entity.Property(e => e.Password)
|
||||
.IsRequired()
|
||||
|
@ -24,22 +24,6 @@
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2021
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ASC.Files.Core;
|
||||
|
||||
public enum DateToAutoCleanUp
|
||||
|
@ -24,22 +24,6 @@
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2020
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace ASC.Files.Core;
|
||||
|
||||
|
||||
|
@ -83,6 +83,7 @@ public abstract class FileEntry : ICloneable
|
||||
public Guid RootCreateBy { get; set; }
|
||||
public abstract bool IsNew { get; set; }
|
||||
public FileEntryType FileEntryType { get; set; }
|
||||
public IEnumerable<Tag> Tags { get; set; }
|
||||
|
||||
private string _modifiedByString;
|
||||
private string _createByString;
|
||||
|
@ -41,6 +41,13 @@ public enum FolderType
|
||||
Recent = 11,
|
||||
Templates = 12,
|
||||
Privacy = 13,
|
||||
VirtualRooms = 14,
|
||||
FillingFormsRoom = 15,
|
||||
EditingRoom = 16,
|
||||
ReviewRoom = 17,
|
||||
ReadOnlyRoom = 18,
|
||||
CustomRoom = 19,
|
||||
Archive = 20,
|
||||
}
|
||||
|
||||
public interface IFolder
|
||||
@ -51,6 +58,7 @@ public interface IFolder
|
||||
public bool Shareable { get; set; }
|
||||
public int NewForMe { get; set; }
|
||||
public string FolderUrl { get; set; }
|
||||
public bool Pinned { get; set; }
|
||||
}
|
||||
|
||||
[DebuggerDisplay("{Title} ({Id})")]
|
||||
@ -63,6 +71,7 @@ public class Folder<T> : FileEntry<T>, IFolder, IMapFrom<DbFolder>
|
||||
public bool Shareable { get; set; }
|
||||
public int NewForMe { get; set; }
|
||||
public string FolderUrl { get; set; }
|
||||
public bool Pinned { get; set; }
|
||||
public override bool IsNew
|
||||
{
|
||||
get => Convert.ToBoolean(NewForMe);
|
||||
@ -127,6 +136,12 @@ public class Folder<T> : FileEntry<T>, IFolder, IMapFrom<DbFolder>
|
||||
case FolderType.Projects:
|
||||
result.Title = FilesUCResource.ProjectFiles;
|
||||
break;
|
||||
case FolderType.VirtualRooms:
|
||||
result.Title = FilesUCResource.VirtualRooms;
|
||||
break;
|
||||
case FolderType.Archive:
|
||||
result.Title = FilesUCResource.Archive;
|
||||
break;
|
||||
case FolderType.BUNCH:
|
||||
try
|
||||
{
|
||||
|
@ -37,6 +37,8 @@ public enum TagType
|
||||
Locked = 8,
|
||||
Recent = 16,
|
||||
Template = 32,
|
||||
Custom = 64,
|
||||
Pin = 128,
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
@ -102,13 +104,24 @@ public sealed class Tag : IMapFrom<DbFilesTag>
|
||||
return new Tag("template", TagType.Template, owner, 0).AddEntry(entry);
|
||||
}
|
||||
|
||||
public static Tag Custom<T>(Guid owner, FileEntry<T> entry, string name)
|
||||
{
|
||||
return new Tag(name, TagType.Custom, owner, 0).AddEntry(entry);
|
||||
}
|
||||
|
||||
public static Tag Pin<T>(Guid owner, FileEntry<T> entry)
|
||||
{
|
||||
return new Tag("pin", TagType.Pin, owner, 0).AddEntry(entry);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is Tag f && Equals(f);
|
||||
}
|
||||
|
||||
public bool Equals(Tag f)
|
||||
{
|
||||
return f.Id == Id && f.EntryType == EntryType && Equals(f.EntryId, EntryId);
|
||||
return f != null && f.Id == Id && f.EntryType == EntryType && Equals(f.EntryId, EntryId);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
|
35
products/ASC.Files/Core/Core/Entries/TagInfo.cs
Normal file
35
products/ASC.Files/Core/Core/Entries/TagInfo.cs
Normal file
@ -0,0 +1,35 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Files.Core.Entries;
|
||||
|
||||
public class TagInfo : IMapFrom<DbFilesTag>
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public Guid Owner { get; set; }
|
||||
public TagType Type { get; set; }
|
||||
}
|
@ -237,7 +237,14 @@ public class FileStorageService<T> //: IFileStorageService
|
||||
}));
|
||||
}
|
||||
|
||||
public async Task<DataWrapper<T>> GetFolderItemsAsync(T parentId, int from, int count, FilterType filter, bool subjectGroup, string ssubject, string searchText, bool searchInContent, bool withSubfolders, OrderBy orderBy)
|
||||
public async Task<DataWrapper<T>> GetFolderItemsAsync(T parentId, int from, int count, FilterType filter, bool subjectGroup, string ssubject, string searchText, bool searchInContent, bool withSubfolders, OrderBy orderBy,
|
||||
SearchArea searchArea = SearchArea.Active, IEnumerable<string> tagNames = null)
|
||||
{
|
||||
return await GetFolderItemsAsync(parentId, from, count, new[] { filter }, subjectGroup, ssubject, searchText, searchInContent, withSubfolders, orderBy, searchArea, tagNames);
|
||||
}
|
||||
|
||||
public async Task<DataWrapper<T>> GetFolderItemsAsync(T parentId, int from, int count, IEnumerable<FilterType> filterTypes, bool subjectGroup, string ssubject, string searchText, bool searchInContent, bool withSubfolders, OrderBy orderBy,
|
||||
SearchArea searchArea = SearchArea.Active, IEnumerable<string> tagNames = null)
|
||||
{
|
||||
var subjectId = string.IsNullOrEmpty(ssubject) ? Guid.Empty : new Guid(ssubject);
|
||||
|
||||
@ -284,7 +291,7 @@ public class FileStorageService<T> //: IFileStorageService
|
||||
IEnumerable<FileEntry> entries;
|
||||
try
|
||||
{
|
||||
(entries, total) = await _entryManager.GetEntriesAsync(parent, from, count, filter, subjectGroup, subjectId, searchText, searchInContent, withSubfolders, orderBy);
|
||||
(entries, total) = await _entryManager.GetEntriesAsync(parent, from, count, filterTypes, subjectGroup, subjectId, searchText, searchInContent, withSubfolders, orderBy, searchArea, tagNames);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -410,26 +417,128 @@ public class FileStorageService<T> //: IFileStorageService
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
return InternalCreateNewFolderAsync(parentId, title);
|
||||
return InternalCreateNewFolderAsync(parentId, title, FolderType.DEFAULT);
|
||||
}
|
||||
|
||||
public async Task<Folder<T>> InternalCreateNewFolderAsync(T parentId, string title)
|
||||
public async Task<Folder<T>> CreateRoomAsync(string title, RoomType roomType)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(title, nameof(title));
|
||||
|
||||
var parentId = await _globalFolderHelper.GetFolderVirtualRooms<T>();
|
||||
|
||||
return roomType switch
|
||||
{
|
||||
RoomType.CustomRoom => await CreateCustomRoomAsync(title, parentId),
|
||||
RoomType.FillingFormsRoom => await CreateFillingFormsRoom(title, parentId),
|
||||
RoomType.EditingRoom => await CreateEditingRoom(title, parentId),
|
||||
RoomType.ReviewRoom => await CreateReviewRoom(title, parentId),
|
||||
RoomType.ReadOnlyRoom => await CreateReadOnlyRoom(title, parentId),
|
||||
_ => await CreateCustomRoomAsync(title, parentId),
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<Folder<T>> CreateThirdpartyRoomAsync(string title, RoomType roomType, T parentId)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(title, nameof(title));
|
||||
ArgumentNullException.ThrowIfNull(parentId, nameof(parentId));
|
||||
|
||||
var folderDao = GetFolderDao();
|
||||
var providerDao = GetProviderDao();
|
||||
|
||||
var parent = await folderDao.GetFolderAsync(parentId);
|
||||
var providerInfo = await providerDao.GetProviderInfoAsync(parent.ProviderId);
|
||||
|
||||
if (providerInfo.RootFolderType != FolderType.VirtualRooms)
|
||||
{
|
||||
throw new InvalidOperationException("Invalid provider type");
|
||||
}
|
||||
|
||||
if (providerInfo.FolderId != null)
|
||||
{
|
||||
throw new InvalidOperationException("This provider already corresponds to the virtual room");
|
||||
}
|
||||
|
||||
var room = roomType switch
|
||||
{
|
||||
RoomType.CustomRoom => await CreateCustomRoomAsync(title, parentId),
|
||||
RoomType.FillingFormsRoom => await CreateFillingFormsRoom(title, parentId),
|
||||
RoomType.EditingRoom => await CreateEditingRoom(title, parentId),
|
||||
RoomType.ReviewRoom => await CreateReviewRoom(title, parentId),
|
||||
RoomType.ReadOnlyRoom => await CreateReadOnlyRoom(title, parentId),
|
||||
_ => await CreateCustomRoomAsync(title, parentId),
|
||||
};
|
||||
|
||||
var folderType = roomType switch
|
||||
{
|
||||
RoomType.CustomRoom => FolderType.CustomRoom,
|
||||
RoomType.ReviewRoom => FolderType.ReviewRoom,
|
||||
RoomType.EditingRoom => FolderType.EditingRoom,
|
||||
RoomType.FillingFormsRoom => FolderType.FillingFormsRoom,
|
||||
RoomType.ReadOnlyRoom => FolderType.ReadOnlyRoom,
|
||||
_ => FolderType.CustomRoom
|
||||
};
|
||||
|
||||
await providerDao.UpdateProviderInfoAsync(providerInfo.ID, room.Id.ToString(), folderType);
|
||||
|
||||
return room;
|
||||
}
|
||||
|
||||
private async Task<Folder<T>> CreateCustomRoomAsync(string title, T parentId)
|
||||
{
|
||||
return await InternalCreateNewFolderAsync(parentId, title, FolderType.CustomRoom);
|
||||
}
|
||||
|
||||
private async Task<Folder<T>> CreateFillingFormsRoom(string title, T parentId)
|
||||
{
|
||||
return await InternalCreateNewFolderAsync(parentId, title, FolderType.FillingFormsRoom);
|
||||
}
|
||||
|
||||
private async Task<Folder<T>> CreateReviewRoom(string title, T parentId)
|
||||
{
|
||||
return await InternalCreateNewFolderAsync(parentId, title, FolderType.ReviewRoom);
|
||||
}
|
||||
|
||||
private async Task<Folder<T>> CreateReadOnlyRoom(string title, T parentId)
|
||||
{
|
||||
return await InternalCreateNewFolderAsync(parentId, title, FolderType.ReadOnlyRoom);
|
||||
}
|
||||
|
||||
private async Task<Folder<T>> CreateEditingRoom(string title, T parentId)
|
||||
{
|
||||
return await InternalCreateNewFolderAsync(parentId, title, FolderType.EditingRoom);
|
||||
}
|
||||
|
||||
public async Task<Folder<T>> InternalCreateNewFolderAsync(T parentId, string title, FolderType folderType = FolderType.DEFAULT)
|
||||
{
|
||||
var folderDao = GetFolderDao();
|
||||
|
||||
var parent = await folderDao.GetFolderAsync(parentId);
|
||||
var isRoom = DocSpaceHelper.IsRoom(folderType);
|
||||
|
||||
ErrorIf(parent == null, FilesCommonResource.ErrorMassage_FolderNotFound);
|
||||
ErrorIf(!await _fileSecurity.CanCreateAsync(parent), FilesCommonResource.ErrorMassage_SecurityException_Create);
|
||||
ErrorIf(parent.RootFolderType == FolderType.Archive, FilesCommonResource.ErrorMessage_UpdateArchivedRoom);
|
||||
ErrorIf(parent.FolderType == FolderType.Archive, FilesCommonResource.ErrorMassage_SecurityException);
|
||||
ErrorIf(!isRoom && parent.FolderType == FolderType.VirtualRooms, FilesCommonResource.ErrorMassage_SecurityException_Create);
|
||||
|
||||
try
|
||||
{
|
||||
var newFolder = _serviceProvider.GetService<Folder<T>>();
|
||||
newFolder.Title = title;
|
||||
newFolder.ParentId = parent.Id;
|
||||
newFolder.FolderType = folderType;
|
||||
|
||||
var folderId = await folderDao.SaveFolderAsync(newFolder);
|
||||
var folder = await folderDao.GetFolderAsync(folderId);
|
||||
_filesMessageService.Send(folder, GetHttpHeaders(), MessageAction.FolderCreated, folder.Title);
|
||||
|
||||
if (isRoom)
|
||||
{
|
||||
_filesMessageService.Send(folder, GetHttpHeaders(), MessageAction.RoomCreated, folder.Title);
|
||||
}
|
||||
else
|
||||
{
|
||||
_filesMessageService.Send(folder, GetHttpHeaders(), MessageAction.FolderCreated, folder.Title);
|
||||
}
|
||||
|
||||
return folder;
|
||||
}
|
||||
@ -445,13 +554,19 @@ public class FileStorageService<T> //: IFileStorageService
|
||||
var folderDao = GetFolderDao();
|
||||
var folder = await folderDao.GetFolderAsync(folderId);
|
||||
ErrorIf(folder == null, FilesCommonResource.ErrorMassage_FolderNotFound);
|
||||
ErrorIf(!await _fileSecurity.CanEditAsync(folder), FilesCommonResource.ErrorMassage_SecurityException_RenameFolder);
|
||||
if (!await _fileSecurity.CanDeleteAsync(folder) && _userManager.GetUsers(_authContext.CurrentAccount.ID).IsVisitor(_userManager))
|
||||
|
||||
var canEdit = (folder.FolderType == FolderType.FillingFormsRoom || folder.FolderType == FolderType.EditingRoom
|
||||
|| folder.FolderType == FolderType.ReviewRoom || folder.FolderType == FolderType.ReadOnlyRoom || folder.FolderType == FolderType.CustomRoom)
|
||||
? await _fileSecurity.CanEditRoomAsync(folder) : await _fileSecurity.CanRenameAsync(folder);
|
||||
|
||||
ErrorIf(!canEdit, FilesCommonResource.ErrorMassage_SecurityException_RenameFolder);
|
||||
if (!canEdit && _userManager.GetUsers(_authContext.CurrentAccount.ID).IsVisitor(_userManager))
|
||||
{
|
||||
throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException_RenameFolder);
|
||||
}
|
||||
|
||||
ErrorIf(folder.RootFolderType == FolderType.TRASH, FilesCommonResource.ErrorMassage_ViewTrashItem);
|
||||
ErrorIf(folder.RootFolderType == FolderType.Archive, FilesCommonResource.ErrorMessage_UpdateArchivedRoom);
|
||||
|
||||
var folderAccess = folder.Access;
|
||||
|
||||
@ -461,7 +576,14 @@ public class FileStorageService<T> //: IFileStorageService
|
||||
folder = await folderDao.GetFolderAsync(newFolderID);
|
||||
folder.Access = folderAccess;
|
||||
|
||||
_filesMessageService.Send(folder, GetHttpHeaders(), MessageAction.FolderRenamed, folder.Title);
|
||||
if (DocSpaceHelper.IsRoom(folder.FolderType))
|
||||
{
|
||||
_filesMessageService.Send(folder, GetHttpHeaders(), MessageAction.RoomRenamed, folder.Title);
|
||||
}
|
||||
else
|
||||
{
|
||||
_filesMessageService.Send(folder, GetHttpHeaders(), MessageAction.FolderRenamed, folder.Title);
|
||||
}
|
||||
|
||||
//if (!folder.ProviderEntry)
|
||||
//{
|
||||
@ -598,7 +720,9 @@ public class FileStorageService<T> //: IFileStorageService
|
||||
if (!EqualityComparer<T>.Default.Equals(fileWrapper.ParentId, default(T)))
|
||||
{
|
||||
folder = await folderDao.GetFolderAsync(fileWrapper.ParentId);
|
||||
var canCreate = await _fileSecurity.CanCreateAsync(folder);
|
||||
var canCreate = await _fileSecurity.CanCreateAsync(folder) && folder.FolderType != FolderType.VirtualRooms
|
||||
&& folder.FolderType != FolderType.Archive;
|
||||
|
||||
if (!canCreate)
|
||||
{
|
||||
folder = null;
|
||||
@ -1482,12 +1606,17 @@ public class FileStorageService<T> //: IFileStorageService
|
||||
var folderDao = GetFolderDao();
|
||||
|
||||
ErrorIf(thirdPartyParams == null, FilesCommonResource.ErrorMassage_BadRequest);
|
||||
var parentFolder = await folderDaoInt.GetFolderAsync(thirdPartyParams.Corporate && !_coreBaseSettings.Personal ? await _globalFolderHelper.FolderCommonAsync : _globalFolderHelper.FolderMy);
|
||||
|
||||
var folderId = thirdPartyParams.Corporate && !_coreBaseSettings.Personal ? await _globalFolderHelper.FolderCommonAsync
|
||||
: thirdPartyParams.RoomsStorage && !_coreBaseSettings.DisableDocSpace ? await _globalFolderHelper.FolderVirtualRoomsAsync : _globalFolderHelper.FolderMy;
|
||||
|
||||
var parentFolder = await folderDaoInt.GetFolderAsync(folderId);
|
||||
|
||||
ErrorIf(!await _fileSecurity.CanCreateAsync(parentFolder), FilesCommonResource.ErrorMassage_SecurityException_Create);
|
||||
ErrorIf(!_filesSettingsHelper.EnableThirdParty, FilesCommonResource.ErrorMassage_SecurityException_Create);
|
||||
|
||||
var lostFolderType = FolderType.USER;
|
||||
var folderType = thirdPartyParams.Corporate ? FolderType.COMMON : FolderType.USER;
|
||||
var folderType = thirdPartyParams.Corporate ? FolderType.COMMON : thirdPartyParams.RoomsStorage ? FolderType.VirtualRooms : FolderType.USER;
|
||||
|
||||
int curProviderId;
|
||||
|
||||
@ -2174,9 +2303,9 @@ public class FileStorageService<T> //: IFileStorageService
|
||||
|
||||
#endregion
|
||||
|
||||
public Task<List<AceWrapper>> GetSharedInfoAsync(IEnumerable<T> fileIds, IEnumerable<T> folderIds)
|
||||
public Task<List<AceWrapper>> GetSharedInfoAsync(IEnumerable<T> fileIds, IEnumerable<T> folderIds, bool invite = false)
|
||||
{
|
||||
return _fileSharing.GetSharedInfoAsync(fileIds, folderIds);
|
||||
return _fileSharing.GetSharedInfoAsync(fileIds, folderIds, invite);
|
||||
}
|
||||
|
||||
public Task<List<AceShortWrapper>> GetSharedInfoShortFileAsync(T fileId)
|
||||
@ -2189,7 +2318,7 @@ public class FileStorageService<T> //: IFileStorageService
|
||||
return _fileSharing.GetSharedInfoShortFolderAsync(folderId);
|
||||
}
|
||||
|
||||
public async Task<List<T>> SetAceObjectAsync(AceCollection<T> aceCollection, bool notify)
|
||||
public async Task<List<T>> SetAceObjectAsync(AceCollection<T> aceCollection, bool notify, bool invite = false)
|
||||
{
|
||||
var fileDao = GetFileDao();
|
||||
var folderDao = GetFolderDao();
|
||||
@ -2211,15 +2340,24 @@ public class FileStorageService<T> //: IFileStorageService
|
||||
{
|
||||
try
|
||||
{
|
||||
var changed = await _fileSharingAceHelper.SetAceObjectAsync(aceCollection.Aces, entry, notify, aceCollection.Message, aceCollection.AdvancedSettings);
|
||||
var changed = await _fileSharingAceHelper.SetAceObjectAsync(aceCollection.Aces, entry, notify, aceCollection.Message, aceCollection.AdvancedSettings, !_coreBaseSettings.DisableDocSpace, invite);
|
||||
if (changed)
|
||||
{
|
||||
foreach (var ace in aceCollection.Aces)
|
||||
{
|
||||
var name = ace.SubjectGroup ? _userManager.GetGroupInfo(ace.SubjectId).Name : _userManager.GetUsers(ace.SubjectId).DisplayUserName(false, _displayUserSettingsHelper);
|
||||
_filesMessageService.Send(entry, GetHttpHeaders(),
|
||||
entry.FileEntryType == FileEntryType.Folder ? MessageAction.FolderUpdatedAccessFor : MessageAction.FileUpdatedAccessFor,
|
||||
entry.Title, name, GetAccessString(ace.Share));
|
||||
|
||||
if (entry.FileEntryType == FileEntryType.Folder && DocSpaceHelper.IsRoom(((Folder<T>)entry).FolderType))
|
||||
{
|
||||
_filesMessageService.Send(entry, GetHttpHeaders(), MessageAction.RoomUpdateAccess, entry.Title, name, GetAccessString(ace.Share));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
_filesMessageService.Send(entry, GetHttpHeaders(),
|
||||
entry.FileEntryType == FileEntryType.Folder ? MessageAction.FolderUpdatedAccessFor : MessageAction.FileUpdatedAccessFor,
|
||||
entry.Title, name, GetAccessString(ace.Share));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2360,6 +2498,32 @@ public class FileStorageService<T> //: IFileStorageService
|
||||
return new List<MentionWrapper>(users);
|
||||
}
|
||||
|
||||
public async Task<Folder<T>> SetPinnedStatusAsync(T folderId, bool pin)
|
||||
{
|
||||
var folderDao = GetFolderDao();
|
||||
|
||||
var room = await folderDao.GetFolderAsync(folderId);
|
||||
|
||||
ErrorIf(room == null, FilesCommonResource.ErrorMassage_FolderNotFound);
|
||||
ErrorIf(!await _fileSecurity.CanReadAsync(room), FilesCommonResource.ErrorMassage_SecurityException_ReadFolder);
|
||||
|
||||
var tagDao = GetTagDao();
|
||||
var tag = Tag.Pin(_authContext.CurrentAccount.ID, room);
|
||||
|
||||
if (pin)
|
||||
{
|
||||
tagDao.SaveTags(tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
tagDao.RemoveTags(tag);
|
||||
}
|
||||
|
||||
room.Pinned = pin;
|
||||
|
||||
return room;
|
||||
}
|
||||
|
||||
public async Task<List<AceShortWrapper>> SendEditorNotifyAsync(T fileId, MentionMessageWrapper mentionMessage)
|
||||
{
|
||||
ErrorIf(!_authContext.IsAuthenticated, FilesCommonResource.ErrorMassage_SecurityException);
|
||||
@ -2465,7 +2629,7 @@ public class FileStorageService<T> //: IFileStorageService
|
||||
|
||||
return new List<EncryptionKeyPairDto>(fileKeyPair);
|
||||
}
|
||||
|
||||
|
||||
public bool ChangeExternalShareSettings(bool enable)
|
||||
{
|
||||
ErrorIf(!_global.IsAdministrator, FilesCommonResource.ErrorMassage_SecurityException);
|
||||
|
@ -40,4 +40,9 @@ public enum FilterType
|
||||
[EnumMember] ArchiveOnly = 10,
|
||||
[EnumMember] ByExtension = 11,
|
||||
[EnumMember] MediaOnly = 12,
|
||||
[EnumMember] FillingFormsRooms = 13,
|
||||
[EnumMember] EditingRooms = 14,
|
||||
[EnumMember] ReviewRooms = 15,
|
||||
[EnumMember] ReadOnlyRooms = 16,
|
||||
[EnumMember] CustomRooms = 17,
|
||||
}
|
@ -62,7 +62,7 @@ public class FileSecurity : IFileSecurity
|
||||
private readonly GlobalFolder _globalFolder;
|
||||
private readonly FileSecurityCommon _fileSecurityCommon;
|
||||
private readonly FilesSettingsHelper _filesSettingsHelper;
|
||||
|
||||
|
||||
public FileSecurity(
|
||||
IDaoFactory daoFactory,
|
||||
UserManager userManager,
|
||||
@ -132,7 +132,17 @@ public class FileSecurity : IFileSecurity
|
||||
{
|
||||
return CanAsync(entry, userId, FilesSecurityActions.Delete);
|
||||
}
|
||||
|
||||
public Task<bool> CanEditRoomAsync<T>(FileEntry<T> entry, Guid userId)
|
||||
{
|
||||
return CanAsync(entry, userId, FilesSecurityActions.RoomEdit);
|
||||
}
|
||||
|
||||
public Task<bool> CanRenameAsync<T>(FileEntry<T> entry, Guid userId)
|
||||
{
|
||||
return CanAsync(entry, userId, FilesSecurityActions.Rename);
|
||||
}
|
||||
|
||||
public Task<bool> CanDownloadAsync<T>(FileEntry<T> entry)
|
||||
{
|
||||
return CanDownloadAsync(entry, _authContext.CurrentAccount.ID);
|
||||
@ -193,6 +203,11 @@ public class FileSecurity : IFileSecurity
|
||||
return CanEditAsync(entry, _authContext.CurrentAccount.ID);
|
||||
}
|
||||
|
||||
public Task<bool> CanRenameAsync<T>(FileEntry<T> entry)
|
||||
{
|
||||
return CanRenameAsync(entry, _authContext.CurrentAccount.ID);
|
||||
}
|
||||
|
||||
public Task<bool> CanDeleteAsync<T>(FileEntry<T> entry)
|
||||
{
|
||||
return CanDeleteAsync(entry, _authContext.CurrentAccount.ID);
|
||||
@ -201,7 +216,12 @@ public class FileSecurity : IFileSecurity
|
||||
{
|
||||
return CanDownloadAsync(entry, _authContext.CurrentAccount.ID);
|
||||
}
|
||||
|
||||
|
||||
public Task<bool> CanEditRoomAsync<T>(FileEntry<T> entry)
|
||||
{
|
||||
return CanEditRoomAsync(entry, _authContext.CurrentAccount.ID);
|
||||
}
|
||||
|
||||
public Task<bool> CanShare<T>(FileEntry<T> entry)
|
||||
{
|
||||
return CanShareAsync(entry, _authContext.CurrentAccount.ID);
|
||||
@ -312,6 +332,32 @@ public class FileSecurity : IFileSecurity
|
||||
defaultShareRecord = null;
|
||||
break;
|
||||
|
||||
case FolderType.VirtualRooms:
|
||||
defaultShareRecord = new FileShareRecord
|
||||
{
|
||||
Level = int.MaxValue,
|
||||
EntryId = entry.Id,
|
||||
EntryType = entry.FileEntryType,
|
||||
Share = FileShare.Read,
|
||||
Subject = WebItemManager.DocumentsProductID,
|
||||
TenantId = _tenantManager.GetCurrentTenant().Id,
|
||||
Owner = entry.RootCreateBy
|
||||
};
|
||||
|
||||
if (!shares.Any())
|
||||
{
|
||||
if ((defaultShareRecord.Share == FileShare.Read && action == FilesSecurityActions.Read) ||
|
||||
(defaultShareRecord.Share == FileShare.ReadWrite))
|
||||
{
|
||||
return _userManager.GetUsersByGroup(defaultShareRecord.Subject)
|
||||
.Where(x => x.Status == EmployeeStatus.Active).Select(y => y.Id).Distinct();
|
||||
}
|
||||
|
||||
return Enumerable.Empty<Guid>();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
defaultShareRecord = null;
|
||||
break;
|
||||
@ -374,7 +420,7 @@ public class FileSecurity : IFileSecurity
|
||||
{
|
||||
return (await FilterAsync(new[] { entry }, action, userId, shares)).Any();
|
||||
}
|
||||
|
||||
|
||||
public async Task<IEnumerable<File<T>>> FilterDownloadAsync<T>(IEnumerable<File<T>> entries)
|
||||
{
|
||||
return (await FilterReadAsync(entries)).Where(CheckDenyDownload).ToList();
|
||||
@ -446,7 +492,9 @@ public class FileSecurity : IFileSecurity
|
||||
f.RootFolderType == FolderType.Favorites ||
|
||||
f.RootFolderType == FolderType.Templates ||
|
||||
f.RootFolderType == FolderType.Privacy ||
|
||||
f.RootFolderType == FolderType.Projects;
|
||||
f.RootFolderType == FolderType.Projects ||
|
||||
f.RootFolderType == FolderType.VirtualRooms ||
|
||||
f.RootFolderType == FolderType.Archive;
|
||||
|
||||
var isVisitor = user.IsVisitor(_userManager);
|
||||
|
||||
@ -526,6 +574,11 @@ public class FileSecurity : IFileSecurity
|
||||
// Templates folder read-only
|
||||
continue;
|
||||
}
|
||||
|
||||
if (folder.FolderType == FolderType.Archive)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (isVisitor && e.ProviderEntry)
|
||||
@ -610,6 +663,19 @@ public class FileSecurity : IFileSecurity
|
||||
continue;
|
||||
}
|
||||
|
||||
if (e.RootFolderType == FolderType.VirtualRooms && _fileSecurityCommon.IsAdministrator(userId))
|
||||
{
|
||||
// administrator in VirtualRooms has all right
|
||||
result.Add(e);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (action == FilesSecurityActions.Delete && e.RootFolderType == FolderType.Archive && _fileSecurityCommon.IsAdministrator(userId))
|
||||
{
|
||||
result.Add(e);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (subjects == null)
|
||||
{
|
||||
subjects = GetUserSubjects(userId);
|
||||
@ -663,30 +729,49 @@ public class FileSecurity : IFileSecurity
|
||||
{
|
||||
result.Add(e);
|
||||
}
|
||||
else if (action == FilesSecurityActions.Comment && (e.Access == FileShare.Comment || e.Access == FileShare.Review || e.Access == FileShare.CustomFilter || e.Access == FileShare.ReadWrite))
|
||||
else if (action == FilesSecurityActions.Comment && (e.Access == FileShare.Comment || e.Access == FileShare.Review || e.Access == FileShare.CustomFilter || e.Access == FileShare.ReadWrite || e.Access == FileShare.RoomManager || e.Access == FileShare.Editing))
|
||||
{
|
||||
result.Add(e);
|
||||
}
|
||||
else if (action == FilesSecurityActions.FillForms && (e.Access == FileShare.FillForms || e.Access == FileShare.Review || e.Access == FileShare.ReadWrite))
|
||||
else if (action == FilesSecurityActions.FillForms && (e.Access == FileShare.FillForms || e.Access == FileShare.Review || e.Access == FileShare.ReadWrite || e.Access == FileShare.RoomManager || e.Access == FileShare.Editing))
|
||||
{
|
||||
result.Add(e);
|
||||
}
|
||||
else if (action == FilesSecurityActions.Review && (e.Access == FileShare.Review || e.Access == FileShare.ReadWrite))
|
||||
else if (action == FilesSecurityActions.Review && (e.Access == FileShare.Review || e.Access == FileShare.ReadWrite || e.Access == FileShare.RoomManager || e.Access == FileShare.Editing))
|
||||
{
|
||||
result.Add(e);
|
||||
}
|
||||
else if (action == FilesSecurityActions.CustomFilter && (e.Access == FileShare.CustomFilter || e.Access == FileShare.ReadWrite))
|
||||
else if (action == FilesSecurityActions.CustomFilter && (e.Access == FileShare.CustomFilter || e.Access == FileShare.ReadWrite || e.Access == FileShare.RoomManager || e.Access == FileShare.Editing))
|
||||
{
|
||||
result.Add(e);
|
||||
}
|
||||
else if (action == FilesSecurityActions.Edit && e.Access == FileShare.ReadWrite)
|
||||
else if (action == FilesSecurityActions.Edit && (e.Access == FileShare.ReadWrite || e.Access == FileShare.RoomManager || e.Access == FileShare.Editing))
|
||||
{
|
||||
result.Add(e);
|
||||
}
|
||||
else if (action == FilesSecurityActions.Create && e.Access == FileShare.ReadWrite)
|
||||
else if (action == FilesSecurityActions.Rename && (e.Access == FileShare.ReadWrite || e.Access == FileShare.RoomManager))
|
||||
{
|
||||
result.Add(e);
|
||||
}
|
||||
else if (action == FilesSecurityActions.RoomEdit && e.Access == FileShare.RoomManager)
|
||||
{
|
||||
result.Add(e);
|
||||
}
|
||||
else if (action == FilesSecurityActions.Create && (e.Access == FileShare.ReadWrite || e.Access == FileShare.RoomManager))
|
||||
{
|
||||
result.Add(e);
|
||||
}
|
||||
else if (action == FilesSecurityActions.Delete && (e.Access == FileShare.RoomManager || e.Access == FileShare.ReadWrite))
|
||||
{
|
||||
if (file != null && (file.RootFolderType == FolderType.VirtualRooms || file.RootFolderType == FolderType.Archive))
|
||||
{
|
||||
result.Add(e);
|
||||
}
|
||||
else if (folder != null && folder.FolderType == FolderType.DEFAULT)
|
||||
{
|
||||
result.Add(e);
|
||||
}
|
||||
}
|
||||
else if (e.Access != FileShare.Restrict && e.CreateBy == userId && (e.FileEntryType == FileEntryType.File || folder.FolderType != FolderType.COMMON))
|
||||
{
|
||||
result.Add(e);
|
||||
@ -965,6 +1050,194 @@ public class FileSecurity : IFileSecurity
|
||||
return entries.Where(x => string.IsNullOrEmpty(x.Error)).Cast<FileEntry>().ToList();
|
||||
}
|
||||
|
||||
public async Task<List<FileEntry>> GetVirtualRoomsAsync(IEnumerable<FilterType> filterTypes, Guid subjectId, string searchText, bool searchInContent, bool withSubfolders,
|
||||
OrderBy orderBy, SearchArea searchArea, IEnumerable<string> tagNames)
|
||||
{
|
||||
if (_fileSecurityCommon.IsAdministrator(_authContext.CurrentAccount.ID))
|
||||
{
|
||||
return await GetVirtualRoomsForAdminAsync(filterTypes, subjectId, searchText, searchInContent, withSubfolders, searchArea, orderBy, tagNames);
|
||||
}
|
||||
else
|
||||
{
|
||||
var securityDao = _daoFactory.GetSecurityDao<int>();
|
||||
var subjects = GetUserSubjects(_authContext.CurrentAccount.ID);
|
||||
var records = await securityDao.GetSharesAsync(subjects);
|
||||
var entries = new List<FileEntry>();
|
||||
|
||||
var rooms = await GetVirtualRoomsForUserAsync<int>(records.Where(r => r.EntryId is int), subjects, filterTypes, subjectId, searchText, searchInContent, withSubfolders, searchArea, tagNames);
|
||||
var thirdPartyRooms = await GetVirtualRoomsForUserAsync<string>(records.Where(r => r.EntryId is string), subjects, filterTypes, subjectId, searchText, searchInContent, withSubfolders, searchArea, tagNames);
|
||||
|
||||
entries.AddRange(rooms);
|
||||
entries.AddRange(thirdPartyRooms);
|
||||
|
||||
return entries;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<List<FileEntry>> GetVirtualRoomsForAdminAsync(IEnumerable<FilterType> filterTypes, Guid subjectId, string search, bool searchInContent, bool withSubfolders, SearchArea searchArea,
|
||||
OrderBy orderBy, IEnumerable<string> tagNames)
|
||||
{
|
||||
var folderDao = _daoFactory.GetFolderDao<int>();
|
||||
var folderThirdpartyDao = _daoFactory.GetFolderDao<string>();
|
||||
var fileDao = _daoFactory.GetFileDao<int>();
|
||||
var fileThidpartyDao = _daoFactory.GetFileDao<string>();
|
||||
var providerDao = _daoFactory.ProviderDao;
|
||||
var entries = new List<FileEntry>();
|
||||
|
||||
var foldersInt = new List<FileEntry<int>>();
|
||||
var foldersString = new List<FileEntry<string>>();
|
||||
|
||||
if (searchArea == SearchArea.Any || searchArea == SearchArea.Active)
|
||||
{
|
||||
var roomsFolderId = await _globalFolder.GetFolderVirtualRoomsAsync<int>(_daoFactory);
|
||||
var thirdpartyFoldersId = await providerDao.GetProvidersInfoAsync(FolderType.VirtualRooms).Select(p => p.FolderId).ToListAsync();
|
||||
|
||||
var rooms = await folderDao.GetFoldersAsync(roomsFolderId, orderBy, filterTypes, false, subjectId, search, withSubfolders, tagNames).ToListAsync();
|
||||
var thirdpartyRooms = await folderThirdpartyDao.GetFoldersAsync(thirdpartyFoldersId, filterTypes, false, subjectId, search, withSubfolders, false, tagNames)
|
||||
.ToListAsync();
|
||||
|
||||
foldersInt.AddRange(rooms);
|
||||
foldersString.AddRange(thirdpartyRooms);
|
||||
|
||||
if (withSubfolders)
|
||||
{
|
||||
var files = await fileDao.GetFilesAsync(roomsFolderId, orderBy, FilterType.None, false, subjectId, search, searchInContent, withSubfolders).ToListAsync();
|
||||
var thidpartyFiles = await fileThidpartyDao.GetFilesAsync(thirdpartyFoldersId, FilterType.None, false, subjectId, search, searchInContent);
|
||||
|
||||
entries.AddRange(files);
|
||||
entries.AddRange(thidpartyFiles);
|
||||
}
|
||||
}
|
||||
if (searchArea == SearchArea.Any || searchArea == SearchArea.Archive)
|
||||
{
|
||||
var archiveFolderId = await _globalFolder.GetFolderArchive<int>(_daoFactory);
|
||||
var thirdpartyFoldersId = await providerDao.GetProvidersInfoAsync(FolderType.Archive).Select(p => p.FolderId).ToListAsync();
|
||||
|
||||
var rooms = await folderDao.GetFoldersAsync(archiveFolderId, orderBy, filterTypes, false, subjectId, search, withSubfolders, tagNames).ToListAsync();
|
||||
var thirdpartyRooms = await folderThirdpartyDao.GetFoldersAsync(thirdpartyFoldersId, filterTypes, false, subjectId, search, withSubfolders, false, tagNames)
|
||||
.ToListAsync();
|
||||
|
||||
foldersInt.AddRange(rooms);
|
||||
foldersString.AddRange(thirdpartyRooms);
|
||||
|
||||
if (withSubfolders)
|
||||
{
|
||||
var files = await fileDao.GetFilesAsync(archiveFolderId, orderBy, FilterType.None, false, subjectId, search, searchInContent, withSubfolders).ToListAsync();
|
||||
var thidpartyFiles = await fileThidpartyDao.GetFilesAsync(thirdpartyFoldersId, FilterType.None, false, subjectId, search, searchInContent);
|
||||
|
||||
entries.AddRange(files);
|
||||
entries.AddRange(thidpartyFiles);
|
||||
}
|
||||
}
|
||||
|
||||
await SetTagsAsync(foldersInt);
|
||||
await SetTagsAsync(foldersString);
|
||||
await SetPinAsync(foldersInt);
|
||||
await SetPinAsync(foldersString);
|
||||
|
||||
entries.AddRange(foldersInt);
|
||||
entries.AddRange(foldersString);
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
private async Task<List<FileEntry>> GetVirtualRoomsForUserAsync<T>(IEnumerable<FileShareRecord> records, List<Guid> subjects, IEnumerable<FilterType> filterTypes, Guid subjectId, string search,
|
||||
bool searchInContent, bool withSubfolders, SearchArea searchArea, IEnumerable<string> tagNames)
|
||||
{
|
||||
var folderDao = _daoFactory.GetFolderDao<T>();
|
||||
var fileDao = _daoFactory.GetFileDao<T>();
|
||||
var entries = new List<FileEntry>();
|
||||
|
||||
var folderIds = new Dictionary<T, FileShare>();
|
||||
var recordGroup = records.GroupBy(r => new { r.EntryId, r.EntryType }, (key, group) => new
|
||||
{
|
||||
firstRecord = group.OrderBy(r => r, new SubjectComparer(subjects))
|
||||
.ThenByDescending(r => r.Share, new FileShareRecord.ShareComparer())
|
||||
.First()
|
||||
});
|
||||
|
||||
foreach (var record in recordGroup.Where(r => r.firstRecord.Share != FileShare.Restrict))
|
||||
{
|
||||
if (!folderIds.ContainsKey((T)record.firstRecord.EntryId))
|
||||
{
|
||||
folderIds.Add((T)record.firstRecord.EntryId, record.firstRecord.Share);
|
||||
}
|
||||
}
|
||||
|
||||
Func<FileEntry<T>, bool> filter = f =>
|
||||
{
|
||||
var id = f.FileEntryType == FileEntryType.Folder ? f.Id : f.ParentId;
|
||||
|
||||
if (searchArea == SearchArea.Archive && f.RootFolderType == FolderType.Archive && folderIds[id] == FileShare.RoomManager)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (searchArea == SearchArea.Active && f.RootFolderType == FolderType.VirtualRooms)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (searchArea == SearchArea.Any && (f.RootFolderType == FolderType.VirtualRooms || (f.RootFolderType == FolderType.Archive && folderIds[id] == FileShare.RoomManager)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
var rooms = await folderDao.GetFoldersAsync(folderIds.Keys, filterTypes, false, subjectId, search, withSubfolders, false, tagNames)
|
||||
.Where(filter).ToListAsync();
|
||||
|
||||
await SetTagsAsync(rooms);
|
||||
await SetPinAsync(rooms);
|
||||
|
||||
entries.AddRange(rooms);
|
||||
|
||||
if (withSubfolders)
|
||||
{
|
||||
var files = await fileDao.GetFilesAsync(folderIds.Keys, FilterType.None, false, subjectId, search, searchInContent);
|
||||
entries.AddRange(files.Where(filter));
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
private async Task SetTagsAsync<T>(IEnumerable<FileEntry<T>> entries)
|
||||
{
|
||||
if (!entries.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var tagDao = _daoFactory.GetTagDao<T>();
|
||||
|
||||
var tags = await tagDao.GetTagsAsync(TagType.Custom, entries).ToLookupAsync(f => (T)f.EntryId);
|
||||
|
||||
foreach (var room in entries)
|
||||
{
|
||||
room.Tags = tags[room.Id];
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SetPinAsync<T>(IEnumerable<FileEntry<T>> entries)
|
||||
{
|
||||
if (!entries.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var tagDao = _daoFactory.GetTagDao<T>();
|
||||
|
||||
var tags = await tagDao.GetTagsAsync(_authContext.CurrentAccount.ID, TagType.Pin, entries).ToDictionaryAsync(t => (T)t.EntryId);
|
||||
|
||||
foreach (Folder<T> room in entries.Where(e => e.FileEntryType == FileEntryType.Folder))
|
||||
{
|
||||
if (tags.ContainsKey(room.Id))
|
||||
{
|
||||
room.Pinned = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<FileEntry>> GetPrivacyForMeAsync(FilterType filterType, bool subjectGroup, Guid subjectID, string searchText = "", bool searchInContent = false, bool withSubfolders = false)
|
||||
{
|
||||
var securityDao = _daoFactory.GetSecurityDao<int>();
|
||||
@ -1134,6 +1407,8 @@ public class FileSecurity : IFileSecurity
|
||||
Create,
|
||||
Edit,
|
||||
Delete,
|
||||
CustomFilter
|
||||
CustomFilter,
|
||||
RoomEdit,
|
||||
Rename
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,9 @@ public enum FileShare
|
||||
Review,
|
||||
Comment,
|
||||
FillForms,
|
||||
CustomFilter
|
||||
CustomFilter,
|
||||
RoomManager,
|
||||
Editing
|
||||
}
|
||||
|
||||
public class FileShareConverter : System.Text.Json.Serialization.JsonConverter<FileShare>
|
||||
|
@ -122,6 +122,7 @@ internal abstract class BoxDaoBase : ThirdPartyProviderDao<BoxProviderInfo>
|
||||
folder.Title = MakeFolderTitle(boxFolder);
|
||||
folder.FilesCount = boxFolder.ItemCollection != null ? boxFolder.ItemCollection.Entries.Count(item => item is BoxFile) : 0;
|
||||
folder.FoldersCount = boxFolder.ItemCollection != null ? boxFolder.ItemCollection.Entries.Count(item => item is BoxFolder) : 0;
|
||||
SetFolderType(folder, isRoot);
|
||||
|
||||
if (folder.CreateOn != DateTime.MinValue && folder.CreateOn.Kind == DateTimeKind.Utc)
|
||||
{
|
||||
|
@ -83,18 +83,24 @@ internal class BoxFolderDao : BoxDaoBase, IFolderDao<string>
|
||||
}
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(string parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false)
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(string parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false,
|
||||
IEnumerable<string> tagName = null)
|
||||
{
|
||||
if (filterType == FilterType.FilesOnly || filterType == FilterType.ByExtension
|
||||
|| filterType == FilterType.DocumentsOnly || filterType == FilterType.ImagesOnly
|
||||
|| filterType == FilterType.PresentationsOnly || filterType == FilterType.SpreadsheetsOnly
|
||||
|| filterType == FilterType.ArchiveOnly || filterType == FilterType.MediaOnly)
|
||||
return GetFoldersAsync(parentId, orderBy, new[] { filterType }, subjectGroup, subjectID, searchText, withSubfolders, tagName);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(string parentId, OrderBy orderBy, IEnumerable<FilterType> filterTypes, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (!CheckForInvalidFilters(filterTypes))
|
||||
{
|
||||
return AsyncEnumerable.Empty<Folder<string>>();
|
||||
}
|
||||
|
||||
var folders = GetFoldersAsync(parentId); //TODO:!!!
|
||||
|
||||
folders = SetFilterByTypes(folders, filterTypes);
|
||||
|
||||
if (subjectID != Guid.Empty)
|
||||
{
|
||||
folders = folders.Where(x => subjectGroup
|
||||
@ -107,6 +113,8 @@ internal class BoxFolderDao : BoxDaoBase, IFolderDao<string>
|
||||
folders = folders.Where(x => x.Title.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) != -1);
|
||||
}
|
||||
|
||||
folders = FilterByTags(folders, tagNames);
|
||||
|
||||
if (orderBy == null)
|
||||
{
|
||||
orderBy = new OrderBy(SortedByType.DateAndTime, false);
|
||||
@ -124,18 +132,24 @@ internal class BoxFolderDao : BoxDaoBase, IFolderDao<string>
|
||||
return folders;
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(IEnumerable<string> folderIds, FilterType filterType = FilterType.None, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true)
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(IEnumerable<string> folderIds, FilterType filterType = FilterType.None, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (filterType == FilterType.FilesOnly || filterType == FilterType.ByExtension
|
||||
|| filterType == FilterType.DocumentsOnly || filterType == FilterType.ImagesOnly
|
||||
|| filterType == FilterType.PresentationsOnly || filterType == FilterType.SpreadsheetsOnly
|
||||
|| filterType == FilterType.ArchiveOnly || filterType == FilterType.MediaOnly)
|
||||
return GetFoldersAsync(folderIds, new[] { filterType }, subjectGroup, subjectID, searchText, searchSubfolders, checkShare, tagNames);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(IEnumerable<string> folderIds, IEnumerable<FilterType> filterTypes, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (!CheckForInvalidFilters(filterTypes))
|
||||
{
|
||||
return AsyncEnumerable.Empty<Folder<string>>();
|
||||
}
|
||||
|
||||
var folders = folderIds.ToAsyncEnumerable().SelectAwait(async e => await GetFolderAsync(e).ConfigureAwait(false));
|
||||
|
||||
folders = SetFilterByTypes(folders, filterTypes);
|
||||
|
||||
if (subjectID.HasValue && subjectID != Guid.Empty)
|
||||
{
|
||||
folders = folders.Where(x => subjectGroup
|
||||
@ -148,6 +162,8 @@ internal class BoxFolderDao : BoxDaoBase, IFolderDao<string>
|
||||
folders = folders.Where(x => x.Title.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) != -1);
|
||||
}
|
||||
|
||||
folders = FilterByTags(folders, tagNames);
|
||||
|
||||
return folders;
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,8 @@ internal class BoxProviderInfo : IProviderInfo
|
||||
public string RootFolderId => "box-" + ID;
|
||||
public string ProviderKey { get; set; }
|
||||
public FolderType RootFolderType { get; set; }
|
||||
public FolderType FolderType { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
|
||||
public string BoxRootId
|
||||
{
|
||||
|
@ -126,6 +126,7 @@ internal abstract class DropboxDaoBase : ThirdPartyProviderDao<DropboxProviderIn
|
||||
folder.CreateOn = isRoot ? ProviderInfo.CreateOn : default;
|
||||
folder.ModifiedOn = isRoot ? ProviderInfo.CreateOn : default;
|
||||
folder.Title = MakeFolderTitle(dropboxFolder);
|
||||
SetFolderType(folder, isRoot);
|
||||
|
||||
if (folder.CreateOn != DateTime.MinValue && folder.CreateOn.Kind == DateTimeKind.Utc)
|
||||
{
|
||||
|
@ -85,18 +85,24 @@ internal class DropboxFolderDao : DropboxDaoBase, IFolderDao<string>
|
||||
}
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(string parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false)
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(string parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (filterType == FilterType.FilesOnly || filterType == FilterType.ByExtension
|
||||
|| filterType == FilterType.DocumentsOnly || filterType == FilterType.ImagesOnly
|
||||
|| filterType == FilterType.PresentationsOnly || filterType == FilterType.SpreadsheetsOnly
|
||||
|| filterType == FilterType.ArchiveOnly || filterType == FilterType.MediaOnly)
|
||||
return GetFoldersAsync(parentId, orderBy, new[] { filterType }, subjectGroup, subjectID, searchText, withSubfolders, tagNames);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(string parentId, OrderBy orderBy, IEnumerable<FilterType> filterTypes, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (!CheckForInvalidFilters(filterTypes))
|
||||
{
|
||||
return AsyncEnumerable.Empty<Folder<string>>();
|
||||
}
|
||||
|
||||
var folders = GetFoldersAsync(parentId); //TODO:!!!
|
||||
|
||||
folders = SetFilterByTypes(folders, filterTypes);
|
||||
|
||||
if (subjectID != Guid.Empty)
|
||||
{
|
||||
folders = folders.Where(x => subjectGroup
|
||||
@ -109,6 +115,8 @@ internal class DropboxFolderDao : DropboxDaoBase, IFolderDao<string>
|
||||
folders = folders.Where(x => x.Title.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) != -1);
|
||||
}
|
||||
|
||||
folders = FilterByTags(folders, tagNames);
|
||||
|
||||
if (orderBy == null)
|
||||
{
|
||||
orderBy = new OrderBy(SortedByType.DateAndTime, false);
|
||||
@ -126,18 +134,24 @@ internal class DropboxFolderDao : DropboxDaoBase, IFolderDao<string>
|
||||
return folders;
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(IEnumerable<string> folderIds, FilterType filterType = FilterType.None, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true)
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(IEnumerable<string> folderIds, FilterType filterType = FilterType.None, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (filterType == FilterType.FilesOnly || filterType == FilterType.ByExtension
|
||||
|| filterType == FilterType.DocumentsOnly || filterType == FilterType.ImagesOnly
|
||||
|| filterType == FilterType.PresentationsOnly || filterType == FilterType.SpreadsheetsOnly
|
||||
|| filterType == FilterType.ArchiveOnly || filterType == FilterType.MediaOnly)
|
||||
return GetFoldersAsync(folderIds, new[] { filterType }, subjectGroup, subjectID, searchText, searchSubfolders, checkShare, tagNames);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(IEnumerable<string> folderIds, IEnumerable<FilterType> filterTypes, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (!CheckForInvalidFilters(filterTypes))
|
||||
{
|
||||
return AsyncEnumerable.Empty<Folder<string>>();
|
||||
}
|
||||
|
||||
var folders = folderIds.ToAsyncEnumerable().SelectAwait(async e => await GetFolderAsync(e).ConfigureAwait(false));
|
||||
|
||||
folders = SetFilterByTypes(folders, filterTypes);
|
||||
|
||||
if (subjectID.HasValue && subjectID != Guid.Empty)
|
||||
{
|
||||
folders = folders.Where(x => subjectGroup
|
||||
@ -150,6 +164,8 @@ internal class DropboxFolderDao : DropboxDaoBase, IFolderDao<string>
|
||||
folders = folders.Where(x => x.Title.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) != -1);
|
||||
}
|
||||
|
||||
folders = FilterByTags(folders, tagNames);
|
||||
|
||||
return folders;
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,8 @@ internal class DropboxProviderInfo : IProviderInfo
|
||||
public string RootFolderId => "dropbox-" + ID;
|
||||
public string ProviderKey { get; set; }
|
||||
public FolderType RootFolderType { get; set; }
|
||||
public FolderType FolderType { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
|
||||
private readonly DropboxStorageDisposableWrapper _wrapper;
|
||||
private readonly DropboxProviderInfoHelper _dropboxProviderInfoHelper;
|
||||
|
@ -138,6 +138,7 @@ internal abstract class GoogleDriveDaoBase : ThirdPartyProviderDao<GoogleDrivePr
|
||||
folder.ParentId = isRoot ? null : MakeId(GetParentDriveId(driveEntry));
|
||||
folder.CreateOn = isRoot ? ProviderInfo.CreateOn : (driveEntry.CreatedTime ?? default);
|
||||
folder.ModifiedOn = isRoot ? ProviderInfo.CreateOn : (driveEntry.ModifiedTime ?? default);
|
||||
SetFolderType(folder, isRoot);
|
||||
|
||||
folder.Title = MakeFolderTitle(driveEntry);
|
||||
|
||||
|
@ -83,18 +83,24 @@ internal class GoogleDriveFolderDao : GoogleDriveDaoBase, IFolderDao<string>
|
||||
}
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(string parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false)
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(string parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (filterType == FilterType.FilesOnly || filterType == FilterType.ByExtension
|
||||
|| filterType == FilterType.DocumentsOnly || filterType == FilterType.ImagesOnly
|
||||
|| filterType == FilterType.PresentationsOnly || filterType == FilterType.SpreadsheetsOnly
|
||||
|| filterType == FilterType.ArchiveOnly || filterType == FilterType.MediaOnly)
|
||||
return GetFoldersAsync(parentId, orderBy, new[] { filterType }, subjectGroup, subjectID, searchText, withSubfolders, tagNames);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(string parentId, OrderBy orderBy, IEnumerable<FilterType> filterTypes, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (!CheckForInvalidFilters(filterTypes))
|
||||
{
|
||||
return AsyncEnumerable.Empty<Folder<string>>();
|
||||
}
|
||||
|
||||
var folders = GetFoldersAsync(parentId); //TODO:!!!
|
||||
|
||||
folders = SetFilterByTypes(folders, filterTypes);
|
||||
|
||||
if (subjectID != Guid.Empty)
|
||||
{
|
||||
folders = folders.Where(x => subjectGroup
|
||||
@ -107,6 +113,8 @@ internal class GoogleDriveFolderDao : GoogleDriveDaoBase, IFolderDao<string>
|
||||
folders = folders.Where(x => x.Title.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) != -1);
|
||||
}
|
||||
|
||||
folders = FilterByTags(folders, tagNames);
|
||||
|
||||
if (orderBy == null)
|
||||
{
|
||||
orderBy = new OrderBy(SortedByType.DateAndTime, false);
|
||||
@ -124,18 +132,24 @@ internal class GoogleDriveFolderDao : GoogleDriveDaoBase, IFolderDao<string>
|
||||
return folders;
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(IEnumerable<string> folderIds, FilterType filterType = FilterType.None, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true)
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(IEnumerable<string> folderIds, FilterType filterType, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (filterType == FilterType.FilesOnly || filterType == FilterType.ByExtension
|
||||
|| filterType == FilterType.DocumentsOnly || filterType == FilterType.ImagesOnly
|
||||
|| filterType == FilterType.PresentationsOnly || filterType == FilterType.SpreadsheetsOnly
|
||||
|| filterType == FilterType.ArchiveOnly || filterType == FilterType.MediaOnly)
|
||||
return GetFoldersAsync(folderIds, new[] { filterType }, subjectGroup, subjectID, searchText, searchSubfolders, checkShare, tagNames);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(IEnumerable<string> folderIds, IEnumerable<FilterType> filterTypes, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (!CheckForInvalidFilters(filterTypes))
|
||||
{
|
||||
return AsyncEnumerable.Empty<Folder<string>>();
|
||||
}
|
||||
|
||||
var folders = folderIds.ToAsyncEnumerable().SelectAwait(async e => await GetFolderAsync(e).ConfigureAwait(false));
|
||||
|
||||
folders = SetFilterByTypes(folders, filterTypes);
|
||||
|
||||
if (subjectID.HasValue && subjectID != Guid.Empty)
|
||||
{
|
||||
folders = folders.Where(x => subjectGroup
|
||||
@ -148,6 +162,8 @@ internal class GoogleDriveFolderDao : GoogleDriveDaoBase, IFolderDao<string>
|
||||
folders = folders.Where(x => x.Title.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) != -1);
|
||||
}
|
||||
|
||||
folders = FilterByTags(folders, tagNames);
|
||||
|
||||
return folders;
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,8 @@ internal class GoogleDriveProviderInfo : IProviderInfo
|
||||
public string RootFolderId => "drive-" + ID;
|
||||
public string ProviderKey { get; set; }
|
||||
public FolderType RootFolderType { get; set; }
|
||||
public FolderType FolderType { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
public string DriveRootId
|
||||
{
|
||||
get
|
||||
|
@ -189,6 +189,16 @@ internal abstract class ThirdPartyProviderDao
|
||||
return null;
|
||||
}
|
||||
|
||||
public Task<string> GetFolderIDVirtualRooms(bool createIfNotExists)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public Task<string> GetFolderIDArchive(bool createIfNotExists)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public Task<string> GetBunchObjectIDAsync(string folderID)
|
||||
{
|
||||
return null;
|
||||
@ -227,6 +237,9 @@ internal abstract class ThirdPartyProviderDao<T> : ThirdPartyProviderDao, IDispo
|
||||
protected RegexDaoSelectorBase<T> DaoSelector { get; set; }
|
||||
protected T ProviderInfo { get; set; }
|
||||
protected string PathPrefix { get; private set; }
|
||||
protected List<FilterType> _constraintFolderFilters =
|
||||
new List<FilterType> { FilterType.FilesOnly, FilterType.ByExtension, FilterType.DocumentsOnly, FilterType.ImagesOnly,
|
||||
FilterType.PresentationsOnly, FilterType.SpreadsheetsOnly, FilterType.ArchiveOnly, FilterType.MediaOnly };
|
||||
|
||||
protected abstract string Id { get; }
|
||||
|
||||
@ -371,6 +384,61 @@ internal abstract class ThirdPartyProviderDao<T> : ThirdPartyProviderDao, IDispo
|
||||
fileEntry.Error = entry.Error;
|
||||
}
|
||||
|
||||
protected void SetFolderType(Folder<string> folder, bool isRoot)
|
||||
{
|
||||
if (isRoot && (ProviderInfo.RootFolderType == FolderType.VirtualRooms ||
|
||||
ProviderInfo.RootFolderType == FolderType.Archive))
|
||||
{
|
||||
folder.FolderType = ProviderInfo.RootFolderType;
|
||||
}
|
||||
else if (ProviderInfo.FolderId == folder.Id)
|
||||
{
|
||||
folder.FolderType = ProviderInfo.FolderType;
|
||||
}
|
||||
}
|
||||
|
||||
protected IAsyncEnumerable<Folder<string>> FilterByTags(IAsyncEnumerable<Folder<string>> folders, IEnumerable<string> tagNames)
|
||||
{
|
||||
if (tagNames == null || !tagNames.Any())
|
||||
{
|
||||
return folders;
|
||||
}
|
||||
|
||||
var filtered = folders.Join(FilesDbContext.ThirdpartyIdMapping.ToAsyncEnumerable(), f => f.Id, m => m.Id, (folder, map) => new { folder, map.HashId })
|
||||
.Join(FilesDbContext.TagLink.ToAsyncEnumerable(), r => r.HashId, t => t.EntryId, (result, tag) => new { result.folder, tag.TagId })
|
||||
.Join(FilesDbContext.Tag.ToAsyncEnumerable(), r => r.TagId, t => t.Id, (result, tagInfo) => new {result.folder, tagInfo.Name })
|
||||
.Where(r => tagNames.Contains(r.Name))
|
||||
.Select(r => r.folder);
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
protected IAsyncEnumerable<Folder<string>> SetFilterByTypes(IAsyncEnumerable<Folder<string>> folders, IEnumerable<FilterType> filterTypes)
|
||||
{
|
||||
if (filterTypes.Any() && !filterTypes.Contains(FilterType.None))
|
||||
{
|
||||
var filter = filterTypes.Select(f => f switch
|
||||
{
|
||||
FilterType.FillingFormsRooms => FolderType.FillingFormsRoom,
|
||||
FilterType.EditingRooms => FolderType.EditingRoom,
|
||||
FilterType.ReviewRooms => FolderType.ReviewRoom,
|
||||
FilterType.ReadOnlyRooms => FolderType.ReadOnlyRoom,
|
||||
FilterType.CustomRooms => FolderType.CustomRoom,
|
||||
_ => FolderType.CustomRoom
|
||||
}).ToHashSet();
|
||||
|
||||
return folders.Where(f => filter.Contains(f.FolderType));
|
||||
}
|
||||
|
||||
return folders;
|
||||
}
|
||||
|
||||
protected bool CheckForInvalidFilters(IEnumerable<FilterType> filterTypes)
|
||||
{
|
||||
var intersection = filterTypes.Intersect(_constraintFolderFilters);
|
||||
|
||||
return !intersection.Any();
|
||||
}
|
||||
|
||||
protected abstract string MakeId(string path = null);
|
||||
|
||||
@ -465,6 +533,21 @@ internal abstract class ThirdPartyProviderDao<T> : ThirdPartyProviderDao, IDispo
|
||||
{
|
||||
return AsyncEnumerable.Empty<Tag>();
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<TagInfo> GetTagsInfoAsync(string searchText, TagType tagType, bool byName, int from = 0, int count = 0)
|
||||
{
|
||||
return AsyncEnumerable.Empty<TagInfo>();
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<TagInfo> GetTagsInfoAsync(IEnumerable<string> names)
|
||||
{
|
||||
return AsyncEnumerable.Empty<TagInfo>();
|
||||
}
|
||||
|
||||
public Task<TagInfo> SaveTagInfoAsync(TagInfo tagInfo)
|
||||
{
|
||||
return Task.FromResult(tagInfo);
|
||||
}
|
||||
|
||||
public IEnumerable<Tag> SaveTags(IEnumerable<Tag> tag)
|
||||
{
|
||||
@ -483,6 +566,16 @@ internal abstract class ThirdPartyProviderDao<T> : ThirdPartyProviderDao, IDispo
|
||||
public void UpdateNewTags(Tag tag)
|
||||
{
|
||||
}
|
||||
|
||||
public Task RemoveTagsAsync(FileEntry<string> entry, IEnumerable<int> tagsIds)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task RemoveTagsAsync(IEnumerable<int> tagsIds)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void RemoveTags(IEnumerable<Tag> tag)
|
||||
{
|
||||
|
@ -125,6 +125,7 @@ internal abstract class OneDriveDaoBase : ThirdPartyProviderDao<OneDriveProvider
|
||||
folder.ParentId = isRoot ? null : MakeId(GetParentFolderId(onedriveFolder));
|
||||
folder.CreateOn = isRoot ? ProviderInfo.CreateOn : (onedriveFolder.CreatedDateTime.HasValue ? _tenantUtil.DateTimeFromUtc(onedriveFolder.CreatedDateTime.Value.DateTime) : default);
|
||||
folder.ModifiedOn = isRoot ? ProviderInfo.CreateOn : (onedriveFolder.LastModifiedDateTime.HasValue ? _tenantUtil.DateTimeFromUtc(onedriveFolder.LastModifiedDateTime.Value.DateTime) : default);
|
||||
SetFolderType(folder, isRoot);
|
||||
|
||||
folder.Title = MakeItemTitle(onedriveFolder);
|
||||
|
||||
|
@ -83,18 +83,25 @@ internal class OneDriveFolderDao : OneDriveDaoBase, IFolderDao<string>
|
||||
}
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(string parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false)
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(string parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (filterType == FilterType.FilesOnly || filterType == FilterType.ByExtension
|
||||
|| filterType == FilterType.DocumentsOnly || filterType == FilterType.ImagesOnly
|
||||
|| filterType == FilterType.PresentationsOnly || filterType == FilterType.SpreadsheetsOnly
|
||||
|| filterType == FilterType.ArchiveOnly || filterType == FilterType.MediaOnly)
|
||||
return GetFoldersAsync(parentId, orderBy, new[] { filterType }, subjectGroup, subjectID, searchText, withSubfolders, tagNames);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(string parentId, OrderBy orderBy, IEnumerable<FilterType> filterTypes, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (!CheckForInvalidFilters(filterTypes))
|
||||
{
|
||||
return AsyncEnumerable.Empty<Folder<string>>();
|
||||
}
|
||||
|
||||
var folders = GetFoldersAsync(parentId); //TODO:!!!
|
||||
//Filter
|
||||
|
||||
folders = SetFilterByTypes(folders, filterTypes);
|
||||
|
||||
//Filter
|
||||
if (subjectID != Guid.Empty)
|
||||
{
|
||||
folders = folders.Where(x => subjectGroup
|
||||
@ -107,6 +114,8 @@ internal class OneDriveFolderDao : OneDriveDaoBase, IFolderDao<string>
|
||||
folders = folders.Where(x => x.Title.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) != -1);
|
||||
}
|
||||
|
||||
folders = FilterByTags(folders, tagNames);
|
||||
|
||||
if (orderBy == null)
|
||||
{
|
||||
orderBy = new OrderBy(SortedByType.DateAndTime, false);
|
||||
@ -124,18 +133,24 @@ internal class OneDriveFolderDao : OneDriveDaoBase, IFolderDao<string>
|
||||
return folders;
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(IEnumerable<string> folderIds, FilterType filterType = FilterType.None, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true)
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(IEnumerable<string> folderIds, FilterType filterType = FilterType.None, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (filterType == FilterType.FilesOnly || filterType == FilterType.ByExtension
|
||||
|| filterType == FilterType.DocumentsOnly || filterType == FilterType.ImagesOnly
|
||||
|| filterType == FilterType.PresentationsOnly || filterType == FilterType.SpreadsheetsOnly
|
||||
|| filterType == FilterType.ArchiveOnly || filterType == FilterType.MediaOnly)
|
||||
return GetFoldersAsync(folderIds, new[] { filterType }, subjectGroup, subjectID, searchText, searchSubfolders, checkShare, tagNames);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(IEnumerable<string> folderIds, IEnumerable<FilterType> filterTypes, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (!CheckForInvalidFilters(filterTypes))
|
||||
{
|
||||
return AsyncEnumerable.Empty<Folder<string>>();
|
||||
}
|
||||
|
||||
var folders = folderIds.ToAsyncEnumerable().SelectAwait(async e => await GetFolderAsync(e).ConfigureAwait(false));
|
||||
|
||||
folders = SetFilterByTypes(folders, filterTypes);
|
||||
|
||||
if (subjectID.HasValue && subjectID != Guid.Empty)
|
||||
{
|
||||
folders = folders.Where(x => subjectGroup
|
||||
@ -148,6 +163,8 @@ internal class OneDriveFolderDao : OneDriveDaoBase, IFolderDao<string>
|
||||
folders = folders.Where(x => x.Title.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) != -1);
|
||||
}
|
||||
|
||||
folders = FilterByTags(folders, tagNames);
|
||||
|
||||
return folders;
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,8 @@ internal class OneDriveProviderInfo : IProviderInfo
|
||||
public string RootFolderId => "onedrive-" + ID;
|
||||
public string ProviderKey { get; set; }
|
||||
public FolderType RootFolderType { get; set; }
|
||||
public FolderType FolderType { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
|
||||
private readonly OneDriveStorageDisposableWrapper _wrapper;
|
||||
private readonly OneDriveProviderInfoHelper _oneDriveProviderInfoHelper;
|
||||
|
@ -203,6 +203,45 @@ internal class ProviderAccountDao : IProviderDao
|
||||
{
|
||||
return providerInfo != null && await providerInfo.CheckAccessAsync();
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateProviderInfoAsync(int linkId, FolderType rootFolderType)
|
||||
{
|
||||
var forUpdate = await FilesDbContext.ThirdpartyAccount
|
||||
.Where(r => r.Id == linkId)
|
||||
.Where(r => r.TenantId == TenantID)
|
||||
.FirstOrDefaultAsync().ConfigureAwait(false);
|
||||
|
||||
if (forUpdate == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
forUpdate.FolderType = rootFolderType;
|
||||
|
||||
await FilesDbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateProviderInfoAsync(int linkId, string folderId, FolderType folderType)
|
||||
{
|
||||
var forUpdate = await FilesDbContext.ThirdpartyAccount
|
||||
.Where(r => r.Id == linkId)
|
||||
.Where(r => r.TenantId == TenantID)
|
||||
.FirstOrDefaultAsync().ConfigureAwait(false);
|
||||
|
||||
if (forUpdate == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
forUpdate.RoomType = folderType;
|
||||
forUpdate.FolderId = folderId;
|
||||
|
||||
await FilesDbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual async Task<int> UpdateProviderInfoAsync(int linkId, AuthData authData)
|
||||
{
|
||||
@ -389,7 +428,9 @@ internal class ProviderAccountDao : IProviderDao
|
||||
var providerTitle = input.Title ?? string.Empty;
|
||||
var token = DecryptToken(input.Token, id);
|
||||
var owner = input.UserId;
|
||||
var folderType = input.FolderType;
|
||||
var rootFolderType = input.FolderType;
|
||||
var folderType = input.RoomType;
|
||||
var folderId = input.FolderId;
|
||||
var createOn = _tenantUtil.DateTimeFromUtc(input.CreateOn);
|
||||
var authData = new AuthData(input.Url, input.UserName, DecryptPassword(input.Password, id), token);
|
||||
|
||||
@ -405,9 +446,11 @@ internal class ProviderAccountDao : IProviderDao
|
||||
box.CustomerTitle = providerTitle;
|
||||
box.Owner = owner == Guid.Empty ? _securityContext.CurrentAccount.ID : owner;
|
||||
box.ProviderKey = input.Provider;
|
||||
box.RootFolderType = folderType;
|
||||
box.RootFolderType = rootFolderType;
|
||||
box.CreateOn = createOn;
|
||||
box.Token = OAuth20Token.FromJson(token);
|
||||
box.FolderType = folderType;
|
||||
box.FolderId = folderId;
|
||||
|
||||
return box;
|
||||
}
|
||||
@ -424,9 +467,11 @@ internal class ProviderAccountDao : IProviderDao
|
||||
drop.CustomerTitle = providerTitle;
|
||||
drop.Owner = owner == Guid.Empty ? _securityContext.CurrentAccount.ID : owner;
|
||||
drop.ProviderKey = input.Provider;
|
||||
drop.RootFolderType = folderType;
|
||||
drop.RootFolderType = rootFolderType;
|
||||
drop.CreateOn = createOn;
|
||||
drop.Token = OAuth20Token.FromJson(token);
|
||||
drop.FolderType = folderType;
|
||||
drop.FolderId = folderId;
|
||||
|
||||
return drop;
|
||||
}
|
||||
@ -443,9 +488,11 @@ internal class ProviderAccountDao : IProviderDao
|
||||
sh.CustomerTitle = providerTitle;
|
||||
sh.Owner = owner == Guid.Empty ? _securityContext.CurrentAccount.ID : owner;
|
||||
sh.ProviderKey = input.Provider;
|
||||
sh.RootFolderType = folderType;
|
||||
sh.RootFolderType = rootFolderType;
|
||||
sh.CreateOn = createOn;
|
||||
sh.InitClientContext(authData);
|
||||
sh.FolderType = folderType;
|
||||
sh.FolderId = folderId;
|
||||
|
||||
return sh;
|
||||
}
|
||||
@ -462,9 +509,11 @@ internal class ProviderAccountDao : IProviderDao
|
||||
gd.CustomerTitle = providerTitle;
|
||||
gd.Owner = owner == Guid.Empty ? _securityContext.CurrentAccount.ID : owner;
|
||||
gd.ProviderKey = input.Provider;
|
||||
gd.RootFolderType = folderType;
|
||||
gd.RootFolderType = rootFolderType;
|
||||
gd.CreateOn = createOn;
|
||||
gd.Token = OAuth20Token.FromJson(token);
|
||||
gd.FolderType = folderType;
|
||||
gd.FolderId = folderId;
|
||||
|
||||
return gd;
|
||||
}
|
||||
@ -481,9 +530,11 @@ internal class ProviderAccountDao : IProviderDao
|
||||
od.CustomerTitle = providerTitle;
|
||||
od.Owner = owner == Guid.Empty ? _securityContext.CurrentAccount.ID : owner;
|
||||
od.ProviderKey = input.Provider;
|
||||
od.RootFolderType = folderType;
|
||||
od.RootFolderType = rootFolderType;
|
||||
od.CreateOn = createOn;
|
||||
od.Token = OAuth20Token.FromJson(token);
|
||||
od.FolderType = folderType;
|
||||
od.FolderId = folderId;
|
||||
|
||||
return od;
|
||||
}
|
||||
@ -508,9 +559,11 @@ internal class ProviderAccountDao : IProviderDao
|
||||
sharpBoxProviderInfo.CustomerTitle = providerTitle;
|
||||
sharpBoxProviderInfo.Owner = owner == Guid.Empty ? _securityContext.CurrentAccount.ID : owner;
|
||||
sharpBoxProviderInfo.ProviderKey = input.Provider;
|
||||
sharpBoxProviderInfo.RootFolderType = folderType;
|
||||
sharpBoxProviderInfo.RootFolderType = rootFolderType;
|
||||
sharpBoxProviderInfo.CreateOn = createOn;
|
||||
sharpBoxProviderInfo.AuthData = authData;
|
||||
sharpBoxProviderInfo.FolderType = folderType;
|
||||
sharpBoxProviderInfo.FolderId = folderId;
|
||||
|
||||
return sharpBoxProviderInfo;
|
||||
}
|
||||
|
@ -99,7 +99,8 @@ internal class ProviderFolderDao : ProviderDaoBase, IFolderDao<string>
|
||||
return folders.Where(r => r != null);
|
||||
}
|
||||
|
||||
public async IAsyncEnumerable<Folder<string>> GetFoldersAsync(string parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false)
|
||||
public async IAsyncEnumerable<Folder<string>> GetFoldersAsync(string parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
var selector = GetSelector(parentId);
|
||||
var folderDao = selector.GetFolderDao(parentId);
|
||||
@ -114,7 +115,24 @@ internal class ProviderFolderDao : ProviderDaoBase, IFolderDao<string>
|
||||
}
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(IEnumerable<string> folderIds, FilterType filterType = FilterType.None, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true)
|
||||
public async IAsyncEnumerable<Folder<string>> GetFoldersAsync(string parentId, OrderBy orderBy, IEnumerable<FilterType> filterTypes, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
var selector = GetSelector(parentId);
|
||||
var folderDao = selector.GetFolderDao(parentId);
|
||||
var folders = folderDao.GetFoldersAsync(selector.ConvertId(parentId), orderBy, filterTypes, subjectGroup, subjectID, searchText, withSubfolders);
|
||||
var result = folders.Where(r => r != null);
|
||||
|
||||
await SetSharedPropertyAsync(result).ConfigureAwait(false);
|
||||
|
||||
await foreach (var r in result.ConfigureAwait(false))
|
||||
{
|
||||
yield return r;
|
||||
}
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(IEnumerable<string> folderIds, FilterType filterType = FilterType.None, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
var result = AsyncEnumerable.Empty<Folder<string>>();
|
||||
|
||||
@ -135,7 +153,37 @@ internal class ProviderFolderDao : ProviderDaoBase, IFolderDao<string>
|
||||
var folderDao = selectorLocal.GetFolderDao(matchedId.FirstOrDefault());
|
||||
|
||||
return folderDao.GetFoldersAsync(matchedId.Select(selectorLocal.ConvertId).ToList(),
|
||||
filterType, subjectGroup, subjectID, searchText, searchSubfolders, checkShare);
|
||||
filterType, subjectGroup, subjectID, searchText, searchSubfolders, checkShare, tagNames);
|
||||
})
|
||||
.Where(r => r != null));
|
||||
}
|
||||
|
||||
return result.Distinct();
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(IEnumerable<string> folderIds, IEnumerable<FilterType> filterTypes, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
var result = AsyncEnumerable.Empty<Folder<string>>();
|
||||
|
||||
foreach (var selector in GetSelectors())
|
||||
{
|
||||
var selectorLocal = selector;
|
||||
var matchedIds = folderIds.Where(selectorLocal.IsMatch).ToList();
|
||||
|
||||
if (matchedIds.Count == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
result = result.Concat(matchedIds.GroupBy(selectorLocal.GetIdCode)
|
||||
.ToAsyncEnumerable()
|
||||
.SelectMany(matchedId =>
|
||||
{
|
||||
var folderDao = selectorLocal.GetFolderDao(matchedId.FirstOrDefault());
|
||||
|
||||
return folderDao.GetFoldersAsync(matchedId.Select(selectorLocal.ConvertId).ToList(),
|
||||
filterTypes, subjectGroup, subjectID, searchText, searchSubfolders, checkShare, tagNames);
|
||||
})
|
||||
.Where(r => r != null));
|
||||
}
|
||||
|
@ -152,9 +152,9 @@ internal class ProviderSecurityDao : ProviderDaoBase, ISecurityDao<string>
|
||||
private Task<List<FileShareRecord>> GetShareForFoldersAsync(IReadOnlyCollection<FileEntry<string>> folders)
|
||||
{
|
||||
if (folders.Count == 0)
|
||||
{
|
||||
return Task.FromResult(new List<FileShareRecord>());
|
||||
}
|
||||
{
|
||||
return Task.FromResult(new List<FileShareRecord>());
|
||||
}
|
||||
|
||||
return InternalGetShareForFoldersAsync(folders);
|
||||
}
|
||||
@ -172,11 +172,11 @@ internal class ProviderSecurityDao : ProviderDaoBase, ISecurityDao<string>
|
||||
continue;
|
||||
}
|
||||
|
||||
var parentFolders = await folderDao.GetParentFoldersAsync(selector.ConvertId(folder.Id));
|
||||
var parentFolders = await folderDao.GetParentFoldersAsync(selector.ConvertId(folder.Id));
|
||||
if (parentFolders == null || parentFolders.Count == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
parentFolders.Reverse();
|
||||
var pureShareRecords = await GetPureShareRecordsAsync(parentFolders);
|
||||
|
@ -103,6 +103,11 @@ internal class ProviderTagDao : ProviderDaoBase, ITagDao<string>
|
||||
_tagDao.UpdateNewTags(tag);
|
||||
}
|
||||
|
||||
public async Task RemoveTagsAsync(FileEntry<string> entry, IEnumerable<int> tagsIds)
|
||||
{
|
||||
await _tagDao.RemoveTagsAsync(entry, tagsIds);
|
||||
}
|
||||
|
||||
public void RemoveTags(IEnumerable<Tag> tag)
|
||||
{
|
||||
_tagDao.RemoveTags(tag);
|
||||
@ -123,5 +128,25 @@ internal class ProviderTagDao : ProviderDaoBase, ITagDao<string>
|
||||
return _tagDao.GetTagsAsync(subject, tagType, fileEntries);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<TagInfo> GetTagsInfoAsync(string searchText, TagType tagType, bool byName, int from = 0, int count = 0)
|
||||
{
|
||||
return _tagDao.GetTagsInfoAsync(searchText, tagType, byName, from, count);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<TagInfo> GetTagsInfoAsync(IEnumerable<string> names)
|
||||
{
|
||||
return _tagDao.GetTagsInfoAsync(names);
|
||||
}
|
||||
|
||||
public Task<TagInfo> SaveTagInfoAsync(TagInfo tagInfo)
|
||||
{
|
||||
return _tagDao.SaveTagInfoAsync(tagInfo);
|
||||
}
|
||||
|
||||
public Task RemoveTagsAsync(IEnumerable<int> tagsIds)
|
||||
{
|
||||
return _tagDao.RemoveTagsAsync(tagsIds);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
@ -89,18 +89,24 @@ internal class SharePointFolderDao : SharePointDaoBase, IFolderDao<string>
|
||||
}
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(string parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false)
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(string parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (filterType == FilterType.FilesOnly || filterType == FilterType.ByExtension
|
||||
|| filterType == FilterType.DocumentsOnly || filterType == FilterType.ImagesOnly
|
||||
|| filterType == FilterType.PresentationsOnly || filterType == FilterType.SpreadsheetsOnly
|
||||
|| filterType == FilterType.ArchiveOnly || filterType == FilterType.MediaOnly)
|
||||
return GetFoldersAsync(parentId, orderBy, new[] { filterType }, subjectGroup, subjectID, searchText, withSubfolders, tagNames);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(string parentId, OrderBy orderBy, IEnumerable<FilterType> filterTypes, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (!CheckForInvalidFilters(filterTypes))
|
||||
{
|
||||
return AsyncEnumerable.Empty<Folder<string>>();
|
||||
}
|
||||
|
||||
var folders = GetFoldersAsync(parentId);
|
||||
|
||||
folders = SetFilterByTypes(folders, filterTypes);
|
||||
|
||||
//Filter
|
||||
if (subjectID != Guid.Empty)
|
||||
{
|
||||
@ -114,6 +120,8 @@ internal class SharePointFolderDao : SharePointDaoBase, IFolderDao<string>
|
||||
folders = folders.Where(x => x.Title.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) != -1);
|
||||
}
|
||||
|
||||
folders = FilterByTags(folders, tagNames);
|
||||
|
||||
if (orderBy == null)
|
||||
{
|
||||
orderBy = new OrderBy(SortedByType.DateAndTime, false);
|
||||
@ -131,18 +139,24 @@ internal class SharePointFolderDao : SharePointDaoBase, IFolderDao<string>
|
||||
return folders;
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(IEnumerable<string> folderIds, FilterType filterType = FilterType.None, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true)
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(IEnumerable<string> folderIds, FilterType filterType = FilterType.None, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (filterType == FilterType.FilesOnly || filterType == FilterType.ByExtension
|
||||
|| filterType == FilterType.DocumentsOnly || filterType == FilterType.ImagesOnly
|
||||
|| filterType == FilterType.PresentationsOnly || filterType == FilterType.SpreadsheetsOnly
|
||||
|| filterType == FilterType.ArchiveOnly || filterType == FilterType.MediaOnly)
|
||||
return GetFoldersAsync(folderIds, new[] { filterType }, subjectGroup, subjectID, searchText, searchSubfolders, checkShare, tagNames);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(IEnumerable<string> folderIds, IEnumerable<FilterType> filterTypes, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (!CheckForInvalidFilters(filterTypes))
|
||||
{
|
||||
return AsyncEnumerable.Empty<Folder<string>>();
|
||||
}
|
||||
|
||||
var folders = folderIds.ToAsyncEnumerable().SelectAwait(async e => await GetFolderAsync(e).ConfigureAwait(false));
|
||||
|
||||
folders = SetFilterByTypes(folders, filterTypes);
|
||||
|
||||
if (subjectID.HasValue && subjectID != Guid.Empty)
|
||||
{
|
||||
folders = folders.Where(x => subjectGroup
|
||||
@ -155,6 +169,8 @@ internal class SharePointFolderDao : SharePointDaoBase, IFolderDao<string>
|
||||
folders = folders.Where(x => x.Title.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) != -1);
|
||||
}
|
||||
|
||||
folders = FilterByTags(folders, tagNames);
|
||||
|
||||
return folders;
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,8 @@
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
using ASC.Files.Core;
|
||||
|
||||
using File = Microsoft.SharePoint.Client.File;
|
||||
using Folder = Microsoft.SharePoint.Client.Folder;
|
||||
|
||||
@ -38,10 +40,12 @@ public class SharePointProviderInfo : IProviderInfo
|
||||
public string ProviderKey { get; set; }
|
||||
public Guid Owner { get; set; }
|
||||
public FolderType RootFolderType { get; set; }
|
||||
public FolderType FolderType { get; set; }
|
||||
public DateTime CreateOn { get; set; }
|
||||
public string CustomerTitle { get; set; }
|
||||
public string RootFolderId => "spoint-" + ID;
|
||||
public string SpRootFolderId { get; set; } = "/Shared Documents";
|
||||
public string FolderId { get; set; }
|
||||
|
||||
public SharePointProviderInfo(
|
||||
ILogger<SharePointProviderInfo> logger,
|
||||
@ -557,7 +561,7 @@ public class SharePointProviderInfo : IProviderInfo
|
||||
result.ParentId = null;
|
||||
result.CreateBy = Owner;
|
||||
result.CreateOn = DateTime.UtcNow;
|
||||
result.FolderType = FolderType.DEFAULT;
|
||||
result.FolderType = Core.FolderType.DEFAULT;
|
||||
result.ModifiedBy = Owner;
|
||||
result.ModifiedOn = DateTime.UtcNow;
|
||||
result.ProviderId = ID;
|
||||
@ -580,7 +584,7 @@ public class SharePointProviderInfo : IProviderInfo
|
||||
result.ParentId = isRoot ? null : MakeId(GetParentFolderId(folder.ServerRelativeUrl));
|
||||
result.CreateBy = Owner;
|
||||
result.CreateOn = CreateOn;
|
||||
result.FolderType = FolderType.DEFAULT;
|
||||
result.FolderType = Core.FolderType.DEFAULT;
|
||||
result.ModifiedBy = Owner;
|
||||
result.ModifiedOn = CreateOn;
|
||||
result.ProviderId = ID;
|
||||
@ -593,6 +597,8 @@ public class SharePointProviderInfo : IProviderInfo
|
||||
result.FilesCount = 0;
|
||||
result.FoldersCount = 0;
|
||||
|
||||
SetFolderType(result, isRoot);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -637,6 +643,19 @@ public class SharePointProviderInfo : IProviderInfo
|
||||
{
|
||||
_clientContext.Dispose();
|
||||
}
|
||||
|
||||
private void SetFolderType(Folder<string> folder, bool isRoot)
|
||||
{
|
||||
if (isRoot && (RootFolderType == FolderType.VirtualRooms ||
|
||||
RootFolderType == FolderType.Archive))
|
||||
{
|
||||
folder.FolderType = RootFolderType;
|
||||
}
|
||||
else if (FolderId == folder.Id)
|
||||
{
|
||||
folder.FolderType = FolderType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Singletone]
|
||||
|
@ -284,6 +284,7 @@ internal abstract class SharpBoxDaoBase : ThirdPartyProviderDao<SharpBoxProvider
|
||||
folder.Title = MakeTitle(fsEntry);
|
||||
folder.FilesCount = 0; /*fsEntry.Count - childFoldersCount NOTE: Removed due to performance isssues*/
|
||||
folder.FoldersCount = 0; /*childFoldersCount NOTE: Removed due to performance isssues*/
|
||||
SetFolderType(folder, isRoot);
|
||||
|
||||
if (folder.CreateOn != DateTime.MinValue && folder.CreateOn.Kind == DateTimeKind.Utc)
|
||||
{
|
||||
|
@ -85,19 +85,25 @@ internal class SharpBoxFolderDao : SharpBoxDaoBase, IFolderDao<string>
|
||||
return parentFolder.OfType<ICloudDirectoryEntry>().Select(ToFolder).ToAsyncEnumerable();
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(string parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false)
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(string parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
return GetFoldersAsync(parentId, orderBy, new[] { filterType }, subjectGroup, subjectID, searchText, withSubfolders, tagNames);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(string parentId, OrderBy orderBy, IEnumerable<FilterType> filterTypes, bool subjectGroup, Guid subjectID, string searchText, bool withSubfolders = false,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
|
||||
if (filterType == FilterType.FilesOnly || filterType == FilterType.ByExtension
|
||||
|| filterType == FilterType.DocumentsOnly || filterType == FilterType.ImagesOnly
|
||||
|| filterType == FilterType.PresentationsOnly || filterType == FilterType.SpreadsheetsOnly
|
||||
|| filterType == FilterType.ArchiveOnly || filterType == FilterType.MediaOnly)
|
||||
if (!CheckForInvalidFilters(filterTypes))
|
||||
{
|
||||
return AsyncEnumerable.Empty<Folder<string>>();
|
||||
}
|
||||
|
||||
var folders = GetFoldersAsync(parentId); //TODO:!!!
|
||||
|
||||
folders = SetFilterByTypes(folders, filterTypes);
|
||||
|
||||
//Filter
|
||||
if (subjectID != Guid.Empty)
|
||||
{
|
||||
@ -111,6 +117,8 @@ internal class SharpBoxFolderDao : SharpBoxDaoBase, IFolderDao<string>
|
||||
folders = folders.Where(x => x.Title.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) != -1);
|
||||
}
|
||||
|
||||
folders = FilterByTags(folders, tagNames);
|
||||
|
||||
if (orderBy == null)
|
||||
{
|
||||
orderBy = new OrderBy(SortedByType.DateAndTime, false);
|
||||
@ -128,18 +136,24 @@ internal class SharpBoxFolderDao : SharpBoxDaoBase, IFolderDao<string>
|
||||
return folders;
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(IEnumerable<string> folderIds, FilterType filterType = FilterType.None, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true)
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(IEnumerable<string> folderIds, FilterType filterType = FilterType.None, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (filterType == FilterType.FilesOnly || filterType == FilterType.ByExtension
|
||||
|| filterType == FilterType.DocumentsOnly || filterType == FilterType.ImagesOnly
|
||||
|| filterType == FilterType.PresentationsOnly || filterType == FilterType.SpreadsheetsOnly
|
||||
|| filterType == FilterType.ArchiveOnly || filterType == FilterType.MediaOnly)
|
||||
return GetFoldersAsync(folderIds, new[] { filterType }, subjectGroup, subjectID, searchText, searchSubfolders, checkShare, tagNames);
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Folder<string>> GetFoldersAsync(IEnumerable<string> folderIds, IEnumerable<FilterType> filterTypes, bool subjectGroup = false, Guid? subjectID = null, string searchText = "", bool searchSubfolders = false, bool checkShare = true,
|
||||
IEnumerable<string> tagNames = null)
|
||||
{
|
||||
if (!CheckForInvalidFilters(filterTypes))
|
||||
{
|
||||
return AsyncEnumerable.Empty<Folder<string>>();
|
||||
}
|
||||
|
||||
var folders = folderIds.ToAsyncEnumerable().SelectAwait(async e => await GetFolderAsync(e).ConfigureAwait(false));
|
||||
|
||||
folders = SetFilterByTypes(folders, filterTypes);
|
||||
|
||||
if (subjectID.HasValue && subjectID != Guid.Empty)
|
||||
{
|
||||
folders = folders.Where(x => subjectGroup
|
||||
@ -152,6 +166,8 @@ internal class SharpBoxFolderDao : SharpBoxDaoBase, IFolderDao<string>
|
||||
folders = folders.Where(x => x.Title.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) != -1);
|
||||
}
|
||||
|
||||
folders = FilterByTags(folders, tagNames);
|
||||
|
||||
return folders;
|
||||
}
|
||||
|
||||
|
@ -109,6 +109,8 @@ internal class SharpBoxProviderInfo : IProviderInfo
|
||||
}
|
||||
|
||||
public FolderType RootFolderType { get; set; }
|
||||
public FolderType FolderType { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
private readonly SharpBoxStorageDisposableWrapper _wrapper;
|
||||
}
|
||||
|
||||
|
166
products/ASC.Files/Core/Core/VirtualRooms/CustomTagsService.cs
Normal file
166
products/ASC.Files/Core/Core/VirtualRooms/CustomTagsService.cs
Normal file
@ -0,0 +1,166 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Files.Core.VirtualRooms;
|
||||
|
||||
[Scope]
|
||||
public class CustomTagsService<T>
|
||||
{
|
||||
private readonly IDaoFactory _daoFactory;
|
||||
private readonly FileSecurity _fileSecurity;
|
||||
private readonly AuthContext _authContext;
|
||||
private readonly FileSecurityCommon _fileSecurityCommon;
|
||||
private readonly FilesMessageService _filesMessageService;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public CustomTagsService(IDaoFactory daoFactory, FileSecurity fileSecurity, AuthContext authContext, FileSecurityCommon fileSecurityCommon,
|
||||
FilesMessageService filesMessageService, IHttpContextAccessor httpContextAccessor, IMapper mapper)
|
||||
{
|
||||
_daoFactory = daoFactory;
|
||||
_fileSecurity = fileSecurity;
|
||||
_authContext = authContext;
|
||||
_fileSecurityCommon = fileSecurityCommon;
|
||||
_filesMessageService = filesMessageService;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
private ITagDao<T> TagDao => _daoFactory.GetTagDao<T>();
|
||||
private IFolderDao<T> FolderDao => _daoFactory.GetFolderDao<T>();
|
||||
private IDictionary<string, StringValues> Headers => _httpContextAccessor?.HttpContext?.Request?.Headers;
|
||||
|
||||
public async Task<object> CreateTagAsync(string name)
|
||||
{
|
||||
if (!_fileSecurityCommon.IsAdministrator(_authContext.CurrentAccount.ID))
|
||||
{
|
||||
throw new SecurityException("You do not have permission to create tags");
|
||||
}
|
||||
|
||||
ArgumentNullOrEmptyException.ThrowIfNullOrEmpty(name);
|
||||
|
||||
var tags = await TagDao.GetTagsInfoAsync(name, TagType.Custom, true).ToListAsync();
|
||||
|
||||
if (tags.Any())
|
||||
{
|
||||
throw new Exception("The tag already exists");
|
||||
}
|
||||
|
||||
var tagInfo = new TagInfo
|
||||
{
|
||||
Name = name,
|
||||
Owner = _authContext.CurrentAccount.ID,
|
||||
Type = TagType.Custom
|
||||
};
|
||||
|
||||
var savedTag = await TagDao.SaveTagInfoAsync(tagInfo);
|
||||
|
||||
_filesMessageService.Send(Headers, MessageAction.TagCreated, savedTag.Name);
|
||||
|
||||
return savedTag.Name;
|
||||
}
|
||||
|
||||
public async Task DeleteTagsAsync(IEnumerable<string> names)
|
||||
{
|
||||
if (!_fileSecurityCommon.IsAdministrator(_authContext.CurrentAccount.ID))
|
||||
{
|
||||
throw new SecurityException("You do not have permission to remove tags");
|
||||
}
|
||||
|
||||
if (!names.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var tagDao = TagDao;
|
||||
|
||||
var tags = await tagDao.GetTagsInfoAsync(names).ToListAsync();
|
||||
|
||||
await tagDao.RemoveTagsAsync(tags.Select(t => t.Id));
|
||||
|
||||
_filesMessageService.Send(Headers, MessageAction.TagsDeleted, tags.Select(t => t.Name).ToArray());
|
||||
}
|
||||
|
||||
public async Task<Folder<T>> AddRoomTagsAsync(T folderId, IEnumerable<string> names)
|
||||
{
|
||||
var folder = await FolderDao.GetFolderAsync(folderId);
|
||||
|
||||
if (!await _fileSecurity.CanEditRoomAsync(folder))
|
||||
{
|
||||
throw new SecurityException("You do not have permission to edit the room");
|
||||
}
|
||||
|
||||
if (!names.Any())
|
||||
{
|
||||
return folder;
|
||||
}
|
||||
|
||||
var tagDao = TagDao;
|
||||
|
||||
var tagsInfos = await tagDao.GetTagsInfoAsync(names).ToListAsync();
|
||||
|
||||
var tags = tagsInfos.Select(tagInfo => Tag.Custom(_authContext.CurrentAccount.ID, folder, tagInfo.Name));
|
||||
|
||||
tagDao.SaveTags(tags);
|
||||
|
||||
_filesMessageService.Send(folder, Headers, MessageAction.AddedRoomTags, tagsInfos.Select(t => t.Name).ToArray());
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
public async Task<Folder<T>> DeleteRoomTagsAsync(T folderId, IEnumerable<string> names)
|
||||
{
|
||||
var folder = await FolderDao.GetFolderAsync(folderId);
|
||||
|
||||
if (!await _fileSecurity.CanEditRoomAsync(folder))
|
||||
{
|
||||
throw new SecurityException("You do not have permission to edit the room");
|
||||
}
|
||||
|
||||
if (!names.Any())
|
||||
{
|
||||
return folder;
|
||||
}
|
||||
|
||||
var tagDao = TagDao;
|
||||
|
||||
var tagsInfos = await tagDao.GetTagsInfoAsync(names).ToListAsync();
|
||||
|
||||
await tagDao.RemoveTagsAsync(folder, tagsInfos.Select(t => t.Id));
|
||||
|
||||
_filesMessageService.Send(folder, Headers, MessageAction.DeletedRoomTags, tagsInfos.Select(t => t.Name).ToArray());
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
public async IAsyncEnumerable<object> GetTagsInfoAsync(string searchText, TagType tagType, int from, int count)
|
||||
{
|
||||
await foreach (var tagInfo in TagDao.GetTagsInfoAsync(searchText, tagType, false, from, count))
|
||||
{
|
||||
yield return tagInfo.Name;
|
||||
}
|
||||
}
|
||||
}
|
34
products/ASC.Files/Core/Core/VirtualRooms/Logo.cs
Normal file
34
products/ASC.Files/Core/Core/VirtualRooms/Logo.cs
Normal file
@ -0,0 +1,34 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Files.Core.VirtualRooms;
|
||||
|
||||
public class Logo
|
||||
{
|
||||
public string Original { get; set; }
|
||||
public string Big { get; set; }
|
||||
public string Small { get; set; }
|
||||
}
|
315
products/ASC.Files/Core/Core/VirtualRooms/RoomLogoManager.cs
Normal file
315
products/ASC.Files/Core/Core/VirtualRooms/RoomLogoManager.cs
Normal file
@ -0,0 +1,315 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
using Image = SixLabors.ImageSharp.Image;
|
||||
|
||||
namespace ASC.Files.Core.VirtualRooms;
|
||||
|
||||
[Scope]
|
||||
public class RoomLogoManager
|
||||
{
|
||||
private const string LogosPath = "{0}_size_{1}-{2}.{3}";
|
||||
private const string ModuleName = "room_logos";
|
||||
private const string TempDomainPath = "logos_temp";
|
||||
private static Size _originalLogoSize = new Size(1280, 1280);
|
||||
private static Size _bigLogoSize = new Size(32, 32);
|
||||
private static Size _smallLogoSize = new Size(16, 16);
|
||||
private readonly IDaoFactory _daoFactory;
|
||||
private readonly FileSecurity _fileSecurity;
|
||||
private readonly ILogger<RoomLogoManager> _logger;
|
||||
private readonly StorageFactory _storageFactory;
|
||||
private readonly TenantManager _tenantManager;
|
||||
private IDataStore _dataStore;
|
||||
private readonly ICache _cache;
|
||||
private readonly FilesMessageService _filesMessageService;
|
||||
private static readonly Regex _pattern = new Regex(@"\d+-\d+", RegexOptions.Compiled);
|
||||
private static readonly Regex _cachePattern = new Regex(@"\d+\/\S+\/\d+\/\d+", RegexOptions.Compiled);
|
||||
private static readonly TimeSpan _cacheLifeTime = TimeSpan.FromMinutes(30);
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
|
||||
public RoomLogoManager(StorageFactory storageFactory, TenantManager tenantManager, IDaoFactory daoFactory, FileSecurity fileSecurity, ILogger<RoomLogoManager> logger, AscCache cache, FilesMessageService filesMessageService, IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
_storageFactory = storageFactory;
|
||||
_tenantManager = tenantManager;
|
||||
_daoFactory = daoFactory;
|
||||
_fileSecurity = fileSecurity;
|
||||
_logger = logger;
|
||||
_cache = cache;
|
||||
_filesMessageService = filesMessageService;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
}
|
||||
|
||||
public bool EnableAudit { get; set; } = true;
|
||||
private IDataStore DataStore => _dataStore ??= _storageFactory.GetStorage(TenantId.ToString(), ModuleName);
|
||||
private int TenantId => _tenantManager.GetCurrentTenant().Id;
|
||||
private IDictionary<string, StringValues> Headers => _httpContextAccessor?.HttpContext?.Request?.Headers;
|
||||
|
||||
public async Task<Folder<T>> CreateAsync<T>(T id, string tempFile, int x, int y, int width, int height)
|
||||
{
|
||||
var folderDao = _daoFactory.GetFolderDao<T>();
|
||||
var room = await folderDao.GetFolderAsync(id);
|
||||
|
||||
if (string.IsNullOrEmpty(tempFile))
|
||||
{
|
||||
return room;
|
||||
}
|
||||
|
||||
if (room == null || !DocSpaceHelper.IsRoom(room.FolderType))
|
||||
{
|
||||
throw new ItemNotFoundException("Virtual room not found");
|
||||
}
|
||||
|
||||
if (room.RootFolderType == FolderType.Archive || !await _fileSecurity.CanEditRoomAsync(room))
|
||||
{
|
||||
throw new InvalidOperationException("You don't have permission to edit the room");
|
||||
}
|
||||
|
||||
var fileName = Path.GetFileName(tempFile);
|
||||
var data = await GetTempAsync(fileName);
|
||||
|
||||
await SaveWithProcessAsync(id, data, -1, new Point(x, y), new Size(width, height));
|
||||
|
||||
if (EnableAudit)
|
||||
{
|
||||
_filesMessageService.Send(room, Headers, MessageAction.RoomLogoCreated);
|
||||
}
|
||||
|
||||
return room;
|
||||
}
|
||||
|
||||
public async Task<Folder<T>> DeleteAsync<T>(T id)
|
||||
{
|
||||
var folderDao = _daoFactory.GetFolderDao<T>();
|
||||
var room = await folderDao.GetFolderAsync(id);
|
||||
|
||||
if (!await _fileSecurity.CanEditRoomAsync(room))
|
||||
{
|
||||
throw new InvalidOperationException("You don't have permission to edit the room");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await DataStore.DeleteFilesAsync(string.Empty, $"{ProcessFolderId(id)}*.*", false);
|
||||
|
||||
if (EnableAudit)
|
||||
{
|
||||
_filesMessageService.Send(room, Headers, MessageAction.RoomLogoDeleted);
|
||||
}
|
||||
|
||||
_cache.Remove(_cachePattern);
|
||||
_cache.Remove(GetKey(id));
|
||||
}
|
||||
catch (DirectoryNotFoundException e)
|
||||
{
|
||||
_logger.ErrorRemoveRoomLogo(e);
|
||||
}
|
||||
|
||||
return room;
|
||||
}
|
||||
|
||||
public async Task<Logo> GetLogo<T>(T id)
|
||||
{
|
||||
return new Logo
|
||||
{
|
||||
Original = await GetOriginalLogoPath(id),
|
||||
Big = await GetBigLogoPath(id),
|
||||
Small = await GetSmallLogoPath(id),
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<byte[]> GetTempAsync(string fileName)
|
||||
{
|
||||
using var stream = await DataStore.GetReadStreamAsync(TempDomainPath, fileName);
|
||||
|
||||
var data = new MemoryStream();
|
||||
var buffer = new byte[1024 * 10];
|
||||
while (true)
|
||||
{
|
||||
var count = await stream.ReadAsync(buffer, 0, buffer.Length);
|
||||
if (count == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
data.Write(buffer, 0, count);
|
||||
}
|
||||
|
||||
return data.ToArray();
|
||||
}
|
||||
|
||||
public async Task<string> SaveTempAsync(byte[] data, long maxFileSize)
|
||||
{
|
||||
data = UserPhotoThumbnailManager.TryParseImage(data, maxFileSize, _originalLogoSize, out var imgFormat, out _, out _);
|
||||
|
||||
var fileName = Guid.NewGuid() + "." + CommonPhotoManager.GetImgFormatName(imgFormat);
|
||||
|
||||
using var stream = new MemoryStream(data);
|
||||
var path = await DataStore.SaveAsync(TempDomainPath, fileName, stream);
|
||||
|
||||
return path.ToString();
|
||||
}
|
||||
|
||||
public async Task<string> SaveWithProcessAsync<T>(T id, byte[] imageData, long maxFileSize, Point position, Size cropSize)
|
||||
{
|
||||
imageData = UserPhotoThumbnailManager.TryParseImage(imageData, maxFileSize, _originalLogoSize, out var imageFormat, out var width, out var height);
|
||||
|
||||
var imageExtension = CommonPhotoManager.GetImgFormatName(imageFormat);
|
||||
|
||||
var fileName = $"{ProcessFolderId(id)}_orig_{width}-{height}.{imageExtension}";
|
||||
|
||||
if (imageData == null || imageData.Length == 0)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
using var stream = new MemoryStream(imageData);
|
||||
var path = await DataStore.SaveAsync(fileName, stream);
|
||||
|
||||
await ResizeAndSaveAsync(id, imageData, maxFileSize, _bigLogoSize, position, cropSize);
|
||||
await ResizeAndSaveAsync(id, imageData, maxFileSize, _smallLogoSize, position, cropSize);
|
||||
|
||||
return path.ToString();
|
||||
}
|
||||
|
||||
private async Task ResizeAndSaveAsync<T>(T id, byte[] data, long maxFileSize, Size size, Point position, Size cropSize)
|
||||
{
|
||||
if (data == null || data.Length <= 0)
|
||||
{
|
||||
throw new Web.Core.Users.UnknownImageFormatException();
|
||||
}
|
||||
if (maxFileSize != -1 && data.Length > maxFileSize)
|
||||
{
|
||||
throw new ImageWeightLimitException();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using var stream = new MemoryStream(data);
|
||||
using var img = Image.Load(stream, out var format);
|
||||
var imgFormat = format;
|
||||
|
||||
if (size != img.Size())
|
||||
{
|
||||
using var img2 = UserPhotoThumbnailManager.GetImage(img, size, new UserPhotoThumbnailSettings(position, cropSize));
|
||||
data = CommonPhotoManager.SaveToBytes(img2);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = CommonPhotoManager.SaveToBytes(img);
|
||||
}
|
||||
|
||||
var extension = CommonPhotoManager.GetImgFormatName(imgFormat);
|
||||
var fileName = string.Format(LogosPath, ProcessFolderId(id), size.Width, size.Height, extension);
|
||||
|
||||
using var stream2 = new MemoryStream(data);
|
||||
await DataStore.SaveAsync(fileName, stream2);
|
||||
}
|
||||
catch (ArgumentException error)
|
||||
{
|
||||
throw new Web.Core.Users.UnknownImageFormatException(error);
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<string> GetOriginalLogoPath<T>(T id)
|
||||
{
|
||||
var path = _cache.Get<string>(GetKey(id));
|
||||
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
return await ValueTask.FromResult(path);
|
||||
}
|
||||
|
||||
await LoadPathToCache(id);
|
||||
|
||||
path = _cache.Get<string>(GetKey(id));
|
||||
|
||||
return path ?? string.Empty;
|
||||
}
|
||||
|
||||
public async ValueTask<string> GetBigLogoPath<T>(T id)
|
||||
{
|
||||
return await GetLogoPath(id, _bigLogoSize);
|
||||
}
|
||||
|
||||
public async ValueTask<string> GetSmallLogoPath<T>(T id)
|
||||
{
|
||||
return await GetLogoPath(id, _smallLogoSize);
|
||||
}
|
||||
|
||||
public async ValueTask<string> GetLogoPath<T>(T id, Size size)
|
||||
{
|
||||
var key = GetKey(id, size);
|
||||
|
||||
var path = _cache.Get<string>(key);
|
||||
|
||||
if (!string.IsNullOrEmpty(path))
|
||||
{
|
||||
return await ValueTask.FromResult(path);
|
||||
}
|
||||
|
||||
await LoadPathToCache(id);
|
||||
|
||||
path = _cache.Get<string>(key);
|
||||
|
||||
return path ?? string.Empty;
|
||||
}
|
||||
|
||||
public async Task LoadPathToCache<T>(T id)
|
||||
{
|
||||
var logoPath = await DataStore.ListFilesAsync(string.Empty, $"{ProcessFolderId(id)}*", false)
|
||||
.Select(u => u.ToString()).ToListAsync();
|
||||
|
||||
var original = logoPath.Where(u => u.Contains("orig")).FirstOrDefault();
|
||||
|
||||
_cache.Insert(GetKey(id), original, _cacheLifeTime);
|
||||
|
||||
logoPath.Remove(original);
|
||||
|
||||
foreach (var (k, v) in logoPath.ToDictionary(p => _pattern.Match(p).Value.Split('-')))
|
||||
{
|
||||
_cache.Insert(GetKey(id, new Size(int.Parse(k[0]), int.Parse(k[1]))), v, _cacheLifeTime);
|
||||
}
|
||||
}
|
||||
|
||||
private string ProcessFolderId<T>(T id)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(id, nameof(id));
|
||||
|
||||
return id.GetType() != typeof(string)
|
||||
? id.ToString()
|
||||
: id.ToString()?.Replace("-", "").Replace("|", "");
|
||||
}
|
||||
|
||||
private string GetKey<T>(T id, Size size)
|
||||
{
|
||||
return $"{TenantId}/{id}/{size.Width}/{size.Height}";
|
||||
}
|
||||
|
||||
private string GetKey<T>(T id)
|
||||
{
|
||||
return $"{TenantId}/{id}/orig";
|
||||
}
|
||||
}
|
34
products/ASC.Files/Core/Core/VirtualRooms/SearchArea.cs
Normal file
34
products/ASC.Files/Core/Core/VirtualRooms/SearchArea.cs
Normal file
@ -0,0 +1,34 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Files.Core.VirtualRooms;
|
||||
|
||||
public enum SearchArea
|
||||
{
|
||||
Active,
|
||||
Archive,
|
||||
Any
|
||||
}
|
@ -41,7 +41,7 @@ global using System.Text;
|
||||
global using System.Text.Json;
|
||||
global using System.Text.Json.Serialization;
|
||||
global using System.Text.RegularExpressions;
|
||||
global using System.Web;
|
||||
global using System.Web;
|
||||
global using System.Xml;
|
||||
|
||||
global using AppLimit.CloudComputing.SharpBox;
|
||||
@ -83,6 +83,7 @@ global using ASC.FederatedLogin.Helpers;
|
||||
global using ASC.FederatedLogin.LoginProviders;
|
||||
global using ASC.FederatedLogin.Profile;
|
||||
global using ASC.Files.Core;
|
||||
global using ASC.Files.Core.VirtualRooms;
|
||||
global using ASC.Files.Core.ApiModels.RequestDto;
|
||||
global using ASC.Files.Core.ApiModels.ResponseDto;
|
||||
global using ASC.Files.Core.Core.Entries;
|
||||
@ -90,7 +91,9 @@ global using ASC.Files.Core.Data;
|
||||
global using ASC.Files.Core.EF;
|
||||
global using ASC.Files.Core.IntegrationEvents.Events;
|
||||
global using ASC.Files.Core.Log;
|
||||
global using ASC.Files.Core.Entries;
|
||||
global using ASC.Files.Core.Mapping;
|
||||
global using ASC.Files.Core.Helpers;
|
||||
global using ASC.Files.Core.Resources;
|
||||
global using ASC.Files.Core.Security;
|
||||
global using ASC.Files.Core.Services.NotifyService;
|
||||
@ -197,6 +200,10 @@ global using Newtonsoft.Json.Linq;
|
||||
|
||||
global using ProtoBuf;
|
||||
|
||||
global using SixLabors.ImageSharp;
|
||||
|
||||
global using StackExchange.Redis;
|
||||
|
||||
global using static ASC.Files.Core.Data.AbstractDao;
|
||||
global using static ASC.Web.Core.Files.DocumentService;
|
||||
global using static ASC.Web.Files.Services.DocumentService.DocumentServiceTracker;
|
||||
@ -223,3 +230,4 @@ global using JsonTokenType = System.Text.Json.JsonTokenType;
|
||||
global using JsonConverter = System.Text.Json.Serialization.JsonConverter;
|
||||
global using JsonConverterAttribute = System.Text.Json.Serialization.JsonConverterAttribute;
|
||||
global using JsonIgnoreAttribute = System.Text.Json.Serialization.JsonIgnoreAttribute;
|
||||
global using SocketManager = ASC.Web.Files.Utils.SocketManager;
|
59
products/ASC.Files/Core/Helpers/DocSpaceHelper.cs
Normal file
59
products/ASC.Files/Core/Helpers/DocSpaceHelper.cs
Normal file
@ -0,0 +1,59 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Files.Core.Helpers;
|
||||
|
||||
public static class DocSpaceHelper
|
||||
{
|
||||
private static readonly HashSet<FileShare> _fillingFormRoomConstraints
|
||||
= new HashSet<FileShare> { FileShare.RoomManager, FileShare.ReadWrite, FileShare.FillForms, FileShare.Read };
|
||||
private static readonly HashSet<FileShare> _editingRoomConstraints
|
||||
= new HashSet<FileShare> { FileShare.RoomManager, FileShare.ReadWrite, FileShare.Editing, FileShare.Read };
|
||||
private static readonly HashSet<FileShare> _reviewRoomConstraints
|
||||
= new HashSet<FileShare> { FileShare.RoomManager, FileShare.ReadWrite, FileShare.Review, FileShare.Comment, FileShare.Read };
|
||||
private static readonly HashSet<FileShare> _readOnlyRoomConstraints
|
||||
= new HashSet<FileShare> { FileShare.RoomManager, FileShare.ReadWrite, FileShare.Read };
|
||||
|
||||
public static bool IsRoom(FolderType folderType)
|
||||
{
|
||||
return folderType == FolderType.CustomRoom || folderType == FolderType.EditingRoom
|
||||
|| folderType == FolderType.ReviewRoom || folderType == FolderType.ReadOnlyRoom
|
||||
|| folderType == FolderType.FillingFormsRoom;
|
||||
}
|
||||
|
||||
public static bool ValidateShare(FolderType folderType, FileShare fileShare)
|
||||
{
|
||||
return folderType switch
|
||||
{
|
||||
FolderType.CustomRoom => true,
|
||||
FolderType.FillingFormsRoom => _fillingFormRoomConstraints.Contains(fileShare),
|
||||
FolderType.EditingRoom => _editingRoomConstraints.Contains(fileShare),
|
||||
FolderType.ReviewRoom => _reviewRoomConstraints.Contains(fileShare),
|
||||
FolderType.ReadOnlyRoom => _readOnlyRoomConstraints.Contains(fileShare),
|
||||
_ => false
|
||||
};
|
||||
}
|
||||
}
|
@ -54,6 +54,11 @@ public class FilesMessageService
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
}
|
||||
|
||||
public void Send(IDictionary<string, StringValues> headers, MessageAction action, params string[] description)
|
||||
{
|
||||
SendHeadersMessage(headers, action, null, description);
|
||||
}
|
||||
|
||||
public void Send<T>(FileEntry<T> entry, IDictionary<string, StringValues> headers, MessageAction action, params string[] description)
|
||||
{
|
||||
if (entry == null)
|
||||
|
@ -330,7 +330,7 @@ public class GlobalFolder
|
||||
if (!ProjectsRootFolderCache.TryGetValue(_tenantManager.GetCurrentTenant().Id, out var result))
|
||||
{
|
||||
result = await folderDao.GetFolderIDProjectsAsync(true);
|
||||
|
||||
|
||||
ProjectsRootFolderCache[_tenantManager.GetCurrentTenant().Id] = result;
|
||||
}
|
||||
|
||||
@ -342,6 +342,57 @@ public class GlobalFolder
|
||||
return (T)Convert.ChangeType(await GetFolderProjectsAsync(daoFactory), typeof(T));
|
||||
}
|
||||
|
||||
internal static readonly ConcurrentDictionary<string, int> DocSpaceFolderCache =
|
||||
new ConcurrentDictionary<string, int>();
|
||||
|
||||
public async ValueTask<int> GetFolderVirtualRoomsAsync(IDaoFactory daoFactory)
|
||||
{
|
||||
if (_coreBaseSettings.DisableDocSpace)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
var key = $"vrooms/{_tenantManager.GetCurrentTenant().Id}";
|
||||
|
||||
if (!DocSpaceFolderCache.TryGetValue(key, out var result))
|
||||
{
|
||||
result = await daoFactory.GetFolderDao<int>().GetFolderIDVirtualRooms(true);
|
||||
|
||||
DocSpaceFolderCache[key] = result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async ValueTask<T> GetFolderVirtualRoomsAsync<T>(IDaoFactory daoFactory)
|
||||
{
|
||||
return (T)Convert.ChangeType(await GetFolderVirtualRoomsAsync(daoFactory), typeof(T));
|
||||
}
|
||||
|
||||
public async ValueTask<int> GetFolderArchiveAsync(IDaoFactory daoFactory)
|
||||
{
|
||||
if (_coreBaseSettings.DisableDocSpace)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
var key = $"archive/{_tenantManager.GetCurrentTenant().Id}";
|
||||
|
||||
if (!DocSpaceFolderCache.TryGetValue(key, out var result))
|
||||
{
|
||||
result = await daoFactory.GetFolderDao<int>().GetFolderIDArchive(true);
|
||||
|
||||
DocSpaceFolderCache[key] = result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async ValueTask<T> GetFolderArchive<T>(IDaoFactory daoFactory)
|
||||
{
|
||||
return (T)Convert.ChangeType(await GetFolderArchiveAsync(daoFactory), typeof(T));
|
||||
}
|
||||
|
||||
internal static readonly ConcurrentDictionary<string, Lazy<int>> UserRootFolderCache =
|
||||
new ConcurrentDictionary<string, Lazy<int>>(); /*Use SYNCHRONIZED for cross thread blocks*/
|
||||
|
||||
@ -368,7 +419,7 @@ public class GlobalFolder
|
||||
|
||||
return myFolderId.Value;
|
||||
}
|
||||
|
||||
|
||||
protected internal void SetFolderMy(object value)
|
||||
{
|
||||
var cacheKey = string.Format("my/{0}/{1}", _tenantManager.GetCurrentTenant().Id, value);
|
||||
@ -407,7 +458,7 @@ public class GlobalFolder
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
|
||||
if (!CommonFolderCache.TryGetValue(_tenantManager.GetCurrentTenant().Id, out var commonFolderId))
|
||||
{
|
||||
commonFolderId = await GetFolderIdAndProccessFirstVisitAsync(fileMarker, daoFactory, false);
|
||||
@ -603,7 +654,7 @@ public class GlobalFolder
|
||||
|
||||
return trashFolderId;
|
||||
}
|
||||
|
||||
|
||||
protected internal void SetFolderTrash(object value)
|
||||
{
|
||||
var cacheKey = string.Format("trash/{0}/{1}", _tenantManager.GetCurrentTenant().Id, value);
|
||||
@ -739,6 +790,8 @@ public class GlobalFolderHelper
|
||||
public ValueTask<int> FolderRecentAsync => _globalFolder.GetFolderRecentAsync(_daoFactory);
|
||||
public ValueTask<int> FolderFavoritesAsync => _globalFolder.GetFolderFavoritesAsync(_daoFactory);
|
||||
public ValueTask<int> FolderTemplatesAsync => _globalFolder.GetFolderTemplatesAsync(_daoFactory);
|
||||
public ValueTask<int> FolderVirtualRoomsAsync => _globalFolder.GetFolderVirtualRoomsAsync(_daoFactory);
|
||||
public ValueTask<int> FolderArchiveAsync => _globalFolder.GetFolderArchiveAsync(_daoFactory);
|
||||
|
||||
public T GetFolderMy<T>()
|
||||
{
|
||||
@ -765,6 +818,16 @@ public class GlobalFolderHelper
|
||||
return (T)Convert.ChangeType(await FolderPrivacyAsync, typeof(T));
|
||||
}
|
||||
|
||||
public async ValueTask<T> GetFolderVirtualRooms<T>()
|
||||
{
|
||||
return (T)Convert.ChangeType(await FolderVirtualRoomsAsync, typeof(T));
|
||||
}
|
||||
|
||||
public async ValueTask<T> GetFolderArchive<T>()
|
||||
{
|
||||
return (T)Convert.ChangeType(await FolderArchiveAsync, typeof(T));
|
||||
}
|
||||
|
||||
public void SetFolderMy<T>(T val)
|
||||
{
|
||||
_globalFolder.SetFolderMy(val);
|
||||
|
@ -655,12 +655,14 @@ public class FileHandlerService
|
||||
|
||||
header = header.Substring("Bearer ".Length);
|
||||
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
var stringPayload = JwtBuilder.Create()
|
||||
.WithAlgorithm(new HMACSHA256Algorithm())
|
||||
.WithSerializer(new JwtSerializer())
|
||||
.WithSecret(_fileUtility.SignatureSecret)
|
||||
.MustVerifySignature()
|
||||
.Decode(header);
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
|
||||
_logger.DebugDocServiceStreamFilePayload(stringPayload);
|
||||
//var data = JObject.Parse(stringPayload);
|
||||
@ -767,12 +769,14 @@ public class FileHandlerService
|
||||
|
||||
header = header.Substring("Bearer ".Length);
|
||||
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
var stringPayload = JwtBuilder.Create()
|
||||
.WithAlgorithm(new HMACSHA256Algorithm())
|
||||
.WithSerializer(new JwtSerializer())
|
||||
.WithSecret(_fileUtility.SignatureSecret)
|
||||
.MustVerifySignature()
|
||||
.Decode(header);
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
|
||||
_logger.DebugDocServiceStreamFilePayload(stringPayload);
|
||||
//var data = JObject.Parse(stringPayload);
|
||||
@ -1428,12 +1432,14 @@ public class FileHandlerService
|
||||
{
|
||||
try
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
var dataString = JwtBuilder.Create()
|
||||
.WithAlgorithm(new HMACSHA256Algorithm())
|
||||
.WithSerializer(new JwtSerializer())
|
||||
.WithSecret(_fileUtility.SignatureSecret)
|
||||
.MustVerifySignature()
|
||||
.Decode(fileData.Token);
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
|
||||
var data = JObject.Parse(dataString);
|
||||
if (data == null)
|
||||
@ -1461,12 +1467,14 @@ public class FileHandlerService
|
||||
|
||||
try
|
||||
{
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
var stringPayload = JwtBuilder.Create()
|
||||
.WithAlgorithm(new HMACSHA256Algorithm())
|
||||
.WithSerializer(new JwtSerializer())
|
||||
.WithSecret(_fileUtility.SignatureSecret)
|
||||
.MustVerifySignature()
|
||||
.Decode(header);
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
|
||||
_logger.DebugDocServiceTrackPayload(stringPayload);
|
||||
var jsonPayload = JObject.Parse(stringPayload);
|
||||
|
33
products/ASC.Files/Core/Log/RoomLogoManagerLogger.cs
Normal file
33
products/ASC.Files/Core/Log/RoomLogoManagerLogger.cs
Normal file
@ -0,0 +1,33 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Files.Core.Log;
|
||||
|
||||
public static partial class RoomLogoManagerLogger
|
||||
{
|
||||
[LoggerMessage(Level = LogLevel.Error, Message = "RemoveRoomLogo")]
|
||||
public static partial void ErrorRemoveRoomLogo(this ILogger<RoomLogoManager> logger, Exception exception);
|
||||
}
|
@ -0,0 +1,827 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using ASC.Files.Core.EF;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
{
|
||||
[DbContext(typeof(MySqlFilesDbContext))]
|
||||
[Migration("20220526143057_FilesDbContextMySql_Upgrade2")]
|
||||
partial class FilesDbContextMySql_Upgrade2
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "6.0.4")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.DbQuota", b =>
|
||||
{
|
||||
b.Property<int>("Tenant")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant");
|
||||
|
||||
b.Property<int>("ActiveUsers")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("active_users");
|
||||
|
||||
b.Property<string>("AvangateId")
|
||||
.HasColumnType("varchar(128)")
|
||||
.HasColumnName("avangate_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("varchar(128)")
|
||||
.HasColumnName("description")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Features")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("features")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<long>("MaxFileSize")
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("max_file_size");
|
||||
|
||||
b.Property<long>("MaxTotalSize")
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("max_total_size");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("varchar(128)")
|
||||
.HasColumnName("name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<decimal>("Price")
|
||||
.HasColumnType("decimal(10,2)")
|
||||
.HasColumnName("price");
|
||||
|
||||
b.Property<bool>("Visible")
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("visible");
|
||||
|
||||
b.HasKey("Tenant")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.ToTable("tenants_quota", (string)null);
|
||||
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Tenant = -1,
|
||||
ActiveUsers = 10000,
|
||||
AvangateId = "0",
|
||||
Features = "domain,audit,controlpanel,healthcheck,ldap,sso,whitelabel,branding,ssbranding,update,support,portals:10000,discencryption,privacyroom,restore",
|
||||
MaxFileSize = 102400L,
|
||||
MaxTotalSize = 10995116277760L,
|
||||
Name = "default",
|
||||
Price = 0.00m,
|
||||
Visible = false
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.DbTariff", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<string>("Comment")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("comment")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("CreateOn")
|
||||
.ValueGeneratedOnAddOrUpdate()
|
||||
.HasColumnType("timestamp")
|
||||
.HasColumnName("create_on")
|
||||
.HasDefaultValueSql("CURRENT_TIMESTAMP");
|
||||
|
||||
b.Property<int>("Quantity")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("quantity");
|
||||
|
||||
b.Property<DateTime>("Stamp")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("stamp");
|
||||
|
||||
b.Property<int>("Tariff")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tariff");
|
||||
|
||||
b.Property<int>("Tenant")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Tenant")
|
||||
.HasDatabaseName("tenant");
|
||||
|
||||
b.ToTable("tenants_tariff", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbTenant", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<string>("Alias")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(100)")
|
||||
.HasColumnName("alias")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<bool>("Calls")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("calls")
|
||||
.HasDefaultValueSql("true");
|
||||
|
||||
b.Property<DateTime>("CreationDateTime")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("creationdatetime");
|
||||
|
||||
b.Property<int?>("Industry")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("industry");
|
||||
|
||||
b.Property<string>("Language")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(10)")
|
||||
.HasColumnName("language")
|
||||
.HasDefaultValueSql("'en-US'")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("LastModified")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp")
|
||||
.HasColumnName("last_modified")
|
||||
.HasDefaultValueSql("CURRENT_TIMESTAMP");
|
||||
|
||||
b.Property<string>("MappedDomain")
|
||||
.HasColumnType("varchar(100)")
|
||||
.HasColumnName("mappeddomain")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("OwnerId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(38)")
|
||||
.HasColumnName("owner_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("PaymentId")
|
||||
.HasColumnType("varchar(38)")
|
||||
.HasColumnName("payment_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<bool>("Spam")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("spam")
|
||||
.HasDefaultValueSql("true");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("status");
|
||||
|
||||
b.Property<DateTime?>("StatusChanged")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("statuschanged");
|
||||
|
||||
b.Property<string>("TimeZone")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("timezone")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("TrustedDomainsEnabled")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("trusteddomainsenabled")
|
||||
.HasDefaultValueSql("'1'");
|
||||
|
||||
b.Property<string>("TrustedDomainsRaw")
|
||||
.HasColumnType("varchar(1024)")
|
||||
.HasColumnName("trusteddomains")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("Version")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("version")
|
||||
.HasDefaultValueSql("'2'");
|
||||
|
||||
b.Property<DateTime?>("Version_Changed")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("version_changed");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LastModified")
|
||||
.HasDatabaseName("last_modified");
|
||||
|
||||
b.HasIndex("MappedDomain")
|
||||
.HasDatabaseName("mappeddomain");
|
||||
|
||||
b.HasIndex("Version")
|
||||
.HasDatabaseName("version");
|
||||
|
||||
b.ToTable("tenants_tenants", (string)null);
|
||||
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Id = 1,
|
||||
Alias = "localhost",
|
||||
Calls = false,
|
||||
CreationDateTime = new DateTime(2021, 3, 9, 17, 46, 59, 97, DateTimeKind.Utc).AddTicks(4317),
|
||||
LastModified = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||
Name = "Web Office",
|
||||
OwnerId = "66faa6e4-f133-11ea-b126-00ffeec8b4ef",
|
||||
Spam = false,
|
||||
Status = 0,
|
||||
TrustedDomainsEnabled = 0,
|
||||
Version = 0
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFile", b =>
|
||||
{
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<int>("Id")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<int>("Version")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("version");
|
||||
|
||||
b.Property<int>("Category")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("category");
|
||||
|
||||
b.Property<string>("Changes")
|
||||
.HasColumnType("mediumtext")
|
||||
.HasColumnName("changes")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Comment")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("comment")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<long>("ContentLength")
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("content_length");
|
||||
|
||||
b.Property<string>("ConvertedType")
|
||||
.HasColumnType("varchar(10)")
|
||||
.HasColumnName("converted_type")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("create_by")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("CreateOn")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("create_on");
|
||||
|
||||
b.Property<bool>("CurrentVersion")
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("current_version");
|
||||
|
||||
b.Property<bool>("Encrypted")
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("encrypted");
|
||||
|
||||
b.Property<int>("FileStatus")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("file_status");
|
||||
|
||||
b.Property<int>("Forcesave")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("forcesave");
|
||||
|
||||
b.Property<string>("ModifiedBy")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("modified_by")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("ModifiedOn")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("modified_on");
|
||||
|
||||
b.Property<int>("ParentId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("folder_id");
|
||||
|
||||
b.Property<int>("ThumbnailStatus")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("thumb");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(400)")
|
||||
.HasColumnName("title")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("VersionGroup")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("version_group")
|
||||
.HasDefaultValueSql("'1'");
|
||||
|
||||
b.HasKey("TenantId", "Id", "Version")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.HasIndex("Id")
|
||||
.HasDatabaseName("id");
|
||||
|
||||
b.HasIndex("ModifiedOn")
|
||||
.HasDatabaseName("modified_on");
|
||||
|
||||
b.HasIndex("ParentId")
|
||||
.HasDatabaseName("folder_id");
|
||||
|
||||
b.ToTable("files_file", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesBunchObjects", b =>
|
||||
{
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("RightNode")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("right_node")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("LeftNode")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("left_node")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.HasKey("TenantId", "RightNode")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.HasIndex("LeftNode")
|
||||
.HasDatabaseName("left_node");
|
||||
|
||||
b.ToTable("files_bunch_objects", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesLink", b =>
|
||||
{
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("SourceId")
|
||||
.HasColumnType("varchar(32)")
|
||||
.HasColumnName("source_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("LinkedId")
|
||||
.HasColumnType("varchar(32)")
|
||||
.HasColumnName("linked_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("LinkedFor")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("linked_for")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.HasKey("TenantId", "SourceId", "LinkedId")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.HasIndex("TenantId", "SourceId", "LinkedId", "LinkedFor")
|
||||
.HasDatabaseName("linked_for");
|
||||
|
||||
b.ToTable("files_link", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesSecurity", b =>
|
||||
{
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("EntryId")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("entry_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("EntryType")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("entry_type");
|
||||
|
||||
b.Property<string>("Subject")
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("subject")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Owner")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("owner")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("Share")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("security");
|
||||
|
||||
b.Property<DateTime>("TimeStamp")
|
||||
.ValueGeneratedOnAddOrUpdate()
|
||||
.HasColumnType("timestamp")
|
||||
.HasColumnName("timestamp")
|
||||
.HasDefaultValueSql("CURRENT_TIMESTAMP");
|
||||
|
||||
b.HasKey("TenantId", "EntryId", "EntryType", "Subject")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.HasIndex("Owner")
|
||||
.HasDatabaseName("owner");
|
||||
|
||||
b.HasIndex("TenantId", "EntryType", "EntryId", "Owner")
|
||||
.HasDatabaseName("tenant_id");
|
||||
|
||||
b.ToTable("files_security", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesTag", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Owner")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(38)")
|
||||
.HasColumnName("owner")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("flag");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("TenantId", "Owner", "Name", "Type")
|
||||
.HasDatabaseName("name");
|
||||
|
||||
b.ToTable("files_tag", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesTagLink", b =>
|
||||
{
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<int>("TagId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tag_id");
|
||||
|
||||
b.Property<string>("EntryId")
|
||||
.HasColumnType("varchar(32)")
|
||||
.HasColumnName("entry_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("EntryType")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("entry_type");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tag_count");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("create_by")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime?>("CreateOn")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("create_on");
|
||||
|
||||
b.HasKey("TenantId", "TagId", "EntryId", "EntryType")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.HasIndex("CreateOn")
|
||||
.HasDatabaseName("create_on");
|
||||
|
||||
b.HasIndex("TenantId", "EntryId", "EntryType")
|
||||
.HasDatabaseName("entry_id");
|
||||
|
||||
b.ToTable("files_tag_link", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesThirdpartyAccount", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<DateTime>("CreateOn")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("create_on");
|
||||
|
||||
b.Property<string>("FolderId")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("folder_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("FolderType")
|
||||
.HasColumnType("folder_type");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(100)")
|
||||
.HasColumnName("password")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Provider")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("provider")
|
||||
.HasDefaultValueSql("'0'")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("RootFolderType")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("root_folder_type");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(400)")
|
||||
.HasColumnName("customer_title")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Token")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("token")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("url")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(38)")
|
||||
.HasColumnName("user_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(100)")
|
||||
.HasColumnName("user_name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("files_thirdparty_account", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesThirdpartyApp", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("varchar(38)")
|
||||
.HasColumnName("user_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("App")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("app")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("ModifiedOn")
|
||||
.ValueGeneratedOnAddOrUpdate()
|
||||
.HasColumnType("timestamp")
|
||||
.HasColumnName("modified_on")
|
||||
.HasDefaultValueSql("CURRENT_TIMESTAMP");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("Token")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("token")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.HasKey("UserId", "App")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.ToTable("files_thirdparty_app", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesThirdpartyIdMapping", b =>
|
||||
{
|
||||
b.Property<string>("HashId")
|
||||
.HasColumnType("char(32)")
|
||||
.HasColumnName("hash_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Id")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.HasKey("HashId")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.HasIndex("TenantId", "HashId")
|
||||
.HasDatabaseName("index_1");
|
||||
|
||||
b.ToTable("files_thirdparty_id_mapping", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFolder", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("create_by")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("CreateOn")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("create_on");
|
||||
|
||||
b.Property<int>("FilesCount")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("filesCount");
|
||||
|
||||
b.Property<int>("FolderType")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("folder_type");
|
||||
|
||||
b.Property<int>("FoldersCount")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("foldersCount");
|
||||
|
||||
b.Property<string>("ModifiedBy")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("modified_by")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("ModifiedOn")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("modified_on");
|
||||
|
||||
b.Property<int>("ParentId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("parent_id");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(400)")
|
||||
.HasColumnName("title")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ModifiedOn")
|
||||
.HasDatabaseName("modified_on");
|
||||
|
||||
b.HasIndex("TenantId", "ParentId")
|
||||
.HasDatabaseName("parent_id");
|
||||
|
||||
b.ToTable("files_folder", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFolderTree", b =>
|
||||
{
|
||||
b.Property<int>("ParentId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("parent_id");
|
||||
|
||||
b.Property<int>("FolderId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("folder_id");
|
||||
|
||||
b.Property<int>("Level")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("level");
|
||||
|
||||
b.HasKey("ParentId", "FolderId")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.HasIndex("FolderId")
|
||||
.HasDatabaseName("folder_id");
|
||||
|
||||
b.ToTable("files_folder_tree", (string)null);
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,190 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
{
|
||||
public partial class FilesDbContextMySql_Upgrade2 : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "folder_type",
|
||||
table: "files_thirdparty_account",
|
||||
newName: "FolderType");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "FolderType",
|
||||
table: "files_thirdparty_account",
|
||||
type: "folder_type",
|
||||
nullable: false,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "int");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "folder_id",
|
||||
table: "files_thirdparty_account",
|
||||
type: "text",
|
||||
nullable: true,
|
||||
collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8");
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "root_folder_type",
|
||||
table: "files_thirdparty_account",
|
||||
type: "int",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "tenants_quota",
|
||||
columns: table => new
|
||||
{
|
||||
tenant = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
name = table.Column<string>(type: "varchar(128)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
description = table.Column<string>(type: "varchar(128)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
max_file_size = table.Column<long>(type: "bigint", nullable: false),
|
||||
max_total_size = table.Column<long>(type: "bigint", nullable: false),
|
||||
active_users = table.Column<int>(type: "int", nullable: false),
|
||||
features = table.Column<string>(type: "text", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
price = table.Column<decimal>(type: "decimal(10,2)", nullable: false),
|
||||
avangate_id = table.Column<string>(type: "varchar(128)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
visible = table.Column<bool>(type: "tinyint(1)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PRIMARY", x => x.tenant);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "tenants_tariff",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
tenant = table.Column<int>(type: "int", nullable: false),
|
||||
tariff = table.Column<int>(type: "int", nullable: false),
|
||||
stamp = table.Column<DateTime>(type: "datetime", nullable: false),
|
||||
quantity = table.Column<int>(type: "int", nullable: false),
|
||||
comment = table.Column<string>(type: "varchar(255)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
create_on = table.Column<DateTime>(type: "timestamp", nullable: false, defaultValueSql: "CURRENT_TIMESTAMP")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_tenants_tariff", x => x.id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "tenants_tenants",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
name = table.Column<string>(type: "varchar(255)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
alias = table.Column<string>(type: "varchar(100)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
mappeddomain = table.Column<string>(type: "varchar(100)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
version = table.Column<int>(type: "int", nullable: false, defaultValueSql: "'2'"),
|
||||
version_changed = table.Column<DateTime>(type: "datetime", nullable: true),
|
||||
language = table.Column<string>(type: "char(10)", nullable: false, defaultValueSql: "'en-US'", collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
timezone = table.Column<string>(type: "varchar(50)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
trusteddomains = table.Column<string>(type: "varchar(1024)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
trusteddomainsenabled = table.Column<int>(type: "int", nullable: false, defaultValueSql: "'1'"),
|
||||
status = table.Column<int>(type: "int", nullable: false),
|
||||
statuschanged = table.Column<DateTime>(type: "datetime", nullable: true),
|
||||
creationdatetime = table.Column<DateTime>(type: "datetime", nullable: false),
|
||||
owner_id = table.Column<string>(type: "varchar(38)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
payment_id = table.Column<string>(type: "varchar(38)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
industry = table.Column<int>(type: "int", nullable: true),
|
||||
last_modified = table.Column<DateTime>(type: "timestamp", nullable: false, defaultValueSql: "CURRENT_TIMESTAMP"),
|
||||
spam = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValueSql: "true"),
|
||||
calls = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValueSql: "true")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_tenants_tenants", x => x.id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "tenants_quota",
|
||||
columns: new[] { "tenant", "active_users", "avangate_id", "description", "features", "max_file_size", "max_total_size", "name", "price", "visible" },
|
||||
values: new object[] { -1, 10000, "0", null, "domain,audit,controlpanel,healthcheck,ldap,sso,whitelabel,branding,ssbranding,update,support,portals:10000,discencryption,privacyroom,restore", 102400L, 10995116277760L, "default", 0.00m, false });
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "tenants_tenants",
|
||||
columns: new[] { "id", "alias", "creationdatetime", "industry", "mappeddomain", "name", "owner_id", "payment_id", "status", "statuschanged", "timezone", "trusteddomains", "version_changed" },
|
||||
values: new object[] { 1, "localhost", new DateTime(2021, 3, 9, 17, 46, 59, 97, DateTimeKind.Utc).AddTicks(4317), null, null, "Web Office", "66faa6e4-f133-11ea-b126-00ffeec8b4ef", null, 0, null, null, null, null });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "tenant",
|
||||
table: "tenants_tariff",
|
||||
column: "tenant");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "last_modified",
|
||||
table: "tenants_tenants",
|
||||
column: "last_modified");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "mappeddomain",
|
||||
table: "tenants_tenants",
|
||||
column: "mappeddomain");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "version",
|
||||
table: "tenants_tenants",
|
||||
column: "version");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "tenants_quota");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "tenants_tariff");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "tenants_tenants");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "folder_id",
|
||||
table: "files_thirdparty_account");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "root_folder_type",
|
||||
table: "files_thirdparty_account");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "FolderType",
|
||||
table: "files_thirdparty_account",
|
||||
newName: "folder_type");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "folder_type",
|
||||
table: "files_thirdparty_account",
|
||||
type: "int",
|
||||
nullable: false,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "folder_type");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,12 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using ASC.Files.Core.EF;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
|
||||
namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
{
|
||||
[DbContext(typeof(MySqlFilesDbContext))]
|
||||
@ -12,8 +16,263 @@ namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64)
|
||||
.HasAnnotation("ProductVersion", "5.0.10");
|
||||
.HasAnnotation("ProductVersion", "6.0.4")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.DbQuota", b =>
|
||||
{
|
||||
b.Property<int>("Tenant")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant");
|
||||
|
||||
b.Property<int>("ActiveUsers")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("active_users");
|
||||
|
||||
b.Property<string>("AvangateId")
|
||||
.HasColumnType("varchar(128)")
|
||||
.HasColumnName("avangate_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("varchar(128)")
|
||||
.HasColumnName("description")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Features")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("features")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<long>("MaxFileSize")
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("max_file_size");
|
||||
|
||||
b.Property<long>("MaxTotalSize")
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("max_total_size");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("varchar(128)")
|
||||
.HasColumnName("name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<decimal>("Price")
|
||||
.HasColumnType("decimal(10,2)")
|
||||
.HasColumnName("price");
|
||||
|
||||
b.Property<bool>("Visible")
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("visible");
|
||||
|
||||
b.HasKey("Tenant")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.ToTable("tenants_quota", (string)null);
|
||||
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Tenant = -1,
|
||||
ActiveUsers = 10000,
|
||||
AvangateId = "0",
|
||||
Features = "domain,audit,controlpanel,healthcheck,ldap,sso,whitelabel,branding,ssbranding,update,support,portals:10000,discencryption,privacyroom,restore",
|
||||
MaxFileSize = 102400L,
|
||||
MaxTotalSize = 10995116277760L,
|
||||
Name = "default",
|
||||
Price = 0.00m,
|
||||
Visible = false
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.DbTariff", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<string>("Comment")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("comment")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("CreateOn")
|
||||
.ValueGeneratedOnAddOrUpdate()
|
||||
.HasColumnType("timestamp")
|
||||
.HasColumnName("create_on")
|
||||
.HasDefaultValueSql("CURRENT_TIMESTAMP");
|
||||
|
||||
b.Property<int>("Quantity")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("quantity");
|
||||
|
||||
b.Property<DateTime>("Stamp")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("stamp");
|
||||
|
||||
b.Property<int>("Tariff")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tariff");
|
||||
|
||||
b.Property<int>("Tenant")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Tenant")
|
||||
.HasDatabaseName("tenant");
|
||||
|
||||
b.ToTable("tenants_tariff", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbTenant", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<string>("Alias")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(100)")
|
||||
.HasColumnName("alias")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<bool>("Calls")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("calls")
|
||||
.HasDefaultValueSql("true");
|
||||
|
||||
b.Property<DateTime>("CreationDateTime")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("creationdatetime");
|
||||
|
||||
b.Property<int?>("Industry")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("industry");
|
||||
|
||||
b.Property<string>("Language")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(10)")
|
||||
.HasColumnName("language")
|
||||
.HasDefaultValueSql("'en-US'")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("LastModified")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp")
|
||||
.HasColumnName("last_modified")
|
||||
.HasDefaultValueSql("CURRENT_TIMESTAMP");
|
||||
|
||||
b.Property<string>("MappedDomain")
|
||||
.HasColumnType("varchar(100)")
|
||||
.HasColumnName("mappeddomain")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("OwnerId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(38)")
|
||||
.HasColumnName("owner_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("PaymentId")
|
||||
.HasColumnType("varchar(38)")
|
||||
.HasColumnName("payment_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<bool>("Spam")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("spam")
|
||||
.HasDefaultValueSql("true");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("status");
|
||||
|
||||
b.Property<DateTime?>("StatusChanged")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("statuschanged");
|
||||
|
||||
b.Property<string>("TimeZone")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("timezone")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("TrustedDomainsEnabled")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("trusteddomainsenabled")
|
||||
.HasDefaultValueSql("'1'");
|
||||
|
||||
b.Property<string>("TrustedDomainsRaw")
|
||||
.HasColumnType("varchar(1024)")
|
||||
.HasColumnName("trusteddomains")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("Version")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("version")
|
||||
.HasDefaultValueSql("'2'");
|
||||
|
||||
b.Property<DateTime?>("Version_Changed")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("version_changed");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LastModified")
|
||||
.HasDatabaseName("last_modified");
|
||||
|
||||
b.HasIndex("MappedDomain")
|
||||
.HasDatabaseName("mappeddomain");
|
||||
|
||||
b.HasIndex("Version")
|
||||
.HasDatabaseName("version");
|
||||
|
||||
b.ToTable("tenants_tenants", (string)null);
|
||||
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Id = 1,
|
||||
Alias = "localhost",
|
||||
Calls = false,
|
||||
CreationDateTime = new DateTime(2021, 3, 9, 17, 46, 59, 97, DateTimeKind.Utc).AddTicks(4317),
|
||||
LastModified = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||
Name = "Web Office",
|
||||
OwnerId = "66faa6e4-f133-11ea-b126-00ffeec8b4ef",
|
||||
Spam = false,
|
||||
Status = 0,
|
||||
TrustedDomainsEnabled = 0,
|
||||
Version = 0
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFile", b =>
|
||||
{
|
||||
@ -78,10 +337,6 @@ namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("file_status");
|
||||
|
||||
b.Property<int>("FolderId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("folder_id");
|
||||
|
||||
b.Property<int>("Forcesave")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("forcesave");
|
||||
@ -97,7 +352,11 @@ namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("modified_on");
|
||||
|
||||
b.Property<int>("Thumb")
|
||||
b.Property<int>("ParentId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("folder_id");
|
||||
|
||||
b.Property<int>("ThumbnailStatus")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("thumb");
|
||||
|
||||
@ -117,16 +376,16 @@ namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
b.HasKey("TenantId", "Id", "Version")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.HasIndex("FolderId")
|
||||
.HasDatabaseName("folder_id");
|
||||
|
||||
b.HasIndex("Id")
|
||||
.HasDatabaseName("id");
|
||||
|
||||
b.HasIndex("ModifiedOn")
|
||||
.HasDatabaseName("modified_on");
|
||||
|
||||
b.ToTable("files_file");
|
||||
b.HasIndex("ParentId")
|
||||
.HasDatabaseName("folder_id");
|
||||
|
||||
b.ToTable("files_file", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesBunchObjects", b =>
|
||||
@ -154,7 +413,7 @@ namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
b.HasIndex("LeftNode")
|
||||
.HasDatabaseName("left_node");
|
||||
|
||||
b.ToTable("files_bunch_objects");
|
||||
b.ToTable("files_bunch_objects", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesLink", b =>
|
||||
@ -220,7 +479,7 @@ namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("Security")
|
||||
b.Property<int>("Share")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("security");
|
||||
|
||||
@ -239,7 +498,7 @@ namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
b.HasIndex("TenantId", "EntryType", "EntryId", "Owner")
|
||||
.HasDatabaseName("tenant_id");
|
||||
|
||||
b.ToTable("files_security");
|
||||
b.ToTable("files_security", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesTag", b =>
|
||||
@ -249,10 +508,6 @@ namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<int>("Flag")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("flag");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)")
|
||||
@ -271,12 +526,16 @@ namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("flag");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("TenantId", "Owner", "Name", "Flag")
|
||||
b.HasIndex("TenantId", "Owner", "Name", "Type")
|
||||
.HasDatabaseName("name");
|
||||
|
||||
b.ToTable("files_tag");
|
||||
b.ToTable("files_tag", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesTagLink", b =>
|
||||
@ -299,6 +558,10 @@ namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("entry_type");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tag_count");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("create_by")
|
||||
@ -309,10 +572,6 @@ namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("create_on");
|
||||
|
||||
b.Property<int>("TagCount")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tag_count");
|
||||
|
||||
b.HasKey("TenantId", "TagId", "EntryId", "EntryType")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
@ -322,7 +581,7 @@ namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
b.HasIndex("TenantId", "EntryId", "EntryType")
|
||||
.HasDatabaseName("entry_id");
|
||||
|
||||
b.ToTable("files_tag_link");
|
||||
b.ToTable("files_tag_link", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesThirdpartyAccount", b =>
|
||||
@ -336,9 +595,14 @@ namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("create_on");
|
||||
|
||||
b.Property<string>("FolderId")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("folder_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("FolderType")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("folder_type");
|
||||
.HasColumnType("folder_type");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
@ -356,6 +620,10 @@ namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("RootFolderType")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("root_folder_type");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
@ -395,7 +663,7 @@ namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("files_thirdparty_account");
|
||||
b.ToTable("files_thirdparty_account", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesThirdpartyApp", b =>
|
||||
@ -431,7 +699,7 @@ namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
b.HasKey("UserId", "App")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.ToTable("files_thirdparty_app");
|
||||
b.ToTable("files_thirdparty_app", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesThirdpartyIdMapping", b =>
|
||||
@ -459,7 +727,7 @@ namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
b.HasIndex("TenantId", "HashId")
|
||||
.HasDatabaseName("index_1");
|
||||
|
||||
b.ToTable("files_thirdparty_id_mapping");
|
||||
b.ToTable("files_thirdparty_id_mapping", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFolder", b =>
|
||||
@ -526,7 +794,7 @@ namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
b.HasIndex("TenantId", "ParentId")
|
||||
.HasDatabaseName("parent_id");
|
||||
|
||||
b.ToTable("files_folder");
|
||||
b.ToTable("files_folder", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFolderTree", b =>
|
||||
@ -549,7 +817,7 @@ namespace ASC.Files.Core.Migrations.MySql.FilesDbContextMySql
|
||||
b.HasIndex("FolderId")
|
||||
.HasDatabaseName("folder_id");
|
||||
|
||||
b.ToTable("files_folder_tree");
|
||||
b.ToTable("files_folder_tree", (string)null);
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
|
@ -0,0 +1,827 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using ASC.Files.Core.EF;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
{
|
||||
[DbContext(typeof(PostgreSqlFilesDbContext))]
|
||||
[Migration("20220526143058_FilesDbContextPostgreSql_Upgrade1")]
|
||||
partial class FilesDbContextPostgreSql_Upgrade1
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "6.0.4")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.DbQuota", b =>
|
||||
{
|
||||
b.Property<int>("Tenant")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant");
|
||||
|
||||
b.Property<int>("ActiveUsers")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("active_users");
|
||||
|
||||
b.Property<string>("AvangateId")
|
||||
.HasColumnType("varchar(128)")
|
||||
.HasColumnName("avangate_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("varchar(128)")
|
||||
.HasColumnName("description")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Features")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("features")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<long>("MaxFileSize")
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("max_file_size");
|
||||
|
||||
b.Property<long>("MaxTotalSize")
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("max_total_size");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("varchar(128)")
|
||||
.HasColumnName("name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<decimal>("Price")
|
||||
.HasColumnType("decimal(10,2)")
|
||||
.HasColumnName("price");
|
||||
|
||||
b.Property<bool>("Visible")
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("visible");
|
||||
|
||||
b.HasKey("Tenant")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.ToTable("tenants_quota", (string)null);
|
||||
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Tenant = -1,
|
||||
ActiveUsers = 10000,
|
||||
AvangateId = "0",
|
||||
Features = "domain,audit,controlpanel,healthcheck,ldap,sso,whitelabel,branding,ssbranding,update,support,portals:10000,discencryption,privacyroom,restore",
|
||||
MaxFileSize = 102400L,
|
||||
MaxTotalSize = 10995116277760L,
|
||||
Name = "default",
|
||||
Price = 0.00m,
|
||||
Visible = false
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.DbTariff", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<string>("Comment")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("comment")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("CreateOn")
|
||||
.ValueGeneratedOnAddOrUpdate()
|
||||
.HasColumnType("timestamp")
|
||||
.HasColumnName("create_on")
|
||||
.HasDefaultValueSql("CURRENT_TIMESTAMP");
|
||||
|
||||
b.Property<int>("Quantity")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("quantity");
|
||||
|
||||
b.Property<DateTime>("Stamp")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("stamp");
|
||||
|
||||
b.Property<int>("Tariff")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tariff");
|
||||
|
||||
b.Property<int>("Tenant")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Tenant")
|
||||
.HasDatabaseName("tenant");
|
||||
|
||||
b.ToTable("tenants_tariff", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbTenant", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<string>("Alias")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(100)")
|
||||
.HasColumnName("alias")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<bool>("Calls")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("calls")
|
||||
.HasDefaultValueSql("true");
|
||||
|
||||
b.Property<DateTime>("CreationDateTime")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("creationdatetime");
|
||||
|
||||
b.Property<int?>("Industry")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("industry");
|
||||
|
||||
b.Property<string>("Language")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(10)")
|
||||
.HasColumnName("language")
|
||||
.HasDefaultValueSql("'en-US'")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("LastModified")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp")
|
||||
.HasColumnName("last_modified")
|
||||
.HasDefaultValueSql("CURRENT_TIMESTAMP");
|
||||
|
||||
b.Property<string>("MappedDomain")
|
||||
.HasColumnType("varchar(100)")
|
||||
.HasColumnName("mappeddomain")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("OwnerId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(38)")
|
||||
.HasColumnName("owner_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("PaymentId")
|
||||
.HasColumnType("varchar(38)")
|
||||
.HasColumnName("payment_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<bool>("Spam")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("spam")
|
||||
.HasDefaultValueSql("true");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("status");
|
||||
|
||||
b.Property<DateTime?>("StatusChanged")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("statuschanged");
|
||||
|
||||
b.Property<string>("TimeZone")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("timezone")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("TrustedDomainsEnabled")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("trusteddomainsenabled")
|
||||
.HasDefaultValueSql("'1'");
|
||||
|
||||
b.Property<string>("TrustedDomainsRaw")
|
||||
.HasColumnType("varchar(1024)")
|
||||
.HasColumnName("trusteddomains")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("Version")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("version")
|
||||
.HasDefaultValueSql("'2'");
|
||||
|
||||
b.Property<DateTime?>("Version_Changed")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("version_changed");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LastModified")
|
||||
.HasDatabaseName("last_modified");
|
||||
|
||||
b.HasIndex("MappedDomain")
|
||||
.HasDatabaseName("mappeddomain");
|
||||
|
||||
b.HasIndex("Version")
|
||||
.HasDatabaseName("version");
|
||||
|
||||
b.ToTable("tenants_tenants", (string)null);
|
||||
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Id = 1,
|
||||
Alias = "localhost",
|
||||
Calls = false,
|
||||
CreationDateTime = new DateTime(2021, 3, 9, 17, 46, 59, 97, DateTimeKind.Utc).AddTicks(4317),
|
||||
LastModified = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||
Name = "Web Office",
|
||||
OwnerId = "66faa6e4-f133-11ea-b126-00ffeec8b4ef",
|
||||
Spam = false,
|
||||
Status = 0,
|
||||
TrustedDomainsEnabled = 0,
|
||||
Version = 0
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFile", b =>
|
||||
{
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<int>("Id")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<int>("Version")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("version");
|
||||
|
||||
b.Property<int>("Category")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("category");
|
||||
|
||||
b.Property<string>("Changes")
|
||||
.HasColumnType("mediumtext")
|
||||
.HasColumnName("changes")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Comment")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("comment")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<long>("ContentLength")
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("content_length");
|
||||
|
||||
b.Property<string>("ConvertedType")
|
||||
.HasColumnType("varchar(10)")
|
||||
.HasColumnName("converted_type")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("create_by")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("CreateOn")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("create_on");
|
||||
|
||||
b.Property<bool>("CurrentVersion")
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("current_version");
|
||||
|
||||
b.Property<bool>("Encrypted")
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("encrypted");
|
||||
|
||||
b.Property<int>("FileStatus")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("file_status");
|
||||
|
||||
b.Property<int>("Forcesave")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("forcesave");
|
||||
|
||||
b.Property<string>("ModifiedBy")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("modified_by")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("ModifiedOn")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("modified_on");
|
||||
|
||||
b.Property<int>("ParentId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("folder_id");
|
||||
|
||||
b.Property<int>("ThumbnailStatus")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("thumb");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(400)")
|
||||
.HasColumnName("title")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("VersionGroup")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("version_group")
|
||||
.HasDefaultValueSql("'1'");
|
||||
|
||||
b.HasKey("TenantId", "Id", "Version")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.HasIndex("Id")
|
||||
.HasDatabaseName("id");
|
||||
|
||||
b.HasIndex("ModifiedOn")
|
||||
.HasDatabaseName("modified_on");
|
||||
|
||||
b.HasIndex("ParentId")
|
||||
.HasDatabaseName("folder_id");
|
||||
|
||||
b.ToTable("files_file", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesBunchObjects", b =>
|
||||
{
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("RightNode")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("right_node")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("LeftNode")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("left_node")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.HasKey("TenantId", "RightNode")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.HasIndex("LeftNode")
|
||||
.HasDatabaseName("left_node");
|
||||
|
||||
b.ToTable("files_bunch_objects", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesLink", b =>
|
||||
{
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("SourceId")
|
||||
.HasColumnType("varchar(32)")
|
||||
.HasColumnName("source_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("LinkedId")
|
||||
.HasColumnType("varchar(32)")
|
||||
.HasColumnName("linked_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("LinkedFor")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("linked_for")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.HasKey("TenantId", "SourceId", "LinkedId")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.HasIndex("TenantId", "SourceId", "LinkedId", "LinkedFor")
|
||||
.HasDatabaseName("linked_for");
|
||||
|
||||
b.ToTable("files_link", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesSecurity", b =>
|
||||
{
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("EntryId")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("entry_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("EntryType")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("entry_type");
|
||||
|
||||
b.Property<string>("Subject")
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("subject")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Owner")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("owner")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("Share")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("security");
|
||||
|
||||
b.Property<DateTime>("TimeStamp")
|
||||
.ValueGeneratedOnAddOrUpdate()
|
||||
.HasColumnType("timestamp")
|
||||
.HasColumnName("timestamp")
|
||||
.HasDefaultValueSql("CURRENT_TIMESTAMP");
|
||||
|
||||
b.HasKey("TenantId", "EntryId", "EntryType", "Subject")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.HasIndex("Owner")
|
||||
.HasDatabaseName("owner");
|
||||
|
||||
b.HasIndex("TenantId", "EntryType", "EntryId", "Owner")
|
||||
.HasDatabaseName("tenant_id");
|
||||
|
||||
b.ToTable("files_security", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesTag", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Owner")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(38)")
|
||||
.HasColumnName("owner")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("flag");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("TenantId", "Owner", "Name", "Type")
|
||||
.HasDatabaseName("name");
|
||||
|
||||
b.ToTable("files_tag", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesTagLink", b =>
|
||||
{
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<int>("TagId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tag_id");
|
||||
|
||||
b.Property<string>("EntryId")
|
||||
.HasColumnType("varchar(32)")
|
||||
.HasColumnName("entry_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("EntryType")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("entry_type");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tag_count");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("create_by")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime?>("CreateOn")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("create_on");
|
||||
|
||||
b.HasKey("TenantId", "TagId", "EntryId", "EntryType")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.HasIndex("CreateOn")
|
||||
.HasDatabaseName("create_on");
|
||||
|
||||
b.HasIndex("TenantId", "EntryId", "EntryType")
|
||||
.HasDatabaseName("entry_id");
|
||||
|
||||
b.ToTable("files_tag_link", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesThirdpartyAccount", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<DateTime>("CreateOn")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("create_on");
|
||||
|
||||
b.Property<string>("FolderId")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("folder_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("FolderType")
|
||||
.HasColumnType("folder_type");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(100)")
|
||||
.HasColumnName("password")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Provider")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("provider")
|
||||
.HasDefaultValueSql("'0'")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("RootFolderType")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("root_folder_type");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(400)")
|
||||
.HasColumnName("customer_title")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Token")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("token")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Url")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("url")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(38)")
|
||||
.HasColumnName("user_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(100)")
|
||||
.HasColumnName("user_name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("files_thirdparty_account", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesThirdpartyApp", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("varchar(38)")
|
||||
.HasColumnName("user_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("App")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("app")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("ModifiedOn")
|
||||
.ValueGeneratedOnAddOrUpdate()
|
||||
.HasColumnType("timestamp")
|
||||
.HasColumnName("modified_on")
|
||||
.HasDefaultValueSql("CURRENT_TIMESTAMP");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("Token")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("token")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.HasKey("UserId", "App")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.ToTable("files_thirdparty_app", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesThirdpartyIdMapping", b =>
|
||||
{
|
||||
b.Property<string>("HashId")
|
||||
.HasColumnType("char(32)")
|
||||
.HasColumnName("hash_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Id")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.HasKey("HashId")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.HasIndex("TenantId", "HashId")
|
||||
.HasDatabaseName("index_1");
|
||||
|
||||
b.ToTable("files_thirdparty_id_mapping", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFolder", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("create_by")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("CreateOn")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("create_on");
|
||||
|
||||
b.Property<int>("FilesCount")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("filesCount");
|
||||
|
||||
b.Property<int>("FolderType")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("folder_type");
|
||||
|
||||
b.Property<int>("FoldersCount")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("foldersCount");
|
||||
|
||||
b.Property<string>("ModifiedBy")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("modified_by")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("ModifiedOn")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("modified_on");
|
||||
|
||||
b.Property<int>("ParentId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("parent_id");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(400)")
|
||||
.HasColumnName("title")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ModifiedOn")
|
||||
.HasDatabaseName("modified_on");
|
||||
|
||||
b.HasIndex("TenantId", "ParentId")
|
||||
.HasDatabaseName("parent_id");
|
||||
|
||||
b.ToTable("files_folder", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFolderTree", b =>
|
||||
{
|
||||
b.Property<int>("ParentId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("parent_id");
|
||||
|
||||
b.Property<int>("FolderId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("folder_id");
|
||||
|
||||
b.Property<int>("Level")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("level");
|
||||
|
||||
b.HasKey("ParentId", "FolderId")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.HasIndex("FolderId")
|
||||
.HasDatabaseName("folder_id");
|
||||
|
||||
b.ToTable("files_folder_tree", (string)null);
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,216 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
{
|
||||
public partial class FilesDbContextPostgreSql_Upgrade1 : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "folder_type",
|
||||
table: "files_thirdparty_account",
|
||||
newName: "FolderType");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "FolderType",
|
||||
table: "files_thirdparty_account",
|
||||
type: "folder_type",
|
||||
nullable: false,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "int");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "folder_id",
|
||||
table: "files_thirdparty_account",
|
||||
type: "text",
|
||||
nullable: true,
|
||||
collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8");
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "root_folder_type",
|
||||
table: "files_thirdparty_account",
|
||||
type: "int",
|
||||
nullable: false,
|
||||
defaultValue: 0);
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "files_link",
|
||||
columns: table => new
|
||||
{
|
||||
tenant_id = table.Column<int>(type: "int", nullable: false),
|
||||
source_id = table.Column<string>(type: "varchar(32)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
linked_id = table.Column<string>(type: "varchar(32)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
linked_for = table.Column<string>(type: "char(38)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PRIMARY", x => new { x.tenant_id, x.source_id, x.linked_id });
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "tenants_quota",
|
||||
columns: table => new
|
||||
{
|
||||
tenant = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
name = table.Column<string>(type: "varchar(128)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
description = table.Column<string>(type: "varchar(128)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
max_file_size = table.Column<long>(type: "bigint", nullable: false),
|
||||
max_total_size = table.Column<long>(type: "bigint", nullable: false),
|
||||
active_users = table.Column<int>(type: "int", nullable: false),
|
||||
features = table.Column<string>(type: "text", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
price = table.Column<decimal>(type: "decimal(10,2)", nullable: false),
|
||||
avangate_id = table.Column<string>(type: "varchar(128)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
visible = table.Column<bool>(type: "tinyint(1)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PRIMARY", x => x.tenant);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "tenants_tariff",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
tenant = table.Column<int>(type: "int", nullable: false),
|
||||
tariff = table.Column<int>(type: "int", nullable: false),
|
||||
stamp = table.Column<DateTime>(type: "datetime", nullable: false),
|
||||
quantity = table.Column<int>(type: "int", nullable: false),
|
||||
comment = table.Column<string>(type: "varchar(255)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
create_on = table.Column<DateTime>(type: "timestamp", nullable: false, defaultValueSql: "CURRENT_TIMESTAMP")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_tenants_tariff", x => x.id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "tenants_tenants",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
name = table.Column<string>(type: "varchar(255)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
alias = table.Column<string>(type: "varchar(100)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
mappeddomain = table.Column<string>(type: "varchar(100)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
version = table.Column<int>(type: "int", nullable: false, defaultValueSql: "'2'"),
|
||||
version_changed = table.Column<DateTime>(type: "datetime", nullable: true),
|
||||
language = table.Column<string>(type: "char(10)", nullable: false, defaultValueSql: "'en-US'", collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
timezone = table.Column<string>(type: "varchar(50)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
trusteddomains = table.Column<string>(type: "varchar(1024)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
trusteddomainsenabled = table.Column<int>(type: "int", nullable: false, defaultValueSql: "'1'"),
|
||||
status = table.Column<int>(type: "int", nullable: false),
|
||||
statuschanged = table.Column<DateTime>(type: "datetime", nullable: true),
|
||||
creationdatetime = table.Column<DateTime>(type: "datetime", nullable: false),
|
||||
owner_id = table.Column<string>(type: "varchar(38)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
payment_id = table.Column<string>(type: "varchar(38)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
industry = table.Column<int>(type: "int", nullable: true),
|
||||
last_modified = table.Column<DateTime>(type: "timestamp", nullable: false, defaultValueSql: "CURRENT_TIMESTAMP"),
|
||||
spam = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValueSql: "true"),
|
||||
calls = table.Column<bool>(type: "tinyint(1)", nullable: false, defaultValueSql: "true")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_tenants_tenants", x => x.id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "tenants_quota",
|
||||
columns: new[] { "tenant", "active_users", "avangate_id", "description", "features", "max_file_size", "max_total_size", "name", "price", "visible" },
|
||||
values: new object[] { -1, 10000, "0", null, "domain,audit,controlpanel,healthcheck,ldap,sso,whitelabel,branding,ssbranding,update,support,portals:10000,discencryption,privacyroom,restore", 102400L, 10995116277760L, "default", 0.00m, false });
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "tenants_tenants",
|
||||
columns: new[] { "id", "alias", "creationdatetime", "industry", "mappeddomain", "name", "owner_id", "payment_id", "status", "statuschanged", "timezone", "trusteddomains", "version_changed" },
|
||||
values: new object[] { 1, "localhost", new DateTime(2021, 3, 9, 17, 46, 59, 97, DateTimeKind.Utc).AddTicks(4317), null, null, "Web Office", "66faa6e4-f133-11ea-b126-00ffeec8b4ef", null, 0, null, null, null, null });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "linked_for",
|
||||
table: "files_link",
|
||||
columns: new[] { "tenant_id", "source_id", "linked_id", "linked_for" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "tenant",
|
||||
table: "tenants_tariff",
|
||||
column: "tenant");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "last_modified",
|
||||
table: "tenants_tenants",
|
||||
column: "last_modified");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "mappeddomain",
|
||||
table: "tenants_tenants",
|
||||
column: "mappeddomain");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "version",
|
||||
table: "tenants_tenants",
|
||||
column: "version");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "files_link");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "tenants_quota");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "tenants_tariff");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "tenants_tenants");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "folder_id",
|
||||
table: "files_thirdparty_account");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "root_folder_type",
|
||||
table: "files_thirdparty_account");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "FolderType",
|
||||
table: "files_thirdparty_account",
|
||||
newName: "folder_type");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "folder_type",
|
||||
table: "files_thirdparty_account",
|
||||
type: "int",
|
||||
nullable: false,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "folder_type");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,11 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using ASC.Files.Core.EF;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
{
|
||||
@ -9,8 +16,263 @@ namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64)
|
||||
.HasAnnotation("ProductVersion", "5.0.10");
|
||||
.HasAnnotation("ProductVersion", "6.0.4")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.DbQuota", b =>
|
||||
{
|
||||
b.Property<int>("Tenant")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant");
|
||||
|
||||
b.Property<int>("ActiveUsers")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("active_users");
|
||||
|
||||
b.Property<string>("AvangateId")
|
||||
.HasColumnType("varchar(128)")
|
||||
.HasColumnName("avangate_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("varchar(128)")
|
||||
.HasColumnName("description")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Features")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("features")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<long>("MaxFileSize")
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("max_file_size");
|
||||
|
||||
b.Property<long>("MaxTotalSize")
|
||||
.HasColumnType("bigint")
|
||||
.HasColumnName("max_total_size");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("varchar(128)")
|
||||
.HasColumnName("name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<decimal>("Price")
|
||||
.HasColumnType("decimal(10,2)")
|
||||
.HasColumnName("price");
|
||||
|
||||
b.Property<bool>("Visible")
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("visible");
|
||||
|
||||
b.HasKey("Tenant")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.ToTable("tenants_quota", (string)null);
|
||||
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Tenant = -1,
|
||||
ActiveUsers = 10000,
|
||||
AvangateId = "0",
|
||||
Features = "domain,audit,controlpanel,healthcheck,ldap,sso,whitelabel,branding,ssbranding,update,support,portals:10000,discencryption,privacyroom,restore",
|
||||
MaxFileSize = 102400L,
|
||||
MaxTotalSize = 10995116277760L,
|
||||
Name = "default",
|
||||
Price = 0.00m,
|
||||
Visible = false
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.DbTariff", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<string>("Comment")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("comment")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("CreateOn")
|
||||
.ValueGeneratedOnAddOrUpdate()
|
||||
.HasColumnType("timestamp")
|
||||
.HasColumnName("create_on")
|
||||
.HasDefaultValueSql("CURRENT_TIMESTAMP");
|
||||
|
||||
b.Property<int>("Quantity")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("quantity");
|
||||
|
||||
b.Property<DateTime>("Stamp")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("stamp");
|
||||
|
||||
b.Property<int>("Tariff")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tariff");
|
||||
|
||||
b.Property<int>("Tenant")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("Tenant")
|
||||
.HasDatabaseName("tenant");
|
||||
|
||||
b.ToTable("tenants_tariff", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbTenant", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<string>("Alias")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(100)")
|
||||
.HasColumnName("alias")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<bool>("Calls")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("calls")
|
||||
.HasDefaultValueSql("true");
|
||||
|
||||
b.Property<DateTime>("CreationDateTime")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("creationdatetime");
|
||||
|
||||
b.Property<int?>("Industry")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("industry");
|
||||
|
||||
b.Property<string>("Language")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("char(10)")
|
||||
.HasColumnName("language")
|
||||
.HasDefaultValueSql("'en-US'")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("LastModified")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("timestamp")
|
||||
.HasColumnName("last_modified")
|
||||
.HasDefaultValueSql("CURRENT_TIMESTAMP");
|
||||
|
||||
b.Property<string>("MappedDomain")
|
||||
.HasColumnType("varchar(100)")
|
||||
.HasColumnName("mappeddomain")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("OwnerId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(38)")
|
||||
.HasColumnName("owner_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("PaymentId")
|
||||
.HasColumnType("varchar(38)")
|
||||
.HasColumnName("payment_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<bool>("Spam")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("spam")
|
||||
.HasDefaultValueSql("true");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("status");
|
||||
|
||||
b.Property<DateTime?>("StatusChanged")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("statuschanged");
|
||||
|
||||
b.Property<string>("TimeZone")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("timezone")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("TrustedDomainsEnabled")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("trusteddomainsenabled")
|
||||
.HasDefaultValueSql("'1'");
|
||||
|
||||
b.Property<string>("TrustedDomainsRaw")
|
||||
.HasColumnType("varchar(1024)")
|
||||
.HasColumnName("trusteddomains")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("Version")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("version")
|
||||
.HasDefaultValueSql("'2'");
|
||||
|
||||
b.Property<DateTime?>("Version_Changed")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("version_changed");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("LastModified")
|
||||
.HasDatabaseName("last_modified");
|
||||
|
||||
b.HasIndex("MappedDomain")
|
||||
.HasDatabaseName("mappeddomain");
|
||||
|
||||
b.HasIndex("Version")
|
||||
.HasDatabaseName("version");
|
||||
|
||||
b.ToTable("tenants_tenants", (string)null);
|
||||
|
||||
b.HasData(
|
||||
new
|
||||
{
|
||||
Id = 1,
|
||||
Alias = "localhost",
|
||||
Calls = false,
|
||||
CreationDateTime = new DateTime(2021, 3, 9, 17, 46, 59, 97, DateTimeKind.Utc).AddTicks(4317),
|
||||
LastModified = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
|
||||
Name = "Web Office",
|
||||
OwnerId = "66faa6e4-f133-11ea-b126-00ffeec8b4ef",
|
||||
Spam = false,
|
||||
Status = 0,
|
||||
TrustedDomainsEnabled = 0,
|
||||
Version = 0
|
||||
});
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFile", b =>
|
||||
{
|
||||
@ -75,10 +337,6 @@ namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("file_status");
|
||||
|
||||
b.Property<int>("FolderId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("folder_id");
|
||||
|
||||
b.Property<int>("Forcesave")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("forcesave");
|
||||
@ -94,7 +352,11 @@ namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("modified_on");
|
||||
|
||||
b.Property<int>("Thumb")
|
||||
b.Property<int>("ParentId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("folder_id");
|
||||
|
||||
b.Property<int>("ThumbnailStatus")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("thumb");
|
||||
|
||||
@ -114,16 +376,16 @@ namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
b.HasKey("TenantId", "Id", "Version")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.HasIndex("FolderId")
|
||||
.HasDatabaseName("folder_id");
|
||||
|
||||
b.HasIndex("Id")
|
||||
.HasDatabaseName("id");
|
||||
|
||||
b.HasIndex("ModifiedOn")
|
||||
.HasDatabaseName("modified_on");
|
||||
|
||||
b.ToTable("files_file");
|
||||
b.HasIndex("ParentId")
|
||||
.HasDatabaseName("folder_id");
|
||||
|
||||
b.ToTable("files_file", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesBunchObjects", b =>
|
||||
@ -151,7 +413,41 @@ namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
b.HasIndex("LeftNode")
|
||||
.HasDatabaseName("left_node");
|
||||
|
||||
b.ToTable("files_bunch_objects");
|
||||
b.ToTable("files_bunch_objects", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesLink", b =>
|
||||
{
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("SourceId")
|
||||
.HasColumnType("varchar(32)")
|
||||
.HasColumnName("source_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("LinkedId")
|
||||
.HasColumnType("varchar(32)")
|
||||
.HasColumnName("linked_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("LinkedFor")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("linked_for")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.HasKey("TenantId", "SourceId", "LinkedId")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.HasIndex("TenantId", "SourceId", "LinkedId", "LinkedFor")
|
||||
.HasDatabaseName("linked_for");
|
||||
|
||||
b.ToTable("files_link", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesSecurity", b =>
|
||||
@ -183,7 +479,7 @@ namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("Security")
|
||||
b.Property<int>("Share")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("security");
|
||||
|
||||
@ -202,7 +498,7 @@ namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
b.HasIndex("TenantId", "EntryType", "EntryId", "Owner")
|
||||
.HasDatabaseName("tenant_id");
|
||||
|
||||
b.ToTable("files_security");
|
||||
b.ToTable("files_security", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesTag", b =>
|
||||
@ -212,10 +508,6 @@ namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<int>("Flag")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("flag");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(255)")
|
||||
@ -234,12 +526,16 @@ namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("flag");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("TenantId", "Owner", "Name", "Flag")
|
||||
b.HasIndex("TenantId", "Owner", "Name", "Type")
|
||||
.HasDatabaseName("name");
|
||||
|
||||
b.ToTable("files_tag");
|
||||
b.ToTable("files_tag", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesTagLink", b =>
|
||||
@ -262,6 +558,10 @@ namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("entry_type");
|
||||
|
||||
b.Property<int>("Count")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tag_count");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("create_by")
|
||||
@ -272,10 +572,6 @@ namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("create_on");
|
||||
|
||||
b.Property<int>("TagCount")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tag_count");
|
||||
|
||||
b.HasKey("TenantId", "TagId", "EntryId", "EntryType")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
@ -285,7 +581,7 @@ namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
b.HasIndex("TenantId", "EntryId", "EntryType")
|
||||
.HasDatabaseName("entry_id");
|
||||
|
||||
b.ToTable("files_tag_link");
|
||||
b.ToTable("files_tag_link", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesThirdpartyAccount", b =>
|
||||
@ -299,9 +595,14 @@ namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("create_on");
|
||||
|
||||
b.Property<string>("FolderId")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("folder_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("FolderType")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("folder_type");
|
||||
.HasColumnType("folder_type");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
@ -319,6 +620,10 @@ namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("RootFolderType")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("root_folder_type");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
@ -358,7 +663,7 @@ namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("files_thirdparty_account");
|
||||
b.ToTable("files_thirdparty_account", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesThirdpartyApp", b =>
|
||||
@ -394,7 +699,7 @@ namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
b.HasKey("UserId", "App")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.ToTable("files_thirdparty_app");
|
||||
b.ToTable("files_thirdparty_app", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFilesThirdpartyIdMapping", b =>
|
||||
@ -422,7 +727,7 @@ namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
b.HasIndex("TenantId", "HashId")
|
||||
.HasDatabaseName("index_1");
|
||||
|
||||
b.ToTable("files_thirdparty_id_mapping");
|
||||
b.ToTable("files_thirdparty_id_mapping", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFolder", b =>
|
||||
@ -489,7 +794,7 @@ namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
b.HasIndex("TenantId", "ParentId")
|
||||
.HasDatabaseName("parent_id");
|
||||
|
||||
b.ToTable("files_folder");
|
||||
b.ToTable("files_folder", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Files.Core.EF.DbFolderTree", b =>
|
||||
@ -512,7 +817,7 @@ namespace ASC.Files.Core.Migrations.PostgreSql.FilesDbContextPostgreSql
|
||||
b.HasIndex("FolderId")
|
||||
.HasDatabaseName("folder_id");
|
||||
|
||||
b.ToTable("files_folder_tree");
|
||||
b.ToTable("files_folder_tree", (string)null);
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
|
@ -789,6 +789,33 @@ namespace ASC.Files.Core.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to You don't have enough permission to archive the room.
|
||||
/// </summary>
|
||||
public static string ErrorMessage_ArchiveRoom {
|
||||
get {
|
||||
return ResourceManager.GetString("ErrorMessage_ArchiveRoom", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to You don't have enough permission to archive the room.
|
||||
/// </summary>
|
||||
public static string ErrorMessage_UnarchiveRoom {
|
||||
get {
|
||||
return ResourceManager.GetString("ErrorMessage_UnarchiveRoom", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to You cannot edit archived rooms.
|
||||
/// </summary>
|
||||
public static string ErrorMessage_UpdateArchivedRoom {
|
||||
get {
|
||||
return ResourceManager.GetString("ErrorMessage_UpdateArchivedRoom", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Everyone.
|
||||
/// </summary>
|
||||
|
@ -301,6 +301,15 @@
|
||||
<data name="ErrorMassage_ViewTrashItem" xml:space="preserve">
|
||||
<value>You are not allowed to preview the elements in the Trash</value>
|
||||
</data>
|
||||
<data name="ErrorMessage_ArchiveRoom" xml:space="preserve">
|
||||
<value>You don't have enough permission to archive the room</value>
|
||||
</data>
|
||||
<data name="ErrorMessage_UnarchiveRoom" xml:space="preserve">
|
||||
<value>You don't have enough permission to archive the room</value>
|
||||
</data>
|
||||
<data name="ErrorMessage_UpdateArchivedRoom" xml:space="preserve">
|
||||
<value>You cannot edit archived rooms</value>
|
||||
</data>
|
||||
<data name="Everyone" xml:space="preserve">
|
||||
<value>Everyone</value>
|
||||
</data>
|
||||
|
@ -60,6 +60,15 @@ namespace ASC.Files.Core.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Archive.
|
||||
/// </summary>
|
||||
public static string Archive {
|
||||
get {
|
||||
return ResourceManager.GetString("Archive", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Common.
|
||||
/// </summary>
|
||||
@ -149,5 +158,14 @@ namespace ASC.Files.Core.Resources {
|
||||
return ResourceManager.GetString("Trash", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to VirtualRooms.
|
||||
/// </summary>
|
||||
public static string VirtualRooms {
|
||||
get {
|
||||
return ResourceManager.GetString("VirtualRooms", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,64 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
@ -58,6 +117,9 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=6.0.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Archive" xml:space="preserve">
|
||||
<value>Archive</value>
|
||||
</data>
|
||||
<data name="CorporateFiles" xml:space="preserve">
|
||||
<value>Common</value>
|
||||
</data>
|
||||
@ -88,4 +150,7 @@
|
||||
<data name="Trash" xml:space="preserve">
|
||||
<value>Trash</value>
|
||||
</data>
|
||||
<data name="VirtualRooms" xml:space="preserve">
|
||||
<value>VirtualRooms</value>
|
||||
</data>
|
||||
</root>
|
@ -355,9 +355,11 @@ public class DocumentServiceHelper
|
||||
return null;
|
||||
}
|
||||
|
||||
#pragma warning disable CS0618 // Type or member is obsolete
|
||||
var encoder = new JwtEncoder(new HMACSHA256Algorithm(),
|
||||
new JwtSerializer(),
|
||||
new JwtBase64UrlEncoder());
|
||||
#pragma warning restore CS0618 // Type or member is obsolete
|
||||
|
||||
|
||||
return encoder.Encode(payload, _fileUtility.SignatureSecret);
|
||||
|
@ -113,18 +113,23 @@ class FileDeleteOperation<T> : FileOperation<FileDeleteOperationData<T>, T>
|
||||
private async Task DeleteFoldersAsync(IEnumerable<T> folderIds, IServiceScope scope, bool isNeedSendActions = false)
|
||||
{
|
||||
var scopeClass = scope.ServiceProvider.GetService<FileDeleteOperationScope>();
|
||||
var (fileMarker, filesMessageService) = scopeClass;
|
||||
var (fileMarker, filesMessageService, roomLogoManager) = scopeClass;
|
||||
foreach (var folderId in folderIds)
|
||||
{
|
||||
CancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var folder = await FolderDao.GetFolderAsync(folderId);
|
||||
var isRoom = DocSpaceHelper.IsRoom(folder.FolderType);
|
||||
|
||||
T canCalculate = default;
|
||||
if (folder == null)
|
||||
{
|
||||
Error = FilesCommonResource.ErrorMassage_FolderNotFound;
|
||||
}
|
||||
else if (folder.FolderType != FolderType.DEFAULT && folder.FolderType != FolderType.BUNCH)
|
||||
else if (folder.FolderType != FolderType.DEFAULT && folder.FolderType != FolderType.BUNCH
|
||||
&& folder.FolderType != FolderType.FillingFormsRoom && folder.FolderType != FolderType.EditingRoom
|
||||
&& folder.FolderType != FolderType.ReviewRoom && folder.FolderType != FolderType.ReadOnlyRoom
|
||||
&& folder.FolderType != FolderType.CustomRoom)
|
||||
{
|
||||
Error = FilesCommonResource.ErrorMassage_SecurityException_DeleteFolder;
|
||||
}
|
||||
@ -143,6 +148,16 @@ class FileDeleteOperation<T> : FileOperation<FileDeleteOperationData<T>, T>
|
||||
{
|
||||
if (ProviderDao != null)
|
||||
{
|
||||
if (folder.RootFolderType == FolderType.VirtualRooms || folder.RootFolderType == FolderType.Archive)
|
||||
{
|
||||
var providerInfo = await ProviderDao.GetProviderInfoAsync(folder.ProviderId);
|
||||
|
||||
if (providerInfo.FolderId != null)
|
||||
{
|
||||
await roomLogoManager.DeleteAsync(providerInfo.FolderId);
|
||||
}
|
||||
}
|
||||
|
||||
await ProviderDao.RemoveProviderInfoAsync(folder.ProviderId);
|
||||
if (isNeedSendActions)
|
||||
{
|
||||
@ -165,8 +180,26 @@ class FileDeleteOperation<T> : FileOperation<FileDeleteOperationData<T>, T>
|
||||
|
||||
if (await FolderDao.IsEmptyAsync(folder.Id))
|
||||
{
|
||||
if (isRoom)
|
||||
{
|
||||
await roomLogoManager.DeleteAsync(folder.Id);
|
||||
}
|
||||
|
||||
await FolderDao.DeleteFolderAsync(folder.Id);
|
||||
filesMessageService.Send(folder, _headers, MessageAction.FolderDeleted, folder.Title);
|
||||
|
||||
if (isRoom)
|
||||
{
|
||||
if (folder.ProviderEntry)
|
||||
{
|
||||
await ProviderDao.UpdateProviderInfoAsync(folder.ProviderId, null, FolderType.DEFAULT);
|
||||
}
|
||||
|
||||
filesMessageService.Send(folder, _headers, MessageAction.RoomDeleted, folder.Title);
|
||||
}
|
||||
else
|
||||
{
|
||||
filesMessageService.Send(folder, _headers, MessageAction.FolderDeleted, folder.Title);
|
||||
}
|
||||
|
||||
ProcessedFolder(folderId);
|
||||
}
|
||||
@ -184,9 +217,18 @@ class FileDeleteOperation<T> : FileOperation<FileDeleteOperationData<T>, T>
|
||||
if (immediately)
|
||||
{
|
||||
await FolderDao.DeleteFolderAsync(folder.Id);
|
||||
|
||||
if (isNeedSendActions)
|
||||
{
|
||||
filesMessageService.Send(folder, _headers, MessageAction.FolderDeleted, folder.Title);
|
||||
if (isRoom)
|
||||
{
|
||||
await roomLogoManager.DeleteAsync(folder.Id);
|
||||
filesMessageService.Send(folder, _headers, MessageAction.RoomDeleted, folder.Title);
|
||||
}
|
||||
else
|
||||
{
|
||||
filesMessageService.Send(folder, _headers, MessageAction.FolderDeleted, folder.Title);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -212,7 +254,7 @@ class FileDeleteOperation<T> : FileOperation<FileDeleteOperationData<T>, T>
|
||||
var scopeClass = scope.ServiceProvider.GetService<FileDeleteOperationScope>();
|
||||
var socketManager = scope.ServiceProvider.GetService<SocketManager>();
|
||||
|
||||
var (fileMarker, filesMessageService) = scopeClass;
|
||||
var (fileMarker, filesMessageService, _) = scopeClass;
|
||||
foreach (var fileId in fileIds)
|
||||
{
|
||||
CancellationToken.ThrowIfCancellationRequested();
|
||||
@ -245,7 +287,7 @@ class FileDeleteOperation<T> : FileOperation<FileDeleteOperationData<T>, T>
|
||||
{
|
||||
await FileDao.SaveThumbnailAsync(file, null, size.Width, size.Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
socketManager.DeleteFile(file);
|
||||
}
|
||||
@ -322,16 +364,20 @@ public class FileDeleteOperationScope
|
||||
{
|
||||
private readonly FileMarker _fileMarker;
|
||||
private readonly FilesMessageService _filesMessageService;
|
||||
private readonly RoomLogoManager _roomLogoManager;
|
||||
|
||||
public FileDeleteOperationScope(FileMarker fileMarker, FilesMessageService filesMessageService)
|
||||
public FileDeleteOperationScope(FileMarker fileMarker, FilesMessageService filesMessageService, RoomLogoManager roomLogoManager)
|
||||
{
|
||||
_fileMarker = fileMarker;
|
||||
_filesMessageService = filesMessageService;
|
||||
_roomLogoManager = roomLogoManager;
|
||||
_roomLogoManager.EnableAudit = false;
|
||||
}
|
||||
|
||||
public void Deconstruct(out FileMarker fileMarker, out FilesMessageService filesMessageService)
|
||||
public void Deconstruct(out FileMarker fileMarker, out FilesMessageService filesMessageService, out RoomLogoManager roomLogoManager)
|
||||
{
|
||||
fileMarker = _fileMarker;
|
||||
filesMessageService = _filesMessageService;
|
||||
roomLogoManager = _roomLogoManager;
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ class FileDownloadOperation<T> : FileOperation<FileDownloadOperationData<T>, T>
|
||||
{
|
||||
private readonly Dictionary<T, string> _files;
|
||||
private readonly IDictionary<string, StringValues> _headers;
|
||||
private readonly ItemNameValueCollection<T> _entriesPathId;
|
||||
private ItemNameValueCollection<T> _entriesPathId;
|
||||
public override FileOperationType OperationType => FileOperationType.Download;
|
||||
|
||||
public FileDownloadOperation(IServiceProvider serviceProvider, FileDownloadOperationData<T> fileDownloadOperationData)
|
||||
@ -181,7 +181,7 @@ class FileDownloadOperation<T> : FileOperation<FileDownloadOperationData<T>, T>
|
||||
return;
|
||||
}
|
||||
|
||||
var (entriesPathId, filesForSend, folderForSend) = await GetEntriesPathIdAsync(scope);
|
||||
(_entriesPathId, var filesForSend, var folderForSend) = await GetEntriesPathIdAsync(scope);
|
||||
|
||||
if (_entriesPathId == null || _entriesPathId.Count == 0)
|
||||
{
|
||||
@ -193,7 +193,7 @@ class FileDownloadOperation<T> : FileOperation<FileDownloadOperationData<T>, T>
|
||||
throw new DirectoryNotFoundException(FilesCommonResource.ErrorMassage_FolderNotFound);
|
||||
}
|
||||
|
||||
Total = entriesPathId.Count + 1;
|
||||
Total = _entriesPathId.Count + 1;
|
||||
|
||||
ReplaceLongPath(_entriesPathId);
|
||||
|
||||
|
@ -106,6 +106,7 @@ class FileMarkAsReadOperation<T> : FileOperation<FileMarkAsReadOperationData<T>,
|
||||
await globalFolder.GetFolderCommonAsync(fileMarker, daoFactory),
|
||||
await globalFolder.GetFolderShareAsync(daoFactory),
|
||||
await globalFolder.GetFolderProjectsAsync(daoFactory),
|
||||
await globalFolder.GetFolderVirtualRoomsAsync(daoFactory),
|
||||
};
|
||||
|
||||
if (PrivacyRoomSettings.GetEnabled(settingsManager))
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user