Merge branch 'develop' into feature/accounts-room-list
This commit is contained in:
commit
4ff7ea1a33
6
.github/workflows/4testing-multi-build.yml
vendored
6
.github/workflows/4testing-multi-build.yml
vendored
@ -2,7 +2,7 @@ name: 4testing multiarch-build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "develop" ]
|
||||
branches: [ "release/rc-v1.2.0" ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@ -33,10 +33,10 @@ jobs:
|
||||
cd ./build/install/docker
|
||||
REPO="onlyoffice" \
|
||||
DOCKER_IMAGE_PREFIX="4testing-docspace" \
|
||||
DOCKER_TAG="develop" \
|
||||
DOCKER_TAG="rc-v1.2.0" \
|
||||
DOCKERFILE="Dockerfile.app" \
|
||||
docker buildx bake -f build.yml \
|
||||
--set *.args.GIT_BRANCH="develop" \
|
||||
--set *.args.GIT_BRANCH="release/rc-v1.2.0" \
|
||||
--set *.platform=linux/amd64 \
|
||||
--push
|
||||
shell: bash
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -50,4 +50,3 @@ TestsResults/
|
||||
|
||||
**/.yarn/cache
|
||||
**/.yarn/install-state.gz
|
||||
config/appsettings.dev.json
|
||||
|
783
.yarn/releases/yarn-3.2.2.cjs
vendored
783
.yarn/releases/yarn-3.2.2.cjs
vendored
File diff suppressed because one or more lines are too long
801
.yarn/releases/yarn-3.2.4.cjs
vendored
Executable file
801
.yarn/releases/yarn-3.2.4.cjs
vendored
Executable file
File diff suppressed because one or more lines are too long
@ -8,4 +8,4 @@ plugins:
|
||||
- path: .yarn/plugins/@yarnpkg/plugin-version.cjs
|
||||
spec: "@yarnpkg/plugin-version"
|
||||
|
||||
yarnPath: .yarn/releases/yarn-3.2.2.cjs
|
||||
yarnPath: .yarn/releases/yarn-3.2.4.cjs
|
||||
|
42
ASC.Web.slnf
Normal file
42
ASC.Web.slnf
Normal file
@ -0,0 +1,42 @@
|
||||
{
|
||||
"solution": {
|
||||
"path": "ASC.Web.sln",
|
||||
"projects": [
|
||||
"common\\ASC.ActiveDirectory\\ASC.ActiveDirectory.csproj",
|
||||
"common\\ASC.Api.Core\\ASC.Api.Core.csproj",
|
||||
"common\\ASC.Common\\ASC.Common.csproj",
|
||||
"common\\ASC.Core.Common\\ASC.Core.Common.csproj",
|
||||
"common\\ASC.Data.Backup.Core\\ASC.Data.Backup.Core.csproj",
|
||||
"common\\ASC.Data.Encryption\\ASC.Data.Encryption.csproj",
|
||||
"common\\ASC.Data.Reassigns\\ASC.Data.Reassigns.csproj",
|
||||
"common\\ASC.Data.Storage\\ASC.Data.Storage.csproj",
|
||||
"common\\ASC.EventBus.ActiveMQ\\ASC.EventBus.ActiveMQ.csproj",
|
||||
"common\\ASC.EventBus.Extensions.Logger\\ASC.EventBus.Extensions.Logger.csproj",
|
||||
"common\\ASC.EventBus.RabbitMQ\\ASC.EventBus.RabbitMQ.csproj",
|
||||
"common\\ASC.EventBus\\ASC.EventBus.csproj",
|
||||
"common\\ASC.FederatedLogin\\ASC.FederatedLogin.csproj",
|
||||
"common\\ASC.Feed\\ASC.Feed.csproj",
|
||||
"common\\ASC.IPSecurity\\ASC.IPSecurity.csproj",
|
||||
"common\\ASC.MessagingSystem\\ASC.MessagingSystem.csproj",
|
||||
"common\\ASC.Notify.Textile\\ASC.Notify.Textile.csproj",
|
||||
"common\\ASC.Textile\\ASC.Textile.csproj",
|
||||
"common\\services\\ASC.ApiSystem\\ASC.ApiSystem.csproj",
|
||||
"common\\services\\ASC.AuditTrail\\ASC.AuditTrail.csproj",
|
||||
"common\\services\\ASC.ClearEvents\\ASC.ClearEvents.csproj",
|
||||
"common\\services\\ASC.Data.Backup.BackgroundTasks\\ASC.Data.Backup.BackgroundTasks.csproj",
|
||||
"common\\services\\ASC.Data.Backup\\ASC.Data.Backup.csproj",
|
||||
"common\\services\\ASC.ElasticSearch\\ASC.ElasticSearch.csproj",
|
||||
"common\\services\\ASC.Feed.Aggregator\\ASC.Feed.Aggregator.csproj",
|
||||
"common\\services\\ASC.Notify\\ASC.Notify.csproj",
|
||||
"common\\services\\ASC.Studio.Notify\\ASC.Studio.Notify.csproj",
|
||||
"products\\ASC.Files\\Core\\ASC.Files.Core.csproj",
|
||||
"products\\ASC.Files\\Server\\ASC.Files.csproj",
|
||||
"products\\ASC.Files\\Service\\ASC.Files.Service.csproj",
|
||||
"products\\ASC.People\\Server\\ASC.People.csproj",
|
||||
"web\\ASC.Web.Api\\ASC.Web.Api.csproj",
|
||||
"web\\ASC.Web.Core\\ASC.Web.Core.csproj",
|
||||
"web\\ASC.Web.HealthChecks.UI\\ASC.Web.HealthChecks.UI.csproj",
|
||||
"web\\ASC.Web.Studio\\ASC.Web.Studio.csproj"
|
||||
]
|
||||
}
|
||||
}
|
8
build/Jenkinsfile
vendored
8
build/Jenkinsfile
vendored
@ -13,7 +13,7 @@ pipeline {
|
||||
}
|
||||
stage('Backend') {
|
||||
steps {
|
||||
sh 'dotnet build -c Release ASC.Web.sln'
|
||||
sh 'dotnet build -c Release ASC.Web.slnf'
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -28,7 +28,7 @@ pipeline {
|
||||
}
|
||||
stage('Backend') {
|
||||
steps {
|
||||
bat 'dotnet build -c Release ASC.Web.sln'
|
||||
bat 'dotnet build -c Release ASC.Web.slnf'
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -62,7 +62,7 @@ pipeline {
|
||||
}
|
||||
stage('Files') {
|
||||
steps {
|
||||
sh "git submodule update --progress --init -- products/ASC.Files/Server/DocStore && dotnet build ASC.Web.sln && cd ${env.WORKSPACE}/products/ASC.Files/Tests/ && dotnet test ASC.Files.Tests.csproj -r linux-x64 -l \"console;verbosity=detailed\""
|
||||
sh "git submodule update --progress --init -- products/ASC.Files/Server/DocStore && dotnet build ASC.Web.slnf && cd ${env.WORKSPACE}/products/ASC.Files/Tests/ && dotnet test ASC.Files.Tests.csproj -r linux-x64 -l \"console;verbosity=detailed\""
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -90,7 +90,7 @@ pipeline {
|
||||
}
|
||||
stage('Files') {
|
||||
steps {
|
||||
bat "git submodule update --progress --init -- products\\ASC.Files\\Server\\DocStore && dotnet build ASC.Web.sln && cd ${env.WORKSPACE}\\products\\ASC.Files\\Tests\\ && dotnet test ASC.Files.Tests.csproj"
|
||||
bat "git submodule update --progress --init -- products\\ASC.Files\\Server\\DocStore && dotnet build ASC.Web.slnf && cd ${env.WORKSPACE}\\products\\ASC.Files\\Tests\\ && dotnet test ASC.Files.Tests.csproj"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ call runasadmin.bat "%~dpnx0"
|
||||
|
||||
if %errorlevel% == 0 (
|
||||
call start\stop.bat nopause
|
||||
dotnet build ..\asc.web.sln /fl1 /flp1:logfile=asc.web.log;verbosity=normal
|
||||
dotnet build ..\asc.web.slnf /fl1 /flp1:logfile=asc.web.log;verbosity=normal
|
||||
echo.
|
||||
)
|
||||
|
||||
|
7
build/build.backend.docker.bat
Normal file
7
build/build.backend.docker.bat
Normal file
@ -0,0 +1,7 @@
|
||||
@echo off
|
||||
|
||||
pwsh %~dp0/build.backend.docker.ps1 %1
|
||||
|
||||
echo.
|
||||
|
||||
pause
|
81
build/build.backend.docker.ps1
Normal file
81
build/build.backend.docker.ps1
Normal file
@ -0,0 +1,81 @@
|
||||
$PSversionMajor = $PSVersionTable.PSVersion | sort-object major | ForEach-Object { $_.major }
|
||||
$PSversionMinor = $PSVersionTable.PSVersion | sort-object minor | ForEach-Object { $_.minor }
|
||||
|
||||
if ($PSversionMajor -lt 7 -or $PSversionMinor -lt 2) {
|
||||
Write-Error "Powershell version must be greater than or equal to 7.2."
|
||||
exit
|
||||
}
|
||||
|
||||
$Branch = git branch --show-current
|
||||
$BranchExistRemote = git ls-remote --heads origin $Branch
|
||||
|
||||
if (-not $BranchExistRemote) {
|
||||
Write-Error "The current branch does not exist in the remote repository. Please push changes."
|
||||
exit
|
||||
}
|
||||
|
||||
$RootDir = Split-Path -Parent $PSScriptRoot
|
||||
$DockerDir = ($RootDir + "\build\install\docker")
|
||||
$BuildDate = Get-Date -Format "yyyy-MM-dd"
|
||||
$LocalIp = (Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration | Where-Object { $_.DHCPEnabled -ne $null -and $_.DefaultIPGateway -ne $null }).IPAddress | Select-Object -First 1
|
||||
|
||||
$Doceditor = ($LocalIp + ":5013")
|
||||
$Login = ($LocalIp + ":5011")
|
||||
$Client = ($LocalIp + ":5001")
|
||||
|
||||
$DockerFile = "Dockerfile.dev"
|
||||
$EnvExtension = "dev"
|
||||
$CoreBaseDomain = "localhost"
|
||||
|
||||
# Stop all backend services"
|
||||
& "$PSScriptRoot\start\stop.backend.docker.ps1"
|
||||
|
||||
$Env:COMPOSE_IGNORE_ORPHANS = "True"
|
||||
|
||||
$Containers = docker ps -a -f "name=^onlyoffice" --format="{{.ID}} {{.Names}}" | Select-String -Pattern ("mysql|rabbitmq|redis|elasticsearch|documentserver") -NotMatch | ConvertFrom-String | ForEach-Object P1
|
||||
$Images = docker images onlyoffice/docspace* -q
|
||||
|
||||
if ($Containers) {
|
||||
Write-Host "Remove all backend containers" -ForegroundColor Blue
|
||||
docker rm -f $Containers
|
||||
}
|
||||
|
||||
if ($Images) {
|
||||
Write-Host "Remove all docker images except 'mysql, rabbitmq, redis, elasticsearch, documentserver'" -ForegroundColor Blue
|
||||
docker rmi -f $Images
|
||||
}
|
||||
|
||||
Write-Host "Run MySQL" -ForegroundColor Green
|
||||
docker compose -f ($DockerDir + "\db.yml") up -d
|
||||
|
||||
Write-Host "Run environments (redis, rabbitmq)" -ForegroundColor Green
|
||||
$Env:DOCKERFILE = $DockerFile
|
||||
docker compose -f ($DockerDir + "\redis.yml") -f ($DockerDir + "\rabbitmq.yml") up -d
|
||||
|
||||
if ($args[0] -eq "--no_ds") {
|
||||
Write-Host "SKIP Document server" -ForegroundColor Blue
|
||||
}
|
||||
else {
|
||||
Write-Host "Run Document server" -ForegroundColor Green
|
||||
$Env:DOCUMENT_SERVER_IMAGE_NAME = "onlyoffice/documentserver-de:latest"
|
||||
$Env:ROOT_DIR = $RootDir
|
||||
docker compose -f ($DockerDir + "\ds.dev.yml") up -d
|
||||
}
|
||||
|
||||
Write-Host "Build all backend services" -ForegroundColor Blue
|
||||
$Env:DOCKERFILE = $DockerFile
|
||||
$Env:RELEASE_DATE = $BuildDate
|
||||
$Env:GIT_BRANCH = $Branch
|
||||
$Env:SERVICE_DOCEDITOR = $Doceditor
|
||||
$Env:SERVICE_LOGIN = $Login
|
||||
$Env:SERVICE_CLIENT = $Client
|
||||
$Env:APP_CORE_BASE_DOMAIN = $CoreBaseDomain
|
||||
$Env:ENV_EXTENSION = $EnvExtension
|
||||
docker compose -f ($DockerDir + "\build.dev.yml") build --build-arg GIT_BRANCH=$Branch --build-arg RELEASE_DATE=$BuildDate
|
||||
|
||||
Write-Host "Run DB migration" -ForegroundColor Green
|
||||
$Env:DOCKERFILE = $DockerFile
|
||||
docker compose -f ($DockerDir + "\migration-runner.yml") up -d
|
||||
|
||||
# Start all backend services"
|
||||
& "$PSScriptRoot\start\start.backend.docker.ps1"
|
@ -9,10 +9,17 @@ echo "Root directory:" $dir
|
||||
|
||||
cd $dir
|
||||
|
||||
branch=$(git branch | sed -n -e 's/^\* \(.*\)/\1/p')
|
||||
branch=$(git branch --show-current)
|
||||
|
||||
echo "GIT_BRANCH:" $branch
|
||||
|
||||
branch_exist_remote=$(git ls-remote --heads origin $branch)
|
||||
|
||||
if [ -z "$branch_exist_remote" ]; then
|
||||
echo "The current branch does not exist in the remote repository. Please push changes."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd $dir/build/install/docker/
|
||||
|
||||
docker_dir="$( pwd )"
|
||||
@ -43,11 +50,9 @@ $dir/build/start/stop.backend.docker.sh
|
||||
|
||||
echo "Remove all backend containers"
|
||||
docker rm -f $(docker ps -a | egrep "onlyoffice" | egrep -v "mysql|rabbitmq|redis|elasticsearch|documentserver" | awk 'NR>0 {print $1}')
|
||||
echo "Remove all backend images"
|
||||
docker rmi -f $(docker images -a | egrep "onlyoffice" | egrep -v "mysql|rabbitmq|redis|elasticsearch|documentserver" | awk 'NR>0 {print $3}')
|
||||
|
||||
echo "Remove all docker images except 'mysql, rabbitmq, redis, elasticsearch, documentserver'"
|
||||
docker image rm -f $(docker images -a | egrep "onlyoffice" | egrep -v "mysql|rabbitmq|redis|elasticsearch|documentserver" | awk 'NR>0 {print $3}')
|
||||
docker rmi -f $(docker images -a | egrep "onlyoffice" | egrep -v "mysql|rabbitmq|redis|elasticsearch|documentserver" | awk 'NR>0 {print $3}')
|
||||
|
||||
echo "Run MySQL"
|
||||
|
||||
@ -58,7 +63,7 @@ if [ "${arch_name}" = "x86_64" ]; then
|
||||
docker compose -f db.yml up -d
|
||||
elif [ "${arch_name}" = "arm64" ]; then
|
||||
echo "CPU Type: arm64 -> run db.yml with arm64v8 image"
|
||||
MYSQL_IMAGE=arm64v8/mysql:oracle \
|
||||
MYSQL_IMAGE=arm64v8/mysql:8.0.31-oracle \
|
||||
docker compose -f db.yml up -d
|
||||
else
|
||||
echo "Error: Unknown CPU Type: ${arch_name}."
|
||||
|
7
build/build.document.server.docker.bat
Normal file
7
build/build.document.server.docker.bat
Normal file
@ -0,0 +1,7 @@
|
||||
@echo off
|
||||
|
||||
pwsh %~dp0/build.document.server.docker.ps1 %1
|
||||
|
||||
echo.
|
||||
|
||||
pause
|
15
build/build.document.server.docker.ps1
Normal file
15
build/build.document.server.docker.ps1
Normal file
@ -0,0 +1,15 @@
|
||||
$PSversionMajor = $PSVersionTable.PSVersion | sort-object major | ForEach-Object { $_.major }
|
||||
$PSversionMinor = $PSVersionTable.PSVersion | sort-object minor | ForEach-Object { $_.minor }
|
||||
|
||||
if ($PSversionMajor -lt 7 -or $PSversionMinor -lt 2) {
|
||||
Write-Error "Powershell version must be greater than or equal to 7.2."
|
||||
exit
|
||||
}
|
||||
|
||||
$RootDir = Split-Path -Parent $PSScriptRoot
|
||||
|
||||
Write-Host "Run Document server" -ForegroundColor Green
|
||||
$DOCUMENT_SERVER_IMAGE_NAME = "onlyoffice/documentserver-de:latest"
|
||||
|
||||
|
||||
docker run -i -t -d -p 8085:80 -e JWT_ENABLED=false -e JWT_IN_BODY=false --restart=always -v $RootDir/Data:/var/www/onlyoffice/Data $DOCUMENT_SERVER_IMAGE_NAME
|
@ -20,7 +20,7 @@ echo "FRONT-END (for start run command 'yarn start' inside the root folder)"
|
||||
yarn install
|
||||
|
||||
echo "BACK-END"
|
||||
dotnet build $dir/asc.web.sln /fl1 /flp1:logfile=asc.web.log;verbosity=normal
|
||||
dotnet build $dir/asc.web.slnf /fl1 /flp1:logfile=asc.web.log;verbosity=normal
|
||||
|
||||
echo "install nodejs projects dependencies..."
|
||||
pushd $dir/common/ASC.Socket.IO/
|
||||
@ -29,7 +29,5 @@ pushd $dir/common/ASC.SsoAuth/
|
||||
yarn install
|
||||
pushd $dir/common/ASC.WebDav/
|
||||
yarn install
|
||||
pushd $dir/common/ASC.UrlShortener/
|
||||
yarn install
|
||||
pushd $dir/common/ASC.WebPlugins/
|
||||
yarn install
|
7
build/clear.backend.docker.bat
Normal file
7
build/clear.backend.docker.bat
Normal file
@ -0,0 +1,7 @@
|
||||
@echo off
|
||||
|
||||
pwsh %~dp0/clear.backend.docker.ps1
|
||||
|
||||
echo.
|
||||
|
||||
pause
|
21
build/clear.backend.docker.ps1
Normal file
21
build/clear.backend.docker.ps1
Normal file
@ -0,0 +1,21 @@
|
||||
$Containers = docker ps -aqf "name=^onlyoffice"
|
||||
$Images = docker images onlyoffice/docspace* -q
|
||||
|
||||
if ($Containers) {
|
||||
Write-Host "Stop all backend containers" -ForegroundColor Blue
|
||||
docker stop $Containers
|
||||
|
||||
Write-Host "Remove all backend containers" -ForegroundColor Blue
|
||||
docker rm -f $Containers
|
||||
}
|
||||
|
||||
if ($Images) {
|
||||
Write-Host "Remove all docker images except 'mysql, rabbitmq, redis, elasticsearch, documentserver'" -ForegroundColor Blue
|
||||
docker rmi -f $Images
|
||||
}
|
||||
|
||||
Write-Host "Remove unused volumes." -ForegroundColor Blue
|
||||
docker volume prune -f
|
||||
|
||||
Write-Host "Remove unused networks." -ForegroundColor Blue
|
||||
docker network prune -f
|
@ -42,12 +42,11 @@ done
|
||||
echo "== BACK-END-BUILD =="
|
||||
|
||||
cd ${SRC_PATH}
|
||||
dotnet build ASC.Web.sln ${ARGS}
|
||||
dotnet build ASC.Web.slnf ${ARGS}
|
||||
dotnet build ASC.Migrations.sln -o ${SRC_PATH}/ASC.Migration.Runner/service/
|
||||
|
||||
# Array of names backend services in directory common (Nodejs)
|
||||
services_name_backend_nodejs=()
|
||||
services_name_backend_nodejs+=(ASC.UrlShortener)
|
||||
services_name_backend_nodejs+=(ASC.Socket.IO)
|
||||
services_name_backend_nodejs+=(ASC.SsoAuth)
|
||||
|
||||
|
@ -74,14 +74,10 @@ services_name_backend+=(ASC.Data.Backup)
|
||||
services_name_backend+=(ASC.Files.Service)
|
||||
services_name_backend+=(ASC.Notify)
|
||||
services_name_backend+=(ASC.Studio.Notify)
|
||||
services_name_backend+=(ASC.TelegramService)
|
||||
services_name_backend+=(ASC.UrlShortener.Svc)
|
||||
services_name_backend+=(ASC.Web.Api)
|
||||
services_name_backend+=(ASC.Web.Studio)
|
||||
services_name_backend+=(ASC.Data.Backup.BackgroundTasks)
|
||||
services_name_backend+=(ASC.ClearEvents)
|
||||
services_name_backend+=(ASC.Migration)
|
||||
services_name_backend+=(ASC.Webhooks.Service)
|
||||
services_name_backend+=(ASC.ApiSystem)
|
||||
|
||||
# Publish backend services
|
||||
@ -94,7 +90,6 @@ done
|
||||
|
||||
# Array of names backend services in directory common (Nodejs)
|
||||
services_name_backend_nodejs=()
|
||||
services_name_backend_nodejs+=(ASC.UrlShortener)
|
||||
services_name_backend_nodejs+=(ASC.Socket.IO)
|
||||
services_name_backend_nodejs+=(ASC.SsoAuth)
|
||||
|
||||
|
@ -5,12 +5,13 @@
|
||||
DOCKER_IMAGE_PREFIX=${STATUS}docspace
|
||||
DOCKER_TAG=latest
|
||||
CONTAINER_PREFIX=${PRODUCT}-
|
||||
MYSQL_VERSION=8.0.18
|
||||
MYSQL_VERSION=8.0.31
|
||||
MYSQL_IMAGE=mysql:${MYSQL_VERSION}
|
||||
ELK_VERSION=7.13.1
|
||||
SERVICE_PORT=5050
|
||||
DOCUMENT_SERVER_IMAGE_NAME=onlyoffice/4testing-documentserver-ee:latest
|
||||
DOCKERFILE=Dockerfile.app
|
||||
APP_DOTNET_ENV=""
|
||||
|
||||
# zookeeper #
|
||||
ZOO_PORT=2181
|
||||
@ -53,9 +54,6 @@
|
||||
BACKUP_HOST=${CONTAINER_PREFIX}backup
|
||||
BACKUP_BACKGRUOND_TASKS_HOST=${CONTAINER_PREFIX}backup-background-tasks
|
||||
CLEAR_EVENTS_HOST=${CONTAINER_PREFIX}clear-events
|
||||
MIGRATION_HOST=${CONTAINER_PREFIX}migration
|
||||
WEBHOOKS_SERVICE_HOST=${CONTAINER_PREFIX}webhooks-service
|
||||
STORAGE_ENCRYPTION_HOST=${CONTAINER_PREFIX}storage-encryption
|
||||
FILES_HOST=${CONTAINER_PREFIX}files
|
||||
FILES_SERVICES_HOST=${CONTAINER_PREFIX}files-services
|
||||
STORAGE_MIGRATION_HOST=${CONTAINER_PREFIX}storage-migration
|
||||
@ -63,8 +61,6 @@
|
||||
PEOPLE_SERVER_HOST=${CONTAINER_PREFIX}people-server
|
||||
SOCKET_HOST=${CONTAINER_PREFIX}socket
|
||||
STUDIO_NOTIFY_HOST=${CONTAINER_PREFIX}studio-notify
|
||||
TELEGRAM_SERVICE_HOST=${CONTAINER_PREFIX}telegram-service
|
||||
URLSHORTENER_HOST=${CONTAINER_PREFIX}urlshortener
|
||||
API_HOST=${CONTAINER_PREFIX}api
|
||||
STUDIO_HOST=${CONTAINER_PREFIX}studio
|
||||
SSOAUTH_HOST=${CONTAINER_PREFIX}ssoauth
|
||||
@ -78,9 +74,6 @@
|
||||
SERVICE_BACKUP=${BACKUP_HOST}:${SERVICE_PORT}
|
||||
SERVICE_BACKUP_BACKGRUOND_TASKS=${BACKUP_BACKGRUOND_TASKS_HOST}:${SERVICE_PORT}
|
||||
SERVICE_CLEAR_EVENTS=${CLEAR_EVENTS_HOST}:${SERVICE_PORT}
|
||||
SERVICE_MIGRATION=${MIGRATION_HOST}:${SERVICE_PORT}
|
||||
SERVICE_WEBHOOKS_SERVICE=${WEBHOOKS_SERVICE_HOST}:${SERVICE_PORT}
|
||||
SERVICE_STORAGE_ENCRYPTION=${STORAGE_ENCRYPTION_HOST}:${SERVICE_PORT}
|
||||
SERVICE_FILES=${FILES_HOST}:${SERVICE_PORT}
|
||||
SERVICE_FILES_SERVICES=${FILES_SERVICES_HOST}:${SERVICE_PORT}
|
||||
SERVICE_STORAGE_MIGRATION=${STORAGE_MIGRATION_HOST}:${SERVICE_PORT}
|
||||
@ -88,8 +81,6 @@
|
||||
SERVICE_PEOPLE_SERVER=${PEOPLE_SERVER_HOST}:${SERVICE_PORT}
|
||||
SERVICE_SOCKET=${SOCKET_HOST}:${SERVICE_PORT}
|
||||
SERVICE_STUDIO_NOTIFY=${STUDIO_NOTIFY_HOST}:${SERVICE_PORT}
|
||||
SERVICE_TELEGRAM_SERVICE=${TELEGRAM_SERVICE_HOST}:${SERVICE_PORT}
|
||||
SERVICE_URLSHORTENER=${URLSHORTENER_HOST}:${SERVICE_PORT}
|
||||
SERVICE_API=${API_HOST}:${SERVICE_PORT}
|
||||
SERVICE_STUDIO=${STUDIO_HOST}:${SERVICE_PORT}
|
||||
SERVICE_SSOAUTH=${SSOAUTH_HOST}:${SERVICE_PORT}
|
||||
|
@ -140,8 +140,8 @@ RUN cd /app/onlyoffice/src/ && \
|
||||
cp -f config/nginx/onlyoffice*.conf /etc/nginx/conf.d/ && \
|
||||
mkdir -p /etc/nginx/includes/ && cp -f config/nginx/includes/onlyoffice*.conf /etc/nginx/includes/ && \
|
||||
sed -e 's/#//' -i /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
dotnet restore ASC.Web.sln && \
|
||||
dotnet build -r linux-x64 ASC.Web.sln && \
|
||||
dotnet restore ASC.Web.slnf && \
|
||||
dotnet build -r linux-x64 ASC.Web.slnf && \
|
||||
cd products/ASC.People/Server && \
|
||||
dotnet -d publish --no-build --self-contained -r linux-x64 -o /var/www/products/ASC.People/server && \
|
||||
cd ../../../ && \
|
||||
|
@ -30,7 +30,7 @@ RUN apt-get -y update && \
|
||||
npm && \
|
||||
locale-gen en_US.UTF-8 && \
|
||||
npm install --global yarn && \
|
||||
curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash - && \
|
||||
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - && \
|
||||
apt-get install -y nodejs && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
@ -93,7 +93,7 @@ COPY --from=base --chown=onlyoffice:onlyoffice /app/onlyoffice/config/* /app/onl
|
||||
EXPOSE 5050
|
||||
ENTRYPOINT ["python3", "docker-entrypoint.py"]
|
||||
|
||||
FROM node:16.16-slim as noderun
|
||||
FROM node:18.12.1-slim as noderun
|
||||
ARG BUILD_PATH
|
||||
ARG SRC_PATH
|
||||
ENV BUILD_PATH=${BUILD_PATH}
|
||||
@ -150,18 +150,12 @@ RUN chown nginx:nginx /etc/nginx/* -R && \
|
||||
# changes for upstream configure
|
||||
sed -i 's/127.0.0.1:5010/$service_api_system/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:5012/$service_backup/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:5021/$service_crm/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:5007/$service_files/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:5004/$service_people_server/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:5020/$service_projects_server/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:5000/$service_api/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:5003/$service_studio/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:5023/$service_calendar/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:9899/$service_socket/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:9834/$service_sso/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:5022/$service_mail/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:9999/$service_urlshortener/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:5034/$service_migration/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:5013/$service_doceditor/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:5011/$service_login/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/$public_root/\/var\/www\/public\//' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
@ -169,17 +163,21 @@ RUN chown nginx:nginx /etc/nginx/* -R && \
|
||||
|
||||
## Doceditor ##
|
||||
FROM noderun as doceditor
|
||||
WORKDIR ${BUILD_PATH}/products/ASC.Files/editor
|
||||
WORKDIR ${BUILD_PATH}/products/ASC.Editors/editor
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice ${SRC_PATH}/build/deploy/editor/ .
|
||||
ENTRYPOINT ["node", "server.js"]
|
||||
|
||||
CMD ["server.js", "ASC.Editors"]
|
||||
|
||||
## Login ##
|
||||
FROM noderun as login
|
||||
WORKDIR ${BUILD_PATH}/products/ASC.Login/login
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice ${SRC_PATH}/build/deploy/login/ .
|
||||
ENTRYPOINT ["node", "server.js"]
|
||||
|
||||
CMD ["server.js", "ASC.Login"]
|
||||
|
||||
## ASC.Data.Backup.BackgroundTasks ##
|
||||
FROM dotnetrun AS backup_background
|
||||
@ -208,15 +206,6 @@ COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.ClearE
|
||||
|
||||
CMD ["ASC.ClearEvents.dll", "ASC.ClearEvents"]
|
||||
|
||||
## ASC.Migration ##
|
||||
FROM dotnetrun AS migration
|
||||
WORKDIR ${BUILD_PATH}/services/ASC.Migration/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Migration/service/ .
|
||||
|
||||
CMD ["ASC.Migration.dll", "ASC.Migration"]
|
||||
|
||||
## ASC.Data.Backup ##
|
||||
FROM dotnetrun AS backup
|
||||
WORKDIR ${BUILD_PATH}/services/ASC.Data.Backup/
|
||||
@ -289,24 +278,6 @@ COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Studio
|
||||
|
||||
CMD ["ASC.Studio.Notify.dll", "ASC.Studio.Notify"]
|
||||
|
||||
## ASC.TelegramService ##
|
||||
FROM dotnetrun AS telegram_service
|
||||
WORKDIR ${BUILD_PATH}/services/ASC.TelegramService/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.TelegramService/service/ .
|
||||
|
||||
CMD ["ASC.TelegramService.dll", "ASC.TelegramService"]
|
||||
|
||||
## ASC.UrlShortener ##
|
||||
FROM noderun AS urlshortener
|
||||
WORKDIR ${BUILD_PATH}/services/ASC.UrlShortener/service/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.UrlShortener/service/ .
|
||||
|
||||
CMD ["index.js", "ASC.UrlShortener"]
|
||||
|
||||
## ASC.Web.Api ##
|
||||
FROM dotnetrun AS api
|
||||
WORKDIR ${BUILD_PATH}/studio/ASC.Web.Api/
|
||||
@ -316,15 +287,6 @@ COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Web.Ap
|
||||
|
||||
CMD ["ASC.Web.Api.dll", "ASC.Web.Api"]
|
||||
|
||||
## ASC.Webhooks.Service ##
|
||||
FROM dotnetrun AS webhooks-service
|
||||
WORKDIR ${BUILD_PATH}/services/ASC.Webhooks.Service/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Webhooks.Service/service/ .
|
||||
|
||||
CMD ["ASC.Webhooks.Service.dll", "ASC.Webhooks.Service"]
|
||||
|
||||
## ASC.Web.Studio ##
|
||||
FROM dotnetrun AS studio
|
||||
WORKDIR ${BUILD_PATH}/studio/ASC.Web.Studio/
|
||||
|
@ -30,7 +30,7 @@ RUN apt-get -y update && \
|
||||
npm && \
|
||||
locale-gen en_US.UTF-8 && \
|
||||
npm install --global yarn && \
|
||||
curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash - && \
|
||||
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - && \
|
||||
apt-get install -y nodejs && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
@ -91,7 +91,7 @@ COPY --from=base --chown=onlyoffice:onlyoffice /app/onlyoffice/config/* /app/onl
|
||||
EXPOSE 5050
|
||||
ENTRYPOINT ["python3", "docker-entrypoint.py"]
|
||||
|
||||
FROM node:16.16-slim as noderun
|
||||
FROM node:18.12.1-slim as noderun
|
||||
ARG BUILD_PATH
|
||||
ARG SRC_PATH
|
||||
ENV BUILD_PATH=${BUILD_PATH}
|
||||
@ -130,6 +130,7 @@ ENV DNS_NAMESERVER=127.0.0.11 \
|
||||
|
||||
RUN apt-get -y update && \
|
||||
apt-get install -yq vim && \
|
||||
apt-get install -y dos2unix && \
|
||||
rm -rf /var/lib/apt/lists/* && \
|
||||
rm -rf /usr/share/nginx/html/*
|
||||
|
||||
@ -138,13 +139,18 @@ COPY --from=base /etc/nginx/conf.d /etc/nginx/conf.d
|
||||
COPY --from=base /etc/nginx/includes /etc/nginx/includes
|
||||
COPY /config/nginx/templates/upstream.conf.template /etc/nginx/templates/upstream.conf.template
|
||||
COPY /config/nginx/templates/nginx.conf.template /etc/nginx/nginx.conf.template
|
||||
|
||||
COPY prepare-nginx-proxy.sh /docker-entrypoint.d/prepare-nginx-proxy.sh
|
||||
|
||||
RUN dos2unix /docker-entrypoint.d/prepare-nginx-proxy.sh && \
|
||||
apt-get --purge remove -y dos2unix && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# add defualt user and group for no-root run
|
||||
RUN chown nginx:nginx /etc/nginx/* -R && \
|
||||
chown nginx:nginx /docker-entrypoint.d/* && \
|
||||
# changes for upstream configure
|
||||
sed -i 's/127.0.0.1:5010/$service_api_system/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
# sed -i 's/127.0.0.1:5010/$service_api_system/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:5012/$service_backup/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:5007/$service_files/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:5004/$service_people_server/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
@ -152,8 +158,8 @@ RUN chown nginx:nginx /etc/nginx/* -R && \
|
||||
sed -i 's/127.0.0.1:5003/$service_studio/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:9899/$service_socket/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:9834/$service_sso/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:9999/$service_urlshortener/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:5034/$service_migration/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
# sed -i 's/127.0.0.1:9999/$service_urlshortener/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
# sed -i 's/127.0.0.1:5034/$service_migration/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:5013/$service_doceditor/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:5011/$service_login/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
sed -i 's/127.0.0.1:5001/$service_client/' /etc/nginx/conf.d/onlyoffice.conf && \
|
||||
@ -164,36 +170,36 @@ FROM dotnetrun AS backup_background
|
||||
WORKDIR ${BUILD_PATH}/services/ASC.Data.Backup.BackgroundTasks/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Data.Backup.BackgroundTasks/service/ .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Data.Backup.BackgroundTasks/service/ .
|
||||
|
||||
CMD ["ASC.Data.Backup.BackgroundTasks.dll", "ASC.Data.Backup.BackgroundTasks"]
|
||||
|
||||
# ASC.ApiSystem ##
|
||||
FROM dotnetrun AS api_system
|
||||
WORKDIR ${BUILD_PATH}/services/ASC.ApiSystem/
|
||||
# FROM dotnetrun AS api_system
|
||||
# WORKDIR ${BUILD_PATH}/services/ASC.ApiSystem/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.ApiSystem/service/ .
|
||||
# COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||
# COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.ApiSystem/service/ .
|
||||
|
||||
CMD [" ASC.ApiSystem.dll", " ASC.ApiSystem"]
|
||||
# CMD ["ASC.ApiSystem.dll", "ASC.ApiSystem"]
|
||||
|
||||
## ASC.ClearEvents ##
|
||||
FROM dotnetrun AS clear-events
|
||||
WORKDIR ${BUILD_PATH}/services/ASC.ClearEvents/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.ClearEvents/service/ .
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.ClearEvents/service/ .
|
||||
|
||||
CMD ["ASC.ClearEvents.dll", "ASC.ClearEvents"]
|
||||
|
||||
## ASC.Migration ##
|
||||
FROM dotnetrun AS migration
|
||||
WORKDIR ${BUILD_PATH}/services/ASC.Migration/
|
||||
# FROM dotnetrun AS migration
|
||||
# WORKDIR ${BUILD_PATH}/services/ASC.Migration/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Migration/service/ .
|
||||
# COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||
# COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Migration/service/ .
|
||||
|
||||
CMD ["ASC.Migration.dll", "ASC.Migration"]
|
||||
# CMD ["ASC.Migration.dll", "ASC.Migration"]
|
||||
|
||||
## ASC.Data.Backup ##
|
||||
FROM dotnetrun AS backup
|
||||
@ -223,13 +229,13 @@ COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Files.
|
||||
CMD ["ASC.Files.Service.dll", "ASC.Files.Service"]
|
||||
|
||||
## ASC.Notify ##
|
||||
FROM dotnetrun AS notify
|
||||
WORKDIR ${BUILD_PATH}/services/ASC.Notify/service
|
||||
# FROM dotnetrun AS notify
|
||||
# WORKDIR ${BUILD_PATH}/services/ASC.Notify/service
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Notify/service/ .
|
||||
# COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||
# COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Notify/service/ .
|
||||
|
||||
CMD ["ASC.Notify.dll", "ASC.Notify"]
|
||||
# CMD ["ASC.Notify.dll", "ASC.Notify"]
|
||||
|
||||
## ASC.People ##
|
||||
FROM dotnetrun AS people_server
|
||||
@ -268,22 +274,22 @@ COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Studio
|
||||
CMD ["ASC.Studio.Notify.dll", "ASC.Studio.Notify"]
|
||||
|
||||
## ASC.TelegramService ##
|
||||
FROM dotnetrun AS telegram_service
|
||||
WORKDIR ${BUILD_PATH}/services/ASC.TelegramService/
|
||||
# FROM dotnetrun AS telegram_service
|
||||
# WORKDIR ${BUILD_PATH}/services/ASC.TelegramService/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.TelegramService/service/ .
|
||||
# COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||
# COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.TelegramService/service/ .
|
||||
|
||||
CMD ["ASC.TelegramService.dll", "ASC.TelegramService"]
|
||||
# CMD ["ASC.TelegramService.dll", "ASC.TelegramService"]
|
||||
|
||||
## ASC.UrlShortener ##
|
||||
FROM noderun AS urlshortener
|
||||
WORKDIR ${BUILD_PATH}/services/ASC.UrlShortener/service/
|
||||
# FROM noderun AS urlshortener
|
||||
# WORKDIR ${BUILD_PATH}/services/ASC.UrlShortener/service/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.UrlShortener/service/ .
|
||||
# COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||
# COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.UrlShortener/service/ .
|
||||
|
||||
CMD ["index.js", "ASC.UrlShortener"]
|
||||
# CMD ["index.js", "ASC.UrlShortener"]
|
||||
|
||||
## ASC.Web.Api ##
|
||||
FROM dotnetrun AS api
|
||||
@ -295,13 +301,13 @@ COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Web.Ap
|
||||
CMD ["ASC.Web.Api.dll", "ASC.Web.Api"]
|
||||
|
||||
## ASC.Webhooks.Service ##
|
||||
FROM dotnetrun AS webhooks-service
|
||||
WORKDIR ${BUILD_PATH}/services/ASC.Webhooks.Service/
|
||||
# FROM dotnetrun AS webhooks-service
|
||||
# WORKDIR ${BUILD_PATH}/services/ASC.Webhooks.Service/
|
||||
|
||||
COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||
COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Webhooks.Service/service/ .
|
||||
# COPY --chown=onlyoffice:onlyoffice docker-entrypoint.py ./docker-entrypoint.py
|
||||
# COPY --from=base --chown=onlyoffice:onlyoffice ${BUILD_PATH}/services/ASC.Webhooks.Service/service/ .
|
||||
|
||||
CMD ["ASC.Webhooks.Service.dll", "ASC.Webhooks.Service"]
|
||||
# CMD ["ASC.Webhooks.Service.dll", "ASC.Webhooks.Service"]
|
||||
|
||||
## ASC.Web.Studio ##
|
||||
FROM dotnetrun AS studio
|
||||
@ -319,26 +325,16 @@ ARG SRC_PATH
|
||||
ENV BUILD_PATH=${BUILD_PATH}
|
||||
ENV SRC_PATH=${SRC_PATH}
|
||||
WORKDIR ${BUILD_PATH}/services/ASC.Migration.Runner/
|
||||
COPY ./docker-migration-entrypoint.sh ./docker-migration-entrypoint.sh
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y dos2unix
|
||||
|
||||
COPY docker-migration-entrypoint.sh docker-migration-entrypoint.sh
|
||||
|
||||
RUN dos2unix docker-migration-entrypoint.sh && \
|
||||
apt-get --purge remove -y dos2unix && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY --from=base ${SRC_PATH}/ASC.Migration.Runner/service/ .
|
||||
|
||||
ENTRYPOINT ["./docker-migration-entrypoint.sh"]
|
||||
|
||||
## image for k8s bin-share ##
|
||||
FROM busybox:latest AS bin_share
|
||||
RUN mkdir -p /app/appserver/ASC.Files/server && \
|
||||
mkdir -p /app/appserver/ASC.People/server/ && \
|
||||
addgroup --system --gid 107 onlyoffice && \
|
||||
adduser -u 104 onlyoffice --home /var/www/onlyoffice --system -G onlyoffice
|
||||
|
||||
COPY bin-share-docker-entrypoint.sh /app/docker-entrypoint.sh
|
||||
COPY --from=base /var/www/products/ASC.Files/server/ /app/appserver/ASC.Files/server/
|
||||
COPY --from=base /var/www/products/ASC.People/server/ /app/appserver/ASC.People/server/
|
||||
ENTRYPOINT ["./app/docker-entrypoint.sh"]
|
||||
|
||||
## image for k8s wait-bin-share ##
|
||||
FROM busybox:latest AS wait_bin_share
|
||||
RUN mkdir /app
|
||||
|
||||
COPY wait-bin-share-docker-entrypoint.sh /app/docker-entrypoint.sh
|
||||
ENTRYPOINT ["./app/docker-entrypoint.sh"]
|
||||
|
@ -1,34 +1,33 @@
|
||||
version: "3.8"
|
||||
x-service:
|
||||
&x-service-base
|
||||
container_name: base
|
||||
restart: always
|
||||
expose:
|
||||
x-service: &x-service-base
|
||||
container_name: base
|
||||
restart: always
|
||||
expose:
|
||||
- ${SERVICE_PORT}
|
||||
environment:
|
||||
MYSQL_HOST: ${MYSQL_HOST}
|
||||
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
|
||||
MYSQL_DATABASE: ${MYSQL_DATABASE}
|
||||
MYSQL_USER: ${MYSQL_USER}
|
||||
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
|
||||
DATABASE_MIGRATION: ${DATABASE_MIGRATION}
|
||||
APP_DOTNET_ENV: ${APP_DOTNET_ENV}
|
||||
APP_CORE_BASE_DOMAIN: ${APP_CORE_BASE_DOMAIN}
|
||||
APP_CORE_MACHINEKEY: ${APP_CORE_MACHINEKEY}
|
||||
DOCUMENT_SERVER_JWT_SECRET: ${DOCUMENT_SERVER_JWT_SECRET}
|
||||
DOCUMENT_SERVER_JWT_HEADER: ${DOCUMENT_SERVER_JWT_HEADER}
|
||||
DOCUMENT_SERVER_URL_PUBLIC: ${DOCUMENT_SERVER_URL_PUBLIC}
|
||||
DOCUMENT_SERVER_URL_INTERNAL: ${DOCUMENT_SERVER_URL_INTERNAL}
|
||||
KAFKA_HOST: ${KAFKA_HOST}
|
||||
ELK_HOST: ${ELK_HOST}
|
||||
PROXY_HOST: ${PROXY_HOST}
|
||||
volumes:
|
||||
environment:
|
||||
MYSQL_HOST: ${MYSQL_HOST}
|
||||
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
|
||||
MYSQL_DATABASE: ${MYSQL_DATABASE}
|
||||
MYSQL_USER: ${MYSQL_USER}
|
||||
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
|
||||
DATABASE_MIGRATION: ${DATABASE_MIGRATION}
|
||||
APP_DOTNET_ENV: ${APP_DOTNET_ENV}
|
||||
APP_CORE_BASE_DOMAIN: ${APP_CORE_BASE_DOMAIN}
|
||||
APP_CORE_MACHINEKEY: ${APP_CORE_MACHINEKEY}
|
||||
DOCUMENT_SERVER_JWT_SECRET: ${DOCUMENT_SERVER_JWT_SECRET}
|
||||
DOCUMENT_SERVER_JWT_HEADER: ${DOCUMENT_SERVER_JWT_HEADER}
|
||||
DOCUMENT_SERVER_URL_PUBLIC: ${DOCUMENT_SERVER_URL_PUBLIC}
|
||||
DOCUMENT_SERVER_URL_INTERNAL: ${DOCUMENT_SERVER_URL_INTERNAL}
|
||||
KAFKA_HOST: ${KAFKA_HOST}
|
||||
ELK_HOST: ${ELK_HOST}
|
||||
PROXY_HOST: ${PROXY_HOST}
|
||||
volumes:
|
||||
#- /app/onlyoffice/CommunityServer/data:/app/onlyoffice/data
|
||||
- app_data:/app/onlyoffice/data
|
||||
- files_data:/var/www/products/ASC.Files/server/
|
||||
- people_data:/var/www/products/ASC.People/server/
|
||||
|
||||
services:
|
||||
|
||||
services:
|
||||
onlyoffice-elasticsearch:
|
||||
image: docker.elastic.co/elasticsearch/elasticsearch:${ELK_VERSION}
|
||||
container_name: ${ELK_HOST}
|
||||
@ -58,17 +57,12 @@ services:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-backup:${DOCKER_TAG}"
|
||||
container_name: ${BACKUP_HOST}
|
||||
|
||||
|
||||
onlyoffice-clear-events:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-clear-events:${DOCKER_TAG}"
|
||||
container_name: ${CLEAR_EVENTS_HOST}
|
||||
|
||||
onlyoffice-migration:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-migration:${DOCKER_TAG}"
|
||||
container_name: ${MIGRATION_HOST}
|
||||
|
||||
onlyoffice-files:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-files:${DOCKER_TAG}"
|
||||
@ -78,7 +72,7 @@ services:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-files-services:${DOCKER_TAG}"
|
||||
container_name: ${FILES_SERVICES_HOST}
|
||||
|
||||
|
||||
onlyoffice-people-server:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-people-server:${DOCKER_TAG}"
|
||||
@ -89,26 +83,13 @@ services:
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-socket:${DOCKER_TAG}"
|
||||
container_name: ${SOCKET_HOST}
|
||||
expose:
|
||||
- ${SERVICE_PORT}
|
||||
|
||||
- ${SERVICE_PORT}
|
||||
|
||||
onlyoffice-studio-notify:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-studio-notify:${DOCKER_TAG}"
|
||||
container_name: ${STUDIO_NOTIFY_HOST}
|
||||
|
||||
onlyoffice-telegram-service:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-telegram-service:${DOCKER_TAG}"
|
||||
container_name: ${TELEGRAM_SERVICE_HOST}
|
||||
|
||||
onlyoffice-urlshortener:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-urlshortener:${DOCKER_TAG}"
|
||||
container_name: ${URLSHORTENER_HOST}
|
||||
expose:
|
||||
- ${SERVICE_PORT}
|
||||
- "9999"
|
||||
|
||||
onlyoffice-api:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-api:${DOCKER_TAG}"
|
||||
@ -123,19 +104,14 @@ services:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-studio:${DOCKER_TAG}"
|
||||
container_name: ${STUDIO_HOST}
|
||||
|
||||
|
||||
onlyoffice-ssoauth:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-ssoauth:${DOCKER_TAG}"
|
||||
container_name: ${SSOAUTH_HOST}
|
||||
expose:
|
||||
- ${SERVICE_PORT}
|
||||
- "9834"
|
||||
|
||||
onlyoffice-webhooks-service:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-webhooks-service:${DOCKER_TAG}"
|
||||
container_name: ${WEBHOOKS_SERVICE_HOST}
|
||||
- ${SERVICE_PORT}
|
||||
- "9834"
|
||||
|
||||
onlyoffice-doceditor:
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-doceditor:${DOCKER_TAG}"
|
||||
@ -160,20 +136,16 @@ services:
|
||||
- "8099"
|
||||
- "8092"
|
||||
ports:
|
||||
- 8092:8092
|
||||
- 8092:8092
|
||||
depends_on:
|
||||
- onlyoffice-backup-background-tasks
|
||||
- onlyoffice-backup
|
||||
- onlyoffice-clear-events
|
||||
- onlyoffice-migration
|
||||
- onlyoffice-webhooks-service
|
||||
- onlyoffice-files
|
||||
- onlyoffice-files-services
|
||||
- onlyoffice-people-server
|
||||
- onlyoffice-socket
|
||||
- onlyoffice-studio-notify
|
||||
- onlyoffice-telegram-service
|
||||
- onlyoffice-urlshortener
|
||||
- onlyoffice-api
|
||||
- onlyoffice-api-system
|
||||
- onlyoffice-studio
|
||||
@ -185,14 +157,10 @@ services:
|
||||
- SERVICE_FILES=${SERVICE_FILES}
|
||||
- SERVICE_FILES_SERVICES=${SERVICE_FILES_SERVICES}
|
||||
- SERVICE_CLEAR_EVENTS=${SERVICE_CLEAR_EVENTS}
|
||||
- SERVICE_MIGRATION=${SERVICE_MIGRATION}
|
||||
- SERVICE_WEBHOOKS_SERVICE=${SERVICE_WEBHOOKS_SERVICE}
|
||||
- SERVICE_NOTIFY=${SERVICE_NOTIFY}
|
||||
- SERVICE_PEOPLE_SERVER=${SERVICE_PEOPLE_SERVER}
|
||||
- SERVICE_SOCKET=${SERVICE_SOCKET}
|
||||
- SERVICE_STUDIO_NOTIFY=${SERVICE_STUDIO_NOTIFY}
|
||||
- SERVICE_TELEGRAM_SERVICE=${SERVICE_TELEGRAM_SERVICE}
|
||||
- SERVICE_URLSHORTENER=${SERVICE_URLSHORTENER}
|
||||
- SERVICE_API=${SERVICE_API}
|
||||
- SERVICE_API_SYSTEM=${SERVICE_API_SYSTEM}
|
||||
- SERVICE_STUDIO=${SERVICE_STUDIO}
|
||||
@ -206,8 +174,8 @@ services:
|
||||
|
||||
networks:
|
||||
default:
|
||||
external:
|
||||
name: ${NETWORK_NAME}
|
||||
name: ${NETWORK_NAME}
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
es_data:
|
||||
|
@ -15,12 +15,12 @@ services:
|
||||
target: clear-events
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-clear-events:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-migration:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: migration
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-migration:${DOCKER_TAG}"
|
||||
# onlyoffice-migration:
|
||||
# build:
|
||||
# context: ./
|
||||
# dockerfile: "${DOCKERFILE}"
|
||||
# target: migration
|
||||
# image: "${REPO}/${DOCKER_IMAGE_PREFIX}-migration:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-backup:
|
||||
build:
|
||||
@ -43,12 +43,12 @@ services:
|
||||
target: files_services
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-files-services:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-notify:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: notify
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-notify:${DOCKER_TAG}"
|
||||
# onlyoffice-notify:
|
||||
# build:
|
||||
# context: ./
|
||||
# dockerfile: "${DOCKERFILE}"
|
||||
# target: notify
|
||||
# image: "${REPO}/${DOCKER_IMAGE_PREFIX}-notify:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-people-server:
|
||||
build:
|
||||
@ -71,19 +71,19 @@ services:
|
||||
target: studio_notify
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-studio-notify:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-telegram-service:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: telegram_service
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-telegram-service:${DOCKER_TAG}"
|
||||
# onlyoffice-telegram-service:
|
||||
# build:
|
||||
# context: ./
|
||||
# dockerfile: "${DOCKERFILE}"
|
||||
# target: telegram_service
|
||||
# image: "${REPO}/${DOCKER_IMAGE_PREFIX}-telegram-service:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-urlshortener:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: urlshortener
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-urlshortener:${DOCKER_TAG}"
|
||||
# onlyoffice-urlshortener:
|
||||
# build:
|
||||
# context: ./
|
||||
# dockerfile: "${DOCKERFILE}"
|
||||
# target: urlshortener
|
||||
# image: "${REPO}/${DOCKER_IMAGE_PREFIX}-urlshortener:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-api:
|
||||
build:
|
||||
@ -92,12 +92,12 @@ services:
|
||||
target: api
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-api:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-api-system:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: api_system
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-api-system:${DOCKER_TAG}"
|
||||
# onlyoffice-api-system:
|
||||
# build:
|
||||
# context: ./
|
||||
# dockerfile: "${DOCKERFILE}"
|
||||
# target: api_system
|
||||
# image: "${REPO}/${DOCKER_IMAGE_PREFIX}-api-system:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-studio:
|
||||
build:
|
||||
@ -113,26 +113,12 @@ services:
|
||||
target: ssoauth
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-ssoauth:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-webhooks-service:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: webhooks-service
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-webhooks-service:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-bin-share:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: bin_share
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-bin-share:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-wait-bin-share:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: wait_bin_share
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-wait-bin-share:${DOCKER_TAG}"
|
||||
# onlyoffice-webhooks-service:
|
||||
# build:
|
||||
# context: ./
|
||||
# dockerfile: "${DOCKERFILE}"
|
||||
# target: webhooks-service
|
||||
# image: "${REPO}/${DOCKER_IMAGE_PREFIX}-webhooks-service:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-proxy:
|
||||
build:
|
||||
|
@ -15,13 +15,6 @@ services:
|
||||
target: clear-events
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-clear-events:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-migration:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: migration
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-migration:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-backup:
|
||||
build:
|
||||
context: ./
|
||||
@ -71,20 +64,6 @@ services:
|
||||
target: studio_notify
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-studio-notify:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-telegram-service:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: telegram_service
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-telegram-service:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-urlshortener:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: urlshortener
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-urlshortener:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-api:
|
||||
build:
|
||||
context: ./
|
||||
@ -113,13 +92,6 @@ services:
|
||||
target: ssoauth
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-ssoauth:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-webhooks-service:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: "${DOCKERFILE}"
|
||||
target: webhooks-service
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-webhooks-service:${DOCKER_TAG}"
|
||||
|
||||
onlyoffice-bin-share:
|
||||
build:
|
||||
context: ./
|
||||
|
@ -15,11 +15,6 @@ map $SERVICE_CLIENT $service_client {
|
||||
$SERVICE_CLIENT $SERVICE_CLIENT;
|
||||
}
|
||||
|
||||
map $SERVICE_MIGRATION $service_migration {
|
||||
volatile;
|
||||
$SERVICE_MIGRATION $SERVICE_MIGRATION;
|
||||
}
|
||||
|
||||
map $SERVICE_API_SYSTEM $service_api_system {
|
||||
volatile;
|
||||
$SERVICE_API_SYSTEM $SERVICE_API_SYSTEM;
|
||||
@ -30,21 +25,6 @@ map $SERVICE_BACKUP $service_backup {
|
||||
$SERVICE_BACKUP $SERVICE_BACKUP;
|
||||
}
|
||||
|
||||
map $SERVICE_CALENDAR $service_calendar {
|
||||
volatile;
|
||||
$SERVICE_CALENDAR $SERVICE_CALENDAR;
|
||||
}
|
||||
|
||||
map $SERVICE_CRM $service_crm {
|
||||
volatile;
|
||||
$SERVICE_CRM $SERVICE_CRM;
|
||||
}
|
||||
|
||||
map $SERVICE_STORAGE_ENCRYPTION $service_storage_encryption {
|
||||
volatile;
|
||||
$SERVICE_STORAGE_ENCRYPTION $SERVICE_STORAGE_ENCRYPTION;
|
||||
}
|
||||
|
||||
map $SERVICE_FILES $service_files {
|
||||
volatile;
|
||||
$SERVICE_FILES $SERVICE_FILES;
|
||||
@ -55,16 +35,6 @@ map $SERVICE_FILES_SERVICES $service_files_services {
|
||||
$SERVICE_FILES_SERVICES $SERVICE_FILES_SERVICES;
|
||||
}
|
||||
|
||||
map $SERVICE_MAIL $service_mail {
|
||||
volatile;
|
||||
$SERVICE_MAIL $SERVICE_MAIL;
|
||||
}
|
||||
|
||||
map $SERVICE_STORAGE_MIGRATION $service_storage_migration {
|
||||
volatile;
|
||||
$SERVICE_STORAGE_MIGRATION $SERVICE_STORAGE_MIGRATION;
|
||||
}
|
||||
|
||||
map $SERVICE_NOTIFY $service_notify {
|
||||
volatile;
|
||||
$SERVICE_NOTIFY $SERVICE_NOTIFY;
|
||||
@ -75,11 +45,6 @@ map $SERVICE_PEOPLE_SERVER $service_people_server {
|
||||
$SERVICE_PEOPLE_SERVER $SERVICE_PEOPLE_SERVER;
|
||||
}
|
||||
|
||||
map $SERVICE_PROJECTS_SERVER $service_projects_server {
|
||||
volatile;
|
||||
$SERVICE_PROJECTS_SERVER $SERVICE_PROJECTS_SERVER;
|
||||
}
|
||||
|
||||
map $SERVICE_SOCKET $service_socket {
|
||||
volatile;
|
||||
$SERVICE_SOCKET $SERVICE_SOCKET;
|
||||
@ -90,21 +55,11 @@ map $SERVICE_STUDIO_NOTIFY $service_studio_notify {
|
||||
$SERVICE_STUDIO_NOTIFY $SERVICE_STUDIO_NOTIFY;
|
||||
}
|
||||
|
||||
map $SERVICE_TELEGRAM_SERVICE $service_telegram_service {
|
||||
volatile;
|
||||
$SERVICE_TELEGRAM_SERVICE $SERVICE_TELEGRAM_SERVICE;
|
||||
}
|
||||
|
||||
map $SERVICE_THUMBNAILS $service_thumbnails {
|
||||
volatile;
|
||||
$SERVICE_THUMBNAILS $SERVICE_THUMBNAILS;
|
||||
}
|
||||
|
||||
map $SERVICE_URLSHORTENER $service_urlshortener {
|
||||
volatile;
|
||||
$SERVICE_URLSHORTENER $SERVICE_URLSHORTENER;
|
||||
}
|
||||
|
||||
map $SERVICE_API $service_api {
|
||||
volatile;
|
||||
$SERVICE_API $SERVICE_API;
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -21,7 +21,6 @@ MYSQL_HOST = os.environ["MYSQL_HOST"] if environ.get("MYSQL_HOST") else "localho
|
||||
MYSQL_DATABASE = os.environ["MYSQL_DATABASE"] if environ.get("MYSQL_DATABASE") else "onlyoffice"
|
||||
MYSQL_USER = os.environ["MYSQL_USER"] if environ.get("MYSQL_USER") else "onlyoffice_user"
|
||||
MYSQL_PASSWORD = os.environ["MYSQL_PASSWORD"] if environ.get("MYSQL_PASSWORD") else "onlyoffice_pass"
|
||||
DATABASE_MIGRATION = os.environ["DATABASE_MIGRATION"] if environ.get("DATABASE_MIGRATION") else "false"
|
||||
|
||||
APP_CORE_BASE_DOMAIN = os.environ["APP_CORE_BASE_DOMAIN"] if environ.get("APP_CORE_BASE_DOMAIN") is not None else "localhost"
|
||||
APP_CORE_MACHINEKEY = os.environ["APP_CORE_MACHINEKEY"] if environ.get("APP_CORE_MACHINEKEY") else "your_core_machinekey"
|
||||
@ -128,13 +127,11 @@ updateJsonData(jsonData,"$.core.base-domain", APP_CORE_BASE_DOMAIN)
|
||||
updateJsonData(jsonData,"$.core.machinekey", APP_CORE_MACHINEKEY)
|
||||
updateJsonData(jsonData,"$.core.products.subfolder", "server")
|
||||
updateJsonData(jsonData,"$.web.hub.internal", "http://onlyoffice-socket:" + SERVICE_PORT + "/")
|
||||
updateJsonData(jsonData,"$.web.url-shortener.internal", "http://onlyoffice-urlshortener:" + SERVICE_PORT + "/")
|
||||
updateJsonData(jsonData,"$.files.docservice.url.portal", APP_URL_PORTAL)
|
||||
updateJsonData(jsonData,"$.files.docservice.url.public", DOCUMENT_SERVER_URL_PUBLIC)
|
||||
updateJsonData(jsonData,"$.files.docservice.url.internal", DOCUMENT_SERVER_URL_INTERNAL)
|
||||
updateJsonData(jsonData,"$.files.docservice.secret.value", DOCUMENT_SERVER_JWT_SECRET)
|
||||
updateJsonData(jsonData,"$.files.docservice.secret.header", DOCUMENT_SERVER_JWT_HEADER)
|
||||
updateJsonData(jsonData,"$.migration.enabled", DATABASE_MIGRATION)
|
||||
writeJsonFile(filePath, jsonData)
|
||||
|
||||
filePath = "/app/onlyoffice/config/elastic.json"
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/bin/bash
|
||||
|
||||
MYSQL_HOST=${MYSQL_HOST:-"localhost"}
|
||||
MYSQL_DATABASE=${MYSQL_DATABASE:-"onlyoffice"}
|
||||
@ -7,4 +7,4 @@ MYSQL_PASSWORD=${MYSQL_PASSWORD:-"onlyoffice_pass"}
|
||||
|
||||
sed -i "s!\"ConnectionString\".*!\"ConnectionString\": \"Server=${MYSQL_HOST};Database=${MYSQL_DATABASE};User ID=${MYSQL_USER};Password=${MYSQL_PASSWORD}\",!g" ./appsettings.json
|
||||
|
||||
dotnet ASC.Migration.Runner.dll
|
||||
dotnet ASC.Migration.Runner.dll
|
@ -66,10 +66,10 @@ services:
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-clear-events:${DOCKER_TAG}"
|
||||
container_name: ${CLEAR_EVENTS_HOST}
|
||||
|
||||
onlyoffice-migration:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-migration:${DOCKER_TAG}"
|
||||
container_name: ${MIGRATION_HOST}
|
||||
# onlyoffice-migration:
|
||||
# <<: *x-service-base
|
||||
# image: "${REPO}/${DOCKER_IMAGE_PREFIX}-migration:${DOCKER_TAG}"
|
||||
# container_name: ${MIGRATION_HOST}
|
||||
|
||||
onlyoffice-files:
|
||||
<<: *x-service-base
|
||||
@ -98,28 +98,28 @@ services:
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-studio-notify:${DOCKER_TAG}"
|
||||
container_name: ${STUDIO_NOTIFY_HOST}
|
||||
|
||||
onlyoffice-telegram-service:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-telegram-service:${DOCKER_TAG}"
|
||||
container_name: ${TELEGRAM_SERVICE_HOST}
|
||||
# onlyoffice-telegram-service:
|
||||
# <<: *x-service-base
|
||||
# image: "${REPO}/${DOCKER_IMAGE_PREFIX}-telegram-service:${DOCKER_TAG}"
|
||||
# container_name: ${TELEGRAM_SERVICE_HOST}
|
||||
|
||||
onlyoffice-urlshortener:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-urlshortener:${DOCKER_TAG}"
|
||||
container_name: ${URLSHORTENER_HOST}
|
||||
expose:
|
||||
- ${SERVICE_PORT}
|
||||
- "9999"
|
||||
# onlyoffice-urlshortener:
|
||||
# <<: *x-service-base
|
||||
# image: "${REPO}/${DOCKER_IMAGE_PREFIX}-urlshortener:${DOCKER_TAG}"
|
||||
# container_name: ${URLSHORTENER_HOST}
|
||||
# expose:
|
||||
# - ${SERVICE_PORT}
|
||||
# - "9999"
|
||||
|
||||
onlyoffice-api:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-api:${DOCKER_TAG}"
|
||||
container_name: ${API_HOST}
|
||||
|
||||
onlyoffice-api-system:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-api-system:${DOCKER_TAG}"
|
||||
container_name: ${API_SYSTEM_HOST}
|
||||
# onlyoffice-api-system:
|
||||
# <<: *x-service-base
|
||||
# image: "${REPO}/${DOCKER_IMAGE_PREFIX}-api-system:${DOCKER_TAG}"
|
||||
# container_name: ${API_SYSTEM_HOST}
|
||||
|
||||
onlyoffice-studio:
|
||||
<<: *x-service-base
|
||||
@ -134,10 +134,10 @@ services:
|
||||
- ${SERVICE_PORT}
|
||||
- "9834"
|
||||
|
||||
onlyoffice-webhooks-service:
|
||||
<<: *x-service-base
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-webhooks-service:${DOCKER_TAG}"
|
||||
container_name: ${WEBHOOKS_SERVICE_HOST}
|
||||
# onlyoffice-webhooks-service:
|
||||
# <<: *x-service-base
|
||||
# image: "${REPO}/${DOCKER_IMAGE_PREFIX}-webhooks-service:${DOCKER_TAG}"
|
||||
# container_name: ${WEBHOOKS_SERVICE_HOST}
|
||||
|
||||
onlyoffice-proxy:
|
||||
image: "${REPO}/${DOCKER_IMAGE_PREFIX}-proxy:${DOCKER_TAG}"
|
||||
@ -153,17 +153,17 @@ services:
|
||||
- onlyoffice-backup-background-tasks
|
||||
- onlyoffice-backup
|
||||
- onlyoffice-clear-events
|
||||
- onlyoffice-migration
|
||||
- onlyoffice-webhooks-service
|
||||
# - onlyoffice-migration
|
||||
# - webhooks-service
|
||||
- onlyoffice-files
|
||||
- onlyoffice-files-services
|
||||
- onlyoffice-people-server
|
||||
- onlyoffice-socket
|
||||
- onlyoffice-studio-notify
|
||||
- onlyoffice-telegram-service
|
||||
- onlyoffice-urlshortener
|
||||
# - onlyoffice-telegram-service
|
||||
# - onlyoffice-urlshortener
|
||||
- onlyoffice-api
|
||||
- onlyoffice-api-system
|
||||
# - onlyoffice-api-system
|
||||
- onlyoffice-studio
|
||||
- onlyoffice-ssoauth
|
||||
environment:
|
||||
@ -171,14 +171,14 @@ services:
|
||||
- SERVICE_FILES=${SERVICE_FILES}
|
||||
- SERVICE_FILES_SERVICES=${SERVICE_FILES_SERVICES}
|
||||
- SERVICE_CLEAR_EVENTS=${SERVICE_CLEAR_EVENTS}
|
||||
- SERVICE_MIGRATION=${SERVICE_MIGRATION}
|
||||
- SERVICE_WEBHOOKS_SERVICE=${SERVICE_WEBHOOKS_SERVICE}
|
||||
# - SERVICE_MIGRATION=${SERVICE_MIGRATION}
|
||||
# - SERVICE_WEBHOOKS_SERVICE=${SERVICE_WEBHOOKS_SERVICE}
|
||||
- SERVICE_NOTIFY=${SERVICE_NOTIFY}
|
||||
- SERVICE_PEOPLE_SERVER=${SERVICE_PEOPLE_SERVER}
|
||||
- SERVICE_SOCKET=${SERVICE_SOCKET}
|
||||
- SERVICE_STUDIO_NOTIFY=${SERVICE_STUDIO_NOTIFY}
|
||||
- SERVICE_TELEGRAM_SERVICE=${SERVICE_TELEGRAM_SERVICE}
|
||||
- SERVICE_URLSHORTENER=${SERVICE_URLSHORTENER}
|
||||
# - SERVICE_TELEGRAM_SERVICE=${SERVICE_TELEGRAM_SERVICE}
|
||||
# - SERVICE_URLSHORTENER=${SERVICE_URLSHORTENER}
|
||||
- SERVICE_API=${SERVICE_API}
|
||||
- SERVICE_API_SYSTEM=${SERVICE_API_SYSTEM}
|
||||
- SERVICE_STUDIO=${SERVICE_STUDIO}
|
||||
@ -196,8 +196,8 @@ services:
|
||||
|
||||
networks:
|
||||
default:
|
||||
external:
|
||||
name: ${NETWORK_NAME}
|
||||
name: ${NETWORK_NAME}
|
||||
external: true
|
||||
|
||||
volumes:
|
||||
es_data:
|
||||
|
@ -13,5 +13,5 @@ services:
|
||||
|
||||
networks:
|
||||
default:
|
||||
external:
|
||||
name: ${NETWORK_NAME}
|
||||
name: ${NETWORK_NAME}
|
||||
external: true
|
||||
|
@ -1,2 +1,3 @@
|
||||
#!/bin/sh
|
||||
envsubst '$MAP_HASH_BUCKET_SIZE,$COUNT_WORKER_CONNECTIONS' < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf
|
||||
|
||||
envsubst '$MAP_HASH_BUCKET_SIZE,$COUNT_WORKER_CONNECTIONS' < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf
|
@ -1,6 +1,6 @@
|
||||
version: '3'
|
||||
services:
|
||||
onlyoffice-rabbitmq:
|
||||
version: "3"
|
||||
services:
|
||||
onlyoffice-rabbitmq:
|
||||
image: rabbitmq:3
|
||||
container_name: onlyoffice-rabbitmq
|
||||
restart: always
|
||||
@ -9,5 +9,5 @@ services:
|
||||
- "80"
|
||||
networks:
|
||||
default:
|
||||
external:
|
||||
name: ${NETWORK_NAME}
|
||||
name: ${NETWORK_NAME}
|
||||
external: true
|
||||
|
@ -1,6 +1,6 @@
|
||||
version: '3'
|
||||
services:
|
||||
onlyoffice-redis:
|
||||
version: "3"
|
||||
services:
|
||||
onlyoffice-redis:
|
||||
image: redis:7
|
||||
container_name: onlyoffice-redis
|
||||
restart: always
|
||||
@ -8,5 +8,5 @@ services:
|
||||
- "6379"
|
||||
networks:
|
||||
default:
|
||||
external:
|
||||
name: ${NETWORK_NAME}
|
||||
name: ${NETWORK_NAME}
|
||||
external: true
|
||||
|
@ -8,7 +8,7 @@ set SRC_PATH=%~s2
|
||||
|
||||
pushd %~1
|
||||
|
||||
call dotnet build ASC.Web.sln
|
||||
call dotnet build ASC.Web.slnf
|
||||
call dotnet build ASC.Migrations.sln -o %SRC_PATH%\services\ASC.Migration.Runner\service
|
||||
|
||||
echo "== Build ASC.UrlShortener =="
|
||||
|
@ -1,4 +0,0 @@
|
||||
@echo off
|
||||
|
||||
PUSHD %~dp0..\..
|
||||
set servicepath=%cd%\common\services\ASC.Data.Storage.Encryption\bin\Debug\ASC.Data.Storage.Encryption.exe urls=http://0.0.0.0:5019 $STORAGE_ROOT=%cd%\Data log:dir=%cd%\Logs log:name=studio.notify pathToConf=%cd%\config core:products:folder=%cd%\products core:eventBus:subscriptionClientName=asc_event_bus_encryption_queue
|
@ -1,4 +0,0 @@
|
||||
@echo off
|
||||
|
||||
PUSHD %~dp0..\..
|
||||
set servicepath=%cd%\common\ASC.Migration\bin\Debug\ASC.Migration.exe urls=http://0.0.0.0:5034 $STORAGE_ROOT=%cd%\Data pathToConf=%cd%\config log:dir=%cd%\Logs log:name=migration core:products:folder=%cd%\products
|
@ -1,10 +0,0 @@
|
||||
<service>
|
||||
<id>OnlyofficeRadicale</id>
|
||||
<name>ONLYOFFICE Radicale</name>
|
||||
<startmode>manual</startmode>
|
||||
<executable>python</executable>
|
||||
<arguments>-m radicale --config %BASE%/../../config/radicale.config</arguments>
|
||||
<log mode="none"/>
|
||||
<delayedAutoStart>true</delayedAutoStart>
|
||||
<onfailure action="restart" delay="5 sec" />
|
||||
</service>
|
@ -1,4 +0,0 @@
|
||||
@echo off
|
||||
|
||||
PUSHD %~dp0..\..
|
||||
set servicepath=%cd%\common\services\ASC.TelegramService\bin\Debug\ASC.TelegramService.exe urls=http://0.0.0.0:51702 $STORAGE_ROOT=%cd%\Data log:dir=%cd%\Logs log:name=telegram pathToConf=%cd%\config core:eventBus:subscriptionClientName=asc_event_bus_telegram_queue
|
@ -1,10 +0,0 @@
|
||||
<service>
|
||||
<id>OnlyofficeUrlShortenerService</id>
|
||||
<name>ONLYOFFICE UrlShortenerService</name>
|
||||
<startmode>manual</startmode>
|
||||
<executable>node</executable>
|
||||
<arguments>../../common/ASC.UrlShortener/index.js</arguments>
|
||||
<log mode="none"/>
|
||||
<delayedAutoStart>true</delayedAutoStart>
|
||||
<onfailure action="restart" delay="5 sec" />
|
||||
</service>
|
@ -1,4 +0,0 @@
|
||||
@echo off
|
||||
|
||||
PUSHD %~dp0..\..
|
||||
set servicepath=%cd%\common\services\ASC.Webhooks.Service\bin\Debug\ASC.Webhooks.Service.exe urls=http://0.0.0.0:5031 $STORAGE_ROOT=%cd%\Data log:dir=%cd%\Logs log:name=webhooks pathToConf=%cd%\config core:products:folder=%cd%\products
|
@ -3,7 +3,7 @@
|
||||
|
||||
cd /D "%~dp0"
|
||||
call start\stop.bat nopause
|
||||
dotnet build ..\asc.web.sln
|
||||
dotnet build ..\asc.web.slnf
|
||||
dotnet build ..\ASC.Migrations.sln
|
||||
PUSHD %~dp0..\common\Tools\ASC.Migration.Runner\bin\Debug\net6.0
|
||||
dotnet ASC.Migration.Runner.dll
|
||||
|
@ -9,7 +9,7 @@ echo "Run script directory:" $rd
|
||||
dir=$(builtin cd $rd/../; pwd)
|
||||
echo "Root directory:" $dir
|
||||
|
||||
dotnet build $dir/asc.web.sln
|
||||
dotnet build $dir/asc.web.slnf
|
||||
dotnet build $dir/ASC.Migrations.sln
|
||||
|
||||
pushd $dir/common/Tools/ASC.Migration.Runner/bin/Debug/net6.0
|
||||
|
@ -1,7 +0,0 @@
|
||||
PUSHD %~dp0..
|
||||
|
||||
cd %~dp0../../common/ASC.UrlShortener/
|
||||
|
||||
call yarn install --immutable
|
||||
|
||||
POPD
|
7
build/start/restart.backend.docker.bat
Normal file
7
build/start/restart.backend.docker.bat
Normal file
@ -0,0 +1,7 @@
|
||||
@echo off
|
||||
|
||||
pwsh %~dp0/restart.backend.docker.ps1
|
||||
|
||||
echo.
|
||||
|
||||
pause
|
5
build/start/restart.backend.docker.ps1
Normal file
5
build/start/restart.backend.docker.ps1
Normal file
@ -0,0 +1,5 @@
|
||||
# Stop all backend services"
|
||||
& "$PSScriptRoot\stop.backend.docker.ps1"
|
||||
|
||||
# Start all backend services"
|
||||
& "$PSScriptRoot\start.backend.docker.ps1"
|
7
build/start/start.backend.docker.bat
Normal file
7
build/start/start.backend.docker.bat
Normal file
@ -0,0 +1,7 @@
|
||||
@echo off
|
||||
|
||||
pwsh %~dp0/start.backend.docker.ps1
|
||||
|
||||
echo.
|
||||
|
||||
pause
|
41
build/start/start.backend.docker.ps1
Normal file
41
build/start/start.backend.docker.ps1
Normal file
@ -0,0 +1,41 @@
|
||||
$PSversionMajor = $PSVersionTable.PSVersion | sort-object major | ForEach-Object { $_.major }
|
||||
$PSversionMinor = $PSVersionTable.PSVersion | sort-object minor | ForEach-Object { $_.minor }
|
||||
|
||||
if ($PSversionMajor -lt 7 -or $PSversionMinor -lt 2) {
|
||||
Write-Error "Powershell version must be greater than or equal to 7.2."
|
||||
exit
|
||||
}
|
||||
|
||||
$Branch = git branch --show-current
|
||||
$BranchExistRemote = git ls-remote --heads origin $Branch
|
||||
|
||||
if (-not $BranchExistRemote) {
|
||||
Write-Error "The current branch does not exist in the remote repository. Please push changes."
|
||||
exit
|
||||
}
|
||||
|
||||
$RootDir = Split-Path (Split-Path -Parent $PSScriptRoot) -Parent
|
||||
$DockerDir = ($RootDir + "\build\install\docker")
|
||||
$BuildDate = Get-Date -Format "yyyy-MM-dd"
|
||||
$LocalIp = (Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration | Where-Object { $_.DHCPEnabled -ne $null -and $_.DefaultIPGateway -ne $null }).IPAddress | Select-Object -First 1
|
||||
|
||||
$Doceditor = ($LocalIp + ":5013")
|
||||
$Login = ($LocalIp + ":5011")
|
||||
$Client = ($LocalIp + ":5001")
|
||||
|
||||
$DockerFile = "Dockerfile.dev"
|
||||
$EnvExtension = "dev"
|
||||
$CoreBaseDomain = "localhost"
|
||||
|
||||
Write-Host "Start all backend services (containers)" -ForegroundColor Green
|
||||
$Env:DOCKERFILE = $DockerFile
|
||||
$Env:ROOT_DIR = $RootDir
|
||||
$Env:RELEASE_DATE = $BuildDate
|
||||
$Env:GIT_BRANCH = $Branch
|
||||
$Env:SERVICE_DOCEDITOR = $Doceditor
|
||||
$Env:SERVICE_LOGIN = $Login
|
||||
$Env:SERVICE_CLIENT = $Client
|
||||
$Env:APP_CORE_BASE_DOMAIN = $CoreBaseDomain
|
||||
$Env:APP_URL_PORTAL = ("http://" + $LocalIp + ":8092")
|
||||
$Env:ENV_EXTENSION = $EnvExtension
|
||||
docker compose -f ($DockerDir + "\docspace.dev.yml") up -d
|
@ -9,10 +9,17 @@ echo "Root directory:" $dir
|
||||
|
||||
cd $dir
|
||||
|
||||
branch=$(git branch | sed -n -e 's/^\* \(.*\)/\1/p')
|
||||
branch=$(git branch --show-current)
|
||||
|
||||
echo "GIT_BRANCH:" $branch
|
||||
|
||||
branch_exist_remote=$(git ls-remote --heads origin $branch)
|
||||
|
||||
if [ -z "$branch_exist_remote" ]; then
|
||||
echo "The current branch does not exist in the remote repository. Please push changes."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd $dir/build/install/docker/
|
||||
|
||||
docker_dir="$( pwd )"
|
||||
|
7
build/start/stop.backend.docker.bat
Normal file
7
build/start/stop.backend.docker.bat
Normal file
@ -0,0 +1,7 @@
|
||||
@echo off
|
||||
|
||||
pwsh %~dp0/stop.backend.docker.ps1
|
||||
|
||||
echo.
|
||||
|
||||
pause
|
17
build/start/stop.backend.docker.ps1
Normal file
17
build/start/stop.backend.docker.ps1
Normal file
@ -0,0 +1,17 @@
|
||||
$PSversionMajor = $PSVersionTable.PSVersion | sort-object major | ForEach-Object { $_.major }
|
||||
$PSversionMinor = $PSVersionTable.PSVersion | sort-object minor | ForEach-Object { $_.minor }
|
||||
|
||||
if ($PSversionMajor -lt 7 -or $PSversionMinor -lt 2) {
|
||||
Write-Error "Powershell version must be greater than or equal to 7.2."
|
||||
exit
|
||||
}
|
||||
|
||||
$Containers = docker ps -a -f "name=^onlyoffice" --format="{{.ID}} {{.Names}}" | Select-String -Pattern ("mysql|rabbitmq|redis|elasticsearch|documentserver") -NotMatch | ConvertFrom-String | ForEach-Object P1
|
||||
|
||||
if (-not $Containers) {
|
||||
Write-Host "No containers to stop" -ForegroundColor Blue
|
||||
exit
|
||||
}
|
||||
|
||||
Write-Host "Stop all backend services (containers)" -ForegroundColor Green
|
||||
docker stop $Containers
|
@ -364,7 +364,7 @@ public class LdapUserImporter : IDisposable
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool TrySyncUserGroupMembership(Tuple<UserInfo, LdapObject> ldapUserInfo)
|
||||
public async Task<bool> TrySyncUserGroupMembership(Tuple<UserInfo, LdapObject> ldapUserInfo)
|
||||
{
|
||||
if (ldapUserInfo == null ||
|
||||
!Settings.GroupMembership)
|
||||
@ -401,12 +401,12 @@ public class LdapUserImporter : IDisposable
|
||||
groupInfo = UserManager.SaveGroupInfo(_ldapObjectExtension.ToGroupInfo(ldapUserGroup, Settings));
|
||||
|
||||
_logger.DebugTrySyncUserGroupMembershipAddingUserToGroup(userInfo.UserName, ldapUser.Sid, groupInfo.Name, groupInfo.Sid);
|
||||
UserManager.AddUserIntoGroup(userInfo.Id, groupInfo.ID);
|
||||
await UserManager.AddUserIntoGroup(userInfo.Id, groupInfo.ID);
|
||||
}
|
||||
else if (!portalUserLdapGroups.Contains(groupInfo))
|
||||
{
|
||||
_logger.DebugTrySyncUserGroupMembershipAddingUserToGroup(userInfo.UserName, ldapUser.Sid, groupInfo.Name, groupInfo.Sid);
|
||||
UserManager.AddUserIntoGroup(userInfo.Id, groupInfo.ID);
|
||||
await UserManager.AddUserIntoGroup(userInfo.Id, groupInfo.ID);
|
||||
}
|
||||
|
||||
actualPortalLdapGroups.Add(groupInfo);
|
||||
|
@ -136,7 +136,7 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
InitDisturbedTask();
|
||||
}
|
||||
|
||||
protected override void DoJob()
|
||||
protected override async Task DoJob()
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -206,7 +206,7 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
Do();
|
||||
await Do();
|
||||
}
|
||||
catch (AuthorizingException authError)
|
||||
{
|
||||
@ -247,7 +247,7 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
}
|
||||
}
|
||||
|
||||
private void Do()
|
||||
private async Task Do()
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -288,7 +288,7 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
_logger.DebugLdapSettings(sb.ToString());
|
||||
}
|
||||
|
||||
SyncLDAP();
|
||||
await SyncLDAP();
|
||||
|
||||
if (!string.IsNullOrEmpty(Error))
|
||||
{
|
||||
@ -380,7 +380,7 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
|
||||
_logger.DebugSaveUserInfo(existingLDAPUser.GetUserInfoString());
|
||||
|
||||
_userManager.SaveUserInfo(existingLDAPUser);
|
||||
_userManager.UpdateUserInfo(existingLDAPUser);
|
||||
break;
|
||||
case LdapOperationType.SaveTest:
|
||||
case LdapOperationType.SyncTest:
|
||||
@ -394,7 +394,7 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
}
|
||||
}
|
||||
|
||||
private void SyncLDAP()
|
||||
private async Task SyncLDAP()
|
||||
{
|
||||
var currentDomainSettings = _settingsManager.Load<LdapCurrentDomain>();
|
||||
|
||||
@ -408,21 +408,21 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
{
|
||||
_logger.DebugSyncLDAPUsers();
|
||||
|
||||
SyncLDAPUsers();
|
||||
await SyncLDAPUsers();
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.DebugSyncLDAPUsersInGroups();
|
||||
|
||||
SyncLDAPUsersInGroups();
|
||||
await SyncLDAPUsersInGroups();
|
||||
}
|
||||
|
||||
SyncLdapAvatar();
|
||||
await SyncLdapAvatar();
|
||||
|
||||
SyncLdapAccessRights();
|
||||
await SyncLdapAccessRights();
|
||||
}
|
||||
|
||||
private void SyncLdapAvatar()
|
||||
private async Task SyncLdapAvatar()
|
||||
{
|
||||
SetProgress(90, Resource.LdapSettingsStatusUpdatingUserPhotos);
|
||||
|
||||
@ -438,7 +438,7 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
foreach (var guid in ph.CurrentPhotos.Keys)
|
||||
{
|
||||
_logger.InfoSyncLdapAvatarsRemovingPhoto(guid);
|
||||
_userPhotoManager.RemovePhoto(guid);
|
||||
await _userPhotoManager.RemovePhoto(guid);
|
||||
_userPhotoManager.ResetThumbnailSettings(guid);
|
||||
}
|
||||
|
||||
@ -511,16 +511,16 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
_settingsManager.Save(photoSettings);
|
||||
}
|
||||
|
||||
private void SyncLdapAccessRights()
|
||||
private async Task SyncLdapAccessRights()
|
||||
{
|
||||
SetProgress(95, Resource.LdapSettingsStatusUpdatingAccessRights);
|
||||
|
||||
var currentUserRights = new List<LdapSettings.AccessRight>();
|
||||
TakeUsersRights(_currentUser != null ? currentUserRights : null);
|
||||
await TakeUsersRights(_currentUser != null ? currentUserRights : null);
|
||||
|
||||
if (LDAPSettings.GroupMembership && LDAPSettings.AccessRights != null && LDAPSettings.AccessRights.Count > 0)
|
||||
{
|
||||
GiveUsersRights(LDAPSettings.AccessRights, _currentUser != null ? currentUserRights : null);
|
||||
await GiveUsersRights(LDAPSettings.AccessRights, _currentUser != null ? currentUserRights : null);
|
||||
}
|
||||
|
||||
if (currentUserRights.Count > 0)
|
||||
@ -531,7 +531,7 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
_settingsManager.Save(LDAPSettings);
|
||||
}
|
||||
|
||||
private void TakeUsersRights(List<LdapSettings.AccessRight> currentUserRights)
|
||||
private async Task TakeUsersRights(List<LdapSettings.AccessRight> currentUserRights)
|
||||
{
|
||||
var current = _settingsManager.Load<LdapCurrentAcccessSettings>();
|
||||
|
||||
@ -558,7 +558,7 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
else
|
||||
{
|
||||
_logger.DebugTakingAdminRights(right.Key, user);
|
||||
_webItemSecurity.SetProductAdministrator(LdapSettings.AccessRightsGuids[right.Key], userId, false);
|
||||
await _webItemSecurity.SetProductAdministrator(LdapSettings.AccessRightsGuids[right.Key], userId, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -567,7 +567,7 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
_settingsManager.Save(current);
|
||||
}
|
||||
|
||||
private void GiveUsersRights(Dictionary<LdapSettings.AccessRight, string> accessRightsSettings, List<LdapSettings.AccessRight> currentUserRights)
|
||||
private async Task GiveUsersRights(Dictionary<LdapSettings.AccessRight, string> accessRightsSettings, List<LdapSettings.AccessRight> currentUserRights)
|
||||
{
|
||||
var current = _settingsManager.Load<LdapCurrentAcccessSettings>();
|
||||
var currentAccessRights = new Dictionary<LdapSettings.AccessRight, List<string>>();
|
||||
@ -618,7 +618,7 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
if (_webItemSecurity.IsProductAdministrator(prodId, user.Id))
|
||||
{
|
||||
cleared = true;
|
||||
_webItemSecurity.SetProductAdministrator(prodId, user.Id, false);
|
||||
await _webItemSecurity.SetProductAdministrator(prodId, user.Id, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -636,7 +636,7 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
|
||||
SetProgress((int)currentPercent,
|
||||
string.Format(Resource.LdapSettingsStatusGivingRights, _userFormatter.GetUserName(user, DisplayUserNameFormat.Default), access.Key));
|
||||
_webItemSecurity.SetProductAdministrator(LdapSettings.AccessRightsGuids[access.Key], user.Id, true);
|
||||
await _webItemSecurity.SetProductAdministrator(LdapSettings.AccessRightsGuids[access.Key], user.Id, true);
|
||||
|
||||
if (currentUserRights != null && currentUserRights.Contains(access.Key))
|
||||
{
|
||||
@ -651,7 +651,7 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
_settingsManager.Save(current);
|
||||
}
|
||||
|
||||
private void SyncLDAPUsers()
|
||||
private async Task SyncLDAPUsers()
|
||||
{
|
||||
SetProgress(15, Resource.LdapSettingsStatusGettingUsersFromLdap);
|
||||
|
||||
@ -675,14 +675,14 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
: Resource.LdapSettingsStatusSyncingUsers,
|
||||
"");
|
||||
|
||||
SyncDbUsers(ldapUsers);
|
||||
await SyncDbUsers(ldapUsers);
|
||||
|
||||
SetProgress(70, Resource.LdapSettingsStatusRemovingOldGroups, "");
|
||||
|
||||
RemoveOldDbGroups(new List<GroupInfo>()); // Remove all db groups with sid
|
||||
}
|
||||
|
||||
private void SyncLDAPUsersInGroups()
|
||||
private async Task SyncLDAPUsersInGroups()
|
||||
{
|
||||
SetProgress(15, Resource.LdapSettingsStatusGettingGroupsFromLdap);
|
||||
|
||||
@ -717,11 +717,11 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
: Resource.LdapSettingsStatusSyncingUsers,
|
||||
"");
|
||||
|
||||
var newUniqueLdapGroupUsers = SyncGroupsUsers(uniqueLdapGroupUsers);
|
||||
var newUniqueLdapGroupUsers = await SyncGroupsUsers(uniqueLdapGroupUsers);
|
||||
|
||||
SetProgress(60, Resource.LdapSettingsStatusSavingGroups, "");
|
||||
|
||||
SyncDbGroups(ldapGroupsUsers);
|
||||
await SyncDbGroups(ldapGroupsUsers);
|
||||
|
||||
SetProgress(80, Resource.LdapSettingsStatusRemovingOldGroups, "");
|
||||
|
||||
@ -732,7 +732,7 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
RemoveOldDbUsers(newUniqueLdapGroupUsers);
|
||||
}
|
||||
|
||||
private void SyncDbGroups(Dictionary<GroupInfo, List<UserInfo>> ldapGroupsWithUsers)
|
||||
private async Task SyncDbGroups(Dictionary<GroupInfo, List<UserInfo>> ldapGroupsWithUsers)
|
||||
{
|
||||
const double percents = 20;
|
||||
|
||||
@ -765,18 +765,18 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
|
||||
if (Equals(dbLdapGroup, Constants.LostGroupInfo))
|
||||
{
|
||||
AddNewGroup(ldapGroup, ldapGroupUsers, gIndex, gCount);
|
||||
await AddNewGroup(ldapGroup, ldapGroupUsers, gIndex, gCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateDbGroup(dbLdapGroup, ldapGroup, ldapGroupUsers, gIndex, gCount);
|
||||
await UpdateDbGroup(dbLdapGroup, ldapGroup, ldapGroupUsers, gIndex, gCount);
|
||||
}
|
||||
|
||||
percentage += step;
|
||||
}
|
||||
}
|
||||
|
||||
private void AddNewGroup(GroupInfo ldapGroup, List<UserInfo> ldapGroupUsers, int gIndex, int gCount)
|
||||
private async Task AddNewGroup(GroupInfo ldapGroup, List<UserInfo> ldapGroupUsers, int gIndex, int gCount)
|
||||
{
|
||||
if (!ldapGroupUsers.Any()) // Skip empty groups
|
||||
{
|
||||
@ -815,7 +815,7 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
++index, count,
|
||||
_userFormatter.GetUserName(userBySid, DisplayUserNameFormat.Default)));
|
||||
|
||||
_userManager.AddUserIntoGroup(userBySid.Id, ldapGroup.ID);
|
||||
await _userManager.AddUserIntoGroup(userBySid.Id, ldapGroup.ID);
|
||||
}
|
||||
break;
|
||||
case LdapOperationType.SaveTest:
|
||||
@ -846,7 +846,7 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
return needUpdate;
|
||||
}
|
||||
|
||||
private void UpdateDbGroup(GroupInfo dbLdapGroup, GroupInfo ldapGroup, List<UserInfo> ldapGroupUsers, int gIndex,
|
||||
private async Task UpdateDbGroup(GroupInfo dbLdapGroup, GroupInfo ldapGroup, List<UserInfo> ldapGroupUsers, int gIndex,
|
||||
int gCount)
|
||||
{
|
||||
SetProgress(currentSource:
|
||||
@ -911,7 +911,7 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
++index, count,
|
||||
_userFormatter.GetUserName(userInfo, DisplayUserNameFormat.Default)));
|
||||
|
||||
_userManager.AddUserIntoGroup(userInfo.Id, dbLdapGroup.ID);
|
||||
await _userManager.AddUserIntoGroup(userInfo.Id, dbLdapGroup.ID);
|
||||
}
|
||||
|
||||
if (dbGroupMembers.All(dbUser => groupMembersToRemove.Exists(u => u.Id.Equals(dbUser.Id)))
|
||||
@ -965,7 +965,7 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
return foundUser;
|
||||
}
|
||||
|
||||
private void SyncDbUsers(List<UserInfo> ldapUsers)
|
||||
private async Task SyncDbUsers(List<UserInfo> ldapUsers)
|
||||
{
|
||||
const double percents = 35;
|
||||
|
||||
@ -992,12 +992,11 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
{
|
||||
case LdapOperationType.Save:
|
||||
case LdapOperationType.Sync:
|
||||
_lDAPUserManager.SyncLDAPUser(userInfo, ldapUsers);
|
||||
await _lDAPUserManager.SyncLDAPUser(userInfo, ldapUsers);
|
||||
break;
|
||||
case LdapOperationType.SaveTest:
|
||||
case LdapOperationType.SyncTest:
|
||||
LdapChangeCollection changes;
|
||||
_lDAPUserManager.GetLDAPSyncUserChange(userInfo, ldapUsers, out changes);
|
||||
var changes = (await _lDAPUserManager.GetLDAPSyncUserChange(userInfo, ldapUsers)).LdapChangeCollection;
|
||||
_ldapChanges.AddRange(changes);
|
||||
break;
|
||||
default:
|
||||
@ -1065,7 +1064,7 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
|
||||
_logger.DebugSaveUserInfo(removedUser.GetUserInfoString());
|
||||
|
||||
_userManager.SaveUserInfo(removedUser);
|
||||
_userManager.UpdateUserInfo(removedUser);
|
||||
break;
|
||||
case LdapOperationType.SaveTest:
|
||||
case LdapOperationType.SyncTest:
|
||||
@ -1129,7 +1128,7 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
}
|
||||
}
|
||||
|
||||
private List<UserInfo> SyncGroupsUsers(List<UserInfo> uniqueLdapGroupUsers)
|
||||
private async Task<List<UserInfo>> SyncGroupsUsers(List<UserInfo> uniqueLdapGroupUsers)
|
||||
{
|
||||
const double percents = 30;
|
||||
|
||||
@ -1157,7 +1156,7 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
{
|
||||
case LdapOperationType.Save:
|
||||
case LdapOperationType.Sync:
|
||||
user = _lDAPUserManager.SyncLDAPUser(ldapGroupUser, uniqueLdapGroupUsers);
|
||||
user = await _lDAPUserManager.SyncLDAPUser(ldapGroupUser, uniqueLdapGroupUsers);
|
||||
if (!Equals(user, Constants.LostUser))
|
||||
{
|
||||
newUniqueLdapGroupUsers.Add(user);
|
||||
@ -1165,8 +1164,9 @@ public class LdapOperationJob : DistributedTaskProgress
|
||||
break;
|
||||
case LdapOperationType.SaveTest:
|
||||
case LdapOperationType.SyncTest:
|
||||
LdapChangeCollection changes;
|
||||
user = _lDAPUserManager.GetLDAPSyncUserChange(ldapGroupUser, uniqueLdapGroupUsers, out changes);
|
||||
var wrapper = await _lDAPUserManager.GetLDAPSyncUserChange(ldapGroupUser, uniqueLdapGroupUsers);
|
||||
user = wrapper.UserInfo;
|
||||
var changes = wrapper.LdapChangeCollection;
|
||||
if (!Equals(user, Constants.LostUser))
|
||||
{
|
||||
newUniqueLdapGroupUsers.Add(user);
|
||||
|
@ -51,6 +51,7 @@ global using ASC.ActiveDirectory.Novell;
|
||||
global using ASC.ActiveDirectory.Novell.Data;
|
||||
global using ASC.ActiveDirectory.Novell.Exceptions;
|
||||
global using ASC.ActiveDirectory.Novell.Extensions;
|
||||
global using ASC.ActiveDirectory.Wrapper;
|
||||
global using ASC.Common;
|
||||
global using ASC.Common.Security.Authorizing;
|
||||
global using ASC.Common.Threading;
|
||||
|
@ -1,30 +1,31 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
|
||||
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
|
||||
using Constants = ASC.Core.Users.Constants;
|
||||
using Mapping = ASC.ActiveDirectory.Base.Settings.LdapSettings.MappingFields;
|
||||
using SecurityContext = ASC.Core.SecurityContext;
|
||||
@ -43,8 +44,8 @@ public class LdapUserManager
|
||||
private readonly DisplayUserSettingsHelper _displayUserSettingsHelper;
|
||||
private readonly UserFormatter _userFormatter;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly NovellLdapUserImporter _novellLdapUserImporter;
|
||||
private readonly CountRoomAdminChecker _countRoomAdminChecker;
|
||||
private readonly NovellLdapUserImporter _novellLdapUserImporter;
|
||||
private readonly CountRoomAdminChecker _countRoomAdminChecker;
|
||||
private LdapLocalization _resource;
|
||||
|
||||
public LdapUserManager(
|
||||
@ -58,7 +59,7 @@ public class LdapUserManager
|
||||
SettingsManager settingsManager,
|
||||
DisplayUserSettingsHelper displayUserSettingsHelper,
|
||||
UserFormatter userFormatter,
|
||||
NovellLdapUserImporter novellLdapUserImporter,
|
||||
NovellLdapUserImporter novellLdapUserImporter,
|
||||
CountRoomAdminChecker countRoomAdminChecker)
|
||||
{
|
||||
_logger = logger;
|
||||
@ -71,8 +72,8 @@ public class LdapUserManager
|
||||
_displayUserSettingsHelper = displayUserSettingsHelper;
|
||||
_userFormatter = userFormatter;
|
||||
_serviceProvider = serviceProvider;
|
||||
_novellLdapUserImporter = novellLdapUserImporter;
|
||||
_countRoomAdminChecker = countRoomAdminChecker;
|
||||
_novellLdapUserImporter = novellLdapUserImporter;
|
||||
_countRoomAdminChecker = countRoomAdminChecker;
|
||||
}
|
||||
|
||||
public void Init(LdapLocalization resource = null)
|
||||
@ -108,9 +109,9 @@ public class LdapUserManager
|
||||
return Equals(foundUser, Constants.LostUser) || foundUser.Id == userId;
|
||||
}
|
||||
|
||||
public bool TryAddLDAPUser(UserInfo ldapUserInfo, bool onlyGetChanges, out UserInfo portalUserInfo)
|
||||
public async Task<UserInfo> TryAddLDAPUser(UserInfo ldapUserInfo, bool onlyGetChanges)
|
||||
{
|
||||
portalUserInfo = Constants.LostUser;
|
||||
var portalUserInfo = Constants.LostUser;
|
||||
|
||||
try
|
||||
{
|
||||
@ -125,24 +126,14 @@ public class LdapUserManager
|
||||
{
|
||||
_logger.DebugUserAlredyExistsForEmail(ldapUserInfo.Sid, ldapUserInfo.Email);
|
||||
|
||||
return false;
|
||||
return portalUserInfo;
|
||||
}
|
||||
|
||||
if (!TryChangeExistingUserName(ldapUserInfo.UserName, onlyGetChanges))
|
||||
{
|
||||
_logger.DebugUserAlredyExistsForUserName(ldapUserInfo.Sid, ldapUserInfo.UserName);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_countRoomAdminChecker.CheckAppend().Wait();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_logger.DebugExceedQuota(ldapUserInfo.Sid, ldapUserInfo.UserName);
|
||||
throw;
|
||||
return portalUserInfo;
|
||||
}
|
||||
|
||||
if (!ldapUserInfo.WorkFromDate.HasValue)
|
||||
@ -153,12 +144,12 @@ public class LdapUserManager
|
||||
if (onlyGetChanges)
|
||||
{
|
||||
portalUserInfo = ldapUserInfo;
|
||||
return true;
|
||||
return portalUserInfo;
|
||||
}
|
||||
|
||||
_logger.DebugSaveUserInfo(ldapUserInfo.GetUserInfoString());
|
||||
|
||||
portalUserInfo = _userManager.SaveUserInfo(ldapUserInfo);
|
||||
portalUserInfo = await _userManager.SaveUserInfo(ldapUserInfo);
|
||||
|
||||
var quotaSettings = _settingsManager.Load<TenantUserQuotaSettings>();
|
||||
if (quotaSettings.EnableUserQuota)
|
||||
@ -172,8 +163,6 @@ public class LdapUserManager
|
||||
_logger.DebugSetUserPassword(portalUserInfo.Id);
|
||||
|
||||
_securityContext.SetUserPasswordHash(portalUserInfo.Id, passwordHash);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (TenantQuotaException ex)
|
||||
{
|
||||
@ -188,7 +177,7 @@ public class LdapUserManager
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return portalUserInfo;
|
||||
}
|
||||
|
||||
private bool TryChangeExistingUserName(string ldapUserName, bool onlyGetChanges)
|
||||
@ -223,7 +212,7 @@ public class LdapUserManager
|
||||
|
||||
_logger.DebugSaveUserInfo(otherUser.GetUserInfoString());
|
||||
|
||||
_userManager.SaveUserInfo(otherUser);
|
||||
_userManager.UpdateUserInfo(otherUser);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -235,25 +224,26 @@ public class LdapUserManager
|
||||
return false;
|
||||
}
|
||||
|
||||
public UserInfo GetLDAPSyncUserChange(UserInfo ldapUserInfo, List<UserInfo> ldapUsers, out LdapChangeCollection changes)
|
||||
public async Task<UserInfoAndLdapChangeCollectionWrapper> GetLDAPSyncUserChange(UserInfo ldapUserInfo, List<UserInfo> ldapUsers)
|
||||
{
|
||||
return SyncLDAPUser(ldapUserInfo, ldapUsers, out changes, true);
|
||||
return await SyncLDAPUser(ldapUserInfo, ldapUsers, true);
|
||||
}
|
||||
|
||||
public UserInfo SyncLDAPUser(UserInfo ldapUserInfo, List<UserInfo> ldapUsers = null)
|
||||
public async Task<UserInfo> SyncLDAPUser(UserInfo ldapUserInfo, List<UserInfo> ldapUsers = null)
|
||||
{
|
||||
LdapChangeCollection changes;
|
||||
return SyncLDAPUser(ldapUserInfo, ldapUsers, out changes);
|
||||
return (await SyncLDAPUser(ldapUserInfo, ldapUsers, false)).UserInfo;
|
||||
}
|
||||
|
||||
private UserInfo SyncLDAPUser(UserInfo ldapUserInfo, List<UserInfo> ldapUsers, out LdapChangeCollection changes, bool onlyGetChanges = false)
|
||||
private async Task<UserInfoAndLdapChangeCollectionWrapper> SyncLDAPUser(UserInfo ldapUserInfo, List<UserInfo> ldapUsers, bool onlyGetChanges = false)
|
||||
{
|
||||
UserInfo result;
|
||||
|
||||
changes = new LdapChangeCollection(_userFormatter);
|
||||
|
||||
UserInfo userToUpdate;
|
||||
|
||||
var wrapper = new UserInfoAndLdapChangeCollectionWrapper()
|
||||
{
|
||||
LdapChangeCollection = new LdapChangeCollection(_userFormatter),
|
||||
UserInfo = Constants.LostUser
|
||||
};
|
||||
|
||||
var userBySid = _userManager.GetUserBySid(ldapUserInfo.Sid);
|
||||
|
||||
if (Equals(userBySid, Constants.LostUser))
|
||||
@ -266,28 +256,28 @@ public class LdapUserManager
|
||||
{
|
||||
if (onlyGetChanges)
|
||||
{
|
||||
changes.SetSkipUserChange(ldapUserInfo);
|
||||
wrapper.LdapChangeCollection.SetSkipUserChange(ldapUserInfo);
|
||||
}
|
||||
|
||||
_logger.DebugSyncUserLdapFailedWithStatus(ldapUserInfo.Sid, ldapUserInfo.UserName,
|
||||
Enum.GetName(typeof(EmployeeStatus), ldapUserInfo.Status));
|
||||
|
||||
return Constants.LostUser;
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
if (!TryAddLDAPUser(ldapUserInfo, onlyGetChanges, out result))
|
||||
wrapper.UserInfo = await TryAddLDAPUser(ldapUserInfo, onlyGetChanges);
|
||||
if (wrapper.UserInfo == Constants.LostUser)
|
||||
{
|
||||
if (onlyGetChanges)
|
||||
{
|
||||
changes.SetSkipUserChange(ldapUserInfo);
|
||||
wrapper.LdapChangeCollection.SetSkipUserChange(ldapUserInfo);
|
||||
}
|
||||
|
||||
return Constants.LostUser;
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
if (onlyGetChanges)
|
||||
{
|
||||
changes.SetAddUserChange(result, _logger);
|
||||
wrapper.LdapChangeCollection.SetAddUserChange(wrapper.UserInfo, _logger);
|
||||
}
|
||||
|
||||
if (!onlyGetChanges && _settingsManager.Load<LdapSettings>().SendWelcomeEmail &&
|
||||
@ -317,7 +307,7 @@ public class LdapUserManager
|
||||
new TagValue(NotifyCommonTags.WithoutUnsubscribe, true));
|
||||
}
|
||||
|
||||
return result;
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
if (userByEmail.IsLDAP())
|
||||
@ -326,13 +316,13 @@ public class LdapUserManager
|
||||
{
|
||||
if (onlyGetChanges)
|
||||
{
|
||||
changes.SetSkipUserChange(ldapUserInfo);
|
||||
wrapper.LdapChangeCollection.SetSkipUserChange(ldapUserInfo);
|
||||
}
|
||||
|
||||
_logger.DebugSyncUserLdapFailedWithEmail(
|
||||
ldapUserInfo.Sid, ldapUserInfo.UserName, ldapUserInfo.Email);
|
||||
|
||||
return Constants.LostUser;
|
||||
return wrapper;
|
||||
}
|
||||
}
|
||||
|
||||
@ -350,29 +340,30 @@ public class LdapUserManager
|
||||
_logger.DebugSyncUserLdapSkipping(ldapUserInfo.Sid, ldapUserInfo.UserName);
|
||||
if (onlyGetChanges)
|
||||
{
|
||||
changes.SetNoneUserChange(ldapUserInfo);
|
||||
wrapper.LdapChangeCollection.SetNoneUserChange(ldapUserInfo);
|
||||
}
|
||||
|
||||
return userBySid;
|
||||
wrapper.UserInfo = userBySid;
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
_logger.DebugSyncUserLdapUpdaiting(ldapUserInfo.Sid, ldapUserInfo.UserName);
|
||||
if (!TryUpdateUserWithLDAPInfo(userToUpdate, ldapUserInfo, onlyGetChanges, out result))
|
||||
UserInfo uf;
|
||||
if (!TryUpdateUserWithLDAPInfo(userToUpdate, ldapUserInfo, onlyGetChanges, out uf))
|
||||
{
|
||||
if (onlyGetChanges)
|
||||
{
|
||||
changes.SetSkipUserChange(ldapUserInfo);
|
||||
wrapper.LdapChangeCollection.SetSkipUserChange(ldapUserInfo);
|
||||
}
|
||||
|
||||
return Constants.LostUser;
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
if (onlyGetChanges)
|
||||
{
|
||||
changes.SetUpdateUserChange(ldapUserInfo, result, _logger);
|
||||
wrapper.LdapChangeCollection.SetUpdateUserChange(ldapUserInfo, uf, _logger);
|
||||
}
|
||||
|
||||
return result;
|
||||
wrapper.UserInfo = uf;
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
private const string EXT_MOB_PHONE = "extmobphone";
|
||||
@ -601,7 +592,7 @@ public class LdapUserManager
|
||||
{
|
||||
_logger.DebugSaveUserInfo(userToUpdate.GetUserInfoString());
|
||||
|
||||
portlaUserInfo = _userManager.SaveUserInfo(userToUpdate);
|
||||
portlaUserInfo = _userManager.UpdateUserInfo(userToUpdate);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -615,9 +606,9 @@ public class LdapUserManager
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryGetAndSyncLdapUserInfo(string login, string password, out UserInfo userInfo)
|
||||
public async Task<UserInfo> TryGetAndSyncLdapUserInfo(string login, string password)
|
||||
{
|
||||
userInfo = Constants.LostUser;
|
||||
var userInfo = Constants.LostUser;
|
||||
|
||||
|
||||
try
|
||||
@ -626,7 +617,7 @@ public class LdapUserManager
|
||||
|
||||
if (!settings.EnableLdapAuthentication)
|
||||
{
|
||||
return false;
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
_logger.DebugTryGetAndSyncLdapUserInfo(login);
|
||||
@ -638,7 +629,7 @@ public class LdapUserManager
|
||||
if (ldapUserInfo == null || ldapUserInfo.Item1.Equals(Constants.LostUser))
|
||||
{
|
||||
_logger.DebugNovellLdapUserImporterLoginFailed(login);
|
||||
return false;
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
var portalUser = _userManager.GetUserBySid(ldapUserInfo.Item1.Sid);
|
||||
@ -648,16 +639,16 @@ public class LdapUserManager
|
||||
if (!ldapUserInfo.Item2.IsDisabled)
|
||||
{
|
||||
_logger.DebugTryCheckAndSyncToLdapUser(ldapUserInfo.Item1.UserName, ldapUserInfo.Item1.Email, ldapUserInfo.Item2.DistinguishedName);
|
||||
|
||||
if (!TryCheckAndSyncToLdapUser(ldapUserInfo, _novellLdapUserImporter, out userInfo))
|
||||
userInfo = await TryCheckAndSyncToLdapUser(ldapUserInfo, _novellLdapUserImporter);
|
||||
if (Equals(userInfo, Constants.LostUser))
|
||||
{
|
||||
_logger.DebugTryCheckAndSyncToLdapUserFailed();
|
||||
return false;
|
||||
return userInfo;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
return userInfo;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -679,18 +670,18 @@ public class LdapUserManager
|
||||
tenantManager.SetCurrentTenant(tenant);
|
||||
securityContext.AuthenticateMe(Core.Configuration.Constants.CoreSystem);
|
||||
|
||||
var uInfo = SyncLDAPUser(ldapUserInfo.Item1);
|
||||
var uInfo = await SyncLDAPUser(ldapUserInfo.Item1);
|
||||
|
||||
var newLdapUserInfo = new Tuple<UserInfo, LdapObject>(uInfo, ldapUserInfo.Item2);
|
||||
|
||||
if (novellLdapUserImporter.Settings.GroupMembership)
|
||||
{
|
||||
if (!novellLdapUserImporter.TrySyncUserGroupMembership(newLdapUserInfo))
|
||||
if (!(await novellLdapUserImporter.TrySyncUserGroupMembership(newLdapUserInfo)))
|
||||
{
|
||||
log.DebugTryGetAndSyncLdapUserInfoDisablingUser(login, uInfo);
|
||||
uInfo.Status = EmployeeStatus.Terminated;
|
||||
uInfo.Sid = null;
|
||||
userManager.SaveUserInfo(uInfo);
|
||||
userManager.UpdateUserInfo(uInfo);
|
||||
await cookiesManager.ResetUserCookie(uInfo.Id);
|
||||
}
|
||||
}
|
||||
@ -699,7 +690,7 @@ public class LdapUserManager
|
||||
if (ldapUserInfo.Item2.IsDisabled)
|
||||
{
|
||||
_logger.DebugTryGetAndSyncLdapUserInfo(login);
|
||||
return false;
|
||||
return userInfo;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -707,24 +698,24 @@ public class LdapUserManager
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return userInfo;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorTryGetLdapUserInfoFailed(login, ex);
|
||||
userInfo = Constants.LostUser;
|
||||
return false;
|
||||
return userInfo;
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryCheckAndSyncToLdapUser(Tuple<UserInfo, LdapObject> ldapUserInfo, LdapUserImporter importer,
|
||||
out UserInfo userInfo)
|
||||
private async Task<UserInfo> TryCheckAndSyncToLdapUser(Tuple<UserInfo, LdapObject> ldapUserInfo, LdapUserImporter importer)
|
||||
{
|
||||
UserInfo userInfo;
|
||||
try
|
||||
{
|
||||
_securityContext.AuthenticateMe(Core.Configuration.Constants.CoreSystem);
|
||||
|
||||
userInfo = SyncLDAPUser(ldapUserInfo.Item1);
|
||||
userInfo = await SyncLDAPUser(ldapUserInfo.Item1);
|
||||
|
||||
if (userInfo == null || userInfo.Equals(Constants.LostUser))
|
||||
{
|
||||
@ -735,18 +726,18 @@ public class LdapUserManager
|
||||
|
||||
if (!importer.Settings.GroupMembership)
|
||||
{
|
||||
return true;
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
if (!importer.TrySyncUserGroupMembership(newLdapUserInfo))
|
||||
if (!(await importer.TrySyncUserGroupMembership(newLdapUserInfo)))
|
||||
{
|
||||
userInfo.Sid = null;
|
||||
userInfo.Status = EmployeeStatus.Terminated;
|
||||
_userManager.SaveUserInfo(userInfo);
|
||||
_userManager.UpdateUserInfo(userInfo);
|
||||
throw new Exception("The user did not pass the configuration check by ldap group settings");
|
||||
}
|
||||
|
||||
return true;
|
||||
return userInfo;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -759,6 +750,6 @@ public class LdapUserManager
|
||||
}
|
||||
|
||||
userInfo = Constants.LostUser;
|
||||
return false;
|
||||
return userInfo;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,32 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.ActiveDirectory.Wrapper;
|
||||
public class UserInfoAndLdapChangeCollectionWrapper
|
||||
{
|
||||
public UserInfo UserInfo { get; set; }
|
||||
public LdapChangeCollection LdapChangeCollection { get; set; }
|
||||
}
|
@ -57,7 +57,7 @@ public class CookieAuthHandler : AuthenticationHandler<AuthenticationSchemeOptio
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
}
|
||||
|
||||
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -75,7 +75,7 @@ public class CookieAuthHandler : AuthenticationHandler<AuthenticationSchemeOptio
|
||||
authorization = authorization.Substring("Bearer ".Length);
|
||||
}
|
||||
|
||||
if (!_securityContext.AuthenticateMe(authorization))
|
||||
if (!(await _securityContext.AuthenticateMe(authorization)))
|
||||
{
|
||||
throw new AuthenticationException(nameof(HttpStatusCode.Unauthorized));
|
||||
}
|
||||
@ -83,7 +83,7 @@ public class CookieAuthHandler : AuthenticationHandler<AuthenticationSchemeOptio
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return Task.FromResult(AuthenticateResult.Fail(new AuthenticationException(nameof(HttpStatusCode.Unauthorized))));
|
||||
return AuthenticateResult.Fail(new AuthenticationException(nameof(HttpStatusCode.Unauthorized)));
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -95,6 +95,6 @@ public class CookieAuthHandler : AuthenticationHandler<AuthenticationSchemeOptio
|
||||
}
|
||||
}
|
||||
|
||||
return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(Context.User, Scheme.Name)));
|
||||
return AuthenticateResult.Success(new AuthenticationTicket(Context.User, Scheme.Name));
|
||||
}
|
||||
}
|
@ -29,7 +29,7 @@ namespace ASC.Api.Core.Extensions;
|
||||
public static class ISetupBuilderExtension
|
||||
{
|
||||
public static ISetupBuilder LoadConfiguration(this ISetupBuilder loggingBuilder, IConfiguration configuration, IHostEnvironment hostEnvironment)
|
||||
{
|
||||
{
|
||||
var conf = new XmlLoggingConfiguration(CrossPlatform.PathCombine(configuration["pathToConf"], "nlog.config"));
|
||||
|
||||
var settings = new ConfigurationExtension(configuration).GetSetting<NLogSettings>("log");
|
||||
@ -56,10 +56,14 @@ public static class ISetupBuilderExtension
|
||||
{
|
||||
awsTarget.LogGroup = awsTarget.LogGroup.Replace("${var:name}", settings.Name);
|
||||
}
|
||||
|
||||
|
||||
var awsAccessKeyId = string.IsNullOrEmpty(settings.AWSAccessKeyId) ? configuration["aws:cloudWatch:accessKeyId"] : settings.AWSAccessKeyId;
|
||||
var awsSecretAccessKey = string.IsNullOrEmpty(settings.AWSSecretAccessKey) ? configuration["aws:cloudWatch:secretAccessKey"] : settings.AWSSecretAccessKey;
|
||||
|
||||
if (!string.IsNullOrEmpty(settings.AWSSecretAccessKey))
|
||||
if (!string.IsNullOrEmpty(awsAccessKeyId))
|
||||
{
|
||||
awsTarget.Credentials = new Amazon.Runtime.BasicAWSCredentials(settings.AWSAccessKeyId, settings.AWSSecretAccessKey);
|
||||
awsTarget.Credentials = new Amazon.Runtime.BasicAWSCredentials(awsAccessKeyId, awsSecretAccessKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,7 +157,7 @@ public class EmployeeFullDtoHelper : EmployeeDtoHelper
|
||||
|
||||
return lambda;
|
||||
}
|
||||
public EmployeeFullDto GetSimple(UserInfo userInfo)
|
||||
public async Task<EmployeeFullDto> GetSimple(UserInfo userInfo)
|
||||
{
|
||||
var result = new EmployeeFullDto
|
||||
{
|
||||
@ -167,7 +167,7 @@ public class EmployeeFullDtoHelper : EmployeeDtoHelper
|
||||
|
||||
FillGroups(result, userInfo);
|
||||
|
||||
var photoData = _userPhotoManager.GetUserPhotoData(userInfo.Id, UserPhotoManager.BigFotoSize);
|
||||
var photoData = await _userPhotoManager.GetUserPhotoData(userInfo.Id, UserPhotoManager.BigFotoSize);
|
||||
|
||||
if (photoData != null)
|
||||
{
|
||||
|
@ -40,7 +40,6 @@
|
||||
<PackageReference Include="log4net" Version="2.0.14" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="6.0.7" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="6.0.7" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" />
|
||||
|
@ -145,7 +145,7 @@ public class KafkaCacheNotify<T> : IDisposable, ICacheNotify<T> where T : IMessa
|
||||
_cancelationToken[channelName] = new CancellationTokenSource();
|
||||
_actions[channelName] = onchange;
|
||||
|
||||
void action()
|
||||
async void action()
|
||||
{
|
||||
var conf = new ConsumerConfig(_clientConfig)
|
||||
{
|
||||
@ -160,7 +160,7 @@ public class KafkaCacheNotify<T> : IDisposable, ICacheNotify<T> where T : IMessa
|
||||
try
|
||||
{
|
||||
//TODO: must add checking exist
|
||||
adminClient.CreateTopicsAsync(
|
||||
await adminClient.CreateTopicsAsync(
|
||||
new TopicSpecification[]
|
||||
{
|
||||
new TopicSpecification
|
||||
@ -169,7 +169,7 @@ public class KafkaCacheNotify<T> : IDisposable, ICacheNotify<T> where T : IMessa
|
||||
NumPartitions = 1,
|
||||
ReplicationFactor = 1
|
||||
}
|
||||
}).Wait();
|
||||
});
|
||||
}
|
||||
catch (AggregateException) { }
|
||||
}
|
||||
|
@ -185,10 +185,18 @@ public class DIHelper
|
||||
|
||||
public bool TryAdd(Type service, Type implementation = null)
|
||||
{
|
||||
if (service.IsInterface && service.IsGenericType && implementation == null &&
|
||||
(service.GetGenericTypeDefinition() == typeof(IOptionsSnapshot<>) ||
|
||||
service.GetGenericTypeDefinition() == typeof(IOptions<>) ||
|
||||
service.GetGenericTypeDefinition() == typeof(IOptionsMonitor<>)
|
||||
Type serviceGenericTypeDefinition = null;
|
||||
|
||||
if (service.IsGenericType)
|
||||
{
|
||||
serviceGenericTypeDefinition = service.GetGenericTypeDefinition();
|
||||
}
|
||||
|
||||
if (service.IsInterface && serviceGenericTypeDefinition != null && implementation == null &&
|
||||
(
|
||||
serviceGenericTypeDefinition == typeof(IOptionsSnapshot<>) ||
|
||||
serviceGenericTypeDefinition == typeof(IOptions<>) ||
|
||||
serviceGenericTypeDefinition == typeof(IOptionsMonitor<>)
|
||||
))
|
||||
{
|
||||
service = service.GetGenericArguments().FirstOrDefault();
|
||||
@ -208,10 +216,10 @@ public class DIHelper
|
||||
|
||||
Added.Add(serviceName);
|
||||
|
||||
var di = service.IsGenericType && (
|
||||
service.GetGenericTypeDefinition() == typeof(IConfigureOptions<>) ||
|
||||
service.GetGenericTypeDefinition() == typeof(IPostConfigureOptions<>) ||
|
||||
service.GetGenericTypeDefinition() == typeof(IOptionsMonitor<>)
|
||||
var di = serviceGenericTypeDefinition != null && (
|
||||
serviceGenericTypeDefinition == typeof(IConfigureOptions<>) ||
|
||||
serviceGenericTypeDefinition == typeof(IPostConfigureOptions<>) ||
|
||||
serviceGenericTypeDefinition == typeof(IOptionsMonitor<>)
|
||||
) && implementation != null ? implementation.GetCustomAttribute<DIAttribute>() : service.GetCustomAttribute<DIAttribute>();
|
||||
|
||||
var isnew = false;
|
||||
@ -237,11 +245,21 @@ public class DIHelper
|
||||
{
|
||||
if (di.Service != null)
|
||||
{
|
||||
var a = di.Service.GetInterfaces().FirstOrDefault(x => x.IsGenericType && (
|
||||
x.GetGenericTypeDefinition() == typeof(IConfigureOptions<>) ||
|
||||
x.GetGenericTypeDefinition() == typeof(IPostConfigureOptions<>) ||
|
||||
x.GetGenericTypeDefinition() == typeof(IOptionsMonitor<>)
|
||||
));
|
||||
var a = di.Service.GetInterfaces().FirstOrDefault(x =>
|
||||
{
|
||||
Type xGenericTypeDefinition = null;
|
||||
|
||||
if (x.IsGenericType)
|
||||
{
|
||||
xGenericTypeDefinition = x.GetGenericTypeDefinition();
|
||||
}
|
||||
|
||||
return
|
||||
xGenericTypeDefinition != null && (
|
||||
xGenericTypeDefinition == typeof(IConfigureOptions<>) ||
|
||||
xGenericTypeDefinition == typeof(IPostConfigureOptions<>) ||
|
||||
xGenericTypeDefinition == typeof(IOptionsMonitor<>));
|
||||
});
|
||||
|
||||
if (a != null)
|
||||
{
|
||||
@ -302,11 +320,24 @@ public class DIHelper
|
||||
|
||||
if (di.Implementation != null)
|
||||
{
|
||||
var a = di.Implementation.GetInterfaces().FirstOrDefault(x => x.IsGenericType &&
|
||||
(x.GetGenericTypeDefinition() == typeof(IConfigureOptions<>) ||
|
||||
x.GetGenericTypeDefinition() == typeof(IPostConfigureOptions<>) ||
|
||||
x.GetGenericTypeDefinition() == typeof(IOptionsMonitor<>))
|
||||
);
|
||||
var a = di.Implementation.GetInterfaces().FirstOrDefault(x =>
|
||||
{
|
||||
|
||||
Type xGenericTypeDefinition = null;
|
||||
|
||||
if (x.IsGenericType)
|
||||
{
|
||||
xGenericTypeDefinition = x.GetGenericTypeDefinition();
|
||||
}
|
||||
|
||||
return
|
||||
xGenericTypeDefinition != null &&
|
||||
(
|
||||
xGenericTypeDefinition == typeof(IConfigureOptions<>) ||
|
||||
xGenericTypeDefinition == typeof(IPostConfigureOptions<>) ||
|
||||
xGenericTypeDefinition == typeof(IOptionsMonitor<>));
|
||||
});
|
||||
|
||||
if (a != null)
|
||||
{
|
||||
if (!a.ContainsGenericParameters)
|
||||
@ -449,10 +480,17 @@ public class DIHelper
|
||||
return true;
|
||||
}
|
||||
|
||||
var c = service.IsGenericType && (
|
||||
service.GetGenericTypeDefinition() == typeof(IConfigureOptions<>) ||
|
||||
service.GetGenericTypeDefinition() == typeof(IPostConfigureOptions<>) ||
|
||||
service.GetGenericTypeDefinition() == typeof(IOptionsMonitor<>)
|
||||
Type serviceGenericTypeDefinition = null;
|
||||
|
||||
if (service.IsGenericType)
|
||||
{
|
||||
serviceGenericTypeDefinition = service.GetGenericTypeDefinition();
|
||||
}
|
||||
|
||||
var c = serviceGenericTypeDefinition != null && (
|
||||
serviceGenericTypeDefinition == typeof(IConfigureOptions<>) ||
|
||||
serviceGenericTypeDefinition == typeof(IPostConfigureOptions<>) ||
|
||||
serviceGenericTypeDefinition == typeof(IOptionsMonitor<>)
|
||||
) && implementation != null ? implementation.GetCustomAttribute<DIAttribute>() : service.GetCustomAttribute<DIAttribute>();
|
||||
|
||||
var serviceName = $"{service}{implementation}";
|
||||
|
@ -24,8 +24,6 @@
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace System.IO;
|
||||
|
||||
[Singletone]
|
||||
public class TempPath
|
||||
{
|
||||
|
@ -24,8 +24,6 @@
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
using JsonSerializer = System.Text.Json.JsonSerializer;
|
||||
|
||||
namespace ASC.Common.Threading;
|
||||
|
||||
[ProtoContract(IgnoreUnknownSubTypes = true)]
|
||||
@ -77,21 +75,6 @@ public class DistributedTask
|
||||
Publication(this);
|
||||
}
|
||||
|
||||
public T GetProperty<T>(string propName)
|
||||
{
|
||||
if (!_props.TryGetValue(propName, out var propValue))
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
return JsonSerializer.Deserialize<T>(propValue);
|
||||
}
|
||||
|
||||
public void SetProperty<T>(string propName, T propValue)
|
||||
{
|
||||
_props[propName] = JsonSerializer.Serialize(propValue);
|
||||
}
|
||||
|
||||
public dynamic this[string propName]
|
||||
{
|
||||
get
|
||||
|
@ -45,15 +45,15 @@ public class DistributedTaskProgress : DistributedTask
|
||||
[ProtoMember(3)]
|
||||
protected int StepCount { get; set; }
|
||||
|
||||
public void RunJob()
|
||||
public virtual async Task RunJob(DistributedTask _, CancellationToken cancellationToken)
|
||||
{
|
||||
Percentage = 0;
|
||||
Status = DistributedTaskStatus.Running;
|
||||
|
||||
DoJob();
|
||||
await DoJob();
|
||||
}
|
||||
|
||||
protected virtual void DoJob() { }
|
||||
protected virtual Task DoJob() { return Task.CompletedTask; }
|
||||
|
||||
protected void StepDone()
|
||||
{
|
||||
|
@ -121,41 +121,7 @@ public class DistributedTaskQueue
|
||||
|
||||
public void EnqueueTask(DistributedTaskProgress taskProgress)
|
||||
{
|
||||
EnqueueTask((a, b) => taskProgress.RunJob(), taskProgress);
|
||||
}
|
||||
|
||||
public void EnqueueTask(Action<DistributedTask, CancellationToken> action, DistributedTask distributedTask = null)
|
||||
{
|
||||
if (distributedTask == null)
|
||||
{
|
||||
distributedTask = new DistributedTask();
|
||||
}
|
||||
|
||||
distributedTask.InstanceId = INSTANCE_ID;
|
||||
|
||||
var cancelation = new CancellationTokenSource();
|
||||
var token = cancelation.Token;
|
||||
_cancelations[distributedTask.Id] = cancelation;
|
||||
|
||||
var task = new Task(() => { action(distributedTask, token); }, token, TaskCreationOptions.LongRunning);
|
||||
|
||||
task.ConfigureAwait(false)
|
||||
.GetAwaiter()
|
||||
.OnCompleted(() => OnCompleted(task, distributedTask.Id));
|
||||
|
||||
distributedTask.Status = DistributedTaskStatus.Running;
|
||||
|
||||
if (distributedTask.Publication == null)
|
||||
{
|
||||
distributedTask.Publication = GetPublication();
|
||||
}
|
||||
|
||||
distributedTask.PublishChanges();
|
||||
|
||||
task.Start(Scheduler);
|
||||
|
||||
_logger.TraceEnqueueTask(distributedTask.Id, INSTANCE_ID);
|
||||
|
||||
EnqueueTask(taskProgress.RunJob, taskProgress);
|
||||
}
|
||||
|
||||
public void EnqueueTask(Func<DistributedTask, CancellationToken, Task> action, DistributedTask distributedTask = null)
|
||||
@ -393,5 +359,4 @@ public class DistributedTaskQueue
|
||||
|
||||
return destination;
|
||||
}
|
||||
|
||||
}
|
@ -50,7 +50,6 @@
|
||||
<None Remove="protos\user_photo_cache_item.proto" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AWSSDK.Core" Version="3.7.10.11" />
|
||||
<PackageReference Include="AWSSDK.SimpleEmail" Version="3.7.0.150" />
|
||||
<PackageReference Include="FirebaseAdmin" Version="2.3.0" />
|
||||
<PackageReference Include="Grpc.Tools" Version="2.47.0">
|
||||
@ -63,7 +62,6 @@
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="6.0.2" />
|
||||
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
|
||||
<PackageReference Include="Telegram.Bot" Version="17.0.0" />
|
||||
<PackageReference Include="Telegram.Bot.Extensions.Polling" Version="1.0.2" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Protobuf Include="protos\create_client_proto.proto" />
|
||||
|
@ -61,7 +61,7 @@ public class UserManager
|
||||
private readonly CardDavAddressbook _cardDavAddressbook;
|
||||
private readonly ILogger<UserManager> _log;
|
||||
private readonly ICache _cache;
|
||||
private readonly TenantQuotaFeatureCheckerCount<CountRoomAdminFeature> _tenantQuotaFeatureChecker;
|
||||
private readonly TenantQuotaFeatureCheckerCount<CountRoomAdminFeature> _countRoomAdminChecker;
|
||||
private readonly TenantQuotaFeatureCheckerCount<CountUserFeature> _activeUsersFeatureChecker;
|
||||
private readonly Constants _constants;
|
||||
|
||||
@ -85,7 +85,7 @@ public class UserManager
|
||||
CardDavAddressbook cardDavAddressbook,
|
||||
ILogger<UserManager> log,
|
||||
ICache cache,
|
||||
TenantQuotaFeatureCheckerCount<CountRoomAdminFeature> tenantQuotaFeatureChecker,
|
||||
TenantQuotaFeatureCheckerCount<CountRoomAdminFeature> countRoomAdrminChecker,
|
||||
TenantQuotaFeatureCheckerCount<CountUserFeature> activeUsersFeatureChecker
|
||||
)
|
||||
{
|
||||
@ -100,7 +100,7 @@ public class UserManager
|
||||
_cardDavAddressbook = cardDavAddressbook;
|
||||
_log = log;
|
||||
_cache = cache;
|
||||
_tenantQuotaFeatureChecker = tenantQuotaFeatureChecker;
|
||||
_countRoomAdminChecker = countRoomAdrminChecker;
|
||||
_activeUsersFeatureChecker = activeUsersFeatureChecker;
|
||||
_constants = _userManagerConstants.Constants;
|
||||
}
|
||||
@ -135,7 +135,7 @@ public class UserManager
|
||||
}
|
||||
|
||||
|
||||
#region Users
|
||||
#region Users
|
||||
|
||||
public UserInfo[] GetUsers()
|
||||
{
|
||||
@ -198,7 +198,7 @@ public class UserManager
|
||||
public UserInfo GetUserBySid(string sid)
|
||||
{
|
||||
return GetUsersInternal()
|
||||
.FirstOrDefault(u => u.Sid != null && string.Equals(u.Sid, sid, StringComparison.CurrentCultureIgnoreCase)) ?? Constants.LostUser;
|
||||
.FirstOrDefault(u => u.Sid != null && string.Equals(u.Sid, sid, StringComparison.CurrentCultureIgnoreCase)) ?? Constants.LostUser;
|
||||
}
|
||||
|
||||
public UserInfo GetSsoUserByNameId(string nameId)
|
||||
@ -296,11 +296,11 @@ public class UserManager
|
||||
foreach (var user in users)
|
||||
{
|
||||
var properties = new string[]
|
||||
{
|
||||
user.LastName ?? string.Empty,
|
||||
user.FirstName ?? string.Empty,
|
||||
user.Title ?? string.Empty,
|
||||
user.Location ?? string.Empty,
|
||||
{
|
||||
user.LastName ?? string.Empty,
|
||||
user.FirstName ?? string.Empty,
|
||||
user.Title ?? string.Empty,
|
||||
user.Location ?? string.Empty,
|
||||
user.Email ?? string.Empty,
|
||||
};
|
||||
if (IsPropertiesContainsWords(properties, words))
|
||||
@ -312,22 +312,49 @@ public class UserManager
|
||||
return findUsers.ToArray();
|
||||
}
|
||||
|
||||
public UserInfo SaveUserInfo(UserInfo u, bool isUser = false, bool syncCardDav = false)
|
||||
public UserInfo UpdateUserInfo(UserInfo u)
|
||||
{
|
||||
if (IsSystemUser(u.Id))
|
||||
{
|
||||
return SystemUsers[u.Id];
|
||||
}
|
||||
|
||||
if (u.Id == Guid.Empty)
|
||||
_permissionContext.DemandPermissions(new UserSecurityProvider(u.Id), Constants.Action_EditUser);
|
||||
|
||||
if (u.Status == EmployeeStatus.Terminated && u.Id == _tenantManager.GetCurrentTenant().OwnerId)
|
||||
{
|
||||
_permissionContext.DemandPermissions(Constants.Action_AddRemoveUser);
|
||||
throw new InvalidOperationException("Can not disable tenant owner.");
|
||||
}
|
||||
else
|
||||
|
||||
var oldUserData = _userService.GetUserByUserName(_tenantManager.GetCurrentTenant().Id, u.UserName);
|
||||
|
||||
if (oldUserData == null || Equals(oldUserData, Constants.LostUser))
|
||||
{
|
||||
_permissionContext.DemandPermissions(new UserSecurityProvider(u.Id), Constants.Action_EditUser);
|
||||
throw new InvalidOperationException("User not found.");
|
||||
}
|
||||
|
||||
return _userService.SaveUser(_tenantManager.GetCurrentTenant().Id, u);
|
||||
}
|
||||
|
||||
public async Task<UserInfo> UpdateUserInfoWithSyncCardDavAsync(UserInfo u)
|
||||
{
|
||||
var oldUserData = _userService.GetUserByUserName(_tenantManager.GetCurrentTenant().Id, u.UserName);
|
||||
|
||||
var newUser = UpdateUserInfo(u);
|
||||
await SyncCardDavAsync(u, oldUserData, newUser);
|
||||
|
||||
return newUser;
|
||||
}
|
||||
|
||||
public async Task<UserInfo> SaveUserInfo(UserInfo u, bool isVisitor = false, bool syncCardDav = false)
|
||||
{
|
||||
if (IsSystemUser(u.Id))
|
||||
{
|
||||
return SystemUsers[u.Id];
|
||||
}
|
||||
|
||||
_permissionContext.DemandPermissions(Constants.Action_AddRemoveUser);
|
||||
|
||||
if (!_coreBaseSettings.Personal)
|
||||
{
|
||||
if (_constants.MaxEveryoneCount <= GetUsersByGroup(Constants.GroupEveryone.ID).Length)
|
||||
@ -336,97 +363,96 @@ public class UserManager
|
||||
}
|
||||
}
|
||||
|
||||
if (u.Status == EmployeeStatus.Terminated && u.Id == _tenantManager.GetCurrentTenant().OwnerId)
|
||||
{
|
||||
throw new InvalidOperationException("Can not disable tenant owner.");
|
||||
}
|
||||
|
||||
var oldUserData = _userService.GetUserByUserName(_tenantManager.GetCurrentTenant().Id, u.UserName);
|
||||
|
||||
if (Equals(oldUserData, Constants.LostUser))
|
||||
if (oldUserData != null && !Equals(oldUserData, Constants.LostUser))
|
||||
{
|
||||
if (isUser)
|
||||
{
|
||||
_activeUsersFeatureChecker.CheckAppend().Wait();
|
||||
}
|
||||
else
|
||||
{
|
||||
_tenantQuotaFeatureChecker.CheckAppend().Wait();
|
||||
}
|
||||
throw new InvalidOperationException("User already exist.");
|
||||
}
|
||||
|
||||
if (isVisitor)
|
||||
{
|
||||
await _activeUsersFeatureChecker.CheckAppend();
|
||||
}
|
||||
else
|
||||
{
|
||||
await _countRoomAdminChecker.CheckAppend();
|
||||
}
|
||||
|
||||
var newUser = _userService.SaveUser(_tenantManager.GetCurrentTenant().Id, u);
|
||||
|
||||
if (syncCardDav)
|
||||
{
|
||||
var tenant = _tenantManager.GetCurrentTenant();
|
||||
var myUri = (_accessor?.HttpContext != null) ? _accessor.HttpContext.Request.GetUrlRewriter().ToString() :
|
||||
(_cache.Get<string>("REWRITE_URL" + tenant.Id) != null) ?
|
||||
new Uri(_cache.Get<string>("REWRITE_URL" + tenant.Id)).ToString() : tenant.GetTenantDomain(_coreSettings);
|
||||
await SyncCardDavAsync(u, oldUserData, newUser);
|
||||
}
|
||||
|
||||
var rootAuthorization = _cardDavAddressbook.GetSystemAuthorization();
|
||||
var allUserEmails = GetDavUserEmails().ToList();
|
||||
return newUser;
|
||||
}
|
||||
|
||||
if (oldUserData != null && oldUserData.Status != newUser.Status && newUser.Status == EmployeeStatus.Terminated)
|
||||
private async Task SyncCardDavAsync(UserInfo u, UserInfo oldUserData, UserInfo newUser)
|
||||
{
|
||||
var tenant = _tenantManager.GetCurrentTenant();
|
||||
var myUri = (_accessor?.HttpContext != null) ? _accessor.HttpContext.Request.GetUrlRewriter().ToString() :
|
||||
(_cache.Get<string>("REWRITE_URL" + tenant.Id) != null) ?
|
||||
new Uri(_cache.Get<string>("REWRITE_URL" + tenant.Id)).ToString() : tenant.GetTenantDomain(_coreSettings);
|
||||
|
||||
var rootAuthorization = _cardDavAddressbook.GetSystemAuthorization();
|
||||
var allUserEmails = GetDavUserEmails().ToList();
|
||||
|
||||
if (oldUserData != null && oldUserData.Status != newUser.Status && newUser.Status == EmployeeStatus.Terminated)
|
||||
{
|
||||
var userAuthorization = oldUserData.Email.ToLower() + ":" + _instanceCrypto.Encrypt(oldUserData.Email);
|
||||
var requestUrlBook = _cardDavAddressbook.GetRadicaleUrl(myUri, newUser.Email.ToLower(), true, true);
|
||||
var collection = await _cardDavAddressbook.GetCollection(requestUrlBook, userAuthorization, myUri.ToString());
|
||||
if (collection.Completed && collection.StatusCode != 404)
|
||||
{
|
||||
var userAuthorization = oldUserData.Email.ToLower() + ":" + _instanceCrypto.Encrypt(oldUserData.Email);
|
||||
var requestUrlBook = _cardDavAddressbook.GetRadicaleUrl(myUri, newUser.Email.ToLower(), true, true);
|
||||
var collection = _cardDavAddressbook.GetCollection(requestUrlBook, userAuthorization, myUri.ToString()).Result;
|
||||
if (collection.Completed && collection.StatusCode != 404)
|
||||
{
|
||||
_cardDavAddressbook.Delete(myUri, newUser.Id, newUser.Email, tenant.Id).Wait();//TODO
|
||||
}
|
||||
foreach (var email in allUserEmails)
|
||||
{
|
||||
var requestUrlItem = _cardDavAddressbook.GetRadicaleUrl(myUri.ToString(), email.ToLower(), true, true, itemID: newUser.Id.ToString());
|
||||
try
|
||||
{
|
||||
var davItemRequest = new DavRequest()
|
||||
{
|
||||
Url = requestUrlItem,
|
||||
Authorization = rootAuthorization,
|
||||
Header = myUri
|
||||
};
|
||||
_radicaleClient.RemoveAsync(davItemRequest).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_log.ErrorWithException(ex);
|
||||
}
|
||||
}
|
||||
await _cardDavAddressbook.Delete(myUri, newUser.Id, newUser.Email, tenant.Id);
|
||||
}
|
||||
else
|
||||
foreach (var email in allUserEmails)
|
||||
{
|
||||
|
||||
var requestUrlItem = _cardDavAddressbook.GetRadicaleUrl(myUri.ToString(), email.ToLower(), true, true, itemID: newUser.Id.ToString());
|
||||
try
|
||||
{
|
||||
var cardDavUser = new CardDavItem(u.Id, u.FirstName, u.LastName, u.UserName, u.BirthDate, u.Sex, u.Title, u.Email, u.ContactsList, u.MobilePhone);
|
||||
|
||||
try
|
||||
var davItemRequest = new DavRequest()
|
||||
{
|
||||
_cardDavAddressbook.UpdateItemForAllAddBooks(allUserEmails, myUri, cardDavUser, _tenantManager.GetCurrentTenant().Id, oldUserData != null && oldUserData.Email != newUser.Email ? oldUserData.Email : null).Wait(); // todo
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_log.ErrorWithException(ex);
|
||||
}
|
||||
|
||||
Url = requestUrlItem,
|
||||
Authorization = rootAuthorization,
|
||||
Header = myUri
|
||||
};
|
||||
await _radicaleClient.RemoveAsync(davItemRequest).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_log.ErrorWithException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return newUser;
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
var cardDavUser = new CardDavItem(u.Id, u.FirstName, u.LastName, u.UserName, u.BirthDate, u.Sex, u.Title, u.Email, u.ContactsList, u.MobilePhone);
|
||||
try
|
||||
{
|
||||
await _cardDavAddressbook.UpdateItemForAllAddBooks(allUserEmails, myUri, cardDavUser, _tenantManager.GetCurrentTenant().Id, oldUserData != null && oldUserData.Email != newUser.Email ? oldUserData.Email : null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_log.ErrorWithException(ex);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_log.ErrorWithException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetDavUserEmails()
|
||||
{
|
||||
return _userService.GetDavUserEmails(_tenantManager.GetCurrentTenant().Id);
|
||||
}
|
||||
|
||||
public void DeleteUser(Guid id)
|
||||
public async Task DeleteUser(Guid id)
|
||||
{
|
||||
if (IsSystemUser(id))
|
||||
{
|
||||
@ -454,7 +480,7 @@ public class UserManager
|
||||
new Uri(_cache.Get<string>("REWRITE_URL" + tenant.Id)).ToString() : tenant.GetTenantDomain(_coreSettings);
|
||||
var davUsersEmails = GetDavUserEmails();
|
||||
var requestUrlBook = _cardDavAddressbook.GetRadicaleUrl(myUri, delUser.Email.ToLower(), true, true);
|
||||
var addBookCollection = _cardDavAddressbook.GetCollection(requestUrlBook, userAuthorization, myUri.ToString()).Result;
|
||||
var addBookCollection = await _cardDavAddressbook.GetCollection(requestUrlBook, userAuthorization, myUri.ToString());
|
||||
|
||||
|
||||
if (addBookCollection.Completed && addBookCollection.StatusCode != 404)
|
||||
@ -465,7 +491,7 @@ public class UserManager
|
||||
Authorization = rootAuthorization,
|
||||
Header = myUri
|
||||
};
|
||||
_radicaleClient.RemoveAsync(davbookRequest).ConfigureAwait(false);
|
||||
await _radicaleClient.RemoveAsync(davbookRequest).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
foreach (var email in davUsersEmails)
|
||||
@ -479,14 +505,13 @@ public class UserManager
|
||||
Authorization = rootAuthorization,
|
||||
Header = myUri
|
||||
};
|
||||
_radicaleClient.RemoveAsync(davItemRequest).ConfigureAwait(false);
|
||||
await _radicaleClient.RemoveAsync(davItemRequest).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_log.ErrorWithException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -600,7 +625,7 @@ public class UserManager
|
||||
return GetUsers(employeeStatus).Where(u => IsUserInGroupInternal(u.Id, groupId, refs)).ToArray();
|
||||
}
|
||||
|
||||
public void AddUserIntoGroup(Guid userId, Guid groupId, bool dontClearAddressBook = false)
|
||||
public async Task AddUserIntoGroup(Guid userId, Guid groupId, bool dontClearAddressBook = false)
|
||||
{
|
||||
if (Constants.LostUser.Id == userId || Constants.LostGroupInfo.ID == groupId)
|
||||
{
|
||||
@ -618,10 +643,10 @@ public class UserManager
|
||||
var myUri = (_accessor?.HttpContext != null) ? _accessor.HttpContext.Request.GetUrlRewriter().ToString() :
|
||||
(_cache.Get<string>("REWRITE_URL" + tenant.Id) != null) ?
|
||||
new Uri(_cache.Get<string>("REWRITE_URL" + tenant.Id)).ToString() : tenant.GetTenantDomain(_coreSettings);
|
||||
|
||||
|
||||
if (!dontClearAddressBook)
|
||||
{
|
||||
_cardDavAddressbook.Delete(myUri, user.Id, user.Email, tenant.Id).Wait(); //todo
|
||||
await _cardDavAddressbook.Delete(myUri, user.Id, user.Email, tenant.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -646,10 +671,10 @@ public class UserManager
|
||||
new HttpRequestDictionary<List<Guid>>(_accessor?.HttpContext, "GroupInfoID").Reset(userID.ToString());
|
||||
}
|
||||
|
||||
#endregion Users
|
||||
#endregion Users
|
||||
|
||||
|
||||
#region Company
|
||||
#region Company
|
||||
|
||||
public GroupInfo[] GetDepartments()
|
||||
{
|
||||
@ -697,10 +722,10 @@ public class UserManager
|
||||
SetDepartmentManager(Guid.Empty, userId);
|
||||
}
|
||||
|
||||
#endregion Company
|
||||
#endregion Company
|
||||
|
||||
|
||||
#region Groups
|
||||
#region Groups
|
||||
|
||||
public GroupInfo[] GetGroups()
|
||||
{
|
||||
@ -779,7 +804,7 @@ public class UserManager
|
||||
_userService.RemoveGroup(Tenant.Id, id);
|
||||
}
|
||||
|
||||
#endregion Groups
|
||||
#endregion Groups
|
||||
|
||||
|
||||
private bool IsPropertiesContainsWords(IEnumerable<string> properties, IEnumerable<string> words)
|
||||
@ -873,4 +898,4 @@ public class UserManager
|
||||
Sid = g.Sid
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ public class SecurityContext
|
||||
return AuthenticateMe(new UserAccount(u, tenantid, _userFormatter), funcLoginEvent);
|
||||
}
|
||||
|
||||
public bool AuthenticateMe(string cookie)
|
||||
public async Task<bool> AuthenticateMe(string cookie)
|
||||
{
|
||||
if (string.IsNullOrEmpty(cookie)) return false;
|
||||
|
||||
@ -161,8 +161,9 @@ public class SecurityContext
|
||||
return false;
|
||||
}
|
||||
|
||||
var settingLoginEvents = _dbLoginEventsManager.GetLoginEventIds(tenant, userid).Result; // remove Result
|
||||
if (loginEventId != 0 && !settingLoginEvents.Contains(loginEventId))
|
||||
var loginEventById = await _dbLoginEventsManager.GetById(loginEventId);
|
||||
|
||||
if (loginEventById == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
32
common/ASC.Core.Common/Core/Payments.cs
Normal file
32
common/ASC.Core.Common/Core/Payments.cs
Normal file
@ -0,0 +1,32 @@
|
||||
// (c) Copyright Ascensio System SIA 2010-2022
|
||||
//
|
||||
// This program is a free software product.
|
||||
// You can redistribute it and/or modify it under the terms
|
||||
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
|
||||
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
|
||||
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
|
||||
// any third-party rights.
|
||||
//
|
||||
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
|
||||
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
|
||||
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||||
//
|
||||
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
|
||||
//
|
||||
// The interactive user interfaces in modified source and object code versions of the Program must
|
||||
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
|
||||
//
|
||||
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
|
||||
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
|
||||
// trademark law for use of our trademarks.
|
||||
//
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Core;
|
||||
public enum Payments
|
||||
{
|
||||
Paid = 0,
|
||||
Free = 1
|
||||
}
|
@ -24,6 +24,8 @@
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace ASC.Core.Data;
|
||||
|
||||
[Scope]
|
||||
@ -61,26 +63,22 @@ public class DbLoginEventsManager
|
||||
_dbContextFactory = dbContextFactory;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
public async Task<List<int>> GetLoginEventIds(int tenantId, Guid userId)
|
||||
|
||||
public async Task<LoginEvent> GetById(int id)
|
||||
{
|
||||
var date = DateTime.UtcNow.AddYears(-1);
|
||||
if (id < 0) return null;
|
||||
|
||||
using var loginEventContext = _dbContextFactory.CreateDbContext();
|
||||
|
||||
var resultList = await loginEventContext.LoginEvents
|
||||
.Where(r => r.TenantId == tenantId && r.UserId == userId && _loginActions.Contains(r.Action ?? 0) && r.Date >= date && r.Active)
|
||||
.Select(r => r.Id)
|
||||
.ToListAsync();
|
||||
|
||||
return resultList;
|
||||
}
|
||||
using var loginEventContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
|
||||
return await loginEventContext.LoginEvents.FindAsync(id);
|
||||
}
|
||||
|
||||
public async Task<List<BaseEvent>> GetLoginEvents(int tenantId, Guid userId)
|
||||
{
|
||||
var date = DateTime.UtcNow.AddYears(-1);
|
||||
|
||||
using var loginEventContext = _dbContextFactory.CreateDbContext();
|
||||
using var loginEventContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
|
||||
var loginInfo = await loginEventContext.LoginEvents
|
||||
.Where(r => r.TenantId == tenantId && r.UserId == userId && _loginActions.Contains(r.Action ?? 0) && r.Date >= date && r.Active)
|
||||
.OrderByDescending(r => r.Id)
|
||||
@ -91,7 +89,8 @@ public class DbLoginEventsManager
|
||||
|
||||
public async Task LogOutEvent(int loginEventId)
|
||||
{
|
||||
using var loginEventContext = _dbContextFactory.CreateDbContext();
|
||||
using var loginEventContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
|
||||
var events = await loginEventContext.LoginEvents
|
||||
.Where(r => r.Id == loginEventId)
|
||||
.ToListAsync();
|
||||
@ -108,7 +107,8 @@ public class DbLoginEventsManager
|
||||
|
||||
public async Task LogOutAllActiveConnections(int tenantId, Guid userId)
|
||||
{
|
||||
using var loginEventContext = _dbContextFactory.CreateDbContext();
|
||||
using var loginEventContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
|
||||
var events = await loginEventContext.LoginEvents
|
||||
.Where(r => r.TenantId == tenantId && r.UserId == userId && r.Active)
|
||||
.ToListAsync();
|
||||
@ -125,7 +125,8 @@ public class DbLoginEventsManager
|
||||
|
||||
public async Task LogOutAllActiveConnectionsForTenant(int tenantId)
|
||||
{
|
||||
using var loginEventContext = _dbContextFactory.CreateDbContext();
|
||||
using var loginEventContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
|
||||
var events = await loginEventContext.LoginEvents
|
||||
.Where(r => r.TenantId == tenantId && r.Active)
|
||||
.ToListAsync();
|
||||
@ -140,7 +141,8 @@ public class DbLoginEventsManager
|
||||
|
||||
public async Task LogOutAllActiveConnectionsExceptThis(int loginEventId, int tenantId, Guid userId)
|
||||
{
|
||||
using var loginEventContext = _dbContextFactory.CreateDbContext();
|
||||
using var loginEventContext = await _dbContextFactory.CreateDbContextAsync();
|
||||
|
||||
var events = await loginEventContext.LoginEvents
|
||||
.Where(r => r.TenantId == tenantId && r.UserId == userId && r.Id != loginEventId && r.Active)
|
||||
.ToListAsync();
|
||||
|
@ -221,7 +221,18 @@ public class EFUserService : IUserService
|
||||
|
||||
if (!string.IsNullOrEmpty(sortBy))
|
||||
{
|
||||
q = q.OrderBy(sortBy, sortOrderAsc);
|
||||
if (sortBy == "type")
|
||||
{
|
||||
var q1 = from user in q join userGroup in userDbContext.UserGroups.Where(g => !g.Removed && (g.UserGroupId == Users.Constants.GroupAdmin.ID || g.UserGroupId == Users.Constants.GroupUser.ID))
|
||||
on user.Id equals userGroup.Userid into joinedGroup from @group in joinedGroup.DefaultIfEmpty() select new { user, @group };
|
||||
|
||||
q = sortOrderAsc ? q1.OrderBy(r => r.group != null && r.group.UserGroupId == Users.Constants.GroupAdmin.ID ? 1 : r.group == null ? 2 : 3).Select(r => r.user)
|
||||
: q1.OrderByDescending(u => u.group != null && u.group.UserGroupId == Users.Constants.GroupAdmin.ID ? 1 : u.group == null ? 2 : 3).Select(r => r.user);
|
||||
}
|
||||
else
|
||||
{
|
||||
q = q.OrderBy(sortBy, sortOrderAsc);
|
||||
}
|
||||
}
|
||||
|
||||
if (offset != 0)
|
||||
|
@ -59,7 +59,7 @@ public static class BaseDbContextExtension
|
||||
{
|
||||
case Provider.MySql:
|
||||
optionsBuilder.ReplaceService<IMigrationsSqlGenerator, CustomMySqlMigrationsSqlGenerator>();
|
||||
optionsBuilder.UseMySql(connectionString.ConnectionString, ServerVersion.Parse("8.0.25"), providerOptions =>
|
||||
optionsBuilder.UseMySql(connectionString.ConnectionString, ServerVersion.AutoDetect(connectionString.ConnectionString), providerOptions =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(migrateAssembly))
|
||||
{
|
||||
|
@ -23,16 +23,13 @@
|
||||
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
global using System;
|
||||
|
||||
global using System.Collections;
|
||||
global using System.Collections.Concurrent;
|
||||
global using System.Collections.Generic;
|
||||
global using System.Configuration;
|
||||
global using System.Data.Common;
|
||||
global using System.Diagnostics;
|
||||
global using System.Globalization;
|
||||
global using System.Linq;
|
||||
global using System.Linq.Expressions;
|
||||
global using System.Net;
|
||||
global using System.Net.Http.Headers;
|
||||
|
@ -29,6 +29,6 @@ namespace ASC.Notify.Channels;
|
||||
public interface ISenderChannel
|
||||
{
|
||||
string SenderName { get; }
|
||||
SendResponse DirectSend(INoticeMessage message);
|
||||
void SendAsync(INoticeMessage message);
|
||||
Task<SendResponse> DirectSend(INoticeMessage message);
|
||||
Task SendAsync(INoticeMessage message);
|
||||
}
|
||||
|
@ -45,16 +45,16 @@ public class SenderChannel : ISenderChannel
|
||||
_firstSink = AddSink(_firstSink, dispatcherSink);
|
||||
}
|
||||
|
||||
public void SendAsync(INoticeMessage message)
|
||||
public async Task SendAsync(INoticeMessage message)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(message);
|
||||
|
||||
_firstSink.ProcessMessageAsync(message);
|
||||
await _firstSink.ProcessMessageAsync(message);
|
||||
}
|
||||
|
||||
public SendResponse DirectSend(INoticeMessage message)
|
||||
public async Task<SendResponse> DirectSend(INoticeMessage message)
|
||||
{
|
||||
return _senderSink.ProcessMessage(message);
|
||||
return await _senderSink.ProcessMessage(message);
|
||||
}
|
||||
|
||||
private ISink AddSink(ISink firstSink, ISink addedSink)
|
||||
|
@ -38,7 +38,7 @@ public class EmailSenderSink : Sink
|
||||
_serviceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
public override SendResponse ProcessMessage(INoticeMessage message)
|
||||
public override async Task<SendResponse> ProcessMessage(INoticeMessage message)
|
||||
{
|
||||
if (message.Recipient.Addresses == null || message.Recipient.Addresses.Length == 0)
|
||||
{
|
||||
@ -50,7 +50,7 @@ public class EmailSenderSink : Sink
|
||||
{
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
var m = scope.ServiceProvider.GetRequiredService<EmailSenderSinkMessageCreator>().CreateNotifyMessage(message, _senderName);
|
||||
var result = _sender.Send(m);
|
||||
var result = await _sender.Send(m);
|
||||
|
||||
responce.Result = result switch
|
||||
{
|
||||
|
@ -43,7 +43,7 @@ public class DispatchEngine
|
||||
_logger.LogOnly(_logOnly);
|
||||
}
|
||||
|
||||
public SendResponse Dispatch(INoticeMessage message, string senderName)
|
||||
public async Task<SendResponse> Dispatch(INoticeMessage message, string senderName)
|
||||
{
|
||||
var response = new SendResponse(message, senderName, SendResult.OK);
|
||||
if (!_logOnly)
|
||||
@ -51,7 +51,7 @@ public class DispatchEngine
|
||||
var sender = _context.GetSender(senderName);
|
||||
if (sender != null)
|
||||
{
|
||||
response = sender.DirectSend(message);
|
||||
response = await sender.DirectSend(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -110,7 +110,7 @@ public class NotifyEngine : INotifyEngine, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
private void NotifyScheduler(object state)
|
||||
private async void NotifyScheduler(object state)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -124,8 +124,9 @@ public class NotifyEngine : INotifyEngine, IDisposable
|
||||
copy = _sendMethods.ToList();
|
||||
}
|
||||
|
||||
foreach (var w in copy)
|
||||
for (var i = 0; i < copy.Count; i++)
|
||||
{
|
||||
using var w = copy[i];
|
||||
if (!w.ScheduleDate.HasValue)
|
||||
{
|
||||
lock (_sendMethods)
|
||||
@ -138,7 +139,7 @@ public class NotifyEngine : INotifyEngine, IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
w.InvokeSendMethod(now);
|
||||
await w.InvokeSendMethod(now);
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
@ -177,7 +178,7 @@ public class NotifyEngine : INotifyEngine, IDisposable
|
||||
}
|
||||
|
||||
|
||||
private void NotifySender(object state)
|
||||
private async void NotifySender(object state)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -201,7 +202,7 @@ public class NotifyEngine : INotifyEngine, IDisposable
|
||||
|
||||
try
|
||||
{
|
||||
SendNotify(request, scope);
|
||||
await SendNotify(request, scope);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -225,7 +226,7 @@ public class NotifyEngine : INotifyEngine, IDisposable
|
||||
}
|
||||
|
||||
|
||||
private NotifyResult SendNotify(NotifyRequest request, IServiceScope serviceScope)
|
||||
private async Task<NotifyResult> SendNotify(NotifyRequest request, IServiceScope serviceScope)
|
||||
{
|
||||
var sendResponces = new List<SendResponse>();
|
||||
|
||||
@ -236,7 +237,7 @@ public class NotifyEngine : INotifyEngine, IDisposable
|
||||
}
|
||||
else
|
||||
{
|
||||
sendResponces.AddRange(SendGroupNotify(request, serviceScope));
|
||||
sendResponces.AddRange(await SendGroupNotify(request, serviceScope));
|
||||
}
|
||||
|
||||
NotifyResult result;
|
||||
@ -258,15 +259,15 @@ public class NotifyEngine : INotifyEngine, IDisposable
|
||||
return request.Intercept(place, serviceScope) ? new SendResponse(request.NotifyAction, sender, request.Recipient, SendResult.Prevented) : null;
|
||||
}
|
||||
|
||||
private List<SendResponse> SendGroupNotify(NotifyRequest request, IServiceScope serviceScope)
|
||||
private async Task<List<SendResponse>> SendGroupNotify(NotifyRequest request, IServiceScope serviceScope)
|
||||
{
|
||||
var responces = new List<SendResponse>();
|
||||
SendGroupNotify(request, responces, serviceScope);
|
||||
await SendGroupNotify(request, responces, serviceScope);
|
||||
|
||||
return responces;
|
||||
}
|
||||
|
||||
private void SendGroupNotify(NotifyRequest request, List<SendResponse> responces, IServiceScope serviceScope)
|
||||
private async Task SendGroupNotify(NotifyRequest request, List<SendResponse> responces, IServiceScope serviceScope)
|
||||
{
|
||||
if (request.Recipient is IDirectRecipient)
|
||||
{
|
||||
@ -276,7 +277,7 @@ public class NotifyEngine : INotifyEngine, IDisposable
|
||||
var directresponses = new List<SendResponse>(1);
|
||||
try
|
||||
{
|
||||
directresponses = SendDirectNotify(request, serviceScope);
|
||||
directresponses = await SendDirectNotify(request, serviceScope);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
@ -308,7 +309,7 @@ public class NotifyEngine : INotifyEngine, IDisposable
|
||||
try
|
||||
{
|
||||
var newRequest = request.Split(recipient);
|
||||
SendGroupNotify(newRequest, responces, serviceScope);
|
||||
await SendGroupNotify(newRequest, responces, serviceScope);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
@ -334,7 +335,7 @@ public class NotifyEngine : INotifyEngine, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
private List<SendResponse> SendDirectNotify(NotifyRequest request, IServiceScope serviceScope)
|
||||
private async Task<List<SendResponse>> SendDirectNotify(NotifyRequest request, IServiceScope serviceScope)
|
||||
{
|
||||
if (request.Recipient is not IDirectRecipient)
|
||||
{
|
||||
@ -371,7 +372,7 @@ public class NotifyEngine : INotifyEngine, IDisposable
|
||||
{
|
||||
try
|
||||
{
|
||||
response = SendDirectNotify(request, channel, serviceScope);
|
||||
response = await SendDirectNotify(request, channel, serviceScope);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
@ -396,7 +397,7 @@ public class NotifyEngine : INotifyEngine, IDisposable
|
||||
return responses;
|
||||
}
|
||||
|
||||
private SendResponse SendDirectNotify(NotifyRequest request, ISenderChannel channel, IServiceScope serviceScope)
|
||||
private async Task<SendResponse> SendDirectNotify(NotifyRequest request, ISenderChannel channel, IServiceScope serviceScope)
|
||||
{
|
||||
if (request.Recipient is not IDirectRecipient)
|
||||
{
|
||||
@ -418,7 +419,7 @@ public class NotifyEngine : INotifyEngine, IDisposable
|
||||
return preventresponse;
|
||||
}
|
||||
|
||||
channel.SendAsync(noticeMessage);
|
||||
await channel.SendAsync(noticeMessage);
|
||||
|
||||
return new SendResponse(noticeMessage, channel.SenderName, SendResult.Inprogress);
|
||||
}
|
||||
@ -585,19 +586,21 @@ public class NotifyEngine : INotifyEngine, IDisposable
|
||||
}
|
||||
|
||||
|
||||
private sealed class SendMethodWrapper
|
||||
private sealed class SendMethodWrapper : IDisposable
|
||||
{
|
||||
private readonly object _locker = new object();
|
||||
private readonly SemaphoreSlim _semaphore;
|
||||
private readonly CronExpression _cronExpression;
|
||||
private readonly Action<DateTime> _method;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public DateTime? ScheduleDate { get; private set; }
|
||||
public ILogger Logger { get; }
|
||||
|
||||
public SendMethodWrapper(Action<DateTime> method, string cron, ILogger log)
|
||||
{
|
||||
_semaphore = new SemaphoreSlim(1);
|
||||
_method = method;
|
||||
Logger = log;
|
||||
_logger = log;
|
||||
|
||||
if (!string.IsNullOrEmpty(cron))
|
||||
{
|
||||
_cronExpression = new CronExpression(cron);
|
||||
@ -617,26 +620,25 @@ public class NotifyEngine : INotifyEngine, IDisposable
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.ErrorUpdateScheduleDate(e);
|
||||
_logger.ErrorUpdateScheduleDate(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void InvokeSendMethod(DateTime d)
|
||||
public async Task InvokeSendMethod(DateTime d)
|
||||
{
|
||||
lock (_locker)
|
||||
await _semaphore.WaitAsync();
|
||||
await Task.Run(() =>
|
||||
{
|
||||
Task.Run(() =>
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
_method(d);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.ErrorInvokeSendMethod(e);
|
||||
}
|
||||
}).Wait();
|
||||
}
|
||||
_method(d);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.ErrorInvokeSendMethod(e);
|
||||
}
|
||||
});
|
||||
_semaphore.Release();
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
@ -648,6 +650,11 @@ public class NotifyEngine : INotifyEngine, IDisposable
|
||||
{
|
||||
return _method.GetHashCode();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_semaphore.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
@ -39,7 +39,7 @@ class JabberSenderSink : Sink
|
||||
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
public override SendResponse ProcessMessage(INoticeMessage message)
|
||||
public override async Task<SendResponse> ProcessMessage(INoticeMessage message)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -53,7 +53,7 @@ class JabberSenderSink : Sink
|
||||
}
|
||||
else
|
||||
{
|
||||
_sender.Send(m);
|
||||
await _sender.Send(m);
|
||||
}
|
||||
|
||||
return new SendResponse(message, _senderName, result);
|
||||
|
@ -43,7 +43,7 @@ class PushSenderSink : Sink
|
||||
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
public override SendResponse ProcessMessage(INoticeMessage message)
|
||||
public override async Task<SendResponse> ProcessMessage(INoticeMessage message)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -58,7 +58,7 @@ class PushSenderSink : Sink
|
||||
}
|
||||
else
|
||||
{
|
||||
_sender.Send(m);
|
||||
await _sender.Send(m);
|
||||
}
|
||||
|
||||
return new SendResponse(message, Constants.NotifyPushSenderSysName, result);
|
||||
|
@ -31,7 +31,7 @@ namespace ASC.Core.Notify.Senders;
|
||||
[Singletone]
|
||||
public class AWSSender : SmtpSender, IDisposable
|
||||
{
|
||||
private readonly object _locker = new object();
|
||||
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1);
|
||||
private AmazonSimpleEmailServiceClient _amazonEmailServiceClient;
|
||||
private TimeSpan _refreshTimeout;
|
||||
private DateTime _lastRefresh;
|
||||
@ -56,7 +56,7 @@ public class AWSSender : SmtpSender, IDisposable
|
||||
_lastRefresh = DateTime.UtcNow - _refreshTimeout; //set to refresh on first send
|
||||
}
|
||||
|
||||
public override NoticeSendResult Send(NotifyMessage m)
|
||||
public override async Task<NoticeSendResult> Send(NotifyMessage m)
|
||||
{
|
||||
NoticeSendResult result;
|
||||
try
|
||||
@ -71,11 +71,11 @@ public class AWSSender : SmtpSender, IDisposable
|
||||
var configuration = scope.ServiceProvider.GetService<CoreConfiguration>();
|
||||
if (!configuration.SmtpSettings.IsDefaultSettings)
|
||||
{
|
||||
result = base.Send(m);
|
||||
result = await base.Send(m);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = SendMessage(m);
|
||||
result = await SendMessage(m);
|
||||
}
|
||||
|
||||
_logger.Debug(result.ToString());
|
||||
@ -106,29 +106,28 @@ public class AWSSender : SmtpSender, IDisposable
|
||||
if (result == NoticeSendResult.MessageIncorrect || result == NoticeSendResult.SendingImpossible)
|
||||
{
|
||||
_logger.DebugAmazonSendingFailed(result);
|
||||
result = base.Send(m);
|
||||
result = await base.Send(m);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private NoticeSendResult SendMessage(NotifyMessage m)
|
||||
private async Task<NoticeSendResult> SendMessage(NotifyMessage m)
|
||||
{
|
||||
//Check if we need to query stats
|
||||
RefreshQuotaIfNeeded();
|
||||
await RefreshQuotaIfNeeded();
|
||||
if (_quota != null)
|
||||
{
|
||||
lock (_locker)
|
||||
await _semaphore.WaitAsync();
|
||||
if (_quota.Max24HourSend <= _quota.SentLast24Hours)
|
||||
{
|
||||
if (_quota.Max24HourSend <= _quota.SentLast24Hours)
|
||||
{
|
||||
//Quota exceeded, queue next refresh to +24 hours
|
||||
_lastRefresh = DateTime.UtcNow.AddHours(24);
|
||||
_logger.WarningQuotaLimit(_lastRefresh);
|
||||
//Quota exceeded, queue next refresh to +24 hours
|
||||
_lastRefresh = DateTime.UtcNow.AddHours(24);
|
||||
_logger.WarningQuotaLimit(_lastRefresh);
|
||||
|
||||
return NoticeSendResult.SendingImpossible;
|
||||
}
|
||||
return NoticeSendResult.SendingImpossible;
|
||||
}
|
||||
_semaphore.Release();
|
||||
}
|
||||
|
||||
var dest = new Destination
|
||||
@ -160,7 +159,7 @@ public class AWSSender : SmtpSender, IDisposable
|
||||
|
||||
ThrottleIfNeeded();
|
||||
|
||||
var response = _amazonEmailServiceClient.SendEmailAsync(request).Result;
|
||||
var response = await _amazonEmailServiceClient.SendEmailAsync(request);
|
||||
_lastSend = DateTime.UtcNow;
|
||||
|
||||
return response != null ? NoticeSendResult.OK : NoticeSendResult.TryOnceAgain;
|
||||
@ -182,34 +181,33 @@ public class AWSSender : SmtpSender, IDisposable
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshQuotaIfNeeded()
|
||||
private async Task RefreshQuotaIfNeeded()
|
||||
{
|
||||
if (!IsRefreshNeeded())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (_locker)
|
||||
await _semaphore.WaitAsync();
|
||||
if (IsRefreshNeeded())//Double check
|
||||
{
|
||||
if (IsRefreshNeeded())//Double check
|
||||
{
|
||||
_logger.DebugRefreshingQuota(_refreshTimeout, _lastRefresh);
|
||||
_logger.DebugRefreshingQuota(_refreshTimeout, _lastRefresh);
|
||||
|
||||
//Do quota refresh
|
||||
_lastRefresh = DateTime.UtcNow.AddMinutes(1);
|
||||
try
|
||||
{
|
||||
var r = new GetSendQuotaRequest();
|
||||
_quota = _amazonEmailServiceClient.GetSendQuotaAsync(r).Result;
|
||||
_sendWindow = TimeSpan.FromSeconds(1.0 / _quota.MaxSendRate);
|
||||
_logger.DebugQuota(_quota.SentLast24Hours, _quota.Max24HourSend, _quota.MaxSendRate, _sendWindow);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.ErrorRefreshingQuota(e);
|
||||
}
|
||||
//Do quota refresh
|
||||
_lastRefresh = DateTime.UtcNow.AddMinutes(1);
|
||||
try
|
||||
{
|
||||
var r = new GetSendQuotaRequest();
|
||||
_quota = await _amazonEmailServiceClient.GetSendQuotaAsync(r);
|
||||
_sendWindow = TimeSpan.FromSeconds(1.0 / _quota.MaxSendRate);
|
||||
_logger.DebugQuota(_quota.SentLast24Hours, _quota.Max24HourSend, _quota.MaxSendRate, _sendWindow);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.ErrorRefreshingQuota(e);
|
||||
}
|
||||
}
|
||||
_semaphore.Release();
|
||||
}
|
||||
|
||||
private bool IsRefreshNeeded()
|
||||
|
@ -29,5 +29,5 @@ namespace ASC.Core.Notify.Senders;
|
||||
public interface INotifySender
|
||||
{
|
||||
void Init(IDictionary<string, string> properties);
|
||||
NoticeSendResult Send(NotifyMessage m);
|
||||
Task<NoticeSendResult> Send(NotifyMessage m);
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ public class JabberSender : INotifySender
|
||||
|
||||
public void Init(IDictionary<string, string> properties) { }
|
||||
|
||||
public NoticeSendResult Send(NotifyMessage m)
|
||||
public Task<NoticeSendResult> Send(NotifyMessage m)
|
||||
{
|
||||
var text = m.Content;
|
||||
if (!string.IsNullOrEmpty(text))
|
||||
@ -59,7 +59,7 @@ public class JabberSender : INotifySender
|
||||
_logger.ErrorUnexpected(e);
|
||||
}
|
||||
|
||||
return NoticeSendResult.OK;
|
||||
return Task.FromResult(NoticeSendResult.OK);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,10 +38,10 @@ public class NotifyServiceSender : INotifySender
|
||||
|
||||
public void Init(IDictionary<string, string> properties) { }
|
||||
|
||||
public NoticeSendResult Send(NotifyMessage m)
|
||||
public Task<NoticeSendResult> Send(NotifyMessage m)
|
||||
{
|
||||
_notifyServiceClient.SendNotifyMessage(m);
|
||||
|
||||
return NoticeSendResult.OK;
|
||||
return Task.FromResult(NoticeSendResult.OK);
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ public class PushSender : INotifySender
|
||||
|
||||
public void Init(IDictionary<string, string> properties) { }
|
||||
|
||||
public NoticeSendResult Send(NotifyMessage m)
|
||||
public Task<NoticeSendResult> Send(NotifyMessage m)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(m.Content))
|
||||
{
|
||||
@ -59,7 +59,7 @@ public class PushSender : INotifySender
|
||||
_logger.ErrorUnexpected(e);
|
||||
}
|
||||
|
||||
return NoticeSendResult.OK;
|
||||
return Task.FromResult(NoticeSendResult.OK);
|
||||
}
|
||||
}
|
||||
public static class FirebaseSenderExtension
|
||||
|
@ -57,7 +57,7 @@ public class SmtpSender : INotifySender
|
||||
_initProperties = properties;
|
||||
}
|
||||
|
||||
public virtual NoticeSendResult Send(NotifyMessage m)
|
||||
public virtual Task<NoticeSendResult> Send(NotifyMessage m)
|
||||
{
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
|
||||
@ -149,7 +149,7 @@ public class SmtpSender : INotifySender
|
||||
smtpClient.Dispose();
|
||||
}
|
||||
|
||||
return result;
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
private void BuildSmtpSettings(CoreConfiguration configuration)
|
||||
|
@ -41,7 +41,7 @@ public class TelegramSender : INotifySender
|
||||
|
||||
public void Init(IDictionary<string, string> properties) { }
|
||||
|
||||
public NoticeSendResult Send(NotifyMessage m)
|
||||
public Task<NoticeSendResult> Send(NotifyMessage m)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(m.Content))
|
||||
{
|
||||
@ -59,6 +59,6 @@ public class TelegramSender : INotifySender
|
||||
_logger.ErrorUnexpected(e);
|
||||
}
|
||||
|
||||
return NoticeSendResult.OK;
|
||||
return Task.FromResult(NoticeSendResult.OK);
|
||||
}
|
||||
}
|
||||
|
@ -37,13 +37,13 @@ class DispatchSink : Sink
|
||||
_senderName = senderName;
|
||||
}
|
||||
|
||||
public override SendResponse ProcessMessage(INoticeMessage message)
|
||||
public override Task<SendResponse> ProcessMessage(INoticeMessage message)
|
||||
{
|
||||
return _dispatcher.Dispatch(message, _senderName);
|
||||
}
|
||||
|
||||
public override void ProcessMessageAsync(INoticeMessage message)
|
||||
public override async Task ProcessMessageAsync(INoticeMessage message)
|
||||
{
|
||||
_dispatcher.Dispatch(message, _senderName);
|
||||
await _dispatcher.Dispatch(message, _senderName);
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,6 @@ namespace ASC.Notify.Sinks;
|
||||
public interface ISink
|
||||
{
|
||||
ISink NextSink { get; set; }
|
||||
SendResponse ProcessMessage(INoticeMessage message);
|
||||
void ProcessMessageAsync(INoticeMessage message);
|
||||
Task<SendResponse> ProcessMessage(INoticeMessage message);
|
||||
Task ProcessMessageAsync(INoticeMessage message);
|
||||
}
|
||||
|
@ -35,10 +35,10 @@ public abstract class Sink : ISink
|
||||
{
|
||||
public ISink NextSink { get; set; }
|
||||
|
||||
public abstract SendResponse ProcessMessage(INoticeMessage message);
|
||||
public abstract Task<SendResponse> ProcessMessage(INoticeMessage message);
|
||||
|
||||
public virtual void ProcessMessageAsync(INoticeMessage message)
|
||||
public virtual async Task ProcessMessageAsync(INoticeMessage message)
|
||||
{
|
||||
NextSink.ProcessMessageAsync(message);
|
||||
await NextSink.ProcessMessageAsync(message);
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ class TelegramSenderSink : Sink
|
||||
}
|
||||
|
||||
|
||||
public override SendResponse ProcessMessage(INoticeMessage message)
|
||||
public override async Task<SendResponse> ProcessMessage(INoticeMessage message)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -47,7 +47,7 @@ class TelegramSenderSink : Sink
|
||||
|
||||
using var scope = _serviceProvider.CreateScope();
|
||||
var m = scope.ServiceProvider.GetRequiredService<TelegramSenderSinkMessageCreator>().CreateNotifyMessage(message, _senderName);
|
||||
_sender.Send(m);
|
||||
await _sender.Send(m);
|
||||
|
||||
return new SendResponse(message, _senderName, result);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MySql.Data" Version="8.0.30" />
|
||||
<PackageReference Include="MySql.Data" Version="8.0.31" />
|
||||
<PackageReference Include="protobuf-net" Version="3.1.17" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -76,4 +76,42 @@ public static class ActionInvoker
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task Try(
|
||||
Func<object, Task> action,
|
||||
object state,
|
||||
int maxAttempts,
|
||||
Action<Exception> onFailure = null,
|
||||
Action<Exception> onAttemptFailure = null,
|
||||
int sleepMs = 1000,
|
||||
bool isSleepExponential = true)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(action);
|
||||
|
||||
var countAttempts = 0;
|
||||
while (countAttempts++ < maxAttempts)
|
||||
{
|
||||
try
|
||||
{
|
||||
await action(state);
|
||||
return;
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
if (countAttempts < maxAttempts)
|
||||
{
|
||||
onAttemptFailure?.Invoke(error);
|
||||
|
||||
if (sleepMs > 0)
|
||||
{
|
||||
await Task.Delay(isSleepExponential ? sleepMs * countAttempts : sleepMs);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
onFailure?.Invoke(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -122,25 +122,25 @@ public class BackupAjaxHandler
|
||||
return _backupService.GetBackupProgress(tenantId);
|
||||
}
|
||||
|
||||
public void DeleteBackup(Guid id)
|
||||
public async Task DeleteBackup(Guid id)
|
||||
{
|
||||
DemandPermissionsBackup();
|
||||
|
||||
_backupService.DeleteBackup(id);
|
||||
await _backupService.DeleteBackup(id);
|
||||
}
|
||||
|
||||
public void DeleteAllBackups()
|
||||
public async Task DeleteAllBackups()
|
||||
{
|
||||
DemandPermissionsBackup();
|
||||
|
||||
_backupService.DeleteAllBackups(GetCurrentTenantId());
|
||||
await _backupService.DeleteAllBackups(GetCurrentTenantId());
|
||||
}
|
||||
|
||||
public List<BackupHistoryRecord> GetBackupHistory()
|
||||
public async Task<List<BackupHistoryRecord>> GetBackupHistory()
|
||||
{
|
||||
DemandPermissionsBackup();
|
||||
|
||||
return _backupService.GetBackupHistory(GetCurrentTenantId());
|
||||
return await _backupService.GetBackupHistory(GetCurrentTenantId());
|
||||
}
|
||||
|
||||
public void CreateSchedule(BackupStorageType storageType, Dictionary<string, string> storageParams, int backupsStored, CronParams cronParams)
|
||||
|
@ -32,13 +32,13 @@ public interface IBackupService
|
||||
BackupProgress GetBackupProgress(int tenantId);
|
||||
BackupProgress GetRestoreProgress(int tenantId);
|
||||
BackupProgress GetTransferProgress(int tenantId);
|
||||
List<BackupHistoryRecord> GetBackupHistory(int tenantId);
|
||||
Task<List<BackupHistoryRecord>> GetBackupHistory(int tenantId);
|
||||
List<TransferRegion> GetTransferRegions();
|
||||
ScheduleResponse GetSchedule(int tenantId);
|
||||
string GetTmpFolder();
|
||||
void CreateSchedule(CreateScheduleRequest request);
|
||||
void DeleteAllBackups(int tenantId);
|
||||
void DeleteBackup(Guid backupId);
|
||||
Task DeleteAllBackups(int tenantId);
|
||||
Task DeleteBackup(Guid backupId);
|
||||
void DeleteSchedule(int tenantId);
|
||||
void StartBackup(StartBackupRequest request);
|
||||
void StartRestore(StartRestoreRequest request);
|
||||
|
@ -45,7 +45,7 @@ public class DbBackupProvider : IBackupProvider
|
||||
|
||||
public event EventHandler<ProgressChangedEventArgs> ProgressChanged;
|
||||
|
||||
public IEnumerable<XElement> GetElements(int tenant, string[] configs, IDataWriteOperator writer)
|
||||
public Task<IEnumerable<XElement>> GetElements(int tenant, string[] configs, IDataWriteOperator writer)
|
||||
{
|
||||
_processedTables.Clear();
|
||||
var xml = new List<XElement>();
|
||||
@ -69,18 +69,19 @@ public class DbBackupProvider : IBackupProvider
|
||||
node.Add(BackupDatabase(tenant, connectionString, writer));
|
||||
}
|
||||
}
|
||||
|
||||
return xml;
|
||||
|
||||
return Task.FromResult(xml.AsEnumerable());
|
||||
}
|
||||
|
||||
public void LoadFrom(IEnumerable<XElement> elements, int tenant, string[] configs, IDataReadOperator reader)
|
||||
public Task LoadFrom(IEnumerable<XElement> elements, int tenant, string[] configs, IDataReadOperator reader)
|
||||
{
|
||||
_processedTables.Clear();
|
||||
|
||||
foreach (var connectionString in GetConnectionStrings(configs))
|
||||
{
|
||||
RestoreDatabase(connectionString, elements, reader);
|
||||
}
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public IEnumerable<ConnectionStringSettings> GetConnectionStrings(string[] configs)
|
||||
|
@ -50,12 +50,12 @@ public class FileBackupProvider : IBackupProvider
|
||||
|
||||
public event EventHandler<ProgressChangedEventArgs> ProgressChanged;
|
||||
|
||||
public IEnumerable<XElement> GetElements(int tenant, string[] configs, IDataWriteOperator writer)
|
||||
public async Task<IEnumerable<XElement>> GetElements(int tenant, string[] configs, IDataWriteOperator writer)
|
||||
{
|
||||
InvokeProgressChanged("Saving files...", 0);
|
||||
|
||||
var config = GetWebConfig(configs);
|
||||
var files = ComposeFiles(tenant, config);
|
||||
var files = await ComposeFiles(tenant, config);
|
||||
|
||||
var elements = new List<XElement>();
|
||||
var backupKeys = new List<string>();
|
||||
@ -74,7 +74,7 @@ public class FileBackupProvider : IBackupProvider
|
||||
{
|
||||
try
|
||||
{
|
||||
using var stream = storage.GetReadStreamAsync(file.Domain, file.Path).Result;
|
||||
using var stream = await storage.GetReadStreamAsync(file.Domain, file.Path);
|
||||
writer.WriteEntry(backupPath, stream);
|
||||
break;
|
||||
}
|
||||
@ -97,7 +97,7 @@ public class FileBackupProvider : IBackupProvider
|
||||
return elements;
|
||||
}
|
||||
|
||||
public void LoadFrom(IEnumerable<XElement> elements, int tenant, string[] configs, IDataReadOperator dataOperator)
|
||||
public async Task LoadFrom(IEnumerable<XElement> elements, int tenant, string[] configs, IDataReadOperator dataOperator)
|
||||
{
|
||||
InvokeProgressChanged("Restoring files...", 0);
|
||||
|
||||
@ -114,7 +114,7 @@ public class FileBackupProvider : IBackupProvider
|
||||
var storage = _storageFactory.GetStorage(config, tenant, backupInfo.Module, null);
|
||||
try
|
||||
{
|
||||
storage.SaveAsync(backupInfo.Domain, backupInfo.Path, entry).Wait();
|
||||
await storage.SaveAsync(backupInfo.Domain, backupInfo.Path, entry);
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
@ -126,7 +126,7 @@ public class FileBackupProvider : IBackupProvider
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<FileBackupInfo> ComposeFiles(int tenant, string config)
|
||||
private async Task<IEnumerable<FileBackupInfo>> ComposeFiles(int tenant, string config)
|
||||
{
|
||||
var files = new List<FileBackupInfo>();
|
||||
foreach (var module in _storageFactoryConfig.GetModuleList(config))
|
||||
@ -138,13 +138,13 @@ public class FileBackupProvider : IBackupProvider
|
||||
|
||||
foreach (var domain in domainList)
|
||||
{
|
||||
files.AddRange(store
|
||||
.ListFilesRelativeAsync(domain, "\\", "*.*", true).ToArrayAsync().Result
|
||||
files.AddRange((await store
|
||||
.ListFilesRelativeAsync(domain, "\\", "*.*", true).ToArrayAsync())
|
||||
.Select(x => new FileBackupInfo(domain, module, x)));
|
||||
}
|
||||
|
||||
files.AddRange(store
|
||||
.ListFilesRelativeAsync(string.Empty, "\\", "*.*", true).ToArrayAsync().Result
|
||||
files.AddRange((await store
|
||||
.ListFilesRelativeAsync(string.Empty, "\\", "*.*", true).ToArrayAsync())
|
||||
.Where(x => domainList.All(domain => x.IndexOf($"{domain}/") == -1))
|
||||
.Select(x => new FileBackupInfo(string.Empty, module, x)));
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user