Merge branch 'develop' of github.com:ONLYOFFICE/AppServer into develop
This commit is contained in:
commit
ff3279acf7
@ -68,13 +68,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Data.Storage.Encryption
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.TelegramService", "common\services\ASC.TelegramService\ASC.TelegramService.csproj", "{95CE7371-17B6-4EEE-8E38-2FDE6347E955}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ASC.AuditTrail", "common\services\ASC.AuditTrail\ASC.AuditTrail.csproj", "{2C111161-B7C5-4869-9F52-EA725E64BA40}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.AuditTrail", "common\services\ASC.AuditTrail\ASC.AuditTrail.csproj", "{2C111161-B7C5-4869-9F52-EA725E64BA40}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0E35EB77-EC53-44C2-99EB-3D845C79675D}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.editorconfig = .editorconfig
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ASC.Data.Encryption", "common\ASC.Data.Encryption\ASC.Data.Encryption.csproj", "{C4DF1A63-C9EB-4D8F-A4E5-4FD9249A5089}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -209,6 +211,10 @@ Global
|
||||
{2C111161-B7C5-4869-9F52-EA725E64BA40}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2C111161-B7C5-4869-9F52-EA725E64BA40}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2C111161-B7C5-4869-9F52-EA725E64BA40}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C4DF1A63-C9EB-4D8F-A4E5-4FD9249A5089}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C4DF1A63-C9EB-4D8F-A4E5-4FD9249A5089}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C4DF1A63-C9EB-4D8F-A4E5-4FD9249A5089}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C4DF1A63-C9EB-4D8F-A4E5-4FD9249A5089}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -6,7 +6,7 @@ ARG RELEASE_DATE_SIGN=""
|
||||
ARG VERSION="8.9.0.190"
|
||||
ARG SOURCE_REPO_URL="deb http://static.teamlab.com.s3.amazonaws.com/repo/debian squeeze main"
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG GIT_BRANCH="develop"
|
||||
ARG GIT_BRANCH="master"
|
||||
|
||||
LABEL onlyoffice.community.release-date="${RELEASE_DATE}" \
|
||||
onlyoffice.community.version="${VERSION}" \
|
||||
@ -40,9 +40,7 @@ RUN echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null && \
|
||||
dotnet-sdk-3.1
|
||||
|
||||
RUN echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null && \
|
||||
git clone https://github.com/ONLYOFFICE/AppServer.git /app/onlyoffice/src/ && \
|
||||
cd /app/onlyoffice/src/ && \
|
||||
git checkout ${GIT_BRANCH}
|
||||
git clone --depth 1 -b ${GIT_BRANCH} https://github.com/ONLYOFFICE/AppServer.git /app/onlyoffice/src/
|
||||
|
||||
RUN echo "nameserver 8.8.8.8" | tee /etc/resolv.conf > /dev/null && \
|
||||
cd /app/onlyoffice/src/ && \
|
||||
|
@ -1,2 +1,3 @@
|
||||
#!/bin/bash
|
||||
export SRV_VERSION=$DOCKER_TAG
|
||||
docker-compose -f build.yml build
|
||||
|
@ -1,3 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
export SRV_VERSION=$DOCKER_TAG
|
||||
docker-compose -f build.yml push
|
||||
|
@ -32,6 +32,7 @@
|
||||
<None Remove="protos\ConsumerCacheItem.proto" />
|
||||
<None Remove="protos\CreateClientProto.proto" />
|
||||
<None Remove="protos\DisableClientProto.proto" />
|
||||
<None Remove="protos\EncryptionSettingsProto.proto" />
|
||||
<None Remove="protos\GroupCacheItem.proto" />
|
||||
<None Remove="protos\NotifyInvoke.proto" />
|
||||
<None Remove="protos\NotifyMessage.proto" />
|
||||
@ -65,6 +66,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Protobuf Include="protos\CreateClientProto.proto" />
|
||||
<Protobuf Include="protos\EncryptionSettingsProto.proto" />
|
||||
<Protobuf Include="protos\NotifyInvoke.proto" />
|
||||
<Protobuf Include="protos\NotifyMessage.proto" />
|
||||
<Protobuf Include="protos\DisableClientProto.proto" />
|
||||
|
@ -227,8 +227,8 @@ namespace ASC.Core.Billing
|
||||
Support = true,
|
||||
Trial = license.Trial,
|
||||
CountPortals = license.PortalCount,
|
||||
DiscEncryption = license.DiscEncryption ?? !license.Trial,
|
||||
PrivacyRoom = !license.Trial,
|
||||
DiscEncryption = true,
|
||||
PrivacyRoom = true,
|
||||
};
|
||||
|
||||
if (defaultQuota.Name != "overdue" && !defaultQuota.Trial)
|
||||
@ -236,7 +236,6 @@ namespace ASC.Core.Billing
|
||||
quota.WhiteLabel |= defaultQuota.WhiteLabel;
|
||||
quota.Branding |= defaultQuota.Branding;
|
||||
quota.SSBranding |= defaultQuota.SSBranding;
|
||||
quota.DiscEncryption |= defaultQuota.DiscEncryption;
|
||||
|
||||
quota.CountPortals = Math.Max(defaultQuota.CountPortals, quota.CountPortals);
|
||||
}
|
||||
|
@ -63,18 +63,18 @@ namespace ASC.Core.Caching
|
||||
|
||||
CacheNotify = cacheNotify;
|
||||
Cache = AscCache.Memory;
|
||||
Interval = new TrustInterval();
|
||||
|
||||
cacheNotify.Subscribe((i) =>
|
||||
{
|
||||
if (i.Key == KEY_QUOTA_ROWS)
|
||||
{
|
||||
Interval.Expire();
|
||||
}
|
||||
else if (i.Key == KEY_QUOTA)
|
||||
{
|
||||
Cache.Remove(KEY_QUOTA);
|
||||
}
|
||||
Interval = new TrustInterval();
|
||||
|
||||
cacheNotify.Subscribe((i) =>
|
||||
{
|
||||
if (i.Key == KEY_QUOTA)
|
||||
{
|
||||
Cache.Remove(KEY_QUOTA);
|
||||
}
|
||||
else
|
||||
{
|
||||
Cache.Remove(i.Key);
|
||||
}
|
||||
}, CacheNotifyAction.Any);
|
||||
}
|
||||
}
|
||||
@ -167,76 +167,27 @@ namespace ASC.Core.Caching
|
||||
|
||||
public void SetTenantQuotaRow(TenantQuotaRow row, bool exchange)
|
||||
{
|
||||
Service.SetTenantQuotaRow(row, exchange);
|
||||
CacheNotify.Publish(new QuotaCacheItem { Key = QuotaServiceCache.KEY_QUOTA_ROWS }, CacheNotifyAction.Any);
|
||||
Service.SetTenantQuotaRow(row, exchange);
|
||||
CacheNotify.Publish(new QuotaCacheItem { Key = GetKey(row.Tenant) }, CacheNotifyAction.InsertOrUpdate);
|
||||
}
|
||||
|
||||
public IEnumerable<TenantQuotaRow> FindTenantQuotaRows(TenantQuotaRowQuery query)
|
||||
public IEnumerable<TenantQuotaRow> FindTenantQuotaRows(int tenantId)
|
||||
{
|
||||
if (query == null) throw new ArgumentNullException("query");
|
||||
|
||||
var rows = Cache.Get<Dictionary<string, List<TenantQuotaRow>>>(QuotaServiceCache.KEY_QUOTA_ROWS);
|
||||
if (rows == null || Interval.Expired)
|
||||
{
|
||||
var date = rows != null ? Interval.StartTime : DateTime.MinValue;
|
||||
Interval.Start(CacheExpiration);
|
||||
|
||||
var changes = Service.FindTenantQuotaRows(new TenantQuotaRowQuery(Tenant.DEFAULT_TENANT).WithLastModified(date))
|
||||
.GroupBy(r => r.Tenant.ToString())
|
||||
.ToDictionary(g => g.Key, g => g.ToList());
|
||||
|
||||
// merge changes from db to cache
|
||||
if (rows == null)
|
||||
{
|
||||
rows = changes;
|
||||
}
|
||||
else
|
||||
{
|
||||
lock (rows)
|
||||
{
|
||||
foreach (var p in changes)
|
||||
{
|
||||
if (rows.ContainsKey(p.Key))
|
||||
{
|
||||
var cachedRows = rows[p.Key];
|
||||
foreach (var r in p.Value)
|
||||
{
|
||||
cachedRows.RemoveAll(c => c.Path == r.Path);
|
||||
cachedRows.Add(r);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rows[p.Key] = p.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (QuotaServiceCache.QuotaCacheEnabled)
|
||||
{
|
||||
Cache.Insert(QuotaServiceCache.KEY_QUOTA_ROWS, rows, DateTime.UtcNow.Add(CacheExpiration));
|
||||
}
|
||||
}
|
||||
|
||||
var quotaRows = Cache.Get<Dictionary<string, List<TenantQuotaRow>>>(QuotaServiceCache.KEY_QUOTA_ROWS);
|
||||
if (quotaRows == null)
|
||||
{
|
||||
return Enumerable.Empty<TenantQuotaRow>();
|
||||
}
|
||||
|
||||
lock (quotaRows)
|
||||
{
|
||||
var list = quotaRows.ContainsKey(query.Tenant.ToString()) ?
|
||||
quotaRows[query.Tenant.ToString()] :
|
||||
new List<TenantQuotaRow>();
|
||||
|
||||
if (query != null && !string.IsNullOrEmpty(query.Path))
|
||||
{
|
||||
return list.Where(r => query.Path == r.Path);
|
||||
}
|
||||
return list.ToList();
|
||||
}
|
||||
var key = GetKey(tenantId);
|
||||
var result = Cache.Get<IEnumerable<TenantQuotaRow>>(key);
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
result = Service.FindTenantQuotaRows(tenantId);
|
||||
Cache.Insert(key, result, DateTime.UtcNow.Add(CacheExpiration));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public string GetKey(int tenant)
|
||||
{
|
||||
return QuotaServiceCache.KEY_QUOTA_ROWS + tenant;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -140,6 +140,16 @@ namespace ASC.Core.Caching
|
||||
}
|
||||
}
|
||||
|
||||
public string[] GetRecipients(int tenant, string sourceID, string actionID, string objectID)
|
||||
{
|
||||
return service.GetRecipients(tenant, sourceID, actionID, objectID);
|
||||
}
|
||||
|
||||
public string[] GetSubscriptions(int tenant, string sourceId, string actionId, string recipientId, bool checkSubscribe)
|
||||
{
|
||||
return service.GetSubscriptions(tenant, sourceId, actionId, recipientId, checkSubscribe);
|
||||
}
|
||||
|
||||
public SubscriptionRecord GetSubscription(int tenant, string sourceId, string actionId, string recipientId, string objectId)
|
||||
{
|
||||
var store = GetSubsciptionsStore(tenant, sourceId, actionId);
|
||||
@ -195,7 +205,12 @@ namespace ASC.Core.Caching
|
||||
}
|
||||
return store;
|
||||
}
|
||||
public bool IsUnsubscribe(int tenant, string sourceId, string actionId, string recipientId, string objectId)
|
||||
{
|
||||
return service.IsUnsubscribe(tenant, sourceId, actionId, recipientId, objectId);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SubsciptionsStore
|
||||
{
|
||||
private readonly List<SubscriptionRecord> records;
|
||||
|
@ -257,7 +257,13 @@ namespace ASC.Core.Caching
|
||||
users.TryGetValue(id, out var u);
|
||||
return u;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public UserInfo GetUser(int tenant, string email)
|
||||
{
|
||||
return Service.GetUser(tenant, email);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// For Personal only
|
||||
|
@ -176,7 +176,7 @@ namespace ASC.Core.Common.Configuration
|
||||
{
|
||||
if (!CanSet)
|
||||
{
|
||||
throw new NotSupportedException("Key for read only.");
|
||||
throw new NotSupportedException("Key for read only. Consumer " + Name);
|
||||
}
|
||||
|
||||
foreach (var providerProp in Props)
|
||||
@ -258,7 +258,7 @@ namespace ASC.Core.Common.Configuration
|
||||
{
|
||||
if (!CanSet)
|
||||
{
|
||||
throw new NotSupportedException("Key for read only.");
|
||||
throw new NotSupportedException("Key for read only. Key " + name);
|
||||
}
|
||||
|
||||
if (!ManagedKeys.Contains(name))
|
||||
|
@ -107,7 +107,7 @@ namespace ASC.Core.Configuration
|
||||
{
|
||||
throw new ArgumentException("Empty user name.", "userName");
|
||||
}
|
||||
if (string.IsNullOrEmpty("password"))
|
||||
if (string.IsNullOrEmpty(password))
|
||||
{
|
||||
throw new ArgumentException("Empty password.", "password");
|
||||
}
|
||||
|
@ -25,10 +25,13 @@
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using ASC.Common;
|
||||
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Common.Security.Authorizing;
|
||||
|
||||
namespace ASC.Core
|
||||
{
|
||||
[Scope]
|
||||
@ -36,12 +39,28 @@ namespace ASC.Core
|
||||
{
|
||||
private readonly ISubscriptionService service;
|
||||
|
||||
private TenantManager TenantManager { get; }
|
||||
private TenantManager TenantManager { get; }
|
||||
|
||||
private ICache Cache { get; set; }
|
||||
public static readonly object CacheLocker;
|
||||
public static readonly List<Guid> Groups;
|
||||
|
||||
static SubscriptionManager()
|
||||
{
|
||||
CacheLocker = new object();
|
||||
Groups = new List<Guid>
|
||||
{
|
||||
Constants.Admin.ID,
|
||||
Constants.Everyone.ID,
|
||||
Constants.User.ID
|
||||
};
|
||||
}
|
||||
|
||||
public SubscriptionManager(ISubscriptionService service, TenantManager tenantManager)
|
||||
{
|
||||
this.service = service ?? throw new ArgumentNullException("subscriptionManager");
|
||||
TenantManager = tenantManager;
|
||||
TenantManager = tenantManager;
|
||||
Cache = AscCache.Memory;
|
||||
}
|
||||
|
||||
|
||||
@ -85,25 +104,31 @@ namespace ASC.Core
|
||||
|
||||
public string[] GetSubscriptionMethod(string sourceID, string actionID, string recipientID)
|
||||
{
|
||||
var m = service.GetSubscriptionMethods(GetTenant(), sourceID, actionID, recipientID)
|
||||
.FirstOrDefault(x => x.ActionId.Equals(actionID, StringComparison.OrdinalIgnoreCase));
|
||||
if (m == null)
|
||||
{
|
||||
m = service.GetSubscriptionMethods(GetTenant(), sourceID, actionID, recipientID).FirstOrDefault();
|
||||
}
|
||||
if (m == null)
|
||||
{
|
||||
m = service.GetSubscriptionMethods(GetTenant(), sourceID, actionID, Guid.Empty.ToString()).FirstOrDefault();
|
||||
}
|
||||
IEnumerable<SubscriptionMethod> methods;
|
||||
|
||||
if (Groups.Any(r => r.ToString() == recipientID))
|
||||
{
|
||||
methods = GetDefaultSubscriptionMethodsFromCache(sourceID, actionID, recipientID);
|
||||
}
|
||||
else
|
||||
{
|
||||
methods = service.GetSubscriptionMethods(GetTenant(), sourceID, actionID, recipientID);
|
||||
}
|
||||
|
||||
var m = methods
|
||||
.FirstOrDefault(x => x.ActionId.Equals(actionID, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (m == null)
|
||||
{
|
||||
m = methods.FirstOrDefault();
|
||||
}
|
||||
|
||||
return m != null ? m.Methods : new string[0];
|
||||
}
|
||||
|
||||
public string[] GetRecipients(string sourceID, string actionID, string objectID)
|
||||
{
|
||||
return service.GetSubscriptions(GetTenant(), sourceID, actionID, null, objectID)
|
||||
.Where(s => s.Subscribed)
|
||||
.Select(s => s.RecipientId)
|
||||
.ToArray();
|
||||
{
|
||||
return service.GetRecipients(GetTenant(), sourceID, actionID, objectID);
|
||||
}
|
||||
|
||||
public object GetSubscriptionRecord(string sourceID, string actionID, string recipientID, string objectID)
|
||||
@ -112,21 +137,13 @@ namespace ASC.Core
|
||||
}
|
||||
|
||||
public string[] GetSubscriptions(string sourceID, string actionID, string recipientID, bool checkSubscribe = true)
|
||||
{
|
||||
return service.GetSubscriptions(GetTenant(), sourceID, actionID, recipientID, null)
|
||||
.Where(s => !checkSubscribe || s.Subscribed)
|
||||
.Select(s => s.ObjectId)
|
||||
.ToArray();
|
||||
{
|
||||
return service.GetSubscriptions(GetTenant(), sourceID, actionID, recipientID, checkSubscribe);
|
||||
}
|
||||
|
||||
public bool IsUnsubscribe(string sourceID, string recipientID, string actionID, string objectID)
|
||||
{
|
||||
var s = service.GetSubscription(GetTenant(), sourceID, actionID, recipientID, objectID);
|
||||
if (s == null && !string.IsNullOrEmpty(objectID))
|
||||
{
|
||||
s = service.GetSubscription(GetTenant(), sourceID, actionID, recipientID, null);
|
||||
}
|
||||
return s != null && !s.Subscribed;
|
||||
{
|
||||
return service.IsUnsubscribe(GetTenant(), sourceID, actionID, recipientID, objectID);
|
||||
}
|
||||
|
||||
public void UpdateSubscriptionMethod(string sourceID, string actionID, string recipientID, string[] senderNames)
|
||||
@ -140,8 +157,24 @@ namespace ASC.Core
|
||||
Methods = senderNames,
|
||||
};
|
||||
service.SetSubscriptionMethod(m);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private IEnumerable<SubscriptionMethod> GetDefaultSubscriptionMethodsFromCache(string sourceID, string actionID, string recepient)
|
||||
{
|
||||
lock (CacheLocker)
|
||||
{
|
||||
var key = $"subs|-1{sourceID}{actionID}{recepient}";
|
||||
var result = Cache.Get<IEnumerable<SubscriptionMethod>>(key);
|
||||
if (result == null)
|
||||
{
|
||||
result = service.GetSubscriptionMethods(-1, sourceID, actionID, recepient);
|
||||
Cache.Insert(key, result, DateTime.UtcNow.AddDays(1));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private int GetTenant()
|
||||
{
|
||||
|
@ -349,9 +349,9 @@ namespace ASC.Core
|
||||
QuotaService.SetTenantQuotaRow(row, exchange);
|
||||
}
|
||||
|
||||
public List<TenantQuotaRow> FindTenantQuotaRows(TenantQuotaRowQuery query)
|
||||
public List<TenantQuotaRow> FindTenantQuotaRows(int tenantId)
|
||||
{
|
||||
return QuotaService.FindTenantQuotaRows(query).ToList();
|
||||
return QuotaService.FindTenantQuotaRows(tenantId).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +65,8 @@ namespace ASC.Core
|
||||
private IUserService UserService { get; }
|
||||
private TenantManager TenantManager { get; }
|
||||
private PermissionContext PermissionContext { get; }
|
||||
private UserManagerConstants UserManagerConstants { get; }
|
||||
private UserManagerConstants UserManagerConstants { get; }
|
||||
public CoreBaseSettings CoreBaseSettings { get; }
|
||||
private Constants Constants { get; }
|
||||
|
||||
private Tenant tenant;
|
||||
@ -80,12 +81,14 @@ namespace ASC.Core
|
||||
IUserService service,
|
||||
TenantManager tenantManager,
|
||||
PermissionContext permissionContext,
|
||||
UserManagerConstants userManagerConstants)
|
||||
UserManagerConstants userManagerConstants,
|
||||
CoreBaseSettings coreBaseSettings)
|
||||
{
|
||||
UserService = service;
|
||||
TenantManager = tenantManager;
|
||||
PermissionContext = permissionContext;
|
||||
UserManagerConstants = userManagerConstants;
|
||||
UserManagerConstants = userManagerConstants;
|
||||
CoreBaseSettings = coreBaseSettings;
|
||||
Constants = UserManagerConstants.Constants;
|
||||
}
|
||||
|
||||
@ -94,8 +97,9 @@ namespace ASC.Core
|
||||
TenantManager tenantManager,
|
||||
PermissionContext permissionContext,
|
||||
UserManagerConstants userManagerConstants,
|
||||
CoreBaseSettings coreBaseSettings,
|
||||
IHttpContextAccessor httpContextAccessor)
|
||||
: this(service, tenantManager, permissionContext, userManagerConstants)
|
||||
: this(service, tenantManager, permissionContext, userManagerConstants, coreBaseSettings)
|
||||
{
|
||||
Accessor = httpContextAccessor;
|
||||
}
|
||||
@ -230,7 +234,14 @@ namespace ASC.Core
|
||||
|
||||
public UserInfo GetUserByEmail(string email)
|
||||
{
|
||||
if (string.IsNullOrEmpty(email)) return Constants.LostUser;
|
||||
if (string.IsNullOrEmpty(email)) return Constants.LostUser;
|
||||
|
||||
if (CoreBaseSettings.Personal)
|
||||
{
|
||||
var u = UserService.GetUser(Tenant.TenantId, email);
|
||||
return u != null && !u.Removed ? u : Constants.LostUser;
|
||||
}
|
||||
|
||||
|
||||
return GetUsersInternal()
|
||||
.FirstOrDefault(u => string.Compare(u.Email, email, StringComparison.CurrentCultureIgnoreCase) == 0) ?? Constants.LostUser;
|
||||
|
@ -44,8 +44,7 @@ namespace ASC.Core
|
||||
|
||||
void RemoveTenantQuota(int id);
|
||||
|
||||
|
||||
IEnumerable<TenantQuotaRow> FindTenantQuotaRows(TenantQuotaRowQuery query);
|
||||
IEnumerable<TenantQuotaRow> FindTenantQuotaRows(int tenantId);
|
||||
|
||||
void SetTenantQuotaRow(TenantQuotaRow row, bool exchange);
|
||||
}
|
||||
|
@ -27,19 +27,24 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
using ASC.Common;
|
||||
using ASC.Core.Caching;
|
||||
using ASC.Core.Data;
|
||||
|
||||
namespace ASC.Core
|
||||
{
|
||||
[Scope(typeof(DbSubscriptionService), typeof(CachedSubscriptionService))]
|
||||
[Scope(typeof(DbSubscriptionService))]
|
||||
public interface ISubscriptionService
|
||||
{
|
||||
IEnumerable<SubscriptionRecord> GetSubscriptions(int tenant, string sourceId, string actionId);
|
||||
|
||||
IEnumerable<SubscriptionRecord> GetSubscriptions(int tenant, string sourceId, string actionId, string recipientId, string objectId);
|
||||
|
||||
SubscriptionRecord GetSubscription(int tenant, string sourceId, string actionId, string recipientId, string objectId);
|
||||
string[] GetRecipients(int tenant, string sourceID, string actionID, string objectID);
|
||||
|
||||
IEnumerable<SubscriptionRecord> GetSubscriptions(int tenant, string sourceId, string actionId);
|
||||
|
||||
IEnumerable<SubscriptionRecord> GetSubscriptions(int tenant, string sourceId, string actionId, string recipientId, string objectId);
|
||||
|
||||
string[] GetSubscriptions(int tenant, string sourceId, string actionId, string recipientId, bool checkSubscribe);
|
||||
|
||||
SubscriptionRecord GetSubscription(int tenant, string sourceId, string actionId, string recipientId, string objectId);
|
||||
|
||||
bool IsUnsubscribe(int tenant, string sourceId, string actionId, string recipientId, string objectId);
|
||||
|
||||
void SaveSubscription(SubscriptionRecord s);
|
||||
|
||||
|
@ -57,6 +57,8 @@ namespace ASC.Core
|
||||
|
||||
UserInfo GetUser(int tenant, Guid id);
|
||||
|
||||
UserInfo GetUser(int tenant, string email);
|
||||
|
||||
UserInfo GetUser(int tenant, Guid id, Expression<Func<User, UserInfo>> exp);
|
||||
|
||||
UserInfo GetUserByPasswordHash(int tenant, string login, string passwordHash);
|
||||
|
@ -182,27 +182,14 @@ namespace ASC.Core.Data
|
||||
tx.Commit();
|
||||
}
|
||||
|
||||
public IEnumerable<TenantQuotaRow> FindTenantQuotaRows(TenantQuotaRowQuery query)
|
||||
{
|
||||
if (query == null) throw new ArgumentNullException("query");
|
||||
|
||||
IQueryable<DbQuotaRow> q = CoreDbContext.QuotaRows;
|
||||
public IEnumerable<TenantQuotaRow> FindTenantQuotaRows(int tenantId)
|
||||
{
|
||||
IQueryable<DbQuotaRow> q = CoreDbContext.QuotaRows;
|
||||
|
||||
|
||||
if (query.Tenant != Tenant.DEFAULT_TENANT)
|
||||
if (tenantId != Tenant.DEFAULT_TENANT)
|
||||
{
|
||||
q = q.Where(r => r.Tenant == query.Tenant);
|
||||
q = q.Where(r => r.Tenant == tenantId);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(query.Path))
|
||||
{
|
||||
q = q.Where(r => r.Path == query.Path);
|
||||
}
|
||||
|
||||
if (query.LastModified != default)
|
||||
{
|
||||
q = q.Where(r => r.LastModified >= query.LastModified);
|
||||
}
|
||||
|
||||
|
||||
return q.Select(FromDbQuotaRowToTenantQuotaRow).ToList();
|
||||
}
|
||||
|
@ -63,8 +63,21 @@ namespace ASC.Core.Data
|
||||
Tenant = r.Tenant,
|
||||
MethodsFromDb = r.Sender
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public string[] GetRecipients(int tenant, string sourceId, string actionId, string objectId)
|
||||
{
|
||||
if (sourceId == null) throw new ArgumentNullException("sourceId");
|
||||
if (actionId == null) throw new ArgumentNullException("actionId");
|
||||
|
||||
var q = GetQuery(tenant, sourceId, actionId)
|
||||
.Where(r => r.Object == (objectId ?? string.Empty))
|
||||
.Where(r => !r.Unsubscribed)
|
||||
.Select(r => r.Recipient)
|
||||
.Distinct();
|
||||
|
||||
return q.ToArray();
|
||||
}
|
||||
|
||||
public IEnumerable<SubscriptionRecord> GetSubscriptions(int tenant, string sourceId, string actionId)
|
||||
{
|
||||
@ -99,8 +112,52 @@ namespace ASC.Core.Data
|
||||
.Where(r => r.Recipient == recipientId)
|
||||
.Where(r => r.Object == (objectId ?? string.Empty));
|
||||
|
||||
return GetSubscriptions(q, tenant).FirstOrDefault();
|
||||
return GetSubscriptions(q, tenant).Take(1).FirstOrDefault();
|
||||
}
|
||||
|
||||
public bool IsUnsubscribe(int tenant, string sourceId, string actionId, string recipientId, string objectId)
|
||||
{
|
||||
if (recipientId == null) throw new ArgumentNullException("recipientId");
|
||||
if (sourceId == null) throw new ArgumentNullException("sourceId");
|
||||
if (actionId == null) throw new ArgumentNullException("actionId");
|
||||
|
||||
var q = UserDbContext.Subscriptions
|
||||
.Where(r => r.Source == sourceId &&
|
||||
r.Action == actionId &&
|
||||
r.Tenant == tenant &&
|
||||
r.Recipient == recipientId &&
|
||||
r.Unsubscribed);
|
||||
|
||||
if (!string.IsNullOrEmpty(objectId))
|
||||
{
|
||||
q = q.Where(r=> r.Object == objectId || r.Object == string.Empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
q = q = q.Where(r => r.Object == string.Empty);;
|
||||
}
|
||||
|
||||
return q.Any();
|
||||
}
|
||||
|
||||
public string[] GetSubscriptions(int tenant, string sourceId, string actionId, string recipientId, bool checkSubscribe)
|
||||
{
|
||||
if (recipientId == null) throw new ArgumentNullException("recipientId");
|
||||
if (sourceId == null) throw new ArgumentNullException("sourceId");
|
||||
if (actionId == null) throw new ArgumentNullException("actionId");
|
||||
|
||||
var q = GetQuery(tenant, sourceId, actionId)
|
||||
.Where(r=> r.Recipient == recipientId)
|
||||
.Distinct();
|
||||
|
||||
if (checkSubscribe)
|
||||
{
|
||||
q = q.Where(r=> !r.Unsubscribed);
|
||||
}
|
||||
|
||||
return q.Select(r=> r.Object).ToArray();
|
||||
}
|
||||
|
||||
|
||||
public void SaveSubscription(SubscriptionRecord s)
|
||||
{
|
||||
@ -171,24 +228,26 @@ namespace ASC.Core.Data
|
||||
.Distinct();
|
||||
|
||||
|
||||
var methods = a.Select(FromDbSubscriptionMethodToSubscriptionMethod).ToList();
|
||||
var methods = a.ToList();
|
||||
var result = new List<SubscriptionMethod>();
|
||||
var common = new Dictionary<string, SubscriptionMethod>();
|
||||
var conv = FromDbSubscriptionMethodToSubscriptionMethod.Compile();
|
||||
|
||||
var result = methods.ToList();
|
||||
|
||||
var common = new Dictionary<string, SubscriptionMethod>();
|
||||
foreach (var m in methods)
|
||||
{
|
||||
foreach (var r in methods)
|
||||
{
|
||||
var m = conv(r);
|
||||
var key = m.SourceId + m.ActionId + m.RecipientId;
|
||||
if (m.Tenant == Tenant.DEFAULT_TENANT)
|
||||
{
|
||||
m.Tenant = tenant;
|
||||
common.Add(key, m);
|
||||
common.Add(key, m);
|
||||
result.Add(m);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (common.TryGetValue(key, out var r))
|
||||
if (!common.TryGetValue(key, out var rec))
|
||||
{
|
||||
result.Remove(r);
|
||||
result.Add(rec);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -250,23 +309,26 @@ namespace ASC.Core.Data
|
||||
|
||||
private IEnumerable<SubscriptionRecord> GetSubscriptions(IQueryable<Subscription> q, int tenant)
|
||||
{
|
||||
var subs = q.Select(FromSubscriptionToSubscriptionRecord).ToList();
|
||||
var subs = q.ToList();
|
||||
var result = new List<SubscriptionRecord>();
|
||||
var common = new Dictionary<string, SubscriptionRecord>();
|
||||
var conv = FromSubscriptionToSubscriptionRecord.Compile();
|
||||
|
||||
var result = subs.ToList();
|
||||
var common = new Dictionary<string, SubscriptionRecord>();
|
||||
foreach (var s in subs)
|
||||
{
|
||||
foreach (var r in subs)
|
||||
{
|
||||
var s = conv(r);
|
||||
var key = s.SourceId + s.ActionId + s.RecipientId + s.ObjectId;
|
||||
if (s.Tenant == Tenant.DEFAULT_TENANT)
|
||||
{
|
||||
s.Tenant = tenant;
|
||||
common.Add(key, s);
|
||||
common.Add(key, s);
|
||||
result.Add(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (common.TryGetValue(key, out var r))
|
||||
if (common.TryGetValue(key, out var rec))
|
||||
{
|
||||
result.Remove(r);
|
||||
result.Remove(rec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -223,6 +223,13 @@ namespace ASC.Core.Data
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
public UserInfo GetUser(int tenant, string email)
|
||||
{
|
||||
return GetUserQuery(tenant, default(DateTime))
|
||||
.Select(FromUserToUserInfo)
|
||||
.FirstOrDefault(r=> r.Email == email && !r.Removed);
|
||||
}
|
||||
|
||||
public UserInfo GetUserByPasswordHash(int tenant, string login, string passwordHash)
|
||||
{
|
||||
if (string.IsNullOrEmpty(login)) throw new ArgumentNullException("login");
|
||||
@ -259,8 +266,9 @@ namespace ASC.Core.Data
|
||||
.Where(r => r.Email == login)
|
||||
;
|
||||
|
||||
var user = q.Select(FromUserToUserInfo).Take(1).FirstOrDefault();
|
||||
if (user != null)
|
||||
var users = q.Select(FromUserToUserInfo).ToList();
|
||||
UserInfo result = null;
|
||||
foreach (var user in users)
|
||||
{
|
||||
RegeneratePassword(tenant, user.ID);
|
||||
|
||||
@ -270,27 +278,40 @@ namespace ASC.Core.Data
|
||||
var any = UserDbContext.UserSecurity
|
||||
.Any(r => r.UserId == user.ID && (r.PwdHash == pwdHash || r.PwdHash == oldHash));//todo: remove old scheme
|
||||
|
||||
if (any) return user;
|
||||
if (any)
|
||||
{
|
||||
if (tenant != Tenant.DEFAULT_TENANT) return user;
|
||||
|
||||
//need for regenerate all passwords only
|
||||
//todo: remove with old scheme
|
||||
result = user;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
//todo: remove
|
||||
private void RegeneratePassword(int tenant, Guid userId)
|
||||
{
|
||||
var h2 = UserDbContext.UserSecurity
|
||||
.Where(r => r.Tenant == tenant)
|
||||
.Where(r => r.UserId == userId)
|
||||
.Select(r => r.PwdHashSha512)
|
||||
var q = UserDbContext.UserSecurity
|
||||
.Where(r => r.UserId == userId);
|
||||
|
||||
if (tenant != Tenant.DEFAULT_TENANT)
|
||||
{
|
||||
q = q.Where(r => r.Tenant == tenant);
|
||||
}
|
||||
|
||||
var h2 = q.Select(r => new { r.Tenant, r.PwdHashSha512 })
|
||||
.Take(1)
|
||||
.FirstOrDefault();
|
||||
if (string.IsNullOrEmpty(h2)) return;
|
||||
|
||||
var password = Crypto.GetV(h2, 1, false);
|
||||
if (h2 == null || string.IsNullOrEmpty(h2.PwdHashSha512)) return;
|
||||
|
||||
var password = Crypto.GetV(h2.PwdHashSha512, 1, false);
|
||||
var passwordHash = PasswordHasher.GetClientPassword(password);
|
||||
SetUserPasswordHash(tenant, userId, passwordHash);
|
||||
SetUserPasswordHash(h2.Tenant, userId, passwordHash);
|
||||
}
|
||||
|
||||
public IDictionary<string, UserGroupRef> GetUserGroupRefs(int tenant, DateTime from)
|
||||
|
@ -29,10 +29,9 @@ using System.Security.Cryptography;
|
||||
|
||||
using ASC.Common;
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Core;
|
||||
using ASC.Security.Cryptography;
|
||||
|
||||
namespace ASC.Data.Storage.Encryption
|
||||
namespace ASC.Core.Encryption
|
||||
{
|
||||
public class EncryptionSettings
|
||||
{
|
||||
@ -151,7 +150,7 @@ namespace ASC.Data.Storage.Encryption
|
||||
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
var num2 = (int)array[i] % 87;
|
||||
var num2 = array[i] % 87;
|
||||
if (num2 < 10)
|
||||
{
|
||||
array2[i] = (char)(48 + num2);
|
@ -26,7 +26,7 @@
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace ASC.Data.Storage.Encryption
|
||||
namespace ASC.Core.Encryption
|
||||
{
|
||||
public interface ICrypt
|
||||
{
|
||||
@ -38,6 +38,8 @@ namespace ASC.Data.Storage.Encryption
|
||||
|
||||
Stream GetReadStream(string filePath);
|
||||
|
||||
long GetFileSize(string filePath);
|
||||
long GetFileSize(string filePath);
|
||||
|
||||
void Init(string storageName, EncryptionSettings encryptionSettings);
|
||||
}
|
||||
}
|
@ -205,8 +205,7 @@ namespace ASC.Core
|
||||
// save tenant owner
|
||||
tenant.OwnerId = user.ID;
|
||||
tenant = TenantService.SaveTenant(CoreSettings, tenant);
|
||||
|
||||
SettingsManager.SaveSettings(new TenantAnalyticsSettings() { Analytics = ri.Analytics }, tenant.TenantId);
|
||||
|
||||
SettingsManager.SaveSettings(new TenantControlPanelSettings { LimitedAccess = ri.LimitedControlPanel }, tenant.TenantId);
|
||||
}
|
||||
|
||||
|
@ -44,8 +44,8 @@ namespace ASC.Notify.Engine
|
||||
|
||||
public SendInterceptorSkeleton(string name, InterceptorPlace preventPlace, InterceptorLifetime lifetime, Func<NotifyRequest, InterceptorPlace, IServiceScope, bool> sendInterceptor)
|
||||
{
|
||||
if (string.IsNullOrEmpty("name")) throw new ArgumentNullException("name");
|
||||
if (string.IsNullOrEmpty("sendInterceptor")) throw new ArgumentNullException("sendInterceptor");
|
||||
if (string.IsNullOrEmpty(name)) throw new ArgumentException("Empty name.", "name");
|
||||
if (sendInterceptor == null) throw new ArgumentNullException("sendInterceptor");
|
||||
|
||||
method = sendInterceptor;
|
||||
Name = name;
|
||||
|
@ -34,6 +34,9 @@ namespace ASC.Core.Notify.Jabber
|
||||
[ServiceContract]
|
||||
public interface IJabberService
|
||||
{
|
||||
[OperationContract]
|
||||
string GetVersion();
|
||||
|
||||
[OperationContract]
|
||||
byte AddXmppConnection(string connectionId, string userName, byte state, int tenantId);
|
||||
|
||||
|
@ -74,7 +74,23 @@ namespace ASC.Core.Notify.Jabber
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetVersion()
|
||||
{
|
||||
using (var service = GetService())
|
||||
{
|
||||
try
|
||||
{
|
||||
return service.GetVersion();
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
ProcessError(error);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int GetNewMessagesCount()
|
||||
{
|
||||
|
@ -36,7 +36,12 @@ namespace ASC.Core.Notify.Jabber
|
||||
{
|
||||
public JabberServiceClientWcf()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public string GetVersion()
|
||||
{
|
||||
return Channel.GetVersion();
|
||||
}
|
||||
|
||||
public byte AddXmppConnection(string connectionId, string userName, byte state, int tenantId)
|
||||
{
|
||||
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2018
|
||||
*
|
||||
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
|
||||
* In accordance with Section 7(a) of the GNU GPL 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 more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
|
||||
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
|
||||
* relevant author attributions when distributing the software. If the display of the logo in its graphic
|
||||
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
|
||||
* in every copy of the program you distribute.
|
||||
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
using System;
|
||||
|
||||
using ASC.Core.Common.Settings;
|
||||
|
||||
namespace ASC.Core.Tenants
|
||||
{
|
||||
[Serializable]
|
||||
public class TenantAnalyticsSettings : ISettings
|
||||
{
|
||||
public bool Analytics { get; set; }
|
||||
|
||||
public Guid ID
|
||||
{
|
||||
get { return new Guid("{02943039-F399-421E-A552-23D70651AEBD}"); }
|
||||
}
|
||||
|
||||
public ISettings GetDefault(IServiceProvider serviceProvider)
|
||||
{
|
||||
return new TenantAnalyticsSettings
|
||||
{
|
||||
Analytics = true
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2018
|
||||
*
|
||||
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
|
||||
* In accordance with Section 7(a) of the GNU GPL 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 more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
|
||||
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
|
||||
* relevant author attributions when distributing the software. If the display of the logo in its graphic
|
||||
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
|
||||
* in every copy of the program you distribute.
|
||||
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
using System;
|
||||
|
||||
namespace ASC.Core.Tenants
|
||||
{
|
||||
[Serializable]
|
||||
public class TenantQuotaRowQuery
|
||||
{
|
||||
public int Tenant
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public string Path
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public DateTime LastModified
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
|
||||
public TenantQuotaRowQuery(int tenant)
|
||||
{
|
||||
Tenant = tenant;
|
||||
}
|
||||
|
||||
|
||||
public TenantQuotaRowQuery WithPath(string path)
|
||||
{
|
||||
Path = path;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TenantQuotaRowQuery WithLastModified(DateTime lastModified)
|
||||
{
|
||||
LastModified = lastModified;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
@ -65,8 +65,6 @@ namespace ASC.Core.Tenants
|
||||
|
||||
public bool Calls { get; set; }
|
||||
|
||||
public bool Analytics { get; set; }
|
||||
|
||||
public string Campaign { get; set; }
|
||||
|
||||
public bool LimitedControlPanel { get; set; }
|
||||
|
@ -47,7 +47,7 @@ namespace ASC.Core.Common.Tests
|
||||
public void ClearData()
|
||||
{
|
||||
Service.RemoveTenantQuota(Tenant);
|
||||
foreach (var row in Service.FindTenantQuotaRows(new TenantQuotaRowQuery(Tenant) { Path = "path" }))
|
||||
foreach (var row in Service.FindTenantQuotaRows(Tenant))
|
||||
{
|
||||
//DeleteQuotaRow(row);
|
||||
}
|
||||
@ -71,12 +71,12 @@ namespace ASC.Core.Common.Tests
|
||||
var row = new TenantQuotaRow { Tenant = this.Tenant, Path = "path", Counter = 1000, Tag = "tag" };
|
||||
Service.SetTenantQuotaRow(row, false);
|
||||
|
||||
var rows = Service.FindTenantQuotaRows(new TenantQuotaRowQuery(Tenant).WithPath("path")).ToList();
|
||||
var rows = Service.FindTenantQuotaRows(Tenant).ToList();
|
||||
CompareQuotaRows(row, rows.Find(r => r.Tenant == row.Tenant && r.Tag == row.Tag));
|
||||
|
||||
Service.SetTenantQuotaRow(row, true);
|
||||
row.Counter += 1000;
|
||||
rows = Service.FindTenantQuotaRows(new TenantQuotaRowQuery(Tenant).WithPath("path")).ToList();
|
||||
rows = Service.FindTenantQuotaRows(Tenant).ToList();
|
||||
CompareQuotaRows(row, rows.Find(r => r.Tenant == row.Tenant && r.Tag == row.Tag));
|
||||
|
||||
//DeleteQuotaRow(row);
|
||||
|
@ -56,7 +56,7 @@ namespace ASC.Core.Users
|
||||
|
||||
public string GetUserName(string firstName, string lastName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(firstName) || string.IsNullOrEmpty("lastName")) throw new ArgumentException();
|
||||
if (string.IsNullOrEmpty(firstName) || string.IsNullOrEmpty(lastName)) throw new ArgumentException();
|
||||
|
||||
return string.Format(GetUserDisplayFormat(DisplayUserNameFormat.Default), firstName, lastName);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package ASC.Data.Storage.Encryption;
|
||||
package ASC.Core.Encryption;
|
||||
|
||||
message EncryptionSettingsProto {
|
||||
string password = 1;
|
13
common/ASC.Data.Encryption/ASC.Data.Encryption.csproj
Normal file
13
common/ASC.Data.Encryption/ASC.Data.Encryption.csproj
Normal file
@ -0,0 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ASC.Common\ASC.Common.csproj" />
|
||||
<ProjectReference Include="..\ASC.Core.Common\ASC.Core.Common.csproj" />
|
||||
<ProjectReference Include="..\ASC.Data.Storage\ASC.Data.Storage.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -29,10 +29,12 @@ using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
using ASC.Common;
|
||||
using ASC.Core.Encryption;
|
||||
using ASC.Data.Storage.Encryption;
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace ASC.Data.Storage.Encryption
|
||||
namespace ASC.Data.Encryption
|
||||
{
|
||||
[Transient]
|
||||
public class Crypt : ICrypt
|
||||
@ -42,7 +44,6 @@ namespace ASC.Data.Storage.Encryption
|
||||
private string TempDir { get; set; }
|
||||
|
||||
private IConfiguration Configuration { get; set; }
|
||||
private EncryptionFactory EncryptionFactory { get; set; }
|
||||
|
||||
public void Init(string storageName, EncryptionSettings encryptionSettings)
|
||||
{
|
||||
@ -51,19 +52,18 @@ namespace ASC.Data.Storage.Encryption
|
||||
TempDir = Configuration["storage:encryption:tempdir"] ?? Path.GetTempPath();
|
||||
}
|
||||
|
||||
public Crypt(IConfiguration configuration, EncryptionFactory encryptionFactory)
|
||||
public Crypt(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
EncryptionFactory = encryptionFactory;
|
||||
}
|
||||
|
||||
public byte Version { get { return 1; } }
|
||||
|
||||
public void EncryptFile(string filePath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Settings.Password)) return;
|
||||
|
||||
var metadata = EncryptionFactory.GetMetadata();
|
||||
if (string.IsNullOrEmpty(Settings.Password)) return;
|
||||
|
||||
var metadata = new Metadata(Configuration);
|
||||
|
||||
metadata.Initialize(Settings.Password);
|
||||
|
||||
@ -122,7 +122,7 @@ namespace ASC.Data.Storage.Encryption
|
||||
|
||||
try
|
||||
{
|
||||
var metadata = EncryptionFactory.GetMetadata();
|
||||
var metadata = new Metadata(Configuration);
|
||||
|
||||
metadata.Initialize(Version, password, fileInfo.Length);
|
||||
|
||||
@ -176,7 +176,7 @@ namespace ASC.Data.Storage.Encryption
|
||||
|
||||
try
|
||||
{
|
||||
var metadata = EncryptionFactory.GetMetadata();
|
||||
var metadata = new Metadata(Configuration);
|
||||
|
||||
metadata.Initialize(password);
|
||||
|
||||
@ -221,7 +221,7 @@ namespace ASC.Data.Storage.Encryption
|
||||
{
|
||||
var decryptedMemoryStream = new MemoryStream(); //TODO: MemoryStream or temporary decrypted file on disk?
|
||||
|
||||
var metadata = EncryptionFactory.GetMetadata();
|
||||
var metadata = new Metadata(Configuration);
|
||||
|
||||
metadata.Initialize(password);
|
||||
|
||||
@ -253,7 +253,7 @@ namespace ASC.Data.Storage.Encryption
|
||||
|
||||
private Stream GetReadStream(string filePath, string password)
|
||||
{
|
||||
var metadata = EncryptionFactory.GetMetadata();
|
||||
var metadata = new Metadata(Configuration);
|
||||
|
||||
metadata.Initialize(password);
|
||||
|
||||
@ -274,7 +274,7 @@ namespace ASC.Data.Storage.Encryption
|
||||
|
||||
private long GetFileSize(string filePath, string password)
|
||||
{
|
||||
var metadata = EncryptionFactory.GetMetadata();
|
||||
var metadata = new Metadata(Configuration);
|
||||
|
||||
metadata.Initialize(password);
|
||||
|
@ -27,7 +27,7 @@
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace ASC.Data.Storage.Encryption
|
||||
namespace ASC.Data.Encryption
|
||||
{
|
||||
//https://stackoverflow.com/a/22072068
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
using System;
|
||||
|
||||
namespace ASC.Data.Storage.Encryption
|
||||
namespace ASC.Data.Encryption
|
||||
{
|
||||
public class IntegrityProtectionException : Exception
|
||||
{
|
@ -34,10 +34,10 @@ using ASC.Common;
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace ASC.Data.Storage.Encryption
|
||||
namespace ASC.Data.Encryption
|
||||
{
|
||||
[Transient]
|
||||
public class Metadata : IMetadata
|
||||
public class Metadata
|
||||
{
|
||||
private const string prefixString = "AscEncrypted";
|
||||
|
@ -28,7 +28,7 @@ using System;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace ASC.Data.Storage.Encryption
|
||||
namespace ASC.Data.Encryption
|
||||
{
|
||||
internal sealed class StreamWrapper : Stream
|
||||
{
|
||||
@ -39,7 +39,7 @@ namespace ASC.Data.Storage.Encryption
|
||||
private readonly long fileSize;
|
||||
private readonly long metadataLength;
|
||||
|
||||
public StreamWrapper(Stream fileStream, IMetadata metadata)
|
||||
public StreamWrapper(Stream fileStream, Metadata metadata)
|
||||
{
|
||||
stream = fileStream;
|
||||
symmetricAlgorithm = metadata.GetCryptographyAlgorithm();
|
@ -20,7 +20,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="protos\EncryptionSettingsProto.proto" />
|
||||
<None Remove="protos\EncryptionStop.proto" />
|
||||
<None Remove="protos\MigrationCache.proto" />
|
||||
<None Remove="protos\MigrationProgress.proto" />
|
||||
@ -51,7 +50,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<Protobuf Include="protos\DataStoreCacheItem.proto" />
|
||||
<Protobuf Include="protos\EncryptionSettingsProto.proto" />
|
||||
<Protobuf Include="protos\EncryptionStop.proto" />
|
||||
<Protobuf Include="protos\MigrationCache.proto" />
|
||||
<Protobuf Include="protos\MigrationProgress.proto" />
|
||||
|
@ -32,6 +32,7 @@ using System.Linq;
|
||||
using ASC.Common;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Core;
|
||||
using ASC.Core.Encryption;
|
||||
using ASC.Data.Storage.Configuration;
|
||||
using ASC.Data.Storage.Encryption;
|
||||
using ASC.Security.Cryptography;
|
||||
|
@ -24,43 +24,36 @@
|
||||
*/
|
||||
|
||||
|
||||
using System;
|
||||
|
||||
using ASC.Common;
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ASC.Core.Encryption;
|
||||
|
||||
using Autofac;
|
||||
|
||||
namespace ASC.Data.Storage.Encryption
|
||||
{
|
||||
[Singletone(Additional = typeof(EncryptionFactoryExtension))]
|
||||
[Singletone]
|
||||
public class EncryptionFactory
|
||||
{
|
||||
private IServiceProvider ServiceProvider { get; }
|
||||
|
||||
public EncryptionFactory(IServiceProvider serviceProvider)
|
||||
{
|
||||
ServiceProvider = serviceProvider;
|
||||
{
|
||||
private ILifetimeScope Container { get; }
|
||||
|
||||
public EncryptionFactory(ILifetimeScope container)
|
||||
{
|
||||
Container = container;
|
||||
}
|
||||
|
||||
public ICrypt GetCrypt(string storageName, EncryptionSettings encryptionSettings)
|
||||
{
|
||||
var crypt = ServiceProvider.GetService<Crypt>();
|
||||
crypt.Init(storageName, encryptionSettings);
|
||||
return crypt;
|
||||
}
|
||||
|
||||
public IMetadata GetMetadata()
|
||||
{
|
||||
return ServiceProvider.GetService<Metadata>();
|
||||
}
|
||||
}
|
||||
|
||||
public class EncryptionFactoryExtension
|
||||
{
|
||||
public static void Register(DIHelper services)
|
||||
{
|
||||
services.TryAdd<Crypt>();
|
||||
services.TryAdd<Metadata>();
|
||||
}
|
||||
ICrypt result = null;
|
||||
|
||||
using var scope = Container.BeginLifetimeScope();
|
||||
if (scope != null)
|
||||
{
|
||||
result = scope.Resolve<ICrypt>();
|
||||
}
|
||||
|
||||
result ??= new FakeCrypt();
|
||||
result.Init(storageName, encryptionSettings);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,8 @@
|
||||
|
||||
using ASC.Common;
|
||||
using ASC.Common.Caching;
|
||||
|
||||
using ASC.Core.Encryption;
|
||||
|
||||
namespace ASC.Data.Storage.Encryption
|
||||
{
|
||||
[Scope]
|
||||
|
37
common/ASC.Data.Storage/Encryption/FakeCrypt.cs
Normal file
37
common/ASC.Data.Storage/Encryption/FakeCrypt.cs
Normal file
@ -0,0 +1,37 @@
|
||||
|
||||
using System.IO;
|
||||
|
||||
using ASC.Core.Encryption;
|
||||
|
||||
namespace ASC.Data.Storage.Encryption
|
||||
{
|
||||
public class FakeCrypt : ICrypt
|
||||
{
|
||||
public byte Version { get { return 1; } }
|
||||
|
||||
public void EncryptFile(string filePath)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public void DecryptFile(string filePath)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public Stream GetReadStream(string filePath)
|
||||
{
|
||||
return File.OpenRead(filePath);
|
||||
}
|
||||
|
||||
public long GetFileSize(string filePath)
|
||||
{
|
||||
return new FileInfo(filePath).Length;
|
||||
}
|
||||
|
||||
public void Init(string storageName, EncryptionSettings encryptionSettings)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -23,6 +23,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
using ASC.Core.Encryption;
|
||||
|
||||
namespace ASC.Data.Storage.Encryption
|
||||
{
|
||||
public interface IEncryptionService
|
||||
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2020
|
||||
*
|
||||
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
|
||||
* In accordance with Section 7(a) of the GNU GPL 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 more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
|
||||
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
|
||||
* relevant author attributions when distributing the software. If the display of the logo in its graphic
|
||||
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
|
||||
* in every copy of the program you distribute.
|
||||
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace ASC.Data.Storage.Encryption
|
||||
{
|
||||
public interface IMetadata
|
||||
{
|
||||
void Initialize(string password);
|
||||
|
||||
void Initialize(byte version, string password, long fileSize);
|
||||
|
||||
bool TryReadFromStream(Stream stream, byte cryptVersion);
|
||||
|
||||
void WriteToStream(Stream stream);
|
||||
|
||||
SymmetricAlgorithm GetCryptographyAlgorithm();
|
||||
|
||||
void ComputeAndWriteHmacHash(Stream stream);
|
||||
|
||||
void ComputeAndValidateHmacHash(Stream stream);
|
||||
|
||||
byte GetCryptoVersion();
|
||||
|
||||
long GetFileSize();
|
||||
|
||||
int GetMetadataLength();
|
||||
}
|
||||
}
|
@ -34,8 +34,6 @@ namespace ASC.Data.Storage
|
||||
|
||||
void QuotaUsedSet(string module, string domain, string dataTag, long size);
|
||||
|
||||
long QuotaUsedGet(string module, string domain);
|
||||
|
||||
void QuotaUsedCheck(long size);
|
||||
}
|
||||
}
|
@ -616,6 +616,7 @@ namespace ASC.Data.Storage.S3
|
||||
public override string SavePrivate(string domain, string path, Stream stream, DateTime expires)
|
||||
{
|
||||
using var client = GetClient();
|
||||
using var uploader = new TransferUtility(client);
|
||||
var objectKey = MakePath(domain, path);
|
||||
var buffered = stream.GetBuffered();
|
||||
var request = new TransferUtilityUploadRequest
|
||||
@ -636,7 +637,7 @@ namespace ASC.Data.Storage.S3
|
||||
|
||||
request.Metadata.Add("private-expire", expires.ToFileTimeUtc().ToString(CultureInfo.InvariantCulture));
|
||||
|
||||
new TransferUtility(client).Upload(request);
|
||||
uploader.Upload(request);
|
||||
|
||||
//Get presigned url
|
||||
var pUrlRequest = new GetPreSignedUrlRequest
|
||||
|
@ -60,7 +60,7 @@ namespace ASC.Data.Storage
|
||||
{
|
||||
this.tenant = tenant;
|
||||
TenantManager = tenantManager;
|
||||
lazyCurrentSize = new Lazy<long>(() => TenantManager.FindTenantQuotaRows(new TenantQuotaRowQuery(tenant))
|
||||
lazyCurrentSize = new Lazy<long>(() => TenantManager.FindTenantQuotaRows(tenant)
|
||||
.Where(r => UsedInQuota(r.Tag))
|
||||
.Sum(r => r.Counter));
|
||||
}
|
||||
@ -98,14 +98,6 @@ namespace ASC.Data.Storage
|
||||
SetTenantQuotaRow(module, domain, size, dataTag, false);
|
||||
}
|
||||
|
||||
public long QuotaUsedGet(string module, string domain)
|
||||
{
|
||||
var path = string.IsNullOrEmpty(module) ? null : string.Format("/{0}/{1}", module, domain);
|
||||
return TenantManager.FindTenantQuotaRows(new TenantQuotaRowQuery(tenant).WithPath(path))
|
||||
.Where(r => UsedInQuota(r.Tag))
|
||||
.Sum(r => r.Counter);
|
||||
}
|
||||
|
||||
public void QuotaUsedCheck(long size)
|
||||
{
|
||||
var quota = TenantManager.GetTenantQuota(tenant);
|
||||
|
@ -93,7 +93,6 @@ namespace ASC.Notify.Textile
|
||||
formatter.Format(message.Body);
|
||||
|
||||
var template = GetTemplate(message);
|
||||
var analytics = GetAnalytics(message);
|
||||
var imagePath = GetImagePath(message);
|
||||
var logoImg = GetLogoImg(message, imagePath);
|
||||
var logoText = GetLogoText(message);
|
||||
@ -103,7 +102,7 @@ namespace ASC.Notify.Textile
|
||||
|
||||
InitFooter(message, mailSettings, out var footerContent, out var footerSocialContent);
|
||||
|
||||
message.Body = template.Replace("%ANALYTICS%", analytics)
|
||||
message.Body = template
|
||||
.Replace("%CONTENT%", output.GetFormattedText())
|
||||
.Replace("%LOGO%", logoImg)
|
||||
.Replace("%LOGOTEXT%", logoText)
|
||||
@ -133,12 +132,6 @@ namespace ASC.Notify.Textile
|
||||
return template;
|
||||
}
|
||||
|
||||
private static string GetAnalytics(NoticeMessage message)
|
||||
{
|
||||
var analyticsTag = message.GetArgument("Analytics");
|
||||
return analyticsTag == null ? string.Empty : (string)analyticsTag.Value;
|
||||
}
|
||||
|
||||
private static string GetImagePath(NoticeMessage message)
|
||||
{
|
||||
var imagePathTag = message.GetArgument("ImagePath");
|
||||
|
@ -12,7 +12,6 @@ using ASC.Common.Utils;
|
||||
|
||||
using CommandLine;
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace ASC.Resource.Manager
|
||||
@ -29,6 +28,7 @@ namespace ASC.Resource.Manager
|
||||
var services = new ServiceCollection();
|
||||
var startup = new Startup();
|
||||
startup.ConfigureServices(services);
|
||||
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
using var scope = serviceProvider.CreateScope();
|
||||
var scopeClass = scope.ServiceProvider.GetService<ProgramScope>();
|
||||
@ -42,11 +42,11 @@ namespace ASC.Resource.Manager
|
||||
{
|
||||
var (project, module, filePath, exportPath, culture, format, key) = options;
|
||||
|
||||
project = "Files";
|
||||
module = "Common";
|
||||
filePath = "FilesCommonResource.resx";
|
||||
exportPath = @"C:\Git\portals_core\products\ASC.Files\Core\Resources";
|
||||
key = "AceStatusEnum_CustomFilter";
|
||||
project = "WebStudio";
|
||||
module = "WebStudio";
|
||||
filePath = "Resource.resx";
|
||||
exportPath = @"C:\Git\portals_core\web\ASC.Web.Core\PublicResources";
|
||||
key = "LicenseUploadedOverdueSupport";
|
||||
|
||||
if (format == "json")
|
||||
{
|
||||
@ -192,24 +192,16 @@ namespace ASC.Resource.Manager
|
||||
}
|
||||
}
|
||||
|
||||
[Scope]
|
||||
public class ProgramScope
|
||||
{
|
||||
internal ResourceData ResourceData { get; }
|
||||
internal IConfiguration Configuration { get; }
|
||||
internal ConfigurationExtension Configuration { get; }
|
||||
|
||||
public ProgramScope(ResourceData resourceData, IConfiguration configuration)
|
||||
public ProgramScope(ResourceData resourceData, ConfigurationExtension configuration)
|
||||
{
|
||||
ResourceData = resourceData;
|
||||
Configuration = configuration;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ProgramExtension
|
||||
{
|
||||
public static DIHelper AddProgramService(this DIHelper services)
|
||||
{
|
||||
services.TryAddScoped<ProgramScope>();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,12 +29,14 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
using ASC.Common;
|
||||
using ASC.Core.Common.EF;
|
||||
using ASC.Core.Common.EF.Context;
|
||||
using ASC.Core.Common.EF.Model.Resource;
|
||||
|
||||
namespace ASC.Resource.Manager
|
||||
{
|
||||
[Scope]
|
||||
public class ResourceData
|
||||
{
|
||||
private const string Dbid = "tmresource";
|
||||
|
@ -1,7 +1,5 @@
|
||||
using ASC.Common;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Core.Common.EF;
|
||||
using ASC.Core.Common.EF.Context;
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@ -24,13 +22,10 @@ namespace ASC.Resource.Manager
|
||||
{
|
||||
var diHelper = new DIHelper(services);
|
||||
services.AddLogging();
|
||||
diHelper.TryAddScoped<ResourceData>();
|
||||
diHelper.TryAddScoped<ProgramScope>();
|
||||
|
||||
diHelper.AddDbContextManagerService<ResourceDbContext>();
|
||||
diHelper.AddLoggerService();
|
||||
diHelper.AddNLogManager();
|
||||
diHelper.TryAddSingleton(Configuration);
|
||||
diHelper.Configure(services);
|
||||
services.AddSingleton(Configuration);
|
||||
diHelper.TryAdd<ProgramScope>();
|
||||
LogNLogExtension.ConfigureLog(diHelper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -304,7 +304,7 @@ namespace ASC.ApiSystem.Controllers
|
||||
try
|
||||
{
|
||||
var data = string.Format("secret={0}&remoteip={1}&response={2}", Configuration["recaptcha:private-key"], ip, response);
|
||||
var url = Configuration["recaptcha:verify-url"] ?? "https://www.google.com/recaptcha/api/siteverify";
|
||||
var url = Configuration["recaptcha:verify-url"] ?? "https://www.recaptcha.net/recaptcha/api/siteverify";
|
||||
|
||||
var webRequest = (HttpWebRequest)WebRequest.Create(url);
|
||||
webRequest.Method = WebRequestMethods.Http.Post;
|
||||
|
@ -248,8 +248,7 @@ namespace ASC.ApiSystem.Controllers
|
||||
MobilePhone = string.IsNullOrEmpty(model.Phone) ? null : model.Phone.Trim(),
|
||||
Industry = (TenantIndustry)model.Industry,
|
||||
Spam = model.Spam,
|
||||
Calls = model.Calls,
|
||||
Analytics = model.Analytics,
|
||||
Calls = model.Calls,
|
||||
LimitedControlPanel = model.LimitedControlPanel
|
||||
};
|
||||
|
||||
|
@ -274,8 +274,7 @@ namespace ASC.ApiSystem.Controllers
|
||||
MobilePhone = string.IsNullOrEmpty(model.Phone) ? null : model.Phone.Trim(),
|
||||
Industry = (TenantIndustry)model.Industry,
|
||||
Spam = model.Spam,
|
||||
Calls = model.Calls,
|
||||
Analytics = model.Analytics,
|
||||
Calls = model.Calls,
|
||||
LimitedControlPanel = model.LimitedControlPanel
|
||||
};
|
||||
|
||||
|
@ -89,8 +89,6 @@ namespace ASC.ApiSystem.Models
|
||||
|
||||
public bool Calls { get; set; }
|
||||
|
||||
public bool Analytics { get; set; }
|
||||
|
||||
public string AppKey { get; set; }
|
||||
|
||||
public bool LimitedControlPanel { get; set; }
|
||||
|
@ -30,6 +30,7 @@
|
||||
<ProjectReference Include="..\..\..\web\ASC.Web.Core\ASC.Web.Core.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Common\ASC.Common.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Core.Common\ASC.Core.Common.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Data.Encryption\ASC.Data.Encryption.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Data.Storage\ASC.Data.Storage.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -3,7 +3,6 @@ using System.Linq;
|
||||
|
||||
using ASC.Common;
|
||||
using ASC.Core;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.Web.Studio.UserControls.Statistics;
|
||||
|
||||
namespace ASC.Data.Backup
|
||||
@ -30,7 +29,7 @@ namespace ASC.Data.Backup
|
||||
if (CoreBaseSettings.Standalone)
|
||||
return BackupAvailableSize.Available;
|
||||
|
||||
var size = TenantManager.FindTenantQuotaRows(new TenantQuotaRowQuery(tenantId))
|
||||
var size = TenantManager.FindTenantQuotaRows(tenantId)
|
||||
.Where(r => !string.IsNullOrEmpty(r.Tag) && new Guid(r.Tag) != Guid.Empty && !new Guid(r.Tag).Equals(mailStorageTag))
|
||||
.Sum(r => r.Counter);
|
||||
if (size > AvailableZipSize)
|
||||
|
@ -31,6 +31,7 @@ using System.Threading;
|
||||
using ASC.Common;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Data.Backup.Storage;
|
||||
using ASC.Files.Core;
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
@ -94,10 +95,18 @@ namespace ASC.Data.Backup.Service
|
||||
backupStorage.Delete(backupRecord.StoragePath);
|
||||
|
||||
BackupRepository.DeleteBackupRecord(backupRecord.Id);
|
||||
}
|
||||
catch (ProviderInfoArgumentException error)
|
||||
{
|
||||
log.Warn("can't remove backup record " + backupRecord.Id, error);
|
||||
if (DateTime.UtcNow > backupRecord.CreatedOn.AddMonths(6))
|
||||
{
|
||||
BackupRepository.DeleteBackupRecord(backupRecord.Id);
|
||||
}
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
log.Warn("can't remove backup record: {0}", error);
|
||||
log.Warn("can't remove backup record: " + backupRecord.Id, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,12 +28,15 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using ASC.Common;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Common.Utils;
|
||||
using ASC.Core;
|
||||
using ASC.Data.Backup.Contracts;
|
||||
using ASC.Data.Backup.EF.Model;
|
||||
using ASC.Data.Backup.Service;
|
||||
using ASC.Data.Backup.Utils;
|
||||
using ASC.Data.Backup.Utils;
|
||||
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
@ -44,7 +47,8 @@ namespace ASC.Data.Backup.Storage
|
||||
{
|
||||
private ConfigurationExtension Configuration { get; }
|
||||
private DocumentsBackupStorage DocumentsBackupStorage { get; }
|
||||
private DataStoreBackupStorage DataStoreBackupStorage { get; }
|
||||
private DataStoreBackupStorage DataStoreBackupStorage { get; }
|
||||
private ILog Log { get; }
|
||||
private LocalBackupStorage LocalBackupStorage { get; }
|
||||
private ConsumerBackupStorage ConsumerBackupStorage { get; }
|
||||
private TenantManager TenantManager { get; }
|
||||
@ -55,19 +59,29 @@ namespace ASC.Data.Backup.Storage
|
||||
ConfigurationExtension configuration,
|
||||
DocumentsBackupStorage documentsBackupStorage,
|
||||
TenantManager tenantManager,
|
||||
DataStoreBackupStorage dataStoreBackupStorage)
|
||||
DataStoreBackupStorage dataStoreBackupStorage,
|
||||
IOptionsMonitor<ILog> options)
|
||||
{
|
||||
Configuration = configuration;
|
||||
DocumentsBackupStorage = documentsBackupStorage;
|
||||
DataStoreBackupStorage = dataStoreBackupStorage;
|
||||
DataStoreBackupStorage = dataStoreBackupStorage;
|
||||
Log = options.CurrentValue;
|
||||
LocalBackupStorage = localBackupStorage;
|
||||
ConsumerBackupStorage = consumerBackupStorage;
|
||||
TenantManager = tenantManager;
|
||||
}
|
||||
|
||||
public IBackupStorage GetBackupStorage(BackupRecord record)
|
||||
{
|
||||
return GetBackupStorage(record.StorageType, record.TenantId, JsonConvert.DeserializeObject<Dictionary<string, string>>(record.StorageParams));
|
||||
{
|
||||
try
|
||||
{
|
||||
return GetBackupStorage(record.StorageType, record.TenantId, JsonConvert.DeserializeObject<Dictionary<string, string>>(record.StorageParams));
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
Log.Error("can't get backup storage for record " + record.Id, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public IBackupStorage GetBackupStorage(BackupStorageType type, int tenantId, Dictionary<string, string> storageParams)
|
||||
|
@ -105,7 +105,7 @@ namespace ASC.Data.Backup.Tasks.Modules
|
||||
|
||||
if (table.Name == "calendar_event_history")
|
||||
return string.Format(
|
||||
"inner join calendar_calendars as t1 on t1.id = t.calendar_id inner join calendar_events as t2 on t2.id = t.event_id where t1.tenant = {0} and t2.tenant = {0}",
|
||||
"inner join calendar_calendars as t1 on t1.id = t.calendar_id and t1.tenant = t.tenant inner join calendar_events as t2 on t2.id = t.event_id where t1.tenant = {0} and t2.tenant = {0}",
|
||||
tenantId);
|
||||
|
||||
return base.GetSelectCommandConditionText(tenantId, table);
|
||||
|
@ -31,6 +31,7 @@
|
||||
<ProjectReference Include="..\..\ASC.Api.Core\ASC.Api.Core.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Common\ASC.Common.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Core.Common\ASC.Core.Common.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Data.Encryption\ASC.Data.Encryption.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Data.Storage\ASC.Data.Storage.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -34,6 +34,7 @@ using ASC.Common.Caching;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Common.Threading.Progress;
|
||||
using ASC.Core;
|
||||
using ASC.Core.Encryption;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.Data.Storage.DiscStorage;
|
||||
|
||||
|
@ -24,7 +24,8 @@
|
||||
*/
|
||||
using ASC.Common;
|
||||
using ASC.Common.Caching;
|
||||
|
||||
using ASC.Core.Encryption;
|
||||
|
||||
namespace ASC.Data.Storage.Encryption
|
||||
{
|
||||
[Singletone]
|
||||
|
@ -30,7 +30,8 @@ using System.Threading.Tasks;
|
||||
|
||||
using ASC.Common;
|
||||
using ASC.Common.Caching;
|
||||
|
||||
using ASC.Core.Encryption;
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace ASC.Data.Storage.Encryption
|
||||
|
@ -7,6 +7,7 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\ASC.Common\ASC.Common.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Core.Common\ASC.Core.Common.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Data.Encryption\ASC.Data.Encryption.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Data.Storage\ASC.Data.Storage.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -171,7 +171,7 @@ namespace ASC.ElasticSearch
|
||||
|
||||
if (runBulk)
|
||||
{
|
||||
var portion1 = portion;
|
||||
var portion1 = portion.ToList();
|
||||
Client.Instance.Bulk(r => r.IndexMany(portion1, GetMeta));
|
||||
for (var j = portionStart; j < i; j++)
|
||||
{
|
||||
@ -567,6 +567,7 @@ namespace ASC.ElasticSearch
|
||||
|
||||
public IEnumerable<List<T>> IndexAll(Func<DateTime, (int, int, int)> getCount, Func<long, long, DateTime, List<T>> getData)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
var lastIndexed = WebstudioDbContext.WebstudioIndex
|
||||
.Where(r => r.IndexName == Wrapper.IndexName)
|
||||
.Select(r => r.LastModified)
|
||||
@ -600,7 +601,7 @@ namespace ASC.ElasticSearch
|
||||
WebstudioDbContext.AddOrUpdate(r => r.WebstudioIndex, new DbWebstudioIndex()
|
||||
{
|
||||
IndexName = Wrapper.IndexName,
|
||||
LastModified = DateTime.UtcNow
|
||||
LastModified = now
|
||||
});
|
||||
|
||||
WebstudioDbContext.SaveChanges();
|
||||
|
@ -76,26 +76,25 @@ namespace ASC.ElasticSearch
|
||||
var settings = new ConnectionSettings(new SingleNodeConnectionPool(uri))
|
||||
.RequestTimeout(TimeSpan.FromMinutes(5))
|
||||
.MaximumRetries(10)
|
||||
.ThrowExceptions();
|
||||
#if DEBUG
|
||||
.ThrowExceptions();
|
||||
|
||||
if (Log.IsTraceEnabled)
|
||||
{
|
||||
settings.DisableDirectStreaming().PrettyJson().EnableDebugMode(r =>
|
||||
{
|
||||
Log.Trace(r.DebugInformation);
|
||||
//Log.Trace(r.DebugInformation);
|
||||
|
||||
if (r.RequestBodyInBytes != null)
|
||||
{
|
||||
Log.TraceFormat("Request: {0}", Encoding.UTF8.GetString(r.RequestBodyInBytes));
|
||||
}
|
||||
//if (r.RequestBodyInBytes != null)
|
||||
//{
|
||||
// Log.TraceFormat("Request: {0}", Encoding.UTF8.GetString(r.RequestBodyInBytes));
|
||||
//}
|
||||
|
||||
if (r.ResponseBodyInBytes != null)
|
||||
if (r.HttpStatusCode != null && (r.HttpStatusCode == 403 || r.HttpStatusCode == 500) && r.ResponseBodyInBytes != null)
|
||||
{
|
||||
Log.TraceFormat("Response: {0}", Encoding.UTF8.GetString(r.ResponseBodyInBytes));
|
||||
}
|
||||
});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
client = new ElasticClient(settings);
|
||||
|
||||
|
@ -223,7 +223,7 @@ namespace ASC.ElasticSearch
|
||||
{
|
||||
Logger.Error("inner", inner.Response.OriginalException);
|
||||
|
||||
if (inner.Response.HttpStatusCode == 413)
|
||||
if (inner.Response.HttpStatusCode == 413 || inner.Response.HttpStatusCode == 403)
|
||||
{
|
||||
data.ForEach(r => Index(r, immediately));
|
||||
}
|
||||
|
@ -110,6 +110,7 @@ namespace ASC.ElasticSearch
|
||||
|
||||
}, CancellationTokenSource.Token, TaskCreationOptions.LongRunning);
|
||||
|
||||
task.ConfigureAwait(false);
|
||||
task.Start();
|
||||
|
||||
return Task.CompletedTask;
|
||||
@ -131,20 +132,28 @@ namespace ASC.ElasticSearch
|
||||
|
||||
private void IndexAll(bool reindex = false)
|
||||
{
|
||||
Timer.Change(-1, -1);
|
||||
IsStarted = true;
|
||||
|
||||
using var scope = Container.BeginLifetimeScope();
|
||||
var wrappers = scope.Resolve<IEnumerable<IFactoryIndexer>>();
|
||||
|
||||
foreach (var w in wrappers)
|
||||
try
|
||||
{
|
||||
IndexProduct(w, reindex);
|
||||
}
|
||||
Timer.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
IsStarted = true;
|
||||
|
||||
Timer.Change(Period, Period);
|
||||
IndexNotify.Publish(new IndexAction() { Indexing = "", LastIndexed = DateTime.Now.Ticks }, CacheNotifyAction.Any);
|
||||
IsStarted = false;
|
||||
using var scope = Container.BeginLifetimeScope();
|
||||
var wrappers = scope.Resolve<IEnumerable<IFactoryIndexer>>();
|
||||
|
||||
foreach (var w in wrappers)
|
||||
{
|
||||
IndexProduct(w, reindex);
|
||||
}
|
||||
|
||||
Timer.Change(Period, Period);
|
||||
IndexNotify.Publish(new IndexAction() { Indexing = "", LastIndexed = DateTime.Now.Ticks }, CacheNotifyAction.Any);
|
||||
IsStarted = false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Fatal("IndexAll", e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public void IndexProduct(IFactoryIndexer product, bool reindex)
|
||||
|
@ -44,7 +44,8 @@ namespace ASC.ElasticSearch.Service
|
||||
Host = cfg.Host ?? "localhost";
|
||||
Port = cfg.Port ?? 9200;
|
||||
Period = cfg.Period ?? 1;
|
||||
MemoryLimit = cfg.MemoryLimit ?? 10 * 1024 * 1024L;
|
||||
MemoryLimit = cfg.MemoryLimit ?? 1 * 1024 * 1024L;
|
||||
MaxContentLength = cfg.MaxContentLength ?? 10 * 1024 * 1024L;
|
||||
}
|
||||
|
||||
public string Host { get; set; }
|
||||
@ -55,6 +56,8 @@ namespace ASC.ElasticSearch.Service
|
||||
|
||||
public int? Period { get; set; }
|
||||
|
||||
public long? MemoryLimit { get; set; }
|
||||
public long? MemoryLimit { get; set; }
|
||||
|
||||
public long? MaxContentLength { get; set; }
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\ASC.Common\ASC.Common.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Core.Common\ASC.Core.Common.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Data.Encryption\ASC.Data.Encryption.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -12,6 +12,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\web\ASC.Web.Core\ASC.Web.Core.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Data.Encryption\ASC.Data.Encryption.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Data.Storage\ASC.Data.Storage.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\ASC.Common\ASC.Common.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Core.Common\ASC.Core.Common.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Data.Encryption\ASC.Data.Encryption.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Data.Storage\ASC.Data.Storage.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\ASC.Common\ASC.Common.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Data.Encryption\ASC.Data.Encryption.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -77,7 +77,7 @@
|
||||
},
|
||||
"viewed-images": [ ".bmp", ".gif", ".jpeg", ".jpg", ".png", ".ico", ".tif", ".tiff", ".webp" ],
|
||||
"viewed-media": [ ".aac", ".flac", ".m4a", ".mp3", ".oga", ".ogg", ".wav", ".f4v", ".m4v", ".mov", ".mp4", ".ogv", ".webm" ],
|
||||
"index": [ ".pptx", ".pptm", ".ppt", ".ppsx", ".ppsm", ".pps", ".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".gslides", ".xlsx", ".xlsm", ".xls", ".xltx", ".xltm", ".xlt", ".ods", ".fods", ".ots", ".gsheet", ".csv", ".docx", ".docm", ".doc", ".dotx", ".dotm", ".dot", ".odt", ".fodt", ".ott", ".gdoc", ".txt", ".rtf", ".mht", ".html", ".htm", ".epub", ".pdf", ".djvu", ".xps" ]
|
||||
"index": [ ".pptx", ".xlsx", ".docx" ]
|
||||
},
|
||||
"web": {
|
||||
"api": "api/2.0",
|
||||
|
@ -7,6 +7,14 @@
|
||||
"type": "ASC.Common.Logging.ILog, ASC.Common"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "ASC.Data.Encryption.Crypt, ASC.Data.Encryption",
|
||||
"services": [
|
||||
{
|
||||
"type": "ASC.Core.Encryption.ICrypt, ASC.Core.Common"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
<conversionPattern value=""/>
|
||||
|
||||
<targets async="true">
|
||||
<default-target-parameters type="SelfCleaning" archiveNumbering="DateAndSequence" archiveEvery="Day" enableArchiveFileCompression="true" archiveAboveSize="52428800" keepFileOpen="true" archiveDateFormat="MM-dd" layout="${date:format=yyyy-MM-dd HH\:mm\:ss,fff} ${level:uppercase=true} [${threadid}] ${logger} - ${message} ${exception:format=ToString}"/>
|
||||
<default-target-parameters type="SelfCleaning" encoding="utf-8" archiveNumbering="DateAndSequence" archiveEvery="Day" enableArchiveFileCompression="true" archiveAboveSize="52428800" keepFileOpen="true" archiveDateFormat="MM-dd" layout="${date:format=yyyy-MM-dd HH\:mm\:ss,fff} ${level:uppercase=true} [${threadid}] ${logger} - ${message} ${exception:format=ToString}"/>
|
||||
<target name="web" type="SelfCleaning" fileName="${var:dir}${var:name}.log" />
|
||||
<target name="sql" type="SelfCleaning" fileName="${var:dir}${var:name}.sql.log" layout="${date:universalTime=true:format=yyyy-MM-dd HH\:mm\:ss,fff}|${threadid}|${event-properties:item=duration}|${message}|${event-properties:item=sql}|${event-properties:item=sqlParams}"/>
|
||||
<target name="ownFile-web" type="File" fileName="${var:dir}web.asp.log" layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" />
|
||||
|
@ -87,6 +87,13 @@
|
||||
"path": "$STORAGE_ROOT\\Products\\CRM\\Data",
|
||||
"virtualpath": "~/products/crm/data",
|
||||
"domain": [
|
||||
{
|
||||
"name": "export",
|
||||
"visible": false,
|
||||
"data": "00000000-0000-0000-0000-000000000000",
|
||||
"path": "$STORAGE_ROOT\\Products\\CRM\\Data\\{0}\\export",
|
||||
"expires": "1.0:0:0"
|
||||
},
|
||||
{
|
||||
"name": "temp",
|
||||
"visible": false,
|
||||
|
@ -36,6 +36,7 @@
|
||||
<ProjectReference Include="..\..\..\common\ASC.Api.Core\ASC.Api.Core.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\ASC.Common\ASC.Common.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\ASC.Core.Common\ASC.Core.Common.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\ASC.Data.Encryption\ASC.Data.Encryption.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\ASC.Data.Storage\ASC.Data.Storage.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\ASC.FederatedLogin\ASC.FederatedLogin.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\ASC.MessagingSystem\ASC.MessagingSystem.csproj" />
|
||||
|
@ -42,5 +42,12 @@ namespace ASC.Files.Core
|
||||
bool CheckAccess();
|
||||
void InvalidateStorage();
|
||||
void UpdateTitle(string newtitle);
|
||||
}
|
||||
|
||||
public class ProviderInfoArgumentException : ArgumentException
|
||||
{
|
||||
public ProviderInfoArgumentException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -317,7 +317,10 @@ namespace ASC.Files.Core.Data
|
||||
|
||||
FilesDbContext.SaveChanges();
|
||||
|
||||
FactoryIndexer.IndexAsync(toUpdate);
|
||||
if (folder.FolderType == FolderType.DEFAULT || folder.FolderType == FolderType.BUNCH)
|
||||
{
|
||||
FactoryIndexer.IndexAsync(toUpdate);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -337,7 +340,10 @@ namespace ASC.Files.Core.Data
|
||||
|
||||
newFolder = FilesDbContext.Folders.Add(newFolder).Entity;
|
||||
FilesDbContext.SaveChanges();
|
||||
FactoryIndexer.IndexAsync(newFolder);
|
||||
if (folder.FolderType == FolderType.DEFAULT || folder.FolderType == FolderType.BUNCH)
|
||||
{
|
||||
FactoryIndexer.IndexAsync(newFolder);
|
||||
}
|
||||
folder.ID = newFolder.Id;
|
||||
|
||||
//itself link
|
||||
@ -755,7 +761,9 @@ namespace ASC.Files.Core.Data
|
||||
private void RecalculateFoldersCount(int id)
|
||||
{
|
||||
var toUpdate = Query(FilesDbContext.Folders)
|
||||
.Where(r => FilesDbContext.Tree.Where(a => a.FolderId == id).Select(a => a.ParentId).Contains(r.Id))
|
||||
.Join(FilesDbContext.Tree, r=> r.Id, r=> r.ParentId,(file, tree) => new { file, tree })
|
||||
.Where(r => r.tree.FolderId == id)
|
||||
.Select(r=> r.file)
|
||||
.ToList();
|
||||
|
||||
foreach (var f in toUpdate)
|
||||
@ -1247,7 +1255,7 @@ namespace ASC.Files.Core.Data
|
||||
|
||||
//var projectID = Convert.ToInt32(bunchObjectIDParts[bunchObjectIDParts.Length - 1]);
|
||||
|
||||
//if (HttpContext.Current == null)
|
||||
//if (HttpContext.Current == null || !SecurityContext.IsAuthenticated)
|
||||
// return string.Empty;
|
||||
|
||||
//var apiServer = new ApiServer();
|
||||
|
@ -1727,8 +1727,9 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
IEnumerable<File<T>> result;
|
||||
|
||||
var subjectId = string.IsNullOrEmpty(subjectID) ? Guid.Empty : new Guid(subjectID);
|
||||
var folderDao = GetFolderDao();
|
||||
var fileDao = GetFileDao();
|
||||
result = EntryManager.GetTemplates(fileDao, filter, subjectGroup, subjectId, search, searchInContent);
|
||||
result = EntryManager.GetTemplates(folderDao, fileDao, filter, subjectGroup, subjectId, search, searchInContent);
|
||||
|
||||
if (result.Count() <= from)
|
||||
return null;
|
||||
|
@ -163,7 +163,7 @@ namespace ASC.Files.Thirdparty
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
throw new ArgumentException("Provider id not found or you have no access");
|
||||
throw new ProviderInfoArgumentException("Provider id not found or you have no access");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -395,8 +395,9 @@ namespace ASC.Web.Files.Services.DocumentService
|
||||
break;
|
||||
}
|
||||
|
||||
var folderDao = DaoFactory.GetFolderDao<int>();
|
||||
var fileDao = DaoFactory.GetFileDao<int>();
|
||||
var files = entryManager.GetTemplates(fileDao, filter, false, Guid.Empty, string.Empty, false);
|
||||
var files = entryManager.GetTemplates(folderDao, fileDao, filter, false, Guid.Empty, string.Empty, false);
|
||||
var listTemplates = from file in files
|
||||
select
|
||||
new TemplatesConfig
|
||||
@ -480,7 +481,7 @@ namespace ASC.Web.Files.Services.DocumentService
|
||||
|
||||
var folderDao = DaoFactory.GetFolderDao<int>();
|
||||
var fileDao = DaoFactory.GetFileDao<int>();
|
||||
var files = entryManager.GetRecent(fileDao, filter, false, Guid.Empty, string.Empty, false);
|
||||
var files = entryManager.GetRecent(folderDao, fileDao, filter, false, Guid.Empty, string.Empty, false);
|
||||
|
||||
var listRecent = from file in files
|
||||
where !Equals(_configuration.Document.Info.File.ID, file.ID)
|
||||
|
@ -586,7 +586,9 @@ namespace ASC.Web.Files.Services.DocumentService
|
||||
|
||||
|
||||
private void StoringFileAfterError<T>(T fileId, string userId, string downloadUri)
|
||||
{
|
||||
{
|
||||
if (string.IsNullOrEmpty(downloadUri)) return;
|
||||
|
||||
try
|
||||
{
|
||||
var fileName = Global.ReplaceInvalidCharsAndTruncate(fileId + FileUtility.GetFileExtension(downloadUri));
|
||||
|
@ -36,6 +36,7 @@ using ASC.Files.Core.Security;
|
||||
using ASC.Notify.Patterns;
|
||||
using ASC.Web.Core.Files;
|
||||
using ASC.Web.Files.Classes;
|
||||
using ASC.Web.Studio.Core.Notify;
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
@ -115,6 +116,7 @@ namespace ASC.Files.Core.Services.NotifyService
|
||||
var scopeClass = scope.ServiceProvider.GetService<NotifyClientScope>();
|
||||
var (notifySource, _, filesLinkUtility, fileUtility, baseCommonLinkUtility, daoFactory, pathProvider, userManager, tenantManager) = scopeClass;
|
||||
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope);
|
||||
var studioNotifyHelper = scope.ServiceProvider.GetService<StudioNotifyHelper>();
|
||||
|
||||
var folderDao = daoFactory.GetFolderDao<T>();
|
||||
if (fileEntry.FileEntryType == FileEntryType.File && folderDao.GetFolder(((File<T>)fileEntry).FolderID) == null) return;
|
||||
@ -123,7 +125,14 @@ namespace ASC.Files.Core.Services.NotifyService
|
||||
? filesLinkUtility.GetFileWebPreviewUrl(fileUtility, fileEntry.Title, fileEntry.ID)
|
||||
: pathProvider.GetFolderUrl((Folder<T>)fileEntry);
|
||||
|
||||
var recipientsProvider = notifySource.GetRecipientsProvider();
|
||||
var recipientsProvider = notifySource.GetRecipientsProvider();
|
||||
|
||||
var action = fileEntry.FileEntryType == FileEntryType.File
|
||||
? ((File<T>)fileEntry).Encrypted
|
||||
? NotifyConstants.Event_ShareEncryptedDocument
|
||||
: NotifyConstants.Event_ShareDocument
|
||||
: NotifyConstants.Event_ShareFolder;
|
||||
|
||||
|
||||
foreach (var recipientPair in recipients)
|
||||
{
|
||||
@ -136,14 +145,15 @@ namespace ASC.Files.Core.Services.NotifyService
|
||||
var recipient = recipientsProvider.GetRecipient(u.ID.ToString());
|
||||
|
||||
client.SendNoticeAsync(
|
||||
fileEntry.FileEntryType == FileEntryType.File ? NotifyConstants.Event_ShareDocument : NotifyConstants.Event_ShareFolder,
|
||||
action,
|
||||
fileEntry.UniqID,
|
||||
recipient,
|
||||
true,
|
||||
new TagValue(NotifyConstants.Tag_DocumentTitle, fileEntry.Title),
|
||||
new TagValue(NotifyConstants.Tag_DocumentUrl, baseCommonLinkUtility.GetFullAbsolutePath(url)),
|
||||
new TagValue(NotifyConstants.Tag_AccessRights, aceString),
|
||||
new TagValue(NotifyConstants.Tag_Message, message.HtmlEncode())
|
||||
new TagValue(NotifyConstants.Tag_Message, message.HtmlEncode()),
|
||||
TagValues.Image(studioNotifyHelper,0, "privacy.png")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,8 @@ namespace ASC.Files.Core.Services.NotifyService
|
||||
public static readonly INotifyAction Event_DocuSignComplete = new NotifyAction("DocuSignComplete", "docusign complete");
|
||||
public static readonly INotifyAction Event_DocuSignStatus = new NotifyAction("DocuSignStatus", "docusign status");
|
||||
public static readonly INotifyAction Event_MailMergeEnd = new NotifyAction("MailMergeEnd", "mail merge end");
|
||||
public static readonly INotifyAction Event_ShareDocument = new NotifyAction("ShareDocument", "share document");
|
||||
public static readonly INotifyAction Event_ShareDocument = new NotifyAction("ShareDocument", "share document");
|
||||
public static readonly INotifyAction Event_ShareEncryptedDocument = new NotifyAction("ShareEncryptedDocument", "share encrypted document");
|
||||
public static readonly INotifyAction Event_ShareFolder = new NotifyAction("ShareFolder", "share folder");
|
||||
public static readonly INotifyAction Event_EditorMentions = new NotifyAction("EditorMentions", "editor mentions");
|
||||
|
||||
|
@ -380,8 +380,9 @@ namespace ASC.Web.Files.Utils
|
||||
}
|
||||
else if (parent.FolderType == FolderType.Recent)
|
||||
{
|
||||
var folderDao = DaoFactory.GetFolderDao<T>();
|
||||
var fileDao = DaoFactory.GetFileDao<T>();
|
||||
var files = GetRecent(fileDao, filter, subjectGroup, subjectId, searchText, searchInContent);
|
||||
var files = GetRecent(folderDao, fileDao, filter, subjectGroup, subjectId, searchText, searchInContent);
|
||||
entries = entries.Concat(files);
|
||||
|
||||
CalculateTotal();
|
||||
@ -400,8 +401,9 @@ namespace ASC.Web.Files.Utils
|
||||
}
|
||||
else if (parent.FolderType == FolderType.Templates)
|
||||
{
|
||||
var folderDao = DaoFactory.GetFolderDao<T>();
|
||||
var fileDao = DaoFactory.GetFileDao<T>();
|
||||
var files = GetTemplates(fileDao, filter, subjectGroup, subjectId, searchText, searchInContent);
|
||||
var files = GetTemplates(folderDao, fileDao, filter, subjectGroup, subjectId, searchText, searchInContent);
|
||||
entries = entries.Concat(files);
|
||||
|
||||
CalculateTotal();
|
||||
@ -443,9 +445,12 @@ namespace ASC.Web.Files.Utils
|
||||
}
|
||||
}
|
||||
|
||||
if (orderBy.SortedBy != SortedByType.New && parent.FolderType != FolderType.Recent)
|
||||
{
|
||||
entries = SortEntries<T>(entries, orderBy);
|
||||
if (orderBy.SortedBy != SortedByType.New)
|
||||
{
|
||||
if (parent.FolderType != FolderType.Recent)
|
||||
{
|
||||
entries = SortEntries<T>(entries, orderBy);
|
||||
}
|
||||
|
||||
total = entries.Count();
|
||||
if (0 < from) entries = entries.Skip(from);
|
||||
@ -484,7 +489,7 @@ namespace ASC.Web.Files.Utils
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<File<T>> GetTemplates<T>(IFileDao<T> fileDao, FilterType filter, bool subjectGroup, Guid subjectId, string searchText, bool searchInContent)
|
||||
public IEnumerable<File<T>> GetTemplates<T>(IFolderDao<T> folderDao, IFileDao<T> fileDao, FilterType filter, bool subjectGroup, Guid subjectId, string searchText, bool searchInContent)
|
||||
{
|
||||
var tagDao = DaoFactory.GetTagDao<T>();
|
||||
var tags = tagDao.GetTags(AuthContext.CurrentAccount.ID, TagType.Template);
|
||||
@ -496,6 +501,8 @@ namespace ASC.Web.Files.Utils
|
||||
|
||||
files = FileSecurity.FilterRead(files).ToList();
|
||||
|
||||
CheckFolderId(folderDao, files);
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
@ -534,7 +541,7 @@ namespace ASC.Web.Files.Utils
|
||||
return folderList;
|
||||
}
|
||||
|
||||
public IEnumerable<File<T>> GetRecent<T>(IFileDao<T> fileDao, FilterType filter, bool subjectGroup, Guid subjectId, string searchText, bool searchInContent)
|
||||
public IEnumerable<File<T>> GetRecent<T>(IFolderDao<T> folderDao, IFileDao<T> fileDao, FilterType filter, bool subjectGroup, Guid subjectId, string searchText, bool searchInContent)
|
||||
{
|
||||
var tagDao = DaoFactory.GetTagDao<T>();
|
||||
var tags = tagDao.GetTags(AuthContext.CurrentAccount.ID, TagType.Recent).ToList();
|
||||
@ -545,6 +552,8 @@ namespace ASC.Web.Files.Utils
|
||||
|
||||
files = FileSecurity.FilterRead(files).ToList();
|
||||
|
||||
CheckFolderId(folderDao, files);
|
||||
|
||||
var listFileIds = fileIds.ToList();
|
||||
files = files.OrderBy(file => listFileIds.IndexOf(file.ID)).ToList();
|
||||
|
||||
@ -566,6 +575,8 @@ namespace ASC.Web.Files.Utils
|
||||
folders = folders.Where(folder => folder.RootFolderType != FolderType.TRASH).ToList();
|
||||
|
||||
folders = fileSecurity.FilterRead(folders).ToList();
|
||||
|
||||
CheckFolderId(folderDao, folders);
|
||||
}
|
||||
|
||||
if (filter != FilterType.FoldersOnly)
|
||||
@ -575,6 +586,8 @@ namespace ASC.Web.Files.Utils
|
||||
files = files.Where(file => file.RootFolderType != FolderType.TRASH).ToList();
|
||||
|
||||
files = fileSecurity.FilterRead(files).ToList();
|
||||
|
||||
CheckFolderId(folderDao, folders);
|
||||
}
|
||||
}
|
||||
|
||||
@ -734,8 +747,25 @@ namespace ASC.Web.Files.Utils
|
||||
public List<FileEntry> GetBreadCrumbs<T>(T folderId, IFolderDao<T> folderDao)
|
||||
{
|
||||
return BreadCrumbsManager.GetBreadCrumbs(folderId, folderDao);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void CheckFolderId<T>(IFolderDao<T> folderDao, IEnumerable<FileEntry<T>> entries)
|
||||
{
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
if (entry.RootFolderType == FolderType.USER
|
||||
&& entry.RootFolderCreator != AuthContext.CurrentAccount.ID)
|
||||
{
|
||||
var folderId = entry.FolderID;
|
||||
var folder = folderDao.GetFolder(folderId);
|
||||
if (!FileSecurity.CanRead(folder))
|
||||
{
|
||||
entry.FolderIdDisplay = GlobalFolderHelper.GetFolderShare<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void SetFileStatus<T>(File<T> file)
|
||||
{
|
||||
|
@ -39,8 +39,4 @@
|
||||
<ProjectReference Include="..\ASC.Web.Core\ASC.Web.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Core\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -49,6 +49,9 @@ namespace ASC.Web.Api.Controllers
|
||||
private SettingsManager SettingsManager { get; }
|
||||
private IMobileAppInstallRegistrator MobileAppInstallRegistrator { get; }
|
||||
private IConfiguration Configuration { get; set; }
|
||||
public CoreBaseSettings CoreBaseSettings { get; }
|
||||
public LicenseReader LicenseReader { get; }
|
||||
public SetupInfo SetupInfo { get; }
|
||||
private TenantExtra TenantExtra { get; set; }
|
||||
public ILog Log { get; }
|
||||
|
||||
@ -67,7 +70,10 @@ namespace ASC.Web.Api.Controllers
|
||||
SettingsManager settingsManager,
|
||||
IMobileAppInstallRegistrator mobileAppInstallRegistrator,
|
||||
TenantExtra tenantExtra,
|
||||
IConfiguration configuration
|
||||
IConfiguration configuration,
|
||||
CoreBaseSettings coreBaseSettings,
|
||||
LicenseReader licenseReader,
|
||||
SetupInfo setupInfo
|
||||
)
|
||||
{
|
||||
Log = options.CurrentValue;
|
||||
@ -83,6 +89,9 @@ namespace ASC.Web.Api.Controllers
|
||||
SettingsManager = settingsManager;
|
||||
MobileAppInstallRegistrator = mobileAppInstallRegistrator;
|
||||
Configuration = configuration;
|
||||
CoreBaseSettings = coreBaseSettings;
|
||||
LicenseReader = licenseReader;
|
||||
SetupInfo = setupInfo;
|
||||
TenantExtra = tenantExtra;
|
||||
}
|
||||
|
||||
@ -129,12 +138,17 @@ namespace ASC.Web.Api.Controllers
|
||||
{
|
||||
return new
|
||||
{
|
||||
customMode = CoreBaseSettings.CustomMode,
|
||||
opensource = TenantExtra.Opensource,
|
||||
enterprise = TenantExtra.Enterprise,
|
||||
tariff = TenantExtra.GetCurrentTariff(),
|
||||
quota = TenantExtra.GetTenantQuota(),
|
||||
notPaid = TenantExtra.IsNotPaid(),
|
||||
licenseAccept = SettingsManager.LoadForCurrentUser<TariffSettings>().LicenseAcceptSetting
|
||||
licenseAccept = SettingsManager.LoadForCurrentUser<TariffSettings>().LicenseAcceptSetting,
|
||||
enableTariffPage = //TenantExtra.EnableTarrifSettings - think about hide-settings for opensource
|
||||
(!CoreBaseSettings.Standalone || !string.IsNullOrEmpty(LicenseReader.LicensePath))
|
||||
&& string.IsNullOrEmpty(SetupInfo.AmiMetaUrl)
|
||||
&& !CoreBaseSettings.CustomMode
|
||||
};
|
||||
}
|
||||
|
||||
@ -143,7 +157,7 @@ namespace ASC.Web.Api.Controllers
|
||||
public double GetUsedSpace()
|
||||
{
|
||||
return Math.Round(
|
||||
TenantManager.FindTenantQuotaRows(new TenantQuotaRowQuery(Tenant.TenantId))
|
||||
TenantManager.FindTenantQuotaRows(Tenant.TenantId)
|
||||
.Where(q => !string.IsNullOrEmpty(q.Tag) && new Guid(q.Tag) != Guid.Empty)
|
||||
.Sum(q => q.Counter) / 1024f / 1024f / 1024f, 2);
|
||||
}
|
||||
@ -209,7 +223,7 @@ namespace ASC.Web.Api.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
var settings = SettingsManager.LoadForCurrentUser<OpensourcePresentSettings>();
|
||||
var settings = SettingsManager.LoadForCurrentUser<OpensourceGiftSettings>();
|
||||
settings.Readed = true;
|
||||
SettingsManager.SaveForCurrentUser(settings);
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ using ASC.Core.Billing;
|
||||
using ASC.Core.Common.Configuration;
|
||||
using ASC.Core.Common.Notify;
|
||||
using ASC.Core.Common.Settings;
|
||||
using ASC.Core.Encryption;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.Core.Users;
|
||||
using ASC.Data.Backup;
|
||||
@ -169,6 +170,7 @@ namespace ASC.Api.Settings
|
||||
private ILog Log { get; set; }
|
||||
private TelegramHelper TelegramHelper { get; }
|
||||
private BackupAjaxHandler BackupAjaxHandler { get; }
|
||||
private PaymentManager PaymentManager { get; }
|
||||
|
||||
public SettingsController(
|
||||
IOptionsMonitor<ILog> option,
|
||||
@ -231,7 +233,8 @@ namespace ASC.Api.Settings
|
||||
ICacheNotify<DeleteSchedule> cacheDeleteSchedule,
|
||||
EncryptionServiceNotifier encryptionServiceNotifier,
|
||||
PasswordHasher passwordHasher,
|
||||
BackupAjaxHandler backupAjaxHandler)
|
||||
BackupAjaxHandler backupAjaxHandler,
|
||||
PaymentManager paymentManager)
|
||||
{
|
||||
Log = option.Get("ASC.Api");
|
||||
WebHostEnvironment = webHostEnvironment;
|
||||
@ -294,6 +297,7 @@ namespace ASC.Api.Settings
|
||||
UrlShortener = urlShortener;
|
||||
TelegramHelper = telegramHelper;
|
||||
BackupAjaxHandler = backupAjaxHandler;
|
||||
PaymentManager = paymentManager;
|
||||
}
|
||||
|
||||
[Read("", Check = false)]
|
||||
@ -1157,8 +1161,6 @@ namespace ASC.Api.Settings
|
||||
|
||||
if (query.IsDefault)
|
||||
{
|
||||
DemandRebrandingPermission();
|
||||
|
||||
result = new Dictionary<string, string>
|
||||
{
|
||||
{ ((int)WhiteLabelLogoTypeEnum.LightSmall).ToString(), CommonLinkUtility.GetFullAbsolutePath(TenantWhiteLabelSettingsHelper.GetAbsoluteDefaultLogoPath(WhiteLabelLogoTypeEnum.LightSmall, !query.IsRetina)) },
|
||||
@ -1192,12 +1194,6 @@ namespace ASC.Api.Settings
|
||||
throw new BillingException(Resource.ErrorNotAllowedOption, "WhiteLabel");
|
||||
}
|
||||
|
||||
|
||||
if (query.IsDefault)
|
||||
{
|
||||
DemandRebrandingPermission();
|
||||
}
|
||||
|
||||
var settings = query.IsDefault ? SettingsManager.LoadForDefaultTenant<TenantWhiteLabelSettings>() : SettingsManager.Load<TenantWhiteLabelSettings>();
|
||||
|
||||
return settings.LogoText ?? TenantWhiteLabelSettings.DefaultLogoText;
|
||||
@ -1774,6 +1770,47 @@ namespace ASC.Api.Settings
|
||||
return "";
|
||||
}
|
||||
|
||||
///<visible>false</visible>
|
||||
[Create("license/trial")]
|
||||
public bool ActivateTrial()
|
||||
{
|
||||
if (!CoreBaseSettings.Standalone) throw new NotSupportedException();
|
||||
if (!UserManager.GetUsers(AuthContext.CurrentAccount.ID).IsAdmin(UserManager)) throw new SecurityException();
|
||||
|
||||
var curQuota = TenantExtra.GetTenantQuota();
|
||||
if (curQuota.Id != Tenant.DEFAULT_TENANT) return false;
|
||||
if (curQuota.Trial) return false;
|
||||
|
||||
var curTariff = TenantExtra.GetCurrentTariff();
|
||||
if (curTariff.DueDate.Date != DateTime.MaxValue.Date) return false;
|
||||
|
||||
var quota = new TenantQuota(-1000)
|
||||
{
|
||||
Name = "apirequest",
|
||||
ActiveUsers = curQuota.ActiveUsers,
|
||||
MaxFileSize = curQuota.MaxFileSize,
|
||||
MaxTotalSize = curQuota.MaxTotalSize,
|
||||
Features = curQuota.Features
|
||||
};
|
||||
quota.Trial = true;
|
||||
|
||||
TenantManager.SaveTenantQuota(quota);
|
||||
|
||||
var DEFAULT_TRIAL_PERIOD = 30;
|
||||
|
||||
var tariff = new Tariff
|
||||
{
|
||||
QuotaId = quota.Id,
|
||||
DueDate = DateTime.Today.AddDays(DEFAULT_TRIAL_PERIOD)
|
||||
};
|
||||
|
||||
PaymentManager.SetTariff(-1, tariff);
|
||||
|
||||
MessageService.Send(MessageAction.LicenseKeyUploaded);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[AllowAnonymous]
|
||||
[Read("license/required", Check = false)]
|
||||
public bool RequestLicense()
|
||||
@ -1799,7 +1836,10 @@ namespace ASC.Api.Settings
|
||||
|
||||
return dueDate >= DateTime.UtcNow.Date
|
||||
? Resource.LicenseUploaded
|
||||
: string.Format(Resource.LicenseUploadedOverdue,
|
||||
: string.Format(
|
||||
(TenantExtra.GetTenantQuota().Update
|
||||
? Resource.LicenseUploadedOverdueSupport
|
||||
: Resource.LicenseUploadedOverdue),
|
||||
"",
|
||||
"",
|
||||
dueDate.Date.ToLongDateString());
|
||||
@ -2072,6 +2112,11 @@ namespace ASC.Api.Settings
|
||||
|
||||
private bool StartStorageEncryption(StorageEncryptionModel storageEncryption)
|
||||
{
|
||||
if (CoreBaseSettings.CustomMode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
lock (Locker)
|
||||
{
|
||||
var activeTenants = TenantManager.GetTenants();
|
||||
@ -2195,6 +2240,11 @@ namespace ASC.Api.Settings
|
||||
{
|
||||
try
|
||||
{
|
||||
if (CoreBaseSettings.CustomMode)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!SetupInfo.IsVisibleSettings<EncryptionSettings>())
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
@ -2230,6 +2280,11 @@ namespace ASC.Api.Settings
|
||||
[Read("encryption/progress")]
|
||||
public double? GetStorageEncryptionProgress()
|
||||
{
|
||||
if (CoreBaseSettings.CustomMode)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!SetupInfo.IsVisibleSettings<EncryptionSettings>())
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
|
@ -31,7 +31,6 @@ using System.IO;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
|
||||
using ASC.Common;
|
||||
using ASC.Common.Logging;
|
||||
@ -113,7 +112,7 @@ namespace ASC.Web.Studio.UserControls.FirstTime
|
||||
{
|
||||
try
|
||||
{
|
||||
var (email, passwordHash, lng, timeZone, promocode, amiid, analytics, subscribeFromSite) = wizardModel;
|
||||
var (email, passwordHash, lng, timeZone, promocode, amiid, subscribeFromSite) = wizardModel;
|
||||
|
||||
var tenant = TenantManager.GetCurrentTenant();
|
||||
var settings = SettingsManager.Load<WizardSettings>();
|
||||
@ -178,10 +177,6 @@ namespace ASC.Web.Studio.UserControls.FirstTime
|
||||
LicenseReader.RefreshLicense();
|
||||
}
|
||||
|
||||
if (TenantExtra.Opensource)
|
||||
{
|
||||
settings.Analytics = analytics;
|
||||
}
|
||||
settings.Completed = true;
|
||||
SettingsManager.Save(settings);
|
||||
|
||||
@ -194,8 +189,6 @@ namespace ASC.Web.Studio.UserControls.FirstTime
|
||||
StudioNotifyService.SendCongratulations(currentUser);
|
||||
StudioNotifyService.SendRegData(currentUser);
|
||||
|
||||
SendInstallInfo(currentUser);
|
||||
|
||||
if (subscribeFromSite && TenantExtra.Opensource && !CoreBaseSettings.CustomMode)
|
||||
{
|
||||
SubscribeFromSite(currentUser);
|
||||
@ -226,7 +219,7 @@ namespace ASC.Web.Studio.UserControls.FirstTime
|
||||
{
|
||||
get
|
||||
{
|
||||
return TenantExtra.EnableTarrifSettings && TenantExtra.Enterprise && !TenantExtra.EnterprisePaid;
|
||||
return TenantExtra.EnableTarrifSettings && TenantExtra.Enterprise;
|
||||
}
|
||||
}
|
||||
|
||||
@ -276,72 +269,29 @@ namespace ASC.Web.Studio.UserControls.FirstTime
|
||||
return string.IsNullOrEmpty(_amiId) || _amiId != customAmiId;
|
||||
}
|
||||
|
||||
public void SendInstallInfo(UserInfo user)
|
||||
{
|
||||
try
|
||||
{
|
||||
StudioNotifyService.SendRegData(user);
|
||||
|
||||
var url = Configuration["web:install-url"];
|
||||
if (string.IsNullOrEmpty(url)) return;
|
||||
|
||||
var tenant = TenantManager.GetCurrentTenant();
|
||||
var q = new MailQuery
|
||||
{
|
||||
Email = user.Email,
|
||||
Id = CoreSettings.GetKey(tenant.TenantId),
|
||||
Alias = tenant.GetTenantDomain(CoreSettings),
|
||||
};
|
||||
|
||||
var index = url.IndexOf("?v=", StringComparison.InvariantCultureIgnoreCase);
|
||||
if (0 < index)
|
||||
{
|
||||
q.Version = url.Substring(index + 3) + Environment.OSVersion;
|
||||
url = url.Substring(0, index);
|
||||
}
|
||||
|
||||
using var webClient = new WebClient();
|
||||
var values = new NameValueCollection
|
||||
{
|
||||
{"query", Signature.Create(q, "4be71393-0c90-41bf-b641-a8d9523fba5c")}
|
||||
};
|
||||
webClient.UploadValues(url, values);
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
Log.Error(error);
|
||||
}
|
||||
}
|
||||
|
||||
private void SubscribeFromSite(UserInfo user)
|
||||
{
|
||||
try
|
||||
{
|
||||
var url = (SetupInfo.TeamlabSiteRedirect ?? "").Trim().TrimEnd('/');
|
||||
|
||||
if (string.IsNullOrEmpty(url)) return;
|
||||
|
||||
url += "/post.ashx";
|
||||
|
||||
var request = (HttpWebRequest)WebRequest.Create(url);
|
||||
request.Method = "POST";
|
||||
request.ContentType = "application/x-www-form-urlencoded";
|
||||
request.Timeout = 10000;
|
||||
|
||||
var bodyString = string.Format("type=sendsubscription&email={0}", HttpUtility.UrlEncode(user.Email));
|
||||
var bytes = Encoding.UTF8.GetBytes(bodyString);
|
||||
request.ContentLength = bytes.Length;
|
||||
using (var stream = request.GetRequestStream())
|
||||
using (var webClient = new WebClient())
|
||||
{
|
||||
stream.Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
var values = new NameValueCollection
|
||||
{
|
||||
{ "type", "sendsubscription" },
|
||||
{ "subscr_type", "Opensource" },
|
||||
{ "email", user.Email }
|
||||
};
|
||||
|
||||
using (var response = request.GetResponse())
|
||||
using (var stream = response.GetResponseStream())
|
||||
{
|
||||
if (stream == null) throw new Exception("Response is null");
|
||||
var responseBody = webClient.UploadValues(url, values);
|
||||
var responseBodyStr = Encoding.UTF8.GetString(responseBody);
|
||||
|
||||
using var reader = new StreamReader(stream);
|
||||
Log.Debug("Subscribe response: " + reader.ReadToEnd());
|
||||
Log.Debug("Subscribe response: " + responseBodyStr);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -349,13 +299,5 @@ namespace ASC.Web.Studio.UserControls.FirstTime
|
||||
Log.Error("Subscribe request", e);
|
||||
}
|
||||
}
|
||||
|
||||
private class MailQuery
|
||||
{
|
||||
public string Email { get; set; }
|
||||
public string Version { get; set; }
|
||||
public string Id { get; set; }
|
||||
public string Alias { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
@ -30,7 +30,7 @@ using ASC.Core.Common.Settings;
|
||||
|
||||
namespace ASC.Web.Studio.Core
|
||||
{
|
||||
public class OpensourcePresentSettings : ISettings
|
||||
public class OpensourceGiftSettings : ISettings
|
||||
{
|
||||
public bool Readed { get; set; }
|
||||
|
||||
@ -43,7 +43,7 @@ namespace ASC.Web.Studio.Core
|
||||
|
||||
public ISettings GetDefault(IServiceProvider serviceProvider)
|
||||
{
|
||||
return new OpensourcePresentSettings { Readed = false };
|
||||
return new OpensourceGiftSettings { Readed = false };
|
||||
}
|
||||
|
||||
#endregion
|
@ -108,7 +108,7 @@ namespace ASC.Api.Settings
|
||||
// if (ConfigurationManagerExtension.AppSettings["web.talk"] != "true")
|
||||
// return null;
|
||||
|
||||
// return GetCommunityVersion();
|
||||
// return new JabberServiceClient().GetVersion();
|
||||
//}
|
||||
//catch (Exception e)
|
||||
//{
|
||||
|
@ -1,4 +1,4 @@
|
||||
using ASC.Data.Storage.Encryption;
|
||||
using ASC.Core.Encryption;
|
||||
|
||||
namespace ASC.Web.Api.Models
|
||||
{
|
||||
|
@ -8,12 +8,11 @@
|
||||
public string TimeZone { get; set; }
|
||||
public string Promocode { get; set; }
|
||||
public string AmiId { get; set; }
|
||||
public bool Analytics { get; set; }
|
||||
public bool SubscribeFromSite { get; set; }
|
||||
|
||||
public void Deconstruct(out string email, out string passwordHash, out string lng, out string timeZone, out string promocode, out string amiid, out bool analytics, out bool subscribeFromSite)
|
||||
public void Deconstruct(out string email, out string passwordHash, out string lng, out string timeZone, out string promocode, out string amiid, out bool subscribeFromSite)
|
||||
{
|
||||
(email, passwordHash, lng, timeZone, promocode, amiid, analytics, subscribeFromSite) = (Email, PasswordHash, Lng, TimeZone, Promocode, AmiId, Analytics, SubscribeFromSite);
|
||||
(email, passwordHash, lng, timeZone, promocode, amiid, subscribeFromSite) = (Email, PasswordHash, Lng, TimeZone, Promocode, AmiId, SubscribeFromSite);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\common\ASC.Common\ASC.Common.csproj" />
|
||||
<ProjectReference Include="..\..\common\ASC.Core.Common\ASC.Core.Common.csproj" />
|
||||
<ProjectReference Include="..\..\common\ASC.Data.Encryption\ASC.Data.Encryption.csproj" />
|
||||
<ProjectReference Include="..\..\common\ASC.Data.Storage\ASC.Data.Storage.csproj" />
|
||||
<ProjectReference Include="..\..\common\ASC.FederatedLogin\ASC.FederatedLogin.csproj" />
|
||||
<ProjectReference Include="..\..\common\ASC.Feed\ASC.Feed.csproj" />
|
||||
|
@ -138,60 +138,64 @@ namespace ASC.Web.Studio.Core.Notify
|
||||
(r, p, scope) =>
|
||||
{
|
||||
var scopeClass = scope.ServiceProvider.GetService<NotifyConfigurationScope>();
|
||||
var coreBaseSettings = scope.ServiceProvider.GetService<CoreBaseSettings>();
|
||||
var (tenantManager, webItemSecurity, userManager, options, _, _, _, _, _, _, _, _, _, _, _) = scopeClass;
|
||||
try
|
||||
{
|
||||
// culture
|
||||
var u = Constants.LostUser;
|
||||
var tenant = tenantManager.GetCurrentTenant();
|
||||
|
||||
if (32 <= r.Recipient.ID.Length)
|
||||
if (!(coreBaseSettings.Personal && r.NotifyAction.ID == Actions.PersonalConfirmation.ID))
|
||||
{
|
||||
var guid = default(Guid);
|
||||
try
|
||||
var tenant = tenantManager.GetCurrentTenant();
|
||||
|
||||
if (32 <= r.Recipient.ID.Length)
|
||||
{
|
||||
guid = new Guid(r.Recipient.ID);
|
||||
var guid = default(Guid);
|
||||
try
|
||||
{
|
||||
guid = new Guid(r.Recipient.ID);
|
||||
}
|
||||
catch (FormatException) { }
|
||||
catch (OverflowException) { }
|
||||
|
||||
if (guid != default)
|
||||
{
|
||||
u = userManager.GetUsers(guid);
|
||||
}
|
||||
}
|
||||
catch (FormatException) { }
|
||||
catch (OverflowException) { }
|
||||
|
||||
if (guid != default)
|
||||
if (Constants.LostUser.Equals(u))
|
||||
{
|
||||
u = userManager.GetUsers(guid);
|
||||
u = userManager.GetUserByEmail(r.Recipient.ID);
|
||||
}
|
||||
}
|
||||
|
||||
if (Constants.LostUser.Equals(u))
|
||||
{
|
||||
u = userManager.GetUserByEmail(r.Recipient.ID);
|
||||
}
|
||||
|
||||
if (Constants.LostUser.Equals(u))
|
||||
{
|
||||
u = userManager.GetUserByUserName(r.Recipient.ID);
|
||||
}
|
||||
|
||||
if (!Constants.LostUser.Equals(u))
|
||||
{
|
||||
var culture = !string.IsNullOrEmpty(u.CultureName) ? u.GetCulture() : tenant.GetCulture();
|
||||
Thread.CurrentThread.CurrentCulture = culture;
|
||||
Thread.CurrentThread.CurrentUICulture = culture;
|
||||
|
||||
// security
|
||||
var tag = r.Arguments.Find(a => a.Tag == CommonTags.ModuleID);
|
||||
var productId = tag != null ? (Guid)tag.Value : Guid.Empty;
|
||||
if (productId == Guid.Empty)
|
||||
if (Constants.LostUser.Equals(u))
|
||||
{
|
||||
tag = r.Arguments.Find(a => a.Tag == CommonTags.ProductID);
|
||||
productId = tag != null ? (Guid)tag.Value : Guid.Empty;
|
||||
u = userManager.GetUserByUserName(r.Recipient.ID);
|
||||
}
|
||||
if (productId == Guid.Empty)
|
||||
|
||||
if (!Constants.LostUser.Equals(u))
|
||||
{
|
||||
productId = (Guid)(CallContext.GetData("asc.web.product_id") ?? Guid.Empty);
|
||||
}
|
||||
if (productId != Guid.Empty && productId != new Guid("f4d98afdd336433287783c6945c81ea0") /* ignore people product */)
|
||||
{
|
||||
return !webItemSecurity.IsAvailableForUser(productId, u.ID);
|
||||
var culture = !string.IsNullOrEmpty(u.CultureName) ? u.GetCulture() : tenant.GetCulture();
|
||||
Thread.CurrentThread.CurrentCulture = culture;
|
||||
Thread.CurrentThread.CurrentUICulture = culture;
|
||||
|
||||
// security
|
||||
var tag = r.Arguments.Find(a => a.Tag == CommonTags.ModuleID);
|
||||
var productId = tag != null ? (Guid)tag.Value : Guid.Empty;
|
||||
if (productId == Guid.Empty)
|
||||
{
|
||||
tag = r.Arguments.Find(a => a.Tag == CommonTags.ProductID);
|
||||
productId = tag != null ? (Guid)tag.Value : Guid.Empty;
|
||||
}
|
||||
if (productId == Guid.Empty)
|
||||
{
|
||||
productId = (Guid)(CallContext.GetData("asc.web.product_id") ?? Guid.Empty);
|
||||
}
|
||||
if (productId != Guid.Empty && productId != new Guid("f4d98afdd336433287783c6945c81ea0") /* ignore people product */)
|
||||
{
|
||||
return !webItemSecurity.IsAvailableForUser(productId, u.ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user