Compare commits
104 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
46bb44f0ab | ||
|
|
2f1380f24a | ||
|
|
ece3328e94 | ||
|
|
fdd26d87be | ||
|
|
2ade0dda42 | ||
|
|
a87ae5cf65 | ||
|
|
fe7b8b53a6 | ||
|
|
b929f3efdb | ||
|
|
f847fc076f | ||
|
|
60d0a701ce | ||
|
|
0dedaf6824 | ||
|
|
ab231b3fed | ||
|
|
e7f28cca36 | ||
|
|
505e8aac4b | ||
|
|
746e2a6052 | ||
|
|
dc03d5d83d | ||
|
|
b770ab178d | ||
|
|
fd7e022e88 | ||
|
|
ac5df6826b | ||
|
|
91908859bc | ||
|
|
9c8822f857 | ||
|
|
9709da7fb6 | ||
|
|
1852f10131 | ||
|
|
77d7b43e21 | ||
|
|
7410b539a0 | ||
|
|
0403d71502 | ||
|
|
2af1d93a7d | ||
|
|
76281ad761 | ||
|
|
d1ec9b4916 | ||
|
|
448e7460a9 | ||
|
|
ee0cbabffc | ||
|
|
d6a5af890a | ||
|
|
dc313441e5 | ||
|
|
c75320f4f4 | ||
|
|
c788f78416 | ||
|
|
49cf954d4a | ||
|
|
014e3db54f | ||
|
|
6d9c245c81 | ||
|
|
7fa9b79f31 | ||
|
|
c7f3d13b7f | ||
|
|
46f08a89d2 | ||
|
|
0dcfedb4dc | ||
|
|
918bf85a2d | ||
|
|
99db5f7190 | ||
|
|
18eff791b2 | ||
|
|
624dcacac5 | ||
|
|
878d5fd27c | ||
|
|
4b893ce0e8 | ||
|
|
472524f836 | ||
|
|
dbf8b23b15 | ||
|
|
79a5dd53ae | ||
|
|
8a5b20685c | ||
|
|
5a9c972de0 | ||
|
|
fc0e67122d | ||
|
|
eb642f66ca | ||
|
|
8cac15f7dd | ||
|
|
5011e2b7c1 | ||
|
|
b0008143b1 | ||
|
|
a3c3ab5a72 | ||
|
|
3a16269215 | ||
|
|
151145b0c3 | ||
|
|
9c794e9d4b | ||
|
|
01f697d279 | ||
|
|
6cdc37333b | ||
|
|
ae32915565 | ||
|
|
f49457dc5b | ||
|
|
d9e2e247ea | ||
|
|
c6f2f2f150 | ||
|
|
56b9c66cb8 | ||
|
|
5d8a0d0e1f | ||
|
|
f4cb9beda5 | ||
|
|
b66fc3c06d | ||
|
|
ab2e1a9236 | ||
|
|
ab77b400a1 | ||
|
|
eb7ab63563 | ||
|
|
4cf7d01622 | ||
|
|
a876078a9c | ||
|
|
495f2ae3c6 | ||
|
|
4e6d11baf0 | ||
|
|
a951b982b3 | ||
|
|
a33be66504 | ||
|
|
f41b9d5887 | ||
|
|
3c608463e6 | ||
|
|
eeffbe124a | ||
|
|
d7f2d54faa | ||
|
|
7db4b03634 | ||
|
|
77760a681a | ||
|
|
f9c1447ceb | ||
|
|
fb749c1902 | ||
|
|
240c44aa07 | ||
|
|
92cd8642c8 | ||
|
|
89d90cf919 | ||
|
|
920c6b6d8b | ||
|
|
1dd4df3a1c | ||
|
|
c7d44cc253 | ||
|
|
5082ab1893 | ||
|
|
e8b2425222 | ||
|
|
09d12cefd8 | ||
|
|
5f1166965d | ||
|
|
0dbab182e9 | ||
|
|
512f3f99fd | ||
|
|
6fb4fad705 | ||
|
|
fa92529e9b | ||
|
|
d6c6051a6c |
157
.github/workflows/build.yml
vendored
@@ -57,6 +57,11 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: lejianwen/rustdesk-api-web
|
||||||
|
path: rustdesk-api-web
|
||||||
|
ref: master
|
||||||
|
|
||||||
- name: Set up Go environment
|
- name: Set up Go environment
|
||||||
uses: actions/setup-go@v4
|
uses: actions/setup-go@v4
|
||||||
@@ -68,19 +73,26 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
node-version: '20'
|
node-version: '20'
|
||||||
|
|
||||||
|
|
||||||
- name: build rustdesk-api-web
|
- name: build rustdesk-api-web
|
||||||
|
working-directory: rustdesk-api-web
|
||||||
run: |
|
run: |
|
||||||
git clone ${{ env.WEBCLIENT_SOURCE_LOCATION }}
|
|
||||||
cd rustdesk-api-web
|
|
||||||
npm install
|
npm install
|
||||||
npm run build
|
npm run build
|
||||||
mkdir ../resources/admin/ -p
|
mkdir -p ../resources/admin/
|
||||||
cp -ar dist/* ../resources/admin/
|
cp -ar dist/* ../resources/admin/
|
||||||
|
|
||||||
- name: tidy
|
- name: tidy
|
||||||
run: go mod tidy
|
run: go mod tidy
|
||||||
|
|
||||||
|
- name: Get tag version
|
||||||
|
run: |
|
||||||
|
TAG_VERSION="${GITHUB_REF##*/}"
|
||||||
|
VERSION="${TAG_VERSION#v}"
|
||||||
|
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Write version to resources/version
|
||||||
|
run: echo $VERSION > resources/version
|
||||||
|
|
||||||
- name: swag
|
- name: swag
|
||||||
run: |
|
run: |
|
||||||
go install github.com/swaggo/swag/cmd/swag@latest
|
go install github.com/swaggo/swag/cmd/swag@latest
|
||||||
@@ -98,6 +110,8 @@ jobs:
|
|||||||
if [ "${{ matrix.job.goos }}" = "windows" ]; then
|
if [ "${{ matrix.job.goos }}" = "windows" ]; then
|
||||||
sudo apt-get install gcc-mingw-w64-x86-64 zip -y
|
sudo apt-get install gcc-mingw-w64-x86-64 zip -y
|
||||||
GOOS=${{ matrix.job.goos }} GOARCH=${{ matrix.job.platform }} CC=x86_64-w64-mingw32-gcc CGO_LDFLAGS="-static" CGO_ENABLED=1 go build -ldflags "-s -w" -o ./release/apimain.exe ./cmd/apimain.go
|
GOOS=${{ matrix.job.goos }} GOARCH=${{ matrix.job.platform }} CC=x86_64-w64-mingw32-gcc CGO_LDFLAGS="-static" CGO_ENABLED=1 go build -ldflags "-s -w" -o ./release/apimain.exe ./cmd/apimain.go
|
||||||
|
echo @echo off > release/start.bat
|
||||||
|
echo cmd /c \"%~dp0apimain.exe\" >> release/start.bat
|
||||||
zip -r ${{ matrix.job.goos}}-${{ matrix.job.platform }}.${{matrix.job.file_ext}} ./release
|
zip -r ${{ matrix.job.goos}}-${{ matrix.job.platform }}.${{matrix.job.file_ext}} ./release
|
||||||
else
|
else
|
||||||
if [ "${{ matrix.job.platform }}" = "arm64" ]; then
|
if [ "${{ matrix.job.platform }}" = "arm64" ]; then
|
||||||
@@ -129,7 +143,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
${{ matrix.job.goos}}-${{ matrix.job.platform }}.${{matrix.job.file_ext}}
|
${{ matrix.job.goos}}-${{ matrix.job.platform }}.${{matrix.job.file_ext}}
|
||||||
# tag_name: ${{ env.LATEST_TAG }}
|
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
@@ -138,6 +151,79 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||||
|
|
||||||
|
deb-package:
|
||||||
|
name: debian package - ${{ matrix.job.platform }}
|
||||||
|
needs: build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
job:
|
||||||
|
- { platform: "amd64", goos: "linux", debian_platform: "amd64", crossbuild_package: ""}
|
||||||
|
- { platform: "arm64", goos: "linux", debian_platform: "arm64", crossbuild_package: "crossbuild-essential-arm64" }
|
||||||
|
- { platform: "armv7l", goos: "linux", debian_platform: "armhf", crossbuild_package: "crossbuild-essential-armhf" }
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
|
||||||
|
- name: Create packaging env
|
||||||
|
run: |
|
||||||
|
sudo apt update
|
||||||
|
DEBIAN_FRONTEND=noninteractive sudo apt install -y devscripts build-essential debhelper pkg-config ${{ matrix.job.crossbuild_package }}
|
||||||
|
mkdir -p debian-build/${{ matrix.job.platform }}/bin
|
||||||
|
|
||||||
|
- name: Get tag version
|
||||||
|
id: get_tag
|
||||||
|
run: |
|
||||||
|
TAG_VERSION="${GITHUB_REF##*/}"
|
||||||
|
VERSION="${TAG_VERSION#v}"
|
||||||
|
echo "TAG_VERSION=$TAG_VERSION" >> $GITHUB_ENV
|
||||||
|
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Update changelog
|
||||||
|
run: |
|
||||||
|
DATE=$(date -R)
|
||||||
|
sed -i "1i rustdesk-api-server (${VERSION}) stable; urgency=medium\n\n * Automatically generated release for version ${VERSION}.\n\n -- GitHub Actions <actions@github.com> ${DATE}\n" debian/changelog
|
||||||
|
|
||||||
|
- name: Download binaries
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: rustdesk-api-${{ matrix.job.goos }}-${{ matrix.job.platform }}
|
||||||
|
path: .
|
||||||
|
|
||||||
|
- name: Unzip binaries
|
||||||
|
run: |
|
||||||
|
mkdir -p ${{ matrix.job.platform }}
|
||||||
|
tar -xzf ${{ matrix.job.goos }}-${{ matrix.job.platform }}.tar.gz -C ${{ matrix.job.platform }}
|
||||||
|
|
||||||
|
- name: Build package for ${{ matrix.job.platform }} arch
|
||||||
|
run: |
|
||||||
|
mv ${{ matrix.job.platform }}/release/apimain debian-build/${{ matrix.job.platform }}/bin/rustdesk-api
|
||||||
|
mv ${{ matrix.job.platform }}/release/resources/admin resources
|
||||||
|
chmod -v a+x debian-build/${{ matrix.job.platform }}/bin/*
|
||||||
|
mkdir -p data
|
||||||
|
cp -vr debian systemd conf data resources runtime debian-build/${{ matrix.job.platform }}/
|
||||||
|
cat debian/control.tpl | sed 's/{{ ARCH }}/${{ matrix.job.debian_platform }}/' > debian-build/${{ matrix.job.platform }}/debian/control
|
||||||
|
cd debian-build/${{ matrix.job.platform }}/
|
||||||
|
debuild -i -us -uc -b -a${{ matrix.job.debian_platform}}
|
||||||
|
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: rustdesk-api-${{ matrix.job.debian_platform }}
|
||||||
|
path: |
|
||||||
|
debian-build/*.deb
|
||||||
|
|
||||||
|
- name: Create Release
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
files: |
|
||||||
|
debian-build/rustdesk-api-server_*_${{ matrix.job.debian_platform }}.deb
|
||||||
|
|
||||||
docker:
|
docker:
|
||||||
name: Push Docker Image
|
name: Push Docker Image
|
||||||
needs: build
|
needs: build
|
||||||
@@ -199,7 +285,6 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
mkdir -p ${{ matrix.job.platform }}
|
mkdir -p ${{ matrix.job.platform }}
|
||||||
tar -xzf ${{ matrix.job.goos }}-${{ matrix.job.platform }}.tar.gz -C ${{ matrix.job.platform }}
|
tar -xzf ${{ matrix.job.goos }}-${{ matrix.job.platform }}.tar.gz -C ${{ matrix.job.platform }}
|
||||||
file ${{ matrix.job.platform }}/apimain
|
|
||||||
|
|
||||||
- name: Build and push Docker image to Docker Hub ${{ matrix.job.platform }}
|
- name: Build and push Docker image to Docker Hub ${{ matrix.job.platform }}
|
||||||
if: ${{ env.SKIP_DOCKER_HUB == 'false' }} # Only run this step if SKIP_DOCKER_HUB is false
|
if: ${{ env.SKIP_DOCKER_HUB == 'false' }} # Only run this step if SKIP_DOCKER_HUB is false
|
||||||
@@ -217,6 +302,21 @@ jobs:
|
|||||||
${{ env.DOCKERHUB_IMAGE_NAMESPACE }}/rustdesk-api:${{ env.TAG }}-${{ matrix.job.platform }}
|
${{ env.DOCKERHUB_IMAGE_NAMESPACE }}/rustdesk-api:${{ env.TAG }}-${{ matrix.job.platform }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
|
||||||
|
- name: Build and push Docker Full S6 image to Docker Hub ${{ matrix.job.platform }}
|
||||||
|
if: ${{ env.SKIP_DOCKER_HUB == 'false' }} # Only run this step if SKIP_DOCKER_HUB is false
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: "."
|
||||||
|
file: ./Dockerfile_full_s6
|
||||||
|
platforms: ${{ matrix.job.docker_platform }}
|
||||||
|
push: true
|
||||||
|
provenance: false
|
||||||
|
build-args: |
|
||||||
|
BUILDARCH=${{ matrix.job.platform }}
|
||||||
|
tags: |
|
||||||
|
${{ env.DOCKERHUB_IMAGE_NAMESPACE }}/rustdesk-api:full-s6-${{ matrix.job.platform }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
|
||||||
- name: Build and push Docker image to GHCR ${{ matrix.job.platform }}
|
- name: Build and push Docker image to GHCR ${{ matrix.job.platform }}
|
||||||
if: ${{ env.SKIP_GHCR == 'false' }} # Only run this step if SKIP_GHCR is false
|
if: ${{ env.SKIP_GHCR == 'false' }} # Only run this step if SKIP_GHCR is false
|
||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v5
|
||||||
@@ -233,6 +333,21 @@ jobs:
|
|||||||
ghcr.io/${{ env.GHCR_IMAGE_NAMESPACE }}/rustdesk-api:${{ env.TAG }}-${{ matrix.job.platform }}
|
ghcr.io/${{ env.GHCR_IMAGE_NAMESPACE }}/rustdesk-api:${{ env.TAG }}-${{ matrix.job.platform }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
|
||||||
|
- name: Build and push Docker Full S6 image to GHCR ${{ matrix.job.platform }}
|
||||||
|
if: ${{ env.SKIP_GHCR == 'false' }} # Only run this step if SKIP_GHCR is false
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: "."
|
||||||
|
file: ./Dockerfile
|
||||||
|
platforms: ${{ matrix.job.docker_platform }}
|
||||||
|
push: true
|
||||||
|
provenance: false
|
||||||
|
build-args: |
|
||||||
|
BUILDARCH=${{ matrix.job.platform }}
|
||||||
|
tags: |
|
||||||
|
ghcr.io/${{ env.GHCR_IMAGE_NAMESPACE }}/rustdesk-api:full-s6-${{ matrix.job.platform }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
|
||||||
#
|
#
|
||||||
docker-manifest:
|
docker-manifest:
|
||||||
name: Push Docker Manifest
|
name: Push Docker Manifest
|
||||||
@@ -265,7 +380,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Create and push manifest Docker Hub (:version)
|
- name: Create and push manifest Docker Hub (:version)
|
||||||
if: ${{ env.SKIP_DOCKER_HUB == 'false' }}
|
if: ${{ env.SKIP_DOCKER_HUB == 'false' }}
|
||||||
uses: Noelware/docker-manifest-action@master
|
uses: Noelware/docker-manifest-action@v0.2.3
|
||||||
with:
|
with:
|
||||||
base-image: ${{ env.BASE_IMAGE_NAMESPACE }}/rustdesk-api:${{ env.TAG }}
|
base-image: ${{ env.BASE_IMAGE_NAMESPACE }}/rustdesk-api:${{ env.TAG }}
|
||||||
extra-images: ${{ env.DOCKERHUB_IMAGE_NAMESPACE }}/rustdesk-api:${{ env.TAG }}-amd64,
|
extra-images: ${{ env.DOCKERHUB_IMAGE_NAMESPACE }}/rustdesk-api:${{ env.TAG }}-amd64,
|
||||||
@@ -275,7 +390,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Create and push manifest GHCR (:version)
|
- name: Create and push manifest GHCR (:version)
|
||||||
if: ${{ env.SKIP_GHCR == 'false' }}
|
if: ${{ env.SKIP_GHCR == 'false' }}
|
||||||
uses: Noelware/docker-manifest-action@master
|
uses: Noelware/docker-manifest-action@v0.2.3
|
||||||
with:
|
with:
|
||||||
base-image: ghcr.io/${{ env.BASE_IMAGE_NAMESPACE }}/rustdesk-api:${{ env.TAG }}
|
base-image: ghcr.io/${{ env.BASE_IMAGE_NAMESPACE }}/rustdesk-api:${{ env.TAG }}
|
||||||
extra-images: ghcr.io/${{ env.GHCR_IMAGE_NAMESPACE }}/rustdesk-api:${{ env.TAG }}-amd64,
|
extra-images: ghcr.io/${{ env.GHCR_IMAGE_NAMESPACE }}/rustdesk-api:${{ env.TAG }}-amd64,
|
||||||
@@ -286,7 +401,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Create and push manifest Docker Hub (:latest)
|
- name: Create and push manifest Docker Hub (:latest)
|
||||||
if: ${{ env.SKIP_DOCKER_HUB == 'false' }}
|
if: ${{ env.SKIP_DOCKER_HUB == 'false' }}
|
||||||
uses: Noelware/docker-manifest-action@master
|
uses: Noelware/docker-manifest-action@v0.2.3
|
||||||
with:
|
with:
|
||||||
base-image: ${{ env.BASE_IMAGE_NAMESPACE }}/rustdesk-api:latest
|
base-image: ${{ env.BASE_IMAGE_NAMESPACE }}/rustdesk-api:latest
|
||||||
extra-images: ${{ env.DOCKERHUB_IMAGE_NAMESPACE }}/rustdesk-api:latest-amd64,
|
extra-images: ${{ env.DOCKERHUB_IMAGE_NAMESPACE }}/rustdesk-api:latest-amd64,
|
||||||
@@ -296,11 +411,33 @@ jobs:
|
|||||||
|
|
||||||
- name: Create and push manifest GHCR (:latest)
|
- name: Create and push manifest GHCR (:latest)
|
||||||
if: ${{ env.SKIP_GHCR == 'false' }}
|
if: ${{ env.SKIP_GHCR == 'false' }}
|
||||||
uses: Noelware/docker-manifest-action@master
|
uses: Noelware/docker-manifest-action@v0.2.3
|
||||||
with:
|
with:
|
||||||
base-image: ghcr.io/${{ env.BASE_IMAGE_NAMESPACE }}/rustdesk-api:latest
|
base-image: ghcr.io/${{ env.BASE_IMAGE_NAMESPACE }}/rustdesk-api:latest
|
||||||
extra-images: ghcr.io/${{ env.GHCR_IMAGE_NAMESPACE }}/rustdesk-api:latest-amd64,
|
extra-images: ghcr.io/${{ env.GHCR_IMAGE_NAMESPACE }}/rustdesk-api:latest-amd64,
|
||||||
ghcr.io/${{ env.GHCR_IMAGE_NAMESPACE }}/rustdesk-api:latest-armv7l,
|
ghcr.io/${{ env.GHCR_IMAGE_NAMESPACE }}/rustdesk-api:latest-armv7l,
|
||||||
ghcr.io/${{ env.GHCR_IMAGE_NAMESPACE }}/rustdesk-api:latest-arm64
|
ghcr.io/${{ env.GHCR_IMAGE_NAMESPACE }}/rustdesk-api:latest-arm64
|
||||||
push: true
|
push: true
|
||||||
|
amend: true
|
||||||
|
|
||||||
|
- name: Create and push Full S6 manifest Docker Hub (:version)
|
||||||
|
if: ${{ env.SKIP_DOCKER_HUB == 'false' }}
|
||||||
|
uses: Noelware/docker-manifest-action@v0.2.3
|
||||||
|
with:
|
||||||
|
base-image: ${{ env.BASE_IMAGE_NAMESPACE }}/rustdesk-api:full-s6
|
||||||
|
extra-images: ${{ env.DOCKERHUB_IMAGE_NAMESPACE }}/rustdesk-api:full-s6-amd64,
|
||||||
|
${{ env.DOCKERHUB_IMAGE_NAMESPACE }}/rustdesk-api:full-s6-armv7l,
|
||||||
|
${{ env.DOCKERHUB_IMAGE_NAMESPACE }}/rustdesk-api:full-s6-arm64
|
||||||
|
push: true
|
||||||
|
amend: true
|
||||||
|
|
||||||
|
- name: Create and push Full S6 manifest GHCR (:latest)
|
||||||
|
if: ${{ env.SKIP_GHCR == 'false' }}
|
||||||
|
uses: Noelware/docker-manifest-action@v0.2.3
|
||||||
|
with:
|
||||||
|
base-image: ghcr.io/${{ env.BASE_IMAGE_NAMESPACE }}/rustdesk-api:full-s6
|
||||||
|
extra-images: ghcr.io/${{ env.GHCR_IMAGE_NAMESPACE }}/rustdesk-api:full-s6-amd64,
|
||||||
|
ghcr.io/${{ env.GHCR_IMAGE_NAMESPACE }}/rustdesk-api:full-s6-armv7l,
|
||||||
|
ghcr.io/${{ env.GHCR_IMAGE_NAMESPACE }}/rustdesk-api:full-s6-arm64
|
||||||
|
push: true
|
||||||
amend: true
|
amend: true
|
||||||
80
.github/workflows/build_test.yml
vendored
@@ -52,6 +52,12 @@ jobs:
|
|||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: lejianwen/rustdesk-api-web
|
||||||
|
path: rustdesk-api-web
|
||||||
|
ref: master
|
||||||
|
|
||||||
- name: Set up Go environment
|
- name: Set up Go environment
|
||||||
uses: actions/setup-go@v4
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
@@ -62,14 +68,12 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
node-version: '20'
|
node-version: '20'
|
||||||
|
|
||||||
|
|
||||||
- name: build rustdesk-api-web
|
- name: build rustdesk-api-web
|
||||||
|
working-directory: rustdesk-api-web
|
||||||
run: |
|
run: |
|
||||||
git clone ${{ env.WEBCLIENT_SOURCE_LOCATION }}
|
|
||||||
cd rustdesk-api-web
|
|
||||||
npm install
|
npm install
|
||||||
npm run build
|
npm run build
|
||||||
mkdir ../resources/admin/ -p
|
mkdir -p ../resources/admin/
|
||||||
cp -ar dist/* ../resources/admin/
|
cp -ar dist/* ../resources/admin/
|
||||||
|
|
||||||
- name: tidy
|
- name: tidy
|
||||||
@@ -92,6 +96,8 @@ jobs:
|
|||||||
if [ "${{ matrix.job.goos }}" = "windows" ]; then
|
if [ "${{ matrix.job.goos }}" = "windows" ]; then
|
||||||
sudo apt-get install gcc-mingw-w64-x86-64 zip -y
|
sudo apt-get install gcc-mingw-w64-x86-64 zip -y
|
||||||
GOOS=${{ matrix.job.goos }} GOARCH=${{ matrix.job.platform }} CC=x86_64-w64-mingw32-gcc CGO_LDFLAGS="-static" CGO_ENABLED=1 go build -ldflags "-s -w" -o ./release/apimain.exe ./cmd/apimain.go
|
GOOS=${{ matrix.job.goos }} GOARCH=${{ matrix.job.platform }} CC=x86_64-w64-mingw32-gcc CGO_LDFLAGS="-static" CGO_ENABLED=1 go build -ldflags "-s -w" -o ./release/apimain.exe ./cmd/apimain.go
|
||||||
|
echo @echo off > release/start.bat
|
||||||
|
echo cmd /c \"%~dp0apimain.exe\" >> release/start.bat
|
||||||
zip -r ${{ matrix.job.goos}}-${{ matrix.job.platform }}.${{matrix.job.file_ext}} ./release
|
zip -r ${{ matrix.job.goos}}-${{ matrix.job.platform }}.${{matrix.job.file_ext}} ./release
|
||||||
else
|
else
|
||||||
if [ "${{ matrix.job.platform }}" = "arm64" ]; then
|
if [ "${{ matrix.job.platform }}" = "arm64" ]; then
|
||||||
@@ -117,6 +123,7 @@ jobs:
|
|||||||
name: rustdesk-api-${{ matrix.job.goos }}-${{ matrix.job.platform }}
|
name: rustdesk-api-${{ matrix.job.goos }}-${{ matrix.job.platform }}
|
||||||
path: |
|
path: |
|
||||||
${{ matrix.job.goos}}-${{ matrix.job.platform }}.${{matrix.job.file_ext}}
|
${{ matrix.job.goos}}-${{ matrix.job.platform }}.${{matrix.job.file_ext}}
|
||||||
|
|
||||||
- name: Upload to GitHub Release
|
- name: Upload to GitHub Release
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@v2
|
||||||
with:
|
with:
|
||||||
@@ -126,6 +133,66 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
deb-package:
|
||||||
|
name: debian package - ${{ matrix.job.platform }}
|
||||||
|
needs: build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
job:
|
||||||
|
- { platform: "amd64", goos: "linux", debian_platform: "amd64", crossbuild_package: ""}
|
||||||
|
- { platform: "arm64", goos: "linux", debian_platform: "arm64", crossbuild_package: "crossbuild-essential-arm64" }
|
||||||
|
- { platform: "armv7l", goos: "linux", debian_platform: "armhf", crossbuild_package: "crossbuild-essential-armhf" }
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
|
||||||
|
- name: Create packaging env
|
||||||
|
run: |
|
||||||
|
sudo apt update
|
||||||
|
DEBIAN_FRONTEND=noninteractive sudo apt install -y devscripts build-essential debhelper pkg-config ${{ matrix.job.crossbuild_package }}
|
||||||
|
mkdir -p debian-build/${{ matrix.job.platform }}/bin
|
||||||
|
|
||||||
|
- name: Download binaries
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: rustdesk-api-${{ matrix.job.goos }}-${{ matrix.job.platform }}
|
||||||
|
path: .
|
||||||
|
|
||||||
|
- name: Unzip binaries
|
||||||
|
run: |
|
||||||
|
mkdir -p ${{ matrix.job.platform }}
|
||||||
|
tar -xzf ${{ matrix.job.goos }}-${{ matrix.job.platform }}.tar.gz -C ${{ matrix.job.platform }}
|
||||||
|
|
||||||
|
- name: Build package for ${{ matrix.job.platform }} arch
|
||||||
|
run: |
|
||||||
|
mv ${{ matrix.job.platform }}/release/apimain debian-build/${{ matrix.job.platform }}/bin/rustdesk-api
|
||||||
|
chmod -v a+x debian-build/${{ matrix.job.platform }}/bin/*
|
||||||
|
mkdir -p data
|
||||||
|
cp -vr debian systemd conf data resources runtime debian-build/${{ matrix.job.platform }}/
|
||||||
|
cat debian/control.tpl | sed 's/{{ ARCH }}/${{ matrix.job.debian_platform }}/' > debian-build/${{ matrix.job.platform }}/debian/control
|
||||||
|
cd debian-build/${{ matrix.job.platform }}/
|
||||||
|
debuild -i -us -uc -b -a${{ matrix.job.debian_platform}}
|
||||||
|
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: rustdesk-api-${{ matrix.job.debian_platform }}
|
||||||
|
path: |
|
||||||
|
debian-build/*.deb
|
||||||
|
|
||||||
|
- name: Upload to GitHub Release
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
tag_name: test
|
||||||
|
files: |
|
||||||
|
debian-build/rustdesk-api-server_*_${{ matrix.job.debian_platform }}.deb
|
||||||
|
|
||||||
docker:
|
docker:
|
||||||
name: Push Docker Image
|
name: Push Docker Image
|
||||||
needs: build
|
needs: build
|
||||||
@@ -187,7 +254,6 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
mkdir -p ${{ matrix.job.platform }}
|
mkdir -p ${{ matrix.job.platform }}
|
||||||
tar -xzf ${{ matrix.job.goos }}-${{ matrix.job.platform }}.tar.gz -C ${{ matrix.job.platform }}
|
tar -xzf ${{ matrix.job.goos }}-${{ matrix.job.platform }}.tar.gz -C ${{ matrix.job.platform }}
|
||||||
file ${{ matrix.job.platform }}/apimain
|
|
||||||
|
|
||||||
- name: Build and push Docker image to Docker Hub ${{ matrix.job.platform }}
|
- name: Build and push Docker image to Docker Hub ${{ matrix.job.platform }}
|
||||||
if: ${{ env.SKIP_DOCKER_HUB == 'false' }} # Only run this step if SKIP_DOCKER_HUB is false
|
if: ${{ env.SKIP_DOCKER_HUB == 'false' }} # Only run this step if SKIP_DOCKER_HUB is false
|
||||||
@@ -251,7 +317,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Create and push manifest Docker Hub (:version)
|
- name: Create and push manifest Docker Hub (:version)
|
||||||
if: ${{ env.SKIP_DOCKER_HUB == 'false' }}
|
if: ${{ env.SKIP_DOCKER_HUB == 'false' }}
|
||||||
uses: Noelware/docker-manifest-action@master
|
uses: Noelware/docker-manifest-action@v0.2.3
|
||||||
with:
|
with:
|
||||||
base-image: ${{ env.BASE_IMAGE_NAMESPACE }}/rustdesk-api:${{ env.TAG }}
|
base-image: ${{ env.BASE_IMAGE_NAMESPACE }}/rustdesk-api:${{ env.TAG }}
|
||||||
extra-images: ${{ env.DOCKERHUB_IMAGE_NAMESPACE }}/rustdesk-api:${{ env.TAG }}-amd64,
|
extra-images: ${{ env.DOCKERHUB_IMAGE_NAMESPACE }}/rustdesk-api:${{ env.TAG }}-amd64,
|
||||||
@@ -261,7 +327,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Create and push manifest GHCR (:version)
|
- name: Create and push manifest GHCR (:version)
|
||||||
if: ${{ env.SKIP_GHCR == 'false' }}
|
if: ${{ env.SKIP_GHCR == 'false' }}
|
||||||
uses: Noelware/docker-manifest-action@master
|
uses: Noelware/docker-manifest-action@v0.2.3
|
||||||
with:
|
with:
|
||||||
base-image: ghcr.io/${{ env.BASE_IMAGE_NAMESPACE }}/rustdesk-api:${{ env.TAG }}
|
base-image: ghcr.io/${{ env.BASE_IMAGE_NAMESPACE }}/rustdesk-api:${{ env.TAG }}
|
||||||
extra-images: ghcr.io/${{ env.GHCR_IMAGE_NAMESPACE }}/rustdesk-api:${{ env.TAG }}-amd64,
|
extra-images: ghcr.io/${{ env.GHCR_IMAGE_NAMESPACE }}/rustdesk-api:${{ env.TAG }}-amd64,
|
||||||
|
|||||||
7
.gitignore
vendored
@@ -1,13 +1,8 @@
|
|||||||
.idea
|
.idea
|
||||||
runtime/*
|
runtime/*
|
||||||
!runtime
|
!runtime
|
||||||
!runtime/cache
|
|
||||||
!runtime/cache/.gitkeep
|
!runtime/cache/.gitkeep
|
||||||
go.sum
|
go.sum
|
||||||
resources/*
|
resources/admin
|
||||||
!resources/public/upload/.gitignore
|
|
||||||
!resources/web
|
|
||||||
!resources/web2
|
|
||||||
!resources/i18n
|
|
||||||
release
|
release
|
||||||
data
|
data
|
||||||
@@ -2,9 +2,8 @@ FROM alpine
|
|||||||
|
|
||||||
ARG BUILDARCH
|
ARG BUILDARCH
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN apk add --no-cache tzdata file
|
RUN apk add --no-cache tzdata
|
||||||
COPY ./${BUILDARCH}/release /app/
|
COPY ./${BUILDARCH}/release /app/
|
||||||
RUN file /app/apimain
|
|
||||||
VOLUME /app/data
|
VOLUME /app/data
|
||||||
|
|
||||||
EXPOSE 21114
|
EXPOSE 21114
|
||||||
|
|||||||
38
Dockerfile_full_s6
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
FROM rustdesk/rustdesk-server-s6:latest AS server
|
||||||
|
|
||||||
|
FROM alpine
|
||||||
|
|
||||||
|
ARG BUILDARCH
|
||||||
|
WORKDIR /app
|
||||||
|
RUN apk add --no-cache tzdata
|
||||||
|
COPY ./${BUILDARCH}/release /app/
|
||||||
|
|
||||||
|
COPY --from=server /init /init
|
||||||
|
COPY --from=server /etc/s6-overlay /etc/s6-overlay
|
||||||
|
COPY --from=server /package /package
|
||||||
|
COPY --from=server /usr/bin/healthcheck.sh /usr/bin/healthcheck.sh
|
||||||
|
COPY --from=server /usr/bin/hbbr /usr/bin/hbbr
|
||||||
|
COPY --from=server /usr/bin/hbbs /usr/bin/hbbs
|
||||||
|
COPY --from=server /usr/bin/rustdesk-utils /usr/bin/rustdesk-utils
|
||||||
|
COPY --from=server /command /command
|
||||||
|
|
||||||
|
RUN \
|
||||||
|
mkdir -p /etc/s6-overlay/s6-rc.d/api && \
|
||||||
|
echo -e "key-secret\nhbbs" > /etc/s6-overlay/s6-rc.d/api/dependencies && \
|
||||||
|
echo "longrun" > /etc/s6-overlay/s6-rc.d/api/type && \
|
||||||
|
echo "#!/command/with-contenv sh" > /etc/s6-overlay/s6-rc.d/api/run && \
|
||||||
|
echo "cd /app" >> /etc/s6-overlay/s6-rc.d/api/run && \
|
||||||
|
echo "./apimain" >> /etc/s6-overlay/s6-rc.d/api/run && \
|
||||||
|
touch /etc/s6-overlay/s6-rc.d/user/contents.d/api && \
|
||||||
|
echo "/package/admin/s6/command/s6-svstat /run/s6-rc/servicedirs/api || exit 1" >> /usr/bin/healthcheck.sh && \
|
||||||
|
ln -s /run /var/run
|
||||||
|
|
||||||
|
ENV RELAY=relay.example.com
|
||||||
|
ENV ENCRYPTED_ONLY=0
|
||||||
|
|
||||||
|
VOLUME /data
|
||||||
|
VOLUME /app/data
|
||||||
|
|
||||||
|
EXPOSE 21114 21115 21116 21116/udp 21117 21118 21119
|
||||||
|
|
||||||
|
ENTRYPOINT ["/init"]
|
||||||
288
README.md
@@ -4,11 +4,12 @@
|
|||||||
|
|
||||||
本项目使用 Go 实现了 RustDesk 的 API,并包含了 Web Admin 和 Web 客户端。RustDesk 是一个远程桌面软件,提供了自托管的解决方案。
|
本项目使用 Go 实现了 RustDesk 的 API,并包含了 Web Admin 和 Web 客户端。RustDesk 是一个远程桌面软件,提供了自托管的解决方案。
|
||||||
|
|
||||||
<div align=center>
|
<div align=center>
|
||||||
<img src="https://img.shields.io/badge/golang-1.22-blue"/>
|
<img src="https://img.shields.io/badge/golang-1.22-blue"/>
|
||||||
<img src="https://img.shields.io/badge/gin-v1.9.0-lightBlue"/>
|
<img src="https://img.shields.io/badge/gin-v1.9.0-lightBlue"/>
|
||||||
<img src="https://img.shields.io/badge/gorm-v1.25.7-green"/>
|
<img src="https://img.shields.io/badge/gorm-v1.25.7-green"/>
|
||||||
<img src="https://img.shields.io/badge/swag-v1.16.3-yellow"/>
|
<img src="https://img.shields.io/badge/swag-v1.16.3-yellow"/>
|
||||||
|
<img src="https://goreportcard.com/badge/github.com/lejianwen/rustdesk-api/v2"/>
|
||||||
<img src="https://github.com/lejianwen/rustdesk-api/actions/workflows/build.yml/badge.svg"/>
|
<img src="https://github.com/lejianwen/rustdesk-api/actions/workflows/build.yml/badge.svg"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -19,7 +20,10 @@
|
|||||||
- 登录
|
- 登录
|
||||||
- 地址簿
|
- 地址簿
|
||||||
- 群组
|
- 群组
|
||||||
- 授权登录,支持`github`, `google` 和 `OIDC` 登录,支持`web后台`授权登录
|
- 授权登录
|
||||||
|
- 支持`github`, `google` 和 `OIDC` 登录,
|
||||||
|
- 支持`web后台`授权登录
|
||||||
|
- 支持`LDAP`(AD和OpenLDAP已测试), 如果API Server配置了LDAP
|
||||||
- i18n
|
- i18n
|
||||||
- Web Admin
|
- Web Admin
|
||||||
- 用户管理
|
- 用户管理
|
||||||
@@ -28,12 +32,14 @@
|
|||||||
- 标签管理
|
- 标签管理
|
||||||
- 群组管理
|
- 群组管理
|
||||||
- Oauth 管理
|
- Oauth 管理
|
||||||
|
- 配置LDAP, 配置文件或者环境变量
|
||||||
- 登录日志
|
- 登录日志
|
||||||
- 链接日志
|
- 链接日志
|
||||||
- 文件传输日志
|
- 文件传输日志
|
||||||
- 快速使用web client
|
- 快速使用web client
|
||||||
- i18n
|
- i18n
|
||||||
- 通过 web client 分享给游客
|
- 通过 web client 分享给游客
|
||||||
|
- server控制(一些官方的简单的指令 [WIKI](https://github.com/lejianwen/rustdesk-api/wiki/Rustdesk-Command))
|
||||||
- Web Client
|
- Web Client
|
||||||
- 自动获取API server
|
- 自动获取API server
|
||||||
- 自动获取ID服务器和KEY
|
- 自动获取ID服务器和KEY
|
||||||
@@ -43,98 +49,68 @@
|
|||||||
- CLI
|
- CLI
|
||||||
- 重置管理员密码
|
- 重置管理员密码
|
||||||
|
|
||||||
## 使用前准备
|
|
||||||
|
|
||||||
### [Rustdesk](https://github.com/rustdesk/rustdesk)
|
|
||||||
|
|
||||||
#### PC客户端使用的是 ***1.3.0***,经测试 ***1.2.6+*** 都可以
|
|
||||||
|
|
||||||
#### 关于PC端链接超时或者链接不上的问题以及解决方案
|
|
||||||
##### 链接不上或者超时
|
|
||||||
因为server端相对于客户端落后版本,server不会响应客户端的`secure_tcp`请求,所以客户端超时。
|
|
||||||
相关代码代码位置在`https://github.com/rustdesk/rustdesk/blob/master/src/client.rs#L322`
|
|
||||||
```rust
|
|
||||||
if !key.is_empty() && !token.is_empty() {
|
|
||||||
// mainly for the security of token
|
|
||||||
allow_err!(secure_tcp(&mut socket, key).await);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
可看到当`key`和`token`都不为空时,会调用`secure_tcp`,但是server端不会响应,所以客户端超时
|
|
||||||
`secure_tcp` 代码位置在 `https://github.com/rustdesk/rustdesk/blob/master/src/common.rs#L1203`
|
|
||||||
|
|
||||||
##### 4种解决方案
|
|
||||||
1. server端指定key。
|
|
||||||
- 优点:简单
|
|
||||||
- 缺点:链接不是加密的
|
|
||||||
```bash
|
|
||||||
hbbs -r <relay-server-ip[:port]> -k <key>
|
|
||||||
hbbr -k <key>
|
|
||||||
```
|
|
||||||
比如
|
|
||||||
```bash
|
|
||||||
hbbs -r <relay-server-ip[:port]> -k abc1234567
|
|
||||||
hbbr -k abc1234567
|
|
||||||
```
|
|
||||||
2. server端使用系统生成的key,或者自定义的密钥对,但如果client已登录,链接时容易超时或者链接不上,可以退出登录后再链接就可以了,webclient可以不用退出登录
|
|
||||||
- 优点:链接加密
|
|
||||||
- 缺点:操作麻烦
|
|
||||||
3. server端使用系统生成的key,或者自定义的密钥对,fork官方客户端的代码将`secure_tcp`修改成直接返回,然后通过`Github Actions`编译,下载编译后的客户端。
|
|
||||||
参考[官方文档](https://rustdesk.com/docs/en/dev/build/all/)
|
|
||||||
- 优点:链接加密,可以自定义客户端一些功能,编译后直接可用
|
|
||||||
- 缺点:需要自己fork代码,编译,有点难度
|
|
||||||
4. 使用[我fork的代码](https://github.com/lejianwen/rustdesk),已经修改了`secure_tcp`,可以直接下载使用,[下载地址](https://github.com/lejianwen/rustdesk/releases)
|
|
||||||
- 优点:代码改动可查看,`Github Actions`编译,链接加密,直接下载使用
|
|
||||||
- 缺点:可能跟不上官方版本更新
|
|
||||||
|
|
||||||
***对链接加密要求不高的可以使用`1`,对链接加密要求高的可以使用`3`或`4`***
|
|
||||||
|
|
||||||
## 功能
|
## 功能
|
||||||
|
|
||||||
|
|
||||||
### API 服务
|
### API 服务
|
||||||
基本实现了PC端基础的接口。支持Personal版本接口,可以通过配置文件`rustdesk.personal`或环境变量`RUSTDESK_API_RUSTDESK_PERSONAL`来控制是否启用
|
基本实现了PC端基础的接口。支持Personal版本接口,可以通过配置文件`rustdesk.personal`或环境变量`RUSTDESK_API_RUSTDESK_PERSONAL`来控制是否启用
|
||||||
|
|
||||||
#### 登录
|
<table>
|
||||||
|
<tr>
|
||||||
- 添加了`github`, `google` 以及`OIDC`授权登录,需要在后台配置好就可以用了,具体可看后台OAuth配置
|
<td width="50%" align="center" colspan="2"><b>登录</b></td>
|
||||||
- 添加了web后台授权登录,点击后直接登录后台就自动登录客户端了
|
</tr>
|
||||||
|
<tr>
|
||||||

|
<td width="50%" align="center" colspan="2"><img src="docs/pc_login.png"></td>
|
||||||
|
</tr>
|
||||||
#### 地址簿
|
<tr>
|
||||||
|
<td width="50%" align="center"><b>地址簿</b></td>
|
||||||

|
<td width="50%" align="center"><b>群组</b></td>
|
||||||
|
</tr>
|
||||||
#### 群组
|
<tr>
|
||||||
群组分为`共享组`和`普通组`,共享组中所有人都能看到小组成员的设备,普通组只有管理员能看到所有小组成员的设备
|
<td width="50%" align="center"><img src="docs/pc_ab.png"></td>
|
||||||
|
<td width="50%" align="center"><img src="docs/pc_gr.png"></td>
|
||||||

|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
### Web Admin:
|
### Web Admin:
|
||||||
|
|
||||||
* 使用前后端分离,提供用户友好的管理界面,主要用来管理和展示。前端代码在[rustdesk-api-web](https://github.com/lejianwen/rustdesk-api-web)
|
* 使用前后端分离,提供用户友好的管理界面,主要用来管理和展示。前端代码在[rustdesk-api-web](https://github.com/lejianwen/rustdesk-api-web)
|
||||||
|
|
||||||
* 后台访问地址是`http://<your server>[:port]/_admin/`初次安装管理员为用户名密码为`admin` `admin`,请即时更改密码
|
* 后台访问地址是`http://<your server>[:port]/_admin/`
|
||||||
|
* 初次安装管理员为用户名为`admin`,密码将在控制台打印,可以通过[命令行](#CLI)更改密码
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
1. 管理员界面
|
1. 管理员界面
|
||||||

|

|
||||||
2. 普通用户界面
|
2. 普通用户界面
|
||||||

|

|
||||||
右上角可以更改密码,可以切换语言,可以切换`白天/黑夜`模式
|
|
||||||

|
|
||||||
|
|
||||||
3. 分组可以自定义,方便管理,暂时支持两种类型: `共享组` 和 `普通组`
|
3. 每个用户可以多个地址簿,也可以将地址簿共享给其他用户
|
||||||

|
4. 分组可以自定义,方便管理,暂时支持两种类型: `共享组` 和 `普通组`
|
||||||
4. 可以直接打开webclient,方便使用;也可以分享给游客,游客可以直接通过webclient远程到设备
|
5. 可以直接打开webclient,方便使用;也可以分享给游客,游客可以直接通过webclient远程到设备
|
||||||
|
6. Oauth,支持了`Github`, `Google` 以及 `OIDC`, 需要创建一个`OAuth App`,然后配置到后台
|
||||||

|
|
||||||
5. Oauth,支持了`Github`, `Google` 以及 `OIDC`, 需要创建一个`OAuth App`,然后配置到后台
|
|
||||||

|
|
||||||
- 对于`Google` 和 `Github`, `Issuer` 和 `Scopes`不需要填写.
|
- 对于`Google` 和 `Github`, `Issuer` 和 `Scopes`不需要填写.
|
||||||
- 对于`OIDC`, `Issuer`是必须的。`Scopes`是可选的,默认为 `openid,profile,email`. 确保可以获取 `sub`,`email` 和`preferred_username`
|
- 对于`OIDC`, `Issuer`是必须的。`Scopes`是可选的,默认为 `openid,profile,email`. 确保可以获取 `sub`,`email` 和`preferred_username`
|
||||||
- `github oauth app`在`Settings`->`Developer settings`->`OAuth Apps`->`New OAuth App`
|
- `github oauth app`在`Settings`->`Developer settings`->`OAuth Apps`->`New OAuth App`
|
||||||
中创建,地址 [https://github.com/settings/developers](https://github.com/settings/developers)
|
中创建,地址 [https://github.com/settings/developers](https://github.com/settings/developers)
|
||||||
- `Authorization callback URL`填写`http://<your server[:port]>/api/oauth/callback`
|
- `Authorization callback URL`填写`http://<your server[:port]>/api/oauth/callback`
|
||||||
,比如`http://127.0.0.1:21114/api/oauth/callback`
|
,比如`http://127.0.0.1:21114/api/oauth/callback`
|
||||||
|
7. 登录日志
|
||||||
|
8. 链接日志
|
||||||
|
9. 文件传输日志
|
||||||
|
10. server控制
|
||||||
|
|
||||||
|
- `简易模式`,已经界面化了一些简单的指令,可以直接在后台执行
|
||||||
|

|
||||||
|
|
||||||
|
- `高级模式`,直接在后台执行指令
|
||||||
|
* 可以官方指令
|
||||||
|
* 可以添加自定义指令
|
||||||
|
* 可以执行自定义指令
|
||||||
|
|
||||||
|
|
||||||
|
11. **LDAP 支持**, 当在API Server上设置了LDAP(已测试AD和LDAP),可以通过LDAP中的用户信息进行登录 https://github.com/lejianwen/rustdesk-api/issues/114 ,如果LDAP验证失败,返回本地用户
|
||||||
|
|
||||||
### Web Client:
|
### Web Client:
|
||||||
|
|
||||||
@@ -154,6 +130,7 @@
|
|||||||

|

|
||||||
|
|
||||||
### CLI
|
### CLI
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 查看帮助
|
# 查看帮助
|
||||||
./apimain -h
|
./apimain -h
|
||||||
@@ -168,81 +145,54 @@
|
|||||||
|
|
||||||
### 相关配置
|
### 相关配置
|
||||||
|
|
||||||
|
* [配置文件](./conf/config.yaml)
|
||||||
* 参考`conf/config.yaml`配置文件,修改相关配置。
|
* 参考`conf/config.yaml`配置文件,修改相关配置。
|
||||||
* 如果`gorm.type`是`sqlite`,则不需要配置mysql相关配置。
|
* 如果`gorm.type`是`sqlite`,则不需要配置mysql相关配置。
|
||||||
* 语言如果不设置默认为`zh-CN`
|
* 语言如果不设置默认为`zh-CN`
|
||||||
|
|
||||||
```yaml
|
|
||||||
lang: "en"
|
|
||||||
app:
|
|
||||||
web-client: 1 # 1:启用 0:禁用
|
|
||||||
register: false #是否开启注册
|
|
||||||
show-swagger: 0 #是否显示swagger文档
|
|
||||||
gin:
|
|
||||||
api-addr: "0.0.0.0:21114"
|
|
||||||
mode: "release"
|
|
||||||
resources-path: 'resources'
|
|
||||||
trust-proxy: ""
|
|
||||||
gorm:
|
|
||||||
type: "sqlite"
|
|
||||||
max-idle-conns: 10
|
|
||||||
max-open-conns: 100
|
|
||||||
mysql:
|
|
||||||
username: "root"
|
|
||||||
password: "111111"
|
|
||||||
addr: "192.168.1.66:3308"
|
|
||||||
dbname: "rustdesk"
|
|
||||||
rustdesk:
|
|
||||||
id-server: "192.168.1.66:21116"
|
|
||||||
relay-server: "192.168.1.66:21117"
|
|
||||||
api-server: "http://192.168.1.66:21114"
|
|
||||||
key: "123456789"
|
|
||||||
personal: 1
|
|
||||||
logger:
|
|
||||||
path: "./runtime/log.txt"
|
|
||||||
level: "warn" #trace,debug,info,warn,error,fatal
|
|
||||||
report-caller: true
|
|
||||||
proxy:
|
|
||||||
enable: false
|
|
||||||
host: ""
|
|
||||||
```
|
|
||||||
|
|
||||||
### 环境变量
|
### 环境变量
|
||||||
变量名前缀是`RUSTDESK_API`,环境变量如果存在将覆盖配置文件中的配置
|
环境变量和配置文件`conf/config.yaml`中的配置一一对应,变量名前缀是`RUSTDESK_API`
|
||||||
|
下面表格并未全部列出,可以参考`conf/config.yaml`中的配置。
|
||||||
|
|
||||||
| 变量名 | 说明 | 示例 |
|
| 变量名 | 说明 | 示例 |
|
||||||
|---------------------------------------------------|---------------------------------------------------------|------------------------------|
|
|--------------------------------------------------------|--------------------------------------------------------------------------------|------------------------------|
|
||||||
| TZ | 时区 | Asia/Shanghai |
|
| TZ | 时区 | Asia/Shanghai |
|
||||||
| RUSTDESK_API_LANG | 语言 | `en`,`zh-CN` |
|
| RUSTDESK_API_LANG | 语言 | `en`,`zh-CN` |
|
||||||
| RUSTDESK_API_APP_WEB_CLIENT | 是否启用web-client; 1:启用,0:不启用; 默认启用 | 1 |
|
| RUSTDESK_API_APP_WEB_CLIENT | 是否启用web-client; 1:启用,0:不启用; 默认启用 | 1 |
|
||||||
| RUSTDESK_API_APP_REGISTER | 是否开启注册; `true`, `false` 默认`false` | `false` |
|
| RUSTDESK_API_APP_REGISTER | 是否开启注册; `true`, `false` 默认`false` | `false` |
|
||||||
| RUSTDESK_API_APP_SHOW_SWAGGER | 是否可见swagger文档;`1`显示,`0`不显示,默认`0`不显示 | `1` |
|
| RUSTDESK_API_APP_SHOW_SWAGGER | 是否可见swagger文档;`1`显示,`0`不显示,默认`0`不显示 | `1` |
|
||||||
| -----ADMIN配置----- | ---------- | ---------- |
|
| RUSTDESK_API_APP_TOKEN_EXPIRE | token有效时长 | `168h` |
|
||||||
| RUSTDESK_API_ADMIN_TITLE | 后台标题 | `RustDesk Api Admin` |
|
| RUSTDESK_API_APP_DISABLE_PWD_LOGIN | 是否禁用密码登录; `true`, `false` 默认`false` | `false` |
|
||||||
| RUSTDESK_API_ADMIN_HELLO | 后台欢迎语,可以使用`html` | |
|
| -----ADMIN配置----- | ---------- | ---------- |
|
||||||
| RUSTDESK_API_ADMIN_HELLO_FILE | 后台欢迎语文件,如果内容多,使用文件更方便。<br>会覆盖`RUSTDESK_API_ADMIN_HELLO` | `./conf/admin/hello.html` |
|
| RUSTDESK_API_ADMIN_TITLE | 后台标题 | `RustDesk Api Admin` |
|
||||||
| -----GIN配置----- | ---------- | ---------- |
|
| RUSTDESK_API_ADMIN_HELLO | 后台欢迎语,可以使用`html` | |
|
||||||
| RUSTDESK_API_GIN_TRUST_PROXY | 信任的代理IP列表,以`,`分割,默认信任所有 | 192.168.1.2,192.168.1.3 |
|
| RUSTDESK_API_ADMIN_HELLO_FILE | 后台欢迎语文件,如果内容多,使用文件更方便。<br>会覆盖`RUSTDESK_API_ADMIN_HELLO` | `./conf/admin/hello.html` |
|
||||||
| -----------GORM配置---------------- | ------------------------------------ | --------------------------- |
|
| -----GIN配置----- | ---------- | ---------- |
|
||||||
| RUSTDESK_API_GORM_TYPE | 数据库类型sqlite或者mysql,默认sqlite | sqlite |
|
| RUSTDESK_API_GIN_TRUST_PROXY | 信任的代理IP列表,以`,`分割,默认信任所有 | 192.168.1.2,192.168.1.3 |
|
||||||
| RUSTDESK_API_GORM_MAX_IDLE_CONNS | 数据库最大空闲连接数 | 10 |
|
| -----GORM配置----- | ---------- | --------------------------- |
|
||||||
| RUSTDESK_API_GORM_MAX_OPEN_CONNS | 数据库最大打开连接数 | 100 |
|
| RUSTDESK_API_GORM_TYPE | 数据库类型sqlite或者mysql,默认sqlite | sqlite |
|
||||||
| RUSTDESK_API_RUSTDESK_PERSONAL | 是否启用个人版API, 1:启用,0:不启用; 默认启用 | 1 |
|
| RUSTDESK_API_GORM_MAX_IDLE_CONNS | 数据库最大空闲连接数 | 10 |
|
||||||
| -----MYSQL配置----- | ---------- | ---------- |
|
| RUSTDESK_API_GORM_MAX_OPEN_CONNS | 数据库最大打开连接数 | 100 |
|
||||||
| RUSTDESK_API_MYSQL_USERNAME | mysql用户名 | root |
|
| RUSTDESK_API_RUSTDESK_PERSONAL | 是否启用个人版API, 1:启用,0:不启用; 默认启用 | 1 |
|
||||||
| RUSTDESK_API_MYSQL_PASSWORD | mysql密码 | 111111 |
|
| -----MYSQL配置----- | ---------- | ---------- |
|
||||||
| RUSTDESK_API_MYSQL_ADDR | mysql地址 | 192.168.1.66:3306 |
|
| RUSTDESK_API_MYSQL_USERNAME | mysql用户名 | root |
|
||||||
| RUSTDESK_API_MYSQL_DBNAME | mysql数据库名 | rustdesk |
|
| RUSTDESK_API_MYSQL_PASSWORD | mysql密码 | 111111 |
|
||||||
| -----RUSTDESK配置----- | --------------- | ---------- |
|
| RUSTDESK_API_MYSQL_ADDR | mysql地址 | 192.168.1.66:3306 |
|
||||||
| RUSTDESK_API_RUSTDESK_ID_SERVER | Rustdesk的id服务器地址 | 192.168.1.66:21116 |
|
| RUSTDESK_API_MYSQL_DBNAME | mysql数据库名 | rustdesk |
|
||||||
| RUSTDESK_API_RUSTDESK_RELAY_SERVER | Rustdesk的relay服务器地址 | 192.168.1.66:21117 |
|
| -----RUSTDESK配置----- | ---------- | ---------- |
|
||||||
| RUSTDESK_API_RUSTDESK_API_SERVER | Rustdesk的api服务器地址 | http://192.168.1.66:21114 |
|
| RUSTDESK_API_RUSTDESK_ID_SERVER | Rustdesk的id服务器地址 | 192.168.1.66:21116 |
|
||||||
| RUSTDESK_API_RUSTDESK_KEY | Rustdesk的key | 123456789 |
|
| RUSTDESK_API_RUSTDESK_RELAY_SERVER | Rustdesk的relay服务器地址 | 192.168.1.66:21117 |
|
||||||
| RUSTDESK_API_RUSTDESK_KEY_FILE | Rustdesk存放key的文件 | `./conf/data/id_ed25519.pub` |
|
| RUSTDESK_API_RUSTDESK_API_SERVER | Rustdesk的api服务器地址 | http://192.168.1.66:21114 |
|
||||||
| RUSTDESK_API_RUSTDESK_WEBCLIENT_MAGIC_QUERYONLINE | Web client v2 中是否启用新的在线状态查询方法; `1`:启用,`0`:不启用,默认不启用 | `0` |
|
| RUSTDESK_API_RUSTDESK_KEY | Rustdesk的key | 123456789 |
|
||||||
| ----PROXY配置----- | --------------- | ---------- |
|
| RUSTDESK_API_RUSTDESK_KEY_FILE | Rustdesk存放key的文件 | `./conf/data/id_ed25519.pub` |
|
||||||
| RUSTDESK_API_PROXY_ENABLE | 是否启用代理:`false`, `true` | `false` |
|
| RUSTDESK_API_RUSTDESK_WEBCLIENT<br/>_MAGIC_QUERYONLINE | Web client v2 中是否启用新的在线状态查询方法; `1`:启用,`0`:不启用,默认不启用 | `0` |
|
||||||
| RUSTDESK_API_PROXY_HOST | 代理地址 | `http://127.0.0.1:1080` |
|
| RUSTDESK_API_RUSTDESK_WS_HOST | 自定义Websocket Host | `wss://192.168.1.123:1234` |
|
||||||
|
| ----PROXY配置----- | ---------- | ---------- |
|
||||||
|
| RUSTDESK_API_PROXY_ENABLE | 是否启用代理:`false`, `true` | `false` |
|
||||||
|
| RUSTDESK_API_PROXY_HOST | 代理地址 | `http://127.0.0.1:1080` |
|
||||||
|
| ----JWT配置---- | -------- | -------- |
|
||||||
|
| RUSTDESK_API_JWT_KEY | 自定义JWT KEY,为空则不启用JWT<br/>如果没使用`lejianwen/rustdesk-server`中的`MUST_LOGIN`,建议设置为空 | |
|
||||||
|
| RUSTDESK_API_JWT_EXPIRE_DURATION | JWT有效时间 | `168h` |
|
||||||
|
|
||||||
|
|
||||||
### 运行
|
### 运行
|
||||||
@@ -308,7 +258,61 @@ proxy:
|
|||||||
6. 打开浏览器访问`http://<your server[:port]>/_admin/`,默认用户名密码为`admin`,请及时更改密码。
|
6. 打开浏览器访问`http://<your server[:port]>/_admin/`,默认用户名密码为`admin`,请及时更改密码。
|
||||||
|
|
||||||
|
|
||||||
|
#### 使用`lejianwen/server-s6`镜像运行
|
||||||
|
|
||||||
|
- 已解决链接超时问题
|
||||||
|
- 可以强制登录后才能发起链接
|
||||||
|
- github https://github.com/lejianwen/rustdesk-server
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
networks:
|
||||||
|
rustdesk-net:
|
||||||
|
external: false
|
||||||
|
services:
|
||||||
|
rustdesk:
|
||||||
|
ports:
|
||||||
|
- 21114:21114
|
||||||
|
- 21115:21115
|
||||||
|
- 21116:21116
|
||||||
|
- 21116:21116/udp
|
||||||
|
- 21117:21117
|
||||||
|
- 21118:21118
|
||||||
|
- 21119:21119
|
||||||
|
image: lejianwen/rustdesk-server-s6:latest
|
||||||
|
environment:
|
||||||
|
- RELAY=<relay_server[:port]>
|
||||||
|
- ENCRYPTED_ONLY=1
|
||||||
|
- MUST_LOGIN=N
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
- RUSTDESK_API_RUSTDESK_ID_SERVER=<id_server[:21116]>
|
||||||
|
- RUSTDESK_API_RUSTDESK_RELAY_SERVER=<relay_server[:21117]>
|
||||||
|
- RUSTDESK_API_RUSTDESK_API_SERVER=http://<api_server[:21114]>
|
||||||
|
- RUSTDESK_API_KEY_FILE=/data/id_ed25519.pub
|
||||||
|
- RUSTDESK_API_JWT_KEY=xxxxxx # jwt key
|
||||||
|
volumes:
|
||||||
|
- /data/rustdesk/server:/data
|
||||||
|
- /data/rustdesk/api:/app/data #将数据库挂载
|
||||||
|
networks:
|
||||||
|
- rustdesk-net
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## 其他
|
## 其他
|
||||||
|
|
||||||
|
- [WIKI](https://github.com/lejianwen/rustdesk-api/wiki)
|
||||||
|
- [链接超时问题](https://github.com/lejianwen/rustdesk-api/issues/92)
|
||||||
- [修改客户端ID](https://github.com/abdullah-erturk/RustDesk-ID-Changer)
|
- [修改客户端ID](https://github.com/abdullah-erturk/RustDesk-ID-Changer)
|
||||||
- [webclient来源](https://hub.docker.com/r/keyurbhole/flutter_web_desk)
|
- [webclient来源](https://hub.docker.com/r/keyurbhole/flutter_web_desk)
|
||||||
|
|
||||||
|
|
||||||
|
## 鸣谢
|
||||||
|
|
||||||
|
感谢所有做过贡献的人!
|
||||||
|
|
||||||
|
<a href="https://github.com/lejianwen/rustdesk-api/graphs/contributors">
|
||||||
|
<img src="https://contrib.rocks/image?repo=lejianwen/rustdesk-api" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
## 感谢你的支持!如果这个项目对你有帮助,请点个⭐️鼓励一下,谢谢!
|
||||||
|
|||||||
282
README_EN.md
@@ -8,6 +8,7 @@ desktop software that provides self-hosted solutions.
|
|||||||
<img src="https://img.shields.io/badge/gin-v1.9.0-lightBlue"/>
|
<img src="https://img.shields.io/badge/gin-v1.9.0-lightBlue"/>
|
||||||
<img src="https://img.shields.io/badge/gorm-v1.25.7-green"/>
|
<img src="https://img.shields.io/badge/gorm-v1.25.7-green"/>
|
||||||
<img src="https://img.shields.io/badge/swag-v1.16.3-yellow"/>
|
<img src="https://img.shields.io/badge/swag-v1.16.3-yellow"/>
|
||||||
|
<img src="https://goreportcard.com/badge/github.com/lejianwen/rustdesk-api/v2"/>
|
||||||
<img src="https://github.com/lejianwen/rustdesk-api/actions/workflows/build.yml/badge.svg"/>
|
<img src="https://github.com/lejianwen/rustdesk-api/actions/workflows/build.yml/badge.svg"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -18,7 +19,10 @@ desktop software that provides self-hosted solutions.
|
|||||||
- Login
|
- Login
|
||||||
- Address Book
|
- Address Book
|
||||||
- Groups
|
- Groups
|
||||||
- Authorized login, supports `GitHub`, `Google` and `OIDC` login, supports `web admin` authorized login
|
- Authorized login,
|
||||||
|
- supports `GitHub`, `Google` and `OIDC` login,
|
||||||
|
- supports `web admin` authorized login,
|
||||||
|
- supports LDAP(test AD and openladp) if API Server config
|
||||||
- i18n
|
- i18n
|
||||||
- Web Admin
|
- Web Admin
|
||||||
- User Management
|
- User Management
|
||||||
@@ -27,12 +31,14 @@ desktop software that provides self-hosted solutions.
|
|||||||
- Tag Management
|
- Tag Management
|
||||||
- Group Management
|
- Group Management
|
||||||
- OAuth Management
|
- OAuth Management
|
||||||
|
- LDAP Config by config file or ENV
|
||||||
- Login Logs
|
- Login Logs
|
||||||
- Connection Logs
|
- Connection Logs
|
||||||
- File Transfer Logs
|
- File Transfer Logs
|
||||||
- Quick access to web client
|
- Quick access to web client
|
||||||
- i18n
|
- i18n
|
||||||
- Share to guest by web client
|
- Share to guest by web client
|
||||||
|
- Server control (some simple official commands [WIKI](https://github.com/lejianwen/rustdesk-api/wiki/Rustdesk-Command))
|
||||||
- Web Client
|
- Web Client
|
||||||
- Automatically obtain API server
|
- Automatically obtain API server
|
||||||
- Automatically obtain ID server and KEY
|
- Automatically obtain ID server and KEY
|
||||||
@@ -40,105 +46,71 @@ desktop software that provides self-hosted solutions.
|
|||||||
- Visitors are remotely to the device via a temporary sharing link
|
- Visitors are remotely to the device via a temporary sharing link
|
||||||
- CLI
|
- CLI
|
||||||
- Reset admin password
|
- Reset admin password
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
### [Rustdesk](https://github.com/rustdesk/rustdesk)
|
|
||||||
|
|
||||||
|
|
||||||
#### The PC client uses version ***1.3.0***, and versions ***1.2.6+*** have been tested to work.
|
|
||||||
|
|
||||||
#### Solutions for PC client connection timeout or connection issues
|
|
||||||
##### Connection issues or timeouts
|
|
||||||
Because the server version lags behind the client version, the server does not respond to the client's `secure_tcp` request, causing the client to timeout.
|
|
||||||
Relevant code can be found at `https://github.com/rustdesk/rustdesk/blob/master/src/client.rs#L322`
|
|
||||||
```rust
|
|
||||||
if !key.is_empty() && !token.is_empty() {
|
|
||||||
// mainly for the security of token
|
|
||||||
allow_err!(secure_tcp(&mut socket, key).await);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
As seen, when both `key` and `token` are not empty, `secure_tcp` is called, but the server does not respond, causing the client to timeout.
|
|
||||||
The `secure_tcp` code is located at `https://github.com/rustdesk/rustdesk/blob/master/src/common.rs#L1203`
|
|
||||||
|
|
||||||
##### Four Solutions
|
|
||||||
1. Specify the key on the server.
|
|
||||||
- Advantage: Simple
|
|
||||||
- Disadvantage: The connection is not encrypted
|
|
||||||
```bash
|
|
||||||
hbbs -r <relay-server-ip[:port]> -k <key>
|
|
||||||
hbbr -k <key>
|
|
||||||
```
|
|
||||||
For example
|
|
||||||
```bash
|
|
||||||
hbbs -r <relay-server-ip[:port]> -k abc1234567
|
|
||||||
hbbr -k abc1234567
|
|
||||||
```
|
|
||||||
2. Use a system-generated key or a custom key pair on the server. If the client is already logged in, it may timeout or fail to connect. Logging out and reconnecting usually resolves the issue, and the web client does not need to log out.
|
|
||||||
- Advantage: Encrypted connection
|
|
||||||
- Disadvantage: Complicated operation
|
|
||||||
3. Use a system-generated key or a custom key pair on the server, fork the official client code to modify `secure_tcp` to return directly, then compile using `Github Actions` and download the compiled client.
|
|
||||||
Refer to [official documentation](https://rustdesk.com/docs/en/dev/build/all/)
|
|
||||||
- Advantage: Encrypted connection, customizable client features, ready to use after compilation
|
|
||||||
- Disadvantage: Requires forking code and compiling, which can be challenging
|
|
||||||
4. Use [my forked code](https://github.com/lejianwen/rustdesk), which has already modified `secure_tcp`. You can download and use it directly from [here](https://github.com/lejianwen/rustdesk/releases)
|
|
||||||
- Advantage: Code changes are viewable, compiled with `Github Actions`, encrypted connection, ready to use
|
|
||||||
- Disadvantage: May not keep up with official version updates
|
|
||||||
|
|
||||||
***If encryption is not a high priority, use `1`. If encryption is important, use `3` or `4`.***
|
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
### API Service
|
### API Service
|
||||||
Basic implementation of the PC client's primary interfaces.Supports the Personal version api, which can be enabled by configuring the `rustdesk.personal` file or the `RUSTDESK_API_RUSTDESK_PERSONAL` environment variable.
|
Basic implementation of the PC client's primary interfaces.Supports the Personal version api, which can be enabled by configuring the `rustdesk.personal` file or the `RUSTDESK_API_RUSTDESK_PERSONAL` environment variable.
|
||||||
|
|
||||||
#### Login
|
<table>
|
||||||
|
<tr>
|
||||||
- Added `GitHub`, `Google` and `OIDC` login, which can be used after configuration in the admin panel. See the OAuth
|
<td width="50%" align="center" colspan="2"><b>Login</b></td>
|
||||||
configuration section for details.
|
</tr>
|
||||||
- Added authorization login for the web admin panel.
|
<tr>
|
||||||
|
<td width="50%" align="center" colspan="2"><img src="docs/en_img/pc_login.png"></td>
|
||||||

|
</tr>
|
||||||
|
<tr>
|
||||||
#### Address Book
|
<td width="50%" align="center"><b>Address Book</b></td>
|
||||||
|
<td width="50%" align="center"><b>Groups</b></td>
|
||||||

|
</tr>
|
||||||
|
<tr>
|
||||||
#### Groups
|
<td width="50%" align="center"><img src="docs/en_img/pc_ab.png"></td>
|
||||||
Groups are divided into `shared groups` and `regular groups`. In shared groups, everyone can see the peers of all group members, while in regular groups, only administrators can see all members' peers.
|
<td width="50%" align="center"><img src="docs/en_img/pc_gr.png"></td>
|
||||||
|
</tr>
|
||||||

|
</table>
|
||||||
|
|
||||||
### Web Admin
|
### Web Admin
|
||||||
|
|
||||||
* The frontend and backend are separated to provide a user-friendly management interface, primarily for managing and
|
* The frontend and backend are separated to provide a user-friendly management interface, primarily for managing and
|
||||||
displaying data.Frontend code is available at [rustdesk-api-web](https://github.com/lejianwen/rustdesk-api-web)
|
displaying data.Frontend code is available at [rustdesk-api-web](https://github.com/lejianwen/rustdesk-api-web)
|
||||||
|
|
||||||
* Admin panel URL: `http://<your server[:port]>/_admin/`. The default username and password for the initial
|
* Admin panel URL: `http://<your server[:port]>/_admin/`
|
||||||
installation are `admin` `admin`, please change the password immediately.
|
* For the initial installation, the admin username is `admin`, and the password will be printed in the console. You can change the password via the [command line](#CLI).
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
1. Admin interface:
|
1. Admin interface:
|
||||||

|

|
||||||
2. Regular user interface:
|
2. Regular user interface:
|
||||||

|

|
||||||
In the top right corner, you can change the password, switch languages, and toggle between `day/night` mode.
|
|
||||||
|
|
||||||

|
3. Each user can have multiple address books, which can also be shared with other users.
|
||||||
3. Groups can be customized for easy management. Currently, two types are supported: `shared group` and `regular group`.
|
4. Groups can be customized for easy management. Currently, two types are supported: `shared group` and `regular group`.
|
||||||

|
5. You can directly launch the client or open the web client for convenience; you can also share it with guests, who can remotely access the device via the web client.
|
||||||
4. You can directly launch the client or open the web client for convenience; you can also share it with guests, who can remotely access the device via the web client.
|
6. OAuth support: Currently, `GitHub`, `Google` and `OIDC` are supported. You need to create an `OAuth App` and configure it in
|
||||||
|
|
||||||

|
|
||||||
5. OAuth support: Currently, `GitHub`, `Google` and `OIDC` are supported. You need to create an `OAuth App` and configure it in
|
|
||||||
the admin panel.
|
the admin panel.
|
||||||

|
|
||||||
- For `Google` and `Github`, you don't need to fill the `Issuer` and `Scpoes`
|
- For `Google` and `Github`, you don't need to fill the `Issuer` and `Scpoes`
|
||||||
- For `OIDC`, you must set the `Issuer`. And `Scopes` is optional which default is `openid,email,profile`, please make sure this `Oauth App` can access `sub`, `email` and `preferred_username`
|
- For `OIDC`, you must set the `Issuer`. And `Scopes` is optional which default is `openid,email,profile`, please make sure this `Oauth App` can access `sub`, `email` and `preferred_username`
|
||||||
- Create a `GitHub OAuth App`
|
- Create a `GitHub OAuth App`
|
||||||
at `Settings` -> `Developer settings` -> `OAuth Apps` -> `New OAuth App` [here](https://github.com/settings/developers).
|
at `Settings` -> `Developer settings` -> `OAuth Apps` -> `New OAuth App` [here](https://github.com/settings/developers).
|
||||||
- Set the `Authorization callback URL` to `http://<your server[:port]>/api/oauth/callback`,
|
- Set the `Authorization callback URL` to `http://<your server[:port]>/api/oauth/callback`,
|
||||||
e.g., `http://127.0.0.1:21114/api/oauth/callback`.
|
e.g., `http://127.0.0.1:21114/api/oauth/callback`.
|
||||||
|
|
||||||
|
7. Login logs
|
||||||
|
8. Connection logs
|
||||||
|
9. File transfer logs
|
||||||
|
10. Server control
|
||||||
|
- `Simple mode`, some simple commands have been GUI-ized and can be executed directly in the backend
|
||||||
|

|
||||||
|
|
||||||
|
- `Advanced mode`, commands can be executed directly in the backend
|
||||||
|
* Official commands can be used
|
||||||
|
* Custom commands can be added
|
||||||
|
* Custom commands can be executed
|
||||||
|
|
||||||
|
11. **LDAP Support**, When you setup the LDAP(test for OpenLDAP and AD), you can login with the LDAP's user. https://github.com/lejianwen/rustdesk-api/issues/114 , if LDAP fail fallback local user
|
||||||
|
|
||||||
### Web Client:
|
### Web Client:
|
||||||
|
|
||||||
1. If you're already logged into the admin panel, the web client will log in automatically.
|
1. If you're already logged into the admin panel, the web client will log in automatically.
|
||||||
@@ -171,81 +143,55 @@ installation are `admin` `admin`, please change the password immediately.
|
|||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
||||||
|
* [Config File](./conf/config.yaml)
|
||||||
* Modify the configuration in `conf/config.yaml`.
|
* Modify the configuration in `conf/config.yaml`.
|
||||||
* If `gorm.type` is set to `sqlite`, MySQL-related configurations are not required.
|
* If `gorm.type` is set to `sqlite`, MySQL-related configurations are not required.
|
||||||
* Language support: `en` and `zh-CN` are supported. The default is `zh-CN`.
|
* Language support: `en` and `zh-CN` are supported. The default is `zh-CN`.
|
||||||
|
|
||||||
```yaml
|
|
||||||
lang: "en"
|
|
||||||
app:
|
|
||||||
web-client: 1 # web client route 1:open 0:close
|
|
||||||
register: false #register enable
|
|
||||||
show-swagger: 0 #show swagger 1:open 0:close
|
|
||||||
gin:
|
|
||||||
api-addr: "0.0.0.0:21114"
|
|
||||||
mode: "release"
|
|
||||||
resources-path: 'resources'
|
|
||||||
trust-proxy: ""
|
|
||||||
gorm:
|
|
||||||
type: "sqlite"
|
|
||||||
max-idle-conns: 10
|
|
||||||
max-open-conns: 100
|
|
||||||
mysql:
|
|
||||||
username: "root"
|
|
||||||
password: "111111"
|
|
||||||
addr: "192.168.1.66:3308"
|
|
||||||
dbname: "rustdesk"
|
|
||||||
rustdesk:
|
|
||||||
id-server: "192.168.1.66:21116"
|
|
||||||
relay-server: "192.168.1.66:21117"
|
|
||||||
api-server: "http://192.168.1.66:21114"
|
|
||||||
key: "123456789"
|
|
||||||
personal: 1
|
|
||||||
logger:
|
|
||||||
path: "./runtime/log.txt"
|
|
||||||
level: "warn" #trace,debug,info,warn,error,fatal
|
|
||||||
report-caller: true
|
|
||||||
proxy:
|
|
||||||
enable: false
|
|
||||||
host: ""
|
|
||||||
```
|
|
||||||
|
|
||||||
### Environment Variables
|
### Environment Variables
|
||||||
The prefix for variable names is `RUSTDESK_API`. If environment variables exist, they will override the configurations in the configuration file.
|
The environment variables correspond one-to-one with the configurations in the `conf/config.yaml` file. The prefix for variable names is `RUSTDESK_API`.
|
||||||
|
The table below does not list all configurations. Please refer to the configurations in `conf/config.yaml`.
|
||||||
|
|
||||||
| Variable Name | Description | Example |
|
| Variable Name | Description | Example |
|
||||||
|-----------------------------------------------------|--------------------------------------------------------------------------------------------------------------|-------------------------------|
|
|--------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------|
|
||||||
| TZ | timezone | Asia/Shanghai |
|
| TZ | timezone | Asia/Shanghai |
|
||||||
| RUSTDESK_API_LANG | Language | `en`,`zh-CN` |
|
| RUSTDESK_API_LANG | Language | `en`,`zh-CN` |
|
||||||
| RUSTDESK_API_APP_WEB_CLIENT | web client on/off; 1: on, 0 off, default: 1 | 1 |
|
| RUSTDESK_API_APP_WEB_CLIENT | web client on/off; 1: on, 0 off, default: 1 | 1 |
|
||||||
| RUSTDESK_API_APP_REGISTER | register enable; `true`, `false`; default:`false` | `false` |
|
| RUSTDESK_API_APP_REGISTER | register enable; `true`, `false`; default:`false` | `false` |
|
||||||
| RUSTDESK_API_APP_SHOW_SWAGGER | swagger visible; 1: yes, 0: no; default: 0 | `0` |
|
| RUSTDESK_API_APP_SHOW_SWAGGER | swagger visible; 1: yes, 0: no; default: 0 | `0` |
|
||||||
| ----- ADMIN Configuration----- | ---------- | ---------- |
|
| RUSTDESK_API_APP_TOKEN_EXPIRE | token expire duration | `168h` |
|
||||||
| RUSTDESK_API_ADMIN_TITLE | Admin Title | `RustDesk Api Admin` |
|
| RUSTDESK_API_APP_DISABLE_PWD_LOGIN | disable password login | `false` |
|
||||||
| RUSTDESK_API_ADMIN_HELLO | Admin welcome message, you can use `html` | |
|
| ----- ADMIN Configuration----- | ---------- | ---------- |
|
||||||
| RUSTDESK_API_ADMIN_HELLO_FILE | Admin welcome message file,<br>will override `RUSTDESK_API_ADMIN_HELLO` | `./conf/admin/hello.html` |
|
| RUSTDESK_API_ADMIN_TITLE | Admin Title | `RustDesk Api Admin` |
|
||||||
| ----- GIN Configuration ----- | --------------------------------------- | ----------------------------- |
|
| RUSTDESK_API_ADMIN_HELLO | Admin welcome message, you can use `html` | |
|
||||||
| RUSTDESK_API_GIN_TRUST_PROXY | Trusted proxy IPs, separated by commas. | 192.168.1.2,192.168.1.3 |
|
| RUSTDESK_API_ADMIN_HELLO_FILE | Admin welcome message file,<br>will override `RUSTDESK_API_ADMIN_HELLO` | `./conf/admin/hello.html` |
|
||||||
| ----- GORM Configuration ----- | --------------------------------------- | ----------------------------- |
|
| ----- GIN Configuration ----- | --------------------------------------- | ----------------------------- |
|
||||||
| RUSTDESK_API_GORM_TYPE | Database type (`sqlite` or `mysql`). Default is `sqlite`. | sqlite |
|
| RUSTDESK_API_GIN_TRUST_PROXY | Trusted proxy IPs, separated by commas. | 192.168.1.2,192.168.1.3 |
|
||||||
| RUSTDESK_API_GORM_MAX_IDLE_CONNS | Maximum idle connections | 10 |
|
| ----- GORM Configuration ----- | --------------------------------------- | ----------------------------- |
|
||||||
| RUSTDESK_API_GORM_MAX_OPEN_CONNS | Maximum open connections | 100 |
|
| RUSTDESK_API_GORM_TYPE | Database type (`sqlite` or `mysql`). Default is `sqlite`. | sqlite |
|
||||||
| RUSTDESK_API_RUSTDESK_PERSONAL | Open Personal Api 1:Enable,0:Disable | 1 |
|
| RUSTDESK_API_GORM_MAX_IDLE_CONNS | Maximum idle connections | 10 |
|
||||||
| ----- MYSQL Configuration ----- | --------------------------------------- | ----------------------------- |
|
| RUSTDESK_API_GORM_MAX_OPEN_CONNS | Maximum open connections | 100 |
|
||||||
| RUSTDESK_API_MYSQL_USERNAME | MySQL username | root |
|
| RUSTDESK_API_RUSTDESK_PERSONAL | Open Personal Api 1:Enable,0:Disable | 1 |
|
||||||
| RUSTDESK_API_MYSQL_PASSWORD | MySQL password | 111111 |
|
| ----- MYSQL Configuration ----- | --------------------------------------- | ----------------------------- |
|
||||||
| RUSTDESK_API_MYSQL_ADDR | MySQL address | 192.168.1.66:3306 |
|
| RUSTDESK_API_MYSQL_USERNAME | MySQL username | root |
|
||||||
| RUSTDESK_API_MYSQL_DBNAME | MySQL database name | rustdesk |
|
| RUSTDESK_API_MYSQL_PASSWORD | MySQL password | 111111 |
|
||||||
| ----- RUSTDESK Configuration ----- | --------------------------------------- | ----------------------------- |
|
| RUSTDESK_API_MYSQL_ADDR | MySQL address | 192.168.1.66:3306 |
|
||||||
| RUSTDESK_API_RUSTDESK_ID_SERVER | Rustdesk ID server address | 192.168.1.66:21116 |
|
| RUSTDESK_API_MYSQL_DBNAME | MySQL database name | rustdesk |
|
||||||
| RUSTDESK_API_RUSTDESK_RELAY_SERVER | Rustdesk relay server address | 192.168.1.66:21117 |
|
| ----- RUSTDESK Configuration ----- | --------------------------------------- | ----------------------------- |
|
||||||
| RUSTDESK_API_RUSTDESK_API_SERVER | Rustdesk API server address | http://192.168.1.66:21114 |
|
| RUSTDESK_API_RUSTDESK_ID_SERVER | Rustdesk ID server address | 192.168.1.66:21116 |
|
||||||
| RUSTDESK_API_RUSTDESK_KEY | Rustdesk key | 123456789 |
|
| RUSTDESK_API_RUSTDESK_RELAY_SERVER | Rustdesk relay server address | 192.168.1.66:21117 |
|
||||||
| RUSTDESK_API_RUSTDESK_KEY_FILE | Rustdesk key file | `./conf/data/id_ed25519.pub` |
|
| RUSTDESK_API_RUSTDESK_API_SERVER | Rustdesk API server address | http://192.168.1.66:21114 |
|
||||||
| RUSTDESK_API_RUSTDESK_WEBCLIENT_MAGIC_QUERYONLINE | New online query method is enabled in the web client v2; '1': Enabled, '0': Disabled, not enabled by default | `0` |
|
| RUSTDESK_API_RUSTDESK_KEY | Rustdesk key | 123456789 |
|
||||||
| ---- PROXY ----- | --------------- | ---------- |
|
| RUSTDESK_API_RUSTDESK_KEY_FILE | Rustdesk key file | `./conf/data/id_ed25519.pub` |
|
||||||
| RUSTDESK_API_PROXY_ENABLE | proxy_enable :`false`, `true` | `false` |
|
| RUSTDESK_API_RUSTDESK<br/>_WEBCLIENT_MAGIC_QUERYONLINE | New online query method is enabled in the web client v2; '1': Enabled, '0': Disabled, not enabled by default | `0` |
|
||||||
| RUSTDESK_API_PROXY_HOST | proxy_host | `http://127.0.0.1:1080` |
|
| RUSTDESK_API_RUSTDESK_WS_HOST | Custom Websocket Host | `wss://192.168.1.123:1234` |
|
||||||
|
| ---- PROXY ----- | --------------- | ---------- |
|
||||||
|
| RUSTDESK_API_PROXY_ENABLE | proxy_enable :`false`, `true` | `false` |
|
||||||
|
| RUSTDESK_API_PROXY_HOST | proxy_host | `http://127.0.0.1:1080` |
|
||||||
|
| ----JWT---- | -------- | -------- |
|
||||||
|
| RUSTDESK_API_JWT_KEY | Custom JWT KEY, if empty JWT is not enabled.<br/>If `MUST_LOGIN` from `lejianwen/rustdesk-server` is not used, it is recommended to leave it empty. | |
|
||||||
|
| RUSTDESK_API_JWT_EXPIRE_DURATION | JWT expire duration | `168h` |
|
||||||
|
|
||||||
### Installation Steps
|
### Installation Steps
|
||||||
|
|
||||||
@@ -314,8 +260,58 @@ Download the release from [release](https://github.com/lejianwen/rustdesk-api/re
|
|||||||
6. Open your browser and visit `http://<your server[:port]>/_admin/`, with default credentials `admin admin`. Please
|
6. Open your browser and visit `http://<your server[:port]>/_admin/`, with default credentials `admin admin`. Please
|
||||||
change the password promptly.
|
change the password promptly.
|
||||||
|
|
||||||
|
#### Running with my forked server-s6 image
|
||||||
|
|
||||||
|
- Connection timeout issue resolved
|
||||||
|
- Can enforce login before initiating a connection
|
||||||
|
- github https://github.com/lejianwen/rustdesk-server
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
networks:
|
||||||
|
rustdesk-net:
|
||||||
|
external: false
|
||||||
|
services:
|
||||||
|
rustdesk:
|
||||||
|
ports:
|
||||||
|
- 21114:21114
|
||||||
|
- 21115:21115
|
||||||
|
- 21116:21116
|
||||||
|
- 21116:21116/udp
|
||||||
|
- 21117:21117
|
||||||
|
- 21118:21118
|
||||||
|
- 21119:21119
|
||||||
|
image: lejianwen/rustdesk-server-s6:latest
|
||||||
|
environment:
|
||||||
|
- RELAY=<relay_server[:port]>
|
||||||
|
- ENCRYPTED_ONLY=1
|
||||||
|
- MUST_LOGIN=N
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
- RUSTDESK_API_RUSTDESK_ID_SERVER=<id_server[:21116]>
|
||||||
|
- RUSTDESK_API_RUSTDESK_RELAY_SERVER=<relay_server[:21117]>
|
||||||
|
- RUSTDESK_API_RUSTDESK_API_SERVER=http://<api_server[:21114]>
|
||||||
|
- RUSTDESK_API_KEY_FILE=/data/id_ed25519.pub
|
||||||
|
- RUSTDESK_API_JWT_KEY=xxxxxx # jwt key
|
||||||
|
volumes:
|
||||||
|
- /data/rustdesk/server:/data
|
||||||
|
- /data/rustdesk/api:/app/data #将数据库挂载
|
||||||
|
networks:
|
||||||
|
- rustdesk-net
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
```
|
||||||
## Others
|
## Others
|
||||||
|
|
||||||
|
- [WIKI](https://github.com/lejianwen/rustdesk-api/wiki)
|
||||||
|
- [Connection Timeout](https://github.com/lejianwen/rustdesk-api/issues/92)
|
||||||
- [Change client ID](https://github.com/abdullah-erturk/RustDesk-ID-Changer)
|
- [Change client ID](https://github.com/abdullah-erturk/RustDesk-ID-Changer)
|
||||||
- [Web client source](https://hub.docker.com/r/keyurbhole/flutter_web_desk)
|
- [Web client source](https://hub.docker.com/r/keyurbhole/flutter_web_desk)
|
||||||
|
|
||||||
|
## Acknowledgements
|
||||||
|
|
||||||
|
Thanks to everyone who contributed!
|
||||||
|
|
||||||
|
<a href="https://github.com/lejianwen/rustdesk-api/graphs/contributors">
|
||||||
|
<img src="https://contrib.rocks/image?repo=lejianwen/rustdesk-api" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
## Thanks for your support! If you find this project useful, please give it a ⭐️. Thank you!
|
||||||
@@ -1,18 +1,19 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/config"
|
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http"
|
|
||||||
"Gwen/lib/cache"
|
|
||||||
"Gwen/lib/lock"
|
|
||||||
"Gwen/lib/logger"
|
|
||||||
"Gwen/lib/orm"
|
|
||||||
"Gwen/lib/upload"
|
|
||||||
"Gwen/model"
|
|
||||||
"Gwen/service"
|
|
||||||
"fmt"
|
|
||||||
"github.com/go-redis/redis/v8"
|
"github.com/go-redis/redis/v8"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/config"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/lib/cache"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/lib/jwt"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/lib/lock"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/lib/logger"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/lib/orm"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/lib/upload"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/utils"
|
||||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"os"
|
"os"
|
||||||
@@ -37,7 +38,7 @@ var rootCmd = &cobra.Command{
|
|||||||
InitGlobal()
|
InitGlobal()
|
||||||
},
|
},
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
//gin
|
global.Logger.Info("API SERVER START")
|
||||||
http.ApiInit()
|
http.ApiInit()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -50,12 +51,16 @@ var resetPwdCmd = &cobra.Command{
|
|||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
pwd := args[0]
|
pwd := args[0]
|
||||||
admin := service.AllService.UserService.InfoById(1)
|
admin := service.AllService.UserService.InfoById(1)
|
||||||
err := service.AllService.UserService.UpdatePassword(admin, pwd)
|
if admin.Id == 0 {
|
||||||
if err != nil {
|
global.Logger.Warn("user not found! ")
|
||||||
fmt.Printf("reset password fail! %v \n", err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Printf("reset password success! \n")
|
err := service.AllService.UserService.UpdatePassword(admin, pwd)
|
||||||
|
if err != nil {
|
||||||
|
global.Logger.Error("reset password fail! ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
global.Logger.Info("reset password success! ")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
var resetUserPwdCmd = &cobra.Command{
|
var resetUserPwdCmd = &cobra.Command{
|
||||||
@@ -68,20 +73,24 @@ var resetUserPwdCmd = &cobra.Command{
|
|||||||
pwd := args[1]
|
pwd := args[1]
|
||||||
uid, err := strconv.Atoi(userId)
|
uid, err := strconv.Atoi(userId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("userId must be int! \n")
|
global.Logger.Warn("userId must be int!")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if uid <= 0 {
|
if uid <= 0 {
|
||||||
fmt.Printf("userId must be greater than 0! \n")
|
global.Logger.Warn("userId must be greater than 0! ")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
u := service.AllService.UserService.InfoById(uint(uid))
|
u := service.AllService.UserService.InfoById(uint(uid))
|
||||||
err = service.AllService.UserService.UpdatePassword(u, pwd)
|
if u.Id == 0 {
|
||||||
if err != nil {
|
global.Logger.Warn("user not found! ")
|
||||||
fmt.Printf("reset password fail! %v \n", err)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Printf("reset password success! \n")
|
err = service.AllService.UserService.UpdatePassword(u, pwd)
|
||||||
|
if err != nil {
|
||||||
|
global.Logger.Warn("reset password fail! ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
global.Logger.Info("reset password success!")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +100,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
func main() {
|
func main() {
|
||||||
if err := rootCmd.Execute(); err != nil {
|
if err := rootCmd.Execute(); err != nil {
|
||||||
fmt.Println(err)
|
global.Logger.Error(err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,9 +109,6 @@ func InitGlobal() {
|
|||||||
//配置解析
|
//配置解析
|
||||||
global.Viper = config.Init(&global.Config, global.ConfigPath)
|
global.Viper = config.Init(&global.Config, global.ConfigPath)
|
||||||
|
|
||||||
//从配置文件中加载密钥
|
|
||||||
config.LoadKeyFile(&global.Config.Rustdesk)
|
|
||||||
|
|
||||||
//日志
|
//日志
|
||||||
global.Logger = logger.New(&logger.Config{
|
global.Logger = logger.New(&logger.Config{
|
||||||
Path: global.Config.Logger.Path,
|
Path: global.Config.Logger.Path,
|
||||||
@@ -146,7 +152,6 @@ func InitGlobal() {
|
|||||||
MaxOpenConns: global.Config.Gorm.MaxOpenConns,
|
MaxOpenConns: global.Config.Gorm.MaxOpenConns,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
DatabaseAutoUpdate()
|
|
||||||
|
|
||||||
//validator
|
//validator
|
||||||
global.ApiInitValidator()
|
global.ApiInitValidator()
|
||||||
@@ -163,20 +168,23 @@ func InitGlobal() {
|
|||||||
|
|
||||||
//jwt
|
//jwt
|
||||||
//fmt.Println(global.Config.Jwt.PrivateKey)
|
//fmt.Println(global.Config.Jwt.PrivateKey)
|
||||||
//global.Jwt = jwt.NewJwt(global.Config.Jwt.PrivateKey, global.Config.Jwt.ExpireDuration*time.Second)
|
global.Jwt = jwt.NewJwt(global.Config.Jwt.Key, global.Config.Jwt.ExpireDuration)
|
||||||
|
|
||||||
//locker
|
//locker
|
||||||
global.Lock = lock.NewLocal()
|
global.Lock = lock.NewLocal()
|
||||||
|
|
||||||
|
//service
|
||||||
|
service.New(&global.Config, global.DB, global.Logger, global.Jwt, global.Lock)
|
||||||
|
|
||||||
|
DatabaseAutoUpdate()
|
||||||
}
|
}
|
||||||
func DatabaseAutoUpdate() {
|
func DatabaseAutoUpdate() {
|
||||||
version := 246
|
version := 262
|
||||||
|
|
||||||
db := global.DB
|
db := global.DB
|
||||||
|
|
||||||
if global.Config.Gorm.Type == config.TypeMysql {
|
if global.Config.Gorm.Type == config.TypeMysql {
|
||||||
//检查存不存在数据库,不存在则创建
|
//检查存不存在数据库,不存在则创建
|
||||||
dbName := db.Migrator().CurrentDatabase()
|
dbName := db.Migrator().CurrentDatabase()
|
||||||
fmt.Println("dbName", dbName)
|
|
||||||
if dbName == "" {
|
if dbName == "" {
|
||||||
dbName = global.Config.Mysql.Dbname
|
dbName = global.Config.Mysql.Dbname
|
||||||
// 移除 DSN 中的数据库名称,以便初始连接时不指定数据库
|
// 移除 DSN 中的数据库名称,以便初始连接时不指定数据库
|
||||||
@@ -188,18 +196,18 @@ func DatabaseAutoUpdate() {
|
|||||||
// 获取底层的 *sql.DB 对象,并确保在程序退出时关闭连接
|
// 获取底层的 *sql.DB 对象,并确保在程序退出时关闭连接
|
||||||
sqlDBWithoutDB, err := dbWithoutDB.DB()
|
sqlDBWithoutDB, err := dbWithoutDB.DB()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("获取底层 *sql.DB 对象失败: %v\n", err)
|
global.Logger.Errorf("获取底层 *sql.DB 对象失败: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := sqlDBWithoutDB.Close(); err != nil {
|
if err := sqlDBWithoutDB.Close(); err != nil {
|
||||||
fmt.Printf("关闭连接失败: %v\n", err)
|
global.Logger.Errorf("关闭连接失败: %v", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
err = dbWithoutDB.Exec("CREATE DATABASE IF NOT EXISTS " + dbName + " DEFAULT CHARSET utf8mb4").Error
|
err = dbWithoutDB.Exec("CREATE DATABASE IF NOT EXISTS " + dbName + " DEFAULT CHARSET utf8mb4").Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
global.Logger.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -214,6 +222,7 @@ func DatabaseAutoUpdate() {
|
|||||||
if v.Version < uint(version) {
|
if v.Version < uint(version) {
|
||||||
Migrate(uint(version))
|
Migrate(uint(version))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 245迁移
|
// 245迁移
|
||||||
if v.Version < 245 {
|
if v.Version < 245 {
|
||||||
//oauths 表的 oauth_type 字段设置为 op同样的值
|
//oauths 表的 oauth_type 字段设置为 op同样的值
|
||||||
@@ -236,7 +245,7 @@ func DatabaseAutoUpdate() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
func Migrate(version uint) {
|
func Migrate(version uint) {
|
||||||
fmt.Println("migrating....", version)
|
global.Logger.Info("Migrating....", version)
|
||||||
err := global.DB.AutoMigrate(
|
err := global.DB.AutoMigrate(
|
||||||
&model.Version{},
|
&model.Version{},
|
||||||
&model.User{},
|
&model.User{},
|
||||||
@@ -253,9 +262,11 @@ func Migrate(version uint) {
|
|||||||
&model.AuditFile{},
|
&model.AuditFile{},
|
||||||
&model.AddressBookCollection{},
|
&model.AddressBookCollection{},
|
||||||
&model.AddressBookCollectionRule{},
|
&model.AddressBookCollectionRule{},
|
||||||
|
&model.ServerCmd{},
|
||||||
|
&model.DeviceGroup{},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("migrate err :=>", err)
|
global.Logger.Error("migrate err :=>", err)
|
||||||
}
|
}
|
||||||
global.DB.Create(&model.Version{Version: version})
|
global.DB.Create(&model.Version{Version: version})
|
||||||
//如果是初次则创建一个默认用户
|
//如果是初次则创建一个默认用户
|
||||||
@@ -289,7 +300,11 @@ func Migrate(version uint) {
|
|||||||
IsAdmin: &is_admin,
|
IsAdmin: &is_admin,
|
||||||
GroupId: 1,
|
GroupId: 1,
|
||||||
}
|
}
|
||||||
admin.Password = service.AllService.UserService.EncryptPassword("admin")
|
|
||||||
|
// 生成随机密码
|
||||||
|
pwd := utils.RandomString(8)
|
||||||
|
global.Logger.Info("Admin Password Is: ", pwd)
|
||||||
|
admin.Password = service.AllService.UserService.EncryptPassword(pwd)
|
||||||
global.DB.Create(admin)
|
global.DB.Create(admin)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
👏👏👏 你好 <strong>{{username}}</strong>, 欢迎使用 <a href='https://github.com/lejianwen/rustdesk-api' target='_blank'>RustDesk Api Admin</a>
|
### 👏👏👏 你好 ***{{username}}***, 欢迎使用 [RustDesk API](https://github.com/lejianwen/rustdesk-api)
|
||||||
@@ -3,6 +3,9 @@ app:
|
|||||||
web-client: 1 # 1:启用 0:禁用
|
web-client: 1 # 1:启用 0:禁用
|
||||||
register: false #是否开启注册
|
register: false #是否开启注册
|
||||||
show-swagger: 0 # 1:启用 0:禁用
|
show-swagger: 0 # 1:启用 0:禁用
|
||||||
|
token-expire: 168h
|
||||||
|
web-sso: true #web auth sso
|
||||||
|
disable-pwd-login: false #禁用密码登录
|
||||||
admin:
|
admin:
|
||||||
title: "RustDesk Api Admin"
|
title: "RustDesk Api Admin"
|
||||||
hello-file: "./conf/admin/hello.html" #优先使用file
|
hello-file: "./conf/admin/hello.html" #优先使用file
|
||||||
@@ -26,33 +29,38 @@ rustdesk:
|
|||||||
relay-server: "192.168.1.66:21117"
|
relay-server: "192.168.1.66:21117"
|
||||||
api-server: "http://127.0.0.1:21114"
|
api-server: "http://127.0.0.1:21114"
|
||||||
key: ""
|
key: ""
|
||||||
key-file: "./conf/data/id_ed25519.pub"
|
key-file: "/data/id_ed25519.pub"
|
||||||
personal: 1
|
personal: 1
|
||||||
webclient-magic-queryonline: 0
|
webclient-magic-queryonline: 0
|
||||||
|
ws-host: "" #eg: wss://192.168.1.3:4443
|
||||||
logger:
|
logger:
|
||||||
path: "./runtime/log.txt"
|
path: "./runtime/log.txt"
|
||||||
level: "warn" #trace,debug,info,warn,error,fatal
|
level: "info" #trace,debug,info,warn,error,fatal
|
||||||
report-caller: true
|
report-caller: true
|
||||||
proxy:
|
proxy:
|
||||||
enable: false
|
enable: false
|
||||||
host: "http://127.0.0.1:1080"
|
host: "http://127.0.0.1:1080"
|
||||||
redis:
|
|
||||||
addr: "127.0.0.1:6379"
|
|
||||||
password: ""
|
|
||||||
db: 0
|
|
||||||
cache:
|
|
||||||
type: "file"
|
|
||||||
file-dir: "./runtime/cache"
|
|
||||||
redis-addr: "127.0.0.1:6379"
|
|
||||||
redis-pwd: ""
|
|
||||||
redis-db: 0
|
|
||||||
oss:
|
|
||||||
access-key-id: ""
|
|
||||||
access-key-secret: ""
|
|
||||||
host: ""
|
|
||||||
callback-url: ""
|
|
||||||
expire-time: 30
|
|
||||||
max-byte: 10240
|
|
||||||
jwt:
|
jwt:
|
||||||
private-key: "./conf/jwt_pri.pem"
|
key: ""
|
||||||
expire-duration: 360000
|
expire-duration: 168h
|
||||||
|
ldap:
|
||||||
|
enable: false
|
||||||
|
url: "ldap://ldap.example.com:389"
|
||||||
|
tls-ca-file: ""
|
||||||
|
tls-verify: false
|
||||||
|
base-dn: "dc=example,dc=com"
|
||||||
|
bind-dn: "cn=admin,dc=example,dc=com"
|
||||||
|
bind-password: "password"
|
||||||
|
|
||||||
|
user:
|
||||||
|
base-dn: "ou=users,dc=example,dc=com"
|
||||||
|
enable-attr: "" #The attribute name of the user for enabling, in AD it is "userAccountControl", empty means no enable attribute, all users are enabled
|
||||||
|
enable-attr-value: "" # The value of the enable attribute when the user is enabled. If you are using AD, just set random value, it will be ignored.
|
||||||
|
filter: "(cn=*)"
|
||||||
|
username: "uid" # The attribute name of the user for usernamem if you are using AD, it should be "sAMAccountName"
|
||||||
|
email: "mail"
|
||||||
|
first-name: "givenName"
|
||||||
|
last-name: "sn"
|
||||||
|
sync: false # If true, the user will be synchronized to the database when the user logs in. If false, the user will be synchronized to the database when the user be created.
|
||||||
|
admin-group: "cn=admin,dc=example,dc=com" # The group name of the admin group, if the user is in this group, the user will be an admin.
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/fsnotify/fsnotify"
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -14,9 +14,12 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type App struct {
|
type App struct {
|
||||||
WebClient int `mapstructure:"web-client"`
|
WebClient int `mapstructure:"web-client"`
|
||||||
Register bool `mapstructure:"register"`
|
Register bool `mapstructure:"register"`
|
||||||
ShowSwagger int `mapstructure:"show-swagger"`
|
ShowSwagger int `mapstructure:"show-swagger"`
|
||||||
|
TokenExpire time.Duration `mapstructure:"token-expire"`
|
||||||
|
WebSso bool `mapstructure:"web-sso"`
|
||||||
|
DisablePwdLogin bool `mapstructure:"disable-pwd-login"`
|
||||||
}
|
}
|
||||||
type Admin struct {
|
type Admin struct {
|
||||||
Title string `mapstructure:"title"`
|
Title string `mapstructure:"title"`
|
||||||
@@ -37,10 +40,11 @@ type Config struct {
|
|||||||
Jwt Jwt
|
Jwt Jwt
|
||||||
Rustdesk Rustdesk
|
Rustdesk Rustdesk
|
||||||
Proxy Proxy
|
Proxy Proxy
|
||||||
|
Ldap Ldap
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init 初始化配置
|
// Init 初始化配置
|
||||||
func Init(rowVal interface{}, path string) *viper.Viper {
|
func Init(rowVal *Config, path string) *viper.Viper {
|
||||||
if path == "" {
|
if path == "" {
|
||||||
path = DefaultConfig
|
path = DefaultConfig
|
||||||
}
|
}
|
||||||
@@ -54,18 +58,26 @@ func Init(rowVal interface{}, path string) *viper.Viper {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("Fatal error config file: %s \n", err))
|
panic(fmt.Errorf("Fatal error config file: %s \n", err))
|
||||||
}
|
}
|
||||||
v.WatchConfig()
|
/*
|
||||||
v.OnConfigChange(func(e fsnotify.Event) {
|
v.WatchConfig()
|
||||||
//配置文件修改监听
|
|
||||||
fmt.Println("config file changed:", e.Name)
|
|
||||||
if err2 := v.Unmarshal(rowVal); err2 != nil {
|
|
||||||
fmt.Println(err2)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if err := v.Unmarshal(rowVal); err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
//监听配置修改没什么必要
|
||||||
|
v.OnConfigChange(func(e fsnotify.Event) {
|
||||||
|
//配置文件修改监听
|
||||||
|
fmt.Println("config file changed:", e.Name)
|
||||||
|
if err2 := v.Unmarshal(rowVal); err2 != nil {
|
||||||
|
fmt.Println(err2)
|
||||||
|
}
|
||||||
|
rowVal.Rustdesk.LoadKeyFile()
|
||||||
|
rowVal.Rustdesk.ParsePort()
|
||||||
|
})
|
||||||
|
*/
|
||||||
|
if err := v.Unmarshal(rowVal); err != nil {
|
||||||
|
panic(fmt.Errorf("Fatal error config: %s \n", err))
|
||||||
|
}
|
||||||
|
rowVal.Rustdesk.LoadKeyFile()
|
||||||
|
rowVal.Rustdesk.ParsePort()
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ package config
|
|||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
type Jwt struct {
|
type Jwt struct {
|
||||||
PrivateKey string `mapstructure:"private-key"`
|
Key string `mapstructure:"key"`
|
||||||
ExpireDuration time.Duration `mapstructure:"expire-duration"`
|
ExpireDuration time.Duration `mapstructure:"expire-duration"`
|
||||||
}
|
}
|
||||||
|
|||||||
36
config/ldap.go
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
type LdapUser struct {
|
||||||
|
BaseDn string `mapstructure:"base-dn"` // The base DN of the user for searching
|
||||||
|
EnableAttr string `mapstructure:"enable-attr"` // The attribute name of the user for enabling, in AD it is "userAccountControl", empty means no enable attribute, all users are enabled
|
||||||
|
EnableAttrValue string `mapstructure:"enable-attr-value"` // The value of the enable attribute when the user is enabled. If you are using AD, just leave it random str, it will be ignored.
|
||||||
|
Filter string `mapstructure:"filter"`
|
||||||
|
Username string `mapstructure:"username"`
|
||||||
|
Email string `mapstructure:"email"`
|
||||||
|
FirstName string `mapstructure:"first-name"`
|
||||||
|
LastName string `mapstructure:"last-name"`
|
||||||
|
Sync bool `mapstructure:"sync"` // Will sync the user's information to the internal database
|
||||||
|
AdminGroup string `mapstructure:"admin-group"` // Which group is the admin group
|
||||||
|
}
|
||||||
|
|
||||||
|
// type LdapGroup struct {
|
||||||
|
// BaseDn string `mapstructure:"base-dn"` // The base DN of the group for searching
|
||||||
|
// Name string `mapstructure:"name"` // The attribute name of the group
|
||||||
|
// Filter string `mapstructure:"filter"`
|
||||||
|
// Admin string `mapstructure:"admin"` // Which group is the admin group
|
||||||
|
// Member string `mapstructure:"member"` // How to get the member of the group: member, uniqueMember, or memberOf (default: member)
|
||||||
|
// Mode string `mapstructure:"mode"`
|
||||||
|
// Map map[string]string `mapstructure:"map"` // If mode is "map", map the LDAP group to the internal group
|
||||||
|
// }
|
||||||
|
|
||||||
|
type Ldap struct {
|
||||||
|
Enable bool `mapstructure:"enable"`
|
||||||
|
Url string `mapstructure:"url"`
|
||||||
|
TlsCaFile string `mapstructure:"tls-ca-file"`
|
||||||
|
TlsVerify bool `mapstructure:"tls-verify"`
|
||||||
|
BaseDn string `mapstructure:"base-dn"`
|
||||||
|
BindDn string `mapstructure:"bind-dn"`
|
||||||
|
BindPassword string `mapstructure:"bind-password"`
|
||||||
|
User LdapUser `mapstructure:"user"`
|
||||||
|
// Group LdapGroup `mapstructure:"group"`
|
||||||
|
}
|
||||||
@@ -17,4 +17,4 @@ type OidcOauth struct {
|
|||||||
ClientId string `mapstructure:"client-id"`
|
ClientId string `mapstructure:"client-id"`
|
||||||
ClientSecret string `mapstructure:"client-secret"`
|
ClientSecret string `mapstructure:"client-secret"`
|
||||||
RedirectUrl string `mapstructure:"redirect-url"`
|
RedirectUrl string `mapstructure:"redirect-url"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,31 +2,57 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DefaultIdServerPort = 21116
|
||||||
|
DefaultRelayServerPort = 21117
|
||||||
)
|
)
|
||||||
|
|
||||||
type Rustdesk struct {
|
type Rustdesk struct {
|
||||||
IdServer string `mapstructure:"id-server"`
|
IdServer string `mapstructure:"id-server"`
|
||||||
RelayServer string `mapstructure:"relay-server"`
|
IdServerPort int `mapstructure:"-"`
|
||||||
ApiServer string `mapstructure:"api-server"`
|
RelayServer string `mapstructure:"relay-server"`
|
||||||
Key string `mapstructure:"key"`
|
RelayServerPort int `mapstructure:"-"`
|
||||||
KeyFile string `mapstructure:"key-file"`
|
ApiServer string `mapstructure:"api-server"`
|
||||||
Personal int `mapstructure:"personal"`
|
Key string `mapstructure:"key"`
|
||||||
|
KeyFile string `mapstructure:"key-file"`
|
||||||
|
Personal int `mapstructure:"personal"`
|
||||||
//webclient-magic-queryonline
|
//webclient-magic-queryonline
|
||||||
WebclientMagicQueryonline int `mapstructure:"webclient-magic-queryonline"`
|
WebclientMagicQueryonline int `mapstructure:"webclient-magic-queryonline"`
|
||||||
|
WsHost string `mapstructure:"ws-host"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadKeyFile(rustdesk *Rustdesk) {
|
func (rd *Rustdesk) LoadKeyFile() {
|
||||||
// Load key file
|
// Load key file
|
||||||
if rustdesk.Key != "" {
|
if rd.Key != "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if rustdesk.KeyFile != "" {
|
if rd.KeyFile != "" {
|
||||||
// Load key from file
|
// Load key from file
|
||||||
b, err := os.ReadFile(rustdesk.KeyFile)
|
b, err := os.ReadFile(rd.KeyFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
rustdesk.Key = string(b)
|
rd.Key = string(b)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func (rd *Rustdesk) ParsePort() {
|
||||||
|
// Parse port
|
||||||
|
idres := strings.Split(rd.IdServer, ":")
|
||||||
|
if len(idres) == 1 {
|
||||||
|
rd.IdServerPort = DefaultIdServerPort
|
||||||
|
} else if len(idres) == 2 {
|
||||||
|
rd.IdServerPort, _ = strconv.Atoi(idres[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
relayres := strings.Split(rd.RelayServer, ":")
|
||||||
|
if len(relayres) == 1 {
|
||||||
|
rd.RelayServerPort = DefaultRelayServerPort
|
||||||
|
} else if len(relayres) == 2 {
|
||||||
|
rd.RelayServerPort, _ = strconv.Atoi(relayres[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
5
debian/changelog
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
rustdesk-api-server (1.3.6) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
|
* Update the version to 1.3.6 to match the client.
|
||||||
|
|
||||||
|
-- rustdesk-api <ymwlpoolc@qq.com> Tue, 24 Dec 2024 13:48:34 +0800
|
||||||
1
debian/compat
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
10
|
||||||
13
debian/control.tpl
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
Source: rustdesk-api-server
|
||||||
|
Section: net
|
||||||
|
Priority: optional
|
||||||
|
Maintainer: ymwl <ymwlpoolc@qq.com>
|
||||||
|
Build-Depends: debhelper (>= 10), pkg-config
|
||||||
|
Standards-Version: 4.5.0
|
||||||
|
Homepage: https://github.com/lejianwen/rustdesk-api/
|
||||||
|
|
||||||
|
Package: rustdesk-api-server
|
||||||
|
Architecture: {{ ARCH }}
|
||||||
|
Depends: systemd ${misc:Depends}
|
||||||
|
Description: RustDesk api server
|
||||||
|
RustDesk api server, it is free and open source.
|
||||||
21
debian/copyright
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2024-present Lejianwen and contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
6
debian/rules
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/make -f
|
||||||
|
%:
|
||||||
|
dh $@
|
||||||
|
|
||||||
|
override_dh_builddeb:
|
||||||
|
dh_builddeb -- -Zgzip
|
||||||
6
debian/rustdesk-api-server.install
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
bin/rustdesk-api usr/bin
|
||||||
|
systemd/rustdesk-api.service lib/systemd/system
|
||||||
|
conf var/lib/rustdesk-api
|
||||||
|
data var/lib/rustdesk-api
|
||||||
|
resources var/lib/rustdesk-api
|
||||||
|
runtime var/lib/rustdesk-api
|
||||||
28
debian/rustdesk-api-server.postinst
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SERVICE=rustdesk-api.service
|
||||||
|
|
||||||
|
if [ "$1" = "configure" ]; then
|
||||||
|
mkdir -p /var/log/rustdesk-api
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
configure|abort-upgrade|abort-deconfigure|abort-remove)
|
||||||
|
mkdir -p /var/lib/rustdesk-api/
|
||||||
|
deb-systemd-helper unmask "${SERVICE}" >/dev/null || true
|
||||||
|
if deb-systemd-helper --quiet was-enabled "${SERVICE}"; then
|
||||||
|
deb-systemd-invoke enable "${SERVICE}" >/dev/null || true
|
||||||
|
else
|
||||||
|
deb-systemd-invoke update-state "${SERVICE}" >/dev/null || true
|
||||||
|
fi
|
||||||
|
systemctl --system daemon-reload >/dev/null || true
|
||||||
|
if [ -n "$2" ]; then
|
||||||
|
deb-systemd-invoke restart "${SERVICE}" >/dev/null || true
|
||||||
|
else
|
||||||
|
deb-systemd-invoke start "${SERVICE}" >/dev/null || true
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
||||||
18
debian/rustdesk-api-server.postrm
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SERVICE=rustdesk-api.service
|
||||||
|
|
||||||
|
systemctl --system daemon-reload >/dev/null || true
|
||||||
|
|
||||||
|
if [ "$1" = "purge" ]; then
|
||||||
|
rm -rf /var/log/rustdesk-api/rustdesk-api.*
|
||||||
|
deb-systemd-helper purge "${SERVICE}" >/dev/null || true
|
||||||
|
deb-systemd-helper unmask "${SERVICE}" >/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$1" = "remove" ]; then
|
||||||
|
deb-systemd-helper mask "${SERVICE}" >/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
13
debian/rustdesk-api-server.prerm
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SERVICE=rustdesk-api.service
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
remove|deconfigure)
|
||||||
|
deb-systemd-invoke stop "${SERVICE}" >/dev/null || true
|
||||||
|
deb-systemd-invoke disable "${SERVICE}" >/dev/null || true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
||||||
1
debian/source/format
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
3.0 (native)
|
||||||
@@ -981,40 +981,6 @@ const docTemplateadmin = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/admin/app-config": {
|
|
||||||
"get": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"token": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "APP服务配置",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"produces": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"ADMIN"
|
|
||||||
],
|
|
||||||
"summary": "APP服务配置",
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "OK",
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/response.Response"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"500": {
|
|
||||||
"description": "Internal Server Error",
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/response.Response"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/admin/audit_conn/batchDelete": {
|
"/admin/audit_conn/batchDelete": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -1441,6 +1407,280 @@ const docTemplateadmin = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/admin/device_group/create": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"token": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "创建设备群组",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"设备群组"
|
||||||
|
],
|
||||||
|
"summary": "创建设备群组",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "设备群组信息",
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/admin.DeviceGroupForm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/model.DeviceGroup"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/admin/device_group/delete": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"token": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "设备群组删除",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"设备群组"
|
||||||
|
],
|
||||||
|
"summary": "设备群组删除",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "群组信息",
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/admin.DeviceGroupForm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/admin/device_group/detail/{id}": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"token": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "设备群组详情",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"设备群组"
|
||||||
|
],
|
||||||
|
"summary": "设备群组详情",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/model.Group"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/admin/device_group/list": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"token": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "群组列表",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"群组"
|
||||||
|
],
|
||||||
|
"summary": "群组列表",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "页码",
|
||||||
|
"name": "page",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "页大小",
|
||||||
|
"name": "page_size",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/model.GroupList"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/admin/device_group/update": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"token": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "设备群组编辑",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"设备群组"
|
||||||
|
],
|
||||||
|
"summary": "设备群组编辑",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "群组信息",
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/admin.DeviceGroupForm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/model.Group"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/admin/file/oss_token": {
|
"/admin/file/oss_token": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -1817,7 +2057,7 @@ const docTemplateadmin = `{
|
|||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/Gwen_http_request_admin.Login"
|
"$ref": "#/definitions/github_com_lejianwen_rustdesk-api_v2_http_request_admin.Login"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -1881,7 +2121,7 @@ const docTemplateadmin = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/admin/login_log/delete": {
|
"/admin/login_log/batchDelete": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
@@ -1926,6 +2166,51 @@ const docTemplateadmin = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/admin/login_log/delete": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"token": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "登录日志删除",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"登录日志"
|
||||||
|
],
|
||||||
|
"summary": "登录日志删除",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "登录日志信息",
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/model.LoginLog"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/admin/login_log/detail/{id}": {
|
"/admin/login_log/detail/{id}": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -2757,6 +3042,162 @@ const docTemplateadmin = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/admin/my/login_log/batchDelete": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"token": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "登录日志批量删除",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"我的登录日志"
|
||||||
|
],
|
||||||
|
"summary": "登录日志批量删除",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "登录日志",
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/admin.LoginLogIds"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/admin/my/login_log/delete": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"token": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "登录日志删除",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"我的登录日志"
|
||||||
|
],
|
||||||
|
"summary": "登录日志删除",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "登录日志信息",
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/model.LoginLog"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/admin/my/login_log/list": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"token": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "登录日志列表",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"我的登录日志"
|
||||||
|
],
|
||||||
|
"summary": "登录日志列表",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "页码",
|
||||||
|
"name": "page",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "页大小",
|
||||||
|
"name": "page_size",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "用户ID",
|
||||||
|
"name": "user_id",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/model.LoginLogList"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/admin/my/peer/list": {
|
"/admin/my/peer/list": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -3884,40 +4325,6 @@ const docTemplateadmin = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/admin/server-config": {
|
|
||||||
"get": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"token": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "服务配置,给webclient提供api-server",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"produces": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"ADMIN"
|
|
||||||
],
|
|
||||||
"summary": "RUSTDESK服务配置",
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "OK",
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/response.Response"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"500": {
|
|
||||||
"description": "Internal Server Error",
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/response.Response"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/admin/share_record/batchDelete": {
|
"/admin/share_record/batchDelete": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -4971,27 +5378,6 @@ const docTemplateadmin = `{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
"Gwen_http_request_admin.Login": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"password",
|
|
||||||
"username"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"captcha": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"password": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"platform": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"username": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"admin.AddressBookForm": {
|
"admin.AddressBookForm": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -5107,6 +5493,20 @@ const docTemplateadmin = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"admin.DeviceGroupForm": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"admin.GroupForm": {
|
"admin.GroupForm": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -5194,6 +5594,12 @@ const docTemplateadmin = `{
|
|||||||
"op": {
|
"op": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"pkce_enable": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"pkce_method": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"redirect_url": {
|
"redirect_url": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -5222,6 +5628,9 @@ const docTemplateadmin = `{
|
|||||||
"cpu": {
|
"cpu": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"group_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
"hostname": {
|
"hostname": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -5409,6 +5818,27 @@ const docTemplateadmin = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"github_com_lejianwen_rustdesk-api_v2_http_request_admin.Login": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"password",
|
||||||
|
"username"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"captcha": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"platform": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"username": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"model.AddressBook": {
|
"model.AddressBook": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -5709,6 +6139,23 @@ const docTemplateadmin = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"model.DeviceGroup": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"created_at": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"model.Group": {
|
"model.Group": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -5768,6 +6215,9 @@ const docTemplateadmin = `{
|
|||||||
"ip": {
|
"ip": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"is_deleted": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
"platform": {
|
"platform": {
|
||||||
"description": "windows,linux,mac,android,ios",
|
"description": "windows,linux,mac,android,ios",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -5837,6 +6287,12 @@ const docTemplateadmin = `{
|
|||||||
"op": {
|
"op": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"pkce_enable": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"pkce_method": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"redirect_url": {
|
"redirect_url": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -5877,6 +6333,9 @@ const docTemplateadmin = `{
|
|||||||
"created_at": {
|
"created_at": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"group_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
"hostname": {
|
"hostname": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -974,40 +974,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/admin/app-config": {
|
|
||||||
"get": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"token": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "APP服务配置",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"produces": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"ADMIN"
|
|
||||||
],
|
|
||||||
"summary": "APP服务配置",
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "OK",
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/response.Response"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"500": {
|
|
||||||
"description": "Internal Server Error",
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/response.Response"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/admin/audit_conn/batchDelete": {
|
"/admin/audit_conn/batchDelete": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -1434,6 +1400,280 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/admin/device_group/create": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"token": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "创建设备群组",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"设备群组"
|
||||||
|
],
|
||||||
|
"summary": "创建设备群组",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "设备群组信息",
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/admin.DeviceGroupForm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/model.DeviceGroup"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/admin/device_group/delete": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"token": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "设备群组删除",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"设备群组"
|
||||||
|
],
|
||||||
|
"summary": "设备群组删除",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "群组信息",
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/admin.DeviceGroupForm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/admin/device_group/detail/{id}": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"token": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "设备群组详情",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"设备群组"
|
||||||
|
],
|
||||||
|
"summary": "设备群组详情",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/model.Group"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/admin/device_group/list": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"token": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "群组列表",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"群组"
|
||||||
|
],
|
||||||
|
"summary": "群组列表",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "页码",
|
||||||
|
"name": "page",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "页大小",
|
||||||
|
"name": "page_size",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/model.GroupList"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/admin/device_group/update": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"token": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "设备群组编辑",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"设备群组"
|
||||||
|
],
|
||||||
|
"summary": "设备群组编辑",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "群组信息",
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/admin.DeviceGroupForm"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/model.Group"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/admin/file/oss_token": {
|
"/admin/file/oss_token": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -1810,7 +2050,7 @@
|
|||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/Gwen_http_request_admin.Login"
|
"$ref": "#/definitions/github_com_lejianwen_rustdesk-api_v2_http_request_admin.Login"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -1874,7 +2114,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/admin/login_log/delete": {
|
"/admin/login_log/batchDelete": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
@@ -1919,6 +2159,51 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/admin/login_log/delete": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"token": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "登录日志删除",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"登录日志"
|
||||||
|
],
|
||||||
|
"summary": "登录日志删除",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "登录日志信息",
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/model.LoginLog"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/admin/login_log/detail/{id}": {
|
"/admin/login_log/detail/{id}": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -2750,6 +3035,162 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/admin/my/login_log/batchDelete": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"token": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "登录日志批量删除",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"我的登录日志"
|
||||||
|
],
|
||||||
|
"summary": "登录日志批量删除",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "登录日志",
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/admin.LoginLogIds"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/admin/my/login_log/delete": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"token": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "登录日志删除",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"我的登录日志"
|
||||||
|
],
|
||||||
|
"summary": "登录日志删除",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "登录日志信息",
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/model.LoginLog"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/admin/my/login_log/list": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"token": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "登录日志列表",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"我的登录日志"
|
||||||
|
],
|
||||||
|
"summary": "登录日志列表",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "页码",
|
||||||
|
"name": "page",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "页大小",
|
||||||
|
"name": "page_size",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "用户ID",
|
||||||
|
"name": "user_id",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/model.LoginLogList"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/admin/my/peer/list": {
|
"/admin/my/peer/list": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -3877,40 +4318,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/admin/server-config": {
|
|
||||||
"get": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"token": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "服务配置,给webclient提供api-server",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"produces": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"ADMIN"
|
|
||||||
],
|
|
||||||
"summary": "RUSTDESK服务配置",
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "OK",
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/response.Response"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"500": {
|
|
||||||
"description": "Internal Server Error",
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/response.Response"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/admin/share_record/batchDelete": {
|
"/admin/share_record/batchDelete": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -4964,27 +5371,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
"Gwen_http_request_admin.Login": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"password",
|
|
||||||
"username"
|
|
||||||
],
|
|
||||||
"properties": {
|
|
||||||
"captcha": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"password": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"platform": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"username": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"admin.AddressBookForm": {
|
"admin.AddressBookForm": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -5100,6 +5486,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"admin.DeviceGroupForm": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"admin.GroupForm": {
|
"admin.GroupForm": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
@@ -5187,6 +5587,12 @@
|
|||||||
"op": {
|
"op": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"pkce_enable": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"pkce_method": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"redirect_url": {
|
"redirect_url": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -5215,6 +5621,9 @@
|
|||||||
"cpu": {
|
"cpu": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"group_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
"hostname": {
|
"hostname": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -5402,6 +5811,27 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"github_com_lejianwen_rustdesk-api_v2_http_request_admin.Login": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"password",
|
||||||
|
"username"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"captcha": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"platform": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"username": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"model.AddressBook": {
|
"model.AddressBook": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -5702,6 +6132,23 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"model.DeviceGroup": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"created_at": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"model.Group": {
|
"model.Group": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -5761,6 +6208,9 @@
|
|||||||
"ip": {
|
"ip": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"is_deleted": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
"platform": {
|
"platform": {
|
||||||
"description": "windows,linux,mac,android,ios",
|
"description": "windows,linux,mac,android,ios",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -5830,6 +6280,12 @@
|
|||||||
"op": {
|
"op": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"pkce_enable": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"pkce_method": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"redirect_url": {
|
"redirect_url": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -5870,6 +6326,9 @@
|
|||||||
"created_at": {
|
"created_at": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"group_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
"hostname": {
|
"hostname": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,19 +1,5 @@
|
|||||||
basePath: /api
|
basePath: /api
|
||||||
definitions:
|
definitions:
|
||||||
Gwen_http_request_admin.Login:
|
|
||||||
properties:
|
|
||||||
captcha:
|
|
||||||
type: string
|
|
||||||
password:
|
|
||||||
type: string
|
|
||||||
platform:
|
|
||||||
type: string
|
|
||||||
username:
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- password
|
|
||||||
- username
|
|
||||||
type: object
|
|
||||||
admin.AddressBookForm:
|
admin.AddressBookForm:
|
||||||
properties:
|
properties:
|
||||||
alias:
|
alias:
|
||||||
@@ -91,6 +77,15 @@ definitions:
|
|||||||
- new_password
|
- new_password
|
||||||
- old_password
|
- old_password
|
||||||
type: object
|
type: object
|
||||||
|
admin.DeviceGroupForm:
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
admin.GroupForm:
|
admin.GroupForm:
|
||||||
properties:
|
properties:
|
||||||
id:
|
id:
|
||||||
@@ -144,6 +139,10 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
op:
|
op:
|
||||||
type: string
|
type: string
|
||||||
|
pkce_enable:
|
||||||
|
type: boolean
|
||||||
|
pkce_method:
|
||||||
|
type: string
|
||||||
redirect_url:
|
redirect_url:
|
||||||
type: string
|
type: string
|
||||||
scopes:
|
scopes:
|
||||||
@@ -167,6 +166,8 @@ definitions:
|
|||||||
properties:
|
properties:
|
||||||
cpu:
|
cpu:
|
||||||
type: string
|
type: string
|
||||||
|
group_id:
|
||||||
|
type: integer
|
||||||
hostname:
|
hostname:
|
||||||
type: string
|
type: string
|
||||||
id:
|
id:
|
||||||
@@ -292,6 +293,20 @@ definitions:
|
|||||||
required:
|
required:
|
||||||
- ids
|
- ids
|
||||||
type: object
|
type: object
|
||||||
|
github_com_lejianwen_rustdesk-api_v2_http_request_admin.Login:
|
||||||
|
properties:
|
||||||
|
captcha:
|
||||||
|
type: string
|
||||||
|
password:
|
||||||
|
type: string
|
||||||
|
platform:
|
||||||
|
type: string
|
||||||
|
username:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- password
|
||||||
|
- username
|
||||||
|
type: object
|
||||||
model.AddressBook:
|
model.AddressBook:
|
||||||
properties:
|
properties:
|
||||||
alias:
|
alias:
|
||||||
@@ -492,6 +507,17 @@ definitions:
|
|||||||
total:
|
total:
|
||||||
type: integer
|
type: integer
|
||||||
type: object
|
type: object
|
||||||
|
model.DeviceGroup:
|
||||||
|
properties:
|
||||||
|
created_at:
|
||||||
|
type: string
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
updated_at:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
model.Group:
|
model.Group:
|
||||||
properties:
|
properties:
|
||||||
created_at:
|
created_at:
|
||||||
@@ -531,6 +557,8 @@ definitions:
|
|||||||
type: integer
|
type: integer
|
||||||
ip:
|
ip:
|
||||||
type: string
|
type: string
|
||||||
|
is_deleted:
|
||||||
|
type: integer
|
||||||
platform:
|
platform:
|
||||||
description: windows,linux,mac,android,ios
|
description: windows,linux,mac,android,ios
|
||||||
type: string
|
type: string
|
||||||
@@ -577,6 +605,10 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
op:
|
op:
|
||||||
type: string
|
type: string
|
||||||
|
pkce_enable:
|
||||||
|
type: boolean
|
||||||
|
pkce_method:
|
||||||
|
type: string
|
||||||
redirect_url:
|
redirect_url:
|
||||||
type: string
|
type: string
|
||||||
scopes:
|
scopes:
|
||||||
@@ -603,6 +635,8 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
created_at:
|
created_at:
|
||||||
type: string
|
type: string
|
||||||
|
group_id:
|
||||||
|
type: integer
|
||||||
hostname:
|
hostname:
|
||||||
type: string
|
type: string
|
||||||
id:
|
id:
|
||||||
@@ -1347,27 +1381,6 @@ paths:
|
|||||||
summary: 地址簿规则编辑
|
summary: 地址簿规则编辑
|
||||||
tags:
|
tags:
|
||||||
- 地址簿规则
|
- 地址簿规则
|
||||||
/admin/app-config:
|
|
||||||
get:
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
description: APP服务配置
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: OK
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/response.Response'
|
|
||||||
"500":
|
|
||||||
description: Internal Server Error
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/response.Response'
|
|
||||||
security:
|
|
||||||
- token: []
|
|
||||||
summary: APP服务配置
|
|
||||||
tags:
|
|
||||||
- ADMIN
|
|
||||||
/admin/audit_conn/batchDelete:
|
/admin/audit_conn/batchDelete:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -1629,6 +1642,167 @@ paths:
|
|||||||
summary: RUSTDESK服务配置
|
summary: RUSTDESK服务配置
|
||||||
tags:
|
tags:
|
||||||
- ADMIN
|
- ADMIN
|
||||||
|
/admin/device_group/create:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 创建设备群组
|
||||||
|
parameters:
|
||||||
|
- description: 设备群组信息
|
||||||
|
in: body
|
||||||
|
name: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/admin.DeviceGroupForm'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/response.Response'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/definitions/model.DeviceGroup'
|
||||||
|
type: object
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.Response'
|
||||||
|
security:
|
||||||
|
- token: []
|
||||||
|
summary: 创建设备群组
|
||||||
|
tags:
|
||||||
|
- 设备群组
|
||||||
|
/admin/device_group/delete:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 设备群组删除
|
||||||
|
parameters:
|
||||||
|
- description: 群组信息
|
||||||
|
in: body
|
||||||
|
name: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/admin.DeviceGroupForm'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.Response'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.Response'
|
||||||
|
security:
|
||||||
|
- token: []
|
||||||
|
summary: 设备群组删除
|
||||||
|
tags:
|
||||||
|
- 设备群组
|
||||||
|
/admin/device_group/detail/{id}:
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 设备群组详情
|
||||||
|
parameters:
|
||||||
|
- description: ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/response.Response'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/definitions/model.Group'
|
||||||
|
type: object
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.Response'
|
||||||
|
security:
|
||||||
|
- token: []
|
||||||
|
summary: 设备群组详情
|
||||||
|
tags:
|
||||||
|
- 设备群组
|
||||||
|
/admin/device_group/list:
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 群组列表
|
||||||
|
parameters:
|
||||||
|
- description: 页码
|
||||||
|
in: query
|
||||||
|
name: page
|
||||||
|
type: integer
|
||||||
|
- description: 页大小
|
||||||
|
in: query
|
||||||
|
name: page_size
|
||||||
|
type: integer
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/response.Response'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/definitions/model.GroupList'
|
||||||
|
type: object
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.Response'
|
||||||
|
security:
|
||||||
|
- token: []
|
||||||
|
summary: 群组列表
|
||||||
|
tags:
|
||||||
|
- 群组
|
||||||
|
/admin/device_group/update:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 设备群组编辑
|
||||||
|
parameters:
|
||||||
|
- description: 群组信息
|
||||||
|
in: body
|
||||||
|
name: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/admin.DeviceGroupForm'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/response.Response'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/definitions/model.Group'
|
||||||
|
type: object
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.Response'
|
||||||
|
security:
|
||||||
|
- token: []
|
||||||
|
summary: 设备群组编辑
|
||||||
|
tags:
|
||||||
|
- 设备群组
|
||||||
/admin/file/oss_token:
|
/admin/file/oss_token:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -1849,7 +2023,7 @@ paths:
|
|||||||
name: body
|
name: body
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/Gwen_http_request_admin.Login'
|
$ref: '#/definitions/github_com_lejianwen_rustdesk-api_v2_http_request_admin.Login'
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
@@ -1892,7 +2066,7 @@ paths:
|
|||||||
summary: 登录选项
|
summary: 登录选项
|
||||||
tags:
|
tags:
|
||||||
- 登录
|
- 登录
|
||||||
/admin/login_log/delete:
|
/admin/login_log/batchDelete:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
- application/json
|
- application/json
|
||||||
@@ -1920,6 +2094,34 @@ paths:
|
|||||||
summary: 登录日志批量删除
|
summary: 登录日志批量删除
|
||||||
tags:
|
tags:
|
||||||
- 登录日志
|
- 登录日志
|
||||||
|
/admin/login_log/delete:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 登录日志删除
|
||||||
|
parameters:
|
||||||
|
- description: 登录日志信息
|
||||||
|
in: body
|
||||||
|
name: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/model.LoginLog'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.Response'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.Response'
|
||||||
|
security:
|
||||||
|
- token: []
|
||||||
|
summary: 登录日志删除
|
||||||
|
tags:
|
||||||
|
- 登录日志
|
||||||
/admin/login_log/detail/{id}:
|
/admin/login_log/detail/{id}:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -2413,6 +2615,101 @@ paths:
|
|||||||
summary: 地址簿规则编辑
|
summary: 地址簿规则编辑
|
||||||
tags:
|
tags:
|
||||||
- 我的地址簿规则
|
- 我的地址簿规则
|
||||||
|
/admin/my/login_log/batchDelete:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 登录日志批量删除
|
||||||
|
parameters:
|
||||||
|
- description: 登录日志
|
||||||
|
in: body
|
||||||
|
name: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/admin.LoginLogIds'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.Response'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.Response'
|
||||||
|
security:
|
||||||
|
- token: []
|
||||||
|
summary: 登录日志批量删除
|
||||||
|
tags:
|
||||||
|
- 我的登录日志
|
||||||
|
/admin/my/login_log/delete:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 登录日志删除
|
||||||
|
parameters:
|
||||||
|
- description: 登录日志信息
|
||||||
|
in: body
|
||||||
|
name: body
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/model.LoginLog'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.Response'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.Response'
|
||||||
|
security:
|
||||||
|
- token: []
|
||||||
|
summary: 登录日志删除
|
||||||
|
tags:
|
||||||
|
- 我的登录日志
|
||||||
|
/admin/my/login_log/list:
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 登录日志列表
|
||||||
|
parameters:
|
||||||
|
- description: 页码
|
||||||
|
in: query
|
||||||
|
name: page
|
||||||
|
type: integer
|
||||||
|
- description: 页大小
|
||||||
|
in: query
|
||||||
|
name: page_size
|
||||||
|
type: integer
|
||||||
|
- description: 用户ID
|
||||||
|
in: query
|
||||||
|
name: user_id
|
||||||
|
type: integer
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/response.Response'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/definitions/model.LoginLogList'
|
||||||
|
type: object
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.Response'
|
||||||
|
security:
|
||||||
|
- token: []
|
||||||
|
summary: 登录日志列表
|
||||||
|
tags:
|
||||||
|
- 我的登录日志
|
||||||
/admin/my/peer/list:
|
/admin/my/peer/list:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -3088,27 +3385,6 @@ paths:
|
|||||||
summary: 设备编辑
|
summary: 设备编辑
|
||||||
tags:
|
tags:
|
||||||
- 设备
|
- 设备
|
||||||
/admin/server-config:
|
|
||||||
get:
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
description: 服务配置,给webclient提供api-server
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: OK
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/response.Response'
|
|
||||||
"500":
|
|
||||||
description: Internal Server Error
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/response.Response'
|
|
||||||
security:
|
|
||||||
- token: []
|
|
||||||
summary: RUSTDESK服务配置
|
|
||||||
tags:
|
|
||||||
- ADMIN
|
|
||||||
/admin/share_record/batchDelete:
|
/admin/share_record/batchDelete:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
|
|||||||
@@ -653,40 +653,6 @@ const docTemplateapi = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api": {
|
|
||||||
"get": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"token": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "用户信息",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"produces": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"用户"
|
|
||||||
],
|
|
||||||
"summary": "用户信息",
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "OK",
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/api.UserPayload"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"500": {
|
|
||||||
"description": "Internal Server Error",
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/response.Response"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/audit/conn": {
|
"/audit/conn": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "审计连接",
|
"description": "审计连接",
|
||||||
@@ -767,6 +733,100 @@ const docTemplateapi = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/currentUser": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"token": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "用户信息",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"用户"
|
||||||
|
],
|
||||||
|
"summary": "用户信息",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.UserPayload"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/device-group/accessible": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "机器",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"群组"
|
||||||
|
],
|
||||||
|
"summary": "设备",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "页码",
|
||||||
|
"name": "page",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "每页数量",
|
||||||
|
"name": "pageSize",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "状态",
|
||||||
|
"name": "status",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "accessible",
|
||||||
|
"name": "accessible",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.DataResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/heartbeat": {
|
"/heartbeat": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "心跳",
|
"description": "心跳",
|
||||||
@@ -1178,43 +1238,6 @@ const docTemplateapi = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/tags": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"BearerAuth": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "标签",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"produces": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"地址"
|
|
||||||
],
|
|
||||||
"summary": "标签",
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "OK",
|
|
||||||
"schema": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/definitions/model.Tag"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"500": {
|
|
||||||
"description": "Internal Server Error",
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/response.ErrorResponse"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/users": {
|
"/users": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -1289,6 +1312,35 @@ const docTemplateapi = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"/version": {
|
||||||
|
"get": {
|
||||||
|
"description": "版本",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"首页"
|
||||||
|
],
|
||||||
|
"summary": "版本",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
|
|||||||
@@ -646,40 +646,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api": {
|
|
||||||
"get": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"token": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "用户信息",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"produces": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"用户"
|
|
||||||
],
|
|
||||||
"summary": "用户信息",
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "OK",
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/api.UserPayload"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"500": {
|
|
||||||
"description": "Internal Server Error",
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/response.Response"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/audit/conn": {
|
"/audit/conn": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "审计连接",
|
"description": "审计连接",
|
||||||
@@ -760,6 +726,100 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/currentUser": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"token": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "用户信息",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"用户"
|
||||||
|
],
|
||||||
|
"summary": "用户信息",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/api.UserPayload"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/device-group/accessible": {
|
||||||
|
"get": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "机器",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"群组"
|
||||||
|
],
|
||||||
|
"summary": "设备",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "页码",
|
||||||
|
"name": "page",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "每页数量",
|
||||||
|
"name": "pageSize",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "状态",
|
||||||
|
"name": "status",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "accessible",
|
||||||
|
"name": "accessible",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.DataResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/heartbeat": {
|
"/heartbeat": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "心跳",
|
"description": "心跳",
|
||||||
@@ -1171,43 +1231,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/tags": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"BearerAuth": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "标签",
|
|
||||||
"consumes": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"produces": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"地址"
|
|
||||||
],
|
|
||||||
"summary": "标签",
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "OK",
|
|
||||||
"schema": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"$ref": "#/definitions/model.Tag"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"500": {
|
|
||||||
"description": "Internal Server Error",
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/response.ErrorResponse"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/users": {
|
"/users": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -1282,6 +1305,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"/version": {
|
||||||
|
"get": {
|
||||||
|
"description": "版本",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"首页"
|
||||||
|
],
|
||||||
|
"summary": "版本",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Internal Server Error",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/response.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
|
|||||||
@@ -598,27 +598,6 @@ paths:
|
|||||||
summary: 标签
|
summary: 标签
|
||||||
tags:
|
tags:
|
||||||
- 地址[Personal]
|
- 地址[Personal]
|
||||||
/api:
|
|
||||||
get:
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
description: 用户信息
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: OK
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/api.UserPayload'
|
|
||||||
"500":
|
|
||||||
description: Internal Server Error
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/response.Response'
|
|
||||||
security:
|
|
||||||
- token: []
|
|
||||||
summary: 用户信息
|
|
||||||
tags:
|
|
||||||
- 用户
|
|
||||||
/audit/conn:
|
/audit/conn:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -671,6 +650,65 @@ paths:
|
|||||||
summary: 审计文件
|
summary: 审计文件
|
||||||
tags:
|
tags:
|
||||||
- 审计
|
- 审计
|
||||||
|
/currentUser:
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 用户信息
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/api.UserPayload'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.Response'
|
||||||
|
security:
|
||||||
|
- token: []
|
||||||
|
summary: 用户信息
|
||||||
|
tags:
|
||||||
|
- 用户
|
||||||
|
/device-group/accessible:
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 机器
|
||||||
|
parameters:
|
||||||
|
- description: 页码
|
||||||
|
in: query
|
||||||
|
name: page
|
||||||
|
type: integer
|
||||||
|
- description: 每页数量
|
||||||
|
in: query
|
||||||
|
name: pageSize
|
||||||
|
type: integer
|
||||||
|
- description: 状态
|
||||||
|
in: query
|
||||||
|
name: status
|
||||||
|
type: integer
|
||||||
|
- description: accessible
|
||||||
|
in: query
|
||||||
|
name: accessible
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.DataResponse'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.Response'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: 设备
|
||||||
|
tags:
|
||||||
|
- 群组
|
||||||
/heartbeat:
|
/heartbeat:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -936,29 +974,6 @@ paths:
|
|||||||
summary: 提交系统信息
|
summary: 提交系统信息
|
||||||
tags:
|
tags:
|
||||||
- 地址
|
- 地址
|
||||||
/tags:
|
|
||||||
post:
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
description: 标签
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: OK
|
|
||||||
schema:
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/model.Tag'
|
|
||||||
type: array
|
|
||||||
"500":
|
|
||||||
description: Internal Server Error
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/response.ErrorResponse'
|
|
||||||
security:
|
|
||||||
- BearerAuth: []
|
|
||||||
summary: 标签
|
|
||||||
tags:
|
|
||||||
- 地址
|
|
||||||
/users:
|
/users:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -1004,6 +1019,25 @@ paths:
|
|||||||
summary: 用户列表
|
summary: 用户列表
|
||||||
tags:
|
tags:
|
||||||
- 群组
|
- 群组
|
||||||
|
/version:
|
||||||
|
get:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 版本
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.Response'
|
||||||
|
"500":
|
||||||
|
description: Internal Server Error
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/response.Response'
|
||||||
|
summary: 版本
|
||||||
|
tags:
|
||||||
|
- 首页
|
||||||
securityDefinitions:
|
securityDefinitions:
|
||||||
BearerAuth:
|
BearerAuth:
|
||||||
in: header
|
in: header
|
||||||
|
|||||||
BIN
docs/en_img/rustdesk_command_advance.png
Normal file
|
After Width: | Height: | Size: 99 KiB |
BIN
docs/en_img/rustdesk_command_simple.png
Normal file
|
After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 19 KiB |
BIN
docs/init_admin_pwd.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
docs/rustdesk_command_advance.png
Normal file
|
After Width: | Height: | Size: 99 KiB |
BIN
docs/rustdesk_command_simple.png
Normal file
|
After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 48 KiB |
@@ -1,4 +1,4 @@
|
|||||||
package Gwen
|
package main
|
||||||
|
|
||||||
//go:generate swag init -g cmd/apimain.go --output docs/api --instanceName api --exclude http/controller/admin
|
//go:generate swag init -g cmd/apimain.go --output docs/api --instanceName api --exclude http/controller/admin
|
||||||
//go:generate swag init -g cmd/apimain.go --output docs/admin --instanceName admin --exclude http/controller/api
|
//go:generate swag init -g cmd/apimain.go --output docs/admin --instanceName admin --exclude http/controller/api
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
package Gwen
|
package main
|
||||||
|
|
||||||
//go:generate go run cmd/apimain.go
|
//go:generate go run cmd/apimain.go
|
||||||
|
|||||||
@@ -4,18 +4,20 @@ import (
|
|||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/go-playground/locales/en"
|
"github.com/go-playground/locales/en"
|
||||||
"github.com/go-playground/locales/es"
|
"github.com/go-playground/locales/es"
|
||||||
|
"github.com/go-playground/locales/fr"
|
||||||
"github.com/go-playground/locales/ko"
|
"github.com/go-playground/locales/ko"
|
||||||
"github.com/go-playground/locales/ru"
|
"github.com/go-playground/locales/ru"
|
||||||
"github.com/go-playground/locales/fr"
|
|
||||||
"github.com/go-playground/locales/zh_Hans_CN"
|
"github.com/go-playground/locales/zh_Hans_CN"
|
||||||
|
"github.com/go-playground/locales/zh_Hant"
|
||||||
ut "github.com/go-playground/universal-translator"
|
ut "github.com/go-playground/universal-translator"
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
en_translations "github.com/go-playground/validator/v10/translations/en"
|
en_translations "github.com/go-playground/validator/v10/translations/en"
|
||||||
es_translations "github.com/go-playground/validator/v10/translations/es"
|
es_translations "github.com/go-playground/validator/v10/translations/es"
|
||||||
|
fr_translations "github.com/go-playground/validator/v10/translations/fr"
|
||||||
|
ko_translations "github.com/go-playground/validator/v10/translations/ko"
|
||||||
ru_translations "github.com/go-playground/validator/v10/translations/ru"
|
ru_translations "github.com/go-playground/validator/v10/translations/ru"
|
||||||
zh_translations "github.com/go-playground/validator/v10/translations/zh"
|
zh_translations "github.com/go-playground/validator/v10/translations/zh"
|
||||||
fr_translations "github.com/go-playground/validator/v10/translations/fr"
|
zh_tw_translations "github.com/go-playground/validator/v10/translations/zh_tw"
|
||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -29,8 +31,9 @@ func ApiInitValidator() {
|
|||||||
ruT := ru.New()
|
ruT := ru.New()
|
||||||
esT := es.New()
|
esT := es.New()
|
||||||
frT := fr.New()
|
frT := fr.New()
|
||||||
|
zhTwT := zh_Hant.New()
|
||||||
|
|
||||||
uni := ut.New(enT, cn, koT, ruT, esT, frT)
|
uni := ut.New(enT, cn, koT, ruT, esT, frT, zhTwT)
|
||||||
|
|
||||||
enTrans, _ := uni.GetTranslator("en")
|
enTrans, _ := uni.GetTranslator("en")
|
||||||
zhTrans, _ := uni.GetTranslator("zh_Hans_CN")
|
zhTrans, _ := uni.GetTranslator("zh_Hans_CN")
|
||||||
@@ -38,6 +41,7 @@ func ApiInitValidator() {
|
|||||||
ruTrans, _ := uni.GetTranslator("ru")
|
ruTrans, _ := uni.GetTranslator("ru")
|
||||||
esTrans, _ := uni.GetTranslator("es")
|
esTrans, _ := uni.GetTranslator("es")
|
||||||
frTrans, _ := uni.GetTranslator("fr")
|
frTrans, _ := uni.GetTranslator("fr")
|
||||||
|
zhTwTrans, _ := uni.GetTranslator("zh_Hant")
|
||||||
|
|
||||||
err := zh_translations.RegisterDefaultTranslations(validate, zhTrans)
|
err := zh_translations.RegisterDefaultTranslations(validate, zhTrans)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -48,8 +52,7 @@ func ApiInitValidator() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
//validate没有ko的翻译,使用zh的翻译
|
err = ko_translations.RegisterDefaultTranslations(validate, koTrans)
|
||||||
err = zh_translations.RegisterDefaultTranslations(validate, koTrans)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -65,6 +68,10 @@ func ApiInitValidator() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
err = zh_tw_translations.RegisterDefaultTranslations(validate, zhTwTrans)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
validate.RegisterTagNameFunc(func(field reflect.StructField) string {
|
validate.RegisterTagNameFunc(func(field reflect.StructField) string {
|
||||||
label := field.Tag.Get("label")
|
label := field.Tag.Get("label")
|
||||||
@@ -125,6 +132,13 @@ func getTranslatorForLang(lang string) ut.Translator {
|
|||||||
case "zh":
|
case "zh":
|
||||||
trans, _ := Validator.UT.GetTranslator("zh_Hans_CN")
|
trans, _ := Validator.UT.GetTranslator("zh_Hans_CN")
|
||||||
return trans
|
return trans
|
||||||
|
case "zh_TW":
|
||||||
|
fallthrough
|
||||||
|
case "zh-TW":
|
||||||
|
fallthrough
|
||||||
|
case "zh-tw":
|
||||||
|
trans, _ := Validator.UT.GetTranslator("zh_Hant")
|
||||||
|
return trans
|
||||||
case "ko":
|
case "ko":
|
||||||
trans, _ := Validator.UT.GetTranslator("ko")
|
trans, _ := Validator.UT.GetTranslator("ko")
|
||||||
return trans
|
return trans
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
package global
|
package global
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/config"
|
|
||||||
"Gwen/lib/cache"
|
|
||||||
"Gwen/lib/jwt"
|
|
||||||
"Gwen/lib/lock"
|
|
||||||
"Gwen/lib/upload"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
ut "github.com/go-playground/universal-translator"
|
ut "github.com/go-playground/universal-translator"
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
"github.com/go-redis/redis/v8"
|
"github.com/go-redis/redis/v8"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/config"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/lib/cache"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/lib/jwt"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/lib/lock"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/lib/upload"
|
||||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ func InitI18n() {
|
|||||||
fileInfos, err := os.ReadDir(dir)
|
fileInfos, err := os.ReadDir(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
for _, fileInfo := range fileInfos {
|
for _, fileInfo := range fileInfos {
|
||||||
//如果文件名不是.toml结尾
|
//如果文件名不是.toml结尾
|
||||||
|
|||||||
22
go.mod
@@ -1,4 +1,4 @@
|
|||||||
module Gwen
|
module github.com/lejianwen/rustdesk-api/v2
|
||||||
|
|
||||||
go 1.22
|
go 1.22
|
||||||
|
|
||||||
@@ -10,10 +10,10 @@ require (
|
|||||||
github.com/gin-gonic/gin v1.9.0
|
github.com/gin-gonic/gin v1.9.0
|
||||||
github.com/go-playground/locales v0.14.1
|
github.com/go-playground/locales v0.14.1
|
||||||
github.com/go-playground/universal-translator v0.18.1
|
github.com/go-playground/universal-translator v0.18.1
|
||||||
github.com/go-playground/validator/v10 v10.11.2
|
github.com/go-playground/validator/v10 v10.26.0
|
||||||
github.com/go-redis/redis/v8 v8.11.4
|
github.com/go-redis/redis/v8 v8.11.4
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||||
github.com/google/uuid v1.1.2
|
github.com/google/uuid v1.6.0
|
||||||
github.com/nicksnyder/go-i18n/v2 v2.4.0
|
github.com/nicksnyder/go-i18n/v2 v2.4.0
|
||||||
github.com/sirupsen/logrus v1.8.1
|
github.com/sirupsen/logrus v1.8.1
|
||||||
github.com/spf13/cobra v1.8.1
|
github.com/spf13/cobra v1.8.1
|
||||||
@@ -22,21 +22,27 @@ require (
|
|||||||
github.com/swaggo/gin-swagger v1.6.0
|
github.com/swaggo/gin-swagger v1.6.0
|
||||||
github.com/swaggo/swag v1.16.3
|
github.com/swaggo/swag v1.16.3
|
||||||
golang.org/x/oauth2 v0.23.0
|
golang.org/x/oauth2 v0.23.0
|
||||||
golang.org/x/text v0.18.0
|
golang.org/x/text v0.22.0
|
||||||
gorm.io/driver/mysql v1.5.7
|
gorm.io/driver/mysql v1.5.7
|
||||||
gorm.io/driver/sqlite v1.5.6
|
gorm.io/driver/sqlite v1.5.6
|
||||||
gorm.io/gorm v1.25.7
|
gorm.io/gorm v1.25.7
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
|
||||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||||
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||||
github.com/bytedance/sonic v1.8.0 // indirect
|
github.com/bytedance/sonic v1.8.0 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||||
|
github.com/coreos/go-oidc/v3 v3.12.0 // indirect
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
|
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
||||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
|
github.com/go-asn1-ber/asn1-ber v1.5.7 // indirect
|
||||||
|
github.com/go-jose/go-jose/v4 v4.0.2 // indirect
|
||||||
|
github.com/go-ldap/ldap/v3 v3.4.10 // indirect
|
||||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||||
github.com/go-openapi/jsonreference v0.19.6 // indirect
|
github.com/go-openapi/jsonreference v0.19.6 // indirect
|
||||||
github.com/go-openapi/spec v0.20.4 // indirect
|
github.com/go-openapi/spec v0.20.4 // indirect
|
||||||
@@ -51,7 +57,7 @@ require (
|
|||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
|
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
|
||||||
github.com/leodido/go-urn v1.2.1 // indirect
|
github.com/leodido/go-urn v1.4.0 // indirect
|
||||||
github.com/magiconair/properties v1.8.5 // indirect
|
github.com/magiconair/properties v1.8.5 // indirect
|
||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||||
@@ -70,10 +76,10 @@ require (
|
|||||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
github.com/ugorji/go/codec v1.2.9 // indirect
|
github.com/ugorji/go/codec v1.2.9 // indirect
|
||||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
|
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
|
||||||
golang.org/x/crypto v0.23.0 // indirect
|
golang.org/x/crypto v0.33.0 // indirect
|
||||||
golang.org/x/image v0.13.0 // indirect
|
golang.org/x/image v0.13.0 // indirect
|
||||||
golang.org/x/net v0.25.0 // indirect
|
golang.org/x/net v0.34.0 // indirect
|
||||||
golang.org/x/sys v0.25.0 // indirect
|
golang.org/x/sys v0.30.0 // indirect
|
||||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
||||||
google.golang.org/protobuf v1.33.0 // indirect
|
google.golang.org/protobuf v1.33.0 // indirect
|
||||||
gopkg.in/ini.v1 v1.63.2 // indirect
|
gopkg.in/ini.v1 v1.63.2 // indirect
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/request/admin"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/service"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
_ "encoding/json"
|
_ "encoding/json"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/request/admin"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/model"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/request/admin"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/model"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
@@ -120,7 +120,7 @@ func (abcr *AddressBookCollectionRule) CheckForm(t *model.AddressBookCollectionR
|
|||||||
//check to_id
|
//check to_id
|
||||||
if t.Type == model.ShareAddressBookRuleTypePersonal {
|
if t.Type == model.ShareAddressBookRuleTypePersonal {
|
||||||
if t.ToId == t.UserId {
|
if t.ToId == t.UserId {
|
||||||
return "ParamsError", false
|
return "CannotShareToSelf", false
|
||||||
}
|
}
|
||||||
tou := service.AllService.UserService.InfoById(t.ToId)
|
tou := service.AllService.UserService.InfoById(t.ToId)
|
||||||
if tou.Id == 0 {
|
if tou.Id == 0 {
|
||||||
@@ -135,7 +135,7 @@ func (abcr *AddressBookCollectionRule) CheckForm(t *model.AddressBookCollectionR
|
|||||||
return "ParamsError", false
|
return "ParamsError", false
|
||||||
}
|
}
|
||||||
// 重复检查
|
// 重复检查
|
||||||
ex := service.AllService.AddressBookService.RulePersonalInfoByToIdAndCid(t.ToId, t.CollectionId)
|
ex := service.AllService.AddressBookService.RuleInfoByToIdAndCid(t.Type, t.ToId, t.CollectionId)
|
||||||
if t.Id == 0 && ex.Id > 0 {
|
if t.Id == 0 && ex.Id > 0 {
|
||||||
return "ItemExists", false
|
return "ItemExists", false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/request/admin"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/model"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -60,7 +61,22 @@ func (co *Config) AppConfig(c *gin.Context) {
|
|||||||
// @Security token
|
// @Security token
|
||||||
func (co *Config) AdminConfig(c *gin.Context) {
|
func (co *Config) AdminConfig(c *gin.Context) {
|
||||||
|
|
||||||
u := service.AllService.UserService.CurUser(c)
|
u := &model.User{}
|
||||||
|
token := c.GetHeader("api-token")
|
||||||
|
if token != "" {
|
||||||
|
u, _ = service.AllService.UserService.InfoByAccessToken(token)
|
||||||
|
if !service.AllService.UserService.CheckUserEnable(u) {
|
||||||
|
u.Id = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if u.Id == 0 {
|
||||||
|
response.Success(c, &gin.H{
|
||||||
|
"title": global.Config.Admin.Title,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
hello := global.Config.Admin.Hello
|
hello := global.Config.Admin.Hello
|
||||||
helloFile := global.Config.Admin.HelloFile
|
helloFile := global.Config.Admin.HelloFile
|
||||||
if helloFile != "" {
|
if helloFile != "" {
|
||||||
|
|||||||
160
http/controller/admin/deviceGroup.go
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
package admin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DeviceGroup struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detail 设备群组
|
||||||
|
// @Tags 设备群组
|
||||||
|
// @Summary 设备群组详情
|
||||||
|
// @Description 设备群组详情
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path int true "ID"
|
||||||
|
// @Success 200 {object} response.Response{data=model.Group}
|
||||||
|
// @Failure 500 {object} response.Response
|
||||||
|
// @Router /admin/device_group/detail/{id} [get]
|
||||||
|
// @Security token
|
||||||
|
func (ct *DeviceGroup) Detail(c *gin.Context) {
|
||||||
|
id := c.Param("id")
|
||||||
|
iid, _ := strconv.Atoi(id)
|
||||||
|
u := service.AllService.GroupService.DeviceGroupInfoById(uint(iid))
|
||||||
|
if u.Id > 0 {
|
||||||
|
response.Success(c, u)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create 创建设备群组
|
||||||
|
// @Tags 设备群组
|
||||||
|
// @Summary 创建设备群组
|
||||||
|
// @Description 创建设备群组
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param body body admin.DeviceGroupForm true "设备群组信息"
|
||||||
|
// @Success 200 {object} response.Response{data=model.DeviceGroup}
|
||||||
|
// @Failure 500 {object} response.Response
|
||||||
|
// @Router /admin/device_group/create [post]
|
||||||
|
// @Security token
|
||||||
|
func (ct *DeviceGroup) Create(c *gin.Context) {
|
||||||
|
f := &admin.DeviceGroupForm{}
|
||||||
|
if err := c.ShouldBindJSON(f); err != nil {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
errList := global.Validator.ValidStruct(c, f)
|
||||||
|
if len(errList) > 0 {
|
||||||
|
response.Fail(c, 101, errList[0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
u := f.ToDeviceGroup()
|
||||||
|
err := service.AllService.GroupService.DeviceGroupCreate(u)
|
||||||
|
if err != nil {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.Success(c, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// List 列表
|
||||||
|
// @Tags 群组
|
||||||
|
// @Summary 群组列表
|
||||||
|
// @Description 群组列表
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param page query int false "页码"
|
||||||
|
// @Param page_size query int false "页大小"
|
||||||
|
// @Success 200 {object} response.Response{data=model.GroupList}
|
||||||
|
// @Failure 500 {object} response.Response
|
||||||
|
// @Router /admin/device_group/list [get]
|
||||||
|
// @Security token
|
||||||
|
func (ct *DeviceGroup) List(c *gin.Context) {
|
||||||
|
query := &admin.PageQuery{}
|
||||||
|
if err := c.ShouldBindQuery(query); err != nil {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res := service.AllService.GroupService.DeviceGroupList(query.Page, query.PageSize, nil)
|
||||||
|
response.Success(c, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update 编辑
|
||||||
|
// @Tags 设备群组
|
||||||
|
// @Summary 设备群组编辑
|
||||||
|
// @Description 设备群组编辑
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param body body admin.DeviceGroupForm true "群组信息"
|
||||||
|
// @Success 200 {object} response.Response{data=model.Group}
|
||||||
|
// @Failure 500 {object} response.Response
|
||||||
|
// @Router /admin/device_group/update [post]
|
||||||
|
// @Security token
|
||||||
|
func (ct *DeviceGroup) Update(c *gin.Context) {
|
||||||
|
f := &admin.DeviceGroupForm{}
|
||||||
|
if err := c.ShouldBindJSON(f); err != nil {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if f.Id == 0 {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
errList := global.Validator.ValidStruct(c, f)
|
||||||
|
if len(errList) > 0 {
|
||||||
|
response.Fail(c, 101, errList[0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
u := f.ToDeviceGroup()
|
||||||
|
err := service.AllService.GroupService.DeviceGroupUpdate(u)
|
||||||
|
if err != nil {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.Success(c, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete 删除
|
||||||
|
// @Tags 设备群组
|
||||||
|
// @Summary 设备群组删除
|
||||||
|
// @Description 设备群组删除
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param body body admin.DeviceGroupForm true "群组信息"
|
||||||
|
// @Success 200 {object} response.Response
|
||||||
|
// @Failure 500 {object} response.Response
|
||||||
|
// @Router /admin/device_group/delete [post]
|
||||||
|
// @Security token
|
||||||
|
func (ct *DeviceGroup) Delete(c *gin.Context) {
|
||||||
|
f := &admin.DeviceGroupForm{}
|
||||||
|
if err := c.ShouldBindJSON(f); err != nil {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
id := f.Id
|
||||||
|
errList := global.Validator.ValidVar(c, id, "required,gt=0")
|
||||||
|
if len(errList) > 0 {
|
||||||
|
response.Fail(c, 101, errList[0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
u := service.AllService.GroupService.DeviceGroupInfoById(f.Id)
|
||||||
|
if u.Id > 0 {
|
||||||
|
err := service.AllService.GroupService.DeviceGroupDelete(u)
|
||||||
|
if err == nil {
|
||||||
|
response.Success(c, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "OperationFailed")+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||||
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/lib/upload"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/lib/upload"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/request/admin"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/controller/api"
|
|
||||||
"Gwen/http/request/admin"
|
|
||||||
apiReq "Gwen/http/request/api"
|
|
||||||
"Gwen/http/response"
|
|
||||||
adResp "Gwen/http/response/admin"
|
|
||||||
"Gwen/model"
|
|
||||||
"Gwen/service"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/controller/api"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
apiReq "github.com/lejianwen/rustdesk-api/v2/http/request/api"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
adResp "github.com/lejianwen/rustdesk-api/v2/http/response/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"github.com/mojocn/base64Captcha"
|
"github.com/mojocn/base64Captcha"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -152,6 +152,10 @@ var loginLimiter = NewLoginLimiter(3, 5*time.Minute)
|
|||||||
// @Router /admin/login [post]
|
// @Router /admin/login [post]
|
||||||
// @Security token
|
// @Security token
|
||||||
func (ct *Login) Login(c *gin.Context) {
|
func (ct *Login) Login(c *gin.Context) {
|
||||||
|
if global.Config.App.DisablePwdLogin {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "PwdLoginDisabled"))
|
||||||
|
return
|
||||||
|
}
|
||||||
f := &admin.Login{}
|
f := &admin.Login{}
|
||||||
err := c.ShouldBindJSON(f)
|
err := c.ShouldBindJSON(f)
|
||||||
clientIp := c.ClientIP()
|
clientIp := c.ClientIP()
|
||||||
@@ -182,15 +186,20 @@ func (ct *Login) Login(c *gin.Context) {
|
|||||||
global.Logger.Warn(fmt.Sprintf("Login Fail: %s %s %s", "UsernameOrPasswordError", c.RemoteIP(), clientIp))
|
global.Logger.Warn(fmt.Sprintf("Login Fail: %s %s %s", "UsernameOrPasswordError", c.RemoteIP(), clientIp))
|
||||||
loginLimiter.RecordFailure(clientIp)
|
loginLimiter.RecordFailure(clientIp)
|
||||||
if loginLimiter.NeedsCaptcha(clientIp) {
|
if loginLimiter.NeedsCaptcha(clientIp) {
|
||||||
// 移除原验证码,重新生成
|
|
||||||
loginLimiter.RemoveCaptcha(clientIp)
|
loginLimiter.RemoveCaptcha(clientIp)
|
||||||
response.Fail(c, 110, response.TranslateMsg(c, "UsernameOrPasswordError"))
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
response.Fail(c, 101, response.TranslateMsg(c, "UsernameOrPasswordError"))
|
response.Fail(c, 101, response.TranslateMsg(c, "UsernameOrPasswordError"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !service.AllService.UserService.CheckUserEnable(u) {
|
||||||
|
if loginLimiter.NeedsCaptcha(clientIp) {
|
||||||
|
loginLimiter.RemoveCaptcha(clientIp)
|
||||||
|
}
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "UserDisabled"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ut := service.AllService.UserService.Login(u, &model.LoginLog{
|
ut := service.AllService.UserService.Login(u, &model.LoginLog{
|
||||||
UserId: u.Id,
|
UserId: u.Id,
|
||||||
Client: model.LoginLogClientWebAdmin,
|
Client: model.LoginLogClientWebAdmin,
|
||||||
@@ -274,13 +283,13 @@ func (ct *Login) OidcAuth(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err, code, url := service.AllService.OauthService.BeginAuth(f.Op)
|
err, state, verifier, nonce, url := service.AllService.OauthService.BeginAuth(f.Op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
response.Error(c, response.TranslateMsg(c, err.Error()))
|
response.Error(c, response.TranslateMsg(c, err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
service.AllService.OauthService.SetOauthCache(code, &service.OauthCacheItem{
|
service.AllService.OauthService.SetOauthCache(state, &service.OauthCacheItem{
|
||||||
Action: service.OauthActionTypeLogin,
|
Action: service.OauthActionTypeLogin,
|
||||||
Op: f.Op,
|
Op: f.Op,
|
||||||
Id: f.Id,
|
Id: f.Id,
|
||||||
@@ -288,10 +297,12 @@ func (ct *Login) OidcAuth(c *gin.Context) {
|
|||||||
// DeviceOs: ct.Platform(c),
|
// DeviceOs: ct.Platform(c),
|
||||||
DeviceOs: f.DeviceInfo.Os,
|
DeviceOs: f.DeviceInfo.Os,
|
||||||
Uuid: f.Uuid,
|
Uuid: f.Uuid,
|
||||||
|
Verifier: verifier,
|
||||||
|
Nonce: nonce,
|
||||||
}, 5*60)
|
}, 5*60)
|
||||||
|
|
||||||
response.Success(c, gin.H{
|
response.Success(c, gin.H{
|
||||||
"code": code,
|
"code": state,
|
||||||
"url": url,
|
"url": url,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/request/admin"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/model"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
@@ -56,10 +56,6 @@ func (ct *LoginLog) List(c *gin.Context) {
|
|||||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
u := service.AllService.UserService.CurUser(c)
|
|
||||||
if !service.AllService.UserService.IsAdmin(u) || query.IsMy == 1 {
|
|
||||||
query.UserId = int(u.Id)
|
|
||||||
}
|
|
||||||
res := service.AllService.LoginLogService.List(query.Page, query.PageSize, func(tx *gorm.DB) {
|
res := service.AllService.LoginLogService.List(query.Page, query.PageSize, func(tx *gorm.DB) {
|
||||||
if query.UserId > 0 {
|
if query.UserId > 0 {
|
||||||
tx.Where("user_id = ?", query.UserId)
|
tx.Where("user_id = ?", query.UserId)
|
||||||
@@ -93,21 +89,16 @@ func (ct *LoginLog) Delete(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
l := service.AllService.LoginLogService.InfoById(f.Id)
|
l := service.AllService.LoginLogService.InfoById(f.Id)
|
||||||
u := service.AllService.UserService.CurUser(c)
|
if l.Id == 0 {
|
||||||
if !service.AllService.UserService.IsAdmin(u) && l.UserId != u.Id {
|
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||||
response.Fail(c, 101, response.TranslateMsg(c, "NoAccess"))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if l.Id > 0 {
|
err := service.AllService.LoginLogService.Delete(l)
|
||||||
err := service.AllService.LoginLogService.Delete(l)
|
if err == nil {
|
||||||
if err == nil {
|
response.Success(c, nil)
|
||||||
response.Success(c, nil)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
response.Fail(c, 101, err.Error())
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
response.Fail(c, 101, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// BatchDelete 删除
|
// BatchDelete 删除
|
||||||
@@ -119,7 +110,7 @@ func (ct *LoginLog) Delete(c *gin.Context) {
|
|||||||
// @Param body body admin.LoginLogIds true "登录日志"
|
// @Param body body admin.LoginLogIds true "登录日志"
|
||||||
// @Success 200 {object} response.Response
|
// @Success 200 {object} response.Response
|
||||||
// @Failure 500 {object} response.Response
|
// @Failure 500 {object} response.Response
|
||||||
// @Router /admin/login_log/delete [post]
|
// @Router /admin/login_log/batchDelete [post]
|
||||||
// @Security token
|
// @Security token
|
||||||
func (ct *LoginLog) BatchDelete(c *gin.Context) {
|
func (ct *LoginLog) BatchDelete(c *gin.Context) {
|
||||||
f := &admin.LoginLogIds{}
|
f := &admin.LoginLogIds{}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package my
|
package my
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/request/admin"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/service"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package my
|
package my
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/request/admin"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/model"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package my
|
package my
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/request/admin"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/model"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -100,21 +100,21 @@ func (abcr *AddressBookCollectionRule) CheckForm(u *model.User, t *model.Address
|
|||||||
//check to_id
|
//check to_id
|
||||||
if t.Type == model.ShareAddressBookRuleTypePersonal {
|
if t.Type == model.ShareAddressBookRuleTypePersonal {
|
||||||
if t.ToId == t.UserId {
|
if t.ToId == t.UserId {
|
||||||
return "ParamsError", false
|
return "CannotShareToSelf", false
|
||||||
}
|
}
|
||||||
tou := service.AllService.UserService.InfoById(t.ToId)
|
tou := service.AllService.UserService.InfoById(t.ToId)
|
||||||
if tou.Id == 0 {
|
if tou.Id == 0 {
|
||||||
return "ItemNotFound", false
|
return "ItemNotFound", false
|
||||||
}
|
}
|
||||||
//非管理员不能分享给非本组织用户
|
//非管理员不能分享给非本组织用户
|
||||||
if tou.GroupId != u.GroupId {
|
//if tou.GroupId != u.GroupId {
|
||||||
return "NoAccess", false
|
// return "NoAccess", false
|
||||||
}
|
//}
|
||||||
} else if t.Type == model.ShareAddressBookRuleTypeGroup {
|
} else if t.Type == model.ShareAddressBookRuleTypeGroup {
|
||||||
//非管理员不能分享给其他组
|
//非管理员不能分享给其他组
|
||||||
if t.ToId != u.GroupId {
|
//if t.ToId != u.GroupId {
|
||||||
return "NoAccess", false
|
// return "NoAccess", false
|
||||||
}
|
//}
|
||||||
|
|
||||||
tog := service.AllService.GroupService.InfoById(t.ToId)
|
tog := service.AllService.GroupService.InfoById(t.ToId)
|
||||||
if tog.Id == 0 {
|
if tog.Id == 0 {
|
||||||
@@ -124,7 +124,7 @@ func (abcr *AddressBookCollectionRule) CheckForm(u *model.User, t *model.Address
|
|||||||
return "ParamsError", false
|
return "ParamsError", false
|
||||||
}
|
}
|
||||||
// 重复检查
|
// 重复检查
|
||||||
ex := service.AllService.AddressBookService.RulePersonalInfoByToIdAndCid(t.ToId, t.CollectionId)
|
ex := service.AllService.AddressBookService.RuleInfoByToIdAndCid(t.Type, t.ToId, t.CollectionId)
|
||||||
if t.Id == 0 && ex.Id > 0 {
|
if t.Id == 0 && ex.Id > 0 {
|
||||||
return "ItemExists", false
|
return "ItemExists", false
|
||||||
}
|
}
|
||||||
|
|||||||
113
http/controller/admin/my/loginLog.go
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
package my
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LoginLog struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// List 列表
|
||||||
|
// @Tags 我的登录日志
|
||||||
|
// @Summary 登录日志列表
|
||||||
|
// @Description 登录日志列表
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param page query int false "页码"
|
||||||
|
// @Param page_size query int false "页大小"
|
||||||
|
// @Param user_id query int false "用户ID"
|
||||||
|
// @Success 200 {object} response.Response{data=model.LoginLogList}
|
||||||
|
// @Failure 500 {object} response.Response
|
||||||
|
// @Router /admin/my/login_log/list [get]
|
||||||
|
// @Security token
|
||||||
|
func (ct *LoginLog) List(c *gin.Context) {
|
||||||
|
query := &admin.LoginLogQuery{}
|
||||||
|
if err := c.ShouldBindQuery(query); err != nil {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
u := service.AllService.UserService.CurUser(c)
|
||||||
|
res := service.AllService.LoginLogService.List(query.Page, query.PageSize, func(tx *gorm.DB) {
|
||||||
|
tx.Where("user_id = ? and is_deleted = ?", u.Id, model.IsDeletedNo)
|
||||||
|
tx.Order("id desc")
|
||||||
|
})
|
||||||
|
response.Success(c, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete 删除
|
||||||
|
// @Tags 我的登录日志
|
||||||
|
// @Summary 登录日志删除
|
||||||
|
// @Description 登录日志删除
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param body body model.LoginLog true "登录日志信息"
|
||||||
|
// @Success 200 {object} response.Response
|
||||||
|
// @Failure 500 {object} response.Response
|
||||||
|
// @Router /admin/my/login_log/delete [post]
|
||||||
|
// @Security token
|
||||||
|
func (ct *LoginLog) Delete(c *gin.Context) {
|
||||||
|
f := &model.LoginLog{}
|
||||||
|
if err := c.ShouldBindJSON(f); err != nil {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
id := f.Id
|
||||||
|
errList := global.Validator.ValidVar(c, id, "required,gt=0")
|
||||||
|
if len(errList) > 0 {
|
||||||
|
response.Fail(c, 101, errList[0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
l := service.AllService.LoginLogService.InfoById(f.Id)
|
||||||
|
if l.Id == 0 || l.IsDeleted == model.IsDeletedYes {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
u := service.AllService.UserService.CurUser(c)
|
||||||
|
if l.UserId != u.Id {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err := service.AllService.LoginLogService.SoftDelete(l)
|
||||||
|
if err == nil {
|
||||||
|
response.Success(c, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.Fail(c, 101, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// BatchDelete 删除
|
||||||
|
// @Tags 我的登录日志
|
||||||
|
// @Summary 登录日志批量删除
|
||||||
|
// @Description 登录日志批量删除
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param body body admin.LoginLogIds true "登录日志"
|
||||||
|
// @Success 200 {object} response.Response
|
||||||
|
// @Failure 500 {object} response.Response
|
||||||
|
// @Router /admin/my/login_log/batchDelete [post]
|
||||||
|
// @Security token
|
||||||
|
func (ct *LoginLog) BatchDelete(c *gin.Context) {
|
||||||
|
f := &admin.LoginLogIds{}
|
||||||
|
if err := c.ShouldBindJSON(f); err != nil {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(f.Ids) == 0 {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
u := service.AllService.UserService.CurUser(c)
|
||||||
|
err := service.AllService.LoginLogService.BatchSoftDelete(u.Id, f.Ids)
|
||||||
|
if err == nil {
|
||||||
|
response.Success(c, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.Fail(c, 101, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
package my
|
package my
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/http/request/admin"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package my
|
package my
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/request/admin"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package my
|
package my
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/request/admin"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/request/admin"
|
|
||||||
adminReq "Gwen/http/request/admin"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
adminReq "github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -43,20 +43,22 @@ func (o *Oauth) ToBind(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err, code, url := service.AllService.OauthService.BeginAuth(f.Op)
|
err, state, verifier, nonce, url := service.AllService.OauthService.BeginAuth(f.Op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
response.Error(c, response.TranslateMsg(c, err.Error()))
|
response.Error(c, response.TranslateMsg(c, err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
service.AllService.OauthService.SetOauthCache(code, &service.OauthCacheItem{
|
service.AllService.OauthService.SetOauthCache(state, &service.OauthCacheItem{
|
||||||
Action: service.OauthActionTypeBind,
|
Action: service.OauthActionTypeBind,
|
||||||
Op: f.Op,
|
Op: f.Op,
|
||||||
UserId: u.Id,
|
UserId: u.Id,
|
||||||
|
Verifier: verifier,
|
||||||
|
Nonce: nonce,
|
||||||
}, 5*60)
|
}, 5*60)
|
||||||
|
|
||||||
response.Success(c, gin.H{
|
response.Success(c, gin.H{
|
||||||
"code": code,
|
"code": state,
|
||||||
"url": url,
|
"url": url,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/request/admin"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
@@ -108,6 +108,12 @@ func (ct *Peer) List(c *gin.Context) {
|
|||||||
if query.Uuids != "" {
|
if query.Uuids != "" {
|
||||||
tx.Where("uuid in (?)", query.Uuids)
|
tx.Where("uuid in (?)", query.Uuids)
|
||||||
}
|
}
|
||||||
|
if query.Username != "" {
|
||||||
|
tx.Where("username like ?", "%"+query.Username+"%")
|
||||||
|
}
|
||||||
|
if query.Ip != "" {
|
||||||
|
tx.Where("last_online_ip like ?", "%"+query.Ip+"%")
|
||||||
|
}
|
||||||
})
|
})
|
||||||
response.Success(c, res)
|
response.Success(c, res)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +1,128 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Rustdesk struct {
|
type Rustdesk struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerConfig RUSTDESK服务配置
|
type RustdeskCmd struct {
|
||||||
// @Tags ADMIN
|
Cmd string `json:"cmd"`
|
||||||
// @Summary RUSTDESK服务配置
|
Option string `json:"option"`
|
||||||
// @Description 服务配置,给webclient提供api-server
|
Target string `json:"target"`
|
||||||
// @Accept json
|
|
||||||
// @Produce json
|
|
||||||
// @Success 200 {object} response.Response
|
|
||||||
// @Failure 500 {object} response.Response
|
|
||||||
// @Router /admin/server-config [get]
|
|
||||||
// @Security token
|
|
||||||
func (r *Rustdesk) ServerConfig(c *gin.Context) {
|
|
||||||
cf := &response.ServerConfigResponse{
|
|
||||||
IdServer: global.Config.Rustdesk.IdServer,
|
|
||||||
Key: global.Config.Rustdesk.Key,
|
|
||||||
RelayServer: global.Config.Rustdesk.RelayServer,
|
|
||||||
ApiServer: global.Config.Rustdesk.ApiServer,
|
|
||||||
}
|
|
||||||
response.Success(c, cf)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AppConfig APP服务配置
|
func (r *Rustdesk) CmdList(c *gin.Context) {
|
||||||
// @Tags ADMIN
|
q := &admin.PageQuery{}
|
||||||
// @Summary APP服务配置
|
if err := c.ShouldBindQuery(q); err != nil {
|
||||||
// @Description APP服务配置
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||||
// @Accept json
|
return
|
||||||
// @Produce json
|
}
|
||||||
// @Success 200 {object} response.Response
|
res := service.AllService.ServerCmdService.List(q.Page, 9999)
|
||||||
// @Failure 500 {object} response.Response
|
//在列表前添加系统命令
|
||||||
// @Router /admin/app-config [get]
|
list := make([]*model.ServerCmd, 0)
|
||||||
// @Security token
|
list = append(list, model.SysIdServerCmds...)
|
||||||
func (r *Rustdesk) AppConfig(c *gin.Context) {
|
list = append(list, model.SysRelayServerCmds...)
|
||||||
response.Success(c, &gin.H{
|
list = append(list, res.ServerCmds...)
|
||||||
"web_client": global.Config.App.WebClient,
|
res.ServerCmds = list
|
||||||
})
|
response.Success(c, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Rustdesk) CmdDelete(c *gin.Context) {
|
||||||
|
f := &model.ServerCmd{}
|
||||||
|
if err := c.ShouldBindJSON(f); err != nil {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if f.Id == 0 {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ex := service.AllService.ServerCmdService.Info(f.Id)
|
||||||
|
if ex.Id == 0 {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err := service.AllService.ServerCmdService.Delete(ex)
|
||||||
|
if err != nil {
|
||||||
|
response.Fail(c, 101, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.Success(c, nil)
|
||||||
|
}
|
||||||
|
func (r *Rustdesk) CmdCreate(c *gin.Context) {
|
||||||
|
f := &model.ServerCmd{}
|
||||||
|
if err := c.ShouldBindJSON(f); err != nil {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
errList := global.Validator.ValidStruct(c, f)
|
||||||
|
if len(errList) > 0 {
|
||||||
|
response.Fail(c, 101, errList[0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err := service.AllService.ServerCmdService.Create(f)
|
||||||
|
if err != nil {
|
||||||
|
response.Fail(c, 101, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.Success(c, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Rustdesk) CmdUpdate(c *gin.Context) {
|
||||||
|
f := &model.ServerCmd{}
|
||||||
|
if err := c.ShouldBindJSON(f); err != nil {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
errList := global.Validator.ValidStruct(c, f)
|
||||||
|
if len(errList) > 0 {
|
||||||
|
response.Fail(c, 101, errList[0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ex := service.AllService.ServerCmdService.Info(f.Id)
|
||||||
|
if ex.Id == 0 {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ItemNotFound"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err := service.AllService.ServerCmdService.Update(f)
|
||||||
|
if err != nil {
|
||||||
|
response.Fail(c, 101, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.Success(c, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Rustdesk) SendCmd(c *gin.Context) {
|
||||||
|
rc := &RustdeskCmd{}
|
||||||
|
if err := c.ShouldBindJSON(rc); err != nil {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if rc.Cmd == "" {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if rc.Target == "" {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if rc.Target != model.ServerCmdTargetIdServer && rc.Target != model.ServerCmdTargetRelayServer {
|
||||||
|
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := service.AllService.ServerCmdService.SendCmd(rc.Target, rc.Cmd, rc.Option)
|
||||||
|
if err != nil {
|
||||||
|
response.Fail(c, 101, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.Success(c, res)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/request/admin"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/request/admin"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/request/admin"
|
|
||||||
"Gwen/http/response"
|
|
||||||
adResp "Gwen/http/response/admin"
|
|
||||||
"Gwen/model"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
adResp "github.com/lejianwen/rustdesk-api/v2/http/response/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
@@ -296,32 +296,12 @@ func (ct *User) MyOauth(c *gin.Context) {
|
|||||||
|
|
||||||
// groupUsers
|
// groupUsers
|
||||||
func (ct *User) GroupUsers(c *gin.Context) {
|
func (ct *User) GroupUsers(c *gin.Context) {
|
||||||
q := &admin.GroupUsersQuery{}
|
aG := service.AllService.GroupService.List(1, 999, nil)
|
||||||
if err := c.ShouldBindJSON(q); err != nil {
|
aU := service.AllService.UserService.List(1, 9999, nil)
|
||||||
response.Fail(c, 101, response.TranslateMsg(c, "ParamsError")+err.Error())
|
response.Success(c, gin.H{
|
||||||
return
|
"groups": aG.Groups,
|
||||||
}
|
"users": aU.Users,
|
||||||
u := service.AllService.UserService.CurUser(c)
|
|
||||||
gid := u.GroupId
|
|
||||||
uid := u.Id
|
|
||||||
if service.AllService.UserService.IsAdmin(u) && q.UserId > 0 {
|
|
||||||
nu := service.AllService.UserService.InfoById(q.UserId)
|
|
||||||
gid = nu.GroupId
|
|
||||||
uid = q.UserId
|
|
||||||
}
|
|
||||||
res := service.AllService.UserService.List(1, 999, func(tx *gorm.DB) {
|
|
||||||
tx.Where("group_id = ?", gid)
|
|
||||||
})
|
})
|
||||||
var data []*adResp.GroupUsersPayload
|
|
||||||
for _, _u := range res.Users {
|
|
||||||
gup := &adResp.GroupUsersPayload{}
|
|
||||||
gup.FromUser(_u)
|
|
||||||
if _u.Id == uid {
|
|
||||||
gup.Status = 0
|
|
||||||
}
|
|
||||||
data = append(data, gup)
|
|
||||||
}
|
|
||||||
response.Success(c, data)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register
|
// Register
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/request/admin"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/model"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/admin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
requstform "Gwen/http/request/api"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/http/response/api"
|
|
||||||
"Gwen/model"
|
|
||||||
"Gwen/service"
|
|
||||||
"Gwen/utils"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
requstform "github.com/lejianwen/rustdesk-api/v2/http/request/api"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response/api"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/utils"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -32,8 +32,8 @@ type Ab struct {
|
|||||||
func (a *Ab) Ab(c *gin.Context) {
|
func (a *Ab) Ab(c *gin.Context) {
|
||||||
user := service.AllService.UserService.CurUser(c)
|
user := service.AllService.UserService.CurUser(c)
|
||||||
|
|
||||||
al := service.AllService.AddressBookService.ListByUserId(user.Id, 1, 1000)
|
al := service.AllService.AddressBookService.ListByUserIdAndCollectionId(user.Id, 0, 1, 1000)
|
||||||
tags := service.AllService.TagService.ListByUserId(user.Id)
|
tags := service.AllService.TagService.ListByUserIdAndCollectionId(user.Id, 0)
|
||||||
|
|
||||||
tagColors := map[string]uint{}
|
tagColors := map[string]uint{}
|
||||||
//将tags中的name转成一个以逗号分割的字符串
|
//将tags中的name转成一个以逗号分割的字符串
|
||||||
@@ -98,23 +98,6 @@ func (a *Ab) UpAb(c *gin.Context) {
|
|||||||
c.JSON(http.StatusOK, nil)
|
c.JSON(http.StatusOK, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tags
|
|
||||||
// @Tags 地址
|
|
||||||
// @Summary 标签
|
|
||||||
// @Description 标签
|
|
||||||
// @Accept json
|
|
||||||
// @Produce json
|
|
||||||
// @Success 200 {object} []model.Tag
|
|
||||||
// @Failure 500 {object} response.ErrorResponse
|
|
||||||
// @Router /tags [post]
|
|
||||||
// @Security BearerAuth
|
|
||||||
func (a *Ab) Tags(c *gin.Context) {
|
|
||||||
user := service.AllService.UserService.CurUser(c)
|
|
||||||
|
|
||||||
tags := service.AllService.TagService.ListByUserId(user.Id)
|
|
||||||
c.JSON(http.StatusOK, tags.Tags)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PTags
|
// PTags
|
||||||
// @Tags 地址[Personal]
|
// @Tags 地址[Personal]
|
||||||
// @Summary 标签
|
// @Summary 标签
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
request "Gwen/http/request/api"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/model"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/gin-gonic/gin/binding"
|
"github.com/gin-gonic/gin/binding"
|
||||||
|
request "github.com/lejianwen/rustdesk-api/v2/http/request/api"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
apiReq "Gwen/http/request/api"
|
|
||||||
"Gwen/http/response"
|
|
||||||
apiResp "Gwen/http/response/api"
|
|
||||||
"Gwen/model"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
apiReq "github.com/lejianwen/rustdesk-api/v2/http/request/api"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
apiResp "github.com/lejianwen/rustdesk-api/v2/http/response/api"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ func (g *Group) Users(c *gin.Context) {
|
|||||||
userList = service.AllService.UserService.ListByGroupId(u.GroupId, q.Page, q.PageSize)
|
userList = service.AllService.UserService.ListByGroupId(u.GroupId, q.Page, q.PageSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
var data []*apiResp.UserPayload
|
data := make([]*apiResp.UserPayload, 0, len(userList.Users))
|
||||||
for _, user := range userList.Users {
|
for _, user := range userList.Users {
|
||||||
up := &apiResp.UserPayload{}
|
up := &apiResp.UserPayload{}
|
||||||
up.FromUser(user)
|
up.FromUser(user)
|
||||||
@@ -88,21 +88,30 @@ func (g *Group) Peers(c *gin.Context) {
|
|||||||
users = service.AllService.UserService.ListIdAndNameByGroupId(u.GroupId)
|
users = service.AllService.UserService.ListIdAndNameByGroupId(u.GroupId)
|
||||||
}
|
}
|
||||||
|
|
||||||
namesById := make(map[uint]string)
|
namesById := make(map[uint]string, len(users))
|
||||||
userIds := make([]uint, 0)
|
userIds := make([]uint, 0, len(users))
|
||||||
for _, user := range users {
|
for _, user := range users {
|
||||||
namesById[user.Id] = user.Username
|
namesById[user.Id] = user.Username
|
||||||
userIds = append(userIds, user.Id)
|
userIds = append(userIds, user.Id)
|
||||||
}
|
}
|
||||||
|
dGroupNameById := make(map[uint]string)
|
||||||
|
allGroup := service.AllService.GroupService.DeviceGroupList(1, 999, nil)
|
||||||
|
for _, group := range allGroup.DeviceGroups {
|
||||||
|
dGroupNameById[group.Id] = group.Name
|
||||||
|
}
|
||||||
peerList := service.AllService.PeerService.ListByUserIds(userIds, q.Page, q.PageSize)
|
peerList := service.AllService.PeerService.ListByUserIds(userIds, q.Page, q.PageSize)
|
||||||
var data []*apiResp.GroupPeerPayload
|
data := make([]*apiResp.GroupPeerPayload, 0, len(peerList.Peers))
|
||||||
for _, peer := range peerList.Peers {
|
for _, peer := range peerList.Peers {
|
||||||
uname, ok := namesById[peer.UserId]
|
uname, ok := namesById[peer.UserId]
|
||||||
if !ok {
|
if !ok {
|
||||||
uname = ""
|
uname = ""
|
||||||
}
|
}
|
||||||
|
dGroupName, ok2 := dGroupNameById[peer.GroupId]
|
||||||
|
if !ok2 {
|
||||||
|
dGroupName = ""
|
||||||
|
}
|
||||||
pp := &apiResp.GroupPeerPayload{}
|
pp := &apiResp.GroupPeerPayload{}
|
||||||
pp.FromPeer(peer, uname)
|
pp.FromPeer(peer, uname, dGroupName)
|
||||||
data = append(data, pp)
|
data = append(data, pp)
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -111,3 +120,31 @@ func (g *Group) Peers(c *gin.Context) {
|
|||||||
Data: data,
|
Data: data,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Device
|
||||||
|
// @Tags 群组
|
||||||
|
// @Summary 设备
|
||||||
|
// @Description 机器
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param page query int false "页码"
|
||||||
|
// @Param pageSize query int false "每页数量"
|
||||||
|
// @Param status query int false "状态"
|
||||||
|
// @Param accessible query string false "accessible"
|
||||||
|
// @Success 200 {object} response.DataResponse
|
||||||
|
// @Failure 500 {object} response.Response
|
||||||
|
// @Router /device-group/accessible [get]
|
||||||
|
// @Security BearerAuth
|
||||||
|
func (g *Group) Device(c *gin.Context) {
|
||||||
|
u := service.AllService.UserService.CurUser(c)
|
||||||
|
if !service.AllService.UserService.IsAdmin(u) {
|
||||||
|
response.Error(c, "Permission denied")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
allGroup := service.AllService.GroupService.DeviceGroupList(1, 999, nil)
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, response.DataResponse{
|
||||||
|
Total: 0,
|
||||||
|
Data: allGroup.DeviceGroups,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
requstform "Gwen/http/request/api"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/model"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
requstform "github.com/lejianwen/rustdesk-api/v2/http/request/api"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -55,9 +55,27 @@ func (i *Index) Heartbeat(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
//如果在40s以内则不更新
|
//如果在40s以内则不更新
|
||||||
if time.Now().Unix()-peer.LastOnlineTime > 40 {
|
if time.Now().Unix()-peer.LastOnlineTime >= 30 {
|
||||||
upp := &model.Peer{RowId: peer.RowId, LastOnlineTime: time.Now().Unix(), LastOnlineIp: c.ClientIP()}
|
upp := &model.Peer{RowId: peer.RowId, LastOnlineTime: time.Now().Unix(), LastOnlineIp: c.ClientIP()}
|
||||||
service.AllService.PeerService.Update(upp)
|
service.AllService.PeerService.Update(upp)
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{})
|
c.JSON(http.StatusOK, gin.H{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Version 版本
|
||||||
|
// @Tags 首页
|
||||||
|
// @Summary 版本
|
||||||
|
// @Description 版本
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} response.Response
|
||||||
|
// @Failure 500 {object} response.Response
|
||||||
|
// @Router /version [get]
|
||||||
|
func (i *Index) Version(c *gin.Context) {
|
||||||
|
//读取resources/version文件
|
||||||
|
v := service.AllService.AppService.GetAppVersion()
|
||||||
|
response.Success(
|
||||||
|
c,
|
||||||
|
v,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/request/api"
|
|
||||||
"Gwen/http/response"
|
|
||||||
apiResp "Gwen/http/response/api"
|
|
||||||
"Gwen/model"
|
|
||||||
"Gwen/service"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/api"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
apiResp "github.com/lejianwen/rustdesk-api/v2/http/response/api"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -27,6 +27,10 @@ type Login struct {
|
|||||||
// @Failure 500 {object} response.ErrorResponse
|
// @Failure 500 {object} response.ErrorResponse
|
||||||
// @Router /login [post]
|
// @Router /login [post]
|
||||||
func (l *Login) Login(c *gin.Context) {
|
func (l *Login) Login(c *gin.Context) {
|
||||||
|
if global.Config.App.DisablePwdLogin {
|
||||||
|
response.Error(c, response.TranslateMsg(c, "PwdLoginDisabled"))
|
||||||
|
return
|
||||||
|
}
|
||||||
f := &api.LoginForm{}
|
f := &api.LoginForm{}
|
||||||
err := c.ShouldBindJSON(f)
|
err := c.ShouldBindJSON(f)
|
||||||
//fmt.Println(f)
|
//fmt.Println(f)
|
||||||
@@ -51,6 +55,11 @@ func (l *Login) Login(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !service.AllService.UserService.CheckUserEnable(u) {
|
||||||
|
response.Error(c, response.TranslateMsg(c, "UserDisabled"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
//根据refer判断是webclient还是app
|
//根据refer判断是webclient还是app
|
||||||
ref := c.GetHeader("referer")
|
ref := c.GetHeader("referer")
|
||||||
if ref != "" {
|
if ref != "" {
|
||||||
@@ -85,7 +94,9 @@ func (l *Login) Login(c *gin.Context) {
|
|||||||
// @Router /login-options [get]
|
// @Router /login-options [get]
|
||||||
func (l *Login) LoginOptions(c *gin.Context) {
|
func (l *Login) LoginOptions(c *gin.Context) {
|
||||||
ops := service.AllService.OauthService.GetOauthProviders()
|
ops := service.AllService.OauthService.GetOauthProviders()
|
||||||
ops = append(ops, model.OauthTypeWebauth)
|
if global.Config.App.WebSso {
|
||||||
|
ops = append(ops, model.OauthTypeWebauth)
|
||||||
|
}
|
||||||
var oidcItems []map[string]string
|
var oidcItems []map[string]string
|
||||||
for _, v := range ops {
|
for _, v := range ops {
|
||||||
oidcItems = append(oidcItems, map[string]string{"name": v})
|
oidcItems = append(oidcItems, map[string]string{"name": v})
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/request/api"
|
|
||||||
"Gwen/http/response"
|
|
||||||
apiResp "Gwen/http/response/api"
|
|
||||||
"Gwen/model"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/request/api"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
apiResp "github.com/lejianwen/rustdesk-api/v2/http/response/api"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/utils"
|
||||||
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -32,15 +34,14 @@ func (o *Oauth) OidcAuth(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
oauthService := service.AllService.OauthService
|
oauthService := service.AllService.OauthService
|
||||||
var code string
|
|
||||||
var url string
|
err, state, verifier, nonce, url := oauthService.BeginAuth(f.Op)
|
||||||
err, code, url = oauthService.BeginAuth(f.Op)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
response.Error(c, response.TranslateMsg(c, err.Error()))
|
response.Error(c, response.TranslateMsg(c, err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
service.AllService.OauthService.SetOauthCache(code, &service.OauthCacheItem{
|
service.AllService.OauthService.SetOauthCache(state, &service.OauthCacheItem{
|
||||||
Action: service.OauthActionTypeLogin,
|
Action: service.OauthActionTypeLogin,
|
||||||
Id: f.Id,
|
Id: f.Id,
|
||||||
Op: f.Op,
|
Op: f.Op,
|
||||||
@@ -48,10 +49,12 @@ func (o *Oauth) OidcAuth(c *gin.Context) {
|
|||||||
DeviceName: f.DeviceInfo.Name,
|
DeviceName: f.DeviceInfo.Name,
|
||||||
DeviceOs: f.DeviceInfo.Os,
|
DeviceOs: f.DeviceInfo.Os,
|
||||||
DeviceType: f.DeviceInfo.Type,
|
DeviceType: f.DeviceInfo.Type,
|
||||||
|
Verifier: verifier,
|
||||||
|
Nonce: nonce,
|
||||||
}, 5*60)
|
}, 5*60)
|
||||||
//fmt.Println("code url", code, url)
|
//fmt.Println("code url", code, url)
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"code": code,
|
"code": state,
|
||||||
"url": url,
|
"url": url,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -143,7 +146,10 @@ func (o *Oauth) OidcAuthQuery(c *gin.Context) {
|
|||||||
func (o *Oauth) OauthCallback(c *gin.Context) {
|
func (o *Oauth) OauthCallback(c *gin.Context) {
|
||||||
state := c.Query("state")
|
state := c.Query("state")
|
||||||
if state == "" {
|
if state == "" {
|
||||||
c.String(http.StatusInternalServerError, response.TranslateParamMsg(c, "ParamIsEmpty", "state"))
|
c.HTML(http.StatusOK, "oauth_fail.html", gin.H{
|
||||||
|
"message": "ParamIsEmpty",
|
||||||
|
"sub_message": "state",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cacheKey := state
|
cacheKey := state
|
||||||
@@ -151,17 +157,24 @@ func (o *Oauth) OauthCallback(c *gin.Context) {
|
|||||||
//从缓存中获取
|
//从缓存中获取
|
||||||
oauthCache := oauthService.GetOauthCache(cacheKey)
|
oauthCache := oauthService.GetOauthCache(cacheKey)
|
||||||
if oauthCache == nil {
|
if oauthCache == nil {
|
||||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, "OauthExpired"))
|
c.HTML(http.StatusOK, "oauth_fail.html", gin.H{
|
||||||
|
"message": "OauthExpired",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
nonce := oauthCache.Nonce
|
||||||
op := oauthCache.Op
|
op := oauthCache.Op
|
||||||
action := oauthCache.Action
|
action := oauthCache.Action
|
||||||
|
verifier := oauthCache.Verifier
|
||||||
var user *model.User
|
var user *model.User
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
code := c.Query("code")
|
code := c.Query("code")
|
||||||
err, oauthUser := oauthService.Callback(code, op)
|
err, oauthUser := oauthService.Callback(code, verifier, op, nonce)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, "OauthFailed")+response.TranslateMsg(c, err.Error()))
|
c.HTML(http.StatusOK, "oauth_fail.html", gin.H{
|
||||||
|
"message": "OauthFailed",
|
||||||
|
"sub_message": err.Error(),
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
userId := oauthCache.UserId
|
userId := oauthCache.UserId
|
||||||
@@ -172,28 +185,38 @@ func (o *Oauth) OauthCallback(c *gin.Context) {
|
|||||||
// 检查此openid是否已经绑定过
|
// 检查此openid是否已经绑定过
|
||||||
utr := oauthService.UserThirdInfo(op, openid)
|
utr := oauthService.UserThirdInfo(op, openid)
|
||||||
if utr.UserId > 0 {
|
if utr.UserId > 0 {
|
||||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, "OauthHasBindOtherUser"))
|
c.HTML(http.StatusOK, "oauth_fail.html", gin.H{
|
||||||
|
"message": "OauthHasBindOtherUser",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//绑定
|
//绑定
|
||||||
user = service.AllService.UserService.InfoById(userId)
|
user = service.AllService.UserService.InfoById(userId)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, "ItemNotFound"))
|
c.HTML(http.StatusOK, "oauth_fail.html", gin.H{
|
||||||
|
"message": "ItemNotFound",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//绑定
|
//绑定
|
||||||
err := oauthService.BindOauthUser(userId, oauthUser, op)
|
err := oauthService.BindOauthUser(userId, oauthUser, op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, "BindFail"))
|
c.HTML(http.StatusOK, "oauth_fail.html", gin.H{
|
||||||
|
"message": "BindFail",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.String(http.StatusOK, response.TranslateMsg(c, "BindSuccess"))
|
c.HTML(http.StatusOK, "oauth_success.html", gin.H{
|
||||||
|
"message": "BindSuccess",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
|
|
||||||
} else if action == service.OauthActionTypeLogin {
|
} else if action == service.OauthActionTypeLogin {
|
||||||
//登录
|
//登录
|
||||||
if userId != 0 {
|
if userId != 0 {
|
||||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, "OauthHasBeenSuccess"))
|
c.HTML(http.StatusOK, "oauth_fail.html", gin.H{
|
||||||
|
"message": "OauthHasBeenSuccess",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
user = service.AllService.UserService.InfoByOauthId(op, openid)
|
user = service.AllService.UserService.InfoByOauthId(op, openid)
|
||||||
@@ -210,7 +233,9 @@ func (o *Oauth) OauthCallback(c *gin.Context) {
|
|||||||
//自动注册
|
//自动注册
|
||||||
err, user = service.AllService.UserService.RegisterByOauth(oauthUser, op)
|
err, user = service.AllService.UserService.RegisterByOauth(oauthUser, op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, err.Error()))
|
c.HTML(http.StatusOK, "oauth_fail.html", gin.H{
|
||||||
|
"message": err.Error(),
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -230,11 +255,51 @@ func (o *Oauth) OauthCallback(c *gin.Context) {
|
|||||||
c.Redirect(http.StatusFound, url)
|
c.Redirect(http.StatusFound, url)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.String(http.StatusOK, response.TranslateMsg(c, "OauthSuccess"))
|
c.HTML(http.StatusOK, "oauth_success.html", gin.H{
|
||||||
|
"message": "OauthSuccess",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
c.String(http.StatusInternalServerError, response.TranslateMsg(c, "ParamsError"))
|
c.HTML(http.StatusOK, "oauth_fail.html", gin.H{
|
||||||
|
"message": "ParamsError",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MessageParams struct {
|
||||||
|
Lang string `json:"lang" form:"lang"`
|
||||||
|
Title string `json:"title" form:"title"`
|
||||||
|
Msg string `json:"msg" form:"msg"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Oauth) Message(c *gin.Context) {
|
||||||
|
mp := &MessageParams{}
|
||||||
|
if err := c.ShouldBindQuery(mp); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
localizer := global.Localizer(mp.Lang)
|
||||||
|
res := ""
|
||||||
|
if mp.Title != "" {
|
||||||
|
title, err := localizer.LocalizeMessage(&i18n.Message{
|
||||||
|
ID: mp.Title,
|
||||||
|
})
|
||||||
|
if err == nil {
|
||||||
|
res = utils.StringConcat(";title='", title, "';")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if mp.Msg != "" {
|
||||||
|
msg, err := localizer.LocalizeMessage(&i18n.Message{
|
||||||
|
ID: mp.Msg,
|
||||||
|
})
|
||||||
|
if err == nil {
|
||||||
|
res = utils.StringConcat(res, "msg = '", msg, "';")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//返回js内容
|
||||||
|
c.Header("Content-Type", "application/javascript")
|
||||||
|
c.String(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
requstform "Gwen/http/request/api"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/gin-gonic/gin/binding"
|
"github.com/gin-gonic/gin/binding"
|
||||||
|
requstform "github.com/lejianwen/rustdesk-api/v2/http/request/api"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ func (p *Peer) SysInfo(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
fpe := f.ToPeer()
|
fpe := f.ToPeer()
|
||||||
pe := service.AllService.PeerService.FindById(f.Id)
|
pe := service.AllService.PeerService.FindByUuid(f.Uuid)
|
||||||
if pe.RowId == 0 {
|
if pe.RowId == 0 {
|
||||||
pe = f.ToPeer()
|
pe = f.ToPeer()
|
||||||
pe.UserId = service.AllService.UserService.FindLatestUserIdFromLoginLogByUuid(pe.Uuid)
|
pe.UserId = service.AllService.UserService.FindLatestUserIdFromLoginLogByUuid(pe.Uuid)
|
||||||
@@ -56,3 +56,9 @@ func (p *Peer) SysInfo(c *gin.Context) {
|
|||||||
//直接响应文本
|
//直接响应文本
|
||||||
c.String(http.StatusOK, "SYSINFO_UPDATED")
|
c.String(http.StatusOK, "SYSINFO_UPDATED")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Peer) SysInfoVer(c *gin.Context) {
|
||||||
|
//读取resources/version文件
|
||||||
|
v := service.AllService.AppService.GetAppVersion()
|
||||||
|
c.String(http.StatusOK, v)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
apiResp "Gwen/http/response/api"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
apiResp "github.com/lejianwen/rustdesk-api/v2/http/response/api"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ type User struct {
|
|||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {object} apiResp.UserPayload
|
// @Success 200 {object} apiResp.UserPayload
|
||||||
// @Failure 500 {object} response.Response
|
// @Failure 500 {object} response.Response
|
||||||
// @Router /api [get]
|
// @Router /currentUser [get]
|
||||||
// @Security token
|
// @Security token
|
||||||
func (u *User) Info(c *gin.Context) {
|
func (u *User) Info(c *gin.Context) {
|
||||||
user := service.AllService.UserService.CurUser(c)
|
user := service.AllService.UserService.CurUser(c)
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/http/response/api"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response/api"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ func (i *WebClient) ServerConfig(c *gin.Context) {
|
|||||||
u := service.AllService.UserService.CurUser(c)
|
u := service.AllService.UserService.CurUser(c)
|
||||||
|
|
||||||
peers := map[string]*api.WebClientPeerPayload{}
|
peers := map[string]*api.WebClientPeerPayload{}
|
||||||
abs := service.AllService.AddressBookService.ListByUserId(u.Id, 1, 100)
|
abs := service.AllService.AddressBookService.ListByUserIdAndCollectionId(u.Id, 0, 1, 100)
|
||||||
for _, ab := range abs.AddressBooks {
|
for _, ab := range abs.AddressBooks {
|
||||||
pp := &api.WebClientPeerPayload{}
|
pp := &api.WebClientPeerPayload{}
|
||||||
pp.FromAddressBook(ab)
|
pp.FromAddressBook(ab)
|
||||||
@@ -64,12 +64,15 @@ func (i *WebClient) SharedPeer(c *gin.Context) {
|
|||||||
response.Fail(c, 101, "share not found")
|
response.Fail(c, 101, "share not found")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//判断是否过期,created_at + expire > now
|
if sr.Expire != 0 {
|
||||||
ca := time.Time(sr.CreatedAt)
|
//判断是否过期,created_at + expire > now
|
||||||
if ca.Add(time.Second * time.Duration(sr.Expire)).Before(time.Now()) {
|
ca := time.Time(sr.CreatedAt)
|
||||||
response.Fail(c, 101, "share expired")
|
if ca.Add(time.Second * time.Duration(sr.Expire)).Before(time.Now()) {
|
||||||
return
|
response.Fail(c, 101, "share expired")
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ab := service.AllService.AddressBookService.InfoByUserIdAndId(sr.UserId, sr.PeerId)
|
ab := service.AllService.AddressBookService.InfoByUserIdAndId(sr.UserId, sr.PeerId)
|
||||||
if ab.RowId == 0 {
|
if ab.RowId == 0 {
|
||||||
response.Fail(c, 101, "peer not found")
|
response.Fail(c, 101, "peer not found")
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package web
|
package web
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"strconv"
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Index struct {
|
type Index struct {
|
||||||
@@ -15,13 +15,21 @@ func (i *Index) Index(c *gin.Context) {
|
|||||||
|
|
||||||
func (i *Index) ConfigJs(c *gin.Context) {
|
func (i *Index) ConfigJs(c *gin.Context) {
|
||||||
apiServer := global.Config.Rustdesk.ApiServer
|
apiServer := global.Config.Rustdesk.ApiServer
|
||||||
magicQueryonline := strconv.Itoa(global.Config.Rustdesk.WebclientMagicQueryonline)
|
magicQueryonline := global.Config.Rustdesk.WebclientMagicQueryonline
|
||||||
tmp := `
|
tmp := fmt.Sprintf(`localStorage.setItem('api-server', '%v');
|
||||||
localStorage.setItem('api-server', "` + apiServer + `")
|
const ws2_prefix = 'wc-';
|
||||||
const ws2_prefix = 'wc-'
|
localStorage.setItem(ws2_prefix+'api-server', '%v');
|
||||||
localStorage.setItem(ws2_prefix+'api-server', "` + apiServer + `")
|
|
||||||
|
|
||||||
window.webclient_magic_queryonline = ` + magicQueryonline + ``
|
window.webclient_magic_queryonline = %d;
|
||||||
|
window.ws_host = '%v';
|
||||||
|
`, apiServer, apiServer, magicQueryonline, global.Config.Rustdesk.WsHost)
|
||||||
|
// tmp := `
|
||||||
|
//localStorage.setItem('api-server', "` + apiServer + `")
|
||||||
|
//const ws2_prefix = 'wc-'
|
||||||
|
//localStorage.setItem(ws2_prefix+'api-server', "` + apiServer + `")
|
||||||
|
//
|
||||||
|
//window.webclient_magic_queryonline = ` + magicQueryonline + ``
|
||||||
|
|
||||||
|
c.Header("Content-Type", "application/javascript")
|
||||||
c.String(200, tmp)
|
c.String(200, tmp)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package http
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/middleware"
|
|
||||||
"Gwen/http/router"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/middleware"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/router"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AdminAuth 后台权限验证中间件
|
// BackendUserAuth 后台权限验证中间件
|
||||||
func AdminAuth() gin.HandlerFunc {
|
func BackendUserAuth() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
|
|
||||||
//测试先关闭
|
//测试先关闭
|
||||||
@@ -24,6 +24,14 @@ func AdminAuth() gin.HandlerFunc {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !service.AllService.UserService.CheckUserEnable(user) {
|
||||||
|
c.JSON(401, gin.H{
|
||||||
|
"error": "Unauthorized",
|
||||||
|
})
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
c.Set("curUser", user)
|
c.Set("curUser", user)
|
||||||
c.Set("token", token)
|
c.Set("token", token)
|
||||||
//如果时间小于1天,token自动续期
|
//如果时间小于1天,token自动续期
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AdminPrivilege ...
|
// AdminPrivilege ...
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/http/response"
|
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/http/response"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
func JwtAuth() gin.HandlerFunc {
|
func JwtAuth() gin.HandlerFunc {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/service"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/service"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RustAuth() gin.HandlerFunc {
|
func RustAuth() gin.HandlerFunc {
|
||||||
@@ -27,7 +28,21 @@ func RustAuth() gin.HandlerFunc {
|
|||||||
//提取token,格式是Bearer {token}
|
//提取token,格式是Bearer {token}
|
||||||
//这里只是简单的提取
|
//这里只是简单的提取
|
||||||
token = token[7:]
|
token = token[7:]
|
||||||
|
|
||||||
//验证token
|
//验证token
|
||||||
|
|
||||||
|
//检查是否设置了jwt key
|
||||||
|
if len(global.Jwt.Key) > 0 {
|
||||||
|
uid, _ := service.AllService.UserService.VerifyJWT(token)
|
||||||
|
if uid == 0 {
|
||||||
|
c.JSON(401, gin.H{
|
||||||
|
"error": "Unauthorized",
|
||||||
|
})
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
user, ut := service.AllService.UserService.InfoByAccessToken(token)
|
user, ut := service.AllService.UserService.InfoByAccessToken(token)
|
||||||
if user.Id == 0 {
|
if user.Id == 0 {
|
||||||
c.JSON(401, gin.H{
|
c.JSON(401, gin.H{
|
||||||
@@ -38,7 +53,7 @@ func RustAuth() gin.HandlerFunc {
|
|||||||
}
|
}
|
||||||
if !service.AllService.UserService.CheckUserEnable(user) {
|
if !service.AllService.UserService.CheckUserEnable(user) {
|
||||||
c.JSON(401, gin.H{
|
c.JSON(401, gin.H{
|
||||||
"error": "账号已被禁用",
|
"error": "Unauthorized",
|
||||||
})
|
})
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/model"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AddressBookForm struct {
|
type AddressBookForm struct {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import "Gwen/model"
|
import "github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
|
||||||
type GroupForm struct {
|
type GroupForm struct {
|
||||||
Id uint `json:"id"`
|
Id uint `json:"id"`
|
||||||
@@ -22,3 +22,15 @@ func (gf *GroupForm) ToGroup() *model.Group {
|
|||||||
group.Type = gf.Type
|
group.Type = gf.Type
|
||||||
return group
|
return group
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DeviceGroupForm struct {
|
||||||
|
Id uint `json:"id"`
|
||||||
|
Name string `json:"name" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gf *DeviceGroupForm) ToDeviceGroup() *model.DeviceGroup {
|
||||||
|
group := &model.DeviceGroup{}
|
||||||
|
group.Id = gf.Id
|
||||||
|
group.Name = gf.Name
|
||||||
|
return group
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/model"
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BindOauthForm struct {
|
type BindOauthForm struct {
|
||||||
@@ -15,27 +15,31 @@ type UnBindOauthForm struct {
|
|||||||
Op string `json:"op" binding:"required"`
|
Op string `json:"op" binding:"required"`
|
||||||
}
|
}
|
||||||
type OauthForm struct {
|
type OauthForm struct {
|
||||||
Id uint `json:"id"`
|
Id uint `json:"id"`
|
||||||
Op string `json:"op" validate:"omitempty"`
|
Op string `json:"op" validate:"omitempty"`
|
||||||
OauthType string `json:"oauth_type" validate:"required"`
|
OauthType string `json:"oauth_type" validate:"required"`
|
||||||
Issuer string `json:"issuer" validate:"omitempty,url"`
|
Issuer string `json:"issuer" validate:"omitempty,url"`
|
||||||
Scopes string `json:"scopes" validate:"omitempty"`
|
Scopes string `json:"scopes" validate:"omitempty"`
|
||||||
ClientId string `json:"client_id" validate:"required"`
|
ClientId string `json:"client_id" validate:"required"`
|
||||||
ClientSecret string `json:"client_secret" validate:"required"`
|
ClientSecret string `json:"client_secret" validate:"required"`
|
||||||
RedirectUrl string `json:"redirect_url" validate:"required"`
|
RedirectUrl string `json:"redirect_url" validate:"required"`
|
||||||
AutoRegister *bool `json:"auto_register"`
|
AutoRegister *bool `json:"auto_register"`
|
||||||
|
PkceEnable *bool `json:"pkce_enable"`
|
||||||
|
PkceMethod string `json:"pkce_method"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (of *OauthForm) ToOauth() *model.Oauth {
|
func (of *OauthForm) ToOauth() *model.Oauth {
|
||||||
oa := &model.Oauth{
|
oa := &model.Oauth{
|
||||||
Op: of.Op,
|
Op: of.Op,
|
||||||
OauthType: of.OauthType,
|
OauthType: of.OauthType,
|
||||||
ClientId: of.ClientId,
|
ClientId: of.ClientId,
|
||||||
ClientSecret: of.ClientSecret,
|
ClientSecret: of.ClientSecret,
|
||||||
RedirectUrl: of.RedirectUrl,
|
RedirectUrl: of.RedirectUrl,
|
||||||
AutoRegister: of.AutoRegister,
|
AutoRegister: of.AutoRegister,
|
||||||
Issuer: of.Issuer,
|
Issuer: of.Issuer,
|
||||||
Scopes: of.Scopes,
|
Scopes: of.Scopes,
|
||||||
|
PkceEnable: of.PkceEnable,
|
||||||
|
PkceMethod: of.PkceMethod,
|
||||||
}
|
}
|
||||||
oa.Id = of.Id
|
oa.Id = of.Id
|
||||||
return oa
|
return oa
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import "Gwen/model"
|
import "github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
|
||||||
type PeerForm struct {
|
type PeerForm struct {
|
||||||
RowId uint `json:"row_id" `
|
RowId uint `json:"row_id" `
|
||||||
@@ -12,6 +12,7 @@ type PeerForm struct {
|
|||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Uuid string `json:"uuid"`
|
Uuid string `json:"uuid"`
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
|
GroupId uint `json:"group_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PeerBatchDeleteForm struct {
|
type PeerBatchDeleteForm struct {
|
||||||
@@ -30,6 +31,7 @@ func (f *PeerForm) ToPeer() *model.Peer {
|
|||||||
Username: f.Username,
|
Username: f.Username,
|
||||||
Uuid: f.Uuid,
|
Uuid: f.Uuid,
|
||||||
Version: f.Version,
|
Version: f.Version,
|
||||||
|
GroupId: f.GroupId,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,6 +41,8 @@ type PeerQuery struct {
|
|||||||
Id string `json:"id" form:"id"`
|
Id string `json:"id" form:"id"`
|
||||||
Hostname string `json:"hostname" form:"hostname"`
|
Hostname string `json:"hostname" form:"hostname"`
|
||||||
Uuids string `json:"uuids" form:"uuids"`
|
Uuids string `json:"uuids" form:"uuids"`
|
||||||
|
Ip string `json:"ip" form:"ip"`
|
||||||
|
Username string `json:"username" form:"username"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type SimpleDataQuery struct {
|
type SimpleDataQuery struct {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import "Gwen/model"
|
import "github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
|
||||||
type TagForm struct {
|
type TagForm struct {
|
||||||
Id uint `json:"id"`
|
Id uint `json:"id"`
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/model"
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserForm struct {
|
type UserForm struct {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"Gwen/model"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import "Gwen/model"
|
import "github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
|
||||||
type AddressBookFormData struct {
|
type AddressBookFormData struct {
|
||||||
Tags []string `json:"tags"`
|
Tags []string `json:"tags"`
|
||||||
|
|||||||
@@ -40,14 +40,14 @@ type LoginForm struct {
|
|||||||
|
|
||||||
type UserListQuery struct {
|
type UserListQuery struct {
|
||||||
Page uint `json:"page" form:"page" validate:"required" label:"页码"`
|
Page uint `json:"page" form:"page" validate:"required" label:"页码"`
|
||||||
PageSize uint `json:"page_size" form:"page_size" validate:"required" label:"每页数量"`
|
PageSize uint `json:"pageSize" form:"pageSize" validate:"required" label:"每页数量"`
|
||||||
Status int `json:"status" form:"status" label:"状态"`
|
Status int `json:"status" form:"status" label:"状态"`
|
||||||
Accessible string `json:"accessible" form:"accessible"`
|
Accessible string `json:"accessible" form:"accessible"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PeerListQuery struct {
|
type PeerListQuery struct {
|
||||||
Page uint `json:"page" form:"page" validate:"required" label:"页码"`
|
Page uint `json:"page" form:"page" validate:"required" label:"页码"`
|
||||||
PageSize uint `json:"page_size" form:"page_size" validate:"required" label:"每页数量"`
|
PageSize uint `json:"pageSize" form:"pageSize" validate:"required" label:"每页数量"`
|
||||||
Status int `json:"status" form:"status" label:"状态"`
|
Status int `json:"status" form:"status" label:"状态"`
|
||||||
Accessible string `json:"accessible" form:"accessible"`
|
Accessible string `json:"accessible" form:"accessible"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import "Gwen/model"
|
import "github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
|
||||||
type LoginPayload struct {
|
type LoginPayload struct {
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
@@ -18,24 +18,7 @@ func (lp *LoginPayload) FromUser(user *model.User) {
|
|||||||
lp.Nickname = user.Nickname
|
lp.Nickname = user.Nickname
|
||||||
}
|
}
|
||||||
|
|
||||||
var UserRouteNames = []string{
|
|
||||||
"MyTagList", "MyAddressBookList", "MyInfo", "MyAddressBookCollection", "MyPeer", "MyShareRecordList",
|
|
||||||
}
|
|
||||||
var AdminRouteNames = []string{"*"}
|
|
||||||
|
|
||||||
type UserOauthItem struct {
|
type UserOauthItem struct {
|
||||||
Op string `json:"op"`
|
Op string `json:"op"`
|
||||||
Status int `json:"status"`
|
Status int `json:"status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GroupUsersPayload struct {
|
|
||||||
Id uint `json:"id"`
|
|
||||||
Username string `json:"username"`
|
|
||||||
Status int `json:"status"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *GroupUsersPayload) FromUser(user *model.User) {
|
|
||||||
g.Id = user.Id
|
|
||||||
g.Username = user.Username
|
|
||||||
g.Status = 1
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import "Gwen/model"
|
import "github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
|
||||||
type AbList struct {
|
type AbList struct {
|
||||||
Peers []*model.AddressBook `json:"peers,omitempty"`
|
Peers []*model.AddressBook `json:"peers,omitempty"`
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import "Gwen/model"
|
import "github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
GroupPeerPayload
|
GroupPeerPayload
|
||||||
@@ -32,12 +32,13 @@ https://github.com/rustdesk/rustdesk/blob/master/flutter/lib/common/hbbs/hbbs.da
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
type GroupPeerPayload struct {
|
type GroupPeerPayload struct {
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
Info *PeerPayloadInfo `json:"info"`
|
Info *PeerPayloadInfo `json:"info"`
|
||||||
Status int `json:"status"`
|
Status int `json:"status"`
|
||||||
User string `json:"user"`
|
User string `json:"user"`
|
||||||
UserName string `json:"user_name"`
|
UserName string `json:"user_name"`
|
||||||
Note string `json:"note"`
|
Note string `json:"note"`
|
||||||
|
DeviceGroupName string `json:"device_group_name"`
|
||||||
}
|
}
|
||||||
type PeerPayloadInfo struct {
|
type PeerPayloadInfo struct {
|
||||||
DeviceName string `json:"device_name"`
|
DeviceName string `json:"device_name"`
|
||||||
@@ -59,7 +60,7 @@ func (gpp *GroupPeerPayload) FromAddressBook(a *model.AddressBook, username stri
|
|||||||
gpp.UserName = username
|
gpp.UserName = username
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gpp *GroupPeerPayload) FromPeer(p *model.Peer, username string) {
|
func (gpp *GroupPeerPayload) FromPeer(p *model.Peer, username string, dGroupName string) {
|
||||||
gpp.Id = p.Id
|
gpp.Id = p.Id
|
||||||
gpp.Info = &PeerPayloadInfo{
|
gpp.Info = &PeerPayloadInfo{
|
||||||
DeviceName: p.Hostname,
|
DeviceName: p.Hostname,
|
||||||
@@ -68,4 +69,5 @@ func (gpp *GroupPeerPayload) FromPeer(p *model.Peer, username string) {
|
|||||||
}
|
}
|
||||||
gpp.Note = ""
|
gpp.Note = ""
|
||||||
gpp.UserName = username
|
gpp.UserName = username
|
||||||
|
gpp.DeviceGroupName = dGroupName
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import "Gwen/model"
|
import "github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
pub enum UserStatus {
|
pub enum UserStatus {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/model"
|
"github.com/lejianwen/rustdesk-api/v2/model"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package response
|
package response
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Gwen/global"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/lejianwen/rustdesk-api/v2/global"
|
||||||
"github.com/nicksnyder/go-i18n/v2/i18n"
|
"github.com/nicksnyder/go-i18n/v2/i18n"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|||||||