feat(admin): add routed task evidence details
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"mime"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"cmbuyer/admin/internal/taskdetail"
|
||||
"cmbuyer/admin/internal/transport/webui"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
const detailViewHeader = "X-CMBuyer-View"
|
||||
const detailVaryHeader = "X-CMBuyer-View, Accept, Sec-Fetch-Site"
|
||||
|
||||
func taskDetailPage(options Options) gin.HandlerFunc {
|
||||
return func(context *gin.Context) {
|
||||
context.Header("Vary", detailVaryHeader)
|
||||
if !options.Sessions.IsAuthenticated(context.Request) {
|
||||
context.Redirect(http.StatusSeeOther, "/login?return_to="+url.QueryEscape(context.Request.URL.RequestURI()))
|
||||
return
|
||||
}
|
||||
view := context.GetHeader(detailViewHeader)
|
||||
if view != "" && view != "drawer" {
|
||||
context.Status(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if view == "drawer" {
|
||||
if context.GetHeader("Sec-Fetch-Site") != "same-origin" {
|
||||
context.Status(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
if !acceptsHTML(context.GetHeader("Accept")) {
|
||||
context.Status(http.StatusNotAcceptable)
|
||||
return
|
||||
}
|
||||
}
|
||||
detail, err := options.TaskDetails.Get(context.Request.Context(), context.Param("id"))
|
||||
if errors.Is(err, taskdetail.ErrNotFound) {
|
||||
context.Status(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
context.Status(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
context.Header("Content-Type", "text/html; charset=utf-8")
|
||||
context.Status(http.StatusOK)
|
||||
data := webui.TaskDetailData{Detail: detail}
|
||||
if view == "drawer" {
|
||||
if err := webui.RenderTaskDetailFragment(context.Writer, data); err != nil {
|
||||
_ = context.Error(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err := webui.RenderTaskDetailPage(context.Writer, data); err != nil {
|
||||
_ = context.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func acceptsHTML(header string) bool {
|
||||
for _, value := range strings.Split(header, ",") {
|
||||
mediaType, parameters, err := mime.ParseMediaType(strings.TrimSpace(value))
|
||||
if err != nil || !strings.EqualFold(mediaType, "text/html") {
|
||||
continue
|
||||
}
|
||||
quality := 1.0
|
||||
if rawQuality, exists := parameters["q"]; exists {
|
||||
quality, err = strconv.ParseFloat(rawQuality, 64)
|
||||
if err != nil || quality < 0 || quality > 1 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if quality > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user