package route import ( "encoding/json" "net/http" "time" "git.1e99.eu/1e99/passed/password" ) func CreatePassword(storage password.Storage, maxLength int) http.HandlerFunc { return func(res http.ResponseWriter, req *http.Request) { var reqBody struct { // Go automatically decodes byte arrays using Base64 Password []byte `json:"password"` ExpiresIn time.Duration `json:"expires-in"` } err := json.NewDecoder(req.Body).Decode(&reqBody) if err != nil { http.Error(res, "Malformed JSON body", http.StatusBadRequest) return } if len(reqBody.Password) > maxLength { http.Error(res, "Password too long", http.StatusRequestEntityTooLarge) return } expiresIn := reqBody.ExpiresIn * time.Second if expiresIn <= 0 { http.Error(res, "Too short expires-in", http.StatusBadRequest) return } if expiresIn > 2*7*24*time.Hour { http.Error(res, "Too long expires-in", http.StatusBadRequest) return } id, err := storage.Create( reqBody.Password, time.Now().Add(expiresIn), ) switch { case err == password.ErrFull: http.Error(res, "Insufficient storage", http.StatusInsufficientStorage) return case err != nil: http.Error(res, "", http.StatusInternalServerError) return } err = json.NewEncoder(res).Encode(&id) if err != nil { http.Error(res, "", http.StatusInternalServerError) return } } } func GetPassword(storage password.Storage) http.HandlerFunc { return func(res http.ResponseWriter, req *http.Request) { id := req.PathValue("id") passwd, err := storage.Get(id) switch { case err == password.ErrNotFound: http.Error(res, "Password not found", http.StatusNotFound) return case err != nil: http.Error(res, "", http.StatusInternalServerError) return } err = storage.Delete(id) if err != nil { http.Error(res, "", http.StatusInternalServerError) return } err = json.NewEncoder(res).Encode(&passwd) if err != nil { http.Error(res, "", http.StatusInternalServerError) return } } } func HasPassword(storage password.Storage) http.HandlerFunc { return func(res http.ResponseWriter, req *http.Request) { id := req.PathValue("id") _, err := storage.Get(id) switch { case err == password.ErrNotFound: http.Error(res, "", http.StatusNotFound) return case err != nil: http.Error(res, "", http.StatusInternalServerError) return } res.WriteHeader(http.StatusNoContent) } }