package main import ( // "encoding/json" "fmt" // "html/template" // "log" "net/http" "time" // "github.com/julienschmidt/httprouter" // "strconv" "errors" "party.at/party/internal/data" "party.at/party/internal/validator" "encoding/hex" ) func (app *application) listIssuesHandler(w http.ResponseWriter, r *http.Request) { var input struct { Title string data.Filters } v := validator.New() qs := r.URL.Query() input.Title = app.readString(qs, "title", "") // input.Genres = app.readCSV(qs, "genres", []string{}) input.Filters.Page = app.readInt(qs, "page", 1, v) input.Filters.PageSize = app.readInt(qs, "page_size", 20, v) input.Filters.Sort = app.readString(qs, "sort", "id") input.Filters.SortSafelist = []string{"id", "-id", "title", "-title", "description", "-description"} if data.ValidateFilters(v, input.Filters); !v.Valid() { app.failedValidationResponse(w, r, v.Errors) return } issues, metadata, err := app.models.Issues.GetAll(input.Title, input.Filters) if err != nil { app.serverErrorResponse(w, r, err) return } err = app.writeJSON(w, http.StatusOK, envelope{"issues": issues, "metadata": metadata}, nil) if err != nil { app.serverErrorResponse(w, r, err) } } func (app *application) createIssueHandler(w http.ResponseWriter, r *http.Request) { var input struct { Title string `json:"title"` Description string `json:"description"` StartTime time.Time `json:"start_time"` EndTime time.Time `json:"end_time"` } err := app.readJSON(w, r, &input) if err != nil { // Use the new badRequestResponse() helper. app.badRequestResponse(w, r, err) return } n, e, private_pem, err := GenerateIssueKey() if err != nil { app.serverErrorResponse(w, r, err) return } issue := &data.Issue{ Title: input.Title, Description: input.Description, StartTime: input.StartTime, EndTime: input.EndTime, N: n, E: e, PrivatePem: private_pem, } v := validator.New() if data.ValidateIssue(v, issue); !v.Valid() { app.failedValidationResponse(w, r, v.Errors) return } err = app.models.Issues.Insert(issue) if err != nil { app.serverErrorResponse(w, r, err) return } headers := make(http.Header) headers.Set("Location", fmt.Sprintf("/v1/issues/%d", issue.ID)) err = app.writeJSON(w, http.StatusCreated, envelope{"issue": issue}, headers) if err != nil { app.serverErrorResponse(w, r, err) } } func (app *application) readIssueHandler(w http.ResponseWriter, r *http.Request) { id, err := app.readIDParam(r) if err != nil { app.notFoundResponse(w, r) return } issue, err := app.models.Issues.Get(id) if err != nil { switch { case errors.Is(err, data.ErrRecordNotFound): app.notFoundResponse(w, r) default: app.serverErrorResponse(w, r, err) } return } // Encode the struct to JSON and send it as the HTTP response. err = app.writeJSON(w, http.StatusOK, envelope{"issue": issue}, nil) if err != nil { app.serverErrorResponse(w, r, err) } } func (app *application) updateIssueHandler(w http.ResponseWriter, r *http.Request) { id, err := app.readIDParam(r) if err != nil { app.notFoundResponse(w, r) return } issue, err := app.models.Issues.Get(id) if err != nil { switch { case errors.Is(err, data.ErrRecordNotFound): app.notFoundResponse(w, r) default: app.serverErrorResponse(w, r, err) } return } var input struct { Title *string `json:"title"` Description *string `json:"description"` StartTime *time.Time `json:"start_time"` EndTime *time.Time `json:"end_time"` } err = app.readJSON(w, r, &input) if err != nil { app.badRequestResponse(w, r, err) return } if input.Title != nil { issue.Title = *input.Title } if input.Description != nil { issue.Description = *input.Description } if input.StartTime != nil { issue.StartTime = *input.StartTime } if input.StartTime != nil { issue.EndTime = *input.EndTime } v := validator.New() if data.ValidateIssue(v, issue); !v.Valid() { app.failedValidationResponse(w, r, v.Errors) return } err = app.models.Issues.Update(issue) if err != nil { switch { case errors.Is(err, data.ErrEditConflict): app.editConflictResponse(w, r) default: app.serverErrorResponse(w, r, err) } return } // Write the updated issue record in a JSON response. err = app.writeJSON(w, http.StatusOK, envelope{"issue": issue}, nil) if err != nil { app.serverErrorResponse(w, r, err) } } func (app *application) deleteIssueHandler(w http.ResponseWriter, r *http.Request) { id, err := app.readIDParam(r) if err != nil { app.notFoundResponse(w, r) return } // Delete the issue from the database, sending a 404 Not Found response to the // client if there isn't a matching record. err = app.models.Issues.Delete(id) if err != nil { switch { case errors.Is(err, data.ErrRecordNotFound): app.notFoundResponse(w, r) default: app.serverErrorResponse(w, r, err) } return } // Return a 200 OK status code along with a success message. err = app.writeJSON(w, http.StatusOK, envelope{"message": "issue successfully deleted"}, nil) if err != nil { app.serverErrorResponse(w, r, err) } } func (app *application) readIssuePubKeyHandler(w http.ResponseWriter, r *http.Request) { id, err := app.readIDParam(r) if err != nil { app.notFoundResponse(w, r) return } issue, err := app.models.Issues.Get(id) if err != nil { switch { case errors.Is(err, data.ErrRecordNotFound): app.notFoundResponse(w, r) default: app.serverErrorResponse(w, r, err) } return } type response struct { N string `json:"n"` E int `json:"e"` } res := response{ N: hex.EncodeToString(issue.N), E: issue.E, } err = app.writeJSON(w, http.StatusOK, envelope{"public_key": res}, nil) if err != nil { app.serverErrorResponse(w, r, err) } } func (app *application) blindSignIssueVoteHandler(w http.ResponseWriter, r *http.Request) { id, err := app.readIDParam(r) if err != nil { app.notFoundResponse(w, r) return } issue, err := app.models.Issues.Get(id) if err != nil { switch { case errors.Is(err, data.ErrRecordNotFound): app.notFoundResponse(w, r) default: app.serverErrorResponse(w, r, err) } return } type response struct { N string `json:"n"` E int `json:"e"` } res := response{ N: hex.EncodeToString(issue.N), E: issue.E, } err = app.writeJSON(w, http.StatusOK, envelope{"public_key": res}, nil) if err != nil { app.serverErrorResponse(w, r, err) } }