mirror of
https://gitee.com/goploy/goploy.git
synced 2024-12-02 04:07:33 +08:00
A support delete file via sftp
This commit is contained in:
parent
a810b166f3
commit
6c28feb060
@ -43,6 +43,7 @@ func (s Server) Routes() []core.Route {
|
|||||||
core.NewRoute("/server/previewFile", http.MethodGet, s.PreviewFile).Permissions(permission.SFTPPreviewFile).LogFunc(middleware.AddPreviewLog),
|
core.NewRoute("/server/previewFile", http.MethodGet, s.PreviewFile).Permissions(permission.SFTPPreviewFile).LogFunc(middleware.AddPreviewLog),
|
||||||
core.NewRoute("/server/downloadFile", http.MethodGet, s.DownloadFile).Permissions(permission.SFTPDownloadFile).LogFunc(middleware.AddDownloadLog),
|
core.NewRoute("/server/downloadFile", http.MethodGet, s.DownloadFile).Permissions(permission.SFTPDownloadFile).LogFunc(middleware.AddDownloadLog),
|
||||||
core.NewRoute("/server/uploadFile", http.MethodPost, s.UploadFile).Permissions(permission.SFTPTransferFile).LogFunc(middleware.AddUploadLog),
|
core.NewRoute("/server/uploadFile", http.MethodPost, s.UploadFile).Permissions(permission.SFTPTransferFile).LogFunc(middleware.AddUploadLog),
|
||||||
|
core.NewRoute("/server/deleteFile", http.MethodDelete, s.DeleteFile).Permissions(permission.SFTPDeleteFile).LogFunc(middleware.AddDeleteLog),
|
||||||
core.NewRoute("/server/transferFile", http.MethodPost, s.TransferFile).Permissions(permission.SFTPUploadFile),
|
core.NewRoute("/server/transferFile", http.MethodPost, s.TransferFile).Permissions(permission.SFTPUploadFile),
|
||||||
core.NewRoute("/server/report", http.MethodGet, s.Report).Permissions(permission.ShowServerMonitorPage),
|
core.NewRoute("/server/report", http.MethodGet, s.Report).Permissions(permission.ShowServerMonitorPage),
|
||||||
core.NewRoute("/server/getAllMonitor", http.MethodGet, s.GetAllMonitor).Permissions(permission.ShowServerMonitorPage),
|
core.NewRoute("/server/getAllMonitor", http.MethodGet, s.GetAllMonitor).Permissions(permission.ShowServerMonitorPage),
|
||||||
@ -544,6 +545,50 @@ func (Server) UploadFile(gp *core.Goploy) core.Response {
|
|||||||
|
|
||||||
return response.JSON{}
|
return response.JSON{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (Server) DeleteFile(gp *core.Goploy) core.Response {
|
||||||
|
type ReqData struct {
|
||||||
|
File string `json:"file" validate:"required"`
|
||||||
|
ServerID int64 `json:"serverId" validate:"gt=0"`
|
||||||
|
}
|
||||||
|
var reqData ReqData
|
||||||
|
if err := decodeJson(gp.Body, &reqData); err != nil {
|
||||||
|
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||||
|
}
|
||||||
|
|
||||||
|
server, err := (model.Server{ID: reqData.ServerID}).GetData()
|
||||||
|
if err != nil {
|
||||||
|
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||||
|
}
|
||||||
|
client, err := server.ToSSHConfig().Dial()
|
||||||
|
if err != nil {
|
||||||
|
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||||
|
}
|
||||||
|
defer client.Close()
|
||||||
|
|
||||||
|
sftpClient, err := sftp.NewClient(client)
|
||||||
|
if err != nil {
|
||||||
|
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||||
|
}
|
||||||
|
defer sftpClient.Close()
|
||||||
|
|
||||||
|
fi, err := sftpClient.Stat(reqData.File)
|
||||||
|
if err != nil {
|
||||||
|
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||||
|
}
|
||||||
|
if fi.IsDir() == true {
|
||||||
|
err = sftpClient.RemoveDirectory(reqData.File)
|
||||||
|
} else {
|
||||||
|
err = sftpClient.Remove(reqData.File)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return response.JSON{Code: response.Error, Message: err.Error()}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.JSON{}
|
||||||
|
}
|
||||||
|
|
||||||
func (Server) TransferFile(gp *core.Goploy) core.Response {
|
func (Server) TransferFile(gp *core.Goploy) core.Response {
|
||||||
type ReqData struct {
|
type ReqData struct {
|
||||||
SourceServerID int64 `json:"sourceServerId" validate:"required"`
|
SourceServerID int64 `json:"sourceServerId" validate:"required"`
|
||||||
|
@ -96,6 +96,36 @@ func AddUploadLog(gp *core.Goploy, resp core.Response) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AddDeleteLog(gp *core.Goploy, resp core.Response) {
|
||||||
|
var serverID int64 = 0
|
||||||
|
var path = ""
|
||||||
|
respJson := resp.(response.JSON)
|
||||||
|
if respJson.Code != response.IllegalParam {
|
||||||
|
type ReqData struct {
|
||||||
|
ServerID int64 `json:"account"`
|
||||||
|
File string `json:"file"`
|
||||||
|
}
|
||||||
|
var reqData ReqData
|
||||||
|
_ = json.Unmarshal(gp.Body, &reqData)
|
||||||
|
serverID = reqData.ServerID
|
||||||
|
path = reqData.File
|
||||||
|
}
|
||||||
|
|
||||||
|
err := model.SftpLog{
|
||||||
|
NamespaceID: gp.Namespace.ID,
|
||||||
|
UserID: gp.UserInfo.ID,
|
||||||
|
ServerID: serverID,
|
||||||
|
RemoteAddr: gp.Request.RemoteAddr,
|
||||||
|
UserAgent: gp.Request.UserAgent(),
|
||||||
|
Type: model.SftpLogTypeDelete,
|
||||||
|
Path: path,
|
||||||
|
Reason: respJson.Message,
|
||||||
|
}.AddRow()
|
||||||
|
if err != nil {
|
||||||
|
core.Log(core.ERROR, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func AddDownloadLog(gp *core.Goploy, resp core.Response) {
|
func AddDownloadLog(gp *core.Goploy, resp core.Response) {
|
||||||
msg := ""
|
msg := ""
|
||||||
path := ""
|
path := ""
|
||||||
|
@ -32,6 +32,7 @@ const (
|
|||||||
SftpLogTypeUpload = "UPLOAD"
|
SftpLogTypeUpload = "UPLOAD"
|
||||||
SftpLogTypeRead = "READ"
|
SftpLogTypeRead = "READ"
|
||||||
SftpLogTypePreview = "PREVIEW"
|
SftpLogTypePreview = "PREVIEW"
|
||||||
|
SftpLogTypeDelete = "DELETE"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SftpLogs []SftpLog
|
type SftpLogs []SftpLog
|
||||||
|
1
model/sql/1.12.2.sql
Normal file
1
model/sql/1.12.2.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (76, 23, 'SFTPDeleteFile', 0, '');
|
@ -455,6 +455,7 @@ INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALU
|
|||||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (73, 23, 'DeleteServerProcess', 0, '');
|
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (73, 23, 'DeleteServerProcess', 0, '');
|
||||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (74, 1, 'ShowOperationLogPage', 0, '');
|
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (74, 1, 'ShowOperationLogPage', 0, '');
|
||||||
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (75, 23, 'SFTPTransferFile', 0, '');
|
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (75, 23, 'SFTPTransferFile', 0, '');
|
||||||
|
INSERT IGNORE INTO `permission`(`id`, `pid`, `name`, `sort`, `description`) VALUES (76, 23, 'SFTPDeleteFile', 0, '');
|
||||||
INSERT IGNORE INTO `role_permission`(`role_id`, `permission_id`) VALUES (1, 13);
|
INSERT IGNORE INTO `role_permission`(`role_id`, `permission_id`) VALUES (1, 13);
|
||||||
INSERT IGNORE INTO `role_permission`(`role_id`, `permission_id`) VALUES (1, 14);
|
INSERT IGNORE INTO `role_permission`(`role_id`, `permission_id`) VALUES (1, 14);
|
||||||
INSERT IGNORE INTO `role_permission`(`role_id`, `permission_id`) VALUES (1, 15);
|
INSERT IGNORE INTO `role_permission`(`role_id`, `permission_id`) VALUES (1, 15);
|
||||||
|
@ -80,4 +80,5 @@ const (
|
|||||||
DeleteServerProcess = 73
|
DeleteServerProcess = 73
|
||||||
ShowOperationLogPage = 74
|
ShowOperationLogPage = 74
|
||||||
SFTPTransferFile = 75
|
SFTPTransferFile = 75
|
||||||
|
SFTPDeleteFile = 76
|
||||||
)
|
)
|
||||||
|
@ -394,6 +394,19 @@ export class ServerExecProcess extends Request {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ServerDeleteFile extends Request {
|
||||||
|
readonly url = '/server/deleteFile'
|
||||||
|
readonly method = 'delete'
|
||||||
|
readonly timeout = 0
|
||||||
|
public param: {
|
||||||
|
serverId: number
|
||||||
|
file: string
|
||||||
|
}
|
||||||
|
constructor(param: ServerDeleteFile['param']) {
|
||||||
|
super()
|
||||||
|
this.param = param
|
||||||
|
}
|
||||||
|
}
|
||||||
export class ServerTransferFile extends Request {
|
export class ServerTransferFile extends Request {
|
||||||
readonly url = '/server/transferFile'
|
readonly url = '/server/transferFile'
|
||||||
readonly method = 'post'
|
readonly method = 'post'
|
||||||
@ -410,7 +423,6 @@ export class ServerTransferFile extends Request {
|
|||||||
this.param = param
|
this.param = param
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ServerExecScript extends Request {
|
export class ServerExecScript extends Request {
|
||||||
readonly url = '/server/execScript'
|
readonly url = '/server/execScript'
|
||||||
readonly method = 'post'
|
readonly method = 'post'
|
||||||
|
@ -230,7 +230,8 @@
|
|||||||
"AddServerProcess": "Add a server process",
|
"AddServerProcess": "Add a server process",
|
||||||
"EditServerProcess": "Edit the server process",
|
"EditServerProcess": "Edit the server process",
|
||||||
"DeleteServerProcess": "Delete the server process",
|
"DeleteServerProcess": "Delete the server process",
|
||||||
"SFTPTransferFile": "Can transfer file via SFTP"
|
"SFTPTransferFile": "Can transfer file via SFTP",
|
||||||
|
"SFTPDeleteFile": "Can delete file via SFTP"
|
||||||
},
|
},
|
||||||
"tagsView": {
|
"tagsView": {
|
||||||
"refresh": "Refresh",
|
"refresh": "Refresh",
|
||||||
|
@ -230,7 +230,8 @@
|
|||||||
"EditServerProcess": "编辑服务器进程",
|
"EditServerProcess": "编辑服务器进程",
|
||||||
"DeleteServerProcess": "删除服务器进程",
|
"DeleteServerProcess": "删除服务器进程",
|
||||||
"ShowOperationLogPage": "查看操作日志",
|
"ShowOperationLogPage": "查看操作日志",
|
||||||
"SFTPTransferFile": "SFTP传输文件"
|
"SFTPTransferFile": "SFTP传输文件",
|
||||||
|
"SFTPDeleteFile": "SFTP删除文件"
|
||||||
},
|
},
|
||||||
"tagsView": {
|
"tagsView": {
|
||||||
"refresh": "刷新",
|
"refresh": "刷新",
|
||||||
|
@ -74,4 +74,5 @@ export default Object.freeze({
|
|||||||
DeleteServerProcess: 73,
|
DeleteServerProcess: 73,
|
||||||
ShowOperationLogPage: 74,
|
ShowOperationLogPage: 74,
|
||||||
SFTPTransferFile: 75,
|
SFTPTransferFile: 75,
|
||||||
|
SFTPDeleteFile: 76,
|
||||||
})
|
})
|
||||||
|
@ -171,6 +171,13 @@
|
|||||||
{{ $t('download') }}
|
{{ $t('download') }}
|
||||||
</Link>
|
</Link>
|
||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
|
<DropdownItem
|
||||||
|
v-if="selectedFile['isDir'] === false"
|
||||||
|
:permissions="[permission.SFTPDeleteFile]"
|
||||||
|
@click="deleteFile"
|
||||||
|
>
|
||||||
|
{{ $t('delete') }}
|
||||||
|
</DropdownItem>
|
||||||
<DropdownItem
|
<DropdownItem
|
||||||
:permissions="[permission.SFTPTransferFile]"
|
:permissions="[permission.SFTPTransferFile]"
|
||||||
@click="transferFile"
|
@click="transferFile"
|
||||||
@ -188,9 +195,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-show="selectedFile['mode']">
|
<div v-show="selectedFile['mode']">
|
||||||
<span style="padding: 0 2px">{{ selectedFile['mode'] }}</span>
|
<span style="padding: 0 2px">{{ selectedFile['mode'] }}</span>
|
||||||
<span style="padding: 0 2px">{{
|
<span style="padding: 0 2px">
|
||||||
humanSize(selectedFile['size'])
|
{{ humanSize(selectedFile['size']) }}
|
||||||
}}</span>
|
</span>
|
||||||
<span style="padding: 0 2px">{{ selectedFile['name'] }}</span>
|
<span style="padding: 0 2px">{{ selectedFile['name'] }}</span>
|
||||||
</div>
|
</div>
|
||||||
</el-row>
|
</el-row>
|
||||||
@ -216,7 +223,7 @@ import path from 'path-browserify'
|
|||||||
import { humanSize, parseTime } from '@/utils'
|
import { humanSize, parseTime } from '@/utils'
|
||||||
import { NamespaceKey, getNamespaceId } from '@/utils/namespace'
|
import { NamespaceKey, getNamespaceId } from '@/utils/namespace'
|
||||||
import type { ElUpload } from 'element-plus'
|
import type { ElUpload } from 'element-plus'
|
||||||
import { ServerData, ServerSFTPFile } from '@/api/server'
|
import { ServerData, ServerSFTPFile, ServerDeleteFile } from '@/api/server'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { HttpResponse } from '@/api/types'
|
import { HttpResponse } from '@/api/types'
|
||||||
import { ref, PropType, computed, onBeforeUnmount } from 'vue'
|
import { ref, PropType, computed, onBeforeUnmount } from 'vue'
|
||||||
@ -409,6 +416,33 @@ function dirOpen(dir: string) {
|
|||||||
goto(dir)
|
goto(dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deleteFile() {
|
||||||
|
const file = path.normalize(dir.value + '/' + selectedFile.value.name)
|
||||||
|
ElMessageBox.confirm(t('serverPage.deleteTips', { name: file }), t('tips'), {
|
||||||
|
confirmButtonText: t('confirm'),
|
||||||
|
cancelButtonText: t('cancel'),
|
||||||
|
type: 'warning',
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
fileListLoading.value = true
|
||||||
|
new ServerDeleteFile({
|
||||||
|
serverId: serverId.value,
|
||||||
|
file: file,
|
||||||
|
})
|
||||||
|
.request()
|
||||||
|
.then(() => {
|
||||||
|
const pos = fileList.value.findIndex(
|
||||||
|
(item) => item.name === selectedFile.value.name
|
||||||
|
)
|
||||||
|
fileList.value.splice(pos, 1)
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
fileListLoading.value = false
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch()
|
||||||
|
}
|
||||||
|
|
||||||
function transferFile() {
|
function transferFile() {
|
||||||
emit('transfer-file', selectedFile.value)
|
emit('transfer-file', selectedFile.value)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user