85 lines
2.1 KiB
Go
85 lines
2.1 KiB
Go
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
|
|
}
|