Merge pull request #171 from ONLYOFFICE/release/v0.0.7

Release/v0.0.7
This commit is contained in:
Alexey Safronov 2021-01-14 18:30:28 +03:00 committed by GitHub
commit 7f92ac83a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
148 changed files with 4609 additions and 748 deletions

193
ASC.Tests.sln Normal file
View File

@ -0,0 +1,193 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30413.136
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Files.Tests", "products\ASC.Files\Tests\ASC.Files.Tests.csproj", "{EFB99A37-EF25-4A0F-8D7A-786402B1554C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Api.Core", "common\ASC.Api.Core\ASC.Api.Core.csproj", "{CAA6EED2-094A-42AE-81B6-3FDF142EC277}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Common", "common\ASC.Common\ASC.Common.csproj", "{19FFE246-4270-41A6-AA8D-FB961715FB21}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Core.Common", "common\ASC.Core.Common\ASC.Core.Common.csproj", "{A51D0454-4AFA-46DE-89D4-B03D37E1816C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Data.Storage", "common\ASC.Data.Storage\ASC.Data.Storage.csproj", "{D7F459CE-9EAF-423A-B3DC-EFD107007BCE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.FederatedLogin", "common\ASC.FederatedLogin\ASC.FederatedLogin.csproj", "{484E9663-B9B7-40CA-B600-D5FDCD7CB862}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.MessagingSystem", "common\ASC.MessagingSystem\ASC.MessagingSystem.csproj", "{AB0EFA45-1DAF-42F4-9EE1-4A8EC497DE35}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.ElasticSearch", "common\services\ASC.ElasticSearch\ASC.ElasticSearch.csproj", "{AE1A0E06-6CD4-4E1D-8209-22BBBD6D5652}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Files.Core", "products\ASC.Files\Core\ASC.Files.Core.csproj", "{C277388C-E19E-4A62-A895-8AAB322A4004}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Files", "products\ASC.Files\Server\ASC.Files.csproj", "{77BA2F61-6155-4283-BB39-F8E42F46A0B0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.People", "products\ASC.People\Server\ASC.People.csproj", "{DB492BA0-B072-4056-8A3D-032CD108CD82}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Web.Core", "web\ASC.Web.Core\ASC.Web.Core.csproj", "{9A703423-594E-4851-8A0D-FF582BAF9FC9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Data.Reassigns", "common\ASC.Data.Reassigns\ASC.Data.Reassigns.csproj", "{8682FCD3-C5C5-4946-99FA-B900E9CB68C3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Feed", "common\ASC.Feed\ASC.Feed.csproj", "{5A0DF88C-45C8-4FE2-8144-88E8AC8B7C45}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.IPSecurity", "common\ASC.IPSecurity\ASC.IPSecurity.csproj", "{5E5496B5-5686-4415-B3E0-5F61FCD146A3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Notify.Textile", "common\ASC.Notify.Textile\ASC.Notify.Textile.csproj", "{5FE0EDA2-1FD7-4D43-885E-DBDD858DCC86}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Textile", "common\ASC.Textile\ASC.Textile.csproj", "{1A82BE07-0836-4620-A95D-C6D1E9327589}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.VoipService", "common\ASC.VoipService\ASC.VoipService.csproj", "{664031A4-1652-4B68-8168-FD18998700EE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.UrlShortener.Svc", "common\services\ASC.UrlShortener.Svc\ASC.UrlShortener.Svc.csproj", "{7DC27057-7B61-4381-BF35-ACED2C9987BC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Thumbnails.Svc", "common\services\ASC.Thumbnails.Svc\ASC.Thumbnails.Svc.csproj", "{920A59BF-8EFC-4E0F-82D8-935CC6FD570A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Studio.Notify", "common\services\ASC.Studio.Notify\ASC.Studio.Notify.csproj", "{C024C35A-D0F0-42D6-86B2-64ABF7513C4A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Socket.IO.Svc", "common\services\ASC.Socket.IO.Svc\ASC.Socket.IO.Svc.csproj", "{60CB362A-72F4-426E-BBAE-9A9B7426ED04}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Notify", "common\services\ASC.Notify\ASC.Notify.csproj", "{B30A0D35-7B32-4E13-9F37-B8BC59F839E5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Feed.Aggregator", "common\services\ASC.Feed.Aggregator\ASC.Feed.Aggregator.csproj", "{8ACDEBBD-12DD-43DC-86CF-D66E37528ACC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Data.Storage.Migration", "common\services\ASC.Data.Storage.Migration\ASC.Data.Storage.Migration.csproj", "{1E2A4FE7-5B61-4E76-B62A-3E9CC9FA647C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Data.Backup", "common\services\ASC.Data.Backup\ASC.Data.Backup.csproj", "{630E2649-71B6-4C07-A2FC-C0BC05D77A78}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.ApiSystem", "common\services\ASC.ApiSystem\ASC.ApiSystem.csproj", "{053AFC13-8EF6-43B6-9514-ED9DBBDC3093}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Web.Api", "web\ASC.Web.Api\ASC.Web.Api.csproj", "{D7C5E8A0-0A5E-4BC4-9946-B43D6682D421}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Web.Studio", "web\ASC.Web.Studio\ASC.Web.Studio.csproj", "{9BF17F6E-04A9-4597-9273-21AD09600329}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{EFB99A37-EF25-4A0F-8D7A-786402B1554C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EFB99A37-EF25-4A0F-8D7A-786402B1554C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EFB99A37-EF25-4A0F-8D7A-786402B1554C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EFB99A37-EF25-4A0F-8D7A-786402B1554C}.Release|Any CPU.Build.0 = Release|Any CPU
{CAA6EED2-094A-42AE-81B6-3FDF142EC277}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CAA6EED2-094A-42AE-81B6-3FDF142EC277}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CAA6EED2-094A-42AE-81B6-3FDF142EC277}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CAA6EED2-094A-42AE-81B6-3FDF142EC277}.Release|Any CPU.Build.0 = Release|Any CPU
{19FFE246-4270-41A6-AA8D-FB961715FB21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19FFE246-4270-41A6-AA8D-FB961715FB21}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19FFE246-4270-41A6-AA8D-FB961715FB21}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19FFE246-4270-41A6-AA8D-FB961715FB21}.Release|Any CPU.Build.0 = Release|Any CPU
{A51D0454-4AFA-46DE-89D4-B03D37E1816C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A51D0454-4AFA-46DE-89D4-B03D37E1816C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A51D0454-4AFA-46DE-89D4-B03D37E1816C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A51D0454-4AFA-46DE-89D4-B03D37E1816C}.Release|Any CPU.Build.0 = Release|Any CPU
{D7F459CE-9EAF-423A-B3DC-EFD107007BCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D7F459CE-9EAF-423A-B3DC-EFD107007BCE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D7F459CE-9EAF-423A-B3DC-EFD107007BCE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D7F459CE-9EAF-423A-B3DC-EFD107007BCE}.Release|Any CPU.Build.0 = Release|Any CPU
{484E9663-B9B7-40CA-B600-D5FDCD7CB862}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{484E9663-B9B7-40CA-B600-D5FDCD7CB862}.Debug|Any CPU.Build.0 = Debug|Any CPU
{484E9663-B9B7-40CA-B600-D5FDCD7CB862}.Release|Any CPU.ActiveCfg = Release|Any CPU
{484E9663-B9B7-40CA-B600-D5FDCD7CB862}.Release|Any CPU.Build.0 = Release|Any CPU
{AB0EFA45-1DAF-42F4-9EE1-4A8EC497DE35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AB0EFA45-1DAF-42F4-9EE1-4A8EC497DE35}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AB0EFA45-1DAF-42F4-9EE1-4A8EC497DE35}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AB0EFA45-1DAF-42F4-9EE1-4A8EC497DE35}.Release|Any CPU.Build.0 = Release|Any CPU
{AE1A0E06-6CD4-4E1D-8209-22BBBD6D5652}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AE1A0E06-6CD4-4E1D-8209-22BBBD6D5652}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AE1A0E06-6CD4-4E1D-8209-22BBBD6D5652}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AE1A0E06-6CD4-4E1D-8209-22BBBD6D5652}.Release|Any CPU.Build.0 = Release|Any CPU
{C277388C-E19E-4A62-A895-8AAB322A4004}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C277388C-E19E-4A62-A895-8AAB322A4004}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C277388C-E19E-4A62-A895-8AAB322A4004}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C277388C-E19E-4A62-A895-8AAB322A4004}.Release|Any CPU.Build.0 = Release|Any CPU
{77BA2F61-6155-4283-BB39-F8E42F46A0B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{77BA2F61-6155-4283-BB39-F8E42F46A0B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{77BA2F61-6155-4283-BB39-F8E42F46A0B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{77BA2F61-6155-4283-BB39-F8E42F46A0B0}.Release|Any CPU.Build.0 = Release|Any CPU
{DB492BA0-B072-4056-8A3D-032CD108CD82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DB492BA0-B072-4056-8A3D-032CD108CD82}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DB492BA0-B072-4056-8A3D-032CD108CD82}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DB492BA0-B072-4056-8A3D-032CD108CD82}.Release|Any CPU.Build.0 = Release|Any CPU
{9A703423-594E-4851-8A0D-FF582BAF9FC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9A703423-594E-4851-8A0D-FF582BAF9FC9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9A703423-594E-4851-8A0D-FF582BAF9FC9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9A703423-594E-4851-8A0D-FF582BAF9FC9}.Release|Any CPU.Build.0 = Release|Any CPU
{8682FCD3-C5C5-4946-99FA-B900E9CB68C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8682FCD3-C5C5-4946-99FA-B900E9CB68C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8682FCD3-C5C5-4946-99FA-B900E9CB68C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8682FCD3-C5C5-4946-99FA-B900E9CB68C3}.Release|Any CPU.Build.0 = Release|Any CPU
{5A0DF88C-45C8-4FE2-8144-88E8AC8B7C45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5A0DF88C-45C8-4FE2-8144-88E8AC8B7C45}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5A0DF88C-45C8-4FE2-8144-88E8AC8B7C45}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5A0DF88C-45C8-4FE2-8144-88E8AC8B7C45}.Release|Any CPU.Build.0 = Release|Any CPU
{5E5496B5-5686-4415-B3E0-5F61FCD146A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5E5496B5-5686-4415-B3E0-5F61FCD146A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5E5496B5-5686-4415-B3E0-5F61FCD146A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5E5496B5-5686-4415-B3E0-5F61FCD146A3}.Release|Any CPU.Build.0 = Release|Any CPU
{5FE0EDA2-1FD7-4D43-885E-DBDD858DCC86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5FE0EDA2-1FD7-4D43-885E-DBDD858DCC86}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5FE0EDA2-1FD7-4D43-885E-DBDD858DCC86}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5FE0EDA2-1FD7-4D43-885E-DBDD858DCC86}.Release|Any CPU.Build.0 = Release|Any CPU
{1A82BE07-0836-4620-A95D-C6D1E9327589}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1A82BE07-0836-4620-A95D-C6D1E9327589}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1A82BE07-0836-4620-A95D-C6D1E9327589}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1A82BE07-0836-4620-A95D-C6D1E9327589}.Release|Any CPU.Build.0 = Release|Any CPU
{664031A4-1652-4B68-8168-FD18998700EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{664031A4-1652-4B68-8168-FD18998700EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{664031A4-1652-4B68-8168-FD18998700EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{664031A4-1652-4B68-8168-FD18998700EE}.Release|Any CPU.Build.0 = Release|Any CPU
{7DC27057-7B61-4381-BF35-ACED2C9987BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7DC27057-7B61-4381-BF35-ACED2C9987BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7DC27057-7B61-4381-BF35-ACED2C9987BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7DC27057-7B61-4381-BF35-ACED2C9987BC}.Release|Any CPU.Build.0 = Release|Any CPU
{920A59BF-8EFC-4E0F-82D8-935CC6FD570A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{920A59BF-8EFC-4E0F-82D8-935CC6FD570A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{920A59BF-8EFC-4E0F-82D8-935CC6FD570A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{920A59BF-8EFC-4E0F-82D8-935CC6FD570A}.Release|Any CPU.Build.0 = Release|Any CPU
{C024C35A-D0F0-42D6-86B2-64ABF7513C4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C024C35A-D0F0-42D6-86B2-64ABF7513C4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C024C35A-D0F0-42D6-86B2-64ABF7513C4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C024C35A-D0F0-42D6-86B2-64ABF7513C4A}.Release|Any CPU.Build.0 = Release|Any CPU
{60CB362A-72F4-426E-BBAE-9A9B7426ED04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{60CB362A-72F4-426E-BBAE-9A9B7426ED04}.Debug|Any CPU.Build.0 = Debug|Any CPU
{60CB362A-72F4-426E-BBAE-9A9B7426ED04}.Release|Any CPU.ActiveCfg = Release|Any CPU
{60CB362A-72F4-426E-BBAE-9A9B7426ED04}.Release|Any CPU.Build.0 = Release|Any CPU
{B30A0D35-7B32-4E13-9F37-B8BC59F839E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B30A0D35-7B32-4E13-9F37-B8BC59F839E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B30A0D35-7B32-4E13-9F37-B8BC59F839E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B30A0D35-7B32-4E13-9F37-B8BC59F839E5}.Release|Any CPU.Build.0 = Release|Any CPU
{8ACDEBBD-12DD-43DC-86CF-D66E37528ACC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8ACDEBBD-12DD-43DC-86CF-D66E37528ACC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8ACDEBBD-12DD-43DC-86CF-D66E37528ACC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8ACDEBBD-12DD-43DC-86CF-D66E37528ACC}.Release|Any CPU.Build.0 = Release|Any CPU
{1E2A4FE7-5B61-4E76-B62A-3E9CC9FA647C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1E2A4FE7-5B61-4E76-B62A-3E9CC9FA647C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E2A4FE7-5B61-4E76-B62A-3E9CC9FA647C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1E2A4FE7-5B61-4E76-B62A-3E9CC9FA647C}.Release|Any CPU.Build.0 = Release|Any CPU
{630E2649-71B6-4C07-A2FC-C0BC05D77A78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{630E2649-71B6-4C07-A2FC-C0BC05D77A78}.Debug|Any CPU.Build.0 = Debug|Any CPU
{630E2649-71B6-4C07-A2FC-C0BC05D77A78}.Release|Any CPU.ActiveCfg = Release|Any CPU
{630E2649-71B6-4C07-A2FC-C0BC05D77A78}.Release|Any CPU.Build.0 = Release|Any CPU
{053AFC13-8EF6-43B6-9514-ED9DBBDC3093}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{053AFC13-8EF6-43B6-9514-ED9DBBDC3093}.Debug|Any CPU.Build.0 = Debug|Any CPU
{053AFC13-8EF6-43B6-9514-ED9DBBDC3093}.Release|Any CPU.ActiveCfg = Release|Any CPU
{053AFC13-8EF6-43B6-9514-ED9DBBDC3093}.Release|Any CPU.Build.0 = Release|Any CPU
{D7C5E8A0-0A5E-4BC4-9946-B43D6682D421}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D7C5E8A0-0A5E-4BC4-9946-B43D6682D421}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D7C5E8A0-0A5E-4BC4-9946-B43D6682D421}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D7C5E8A0-0A5E-4BC4-9946-B43D6682D421}.Release|Any CPU.Build.0 = Release|Any CPU
{9BF17F6E-04A9-4597-9273-21AD09600329}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9BF17F6E-04A9-4597-9273-21AD09600329}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9BF17F6E-04A9-4597-9273-21AD09600329}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9BF17F6E-04A9-4597-9273-21AD09600329}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {73201867-1BA9-4F5E-AA69-AFA74662FFFC}
EndGlobalSection
EndGlobal

76
build/Jenkinsfile vendored
View File

@ -60,40 +60,58 @@ pipeline {
parallel { parallel {
stage('Unix') { stage('Unix') {
agent { label 'net-core' } agent { label 'net-core' }
steps { stages {
sh "sh ./build/scripts/components.sh && cd ${env.WORKSPACE}/web/ASC.Web.Components && yarn test:coverage --ci --reporters=default --reporters=jest-junit || true" stage('Components') {
} steps {
post { sh "sh ./build/scripts/components.sh && cd ${env.WORKSPACE}/web/ASC.Web.Components && yarn test:coverage --ci --reporters=default --reporters=jest-junit || true"
success { }
junit 'web/ASC.Web.Components/junit.xml' post {
publishHTML target: [ success {
allowMissing : false, junit 'web/ASC.Web.Components/junit.xml'
alwaysLinkToLastBuild: false, publishHTML target: [
keepAll : true, allowMissing : false,
reportDir : 'web/ASC.Web.Components/coverage/lcov-report', alwaysLinkToLastBuild: false,
reportFiles : 'index.html', keepAll : true,
reportName : 'Unix Test Report' reportDir : 'web/ASC.Web.Components/coverage/lcov-report',
] reportFiles : 'index.html',
publishCoverage adapters: [coberturaAdapter('web/ASC.Web.Components/coverage/cobertura-coverage.xml')] reportName : 'Unix Test Report'
]
publishCoverage adapters: [coberturaAdapter('web/ASC.Web.Components/coverage/cobertura-coverage.xml')]
}
}
}
stage('Files') {
steps {
sh "dotnet restore ASC.Web.sln --configfile .nuget/NuGet.Config && cd ${env.WORKSPACE}/products/ASC.Files/Tests/ && dotnet test ASC.Files.Tests.csproj -r linux-x64 -l \"console;verbosity=detailed\""
}
} }
} }
} }
stage('Windows') { stage('Windows') {
agent { label 'win-core' } agent { label 'win-core' }
steps { stages {
bat "sh build\\scripts\\components.sh && cd ${env.WORKSPACE}\\web\\ASC.Web.Components && yarn test:coverage --ci --reporters=default --reporters=jest-junit || true" stage('Components') {
} steps {
post { bat "sh build\\scripts\\components.sh && cd ${env.WORKSPACE}\\web\\ASC.Web.Components && yarn test:coverage --ci --reporters=default --reporters=jest-junit || true"
success { }
junit 'web\\ASC.Web.Components\\junit.xml' post {
publishHTML target: [ success {
allowMissing : false, junit 'web\\ASC.Web.Components\\junit.xml'
alwaysLinkToLastBuild: false, publishHTML target: [
keepAll : true, allowMissing : false,
reportDir : 'web\\ASC.Web.Components\\coverage\\lcov-report', alwaysLinkToLastBuild: false,
reportFiles : 'index.html', keepAll : true,
reportName : 'Windows Test Report' reportDir : 'web\\ASC.Web.Components\\coverage\\lcov-report',
] reportFiles : 'index.html',
reportName : 'Windows Test Report'
]
}
}
}
stage('Files') {
steps {
bat "dotnet restore ASC.Web.sln --configfile .nuget\\NuGet.Config && cd ${env.WORKSPACE}\\products\\ASC.Files\\Tests\\ && dotnet test ASC.Files.Tests.csproj"
}
} }
} }
} }

View File

@ -2,14 +2,12 @@
FROM ubuntu:18.04 AS develop FROM ubuntu:18.04 AS develop
ARG RELEASE_DATE="2016-06-21" ARG RELEASE_DATE="2016-06-21"
ARG RELEASE_DATE_SIGN=""
ARG VERSION="8.9.0.190" 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 DEBIAN_FRONTEND=noninteractive
ARG GIT_BRANCH="master" ARG GIT_BRANCH="master"
LABEL onlyoffice.community.release-date="${RELEASE_DATE}" \ LABEL onlyoffice.appserver.release-date="${RELEASE_DATE}" \
onlyoffice.community.version="${VERSION}" \ onlyoffice.appserver.version="${VERSION}" \
maintainer="Ascensio System SIA <support@onlyoffice.com>" maintainer="Ascensio System SIA <support@onlyoffice.com>"
ENV LANG=en_US.UTF-8 \ ENV LANG=en_US.UTF-8 \

View File

@ -41,6 +41,7 @@ namespace ASC.Api.Core
public virtual void ConfigureServices(IServiceCollection services) public virtual void ConfigureServices(IServiceCollection services)
{ {
services.AddHttpContextAccessor(); services.AddHttpContextAccessor();
services.AddMemoryCache();
DIHelper.Configure(services); DIHelper.Configure(services);

View File

@ -47,6 +47,7 @@
<PackageReference Include="Microsoft.AspNetCore.Http.Features" Version="3.1.9" /> <PackageReference Include="Microsoft.AspNetCore.Http.Features" Version="3.1.9" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" /> <PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.9" /> <PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.9" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="3.1.9" /> <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="3.1.9" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.9" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.9" />

View File

@ -32,6 +32,8 @@ using System.Text.RegularExpressions;
using Google.Protobuf; using Google.Protobuf;
using Microsoft.Extensions.Caching.Memory;
namespace ASC.Common.Caching namespace ASC.Common.Caching
{ {
[Singletone] [Singletone]
@ -61,71 +63,59 @@ namespace ASC.Common.Caching
} }
} }
} }
[Singletone]
public class AscCache : ICache public class AscCache : ICache
{ {
public static readonly ICache Memory; private IMemoryCache MemoryCache { get; }
static AscCache() public AscCache(IMemoryCache memoryCache)
{ {
Memory = new AscCache(); MemoryCache = memoryCache;
}
private AscCache()
{
} }
public T Get<T>(string key) where T : class public T Get<T>(string key) where T : class
{ {
var cache = GetCache(); return MemoryCache.Get<T>(key);
return cache.Get(key) as T;
} }
public void Insert(string key, object value, TimeSpan sligingExpiration) public void Insert(string key, object value, TimeSpan sligingExpiration)
{ {
var cache = GetCache(); MemoryCache.Set(key, value, new MemoryCacheEntryOptions(){ SlidingExpiration = sligingExpiration });
cache.Set(key, value, new CacheItemPolicy { SlidingExpiration = sligingExpiration });
} }
public void Insert(string key, object value, DateTime absolutExpiration) public void Insert(string key, object value, DateTime absolutExpiration)
{ {
var cache = GetCache(); MemoryCache.Set(key, value, absolutExpiration == DateTime.MaxValue ? DateTimeOffset.MaxValue : new DateTimeOffset(absolutExpiration));
cache.Set(key, value,
absolutExpiration == DateTime.MaxValue ? DateTimeOffset.MaxValue : new DateTimeOffset(absolutExpiration));
} }
public void Remove(string key) public void Remove(string key)
{ {
var cache = GetCache(); MemoryCache.Remove(key);
cache.Remove(key);
} }
public void Remove(Regex pattern) public void Remove(Regex pattern)
{ {
var cache = GetCache(); //var cache = GetCache();
var copy = cache.ToDictionary(p => p.Key, p => p.Value); //var copy = cache.ToDictionary(p => p.Key, p => p.Value);
var keys = copy.Select(p => p.Key).Where(k => pattern.IsMatch(k)).ToArray(); //var keys = copy.Select(p => p.Key).Where(k => pattern.IsMatch(k)).ToArray();
foreach (var key in keys) //foreach (var key in keys)
{ //{
cache.Remove(key); // cache.Remove(key);
} //}
} }
public ConcurrentDictionary<string, T> HashGetAll<T>(string key) public ConcurrentDictionary<string, T> HashGetAll<T>(string key)
{ {
var cache = GetCache(); return MemoryCache.GetOrCreate(key, r=> new ConcurrentDictionary<string, T>());
var dic = (ConcurrentDictionary<string, T>)cache.Get(key);
return dic != null ? dic : new ConcurrentDictionary<string, T>();
} }
public T HashGet<T>(string key, string field) public T HashGet<T>(string key, string field)
{ {
var cache = GetCache(); if (MemoryCache.TryGetValue<ConcurrentDictionary<string, T>>(key, out var dic) && dic.TryGetValue(field, out var value))
var dic = (ConcurrentDictionary<string, T>)cache.Get(key);
if (dic != null && dic.TryGetValue(field, out var value))
{ {
return value; return value;
} }
@ -134,30 +124,24 @@ namespace ASC.Common.Caching
public void HashSet<T>(string key, string field, T value) public void HashSet<T>(string key, string field, T value)
{ {
var cache = GetCache();
var dic = HashGetAll<T>(key); var dic = HashGetAll<T>(key);
if (value != null) if (value != null)
{ {
dic.AddOrUpdate(field, value, (k, v) => value); dic.AddOrUpdate(field, value, (k, v) => value);
cache.Set(key, dic, null); MemoryCache.Set(key, dic, DateTime.MaxValue);
} }
else if (dic != null) else if (dic != null)
{ {
dic.TryRemove(field, out _); dic.TryRemove(field, out _);
if (dic.Count == 0) if (dic.Count == 0)
{ {
cache.Remove(key); MemoryCache.Remove(key);
} }
else else
{ {
cache.Set(key, dic, null); MemoryCache.Set(key, dic, DateTime.MaxValue);
} }
} }
} }
private MemoryCache GetCache()
{
return MemoryCache.Default;
}
} }
} }

View File

@ -29,7 +29,8 @@ using System.Collections.Concurrent;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
namespace ASC.Common.Caching namespace ASC.Common.Caching
{ {
[Singletone(typeof(AscCache))]
public interface ICache public interface ICache
{ {
T Get<T>(string key) where T : class; T Get<T>(string key) where T : class;

View File

@ -101,22 +101,8 @@ namespace ASC.Common.Threading
var prop = DistributedTaskCache.Props.FirstOrDefault(r => r.Key == name); var prop = DistributedTaskCache.Props.FirstOrDefault(r => r.Key == name);
if (prop == null) return default; if (prop == null) return default;
var resType = typeof(T);
var val = prop.Value.Trim('"');
object result = val;
if(resType == typeof(Guid))
{
result = Guid.Parse(val);
}
else if(resType.IsEnum)
{
Enum.TryParse(resType, val, out var e);
result = e;
}
return (T)Convert.ChangeType(result, resType); return JsonSerializer.Deserialize<T>(prop.Value);
} }
public void SetProperty(string name, object value) public void SetProperty(string name, object value)

View File

@ -32,8 +32,8 @@ using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using ASC.Common.Caching; using ASC.Common.Caching;
namespace ASC.Common.Threading namespace ASC.Common.Threading
{ {
[Singletone] [Singletone]
@ -44,11 +44,14 @@ namespace ASC.Common.Threading
private readonly ICacheNotify<DistributedTaskCancelation> notify; private readonly ICacheNotify<DistributedTaskCancelation> notify;
private readonly ICacheNotify<DistributedTaskCache> notifyCache; private readonly ICacheNotify<DistributedTaskCache> notifyCache;
public DistributedTaskCacheNotify(ICacheNotify<DistributedTaskCancelation> notify, ICacheNotify<DistributedTaskCache> notifyCache) public DistributedTaskCacheNotify(
ICacheNotify<DistributedTaskCancelation> notify,
ICacheNotify<DistributedTaskCache> notifyCache,
ICache cache)
{ {
Cancelations = new ConcurrentDictionary<string, CancellationTokenSource>(); Cancelations = new ConcurrentDictionary<string, CancellationTokenSource>();
Cache = AscCache.Memory; Cache = cache;
this.notify = notify; this.notify = notify;
@ -121,7 +124,7 @@ namespace ASC.Common.Threading
key = name + GetType().Name; key = name + GetType().Name;
scheduler = maxThreadsCount <= 0 scheduler = maxThreadsCount <= 0
? TaskScheduler.Default ? TaskScheduler.Default
: new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, 4).ConcurrentScheduler; : new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, maxThreadsCount).ConcurrentScheduler;
DistributedTaskCacheNotify = distributedTaskCacheNotify; DistributedTaskCacheNotify = distributedTaskCacheNotify;
cancelations = DistributedTaskCacheNotify.Cancelations; cancelations = DistributedTaskCacheNotify.Cancelations;
cache = DistributedTaskCacheNotify.Cache; cache = DistributedTaskCacheNotify.Cache;
@ -139,9 +142,9 @@ namespace ASC.Common.Threading
var cancelation = new CancellationTokenSource(); var cancelation = new CancellationTokenSource();
var token = cancelation.Token; var token = cancelation.Token;
cancelations[distributedTask.Id] = cancelation; cancelations[distributedTask.Id] = cancelation;
var task = new Task(() => action(distributedTask, token), token, TaskCreationOptions.LongRunning); var task = new Task(() => { action(distributedTask, token); }, token, TaskCreationOptions.LongRunning);
task task
.ConfigureAwait(false) .ConfigureAwait(false)
.GetAwaiter() .GetAwaiter()
@ -160,7 +163,7 @@ namespace ASC.Common.Threading
public IEnumerable<DistributedTask> GetTasks() public IEnumerable<DistributedTask> GetTasks()
{ {
var tasks = cache.HashGetAll<DistributedTaskCache>(key).Values.Select(r => new DistributedTask(r)).ToList(); var tasks = cache.HashGetAll<DistributedTaskCache>(key).Select(r => new DistributedTask(r.Value)).ToList();
tasks.ForEach(t => tasks.ForEach(t =>
{ {
if (t.Publication == null) if (t.Publication == null)

View File

@ -80,5 +80,11 @@ namespace ASC.Common.Utils
{ {
return GetConnectionStrings()[key]; return GetConnectionStrings()[key];
} }
public string this[string key]
{
get => Configuration[key];
set => Configuration[key] = value;
}
} }
} }

View File

@ -60,7 +60,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.9" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.9" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.9" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.4" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.4" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.2.3" /> <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="3.2.4" />
<PackageReference Include="System.Text.Json" Version="4.7.2" /> <PackageReference Include="System.Text.Json" Version="4.7.2" />
<PackageReference Include="Telegram.Bot" Version="15.7.1" /> <PackageReference Include="Telegram.Bot" Version="15.7.1" />
</ItemGroup> </ItemGroup>

View File

@ -49,9 +49,9 @@ namespace ASC.Core.Billing
public ICache Cache { get; } public ICache Cache { get; }
internal ICacheNotify<TariffCacheItem> Notify { get; } internal ICacheNotify<TariffCacheItem> Notify { get; }
public TariffServiceStorage(ICacheNotify<TariffCacheItem> notify) public TariffServiceStorage(ICacheNotify<TariffCacheItem> notify, ICache cache)
{ {
Cache = AscCache.Memory; Cache = cache;
Notify = notify; Notify = notify;
Notify.Subscribe((i) => Notify.Subscribe((i) =>
{ {

View File

@ -39,10 +39,10 @@ namespace ASC.Core.Caching
internal ICache Cache { get; } internal ICache Cache { get; }
internal ICacheNotify<AzRecordCache> CacheNotify { get; } internal ICacheNotify<AzRecordCache> CacheNotify { get; }
public AzServiceCache(ICacheNotify<AzRecordCache> cacheNotify) public AzServiceCache(ICacheNotify<AzRecordCache> cacheNotify, ICache cache)
{ {
CacheNotify = cacheNotify; CacheNotify = cacheNotify;
Cache = AscCache.Memory; Cache = cache;
cacheNotify.Subscribe((r) => UpdateCache(r, true), CacheNotifyAction.Remove); cacheNotify.Subscribe((r) => UpdateCache(r, true), CacheNotifyAction.Remove);
cacheNotify.Subscribe((r) => UpdateCache(r, false), CacheNotifyAction.InsertOrUpdate); cacheNotify.Subscribe((r) => UpdateCache(r, false), CacheNotifyAction.InsertOrUpdate);

View File

@ -50,7 +50,7 @@ namespace ASC.Core.Caching
internal bool QuotaCacheEnabled { get; } internal bool QuotaCacheEnabled { get; }
public QuotaServiceCache(IConfiguration Configuration, ICacheNotify<QuotaCacheItem> cacheNotify) public QuotaServiceCache(IConfiguration Configuration, ICacheNotify<QuotaCacheItem> cacheNotify, ICache cache)
{ {
if (Configuration["core:enable-quota-cache"] == null) if (Configuration["core:enable-quota-cache"] == null)
{ {
@ -62,7 +62,7 @@ namespace ASC.Core.Caching
} }
CacheNotify = cacheNotify; CacheNotify = cacheNotify;
Cache = AscCache.Memory; Cache = cache;
Interval = new TrustInterval(); Interval = new TrustInterval();
cacheNotify.Subscribe((i) => cacheNotify.Subscribe((i) =>

View File

@ -41,9 +41,9 @@ namespace ASC.Core.Caching
internal ICacheNotify<SubscriptionRecord> NotifyRecord { get; } internal ICacheNotify<SubscriptionRecord> NotifyRecord { get; }
internal ICacheNotify<SubscriptionMethodCache> NotifyMethod { get; } internal ICacheNotify<SubscriptionMethodCache> NotifyMethod { get; }
public SubscriptionServiceCache(ICacheNotify<SubscriptionRecord> notifyRecord, ICacheNotify<SubscriptionMethodCache> notifyMethod) public SubscriptionServiceCache(ICacheNotify<SubscriptionRecord> notifyRecord, ICacheNotify<SubscriptionMethodCache> notifyMethod, ICache cache)
{ {
Cache = AscCache.Memory; Cache = cache;
NotifyRecord = notifyRecord; NotifyRecord = notifyRecord;
NotifyMethod = notifyMethod; NotifyMethod = notifyMethod;

View File

@ -45,11 +45,15 @@ namespace ASC.Core.Caching
internal ICacheNotify<TenantCacheItem> CacheNotifyItem { get; } internal ICacheNotify<TenantCacheItem> CacheNotifyItem { get; }
internal ICacheNotify<TenantSetting> CacheNotifySettings { get; } internal ICacheNotify<TenantSetting> CacheNotifySettings { get; }
public TenantServiceCache(CoreBaseSettings coreBaseSettings, ICacheNotify<TenantCacheItem> cacheNotifyItem, ICacheNotify<TenantSetting> cacheNotifySettings) public TenantServiceCache(
CoreBaseSettings coreBaseSettings,
ICacheNotify<TenantCacheItem> cacheNotifyItem,
ICacheNotify<TenantSetting> cacheNotifySettings,
ICache cache)
{ {
CacheNotifyItem = cacheNotifyItem; CacheNotifyItem = cacheNotifyItem;
CacheNotifySettings = cacheNotifySettings; CacheNotifySettings = cacheNotifySettings;
Cache = AscCache.Memory; Cache = cache;
CacheExpiration = TimeSpan.FromMinutes(2); CacheExpiration = TimeSpan.FromMinutes(2);
cacheNotifyItem.Subscribe((t) => cacheNotifyItem.Subscribe((t) =>
@ -194,12 +198,12 @@ namespace ASC.Core.Caching
public CachedTenantService() public CachedTenantService()
{ {
cache = AscCache.Memory;
SettingsExpiration = TimeSpan.FromMinutes(2); SettingsExpiration = TimeSpan.FromMinutes(2);
} }
public CachedTenantService(DbTenantService service, TenantServiceCache tenantServiceCache) : this() public CachedTenantService(DbTenantService service, TenantServiceCache tenantServiceCache, ICache cache) : this()
{ {
this.cache = cache;
Service = service ?? throw new ArgumentNullException("service"); Service = service ?? throw new ArgumentNullException("service");
TenantServiceCache = tenantServiceCache; TenantServiceCache = tenantServiceCache;
CacheNotifyItem = tenantServiceCache.CacheNotifyItem; CacheNotifyItem = tenantServiceCache.CacheNotifyItem;

View File

@ -49,7 +49,7 @@ namespace ASC.Core.Caching
public const string REFS = "refs"; public const string REFS = "refs";
public TrustInterval TrustInterval { get; set; } public TrustInterval TrustInterval { get; set; }
public ICache Cache { get; } internal ICache Cache { get; }
internal CoreBaseSettings CoreBaseSettings { get; } internal CoreBaseSettings CoreBaseSettings { get; }
internal ICacheNotify<UserInfoCacheItem> CacheUserInfoItem { get; } internal ICacheNotify<UserInfoCacheItem> CacheUserInfoItem { get; }
internal ICacheNotify<UserPhotoCacheItem> CacheUserPhotoItem { get; } internal ICacheNotify<UserPhotoCacheItem> CacheUserPhotoItem { get; }
@ -61,10 +61,11 @@ namespace ASC.Core.Caching
ICacheNotify<UserInfoCacheItem> cacheUserInfoItem, ICacheNotify<UserInfoCacheItem> cacheUserInfoItem,
ICacheNotify<UserPhotoCacheItem> cacheUserPhotoItem, ICacheNotify<UserPhotoCacheItem> cacheUserPhotoItem,
ICacheNotify<GroupCacheItem> cacheGroupCacheItem, ICacheNotify<GroupCacheItem> cacheGroupCacheItem,
ICacheNotify<UserGroupRefCacheItem> cacheUserGroupRefItem) ICacheNotify<UserGroupRefCacheItem> cacheUserGroupRefItem,
ICache cache)
{ {
TrustInterval = new TrustInterval(); TrustInterval = new TrustInterval();
Cache = AscCache.Memory; Cache = cache;
CoreBaseSettings = coreBaseSettings; CoreBaseSettings = coreBaseSettings;
CacheUserInfoItem = cacheUserInfoItem; CacheUserInfoItem = cacheUserInfoItem;
CacheUserPhotoItem = cacheUserPhotoItem; CacheUserPhotoItem = cacheUserPhotoItem;

View File

@ -56,11 +56,11 @@ namespace ASC.Core
}; };
} }
public SubscriptionManager(ISubscriptionService service, TenantManager tenantManager) public SubscriptionManager(ISubscriptionService service, TenantManager tenantManager, ICache cache)
{ {
this.service = service ?? throw new ArgumentNullException("subscriptionManager"); this.service = service ?? throw new ArgumentNullException("subscriptionManager");
TenantManager = tenantManager; TenantManager = tenantManager;
Cache = AscCache.Memory; Cache = cache;
} }

View File

@ -48,9 +48,9 @@ namespace ASC.Core.Data
public ICache Cache { get; } public ICache Cache { get; }
private ICacheNotify<SettingsCacheItem> Notify { get; } private ICacheNotify<SettingsCacheItem> Notify { get; }
public DbSettingsManagerCache(ICacheNotify<SettingsCacheItem> notify) public DbSettingsManagerCache(ICacheNotify<SettingsCacheItem> notify, ICache cache)
{ {
Cache = AscCache.Memory; Cache = cache;
Notify = notify; Notify = notify;
Notify.Subscribe((i) => Cache.Remove(i.Key), CacheNotifyAction.Remove); Notify.Subscribe((i) => Cache.Remove(i.Key), CacheNotifyAction.Remove);
} }

View File

@ -24,6 +24,7 @@ namespace ASC.Core.Common.EF
} }
internal string MigrateAssembly { get; set; }
internal ILoggerFactory LoggerFactory { get; set; } internal ILoggerFactory LoggerFactory { get; set; }
internal ConnectionStringSettings ConnectionStringSettings { get; set; } internal ConnectionStringSettings ConnectionStringSettings { get; set; }
protected internal Provider Provider { get; set; } protected internal Provider Provider { get; set; }
@ -33,7 +34,7 @@ namespace ASC.Core.Common.EF
get { return null; } get { return null; }
} }
internal void Migrate() public void Migrate()
{ {
if (ProviderContext != null) if (ProviderContext != null)
{ {
@ -42,6 +43,7 @@ namespace ASC.Core.Common.EF
using var sqlProvider = ProviderContext[provider](); using var sqlProvider = ProviderContext[provider]();
sqlProvider.ConnectionStringSettings = ConnectionStringSettings; sqlProvider.ConnectionStringSettings = ConnectionStringSettings;
sqlProvider.LoggerFactory = LoggerFactory; sqlProvider.LoggerFactory = LoggerFactory;
sqlProvider.MigrateAssembly = MigrateAssembly;
sqlProvider.Database.Migrate(); sqlProvider.Database.Migrate();
} }
@ -59,12 +61,19 @@ namespace ASC.Core.Common.EF
switch (Provider) switch (Provider)
{ {
case Provider.MySql: case Provider.MySql:
optionsBuilder.UseMySql(ConnectionStringSettings.ConnectionString); optionsBuilder.UseMySql(ConnectionStringSettings.ConnectionString, r=>
{
if (!string.IsNullOrEmpty(MigrateAssembly))
{
r = r.MigrationsAssembly(MigrateAssembly);
}
});
break; break;
case Provider.Postgre: case Provider.Postgre:
optionsBuilder.UseNpgsql(ConnectionStringSettings.ConnectionString); optionsBuilder.UseNpgsql(ConnectionStringSettings.ConnectionString);
break; break;
} }
} }
public Provider GetProviderByConnectionString() public Provider GetProviderByConnectionString()

View File

@ -26,6 +26,7 @@ namespace ASC.Core.Common.EF
{ {
context.LoggerFactory = LoggerFactory; context.LoggerFactory = LoggerFactory;
context.ConnectionStringSettings = Configuration.GetConnectionStrings(name) ?? Configuration.GetConnectionStrings(baseName); context.ConnectionStringSettings = Configuration.GetConnectionStrings(name) ?? Configuration.GetConnectionStrings(baseName);
context.MigrateAssembly = Configuration["testAssembly"];
} }
public void Configure(T context) public void Configure(T context)

View File

@ -99,8 +99,7 @@ namespace ASC.Core.Common.EF
ActivationStatus = 0, ActivationStatus = 0,
WorkFromDate = DateTime.UtcNow, WorkFromDate = DateTime.UtcNow,
LastModified = DateTime.UtcNow LastModified = DateTime.UtcNow
} });
);
return modelBuilder; return modelBuilder;
} }

View File

@ -42,8 +42,7 @@ namespace ASC.Core.Common.EF
PwdHash = "vLFfghR5tNV3K9DKhmwArV+SbjWAcgZZzIDTnJ0JgCo=", PwdHash = "vLFfghR5tNV3K9DKhmwArV+SbjWAcgZZzIDTnJ0JgCo=",
PwdHashSha512 = "USubvPlB+ogq0Q1trcSupg==", PwdHashSha512 = "USubvPlB+ogq0Q1trcSupg==",
LastModified = DateTime.UtcNow LastModified = DateTime.UtcNow
} });
);
return modelBuilder; return modelBuilder;
} }

View File

@ -261,7 +261,7 @@ namespace ASC.Core.Common.Migrations.MySql.TenantDbContextMySql
migrationBuilder.InsertData( migrationBuilder.InsertData(
table: "core_user", table: "core_user",
columns: new[] { "id", "activation_status", "bithdate", "contacts", "culture", "email", "firstname", "last_modified", "lastname", "location", "notes", "phone", "phone_activation", "removed", "sex", "sid", "sso_name_id", "sso_session_id", "status", "tenant", "terminateddate", "title", "username", "workfromdate" }, columns: new[] { "id", "activation_status", "bithdate", "contacts", "culture", "email", "firstname", "last_modified", "lastname", "location", "notes", "phone", "phone_activation", "removed", "sex", "sid", "sso_name_id", "sso_session_id", "status", "tenant", "terminateddate", "title", "username", "workfromdate" },
values: new object[] { "66faa6e4-f133-11ea-b126-00ffeec8b4ef", 0, null, null, null, "", "Administrator", new DateTime(2020, 10, 6, 10, 14, 35, 587, DateTimeKind.Utc).AddTicks(7841), "", null, null, null, 0, false, null, null, null, null, 1, 1, null, null, "administrator", new DateTime(2020, 10, 6, 10, 14, 35, 587, DateTimeKind.Utc).AddTicks(6725) }); values: new object[] {"66faa6e4-f133-11ea-b126-00ffeec8b4ef", 0, null, null, null, "", "Administrator", new DateTime(2020, 10, 6, 10, 14, 35, 587, DateTimeKind.Utc).AddTicks(7841), "", null, null, null, 0, false, null, null, null, null, 1, 1, null, null, "administrator", new DateTime(2020, 10, 6, 10, 14, 35, 587, DateTimeKind.Utc).AddTicks(6725) });
migrationBuilder.InsertData( migrationBuilder.InsertData(
table: "tenants_forbiden", table: "tenants_forbiden",

View File

@ -3,6 +3,7 @@ using System;
using ASC.Core.Common.EF.Context; using ASC.Core.Common.EF.Context;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace ASC.Core.Common.Migrations.MySql.TenantDbContextMySql namespace ASC.Core.Common.Migrations.MySql.TenantDbContextMySql
{ {
@ -13,7 +14,7 @@ namespace ASC.Core.Common.Migrations.MySql.TenantDbContextMySql
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("ProductVersion", "3.1.8") .HasAnnotation("ProductVersion", "3.1.9")
.HasAnnotation("Relational:MaxIdentifierLength", 64); .HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbCoreSettings", b => modelBuilder.Entity("ASC.Core.Common.EF.Model.DbCoreSettings", b =>
@ -49,21 +50,21 @@ namespace ASC.Core.Common.Migrations.MySql.TenantDbContextMySql
{ {
Tenant = -1, Tenant = -1,
Id = "CompanyWhiteLabelSettings", Id = "CompanyWhiteLabelSettings",
LastModified = new DateTime(2020, 10, 6, 10, 14, 35, 611, DateTimeKind.Utc).AddTicks(4820), LastModified = new DateTime(2020, 12, 22, 14, 54, 11, 757, DateTimeKind.Utc).AddTicks(3752),
Value = new byte[] { 48, 120, 70, 53, 52, 55, 48, 52, 56, 65, 52, 56, 54, 53, 49, 55, 49, 53, 56, 55, 68, 57, 67, 69, 66, 67, 56, 65, 52, 57, 54, 67, 54, 48, 49, 68, 57, 54, 48, 51, 49, 70, 50, 67, 49, 67, 51, 69, 57, 49, 54, 48, 51, 53, 51, 57, 52, 50, 69, 69, 55, 54, 53, 68, 65, 67, 68, 51, 49, 54, 70, 52, 66, 53, 70, 52, 50, 56, 57, 50, 52, 51, 54, 70, 67, 52, 65, 50, 49, 66, 57, 65, 54, 68, 70, 56, 70, 70, 68, 51, 66, 67, 52, 48, 51, 54, 66, 52, 55, 69, 51, 65, 53, 65, 49, 66, 52, 67, 56, 56, 49, 66, 50, 54, 54, 48, 57, 56, 54, 57, 70, 69, 66, 66, 54, 56, 52, 56, 66, 68, 56, 56, 67, 48, 50, 69, 69, 65, 67, 54, 65, 52, 67, 67, 66, 51, 69, 56, 70, 52, 48, 52, 50, 57, 48, 56, 49, 50, 70, 48, 69, 54, 69, 49, 50, 52, 65, 53, 53, 50, 66, 69, 56, 49, 65, 53, 56, 67, 54, 52, 66, 66, 56, 66, 68, 51, 67, 57, 65, 56, 67, 48, 69, 68, 69, 49, 70, 57, 52, 50, 49, 50, 56, 49, 68, 69, 48, 67, 55, 65, 70, 56, 50, 55, 51, 51, 67, 48, 66, 55, 53, 52, 69, 57, 55, 69, 70, 70, 70, 65, 53, 65, 55, 53, 54, 48, 55, 65, 57, 49, 57, 53, 55, 56, 57, 54, 67, 66, 69, 67, 70, 57, 53, 54, 51, 70, 67, 56, 51, 49, 51, 48, 48, 68, 67, 56, 69, 55, 67, 57, 51, 48, 65, 53, 53, 66, 50, 57, 56, 69, 66, 56, 50, 68, 54, 70, 54, 57, 69, 48, 69, 68, 54, 69, 52, 68, 56, 55, 53, 50, 54, 48, 55, 70, 49, 56, 56, 49, 70, 54, 49, 66, 48, 51, 50, 51, 48, 54, 69, 48, 70, 48, 54, 57, 65, 53, 70, 54, 57, 70, 48, 56, 54, 65, 49, 55, 55, 69, 66, 52, 49, 65, 67, 48, 54, 70, 56, 56, 57, 69, 66, 48, 66, 51, 57, 67, 66, 70, 68, 52, 66, 53, 67, 68, 66, 55, 54, 51, 69, 57, 57, 54, 53, 53, 52, 68, 69, 65, 68, 66, 57, 67, 55, 49, 67, 70, 51, 69, 70, 56, 54, 70, 52, 65, 48, 51, 53, 52, 65, 56, 54, 52, 65, 49, 48, 54, 51, 57, 68, 70, 68, 50, 57, 66, 53, 67, 54, 68, 53, 68, 67, 68, 65, 57, 68, 52, 66, 48, 57, 56, 56, 69, 69, 52, 48, 54, 57, 52, 56, 66, 67, 66, 53, 52, 67, 54, 65, 55, 48, 65, 68, 67, 54, 67, 48, 48, 53, 55, 55, 49, 55, 52, 50, 56, 53, 67, 69, 66, 67, 68, 55, 54 } Value = new byte[] { 48, 120, 70, 53, 52, 55, 48, 52, 56, 65, 52, 56, 54, 53, 49, 55, 49, 53, 56, 55, 68, 57, 67, 69, 66, 67, 56, 65, 52, 57, 54, 67, 54, 48, 49, 68, 57, 54, 48, 51, 49, 70, 50, 67, 49, 67, 51, 69, 57, 49, 54, 48, 51, 53, 51, 57, 52, 50, 69, 69, 55, 54, 53, 68, 65, 67, 68, 51, 49, 54, 70, 52, 66, 53, 70, 52, 50, 56, 57, 50, 52, 51, 54, 70, 67, 52, 65, 50, 49, 66, 57, 65, 54, 68, 70, 56, 70, 70, 68, 51, 66, 67, 52, 48, 51, 54, 66, 52, 55, 69, 51, 65, 53, 65, 49, 66, 52, 67, 56, 56, 49, 66, 50, 54, 54, 48, 57, 56, 54, 57, 70, 69, 66, 66, 54, 56, 52, 56, 66, 68, 56, 56, 67, 48, 50, 69, 69, 65, 67, 54, 65, 52, 67, 67, 66, 51, 69, 56, 70, 52, 48, 52, 50, 57, 48, 56, 49, 50, 70, 48, 69, 54, 69, 49, 50, 52, 65, 53, 53, 50, 66, 69, 56, 49, 65, 53, 56, 67, 54, 52, 66, 66, 56, 66, 68, 51, 67, 57, 65, 56, 67, 48, 69, 68, 69, 49, 70, 57, 52, 50, 49, 50, 56, 49, 68, 69, 48, 67, 55, 65, 70, 56, 50, 55, 51, 51, 67, 48, 66, 55, 53, 52, 69, 57, 55, 69, 70, 70, 70, 65, 53, 65, 55, 53, 54, 48, 55, 65, 57, 49, 57, 53, 55, 56, 57, 54, 67, 66, 69, 67, 70, 57, 53, 54, 51, 70, 67, 56, 51, 49, 51, 48, 48, 68, 67, 56, 69, 55, 67, 57, 51, 48, 65, 53, 53, 66, 50, 57, 56, 69, 66, 56, 50, 68, 54, 70, 54, 57, 69, 48, 69, 68, 54, 69, 52, 68, 56, 55, 53, 50, 54, 48, 55, 70, 49, 56, 56, 49, 70, 54, 49, 66, 48, 51, 50, 51, 48, 54, 69, 48, 70, 48, 54, 57, 65, 53, 70, 54, 57, 70, 48, 56, 54, 65, 49, 55, 55, 69, 66, 52, 49, 65, 67, 48, 54, 70, 56, 56, 57, 69, 66, 48, 66, 51, 57, 67, 66, 70, 68, 52, 66, 53, 67, 68, 66, 55, 54, 51, 69, 57, 57, 54, 53, 53, 52, 68, 69, 65, 68, 66, 57, 67, 55, 49, 67, 70, 51, 69, 70, 56, 54, 70, 52, 65, 48, 51, 53, 52, 65, 56, 54, 52, 65, 49, 48, 54, 51, 57, 68, 70, 68, 50, 57, 66, 53, 67, 54, 68, 53, 68, 67, 68, 65, 57, 68, 52, 66, 48, 57, 56, 56, 69, 69, 52, 48, 54, 57, 52, 56, 66, 67, 66, 53, 52, 67, 54, 65, 55, 48, 65, 68, 67, 54, 67, 48, 48, 53, 55, 55, 49, 55, 52, 50, 56, 53, 67, 69, 66, 67, 68, 55, 54 }
}, },
new new
{ {
Tenant = -1, Tenant = -1,
Id = "FullTextSearchSettings", Id = "FullTextSearchSettings",
LastModified = new DateTime(2020, 10, 6, 10, 14, 35, 611, DateTimeKind.Utc).AddTicks(6072), LastModified = new DateTime(2020, 12, 22, 14, 54, 11, 757, DateTimeKind.Utc).AddTicks(4636),
Value = new byte[] { 48, 120, 48, 56, 55, 56, 67, 70, 48, 53, 57, 57, 66, 53, 49, 55, 67, 65, 65, 50, 68, 51, 68, 65, 69, 68, 57, 68, 48, 54, 52, 67, 51, 69, 68, 67, 69, 69, 65, 70, 52, 51, 49, 70, 51, 53, 65, 54, 70, 54, 52, 50, 68, 67, 65, 68, 65, 48, 52, 56, 49, 55, 69, 51, 53, 49, 51, 50, 50, 55, 66, 66, 66, 49, 68, 69, 54, 69, 50, 66, 65, 66, 69, 66, 57, 69, 49, 48, 55, 55, 66, 50, 67, 70, 51, 49, 56, 67, 52, 56, 57, 56, 49, 52, 53, 52, 53, 69, 56, 55, 55, 53, 48, 49, 70, 54, 51, 51, 70, 66, 66, 69, 57, 52, 48, 50, 50, 67, 70, 67, 68, 68, 48, 50, 53, 66, 53, 51, 57, 53, 57, 55, 51, 65, 70, 53, 49, 48, 57, 52, 51, 52, 48, 56, 66, 66, 53, 54, 57, 54, 50, 69, 69, 51, 53, 68, 65, 51, 53, 70, 50, 70, 56, 51, 55, 52, 67, 70, 53, 70, 68, 49, 50, 54, 57, 53, 51, 53, 57, 52, 52, 57, 68, 55, 67, 69, 70, 66, 67, 50, 67, 55, 66, 68, 49, 49, 50, 65, 69, 53, 56, 55, 53, 50, 49, 55, 57, 65, 65, 50, 65, 53, 57, 69, 53, 69, 49, 55, 56, 48, 49, 69, 53, 56, 48, 67, 67, 67, 54, 48, 70, 65, 69, 67, 56, 69, 66, 68, 68, 51, 68, 54, 49, 50, 67, 52, 56, 56, 54, 54, 54, 54, 68, 57, 54, 68, 54, 67, 70, 48, 54, 48, 54, 48, 53, 69, 54, 52, 67, 57, 48, 65, 49, 70, 65, 65, 56, 48, 67, 48 } Value = new byte[] { 48, 120, 48, 56, 55, 56, 67, 70, 48, 53, 57, 57, 66, 53, 49, 55, 67, 65, 65, 50, 68, 51, 68, 65, 69, 68, 57, 68, 48, 54, 52, 67, 51, 69, 68, 67, 69, 69, 65, 70, 52, 51, 49, 70, 51, 53, 65, 54, 70, 54, 52, 50, 68, 67, 65, 68, 65, 48, 52, 56, 49, 55, 69, 51, 53, 49, 51, 50, 50, 55, 66, 66, 66, 49, 68, 69, 54, 69, 50, 66, 65, 66, 69, 66, 57, 69, 49, 48, 55, 55, 66, 50, 67, 70, 51, 49, 56, 67, 52, 56, 57, 56, 49, 52, 53, 52, 53, 69, 56, 55, 55, 53, 48, 49, 70, 54, 51, 51, 70, 66, 66, 69, 57, 52, 48, 50, 50, 67, 70, 67, 68, 68, 48, 50, 53, 66, 53, 51, 57, 53, 57, 55, 51, 65, 70, 53, 49, 48, 57, 52, 51, 52, 48, 56, 66, 66, 53, 54, 57, 54, 50, 69, 69, 51, 53, 68, 65, 51, 53, 70, 50, 70, 56, 51, 55, 52, 67, 70, 53, 70, 68, 49, 50, 54, 57, 53, 51, 53, 57, 52, 52, 57, 68, 55, 67, 69, 70, 66, 67, 50, 67, 55, 66, 68, 49, 49, 50, 65, 69, 53, 56, 55, 53, 50, 49, 55, 57, 65, 65, 50, 65, 53, 57, 69, 53, 69, 49, 55, 56, 48, 49, 69, 53, 56, 48, 67, 67, 67, 54, 48, 70, 65, 69, 67, 56, 69, 66, 68, 68, 51, 68, 54, 49, 50, 67, 52, 56, 56, 54, 54, 54, 54, 68, 57, 54, 68, 54, 67, 70, 48, 54, 48, 54, 48, 53, 69, 54, 52, 67, 57, 48, 65, 49, 70, 65, 65, 56, 48, 67, 48 }
}, },
new new
{ {
Tenant = -1, Tenant = -1,
Id = "SmtpSettings", Id = "SmtpSettings",
LastModified = new DateTime(2020, 10, 6, 10, 14, 35, 611, DateTimeKind.Utc).AddTicks(6099), LastModified = new DateTime(2020, 12, 22, 14, 54, 11, 757, DateTimeKind.Utc).AddTicks(4656),
Value = new byte[] { 48, 120, 70, 48, 53, 50, 69, 48, 57, 48, 65, 49, 65, 51, 55, 53, 48, 68, 65, 68, 67, 68, 52, 69, 57, 57, 54, 49, 68, 65, 48, 52, 65, 65, 53, 49, 69, 70, 48, 49, 57, 55, 69, 50, 67, 48, 54, 50, 51, 67, 70, 49, 50, 67, 53, 56, 51, 56, 66, 70, 65, 52, 48, 65, 57, 66, 52, 56, 66, 65, 69, 70, 67, 66, 69, 51, 55, 49, 53, 56, 55, 55, 51, 49, 68, 55, 69, 51, 68, 67, 57, 69, 55, 67, 54, 48, 48, 57, 55, 52, 50, 70, 57, 69, 52, 49, 53, 68, 53, 54, 68, 66, 48, 70, 48, 65, 69, 48, 56, 69, 51, 50, 70, 56, 57, 48, 52, 66, 50, 67, 52, 52, 49, 67, 67, 54, 53, 55, 67, 54, 52, 53, 52, 51, 69, 65, 69, 69, 50, 54, 50, 48, 52, 52, 65, 50, 56, 66, 52, 51, 51, 53, 68, 67, 66, 48, 70, 48, 67, 52, 69, 57, 52, 48, 49, 68, 56, 57, 49, 70, 65, 48, 54, 51, 54, 57, 70, 57, 56, 52, 67, 65, 50, 68, 52, 55, 53, 67, 56, 54, 67, 50, 51, 55, 57, 49, 55, 57, 54, 49, 67, 53, 56, 50, 55, 55, 54, 57, 56, 51, 49, 53, 56, 53, 50, 51, 48, 65, 54, 54, 65, 67, 55, 55, 56, 55, 69, 54, 70, 66, 53, 54, 70, 68, 51, 69, 51, 55, 51, 56, 57, 50, 54, 55, 65, 52, 54, 65 } Value = new byte[] { 48, 120, 70, 48, 53, 50, 69, 48, 57, 48, 65, 49, 65, 51, 55, 53, 48, 68, 65, 68, 67, 68, 52, 69, 57, 57, 54, 49, 68, 65, 48, 52, 65, 65, 53, 49, 69, 70, 48, 49, 57, 55, 69, 50, 67, 48, 54, 50, 51, 67, 70, 49, 50, 67, 53, 56, 51, 56, 66, 70, 65, 52, 48, 65, 57, 66, 52, 56, 66, 65, 69, 70, 67, 66, 69, 51, 55, 49, 53, 56, 55, 55, 51, 49, 68, 55, 69, 51, 68, 67, 57, 69, 55, 67, 54, 48, 48, 57, 55, 52, 50, 70, 57, 69, 52, 49, 53, 68, 53, 54, 68, 66, 48, 70, 48, 65, 69, 48, 56, 69, 51, 50, 70, 56, 57, 48, 52, 66, 50, 67, 52, 52, 49, 67, 67, 54, 53, 55, 67, 54, 52, 53, 52, 51, 69, 65, 69, 69, 50, 54, 50, 48, 52, 52, 65, 50, 56, 66, 52, 51, 51, 53, 68, 67, 66, 48, 70, 48, 67, 52, 69, 57, 52, 48, 49, 68, 56, 57, 49, 70, 65, 48, 54, 51, 54, 57, 70, 57, 56, 52, 67, 65, 50, 68, 52, 55, 53, 67, 56, 54, 67, 50, 51, 55, 57, 49, 55, 57, 54, 49, 67, 53, 56, 50, 55, 55, 54, 57, 56, 51, 49, 53, 56, 53, 50, 51, 48, 65, 54, 54, 65, 67, 55, 55, 56, 55, 69, 54, 70, 66, 53, 54, 70, 68, 51, 69, 51, 55, 51, 56, 57, 50, 54, 55, 65, 52, 54, 65 }
}); });
}); });
@ -185,13 +186,10 @@ namespace ASC.Core.Common.Migrations.MySql.TenantDbContextMySql
.HasColumnType("int") .HasColumnType("int")
.HasDefaultValueSql("'2'"); .HasDefaultValueSql("'2'");
b.Property<DateTime>("VersionChanged") b.Property<DateTime?>("Version_Changed")
.HasColumnName("version_changed") .HasColumnName("version_changed")
.HasColumnType("datetime"); .HasColumnType("datetime");
b.Property<DateTime?>("Version_Changed")
.HasColumnType("datetime(6)");
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("LastModified") b.HasIndex("LastModified")
@ -203,7 +201,7 @@ namespace ASC.Core.Common.Migrations.MySql.TenantDbContextMySql
b.HasIndex("Version") b.HasIndex("Version")
.HasName("version"); .HasName("version");
b.ToTable("tenants_tenants","onlyoffice"); b.ToTable("tenants_tenants");
b.HasData( b.HasData(
new new
@ -211,7 +209,7 @@ namespace ASC.Core.Common.Migrations.MySql.TenantDbContextMySql
Id = 1, Id = 1,
Alias = "localhost", Alias = "localhost",
Calls = false, Calls = false,
CreationDateTime = new DateTime(2020, 10, 6, 10, 14, 35, 606, DateTimeKind.Utc).AddTicks(4422), CreationDateTime = new DateTime(2020, 12, 22, 14, 54, 11, 753, DateTimeKind.Utc).AddTicks(774),
LastModified = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), LastModified = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
Name = "Web Office", Name = "Web Office",
OwnerId = "66faa6e4-f133-11ea-b126-00ffeec8b4ef", OwnerId = "66faa6e4-f133-11ea-b126-00ffeec8b4ef",
@ -219,8 +217,7 @@ namespace ASC.Core.Common.Migrations.MySql.TenantDbContextMySql
Spam = false, Spam = false,
Status = 0, Status = 0,
TrustedDomainsEnabled = 0, TrustedDomainsEnabled = 0,
Version = 0, Version = 0
VersionChanged = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)
}); });
}); });
@ -251,6 +248,7 @@ namespace ASC.Core.Common.Migrations.MySql.TenantDbContextMySql
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbTenantPartner", b => modelBuilder.Entity("ASC.Core.Common.EF.Model.DbTenantPartner", b =>
{ {
b.Property<int>("TenantId") b.Property<int>("TenantId")
.ValueGeneratedOnAdd()
.HasColumnName("tenant_id") .HasColumnName("tenant_id")
.HasColumnType("int"); .HasColumnType("int");
@ -497,14 +495,14 @@ namespace ASC.Core.Common.Migrations.MySql.TenantDbContextMySql
CreateOn = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), CreateOn = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
Email = "", Email = "",
FirstName = "Administrator", FirstName = "Administrator",
LastModified = new DateTime(2020, 10, 6, 10, 14, 35, 587, DateTimeKind.Utc).AddTicks(7841), LastModified = new DateTime(2020, 12, 22, 14, 54, 11, 741, DateTimeKind.Utc).AddTicks(4732),
LastName = "", LastName = "",
PhoneActivation = 0, PhoneActivation = 0,
Removed = false, Removed = false,
Status = 1, Status = 1,
Tenant = 1, Tenant = 1,
UserName = "administrator", UserName = "administrator",
WorkFromDate = new DateTime(2020, 10, 6, 10, 14, 35, 587, DateTimeKind.Utc).AddTicks(6725) WorkFromDate = new DateTime(2020, 12, 22, 14, 54, 11, 741, DateTimeKind.Utc).AddTicks(3715)
}); });
}); });
@ -595,22 +593,13 @@ namespace ASC.Core.Common.Migrations.MySql.TenantDbContextMySql
new new
{ {
UserId = "66faa6e4-f133-11ea-b126-00ffeec8b4ef", UserId = "66faa6e4-f133-11ea-b126-00ffeec8b4ef",
LastModified = new DateTime(2020, 10, 6, 10, 14, 35, 616, DateTimeKind.Utc).AddTicks(3267), LastModified = new DateTime(2020, 12, 22, 14, 54, 11, 761, DateTimeKind.Utc).AddTicks(3260),
PwdHash = "vLFfghR5tNV3K9DKhmwArV+SbjWAcgZZzIDTnJ0JgCo=", PwdHash = "vLFfghR5tNV3K9DKhmwArV+SbjWAcgZZzIDTnJ0JgCo=",
PwdHashSha512 = "USubvPlB+ogq0Q1trcSupg==", PwdHashSha512 = "USubvPlB+ogq0Q1trcSupg==",
Tenant = 1 Tenant = 1
}); });
}); });
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbTenantPartner", b =>
{
b.HasOne("ASC.Core.Common.EF.Model.DbTenant", "Tenant")
.WithOne("Partner")
.HasForeignKey("ASC.Core.Common.EF.Model.DbTenantPartner", "TenantId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("ASC.Core.Common.EF.UserGroup", b => modelBuilder.Entity("ASC.Core.Common.EF.UserGroup", b =>
{ {
b.HasOne("ASC.Core.Common.EF.User", null) b.HasOne("ASC.Core.Common.EF.User", null)

View File

@ -39,10 +39,12 @@ namespace ASC.Core.Common.Notify.Telegram
class ConfigureCachedTelegramDao : IConfigureNamedOptions<CachedTelegramDao> class ConfigureCachedTelegramDao : IConfigureNamedOptions<CachedTelegramDao>
{ {
private IOptionsSnapshot<TelegramDao> Service { get; } private IOptionsSnapshot<TelegramDao> Service { get; }
private ICache Cache { get; }
public ConfigureCachedTelegramDao(IOptionsSnapshot<TelegramDao> service) public ConfigureCachedTelegramDao(IOptionsSnapshot<TelegramDao> service, ICache cache)
{ {
Service = service; Service = service;
Cache = cache;
} }
public void Configure(string name, CachedTelegramDao options) public void Configure(string name, CachedTelegramDao options)
@ -54,7 +56,7 @@ namespace ASC.Core.Common.Notify.Telegram
public void Configure(CachedTelegramDao options) public void Configure(CachedTelegramDao options)
{ {
options.TgDao = Service.Value; options.TgDao = Service.Value;
options.Cache = AscCache.Memory; options.Cache = Cache;
options.Expiration = TimeSpan.FromMinutes(20); options.Expiration = TimeSpan.FromMinutes(20);
options.PairKeyFormat = "tgUser:{0}:{1}"; options.PairKeyFormat = "tgUser:{0}:{1}";

View File

@ -45,13 +45,14 @@ namespace ASC.Core.Common.Notify
public TelegramServiceClient(ICacheNotify<NotifyMessage> cacheMessage, public TelegramServiceClient(ICacheNotify<NotifyMessage> cacheMessage,
ICacheNotify<RegisterUserProto> cacheRegisterUser, ICacheNotify<RegisterUserProto> cacheRegisterUser,
ICacheNotify<CreateClientProto> cacheCreateClient, ICacheNotify<CreateClientProto> cacheCreateClient,
ICacheNotify<DisableClientProto> cacheDisableClient) ICacheNotify<DisableClientProto> cacheDisableClient,
ICache cache)
{ {
CacheMessage = cacheMessage; CacheMessage = cacheMessage;
CacheRegisterUser = cacheRegisterUser; CacheRegisterUser = cacheRegisterUser;
CacheCreateClient = cacheCreateClient; CacheCreateClient = cacheCreateClient;
CacheDisableClient = cacheDisableClient; CacheDisableClient = cacheDisableClient;
Cache = AscCache.Memory; Cache = cache;
} }
public void SendMessage(NotifyMessage m) public void SendMessage(NotifyMessage m)

View File

@ -11,9 +11,9 @@ namespace ASC.Data.Storage.Encryption
private ICacheNotify<ProgressEncryption> СacheBackupProgress { get; } private ICacheNotify<ProgressEncryption> СacheBackupProgress { get; }
private ICache Cache { get; } private ICache Cache { get; }
public EncryptionServiceNotifier(ICacheNotify<ProgressEncryption> сacheBackupProgress) public EncryptionServiceNotifier(ICacheNotify<ProgressEncryption> сacheBackupProgress, ICache cache)
{ {
Cache = AscCache.Memory; Cache = cache;
СacheBackupProgress = сacheBackupProgress; СacheBackupProgress = сacheBackupProgress;
СacheBackupProgress.Subscribe((a) => СacheBackupProgress.Subscribe((a) =>

View File

@ -36,17 +36,18 @@ namespace ASC.Data.Storage.Migration
[Singletone] [Singletone]
public class ServiceClientListener public class ServiceClientListener
{ {
public ICacheNotify<MigrationProgress> ProgressMigrationNotify { get; } private ICacheNotify<MigrationProgress> ProgressMigrationNotify { get; }
public IServiceProvider ServiceProvider { get; } private IServiceProvider ServiceProvider { get; }
public ICache Cache { get; } private ICache Cache { get; }
public ServiceClientListener( public ServiceClientListener(
ICacheNotify<MigrationProgress> progressMigrationNotify, ICacheNotify<MigrationProgress> progressMigrationNotify,
IServiceProvider serviceProvider) IServiceProvider serviceProvider,
ICache cache)
{ {
ProgressMigrationNotify = progressMigrationNotify; ProgressMigrationNotify = progressMigrationNotify;
ServiceProvider = serviceProvider; ServiceProvider = serviceProvider;
Cache = AscCache.Memory; Cache = cache;
ProgressListening(); ProgressListening();
} }

View File

@ -51,7 +51,7 @@ namespace ASC.Data.Storage
private static readonly TaskScheduler Scheduler; private static readonly TaskScheduler Scheduler;
private static readonly CancellationTokenSource TokenSource; private static readonly CancellationTokenSource TokenSource;
private static readonly ICache Cache; private ICache Cache { get; set; }
private static readonly object Locker; private static readonly object Locker;
private IServiceProvider ServiceProvider { get; } private IServiceProvider ServiceProvider { get; }
@ -62,7 +62,6 @@ namespace ASC.Data.Storage
static StaticUploader() static StaticUploader()
{ {
Scheduler = new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, 4).ConcurrentScheduler; Scheduler = new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, 4).ConcurrentScheduler;
Cache = AscCache.Memory;
Locker = new object(); Locker = new object();
TokenSource = new CancellationTokenSource(); TokenSource = new CancellationTokenSource();
} }
@ -71,8 +70,10 @@ namespace ASC.Data.Storage
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
TenantManager tenantManager, TenantManager tenantManager,
SettingsManager settingsManager, SettingsManager settingsManager,
StorageSettingsHelper storageSettingsHelper) StorageSettingsHelper storageSettingsHelper,
{ ICache cache)
{
Cache = cache;
ServiceProvider = serviceProvider; ServiceProvider = serviceProvider;
TenantManager = tenantManager; TenantManager = tenantManager;
SettingsManager = settingsManager; SettingsManager = settingsManager;
@ -170,7 +171,7 @@ namespace ASC.Data.Storage
TokenSource.Cancel(); TokenSource.Cancel();
} }
public static UploadOperationProgress GetProgress(int tenantId) public UploadOperationProgress GetProgress(int tenantId)
{ {
lock (Locker) lock (Locker)
{ {

View File

@ -51,7 +51,7 @@ namespace ASC.Data.Storage
private static readonly TaskScheduler Scheduler; private static readonly TaskScheduler Scheduler;
private static readonly CancellationTokenSource TokenSource; private static readonly CancellationTokenSource TokenSource;
private static readonly ICache Cache; private ICache Cache { get; set; }
private static readonly object Locker; private static readonly object Locker;
private IServiceProvider ServiceProvider { get; } private IServiceProvider ServiceProvider { get; }
@ -61,14 +61,14 @@ namespace ASC.Data.Storage
{ {
Scheduler = new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, 4).ConcurrentScheduler; Scheduler = new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, 4).ConcurrentScheduler;
TokenSource = new CancellationTokenSource(); TokenSource = new CancellationTokenSource();
Cache = AscCache.Memory;
Locker = new object(); Locker = new object();
} }
public StorageUploader(IServiceProvider serviceProvider, ICacheNotify<MigrationProgress> cacheMigrationNotify) public StorageUploader(IServiceProvider serviceProvider, ICacheNotify<MigrationProgress> cacheMigrationNotify, ICache cache)
{ {
ServiceProvider = serviceProvider; ServiceProvider = serviceProvider;
CacheMigrationNotify = cacheMigrationNotify; CacheMigrationNotify = cacheMigrationNotify;
Cache = cache;
} }
public void Start(int tenantId, StorageSettings newStorageSettings, StorageFactoryConfig storageFactoryConfig) public void Start(int tenantId, StorageSettings newStorageSettings, StorageFactoryConfig storageFactoryConfig)
@ -101,7 +101,7 @@ namespace ASC.Data.Storage
task.Start(Scheduler); task.Start(Scheduler);
} }
public static MigrateOperation GetProgress(int tenantId) public MigrateOperation GetProgress(int tenantId)
{ {
lock (Locker) lock (Locker)
{ {

View File

@ -49,9 +49,9 @@ namespace ASC.FederatedLogin
private readonly ICache cache; private readonly ICache cache;
private readonly ICacheNotify<LinkerCacheItem> notify; private readonly ICacheNotify<LinkerCacheItem> notify;
public AccountLinkerStorage(ICacheNotify<LinkerCacheItem> notify) public AccountLinkerStorage(ICacheNotify<LinkerCacheItem> notify, ICache cache)
{ {
cache = AscCache.Memory; this.cache = cache;
this.notify = notify; this.notify = notify;
notify.Subscribe((c) => cache.Remove(c.Obj), CacheNotifyAction.Remove); notify.Subscribe((c) => cache.Remove(c.Obj), CacheNotifyAction.Remove);
} }

View File

@ -63,11 +63,13 @@ namespace ASC.FederatedLogin.Helpers
if (!string.IsNullOrEmpty(query)) query += "&"; if (!string.IsNullOrEmpty(query)) query += "&";
query += "response_type=code"; query += "response_type=code";
if (!string.IsNullOrEmpty(clientID)) query += "&client_id=" + HttpUtility.UrlEncode(clientID); if (!string.IsNullOrEmpty(clientID)) query += $"&client_id={HttpUtility.UrlEncode(clientID)}";
if (!string.IsNullOrEmpty(redirectUri)) query += "&redirect_uri=" + HttpUtility.UrlEncode(redirectUri); if (!string.IsNullOrEmpty(redirectUri)) query += $"&redirect_uri={HttpUtility.UrlEncode(redirectUri)}";
if (!string.IsNullOrEmpty(scope)) query += "&scope=" + HttpUtility.UrlEncode(scope); if (!string.IsNullOrEmpty(scope)) query += $"&scope={HttpUtility.UrlEncode(scope)}";
query += "&state=" + HttpUtility.UrlEncode(HttpContextAccessor.HttpContext.Request.GetUrlRewriter().AbsoluteUri.TrimEnd('/')) + "/code"; var u = HttpContextAccessor.HttpContext.Request.GetUrlRewriter();
var state = HttpUtility.UrlEncode(new UriBuilder(u.Scheme, u.Host, u.Port, $"thirdparty/{loginProvider.Name.ToLower()}/code").Uri.AbsoluteUri);
query += $"&state={state}";
if (additionalArgs != null) if (additionalArgs != null)
{ {

View File

@ -40,9 +40,9 @@ namespace ASC.IPSecurity
internal ICacheNotify<IPRestrictionItem> Notify { get; } internal ICacheNotify<IPRestrictionItem> Notify { get; }
public IPRestrictionsServiceCache(ICacheNotify<IPRestrictionItem> notify) public IPRestrictionsServiceCache(ICacheNotify<IPRestrictionItem> notify, ICache cache)
{ {
Cache = AscCache.Memory; Cache = cache;
notify.Subscribe((r) => Cache.Remove(GetCacheKey(r.TenantId)), CacheNotifyAction.Any); notify.Subscribe((r) => Cache.Remove(GetCacheKey(r.TenantId)), CacheNotifyAction.Any);
Notify = notify; Notify = notify;
} }

View File

@ -70,13 +70,14 @@ namespace ASC.MessagingSystem.DbSender
CacheTime = TimeSpan.FromMinutes(1); CacheTime = TimeSpan.FromMinutes(1);
Cache = new Dictionary<string, EventMessage>(); Cache = new Dictionary<string, EventMessage>();
Parser = Parser.GetDefault(); Parser = Parser.GetDefault();
Timer = new Timer(FlushCache);
timerStarted = false; timerStarted = false;
ClearTimer = new Timer(DeleteOldEvents);
ClearTimer.Change(new TimeSpan(0), TimeSpan.FromDays(1));
Log = options.CurrentValue; Log = options.CurrentValue;
ServiceProvider = serviceProvider; ServiceProvider = serviceProvider;
Timer = new Timer(FlushCache);
ClearTimer = new Timer(DeleteOldEvents);
ClearTimer.Change(new TimeSpan(0), TimeSpan.FromDays(1));
} }
public void Add(EventMessage message) public void Add(EventMessage message)

View File

@ -43,12 +43,12 @@ namespace ASC.VoipService.Dao
[Singletone] [Singletone]
public class VoipDaoCache public class VoipDaoCache
{ {
public ICache Cache { get; } internal ICache Cache { get; }
private ICacheNotify<CachedVoipItem> Notify { get; } private ICacheNotify<CachedVoipItem> Notify { get; }
public VoipDaoCache(ICacheNotify<CachedVoipItem> notify) public VoipDaoCache(ICacheNotify<CachedVoipItem> notify, ICache cache)
{ {
Cache = AscCache.Memory; Cache = cache;
Notify = notify; Notify = notify;
Notify.Subscribe((c) => Cache.Remove(CachedVoipDao.GetCacheKey(c.Tenant)), CacheNotifyAction.Any); Notify.Subscribe((c) => Cache.Remove(CachedVoipDao.GetCacheKey(c.Tenant)), CacheNotifyAction.Any);
} }

View File

@ -61,17 +61,18 @@ namespace ASC.ApiSystem
config.SetBasePath(path); config.SetBasePath(path);
config config
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path}
})
.AddJsonFile("appsettings.json") .AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true) .AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true)
.AddJsonFile("storage.json") .AddJsonFile("storage.json")
.AddJsonFile("kafka.json") .AddJsonFile("kafka.json")
.AddJsonFile($"kafka.{hostingContext.HostingEnvironment.EnvironmentName}.json", true) .AddJsonFile($"kafka.{hostingContext.HostingEnvironment.EnvironmentName}.json", true)
.AddEnvironmentVariables() .AddEnvironmentVariables()
.AddCommandLine(args); .AddCommandLine(args)
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path}
});
}); });
} }
} }

View File

@ -61,6 +61,7 @@ namespace ASC.ApiSystem
var diHelper = new DIHelper(services); var diHelper = new DIHelper(services);
services.AddHttpContextAccessor(); services.AddHttpContextAccessor();
services.AddMemoryCache();
services.AddControllers() services.AddControllers()
.AddJsonOptions(options => .AddJsonOptions(options =>

View File

@ -31,11 +31,6 @@ namespace ASC.Data.Backup
config.SetBasePath(path); config.SetBasePath(path);
var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production"); var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production");
config config
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path }
}
)
.AddJsonFile("appsettings.json") .AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env}.json", true) .AddJsonFile($"appsettings.{env}.json", true)
.AddJsonFile("storage.json") .AddJsonFile("storage.json")
@ -43,7 +38,12 @@ namespace ASC.Data.Backup
.AddJsonFile("backup.json") .AddJsonFile("backup.json")
.AddJsonFile("kafka.json") .AddJsonFile("kafka.json")
.AddJsonFile($"kafka.{env}.json", true) .AddJsonFile($"kafka.{env}.json", true)
.AddEnvironmentVariables(); .AddEnvironmentVariables()
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path }
}
);
}) })
.UseConsoleLifetime() .UseConsoleLifetime()
.Build() .Build()

View File

@ -49,11 +49,11 @@ namespace ASC.Data.Backup.Service
public class BackupServiceNotifier public class BackupServiceNotifier
{ {
private ICacheNotify<BackupProgress> СacheBackupProgress { get; } private ICacheNotify<BackupProgress> СacheBackupProgress { get; }
public ICache Cache { get; } private ICache Cache { get; }
public BackupServiceNotifier(ICacheNotify<BackupProgress> сacheBackupProgress) public BackupServiceNotifier(ICacheNotify<BackupProgress> сacheBackupProgress, ICache cache)
{ {
Cache = AscCache.Memory; Cache = cache;
СacheBackupProgress = сacheBackupProgress; СacheBackupProgress = сacheBackupProgress;
СacheBackupProgress.Subscribe((a) => СacheBackupProgress.Subscribe((a) =>

View File

@ -44,9 +44,9 @@ namespace ASC.Data.Storage.Encryption
private object Locker { get; } private object Locker { get; }
private FactoryOperation FactoryOperation { get; } private FactoryOperation FactoryOperation { get; }
public EncryptionWorker(FactoryOperation factoryOperation) public EncryptionWorker(FactoryOperation factoryOperation, ICache cache)
{ {
Cache = AscCache.Memory; Cache = cache;
Locker = new object(); Locker = new object();
FactoryOperation = factoryOperation; FactoryOperation = factoryOperation;
} }

View File

@ -33,11 +33,6 @@ namespace ASC.Data.Storage.Migration
config.SetBasePath(path); config.SetBasePath(path);
var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production"); var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production");
config config
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path }
}
)
.AddJsonFile("appsettings.json") .AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env}.json", true) .AddJsonFile($"appsettings.{env}.json", true)
.AddJsonFile($"appsettings.services.json", true) .AddJsonFile($"appsettings.services.json", true)
@ -46,12 +41,17 @@ namespace ASC.Data.Storage.Migration
.AddJsonFile("kafka.json") .AddJsonFile("kafka.json")
.AddJsonFile($"kafka.{env}.json", true) .AddJsonFile($"kafka.{env}.json", true)
.AddEnvironmentVariables() .AddEnvironmentVariables()
.AddCommandLine(args); .AddCommandLine(args)
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path }
}
);
}) })
.ConfigureServices((hostContext, services) => .ConfigureServices((hostContext, services) =>
{ {
services.AddMemoryCache();
var diHelper = new DIHelper(services); var diHelper = new DIHelper(services);
LogNLogExtension.ConfigureLog(diHelper, "ASC.Data.Storage.Migration", "ASC.Migration"); LogNLogExtension.ConfigureLog(diHelper, "ASC.Data.Storage.Migration", "ASC.Migration");
diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>)); diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>));

