67 lines
2.4 KiB
Go
67 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"net/http"
|
|
"time"
|
|
|
|
"git.cin.su/m/Assistant/contracts/authority"
|
|
"git.cin.su/m/Assistant/contracts/continuity"
|
|
"git.cin.su/m/Assistant/contracts/identity"
|
|
continuitydomain "git.cin.su/m/Assistant/modules/continuity/domain"
|
|
"git.cin.su/m/Assistant/platform/ids"
|
|
)
|
|
|
|
type responseRepository interface {
|
|
ResponseCandidates(context.Context, identity.PrincipalID, int) ([]continuitydomain.ResponseCandidate, error)
|
|
ApplyHumanResponse(context.Context, continuity.HumanResponse) error
|
|
}
|
|
|
|
func registerCreatorResponseRoute(mux *http.ServeMux, identityClient creatorIdentityClient, repository responseRepository, now func() time.Time) {
|
|
mux.HandleFunc("POST /v1/creator/responses", func(w http.ResponseWriter, r *http.Request) {
|
|
session, err := identityClient.Session(r.Context(), r.Header.Get("Authorization"))
|
|
if errors.Is(err, errCreatorSessionDenied) {
|
|
http.Error(w, "creator session denied", http.StatusUnauthorized)
|
|
return
|
|
}
|
|
if err != nil {
|
|
http.Error(w, "identity service unavailable", http.StatusServiceUnavailable)
|
|
return
|
|
}
|
|
var request continuity.HumanResponseRequest
|
|
decoder := json.NewDecoder(http.MaxBytesReader(w, r.Body, 32<<10))
|
|
decoder.DisallowUnknownFields()
|
|
if err := decoder.Decode(&request); err != nil {
|
|
http.Error(w, "invalid human response", http.StatusBadRequest)
|
|
return
|
|
}
|
|
responseID, err := ids.New()
|
|
if err != nil {
|
|
http.Error(w, "human response unavailable", http.StatusServiceUnavailable)
|
|
return
|
|
}
|
|
candidates, err := repository.ResponseCandidates(r.Context(), session.PrincipalID, 20)
|
|
if err != nil {
|
|
http.Error(w, "response candidates unavailable", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
result, err := continuitydomain.InterpretHumanResponse(request, session.PrincipalID, authority.ScopeID("domovoy-global-scope"), continuity.HumanResponseID(responseID), candidates, now())
|
|
if err != nil {
|
|
http.Error(w, "invalid human response", http.StatusBadRequest)
|
|
return
|
|
}
|
|
if result.Handled {
|
|
if err := repository.ApplyHumanResponse(r.Context(), result.Response); err != nil {
|
|
http.Error(w, "apply human response", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Header().Set("Cache-Control", "no-store")
|
|
w.WriteHeader(http.StatusCreated)
|
|
_ = json.NewEncoder(w).Encode(result)
|
|
})
|
|
}
|