func singleFileHandler(db db.DbManager) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { md5Hash := mux.Vars(r)["hash"] switch r.Method { case "GET": c, err := db.GetFileByHash(md5Hash) if err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintln(w, "error decoding file") return } if c == nil { return404(w) return } if c.PwdHash == nil { // When file is downloaded, the file name is c.Name w.Header().Set("Content-Disposition", "attachment; filename="+c.Name) http.ServeFile(w, r, c.Path) } else { return404(w) } case "DELETE": err := db.DeleteFile(md5Hash) if err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprintln(w, "error deleting file: %v", err) return } fmt.Fprintln(w, "successfully deleted file") default: return404(w) } }) }
func registerHandler(db db.DbManager, jar *sessions.CookieStore) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method == "POST" { session, _ := jar.Get(r, "carton-session") if _, ok := session.Values["user"]; ok { http.Error(w, "already signed in", http.StatusBadRequest) return } decoder := json.NewDecoder(r.Body) var user NewUser err := decoder.Decode(&user) if err != nil { http.Error(w, "error decoding json", http.StatusBadRequest) return } if user.Username == "" || user.Password1 == "" || user.Password2 == "" || user.Password1 != user.Password2 { http.Error(w, "bad arguments", http.StatusBadRequest) return } if db.IsUser(user.Username) { http.Error(w, "user already exists", http.StatusBadRequest) return } bytePass := []byte(user.Password1) hash, err := bcrypt.GenerateFromPassword(bytePass, bcrypt.DefaultCost) if err != nil { http.Error( w, "error hashing password", http.StatusInternalServerError, ) return } err = db.RegisterUser(user.Username, hash) if err != nil { http.Error( w, "unable to add user", http.StatusInternalServerError, ) return } session.Values["user"] = user.Username session.Save(r, w) w.WriteHeader(http.StatusCreated) fmt.Fprintf(w, "Successfully registered %v", user.Username) } else { return404(w) } }) }
func loginHandler(db db.DbManager, jar *sessions.CookieStore) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method == "POST" { session, _ := jar.Get(r, "carton-session") if _, ok := session.Values["user"]; ok { http.Error(w, "already signed in", http.StatusBadRequest) return } decoder := json.NewDecoder(r.Body) var user User err := decoder.Decode(&user) if err != nil { http.Error(w, "error decoding json", http.StatusBadRequest) return } if user.Username == "" || user.Password == "" { http.Error(w, "bad arguments", http.StatusBadRequest) return } dbHash := db.GetPwdHash(user.Username) if dbHash == nil { http.Error( w, "user password combo doesn't exist", http.StatusBadRequest, ) return } err = bcrypt.CompareHashAndPassword(dbHash, []byte(user.Password)) if err != nil { http.Error( w, "user password combo doesn't exist", http.StatusBadRequest, ) return } session.Values["user"] = user.Username session.Save(r, w) // Sets return code to 200 fmt.Fprintln(w, "login succeeded") } else { return404(w) } }) }
func fileHandler( db db.DbManager, jar *sessions.CookieStore, dest string, ) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Check client has permission to upload a file session, _ := jar.Get(r, "carton-session") if _, ok := session.Values["user"]; !ok { http.Error(w, "No user logged in", http.StatusUnauthorized) return } if r.Method == "GET" { files, err := db.GetAllFiles() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } b, err := json.Marshal(files) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } var out bytes.Buffer json.Indent(&out, b, "", "\t") out.WriteTo(w) } else if r.Method == "POST" { reader, err := r.MultipartReader() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } c := &common.CartonFile{} user, _ := session.Values["user"].(string) c.Owner = user for { part, err := reader.NextPart() if err == io.EOF { break } if part.FileName() == "" { continue } if fileExists(dest + part.FileName()) { http.Error(w, "File already exists", http.StatusBadRequest) return } filePath := filepath.Join(dest, part.FileName()) f, err := os.Create(filePath) defer f.Close() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } c.Name = part.FileName() c.Path, _ = filepath.Abs(filePath) hasher := md5.New() writer := io.MultiWriter(f, hasher) _, err = io.Copy(writer, part) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } c.Md5Hash = fmt.Sprintf("%x", hasher.Sum(nil)) c.PwdHash = nil } db.AddFile(c) w.WriteHeader(http.StatusCreated) fmt.Fprintln(w, "upload succeeded") } else { return404(w) } }) }