Allow arbitrary responses from form-encoded POST
Useful for returning full objects
This commit is contained in:
parent
a89a4fbec5
commit
4145944b1b
2 changed files with 28 additions and 16 deletions
|
|
@ -126,23 +126,29 @@ func authenticatedHandlerJSONSlice[T any](f handlerFunctionGetSlice[T]) http.Han
|
|||
}
|
||||
|
||||
type handlerFunctionPost[ReqType any] func(context.Context, *http.Request, ReqType) (string, *nhttp.ErrorWithStatus)
|
||||
type handlerFunctionPostAuthenticated[ReqType any] func(context.Context, *http.Request, platform.User, ReqType) (string, *nhttp.ErrorWithStatus)
|
||||
type handlerFunctionPostAuthenticated[RequestType any, ResponseType any] func(context.Context, *http.Request, platform.User, RequestType) (ResponseType, *nhttp.ErrorWithStatus)
|
||||
|
||||
func authenticatedHandlerJSONPost[ReqType any](f handlerFunctionPostAuthenticated[ReqType]) http.Handler {
|
||||
func authenticatedHandlerJSONPost[RequestType any, ResponseType any](f handlerFunctionPostAuthenticated[RequestType, ResponseType]) http.Handler {
|
||||
return auth.NewEnsureAuth(func(w http.ResponseWriter, r *http.Request, u platform.User) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
req, e := parseRequest[ReqType](r)
|
||||
req, e := parseRequest[RequestType](r)
|
||||
if e != nil {
|
||||
serializeError(w, e)
|
||||
return
|
||||
}
|
||||
ctx := r.Context()
|
||||
path, e := f(ctx, r, u, *req)
|
||||
resp, e := f(ctx, r, u, *req)
|
||||
if e != nil {
|
||||
serializeError(w, e)
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, path, http.StatusFound)
|
||||
body, err := json.Marshal(resp)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to marshal json")
|
||||
http.Error(w, "{\"message\": \"failed to marshal json\"}", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.Write(body)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -214,7 +220,7 @@ type postMultipartResponse struct {
|
|||
URI string `json:"uri"`
|
||||
}
|
||||
|
||||
func authenticatedHandlerPostMultipart(f handlerFunctionPostAuthenticated[[]file.Upload], collection file.Collection) http.Handler {
|
||||
func authenticatedHandlerPostMultipart[ResponseType any](f handlerFunctionPostAuthenticated[[]file.Upload, ResponseType], collection file.Collection) http.Handler {
|
||||
return auth.NewEnsureAuth(func(w http.ResponseWriter, r *http.Request, u platform.User) {
|
||||
err := r.ParseMultipartForm(32 << 10) // 32 MB buffer
|
||||
if err != nil {
|
||||
|
|
@ -235,14 +241,12 @@ func authenticatedHandlerPostMultipart(f handlerFunctionPostAuthenticated[[]file
|
|||
}
|
||||
*/
|
||||
ctx := r.Context()
|
||||
path, e := f(ctx, r, u, uploads)
|
||||
resp, e := f(ctx, r, u, uploads)
|
||||
if e != nil {
|
||||
http.Error(w, e.Error(), e.Status)
|
||||
return
|
||||
}
|
||||
body, err := json.Marshal(postMultipartResponse{
|
||||
URI: path,
|
||||
})
|
||||
body, err := json.Marshal(resp)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("failed to marshal json")
|
||||
http.Error(w, "{\"message\": \"failed to marshal json\"}", http.StatusInternalServerError)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package resource
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
|
||||
|
|
@ -21,6 +20,9 @@ func Avatar(r *router) *avatarR {
|
|||
type avatarR struct {
|
||||
router *router
|
||||
}
|
||||
type avatar struct {
|
||||
URI string `json:"uri"`
|
||||
}
|
||||
|
||||
func (res *avatarR) ByIDGet(ctx context.Context, r *http.Request, u platform.User) (file.Collection, uuid.UUID, *nhttp.ErrorWithStatus) {
|
||||
vars := mux.Vars(r)
|
||||
|
|
@ -31,17 +33,23 @@ func (res *avatarR) ByIDGet(ctx context.Context, r *http.Request, u platform.Use
|
|||
}
|
||||
return file.CollectionAvatar, uid, nil
|
||||
}
|
||||
func (res *avatarR) Create(ctx context.Context, r *http.Request, u platform.User, uploads []file.Upload) (string, *nhttp.ErrorWithStatus) {
|
||||
func (res *avatarR) Create(ctx context.Context, r *http.Request, u platform.User, uploads []file.Upload) (*avatar, *nhttp.ErrorWithStatus) {
|
||||
if len(uploads) == 0 {
|
||||
return "", nhttp.NewErrorStatus(http.StatusBadRequest, "No upload found")
|
||||
return nil, nhttp.NewErrorStatus(http.StatusBadRequest, "No upload found")
|
||||
}
|
||||
if len(uploads) != 1 {
|
||||
return "", nhttp.NewErrorStatus(http.StatusBadRequest, "You must only submit one file at a time")
|
||||
return nil, nhttp.NewErrorStatus(http.StatusBadRequest, "You must only submit one file at a time")
|
||||
}
|
||||
upload := uploads[0]
|
||||
err := platform.AvatarCreate(r.Context(), u, upload)
|
||||
if err != nil {
|
||||
return "", nhttp.NewErrorStatus(http.StatusBadRequest, "Create avatar: %w", err)
|
||||
return nil, nhttp.NewErrorStatus(http.StatusBadRequest, "Create avatar: %w", err)
|
||||
}
|
||||
return fmt.Sprintf("/avatar/%s", upload.UUID.String()), nil
|
||||
uri, err := res.router.UUIDToURI("avatar.ByIDGet", &upload.UUID)
|
||||
if err != nil {
|
||||
return nil, nhttp.NewError("create uri: %w", err)
|
||||
}
|
||||
return &avatar{
|
||||
URI: *uri,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue