Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
Ayideyia committed Jul 1, 2024
1 parent 6ca0c50 commit 73c3d2a
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 162 deletions.
43 changes: 43 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Build Sync-Configuration

on:
push:
tags:
- "v*"

jobs:
Build:
permissions: write-all
runs-on: ubuntu-latest
env:
APP_NAME: GUI-Sync
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: ./go.mod

- name: Build 1
run: GOOS=windows GOARCH=amd64 go build -o ${{ env.APP_NAME }}-windows-amd64.exe

- name: Build 2
run: GOOS=windows GOARCH=arm64 go build -o ${{ env.APP_NAME }}-windows-arm64.exe

- name: Build 3
run: GOOS=windows GOARCH=386 go build -o ${{ env.APP_NAME }}-windows-386.exe

- name: Build 4
run: GOOS=linux GOARCH=amd64 go build -o ${{ env.APP_NAME }}-linux-amd64

- name: Build 5
run: GOOS=linux GOARCH=arm64 go build -o ${{ env.APP_NAME }}-linux-arm64

- name: Create Release and Upload Assets
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ${{ env.APP_NAME }}*
tag: ${{ github.ref }}
overwrite: true
file_glob: true
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
data
backup_index.json
sync_configuration.exe
GUI-Sync
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module sync_configuration

go 1.22.1
go 1.21.10
237 changes: 78 additions & 159 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,62 +8,45 @@ import (
"net/http"
"os"
"path"
"path/filepath"
"strings"
)

var (
backupIndexFile = "backup_index.json"
dataDir = "data"
backupIndex []BackupEntry
addrss = "0.0.0.0"
port = 8080
token = ""
SavePath = "data"
Addrss = "0.0.0.0"
Port = 8080
Token = ""
)

type BackupEntry struct {
Id string `json:"id"`
Files []string `json:"files"`
Id string `json:"id"`
Tag string `json:"tag"`
Files map[string]string `json:"files"`
}

