mirror of
https://github.com/jc21/nginx-proxy-manager.git
synced 2024-08-30 18:22:48 +00:00
173 lines
5.1 KiB
Go
173 lines
5.1 KiB
Go
package handler
|
|
|
|
import (
|
|
"database/sql"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
|
|
c "npm/internal/api/context"
|
|
h "npm/internal/api/http"
|
|
"npm/internal/api/middleware"
|
|
"npm/internal/api/schema"
|
|
"npm/internal/entity/certificate"
|
|
"npm/internal/entity/host"
|
|
"npm/internal/jobqueue"
|
|
"npm/internal/logger"
|
|
)
|
|
|
|
// GetCertificates will return a list of Certificates
|
|
// Route: GET /certificates
|
|
func GetCertificates() func(http.ResponseWriter, *http.Request) {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
pageInfo, err := getPageInfoFromRequest(r)
|
|
if err != nil {
|
|
h.ResultErrorJSON(w, r, http.StatusBadRequest, err.Error(), nil)
|
|
return
|
|
}
|
|
|
|
certificates, err := certificate.List(pageInfo, middleware.GetFiltersFromContext(r))
|
|
if err != nil {
|
|
h.ResultErrorJSON(w, r, http.StatusBadRequest, err.Error(), nil)
|
|
} else {
|
|
h.ResultResponseJSON(w, r, http.StatusOK, certificates)
|
|
}
|
|
}
|
|
}
|
|
|
|
// GetCertificate will return a single Certificate
|
|
// Route: GET /certificates/{certificateID}
|
|
func GetCertificate() func(http.ResponseWriter, *http.Request) {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
var err error
|
|
var certificateID int
|
|
if certificateID, err = getURLParamInt(r, "certificateID"); err != nil {
|
|
h.ResultErrorJSON(w, r, http.StatusBadRequest, err.Error(), nil)
|
|
return
|
|
}
|
|
|
|
cert, err := certificate.GetByID(certificateID)
|
|
if err != nil {
|
|
h.ResultErrorJSON(w, r, http.StatusBadRequest, err.Error(), nil)
|
|
} else {
|
|
h.ResultResponseJSON(w, r, http.StatusOK, cert)
|
|
}
|
|
}
|
|
}
|
|
|
|
// CreateCertificate will create a Certificate
|
|
// Route: POST /certificates
|
|
func CreateCertificate() func(http.ResponseWriter, *http.Request) {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
bodyBytes, _ := r.Context().Value(c.BodyCtxKey).([]byte)
|
|
|
|
var newCertificate certificate.Model
|
|
err := json.Unmarshal(bodyBytes, &newCertificate)
|
|
if err != nil {
|
|
h.ResultErrorJSON(w, r, http.StatusBadRequest, h.ErrInvalidPayload.Error(), nil)
|
|
return
|
|
}
|
|
|
|
// Get userID from token
|
|
userID, _ := r.Context().Value(c.UserIDCtxKey).(int)
|
|
newCertificate.UserID = userID
|
|
|
|
if err = newCertificate.Save(); err != nil {
|
|
h.ResultErrorJSON(w, r, http.StatusBadRequest, fmt.Sprintf("Unable to save Certificate: %s", err.Error()), nil)
|
|
return
|
|
}
|
|
|
|
configureCertificate(newCertificate)
|
|
|
|
h.ResultResponseJSON(w, r, http.StatusOK, newCertificate)
|
|
}
|
|
}
|
|
|
|
// UpdateCertificate updates a cert
|
|
// Route: PUT /certificates/{certificateID}
|
|
func UpdateCertificate() func(http.ResponseWriter, *http.Request) {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
var err error
|
|
var certificateID int
|
|
if certificateID, err = getURLParamInt(r, "certificateID"); err != nil {
|
|
h.ResultErrorJSON(w, r, http.StatusBadRequest, err.Error(), nil)
|
|
return
|
|
}
|
|
|
|
certificateObject, err := certificate.GetByID(certificateID)
|
|
if err != nil {
|
|
h.ResultErrorJSON(w, r, http.StatusBadRequest, err.Error(), nil)
|
|
} else {
|
|
|
|
// This is a special endpoint, as it needs to verify the schema payload
|
|
// based on the certificate type, without being given a type in the payload.
|
|
// The middleware would normally handle this.
|
|
bodyBytes, _ := r.Context().Value(c.BodyCtxKey).([]byte)
|
|
schemaErrors, jsonErr := middleware.CheckRequestSchema(r.Context(), schema.UpdateCertificate(certificateObject.Type), bodyBytes)
|
|
if jsonErr != nil {
|
|
h.ResultErrorJSON(w, r, http.StatusInternalServerError, fmt.Sprintf("Schema Fatal: %v", jsonErr), nil)
|
|
return
|
|
}
|
|
|
|
if len(schemaErrors) > 0 {
|
|
h.ResultSchemaErrorJSON(w, r, schemaErrors)
|
|
return
|
|
}
|
|
|
|
err := json.Unmarshal(bodyBytes, &certificateObject)
|
|
if err != nil {
|
|
h.ResultErrorJSON(w, r, http.StatusBadRequest, h.ErrInvalidPayload.Error(), nil)
|
|
return
|
|
}
|
|
|
|
if err = certificateObject.Save(); err != nil {
|
|
h.ResultErrorJSON(w, r, http.StatusBadRequest, err.Error(), nil)
|
|
return
|
|
}
|
|
|
|
configureCertificate(certificateObject)
|
|
|
|
h.ResultResponseJSON(w, r, http.StatusOK, certificateObject)
|
|
}
|
|
}
|
|
}
|
|
|
|
// DeleteCertificate deletes a cert
|
|
// Route: DELETE /certificates/{certificateID}
|
|
func DeleteCertificate() func(http.ResponseWriter, *http.Request) {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
var err error
|
|
var certificateID int
|
|
if certificateID, err = getURLParamInt(r, "certificateID"); err != nil {
|
|
h.ResultErrorJSON(w, r, http.StatusBadRequest, err.Error(), nil)
|
|
return
|
|
}
|
|
|
|
item, err := certificate.GetByID(certificateID)
|
|
switch err {
|
|
case sql.ErrNoRows:
|
|
h.ResultErrorJSON(w, r, http.StatusNotFound, "Not found", nil)
|
|
case nil:
|
|
// Ensure that this upstream isn't in use by a host
|
|
cnt := host.GetCertificateUseCount(certificateID)
|
|
if cnt > 0 {
|
|
h.ResultErrorJSON(w, r, http.StatusBadRequest, "Cannot delete certificate that is in use by at least 1 host", nil)
|
|
return
|
|
}
|
|
h.ResultResponseJSON(w, r, http.StatusOK, item.Delete())
|
|
default:
|
|
h.ResultErrorJSON(w, r, http.StatusBadRequest, err.Error(), nil)
|
|
}
|
|
}
|
|
}
|
|
|
|
func configureCertificate(c certificate.Model) {
|
|
err := jobqueue.AddJob(jobqueue.Job{
|
|
Name: "RequestCertificate",
|
|
Action: c.Request,
|
|
})
|
|
if err != nil {
|
|
logger.Error("ConfigureCertificateError", err)
|
|
}
|
|
}
|