147 lines
3.6 KiB
Go
147 lines
3.6 KiB
Go
package bot
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
|
|
"codeberg.org/nextgo/dbots/internal/db"
|
|
"codeberg.org/nextgo/dbots/internal/errorutil"
|
|
"codeberg.org/nextgo/dbots/internal/middleware"
|
|
"codeberg.org/nextgo/dbots/internal/paginate"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/go-chi/render"
|
|
)
|
|
|
|
type Router struct {
|
|
bots *Service
|
|
router chi.Router
|
|
}
|
|
|
|
func NewRouter(q *db.Queries) *Router {
|
|
return &Router{
|
|
bots: NewService(q),
|
|
router: chi.NewRouter(),
|
|
}
|
|
}
|
|
|
|
func (r *Router) Routes() http.Handler {
|
|
r.router.Get("/", r.listBots) // todo: deprecate this
|
|
r.router.With(middleware.AuthGuardMiddleware).Post("/", r.submitBot)
|
|
r.router.Route("/{botID}", func(router chi.Router) {
|
|
router.Use(middleware.BotContext(r.bots.q))
|
|
router.With(r.BotCache).Get("/", r.getBot)
|
|
router.Route("/co-owners", func(c chi.Router) {
|
|
c.Use(middleware.AuthGuardMiddleware)
|
|
c.Get("/", r.listCoOwners)
|
|
c.Post("/{userID}", r.addCoOwner)
|
|
c.Delete("/{userID}", r.removeCoOwner)
|
|
})
|
|
})
|
|
|
|
return r.router
|
|
}
|
|
|
|
func (r *Router) submitBot(w http.ResponseWriter, req *http.Request) {
|
|
var data CreateBotRequest
|
|
|
|
if err := render.Bind(req, &data); err != nil {
|
|
render.Render(w, req, errorutil.ErrInvalidRequest(err))
|
|
return
|
|
}
|
|
|
|
ctx := req.Context()
|
|
bot, err := r.bots.Submit(ctx, data)
|
|
if err != nil {
|
|
if errors.Is(err, errorutil.ErrBotAlreadyExists) {
|
|
render.Render(w, req, errorutil.ErrInvalidRequest(err))
|
|
} else {
|
|
render.Render(w, req, errorutil.ErrInternal(err))
|
|
}
|
|
return
|
|
}
|
|
|
|
render.Status(req, http.StatusCreated)
|
|
render.JSON(w, req, bot)
|
|
}
|
|
|
|
func (r *Router) getBot(w http.ResponseWriter, req *http.Request) {
|
|
ctx := req.Context()
|
|
bot := middleware.GetBot(ctx)
|
|
|
|
render.JSON(w, req, bot)
|
|
}
|
|
|
|
func (r *Router) listBots(w http.ResponseWriter, req *http.Request) {
|
|
ctx := req.Context()
|
|
query := req.URL.Query().Get("q")
|
|
p := paginate.ParseParams(req)
|
|
|
|
page, err := r.bots.List(ctx, query, p)
|
|
if err != nil {
|
|
render.Render(w, req, errorutil.ErrInvalidRequest(err))
|
|
return
|
|
}
|
|
|
|
render.JSON(w, req, page)
|
|
}
|
|
|
|
func (r *Router) listCoOwners(w http.ResponseWriter, req *http.Request) {
|
|
ctx := req.Context()
|
|
bot := middleware.GetBot(ctx)
|
|
|
|
owners, err := r.bots.ListCoOwners(ctx, bot.ID)
|
|
if err != nil {
|
|
render.Render(w, req, errorutil.ErrInternal(err))
|
|
return
|
|
}
|
|
|
|
render.JSON(w, req, owners)
|
|
}
|
|
|
|
func (r *Router) addCoOwner(w http.ResponseWriter, req *http.Request) {
|
|
ctx := req.Context()
|
|
bot := middleware.GetBot(ctx)
|
|
userID := chi.URLParam(req, "userID")
|
|
|
|
if err := r.bots.AddCoOwner(ctx, bot.ID, userID); err != nil {
|
|
switch {
|
|
case errors.Is(err, errorutil.ErrNotFound.Err):
|
|
render.Render(w, req, errorutil.ErrNotFound)
|
|
case errors.Is(err, errorutil.ErrForbidden.Err):
|
|
render.Render(w, req, errorutil.ErrForbidden)
|
|
default:
|
|
render.Render(w, req, errorutil.ErrInvalidRequest(err))
|
|
}
|
|
return
|
|
}
|
|
|
|
render.NoContent(w, req)
|
|
}
|
|
|
|
func (r *Router) removeCoOwner(w http.ResponseWriter, req *http.Request) {
|
|
ctx := req.Context()
|
|
bot := middleware.GetBot(ctx)
|
|
userID := chi.URLParam(req, "userID")
|
|
|
|
if err := r.bots.RemoveCoOwner(ctx, bot.ID, userID); err != nil {
|
|
switch {
|
|
case errors.Is(err, errorutil.ErrNotFound.Err):
|
|
render.Render(w, req, errorutil.ErrNotFound)
|
|
case errors.Is(err, errorutil.ErrForbidden.Err):
|
|
render.Render(w, req, errorutil.ErrForbidden)
|
|
default:
|
|
render.Render(w, req, errorutil.ErrInternal(err))
|
|
}
|
|
return
|
|
}
|
|
|
|
render.NoContent(w, req)
|
|
}
|
|
|
|
func (r *Router) BotCache(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
|
w.Header().Add("Cache-Control", "max-age=3600")
|
|
next.ServeHTTP(w, req)
|
|
})
|
|
}
|