Working!
This commit is contained in:
parent
769dd9eb7c
commit
957aebe695
5 changed files with 60 additions and 14 deletions
|
@ -54,7 +54,7 @@ func (c *CallInIncidentCondition) Check(r *restrict.AccessRequest) error {
|
||||||
return restrict.NewConditionNotSatisfiedError(c, r, errors.New("call ID is not UUID"))
|
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 {
|
if err != nil {
|
||||||
return restrict.NewConditionNotSatisfiedError(c, r, err)
|
return restrict.NewConditionNotSatisfiedError(c, r, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,7 +139,12 @@ func (r *rbac) Check(ctx context.Context, res restrict.Resource, opts ...CheckOp
|
||||||
Context: o.context,
|
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 {
|
type PublicSubject struct {
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"dynatron.me/x/stillbox/internal/forms"
|
"dynatron.me/x/stillbox/internal/forms"
|
||||||
"dynatron.me/x/stillbox/pkg/calls/callstore"
|
"dynatron.me/x/stillbox/pkg/calls/callstore"
|
||||||
"dynatron.me/x/stillbox/pkg/database"
|
"dynatron.me/x/stillbox/pkg/database"
|
||||||
|
"dynatron.me/x/stillbox/pkg/shares"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
@ -101,7 +102,7 @@ func (ca *callsAPI) getAudio(p getAudioParams, w http.ResponseWriter, r *http.Re
|
||||||
_, _ = w.Write(call.AudioBlob)
|
_, _ = 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{
|
p := getAudioParams{
|
||||||
CallID: &id,
|
CallID: &id,
|
||||||
}
|
}
|
||||||
|
@ -109,7 +110,7 @@ func (ca *callsAPI) shareCallRoute(id uuid.UUID, w http.ResponseWriter, r *http.
|
||||||
ca.getAudio(p, w, r)
|
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{
|
p := getAudioParams{
|
||||||
CallID: &id,
|
CallID: &id,
|
||||||
Download: common.PtrTo("download"),
|
Download: common.PtrTo("download"),
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"dynatron.me/x/stillbox/internal/jsontypes"
|
"dynatron.me/x/stillbox/internal/jsontypes"
|
||||||
"dynatron.me/x/stillbox/pkg/incidents"
|
"dynatron.me/x/stillbox/pkg/incidents"
|
||||||
"dynatron.me/x/stillbox/pkg/incidents/incstore"
|
"dynatron.me/x/stillbox/pkg/incidents/incstore"
|
||||||
|
"dynatron.me/x/stillbox/pkg/shares"
|
||||||
"dynatron.me/x/stillbox/pkg/talkgroups/tgstore"
|
"dynatron.me/x/stillbox/pkg/talkgroups/tgstore"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
|
@ -93,10 +94,10 @@ func (ia *incidentsAPI) getIncidentRoute(w http.ResponseWriter, r *http.Request)
|
||||||
return
|
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()
|
ctx := r.Context()
|
||||||
incs := incstore.FromCtx(ctx)
|
incs := incstore.FromCtx(ctx)
|
||||||
inc, err := incs.Incident(ctx, id)
|
inc, err := incs.Incident(ctx, id)
|
||||||
|
@ -194,10 +195,10 @@ func (ia *incidentsAPI) getCallsM3URoute(w http.ResponseWriter, r *http.Request)
|
||||||
return
|
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()
|
ctx := r.Context()
|
||||||
incs := incstore.FromCtx(ctx)
|
incs := incstore.FromCtx(ctx)
|
||||||
tgst := tgstore.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)
|
b := new(bytes.Buffer)
|
||||||
|
|
||||||
callUrl := common.PtrTo(*ia.baseURL)
|
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")
|
b.WriteString("#EXTM3U\n\n")
|
||||||
for _, c := range inc.Calls {
|
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)
|
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",
|
fmt.Fprintf(b, "#EXTINF:%d,%s%s (%s)\n%s\n\n",
|
||||||
c.Duration.Seconds(),
|
c.Duration.Seconds(),
|
||||||
|
|
|
@ -29,14 +29,23 @@ const (
|
||||||
|
|
||||||
func (rt ShareRequestType) IsValid() bool {
|
func (rt ShareRequestType) IsValid() bool {
|
||||||
switch rt {
|
switch rt {
|
||||||
case ShareRequestCall, ShareRequestIncident, ShareRequestIncidentM3U:
|
case ShareRequestCall, ShareRequestCallDL, ShareRequestIncident, ShareRequestIncidentM3U:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
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 ShareHandlers map[ShareRequestType]HandlerFunc
|
||||||
type shareAPI struct {
|
type shareAPI struct {
|
||||||
baseURL *url.URL
|
baseURL *url.URL
|
||||||
|
@ -63,6 +72,7 @@ func (sa *shareAPI) RootRouter() http.Handler {
|
||||||
r := chi.NewMux()
|
r := chi.NewMux()
|
||||||
|
|
||||||
r.Get("/{type}/{shareId:[A-Za-z0-9_-]{20,}}", sa.routeShare)
|
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
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,8 +102,10 @@ func (sa *shareAPI) routeShare(w http.ResponseWriter, r *http.Request) {
|
||||||
shs := shares.FromCtx(ctx)
|
shs := shares.FromCtx(ctx)
|
||||||
|
|
||||||
params := struct {
|
params := struct {
|
||||||
Type string `param:"type"`
|
Type string `param:"type"`
|
||||||
ID string `param:"shareId"`
|
ID string `param:"shareId"`
|
||||||
|
SubType *string `param:"subType"`
|
||||||
|
SubID *string `param:"subID"`
|
||||||
}{}
|
}{}
|
||||||
|
|
||||||
err := decodeParams(¶ms, r)
|
err := decodeParams(¶ms, r)
|
||||||
|
@ -124,7 +136,30 @@ func (sa *shareAPI) routeShare(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx = rbac.CtxWithSubject(ctx, sh)
|
ctx = rbac.CtxWithSubject(ctx, sh)
|
||||||
r = r.WithContext(ctx)
|
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) {
|
func (sa *shareAPI) deleteShare(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
Loading…
Reference in a new issue