feat: add DELETE /users/@me/flags/{id}
This commit is contained in:
parent
1360a52488
commit
a4698e179a
3 changed files with 60 additions and 2 deletions
|
@ -55,6 +55,7 @@ const (
|
|||
|
||||
const (
|
||||
ErrInvalidFlagID = errors.Sentinel("invalid flag ID")
|
||||
ErrFlagNotFound = errors.Sentinel("flag not found")
|
||||
)
|
||||
|
||||
func (db *DB) AccountFlags(ctx context.Context, userID xid.ID) (fs []PrideFlag, err error) {
|
||||
|
@ -70,6 +71,23 @@ func (db *DB) AccountFlags(ctx context.Context, userID xid.ID) (fs []PrideFlag,
|
|||
return NotNull(fs), nil
|
||||
}
|
||||
|
||||
func (db *DB) UserFlag(ctx context.Context, flagID xid.ID) (f PrideFlag, err error) {
|
||||
sql, args, err := sq.Select("*").From("pride_flags").Where("id = ?", flagID).ToSql()
|
||||
if err != nil {
|
||||
return f, errors.Wrap(err, "building query")
|
||||
}
|
||||
|
||||
err = pgxscan.Get(ctx, db, &f, sql, args...)
|
||||
if err != nil {
|
||||
if errors.Cause(err) == pgx.ErrNoRows {
|
||||
return f, ErrFlagNotFound
|
||||
}
|
||||
|
||||
return f, errors.Wrap(err, "executing query")
|
||||
}
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (db *DB) UserFlags(ctx context.Context, userID xid.ID) (fs []UserFlag, err error) {
|
||||
sql, args, err := sq.Select("u.id", "u.flag_id", "f.user_id", "f.hash", "f.name", "f.description").
|
||||
From("user_flags AS u").
|
||||
|
@ -241,7 +259,17 @@ func (db *DB) WriteFlag(ctx context.Context, flagID xid.ID, flag *bytes.Buffer)
|
|||
}
|
||||
|
||||
func (db *DB) DeleteFlag(ctx context.Context, flagID xid.ID, hash string) error {
|
||||
err := db.minio.RemoveObject(ctx, db.minioBucket, "/flags/"+flagID.String()+"/"+hash+".webp", minio.RemoveObjectOptions{})
|
||||
sql, args, err := sq.Delete("pride_flags").Where("id = ?", flagID).ToSql()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "building sql")
|
||||
}
|
||||
|
||||
_, err = db.Exec(ctx, sql, args...)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "executing query")
|
||||
}
|
||||
|
||||
err = db.minio.RemoveObject(ctx, db.minioBucket, "/flags/"+flagID.String()+"/"+hash+".webp", minio.RemoveObjectOptions{})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "deleting flag")
|
||||
}
|
||||
|
|
|
@ -203,5 +203,35 @@ func (s *Server) patchUserFlag(w http.ResponseWriter, r *http.Request) error {
|
|||
}
|
||||
|
||||
func (s *Server) deleteUserFlag(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"}
|
||||
}
|
||||
|
||||
flag, err := s.DB.UserFlag(ctx, flagID)
|
||||
if err != nil {
|
||||
if err == db.ErrFlagNotFound {
|
||||
return server.APIError{Code: server.ErrNotFound, Details: "Flag not found"}
|
||||
}
|
||||
|
||||
return errors.Wrap(err, "getting flag object")
|
||||
}
|
||||
if flag.UserID != claims.UserID {
|
||||
return server.APIError{Code: server.ErrNotFound, Details: "Flag not found"}
|
||||
}
|
||||
|
||||
err = s.DB.DeleteFlag(ctx, flag.ID, flag.Hash)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "deleting flag")
|
||||
}
|
||||
|
||||
render.NoContent(w, r)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -33,7 +33,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/{flagID}", server.WrapHandler(s.patchUserFlag))
|
||||
r.Delete("/@me/flags", server.WrapHandler(s.deleteUserFlag))
|
||||
r.Delete("/@me/flags/{flagID}", server.WrapHandler(s.deleteUserFlag))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue