Skip to content

Commit aa9021d

Browse files
committed
🎨 Add kernel API /api/file/workspaceCopyFiles
1 parent a1ade99 commit aa9021d

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed

kernel/api/file.go

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,104 @@ func globalCopyFiles(c *gin.Context) {
105105
model.IncSync()
106106
}
107107

108+
func workspaceCopyFiles(c *gin.Context) {
109+
ret := gulu.Ret.NewResult()
110+
defer c.JSON(http.StatusOK, ret)
111+
112+
arg, ok := util.JsonArg(c, ret)
113+
if !ok {
114+
return
115+
}
116+
117+
var srcsArg []any
118+
var destDirArg string // 相对于工作空间的路径
119+
if !util.ParseJsonArgs(arg, ret,
120+
util.BindJsonArg("srcs", &srcsArg, true, true),
121+
util.BindJsonArg("destDir", &destDirArg, true, true),
122+
) {
123+
return
124+
}
125+
126+
var relSrcs []string
127+
for _, s := range srcsArg {
128+
str, ok := s.(string) // 相对于工作空间的路径
129+
if !ok {
130+
ret.Code = -1
131+
ret.Msg = "Field [srcs]: each element should be of type [String]"
132+
return
133+
}
134+
str = strings.TrimSpace(str)
135+
if str == "" {
136+
ret.Code = -1
137+
ret.Msg = "src path must not be empty"
138+
return
139+
}
140+
relSrcs = append(relSrcs, str)
141+
}
142+
143+
destDir, err := util.GetAbsPathInWorkspace(destDirArg)
144+
if err != nil {
145+
ret.Code = http.StatusForbidden
146+
ret.Msg = err.Error()
147+
return
148+
}
149+
if filelock.IsExist(destDir) {
150+
destInfo, err := os.Stat(destDir)
151+
if err != nil {
152+
ret.Code = -1
153+
ret.Msg = err.Error()
154+
return
155+
}
156+
if !destInfo.IsDir() {
157+
ret.Code = -1
158+
ret.Msg = fmt.Sprintf("destDir [%s] is not a directory", destDirArg)
159+
return
160+
}
161+
} else {
162+
if err = os.MkdirAll(destDir, 0755); err != nil {
163+
logging.LogErrorf("make dir [%s] failed: %s", destDir, err)
164+
ret.Code = -1
165+
ret.Msg = err.Error()
166+
return
167+
}
168+
}
169+
170+
var absSrcs []string
171+
for _, src := range relSrcs {
172+
absSrc, err := util.GetAbsPathInWorkspace(src)
173+
if err != nil {
174+
ret.Code = http.StatusForbidden
175+
ret.Msg = err.Error()
176+
return
177+
}
178+
if !filelock.IsExist(absSrc) {
179+
logging.LogErrorf("file [%s] does not exist", src)
180+
ret.Code = -1
181+
ret.Msg = fmt.Sprintf("file [%s] does not exist", src)
182+
return
183+
}
184+
if util.IsSensitivePath(absSrc) {
185+
logging.LogErrorf("refuse to copy sensitive file [%s]", src)
186+
ret.Code = -2
187+
ret.Msg = fmt.Sprintf("refuse to copy sensitive file [%s]", src)
188+
return
189+
}
190+
absSrcs = append(absSrcs, absSrc)
191+
}
192+
193+
for _, absSrc := range absSrcs {
194+
dest := filepath.Join(destDir, filepath.Base(absSrc))
195+
if err := filelock.Copy(absSrc, dest); err != nil {
196+
logging.LogErrorf("copy file [%s] to [%s] failed: %s", absSrc, dest, err)
197+
ret.Code = -1
198+
ret.Msg = err.Error()
199+
return
200+
}
201+
}
202+
203+
model.IncSync()
204+
}
205+
108206
func copyFile(c *gin.Context) {
109207
ret := gulu.Ret.NewResult()
110208
defer c.JSON(http.StatusOK, ret)

kernel/api/router.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ func ServeAPI(ginServer *gin.Engine) {
252252
ginServer.Handle("POST", "/api/file/putFile", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, putFile)
253253
ginServer.Handle("POST", "/api/file/copyFile", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, copyFile)
254254
ginServer.Handle("POST", "/api/file/globalCopyFiles", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, globalCopyFiles)
255+
ginServer.Handle("POST", "/api/file/workspaceCopyFiles", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, workspaceCopyFiles)
255256
ginServer.Handle("POST", "/api/file/removeFile", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, removeFile)
256257
ginServer.Handle("POST", "/api/file/renameFile", model.CheckAuth, model.CheckAdminRole, model.CheckReadonly, renameFile)
257258
ginServer.Handle("POST", "/api/file/readDir", model.CheckAuth, model.CheckAdminRole, readDir)

0 commit comments

Comments
 (0)