From b960f0375ca3255e88e93b10b917dc3a66cdef1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20B=C3=B6hm?= <lukas.l.boehm@fau.de> Date: Sun, 7 Mar 2021 23:28:26 +0100 Subject: [PATCH] continue working on api --- ablauf.txt | 84 ++++++++++++++++++++++++++++ api/api.go | 101 +++++++++++++++++----------------- api/api_test.go | 28 ++++++++++ api/database.go | 10 ++-- api/main.go | 4 +- web/src/api/index.js | 2 +- web/src/components/Upload.vue | 15 ++++- 7 files changed, 183 insertions(+), 61 deletions(-) create mode 100644 ablauf.txt create mode 100644 api/api_test.go diff --git a/ablauf.txt b/ablauf.txt new file mode 100644 index 0000000..1e52fd2 --- /dev/null +++ b/ablauf.txt @@ -0,0 +1,84 @@ +Siehe Postman!!!!! + + + +********************************************** +******* 1. send stuff user selected and get temporary file and share UUID +********************************************* +POST: /api/containers +req: duration=1, password, message, size, download_limit, number of files, captcha, filenames, emails +res: +{ + { + "container": { + "UUID": "6e7b2e6e-5c32-43c8-a899-33225ee21f27", + "duration": "1", + "downloadLimit": "20", + "lang": "de_DE", + "source": "ST", + "WSUser": null, + "authorIP": "188.192.241.187", + "swiftVersion": "4", + "createdDate": { + "date": "2021-03-07 20:39:50.667215", + "timezone_type": 3, + "timezone": "Europe/Zurich" + }, + "expiredDate": "2021-03-08 20:39:50", + "needPassword": false, + "message": "HALLO NAME", + "numberOfFile": "4" + } + } + uploadHost: ul-gp545fun.swisstransfer.com + { + "filesUUID": [ + "92d11732-1fbf-4fef-b83e-aaf73e8e5a54", + "800819b7-357f-48a3-b6c0-1681421fb38c", + "8ac38609-cfcf-4fc1-9645-aa532295c8a6", + "fb4fafd6-0e92-45b2-b396-e0efdc5e72ca" + ] + } +} +stat: 201 created + + + + + +********************************************** +******* (repeat) send files and store them temporarily +********************************************* +OPTIONS xhr: /api/uploadChunk/6e7b2e6e-5c32-43c8-a899-33225ee21f27/800819b7-357f-48a3-b6c0-1681421fb38c/0/1 +res: "{\"method\":\"OPTIONS\"}" +stat: 200ok + +POST: /api/uploadChunk/6e7b2e6e-5c32-43c8-a899-33225ee21f27/800819b7-357f-48a3-b6c0-1681421fb38c/0/1 +stat: 201 created +res: uploadChunksFileDone: 1 + + + + + +********************************************** +******* 3. send upload complete confirmation that locks the upload and moves the stuff from temporary to permanent (starts deletion timer?) +********************************************* +POST: /api/uploadComplete +req: +Content-Disposition: form-data; name="UUID" 6e7b2e6e-5c32-43c8-a899-33225ee21f27 +stat: 200 ok +res: +{ + "0": { + "linkUUID": "a6407fb3-3b1a-48cf-abb0-edfc043ff683", + "containerUUID": "6e7b2e6e-5c32-43c8-a899-33225ee21f27", + "userEmail": null, + "downloadCounterCredit": 20, + "createdDate": "2021-03-07 20:39:50", + "expiredDate": "2021-03-08 20:39:50", + "isDownloadOnetime": 0, + "isMailSent": 0 + } +} + diff --git a/api/api.go b/api/api.go index c6dde02..6cc1e63 100644 --- a/api/api.go +++ b/api/api.go @@ -19,60 +19,59 @@ import ( ///////////////////////////////// //////////// routes ///////////// ///////////////////////////////// - -func allShares(w http.ResponseWriter, r *http.Request) { - db := getDatabase() +func AllShares(w http.ResponseWriter, r *http.Request) { + db := GetDatabase() var shares []Share db.Where("is_public = ?", 1).Find(&shares) - sendJSON(w, shares) + SendJSON(w, shares) } -func getShare(w http.ResponseWriter, r *http.Request) { +func GetShare(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) - db := getDatabase() + db := GetDatabase() var share Share db.Where("ID = ?", vars["id"]).Find(&share) fmt.Println(share) - sendJSON(w, share) + SendJSON(w, share) } -func addShare(w http.ResponseWriter, r *http.Request) { - db := getDatabase() +func OpenShare(w http.ResponseWriter, r *http.Request) { + db := GetDatabase() + + uid, _ := uuid.NewRandom() // instead: NewRandomFromReader + reqBody, _ := ioutil.ReadAll(r.Body) var newShare Share + json.Unmarshal(reqBody, &newShare) json.NewDecoder(r.Body).Decode(&newShare) - db.Create(newShare) - sendJSON(w, nil) -} - + newShare.ID = uid + b, err := json.MarshalIndent(newShare, "", " ") + if err != nil { + fmt.Println(err) + } + fmt.Print(string(b)) -func allAttachments(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - db := getDatabase() - var att Attachment - db.Where("share_id = ?", vars["id"]).Find(&att) - sendJSON(w, att) + db.Create(&newShare) + SendJSON(w, newShare) + return } -func getAttachment(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - db := getDatabase() - var att Attachment - db.Where("share_id = ?", vars["id"]).Where("id = ?", vars["att"]).Find(&att) - sendJSON(w, att) -} +func CloseShare(w http.ResponseWriter, r *http.Request) { + db := GetDatabase() -func deleteAttachment(w http.ResponseWriter, r *http.Request) { - fmt.Println("DELETE attachment????") + fmt.Println(r.ParseForm()) + + + var share Share + db.Where("id = ?", "asd").Find(&share) } -func addAttachment(w http.ResponseWriter, r *http.Request) { - db := getDatabase() +func UploadAttachment(w http.ResponseWriter, r *http.Request) { + db := GetDatabase() - fmt.Fprintf(w, "Uploading File") r.ParseMultipartForm(10 << 20) // Maximum 10 MB in RAM file, handler, err := r.FormFile("files") if err != nil { @@ -107,34 +106,32 @@ func addAttachment(w http.ResponseWriter, r *http.Request) { fmt.Println("Successfully Uploaded File") } + +func DeleteAttachment(w http.ResponseWriter, r *http.Request) { + fmt.Println("DELETE attachment????") +} + + ///////////////////////////////// ////////// functions //////////// ///////////////////////////////// -func test(w http.ResponseWriter, r *http.Request) { - fmt.Println(r.URL) - fmt.Println("Hallo Welt") - sendJSON(w, nil) -} - -func configureRoutes() { +func ConfigureRoutes() { router := mux.NewRouter().StrictSlash(true) - router.HandleFunc("/", test) + router.HandleFunc("/shares", AllShares).Methods("GET") + router.HandleFunc("/share/{id}", GetShare).Methods("GET") - router.HandleFunc("/shares", allShares).Methods("GET") - router.HandleFunc("/shares", addShare).Methods("POST") - router.HandleFunc("/share/{id}", getShare).Methods("GET") + router.HandleFunc("/shares", OpenShare).Methods("PUT") + router.HandleFunc("/shares", CloseShare).Methods("POST") - router.HandleFunc("/share/{id}/attachments", allAttachments).Methods("GET") - router.HandleFunc("/share/{id}/attachments", addAttachment).Methods("POST", "OPTIONS") - router.HandleFunc("/share/{id}/attachments", deleteAttachment).Methods("DELETE", "OPTIONS") - router.HandleFunc("/share/{id}/attachment/{att}", getAttachment).Methods("GET") + router.HandleFunc("/share/{id}", UploadAttachment).Methods("PUT", "POST", "OPTION") + router.HandleFunc("/share/{id}/attachments", DeleteAttachment).Methods("DELETE", "OPTIONS") handler := cors.Default().Handler(router) log.Fatal(http.ListenAndServe(":6969", handler)) } -func getDatabase()(db *gorm.DB) { +func GetDatabase()(db *gorm.DB) { dsn := os.Getenv("DATABASE_URI") db, err := gorm.Open(sqlserver.Open(dsn), &gorm.Config{}) if err != nil { @@ -143,11 +140,11 @@ func getDatabase()(db *gorm.DB) { return } -func sendJSON(w http.ResponseWriter, res interface{}) { - w.Header().Set("Access-Control-Allow-Origin", "*") +func SendJSON(w http.ResponseWriter, res interface{}) { w.Header().Set("Content-Type", "application/json") - w.Header().Set("Access-Control-Allow-Origin", "*") - w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") - w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") + //w.Header().Set("Access-Control-Allow-Origin", "*") + //w.Header().Set("Access-Control-Allow-Origin", "*") + //w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") + //w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") json.NewEncoder(w).Encode(res) } diff --git a/api/api_test.go b/api/api_test.go new file mode 100644 index 0000000..d3201b8 --- /dev/null +++ b/api/api_test.go @@ -0,0 +1,28 @@ +package main + +import ( + "fmt" + "io" + "io/ioutil" + "net/http" + "testing" + "net/http/httptest" +) + +func TestOpenShare(t *testing.T) { + // expected response + handler := func(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "{ \"status\": \"expected service response\"}") + } + + + req := httptest.NewRequest("PUT", "http://localhost:6969/shares", nil) + w := httptest.NewRecorder() + handler(w, req) + + resp := w.Result() + body, _ := ioutil.ReadAll(resp.Body) + fmt.Println(resp.StatusCode) + fmt.Println(resp.Header.Get("Content-Type")) + fmt.Println(string(body)) +} \ No newline at end of file diff --git a/api/database.go b/api/database.go index 96bda77..cf110ad 100644 --- a/api/database.go +++ b/api/database.go @@ -7,13 +7,15 @@ import ( ) type Share struct { - ID uuid.UUID `gorm:"unique; not null"` //`gorm:"type:uuid;default:uuid_generate_v4()"` - Name string - Expires time.Time - DownloadLimit int + ID uuid.UUID `gorm:"unique; not null; type:uuid; default: uuid.NewRandom()"` + Name string `json:"name"` + Expires time.Time `json:"expires"` + DownloadLimit int `json:"downloadLimit"` IsPublic bool `gorm:"not null; default:false; index"` Password string IsZipped bool `gorm:"not null; default:false"` + IsTemporary bool `gorm:"not null; default:true"` + IsLocked bool `gorm:"not null; default:false"` Attachments []Attachment `gorm:"foreignKey:ShareID; constraint:OnDelete:CASCADE"` } diff --git a/api/main.go b/api/main.go index 965461c..040b7ef 100644 --- a/api/main.go +++ b/api/main.go @@ -3,11 +3,11 @@ package main import "fmt" func main() { - db := getDatabase() + db := GetDatabase() // Migrate the schema db.AutoMigrate(&Attachment{}) db.AutoMigrate(&Share{}) fmt.Println("Let's go!!!") - configureRoutes() + ConfigureRoutes() } diff --git a/web/src/api/index.js b/web/src/api/index.js index ddf951d..1dc803c 100644 --- a/web/src/api/index.js +++ b/web/src/api/index.js @@ -1,7 +1,7 @@ import axios from "axios"; const ax = axios.create({ - baseURL: "http://localhost:5000/api", + baseURL: "http://localhost:6969", headers: { "Content-type": "application/json", }, diff --git a/web/src/components/Upload.vue b/web/src/components/Upload.vue index c4e0c84..a2a40da 100644 --- a/web/src/components/Upload.vue +++ b/web/src/components/Upload.vue @@ -36,17 +36,28 @@ import vueFilePond from "vue-filepond"; import "filepond/dist/filepond.min.css"; const FilePond = vueFilePond(); +import ax from "@/api"; + export default { name: "Upload", - data: function () { + data() { return { myFiles: [], - serverUri: "http://localhost:6969/share/3a325c5b-e8b7-48f2-838c-0e2cfd73aad1/attachments" + serverUri: "http://localhost:6969/share/3a325c5b-e8b7-48f2-838c-0e2cfd73aad1/attachments", + share: { + Name: "Test", + DownloadLimit: 123 + } }; }, methods: { commitShare: function() { console.log("uploading share"); + ax.put("/shares", this.share) + .then((response) => { + this.sid = response.data; + }) + .catch((error) => console.log(error)); } }, components: { -- GitLab