feat: 添加数据库资产、命令拦截器、授权资产等功能,修复GitHub Actions工作流
This commit is contained in:
@@ -9,11 +9,11 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Private Actions Checkout
|
- name: Private Actions Checkout
|
||||||
uses: actions/checkout@v2.3.4
|
uses: actions/checkout@v4
|
||||||
- name: Docker Setup QEMU
|
- name: Docker Setup QEMU
|
||||||
uses: docker/setup-qemu-action@v1.2.0
|
uses: docker/setup-qemu-action@v3
|
||||||
- name: Docker Setup Buildx
|
- name: Docker Setup Buildx
|
||||||
uses: docker/setup-buildx-action@v1.6.0
|
uses: docker/setup-buildx-action@v3
|
||||||
- name: Get resources
|
- name: Get resources
|
||||||
run: |
|
run: |
|
||||||
rm -rf *
|
rm -rf *
|
||||||
@@ -22,15 +22,15 @@ jobs:
|
|||||||
mv /tmp/guacamole-server-master/* .
|
mv /tmp/guacamole-server-master/* .
|
||||||
|
|
||||||
- name: Docker Login
|
- name: Docker Login
|
||||||
uses: docker/login-action@v1.10.0
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||||
- name: Build and push Docker images
|
- name: Build and push Docker images
|
||||||
uses: docker/build-push-action@v2.7.0
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
platforms: linux/arm64,linux/arm/v7,linux/amd64
|
platforms: linux/arm64,linux/amd64
|
||||||
push: true
|
push: true
|
||||||
tags: |
|
tags: |
|
||||||
${{ secrets.DOCKERHUB_USERNAME }}/guacamole-server:latest
|
${{ secrets.DOCKERHUB_USERNAME }}/guacamole-server:latest
|
||||||
|
|||||||
@@ -9,28 +9,28 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Private Actions Checkout
|
- name: Private Actions Checkout
|
||||||
uses: actions/checkout@v2.3.4
|
uses: actions/checkout@v4
|
||||||
- name: Docker Setup QEMU
|
- name: Docker Setup QEMU
|
||||||
uses: docker/setup-qemu-action@v1.2.0
|
uses: docker/setup-qemu-action@v3
|
||||||
- name: Docker Setup Buildx
|
- name: Docker Setup Buildx
|
||||||
uses: docker/setup-buildx-action@v1.6.0
|
uses: docker/setup-buildx-action@v3
|
||||||
- name: Docker Login
|
- name: Docker Login
|
||||||
uses: docker/login-action@v1.10.0
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||||
- name: Docker Aliyun Login
|
- name: Docker Aliyun Login
|
||||||
uses: docker/login-action@v1.10.0
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
registry: registry.cn-beijing.aliyuncs.com
|
registry: registry.cn-beijing.aliyuncs.com
|
||||||
username: ${{ secrets.ALI_USERNAME }}
|
username: ${{ secrets.ALI_USERNAME }}
|
||||||
password: ${{ secrets.ALI_PASSWORD }}
|
password: ${{ secrets.ALI_PASSWORD }}
|
||||||
|
|
||||||
- name: Build and push Docker images
|
- name: Build and push Docker images
|
||||||
uses: docker/build-push-action@v2.7.0
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
platforms: linux/arm64,linux/arm/v7,linux/amd64
|
platforms: linux/arm64,linux/amd64
|
||||||
file: guacd/Dockerfile
|
file: guacd/Dockerfile
|
||||||
push: true
|
push: true
|
||||||
tags: |
|
tags: |
|
||||||
|
|||||||
@@ -13,17 +13,17 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Get version
|
- name: Get version
|
||||||
id: get_version
|
id: get_version
|
||||||
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
|
run: echo "VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT
|
||||||
- name: Private Actions Checkout
|
- name: Private Actions Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
- name: Docker Setup QEMU
|
- name: Docker Setup QEMU
|
||||||
uses: docker/setup-qemu-action@v1.2.0
|
uses: docker/setup-qemu-action@v3
|
||||||
- name: Docker Setup Buildx
|
- name: Docker Setup Buildx
|
||||||
uses: docker/setup-buildx-action@v1.6.0
|
uses: docker/setup-buildx-action@v3
|
||||||
- name: node Setup
|
- name: node Setup
|
||||||
uses: actions/setup-node@v2
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: '16'
|
node-version: '20'
|
||||||
- name: npm install
|
- name: npm install
|
||||||
run: |
|
run: |
|
||||||
cd web
|
cd web
|
||||||
@@ -31,21 +31,21 @@ jobs:
|
|||||||
yarn
|
yarn
|
||||||
yarn build
|
yarn build
|
||||||
- name: Docker Login
|
- name: Docker Login
|
||||||
uses: docker/login-action@v1.10.0
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||||
- name: Docker Aliyun Login
|
- name: Docker Aliyun Login
|
||||||
uses: docker/login-action@v1.10.0
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
registry: registry.cn-beijing.aliyuncs.com
|
registry: registry.cn-beijing.aliyuncs.com
|
||||||
username: ${{ secrets.ALI_USERNAME }}
|
username: ${{ secrets.ALI_USERNAME }}
|
||||||
password: ${{ secrets.ALI_PASSWORD }}
|
password: ${{ secrets.ALI_PASSWORD }}
|
||||||
- name: Build and push Docker images
|
- name: Build and push Docker images
|
||||||
uses: docker/build-push-action@v2.7.0
|
uses: docker/build-push-action@v6
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
platforms: linux/arm64,linux/arm/v7,linux/amd64
|
platforms: linux/arm64,linux/amd64
|
||||||
file: Dockerfile
|
file: Dockerfile
|
||||||
push: true
|
push: true
|
||||||
tags: |
|
tags: |
|
||||||
@@ -62,9 +62,9 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Private Actions Checkout
|
- name: Private Actions Checkout
|
||||||
uses: actions/checkout@v2.3.4
|
uses: actions/checkout@v4
|
||||||
- name: Docker Hub Description
|
- name: Docker Hub Description
|
||||||
uses: peter-evans/dockerhub-description@v2
|
uses: peter-evans/dockerhub-description@v4
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||||
|
|||||||
@@ -13,10 +13,13 @@ jobs:
|
|||||||
name: lint
|
name: lint
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v4
|
||||||
- name: golangci-lint
|
- uses: actions/setup-go@v5
|
||||||
uses: golangci/golangci-lint-action@v2
|
|
||||||
with:
|
with:
|
||||||
# Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
|
go-version: '1.22'
|
||||||
version: v1.42.1
|
- name: golangci-lint
|
||||||
|
uses: golangci/golangci-lint-action@v6
|
||||||
|
with:
|
||||||
|
version: latest
|
||||||
args: --timeout=5m
|
args: --timeout=5m
|
||||||
|
working-directory: server
|
||||||
|
|||||||
@@ -13,22 +13,22 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- name: Get version
|
- name: Get version
|
||||||
id: get_version
|
id: get_version
|
||||||
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
|
run: echo "VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT
|
||||||
- name: Private Actions Checkout
|
- name: Private Actions Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
- name: node Setup
|
- name: node Setup
|
||||||
uses: actions/setup-node@v2
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: '16'
|
node-version: '20'
|
||||||
- name: npm install
|
- name: npm install
|
||||||
run: |
|
run: |
|
||||||
cd web
|
cd web
|
||||||
npm install --global yarn
|
npm install --global yarn
|
||||||
yarn
|
yarn
|
||||||
- name: go Setup
|
- name: go Setup
|
||||||
uses: actions/setup-go@v4
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.20'
|
go-version: '1.22'
|
||||||
- name: Build package Linux
|
- name: Build package Linux
|
||||||
run: |
|
run: |
|
||||||
sh build.sh
|
sh build.sh
|
||||||
@@ -39,7 +39,7 @@ jobs:
|
|||||||
cp LICENSE next-terminal/
|
cp LICENSE next-terminal/
|
||||||
tar zcvf next-terminal.tar.gz next-terminal/
|
tar zcvf next-terminal.tar.gz next-terminal/
|
||||||
- name: release
|
- name: release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v2
|
||||||
with:
|
with:
|
||||||
files: next-terminal.tar.gz
|
files: next-terminal.tar.gz
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ linters-settings:
|
|||||||
linters:
|
linters:
|
||||||
disable-all: true
|
disable-all: true
|
||||||
enable:
|
enable:
|
||||||
- deadcode
|
|
||||||
- errcheck
|
- errcheck
|
||||||
- gofmt
|
- gofmt
|
||||||
- goimports
|
- goimports
|
||||||
@@ -13,10 +12,8 @@ linters:
|
|||||||
- govet
|
- govet
|
||||||
- ineffassign
|
- ineffassign
|
||||||
- staticcheck
|
- staticcheck
|
||||||
- structcheck
|
|
||||||
- typecheck
|
- typecheck
|
||||||
- unused
|
- unused
|
||||||
- varcheck
|
|
||||||
|
|
||||||
run:
|
run:
|
||||||
skip-files:
|
skip-files:
|
||||||
|
|||||||
+18
-3
@@ -122,9 +122,14 @@ func (api AccountApi) LoginEndpoint(c echo.Context) error {
|
|||||||
Username: user.Username,
|
Username: user.Username,
|
||||||
Nickname: user.Nickname,
|
Nickname: user.Nickname,
|
||||||
Type: user.Type,
|
Type: user.Type,
|
||||||
EnableTotp: user.TOTPSecret != "" && user.TOTPSecret != "-",
|
EnabledTotp: user.TOTPSecret != "" && user.TOTPSecret != "-",
|
||||||
|
MfaEnabled: user.TOTPSecret != "" && user.TOTPSecret != "-",
|
||||||
Roles: user.Roles,
|
Roles: user.Roles,
|
||||||
Menus: menus,
|
Menus: menus,
|
||||||
|
Language: "zh-CN",
|
||||||
|
ForceTotpEnabled: false,
|
||||||
|
NeedChangePassword: false,
|
||||||
|
Dev: config.GlobalCfg.Debug,
|
||||||
}
|
}
|
||||||
|
|
||||||
return Success(c, maps.Map{
|
return Success(c, maps.Map{
|
||||||
@@ -273,9 +278,14 @@ type AccountInfo struct {
|
|||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Nickname string `json:"nickname"`
|
Nickname string `json:"nickname"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
EnableTotp bool `json:"enableTotp"`
|
EnabledTotp bool `json:"enabledTotp"`
|
||||||
|
MfaEnabled bool `json:"mfaEnabled"`
|
||||||
Roles []string `json:"roles"`
|
Roles []string `json:"roles"`
|
||||||
Menus []UserMenu `json:"menus"`
|
Menus []UserMenu `json:"menus"`
|
||||||
|
Language string `json:"language"`
|
||||||
|
ForceTotpEnabled bool `json:"forceTotpEnabled"`
|
||||||
|
NeedChangePassword bool `json:"needChangePassword"`
|
||||||
|
Dev bool `json:"dev"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserMenu struct {
|
type UserMenu struct {
|
||||||
@@ -321,9 +331,14 @@ func (api AccountApi) InfoEndpoint(c echo.Context) error {
|
|||||||
Username: user.Username,
|
Username: user.Username,
|
||||||
Nickname: user.Nickname,
|
Nickname: user.Nickname,
|
||||||
Type: user.Type,
|
Type: user.Type,
|
||||||
EnableTotp: user.TOTPSecret != "" && user.TOTPSecret != "-",
|
EnabledTotp: user.TOTPSecret != "" && user.TOTPSecret != "-",
|
||||||
|
MfaEnabled: user.TOTPSecret != "" && user.TOTPSecret != "-",
|
||||||
Roles: user.Roles,
|
Roles: user.Roles,
|
||||||
Menus: menus,
|
Menus: menus,
|
||||||
|
Language: "zh-CN",
|
||||||
|
ForceTotpEnabled: false,
|
||||||
|
NeedChangePassword: false,
|
||||||
|
Dev: config.GlobalCfg.Debug,
|
||||||
}
|
}
|
||||||
return Success(c, info)
|
return Success(c, info)
|
||||||
}
|
}
|
||||||
|
|||||||
+36
-17
@@ -32,9 +32,15 @@ func (api AssetGroupApi) GroupsSetEndpoint(c echo.Context) error {
|
|||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
repository.AssetGroupRepository.DeleteByParentId(ctx, "")
|
repository.AssetGroupRepository.DeleteByParentId(ctx, "")
|
||||||
for i, item := range req {
|
for i, item := range req {
|
||||||
|
name := ""
|
||||||
|
if v, ok := item["name"].(string); ok {
|
||||||
|
name = v
|
||||||
|
} else if v, ok := item["title"].(string); ok {
|
||||||
|
name = v
|
||||||
|
}
|
||||||
group := model.AssetGroup{
|
group := model.AssetGroup{
|
||||||
ID: utils.UUID(),
|
ID: utils.UUID(),
|
||||||
Name: item["name"].(string),
|
Name: name,
|
||||||
ParentId: "",
|
ParentId: "",
|
||||||
Sort: i,
|
Sort: i,
|
||||||
Created: time.Now().UnixMilli(),
|
Created: time.Now().UnixMilli(),
|
||||||
@@ -58,9 +64,15 @@ func (api AssetGroupApi) GroupsDeleteEndpoint(c echo.Context) error {
|
|||||||
func saveChildren(ctx context.Context, children []interface{}, parentId string) {
|
func saveChildren(ctx context.Context, children []interface{}, parentId string) {
|
||||||
for i, item := range children {
|
for i, item := range children {
|
||||||
m := item.(map[string]interface{})
|
m := item.(map[string]interface{})
|
||||||
|
name := ""
|
||||||
|
if v, ok := m["name"].(string); ok {
|
||||||
|
name = v
|
||||||
|
} else if v, ok := m["title"].(string); ok {
|
||||||
|
name = v
|
||||||
|
}
|
||||||
group := model.AssetGroup{
|
group := model.AssetGroup{
|
||||||
ID: utils.UUID(),
|
ID: utils.UUID(),
|
||||||
Name: m["name"].(string),
|
Name: name,
|
||||||
ParentId: parentId,
|
ParentId: parentId,
|
||||||
Sort: i,
|
Sort: i,
|
||||||
Created: time.Now().UnixMilli(),
|
Created: time.Now().UnixMilli(),
|
||||||
@@ -109,27 +121,15 @@ func (api AssetGroupApi) TreeEndpoint(c echo.Context) error {
|
|||||||
|
|
||||||
func buildAssetTree(assets []model.Asset, groups []model.AssetGroup, groupId string) []maps.Map {
|
func buildAssetTree(assets []model.Asset, groups []model.AssetGroup, groupId string) []maps.Map {
|
||||||
var nodes []maps.Map
|
var nodes []maps.Map
|
||||||
var groupAssets []model.Asset
|
|
||||||
for _, a := range assets {
|
|
||||||
groupAssets = append(groupAssets, a)
|
|
||||||
}
|
|
||||||
for _, a := range groupAssets {
|
|
||||||
nodes = append(nodes, maps.Map{
|
|
||||||
"id": a.ID,
|
|
||||||
"name": a.Name,
|
|
||||||
"key": a.ID,
|
|
||||||
"isLeaf": true,
|
|
||||||
"protocol": a.Protocol,
|
|
||||||
"ip": a.IP,
|
|
||||||
"port": a.Port,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
for _, g := range groups {
|
for _, g := range groups {
|
||||||
if g.ParentId == groupId {
|
if g.ParentId == groupId {
|
||||||
node := maps.Map{
|
node := maps.Map{
|
||||||
"id": g.ID,
|
"id": g.ID,
|
||||||
"name": g.Name,
|
"name": g.Name,
|
||||||
"key": g.ID,
|
"key": g.ID,
|
||||||
|
"title": g.Name,
|
||||||
|
"value": g.ID,
|
||||||
}
|
}
|
||||||
children := buildAssetTree(assets, groups, g.ID)
|
children := buildAssetTree(assets, groups, g.ID)
|
||||||
if len(children) > 0 {
|
if len(children) > 0 {
|
||||||
@@ -138,6 +138,25 @@ func buildAssetTree(assets []model.Asset, groups []model.AssetGroup, groupId str
|
|||||||
nodes = append(nodes, node)
|
nodes = append(nodes, node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if groupId == "" {
|
||||||
|
for _, a := range assets {
|
||||||
|
nodes = append(nodes, maps.Map{
|
||||||
|
"id": a.ID,
|
||||||
|
"name": a.Name,
|
||||||
|
"key": a.ID,
|
||||||
|
"title": a.Name,
|
||||||
|
"value": a.ID,
|
||||||
|
"isLeaf": true,
|
||||||
|
"protocol": a.Protocol,
|
||||||
|
"ip": a.IP,
|
||||||
|
"port": a.Port,
|
||||||
|
"extra": maps.Map{
|
||||||
|
"network": a.IP + ":" + strconv.Itoa(a.Port),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
return nodes
|
return nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,12 @@ package api
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
|
"crypto/x509/pkix"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
|
"math/big"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -65,6 +69,43 @@ func parseCertificate(certPEM string) (commonName, subject, issuer string, notBe
|
|||||||
return commonName, subject, issuer, notBefore, notAfter, nil
|
return commonName, subject, issuer, notBefore, notAfter, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func generateSelfSignedCertificate(commonName string) (certPEM, keyPEM string, notBefore, notAfter time.Time, err error) {
|
||||||
|
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", time.Time{}, time.Time{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
notBefore = time.Now()
|
||||||
|
notAfter = notBefore.Add(365 * 24 * time.Hour)
|
||||||
|
|
||||||
|
serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128))
|
||||||
|
if err != nil {
|
||||||
|
return "", "", time.Time{}, time.Time{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
template := x509.Certificate{
|
||||||
|
SerialNumber: serialNumber,
|
||||||
|
Subject: pkix.Name{
|
||||||
|
CommonName: commonName,
|
||||||
|
},
|
||||||
|
NotBefore: notBefore,
|
||||||
|
NotAfter: notAfter,
|
||||||
|
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||||||
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||||
|
BasicConstraintsValid: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", time.Time{}, time.Time{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
certPEM = string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes}))
|
||||||
|
keyPEM = string(pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}))
|
||||||
|
|
||||||
|
return certPEM, keyPEM, notBefore, notAfter, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (api CertificateApi) CreateEndpoint(c echo.Context) error {
|
func (api CertificateApi) CreateEndpoint(c echo.Context) error {
|
||||||
var req struct {
|
var req struct {
|
||||||
CommonName string `json:"commonName"`
|
CommonName string `json:"commonName"`
|
||||||
@@ -89,7 +130,21 @@ func (api CertificateApi) CreateEndpoint(c echo.Context) error {
|
|||||||
UpdatedAt: common.NowJsonTime(),
|
UpdatedAt: common.NowJsonTime(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if req.Certificate != "" {
|
if item.Type == "" {
|
||||||
|
item.Type = "imported"
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.Type == "self-signed" && req.Certificate == "" {
|
||||||
|
certPEM, keyPEM, notBefore, notAfter, err := generateSelfSignedCertificate(req.CommonName)
|
||||||
|
if err == nil {
|
||||||
|
item.Certificate = certPEM
|
||||||
|
item.PrivateKey = keyPEM
|
||||||
|
item.NotBefore = common.NewJsonTime(notBefore)
|
||||||
|
item.NotAfter = common.NewJsonTime(notAfter)
|
||||||
|
item.Subject = "CN=" + req.CommonName
|
||||||
|
item.Issuer = "CN=" + req.CommonName
|
||||||
|
}
|
||||||
|
} else if req.Certificate != "" {
|
||||||
commonName, subject, issuer, notBefore, notAfter, err := parseCertificate(req.Certificate)
|
commonName, subject, issuer, notBefore, notAfter, err := parseCertificate(req.Certificate)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if item.CommonName == "" {
|
if item.CommonName == "" {
|
||||||
@@ -102,10 +157,6 @@ func (api CertificateApi) CreateEndpoint(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if item.Type == "" {
|
|
||||||
item.Type = "imported"
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := repository.CertificateRepository.Create(context.TODO(), item); err != nil {
|
if err := repository.CertificateRepository.Create(context.TODO(), item); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
+114
-18
@@ -1,7 +1,12 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"next-terminal/server/common/maps"
|
"next-terminal/server/common/maps"
|
||||||
|
"next-terminal/server/model"
|
||||||
|
"next-terminal/server/repository"
|
||||||
"next-terminal/server/utils"
|
"next-terminal/server/utils"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
@@ -10,59 +15,150 @@ import (
|
|||||||
type CommandFilterApi struct{}
|
type CommandFilterApi struct{}
|
||||||
|
|
||||||
func (api CommandFilterApi) AllEndpoint(c echo.Context) error {
|
func (api CommandFilterApi) AllEndpoint(c echo.Context) error {
|
||||||
return Success(c, []interface{}{})
|
items, err := repository.CommandFilterRepository.FindAll(context.TODO())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Success(c, items)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api CommandFilterApi) PagingEndpoint(c echo.Context) error {
|
func (api CommandFilterApi) PagingEndpoint(c echo.Context) error {
|
||||||
|
pageIndex, _ := strconv.Atoi(c.QueryParam("pageIndex"))
|
||||||
|
pageSize, _ := strconv.Atoi(c.QueryParam("pageSize"))
|
||||||
|
name := c.QueryParam("name")
|
||||||
|
order := c.QueryParam("order")
|
||||||
|
field := c.QueryParam("field")
|
||||||
|
|
||||||
|
items, total, err := repository.CommandFilterRepository.Find(context.TODO(), pageIndex, pageSize, name, order, field)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return Success(c, maps.Map{
|
return Success(c, maps.Map{
|
||||||
"items": []interface{}{},
|
"items": items,
|
||||||
"total": 0,
|
"total": total,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api CommandFilterApi) CreateEndpoint(c echo.Context) error {
|
func (api CommandFilterApi) CreateEndpoint(c echo.Context) error {
|
||||||
var item map[string]interface{}
|
var item model.CommandFilter
|
||||||
if err := c.Bind(&item); err != nil {
|
if err := c.Bind(&item); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
item["id"] = utils.LongUUID()
|
item.ID = utils.UUID()
|
||||||
|
|
||||||
|
if err := repository.CommandFilterRepository.Create(context.TODO(), &item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return Success(c, item)
|
return Success(c, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api CommandFilterApi) UpdateEndpoint(c echo.Context) error {
|
func (api CommandFilterApi) UpdateEndpoint(c echo.Context) error {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
var item map[string]interface{}
|
var item model.CommandFilter
|
||||||
if err := c.Bind(&item); err != nil {
|
if err := c.Bind(&item); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
item["id"] = id
|
item.ID = id
|
||||||
|
|
||||||
|
if err := repository.CommandFilterRepository.UpdateById(context.TODO(), &item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return Success(c, item)
|
return Success(c, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api CommandFilterApi) DeleteEndpoint(c echo.Context) error {
|
func (api CommandFilterApi) DeleteEndpoint(c echo.Context) error {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
_ = id
|
if err := repository.CommandFilterRepository.DeleteById(context.TODO(), id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api CommandFilterApi) GetEndpoint(c echo.Context) error {
|
func (api CommandFilterApi) GetEndpoint(c echo.Context) error {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
_ = id
|
item, err := repository.CommandFilterRepository.FindById(context.TODO(), id)
|
||||||
return Success(c, maps.Map{
|
if err != nil {
|
||||||
"id": id,
|
return err
|
||||||
"name": "Default Filter",
|
}
|
||||||
"createdAt": 1700000000000,
|
return Success(c, item)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api CommandFilterApi) BindEndpoint(c echo.Context) error {
|
func (api CommandFilterApi) BindEndpoint(c echo.Context) error {
|
||||||
id := c.Param("id")
|
|
||||||
_ = id
|
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api CommandFilterApi) UnbindEndpoint(c echo.Context) error {
|
func (api CommandFilterApi) UnbindEndpoint(c echo.Context) error {
|
||||||
id := c.Param("id")
|
|
||||||
_ = id
|
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CommandFilterRuleApi struct{}
|
||||||
|
|
||||||
|
func (api CommandFilterRuleApi) AllEndpoint(c echo.Context) error {
|
||||||
|
commandFilterId := c.QueryParam("commandFilterId")
|
||||||
|
items, err := repository.CommandFilterRuleRepository.FindByCommandFilterId(context.TODO(), commandFilterId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Success(c, items)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api CommandFilterRuleApi) PagingEndpoint(c echo.Context) error {
|
||||||
|
commandFilterId := c.QueryParam("commandFilterId")
|
||||||
|
items, err := repository.CommandFilterRuleRepository.FindByCommandFilterId(context.TODO(), commandFilterId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Success(c, maps.Map{
|
||||||
|
"items": items,
|
||||||
|
"total": len(items),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api CommandFilterRuleApi) CreateEndpoint(c echo.Context) error {
|
||||||
|
var item model.CommandFilterRule
|
||||||
|
if err := c.Bind(&item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
item.ID = utils.UUID()
|
||||||
|
|
||||||
|
if err := repository.CommandFilterRuleRepository.Create(context.TODO(), &item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success(c, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api CommandFilterRuleApi) UpdateEndpoint(c echo.Context) error {
|
||||||
|
id := c.Param("id")
|
||||||
|
var item model.CommandFilterRule
|
||||||
|
if err := c.Bind(&item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
item.ID = id
|
||||||
|
|
||||||
|
if err := repository.CommandFilterRuleRepository.UpdateById(context.TODO(), &item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success(c, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api CommandFilterRuleApi) DeleteEndpoint(c echo.Context) error {
|
||||||
|
id := c.Param("id")
|
||||||
|
if err := repository.CommandFilterRuleRepository.DeleteById(context.TODO(), id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Success(c, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api CommandFilterRuleApi) GetEndpoint(c echo.Context) error {
|
||||||
|
id := c.Param("id")
|
||||||
|
item, err := repository.CommandFilterRuleRepository.FindById(context.TODO(), id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Success(c, item)
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ func (api DashboardApi) GetTimeCounterEndpoint(c echo.Context) error {
|
|||||||
totalAsset int64
|
totalAsset int64
|
||||||
activeAsset int64
|
activeAsset int64
|
||||||
failLoginCount int64
|
failLoginCount int64
|
||||||
|
totalWebsite int64
|
||||||
)
|
)
|
||||||
|
|
||||||
totalUser, _ = repository.UserRepository.Count(context.TODO())
|
totalUser, _ = repository.UserRepository.Count(context.TODO())
|
||||||
@@ -29,6 +30,7 @@ func (api DashboardApi) GetTimeCounterEndpoint(c echo.Context) error {
|
|||||||
failLoginCount, _ = repository.LoginLogRepository.CountByState(context.TODO(), "0")
|
failLoginCount, _ = repository.LoginLogRepository.CountByState(context.TODO(), "0")
|
||||||
gatewayList, _ := repository.GatewayRepository.FindAll(context.TODO())
|
gatewayList, _ := repository.GatewayRepository.FindAll(context.TODO())
|
||||||
gatewayActiveCount := int64(len(gatewayList))
|
gatewayActiveCount := int64(len(gatewayList))
|
||||||
|
totalWebsite, _ = repository.WebsiteRepository.Count(context.TODO())
|
||||||
|
|
||||||
counter := map[string]interface{}{
|
counter := map[string]interface{}{
|
||||||
"loginFailedTimes": failLoginCount,
|
"loginFailedTimes": failLoginCount,
|
||||||
@@ -39,7 +41,7 @@ func (api DashboardApi) GetTimeCounterEndpoint(c echo.Context) error {
|
|||||||
"assetActiveCount": activeAsset,
|
"assetActiveCount": activeAsset,
|
||||||
"assetTotalCount": totalAsset,
|
"assetTotalCount": totalAsset,
|
||||||
"websiteActiveCount": 0,
|
"websiteActiveCount": 0,
|
||||||
"websiteTotalCount": 0,
|
"websiteTotalCount": totalWebsite,
|
||||||
"gatewayActiveCount": gatewayActiveCount,
|
"gatewayActiveCount": gatewayActiveCount,
|
||||||
"gatewayTotalCount": gatewayActiveCount,
|
"gatewayTotalCount": gatewayActiveCount,
|
||||||
}
|
}
|
||||||
|
|||||||
+131
-28
@@ -1,7 +1,14 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"next-terminal/server/common"
|
||||||
"next-terminal/server/common/maps"
|
"next-terminal/server/common/maps"
|
||||||
|
"next-terminal/server/model"
|
||||||
|
"next-terminal/server/repository"
|
||||||
"next-terminal/server/utils"
|
"next-terminal/server/utils"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
@@ -10,65 +17,161 @@ import (
|
|||||||
type DatabaseAssetApi struct{}
|
type DatabaseAssetApi struct{}
|
||||||
|
|
||||||
func (api DatabaseAssetApi) AllEndpoint(c echo.Context) error {
|
func (api DatabaseAssetApi) AllEndpoint(c echo.Context) error {
|
||||||
return Success(c, []interface{}{})
|
dbType := c.QueryParam("type")
|
||||||
|
items, err := repository.DatabaseAssetRepository.FindByType(context.TODO(), dbType)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Success(c, items)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api DatabaseAssetApi) PagingEndpoint(c echo.Context) error {
|
func (api DatabaseAssetApi) PagingEndpoint(c echo.Context) error {
|
||||||
|
pageIndex, _ := strconv.Atoi(c.QueryParam("pageIndex"))
|
||||||
|
pageSize, _ := strconv.Atoi(c.QueryParam("pageSize"))
|
||||||
|
name := c.QueryParam("keyword")
|
||||||
|
dbType := c.QueryParam("type")
|
||||||
|
order := c.QueryParam("order")
|
||||||
|
field := c.QueryParam("field")
|
||||||
|
|
||||||
|
items, total, err := repository.DatabaseAssetRepository.Find(context.TODO(), pageIndex, pageSize, name, dbType, order, field)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return Success(c, maps.Map{
|
return Success(c, maps.Map{
|
||||||
"items": []interface{}{},
|
"items": items,
|
||||||
"total": 0,
|
"total": total,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api DatabaseAssetApi) CreateEndpoint(c echo.Context) error {
|
func (api DatabaseAssetApi) CreateEndpoint(c echo.Context) error {
|
||||||
var item map[string]interface{}
|
var req struct {
|
||||||
if err := c.Bind(&item); err != nil {
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Host string `json:"host"`
|
||||||
|
Port int `json:"port"`
|
||||||
|
Database string `json:"database"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
GatewayType string `json:"gatewayType"`
|
||||||
|
GatewayId string `json:"gatewayId"`
|
||||||
|
Tags []string `json:"tags"`
|
||||||
|
}
|
||||||
|
if err := c.Bind(&req); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
item["id"] = utils.LongUUID()
|
|
||||||
|
account, _ := GetCurrentAccount(c)
|
||||||
|
|
||||||
|
item := &model.DatabaseAsset{
|
||||||
|
ID: utils.UUID(),
|
||||||
|
Name: req.Name,
|
||||||
|
Type: req.Type,
|
||||||
|
Host: req.Host,
|
||||||
|
Port: req.Port,
|
||||||
|
Database: req.Database,
|
||||||
|
Username: req.Username,
|
||||||
|
Password: req.Password,
|
||||||
|
Description: req.Description,
|
||||||
|
GatewayType: req.GatewayType,
|
||||||
|
GatewayId: req.GatewayId,
|
||||||
|
Tags: strings.Join(req.Tags, ","),
|
||||||
|
Owner: account.ID,
|
||||||
|
Created: common.NowJsonTime(),
|
||||||
|
Updated: common.NowJsonTime(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if item.Port == 0 {
|
||||||
|
item.Port = repository.DatabaseAssetRepository.GetDBPort(item.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := repository.DatabaseAssetRepository.Create(context.TODO(), item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return Success(c, item)
|
return Success(c, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api DatabaseAssetApi) UpdateEndpoint(c echo.Context) error {
|
func (api DatabaseAssetApi) UpdateEndpoint(c echo.Context) error {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
var item map[string]interface{}
|
var req struct {
|
||||||
if err := c.Bind(&item); err != nil {
|
Name string `json:"name"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Host string `json:"host"`
|
||||||
|
Port int `json:"port"`
|
||||||
|
Database string `json:"database"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
GatewayType string `json:"gatewayType"`
|
||||||
|
GatewayId string `json:"gatewayId"`
|
||||||
|
Tags []string `json:"tags"`
|
||||||
|
}
|
||||||
|
if err := c.Bind(&req); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
item["id"] = id
|
|
||||||
return Success(c, item)
|
existing, err := repository.DatabaseAssetRepository.FindById(context.TODO(), id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
existing.Name = req.Name
|
||||||
|
existing.Type = req.Type
|
||||||
|
existing.Host = req.Host
|
||||||
|
existing.Port = req.Port
|
||||||
|
existing.Database = req.Database
|
||||||
|
existing.Username = req.Username
|
||||||
|
if req.Password != "" {
|
||||||
|
existing.Password = req.Password
|
||||||
|
}
|
||||||
|
existing.Description = req.Description
|
||||||
|
existing.GatewayType = req.GatewayType
|
||||||
|
existing.GatewayId = req.GatewayId
|
||||||
|
existing.Tags = strings.Join(req.Tags, ",")
|
||||||
|
existing.Updated = common.NowJsonTime()
|
||||||
|
|
||||||
|
if err := repository.DatabaseAssetRepository.UpdateById(context.TODO(), &existing); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success(c, existing)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api DatabaseAssetApi) DeleteEndpoint(c echo.Context) error {
|
func (api DatabaseAssetApi) DeleteEndpoint(c echo.Context) error {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
_ = id
|
if err := repository.DatabaseAssetRepository.DeleteById(context.TODO(), id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api DatabaseAssetApi) GetEndpoint(c echo.Context) error {
|
func (api DatabaseAssetApi) GetEndpoint(c echo.Context) error {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
_ = id
|
item, err := repository.DatabaseAssetRepository.FindById(context.TODO(), id)
|
||||||
return Success(c, maps.Map{
|
if err != nil {
|
||||||
"id": id,
|
return err
|
||||||
"name": "MySQL Server",
|
}
|
||||||
"type": "mysql",
|
return Success(c, item)
|
||||||
"host": "localhost",
|
|
||||||
"port": 3306,
|
|
||||||
"database": "test_db",
|
|
||||||
"username": "root",
|
|
||||||
"description": "Test database",
|
|
||||||
"status": "active",
|
|
||||||
"statusText": "Active",
|
|
||||||
"createdAt": 1700000000000,
|
|
||||||
"updatedAt": 1700000000000,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api DatabaseAssetApi) DecryptEndpoint(c echo.Context) error {
|
func (api DatabaseAssetApi) DecryptEndpoint(c echo.Context) error {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
_ = id
|
item, err := repository.DatabaseAssetRepository.FindById(context.TODO(), id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return Success(c, maps.Map{
|
return Success(c, maps.Map{
|
||||||
"id": id,
|
"id": id,
|
||||||
"password": "decrypted_password",
|
"password": item.Password,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (api DatabaseAssetApi) TagsEndpoint(c echo.Context) error {
|
||||||
|
tags, err := repository.DatabaseAssetRepository.FindAllTags(context.TODO())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Success(c, tags)
|
||||||
|
}
|
||||||
|
|||||||
+103
-25
@@ -1,7 +1,12 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"next-terminal/server/common/maps"
|
"next-terminal/server/common/maps"
|
||||||
|
"next-terminal/server/model"
|
||||||
|
"next-terminal/server/repository"
|
||||||
"next-terminal/server/utils"
|
"next-terminal/server/utils"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
@@ -10,77 +15,150 @@ import (
|
|||||||
type DepartmentApi struct{}
|
type DepartmentApi struct{}
|
||||||
|
|
||||||
func (api DepartmentApi) AllEndpoint(c echo.Context) error {
|
func (api DepartmentApi) AllEndpoint(c echo.Context) error {
|
||||||
return Success(c, []interface{}{})
|
items, err := repository.DepartmentRepository.FindAll(context.TODO())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Success(c, items)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api DepartmentApi) PagingEndpoint(c echo.Context) error {
|
func (api DepartmentApi) PagingEndpoint(c echo.Context) error {
|
||||||
|
pageIndex, _ := strconv.Atoi(c.QueryParam("pageIndex"))
|
||||||
|
pageSize, _ := strconv.Atoi(c.QueryParam("pageSize"))
|
||||||
|
name := c.QueryParam("keyword")
|
||||||
|
order := c.QueryParam("order")
|
||||||
|
field := c.QueryParam("field")
|
||||||
|
|
||||||
|
items, total, err := repository.DepartmentRepository.Find(context.TODO(), pageIndex, pageSize, name, order, field)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
departmentMap := make(map[string]model.Department)
|
||||||
|
allDepts, _ := repository.DepartmentRepository.FindAll(context.TODO())
|
||||||
|
for _, dept := range allDepts {
|
||||||
|
departmentMap[dept.ID] = dept
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range items {
|
||||||
|
if items[i].ParentId != "" {
|
||||||
|
if parent, ok := departmentMap[items[i].ParentId]; ok {
|
||||||
|
items[i].ParentName = parent.Name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
userCount, _ := repository.UserDepartmentRepository.CountByDepartmentId(context.TODO(), items[i].ID)
|
||||||
|
items[i].UserCount = userCount
|
||||||
|
}
|
||||||
|
|
||||||
return Success(c, maps.Map{
|
return Success(c, maps.Map{
|
||||||
"items": []interface{}{},
|
"items": items,
|
||||||
"total": 0,
|
"total": total,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api DepartmentApi) CreateEndpoint(c echo.Context) error {
|
func (api DepartmentApi) CreateEndpoint(c echo.Context) error {
|
||||||
var item map[string]interface{}
|
var item model.Department
|
||||||
if err := c.Bind(&item); err != nil {
|
if err := c.Bind(&item); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
item["id"] = utils.LongUUID()
|
item.ID = utils.UUID()
|
||||||
|
|
||||||
|
if err := repository.DepartmentRepository.Create(context.TODO(), &item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return Success(c, item)
|
return Success(c, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api DepartmentApi) UpdateEndpoint(c echo.Context) error {
|
func (api DepartmentApi) UpdateEndpoint(c echo.Context) error {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
var item map[string]interface{}
|
var item model.Department
|
||||||
if err := c.Bind(&item); err != nil {
|
if err := c.Bind(&item); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
item["id"] = id
|
item.ID = id
|
||||||
|
|
||||||
|
if err := repository.DepartmentRepository.UpdateById(context.TODO(), &item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return Success(c, item)
|
return Success(c, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api DepartmentApi) DeleteEndpoint(c echo.Context) error {
|
func (api DepartmentApi) DeleteEndpoint(c echo.Context) error {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
_ = id
|
|
||||||
|
count, err := repository.DepartmentRepository.CountByParentId(context.TODO(), id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if count > 0 {
|
||||||
|
return Fail(c, -1, "该部门下存在子部门,无法删除")
|
||||||
|
}
|
||||||
|
|
||||||
|
userCount, err := repository.UserDepartmentRepository.CountByDepartmentId(context.TODO(), id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if userCount > 0 {
|
||||||
|
return Fail(c, -1, "该部门下存在用户,无法删除")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := repository.DepartmentRepository.DeleteById(context.TODO(), id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api DepartmentApi) GetEndpoint(c echo.Context) error {
|
func (api DepartmentApi) GetEndpoint(c echo.Context) error {
|
||||||
id := c.Param("id")
|
id := c.Param("id")
|
||||||
_ = id
|
item, err := repository.DepartmentRepository.FindById(context.TODO(), id)
|
||||||
return Success(c, maps.Map{
|
if err != nil {
|
||||||
"id": id,
|
return err
|
||||||
"name": "Default",
|
}
|
||||||
"parentId": "",
|
return Success(c, item)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api DepartmentApi) GetTreeEndpoint(c echo.Context) error {
|
func (api DepartmentApi) GetTreeEndpoint(c echo.Context) error {
|
||||||
tree := []map[string]interface{}{
|
departments, err := repository.DepartmentRepository.FindAll(context.TODO())
|
||||||
{
|
if err != nil {
|
||||||
"title": "Default",
|
return err
|
||||||
"key": "default",
|
|
||||||
"value": "default",
|
|
||||||
"children": []interface{}{},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
tree := repository.DepartmentRepository.BuildTree(departments)
|
||||||
return Success(c, tree)
|
return Success(c, tree)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api DepartmentApi) GetDepartmentUsersEndpoint(c echo.Context) error {
|
func (api DepartmentApi) GetDepartmentUsersEndpoint(c echo.Context) error {
|
||||||
departmentId := c.Param("id")
|
departmentId := c.Param("id")
|
||||||
_ = departmentId
|
users, err := repository.UserDepartmentRepository.FindUsersByDepartmentId(context.TODO(), departmentId)
|
||||||
return Success(c, []string{})
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Success(c, users)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api DepartmentApi) SetDepartmentUsersEndpoint(c echo.Context) error {
|
func (api DepartmentApi) SetDepartmentUsersEndpoint(c echo.Context) error {
|
||||||
departmentId := c.Param("id")
|
departmentId := c.Param("id")
|
||||||
_ = departmentId
|
var userIds []string
|
||||||
|
if err := c.Bind(&userIds); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := repository.UserDepartmentRepository.SaveDepartmentUsers(context.TODO(), departmentId, userIds); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api DepartmentApi) RemoveUsersFromDepartmentEndpoint(c echo.Context) error {
|
func (api DepartmentApi) RemoveUsersFromDepartmentEndpoint(c echo.Context) error {
|
||||||
departmentId := c.Param("id")
|
departmentId := c.Param("id")
|
||||||
_ = departmentId
|
var userIds []string
|
||||||
|
if err := c.Bind(&userIds); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := repository.UserDepartmentRepository.RemoveUsersFromDepartment(context.TODO(), departmentId, userIds); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"next-terminal/server/common"
|
||||||
"next-terminal/server/common/maps"
|
"next-terminal/server/common/maps"
|
||||||
"next-terminal/server/model"
|
"next-terminal/server/model"
|
||||||
"next-terminal/server/repository"
|
"next-terminal/server/repository"
|
||||||
@@ -43,6 +44,8 @@ func (api GatewayGroupApi) CreateEndpoint(c echo.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
item.ID = utils.UUID()
|
item.ID = utils.UUID()
|
||||||
|
item.Created = common.NowJsonTime()
|
||||||
|
item.Updated = common.NowJsonTime()
|
||||||
|
|
||||||
if err := repository.GatewayGroupRepository.Create(context.TODO(), &item); err != nil {
|
if err := repository.GatewayGroupRepository.Create(context.TODO(), &item); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -56,6 +59,7 @@ func (api GatewayGroupApi) UpdateEndpoint(c echo.Context) error {
|
|||||||
if err := c.Bind(&item); err != nil {
|
if err := c.Bind(&item); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
item.Updated = common.NowJsonTime()
|
||||||
if err := repository.GatewayGroupRepository.UpdateById(context.TODO(), &item, id); err != nil {
|
if err := repository.GatewayGroupRepository.UpdateById(context.TODO(), &item, id); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ func (api LoginPolicyApi) GetUserPageEndpoint(c echo.Context) error {
|
|||||||
order := c.QueryParam("order")
|
order := c.QueryParam("order")
|
||||||
field := c.QueryParam("field")
|
field := c.QueryParam("field")
|
||||||
|
|
||||||
items, total, err := repository.UserRepository.Find(context.TODO(), pageIndex, pageSize, username, nickname, mail, "", id, order, field)
|
items, total, err := repository.UserRepository.Find(context.TODO(), pageIndex, pageSize, username, nickname, mail, "", "", id, order, field)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -5,10 +5,10 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"next-terminal/server/model"
|
|
||||||
"next-terminal/server/repository"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
"next-terminal/server/model"
|
||||||
|
"next-terminal/server/repository"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LogoApi struct{}
|
type LogoApi struct{}
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"encoding/pem"
|
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
|
"encoding/pem"
|
||||||
|
|
||||||
"next-terminal/server/repository"
|
"next-terminal/server/repository"
|
||||||
"next-terminal/server/service"
|
"next-terminal/server/service"
|
||||||
|
|||||||
@@ -0,0 +1,339 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"next-terminal/server/common"
|
||||||
|
"next-terminal/server/common/maps"
|
||||||
|
"next-terminal/server/log"
|
||||||
|
"next-terminal/server/model"
|
||||||
|
"next-terminal/server/repository"
|
||||||
|
"next-terminal/server/service"
|
||||||
|
"next-terminal/server/utils"
|
||||||
|
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/robfig/cron/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ScheduledTaskApi struct{}
|
||||||
|
|
||||||
|
type ScheduledTaskDTO struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
EntryId int `json:"entryId"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Spec string `json:"spec"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
AssetIdList []string `json:"assetIdList"`
|
||||||
|
Mode string `json:"mode"`
|
||||||
|
Script string `json:"script"`
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
CreatedAt common.JsonTime `json:"createdAt"`
|
||||||
|
UpdatedAt common.JsonTime `json:"updatedAt"`
|
||||||
|
LastExecAt *common.JsonTime `json:"lastExecAt,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type JobLogDTO struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
JobId string `json:"jobId"`
|
||||||
|
JobType string `json:"jobType"`
|
||||||
|
Results []interface{} `json:"results"`
|
||||||
|
CreatedAt common.JsonTime `json:"createdAt"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func JobLogToDTO(log model.JobLog, jobType string) JobLogDTO {
|
||||||
|
var results []interface{}
|
||||||
|
if log.Results != "" {
|
||||||
|
json.Unmarshal([]byte(log.Results), &results)
|
||||||
|
}
|
||||||
|
if results == nil {
|
||||||
|
results = []interface{}{}
|
||||||
|
}
|
||||||
|
return JobLogDTO{
|
||||||
|
ID: log.ID,
|
||||||
|
JobId: log.JobId,
|
||||||
|
JobType: jobType,
|
||||||
|
Results: results,
|
||||||
|
CreatedAt: log.Timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func JobToDTO(job model.Job) ScheduledTaskDTO {
|
||||||
|
dto := ScheduledTaskDTO{
|
||||||
|
ID: job.ID,
|
||||||
|
EntryId: job.CronJobId,
|
||||||
|
Name: job.Name,
|
||||||
|
Spec: job.Cron,
|
||||||
|
Type: job.Func,
|
||||||
|
Mode: job.Mode,
|
||||||
|
Enabled: job.Status == "enabled",
|
||||||
|
CreatedAt: job.Created,
|
||||||
|
UpdatedAt: job.Updated,
|
||||||
|
}
|
||||||
|
if job.ResourceIds != "" {
|
||||||
|
dto.AssetIdList = strings.Split(job.ResourceIds, ",")
|
||||||
|
}
|
||||||
|
if job.Metadata != "" && job.Func == "asset-exec-command" {
|
||||||
|
var metadataShell struct {
|
||||||
|
Shell string `json:"shell"`
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal([]byte(job.Metadata), &metadataShell); err == nil {
|
||||||
|
dto.Script = metadataShell.Shell
|
||||||
|
} else {
|
||||||
|
dto.Script = job.Metadata
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dto.Script = job.Metadata
|
||||||
|
}
|
||||||
|
if !job.LastExecAt.IsZero() {
|
||||||
|
dto.LastExecAt = &job.LastExecAt
|
||||||
|
}
|
||||||
|
return dto
|
||||||
|
}
|
||||||
|
|
||||||
|
func DTOToJob(dto ScheduledTaskDTO) model.Job {
|
||||||
|
status := "disabled"
|
||||||
|
if dto.Enabled {
|
||||||
|
status = "enabled"
|
||||||
|
}
|
||||||
|
metadata := dto.Script
|
||||||
|
if dto.Type == "asset-exec-command" && dto.Script != "" {
|
||||||
|
metadataJSON, _ := json.Marshal(map[string]string{"shell": dto.Script})
|
||||||
|
metadata = string(metadataJSON)
|
||||||
|
}
|
||||||
|
return model.Job{
|
||||||
|
ID: dto.ID,
|
||||||
|
CronJobId: dto.EntryId,
|
||||||
|
Name: dto.Name,
|
||||||
|
Cron: dto.Spec,
|
||||||
|
Func: dto.Type,
|
||||||
|
ResourceIds: strings.Join(dto.AssetIdList, ","),
|
||||||
|
Mode: dto.Mode,
|
||||||
|
Metadata: metadata,
|
||||||
|
Status: status,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api ScheduledTaskApi) AllEndpoint(c echo.Context) error {
|
||||||
|
items, err := repository.JobRepository.FindAll(context.TODO())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var dtos []ScheduledTaskDTO
|
||||||
|
for _, item := range items {
|
||||||
|
dtos = append(dtos, JobToDTO(item))
|
||||||
|
}
|
||||||
|
if dtos == nil {
|
||||||
|
dtos = []ScheduledTaskDTO{}
|
||||||
|
}
|
||||||
|
return Success(c, dtos)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api ScheduledTaskApi) PagingEndpoint(c echo.Context) error {
|
||||||
|
pageIndex, _ := strconv.Atoi(c.QueryParam("pageIndex"))
|
||||||
|
pageSize, _ := strconv.Atoi(c.QueryParam("pageSize"))
|
||||||
|
name := c.QueryParam("name")
|
||||||
|
status := c.QueryParam("status")
|
||||||
|
order := c.QueryParam("order")
|
||||||
|
field := c.QueryParam("field")
|
||||||
|
|
||||||
|
items, total, err := repository.JobRepository.Find(context.TODO(), pageIndex, pageSize, name, status, order, field)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var dtos []ScheduledTaskDTO
|
||||||
|
for _, item := range items {
|
||||||
|
dtos = append(dtos, JobToDTO(item))
|
||||||
|
}
|
||||||
|
if dtos == nil {
|
||||||
|
dtos = []ScheduledTaskDTO{}
|
||||||
|
}
|
||||||
|
return Success(c, maps.Map{
|
||||||
|
"total": total,
|
||||||
|
"items": dtos,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api ScheduledTaskApi) CreateEndpoint(c echo.Context) error {
|
||||||
|
var dto ScheduledTaskDTO
|
||||||
|
if err := c.Bind(&dto); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Info("Create ScheduledTask", log.Any("dto", dto))
|
||||||
|
job := DTOToJob(dto)
|
||||||
|
job.ID = utils.UUID()
|
||||||
|
job.Created = common.NowJsonTime()
|
||||||
|
job.Updated = common.NowJsonTime()
|
||||||
|
if job.Status == "" {
|
||||||
|
job.Status = "disabled"
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := repository.JobRepository.Create(context.TODO(), &job); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Success(c, job.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api ScheduledTaskApi) UpdateEndpoint(c echo.Context) error {
|
||||||
|
id := c.Param("id")
|
||||||
|
var dto ScheduledTaskDTO
|
||||||
|
if err := c.Bind(&dto); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
job := DTOToJob(dto)
|
||||||
|
job.ID = id
|
||||||
|
job.Updated = common.NowJsonTime()
|
||||||
|
if err := repository.JobRepository.UpdateById(context.TODO(), &job); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Success(c, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api ScheduledTaskApi) DeleteEndpoint(c echo.Context) error {
|
||||||
|
id := c.Param("id")
|
||||||
|
if err := repository.JobRepository.DeleteJobById(context.TODO(), id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Success(c, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api ScheduledTaskApi) GetEndpoint(c echo.Context) error {
|
||||||
|
id := c.Param("id")
|
||||||
|
item, err := repository.JobRepository.FindById(context.TODO(), id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
dto := JobToDTO(item)
|
||||||
|
log.Info("Get ScheduledTask", log.Any("dto", dto))
|
||||||
|
return Success(c, dto)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api ScheduledTaskApi) ChangeStatusEndpoint(c echo.Context) error {
|
||||||
|
id := c.Param("id")
|
||||||
|
enabled := c.QueryParam("enabled") == "true"
|
||||||
|
var status string
|
||||||
|
if enabled {
|
||||||
|
status = "enabled"
|
||||||
|
} else {
|
||||||
|
status = "disabled"
|
||||||
|
}
|
||||||
|
job := model.Job{
|
||||||
|
ID: id,
|
||||||
|
Status: status,
|
||||||
|
}
|
||||||
|
if err := repository.JobRepository.UpdateById(context.TODO(), &job); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Success(c, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api ScheduledTaskApi) ExecEndpoint(c echo.Context) error {
|
||||||
|
id := c.Param("id")
|
||||||
|
job, err := repository.JobRepository.FindById(context.TODO(), id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
now := common.NowJsonTime()
|
||||||
|
jobUpdate := model.Job{
|
||||||
|
ID: id,
|
||||||
|
LastExecAt: now,
|
||||||
|
}
|
||||||
|
if err := repository.JobRepository.UpdateById(context.TODO(), &jobUpdate); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch job.Func {
|
||||||
|
case "asset-exec-command":
|
||||||
|
shellJob := service.ShellJob{
|
||||||
|
ID: job.ID,
|
||||||
|
Mode: job.Mode,
|
||||||
|
ResourceIds: job.ResourceIds,
|
||||||
|
Metadata: job.Metadata,
|
||||||
|
}
|
||||||
|
shellJob.Run()
|
||||||
|
default:
|
||||||
|
jobLog := &model.JobLog{
|
||||||
|
ID: utils.UUID(),
|
||||||
|
JobId: id,
|
||||||
|
Timestamp: now,
|
||||||
|
Message: "任务执行成功",
|
||||||
|
}
|
||||||
|
_ = repository.JobLogRepository.Create(context.TODO(), jobLog)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success(c, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api ScheduledTaskApi) GetLogsEndpoint(c echo.Context) error {
|
||||||
|
jobId := c.Param("id")
|
||||||
|
pageIndex, _ := strconv.Atoi(c.QueryParam("pageIndex"))
|
||||||
|
pageSize, _ := strconv.Atoi(c.QueryParam("pageSize"))
|
||||||
|
if pageIndex == 0 {
|
||||||
|
pageIndex = 1
|
||||||
|
}
|
||||||
|
if pageSize == 0 {
|
||||||
|
pageSize = 10
|
||||||
|
}
|
||||||
|
|
||||||
|
job, err := repository.JobRepository.FindById(context.TODO(), jobId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
items, total, err := repository.JobLogRepository.FindByJobId(context.TODO(), jobId, pageIndex, pageSize)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var dtos []JobLogDTO
|
||||||
|
for _, item := range items {
|
||||||
|
dtos = append(dtos, JobLogToDTO(item, job.Func))
|
||||||
|
}
|
||||||
|
if dtos == nil {
|
||||||
|
dtos = []JobLogDTO{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success(c, maps.Map{
|
||||||
|
"total": total,
|
||||||
|
"items": dtos,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api ScheduledTaskApi) DeleteLogsEndpoint(c echo.Context) error {
|
||||||
|
jobId := c.Param("id")
|
||||||
|
if err := repository.JobLogRepository.DeleteByJobId(context.TODO(), jobId); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Success(c, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api ScheduledTaskApi) NextTenRunsEndpoint(c echo.Context) error {
|
||||||
|
var req struct {
|
||||||
|
Spec string `json:"spec"`
|
||||||
|
}
|
||||||
|
if err := c.Bind(&req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var results []string
|
||||||
|
if req.Spec == "" {
|
||||||
|
return Success(c, results)
|
||||||
|
}
|
||||||
|
|
||||||
|
parser := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow)
|
||||||
|
schedule, err := parser.Parse(req.Spec)
|
||||||
|
if err != nil {
|
||||||
|
return Success(c, results)
|
||||||
|
}
|
||||||
|
|
||||||
|
now := common.NowJsonTime().Time
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
next := schedule.Next(now)
|
||||||
|
results = append(results, next.Format("2006-01-02 15:04:05"))
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success(c, results)
|
||||||
|
}
|
||||||
@@ -3,71 +3,10 @@ package api
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"next-terminal/server/common/maps"
|
"next-terminal/server/common/maps"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ScheduledTaskApi struct{}
|
|
||||||
|
|
||||||
func (api ScheduledTaskApi) AllEndpoint(c echo.Context) error {
|
|
||||||
return Success(c, []interface{}{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api ScheduledTaskApi) PagingEndpoint(c echo.Context) error {
|
|
||||||
pageIndex, _ := strconv.Atoi(c.QueryParam("pageIndex"))
|
|
||||||
pageSize, _ := strconv.Atoi(c.QueryParam("pageSize"))
|
|
||||||
if pageIndex == 0 {
|
|
||||||
pageIndex = 1
|
|
||||||
}
|
|
||||||
if pageSize == 0 {
|
|
||||||
pageSize = 10
|
|
||||||
}
|
|
||||||
return Success(c, maps.Map{
|
|
||||||
"total": 0,
|
|
||||||
"items": []interface{}{},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api ScheduledTaskApi) CreateEndpoint(c echo.Context) error {
|
|
||||||
return Success(c, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api ScheduledTaskApi) UpdateEndpoint(c echo.Context) error {
|
|
||||||
return Success(c, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api ScheduledTaskApi) DeleteEndpoint(c echo.Context) error {
|
|
||||||
return Success(c, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api ScheduledTaskApi) GetEndpoint(c echo.Context) error {
|
|
||||||
return Success(c, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api ScheduledTaskApi) ChangeStatusEndpoint(c echo.Context) error {
|
|
||||||
return Success(c, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api ScheduledTaskApi) ExecEndpoint(c echo.Context) error {
|
|
||||||
return Success(c, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api ScheduledTaskApi) GetLogsEndpoint(c echo.Context) error {
|
|
||||||
return Success(c, maps.Map{
|
|
||||||
"total": 0,
|
|
||||||
"items": []interface{}{},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api ScheduledTaskApi) DeleteLogsEndpoint(c echo.Context) error {
|
|
||||||
return Success(c, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api ScheduledTaskApi) NextTenRunsEndpoint(c echo.Context) error {
|
|
||||||
return Success(c, []string{})
|
|
||||||
}
|
|
||||||
|
|
||||||
type SessionCommandApi struct{}
|
type SessionCommandApi struct{}
|
||||||
|
|
||||||
func (api SessionCommandApi) AllEndpoint(c echo.Context) error {
|
func (api SessionCommandApi) AllEndpoint(c echo.Context) error {
|
||||||
@@ -186,35 +125,6 @@ func (api FilesystemLogApi) ClearEndpoint(c echo.Context) error {
|
|||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
type CommandFilterRuleApi struct{}
|
|
||||||
|
|
||||||
func (api CommandFilterRuleApi) AllEndpoint(c echo.Context) error {
|
|
||||||
return Success(c, []interface{}{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api CommandFilterRuleApi) PagingEndpoint(c echo.Context) error {
|
|
||||||
return Success(c, maps.Map{
|
|
||||||
"total": 0,
|
|
||||||
"items": []interface{}{},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api CommandFilterRuleApi) CreateEndpoint(c echo.Context) error {
|
|
||||||
return Success(c, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api CommandFilterRuleApi) UpdateEndpoint(c echo.Context) error {
|
|
||||||
return Success(c, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api CommandFilterRuleApi) DeleteEndpoint(c echo.Context) error {
|
|
||||||
return Success(c, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api CommandFilterRuleApi) GetEndpoint(c echo.Context) error {
|
|
||||||
return Success(c, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
type AgentGatewayTokenApi struct{}
|
type AgentGatewayTokenApi struct{}
|
||||||
|
|
||||||
func (api AgentGatewayTokenApi) AllEndpoint(c echo.Context) error {
|
func (api AgentGatewayTokenApi) AllEndpoint(c echo.Context) error {
|
||||||
|
|||||||
+424
-12
@@ -1,7 +1,13 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"next-terminal/server/common/maps"
|
"next-terminal/server/common/maps"
|
||||||
|
"next-terminal/server/model"
|
||||||
|
"next-terminal/server/repository"
|
||||||
|
"next-terminal/server/utils"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
@@ -9,87 +15,493 @@ import (
|
|||||||
type AuthorisedAssetApi struct{}
|
type AuthorisedAssetApi struct{}
|
||||||
|
|
||||||
func (api AuthorisedAssetApi) PagingEndpoint(c echo.Context) error {
|
func (api AuthorisedAssetApi) PagingEndpoint(c echo.Context) error {
|
||||||
|
pageIndex, _ := strconv.Atoi(c.QueryParam("pageIndex"))
|
||||||
|
pageSize, _ := strconv.Atoi(c.QueryParam("pageSize"))
|
||||||
|
userId := c.QueryParam("userId")
|
||||||
|
departmentId := c.QueryParam("departmentId")
|
||||||
|
assetGroupId := c.QueryParam("assetGroupId")
|
||||||
|
assetId := c.QueryParam("assetId")
|
||||||
|
|
||||||
|
items, total, err := repository.AuthorisedAssetRepository.FindWithDetails(context.TODO(), pageIndex, pageSize, userId, departmentId, assetGroupId, assetId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if items == nil {
|
||||||
|
items = []map[string]interface{}{}
|
||||||
|
}
|
||||||
|
|
||||||
return Success(c, maps.Map{
|
return Success(c, maps.Map{
|
||||||
"total": 0,
|
"total": total,
|
||||||
"items": []interface{}{},
|
"items": items,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api AuthorisedAssetApi) AuthorisedAssetsEndpoint(c echo.Context) error {
|
func (api AuthorisedAssetApi) AuthorisedAssetsEndpoint(c echo.Context) error {
|
||||||
|
var req struct {
|
||||||
|
UserIds []string `json:"userIds"`
|
||||||
|
DepartmentIds []string `json:"departmentIds"`
|
||||||
|
AssetIds []string `json:"assetIds"`
|
||||||
|
AssetGroupIds []string `json:"assetGroupIds"`
|
||||||
|
CommandFilterId string `json:"commandFilterId"`
|
||||||
|
StrategyId string `json:"strategyId"`
|
||||||
|
ExpiredAt int64 `json:"expiredAt"`
|
||||||
|
}
|
||||||
|
if err := c.Bind(&req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var items []model.AuthorisedAsset
|
||||||
|
for _, userId := range req.UserIds {
|
||||||
|
for _, assetId := range req.AssetIds {
|
||||||
|
items = append(items, model.AuthorisedAsset{
|
||||||
|
ID: utils.UUID(),
|
||||||
|
UserId: userId,
|
||||||
|
AssetId: assetId,
|
||||||
|
CommandFilterId: req.CommandFilterId,
|
||||||
|
StrategyId: req.StrategyId,
|
||||||
|
ExpiredAt: req.ExpiredAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
for _, assetGroupId := range req.AssetGroupIds {
|
||||||
|
items = append(items, model.AuthorisedAsset{
|
||||||
|
ID: utils.UUID(),
|
||||||
|
UserId: userId,
|
||||||
|
AssetGroupId: assetGroupId,
|
||||||
|
CommandFilterId: req.CommandFilterId,
|
||||||
|
StrategyId: req.StrategyId,
|
||||||
|
ExpiredAt: req.ExpiredAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, departmentId := range req.DepartmentIds {
|
||||||
|
for _, assetId := range req.AssetIds {
|
||||||
|
items = append(items, model.AuthorisedAsset{
|
||||||
|
ID: utils.UUID(),
|
||||||
|
DepartmentId: departmentId,
|
||||||
|
AssetId: assetId,
|
||||||
|
CommandFilterId: req.CommandFilterId,
|
||||||
|
StrategyId: req.StrategyId,
|
||||||
|
ExpiredAt: req.ExpiredAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
for _, assetGroupId := range req.AssetGroupIds {
|
||||||
|
items = append(items, model.AuthorisedAsset{
|
||||||
|
ID: utils.UUID(),
|
||||||
|
DepartmentId: departmentId,
|
||||||
|
AssetGroupId: assetGroupId,
|
||||||
|
CommandFilterId: req.CommandFilterId,
|
||||||
|
StrategyId: req.StrategyId,
|
||||||
|
ExpiredAt: req.ExpiredAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(items) > 0 {
|
||||||
|
if err := repository.AuthorisedAssetRepository.CreateInBatches(context.TODO(), items); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api AuthorisedAssetApi) AuthorisedUsersEndpoint(c echo.Context) error {
|
func (api AuthorisedAssetApi) AuthorisedUsersEndpoint(c echo.Context) error {
|
||||||
|
var req struct {
|
||||||
|
AssetIds []string `json:"assetIds"`
|
||||||
|
AssetGroupIds []string `json:"assetGroupIds"`
|
||||||
|
UserIds []string `json:"userIds"`
|
||||||
|
CommandFilterId string `json:"commandFilterId"`
|
||||||
|
StrategyId string `json:"strategyId"`
|
||||||
|
ExpiredAt int64 `json:"expiredAt"`
|
||||||
|
}
|
||||||
|
if err := c.Bind(&req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var items []model.AuthorisedAsset
|
||||||
|
for _, userId := range req.UserIds {
|
||||||
|
for _, assetId := range req.AssetIds {
|
||||||
|
items = append(items, model.AuthorisedAsset{
|
||||||
|
ID: utils.UUID(),
|
||||||
|
UserId: userId,
|
||||||
|
AssetId: assetId,
|
||||||
|
CommandFilterId: req.CommandFilterId,
|
||||||
|
StrategyId: req.StrategyId,
|
||||||
|
ExpiredAt: req.ExpiredAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
for _, assetGroupId := range req.AssetGroupIds {
|
||||||
|
items = append(items, model.AuthorisedAsset{
|
||||||
|
ID: utils.UUID(),
|
||||||
|
UserId: userId,
|
||||||
|
AssetGroupId: assetGroupId,
|
||||||
|
CommandFilterId: req.CommandFilterId,
|
||||||
|
StrategyId: req.StrategyId,
|
||||||
|
ExpiredAt: req.ExpiredAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(items) > 0 {
|
||||||
|
if err := repository.AuthorisedAssetRepository.CreateInBatches(context.TODO(), items); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api AuthorisedAssetApi) AuthorisedDepartmentsEndpoint(c echo.Context) error {
|
func (api AuthorisedAssetApi) AuthorisedDepartmentsEndpoint(c echo.Context) error {
|
||||||
|
var req struct {
|
||||||
|
AssetIds []string `json:"assetIds"`
|
||||||
|
AssetGroupIds []string `json:"assetGroupIds"`
|
||||||
|
DepartmentIds []string `json:"departmentIds"`
|
||||||
|
CommandFilterId string `json:"commandFilterId"`
|
||||||
|
StrategyId string `json:"strategyId"`
|
||||||
|
ExpiredAt int64 `json:"expiredAt"`
|
||||||
|
}
|
||||||
|
if err := c.Bind(&req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var items []model.AuthorisedAsset
|
||||||
|
for _, departmentId := range req.DepartmentIds {
|
||||||
|
for _, assetId := range req.AssetIds {
|
||||||
|
items = append(items, model.AuthorisedAsset{
|
||||||
|
ID: utils.UUID(),
|
||||||
|
DepartmentId: departmentId,
|
||||||
|
AssetId: assetId,
|
||||||
|
CommandFilterId: req.CommandFilterId,
|
||||||
|
StrategyId: req.StrategyId,
|
||||||
|
ExpiredAt: req.ExpiredAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
for _, assetGroupId := range req.AssetGroupIds {
|
||||||
|
items = append(items, model.AuthorisedAsset{
|
||||||
|
ID: utils.UUID(),
|
||||||
|
DepartmentId: departmentId,
|
||||||
|
AssetGroupId: assetGroupId,
|
||||||
|
CommandFilterId: req.CommandFilterId,
|
||||||
|
StrategyId: req.StrategyId,
|
||||||
|
ExpiredAt: req.ExpiredAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(items) > 0 {
|
||||||
|
if err := repository.AuthorisedAssetRepository.CreateInBatches(context.TODO(), items); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api AuthorisedAssetApi) SelectedEndpoint(c echo.Context) error {
|
func (api AuthorisedAssetApi) SelectedEndpoint(c echo.Context) error {
|
||||||
return Success(c, []string{})
|
expect := c.QueryParam("expect")
|
||||||
|
userId := c.QueryParam("userId")
|
||||||
|
departmentId := c.QueryParam("departmentId")
|
||||||
|
assetId := c.QueryParam("assetId")
|
||||||
|
|
||||||
|
result, err := repository.AuthorisedAssetRepository.Selected(context.TODO(), expect, userId, departmentId, assetId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Success(c, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api AuthorisedAssetApi) DeleteEndpoint(c echo.Context) error {
|
func (api AuthorisedAssetApi) DeleteEndpoint(c echo.Context) error {
|
||||||
|
id := c.Param("id")
|
||||||
|
if err := repository.AuthorisedAssetRepository.DeleteById(context.TODO(), id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api AuthorisedAssetApi) GetEndpoint(c echo.Context) error {
|
func (api AuthorisedAssetApi) GetEndpoint(c echo.Context) error {
|
||||||
return Success(c, nil)
|
id := c.Param("id")
|
||||||
|
item, err := repository.AuthorisedAssetRepository.FindById(context.TODO(), id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Success(c, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api AuthorisedAssetApi) UpdateEndpoint(c echo.Context) error {
|
func (api AuthorisedAssetApi) UpdateEndpoint(c echo.Context) error {
|
||||||
return Success(c, nil)
|
id := c.Param("id")
|
||||||
|
var item model.AuthorisedAsset
|
||||||
|
if err := c.Bind(&item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
item.ID = id
|
||||||
|
if err := repository.AuthorisedAssetRepository.UpdateById(context.TODO(), &item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Success(c, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api AuthorisedAssetApi) CreateEndpoint(c echo.Context) error {
|
func (api AuthorisedAssetApi) CreateEndpoint(c echo.Context) error {
|
||||||
|
var req struct {
|
||||||
|
UserIds []string `json:"userIds"`
|
||||||
|
DepartmentIds []string `json:"departmentIds"`
|
||||||
|
AssetIds []string `json:"assetIds"`
|
||||||
|
AssetGroupIds []string `json:"assetGroupIds"`
|
||||||
|
CommandFilterId string `json:"commandFilterId"`
|
||||||
|
StrategyId string `json:"strategyId"`
|
||||||
|
ExpiredAt int64 `json:"expiredAt"`
|
||||||
|
}
|
||||||
|
if err := c.Bind(&req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var items []model.AuthorisedAsset
|
||||||
|
for _, userId := range req.UserIds {
|
||||||
|
for _, assetId := range req.AssetIds {
|
||||||
|
items = append(items, model.AuthorisedAsset{
|
||||||
|
ID: utils.UUID(),
|
||||||
|
UserId: userId,
|
||||||
|
AssetId: assetId,
|
||||||
|
CommandFilterId: req.CommandFilterId,
|
||||||
|
StrategyId: req.StrategyId,
|
||||||
|
ExpiredAt: req.ExpiredAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
for _, assetGroupId := range req.AssetGroupIds {
|
||||||
|
items = append(items, model.AuthorisedAsset{
|
||||||
|
ID: utils.UUID(),
|
||||||
|
UserId: userId,
|
||||||
|
AssetGroupId: assetGroupId,
|
||||||
|
CommandFilterId: req.CommandFilterId,
|
||||||
|
StrategyId: req.StrategyId,
|
||||||
|
ExpiredAt: req.ExpiredAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, departmentId := range req.DepartmentIds {
|
||||||
|
for _, assetId := range req.AssetIds {
|
||||||
|
items = append(items, model.AuthorisedAsset{
|
||||||
|
ID: utils.UUID(),
|
||||||
|
DepartmentId: departmentId,
|
||||||
|
AssetId: assetId,
|
||||||
|
CommandFilterId: req.CommandFilterId,
|
||||||
|
StrategyId: req.StrategyId,
|
||||||
|
ExpiredAt: req.ExpiredAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
for _, assetGroupId := range req.AssetGroupIds {
|
||||||
|
items = append(items, model.AuthorisedAsset{
|
||||||
|
ID: utils.UUID(),
|
||||||
|
DepartmentId: departmentId,
|
||||||
|
AssetGroupId: assetGroupId,
|
||||||
|
CommandFilterId: req.CommandFilterId,
|
||||||
|
StrategyId: req.StrategyId,
|
||||||
|
ExpiredAt: req.ExpiredAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(items) > 0 {
|
||||||
|
if err := repository.AuthorisedAssetRepository.CreateInBatches(context.TODO(), items); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
type AuthorisedDatabaseAssetApi struct{}
|
type AuthorisedDatabaseAssetApi struct{}
|
||||||
|
|
||||||
func (api AuthorisedDatabaseAssetApi) PagingEndpoint(c echo.Context) error {
|
func (api AuthorisedDatabaseAssetApi) PagingEndpoint(c echo.Context) error {
|
||||||
|
pageIndex, _ := strconv.Atoi(c.QueryParam("pageIndex"))
|
||||||
|
pageSize, _ := strconv.Atoi(c.QueryParam("pageSize"))
|
||||||
|
userId := c.QueryParam("userId")
|
||||||
|
departmentId := c.QueryParam("departmentId")
|
||||||
|
databaseAssetId := c.QueryParam("assetId")
|
||||||
|
|
||||||
|
items, total, err := repository.AuthorisedDatabaseAssetRepository.FindWithDetails(context.TODO(), pageIndex, pageSize, userId, departmentId, databaseAssetId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if items == nil {
|
||||||
|
items = []map[string]interface{}{}
|
||||||
|
}
|
||||||
|
|
||||||
return Success(c, maps.Map{
|
return Success(c, maps.Map{
|
||||||
"total": 0,
|
"total": total,
|
||||||
"items": []interface{}{},
|
"items": items,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api AuthorisedDatabaseAssetApi) SelectedEndpoint(c echo.Context) error {
|
func (api AuthorisedDatabaseAssetApi) SelectedEndpoint(c echo.Context) error {
|
||||||
return Success(c, []string{})
|
expect := c.QueryParam("expect")
|
||||||
|
userId := c.QueryParam("userId")
|
||||||
|
departmentId := c.QueryParam("departmentId")
|
||||||
|
databaseAssetId := c.QueryParam("assetId")
|
||||||
|
|
||||||
|
result, err := repository.AuthorisedDatabaseAssetRepository.Selected(context.TODO(), expect, userId, departmentId, databaseAssetId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Success(c, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api AuthorisedDatabaseAssetApi) DeleteEndpoint(c echo.Context) error {
|
func (api AuthorisedDatabaseAssetApi) DeleteEndpoint(c echo.Context) error {
|
||||||
|
id := c.Param("id")
|
||||||
|
if err := repository.AuthorisedDatabaseAssetRepository.DeleteById(context.TODO(), id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api AuthorisedDatabaseAssetApi) GetEndpoint(c echo.Context) error {
|
func (api AuthorisedDatabaseAssetApi) GetEndpoint(c echo.Context) error {
|
||||||
return Success(c, nil)
|
id := c.Param("id")
|
||||||
|
item, err := repository.AuthorisedDatabaseAssetRepository.FindById(context.TODO(), id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Success(c, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api AuthorisedDatabaseAssetApi) UpdateEndpoint(c echo.Context) error {
|
func (api AuthorisedDatabaseAssetApi) UpdateEndpoint(c echo.Context) error {
|
||||||
return Success(c, nil)
|
id := c.Param("id")
|
||||||
|
var item model.AuthorisedDatabaseAsset
|
||||||
|
if err := c.Bind(&item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
item.ID = id
|
||||||
|
if err := repository.AuthorisedDatabaseAssetRepository.UpdateById(context.TODO(), &item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return Success(c, item)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api AuthorisedDatabaseAssetApi) CreateEndpoint(c echo.Context) error {
|
func (api AuthorisedDatabaseAssetApi) CreateEndpoint(c echo.Context) error {
|
||||||
|
var req struct {
|
||||||
|
UserIds []string `json:"userIds"`
|
||||||
|
DepartmentIds []string `json:"departmentIds"`
|
||||||
|
DatabaseAssetIds []string `json:"assetIds"`
|
||||||
|
CommandFilterId string `json:"commandFilterId"`
|
||||||
|
StrategyId string `json:"strategyId"`
|
||||||
|
ExpiredAt int64 `json:"expiredAt"`
|
||||||
|
}
|
||||||
|
if err := c.Bind(&req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var items []model.AuthorisedDatabaseAsset
|
||||||
|
for _, userId := range req.UserIds {
|
||||||
|
for _, databaseAssetId := range req.DatabaseAssetIds {
|
||||||
|
items = append(items, model.AuthorisedDatabaseAsset{
|
||||||
|
ID: utils.UUID(),
|
||||||
|
UserId: userId,
|
||||||
|
DatabaseAssetId: databaseAssetId,
|
||||||
|
CommandFilterId: req.CommandFilterId,
|
||||||
|
StrategyId: req.StrategyId,
|
||||||
|
ExpiredAt: req.ExpiredAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, departmentId := range req.DepartmentIds {
|
||||||
|
for _, databaseAssetId := range req.DatabaseAssetIds {
|
||||||
|
items = append(items, model.AuthorisedDatabaseAsset{
|
||||||
|
ID: utils.UUID(),
|
||||||
|
DepartmentId: departmentId,
|
||||||
|
DatabaseAssetId: databaseAssetId,
|
||||||
|
CommandFilterId: req.CommandFilterId,
|
||||||
|
StrategyId: req.StrategyId,
|
||||||
|
ExpiredAt: req.ExpiredAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(items) > 0 {
|
||||||
|
if err := repository.AuthorisedDatabaseAssetRepository.CreateInBatches(context.TODO(), items); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
type AuthorisedWebsiteApi struct{}
|
type AuthorisedWebsiteApi struct{}
|
||||||
|
|
||||||
func (api AuthorisedWebsiteApi) PagingEndpoint(c echo.Context) error {
|
func (api AuthorisedWebsiteApi) PagingEndpoint(c echo.Context) error {
|
||||||
|
pageIndex, _ := strconv.Atoi(c.QueryParam("pageIndex"))
|
||||||
|
pageSize, _ := strconv.Atoi(c.QueryParam("pageSize"))
|
||||||
|
userId := c.QueryParam("userId")
|
||||||
|
departmentId := c.QueryParam("departmentId")
|
||||||
|
websiteId := c.QueryParam("websiteId")
|
||||||
|
|
||||||
|
items, total, err := repository.AuthorisedWebsiteRepository.FindWithDetails(context.TODO(), pageIndex, pageSize, userId, departmentId, websiteId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if items == nil {
|
||||||
|
items = []map[string]interface{}{}
|
||||||
|
}
|
||||||
|
|
||||||
return Success(c, maps.Map{
|
return Success(c, maps.Map{
|
||||||
"total": 0,
|
"total": total,
|
||||||
"items": []interface{}{},
|
"items": items,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api AuthorisedWebsiteApi) DeleteEndpoint(c echo.Context) error {
|
func (api AuthorisedWebsiteApi) DeleteEndpoint(c echo.Context) error {
|
||||||
|
id := c.Param("id")
|
||||||
|
if err := repository.AuthorisedWebsiteRepository.DeleteById(context.TODO(), id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api AuthorisedWebsiteApi) CreateEndpoint(c echo.Context) error {
|
func (api AuthorisedWebsiteApi) CreateEndpoint(c echo.Context) error {
|
||||||
|
var req struct {
|
||||||
|
UserIds []string `json:"userIds"`
|
||||||
|
DepartmentIds []string `json:"departmentIds"`
|
||||||
|
WebsiteIds []string `json:"websiteIds"`
|
||||||
|
CommandFilterId string `json:"commandFilterId"`
|
||||||
|
StrategyId string `json:"strategyId"`
|
||||||
|
ExpiredAt int64 `json:"expiredAt"`
|
||||||
|
}
|
||||||
|
if err := c.Bind(&req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var items []model.AuthorisedWebsite
|
||||||
|
for _, userId := range req.UserIds {
|
||||||
|
for _, websiteId := range req.WebsiteIds {
|
||||||
|
items = append(items, model.AuthorisedWebsite{
|
||||||
|
ID: utils.UUID(),
|
||||||
|
UserId: userId,
|
||||||
|
WebsiteId: websiteId,
|
||||||
|
CommandFilterId: req.CommandFilterId,
|
||||||
|
StrategyId: req.StrategyId,
|
||||||
|
ExpiredAt: req.ExpiredAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, departmentId := range req.DepartmentIds {
|
||||||
|
for _, websiteId := range req.WebsiteIds {
|
||||||
|
items = append(items, model.AuthorisedWebsite{
|
||||||
|
ID: utils.UUID(),
|
||||||
|
DepartmentId: departmentId,
|
||||||
|
WebsiteId: websiteId,
|
||||||
|
CommandFilterId: req.CommandFilterId,
|
||||||
|
StrategyId: req.StrategyId,
|
||||||
|
ExpiredAt: req.ExpiredAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(items) > 0 {
|
||||||
|
if err := repository.AuthorisedWebsiteRepository.CreateInBatches(context.TODO(), items); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,161 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"os/exec"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"golang.org/x/text/encoding/simplifiedchinese"
|
||||||
|
"golang.org/x/text/transform"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ToolsApi struct{}
|
||||||
|
|
||||||
|
func (api ToolsApi) TcpingEndpoint(c echo.Context) error {
|
||||||
|
host := c.QueryParam("host")
|
||||||
|
port := c.QueryParam("port")
|
||||||
|
attemptsStr := c.QueryParam("attempts")
|
||||||
|
|
||||||
|
attempts := 4
|
||||||
|
if attemptsStr != "" {
|
||||||
|
attempts, _ = strconv.Atoi(attemptsStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Response().Header().Set("Content-Type", "text/event-stream")
|
||||||
|
c.Response().Header().Set("Cache-Control", "no-cache")
|
||||||
|
c.Response().Header().Set("Connection", "keep-alive")
|
||||||
|
|
||||||
|
flusher, ok := c.Response().Writer.(http.Flusher)
|
||||||
|
if !ok {
|
||||||
|
return echo.NewHTTPError(500, "Streaming unsupported")
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < attempts; i++ {
|
||||||
|
start := time.Now()
|
||||||
|
conn, err := net.DialTimeout("tcp", host+":"+port, 5*time.Second)
|
||||||
|
elapsed := time.Since(start)
|
||||||
|
|
||||||
|
var result string
|
||||||
|
if err != nil {
|
||||||
|
result = fmt.Sprintf("TCP ping %s:%s - Failed: %v", host, port, err)
|
||||||
|
} else {
|
||||||
|
conn.Close()
|
||||||
|
result = fmt.Sprintf("TCP ping %s:%s - Connected, time=%v", host, port, elapsed.Round(time.Millisecond))
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(c.Response(), "data: %s\n\n", result)
|
||||||
|
flusher.Flush()
|
||||||
|
|
||||||
|
if i < attempts-1 {
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(c.Response(), "event: done\ndata: completed\n\n")
|
||||||
|
flusher.Flush()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api ToolsApi) PingEndpoint(c echo.Context) error {
|
||||||
|
host := c.QueryParam("host")
|
||||||
|
attemptsStr := c.QueryParam("attempts")
|
||||||
|
|
||||||
|
attempts := 4
|
||||||
|
if attemptsStr != "" {
|
||||||
|
attempts, _ = strconv.Atoi(attemptsStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Response().Header().Set("Content-Type", "text/event-stream")
|
||||||
|
c.Response().Header().Set("Cache-Control", "no-cache")
|
||||||
|
c.Response().Header().Set("Connection", "keep-alive")
|
||||||
|
|
||||||
|
flusher, ok := c.Response().Writer.(http.Flusher)
|
||||||
|
if !ok {
|
||||||
|
return echo.NewHTTPError(500, "Streaming unsupported")
|
||||||
|
}
|
||||||
|
|
||||||
|
var cmd *exec.Cmd
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
cmd = exec.Command("ping", "-n", strconv.Itoa(attempts), host)
|
||||||
|
} else {
|
||||||
|
cmd = exec.Command("ping", "-c", strconv.Itoa(attempts), host)
|
||||||
|
}
|
||||||
|
|
||||||
|
stdout, err := cmd.StdoutPipe()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(c.Response(), "data: Error: %v\n\n", err)
|
||||||
|
flusher.Flush()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cmd.Start(); err != nil {
|
||||||
|
fmt.Fprintf(c.Response(), "data: Error: %v\n\n", err)
|
||||||
|
flusher.Flush()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var reader io.Reader = stdout
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
reader = transform.NewReader(stdout, simplifiedchinese.GBK.NewDecoder())
|
||||||
|
}
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(reader)
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
if strings.TrimSpace(line) != "" {
|
||||||
|
fmt.Fprintf(c.Response(), "data: %s\n\n", line)
|
||||||
|
flusher.Flush()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Wait()
|
||||||
|
|
||||||
|
fmt.Fprintf(c.Response(), "event: done\ndata: completed\n\n")
|
||||||
|
flusher.Flush()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api ToolsApi) TelnetEndpoint(c echo.Context) error {
|
||||||
|
host := c.QueryParam("host")
|
||||||
|
port := c.QueryParam("port")
|
||||||
|
|
||||||
|
c.Response().Header().Set("Content-Type", "text/event-stream")
|
||||||
|
c.Response().Header().Set("Cache-Control", "no-cache")
|
||||||
|
c.Response().Header().Set("Connection", "keep-alive")
|
||||||
|
|
||||||
|
flusher, ok := c.Response().Writer.(http.Flusher)
|
||||||
|
if !ok {
|
||||||
|
return echo.NewHTTPError(500, "Streaming unsupported")
|
||||||
|
}
|
||||||
|
|
||||||
|
start := time.Now()
|
||||||
|
conn, err := net.DialTimeout("tcp", host+":"+port, 10*time.Second)
|
||||||
|
elapsed := time.Since(start)
|
||||||
|
|
||||||
|
var result bytes.Buffer
|
||||||
|
if err != nil {
|
||||||
|
result.WriteString(fmt.Sprintf("Telnet %s:%s - Connection failed: %v", host, port, err))
|
||||||
|
} else {
|
||||||
|
conn.Close()
|
||||||
|
result.WriteString(fmt.Sprintf("Telnet %s:%s - Connected successfully in %v", host, port, elapsed.Round(time.Millisecond)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(c.Response(), "data: %s\n\n", result.String())
|
||||||
|
flusher.Flush()
|
||||||
|
|
||||||
|
fmt.Fprintf(c.Response(), "event: done\ndata: completed\n\n")
|
||||||
|
flusher.Flush()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
+2
-1
@@ -41,8 +41,9 @@ func (userApi UserApi) PagingEndpoint(c echo.Context) error {
|
|||||||
order := c.QueryParam("order")
|
order := c.QueryParam("order")
|
||||||
field := c.QueryParam("field")
|
field := c.QueryParam("field")
|
||||||
online := c.QueryParam("online")
|
online := c.QueryParam("online")
|
||||||
|
userType := c.QueryParam("type")
|
||||||
|
|
||||||
items, total, err := repository.UserRepository.Find(context.TODO(), pageIndex, pageSize, username, nickname, mail, online, "", order, field)
|
items, total, err := repository.UserRepository.Find(context.TODO(), pageIndex, pageSize, username, nickname, mail, online, userType, "", order, field)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
+108
-1
@@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"next-terminal/server/common"
|
||||||
"next-terminal/server/common/maps"
|
"next-terminal/server/common/maps"
|
||||||
"next-terminal/server/dto"
|
"next-terminal/server/dto"
|
||||||
"next-terminal/server/model"
|
"next-terminal/server/model"
|
||||||
@@ -152,18 +153,124 @@ func (api WebsiteApi) GetEndpoint(c echo.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (api WebsiteApi) GroupsGetEndpoint(c echo.Context) error {
|
func (api WebsiteApi) GroupsGetEndpoint(c echo.Context) error {
|
||||||
return Success(c, []interface{}{})
|
groups, err := repository.WebsiteGroupRepository.FindAll(context.TODO())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
tree := buildWebsiteGroupTree(groups, "")
|
||||||
|
return Success(c, tree)
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildWebsiteGroupTree(groups []model.WebsiteGroup, parentId string) []maps.Map {
|
||||||
|
var tree []maps.Map
|
||||||
|
for _, g := range groups {
|
||||||
|
if g.ParentId == parentId {
|
||||||
|
node := maps.Map{
|
||||||
|
"id": g.ID,
|
||||||
|
"name": g.Name,
|
||||||
|
"title": g.Name,
|
||||||
|
"key": g.ID,
|
||||||
|
"value": g.ID,
|
||||||
|
}
|
||||||
|
children := buildWebsiteGroupTree(groups, g.ID)
|
||||||
|
if len(children) > 0 {
|
||||||
|
node["children"] = children
|
||||||
|
}
|
||||||
|
tree = append(tree, node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tree
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api WebsiteApi) GroupsSetEndpoint(c echo.Context) error {
|
func (api WebsiteApi) GroupsSetEndpoint(c echo.Context) error {
|
||||||
|
var req []map[string]interface{}
|
||||||
|
if err := c.Bind(&req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ctx := context.TODO()
|
||||||
|
repository.WebsiteGroupRepository.DeleteAll(ctx)
|
||||||
|
for i, item := range req {
|
||||||
|
name := ""
|
||||||
|
if v, ok := item["name"].(string); ok {
|
||||||
|
name = v
|
||||||
|
} else if v, ok := item["title"].(string); ok {
|
||||||
|
name = v
|
||||||
|
}
|
||||||
|
group := model.WebsiteGroup{
|
||||||
|
ID: utils.UUID(),
|
||||||
|
Name: name,
|
||||||
|
ParentId: "",
|
||||||
|
Sort: i,
|
||||||
|
Created: common.NowJsonTime(),
|
||||||
|
}
|
||||||
|
repository.WebsiteGroupRepository.Create(ctx, &group)
|
||||||
|
if subChildren, ok := item["children"].([]interface{}); ok {
|
||||||
|
saveWebsiteGroupChildren(ctx, subChildren, group.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func saveWebsiteGroupChildren(ctx context.Context, children []interface{}, parentId string) {
|
||||||
|
for i, child := range children {
|
||||||
|
m, ok := child.(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
name := ""
|
||||||
|
if v, ok := m["name"].(string); ok {
|
||||||
|
name = v
|
||||||
|
} else if v, ok := m["title"].(string); ok {
|
||||||
|
name = v
|
||||||
|
}
|
||||||
|
group := model.WebsiteGroup{
|
||||||
|
ID: utils.UUID(),
|
||||||
|
Name: name,
|
||||||
|
ParentId: parentId,
|
||||||
|
Sort: i,
|
||||||
|
Created: common.NowJsonTime(),
|
||||||
|
}
|
||||||
|
repository.WebsiteGroupRepository.Create(ctx, &group)
|
||||||
|
if subChildren, ok := m["children"].([]interface{}); ok {
|
||||||
|
saveWebsiteGroupChildren(ctx, subChildren, group.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (api WebsiteApi) GroupsDeleteEndpoint(c echo.Context) error {
|
func (api WebsiteApi) GroupsDeleteEndpoint(c echo.Context) error {
|
||||||
|
id := c.Param("id")
|
||||||
|
|
||||||
|
count, err := repository.WebsiteGroupRepository.CountByParentId(context.TODO(), id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if count > 0 {
|
||||||
|
return Fail(c, -1, "该分组下存在子分组,无法删除")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := repository.WebsiteGroupRepository.DeleteById(context.TODO(), id); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api WebsiteApi) ChangeGroupEndpoint(c echo.Context) error {
|
func (api WebsiteApi) ChangeGroupEndpoint(c echo.Context) error {
|
||||||
|
var req struct {
|
||||||
|
WebsiteIds []string `json:"websiteIds"`
|
||||||
|
GroupId string `json:"groupId"`
|
||||||
|
}
|
||||||
|
if err := c.Bind(&req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, websiteId := range req.WebsiteIds {
|
||||||
|
website, err := repository.WebsiteRepository.FindById(context.TODO(), websiteId)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
website.GroupId = req.GroupId
|
||||||
|
repository.WebsiteRepository.UpdateById(context.TODO(), &website, websiteId)
|
||||||
|
}
|
||||||
return Success(c, nil)
|
return Success(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ var allowUrls = []urlpath.Path{
|
|||||||
urlpath.New("/api/portal/websites"),
|
urlpath.New("/api/portal/websites"),
|
||||||
urlpath.New("/api/portal/info"),
|
urlpath.New("/api/portal/info"),
|
||||||
urlpath.New("/api/license"),
|
urlpath.New("/api/license"),
|
||||||
|
urlpath.New("/api/admin/tools/tcping"),
|
||||||
|
urlpath.New("/api/admin/tools/ping"),
|
||||||
}
|
}
|
||||||
|
|
||||||
func Auth(next echo.HandlerFunc) echo.HandlerFunc {
|
func Auth(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ func setupRoutes() *echo.Echo {
|
|||||||
GatewayGroupApi := new(api.GatewayGroupApi)
|
GatewayGroupApi := new(api.GatewayGroupApi)
|
||||||
WebsiteApi := new(api.WebsiteApi)
|
WebsiteApi := new(api.WebsiteApi)
|
||||||
CertificateApi := new(api.CertificateApi)
|
CertificateApi := new(api.CertificateApi)
|
||||||
|
ToolsApi := new(api.ToolsApi)
|
||||||
|
|
||||||
adminGroup.GET("/login-status", setupApi.LoginStatusEndpoint)
|
adminGroup.GET("/login-status", setupApi.LoginStatusEndpoint)
|
||||||
adminGroup.POST("/validate-totp", setupApi.ValidateTOTPEndpoint)
|
adminGroup.POST("/validate-totp", setupApi.ValidateTOTPEndpoint)
|
||||||
@@ -279,6 +280,12 @@ func setupRoutes() *echo.Echo {
|
|||||||
|
|
||||||
adminGroup.GET("/tags", AssetApi.AssetTagsEndpoint)
|
adminGroup.GET("/tags", AssetApi.AssetTagsEndpoint)
|
||||||
|
|
||||||
|
tools := adminGroup.Group("/tools")
|
||||||
|
{
|
||||||
|
tools.GET("/tcping", ToolsApi.TcpingEndpoint)
|
||||||
|
tools.GET("/ping", ToolsApi.PingEndpoint)
|
||||||
|
}
|
||||||
|
|
||||||
commands := adminGroup.Group("/commands")
|
commands := adminGroup.Group("/commands")
|
||||||
{
|
{
|
||||||
commands.GET("", CommandApi.CommandAllEndpoint)
|
commands.GET("", CommandApi.CommandAllEndpoint)
|
||||||
|
|||||||
Vendored
+1
-1
@@ -55,7 +55,7 @@ func setupDB() *gorm.DB {
|
|||||||
&model.Role{}, &model.RoleMenuRef{}, &model.UserRoleRef{},
|
&model.Role{}, &model.RoleMenuRef{}, &model.UserRoleRef{},
|
||||||
&model.LoginPolicy{}, &model.LoginPolicyUserRef{}, &model.TimePeriod{},
|
&model.LoginPolicy{}, &model.LoginPolicyUserRef{}, &model.TimePeriod{},
|
||||||
&model.StorageLog{}, &model.Authorised{}, &model.Logo{}, &model.AssetGroup{},
|
&model.StorageLog{}, &model.Authorised{}, &model.Logo{}, &model.AssetGroup{},
|
||||||
&model.AgentGateway{}, &model.SshGateway{}, &model.GatewayGroup{}, &model.Website{}, &model.Certificate{}, &model.Snippet{}, &model.SessionAudit{}, &model.Department{}, &model.UserDepartmentRef{}); err != nil {
|
&model.AgentGateway{}, &model.SshGateway{}, &model.GatewayGroup{}, &model.Website{}, &model.Certificate{}, &model.Snippet{}, &model.SessionAudit{}, &model.Department{}, &model.UserDepartmentRef{}, &model.DatabaseAsset{}, &model.CommandFilter{}, &model.CommandFilterRule{}, &model.AuthorisedAsset{}, &model.AuthorisedDatabaseAsset{}, &model.AuthorisedWebsite{}, &model.WebsiteGroup{}); err != nil {
|
||||||
panic(fmt.Errorf("初始化数据库表结构异常: %v", err.Error()))
|
panic(fmt.Errorf("初始化数据库表结构异常: %v", err.Error()))
|
||||||
}
|
}
|
||||||
return db
|
return db
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import "next-terminal/server/common"
|
||||||
|
|
||||||
|
type AuthorisedAsset struct {
|
||||||
|
ID string `gorm:"primary_key,type:varchar(36)" json:"id"`
|
||||||
|
UserId string `gorm:"index,type:varchar(36)" json:"userId"`
|
||||||
|
DepartmentId string `gorm:"index,type:varchar(36)" json:"departmentId"`
|
||||||
|
AssetId string `gorm:"index,type:varchar(36)" json:"assetId"`
|
||||||
|
AssetGroupId string `gorm:"index,type:varchar(36)" json:"assetGroupId"`
|
||||||
|
CommandFilterId string `gorm:"index,type:varchar(36)" json:"commandFilterId"`
|
||||||
|
StrategyId string `gorm:"index,type:varchar(36)" json:"strategyId"`
|
||||||
|
ExpiredAt int64 `json:"expiredAt"`
|
||||||
|
Created common.JsonTime `gorm:"type:datetime" json:"createdAt"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m AuthorisedAsset) TableName() string {
|
||||||
|
return "authorised_assets"
|
||||||
|
}
|
||||||
|
|
||||||
|
type AuthorisedDatabaseAsset struct {
|
||||||
|
ID string `gorm:"primary_key,type:varchar(36)" json:"id"`
|
||||||
|
UserId string `gorm:"index,type:varchar(36)" json:"userId"`
|
||||||
|
DepartmentId string `gorm:"index,type:varchar(36)" json:"departmentId"`
|
||||||
|
DatabaseAssetId string `gorm:"index,type:varchar(36)" json:"databaseAssetId"`
|
||||||
|
CommandFilterId string `gorm:"index,type:varchar(36)" json:"commandFilterId"`
|
||||||
|
StrategyId string `gorm:"index,type:varchar(36)" json:"strategyId"`
|
||||||
|
ExpiredAt int64 `json:"expiredAt"`
|
||||||
|
Created common.JsonTime `gorm:"type:datetime" json:"createdAt"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m AuthorisedDatabaseAsset) TableName() string {
|
||||||
|
return "authorised_database_assets"
|
||||||
|
}
|
||||||
|
|
||||||
|
type AuthorisedWebsite struct {
|
||||||
|
ID string `gorm:"primary_key,type:varchar(36)" json:"id"`
|
||||||
|
UserId string `gorm:"index,type:varchar(36)" json:"userId"`
|
||||||
|
DepartmentId string `gorm:"index,type:varchar(36)" json:"departmentId"`
|
||||||
|
WebsiteId string `gorm:"index,type:varchar(36)" json:"websiteId"`
|
||||||
|
CommandFilterId string `gorm:"index,type:varchar(36)" json:"commandFilterId"`
|
||||||
|
StrategyId string `gorm:"index,type:varchar(36)" json:"strategyId"`
|
||||||
|
ExpiredAt int64 `json:"expiredAt"`
|
||||||
|
Created common.JsonTime `gorm:"type:datetime" json:"createdAt"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m AuthorisedWebsite) TableName() string {
|
||||||
|
return "authorised_websites"
|
||||||
|
}
|
||||||
@@ -7,8 +7,8 @@ type Certificate struct {
|
|||||||
CommonName string `gorm:"type:varchar(500)" json:"commonName"`
|
CommonName string `gorm:"type:varchar(500)" json:"commonName"`
|
||||||
Subject string `gorm:"type:varchar(500)" json:"subject"`
|
Subject string `gorm:"type:varchar(500)" json:"subject"`
|
||||||
Issuer string `gorm:"type:varchar(500)" json:"issuer"`
|
Issuer string `gorm:"type:varchar(500)" json:"issuer"`
|
||||||
NotBefore common.JsonTime `json:"notBefore"`
|
NotBefore common.JsonTime `gorm:"type:datetime" json:"notBefore"`
|
||||||
NotAfter common.JsonTime `json:"notAfter"`
|
NotAfter common.JsonTime `gorm:"type:datetime" json:"notAfter"`
|
||||||
Type string `gorm:"type:varchar(20);default:'imported'" json:"type"`
|
Type string `gorm:"type:varchar(20);default:'imported'" json:"type"`
|
||||||
StorageKey string `gorm:"type:varchar(100)" json:"storageKey"`
|
StorageKey string `gorm:"type:varchar(100)" json:"storageKey"`
|
||||||
Certificate string `gorm:"type:text" json:"certificate"`
|
Certificate string `gorm:"type:text" json:"certificate"`
|
||||||
@@ -16,9 +16,9 @@ type Certificate struct {
|
|||||||
RequireClientAuth bool `gorm:"default:false" json:"requireClientAuth"`
|
RequireClientAuth bool `gorm:"default:false" json:"requireClientAuth"`
|
||||||
IssuedStatus string `gorm:"type:varchar(20);default:'success'" json:"issuedStatus"`
|
IssuedStatus string `gorm:"type:varchar(20);default:'success'" json:"issuedStatus"`
|
||||||
IssuedError string `gorm:"type:text" json:"issuedError"`
|
IssuedError string `gorm:"type:text" json:"issuedError"`
|
||||||
UpdatedAt common.JsonTime `json:"updatedAt"`
|
UpdatedAt common.JsonTime `gorm:"type:datetime" json:"updatedAt"`
|
||||||
IsDefault bool `gorm:"default:false" json:"isDefault"`
|
IsDefault bool `gorm:"default:false" json:"isDefault"`
|
||||||
Created common.JsonTime `json:"createdAt"`
|
Created common.JsonTime `gorm:"type:datetime" json:"createdAt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Certificate) TableName() string {
|
func (r *Certificate) TableName() string {
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import "next-terminal/server/common"
|
||||||
|
|
||||||
|
type CommandFilter struct {
|
||||||
|
ID string `gorm:"primary_key,type:varchar(36)" json:"id"`
|
||||||
|
Name string `gorm:"type:varchar(200)" json:"name"`
|
||||||
|
Created common.JsonTime `gorm:"type:datetime" json:"createdAt"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CommandFilter) TableName() string {
|
||||||
|
return "command_filters"
|
||||||
|
}
|
||||||
|
|
||||||
|
type CommandFilterRule struct {
|
||||||
|
ID string `gorm:"primary_key,type:varchar(36)" json:"id"`
|
||||||
|
CommandFilterId string `gorm:"type:varchar(36);index" json:"commandFilterId"`
|
||||||
|
Type string `gorm:"type:varchar(20)" json:"type"`
|
||||||
|
Pattern string `gorm:"type:text" json:"pattern"`
|
||||||
|
Priority int `json:"priority"`
|
||||||
|
Action string `gorm:"type:varchar(20)" json:"action"`
|
||||||
|
Created common.JsonTime `gorm:"type:datetime" json:"createdAt"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *CommandFilterRule) TableName() string {
|
||||||
|
return "command_filter_rules"
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import "next-terminal/server/common"
|
||||||
|
|
||||||
|
type DatabaseAsset struct {
|
||||||
|
ID string `gorm:"primary_key,type:varchar(36)" json:"id"`
|
||||||
|
Name string `gorm:"type:varchar(500)" json:"name"`
|
||||||
|
Type string `gorm:"type:varchar(20)" json:"type"`
|
||||||
|
Host string `gorm:"type:varchar(200)" json:"host"`
|
||||||
|
Port int `json:"port"`
|
||||||
|
Database string `gorm:"type:varchar(200)" json:"database"`
|
||||||
|
Username string `gorm:"type:varchar(200)" json:"username"`
|
||||||
|
Password string `gorm:"type:varchar(500)" json:"password"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
GatewayType string `gorm:"type:varchar(20)" json:"gatewayType"`
|
||||||
|
GatewayId string `gorm:"type:varchar(36)" json:"gatewayId"`
|
||||||
|
Tags string `json:"tags"`
|
||||||
|
Owner string `gorm:"index,type:varchar(36)" json:"owner"`
|
||||||
|
Encrypted bool `json:"encrypted"`
|
||||||
|
Created common.JsonTime `gorm:"type:datetime" json:"createdAt"`
|
||||||
|
Updated common.JsonTime `gorm:"type:datetime" json:"updatedAt"`
|
||||||
|
Sort int `json:"sort" gorm:"default:0"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *DatabaseAsset) TableName() string {
|
||||||
|
return "database_assets"
|
||||||
|
}
|
||||||
@@ -6,8 +6,10 @@ type Department struct {
|
|||||||
ID string `gorm:"primary_key,type:varchar(36)" json:"id"`
|
ID string `gorm:"primary_key,type:varchar(36)" json:"id"`
|
||||||
Name string `gorm:"type:varchar(200)" json:"name"`
|
Name string `gorm:"type:varchar(200)" json:"name"`
|
||||||
ParentId string `gorm:"type:varchar(36)" json:"parentId"`
|
ParentId string `gorm:"type:varchar(36)" json:"parentId"`
|
||||||
Sort int `json:"sort"`
|
Sort int `json:"weight"`
|
||||||
Created common.JsonTime `json:"createdAt"`
|
ParentName string `gorm:"-" json:"parentName"`
|
||||||
|
UserCount int64 `gorm:"-" json:"userCount"`
|
||||||
|
Created common.JsonTime `gorm:"type:datetime" json:"createdAt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Department) TableName() string {
|
func (r *Department) TableName() string {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ type Job struct {
|
|||||||
Metadata string `json:"metadata"`
|
Metadata string `json:"metadata"`
|
||||||
Created common.JsonTime `json:"created"`
|
Created common.JsonTime `json:"created"`
|
||||||
Updated common.JsonTime `json:"updated"`
|
Updated common.JsonTime `json:"updated"`
|
||||||
|
LastExecAt common.JsonTime `json:"lastExecAt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Job) TableName() string {
|
func (r *Job) TableName() string {
|
||||||
@@ -27,6 +28,7 @@ type JobLog struct {
|
|||||||
Timestamp common.JsonTime `json:"timestamp"`
|
Timestamp common.JsonTime `json:"timestamp"`
|
||||||
JobId string `json:"jobId"`
|
JobId string `json:"jobId"`
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
|
Results string `json:"results"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *JobLog) TableName() string {
|
func (r *JobLog) TableName() string {
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ type UserForPage struct {
|
|||||||
Watermark string `json:"watermark"`
|
Watermark string `json:"watermark"`
|
||||||
Remark string `json:"remark"`
|
Remark string `json:"remark"`
|
||||||
SharerAssetCount int64 `json:"sharerAssetCount"`
|
SharerAssetCount int64 `json:"sharerAssetCount"`
|
||||||
Departments []UserDepartment `json:"departments"`
|
Departments []UserDepartment `gorm:"-" json:"departments"`
|
||||||
LastLoginAt *common.JsonTime `json:"lastLoginAt"`
|
LastLoginAt *common.JsonTime `json:"lastLoginAt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import "next-terminal/server/common"
|
||||||
|
|
||||||
|
type WebsiteGroup struct {
|
||||||
|
ID string `gorm:"primary_key,type:varchar(36)" json:"id"`
|
||||||
|
Name string `gorm:"type:varchar(200)" json:"name"`
|
||||||
|
ParentId string `gorm:"type:varchar(36)" json:"parentId"`
|
||||||
|
Sort int `json:"sort"`
|
||||||
|
Created common.JsonTime `gorm:"type:datetime" json:"createdAt"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *WebsiteGroup) TableName() string {
|
||||||
|
return "website_groups"
|
||||||
|
}
|
||||||
@@ -0,0 +1,389 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"next-terminal/server/common"
|
||||||
|
"next-terminal/server/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
var AuthorisedAssetRepository = new(authorisedAssetRepository)
|
||||||
|
|
||||||
|
type authorisedAssetRepository struct {
|
||||||
|
baseRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedAssetRepository) Find(c context.Context, pageIndex, pageSize int, userId, departmentId, assetGroupId, assetId string) (o []model.AuthorisedAsset, total int64, err error) {
|
||||||
|
db := r.GetDB(c).Model(&model.AuthorisedAsset{})
|
||||||
|
|
||||||
|
if userId != "" {
|
||||||
|
db = db.Where("user_id = ?", userId)
|
||||||
|
}
|
||||||
|
if departmentId != "" {
|
||||||
|
db = db.Where("department_id = ?", departmentId)
|
||||||
|
}
|
||||||
|
if assetGroupId != "" {
|
||||||
|
db = db.Where("asset_group_id = ?", assetGroupId)
|
||||||
|
}
|
||||||
|
if assetId != "" {
|
||||||
|
db = db.Where("asset_id = ?", assetId)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Count(&total).Error
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Order("created desc").Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedAssetRepository) FindById(c context.Context, id string) (o model.AuthorisedAsset, err error) {
|
||||||
|
err = r.GetDB(c).Where("id = ?", id).First(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedAssetRepository) Create(c context.Context, o *model.AuthorisedAsset) error {
|
||||||
|
o.Created = common.NowJsonTime()
|
||||||
|
return r.GetDB(c).Create(o).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedAssetRepository) CreateInBatches(c context.Context, items []model.AuthorisedAsset) error {
|
||||||
|
for i := range items {
|
||||||
|
items[i].Created = common.NowJsonTime()
|
||||||
|
}
|
||||||
|
return r.GetDB(c).CreateInBatches(items, 100).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedAssetRepository) UpdateById(c context.Context, o *model.AuthorisedAsset) error {
|
||||||
|
return r.GetDB(c).Updates(o).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedAssetRepository) DeleteById(c context.Context, id string) error {
|
||||||
|
return r.GetDB(c).Where("id = ?", id).Delete(&model.AuthorisedAsset{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedAssetRepository) Selected(c context.Context, expect, userId, departmentId, assetId string) (result []string, err error) {
|
||||||
|
var items []model.AuthorisedAsset
|
||||||
|
db := r.GetDB(c)
|
||||||
|
switch expect {
|
||||||
|
case "userId":
|
||||||
|
db = db.Select("user_id")
|
||||||
|
case "departmentId":
|
||||||
|
db = db.Select("department_id")
|
||||||
|
case "assetId":
|
||||||
|
db = db.Select("asset_id")
|
||||||
|
case "assetGroupId":
|
||||||
|
db = db.Select("asset_group_id")
|
||||||
|
}
|
||||||
|
|
||||||
|
if userId != "" {
|
||||||
|
db = db.Where("user_id = ?", userId)
|
||||||
|
}
|
||||||
|
if departmentId != "" {
|
||||||
|
db = db.Where("department_id = ?", departmentId)
|
||||||
|
}
|
||||||
|
if assetId != "" {
|
||||||
|
db = db.Where("asset_id = ?", assetId)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Find(&items).Error
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range items {
|
||||||
|
switch expect {
|
||||||
|
case "userId":
|
||||||
|
if item.UserId != "" {
|
||||||
|
result = append(result, item.UserId)
|
||||||
|
}
|
||||||
|
case "departmentId":
|
||||||
|
if item.DepartmentId != "" {
|
||||||
|
result = append(result, item.DepartmentId)
|
||||||
|
}
|
||||||
|
case "assetId":
|
||||||
|
if item.AssetId != "" {
|
||||||
|
result = append(result, item.AssetId)
|
||||||
|
}
|
||||||
|
case "assetGroupId":
|
||||||
|
if item.AssetGroupId != "" {
|
||||||
|
result = append(result, item.AssetGroupId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedAssetRepository) FindWithDetails(c context.Context, pageIndex, pageSize int, userId, departmentId, assetGroupId, assetId string) (o []map[string]interface{}, total int64, err error) {
|
||||||
|
db := r.GetDB(c).Table("authorised_assets").
|
||||||
|
Select(`authorised_assets.id,
|
||||||
|
strftime('%s', authorised_assets.created) * 1000 as "createdAt",
|
||||||
|
authorised_assets.expired_at as "expiredAt",
|
||||||
|
authorised_assets.user_id as "userId", users.nickname as "userName",
|
||||||
|
authorised_assets.department_id as "departmentId", departments.name as "departmentName",
|
||||||
|
authorised_assets.asset_id as "assetId", assets.name as "assetName",
|
||||||
|
authorised_assets.asset_group_id as "assetGroupId", asset_groups.name as "assetGroupName",
|
||||||
|
authorised_assets.strategy_id as "strategyId", strategies.name as "strategyName"`).
|
||||||
|
Joins("left join users on users.id = authorised_assets.user_id").
|
||||||
|
Joins("left join departments on departments.id = authorised_assets.department_id").
|
||||||
|
Joins("left join assets on assets.id = authorised_assets.asset_id").
|
||||||
|
Joins("left join asset_groups on asset_groups.id = authorised_assets.asset_group_id").
|
||||||
|
Joins("left join strategies on strategies.id = authorised_assets.strategy_id")
|
||||||
|
|
||||||
|
dbCounter := r.GetDB(c).Model(&model.AuthorisedAsset{})
|
||||||
|
|
||||||
|
if userId != "" {
|
||||||
|
db = db.Where("authorised_assets.user_id = ?", userId)
|
||||||
|
dbCounter = dbCounter.Where("user_id = ?", userId)
|
||||||
|
}
|
||||||
|
if departmentId != "" {
|
||||||
|
db = db.Where("authorised_assets.department_id = ?", departmentId)
|
||||||
|
dbCounter = dbCounter.Where("department_id = ?", departmentId)
|
||||||
|
}
|
||||||
|
if assetGroupId != "" {
|
||||||
|
db = db.Where("authorised_assets.asset_group_id = ?", assetGroupId)
|
||||||
|
dbCounter = dbCounter.Where("asset_group_id = ?", assetGroupId)
|
||||||
|
}
|
||||||
|
if assetId != "" {
|
||||||
|
db = db.Where("authorised_assets.asset_id = ?", assetId)
|
||||||
|
dbCounter = dbCounter.Where("asset_id = ?", assetId)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = dbCounter.Count(&total).Error
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Order("authorised_assets.created desc").Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var AuthorisedDatabaseAssetRepository = new(authorisedDatabaseAssetRepository)
|
||||||
|
|
||||||
|
type authorisedDatabaseAssetRepository struct {
|
||||||
|
baseRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedDatabaseAssetRepository) Find(c context.Context, pageIndex, pageSize int, userId, departmentId, databaseAssetId string) (o []model.AuthorisedDatabaseAsset, total int64, err error) {
|
||||||
|
db := r.GetDB(c).Model(&model.AuthorisedDatabaseAsset{})
|
||||||
|
|
||||||
|
if userId != "" {
|
||||||
|
db = db.Where("user_id = ?", userId)
|
||||||
|
}
|
||||||
|
if departmentId != "" {
|
||||||
|
db = db.Where("department_id = ?", departmentId)
|
||||||
|
}
|
||||||
|
if databaseAssetId != "" {
|
||||||
|
db = db.Where("database_asset_id = ?", databaseAssetId)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Count(&total).Error
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Order("created desc").Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedDatabaseAssetRepository) FindById(c context.Context, id string) (o model.AuthorisedDatabaseAsset, err error) {
|
||||||
|
err = r.GetDB(c).Where("id = ?", id).First(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedDatabaseAssetRepository) Create(c context.Context, o *model.AuthorisedDatabaseAsset) error {
|
||||||
|
o.Created = common.NowJsonTime()
|
||||||
|
return r.GetDB(c).Create(o).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedDatabaseAssetRepository) CreateInBatches(c context.Context, items []model.AuthorisedDatabaseAsset) error {
|
||||||
|
for i := range items {
|
||||||
|
items[i].Created = common.NowJsonTime()
|
||||||
|
}
|
||||||
|
return r.GetDB(c).CreateInBatches(items, 100).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedDatabaseAssetRepository) UpdateById(c context.Context, o *model.AuthorisedDatabaseAsset) error {
|
||||||
|
return r.GetDB(c).Updates(o).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedDatabaseAssetRepository) DeleteById(c context.Context, id string) error {
|
||||||
|
return r.GetDB(c).Where("id = ?", id).Delete(&model.AuthorisedDatabaseAsset{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedDatabaseAssetRepository) Selected(c context.Context, expect, userId, departmentId, databaseAssetId string) (result []string, err error) {
|
||||||
|
var items []model.AuthorisedDatabaseAsset
|
||||||
|
db := r.GetDB(c)
|
||||||
|
switch expect {
|
||||||
|
case "userId":
|
||||||
|
db = db.Select("user_id")
|
||||||
|
case "departmentId":
|
||||||
|
db = db.Select("department_id")
|
||||||
|
case "databaseAssetId":
|
||||||
|
db = db.Select("database_asset_id")
|
||||||
|
}
|
||||||
|
|
||||||
|
if userId != "" {
|
||||||
|
db = db.Where("user_id = ?", userId)
|
||||||
|
}
|
||||||
|
if departmentId != "" {
|
||||||
|
db = db.Where("department_id = ?", departmentId)
|
||||||
|
}
|
||||||
|
if databaseAssetId != "" {
|
||||||
|
db = db.Where("database_asset_id = ?", databaseAssetId)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Find(&items).Error
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, item := range items {
|
||||||
|
switch expect {
|
||||||
|
case "userId":
|
||||||
|
if item.UserId != "" {
|
||||||
|
result = append(result, item.UserId)
|
||||||
|
}
|
||||||
|
case "departmentId":
|
||||||
|
if item.DepartmentId != "" {
|
||||||
|
result = append(result, item.DepartmentId)
|
||||||
|
}
|
||||||
|
case "databaseAssetId":
|
||||||
|
if item.DatabaseAssetId != "" {
|
||||||
|
result = append(result, item.DatabaseAssetId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedDatabaseAssetRepository) FindWithDetails(c context.Context, pageIndex, pageSize int, userId, departmentId, databaseAssetId string) (o []map[string]interface{}, total int64, err error) {
|
||||||
|
db := r.GetDB(c).Table("authorised_database_assets").
|
||||||
|
Select(`authorised_database_assets.id,
|
||||||
|
strftime('%s', authorised_database_assets.created) * 1000 as "createdAt",
|
||||||
|
authorised_database_assets.expired_at as "expiredAt",
|
||||||
|
authorised_database_assets.user_id as "userId", users.nickname as "userName",
|
||||||
|
authorised_database_assets.department_id as "departmentId", departments.name as "departmentName",
|
||||||
|
authorised_database_assets.database_asset_id as "databaseAssetId", database_assets.name as "databaseAssetName",
|
||||||
|
authorised_database_assets.strategy_id as "strategyId", strategies.name as "strategyName"`).
|
||||||
|
Joins("left join users on users.id = authorised_database_assets.user_id").
|
||||||
|
Joins("left join departments on departments.id = authorised_database_assets.department_id").
|
||||||
|
Joins("left join database_assets on database_assets.id = authorised_database_assets.database_asset_id").
|
||||||
|
Joins("left join strategies on strategies.id = authorised_database_assets.strategy_id")
|
||||||
|
|
||||||
|
dbCounter := r.GetDB(c).Model(&model.AuthorisedDatabaseAsset{})
|
||||||
|
|
||||||
|
if userId != "" {
|
||||||
|
db = db.Where("authorised_database_assets.user_id = ?", userId)
|
||||||
|
dbCounter = dbCounter.Where("user_id = ?", userId)
|
||||||
|
}
|
||||||
|
if departmentId != "" {
|
||||||
|
db = db.Where("authorised_database_assets.department_id = ?", departmentId)
|
||||||
|
dbCounter = dbCounter.Where("department_id = ?", departmentId)
|
||||||
|
}
|
||||||
|
if databaseAssetId != "" {
|
||||||
|
db = db.Where("authorised_database_assets.database_asset_id = ?", databaseAssetId)
|
||||||
|
dbCounter = dbCounter.Where("database_asset_id = ?", databaseAssetId)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = dbCounter.Count(&total).Error
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Order("authorised_database_assets.created desc").Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var AuthorisedWebsiteRepository = new(authorisedWebsiteRepository)
|
||||||
|
|
||||||
|
type authorisedWebsiteRepository struct {
|
||||||
|
baseRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedWebsiteRepository) Find(c context.Context, pageIndex, pageSize int, userId, departmentId, websiteId string) (o []model.AuthorisedWebsite, total int64, err error) {
|
||||||
|
db := r.GetDB(c).Model(&model.AuthorisedWebsite{})
|
||||||
|
|
||||||
|
if userId != "" {
|
||||||
|
db = db.Where("user_id = ?", userId)
|
||||||
|
}
|
||||||
|
if departmentId != "" {
|
||||||
|
db = db.Where("department_id = ?", departmentId)
|
||||||
|
}
|
||||||
|
if websiteId != "" {
|
||||||
|
db = db.Where("website_id = ?", websiteId)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Count(&total).Error
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Order("created desc").Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedWebsiteRepository) FindById(c context.Context, id string) (o model.AuthorisedWebsite, err error) {
|
||||||
|
err = r.GetDB(c).Where("id = ?", id).First(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedWebsiteRepository) Create(c context.Context, o *model.AuthorisedWebsite) error {
|
||||||
|
o.Created = common.NowJsonTime()
|
||||||
|
return r.GetDB(c).Create(o).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedWebsiteRepository) CreateInBatches(c context.Context, items []model.AuthorisedWebsite) error {
|
||||||
|
for i := range items {
|
||||||
|
items[i].Created = common.NowJsonTime()
|
||||||
|
}
|
||||||
|
return r.GetDB(c).CreateInBatches(items, 100).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedWebsiteRepository) DeleteById(c context.Context, id string) error {
|
||||||
|
return r.GetDB(c).Where("id = ?", id).Delete(&model.AuthorisedWebsite{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r authorisedWebsiteRepository) FindWithDetails(c context.Context, pageIndex, pageSize int, userId, departmentId, websiteId string) (o []map[string]interface{}, total int64, err error) {
|
||||||
|
db := r.GetDB(c).Table("authorised_websites").
|
||||||
|
Select(`authorised_websites.id,
|
||||||
|
strftime('%s', authorised_websites.created) * 1000 as "createdAt",
|
||||||
|
authorised_websites.expired_at as "expiredAt",
|
||||||
|
authorised_websites.user_id as "userId", users.nickname as "userName",
|
||||||
|
authorised_websites.department_id as "departmentId", departments.name as "departmentName",
|
||||||
|
authorised_websites.website_id as "websiteId", websites.name as "websiteName",
|
||||||
|
authorised_websites.strategy_id as "strategyId", strategies.name as "strategyName"`).
|
||||||
|
Joins("left join users on users.id = authorised_websites.user_id").
|
||||||
|
Joins("left join departments on departments.id = authorised_websites.department_id").
|
||||||
|
Joins("left join websites on websites.id = authorised_websites.website_id").
|
||||||
|
Joins("left join strategies on strategies.id = authorised_websites.strategy_id")
|
||||||
|
|
||||||
|
dbCounter := r.GetDB(c).Model(&model.AuthorisedWebsite{})
|
||||||
|
|
||||||
|
if userId != "" {
|
||||||
|
db = db.Where("authorised_websites.user_id = ?", userId)
|
||||||
|
dbCounter = dbCounter.Where("user_id = ?", userId)
|
||||||
|
}
|
||||||
|
if departmentId != "" {
|
||||||
|
db = db.Where("authorised_websites.department_id = ?", departmentId)
|
||||||
|
dbCounter = dbCounter.Where("department_id = ?", departmentId)
|
||||||
|
}
|
||||||
|
if websiteId != "" {
|
||||||
|
db = db.Where("authorised_websites.website_id = ?", websiteId)
|
||||||
|
dbCounter = dbCounter.Where("website_id = ?", websiteId)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = dbCounter.Count(&total).Error
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Order("authorised_websites.created desc").Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
_ = strconv.Itoa(0)
|
||||||
|
}
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"next-terminal/server/common"
|
||||||
|
"next-terminal/server/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
var CommandFilterRepository = new(commandFilterRepository)
|
||||||
|
|
||||||
|
type commandFilterRepository struct {
|
||||||
|
baseRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r commandFilterRepository) FindAll(c context.Context) (o []model.CommandFilter, err error) {
|
||||||
|
err = r.GetDB(c).Order("name asc").Find(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r commandFilterRepository) Find(c context.Context, pageIndex, pageSize int, name, order, field string) (o []model.CommandFilter, total int64, err error) {
|
||||||
|
db := r.GetDB(c).Model(&model.CommandFilter{})
|
||||||
|
|
||||||
|
if len(name) > 0 {
|
||||||
|
db = db.Where("name like ?", "%"+name+"%")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Count(&total).Error
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if order == "" {
|
||||||
|
order = "asc"
|
||||||
|
}
|
||||||
|
if field == "" {
|
||||||
|
field = "name"
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Order(field + " " + order).Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r commandFilterRepository) FindById(c context.Context, id string) (o model.CommandFilter, err error) {
|
||||||
|
err = r.GetDB(c).Where("id = ?", id).First(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r commandFilterRepository) Create(c context.Context, o *model.CommandFilter) error {
|
||||||
|
o.Created = common.NowJsonTime()
|
||||||
|
return r.GetDB(c).Create(o).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r commandFilterRepository) UpdateById(c context.Context, o *model.CommandFilter) error {
|
||||||
|
return r.GetDB(c).Updates(o).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r commandFilterRepository) DeleteById(c context.Context, id string) error {
|
||||||
|
tx := r.GetDB(c).Begin()
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if err := tx.Where("command_filter_id = ?", id).Delete(&model.CommandFilterRule{}).Error; err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tx.Where("id = ?", id).Delete(&model.CommandFilter{}).Error; err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tx.Commit().Error
|
||||||
|
}
|
||||||
|
|
||||||
|
var CommandFilterRuleRepository = new(commandFilterRuleRepository)
|
||||||
|
|
||||||
|
type commandFilterRuleRepository struct {
|
||||||
|
baseRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r commandFilterRuleRepository) FindByCommandFilterId(c context.Context, commandFilterId string) (o []model.CommandFilterRule, err error) {
|
||||||
|
err = r.GetDB(c).Where("command_filter_id = ?", commandFilterId).Order("priority asc").Find(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r commandFilterRuleRepository) FindById(c context.Context, id string) (o model.CommandFilterRule, err error) {
|
||||||
|
err = r.GetDB(c).Where("id = ?", id).First(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r commandFilterRuleRepository) Create(c context.Context, o *model.CommandFilterRule) error {
|
||||||
|
o.Created = common.NowJsonTime()
|
||||||
|
return r.GetDB(c).Create(o).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r commandFilterRuleRepository) UpdateById(c context.Context, o *model.CommandFilterRule) error {
|
||||||
|
return r.GetDB(c).Updates(o).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r commandFilterRuleRepository) DeleteById(c context.Context, id string) error {
|
||||||
|
return r.GetDB(c).Where("id = ?", id).Delete(&model.CommandFilterRule{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r commandFilterRuleRepository) DeleteByCommandFilterId(c context.Context, commandFilterId string) error {
|
||||||
|
return r.GetDB(c).Where("command_filter_id = ?", commandFilterId).Delete(&model.CommandFilterRule{}).Error
|
||||||
|
}
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"next-terminal/server/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
var DatabaseAssetRepository = new(databaseAssetRepository)
|
||||||
|
|
||||||
|
type databaseAssetRepository struct {
|
||||||
|
baseRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r databaseAssetRepository) FindAll(c context.Context) (o []model.DatabaseAsset, err error) {
|
||||||
|
err = r.GetDB(c).Order("name asc").Find(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r databaseAssetRepository) FindByType(c context.Context, dbType string) (o []model.DatabaseAsset, err error) {
|
||||||
|
db := r.GetDB(c)
|
||||||
|
if dbType != "" {
|
||||||
|
db = db.Where("type = ?", dbType)
|
||||||
|
}
|
||||||
|
err = db.Order("name asc").Find(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r databaseAssetRepository) Find(c context.Context, pageIndex, pageSize int, name, dbType, order, field string) (o []model.DatabaseAsset, total int64, err error) {
|
||||||
|
db := r.GetDB(c).Model(&model.DatabaseAsset{})
|
||||||
|
|
||||||
|
if len(name) > 0 {
|
||||||
|
db = db.Where("name like ?", "%"+name+"%")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(dbType) > 0 {
|
||||||
|
db = db.Where("type = ?", dbType)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Count(&total).Error
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if order == "" {
|
||||||
|
order = "asc"
|
||||||
|
}
|
||||||
|
if field == "" {
|
||||||
|
field = "name"
|
||||||
|
}
|
||||||
|
|
||||||
|
orderBy := field + " " + order
|
||||||
|
if field == "created" {
|
||||||
|
orderBy = "created " + order
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Order(orderBy).Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r databaseAssetRepository) FindById(c context.Context, id string) (o model.DatabaseAsset, err error) {
|
||||||
|
err = r.GetDB(c).Where("id = ?", id).First(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r databaseAssetRepository) Create(c context.Context, o *model.DatabaseAsset) error {
|
||||||
|
return r.GetDB(c).Create(o).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r databaseAssetRepository) UpdateById(c context.Context, o *model.DatabaseAsset) error {
|
||||||
|
return r.GetDB(c).Updates(o).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r databaseAssetRepository) DeleteById(c context.Context, id string) error {
|
||||||
|
return r.GetDB(c).Where("id = ?", id).Delete(&model.DatabaseAsset{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r databaseAssetRepository) Count(c context.Context) (total int64, err error) {
|
||||||
|
err = r.GetDB(c).Model(&model.DatabaseAsset{}).Count(&total).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r databaseAssetRepository) FindAllTags(c context.Context) (o []string, err error) {
|
||||||
|
var assets []model.DatabaseAsset
|
||||||
|
err = r.GetDB(c).Select("tags").Find(&assets).Error
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tagSet := make(map[string]bool)
|
||||||
|
for _, asset := range assets {
|
||||||
|
if asset.Tags == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
tags := strings.Split(asset.Tags, ",")
|
||||||
|
for _, tag := range tags {
|
||||||
|
tag = strings.TrimSpace(tag)
|
||||||
|
if tag != "" {
|
||||||
|
tagSet[tag] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for tag := range tagSet {
|
||||||
|
o = append(o, tag)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r databaseAssetRepository) ParseTags(tags string) []string {
|
||||||
|
if tags == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return strings.Split(tags, ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r databaseAssetRepository) FormatTags(tags []string) string {
|
||||||
|
if len(tags) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return strings.Join(tags, ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r databaseAssetRepository) GetDBPort(dbType string) int {
|
||||||
|
switch dbType {
|
||||||
|
case "mysql":
|
||||||
|
return 3306
|
||||||
|
case "pg":
|
||||||
|
return 5432
|
||||||
|
case "sqlserver":
|
||||||
|
return 1433
|
||||||
|
case "oracle":
|
||||||
|
return 1521
|
||||||
|
default:
|
||||||
|
return 3306
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r databaseAssetRepository) UpdateOwner(c context.Context, ownerId string, newOwnerId string) error {
|
||||||
|
return r.GetDB(c).Model(&model.DatabaseAsset{}).Where("owner = ?", ownerId).Update("owner", newOwnerId).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
_ = strconv.Itoa(0)
|
||||||
|
_ = strings.Join(nil, "")
|
||||||
|
}
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"next-terminal/server/common"
|
||||||
|
"next-terminal/server/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
var DepartmentRepository = new(departmentRepository)
|
||||||
|
|
||||||
|
type departmentRepository struct {
|
||||||
|
baseRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r departmentRepository) FindAll(c context.Context) (o []model.Department, err error) {
|
||||||
|
err = r.GetDB(c).Order("sort asc, name asc").Find(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r departmentRepository) Find(c context.Context, pageIndex, pageSize int, name, order, field string) (o []model.Department, total int64, err error) {
|
||||||
|
db := r.GetDB(c).Model(&model.Department{})
|
||||||
|
|
||||||
|
if len(name) > 0 {
|
||||||
|
db = db.Where("name like ?", "%"+name+"%")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Count(&total).Error
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if order == "" {
|
||||||
|
order = "asc"
|
||||||
|
}
|
||||||
|
if field == "" {
|
||||||
|
field = "sort"
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Order(field + " " + order).Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r departmentRepository) FindById(c context.Context, id string) (o model.Department, err error) {
|
||||||
|
err = r.GetDB(c).Where("id = ?", id).First(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r departmentRepository) FindByParentId(c context.Context, parentId string) (o []model.Department, err error) {
|
||||||
|
db := r.GetDB(c)
|
||||||
|
if parentId == "" {
|
||||||
|
db = db.Where("parent_id = '' or parent_id is null")
|
||||||
|
} else {
|
||||||
|
db = db.Where("parent_id = ?", parentId)
|
||||||
|
}
|
||||||
|
err = db.Order("sort asc, name asc").Find(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r departmentRepository) Create(c context.Context, o *model.Department) error {
|
||||||
|
o.Created = common.NowJsonTime()
|
||||||
|
return r.GetDB(c).Create(o).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r departmentRepository) UpdateById(c context.Context, o *model.Department) error {
|
||||||
|
return r.GetDB(c).Updates(o).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r departmentRepository) DeleteById(c context.Context, id string) error {
|
||||||
|
return r.GetDB(c).Where("id = ?", id).Delete(&model.Department{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r departmentRepository) CountByParentId(c context.Context, parentId string) (total int64, err error) {
|
||||||
|
err = r.GetDB(c).Model(&model.Department{}).Where("parent_id = ?", parentId).Count(&total).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r departmentRepository) BuildTree(departments []model.Department) []map[string]interface{} {
|
||||||
|
departmentMap := make(map[string][]map[string]interface{})
|
||||||
|
var roots []map[string]interface{}
|
||||||
|
|
||||||
|
for _, dept := range departments {
|
||||||
|
node := map[string]interface{}{
|
||||||
|
"title": dept.Name,
|
||||||
|
"key": dept.ID,
|
||||||
|
"value": dept.ID,
|
||||||
|
"children": []map[string]interface{}{},
|
||||||
|
}
|
||||||
|
if dept.ParentId == "" {
|
||||||
|
roots = append(roots, node)
|
||||||
|
} else {
|
||||||
|
departmentMap[dept.ParentId] = append(departmentMap[dept.ParentId], node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var buildChildren func(nodes []map[string]interface{})
|
||||||
|
buildChildren = func(nodes []map[string]interface{}) {
|
||||||
|
for i := range nodes {
|
||||||
|
id := nodes[i]["key"].(string)
|
||||||
|
if children, ok := departmentMap[id]; ok {
|
||||||
|
nodes[i]["children"] = children
|
||||||
|
buildChildren(children)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildChildren(roots)
|
||||||
|
return roots
|
||||||
|
}
|
||||||
@@ -7,6 +7,8 @@ import (
|
|||||||
"next-terminal/server/model"
|
"next-terminal/server/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const SuperAdminID = `abcdefghijklmnopqrstuvwxyz`
|
||||||
|
|
||||||
var UserRepository = new(userRepository)
|
var UserRepository = new(userRepository)
|
||||||
|
|
||||||
type userRepository struct {
|
type userRepository struct {
|
||||||
@@ -18,7 +20,7 @@ func (r userRepository) FindAll(c context.Context) (o []model.User, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r userRepository) Find(c context.Context, pageIndex, pageSize int, username, nickname, mail, online, loginPolicyId, order, field string) (o []model.UserForPage, total int64, err error) {
|
func (r userRepository) Find(c context.Context, pageIndex, pageSize int, username, nickname, mail, online, userType, loginPolicyId, order, field string) (o []model.UserForPage, total int64, err error) {
|
||||||
db := r.GetDB(c).Table("users").Select("users.id,users.username,users.nickname,users.mail,users.phone,users.online,users.created,users.type,users.status,users.source,users.recording,users.watermark, users.totp_secret")
|
db := r.GetDB(c).Table("users").Select("users.id,users.username,users.nickname,users.mail,users.phone,users.online,users.created,users.type,users.status,users.source,users.recording,users.watermark, users.totp_secret")
|
||||||
dbCounter := r.GetDB(c).Table("users")
|
dbCounter := r.GetDB(c).Table("users")
|
||||||
|
|
||||||
@@ -54,6 +56,17 @@ func (r userRepository) Find(c context.Context, pageIndex, pageSize int, usernam
|
|||||||
dbCounter = dbCounter.Where("users.online = ?", _online)
|
dbCounter = dbCounter.Where("users.online = ?", _online)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if userType == "super-admin" {
|
||||||
|
db = db.Where("users.id = ?", SuperAdminID)
|
||||||
|
dbCounter = dbCounter.Where("id = ?", SuperAdminID)
|
||||||
|
} else if userType == "admin" {
|
||||||
|
db = db.Where("users.type = ? and users.id != ?", "admin", SuperAdminID)
|
||||||
|
dbCounter = dbCounter.Where("type = ? and id != ?", "admin", SuperAdminID)
|
||||||
|
} else if userType == "user" {
|
||||||
|
db = db.Where("users.type = ?", "user")
|
||||||
|
dbCounter = dbCounter.Where("type = ?", "user")
|
||||||
|
}
|
||||||
|
|
||||||
err = dbCounter.Count(&total).Error
|
err = dbCounter.Count(&total).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
|
|||||||
@@ -0,0 +1,106 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"next-terminal/server/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
var UserDepartmentRepository = new(userDepartmentRepository)
|
||||||
|
|
||||||
|
type userDepartmentRepository struct {
|
||||||
|
baseRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r userDepartmentRepository) FindByUserId(c context.Context, userId string) (o []model.UserDepartmentRef, err error) {
|
||||||
|
err = r.GetDB(c).Where("user_id = ?", userId).Find(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r userDepartmentRepository) FindByDepartmentId(c context.Context, departmentId string) (o []model.UserDepartmentRef, err error) {
|
||||||
|
err = r.GetDB(c).Where("department_id = ?", departmentId).Find(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r userDepartmentRepository) FindUsersByDepartmentId(c context.Context, departmentId string) (userIds []string, err error) {
|
||||||
|
var refs []model.UserDepartmentRef
|
||||||
|
err = r.GetDB(c).Where("department_id = ?", departmentId).Find(&refs).Error
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, ref := range refs {
|
||||||
|
userIds = append(userIds, ref.UserId)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r userDepartmentRepository) SaveUserDepartments(c context.Context, userId string, departmentIds []string) error {
|
||||||
|
tx := r.GetDB(c).Begin()
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if err := tx.Where("user_id = ?", userId).Delete(&model.UserDepartmentRef{}).Error; err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, deptId := range departmentIds {
|
||||||
|
ref := model.UserDepartmentRef{
|
||||||
|
UserId: userId,
|
||||||
|
DepartmentId: deptId,
|
||||||
|
}
|
||||||
|
if err := tx.Create(&ref).Error; err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tx.Commit().Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r userDepartmentRepository) SaveDepartmentUsers(c context.Context, departmentId string, userIds []string) error {
|
||||||
|
tx := r.GetDB(c).Begin()
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if err := tx.Where("department_id = ?", departmentId).Delete(&model.UserDepartmentRef{}).Error; err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, userId := range userIds {
|
||||||
|
ref := model.UserDepartmentRef{
|
||||||
|
UserId: userId,
|
||||||
|
DepartmentId: departmentId,
|
||||||
|
}
|
||||||
|
if err := tx.Create(&ref).Error; err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tx.Commit().Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r userDepartmentRepository) RemoveUsersFromDepartment(c context.Context, departmentId string, userIds []string) error {
|
||||||
|
return r.GetDB(c).Where("department_id = ? AND user_id IN ?", departmentId, userIds).Delete(&model.UserDepartmentRef{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r userDepartmentRepository) DeleteByUserId(c context.Context, userId string) error {
|
||||||
|
return r.GetDB(c).Where("user_id = ?", userId).Delete(&model.UserDepartmentRef{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r userDepartmentRepository) DeleteByDepartmentId(c context.Context, departmentId string) error {
|
||||||
|
return r.GetDB(c).Where("department_id = ?", departmentId).Delete(&model.UserDepartmentRef{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r userDepartmentRepository) CountByDepartmentId(c context.Context, departmentId string) (total int64, err error) {
|
||||||
|
err = r.GetDB(c).Model(&model.UserDepartmentRef{}).Where("department_id = ?", departmentId).Count(&total).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package repository
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"next-terminal/server/common"
|
||||||
"next-terminal/server/model"
|
"next-terminal/server/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -18,7 +19,8 @@ func (r websiteRepository) FindAll(c context.Context) (o []model.Website, err er
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r websiteRepository) Find(c context.Context, pageIndex, pageSize int, keyword string) (o []model.WebsiteForPage, total int64, err error) {
|
func (r websiteRepository) Find(c context.Context, pageIndex, pageSize int, keyword string) (o []model.WebsiteForPage, total int64, err error) {
|
||||||
db := r.GetDB(c).Table("websites").Select("id,name,enabled,target_url,target_host,target_port,domain,status,status_text,created,group_id,sort")
|
db := r.GetDB(c).Table("websites").Select(`id,name,enabled,target_url,target_host,target_port,domain,status,status_text,
|
||||||
|
strftime('%s', created) * 1000 as created,group_id,sort`)
|
||||||
dbCounter := r.GetDB(c).Table("websites")
|
dbCounter := r.GetDB(c).Table("websites")
|
||||||
|
|
||||||
if len(keyword) > 0 {
|
if len(keyword) > 0 {
|
||||||
@@ -39,6 +41,7 @@ func (r websiteRepository) Find(c context.Context, pageIndex, pageSize int, keyw
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r websiteRepository) Create(c context.Context, o *model.Website) error {
|
func (r websiteRepository) Create(c context.Context, o *model.Website) error {
|
||||||
|
o.Created = common.NowJsonTime()
|
||||||
return r.GetDB(c).Create(o).Error
|
return r.GetDB(c).Create(o).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,3 +58,8 @@ func (r websiteRepository) FindById(c context.Context, id string) (o model.Websi
|
|||||||
err = r.GetDB(c).Where("id = ?", id).First(&o).Error
|
err = r.GetDB(c).Where("id = ?", id).First(&o).Error
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r websiteRepository) Count(c context.Context) (total int64, err error) {
|
||||||
|
err = r.GetDB(c).Model(&model.Website{}).Count(&total).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"next-terminal/server/common"
|
||||||
|
"next-terminal/server/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
var WebsiteGroupRepository = new(websiteGroupRepository)
|
||||||
|
|
||||||
|
type websiteGroupRepository struct {
|
||||||
|
baseRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r websiteGroupRepository) FindAll(c context.Context) (o []model.WebsiteGroup, err error) {
|
||||||
|
err = r.GetDB(c).Order("sort asc, name asc").Find(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r websiteGroupRepository) FindById(c context.Context, id string) (o model.WebsiteGroup, err error) {
|
||||||
|
err = r.GetDB(c).Where("id = ?", id).First(&o).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r websiteGroupRepository) Create(c context.Context, o *model.WebsiteGroup) error {
|
||||||
|
o.Created = common.NowJsonTime()
|
||||||
|
return r.GetDB(c).Create(o).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r websiteGroupRepository) UpdateById(c context.Context, o *model.WebsiteGroup) error {
|
||||||
|
return r.GetDB(c).Updates(o).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r websiteGroupRepository) DeleteById(c context.Context, id string) error {
|
||||||
|
return r.GetDB(c).Where("id = ?", id).Delete(&model.WebsiteGroup{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r websiteGroupRepository) DeleteByParentId(c context.Context, parentId string) error {
|
||||||
|
return r.GetDB(c).Where("parent_id = ?", parentId).Delete(&model.WebsiteGroup{}).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r websiteGroupRepository) CountByParentId(c context.Context, parentId string) (total int64, err error) {
|
||||||
|
err = r.GetDB(c).Model(&model.WebsiteGroup{}).Where("parent_id = ?", parentId).Count(&total).Error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r websiteGroupRepository) DeleteAll(c context.Context) error {
|
||||||
|
return r.GetDB(c).Where("1 = 1").Delete(&model.WebsiteGroup{}).Error
|
||||||
|
}
|
||||||
@@ -30,6 +30,14 @@ type MetadataShell struct {
|
|||||||
Shell string
|
Shell string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ExecScriptResult struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Success bool `json:"success"`
|
||||||
|
UsedTime int64 `json:"usedTime"`
|
||||||
|
UsedTimeStr string `json:"usedTimeStr"`
|
||||||
|
Result string `json:"result"`
|
||||||
|
}
|
||||||
|
|
||||||
func (r ShellJob) Run() {
|
func (r ShellJob) Run() {
|
||||||
if r.ID == "" {
|
if r.ID == "" {
|
||||||
return
|
return
|
||||||
@@ -49,6 +57,14 @@ func (r ShellJob) Run() {
|
|||||||
|
|
||||||
func (r ShellJob) executeShellByAssets(assets []model.Asset) {
|
func (r ShellJob) executeShellByAssets(assets []model.Asset) {
|
||||||
if len(assets) == 0 {
|
if len(assets) == 0 {
|
||||||
|
jobLog := model.JobLog{
|
||||||
|
ID: utils.UUID(),
|
||||||
|
JobId: r.ID,
|
||||||
|
Timestamp: common.NowJsonTime(),
|
||||||
|
Message: "没有找到符合条件的SSH资产",
|
||||||
|
Results: "[]",
|
||||||
|
}
|
||||||
|
_ = repository.JobLogRepository.Create(context.TODO(), &jobLog)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,12 +75,23 @@ func (r ShellJob) executeShellByAssets(assets []model.Asset) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
msgChan := make(chan string)
|
type execResult struct {
|
||||||
|
msg string
|
||||||
|
result ExecScriptResult
|
||||||
|
}
|
||||||
|
resultChan := make(chan execResult)
|
||||||
for i := range assets {
|
for i := range assets {
|
||||||
asset, err := AssetService.FindByIdAndDecrypt(context.TODO(), assets[i].ID)
|
asset, err := AssetService.FindByIdAndDecrypt(context.TODO(), assets[i].ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
msgChan <- fmt.Sprintf("资产「%v」Shell执行失败,查询数据异常「%v」", assets[i].Name, err.Error())
|
resultChan <- execResult{
|
||||||
return
|
msg: fmt.Sprintf("资产「%v」Shell执行失败,查询数据异常「%v」", assets[i].Name, err.Error()),
|
||||||
|
result: ExecScriptResult{
|
||||||
|
Name: assets[i].Name,
|
||||||
|
Success: false,
|
||||||
|
Result: err.Error(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -79,8 +106,15 @@ func (r ShellJob) executeShellByAssets(assets []model.Asset) {
|
|||||||
if asset.AccountType == "credential" {
|
if asset.AccountType == "credential" {
|
||||||
credential, err := CredentialService.FindByIdAndDecrypt(context.TODO(), asset.CredentialId)
|
credential, err := CredentialService.FindByIdAndDecrypt(context.TODO(), asset.CredentialId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
msgChan <- fmt.Sprintf("资产「%v」Shell执行失败,查询授权凭证数据异常「%v」", assets[i].Name, err.Error())
|
resultChan <- execResult{
|
||||||
return
|
msg: fmt.Sprintf("资产「%v」Shell执行失败,查询授权凭证数据异常「%v」", assets[i].Name, err.Error()),
|
||||||
|
result: ExecScriptResult{
|
||||||
|
Name: asset.Name,
|
||||||
|
Success: false,
|
||||||
|
Result: err.Error(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if credential.Type == nt.Custom {
|
if credential.Type == nt.Custom {
|
||||||
@@ -98,33 +132,54 @@ func (r ShellJob) executeShellByAssets(assets []model.Asset) {
|
|||||||
result, err := execute(metadataShell.Shell, asset.AccessGatewayId, ip, port, username, password, privateKey, passphrase)
|
result, err := execute(metadataShell.Shell, asset.AccessGatewayId, ip, port, username, password, privateKey, passphrase)
|
||||||
elapsed := time.Since(t1)
|
elapsed := time.Since(t1)
|
||||||
var msg string
|
var msg string
|
||||||
|
var execRes ExecScriptResult
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(gorm.ErrRecordNotFound, err) {
|
if errors.Is(gorm.ErrRecordNotFound, err) {
|
||||||
msg = fmt.Sprintf("资产「%v」Shell执行失败,请检查资产所关联接入网关是否存在,耗时「%v」", asset.Name, elapsed)
|
msg = fmt.Sprintf("资产「%v」Shell执行失败,请检查资产所关联接入网关是否存在,耗时「%v」", asset.Name, elapsed)
|
||||||
} else {
|
} else {
|
||||||
msg = fmt.Sprintf("资产「%v」Shell执行失败,错误内容为:「%v」,耗时「%v」", asset.Name, err.Error(), elapsed)
|
msg = fmt.Sprintf("资产「%v」Shell执行失败,错误内容为:「%v」,耗时「%v」", asset.Name, err.Error(), elapsed)
|
||||||
}
|
}
|
||||||
|
execRes = ExecScriptResult{
|
||||||
|
Name: asset.Name,
|
||||||
|
Success: false,
|
||||||
|
UsedTime: elapsed.Milliseconds(),
|
||||||
|
UsedTimeStr: elapsed.String(),
|
||||||
|
Result: err.Error(),
|
||||||
|
}
|
||||||
log.Debug(msg)
|
log.Debug(msg)
|
||||||
} else {
|
} else {
|
||||||
msg = fmt.Sprintf("资产「%v」Shell执行成功,返回值「%v」,耗时「%v」", asset.Name, result, elapsed)
|
msg = fmt.Sprintf("资产「%v」Shell执行成功,返回值「%v」,耗时「%v」", asset.Name, result, elapsed)
|
||||||
|
execRes = ExecScriptResult{
|
||||||
|
Name: asset.Name,
|
||||||
|
Success: true,
|
||||||
|
UsedTime: elapsed.Milliseconds(),
|
||||||
|
UsedTimeStr: elapsed.String(),
|
||||||
|
Result: result,
|
||||||
|
}
|
||||||
log.Debug(msg)
|
log.Debug(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
msgChan <- msg
|
resultChan <- execResult{msg: msg, result: execRes}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
var message = ""
|
var message = ""
|
||||||
|
var results []ExecScriptResult
|
||||||
for i := 0; i < len(assets); i++ {
|
for i := 0; i < len(assets); i++ {
|
||||||
message += <-msgChan + "\n"
|
res := <-resultChan
|
||||||
|
message += res.msg + "\n"
|
||||||
|
results = append(results, res.result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resultsJSON, _ := json.Marshal(results)
|
||||||
|
|
||||||
_ = repository.JobRepository.UpdateLastUpdatedById(context.TODO(), r.ID)
|
_ = repository.JobRepository.UpdateLastUpdatedById(context.TODO(), r.ID)
|
||||||
jobLog := model.JobLog{
|
jobLog := model.JobLog{
|
||||||
ID: utils.UUID(),
|
ID: utils.UUID(),
|
||||||
JobId: r.ID,
|
JobId: r.ID,
|
||||||
Timestamp: common.NowJsonTime(),
|
Timestamp: common.NowJsonTime(),
|
||||||
Message: message,
|
Message: message,
|
||||||
|
Results: string(resultsJSON),
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = repository.JobLogRepository.Create(context.TODO(), &jobLog)
|
_ = repository.JobLogRepository.Create(context.TODO(), &jobLog)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, {useEffect, useMemo, useState} from 'react';
|
import React, {useEffect, useMemo, useRef, useState} from 'react';
|
||||||
import {Button, Card, Input, Modal, Result, Space, Spin} from "antd";
|
import {Button, Card, Input, Modal, Result, Space, Spin} from "antd";
|
||||||
import accountApi, {AuthType} from "@/api/account-api";
|
import accountApi, {AuthType} from "@/api/account-api";
|
||||||
import {startAuthentication} from "@simplewebauthn/browser";
|
import {startAuthentication} from "@simplewebauthn/browser";
|
||||||
@@ -26,7 +26,8 @@ const MultiFactorAuthentication = ({open, handleOk, handleCancel, forceReauth =
|
|||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [otpValue, setOtpValue] = useState('');
|
const [otpValue, setOtpValue] = useState('');
|
||||||
const [showSelector, setShowSelector] = useState(false);
|
const [showSelector, setShowSelector] = useState(false);
|
||||||
const [otpKey, setOtpKey] = useState(0); // 用于强制重新挂载 InputOTP
|
const [otpKey, setOtpKey] = useState(0);
|
||||||
|
const handledRef = useRef(false);
|
||||||
|
|
||||||
// 查询支持的认证类型
|
// 查询支持的认证类型
|
||||||
const {data: supportedAuthTypes = []} = useQuery({
|
const {data: supportedAuthTypes = []} = useQuery({
|
||||||
@@ -58,6 +59,7 @@ const MultiFactorAuthentication = ({open, handleOk, handleCancel, forceReauth =
|
|||||||
setOtpValue('');
|
setOtpValue('');
|
||||||
setShowSelector(false);
|
setShowSelector(false);
|
||||||
setAuthType('');
|
setAuthType('');
|
||||||
|
handledRef.current = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 清除输入
|
// 清除输入
|
||||||
@@ -81,12 +83,10 @@ const MultiFactorAuthentication = ({open, handleOk, handleCancel, forceReauth =
|
|||||||
const validateSecurityToken = () => {
|
const validateSecurityToken = () => {
|
||||||
const securityToken = sessionStorage.getItem('securityToken');
|
const securityToken = sessionStorage.getItem('securityToken');
|
||||||
if (securityToken) {
|
if (securityToken) {
|
||||||
// 检查 Token 是否有效,有效则直接使用
|
|
||||||
accountApi.validateSecurityToken(securityToken).then((ok) => {
|
accountApi.validateSecurityToken(securityToken).then((ok) => {
|
||||||
if (ok) {
|
if (ok) {
|
||||||
storeSecurityToken(securityToken);
|
storeSecurityToken(securityToken);
|
||||||
} else {
|
} else {
|
||||||
// 无效则清除
|
|
||||||
sessionStorage.removeItem('securityToken');
|
sessionStorage.removeItem('securityToken');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -121,7 +121,7 @@ const MultiFactorAuthentication = ({open, handleOk, handleCancel, forceReauth =
|
|||||||
onSuccess: (token) => token && storeSecurityToken(token),
|
onSuccess: (token) => token && storeSecurityToken(token),
|
||||||
onError: (e: any) => {
|
onError: (e: any) => {
|
||||||
setOtpValue('');
|
setOtpValue('');
|
||||||
setOtpKey(prev => prev + 1); // 强制重新挂载以重新获得焦点
|
setOtpKey(prev => prev + 1);
|
||||||
const code = typeof e?.code === 'number' ? e.code : 1;
|
const code = typeof e?.code === 'number' ? e.code : 1;
|
||||||
setError({code, message: e?.message || String(e)});
|
setError({code, message: e?.message || String(e)});
|
||||||
}
|
}
|
||||||
@@ -141,8 +141,13 @@ const MultiFactorAuthentication = ({open, handleOk, handleCancel, forceReauth =
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (handledRef.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 没有可用的认证方式,直接通过
|
// 没有可用的认证方式,直接通过
|
||||||
if (supportedAuthTypes.length === 0) {
|
if (supportedAuthTypes.length === 0) {
|
||||||
|
handledRef.current = true;
|
||||||
handleOk('');
|
handleOk('');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -153,7 +158,6 @@ const MultiFactorAuthentication = ({open, handleOk, handleCancel, forceReauth =
|
|||||||
setAuthType(supportedAuthTypes[0]);
|
setAuthType(supportedAuthTypes[0]);
|
||||||
setShowSelector(false);
|
setShowSelector(false);
|
||||||
} else {
|
} else {
|
||||||
// 有可用的认证方式
|
|
||||||
if (!authType || authType === 'none') {
|
if (!authType || authType === 'none') {
|
||||||
setAuthType('');
|
setAuthType('');
|
||||||
setShowSelector(true);
|
setShowSelector(true);
|
||||||
@@ -170,8 +174,7 @@ const MultiFactorAuthentication = ({open, handleOk, handleCancel, forceReauth =
|
|||||||
}, [authType, showSelector, open]);
|
}, [authType, showSelector, open]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open && !forceReauth) {
|
if (open && !forceReauth && !handledRef.current) {
|
||||||
// 检查是否有存储的 securityToken
|
|
||||||
validateSecurityToken();
|
validateSecurityToken();
|
||||||
}
|
}
|
||||||
}, [open, forceReauth]);
|
}, [open, forceReauth]);
|
||||||
|
|||||||
@@ -93,24 +93,14 @@ const AuthorisedAssetPost = () => {
|
|||||||
}}
|
}}
|
||||||
request={async () => {
|
request={async () => {
|
||||||
let items = await assetApi.getGroups();
|
let items = await assetApi.getGroups();
|
||||||
// let selected = await authorisedAssetApi.selected('assetId', userId, userGroupId, '');
|
function processNode(item: any) {
|
||||||
// 递归把 key 字段设置为 value,并且非叶子节点全部 disabled
|
item.value = item.id;
|
||||||
function setKeyAndDisabled(item: any) {
|
|
||||||
item.value = item.key;
|
|
||||||
if (!item.isLeaf) {
|
|
||||||
// 递归处理子节点
|
|
||||||
if (item.children) {
|
if (item.children) {
|
||||||
item.children.forEach(setKeyAndDisabled);
|
item.children.forEach(processNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if (selected.includes(item.key)) {
|
|
||||||
// item.disabled = true;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
// 对获取到的所有节点进行处理
|
|
||||||
items.forEach((item: any) => {
|
items.forEach((item: any) => {
|
||||||
setKeyAndDisabled(item);
|
processNode(item);
|
||||||
});
|
});
|
||||||
return items;
|
return items;
|
||||||
}}
|
}}
|
||||||
@@ -127,28 +117,19 @@ const AuthorisedAssetPost = () => {
|
|||||||
}}
|
}}
|
||||||
request={async () => {
|
request={async () => {
|
||||||
let items = await assetApi.tree();
|
let items = await assetApi.tree();
|
||||||
// let selected = await authorisedAssetApi.selected('assetId', userId, userGroupId, '');
|
function processNode(item: any) {
|
||||||
|
item.value = item.id;
|
||||||
// 递归把 key 字段设置为 value,并且非叶子节点全部 disabled
|
|
||||||
function setKeyAndDisabled(item: any) {
|
|
||||||
item.value = item.key;
|
|
||||||
if (!item.isLeaf) {
|
if (!item.isLeaf) {
|
||||||
item.disabled = true;
|
item.disabled = true;
|
||||||
// 递归处理子节点
|
|
||||||
if (item.children) {
|
|
||||||
item.children.forEach(setKeyAndDisabled);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
item.title = item.title + ' (' + item.extra?.network + ')';
|
item.title = item.title + ' (' + item.extra?.network + ')';
|
||||||
}
|
}
|
||||||
// if (selected.includes(item.key)) {
|
if (item.children) {
|
||||||
// item.disabled = true;
|
item.children.forEach(processNode);
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 对获取到的所有节点进行处理
|
|
||||||
items.forEach((item: any) => {
|
items.forEach((item: any) => {
|
||||||
setKeyAndDisabled(item);
|
processNode(item);
|
||||||
});
|
});
|
||||||
return items;
|
return items;
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -29,7 +29,18 @@ const GatewayGroupDrawer: React.FC<Props> = ({open, group, onClose}) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (open && group) {
|
if (open && group) {
|
||||||
form.setFieldsValue(group);
|
let members = group.members;
|
||||||
|
if (typeof members === 'string') {
|
||||||
|
try {
|
||||||
|
members = JSON.parse(members);
|
||||||
|
} catch {
|
||||||
|
members = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
form.setFieldsValue({
|
||||||
|
...group,
|
||||||
|
members,
|
||||||
|
});
|
||||||
} else if (open) {
|
} else if (open) {
|
||||||
form.resetFields();
|
form.resetFields();
|
||||||
form.setFieldsValue({
|
form.setFieldsValue({
|
||||||
@@ -41,10 +52,14 @@ const GatewayGroupDrawer: React.FC<Props> = ({open, group, onClose}) => {
|
|||||||
|
|
||||||
const handleSubmit = async (values: any) => {
|
const handleSubmit = async (values: any) => {
|
||||||
try {
|
try {
|
||||||
|
const submitData = {
|
||||||
|
...values,
|
||||||
|
members: JSON.stringify(values.members || []),
|
||||||
|
};
|
||||||
if (group?.id) {
|
if (group?.id) {
|
||||||
await gatewayGroupApi.updateById(group.id, values);
|
await gatewayGroupApi.updateById(group.id, submitData);
|
||||||
} else {
|
} else {
|
||||||
await gatewayGroupApi.create(values);
|
await gatewayGroupApi.create(submitData);
|
||||||
}
|
}
|
||||||
message.success(t('general.success'));
|
message.success(t('general.success'));
|
||||||
onClose(true);
|
onClose(true);
|
||||||
|
|||||||
@@ -43,6 +43,16 @@ const GatewayGroupPage: React.FC = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const parseMembers = (members: string | undefined): any[] => {
|
||||||
|
if (!members) return [];
|
||||||
|
if (Array.isArray(members)) return members;
|
||||||
|
try {
|
||||||
|
return JSON.parse(members);
|
||||||
|
} catch {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const columns: ProColumns<GatewayGroup>[] = [
|
const columns: ProColumns<GatewayGroup>[] = [
|
||||||
{
|
{
|
||||||
title: t('gateway_group.name'),
|
title: t('gateway_group.name'),
|
||||||
@@ -69,8 +79,9 @@ const GatewayGroupPage: React.FC = () => {
|
|||||||
dataIndex: 'members',
|
dataIndex: 'members',
|
||||||
width: 100,
|
width: 100,
|
||||||
render: (_, record) => {
|
render: (_, record) => {
|
||||||
const enabledCount = record.members?.filter(m => m.enabled).length || 0;
|
const members = parseMembers(record.members as unknown as string);
|
||||||
const totalCount = record.members?.length || 0;
|
const enabledCount = members.filter(m => m.enabled).length;
|
||||||
|
const totalCount = members.length;
|
||||||
return `${enabledCount}/${totalCount}`;
|
return `${enabledCount}/${totalCount}`;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -194,7 +194,25 @@ const ScheduledTaskLogPage = ({open, jobId, handleCancel}: Props) => {
|
|||||||
title: t('sysops.logs.result'),
|
title: t('sysops.logs.result'),
|
||||||
dataIndex: 'result',
|
dataIndex: 'result',
|
||||||
key: 'result',
|
key: 'result',
|
||||||
valueType: 'code',
|
width: 200,
|
||||||
|
render: (text: string) => {
|
||||||
|
if (!text) return <Text type="secondary">-</Text>
|
||||||
|
return (
|
||||||
|
<div style={{
|
||||||
|
maxHeight: 60,
|
||||||
|
overflow: 'auto',
|
||||||
|
backgroundColor: '#f5f5f5',
|
||||||
|
padding: '4px 8px',
|
||||||
|
borderRadius: '4px',
|
||||||
|
fontSize: '12px',
|
||||||
|
fontFamily: 'monospace',
|
||||||
|
whiteSpace: 'pre-wrap',
|
||||||
|
wordBreak: 'break-all',
|
||||||
|
}}>
|
||||||
|
{text}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
case 'renew-certificate':
|
case 'renew-certificate':
|
||||||
@@ -244,6 +262,7 @@ const ScheduledTaskLogPage = ({open, jobId, handleCancel}: Props) => {
|
|||||||
options={false}
|
options={false}
|
||||||
dataSource={record.results}
|
dataSource={record.results}
|
||||||
pagination={false}
|
pagination={false}
|
||||||
|
rowKey={(r: any, index: number) => r.name || r.id || index}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {Col, Modal, Popover, Row} from "antd";
|
|||||||
import scheduledTaskApi, {ScheduledTask} from "@/api/scheduled-task-api";
|
import scheduledTaskApi, {ScheduledTask} from "@/api/scheduled-task-api";
|
||||||
import assetApi from "@/api/asset-api";
|
import assetApi from "@/api/asset-api";
|
||||||
import ScheduledTaskRuntime from "@/pages/sysops/ScheduledTaskRuntime";
|
import ScheduledTaskRuntime from "@/pages/sysops/ScheduledTaskRuntime";
|
||||||
|
import {useQuery} from "@tanstack/react-query";
|
||||||
|
|
||||||
const ScheduledTaskModal = ({
|
const ScheduledTaskModal = ({
|
||||||
open,
|
open,
|
||||||
@@ -23,13 +24,33 @@ const ScheduledTaskModal = ({
|
|||||||
}: Props) => {
|
}: Props) => {
|
||||||
let {t} = useTranslation();
|
let {t} = useTranslation();
|
||||||
const formRef = useRef<ProFormInstance>(null);
|
const formRef = useRef<ProFormInstance>(null);
|
||||||
let [spec, setSpec] = useState('');
|
|
||||||
let [runtimeOpen, setRuntimeOpen] = useState(false);
|
let [runtimeOpen, setRuntimeOpen] = useState(false);
|
||||||
|
let [specForRuntime, setSpecForRuntime] = useState('');
|
||||||
|
|
||||||
|
const {data: assetTreeData} = useQuery({
|
||||||
|
queryKey: ['asset-tree', 'ssh'],
|
||||||
|
queryFn: async () => {
|
||||||
|
let items = await assetApi.tree('ssh');
|
||||||
|
function processItem(item: any) {
|
||||||
|
item.value = item.value || item.key || item.id;
|
||||||
|
item.title = item.title || item.name || '';
|
||||||
|
if (item.isLeaf && item.extra?.network) {
|
||||||
|
item.title = item.title + ' (' + item.extra.network + ')';
|
||||||
|
}
|
||||||
|
if (item.children && item.children.length > 0) {
|
||||||
|
item.children.forEach(processItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (items && items.length > 0) {
|
||||||
|
items.forEach(processItem);
|
||||||
|
}
|
||||||
|
return items || [];
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const get = async () => {
|
const get = async () => {
|
||||||
if (id) {
|
if (id) {
|
||||||
let data = await scheduledTaskApi.getById(id);
|
let data = await scheduledTaskApi.getById(id);
|
||||||
setSpec(data.spec);
|
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
@@ -38,6 +59,14 @@ const ScheduledTaskModal = ({
|
|||||||
} as ScheduledTask;
|
} as ScheduledTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleRuntimeOpenChange = (open: boolean) => {
|
||||||
|
if (open) {
|
||||||
|
const currentSpec = formRef.current?.getFieldValue('spec') || '';
|
||||||
|
setSpecForRuntime(currentSpec);
|
||||||
|
}
|
||||||
|
setRuntimeOpen(open);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
@@ -82,20 +111,14 @@ const ScheduledTaskModal = ({
|
|||||||
rules={[{required: true}]}
|
rules={[{required: true}]}
|
||||||
tooltip={t('sysops.spec_tooltip')}
|
tooltip={t('sysops.spec_tooltip')}
|
||||||
fieldProps={{
|
fieldProps={{
|
||||||
value: spec,
|
|
||||||
onChange: (e) => {
|
|
||||||
setSpec(e.target.value);
|
|
||||||
},
|
|
||||||
addonAfter: <div className={'cursor-pointer'}>
|
addonAfter: <div className={'cursor-pointer'}>
|
||||||
<Popover
|
<Popover
|
||||||
content={<ScheduledTaskRuntime open={runtimeOpen} spec={spec}/>}
|
content={runtimeOpen ? <ScheduledTaskRuntime open={runtimeOpen} spec={specForRuntime}/> : null}
|
||||||
title={t('sysops.spec_run_time')}
|
title={t('sysops.spec_run_time')}
|
||||||
trigger="click"
|
trigger="click"
|
||||||
placement="rightTop"
|
placement="rightTop"
|
||||||
open={runtimeOpen}
|
open={runtimeOpen}
|
||||||
onOpenChange={(open) => {
|
onOpenChange={handleRuntimeOpenChange}
|
||||||
setRuntimeOpen(open);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{t('sysops.spec_run')}
|
{t('sysops.spec_run')}
|
||||||
</Popover>
|
</Popover>
|
||||||
@@ -135,34 +158,12 @@ const ScheduledTaskModal = ({
|
|||||||
name='assetIdList'
|
name='assetIdList'
|
||||||
rules={[{required: true}]}
|
rules={[{required: true}]}
|
||||||
fieldProps={{
|
fieldProps={{
|
||||||
|
treeData: assetTreeData || [],
|
||||||
multiple: true,
|
multiple: true,
|
||||||
showSearch: true,
|
showSearch: true,
|
||||||
treeDefaultExpandAll: true,
|
treeDefaultExpandAll: true,
|
||||||
treeNodeFilterProp: "title",
|
treeNodeFilterProp: "title",
|
||||||
}}
|
}}
|
||||||
request={async () => {
|
|
||||||
let items = await assetApi.tree('ssh');
|
|
||||||
|
|
||||||
// 递归把 key 字段设置为 value,并且非叶子节点全部 disabled
|
|
||||||
function setKeyAndDisabled(item: any) {
|
|
||||||
item.value = item.key;
|
|
||||||
if (!item.isLeaf) {
|
|
||||||
// item.disabled = true;
|
|
||||||
// 递归处理子节点
|
|
||||||
if (item.children) {
|
|
||||||
item.children.forEach(setKeyAndDisabled);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
item.title = item.title + ' (' + item.extra?.network + ')';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 对获取到的所有节点进行处理
|
|
||||||
items.forEach((item: any) => {
|
|
||||||
setKeyAndDisabled(item);
|
|
||||||
});
|
|
||||||
return items;
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
return <></>
|
return <></>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, {useEffect} from 'react';
|
import React from 'react';
|
||||||
import {useQuery} from "@tanstack/react-query";
|
import {useQuery} from "@tanstack/react-query";
|
||||||
import scheduledTaskApi from '@/api/scheduled-task-api';
|
import scheduledTaskApi from '@/api/scheduled-task-api';
|
||||||
|
|
||||||
@@ -14,22 +14,16 @@ const ScheduledTaskRuntime = ({open, spec}: Props) => {
|
|||||||
queryFn: () => {
|
queryFn: () => {
|
||||||
return scheduledTaskApi.getNextTenRuns(spec);
|
return scheduledTaskApi.getNextTenRuns(spec);
|
||||||
},
|
},
|
||||||
enabled: open,
|
enabled: open && !!spec,
|
||||||
retry: false,
|
retry: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (open) {
|
|
||||||
query.refetch();
|
|
||||||
}
|
|
||||||
}, [open]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={''}>
|
<div className={''}>
|
||||||
{query.isError && <div className={'text-red-500'}>Error: {query.error?.message}</div>}
|
{query.isError && <div className={'text-red-500'}>Error: {query.error?.message}</div>}
|
||||||
<div className={'space-y-1'}>
|
<div className={'space-y-1'}>
|
||||||
{Array.isArray(query.data) ? query.data.map((item: any) => {
|
{Array.isArray(query.data) ? query.data.map((item: any, index: number) => {
|
||||||
return <div key={item.id}>{item}</div>
|
return <div key={index}>{item}</div>
|
||||||
}) : []}
|
}) : []}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -23,6 +23,11 @@ const ToolsPing = () => {
|
|||||||
setLogs((prevLogs) => [...prevLogs, event.data]);
|
setLogs((prevLogs) => [...prevLogs, event.data]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
eventSource.addEventListener('done', () => {
|
||||||
|
eventSource?.close();
|
||||||
|
setRunning(false);
|
||||||
|
});
|
||||||
|
|
||||||
eventSource.onerror = () => {
|
eventSource.onerror = () => {
|
||||||
eventSource?.close();
|
eventSource?.close();
|
||||||
setRunning(false);
|
setRunning(false);
|
||||||
@@ -67,8 +72,8 @@ const ToolsPing = () => {
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
<div className='border rounded-lg p-4 flex-grow'>
|
<div className='border rounded-lg p-4 flex-grow overflow-auto'>
|
||||||
<pre>{logs.join("\n")}</pre>
|
<pre className='whitespace-pre-wrap break-all'>{logs.join("\n")}</pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {Button, Form, Input, InputNumber, Space} from 'antd';
|
import {Button, Form, Input, InputNumber} from 'antd';
|
||||||
import React, {useState} from 'react';
|
import React, {useState} from 'react';
|
||||||
import {baseUrl, getToken} from "@/api/core/requests";
|
import {baseUrl, getToken} from "@/api/core/requests";
|
||||||
import {useTranslation} from "react-i18next";
|
import {useTranslation} from "react-i18next";
|
||||||
@@ -15,7 +15,7 @@ const ToolsTcping = () => {
|
|||||||
let eventSource: EventSource | null = null;
|
let eventSource: EventSource | null = null;
|
||||||
|
|
||||||
const onSearch = (host: string, port: number) => {
|
const onSearch = (host: string, port: number) => {
|
||||||
if (running) return; // 防止重复启动
|
if (running) return;
|
||||||
setRunning(true);
|
setRunning(true);
|
||||||
setLogs([]);
|
setLogs([]);
|
||||||
|
|
||||||
@@ -25,6 +25,11 @@ const ToolsTcping = () => {
|
|||||||
setLogs((prevLogs) => [...prevLogs, event.data]);
|
setLogs((prevLogs) => [...prevLogs, event.data]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
eventSource.addEventListener('done', () => {
|
||||||
|
eventSource?.close();
|
||||||
|
setRunning(false);
|
||||||
|
});
|
||||||
|
|
||||||
eventSource.onerror = () => {
|
eventSource.onerror = () => {
|
||||||
eventSource?.close();
|
eventSource?.close();
|
||||||
setRunning(false);
|
setRunning(false);
|
||||||
@@ -79,8 +84,8 @@ const ToolsTcping = () => {
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
<div className='border rounded-lg p-4 flex-grow'>
|
<div className='border rounded-lg p-4 flex-grow overflow-auto'>
|
||||||
<pre>{logs.join("\n")}</pre>
|
<pre className='whitespace-pre-wrap break-all'>{logs.join("\n")}</pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -50,7 +50,8 @@
|
|||||||
"upload": "上传",
|
"upload": "上传",
|
||||||
"offline": "离线",
|
"offline": "离线",
|
||||||
"online": "在线",
|
"online": "在线",
|
||||||
"search_placeholder": "关键词搜索"
|
"search_placeholder": "关键词搜索",
|
||||||
|
"max_length": "最大长度为 {{max}} 个字符"
|
||||||
},
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
"new": "新建",
|
"new": "新建",
|
||||||
@@ -1834,5 +1835,101 @@
|
|||||||
"403": "没有权限执行此操作",
|
"403": "没有权限执行此操作",
|
||||||
"404": "请求的资源不存在",
|
"404": "请求的资源不存在",
|
||||||
"500": "服务器内部错误"
|
"500": "服务器内部错误"
|
||||||
|
},
|
||||||
|
"permissions": {
|
||||||
|
"dashboard": "数据概览",
|
||||||
|
"asset-access": "访问资产",
|
||||||
|
"asset-add": "新增资产",
|
||||||
|
"asset-edit": "编辑资产",
|
||||||
|
"asset-del": "删除资产",
|
||||||
|
"asset-copy": "复制资产",
|
||||||
|
"asset-conn-test": "连接测试",
|
||||||
|
"asset-import": "导入资产",
|
||||||
|
"asset-change-owner": "修改所有者",
|
||||||
|
"asset-authorised-user-add": "授权用户",
|
||||||
|
"asset-authorised-user-del": "取消授权用户",
|
||||||
|
"asset-authorised-user-group-add": "授权用户组",
|
||||||
|
"asset-authorised-user-group-del": "取消授权用户组",
|
||||||
|
"credential-add": "新增凭证",
|
||||||
|
"credential-del": "删除凭证",
|
||||||
|
"credential-edit": "编辑凭证",
|
||||||
|
"command-add": "新增命令",
|
||||||
|
"command-edit": "编辑命令",
|
||||||
|
"command-del": "删除命令",
|
||||||
|
"command-exec": "执行命令",
|
||||||
|
"command-change-owner": "修改所有者",
|
||||||
|
"access-gateway-add": "新增网关",
|
||||||
|
"access-gateway-del": "删除网关",
|
||||||
|
"access-gateway-edit": "编辑网关",
|
||||||
|
"online-session-disconnect": "断开会话",
|
||||||
|
"online-session-monitor": "监控会话",
|
||||||
|
"offline-session-playback": "回放会话",
|
||||||
|
"offline-session-del": "删除会话",
|
||||||
|
"offline-session-clear": "清空会话",
|
||||||
|
"offline-session-command": "命令记录",
|
||||||
|
"offline-session-reviewed": "标记已阅",
|
||||||
|
"offline-session-unreviewed": "标记未读",
|
||||||
|
"offline-session-reviewed-all": "全部标记已阅",
|
||||||
|
"login-log-del": "删除登录日志",
|
||||||
|
"login-log-clear": "清空登录日志",
|
||||||
|
"storage-log-del": "删除文件日志",
|
||||||
|
"storage-log-clear": "清空文件日志",
|
||||||
|
"session-command": "命令日志",
|
||||||
|
"job-add": "新增任务",
|
||||||
|
"job-del": "删除任务",
|
||||||
|
"job-edit": "编辑任务",
|
||||||
|
"job-run": "执行任务",
|
||||||
|
"job-change-status": "修改状态",
|
||||||
|
"job-log": "任务日志",
|
||||||
|
"job-log-clear": "清空日志",
|
||||||
|
"storage-add": "新增存储",
|
||||||
|
"storage-del": "删除存储",
|
||||||
|
"storage-edit": "编辑存储",
|
||||||
|
"storage-browse-download": "下载文件",
|
||||||
|
"storage-browse-upload": "上传文件",
|
||||||
|
"storage-browse-mkdir": "创建目录",
|
||||||
|
"storage-browse-rm": "删除文件",
|
||||||
|
"storage-browse-rename": "重命名",
|
||||||
|
"storage-browse-edit": "编辑文件",
|
||||||
|
"monitoring": "系统监控",
|
||||||
|
"access-security-add": "新增规则",
|
||||||
|
"access-security-del": "删除规则",
|
||||||
|
"access-security-edit": "编辑规则",
|
||||||
|
"login-policy-add": "新增策略",
|
||||||
|
"login-policy-del": "删除策略",
|
||||||
|
"login-policy-edit": "编辑策略",
|
||||||
|
"login-policy-bind-user": "绑定用户",
|
||||||
|
"user-add": "新增用户",
|
||||||
|
"user-del": "删除用户",
|
||||||
|
"user-edit": "编辑用户",
|
||||||
|
"user-change-password": "修改密码",
|
||||||
|
"user-enable-disable": "启用/禁用",
|
||||||
|
"user-reset-totp": "重置OTP",
|
||||||
|
"user-bind-asset": "绑定资产",
|
||||||
|
"user-unbind-asset": "解绑资产",
|
||||||
|
"login-policy-unbind-user": "解绑用户",
|
||||||
|
"user-unbind-login-policy": "解绑策略",
|
||||||
|
"role-add": "新增角色",
|
||||||
|
"role-del": "删除角色",
|
||||||
|
"role-edit": "编辑角色",
|
||||||
|
"role-detail": "角色详情",
|
||||||
|
"user-group-add": "新增用户组",
|
||||||
|
"user-group-del": "删除用户组",
|
||||||
|
"user-group-edit": "编辑用户组",
|
||||||
|
"user-group-detail": "用户组详情",
|
||||||
|
"user-group-bind-asset": "绑定资产",
|
||||||
|
"user-group-unbind-asset": "解绑资产",
|
||||||
|
"command-filter-add": "新增拦截器",
|
||||||
|
"command-filter-del": "删除拦截器",
|
||||||
|
"command-filter-edit": "编辑拦截器",
|
||||||
|
"command-filter-rule-add": "新增规则",
|
||||||
|
"command-filter-rule-put": "修改规则",
|
||||||
|
"command-filter-rule-del": "删除规则",
|
||||||
|
"strategy-add": "新增策略",
|
||||||
|
"strategy-edit": "编辑策略",
|
||||||
|
"strategy-del": "删除策略",
|
||||||
|
"strategy-detail": "策略详情",
|
||||||
|
"setting": "系统设置",
|
||||||
|
"info": "系统信息"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user