commit
7f92ac83a1
193
ASC.Tests.sln
Normal file
193
ASC.Tests.sln
Normal 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
76
build/Jenkinsfile
vendored
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 \
|
||||
|
@ -41,6 +41,7 @@ namespace ASC.Api.Core
|
||||
public virtual void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddHttpContextAccessor();
|
||||
services.AddMemoryCache();
|
||||
|
||||
DIHelper.Configure(services);
|
||||
|
||||
|
@ -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" />
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -80,5 +80,11 @@ namespace ASC.Common.Utils
|
||||
{
|
||||
return GetConnectionStrings()[key];
|
||||
}
|
||||
|
||||
public string this[string key]
|
||||
{
|
||||
get => Configuration[key];
|
||||
set => Configuration[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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) =>
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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) =>
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -99,8 +99,7 @@ namespace ASC.Core.Common.EF
|
||||
ActivationStatus = 0,
|
||||
WorkFromDate = DateTime.UtcNow,
|
||||
LastModified = DateTime.UtcNow
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
return modelBuilder;
|
||||
}
|
||||
|
@ -42,8 +42,7 @@ namespace ASC.Core.Common.EF
|
||||
PwdHash = "vLFfghR5tNV3K9DKhmwArV+SbjWAcgZZzIDTnJ0JgCo=",
|
||||
PwdHashSha512 = "USubvPlB+ogq0Q1trcSupg==",
|
||||
LastModified = DateTime.UtcNow
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
return modelBuilder;
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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)
|
||||
|
@ -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}";
|
||||
|
@ -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)
|
||||
|
@ -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) =>
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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}
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -61,6 +61,7 @@ namespace ASC.ApiSystem
|
||||
var diHelper = new DIHelper(services);
|
||||
|
||||
services.AddHttpContextAccessor();
|
||||
services.AddMemoryCache();
|
||||
|
||||
services.AddControllers()
|
||||
.AddJsonOptions(options =>
|
||||
|
@ -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()
|
||||
|
@ -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) =>
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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<>));
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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");
|
||||
|
@ -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<>));
|
||||
|
@ -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>();
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "asc-files-client",
|
||||
"version": "0.0.6",
|
||||
"version": "0.0.7",
|
||||
"private": true,
|
||||
"homepage": "/products/files",
|
||||
"dependencies": {
|
||||
|
10
products/ASC.Files/Client/public/images/security.svg
Normal file
10
products/ASC.Files/Client/public/images/security.svg
Normal 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 |
@ -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";
|
||||
}
|
||||
|
@ -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)),
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -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),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -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),
|
||||
};
|
||||
};
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)));
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -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"}
|
||||
|
@ -120,5 +120,6 @@
|
||||
"CopyItems": "Скопировано элементов: <strong>{{qty}}</strong>",
|
||||
"ContainsSpecCharacter": "Название не должно содержать следующих символов: *+:\"<>?|/",
|
||||
"CreateWithEmptyTitle": "Нельзя создать папку или файл с пустым названием",
|
||||
"ChangeOwner": "Сменить владельца"
|
||||
}
|
||||
"ChangeOwner": "Сменить владельца",
|
||||
"EncryptedFileSaving": "Сохранение зашифрованного файла",
|
||||
"EncryptedFileCreating": "Создан новый файл <strong>{{itemTitle}}</strong>"}
|
||||
|
@ -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;
|
||||
|
@ -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),
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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}}"
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,9 @@
|
||||
"ExternalLink": "Внешняя ссылка",
|
||||
"InternalLink": "Внутренняя ссылка",
|
||||
|
||||
"EncryptedFileSaving": "Сохранение зашифрованного файла",
|
||||
"EncryptedFileSharing": "К файлу <strong>{{title}}</strong> успешно предоставлен доступ",
|
||||
|
||||
"FullAccess": "Полный доступ",
|
||||
"ReadOnly": "Только чтение",
|
||||
"Review": "Рецензирование",
|
||||
|
57
products/ASC.Files/Client/src/helpers/desktop.js
Normal file
57
products/ASC.Files/Client/src/helpers/desktop.js
Normal 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;
|
||||
});
|
||||
}
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) =>
|
||||
{
|
||||
|
@ -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) =>
|
||||
|
@ -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) =>
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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) =>
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) =>
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user