Merge branch 'develop' into feature/accounts-room-list

This commit is contained in:
Timofey Boyko 2022-11-30 11:15:42 +03:00
commit 4ff7ea1a33
564 changed files with 13566 additions and 14855 deletions

View File

@ -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
View File

@ -50,4 +50,3 @@ TestsResults/
**/.yarn/cache
**/.yarn/install-state.gz
config/appsettings.dev.json

File diff suppressed because one or more lines are too long

801
.yarn/releases/yarn-3.2.4.cjs vendored Executable file

File diff suppressed because one or more lines are too long

View File

@ -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
View 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
View File

@ -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"
}
}
}

View File

@ -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.
)

View File

@ -0,0 +1,7 @@
@echo off
pwsh %~dp0/build.backend.docker.ps1 %1
echo.
pause

View 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"

View File

@ -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}."

View File

@ -0,0 +1,7 @@
@echo off
pwsh %~dp0/build.document.server.docker.ps1 %1
echo.
pause

View 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

View File

@ -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

View File

@ -0,0 +1,7 @@
@echo off
pwsh %~dp0/clear.backend.docker.ps1
echo.
pause

View 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

View File

@ -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)

View File

@ -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)

View File

@ -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}

View File

@ -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 ../../../ && \

View File

@ -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/

View File

@ -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"]

View File

@ -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:

View File

@ -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:

View File

@ -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: ./

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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:

View File

@ -13,5 +13,5 @@ services:
networks:
default:
external:
name: ${NETWORK_NAME}
name: ${NETWORK_NAME}
external: true

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 =="

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,7 +0,0 @@
PUSHD %~dp0..
cd %~dp0../../common/ASC.UrlShortener/
call yarn install --immutable
POPD

View File

@ -0,0 +1,7 @@
@echo off
pwsh %~dp0/restart.backend.docker.ps1
echo.
pause

View File

@ -0,0 +1,5 @@
# Stop all backend services"
& "$PSScriptRoot\stop.backend.docker.ps1"
# Start all backend services"
& "$PSScriptRoot\start.backend.docker.ps1"

View File

@ -0,0 +1,7 @@
@echo off
pwsh %~dp0/start.backend.docker.ps1
echo.
pause

View 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

View File

@ -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 )"

View File

@ -0,0 +1,7 @@
@echo off
pwsh %~dp0/stop.backend.docker.ps1
echo.
pause

View 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

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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;
}
}

View 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.ActiveDirectory.Wrapper;
public class UserInfoAndLdapChangeCollectionWrapper
{
public UserInfo UserInfo { get; set; }
public LdapChangeCollection LdapChangeCollection { get; set; }
}

View File

@ -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));
}
}

View File

@ -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);
}
}

View File

@ -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)
{

View File

@ -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" />

View File

@ -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) { }
}

View File

@ -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}";

View File

@ -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
{

View File

@ -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

View File

@ -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()
{

View File

@ -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;
}
}

View File

@ -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" />

View File

@ -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
};
}
}
}

View File

@ -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;
}

View 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
}

View File

@ -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();

View File

@ -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)

View File

@ -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))
{

View File

@ -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;

View File

@ -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);
}

View File

@ -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)

View File

@ -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
{

View File

@ -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
{

View File

@ -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()

View File

@ -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);

View File

@ -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);

View File

@ -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()

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -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)

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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>

View File

@ -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);
}
}
}
}
}

View File

@ -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)

View File

@ -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);

View File

@ -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)

View File

@ -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