This commit is contained in:
Daniel Ponte 2025-01-21 09:21:46 -05:00
parent 769dd9eb7c
commit 957aebe695
5 changed files with 60 additions and 14 deletions

View file

@ -54,7 +54,7 @@ func (c *CallInIncidentCondition) Check(r *restrict.AccessRequest) error {
return restrict.NewConditionNotSatisfiedError(c, r, errors.New("call ID is not UUID"))
}
inCall, err := database.FromCtx(ctx).CallInIncident(ctx, incID, incID)
inCall, err := database.FromCtx(ctx).CallInIncident(ctx, incID, callID)
if err != nil {
return restrict.NewConditionNotSatisfiedError(c, r, err)
}

View file

@ -139,7 +139,12 @@ func (r *rbac) Check(ctx context.Context, res restrict.Resource, opts ...CheckOp
Context: o.context,
}
return sub, r.access.Authorize(req)
err := r.access.Authorize(req)
if err != nil {
return nil, err
}
return sub, nil
}
type PublicSubject struct {

View file

@ -11,6 +11,7 @@ import (
"dynatron.me/x/stillbox/internal/forms"
"dynatron.me/x/stillbox/pkg/calls/callstore"
"dynatron.me/x/stillbox/pkg/database"
"dynatron.me/x/stillbox/pkg/shares"
"github.com/go-chi/chi/v5"
"github.com/google/uuid"
@ -101,7 +102,7 @@ func (ca *callsAPI) getAudio(p getAudioParams, w http.ResponseWriter, r *http.Re
_, _ = w.Write(call.AudioBlob)
}
func (ca *callsAPI) shareCallRoute(id uuid.UUID, w http.ResponseWriter, r *http.Request) {
func (ca *callsAPI) shareCallRoute(id uuid.UUID, _ *shares.Share, w http.ResponseWriter, r *http.Request) {
p := getAudioParams{
CallID: &id,
}
@ -109,7 +110,7 @@ func (ca *callsAPI) shareCallRoute(id uuid.UUID, w http.ResponseWriter, r *http.
ca.getAudio(p, w, r)
}
func (ca *callsAPI) shareCallDLRoute(id uuid.UUID, w http.ResponseWriter, r *http.Request) {
func (ca *callsAPI) shareCallDLRoute(id uuid.UUID, _ *shares.Share, w http.ResponseWriter, r *http.Request) {
p := getAudioParams{
CallID: &id,
Download: common.PtrTo("download"),

View file

@ -12,6 +12,7 @@ import (
"dynatron.me/x/stillbox/internal/jsontypes"
"dynatron.me/x/stillbox/pkg/incidents"
"dynatron.me/x/stillbox/pkg/incidents/incstore"
"dynatron.me/x/stillbox/pkg/shares"
"dynatron.me/x/stillbox/pkg/talkgroups/tgstore"
"github.com/go-chi/chi/v5"
@ -93,10 +94,10 @@ func (ia *incidentsAPI) getIncidentRoute(w http.ResponseWriter, r *http.Request)
return
}
ia.getIncident(id, w, r)
ia.getIncident(id, nil, w, r)
}
func (ia *incidentsAPI) getIncident(id uuid.UUID, w http.ResponseWriter, r *http.Request) {
func (ia *incidentsAPI) getIncident(id uuid.UUID, share *shares.Share, w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
incs := incstore.FromCtx(ctx)
inc, err := incs.Incident(ctx, id)
@ -194,10 +195,10 @@ func (ia *incidentsAPI) getCallsM3URoute(w http.ResponseWriter, r *http.Request)
return
}
ia.getCallsM3U(id, w, r)
ia.getCallsM3U(id, nil, w, r)
}
func (ia *incidentsAPI) getCallsM3U(id uuid.UUID, w http.ResponseWriter, r *http.Request) {
func (ia *incidentsAPI) getCallsM3U(id uuid.UUID, share *shares.Share, w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
incs := incstore.FromCtx(ctx)
tgst := tgstore.FromCtx(ctx)
@ -211,6 +212,10 @@ func (ia *incidentsAPI) getCallsM3U(id uuid.UUID, w http.ResponseWriter, r *http
b := new(bytes.Buffer)
callUrl := common.PtrTo(*ia.baseURL)
urlRoot := "/api/call"
if share != nil {
urlRoot = fmt.Sprintf("/share/%s/%s/call/", share.Type, share.ID)
}
b.WriteString("#EXTM3U\n\n")
for _, c := range inc.Calls {
@ -224,7 +229,7 @@ func (ia *incidentsAPI) getCallsM3U(id uuid.UUID, w http.ResponseWriter, r *http
from = fmt.Sprintf(" from %d", c.Source)
}
callUrl.Path = "/api/call/" + c.ID.String()
callUrl.Path = urlRoot + c.ID.String()
fmt.Fprintf(b, "#EXTINF:%d,%s%s (%s)\n%s\n\n",
c.Duration.Seconds(),

View file

@ -29,14 +29,23 @@ const (
func (rt ShareRequestType) IsValid() bool {
switch rt {
case ShareRequestCall, ShareRequestIncident, ShareRequestIncidentM3U:
case ShareRequestCall, ShareRequestCallDL, ShareRequestIncident, ShareRequestIncidentM3U:
return true
}
return false
}
type HandlerFunc func(uuid.UUID, http.ResponseWriter, *http.Request)
func (rt ShareRequestType) IsValidSubtype() bool {
switch rt {
case ShareRequestCall, ShareRequestCallDL:
return true
}
return false
}
type HandlerFunc func(id uuid.UUID, share *shares.Share, w http.ResponseWriter, r *http.Request)
type ShareHandlers map[ShareRequestType]HandlerFunc
type shareAPI struct {
baseURL *url.URL
@ -63,6 +72,7 @@ func (sa *shareAPI) RootRouter() http.Handler {
r := chi.NewMux()
r.Get("/{type}/{shareId:[A-Za-z0-9_-]{20,}}", sa.routeShare)
r.Get("/{type}/{shareId:[A-Za-z0-9_-]{20,}}/{subType}/{subID}", sa.routeShare)
return r
}
@ -92,8 +102,10 @@ func (sa *shareAPI) routeShare(w http.ResponseWriter, r *http.Request) {
shs := shares.FromCtx(ctx)
params := struct {
Type string `param:"type"`
ID string `param:"shareId"`
Type string `param:"type"`
ID string `param:"shareId"`
SubType *string `param:"subType"`
SubID *string `param:"subID"`
}{}
err := decodeParams(&params, r)
@ -124,7 +136,30 @@ func (sa *shareAPI) routeShare(w http.ResponseWriter, r *http.Request) {
ctx = rbac.CtxWithSubject(ctx, sh)
r = r.WithContext(ctx)
sa.shnd[rType](sh.EntityID, w, r)
if params.SubType != nil {
if params.SubID == nil {
// probably can't happen
wErr(w, r, autoError(ErrBadShare))
return
}
subT := ShareRequestType(*params.SubType)
if !subT.IsValidSubtype() {
wErr(w, r, autoError(ErrBadShare))
return
}
subIDU, err := uuid.Parse(*params.SubID)
if err != nil {
wErr(w, r, badRequest(err))
return
}
sa.shnd[subT](subIDU, sh, w, r)
return
}
sa.shnd[rType](sh.EntityID, sh, w, r)
}
func (sa *shareAPI) deleteShare(w http.ResponseWriter, r *http.Request) {