View File

@ -91,7 +91,7 @@ namespace ASC.ElasticSearch
private IServiceProvider ServiceProvider { get; } private IServiceProvider ServiceProvider { get; }
public string IndexName { get => Indexer.IndexName; } public string IndexName { get => Indexer.IndexName; }
public ICache Cache { get; } private ICache Cache { get; }
public virtual string SettingsTitle { get => ""; } public virtual string SettingsTitle { get => ""; }
public FactoryIndexer( public FactoryIndexer(
@ -100,9 +100,10 @@ namespace ASC.ElasticSearch
SearchSettingsHelper searchSettingsHelper, SearchSettingsHelper searchSettingsHelper,
FactoryIndexer factoryIndexer, FactoryIndexer factoryIndexer,
BaseIndexer<T> baseIndexer, BaseIndexer<T> baseIndexer,
IServiceProvider serviceProvider) IServiceProvider serviceProvider,
ICache cache)
{ {
Cache = AscCache.Memory; Cache = cache;
Logger = options.Get("ASC.Indexer"); Logger = options.Get("ASC.Indexer");
TenantManager = tenantManager; TenantManager = tenantManager;
SearchSettingsHelper = searchSettingsHelper; SearchSettingsHelper = searchSettingsHelper;
@ -455,7 +456,7 @@ namespace ASC.ElasticSearch
[Scope] [Scope]
public class FactoryIndexer public class FactoryIndexer
{ {
private static readonly ICache cache = AscCache.Memory; private readonly ICache cache;
private FactoryIndexerHelper FactoryIndexerHelper { get; } private FactoryIndexerHelper FactoryIndexerHelper { get; }
internal ILifetimeScope Builder { get; set; } internal ILifetimeScope Builder { get; set; }
@ -469,8 +470,10 @@ namespace ASC.ElasticSearch
FactoryIndexerHelper factoryIndexerHelper, FactoryIndexerHelper factoryIndexerHelper,
Client client, Client client,
IOptionsMonitor<ILog> options, IOptionsMonitor<ILog> options,
CoreBaseSettings coreBaseSettings) CoreBaseSettings coreBaseSettings,
ICache cache)
{ {
this.cache = cache;
Builder = container; Builder = container;
FactoryIndexerHelper = factoryIndexerHelper; FactoryIndexerHelper = factoryIndexerHelper;
Client = client; Client = client;

View File

@ -121,6 +121,7 @@ namespace ASC.Feed.Aggregator
var cfg = FeedSettings.GetInstance(Configuration); var cfg = FeedSettings.GetInstance(Configuration);
using var scope = ServiceProvider.CreateScope(); using var scope = ServiceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<FeedAggregatorServiceScope>(); var scopeClass = scope.ServiceProvider.GetService<FeedAggregatorServiceScope>();
var cache = scope.ServiceProvider.GetService<ICache>();
var (baseCommonLinkUtility, tenantManager, feedAggregateDataProvider, userManager, securityContext, authManager) = scopeClass; var (baseCommonLinkUtility, tenantManager, feedAggregateDataProvider, userManager, securityContext, authManager) = scopeClass;
baseCommonLinkUtility.Initialize(cfg.ServerRoot); baseCommonLinkUtility.Initialize(cfg.ServerRoot);
@ -145,7 +146,6 @@ namespace ASC.Feed.Aggregator
{ {
// Warning! There is hack here! // Warning! There is hack here!
// clearing the cache to get the correct acl // clearing the cache to get the correct acl
var cache = AscCache.Memory;
cache.Remove("acl" + tenant); cache.Remove("acl" + tenant);
cache.Remove("/webitemsecurity/" + tenant); cache.Remove("/webitemsecurity/" + tenant);
//cache.Remove(string.Format("sub/{0}/{1}/{2}", tenant, "6045b68c-2c2e-42db-9e53-c272e814c4ad", NotifyConstants.Event_NewCommentForMessage.ID)); //cache.Remove(string.Format("sub/{0}/{1}/{2}", tenant, "6045b68c-2c2e-42db-9e53-c272e814c4ad", NotifyConstants.Event_NewCommentForMessage.ID));

View File

@ -35,11 +35,6 @@ namespace ASC.Notify
config.SetBasePath(path); config.SetBasePath(path);
var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production"); var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production");
config config
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path }
}
)
.AddJsonFile("appsettings.json") .AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env}.json", true) .AddJsonFile($"appsettings.{env}.json", true)
.AddJsonFile($"appsettings.services.json", true) .AddJsonFile($"appsettings.services.json", true)
@ -48,10 +43,16 @@ namespace ASC.Notify
.AddJsonFile("kafka.json") .AddJsonFile("kafka.json")
.AddJsonFile($"kafka.{env}.json", true) .AddJsonFile($"kafka.{env}.json", true)
.AddEnvironmentVariables() .AddEnvironmentVariables()
.AddCommandLine(args); .AddCommandLine(args)
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path }
}
);
}) })
.ConfigureServices((hostContext, services) => .ConfigureServices((hostContext, services) =>
{ {
services.AddMemoryCache();
var diHelper = new DIHelper(services); var diHelper = new DIHelper(services);
LogNLogExtension.ConfigureLog(diHelper, "ASC.Notify", "ASC.Notify.Messages"); LogNLogExtension.ConfigureLog(diHelper, "ASC.Notify", "ASC.Notify.Messages");

View File

@ -60,11 +60,6 @@ namespace ASC.Socket.IO.Svc
config.SetBasePath(path); config.SetBasePath(path);
var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production"); var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production");
config config
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path }
}
)
.AddJsonFile("appsettings.json") .AddJsonFile("appsettings.json")
.AddJsonFile("storage.json") .AddJsonFile("storage.json")
.AddJsonFile("kafka.json") .AddJsonFile("kafka.json")
@ -73,10 +68,16 @@ namespace ASC.Socket.IO.Svc
.AddJsonFile($"appsettings.{env}.json", true) .AddJsonFile($"appsettings.{env}.json", true)
.AddJsonFile($"socket.{env}.json", true) .AddJsonFile($"socket.{env}.json", true)
.AddEnvironmentVariables() .AddEnvironmentVariables()
.AddCommandLine(args); .AddCommandLine(args)
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path }
}
);
}) })
.ConfigureServices((hostContext, services) => .ConfigureServices((hostContext, services) =>
{ {
services.AddMemoryCache();
var diHelper = new DIHelper(services); var diHelper = new DIHelper(services);
diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>)); diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>));
LogNLogExtension.ConfigureLog(diHelper, "ASC.Socket.IO.Svc"); LogNLogExtension.ConfigureLog(diHelper, "ASC.Socket.IO.Svc");

View File

@ -36,11 +36,6 @@ namespace ASC.Studio.Notify
config.SetBasePath(path); config.SetBasePath(path);
var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production"); var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production");
config config
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path }
}
)
.AddJsonFile("appsettings.json") .AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env}.json", true) .AddJsonFile($"appsettings.{env}.json", true)
.AddJsonFile($"appsettings.services.json", true) .AddJsonFile($"appsettings.services.json", true)
@ -49,10 +44,16 @@ namespace ASC.Studio.Notify
.AddJsonFile("kafka.json") .AddJsonFile("kafka.json")
.AddJsonFile($"kafka.{env}.json", true) .AddJsonFile($"kafka.{env}.json", true)
.AddEnvironmentVariables() .AddEnvironmentVariables()
.AddCommandLine(args); .AddCommandLine(args)
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path }
}
);
}) })
.ConfigureServices((hostContext, services) => .ConfigureServices((hostContext, services) =>
{ {
services.AddMemoryCache();
var diHelper = new DIHelper(services); var diHelper = new DIHelper(services);
diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>)); diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>));
LogNLogExtension.ConfigureLog(diHelper, "ASC.Notify", "ASC.Notify.Messages"); LogNLogExtension.ConfigureLog(diHelper, "ASC.Notify", "ASC.Notify.Messages");

View File

@ -60,11 +60,6 @@ namespace ASC.Thumbnails.Svc
config.SetBasePath(path); config.SetBasePath(path);
var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production"); var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production");
config config
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path }
}
)
.AddJsonFile("appsettings.json") .AddJsonFile("appsettings.json")
.AddJsonFile("storage.json") .AddJsonFile("storage.json")
.AddJsonFile("kafka.json") .AddJsonFile("kafka.json")
@ -73,10 +68,16 @@ namespace ASC.Thumbnails.Svc
.AddJsonFile($"appsettings.{env}.json", true) .AddJsonFile($"appsettings.{env}.json", true)
.AddJsonFile($"thumb.{env}.json", true) .AddJsonFile($"thumb.{env}.json", true)
.AddEnvironmentVariables() .AddEnvironmentVariables()
.AddCommandLine(args); .AddCommandLine(args)
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path }
}
);
}) })
.ConfigureServices((hostContext, services) => .ConfigureServices((hostContext, services) =>
{ {
services.AddMemoryCache();
var diHelper = new DIHelper(services); var diHelper = new DIHelper(services);
diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>)); diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>));

View File

@ -59,11 +59,6 @@ namespace ASC.UrlShortener.Svc
config.SetBasePath(path); config.SetBasePath(path);
var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production"); var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production");
config config
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path }
}
)
.AddJsonFile("appsettings.json") .AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env}.json", true) .AddJsonFile($"appsettings.{env}.json", true)
.AddJsonFile($"urlshortener.{env}.json", true) .AddJsonFile($"urlshortener.{env}.json", true)
@ -71,10 +66,16 @@ namespace ASC.UrlShortener.Svc
.AddJsonFile("kafka.json") .AddJsonFile("kafka.json")
.AddJsonFile($"kafka.{env}.json", true) .AddJsonFile($"kafka.{env}.json", true)
.AddEnvironmentVariables() .AddEnvironmentVariables()
.AddCommandLine(args); .AddCommandLine(args)
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path }
}
);
}) })
.ConfigureServices((hostContext, services) => .ConfigureServices((hostContext, services) =>
{ {
services.AddMemoryCache();
var diHelper = new DIHelper(services); var diHelper = new DIHelper(services);
LogNLogExtension.ConfigureLog(diHelper, "ASC.UrlShortener.Svc"); LogNLogExtension.ConfigureLog(diHelper, "ASC.UrlShortener.Svc");
services.AddHostedService<UrlShortenerServiceLauncher>(); services.AddHostedService<UrlShortenerServiceLauncher>();

View File

@ -1,6 +1,6 @@
{ {
"name": "asc-files-client", "name": "asc-files-client",
"version": "0.0.6", "version": "0.0.7",
"private": true, "private": true,
"homepage": "/products/files", "homepage": "/products/files",
"dependencies": { "dependencies": {

View File

@ -0,0 +1,10 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path d="M14.9488 2.23878C14.92 2.03249 14.7716 1.8628 14.571 1.80702L8.14028 0.018649C8.04861 -0.00686737 7.95177 -0.00686737 7.86002 0.018649L1.42935 1.80702C1.2287 1.8628 1.08028 2.03242 1.05155 2.23878C1.01425 2.50698 0.16336 8.84396 2.34584 11.9964C4.52575 15.1451 7.74157 15.952 7.87738 15.9848C7.91775 15.9946 7.95888 15.9994 8.00015 15.9994C8.04143 15.9994 8.08256 15.9945 8.12292 15.9848C8.2588 15.952 11.4746 15.1451 13.6545 11.9964C15.8369 8.84402 14.9861 2.50705 14.9488 2.23878ZM12.1471 5.93837L7.76075 10.3247C7.65868 10.4268 7.52482 10.4779 7.39104 10.4779C7.25725 10.4779 7.1234 10.4269 7.02133 10.3247L4.30928 7.61269C4.21119 7.51467 4.15611 7.38165 4.15611 7.24298C4.15611 7.10431 4.21126 6.97129 4.30928 6.87327L4.84777 6.33478C5.05197 6.13065 5.38306 6.13058 5.58719 6.33478L7.39104 8.13863L10.8692 4.66039C10.9672 4.5623 11.1002 4.50722 11.2389 4.50722C11.3776 4.50722 11.5106 4.5623 11.6086 4.66039L12.1471 5.19888C12.3513 5.40308 12.3513 5.73417 12.1471 5.93837Z" fill="#657077"/>
</g>
<defs>
<clipPath id="clip0">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -255,7 +255,11 @@
To create a production bundle, use `npm run build` or `yarn build`. To create a production bundle, use `npm run build` or `yarn build`.
--> -->
<script> <script>
if (window.location.pathname.indexOf("doceditor") === -1) { var pathname = window.location.pathname.toLowerCase();
if (
pathname.indexOf("doceditor") !== -1 &&
window["AscDesktopEditor"] === undefined
) {
let el = document.getElementById("temp-content"); let el = document.getElementById("temp-content");
el.style.display = "block"; el.style.display = "block";
} }

View File

@ -22,6 +22,7 @@ import {
utils, utils,
toastr, toastr,
Layout, Layout,
regDesktop,
} from "asc-web-common"; } from "asc-web-common";
const { const {
@ -32,14 +33,25 @@ const {
setCurrentProductId, setCurrentProductId,
setCurrentProductHomePage, setCurrentProductHomePage,
getPortalCultures, getPortalCultures,
setEncryptionKeys,
getIsEncryptionSupport,
getEncryptionKeys,
getIsAuthenticated, getIsAuthenticated,
} = commonStore.auth.actions; } = commonStore.auth.actions;
const {
getCurrentUser,
isEncryptionSupport,
isDesktopClient,
getIsLoaded,
} = commonStore.auth.selectors;
class App extends React.Component { class App extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.isEditor = window.location.pathname.indexOf("doceditor") !== -1; const pathname = window.location.pathname.toLowerCase();
this.isEditor = pathname.indexOf("doceditor") !== -1;
this.isDesktopInit = false;
} }
componentDidMount() { componentDidMount() {
@ -51,6 +63,9 @@ class App extends React.Component {
getPortalCultures, getPortalCultures,
fetchTreeFolders, fetchTreeFolders,
setIsLoaded, setIsLoaded,
getIsEncryptionSupport,
getEncryptionKeys,
isDesktop,
getIsAuthenticated, getIsAuthenticated,
} = this.props; } = this.props;
@ -69,15 +84,23 @@ class App extends React.Component {
utils.updateTempContent(isAuthenticated); utils.updateTempContent(isAuthenticated);
} }
const requests = [ const requests = [getUser()];
getUser(), if (!this.isEditor) {
getPortalSettings(), requests.push(
getModules(), getPortalSettings(),
getPortalCultures(), getModules(),
fetchTreeFolders(), getPortalCultures(),
]; fetchTreeFolders()
);
if (isDesktop) {
requests.push(getIsEncryptionSupport(), getEncryptionKeys());
}
}
Promise.all(requests) Promise.all(requests)
.then(() => {
if (this.isEditor) return Promise.resolve();
})
.catch((e) => { .catch((e) => {
toastr.error(e); toastr.error(e);
}) })
@ -88,15 +111,43 @@ class App extends React.Component {
}); });
} }
componentDidUpdate(prevProps) {
const {
isAuthenticated,
user,
isEncryption,
encryptionKeys,
setEncryptionKeys,
isLoaded,
} = this.props;
console.log("componentDidUpdate: ", this.props);
if (isAuthenticated && !this.isDesktopInit && isEncryption && isLoaded) {
this.isDesktopInit = true;
regDesktop(
user,
isEncryption,
encryptionKeys,
setEncryptionKeys,
this.isEditor
);
console.log(
"%c%s",
"color: green; font: 1.2em bold;",
"Current keys is: ",
encryptionKeys
);
}
}
render() { render() {
const { homepage } = this.props; const { homepage, isDesktop } = this.props;
console.log(Layout); console.log(Layout);
return navigator.onLine ? ( return navigator.onLine ? (
<Layout> <Layout>
<Router history={history}> <Router history={history}>
{!this.isEditor && <NavMenu />} {!this.isEditor && <NavMenu />}
<Main> <Main isDesktop={isDesktop}>
<Suspense fallback={null}> <Suspense fallback={null}>
<Switch> <Switch>
<Redirect exact from="/" to={`${homepage}`} /> <Redirect exact from="/" to={`${homepage}`} />
@ -107,7 +158,10 @@ class App extends React.Component {
/> />
<Route <Route
exact exact
path={`${homepage}/doceditor`} path={[
`${homepage}/doceditor`,
`/Products/Files/DocEditor.aspx`,
]}
component={DocEditor} component={DocEditor}
/> />
<PrivateRoute <PrivateRoute
@ -148,6 +202,12 @@ const mapStateToProps = (state) => {
const { homepage } = settings; const { homepage } = settings;
return { return {
homepage: homepage || config.homepage, homepage: homepage || config.homepage,
user: getCurrentUser(state),
isAuthenticated: state.auth.isAuthenticated,
isLoaded: getIsLoaded(state),
isEncryption: isEncryptionSupport(state),
isDesktop: isDesktopClient(state),
encryptionKeys: settings.encryptionKeys,
}; };
}; };
@ -164,6 +224,9 @@ const mapDispatchToProps = (dispatch) => {
getPortalCultures: () => getPortalCultures(dispatch), getPortalCultures: () => getPortalCultures(dispatch),
fetchTreeFolders: () => fetchTreeFolders(dispatch), fetchTreeFolders: () => fetchTreeFolders(dispatch),
setIsLoaded: () => dispatch(setIsLoaded(true)), setIsLoaded: () => dispatch(setIsLoaded(true)),
getIsEncryptionSupport: () => getIsEncryptionSupport(dispatch),
getEncryptionKeys: () => getEncryptionKeys(dispatch),
setEncryptionKeys: (keys) => dispatch(setEncryptionKeys(keys)),
}; };
}; };

View File

@ -22,9 +22,10 @@ import {
getShareFolderId, getShareFolderId,
getRootFolderId, getRootFolderId,
getDraggableItems, getDraggableItems,
getIsPrivacyFolder,
} from "../../../store/files/selectors"; } from "../../../store/files/selectors";
import { onConvertFiles } from "../../../helpers/files-converter"; import { onConvertFiles } from "../../../helpers/files-converter";
const { isAdmin } = initStore.auth.selectors; const { isAdmin, isDesktopClient } = initStore.auth.selectors;
const { files } = api; const { files } = api;
const { FolderType, ShareAccessRights } = constants; const { FolderType, ShareAccessRights } = constants;
@ -185,11 +186,24 @@ class TreeFolders extends React.Component {
title={item.title} title={item.title}
icon={this.getFolderIcon(item)} icon={this.getFolderIcon(item)}
dragging={dragging} dragging={dragging}
newItems={item.newItems} isLeaf={
item.rootFolderType === FolderType.Privacy &&
!this.props.isDesktop
? true
: null
}
newItems={
!this.props.isDesktop &&
item.rootFolderType === FolderType.Privacy
? null
: item.newItems
}
onBadgeClick={this.onBadgeClick} onBadgeClick={this.onBadgeClick}
showBadge={showBadge} showBadge={showBadge}
> >
{this.getItems(item.folders)} {item.rootFolderType === FolderType.Privacy && !this.props.isDesktop
? null
: this.getItems(item.folders)}
</TreeNode> </TreeNode>
); );
} }
@ -198,11 +212,15 @@ class TreeFolders extends React.Component {
id={item.id} id={item.id}
key={item.id} key={item.id}
title={item.title} title={item.title}
needTopMargin={item.key === "0-5" ? true : false} needTopMargin={item.rootFolderType === FolderType.TRASH}
dragging={dragging} dragging={dragging}
isLeaf={item.foldersCount ? false : true} isLeaf={item.foldersCount ? false : true}
icon={this.getFolderIcon(item)} icon={this.getFolderIcon(item)}
newItems={item.newItems} newItems={
!this.props.isDesktop && item.rootFolderType === FolderType.Privacy
? null
: item.newItems
}
onBadgeClick={this.onBadgeClick} onBadgeClick={this.onBadgeClick}
showBadge={showBadge} showBadge={showBadge}
/> />
@ -214,7 +232,6 @@ class TreeFolders extends React.Component {
if (obj.isLeaf) { if (obj.isLeaf) {
return null; return null;
} }
if (obj.expanded) { if (obj.expanded) {
return <Icons.ExpanderDownIcon size="scale" isfill color="dimgray" />; return <Icons.ExpanderDownIcon size="scale" isfill color="dimgray" />;
} else { } else {
@ -442,6 +459,8 @@ function mapStateToProps(state) {
updateTree: getUpdateTree(state), updateTree: getUpdateTree(state),
rootFolderId: getRootFolderId(state), rootFolderId: getRootFolderId(state),
draggableItems: getDraggableItems(state), draggableItems: getDraggableItems(state),
isDesktop: isDesktopClient(state),
isPrivacy: getIsPrivacyFolder(state),
}; };
} }

View File

@ -11,6 +11,7 @@ import {
getFilter, getFilter,
getSelectedFolder, getSelectedFolder,
getFirstLoad, getFirstLoad,
getIsPrivacyFolder,
} from "../../../store/files/selectors"; } from "../../../store/files/selectors";
import { import {
utils as commonUtils, utils as commonUtils,
@ -19,6 +20,7 @@ import {
Loaders, Loaders,
} from "asc-web-common"; } from "asc-web-common";
import { createI18N } from "../../../helpers/i18n"; import { createI18N } from "../../../helpers/i18n";
import { encryptionUploadDialog } from "../../../helpers/desktop";
const { getSettings } = initStore.auth.selectors; const { getSettings } = initStore.auth.selectors;
const i18n = createI18N({ const i18n = createI18N({
@ -40,7 +42,19 @@ class PureArticleMainButtonContent extends React.Component {
}); });
}; };
onUploadFileClick = () => this.inputFilesElement.click(); onUploadFileClick = () => {
if (this.props.isPrivacy) {
encryptionUploadDialog((encryptedFile, encrypted) => {
const { selectedFolder, startUpload, t } = this.props;
encryptedFile.encrypted = encrypted;
this.goToHomePage();
startUpload([encryptedFile], selectedFolder.id, t);
});
} else {
this.inputFilesElement.click();
}
};
onUploadFolderClick = () => this.inputFolderElement.click(); onUploadFolderClick = () => this.inputFolderElement.click();
goToHomePage = () => { goToHomePage = () => {
@ -51,22 +65,23 @@ class PureArticleMainButtonContent extends React.Component {
onFileChange = (e) => { onFileChange = (e) => {
const { selectedFolder, startUpload, t } = this.props; const { selectedFolder, startUpload, t } = this.props;
this.goToHomePage(); this.goToHomePage();
startUpload(e.target.files, selectedFolder.id, t); startUpload(e.target.files, selectedFolder.id, t);
}; };
onInputClick = (e) => (e.target.value = null); onInputClick = (e) => (e.target.value = null);
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps, nextState) {
return ( return (
nextProps.canCreate !== this.props.canCreate || nextProps.canCreate !== this.props.canCreate ||
nextProps.firstLoad !== this.props.firstLoad nextProps.firstLoad !== this.props.firstLoad ||
nextProps.isPrivacy !== this.props.isPrivacy
); );
} }
render() { render() {
//console.log("Files ArticleMainButtonContent render"); //console.log("Files ArticleMainButtonContent render");
const { t, canCreate, isDisabled, firstLoad } = this.props; const { t, canCreate, isDisabled, firstLoad, isPrivacy } = this.props;
return firstLoad ? ( return firstLoad ? (
<Loaders.Rectangle /> <Loaders.Rectangle />
@ -115,6 +130,7 @@ class PureArticleMainButtonContent extends React.Component {
className="main-button_drop-down" className="main-button_drop-down"
icon="ActionsUploadIcon" icon="ActionsUploadIcon"
label={t("UploadFolder")} label={t("UploadFolder")}
disabled={isPrivacy}
onClick={this.onUploadFolderClick} onClick={this.onUploadFolderClick}
/> />
)} )}
@ -170,6 +186,7 @@ const mapStateToProps = (state) => {
settings: getSettings(state), settings: getSettings(state),
filter: getFilter(state), filter: getFilter(state),
selectedFolder: getSelectedFolder(state), selectedFolder: getSelectedFolder(state),
isPrivacy: getIsPrivacyFolder(state),
}; };
}; };

