|
|
@ -3,139 +3,188 @@ package files |
|
|
|
import ( |
|
|
|
"encoding/base64" |
|
|
|
"encoding/json" |
|
|
|
"fmt" |
|
|
|
"godo/libs" |
|
|
|
"io" |
|
|
|
"log" |
|
|
|
"net/http" |
|
|
|
"strconv" |
|
|
|
"os" |
|
|
|
"path/filepath" |
|
|
|
"strings" |
|
|
|
) |
|
|
|
|
|
|
|
func HandleReadFile(w http.ResponseWriter, r *http.Request) { |
|
|
|
|
|
|
|
// 初始值
|
|
|
|
func HandleWriteFile(w http.ResponseWriter, r *http.Request) { |
|
|
|
path := r.URL.Query().Get("path") |
|
|
|
if err := validateFilePath(path); err != nil { |
|
|
|
libs.HTTPError(w, http.StatusBadRequest, err.Error()) |
|
|
|
return |
|
|
|
} |
|
|
|
basePath, err := libs.GetOsDir() |
|
|
|
if err != nil { |
|
|
|
libs.HTTPError(w, http.StatusInternalServerError, err.Error()) |
|
|
|
return |
|
|
|
} |
|
|
|
// 非加密文件直接返回base64编码
|
|
|
|
isHide := IsHaveHiddenFile(basePath, path) |
|
|
|
//Liuziwang888!@#
|
|
|
|
if !isHide { |
|
|
|
fileContent, err := ReadFile(basePath, path) |
|
|
|
if err != nil { |
|
|
|
libs.HTTPError(w, http.StatusNotFound, err.Error()) |
|
|
|
return |
|
|
|
} |
|
|
|
data := string(fileContent) |
|
|
|
if !strings.HasPrefix(data, "link::") { |
|
|
|
data = base64.StdEncoding.EncodeToString(fileContent) |
|
|
|
} |
|
|
|
resp := libs.APIResponse{Message: "success", Data: data} |
|
|
|
json.NewEncoder(w).Encode(resp) |
|
|
|
fullFilePath := filepath.Join(basePath, path) |
|
|
|
newFile, err := os.Create(fullFilePath) |
|
|
|
if err != nil { |
|
|
|
libs.HTTPError(w, http.StatusInternalServerError, err.Error()) |
|
|
|
return |
|
|
|
} |
|
|
|
// 有隐藏文件说明这是一个加密过的文件,需要验证密码
|
|
|
|
fPwd := r.Header.Get("pwd") |
|
|
|
if fPwd == "" { |
|
|
|
libs.HTTPError(w, http.StatusBadRequest, "密码不能为空") |
|
|
|
defer newFile.Close() |
|
|
|
// 获取文件内容
|
|
|
|
fileContent, _, err := r.FormFile("content") |
|
|
|
if err != nil { |
|
|
|
libs.HTTPError(w, http.StatusBadRequest, err.Error()) |
|
|
|
return |
|
|
|
} |
|
|
|
salt, err := GetSalt(r) |
|
|
|
defer fileContent.Close() |
|
|
|
fileData, err := io.ReadAll(fileContent) |
|
|
|
fmt.Println("表单数据为:", string(fileData)) |
|
|
|
if err != nil { |
|
|
|
libs.HTTPError(w, http.StatusInternalServerError, err.Error()) |
|
|
|
return |
|
|
|
} |
|
|
|
if !CheckFilePwd(fPwd, salt) { |
|
|
|
libs.HTTPError(w, http.StatusBadRequest, "密码错误") |
|
|
|
configPwd, ishas := libs.GetConfig("filePwd") |
|
|
|
configPwdStr, ok := configPwd.(string) |
|
|
|
if !ok { |
|
|
|
libs.HTTPError(w, http.StatusInternalServerError, "配置文件密码格式错误") |
|
|
|
return |
|
|
|
} |
|
|
|
// 密码正确则读取内容并解密
|
|
|
|
fileContent, err := ReadFile(basePath, path) |
|
|
|
if !ishas { |
|
|
|
// 没开启加密,直接明文写入
|
|
|
|
_, err := newFile.Write(fileData) |
|
|
|
if err != nil { |
|
|
|
libs.HTTPError(w, http.StatusInternalServerError, "数据写入失败") |
|
|
|
return |
|
|
|
} |
|
|
|
err = CheckAddDesktop(path) |
|
|
|
if err != nil { |
|
|
|
log.Printf("Error adding file to desktop: %s", err.Error()) |
|
|
|
} |
|
|
|
libs.SuccessMsg(w, "", "文件写入成功") |
|
|
|
return |
|
|
|
} |
|
|
|
// 开启加密后,写入加密数据
|
|
|
|
_, err = newFile.WriteString(fmt.Sprintf("@%s@", configPwdStr)) |
|
|
|
if err != nil { |
|
|
|
libs.HTTPError(w, http.StatusNotFound, err.Error()) |
|
|
|
libs.HTTPError(w, http.StatusInternalServerError, "密码写入失败") |
|
|
|
return |
|
|
|
} |
|
|
|
// 解密
|
|
|
|
fileContent, err = libs.DecryptData(fileContent, libs.EncryptionKey) |
|
|
|
entryData, err := libs.EncryptData(fileData, []byte(configPwdStr)) |
|
|
|
if err != nil { |
|
|
|
libs.HTTPError(w, http.StatusInternalServerError, err.Error()) |
|
|
|
libs.HTTPError(w, http.StatusInternalServerError, "文件加密失败") |
|
|
|
return |
|
|
|
} |
|
|
|
data := string(fileContent) |
|
|
|
if !strings.HasPrefix(data, "link::") { |
|
|
|
data = base64.StdEncoding.EncodeToString(fileContent) |
|
|
|
_, err = newFile.Write(entryData) |
|
|
|
if err != nil { |
|
|
|
libs.HTTPError(w, http.StatusInternalServerError, "文件写入失败") |
|
|
|
return |
|
|
|
} |
|
|
|
err = CheckAddDesktop(path) |
|
|
|
if err != nil { |
|
|
|
log.Printf("Error adding file to desktop: %s", err.Error()) |
|
|
|
} |
|
|
|
resp := libs.APIResponse{Message: "success", Data: data} |
|
|
|
json.NewEncoder(w).Encode(resp) |
|
|
|
libs.SuccessMsg(w, "", "文件写入成功") |
|
|
|
} |
|
|
|
|
|
|
|
// 设置文件密码
|
|
|
|
func HandleSetFilePwd(w http.ResponseWriter, r *http.Request) { |
|
|
|
fPwd := r.Header.Get("Pwd") |
|
|
|
salt, err := GetSalt(r) // 获取盐值
|
|
|
|
// 处理获取盐值时的错误
|
|
|
|
if err != nil || fPwd == "" { |
|
|
|
libs.HTTPError(w, http.StatusInternalServerError, err.Error()) |
|
|
|
func HandleReadFile(w http.ResponseWriter, r *http.Request) { |
|
|
|
path := r.URL.Query().Get("path") |
|
|
|
if path == "" { |
|
|
|
libs.ErrorMsg(w, "文件路径不能为空") |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
// 服务端再hash加密
|
|
|
|
hashPwd := libs.HashPassword(fPwd, salt) |
|
|
|
|
|
|
|
// 服务端存储
|
|
|
|
err = libs.SetConfigByName("filePwd", hashPwd) |
|
|
|
basePath, err := libs.GetOsDir() |
|
|
|
if err != nil { |
|
|
|
libs.HTTPError(w, http.StatusInternalServerError, err.Error()) |
|
|
|
libs.ErrorMsg(w, err.Error()) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
// salt值存储
|
|
|
|
err = libs.SetConfigByName("salt", salt) |
|
|
|
fullFilePath := filepath.Join(basePath, path) |
|
|
|
file, err := os.Open(fullFilePath) |
|
|
|
if err != nil { |
|
|
|
libs.HTTPError(w, http.StatusInternalServerError, err.Error()) |
|
|
|
libs.ErrorMsg(w, err.Error()) |
|
|
|
return |
|
|
|
} |
|
|
|
res := libs.APIResponse{Message: "密码设置成功"} |
|
|
|
json.NewEncoder(w).Encode(res) |
|
|
|
} |
|
|
|
|
|
|
|
// 更改文件密码
|
|
|
|
func HandleChangeFilePwd(w http.ResponseWriter, r *http.Request) { |
|
|
|
filePwd := r.Header.Get("Pwd") |
|
|
|
salt, err := GetSalt(r) // 获取盐值
|
|
|
|
if err != nil || filePwd == "" { // 检查错误和密码是否为空
|
|
|
|
libs.ErrorMsg(w, "参数错误") |
|
|
|
fileData, err := io.ReadAll(file) |
|
|
|
if err != nil { |
|
|
|
libs.ErrorMsg(w, err.Error()) |
|
|
|
return |
|
|
|
} |
|
|
|
strData := string(fileData) |
|
|
|
if strings.HasPrefix(strData, "link::") { |
|
|
|
res := libs.APIResponse{Message: "文件读取成功", Data: strData} |
|
|
|
json.NewEncoder(w).Encode(res) |
|
|
|
return |
|
|
|
} |
|
|
|
newPwd := libs.HashPassword(filePwd, salt) |
|
|
|
err = libs.SetConfigByName("filePwd", newPwd) |
|
|
|
// 判断是否为加密文件
|
|
|
|
isPwd := IsPwdFile(fileData) |
|
|
|
if !isPwd { |
|
|
|
// 未加密文件,直接返回
|
|
|
|
content := base64.StdEncoding.EncodeToString(fileData) |
|
|
|
res := libs.APIResponse{Message: "文件读取成功", Data: content} |
|
|
|
json.NewEncoder(w).Encode(res) |
|
|
|
return |
|
|
|
} |
|
|
|
Pwd := r.Header.Get("Pwd") |
|
|
|
filePwd := strData[1:33] |
|
|
|
// Pwd为空,info密码与文件密码做比对
|
|
|
|
if Pwd == "" { |
|
|
|
configPwd, ishas := libs.GetConfig("filePwd") |
|
|
|
if !ishas { |
|
|
|
libs.ErrorMsg(w, "未设置密码") |
|
|
|
return |
|
|
|
} |
|
|
|
configPwdStr, ok := configPwd.(string) |
|
|
|
if !ok { |
|
|
|
libs.ErrorMsg(w, "后端配置文件密码格式错误") |
|
|
|
return |
|
|
|
} |
|
|
|
// 校验密码
|
|
|
|
if filePwd != configPwdStr { |
|
|
|
res := libs.APIResponse{Message: "密码错误,请输入正确的密码", Code: -1, Error: "needPwd"} |
|
|
|
json.NewEncoder(w).Encode(res) |
|
|
|
return |
|
|
|
} |
|
|
|
decryptData, err := libs.DecryptData(fileData[34:], []byte(filePwd)) |
|
|
|
if err != nil { |
|
|
|
libs.ErrorMsg(w, err.Error()) |
|
|
|
return |
|
|
|
} |
|
|
|
content := base64.StdEncoding.EncodeToString(decryptData) |
|
|
|
res := libs.APIResponse{Message: "加密文件读取成功", Data: content} |
|
|
|
json.NewEncoder(w).Encode(res) |
|
|
|
return |
|
|
|
} |
|
|
|
// Pwd不为空,Pwd与文件密码做比对
|
|
|
|
if Pwd != filePwd { |
|
|
|
res := libs.APIResponse{Message: "密码错误,请输入正确的密码", Code: -1, Error: "needPwd"} |
|
|
|
json.NewEncoder(w).Encode(res) |
|
|
|
return |
|
|
|
} |
|
|
|
decryptData, err := libs.DecryptData(fileData[34:], []byte(filePwd)) |
|
|
|
if err != nil { |
|
|
|
libs.HTTPError(w, http.StatusInternalServerError, err.Error()) |
|
|
|
libs.ErrorMsg(w, err.Error()) |
|
|
|
return |
|
|
|
} |
|
|
|
libs.SuccessMsg(w, "success", "The file password change success!") |
|
|
|
content := base64.StdEncoding.EncodeToString(decryptData) |
|
|
|
res := libs.APIResponse{Message: "加密文件读取成功", Data: content} |
|
|
|
json.NewEncoder(w).Encode(res) |
|
|
|
} |
|
|
|
|
|
|
|
// 更改加密状态
|
|
|
|
func HandleSetIsPwd(w http.ResponseWriter, r *http.Request) { |
|
|
|
isPwd := r.URL.Query().Get("ispwd") |
|
|
|
// 0非加密机器 1加密机器
|
|
|
|
isPwdValue, err := strconv.Atoi(isPwd) |
|
|
|
if err != nil { |
|
|
|
libs.HTTPError(w, http.StatusBadRequest, err.Error()) |
|
|
|
func HandleSetFilePwd(w http.ResponseWriter, r *http.Request) { |
|
|
|
Pwd := r.Header.Get("Pwd") |
|
|
|
if Pwd == "" { |
|
|
|
err := libs.DeleteConfig("filePwd") |
|
|
|
if err != nil { |
|
|
|
libs.ErrorMsg(w, fmt.Sprintf("取消加密失败:%s", err.Error())) |
|
|
|
return |
|
|
|
} |
|
|
|
libs.SuccessMsg(w, nil, "取消加密成功") |
|
|
|
return |
|
|
|
} |
|
|
|
var isPwdBool bool |
|
|
|
if isPwdValue == 0 { |
|
|
|
isPwdBool = false |
|
|
|
} else { |
|
|
|
isPwdBool = true |
|
|
|
} |
|
|
|
err = libs.SetConfigByName("isPwd", isPwdBool) |
|
|
|
err := libs.SetConfigByName("filePwd", Pwd) |
|
|
|
if err != nil { |
|
|
|
libs.HTTPError(w, http.StatusInternalServerError, err.Error()) |
|
|
|
libs.ErrorMsg(w, err.Error()) |
|
|
|
return |
|
|
|
} |
|
|
|
libs.SuccessMsg(w, "success", "") |
|
|
|
libs.SuccessMsg(w, nil, "设置密码成功") |
|
|
|
} |
|
|
|