add PATCH /users/@me/flags/{id}
This commit is contained in:
		
							parent
							
								
									ea2ae94742
								
							
						
					
					
						commit
						1360a52488
					
				
					 3 changed files with 88 additions and 2 deletions
				
			
		|  | @ -50,7 +50,7 @@ type MemberFlag struct { | |||
| const ( | ||||
| 	MaxPrideFlags           = 100 | ||||
| 	MaxPrideFlagTitleLength = 100 | ||||
| 	MaxPrideFlagDescLength  = 200 | ||||
| 	MaxPrideFlagDescLength  = 500 | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
|  |  | |||
|  | @ -10,7 +10,9 @@ import ( | |||
| 	"codeberg.org/u1f320/pronouns.cc/backend/log" | ||||
| 	"codeberg.org/u1f320/pronouns.cc/backend/server" | ||||
| 	"emperror.dev/errors" | ||||
| 	"github.com/go-chi/chi/v5" | ||||
| 	"github.com/go-chi/render" | ||||
| 	"github.com/rs/xid" | ||||
| ) | ||||
| 
 | ||||
| func (s *Server) getUserFlags(w http.ResponseWriter, r *http.Request) error { | ||||
|  | @ -112,7 +114,91 @@ func (s *Server) postUserFlag(w http.ResponseWriter, r *http.Request) error { | |||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| type patchUserFlagRequest struct { | ||||
| 	Name        *string `json:"name"` | ||||
| 	Description *string `json:"description"` | ||||
| } | ||||
| 
 | ||||
| func (s *Server) patchUserFlag(w http.ResponseWriter, r *http.Request) error { | ||||
| 	ctx := r.Context() | ||||
| 	claims, _ := server.ClaimsFromContext(ctx) | ||||
| 
 | ||||
| 	if !claims.TokenWrite { | ||||
| 		return server.APIError{Code: server.ErrMissingPermissions, Details: "This token is read-only"} | ||||
| 	} | ||||
| 
 | ||||
| 	flagID, err := xid.FromString(chi.URLParam(r, "flagID")) | ||||
| 	if err != nil { | ||||
| 		return server.APIError{Code: server.ErrNotFound, Details: "Invalid flag ID"} | ||||
| 	} | ||||
| 
 | ||||
| 	flags, err := s.DB.AccountFlags(ctx, claims.UserID) | ||||
| 	if err != nil { | ||||
| 		return errors.Wrap(err, "getting current user flags") | ||||
| 	} | ||||
| 	if len(flags) >= db.MaxPrideFlags { | ||||
| 		return server.APIError{ | ||||
| 			Code: server.ErrFlagLimitReached, | ||||
| 		} | ||||
| 	} | ||||
| 	var found bool | ||||
| 	for _, flag := range flags { | ||||
| 		if flag.ID == flagID { | ||||
| 			found = true | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 	if !found { | ||||
| 		return server.APIError{Code: server.ErrNotFound, Details: "No flag with that ID found"} | ||||
| 	} | ||||
| 
 | ||||
| 	var req patchUserFlagRequest | ||||
| 	err = render.Decode(r, &req) | ||||
| 	if err != nil { | ||||
| 		return server.APIError{Code: server.ErrBadRequest} | ||||
| 	} | ||||
| 
 | ||||
| 	if req.Name != nil { | ||||
| 		*req.Name = strings.TrimSpace(*req.Name) | ||||
| 	} | ||||
| 	if req.Description != nil { | ||||
| 		*req.Description = strings.TrimSpace(*req.Description) | ||||
| 	} | ||||
| 
 | ||||
| 	if req.Name == nil && req.Description == nil { | ||||
| 		return server.APIError{Code: server.ErrBadRequest, Details: "Request cannot be empty"} | ||||
| 	} | ||||
| 
 | ||||
| 	if s := common.StringLength(req.Name); s > db.MaxPrideFlagTitleLength { | ||||
| 		return server.APIError{ | ||||
| 			Code:    server.ErrBadRequest, | ||||
| 			Details: fmt.Sprintf("name too long, must be %v characters or less, is %v", db.MaxPrideFlagTitleLength, s), | ||||
| 		} | ||||
| 	} | ||||
| 	if s := common.StringLength(req.Description); s > db.MaxPrideFlagDescLength { | ||||
| 		return server.APIError{ | ||||
| 			Code:    server.ErrBadRequest, | ||||
| 			Details: fmt.Sprintf("description too long, must be %v characters or less, is %v", db.MaxPrideFlagDescLength, s), | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	tx, err := s.DB.Begin(ctx) | ||||
| 	if err != nil { | ||||
| 		return errors.Wrap(err, "beginning transaction") | ||||
| 	} | ||||
| 	defer tx.Rollback(ctx) | ||||
| 
 | ||||
| 	flag, err := s.DB.EditFlag(ctx, tx, flagID, req.Name, req.Description, nil) | ||||
| 	if err != nil { | ||||
| 		return errors.Wrap(err, "updating flag") | ||||
| 	} | ||||
| 
 | ||||
| 	err = tx.Commit(ctx) | ||||
| 	if err != nil { | ||||
| 		return errors.Wrap(err, "committing transaction") | ||||
| 	} | ||||
| 
 | ||||
| 	render.JSON(w, r, flag) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -32,7 +32,7 @@ func Mount(srv *server.Server, r chi.Router) { | |||
| 
 | ||||
| 			r.Get("/@me/flags", server.WrapHandler(s.getUserFlags)) | ||||
| 			r.Post("/@me/flags", server.WrapHandler(s.postUserFlag)) | ||||
| 			r.Patch("/@me/flags", server.WrapHandler(s.patchUserFlag)) | ||||
| 			r.Patch("/@me/flags/{flagID}", server.WrapHandler(s.patchUserFlag)) | ||||
| 			r.Delete("/@me/flags", server.WrapHandler(s.deleteUserFlag)) | ||||
| 		}) | ||||
| 	}) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue