Beispiel #1
0
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)
		}
	})
}
Beispiel #2
0
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)
		}
	})
}
Beispiel #3
0
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)
		}
	})
}
Beispiel #4
0
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)
		}
	})
}