package routes import ( "encoding/base64" "encoding/json" "net/http" "time" "git.1e99.eu/1e99/passed/storage" ) func CreatePassword(store storage.Store, maxLength int, encoding *base64.Encoding) http.HandlerFunc { return func(res http.ResponseWriter, req *http.Request) { var reqBody struct { Password string `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 } password, err := encoding.DecodeString(reqBody.Password) if err != nil { http.Error(res, "Bad base64 encoding", http.StatusBadRequest) return } if len(password) > maxLength { http.Error(res, "Password too long", 413) // Payload Too Large 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 := store.Create( password, time.Now().Add(expiresIn), ) switch { case err == storage.ErrFull: http.Error(res, "Insufficient storage", http.StatusInsufficientStorage) return case err != nil: http.Error(res, "", http.StatusInternalServerError) return } resBody := struct { Id string `json:"id"` }{ Id: id, } err = json.NewEncoder(res).Encode(&resBody) if err != nil { http.Error(res, "", http.StatusInternalServerError) return } } }