func main() {

flag.StringVar(&token, "token", "", "Authorization")
flag.StringVar(&addrss, "address", "0.0.0.0", "Address to listen on")
flag.IntVar(&port, "port", 8080, "Port to listen on")
flag.StringVar(&Token, "token", "", "Authorization")
flag.StringVar(&Addrss, "address", "0.0.0.0", "Address to listen on")
flag.IntVar(&Port, "port", 8080, "Port to listen on")
flag.Parse()

if token == "" {
if Token == "" {
fmt.Println("You need to specify a token that is the same as the client")
return
}

loadBackupIndex()
os.MkdirAll(SavePath, os.ModePerm)

http.HandleFunc("/backup", withAuth(handleBackup))
http.HandleFunc("/file", withAuth(handleFile))
http.ListenAndServe(fmt.Sprintf("%s:%d", addrss, port), nil)
}

func loadBackupIndex() {
file, err := os.ReadFile(backupIndexFile)
if err != nil {
log.Printf("Error reading backup index file: %v\n", err)
return
}

err = json.Unmarshal(file, &backupIndex)
if err != nil {
log.Printf("Error decoding backup index JSON: %v\n", err)
return
}
http.HandleFunc("/sync", withAuth(handleSync))
http.ListenAndServe(fmt.Sprintf("%s:%d", Addrss, Port), nil)
}

func withAuth(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
authHeader := r.Header.Get("Authorization")
uaHeader := r.Header.Get("User-Agent")
if uaHeader != "GUI.for.Cores" || authHeader != "Bearer "+token {
if uaHeader != "GUI.for.Cores" || authHeader != "Bearer "+Token {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
Expand All @@ -74,182 +57,118 @@ func withAuth(next http.HandlerFunc) http.HandlerFunc {
func handleBackup(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
idParam := r.URL.Query().Get("id")
tag := r.URL.Query().Get("tag")
p := path.Join(SavePath, tag)

log.Printf("List => %s\n", idParam)
log.Printf("List => where tag = %s\n", tag)

var response []byte
result := make([]string, 0)
if !strings.HasPrefix(path.Clean(p), SavePath) {
http.Error(w, "403", http.StatusForbidden)
return
}

if idParam != "" {
for _, entry := range backupIndex {
if entry.Id == idParam {
result = entry.Files
break
}
}
dirs, err := os.ReadDir(p)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

var err error
response, err = json.Marshal(result)
if err != nil {
http.Error(w, "Failed to marshal JSON response", http.StatusInternalServerError)
return
}
} else {
for _, entry := range backupIndex {
result = append(result, entry.Id)
result := make([]string, 0)
for _, file := range dirs {
if !file.IsDir() {
result = append(result, file.Name())
}
}

var err error
response, err = json.Marshal(result)
if err != nil {
http.Error(w, "Failed to marshal JSON response", http.StatusInternalServerError)
return
}
response, err := json.Marshal(result)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write(response)

case http.MethodDelete:
tag := r.URL.Query().Get("tag")
ids := r.URL.Query().Get("ids")

if ids == "" {
http.Error(w, "Error parameter", http.StatusBadRequest)
return
}

p := path.Join(SavePath, tag)
idsToDelete := strings.Split(ids, ",")

log.Printf("Remove => %s\n", ids)

updatedBackupIndex := make([]BackupEntry, 0)
log.Printf("Remove => where tag = %s and id in %s\n", tag, ids)

for _, entry := range backupIndex {
found := false
for _, id := range idsToDelete {
if entry.Id == id {
found = true
break
}
}
if !found {
updatedBackupIndex = append(updatedBackupIndex, entry)
} else {
filePath := filepath.Join(dataDir, entry.Id)
os.RemoveAll(filePath)
}
}

backupIndex = updatedBackupIndex

updateBackupIndexFile()

default:
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
}

func handleFile(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
pathParam := r.URL.Query().Get("path")

_path := path.Clean(path.Join(dataDir, pathParam))
if !strings.HasPrefix(_path, dataDir) {
w.WriteHeader(http.StatusBadRequest)
if !strings.HasPrefix(path.Clean(p), SavePath) {
http.Error(w, "403", http.StatusForbidden)
return
}

log.Printf("Sync : %v\n", pathParam)

body, err := os.ReadFile(_path)
if err != nil {
w.WriteHeader(http.StatusNotFound)
return
for _, id := range idsToDelete {
os.RemoveAll(path.Join(p, id))
}

w.Header().Set("Content-Type", "text/plain")
w.WriteHeader(http.StatusOK)
w.Write(body)

case http.MethodPost:
var requestBody map[string]string
err := json.NewDecoder(r.Body).Decode(&requestBody)
var body BackupEntry
err := json.NewDecoder(r.Body).Decode(&body)
if err != nil {
http.Error(w, "Failed to parse request body", http.StatusBadRequest)
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

id := requestBody["id"]
filename := requestBody["file"]
fileContent := requestBody["body"]
p := path.Join(SavePath, body.Tag, body.Id)

log.Printf("Backup : %v => %v\n", id, filename)
log.Printf("Backup : id = %s, tag = %s, files.length = %v\n", body.Id, body.Tag, len(body.Files))

filePath := filepath.Join(dataDir, id, filename)
err = os.MkdirAll(filepath.Dir(filePath), 0755)
if err != nil {
http.Error(w, "Failed to create directory", http.StatusInternalServerError)
if !strings.HasPrefix(path.Clean(p), SavePath) {
http.Error(w, "403", http.StatusForbidden)
return
}

err = os.WriteFile(filePath, []byte(fileContent), 0644)
b, err := json.Marshal(body)
if err != nil {
http.Error(w, "Failed to write file", http.StatusInternalServerError)
log.Printf("Backup err %v", err.Error())
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

updateBackupIndex(id, filename)
os.MkdirAll(path.Join(SavePath, body.Tag), os.ModePerm)

os.WriteFile(p+".json", b, 0644)

w.WriteHeader(http.StatusCreated)

default:
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
}

func updateBackupIndex(id, filename string) {
var found bool
for i, entry := range backupIndex {
if entry.Id == id {
// Check if file already exists in the list
found = true
foundFile := false
for _, file := range entry.Files {
if file == filename {
foundFile = true
break
}
}
// If file not found, append to the list
if !foundFile {
backupIndex[i].Files = append(backupIndex[i].Files, filename)
}
break
func handleSync(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
tag := r.URL.Query().Get("tag")
id := r.URL.Query().Get("id")

p := path.Join(SavePath, tag, id)

if !strings.HasPrefix(p, SavePath) {
http.Error(w, "403", http.StatusForbidden)
return
}
}
if !found {
backupIndex = append(backupIndex, BackupEntry{
Id: id,
Files: []string{filename},
})
}

updateBackupIndexFile()
}
b, err := os.ReadFile(p)
if err != nil {
http.Error(w, "403", http.StatusForbidden)
return
}

func updateBackupIndexFile() {
// Update backup index file
jsonData, err := json.MarshalIndent(backupIndex, "", " ")
if err != nil {
log.Printf("Error marshaling backup index JSON: %v\n", err)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write(b)

err = os.WriteFile(backupIndexFile, jsonData, 0644)
if err != nil {
log.Printf("Error writing backup index file: %v\n", err)
return
default:
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
}

0 comments on commit 73c3d2a

Please sign in to comment.