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 {
stage('Unix') {
agent { label 'net-core' }
steps {
sh "sh ./build/scripts/components.sh && cd ${env.WORKSPACE}/web/ASC.Web.Components && yarn test:coverage --ci --reporters=default --reporters=jest-junit || true"
}
post {
success {
junit 'web/ASC.Web.Components/junit.xml'
publishHTML target: [
allowMissing : false,
alwaysLinkToLastBuild: false,
keepAll : true,
reportDir : 'web/ASC.Web.Components/coverage/lcov-report',
reportFiles : 'index.html',
reportName : 'Unix Test Report'
]
publishCoverage adapters: [coberturaAdapter('web/ASC.Web.Components/coverage/cobertura-coverage.xml')]
stages {
stage('Components') {
steps {
sh "sh ./build/scripts/components.sh && cd ${env.WORKSPACE}/web/ASC.Web.Components && yarn test:coverage --ci --reporters=default --reporters=jest-junit || true"
}
post {
success {
junit 'web/ASC.Web.Components/junit.xml'
publishHTML target: [
allowMissing : false,
alwaysLinkToLastBuild: false,
keepAll : true,
reportDir : 'web/ASC.Web.Components/coverage/lcov-report',
reportFiles : 'index.html',
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') {
agent { label 'win-core' }
steps {
bat "sh build\\scripts\\components.sh && cd ${env.WORKSPACE}\\web\\ASC.Web.Components && yarn test:coverage --ci --reporters=default --reporters=jest-junit || true"
}
post {
success {
junit 'web\\ASC.Web.Components\\junit.xml'
publishHTML target: [
allowMissing : false,
alwaysLinkToLastBuild: false,
keepAll : true,
reportDir : 'web\\ASC.Web.Components\\coverage\\lcov-report',
reportFiles : 'index.html',
reportName : 'Windows Test Report'
]
stages {
stage('Components') {
steps {
bat "sh build\\scripts\\components.sh && cd ${env.WORKSPACE}\\web\\ASC.Web.Components && yarn test:coverage --ci --reporters=default --reporters=jest-junit || true"
}
post {
success {
junit 'web\\ASC.Web.Components\\junit.xml'
publishHTML target: [
allowMissing : false,
alwaysLinkToLastBuild: false,
keepAll : true,
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
ARG RELEASE_DATE="2016-06-21"
ARG RELEASE_DATE_SIGN=""
ARG VERSION="8.9.0.190"
ARG SOURCE_REPO_URL="deb http://static.teamlab.com.s3.amazonaws.com/repo/debian squeeze main"
ARG DEBIAN_FRONTEND=noninteractive
ARG GIT_BRANCH="master"
LABEL onlyoffice.community.release-date="${RELEASE_DATE}" \
onlyoffice.community.version="${VERSION}" \
LABEL onlyoffice.appserver.release-date="${RELEASE_DATE}" \
onlyoffice.appserver.version="${VERSION}" \
maintainer="Ascensio System SIA <support@onlyoffice.com>"
ENV LANG=en_US.UTF-8 \

View File

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

View File

@ -47,6 +47,7 @@
<PackageReference Include="Microsoft.AspNetCore.Http.Features" Version="3.1.9" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<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.Binder" 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 Microsoft.Extensions.Caching.Memory;
namespace ASC.Common.Caching
{
[Singletone]
@ -61,71 +63,59 @@ namespace ASC.Common.Caching
}
}
}
[Singletone]
public class AscCache : ICache
{
public static readonly ICache Memory;
static AscCache()
{
Memory = new AscCache();
}
private AscCache()
{
{
private IMemoryCache MemoryCache { get; }
public AscCache(IMemoryCache memoryCache)
{
MemoryCache = memoryCache;
}
public T Get<T>(string key) where T : class
{
var cache = GetCache();
return cache.Get(key) as T;
return MemoryCache.Get<T>(key);
}
public void Insert(string key, object value, TimeSpan sligingExpiration)
{
var cache = GetCache();
cache.Set(key, value, new CacheItemPolicy { SlidingExpiration = sligingExpiration });
MemoryCache.Set(key, value, new MemoryCacheEntryOptions(){ SlidingExpiration = sligingExpiration });
}
public void Insert(string key, object value, DateTime absolutExpiration)
{
var cache = GetCache();
cache.Set(key, value,
absolutExpiration == DateTime.MaxValue ? DateTimeOffset.MaxValue : new DateTimeOffset(absolutExpiration));
MemoryCache.Set(key, value, absolutExpiration == DateTime.MaxValue ? DateTimeOffset.MaxValue : new DateTimeOffset(absolutExpiration));
}
public void Remove(string key)
{
var cache = GetCache();
cache.Remove(key);
MemoryCache.Remove(key);
}
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();
foreach (var key in keys)
{
cache.Remove(key);
}
//var keys = copy.Select(p => p.Key).Where(k => pattern.IsMatch(k)).ToArray();
//foreach (var key in keys)
//{
// cache.Remove(key);
//}
}
public ConcurrentDictionary<string, T> HashGetAll<T>(string key)
{
var cache = GetCache();
var dic = (ConcurrentDictionary<string, T>)cache.Get(key);
return dic != null ? dic : new ConcurrentDictionary<string, T>();
return MemoryCache.GetOrCreate(key, r=> new ConcurrentDictionary<string, T>());
}
public T HashGet<T>(string key, string field)
{
var cache = GetCache();
var dic = (ConcurrentDictionary<string, T>)cache.Get(key);
if (dic != null && dic.TryGetValue(field, out var value))
if (MemoryCache.TryGetValue<ConcurrentDictionary<string, T>>(key, out var dic) && dic.TryGetValue(field, out var value))
{
return value;
}
@ -134,30 +124,24 @@ namespace ASC.Common.Caching
public void HashSet<T>(string key, string field, T value)
{
var cache = GetCache();
var dic = HashGetAll<T>(key);
if (value != null)
{
dic.AddOrUpdate(field, value, (k, v) => value);
cache.Set(key, dic, null);
MemoryCache.Set(key, dic, DateTime.MaxValue);
}
else if (dic != null)
{
dic.TryRemove(field, out _);
if (dic.Count == 0)
{
cache.Remove(key);
MemoryCache.Remove(key);
}
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;
namespace ASC.Common.Caching
{
{
[Singletone(typeof(AscCache))]
public interface ICache
{
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);
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)

View File

@ -32,8 +32,8 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using ASC.Common.Caching;
using ASC.Common.Caching;
namespace ASC.Common.Threading
{
[Singletone]
@ -44,11 +44,14 @@ namespace ASC.Common.Threading
private readonly ICacheNotify<DistributedTaskCancelation> notify;
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>();
Cache = AscCache.Memory;
Cache = cache;
this.notify = notify;
@ -121,7 +124,7 @@ namespace ASC.Common.Threading
key = name + GetType().Name;
scheduler = maxThreadsCount <= 0
? TaskScheduler.Default
: new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, 4).ConcurrentScheduler;
: new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, maxThreadsCount).ConcurrentScheduler;
DistributedTaskCacheNotify = distributedTaskCacheNotify;
cancelations = DistributedTaskCacheNotify.Cancelations;
cache = DistributedTaskCacheNotify.Cache;
@ -139,9 +142,9 @@ namespace ASC.Common.Threading
var cancelation = new CancellationTokenSource();
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
.ConfigureAwait(false)
.GetAwaiter()
@ -160,7 +163,7 @@ namespace ASC.Common.Threading
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 =>
{
if (t.Publication == null)

View File

@ -80,5 +80,11 @@ namespace ASC.Common.Utils
{
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.Relational" Version="3.1.9" />
<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="Telegram.Bot" Version="15.7.1" />
</ItemGroup>

View File

@ -49,9 +49,9 @@ namespace ASC.Core.Billing
public ICache Cache { 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.Subscribe((i) =>
{

View File

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

View File

@ -50,7 +50,7 @@ namespace ASC.Core.Caching
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)
{
@ -62,7 +62,7 @@ namespace ASC.Core.Caching
}
CacheNotify = cacheNotify;
Cache = AscCache.Memory;
Cache = cache;
Interval = new TrustInterval();
cacheNotify.Subscribe((i) =>

View File

@ -41,9 +41,9 @@ namespace ASC.Core.Caching
internal ICacheNotify<SubscriptionRecord> NotifyRecord { 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;
NotifyMethod = notifyMethod;

View File

@ -45,11 +45,15 @@ namespace ASC.Core.Caching
internal ICacheNotify<TenantCacheItem> CacheNotifyItem { 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;
CacheNotifySettings = cacheNotifySettings;
Cache = AscCache.Memory;
Cache = cache;
CacheExpiration = TimeSpan.FromMinutes(2);
cacheNotifyItem.Subscribe((t) =>
@ -194,12 +198,12 @@ namespace ASC.Core.Caching
public CachedTenantService()
{
cache = AscCache.Memory;
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");
TenantServiceCache = tenantServiceCache;
CacheNotifyItem = tenantServiceCache.CacheNotifyItem;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -261,7 +261,7 @@ namespace ASC.Core.Common.Migrations.MySql.TenantDbContextMySql
migrationBuilder.InsertData(
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" },
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(
table: "tenants_forbiden",

View File

@ -3,6 +3,7 @@ using System;
using ASC.Core.Common.EF.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace ASC.Core.Common.Migrations.MySql.TenantDbContextMySql
{
@ -13,7 +14,7 @@ namespace ASC.Core.Common.Migrations.MySql.TenantDbContextMySql
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.8")
.HasAnnotation("ProductVersion", "3.1.9")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbCoreSettings", b =>
@ -49,21 +50,21 @@ namespace ASC.Core.Common.Migrations.MySql.TenantDbContextMySql
{
Tenant = -1,
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 }
},
new
{
Tenant = -1,
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 }
},
new
{
Tenant = -1,
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 }
});
});
@ -185,13 +186,10 @@ namespace ASC.Core.Common.Migrations.MySql.TenantDbContextMySql
.HasColumnType("int")
.HasDefaultValueSql("'2'");
b.Property<DateTime>("VersionChanged")
b.Property<DateTime?>("Version_Changed")
.HasColumnName("version_changed")
.HasColumnType("datetime");
b.Property<DateTime?>("Version_Changed")
.HasColumnType("datetime(6)");
b.HasKey("Id");
b.HasIndex("LastModified")
@ -203,7 +201,7 @@ namespace ASC.Core.Common.Migrations.MySql.TenantDbContextMySql
b.HasIndex("Version")
.HasName("version");
b.ToTable("tenants_tenants","onlyoffice");
b.ToTable("tenants_tenants");
b.HasData(
new
@ -211,7 +209,7 @@ namespace ASC.Core.Common.Migrations.MySql.TenantDbContextMySql
Id = 1,
Alias = "localhost",
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),
Name = "Web Office",
OwnerId = "66faa6e4-f133-11ea-b126-00ffeec8b4ef",
@ -219,8 +217,7 @@ namespace ASC.Core.Common.Migrations.MySql.TenantDbContextMySql
Spam = false,
Status = 0,
TrustedDomainsEnabled = 0,
Version = 0,
VersionChanged = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)
Version = 0
});
});
@ -251,6 +248,7 @@ namespace ASC.Core.Common.Migrations.MySql.TenantDbContextMySql
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbTenantPartner", b =>
{
b.Property<int>("TenantId")
.ValueGeneratedOnAdd()
.HasColumnName("tenant_id")
.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),
Email = "",
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 = "",
PhoneActivation = 0,
Removed = false,
Status = 1,
Tenant = 1,
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
{
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=",
PwdHashSha512 = "USubvPlB+ogq0Q1trcSupg==",
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 =>
{
b.HasOne("ASC.Core.Common.EF.User", null)

View File

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

View File

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

View File

@ -11,9 +11,9 @@ namespace ASC.Data.Storage.Encryption
private ICacheNotify<ProgressEncryption> СacheBackupProgress { 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.Subscribe((a) =>

View File

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

View File

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

View File

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

View File

@ -49,9 +49,9 @@ namespace ASC.FederatedLogin
private readonly ICache cache;
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;
notify.Subscribe((c) => cache.Remove(c.Obj), CacheNotifyAction.Remove);
}

View File

@ -63,11 +63,13 @@ namespace ASC.FederatedLogin.Helpers
if (!string.IsNullOrEmpty(query)) query += "&";
query += "response_type=code";
if (!string.IsNullOrEmpty(clientID)) query += "&client_id=" + HttpUtility.UrlEncode(clientID);
if (!string.IsNullOrEmpty(redirectUri)) query += "&redirect_uri=" + HttpUtility.UrlEncode(redirectUri);
if (!string.IsNullOrEmpty(scope)) query += "&scope=" + HttpUtility.UrlEncode(scope);
if (!string.IsNullOrEmpty(clientID)) query += $"&client_id={HttpUtility.UrlEncode(clientID)}";
if (!string.IsNullOrEmpty(redirectUri)) query += $"&redirect_uri={HttpUtility.UrlEncode(redirectUri)}";
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)
{

View File

@ -40,9 +40,9 @@ namespace ASC.IPSecurity
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 = notify;
}

View File

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

View File

@ -43,12 +43,12 @@ namespace ASC.VoipService.Dao
[Singletone]
public class VoipDaoCache
{
public ICache Cache { get; }
internal ICache Cache { 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.Subscribe((c) => Cache.Remove(CachedVoipDao.GetCacheKey(c.Tenant)), CacheNotifyAction.Any);
}

View File

@ -61,17 +61,18 @@ namespace ASC.ApiSystem
config.SetBasePath(path);
config
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path}
})
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true)
.AddJsonFile("storage.json")
.AddJsonFile("kafka.json")
.AddJsonFile($"kafka.{hostingContext.HostingEnvironment.EnvironmentName}.json", true)
.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);
services.AddHttpContextAccessor();
services.AddMemoryCache();
services.AddControllers()
.AddJsonOptions(options =>

View File

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

View File

@ -49,11 +49,11 @@ namespace ASC.Data.Backup.Service
public class BackupServiceNotifier
{
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.Subscribe((a) =>

View File

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

View File

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

View File

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

View File

@ -121,6 +121,7 @@ namespace ASC.Feed.Aggregator
var cfg = FeedSettings.GetInstance(Configuration);
using var scope = ServiceProvider.CreateScope();
var scopeClass = scope.ServiceProvider.GetService<FeedAggregatorServiceScope>();
var cache = scope.ServiceProvider.GetService<ICache>();
var (baseCommonLinkUtility, tenantManager, feedAggregateDataProvider, userManager, securityContext, authManager) = scopeClass;
baseCommonLinkUtility.Initialize(cfg.ServerRoot);
@ -145,7 +146,6 @@ namespace ASC.Feed.Aggregator
{
// Warning! There is hack here!
// clearing the cache to get the correct acl
var cache = AscCache.Memory;
cache.Remove("acl" + tenant);
cache.Remove("/webitemsecurity/" + tenant);
//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);
var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production");
config
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path }
}
)
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{env}.json", true)
.AddJsonFile($"appsettings.services.json", true)
@ -48,10 +43,16 @@ namespace ASC.Notify
.AddJsonFile("kafka.json")
.AddJsonFile($"kafka.{env}.json", true)
.AddEnvironmentVariables()
.AddCommandLine(args);
.AddCommandLine(args)
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path }
}
);
})
.ConfigureServices((hostContext, services) =>
{
services.AddMemoryCache();
var diHelper = new DIHelper(services);
LogNLogExtension.ConfigureLog(diHelper, "ASC.Notify", "ASC.Notify.Messages");

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
{
"name": "asc-files-client",
"version": "0.0.6",
"version": "0.0.7",
"private": true,
"homepage": "/products/files",
"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`.
-->
<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");
el.style.display = "block";
}

View File

@ -22,6 +22,7 @@ import {
utils,
toastr,
Layout,
regDesktop,
} from "asc-web-common";
const {
@ -32,14 +33,25 @@ const {
setCurrentProductId,
setCurrentProductHomePage,
getPortalCultures,
setEncryptionKeys,
getIsEncryptionSupport,
getEncryptionKeys,
getIsAuthenticated,
} = commonStore.auth.actions;
const {
getCurrentUser,
isEncryptionSupport,
isDesktopClient,
getIsLoaded,
} = commonStore.auth.selectors;
class App extends React.Component {
constructor(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() {
@ -51,6 +63,9 @@ class App extends React.Component {
getPortalCultures,
fetchTreeFolders,
setIsLoaded,
getIsEncryptionSupport,
getEncryptionKeys,
isDesktop,
getIsAuthenticated,
} = this.props;
@ -69,15 +84,23 @@ class App extends React.Component {
utils.updateTempContent(isAuthenticated);
}
const requests = [
getUser(),
getPortalSettings(),
getModules(),
getPortalCultures(),
fetchTreeFolders(),
];
const requests = [getUser()];
if (!this.isEditor) {
requests.push(
getPortalSettings(),
getModules(),
getPortalCultures(),
fetchTreeFolders()
);
if (isDesktop) {
requests.push(getIsEncryptionSupport(), getEncryptionKeys());
}
}
Promise.all(requests)
.then(() => {
if (this.isEditor) return Promise.resolve();
})
.catch((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() {
const { homepage } = this.props;
const { homepage, isDesktop } = this.props;
console.log(Layout);
return navigator.onLine ? (
<Layout>
<Router history={history}>
{!this.isEditor && <NavMenu />}
<Main>
<Main isDesktop={isDesktop}>
<Suspense fallback={null}>
<Switch>
<Redirect exact from="/" to={`${homepage}`} />
@ -107,7 +158,10 @@ class App extends React.Component {
/>
<Route
exact
path={`${homepage}/doceditor`}
path={[
`${homepage}/doceditor`,
`/Products/Files/DocEditor.aspx`,
]}
component={DocEditor}
/>
<PrivateRoute
@ -148,6 +202,12 @@ const mapStateToProps = (state) => {
const { homepage } = settings;
return {
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),
fetchTreeFolders: () => fetchTreeFolders(dispatch),
setIsLoaded: () => dispatch(setIsLoaded(true)),
getIsEncryptionSupport: () => getIsEncryptionSupport(dispatch),
getEncryptionKeys: () => getEncryptionKeys(dispatch),
setEncryptionKeys: (keys) => dispatch(setEncryptionKeys(keys)),
};
};

View File

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

View File

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

View File

@ -27,6 +27,7 @@ import {
getIsLoading,
getIsRecycleBinFolder,
getSelection,
getIsPrivacyFolder,
} from "../../../store/files/selectors";
import { createI18N } from "../../../helpers/i18n";
const i18n = createI18N({
@ -71,7 +72,7 @@ class DeleteDialogComponent extends React.Component {
isRecycleBinFolder,
setSecondaryProgressBarData,
clearSecondaryProgressData,
t,
isPrivacy, t,
fetchFiles,
setUpdateTree,
} = this.props;
@ -125,6 +126,7 @@ class DeleteDialogComponent extends React.Component {
onDelete = () => {
const {
isRecycleBinFolder,
isPrivacy,
onClose,
t,
setSecondaryProgressBarData,
@ -133,7 +135,7 @@ class DeleteDialogComponent extends React.Component {
const { selection } = this.state;
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 fileIds = [];
@ -300,6 +302,7 @@ const mapStateToProps = (state) => {
treeFolders: getTreeFolders(state),
isLoading: getIsLoading(state),
isRecycleBinFolder: getIsRecycleBinFolder(state),
isPrivacy: getIsPrivacyFolder(state),
selection: getSelection(state),
};
};

View File

@ -1,7 +1,8 @@
import React from "react";
import { withRouter } from "react-router";
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 { setDocumentTitle } from "../../../helpers/utils";
import { changeTitle, setFavicon, isIPad } from "./utils";
@ -26,19 +27,23 @@ class PureEditor extends React.Component {
super(props);
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 desktop = window["AscDesktopEditor"] !== undefined;
this.state = {
fileId,
doc,
isLoading: true,
isDesktop: desktop,
};
}
async componentDidMount() {
try {
const { fileId, doc } = this.state;
const { fileId, doc, isDesktop } = this.state;
if (!fileId) return;
@ -61,6 +66,20 @@ class PureEditor extends React.Component {
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.loadDocApi(docApiUrl, () => this.onLoad(config))
);
@ -90,7 +109,10 @@ class PureEditor extends React.Component {
};
onLoad = (config) => {
console.log("Editor config: ", config);
try {
console.log(config);
docTitle = config.document.title;
fileType = config.document.fileType;

View File

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

View File

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

View File

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

View File

@ -120,5 +120,6 @@
"CopyItems": "<strong>{{qty}}</strong> elements copied",
"ContainsSpecCharacter": "The title cannot contain any of the following characters: *+:\"<>?|/",
"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>",
"ContainsSpecCharacter": "Название не должно содержать следующих символов: *+:\"<>?|/",
"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 { IconButton, utils } from "asc-web-components";
import { setFilesFilter } from "../../../../../store/files/actions";
import { getFilter } from "../../../../../store/files/selectors";
const { tablet, desktop } = utils.device;
const { desktop } = utils.device;
const StyledContainer = styled.div`
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 {
@media ${desktop} {
margin-left: -9px;

View File

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

View File

@ -12,7 +12,7 @@ import {
} from "asc-web-components";
import { connect } from "react-redux";
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 {
getShareUsers,
@ -31,6 +31,7 @@ import {
getIsLoading,
getFiles,
getFolders,
getIsPrivacyFolder,
} from "../../../store/files/selectors";
import {
StyledAsidePanel,
@ -42,12 +43,14 @@ import {
import { AddUsersPanel, AddGroupsPanel, EmbeddingPanel } from "../index";
import SharingRow from "./SharingRow";
import { createI18N } from "../../../helpers/i18n";
import { setEncryptionAccess } from "../../../helpers/desktop";
const i18n = createI18N({
page: "SharingPanel",
localesPath: "panels/SharingPanel",
});
const { changeLanguage } = commonUtils;
const { ShareAccessRights } = constants;
const { replaceFileStream } = store.auth.actions;
const {
getCurrentUserId,
getSettingsCustomNamesGroupsCaption,
@ -133,7 +136,14 @@ class SharingPanelComponent extends React.Component {
shareDataItems,
filesOwnerId,
} = this.state;
const { selection, setIsLoading } = this.props;
const {
selection,
setIsLoading,
isPrivacy,
replaceFileStream,
i18n,
t,
} = this.props;
const folderIds = [];
const fileIds = [];
@ -179,7 +189,6 @@ class SharingPanelComponent extends React.Component {
folderIds.push(item.id);
}
}
const owner = shareDataItems.find((x) => x.isOwner);
const ownerId =
filesOwnerId !== owner.sharedTo.id ? owner.sharedTo.id : null;
@ -199,6 +208,28 @@ class SharingPanelComponent extends React.Component {
if (ownerId) {
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))
.finally(() => setIsLoading(false));
@ -574,6 +605,7 @@ const mapStateToProps = (state) => {
getExternalAccessOption(state, selection),
isMyId: getCurrentUserId(state),
selection: getSelection(state),
isPrivacy: getIsPrivacyFolder(state),
groupsCaption: getSettingsCustomNamesGroupsCaption(state),
sharingPanelVisible: getSharePanelVisible(state),
canShareOwnerChange: getCanShareOwnerChange(state),
@ -585,6 +617,7 @@ const mapStateToProps = (state) => {
};
export default connect(mapStateToProps, {
replaceFileStream,
setSharingPanelVisible,
setIsLoading,
setFiles,

View File

@ -16,6 +16,9 @@
"ExternalLink": "External link",
"InternalLink": "Internal link",
"EncryptedFileSaving": "Saving encrypted file",
"EncryptedFileSharing": "File <strong>{{title}}</strong> successfully shared",
"FullAccess": "Full access",
"ReadOnly": "Read only",
"Review": "Review",
@ -27,4 +30,4 @@
"ShareEveryone": "Everyone",
"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}}"
}
}

View File

@ -16,6 +16,9 @@
"ExternalLink": "Внешняя ссылка",
"InternalLink": "Внутренняя ссылка",
"EncryptedFileSaving": "Сохранение зашифрованного файла",
"EncryptedFileSharing": "К файлу <strong>{{title}}</strong> успешно предоставлен доступ",
"FullAccess": "Полный доступ",
"ReadOnly": "Только чтение",
"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) => {
if (isPrivacy) return Promise.resolve();
return files.addFileToRecentlyViewed(fileId);
};
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -31,6 +31,7 @@ using System.Linq;
using System.Text.RegularExpressions;
using ASC.Common;
using ASC.Common.Caching;
using ASC.Core;
using ASC.Core.Common.EF;
using ASC.Core.Common.Settings;
@ -59,7 +60,8 @@ namespace ASC.Files.Core.Data
CoreConfiguration coreConfiguration,
SettingsManager settingsManager,
AuthContext authContext,
IServiceProvider serviceProvider)
IServiceProvider serviceProvider,
ICache cache)
: base(dbContextManager,
userManager,
tenantManager,
@ -71,7 +73,8 @@ namespace ASC.Files.Core.Data
coreConfiguration,
settingsManager,
authContext,
serviceProvider)
serviceProvider,
cache)
{
}
@ -108,7 +111,7 @@ namespace ASC.Files.Core.Data
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 foldersId = new HashSet<string>();
@ -139,7 +142,8 @@ namespace ASC.Files.Core.Data
}
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)

View File

@ -94,7 +94,12 @@ namespace ASC.Web.Files.Core.Entries
var currentAddressString = EncryptionLoginProvider.GetKeys();
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;
return keyPair;
}
@ -120,7 +125,13 @@ namespace ASC.Web.Files.Core.Entries
var fileKeyPairString = EncryptionLoginProvider.GetKeys(share.SubjectId);
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;
fileKeyPair.PrivateKeyEnc = null;

View File

@ -66,7 +66,8 @@ namespace ASC.Files.Core
public File(Global global,
FilesLinkUtility filesLinkUtility,
FileUtility fileUtility,
FileConverter fileConverter)
FileConverter fileConverter,
FileTrackerHelper fileTracker)
: base(global)
{
Version = 1;
@ -74,7 +75,8 @@ namespace ASC.Files.Core
FileEntryType = FileEntryType.File;
FilesLinkUtility = filesLinkUtility;
FileUtility = fileUtility;
FileConverter = fileConverter;
FileConverter = fileConverter;
FileTracker = fileTracker;
}
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]
private readonly FilesLinkUtility FilesLinkUtility;

View File

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

View File

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

View File

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

View File

@ -217,13 +217,16 @@ namespace ASC.Files.Thirdparty.Box
public class BoxProviderInfoHelper
{
private readonly TimeSpan CacheExpiration = TimeSpan.FromMinutes(1);
private readonly ICache CacheFile = AscCache.Memory;
private readonly ICache CacheFolder = AscCache.Memory;
private readonly ICache CacheChildItems = AscCache.Memory;
private readonly ICache CacheFile;
private readonly ICache CacheFolder;
private readonly ICache CacheChildItems;
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.Subscribe((i) =>
{

View File

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

View File

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

View File

@ -402,9 +402,9 @@ namespace ASC.Files.Thirdparty
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>();
var q = FilesDbContext.Tag
.Join(FilesDbContext.TagLink.DefaultIfEmpty(),
r => new TagLink { TenantId = r.TenantId, Id = r.Id },
r => new TagLink { TenantId = r.TenantId, Id = r.TagId },
(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));
var q = from r in FilesDbContext.Tag
from l in FilesDbContext.TagLink.Where(a => a.TenantId == r.TenantId && a.TagId == r.Id).DefaultIfEmpty()
where r.TenantId == TenantID && l.TenantId == TenantID && r.Flag == TagType.New && entryIDs.Contains(l.EntryId)
select new { tag = r, tagLink = l };
if (subject != Guid.Empty)
{
q = q.Where(r => r.tag.Owner == subject);
}
var tags = q
var tags = q
.Distinct()
.ToList()
.Select(r => new Tag
{

View File

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

View File

@ -129,7 +129,7 @@ namespace ASC.Files.Thirdparty.ProviderDao
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);
}

View File

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

View File

@ -364,8 +364,13 @@ namespace ASC.Web.Files.Services.DocumentService
set
{
try
{
JsonSerializer.Deserialize<ActionLinkConfig>(value);
{
var options = new JsonSerializerOptions
{
AllowTrailingCommas = true,
PropertyNameCaseInsensitive = true
};
JsonSerializer.Deserialize<ActionLinkConfig>(value, options);
}
catch (Exception)
{
@ -584,7 +589,7 @@ namespace ASC.Web.Files.Services.DocumentService
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; }

View File

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

View File

@ -181,7 +181,8 @@ namespace ASC.Web.Files.Services.DocumentService
private FilesMessageService FilesMessageService { get; }
private DocumentServiceConnector DocumentServiceConnector { get; }
private NotifyClient NotifyClient { get; }
private MailMergeTaskRunner MailMergeTaskRunner { get; }
private MailMergeTaskRunner MailMergeTaskRunner { get; }
public FileTrackerHelper FileTracker { get; }
public ILog Logger { get; }
public DocumentServiceTrackerHelper(
@ -202,7 +203,8 @@ namespace ASC.Web.Files.Services.DocumentService
FilesMessageService filesMessageService,
DocumentServiceConnector documentServiceConnector,
NotifyClient notifyClient,
MailMergeTaskRunner mailMergeTaskRunner)
MailMergeTaskRunner mailMergeTaskRunner,
FileTrackerHelper fileTracker)
{
SecurityContext = securityContext;
UserManager = userManager;
@ -220,7 +222,8 @@ namespace ASC.Web.Files.Services.DocumentService
FilesMessageService = filesMessageService;
DocumentServiceConnector = documentServiceConnector;
NotifyClient = notifyClient;
MailMergeTaskRunner = mailMergeTaskRunner;
MailMergeTaskRunner = mailMergeTaskRunner;
FileTracker = fileTracker;
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)
{
var entryManager = scope.ServiceProvider.GetService<EntryManager>();
var entryManager = scope.ServiceProvider.GetService<EntryManager>();
var fileTracker = scope.ServiceProvider.GetService<FileTrackerHelper>();
error = null;
foreach (var file in files)
@ -267,7 +268,7 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
error = FilesCommonResource.ErrorMassage_LockedFile;
return true;
}
if (FileTracker.IsEditing(file.ID))
if (fileTracker.IsEditing(file.ID))
{
error = folder ? FilesCommonResource.ErrorMassage_SecurityException_DeleteEditingFolder : FilesCommonResource.ErrorMassage_SecurityException_DeleteEditingFile;
return true;

View File

@ -364,7 +364,8 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
var scopeClass = scope.ServiceProvider.GetService<FileMoveCopyOperationScope>();
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;
foreach (var fileId in fileIds)
@ -474,7 +475,7 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
{
Error = FilesCommonResource.ErrorMassage_LockedFile;
}
else if (FileTracker.IsEditing(conflict.ID))
else if (fileTracker.IsEditing(conflict.ID))
{
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)
{
var entryManager = scope.ServiceProvider.GetService<EntryManager>();
var entryManager = scope.ServiceProvider.GetService<EntryManager>();
var fileTracker = scope.ServiceProvider.GetService<FileTrackerHelper>();
error = null;
foreach (var file in files)
{
@ -576,7 +578,7 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
error = FilesCommonResource.ErrorMassage_LockedFile;
return true;
}
if (FileTracker.IsEditing(file.ID))
if (fileTracker.IsEditing(file.ID))
{
error = FilesCommonResource.ErrorMassage_SecurityException_UpdateEditingFile;
return true;

View File

@ -35,8 +35,8 @@ using ASC.Common.Threading;
using ASC.Core.Tenants;
using ASC.Files.Core.Resources;
using Microsoft.Extensions.Primitives;
using Microsoft.Extensions.Primitives;
namespace ASC.Web.Files.Services.WCFService.FileOperations
{
[Singletone(Additional = typeof(FileOperationsManagerHelperExtention))]
@ -55,21 +55,24 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
public ItemList<FileOperationResult> GetOperationResults(Guid userId)
{
var operations = tasks.GetTasks();
var processlist = Process.GetProcesses();
var processlist = Process.GetProcesses();
//TODO: replace with distributed cache
foreach (var o in operations.Where(o => processlist.All(p => p.Id != o.InstanceId)))
{
o.SetProperty(FileOperation.PROGRESS, 100);
tasks.RemoveTask(o.Id);
}
//TODO: replace with distributed cache
if (processlist.Any())
{
foreach (var o in operations.Where(o => processlist.All(p => p.Id != o.InstanceId)))
{
o.SetProperty(FileOperation.PROGRESS, 100);
tasks.RemoveTask(o.Id);
}
}
operations = operations.Where(t => t.GetProperty<Guid>(FileOperation.OWNER) == userId);
foreach (var o in operations.Where(o => o.Status > DistributedTaskStatus.Running))
{
o.SetProperty(FileOperation.PROGRESS, 100);
tasks.RemoveTask(o.Id);
}
}
var results = operations
.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
{
private const string UPDATE_LIST = "filesUpdateList";
private readonly ICache cache;
private ICache Cache { get; set; }
public FileTrackerHelper FileTracker { get; }
private IDaoFactory DaoFactory { get; }
private FileSecurity FileSecurity { get; }
private GlobalFolderHelper GlobalFolderHelper { get; }
@ -226,7 +227,9 @@ namespace ASC.Web.Files.Utils
BreadCrumbsManager breadCrumbsManager,
TenantManager tenantManager,
SettingsManager settingsManager,
IServiceProvider serviceProvider)
IServiceProvider serviceProvider,
ICache cache,
FileTrackerHelper fileTracker)
{
DaoFactory = daoFactory;
FileSecurity = fileSecurity;
@ -251,7 +254,8 @@ namespace ASC.Web.Files.Utils
SettingsManager = settingsManager;
ServiceProvider = serviceProvider;
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)
@ -319,8 +323,8 @@ namespace ASC.Web.Files.Utils
if (!folderIDProjectTitle.ContainsKey(projectFolderID))
folderIDProjectTitle.Add(projectFolderID, new KeyValuePair<int, string>(projectID, projectTitle));
AscCache.Memory.Remove("documents/folders/" + projectFolderID);
AscCache.Memory.Insert("documents/folders/" + projectFolderID, projectTitle, TimeSpan.FromMinutes(30));
Cache.Remove("documents/folders/" + projectFolderID);
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.Value.TagType == TagType.Favorite)
{
file.IsFavorite = true;
continue;
}
file.IsFavorite = t.Value.Any(r=> r.TagType == TagType.Favorite);
file.IsTemplate = t.Value.Any(r => r.TagType == TagType.Template);
if (t.Value.TagType == TagType.Template)
var lockedTag = t.Value.FirstOrDefault(r => r.TagType == TagType.Locked);
if (lockedTag != null)
{
file.IsTemplate = true;
continue;
}
if (t.Value.TagType == TagType.Locked)
{
var lockedBy = t.Value.Owner;
var lockedBy = lockedTag.Owner;
file.Locked = lockedBy != Guid.Empty;
file.LockedBy = lockedBy != Guid.Empty && lockedBy != AuthContext.CurrentAccount.ID
? Global.GetUserName(lockedBy)
@ -1026,14 +1022,14 @@ namespace ASC.Web.Files.Utils
if (fromFile.ProviderEntry) throw new Exception(FilesCommonResource.ErrorMassage_BadRequest);
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)
{
throw new Exception(FilesCommonResource.ErrorMassage_UpdateEditingFile);
}
else
{
cache.Insert(UPDATE_LIST + fileId.ToString(), fileId.ToString(), TimeSpan.FromMinutes(2));
Cache.Insert(UPDATE_LIST + fileId.ToString(), fileId.ToString(), TimeSpan.FromMinutes(2));
}
try
@ -1086,7 +1082,7 @@ namespace ASC.Web.Files.Utils
}
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; }
public FileConverterQueue(IServiceProvider ServiceProvider)
public FileConverterQueue(IServiceProvider ServiceProvider, ICache cache)
{
conversionQueue = new Dictionary<File<T>, ConvertFileOperationResult>(new FileComparer<T>());
timer = new Timer(CheckConvertFilesStatus, null, 0, Timeout.Infinite);
locker = new object();
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)
@ -515,7 +515,8 @@ namespace ASC.Web.Files.Utils
private FilesMessageService FilesMessageService { get; }
private FileShareLink FileShareLink { get; }
private DocumentServiceHelper DocumentServiceHelper { get; }
private DocumentServiceConnector DocumentServiceConnector { get; }
private DocumentServiceConnector DocumentServiceConnector { get; }
public FileTrackerHelper FileTracker { get; }
private IServiceProvider ServiceProvider { get; }
private IHttpContextAccessor HttpContextAccesor { get; }
@ -535,7 +536,8 @@ namespace ASC.Web.Files.Utils
FilesMessageService filesMessageService,
FileShareLink fileShareLink,
DocumentServiceHelper documentServiceHelper,
DocumentServiceConnector documentServiceConnector,
DocumentServiceConnector documentServiceConnector,
FileTrackerHelper fileTracker,
IServiceProvider serviceProvider)
{
FileUtility = fileUtility;
@ -553,7 +555,8 @@ namespace ASC.Web.Files.Utils
FilesMessageService = filesMessageService;
FileShareLink = fileShareLink;
DocumentServiceHelper = documentServiceHelper;
DocumentServiceConnector = documentServiceConnector;
DocumentServiceConnector = documentServiceConnector;
FileTracker = fileTracker;
ServiceProvider = serviceProvider;
}
public FileConverter(
@ -572,12 +575,13 @@ namespace ASC.Web.Files.Utils
FilesMessageService filesMessageService,
FileShareLink fileShareLink,
DocumentServiceHelper documentServiceHelper,
DocumentServiceConnector documentServiceConnector,
DocumentServiceConnector documentServiceConnector,
FileTrackerHelper fileTracker,
IServiceProvider serviceProvider,
IHttpContextAccessor httpContextAccesor)
: this(fileUtility, filesLinkUtility, daoFactory, setupInfo, pathProvider, fileSecurity,
fileMarker, tenantManager, authContext, entryManager, filesSettingsHelper,
globalFolderHelper, filesMessageService, fileShareLink, documentServiceHelper, documentServiceConnector,
globalFolderHelper, filesMessageService, fileShareLink, documentServiceHelper, documentServiceConnector, fileTracker,
serviceProvider)
{
HttpContextAccesor = httpContextAccesor;

View File

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

View File

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

View File

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

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