View File

@ -27,6 +27,7 @@ import {
getIsLoading, getIsLoading,
getIsRecycleBinFolder, getIsRecycleBinFolder,
getSelection, getSelection,
getIsPrivacyFolder,
} from "../../../store/files/selectors"; } from "../../../store/files/selectors";
import { createI18N } from "../../../helpers/i18n"; import { createI18N } from "../../../helpers/i18n";
const i18n = createI18N({ const i18n = createI18N({
@ -71,7 +72,7 @@ class DeleteDialogComponent extends React.Component {
isRecycleBinFolder, isRecycleBinFolder,
setSecondaryProgressBarData, setSecondaryProgressBarData,
clearSecondaryProgressData, clearSecondaryProgressData,
t, isPrivacy, t,
fetchFiles, fetchFiles,
setUpdateTree, setUpdateTree,
} = this.props; } = this.props;
@ -125,6 +126,7 @@ class DeleteDialogComponent extends React.Component {
onDelete = () => { onDelete = () => {
const { const {
isRecycleBinFolder, isRecycleBinFolder,
isPrivacy,
onClose, onClose,
t, t,
setSecondaryProgressBarData, setSecondaryProgressBarData,
@ -133,7 +135,7 @@ class DeleteDialogComponent extends React.Component {
const { selection } = this.state; const { selection } = this.state;
const deleteAfter = true; //Delete after finished const deleteAfter = true; //Delete after finished
const immediately = isRecycleBinFolder ? true : false; //Don't move to the Recycle Bin const immediately = isRecycleBinFolder || isPrivacy ? true : false; //Don't move to the Recycle Bin
const folderIds = []; const folderIds = [];
const fileIds = []; const fileIds = [];
@ -300,6 +302,7 @@ const mapStateToProps = (state) => {
treeFolders: getTreeFolders(state), treeFolders: getTreeFolders(state),
isLoading: getIsLoading(state), isLoading: getIsLoading(state),
isRecycleBinFolder: getIsRecycleBinFolder(state), isRecycleBinFolder: getIsRecycleBinFolder(state),
isPrivacy: getIsPrivacyFolder(state),
selection: getSelection(state), selection: getSelection(state),
}; };
}; };

View File

@ -1,7 +1,8 @@
import React from "react"; import React from "react";
import { withRouter } from "react-router"; import { withRouter } from "react-router";
import { Toast, Box } from "asc-web-components"; import { Toast, Box } from "asc-web-components";
import { utils, api, toastr, Loaders } from "asc-web-common"; import { utils, api, toastr, Loaders, regDesktop } from "asc-web-common";
import { isIOS, deviceType } from "react-device-detect"; import { isIOS, deviceType } from "react-device-detect";
import { setDocumentTitle } from "../../../helpers/utils"; import { setDocumentTitle } from "../../../helpers/utils";
import { changeTitle, setFavicon, isIPad } from "./utils"; import { changeTitle, setFavicon, isIPad } from "./utils";
@ -26,19 +27,23 @@ class PureEditor extends React.Component {
super(props); super(props);
const urlParams = getObjectByLocation(window.location); const urlParams = getObjectByLocation(window.location);
const fileId = urlParams ? urlParams.fileId || null : null; const fileId = urlParams
? urlParams.fileId || urlParams.fileid || null
: null;
const doc = urlParams ? urlParams.doc || null : null; const doc = urlParams ? urlParams.doc || null : null;
const desktop = window["AscDesktopEditor"] !== undefined;
this.state = { this.state = {
fileId, fileId,
doc, doc,
isLoading: true, isLoading: true,
isDesktop: desktop,
}; };
} }
async componentDidMount() { async componentDidMount() {
try { try {
const { fileId, doc } = this.state; const { fileId, doc, isDesktop } = this.state;
if (!fileId) return; if (!fileId) return;
@ -61,6 +66,20 @@ class PureEditor extends React.Component {
const config = await api.files.openEdit(fileId, doc); const config = await api.files.openEdit(fileId, doc);
if (isDesktop) {
const isEncryption =
config.editorConfig["encryptionKeys"] !== undefined;
const user = await api.people.getUser();
regDesktop(
user,
isEncryption,
config.editorConfig.encryptionKeys,
(keys) => api.files.setEncryptionKeys(keys),
true
);
}
this.setState({ isLoading: false }, () => this.setState({ isLoading: false }, () =>
this.loadDocApi(docApiUrl, () => this.onLoad(config)) this.loadDocApi(docApiUrl, () => this.onLoad(config))
); );
@ -90,7 +109,10 @@ class PureEditor extends React.Component {
}; };
onLoad = (config) => { onLoad = (config) => {
console.log("Editor config: ", config);
try { try {
console.log(config);
docTitle = config.document.title; docTitle = config.document.title;
fileType = config.document.fileType; fileType = config.document.fileType;

View File

@ -34,6 +34,7 @@ import {
getFilter, getFilter,
getFolders, getFolders,
getIsLoading, getIsLoading,
getIsPrivacyFolder,
getIsRecycleBinFolder, getIsRecycleBinFolder,
getNewRowItems, getNewRowItems,
getSelectedFolderId, getSelectedFolderId,
@ -50,10 +51,12 @@ import { NewFilesPanel } from "../../../../panels";
import { ConvertDialog } from "../../../../dialogs"; import { ConvertDialog } from "../../../../dialogs";
import EditingWrapperComponent from "./EditingWrapperComponent"; import EditingWrapperComponent from "./EditingWrapperComponent";
import { isMobile } from "react-device-detect"; import { isMobile } from "react-device-detect";
import { setEncryptionAccess } from "../../../../../helpers/desktop";
const { FileAction } = constants; const { FileAction } = constants;
const sideColor = "#A3A9AE"; const sideColor = "#A3A9AE";
const { getSettings } = initStore.auth.selectors; const { getSettings, isDesktopClient } = initStore.auth.selectors;
const { getEncryptionAccess, replaceFileStream } = initStore.auth.actions;
const SimpleFilesRowContent = styled(RowContent)` const SimpleFilesRowContent = styled(RowContent)`
.badge-ext { .badge-ext {
@ -163,7 +166,17 @@ class FilesRowContent extends React.PureComponent {
}; };
createItem = (e) => { createItem = (e) => {
const { createFile, item, setIsLoading, openDocEditor, i18n } = this.props; const {
createFile,
item,
setIsLoading,
openDocEditor,
isPrivacy,
isDesktop,
replaceFileStream,
i18n,
t,
} = this.props;
const { itemTitle } = this.state; const { itemTitle } = this.state;
setIsLoading(true); setIsLoading(true);
@ -175,9 +188,10 @@ class FilesRowContent extends React.PureComponent {
return this.completeAction(itemId); return this.completeAction(itemId);
} }
let tab = item.fileExst let tab =
? window.open("/products/files/doceditor", "_blank") !isDesktop && item.fileExst
: null; ? window.open("/products/files/doceditor", "_blank")
: null;
!item.fileExst !item.fileExst
? createFolder(item.parentId, itemTitle) ? createFolder(item.parentId, itemTitle)
@ -195,9 +209,21 @@ class FilesRowContent extends React.PureComponent {
}) })
: createFile(item.parentId, `${itemTitle}.${item.fileExst}`) : createFile(item.parentId, `${itemTitle}.${item.fileExst}`)
.then((file) => { .then((file) => {
openDocEditor(file.id, tab, file.webUrl); if (isPrivacy) {
this.completeAction(itemId); return setEncryptionAccess(file).then((encryptedFile) => {
if (!encryptedFile) return Promise.resolve();
toastr.info(t("EncryptedFileSaving"));
return replaceFileStream(
file.id,
encryptedFile,
true,
false
).then(() => openDocEditor(file.id, tab, file.webUrl));
});
}
return openDocEditor(file.id, tab, file.webUrl);
}) })
.then(() => this.completeAction(itemId))
.then(() => { .then(() => {
const exst = item.fileExst; const exst = item.fileExst;
return toastr.success( return toastr.success(
@ -733,6 +759,8 @@ function mapStateToProps(state, props) {
newRowItems: getNewRowItems(state), newRowItems: getNewRowItems(state),
dragging: getDragging(state), dragging: getDragging(state),
isLoading: getIsLoading(state), isLoading: getIsLoading(state),
isPrivacy: getIsPrivacyFolder(state),
isDesktop: isDesktopClient(state),
canWebEdit: canWebEdit(props.item.fileExst)(state), canWebEdit: canWebEdit(props.item.fileExst)(state),
canConvert: canConvert(props.item.fileExst)(state), canConvert: canConvert(props.item.fileExst)(state),
@ -753,4 +781,6 @@ export default connect(mapStateToProps, {
setIsLoading, setIsLoading,
clearSecondaryProgressData, clearSecondaryProgressData,
fetchFiles, fetchFiles,
getEncryptionAccess,
replaceFileStream,
})(withRouter(withTranslation()(FilesRowContent))); })(withRouter(withTranslation()(FilesRowContent)));

View File

@ -55,7 +55,7 @@ import {
setIsVerHistoryPanel, setIsVerHistoryPanel,
setVerHistoryFileId, setVerHistoryFileId,
setSharingPanelVisible, setSharingPanelVisible,
setChangeOwnerPanelVisible setChangeOwnerPanelVisible,
} from "../../../../../store/files/actions"; } from "../../../../../store/files/actions";
import { TIMEOUT } from "../../../../../helpers/constants"; import { TIMEOUT } from "../../../../../helpers/constants";
import { import {
@ -103,6 +103,7 @@ const {
isAdmin, isAdmin,
getSettings, getSettings,
getCurrentUser, getCurrentUser,
isDesktopClient,
isEncryptionSupport, isEncryptionSupport,
getOrganizationName, getOrganizationName,
getIsTabletView, getIsTabletView,
@ -188,6 +189,15 @@ const SimpleFilesRow = styled(Row)`
} }
`; `;
const EncryptedFileIcon = styled.div`
background: url("images/security.svg") no-repeat 0 0 / 16px 16px transparent;
height: 16px;
position: absolute;
width: 16px;
margin-top: 14px;
margin-left: ${(props) => (props.isEdit ? "40px" : "12px")};
`;
class SectionBodyContent extends React.Component { class SectionBodyContent extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
@ -546,7 +556,7 @@ class SectionBodyContent extends React.Component {
openDocEditor = (id, tab = null, url = null) => { openDocEditor = (id, tab = null, url = null) => {
return this.props return this.props
.addFileToRecentlyViewed(id) .addFileToRecentlyViewed(id, this.props.isPrivacy)
.then(() => console.log("Pushed to recently viewed")) .then(() => console.log("Pushed to recently viewed"))
.catch((e) => console.error(e)) .catch((e) => console.error(e))
.finally( .finally(
@ -883,6 +893,10 @@ class SectionBodyContent extends React.Component {
if (currentProps.viewAs !== nextProps.viewAs) { if (currentProps.viewAs !== nextProps.viewAs) {
return true; return true;
} }
if (currentProps.isPrivacy !== nextProps.isPrivacy) {
return true;
}
return false; return false;
}; };
@ -902,14 +916,19 @@ class SectionBodyContent extends React.Component {
getItemIcon = (item, isEdit) => { getItemIcon = (item, isEdit) => {
return ( return (
<ReactSVG <>
beforeInjection={(svg) => { <ReactSVG
svg.setAttribute("style", "margin-top: 4px"); beforeInjection={(svg) => {
isEdit && svg.setAttribute("style", "margin: 4px 0 0 28px"); svg.setAttribute("style", "margin-top: 4px");
}} isEdit && svg.setAttribute("style", "margin: 4px 0 0 28px");
src={item.icon} }}
loading={this.svgLoader} src={item.icon}
/> loading={this.svgLoader}
/>
{this.props.isPrivacy && item.fileExst && (
<EncryptedFileIcon isEdit={isEdit} />
)}
</>
); );
}; };
@ -954,6 +973,8 @@ class SectionBodyContent extends React.Component {
isFavorites, isFavorites,
isRecent, isRecent,
isPrivacy, isPrivacy,
isDesktop,
isEncryptionSupport,
organizationName, organizationName,
privacyInstructions, privacyInstructions,
title, title,
@ -991,15 +1012,17 @@ class SectionBodyContent extends React.Component {
</Box> </Box>
))} ))}
</Text> </Text>
<Text fontSize="12px"> {!isDesktop && (
<Trans i18nKey="PrivateRoomSupport" i18n={i18n}> <Text fontSize="12px">
Work in Private Room is available via {{ organizationName }} desktop <Trans i18nKey="PrivateRoomSupport" i18n={i18n}>
app. Work in Private Room is available via {{ organizationName }}
<Link isBold isHovered color="#116d9d" href={privacyInstructions}> desktop app.
Instructions <Link isBold isHovered color="#116d9d" href={privacyInstructions}>
</Link> Instructions
</Trans> </Link>
</Text> </Trans>
</Text>
)}
</> </>
); );
@ -1118,6 +1141,7 @@ class SectionBodyContent extends React.Component {
headerText={privateRoomHeader} headerText={privateRoomHeader}
descriptionText={privateRoomDescription} descriptionText={privateRoomDescription}
imageSrc="images/empty_screen_privacy.png" imageSrc="images/empty_screen_privacy.png"
buttons={isDesktop && isEncryptionSupport && commonButtons}
/> />
); );
} else { } else {
@ -1859,7 +1883,11 @@ class SectionBodyContent extends React.Component {
isEdit || item.id <= 0 isEdit || item.id <= 0
); );
const sharedButton = const sharedButton =
!canShare || isEdit || item.id <= 0 || sectionWidth < 500 !canShare ||
(isPrivacy && !item.fileExst) ||
isEdit ||
item.id <= 0 ||
sectionWidth < 500
? null ? null
: this.getSharedButton(item.shared); : this.getSharedButton(item.shared);
const displayShareButton = const displayShareButton =
@ -1889,6 +1917,7 @@ class SectionBodyContent extends React.Component {
contentElement={sharedButton} contentElement={sharedButton}
onSelect={this.onContentRowSelect} onSelect={this.onContentRowSelect}
editing={editingId} editing={editingId}
isPrivacy={isPrivacy}
{...checkedProps} {...checkedProps}
{...contextOptionsProps} {...contextOptionsProps}
needForUpdate={this.needForUpdate} needForUpdate={this.needForUpdate}
@ -1959,6 +1988,7 @@ const mapStateToProps = (state) => {
folders: getFolders(state), folders: getFolders(state),
isAdmin: isAdmin(state), isAdmin: isAdmin(state),
isCommon: getIsCommonFolder(state), isCommon: getIsCommonFolder(state),
isDesktop: isDesktopClient(state),
isEncryptionSupport: isEncryptionSupport(state), isEncryptionSupport: isEncryptionSupport(state),
isFavorites: getIsFavoritesFolder(state), isFavorites: getIsFavoritesFolder(state),
isMy: getIsMyFolder(state), isMy: getIsMyFolder(state),

View File

@ -52,9 +52,11 @@ import {
getAccessedSelected, getAccessedSelected,
getSelectionLength, getSelectionLength,
getSharePanelVisible, getSharePanelVisible,
getIsPrivacyFolder,
getOnlyFoldersSelected,
} from "../../../../../store/files/selectors"; } from "../../../../../store/files/selectors";
const { isAdmin } = store.auth.selectors; const { isAdmin, isDesktopClient } = store.auth.selectors;
const { FilterType, FileAction } = constants; const { FilterType, FileAction } = constants;
const { tablet, desktop } = utils.device; const { tablet, desktop } = utils.device;
const { Consumer } = utils.context; const { Consumer } = utils.context;
@ -144,7 +146,11 @@ const StyledContainer = styled.div`
width: ${props.width + 16 + "px"}; width: ${props.width + 16 + "px"};
`} `}
position: absolute; position: absolute;
top: 56px; ${(props) =>
!props.isDesktop &&
css`
top: 56px;
`}
z-index: 180; z-index: 180;
} }
} }
@ -404,6 +410,9 @@ class SectionHeaderContent extends React.Component {
isWebEditSelected, isWebEditSelected,
deleteDialogVisible, deleteDialogVisible,
isRecycleBin, isRecycleBin,
isPrivacy,
selection,
isOnlyFoldersSelected,
} = this.props; } = this.props;
let menu = [ let menu = [
@ -460,7 +469,9 @@ class SectionHeaderContent extends React.Component {
}, },
{ {
label: t("Share"), label: t("Share"),
disabled: !isAccessedSelected, disabled:
!isAccessedSelected ||
(isPrivacy && (isOnlyFoldersSelected || selection.length > 1)),
onClick: this.onOpenSharingPanel, onClick: this.onOpenSharingPanel,
}, },
{ {
@ -504,6 +515,11 @@ class SectionHeaderContent extends React.Component {
menu.splice(1, 1); menu.splice(1, 1);
} }
if (isPrivacy) {
menu.splice(3, 1);
menu.splice(4, 1);
}
return menu; return menu;
}; };
@ -520,6 +536,7 @@ class SectionHeaderContent extends React.Component {
isRootFolder, isRootFolder,
title, title,
canCreate, canCreate,
isDesktop,
} = this.props; } = this.props;
const { const {
@ -540,6 +557,7 @@ class SectionHeaderContent extends React.Component {
isRootFolder={isRootFolder} isRootFolder={isRootFolder}
canCreate={canCreate} canCreate={canCreate}
title={title} title={title}
isDesktop={isDesktop}
> >
{isHeaderVisible ? ( {isHeaderVisible ? (
<div className="group-button-menu-container"> <div className="group-button-menu-container">
@ -676,6 +694,8 @@ const mapStateToProps = (state) => {
isRootFolder: getIsRootFolder(state), isRootFolder: getIsRootFolder(state),
isAdmin: isAdmin(state), isAdmin: isAdmin(state),
isRecycleBin: getIsRecycleBinFolder(state), isRecycleBin: getIsRecycleBinFolder(state),
isPrivacy: getIsPrivacyFolder(state),
isDesktop: isDesktopClient(state),
parentId: getSelectedFolderParentId(state), parentId: getSelectedFolderParentId(state),
selection: getSelection(state), selection: getSelection(state),
title: getSelectedFolderTitle(state), title: getSelectedFolderTitle(state),
@ -690,6 +710,7 @@ const mapStateToProps = (state) => {
isAccessedSelected: getAccessedSelected(state), isAccessedSelected: getAccessedSelected(state),
isItemsSelected: getSelectionLength(state), isItemsSelected: getSelectionLength(state),
sharingPanelVisible: getSharePanelVisible(state), sharingPanelVisible: getSharePanelVisible(state),
isOnlyFoldersSelected: getOnlyFoldersSelected(state),
}; };
}; };

View File

@ -120,5 +120,6 @@
"CopyItems": "<strong>{{qty}}</strong> elements copied", "CopyItems": "<strong>{{qty}}</strong> elements copied",
"ContainsSpecCharacter": "The title cannot contain any of the following characters: *+:\"<>?|/", "ContainsSpecCharacter": "The title cannot contain any of the following characters: *+:\"<>?|/",
"CreateWithEmptyTitle": "Can't create folder or file with empty title", "CreateWithEmptyTitle": "Can't create folder or file with empty title",
"ChangeOwner": "Change owner" "ChangeOwner": "Change owner",
} "EncryptedFileSaving": "Saving encrypted file",
"EncryptedFileCreating": "File <strong>{{itemTitle}}</strong> successfully created"}

View File

@ -120,5 +120,6 @@
"CopyItems": "Скопировано элементов: <strong>{{qty}}</strong>", "CopyItems": "Скопировано элементов: <strong>{{qty}}</strong>",
"ContainsSpecCharacter": "Название не должно содержать следующих символов: *+:\"<>?|/", "ContainsSpecCharacter": "Название не должно содержать следующих символов: *+:\"<>?|/",
"CreateWithEmptyTitle": "Нельзя создать папку или файл с пустым названием", "CreateWithEmptyTitle": "Нельзя создать папку или файл с пустым названием",
"ChangeOwner": "Сменить владельца" "ChangeOwner": "Сменить владельца",
} "EncryptedFileSaving": "Сохранение зашифрованного файла",
"EncryptedFileCreating": "Создан новый файл <strong>{{itemTitle}}</strong>"}

View File

@ -3,10 +3,7 @@ import styled from "styled-components";
import { Headline } from "asc-web-common"; import { Headline } from "asc-web-common";
import { IconButton, utils } from "asc-web-components"; import { IconButton, utils } from "asc-web-components";
import { setFilesFilter } from "../../../../../store/files/actions"; const { desktop } = utils.device;
import { getFilter } from "../../../../../store/files/selectors";
const { tablet, desktop } = utils.device;
const StyledContainer = styled.div` const StyledContainer = styled.div`
display: grid; display: grid;
@ -24,43 +21,6 @@ const StyledContainer = styled.div`
} }
} }
.group-button-menu-container {
margin: 0 -16px;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
@media ${tablet} {
& > div:first-child {
position: absolute;
top: 56px;
z-index: 180;
}
}
@media ${desktop} {
margin: 0 -24px;
}
}
.header-container {
position: relative;
display: flex;
align-items: center;
max-width: calc(100vw - 32px);
.action-button {
margin-left: 16px;
@media ${tablet} {
margin-left: auto;
& > div:first-child {
padding: 8px 16px 8px 16px;
margin-right: -16px;
}
}
}
}
.headline-header { .headline-header {
@media ${desktop} { @media ${desktop} {
margin-left: -9px; margin-left: -9px;

View File

@ -30,6 +30,7 @@ import {
getFolders, getFolders,
getTreeFolders, getTreeFolders,
getSelectedFolder, getSelectedFolder,
getIsPrivacyFolder,
} from "../../../store/files/selectors"; } from "../../../store/files/selectors";
import { import {
fetchFiles, fetchFiles,
@ -140,6 +141,7 @@ class NewFilesPanelComponent extends React.Component {
setMediaViewerData, setMediaViewerData,
fetchFiles, fetchFiles,
addFileToRecentlyViewed, addFileToRecentlyViewed,
isPrivacy,
} = this.props; } = this.props;
if (!fileExst) { if (!fileExst) {
@ -149,7 +151,7 @@ class NewFilesPanelComponent extends React.Component {
const isMedia = [2, 3, 4].includes(fileType); const isMedia = [2, 3, 4].includes(fileType);
if (canEdit) { if (canEdit) {
return addFileToRecentlyViewed(id) return addFileToRecentlyViewed(id, isPrivacy)
.then(() => console.log("Pushed to recently viewed")) .then(() => console.log("Pushed to recently viewed"))
.catch((e) => console.error(e)) .catch((e) => console.error(e))
.finally(window.open(`./doceditor?fileId=${id}`, "_blank")); .finally(window.open(`./doceditor?fileId=${id}`, "_blank"));
@ -316,6 +318,7 @@ const mapStateToProps = (state) => {
folders: getFolders(state), folders: getFolders(state),
treeFolders: getTreeFolders(state), treeFolders: getTreeFolders(state),
selectedFolder: getSelectedFolder(state), selectedFolder: getSelectedFolder(state),
isPrivacy: getIsPrivacyFolder(state),
}; };
}; };

View File

@ -12,7 +12,7 @@ import {
} from "asc-web-components"; } from "asc-web-components";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { withRouter } from "react-router"; import { withRouter } from "react-router";
import { withTranslation } from "react-i18next"; import { withTranslation, Trans } from "react-i18next";
import { utils as commonUtils, constants, toastr, store } from "asc-web-common"; import { utils as commonUtils, constants, toastr, store } from "asc-web-common";
import { import {
getShareUsers, getShareUsers,
@ -31,6 +31,7 @@ import {
getIsLoading, getIsLoading,
getFiles, getFiles,
getFolders, getFolders,
getIsPrivacyFolder,
} from "../../../store/files/selectors"; } from "../../../store/files/selectors";
import { import {
StyledAsidePanel, StyledAsidePanel,
@ -42,12 +43,14 @@ import {
import { AddUsersPanel, AddGroupsPanel, EmbeddingPanel } from "../index"; import { AddUsersPanel, AddGroupsPanel, EmbeddingPanel } from "../index";
import SharingRow from "./SharingRow"; import SharingRow from "./SharingRow";
import { createI18N } from "../../../helpers/i18n"; import { createI18N } from "../../../helpers/i18n";
import { setEncryptionAccess } from "../../../helpers/desktop";
const i18n = createI18N({ const i18n = createI18N({
page: "SharingPanel", page: "SharingPanel",
localesPath: "panels/SharingPanel", localesPath: "panels/SharingPanel",
}); });
const { changeLanguage } = commonUtils; const { changeLanguage } = commonUtils;
const { ShareAccessRights } = constants; const { ShareAccessRights } = constants;
const { replaceFileStream } = store.auth.actions;
const { const {
getCurrentUserId, getCurrentUserId,
getSettingsCustomNamesGroupsCaption, getSettingsCustomNamesGroupsCaption,
@ -133,7 +136,14 @@ class SharingPanelComponent extends React.Component {
shareDataItems, shareDataItems,
filesOwnerId, filesOwnerId,
} = this.state; } = this.state;
const { selection, setIsLoading } = this.props; const {
selection,
setIsLoading,
isPrivacy,
replaceFileStream,
i18n,
t,
} = this.props;
const folderIds = []; const folderIds = [];
const fileIds = []; const fileIds = [];
@ -179,7 +189,6 @@ class SharingPanelComponent extends React.Component {
folderIds.push(item.id); folderIds.push(item.id);
} }
} }
const owner = shareDataItems.find((x) => x.isOwner); const owner = shareDataItems.find((x) => x.isOwner);
const ownerId = const ownerId =
filesOwnerId !== owner.sharedTo.id ? owner.sharedTo.id : null; filesOwnerId !== owner.sharedTo.id ? owner.sharedTo.id : null;
@ -199,6 +208,28 @@ class SharingPanelComponent extends React.Component {
if (ownerId) { if (ownerId) {
this.updateRowData(res[0]); this.updateRowData(res[0]);
} }
if (isPrivacy) {
if (share.length === 0) return Promise.resolve();
selection.forEach((item) => {
return setEncryptionAccess(item).then((encryptedFile) => {
if (!encryptedFile) return Promise.resolve();
toastr.info(t("EncryptedFileSaving"));
const title = item.title;
return replaceFileStream(item.id, encryptedFile, true, true).then(
() =>
toastr.success(
<Trans i18nKey="EncryptedFileSharing" i18n={i18n}>
File {{ title }} successfully shared
</Trans>
)
);
});
});
}
return Promise.resolve();
}) })
.catch((err) => toastr.error(err)) .catch((err) => toastr.error(err))
.finally(() => setIsLoading(false)); .finally(() => setIsLoading(false));
@ -574,6 +605,7 @@ const mapStateToProps = (state) => {
getExternalAccessOption(state, selection), getExternalAccessOption(state, selection),
isMyId: getCurrentUserId(state), isMyId: getCurrentUserId(state),
selection: getSelection(state), selection: getSelection(state),
isPrivacy: getIsPrivacyFolder(state),
groupsCaption: getSettingsCustomNamesGroupsCaption(state), groupsCaption: getSettingsCustomNamesGroupsCaption(state),
sharingPanelVisible: getSharePanelVisible(state), sharingPanelVisible: getSharePanelVisible(state),
canShareOwnerChange: getCanShareOwnerChange(state), canShareOwnerChange: getCanShareOwnerChange(state),
@ -585,6 +617,7 @@ const mapStateToProps = (state) => {
}; };
export default connect(mapStateToProps, { export default connect(mapStateToProps, {
replaceFileStream,
setSharingPanelVisible, setSharingPanelVisible,
setIsLoading, setIsLoading,
setFiles, setFiles,

View File

@ -16,6 +16,9 @@
"ExternalLink": "External link", "ExternalLink": "External link",
"InternalLink": "Internal link", "InternalLink": "Internal link",
"EncryptedFileSaving": "Saving encrypted file",
"EncryptedFileSharing": "File <strong>{{title}}</strong> successfully shared",
"FullAccess": "Full access", "FullAccess": "Full access",
"ReadOnly": "Read only", "ReadOnly": "Read only",
"Review": "Review", "Review": "Review",
@ -27,4 +30,4 @@
"ShareEveryone": "Everyone", "ShareEveryone": "Everyone",
"ShareEmailSubject": "You have been granted access to the {{itemName}} document", "ShareEmailSubject": "You have been granted access to the {{itemName}} document",
"ShareEmailBody": "You have been granted access to the {{itemName}} document. Click the link below to open the document right now: {{shareLink}}" "ShareEmailBody": "You have been granted access to the {{itemName}} document. Click the link below to open the document right now: {{shareLink}}"
} }

View File

@ -16,6 +16,9 @@
"ExternalLink": "Внешняя ссылка", "ExternalLink": "Внешняя ссылка",
"InternalLink": "Внутренняя ссылка", "InternalLink": "Внутренняя ссылка",
"EncryptedFileSaving": "Сохранение зашифрованного файла",
"EncryptedFileSharing": "К файлу <strong>{{title}}</strong> успешно предоставлен доступ",
"FullAccess": "Полный доступ", "FullAccess": "Полный доступ",
"ReadOnly": "Только чтение", "ReadOnly": "Только чтение",
"Review": "Рецензирование", "Review": "Рецензирование",

View File

@ -0,0 +1,57 @@
import store from "../store/store";
import { store as commonStore } from "asc-web-common";
import { getEncryptedFormats } from "../store/files/selectors";
import { desktopConstants } from "asc-web-common";
const { getEncryptionAccess } = commonStore.auth.actions;
export function encryptionUploadDialog(callback) {
const state = store.getState();
const filter = getEncryptedFormats(state)
.map((f) => "*" + f)
.join(" ");
const data = {
cryptoEngineId: desktopConstants.guid,
filter: filter,
};
window.AscDesktopEditor.cloudCryptoCommand("upload", data, function (obj) {
let bytes = obj.bytes;
let filename = obj.name;
let file = new File([bytes], filename);
if (typeof callback == "function") {
callback(file, obj.isCrypto !== false);
}
});
}
export function setEncryptionAccess(file) {
return getEncryptionAccess(file.id).then((keys) => {
let promise = new Promise((resolve, reject) => {
try {
window.AscDesktopEditor.cloudCryptoCommand(
"share",
{
"cryptoEngineId": desktopConstants.guid,
"file": [file.viewUrl],
"keys": keys,
},
(obj) => {
let file = null;
if (obj.isCrypto) {
let bytes = obj.bytes;
let filename = "temp_name";
file = new File([bytes], filename);
}
resolve(file);
}
);
} catch (e) {
reject(e);
}
});
return promise;
});
}

View File

@ -562,8 +562,9 @@ export function updateFile(fileId, title) {
}; };
} }
export function addFileToRecentlyViewed(fileId) { export function addFileToRecentlyViewed(fileId, isPrivacy) {
return (dispatch) => { return (dispatch) => {
if (isPrivacy) return Promise.resolve();
return files.addFileToRecentlyViewed(fileId); return files.addFileToRecentlyViewed(fileId);
}; };
} }

View File

@ -3,7 +3,13 @@ import { constants, store } from "asc-web-common";
import { createSelector } from "reselect"; import { createSelector } from "reselect";
const { FileType, FilterType, FolderType } = constants; const { FileType, FilterType, FolderType } = constants;
const { isAdmin, isVisitor, getCurrentUserId } = store.auth.selectors; const {
isAdmin,
isVisitor,
getCurrentUserId,
isEncryptionSupport,
isDesktopClient,
} = store.auth.selectors;
const presentInArray = (array, search) => { const presentInArray = (array, search) => {
const result = array.findIndex((item) => item === search); const result = array.findIndex((item) => item === search);
@ -65,6 +71,10 @@ export const getConvertedFormats = (state) => {
return state.files.docservice.convertDocs; return state.files.docservice.convertDocs;
}; };
export const getEncryptedFormats = (state) => {
return state.files.docservice.encryptedDocs;
};
export const getArchiveFormats = (state) => { export const getArchiveFormats = (state) => {
return state.files.formats.archive; return state.files.formats.archive;
}; };
@ -398,7 +408,9 @@ export const canCreate = createSelector(
isAdmin, isAdmin,
getPathParts, getPathParts,
getSelectedFolderAccess, getSelectedFolderAccess,
(folderType, isAdmin, pathParts, access) => { isEncryptionSupport,
isDesktopClient,
(folderType, isAdmin, pathParts, access, isSupport, isDesktop) => {
switch (folderType) { switch (folderType) {
case FolderType.USER: case FolderType.USER:
return true; return true;
@ -406,6 +418,8 @@ export const canCreate = createSelector(
const isNotRootFolder = pathParts.length > 1; const isNotRootFolder = pathParts.length > 1;
const canCreateInSharedFolder = access === 1; const canCreateInSharedFolder = access === 1;
return isNotRootFolder && canCreateInSharedFolder; return isNotRootFolder && canCreateInSharedFolder;
case FolderType.Privacy:
return isDesktop && isSupport;
case FolderType.COMMON: case FolderType.COMMON:
return isAdmin; return isAdmin;
case FolderType.TRASH: case FolderType.TRASH:
@ -657,7 +671,8 @@ const getFilesContextOptions = (
canOpenPlayer, canOpenPlayer,
canChangeOwner, canChangeOwner,
canBeDeleted, canBeDeleted,
canShare canShare,
isPrivacy
) => { ) => {
const options = []; const options = [];
@ -673,6 +688,18 @@ const getFilesContextOptions = (
options.push("restore"); options.push("restore");
options.push("separator0"); options.push("separator0");
options.push("delete"); options.push("delete");
} else if (isPrivacy) {
if (isFile) {
options.push("sharing-settings");
options.push("separator0");
options.push("show-version-history");
options.push("separator1");
}
options.push("download");
options.push("move");
options.push("rename");
options.push("separator2");
options.push("delete");
} else { } else {
if (!isFile) { if (!isFile) {
options.push("open"); options.push("open");
@ -900,6 +927,7 @@ export const getFilesList = (state) => {
getIsRecentFolder, getIsRecentFolder,
getIsFavoritesFolder, getIsFavoritesFolder,
getFileActionId, getFileActionId,
getIsPrivacyFolder,
isVisitor, isVisitor,
getCanShareOwnerChange, getCanShareOwnerChange,
isCanBeDeleted, isCanBeDeleted,
@ -916,7 +944,8 @@ export const getFilesList = (state) => {
isVisitor, isVisitor,
canChangeOwner, canChangeOwner,
canBeDeleted, canBeDeleted,
canShare canShare,
isPrivacy
) => { ) => {
const items = const items =
folders && files folders && files
@ -965,7 +994,8 @@ export const getFilesList = (state) => {
canOpenPlayer, canOpenPlayer,
canChangeOwner, canChangeOwner,
canBeDeleted, canBeDeleted,
canShare canShare,
isPrivacy
); );
const checked = isFileSelected(selection, id, parentId); const checked = isFileSelected(selection, id, parentId);
@ -1234,14 +1264,21 @@ export const getAccessedSelected = createSelector(
export const getOperationsFolders = createSelector( export const getOperationsFolders = createSelector(
getTreeFolders, getTreeFolders,
(treeFolders) => { getIsPrivacyFolder,
return treeFolders.filter( (treeFolders, isPrivacy) => {
(folder) => if (isPrivacy) {
(folder.rootFolderType === FolderType.USER || return treeFolders.filter(
folder.rootFolderType === FolderType.COMMON || (folder) => folder.rootFolderType === FolderType.Privacy && folder
folder.rootFolderType === FolderType.Projects) && );
folder } else {
); return treeFolders.filter(
(folder) =>
(folder.rootFolderType === FolderType.USER ||
folder.rootFolderType === FolderType.COMMON ||
folder.rootFolderType === FolderType.Projects) &&
folder
);
}
} }
); );
const getIcon = (state, size = 24, fileExst = null, providerKey = null) => { const getIcon = (state, size = 24, fileExst = null, providerKey = null) => {
@ -1365,6 +1402,8 @@ export const isCanBeDeleted = createSelector(
return ( return (
isAdmin || selection.some((x) => x.access === 0 || x.access === 1) isAdmin || selection.some((x) => x.access === 0 || x.access === 1)
); );
case FolderType.Privacy:
return true;
case FolderType.TRASH: case FolderType.TRASH:
return true; return true;
default: default:
@ -1395,6 +1434,8 @@ export const isCanShare = createSelector(
return false; return false;
case FolderType.Recent: case FolderType.Recent:
return false; return false;
case FolderType.Privacy:
return true;
default: default:
return false; return false;
} }

View File

@ -1712,9 +1712,9 @@
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
"@types/node@*": "@types/node@*":
version "14.14.16" version "14.14.17"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.16.tgz#3cc351f8d48101deadfed4c9e4f116048d437b4b" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.17.tgz#29fab92f3986c0e379968ad3c2043683d8020dbb"
integrity sha512-naXYePhweTi+BMv11TgioE2/FXU4fSl29HAH1ffxVciNsH3rYXjNP2yM8wqmSm7jS20gM8TIklKiTen+1iVncw== integrity sha512-G0lD1/7qD60TJ/mZmhog76k7NcpLWkPVGgzkRy3CTlnFu4LUQh5v2Wa661z6vnXmD8EQrnALUyf0VRtrACYztw==
"@types/normalize-package-data@^2.4.0": "@types/normalize-package-data@^2.4.0":
version "2.4.0" version "2.4.0"
@ -2379,7 +2379,7 @@ asap@~2.0.6:
integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
"asc-web-common@file:../../../packages/asc-web-common": "asc-web-common@file:../../../packages/asc-web-common":
version "1.0.312" version "1.0.313"
dependencies: dependencies:
axios "^0.21.1" axios "^0.21.1"
history "4.10.1" history "4.10.1"
@ -2396,7 +2396,7 @@ asap@~2.0.6:
sjcl "^1.0.8" sjcl "^1.0.8"
"asc-web-components@file:../../../packages/asc-web-components": "asc-web-components@file:../../../packages/asc-web-components":
version "1.0.499" version "1.0.500"
dependencies: dependencies:
email-addresses "^3.1.0" email-addresses "^3.1.0"
html-to-react "^1.4.5" html-to-react "^1.4.5"
@ -4607,7 +4607,7 @@ es-abstract@^1.17.0-next.1, es-abstract@^1.17.2:
string.prototype.trimend "^1.0.1" string.prototype.trimend "^1.0.1"
string.prototype.trimstart "^1.0.1" string.prototype.trimstart "^1.0.1"
es-abstract@^1.18.0-next.0, es-abstract@^1.18.0-next.1: es-abstract@^1.18.0-next.1:
version "1.18.0-next.1" version "1.18.0-next.1"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.1.tgz#6e3a0a4bda717e5023ab3b8e90bec36108d22c68" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.1.tgz#6e3a0a4bda717e5023ab3b8e90bec36108d22c68"
integrity sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA== integrity sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==
@ -4772,9 +4772,9 @@ eslint-plugin-react-hooks@^4.2.0:
integrity sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ== integrity sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==
eslint-plugin-react@^7.21.5: eslint-plugin-react@^7.21.5:
version "7.21.5" version "7.22.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.21.5.tgz#50b21a412b9574bfe05b21db176e8b7b3b15bff3" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.22.0.tgz#3d1c542d1d3169c45421c1215d9470e341707269"
integrity sha512-8MaEggC2et0wSF6bUeywF7qQ46ER81irOdWS4QWxnnlAEsnzeBevk1sWh7fhpCghPpXb+8Ks7hvaft6L/xsR6g== integrity sha512-p30tuX3VS+NWv9nQot9xIGAHBXR0+xJVaZriEsHoJrASGCJZDJ8JLNM0YqKqI0AKm6Uxaa1VUHoNEibxRCMQHA==
dependencies: dependencies:
array-includes "^3.1.1" array-includes "^3.1.1"
array.prototype.flatmap "^1.2.3" array.prototype.flatmap "^1.2.3"
@ -5502,7 +5502,7 @@ get-caller-file@^2.0.1:
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
get-intrinsic@^1.0.0, get-intrinsic@^1.0.1: get-intrinsic@^1.0.0, get-intrinsic@^1.0.1, get-intrinsic@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49"
integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg== integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==
@ -8157,7 +8157,7 @@ object-copy@^0.1.0:
define-property "^0.2.5" define-property "^0.2.5"
kind-of "^3.0.3" kind-of "^3.0.3"
object-inspect@^1.8.0: object-inspect@^1.8.0, object-inspect@^1.9.0:
version "1.9.0" version "1.9.0"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a"
integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==
@ -9389,9 +9389,9 @@ postcss@^7, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, po
supports-color "^6.1.0" supports-color "^6.1.0"
postcss@^8.1.0: postcss@^8.1.0:
version "8.2.1" version "8.2.2"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.1.tgz#eabc5557c4558059b9d9e5b15bce7ffa9089c2a8" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.2.tgz#60613b62297005084fd21024a68637798864fe26"
integrity sha512-RhsqOOAQzTgh1UB/IZdca7F9WDb7SUCR2Vnv1x7DbvuuggQIpoDwjK+q0rzoPffhYvWNKX5JSwS4so4K3UC6vA== integrity sha512-HM1NDNWLgglJPQQMNwvLxgH2KcrKZklKLi/xXYIOaqQB57p/pDWEJNS83PVICYsn1Dg/9C26TiejNr422/ePaQ==
dependencies: dependencies:
colorette "^1.2.1" colorette "^1.2.1"
nanoid "^3.1.20" nanoid "^3.1.20"
@ -10841,12 +10841,13 @@ shellwords@^0.1.1:
integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==
side-channel@^1.0.2, side-channel@^1.0.3: side-channel@^1.0.2, side-channel@^1.0.3:
version "1.0.3" version "1.0.4"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.3.tgz#cdc46b057550bbab63706210838df5d4c19519c3" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
integrity sha512-A6+ByhlLkksFoUepsGxfj5x1gTSrs+OydsRptUxeNCabQpCFUvcwIczgOigI8vhY/OJCnPnyE9rGiwgvr9cS1g== integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
dependencies: dependencies:
es-abstract "^1.18.0-next.0" call-bind "^1.0.0"
object-inspect "^1.8.0" get-intrinsic "^1.0.2"
object-inspect "^1.9.0"
signal-exit@^3.0.0, signal-exit@^3.0.2: signal-exit@^3.0.0, signal-exit@^3.0.2:
version "3.0.3" version "3.0.3"
@ -12578,9 +12579,9 @@ ws@^6.0.0, ws@^6.2.1:
async-limiter "~1.0.0" async-limiter "~1.0.0"
ws@^7.2.3: ws@^7.2.3:
version "7.4.1" version "7.4.2"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.1.tgz#a333be02696bd0e54cea0434e21dcc8a9ac294bb" resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.2.tgz#782100048e54eb36fe9843363ab1c68672b261dd"
integrity sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ== integrity sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==
xml-name-validator@^3.0.0: xml-name-validator@^3.0.0:
version "3.0.0" version "3.0.0"

View File

@ -42,7 +42,7 @@ namespace ASC.Files.Core
IEnumerable<Tag> GetTags(TagType tagType, IEnumerable<FileEntry<T>> fileEntries); IEnumerable<Tag> GetTags(TagType tagType, IEnumerable<FileEntry<T>> fileEntries);
IDictionary<object, Tag> GetTags(Guid subject, IEnumerable<TagType> tagType, IEnumerable<FileEntry<T>> fileEntries); IDictionary<object, IEnumerable<Tag>> GetTags(Guid subject, IEnumerable<TagType> tagType, IEnumerable<FileEntry<T>> fileEntries);
IEnumerable<Tag> GetNewTags(Guid subject, IEnumerable<FileEntry<T>> fileEntries); IEnumerable<Tag> GetNewTags(Guid subject, IEnumerable<FileEntry<T>> fileEntries);

View File

@ -79,9 +79,10 @@ namespace ASC.Files.Core.Data
CoreConfiguration coreConfiguration, CoreConfiguration coreConfiguration,
SettingsManager settingsManager, SettingsManager settingsManager,
AuthContext authContext, AuthContext authContext,
IServiceProvider serviceProvider) IServiceProvider serviceProvider,
ICache cache)
{ {
cache = AscCache.Memory; this.cache = cache;
FilesDbContext = dbContextManager.Get(FileConstant.DatabaseId); FilesDbContext = dbContextManager.Get(FileConstant.DatabaseId);
UserManager = userManager; UserManager = userManager;
TenantManager = tenantManager; TenantManager = tenantManager;

View File

@ -32,6 +32,7 @@ using System.Linq.Expressions;
using System.Text; using System.Text;
using ASC.Common; using ASC.Common;
using ASC.Common.Caching;
using ASC.Core; using ASC.Core;
using ASC.Core.Common.EF; using ASC.Core.Common.EF;
using ASC.Core.Common.Settings; using ASC.Core.Common.Settings;
@ -85,6 +86,7 @@ namespace ASC.Files.Core.Data
SettingsManager settingsManager, SettingsManager settingsManager,
AuthContext authContext, AuthContext authContext,
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
ICache cache,
GlobalStore globalStore, GlobalStore globalStore,
GlobalSpace globalSpace, GlobalSpace globalSpace,
GlobalFolder globalFolder, GlobalFolder globalFolder,
@ -104,7 +106,8 @@ namespace ASC.Files.Core.Data
coreConfiguration, coreConfiguration,
settingsManager, settingsManager,
authContext, authContext,
serviceProvider) serviceProvider,
cache)
{ {
FactoryIndexer = factoryIndexer; FactoryIndexer = factoryIndexer;
GlobalStore = globalStore; GlobalStore = globalStore;

View File

@ -31,6 +31,7 @@ using System.Linq.Expressions;
using System.Threading; using System.Threading;
using ASC.Common; using ASC.Common;
using ASC.Common.Caching;
using ASC.Core; using ASC.Core;
using ASC.Core.Common.EF; using ASC.Core.Common.EF;
using ASC.Core.Common.Settings; using ASC.Core.Common.Settings;
@ -86,6 +87,7 @@ namespace ASC.Files.Core.Data
SettingsManager settingsManager, SettingsManager settingsManager,
AuthContext authContext, AuthContext authContext,
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
ICache cache,
GlobalSpace globalSpace, GlobalSpace globalSpace,
IDaoFactory daoFactory, IDaoFactory daoFactory,
ProviderFolderDao providerFolderDao, ProviderFolderDao providerFolderDao,
@ -102,7 +104,8 @@ namespace ASC.Files.Core.Data
coreConfiguration, coreConfiguration,
settingsManager, settingsManager,
authContext, authContext,
serviceProvider) serviceProvider,
cache)
{ {
FactoryIndexer = factoryIndexer; FactoryIndexer = factoryIndexer;
GlobalSpace = globalSpace; GlobalSpace = globalSpace;

View File

@ -30,6 +30,7 @@ using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using ASC.Common; using ASC.Common;
using ASC.Common.Caching;
using ASC.Core; using ASC.Core;
using ASC.Core.Common.EF; using ASC.Core.Common.EF;
using ASC.Core.Common.Settings; using ASC.Core.Common.Settings;
@ -56,7 +57,8 @@ namespace ASC.Files.Core.Data
CoreConfiguration coreConfiguration, CoreConfiguration coreConfiguration,
SettingsManager settingsManager, SettingsManager settingsManager,
AuthContext authContext, AuthContext authContext,
IServiceProvider serviceProvider) IServiceProvider serviceProvider,
ICache cache)
: base(dbContextManager, : base(dbContextManager,
userManager, userManager,
tenantManager, tenantManager,
@ -68,7 +70,8 @@ namespace ASC.Files.Core.Data
coreConfiguration, coreConfiguration,
settingsManager, settingsManager,
authContext, authContext,
serviceProvider) serviceProvider,
cache)
{ {
} }

View File

@ -31,6 +31,7 @@ using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using ASC.Common; using ASC.Common;
using ASC.Common.Caching;
using ASC.Core; using ASC.Core;
using ASC.Core.Common.EF; using ASC.Core.Common.EF;
using ASC.Core.Common.Settings; using ASC.Core.Common.Settings;
@ -59,7 +60,8 @@ namespace ASC.Files.Core.Data
CoreConfiguration coreConfiguration, CoreConfiguration coreConfiguration,
SettingsManager settingsManager, SettingsManager settingsManager,
AuthContext authContext, AuthContext authContext,
IServiceProvider serviceProvider) IServiceProvider serviceProvider,
ICache cache)
: base(dbContextManager, : base(dbContextManager,
userManager, userManager,
tenantManager, tenantManager,
@ -71,7 +73,8 @@ namespace ASC.Files.Core.Data
coreConfiguration, coreConfiguration,
settingsManager, settingsManager,
authContext, authContext,
serviceProvider) serviceProvider,
cache)
{ {
} }
@ -108,7 +111,7 @@ namespace ASC.Files.Core.Data
return FromQuery(q); return FromQuery(q);
} }
public IDictionary<object, Tag> GetTags(Guid subject, IEnumerable<TagType> tagType, IEnumerable<FileEntry<T>> fileEntries) public IDictionary<object, IEnumerable<Tag>> GetTags(Guid subject, IEnumerable<TagType> tagType, IEnumerable<FileEntry<T>> fileEntries)
{ {
var filesId = new HashSet<string>(); var filesId = new HashSet<string>();
var foldersId = new HashSet<string>(); var foldersId = new HashSet<string>();
@ -139,7 +142,8 @@ namespace ASC.Files.Core.Data
} }
return FromQuery(q) return FromQuery(q)
.ToDictionary(r=> r.EntryId); .GroupBy(r=> r.EntryId)
.ToDictionary(r=> r.Key, r=> r.AsEnumerable());
} }
public IEnumerable<Tag> GetTags(TagType tagType, IEnumerable<FileEntry<T>> fileEntries) public IEnumerable<Tag> GetTags(TagType tagType, IEnumerable<FileEntry<T>> fileEntries)

View File

@ -94,7 +94,12 @@ namespace ASC.Web.Files.Core.Entries
var currentAddressString = EncryptionLoginProvider.GetKeys(); var currentAddressString = EncryptionLoginProvider.GetKeys();
if (string.IsNullOrEmpty(currentAddressString)) return null; if (string.IsNullOrEmpty(currentAddressString)) return null;
var keyPair = JsonSerializer.Deserialize<EncryptionKeyPair>(currentAddressString); var options = new JsonSerializerOptions
{
AllowTrailingCommas = true,
PropertyNameCaseInsensitive = true
};
var keyPair = JsonSerializer.Deserialize<EncryptionKeyPair>(currentAddressString, options);
if (keyPair.UserId != AuthContext.CurrentAccount.ID) return null; if (keyPair.UserId != AuthContext.CurrentAccount.ID) return null;
return keyPair; return keyPair;
} }
@ -120,7 +125,13 @@ namespace ASC.Web.Files.Core.Entries
var fileKeyPairString = EncryptionLoginProvider.GetKeys(share.SubjectId); var fileKeyPairString = EncryptionLoginProvider.GetKeys(share.SubjectId);
if (string.IsNullOrEmpty(fileKeyPairString)) return null; if (string.IsNullOrEmpty(fileKeyPairString)) return null;
var fileKeyPair = JsonSerializer.Deserialize<EncryptionKeyPair>(fileKeyPairString);
var options = new JsonSerializerOptions
{
AllowTrailingCommas = true,
PropertyNameCaseInsensitive = true
};
var fileKeyPair = JsonSerializer.Deserialize<EncryptionKeyPair>(fileKeyPairString, options);
if (fileKeyPair.UserId != share.SubjectId) return null; if (fileKeyPair.UserId != share.SubjectId) return null;
fileKeyPair.PrivateKeyEnc = null; fileKeyPair.PrivateKeyEnc = null;

View File

@ -66,7 +66,8 @@ namespace ASC.Files.Core
public File(Global global, public File(Global global,
FilesLinkUtility filesLinkUtility, FilesLinkUtility filesLinkUtility,
FileUtility fileUtility, FileUtility fileUtility,
FileConverter fileConverter) FileConverter fileConverter,
FileTrackerHelper fileTracker)
: base(global) : base(global)
{ {
Version = 1; Version = 1;
@ -74,7 +75,8 @@ namespace ASC.Files.Core
FileEntryType = FileEntryType.File; FileEntryType = FileEntryType.File;
FilesLinkUtility = filesLinkUtility; FilesLinkUtility = filesLinkUtility;
FileUtility = fileUtility; FileUtility = fileUtility;
FileConverter = fileConverter; FileConverter = fileConverter;
FileTracker = fileTracker;
} }
public int Version { get; set; } public int Version { get; set; }
@ -230,8 +232,9 @@ namespace ASC.Files.Core
} }
} }
public object NativeAccessor { get; set; } public object NativeAccessor { get; set; }
public FileTrackerHelper FileTracker { get; }
[NonSerialized] [NonSerialized]
private readonly FilesLinkUtility FilesLinkUtility; private readonly FilesLinkUtility FilesLinkUtility;

View File

@ -115,6 +115,7 @@ namespace ASC.Web.Files.Services.WCFService
private SettingsManager SettingsManager { get; } private SettingsManager SettingsManager { get; }
private FileOperationsManager FileOperationsManager { get; } private FileOperationsManager FileOperationsManager { get; }
private TenantManager TenantManager { get; } private TenantManager TenantManager { get; }
public FileTrackerHelper FileTracker { get; }
private ILog Logger { get; set; } private ILog Logger { get; set; }
public FileStorageService( public FileStorageService(
@ -156,7 +157,8 @@ namespace ASC.Web.Files.Services.WCFService
EncryptionKeyPairHelper encryptionKeyPairHelper, EncryptionKeyPairHelper encryptionKeyPairHelper,
SettingsManager settingsManager, SettingsManager settingsManager,
FileOperationsManager fileOperationsManager, FileOperationsManager fileOperationsManager,
TenantManager tenantManager) TenantManager tenantManager,
FileTrackerHelper fileTracker)
{ {
Global = global; Global = global;
GlobalStore = globalStore; GlobalStore = globalStore;
@ -197,6 +199,7 @@ namespace ASC.Web.Files.Services.WCFService
Logger = optionMonitor.Get("ASC.Files"); Logger = optionMonitor.Get("ASC.Files");
FileOperationsManager = fileOperationsManager; FileOperationsManager = fileOperationsManager;
TenantManager = tenantManager; TenantManager = tenantManager;
FileTracker = fileTracker;
} }
public Folder<T> GetFolder(T folderId) public Folder<T> GetFolder(T folderId)

View File

@ -28,6 +28,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using ASC.Common; using ASC.Common;
using ASC.Common.Caching;
using ASC.Common.Logging; using ASC.Common.Logging;
using ASC.Core; using ASC.Core;
using ASC.ElasticSearch; using ASC.ElasticSearch;
@ -53,8 +54,9 @@ namespace ASC.Web.Files.Core.Search
FactoryIndexer factoryIndexer, FactoryIndexer factoryIndexer,
BaseIndexer<DbFile> baseIndexer, BaseIndexer<DbFile> baseIndexer,
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
IDaoFactory daoFactory) IDaoFactory daoFactory,
: base(options, tenantManager, searchSettingsHelper, factoryIndexer, baseIndexer, serviceProvider) ICache cache)
: base(options, tenantManager, searchSettingsHelper, factoryIndexer, baseIndexer, serviceProvider, cache)
{ {
DaoFactory = daoFactory; DaoFactory = daoFactory;
} }

View File

@ -29,6 +29,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using ASC.Common; using ASC.Common;
using ASC.Common.Caching;
using ASC.Common.Logging; using ASC.Common.Logging;
using ASC.Core; using ASC.Core;
using ASC.ElasticSearch; using ASC.ElasticSearch;
@ -53,8 +54,9 @@ namespace ASC.Web.Files.Core.Search
FactoryIndexer factoryIndexer, FactoryIndexer factoryIndexer,
BaseIndexer<DbFolder> baseIndexer, BaseIndexer<DbFolder> baseIndexer,
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
IDaoFactory daoFactory) IDaoFactory daoFactory,
: base(options, tenantManager, searchSettingsHelper, factoryIndexer, baseIndexer, serviceProvider) ICache cache)
: base(options, tenantManager, searchSettingsHelper, factoryIndexer, baseIndexer, serviceProvider, cache)
{ {
DaoFactory = daoFactory; DaoFactory = daoFactory;
} }

View File

@ -217,13 +217,16 @@ namespace ASC.Files.Thirdparty.Box
public class BoxProviderInfoHelper public class BoxProviderInfoHelper
{ {
private readonly TimeSpan CacheExpiration = TimeSpan.FromMinutes(1); private readonly TimeSpan CacheExpiration = TimeSpan.FromMinutes(1);
private readonly ICache CacheFile = AscCache.Memory; private readonly ICache CacheFile;
private readonly ICache CacheFolder = AscCache.Memory; private readonly ICache CacheFolder;
private readonly ICache CacheChildItems = AscCache.Memory; private readonly ICache CacheChildItems;
private readonly ICacheNotify<BoxCacheItem> CacheNotify; private readonly ICacheNotify<BoxCacheItem> CacheNotify;
public BoxProviderInfoHelper(ICacheNotify<BoxCacheItem> cacheNotify) public BoxProviderInfoHelper(ICacheNotify<BoxCacheItem> cacheNotify, ICache cache)
{ {
CacheFile = cache;
CacheFolder = cache;
CacheChildItems = cache;
CacheNotify = cacheNotify; CacheNotify = cacheNotify;
CacheNotify.Subscribe((i) => CacheNotify.Subscribe((i) =>
{ {

View File

@ -185,12 +185,12 @@ namespace ASC.Files.Thirdparty.Dropbox
private readonly ICache CacheChildItems; private readonly ICache CacheChildItems;
private readonly ICacheNotify<DropboxCacheItem> CacheNotify; private readonly ICacheNotify<DropboxCacheItem> CacheNotify;
public DropboxProviderInfoHelper(ICacheNotify<DropboxCacheItem> cacheNotify) public DropboxProviderInfoHelper(ICacheNotify<DropboxCacheItem> cacheNotify, ICache cache)
{ {
CacheExpiration = TimeSpan.FromMinutes(1); CacheExpiration = TimeSpan.FromMinutes(1);
CacheFile = AscCache.Memory; CacheFile = cache;
CacheFolder = AscCache.Memory; CacheFolder = cache;
CacheChildItems = AscCache.Memory; CacheChildItems = cache;
CacheNotify = cacheNotify; CacheNotify = cacheNotify;
CacheNotify.Subscribe((i) => CacheNotify.Subscribe((i) =>

View File

@ -233,12 +233,12 @@ namespace ASC.Files.Thirdparty.GoogleDrive
private readonly ICache CacheChildFolders; private readonly ICache CacheChildFolders;
private readonly ICacheNotify<GoogleDriveCacheItem> CacheNotify; private readonly ICacheNotify<GoogleDriveCacheItem> CacheNotify;
public GoogleDriveProviderInfoHelper(ICacheNotify<GoogleDriveCacheItem> cacheNotify) public GoogleDriveProviderInfoHelper(ICacheNotify<GoogleDriveCacheItem> cacheNotify, ICache cache)
{ {
CacheExpiration = TimeSpan.FromMinutes(1); CacheExpiration = TimeSpan.FromMinutes(1);
CacheEntry = AscCache.Memory; CacheEntry = cache;
CacheChildFiles = AscCache.Memory; CacheChildFiles = cache;
CacheChildFolders = AscCache.Memory; CacheChildFolders = cache;
CacheNotify = cacheNotify; CacheNotify = cacheNotify;
CacheNotify.Subscribe((i) => CacheNotify.Subscribe((i) =>

View File

@ -402,9 +402,9 @@ namespace ASC.Files.Thirdparty
return new List<Tag>(); return new List<Tag>();
} }
public IDictionary<object, Tag> GetTags(Guid subject, IEnumerable<TagType> tagType, IEnumerable<FileEntry<string>> fileEntries) public IDictionary<object, IEnumerable<Tag>> GetTags(Guid subject, IEnumerable<TagType> tagType, IEnumerable<FileEntry<string>> fileEntries)
{ {
return new Dictionary<object, Tag>(); return new Dictionary<object, IEnumerable<Tag>>();
} }
@ -464,23 +464,18 @@ namespace ASC.Files.Thirdparty
if (!entryIDs.Any()) return new List<Tag>(); if (!entryIDs.Any()) return new List<Tag>();
var q = FilesDbContext.Tag var q = from r in FilesDbContext.Tag
.Join(FilesDbContext.TagLink.DefaultIfEmpty(), from l in FilesDbContext.TagLink.Where(a => a.TenantId == r.TenantId && a.TagId == r.Id).DefaultIfEmpty()
r => new TagLink { TenantId = r.TenantId, Id = r.Id }, where r.TenantId == TenantID && l.TenantId == TenantID && r.Flag == TagType.New && entryIDs.Contains(l.EntryId)
r => new TagLink { TenantId = r.TenantId, Id = r.TagId }, select new { tag = r, tagLink = l };
(tag, tagLink) => new { tag, tagLink },
new TagLinkComparer())
.Where(r => r.tag.TenantId == TenantID)
.Where(r => r.tag.Flag == TagType.New)
.Where(r => r.tagLink.TenantId == TenantID)
.Where(r => entryIDs.Any(a => a == r.tagLink.EntryId));
if (subject != Guid.Empty) if (subject != Guid.Empty)
{ {
q = q.Where(r => r.tag.Owner == subject); q = q.Where(r => r.tag.Owner == subject);
} }
var tags = q var tags = q
.Distinct()
.ToList() .ToList()
.Select(r => new Tag .Select(r => new Tag
{ {

View File

@ -197,11 +197,11 @@ namespace ASC.Files.Thirdparty.OneDrive
private readonly ICache CacheChildItems; private readonly ICache CacheChildItems;
private readonly ICacheNotify<OneDriveCacheItem> CacheNotify; private readonly ICacheNotify<OneDriveCacheItem> CacheNotify;
public OneDriveProviderInfoHelper(ICacheNotify<OneDriveCacheItem> cacheNotify) public OneDriveProviderInfoHelper(ICacheNotify<OneDriveCacheItem> cacheNotify, ICache cache)
{ {
CacheExpiration = TimeSpan.FromMinutes(1); CacheExpiration = TimeSpan.FromMinutes(1);
CacheItem = AscCache.Memory; CacheItem = cache;
CacheChildItems = AscCache.Memory; CacheChildItems = cache;
CacheNotify = cacheNotify; CacheNotify = cacheNotify;
CacheNotify.Subscribe((i) => CacheNotify.Subscribe((i) =>

View File

@ -129,7 +129,7 @@ namespace ASC.Files.Thirdparty.ProviderDao
return TagDao.GetTags(entryID, entryType, tagType); return TagDao.GetTags(entryID, entryType, tagType);
} }
public IDictionary<object, Tag> GetTags(Guid subject, IEnumerable<TagType> tagType, IEnumerable<FileEntry<string>> fileEntries) public IDictionary<object, IEnumerable<Tag>> GetTags(Guid subject, IEnumerable<TagType> tagType, IEnumerable<FileEntry<string>> fileEntries)
{ {
return TagDao.GetTags(subject, tagType, fileEntries); return TagDao.GetTags(subject, tagType, fileEntries);
} }

View File

@ -592,11 +592,11 @@ namespace ASC.Files.Thirdparty.SharePoint
private readonly ICache FolderCache; private readonly ICache FolderCache;
private readonly ICacheNotify<SharePointProviderCacheItem> Notify; private readonly ICacheNotify<SharePointProviderCacheItem> Notify;
public SharePointProviderInfoHelper(ICacheNotify<SharePointProviderCacheItem> notify) public SharePointProviderInfoHelper(ICacheNotify<SharePointProviderCacheItem> notify, ICache cache)
{ {
CacheExpiration = TimeSpan.FromMinutes(1); CacheExpiration = TimeSpan.FromMinutes(1);
FileCache = AscCache.Memory; FileCache = cache;
FolderCache = AscCache.Memory; FolderCache = cache;
Notify = notify; Notify = notify;
Notify.Subscribe((i) => Notify.Subscribe((i) =>

View File

@ -364,8 +364,13 @@ namespace ASC.Web.Files.Services.DocumentService
set set
{ {
try try
{ {
JsonSerializer.Deserialize<ActionLinkConfig>(value); var options = new JsonSerializerOptions
{
AllowTrailingCommas = true,
PropertyNameCaseInsensitive = true
};
JsonSerializer.Deserialize<ActionLinkConfig>(value, options);
} }
catch (Exception) catch (Exception)
{ {
@ -584,7 +589,7 @@ namespace ASC.Web.Files.Services.DocumentService
public class EncryptionKeysConfig public class EncryptionKeysConfig
{ {
public string CryptoEngineId = "{FFF0E1EB-13DB-4678-B67D-FF0A41DBBCEF}"; public string CryptoEngineId { get => "{FFF0E1EB-13DB-4678-B67D-FF0A41DBBCEF}"; }
public string PrivateKeyEnc { get; set; } public string PrivateKeyEnc { get; set; }

View File

@ -59,7 +59,8 @@ namespace ASC.Web.Files.Services.DocumentService
private MachinePseudoKeys MachinePseudoKeys { get; } private MachinePseudoKeys MachinePseudoKeys { get; }
private Global Global { get; } private Global Global { get; }
private DocumentServiceConnector DocumentServiceConnector { get; } private DocumentServiceConnector DocumentServiceConnector { get; }
private LockerManager LockerManager { get; } private LockerManager LockerManager { get; }
public FileTrackerHelper FileTracker { get; }
private IServiceProvider ServiceProvider { get; } private IServiceProvider ServiceProvider { get; }
public DocumentServiceHelper( public DocumentServiceHelper(
@ -73,7 +74,8 @@ namespace ASC.Web.Files.Services.DocumentService
MachinePseudoKeys machinePseudoKeys, MachinePseudoKeys machinePseudoKeys,
Global global, Global global,
DocumentServiceConnector documentServiceConnector, DocumentServiceConnector documentServiceConnector,
LockerManager lockerManager, LockerManager lockerManager,
FileTrackerHelper fileTracker,
IServiceProvider serviceProvider) IServiceProvider serviceProvider)
{ {
DaoFactory = daoFactory; DaoFactory = daoFactory;
@ -86,7 +88,8 @@ namespace ASC.Web.Files.Services.DocumentService
MachinePseudoKeys = machinePseudoKeys; MachinePseudoKeys = machinePseudoKeys;
Global = global; Global = global;
DocumentServiceConnector = documentServiceConnector; DocumentServiceConnector = documentServiceConnector;
LockerManager = lockerManager; LockerManager = lockerManager;
FileTracker = fileTracker;
ServiceProvider = serviceProvider; ServiceProvider = serviceProvider;
} }

View File

@ -181,7 +181,8 @@ namespace ASC.Web.Files.Services.DocumentService
private FilesMessageService FilesMessageService { get; } private FilesMessageService FilesMessageService { get; }
private DocumentServiceConnector DocumentServiceConnector { get; } private DocumentServiceConnector DocumentServiceConnector { get; }
private NotifyClient NotifyClient { get; } private NotifyClient NotifyClient { get; }
private MailMergeTaskRunner MailMergeTaskRunner { get; } private MailMergeTaskRunner MailMergeTaskRunner { get; }
public FileTrackerHelper FileTracker { get; }
public ILog Logger { get; } public ILog Logger { get; }
public DocumentServiceTrackerHelper( public DocumentServiceTrackerHelper(
@ -202,7 +203,8 @@ namespace ASC.Web.Files.Services.DocumentService
FilesMessageService filesMessageService, FilesMessageService filesMessageService,
DocumentServiceConnector documentServiceConnector, DocumentServiceConnector documentServiceConnector,
NotifyClient notifyClient, NotifyClient notifyClient,
MailMergeTaskRunner mailMergeTaskRunner) MailMergeTaskRunner mailMergeTaskRunner,
FileTrackerHelper fileTracker)
{ {
SecurityContext = securityContext; SecurityContext = securityContext;
UserManager = userManager; UserManager = userManager;
@ -220,7 +222,8 @@ namespace ASC.Web.Files.Services.DocumentService
FilesMessageService = filesMessageService; FilesMessageService = filesMessageService;
DocumentServiceConnector = documentServiceConnector; DocumentServiceConnector = documentServiceConnector;
NotifyClient = notifyClient; NotifyClient = notifyClient;
MailMergeTaskRunner = mailMergeTaskRunner; MailMergeTaskRunner = mailMergeTaskRunner;
FileTracker = fileTracker;
Logger = options.CurrentValue; Logger = options.CurrentValue;
} }

View File

@ -252,7 +252,8 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
private bool WithError(IServiceScope scope, IEnumerable<File<T>> files, bool folder, out string error) private bool WithError(IServiceScope scope, IEnumerable<File<T>> files, bool folder, out string error)
{ {
var entryManager = scope.ServiceProvider.GetService<EntryManager>(); var entryManager = scope.ServiceProvider.GetService<EntryManager>();
var fileTracker = scope.ServiceProvider.GetService<FileTrackerHelper>();
error = null; error = null;
foreach (var file in files) foreach (var file in files)
@ -267,7 +268,7 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
error = FilesCommonResource.ErrorMassage_LockedFile; error = FilesCommonResource.ErrorMassage_LockedFile;
return true; return true;
} }
if (FileTracker.IsEditing(file.ID)) if (fileTracker.IsEditing(file.ID))
{ {
error = folder ? FilesCommonResource.ErrorMassage_SecurityException_DeleteEditingFolder : FilesCommonResource.ErrorMassage_SecurityException_DeleteEditingFile; error = folder ? FilesCommonResource.ErrorMassage_SecurityException_DeleteEditingFolder : FilesCommonResource.ErrorMassage_SecurityException_DeleteEditingFile;
return true; return true;

View File

@ -364,7 +364,8 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
var scopeClass = scope.ServiceProvider.GetService<FileMoveCopyOperationScope>(); var scopeClass = scope.ServiceProvider.GetService<FileMoveCopyOperationScope>();
var (filesMessageService, fileMarker, fileUtility, global, entryManager) = scopeClass; var (filesMessageService, fileMarker, fileUtility, global, entryManager) = scopeClass;
var fileDao = scope.ServiceProvider.GetService<IFileDao<TTo>>(); var fileDao = scope.ServiceProvider.GetService<IFileDao<TTo>>();
var fileTracker = scope.ServiceProvider.GetService<FileTrackerHelper>();
var toFolderId = toFolder.ID; var toFolderId = toFolder.ID;
foreach (var fileId in fileIds) foreach (var fileId in fileIds)
@ -474,7 +475,7 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
{ {
Error = FilesCommonResource.ErrorMassage_LockedFile; Error = FilesCommonResource.ErrorMassage_LockedFile;
} }
else if (FileTracker.IsEditing(conflict.ID)) else if (fileTracker.IsEditing(conflict.ID))
{ {
Error = FilesCommonResource.ErrorMassage_SecurityException_UpdateEditingFile; Error = FilesCommonResource.ErrorMassage_SecurityException_UpdateEditingFile;
} }
@ -562,7 +563,8 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
private bool WithError(IServiceScope scope, IEnumerable<File<T>> files, out string error) private bool WithError(IServiceScope scope, IEnumerable<File<T>> files, out string error)
{ {
var entryManager = scope.ServiceProvider.GetService<EntryManager>(); var entryManager = scope.ServiceProvider.GetService<EntryManager>();
var fileTracker = scope.ServiceProvider.GetService<FileTrackerHelper>();
error = null; error = null;
foreach (var file in files) foreach (var file in files)
{ {
@ -576,7 +578,7 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
error = FilesCommonResource.ErrorMassage_LockedFile; error = FilesCommonResource.ErrorMassage_LockedFile;
return true; return true;
} }
if (FileTracker.IsEditing(file.ID)) if (fileTracker.IsEditing(file.ID))
{ {
error = FilesCommonResource.ErrorMassage_SecurityException_UpdateEditingFile; error = FilesCommonResource.ErrorMassage_SecurityException_UpdateEditingFile;
return true; return true;

View File

@ -35,8 +35,8 @@ using ASC.Common.Threading;
using ASC.Core.Tenants; using ASC.Core.Tenants;
using ASC.Files.Core.Resources; using ASC.Files.Core.Resources;
using Microsoft.Extensions.Primitives; using Microsoft.Extensions.Primitives;
namespace ASC.Web.Files.Services.WCFService.FileOperations namespace ASC.Web.Files.Services.WCFService.FileOperations
{ {
[Singletone(Additional = typeof(FileOperationsManagerHelperExtention))] [Singletone(Additional = typeof(FileOperationsManagerHelperExtention))]
@ -55,21 +55,24 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
public ItemList<FileOperationResult> GetOperationResults(Guid userId) public ItemList<FileOperationResult> GetOperationResults(Guid userId)
{ {
var operations = tasks.GetTasks(); var operations = tasks.GetTasks();
var processlist = Process.GetProcesses(); var processlist = Process.GetProcesses();
//TODO: replace with distributed cache //TODO: replace with distributed cache
foreach (var o in operations.Where(o => processlist.All(p => p.Id != o.InstanceId))) if (processlist.Any())
{ {
o.SetProperty(FileOperation.PROGRESS, 100); foreach (var o in operations.Where(o => processlist.All(p => p.Id != o.InstanceId)))
tasks.RemoveTask(o.Id); {
} o.SetProperty(FileOperation.PROGRESS, 100);
tasks.RemoveTask(o.Id);
}
}
operations = operations.Where(t => t.GetProperty<Guid>(FileOperation.OWNER) == userId); operations = operations.Where(t => t.GetProperty<Guid>(FileOperation.OWNER) == userId);
foreach (var o in operations.Where(o => o.Status > DistributedTaskStatus.Running)) foreach (var o in operations.Where(o => o.Status > DistributedTaskStatus.Running))
{ {
o.SetProperty(FileOperation.PROGRESS, 100); o.SetProperty(FileOperation.PROGRESS, 100);
tasks.RemoveTask(o.Id); tasks.RemoveTask(o.Id);
} }
var results = operations var results = operations
.Where(o => o.GetProperty<bool>(FileOperation.HOLD) || o.GetProperty<int>(FileOperation.PROGRESS) != 100) .Where(o => o.GetProperty<bool>(FileOperation.HOLD) || o.GetProperty<int>(FileOperation.PROGRESS) != 100)

View File

@ -177,8 +177,9 @@ namespace ASC.Web.Files.Utils
public class EntryManager public class EntryManager
{ {
private const string UPDATE_LIST = "filesUpdateList"; private const string UPDATE_LIST = "filesUpdateList";
private readonly ICache cache;
private ICache Cache { get; set; }
public FileTrackerHelper FileTracker { get; }
private IDaoFactory DaoFactory { get; } private IDaoFactory DaoFactory { get; }
private FileSecurity FileSecurity { get; } private FileSecurity FileSecurity { get; }
private GlobalFolderHelper GlobalFolderHelper { get; } private GlobalFolderHelper GlobalFolderHelper { get; }
@ -226,7 +227,9 @@ namespace ASC.Web.Files.Utils
BreadCrumbsManager breadCrumbsManager, BreadCrumbsManager breadCrumbsManager,
TenantManager tenantManager, TenantManager tenantManager,
SettingsManager settingsManager, SettingsManager settingsManager,
IServiceProvider serviceProvider) IServiceProvider serviceProvider,
ICache cache,
FileTrackerHelper fileTracker)
{ {
DaoFactory = daoFactory; DaoFactory = daoFactory;
FileSecurity = fileSecurity; FileSecurity = fileSecurity;
@ -251,7 +254,8 @@ namespace ASC.Web.Files.Utils
SettingsManager = settingsManager; SettingsManager = settingsManager;
ServiceProvider = serviceProvider; ServiceProvider = serviceProvider;
Logger = optionsMonitor.CurrentValue; Logger = optionsMonitor.CurrentValue;
cache = AscCache.Memory; Cache = cache;
FileTracker = fileTracker;
} }
public IEnumerable<FileEntry> GetEntries<T>(Folder<T> parent, int from, int count, FilterType filter, bool subjectGroup, Guid subjectId, string searchText, bool searchInContent, bool withSubfolders, OrderBy orderBy, out int total) public IEnumerable<FileEntry> GetEntries<T>(Folder<T> parent, int from, int count, FilterType filter, bool subjectGroup, Guid subjectId, string searchText, bool searchInContent, bool withSubfolders, OrderBy orderBy, out int total)
@ -319,8 +323,8 @@ namespace ASC.Web.Files.Utils
if (!folderIDProjectTitle.ContainsKey(projectFolderID)) if (!folderIDProjectTitle.ContainsKey(projectFolderID))
folderIDProjectTitle.Add(projectFolderID, new KeyValuePair<int, string>(projectID, projectTitle)); folderIDProjectTitle.Add(projectFolderID, new KeyValuePair<int, string>(projectID, projectTitle));
AscCache.Memory.Remove("documents/folders/" + projectFolderID); Cache.Remove("documents/folders/" + projectFolderID);
AscCache.Memory.Insert("documents/folders/" + projectFolderID, projectTitle, TimeSpan.FromMinutes(30)); Cache.Insert("documents/folders/" + projectFolderID, projectTitle, TimeSpan.FromMinutes(30));
} }
} }
@ -787,21 +791,13 @@ namespace ASC.Web.Files.Utils
{ {
if (!t.Key.Equals(file.ID)) continue; if (!t.Key.Equals(file.ID)) continue;
if (t.Value.TagType == TagType.Favorite) file.IsFavorite = t.Value.Any(r=> r.TagType == TagType.Favorite);
{ file.IsTemplate = t.Value.Any(r => r.TagType == TagType.Template);
file.IsFavorite = true;
continue;
}
if (t.Value.TagType == TagType.Template) var lockedTag = t.Value.FirstOrDefault(r => r.TagType == TagType.Locked);
if (lockedTag != null)
{ {
file.IsTemplate = true; var lockedBy = lockedTag.Owner;
continue;
}
if (t.Value.TagType == TagType.Locked)
{
var lockedBy = t.Value.Owner;
file.Locked = lockedBy != Guid.Empty; file.Locked = lockedBy != Guid.Empty;
file.LockedBy = lockedBy != Guid.Empty && lockedBy != AuthContext.CurrentAccount.ID file.LockedBy = lockedBy != Guid.Empty && lockedBy != AuthContext.CurrentAccount.ID
? Global.GetUserName(lockedBy) ? Global.GetUserName(lockedBy)
@ -1026,14 +1022,14 @@ namespace ASC.Web.Files.Utils
if (fromFile.ProviderEntry) throw new Exception(FilesCommonResource.ErrorMassage_BadRequest); if (fromFile.ProviderEntry) throw new Exception(FilesCommonResource.ErrorMassage_BadRequest);
if (fromFile.Encrypted) throw new Exception(FilesCommonResource.ErrorMassage_NotSupportedFormat); if (fromFile.Encrypted) throw new Exception(FilesCommonResource.ErrorMassage_NotSupportedFormat);
var exists = cache.Get<string>(UPDATE_LIST + fileId.ToString()) != null; var exists = Cache.Get<string>(UPDATE_LIST + fileId.ToString()) != null;
if (exists) if (exists)
{ {
throw new Exception(FilesCommonResource.ErrorMassage_UpdateEditingFile); throw new Exception(FilesCommonResource.ErrorMassage_UpdateEditingFile);
} }
else else
{ {
cache.Insert(UPDATE_LIST + fileId.ToString(), fileId.ToString(), TimeSpan.FromMinutes(2)); Cache.Insert(UPDATE_LIST + fileId.ToString(), fileId.ToString(), TimeSpan.FromMinutes(2));
} }
try try
@ -1086,7 +1082,7 @@ namespace ASC.Web.Files.Utils
} }
finally finally
{ {
cache.Remove(UPDATE_LIST + fromFile.ID); Cache.Remove(UPDATE_LIST + fromFile.ID);
} }
} }

View File

@ -72,13 +72,13 @@ namespace ASC.Web.Files.Utils
private IServiceProvider ServiceProvider { get; } private IServiceProvider ServiceProvider { get; }
public FileConverterQueue(IServiceProvider ServiceProvider) public FileConverterQueue(IServiceProvider ServiceProvider, ICache cache)
{ {
conversionQueue = new Dictionary<File<T>, ConvertFileOperationResult>(new FileComparer<T>()); conversionQueue = new Dictionary<File<T>, ConvertFileOperationResult>(new FileComparer<T>());
timer = new Timer(CheckConvertFilesStatus, null, 0, Timeout.Infinite); timer = new Timer(CheckConvertFilesStatus, null, 0, Timeout.Infinite);
locker = new object(); locker = new object();
this.ServiceProvider = ServiceProvider; this.ServiceProvider = ServiceProvider;
cache = AscCache.Memory; this.cache = cache;
} }
public void Add(File<T> file, string password, int tenantId, IAccount account, bool deleteAfter, string url) public void Add(File<T> file, string password, int tenantId, IAccount account, bool deleteAfter, string url)
@ -515,7 +515,8 @@ namespace ASC.Web.Files.Utils
private FilesMessageService FilesMessageService { get; } private FilesMessageService FilesMessageService { get; }
private FileShareLink FileShareLink { get; } private FileShareLink FileShareLink { get; }
private DocumentServiceHelper DocumentServiceHelper { get; } private DocumentServiceHelper DocumentServiceHelper { get; }
private DocumentServiceConnector DocumentServiceConnector { get; } private DocumentServiceConnector DocumentServiceConnector { get; }
public FileTrackerHelper FileTracker { get; }
private IServiceProvider ServiceProvider { get; } private IServiceProvider ServiceProvider { get; }
private IHttpContextAccessor HttpContextAccesor { get; } private IHttpContextAccessor HttpContextAccesor { get; }
@ -535,7 +536,8 @@ namespace ASC.Web.Files.Utils
FilesMessageService filesMessageService, FilesMessageService filesMessageService,
FileShareLink fileShareLink, FileShareLink fileShareLink,
DocumentServiceHelper documentServiceHelper, DocumentServiceHelper documentServiceHelper,
DocumentServiceConnector documentServiceConnector, DocumentServiceConnector documentServiceConnector,
FileTrackerHelper fileTracker,
IServiceProvider serviceProvider) IServiceProvider serviceProvider)
{ {
FileUtility = fileUtility; FileUtility = fileUtility;
@ -553,7 +555,8 @@ namespace ASC.Web.Files.Utils
FilesMessageService = filesMessageService; FilesMessageService = filesMessageService;
FileShareLink = fileShareLink; FileShareLink = fileShareLink;
DocumentServiceHelper = documentServiceHelper; DocumentServiceHelper = documentServiceHelper;
DocumentServiceConnector = documentServiceConnector; DocumentServiceConnector = documentServiceConnector;
FileTracker = fileTracker;
ServiceProvider = serviceProvider; ServiceProvider = serviceProvider;
} }
public FileConverter( public FileConverter(
@ -572,12 +575,13 @@ namespace ASC.Web.Files.Utils
FilesMessageService filesMessageService, FilesMessageService filesMessageService,
FileShareLink fileShareLink, FileShareLink fileShareLink,
DocumentServiceHelper documentServiceHelper, DocumentServiceHelper documentServiceHelper,
DocumentServiceConnector documentServiceConnector, DocumentServiceConnector documentServiceConnector,
FileTrackerHelper fileTracker,
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
IHttpContextAccessor httpContextAccesor) IHttpContextAccessor httpContextAccesor)
: this(fileUtility, filesLinkUtility, daoFactory, setupInfo, pathProvider, fileSecurity, : this(fileUtility, filesLinkUtility, daoFactory, setupInfo, pathProvider, fileSecurity,
fileMarker, tenantManager, authContext, entryManager, filesSettingsHelper, fileMarker, tenantManager, authContext, entryManager, filesSettingsHelper,
globalFolderHelper, filesMessageService, fileShareLink, documentServiceHelper, documentServiceConnector, globalFolderHelper, filesMessageService, fileShareLink, documentServiceHelper, documentServiceConnector, fileTracker,
serviceProvider) serviceProvider)
{ {
HttpContextAccesor = httpContextAccesor; HttpContextAccesor = httpContextAccesor;

View File

@ -121,7 +121,8 @@ namespace ASC.Web.Files.Utils
CoreBaseSettings coreBaseSettings, CoreBaseSettings coreBaseSettings,
AuthContext authContext, AuthContext authContext,
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
FilesSettingsHelper filesSettingsHelper) FilesSettingsHelper filesSettingsHelper,
ICache cache)
{ {
TenantManager = tenantManager; TenantManager = tenantManager;
UserManager = userManager; UserManager = userManager;
@ -132,7 +133,7 @@ namespace ASC.Web.Files.Utils
AuthContext = authContext; AuthContext = authContext;
ServiceProvider = serviceProvider; ServiceProvider = serviceProvider;
FilesSettingsHelper = filesSettingsHelper; FilesSettingsHelper = filesSettingsHelper;
cache = AscCache.Memory; this.cache = cache;
} }
internal void ExecMarkFileAsNew<T>(AsyncTaskData<T> obj) internal void ExecMarkFileAsNew<T>(AsyncTaskData<T> obj)

View File

@ -59,8 +59,9 @@ namespace ASC.Web.Files.Utils
private FileMarker FileMarker { get; } private FileMarker FileMarker { get; }
private NotifyClient NotifyClient { get; } private NotifyClient NotifyClient { get; }
private GlobalFolderHelper GlobalFolderHelper { get; } private GlobalFolderHelper GlobalFolderHelper { get; }
private FileSharingHelper FileSharingHelper { get; } private FileSharingHelper FileSharingHelper { get; }
private FileTrackerHelper FileTracker { get; }
public FileSharingAceHelper( public FileSharingAceHelper(
FileSecurity fileSecurity, FileSecurity fileSecurity,
CoreBaseSettings coreBaseSettings, CoreBaseSettings coreBaseSettings,
@ -71,7 +72,8 @@ namespace ASC.Web.Files.Utils
FileMarker fileMarker, FileMarker fileMarker,
NotifyClient notifyClient, NotifyClient notifyClient,
GlobalFolderHelper globalFolderHelper, GlobalFolderHelper globalFolderHelper,
FileSharingHelper fileSharingHelper) FileSharingHelper fileSharingHelper,
FileTrackerHelper fileTracker)
{ {
FileSecurity = fileSecurity; FileSecurity = fileSecurity;
CoreBaseSettings = coreBaseSettings; CoreBaseSettings = coreBaseSettings;
@ -82,7 +84,8 @@ namespace ASC.Web.Files.Utils
FileMarker = fileMarker; FileMarker = fileMarker;
NotifyClient = notifyClient; NotifyClient = notifyClient;
GlobalFolderHelper = globalFolderHelper; GlobalFolderHelper = globalFolderHelper;
FileSharingHelper = fileSharingHelper; FileSharingHelper = fileSharingHelper;
FileTracker = fileTracker;
} }
public bool SetAceObject(List<AceWrapper> aceWrappers, FileEntry<T> entry, bool notify, string message) public bool SetAceObject(List<AceWrapper> aceWrappers, FileEntry<T> entry, bool notify, string message)

View File

@ -26,55 +26,51 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using ASC.Common.Caching; using ASC.Common;
using ASC.Common.Caching;
using static ASC.Web.Files.Utils.FileTracker;
namespace ASC.Web.Files.Utils namespace ASC.Web.Files.Utils
{ {
public class FileTracker [Singletone]
{ public class FileTrackerHelper
private const string TRACKER = "filesTracker"; {
private static readonly ICache cache = AscCache.Memory; private const string TRACKER = "filesTracker";
private ICache Cache { get; }
public static readonly TimeSpan TrackTimeout = TimeSpan.FromSeconds(12); public static readonly TimeSpan TrackTimeout = TimeSpan.FromSeconds(12);
public static readonly TimeSpan CacheTimeout = TimeSpan.FromSeconds(60); public static readonly TimeSpan CacheTimeout = TimeSpan.FromSeconds(60);
public static readonly TimeSpan CheckRightTimeout = TimeSpan.FromMinutes(1); public static readonly TimeSpan CheckRightTimeout = TimeSpan.FromMinutes(1);
private readonly Dictionary<Guid, TrackInfo> _editingBy; public FileTrackerHelper(ICache cache)
{
Cache = cache;
private FileTracker() }
{
} public Guid Add<T>(Guid userId, T fileId)
private FileTracker(Guid tabId, Guid userId, bool newScheme, bool editingAlone)
{
_editingBy = new Dictionary<Guid, TrackInfo> { { tabId, new TrackInfo(userId, newScheme, editingAlone) } };
}
public static Guid Add<T>(Guid userId, T fileId)
{ {
var tabId = Guid.NewGuid(); var tabId = Guid.NewGuid();
ProlongEditing(fileId, tabId, userId); ProlongEditing(fileId, tabId, userId);
return tabId; return tabId;
} }
public static bool ProlongEditing<T>(T fileId, Guid tabId, Guid userId, bool editingAlone = false) public bool ProlongEditing<T>(T fileId, Guid tabId, Guid userId, bool editingAlone = false)
{ {
var checkRight = true; var checkRight = true;
var tracker = GetTracker(fileId); var tracker = GetTracker(fileId);
if (tracker != null && IsEditing(fileId)) if (tracker != null && IsEditing(fileId))
{ {
if (tracker._editingBy.Keys.Contains(tabId)) if (tracker.EditingBy.Keys.Contains(tabId))
{ {
tracker._editingBy[tabId].TrackTime = DateTime.UtcNow; tracker.EditingBy[tabId].TrackTime = DateTime.UtcNow;
checkRight = (DateTime.UtcNow - tracker._editingBy[tabId].CheckRightTime > CheckRightTimeout); checkRight = (DateTime.UtcNow - tracker.EditingBy[tabId].CheckRightTime > CheckRightTimeout);
} }
else else
{ {
tracker._editingBy.Add(tabId, new TrackInfo(userId, tabId == userId, editingAlone)); tracker.EditingBy.Add(tabId, new TrackInfo(userId, tabId == userId, editingAlone));
} }
} }
else else
@ -87,25 +83,25 @@ namespace ASC.Web.Files.Utils
return checkRight; return checkRight;
} }
public static void Remove<T>(T fileId, Guid tabId = default, Guid userId = default) public void Remove<T>(T fileId, Guid tabId = default, Guid userId = default)
{ {
var tracker = GetTracker(fileId); var tracker = GetTracker(fileId);
if (tracker != null) if (tracker != null)
{ {
if (tabId != default) if (tabId != default)
{ {
tracker._editingBy.Remove(tabId); tracker.EditingBy.Remove(tabId);
SetTracker(fileId, tracker); SetTracker(fileId, tracker);
return; return;
} }
if (userId != default) if (userId != default)
{ {
var listForRemove = tracker._editingBy var listForRemove = tracker.EditingBy
.Where(b => tracker._editingBy[b.Key].UserId == userId) .Where(b => tracker.EditingBy[b.Key].UserId == userId)
.ToList(); .ToList();
foreach (var editTab in listForRemove) foreach (var editTab in listForRemove)
{ {
tracker._editingBy.Remove(editTab.Key); tracker.EditingBy.Remove(editTab.Key);
} }
SetTracker(fileId, tracker); SetTracker(fileId, tracker);
return; return;
@ -115,19 +111,19 @@ namespace ASC.Web.Files.Utils
SetTracker(fileId, null); SetTracker(fileId, null);
} }
public static void RemoveAllOther<T>(Guid userId, T fileId) public void RemoveAllOther<T>(Guid userId, T fileId)
{ {
var tracker = GetTracker(fileId); var tracker = GetTracker(fileId);
if (tracker != null) if (tracker != null)
{ {
var listForRemove = tracker._editingBy var listForRemove = tracker.EditingBy
.Where(b => b.Value.UserId != userId) .Where(b => b.Value.UserId != userId)
.ToList(); .ToList();
if (listForRemove.Count() != tracker._editingBy.Count) if (listForRemove.Count() != tracker.EditingBy.Count)
{ {
foreach (var forRemove in listForRemove) foreach (var forRemove in listForRemove)
{ {
tracker._editingBy.Remove(forRemove.Key); tracker.EditingBy.Remove(forRemove.Key);
} }
SetTracker(fileId, tracker); SetTracker(fileId, tracker);
return; return;
@ -136,20 +132,20 @@ namespace ASC.Web.Files.Utils
SetTracker(fileId, null); SetTracker(fileId, null);
} }
public static bool IsEditing<T>(T fileId) public bool IsEditing<T>(T fileId)
{ {
var tracker = GetTracker(fileId); var tracker = GetTracker(fileId);
if (tracker != null) if (tracker != null)
{ {
var listForRemove = tracker._editingBy var listForRemove = tracker.EditingBy
.Where(e => !e.Value.NewScheme && (DateTime.UtcNow - e.Value.TrackTime).Duration() > TrackTimeout) .Where(e => !e.Value.NewScheme && (DateTime.UtcNow - e.Value.TrackTime).Duration() > TrackTimeout)
.ToList(); .ToList();
foreach (var editTab in listForRemove) foreach (var editTab in listForRemove)
{ {
tracker._editingBy.Remove(editTab.Key); tracker.EditingBy.Remove(editTab.Key);
} }
if (tracker._editingBy.Count == 0) if (tracker.EditingBy.Count == 0)
{ {
SetTracker(fileId, null); SetTracker(fileId, null);
return false; return false;
@ -160,28 +156,29 @@ namespace ASC.Web.Files.Utils
} }
SetTracker(fileId, null); SetTracker(fileId, null);
return false; return false;
} }
public static bool IsEditingAlone<T>(T fileId)
public bool IsEditingAlone<T>(T fileId)
{ {
var tracker = GetTracker(fileId); var tracker = GetTracker(fileId);
return tracker != null && tracker._editingBy.Count == 1 && tracker._editingBy.FirstOrDefault().Value.EditingAlone; return tracker != null && tracker.EditingBy.Count == 1 && tracker.EditingBy.FirstOrDefault().Value.EditingAlone;
} }
public static void ChangeRight<T>(T fileId, Guid userId, bool check) public void ChangeRight<T>(T fileId, Guid userId, bool check)
{ {
var tracker = GetTracker(fileId); var tracker = GetTracker(fileId);
if (tracker != null) if (tracker != null)
{ {
tracker._editingBy.Values tracker.EditingBy.Values
.ToList() .ToList()
.ForEach(i => .ForEach(i =>
{ {
if (i.UserId == userId || userId == Guid.Empty) if (i.UserId == userId || userId == Guid.Empty)
{ {
i.CheckRightTime = check ? DateTime.MinValue : DateTime.UtcNow; i.CheckRightTime = check ? DateTime.MinValue : DateTime.UtcNow;
} }
}); });
SetTracker(fileId, tracker); SetTracker(fileId, tracker);
} }
else else
@ -190,36 +187,48 @@ namespace ASC.Web.Files.Utils
} }
} }
public static List<Guid> GetEditingBy<T>(T fileId) public List<Guid> GetEditingBy<T>(T fileId)
{ {
var tracker = GetTracker(fileId); var tracker = GetTracker(fileId);
return tracker != null && IsEditing(fileId) ? tracker._editingBy.Values.Select(i => i.UserId).Distinct().ToList() : new List<Guid>(); return tracker != null && IsEditing(fileId) ? tracker.EditingBy.Values.Select(i => i.UserId).Distinct().ToList() : new List<Guid>();
} }
private static FileTracker GetTracker<T>(T fileId) private FileTracker GetTracker<T>(T fileId)
{ {
if (!fileId.Equals(default(T))) if (!fileId.Equals(default(T)))
{ {
return cache.Get<FileTracker>(TRACKER + fileId); return Cache.Get<FileTracker>(TRACKER + fileId);
} }
return null; return null;
} }
private static void SetTracker<T>(T fileId, FileTracker tracker) private void SetTracker<T>(T fileId, FileTracker tracker)
{ {
if (!fileId.Equals(default(T))) if (!fileId.Equals(default(T)))
{ {
if (tracker != null) if (tracker != null)
{ {
cache.Insert(TRACKER + fileId, tracker, CacheTimeout); Cache.Insert(TRACKER + fileId, tracker, CacheTimeout);
} }
else else
{ {
cache.Remove(TRACKER + fileId); Cache.Remove(TRACKER + fileId);
} }
} }
} }
}
public class FileTracker
{
internal Dictionary<Guid, TrackInfo> EditingBy { get; private set; }
internal FileTracker(Guid tabId, Guid userId, bool newScheme, bool editingAlone)
{
EditingBy = new Dictionary<Guid, TrackInfo> { { tabId, new TrackInfo(userId, newScheme, editingAlone) } };
}
internal class TrackInfo internal class TrackInfo

Some files were not shown because too many files have changed in this diff Show More