mirror of
https://github.com/pocketbase/pocketbase.git
synced 2025-03-20 14:31:09 +02:00
execute the delete realtime access checks against the non-transactional app instance
This commit is contained in:
parent
c70ca97888
commit
25dd858c18
@ -353,7 +353,10 @@ func bindRealtimeEvents(app core.App) {
|
|||||||
Func: func(e *core.ModelEvent) error {
|
Func: func(e *core.ModelEvent) error {
|
||||||
record := realtimeResolveRecord(e.App, e.Model, "")
|
record := realtimeResolveRecord(e.App, e.Model, "")
|
||||||
if record != nil {
|
if record != nil {
|
||||||
err := realtimeBroadcastRecord(e.App, "delete", record, true)
|
// note: use the outside scoped app instance for the access checks so that the API ruless
|
||||||
|
// are performed out of the delete transaction ensuring that they would still work even if
|
||||||
|
// a cascade-deleted record's API rule relies on an already deleted parent record
|
||||||
|
err := realtimeBroadcastRecord(e.App, "delete", record, true, app)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
app.Logger().Debug(
|
app.Logger().Debug(
|
||||||
"Failed to dry cache record delete",
|
"Failed to dry cache record delete",
|
||||||
@ -460,7 +463,11 @@ type recordData struct {
|
|||||||
Action string `json:"action"`
|
Action string `json:"action"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func realtimeBroadcastRecord(app core.App, action string, record *core.Record, dryCache bool) error {
|
// Note: the optAccessCheckApp is there in case you want the access check
|
||||||
|
// to be performed against different db app context (e.g. out of a transaction).
|
||||||
|
// If set, it is expected that optAccessCheckApp instance is used for read-only operations to avoid deadlocks.
|
||||||
|
// If not set, it fallbacks to app.
|
||||||
|
func realtimeBroadcastRecord(app core.App, action string, record *core.Record, dryCache bool, optAccessCheckApp ...core.App) error {
|
||||||
collection := record.Collection()
|
collection := record.Collection()
|
||||||
if collection == nil {
|
if collection == nil {
|
||||||
return errors.New("[broadcastRecord] Record collection not set")
|
return errors.New("[broadcastRecord] Record collection not set")
|
||||||
@ -486,6 +493,11 @@ func realtimeBroadcastRecord(app core.App, action string, record *core.Record, d
|
|||||||
|
|
||||||
group := new(errgroup.Group)
|
group := new(errgroup.Group)
|
||||||
|
|
||||||
|
accessCheckApp := app
|
||||||
|
if len(optAccessCheckApp) > 0 {
|
||||||
|
accessCheckApp = optAccessCheckApp[0]
|
||||||
|
}
|
||||||
|
|
||||||
for _, chunk := range chunks {
|
for _, chunk := range chunks {
|
||||||
group.Go(func() error {
|
group.Go(func() error {
|
||||||
var clientAuth *core.Record
|
var clientAuth *core.Record
|
||||||
@ -502,10 +514,6 @@ func realtimeBroadcastRecord(app core.App, action string, record *core.Record, d
|
|||||||
clientAuth, _ = client.Get(RealtimeClientAuthKey).(*core.Record)
|
clientAuth, _ = client.Get(RealtimeClientAuthKey).(*core.Record)
|
||||||
|
|
||||||
for sub, options := range subs {
|
for sub, options := range subs {
|
||||||
// create a clean record copy without expand and unknown fields
|
|
||||||
// because we don't know yet which exact fields the client subscription has permissions to access
|
|
||||||
cleanRecord := record.Fresh()
|
|
||||||
|
|
||||||
// mock request data
|
// mock request data
|
||||||
requestInfo := &core.RequestInfo{
|
requestInfo := &core.RequestInfo{
|
||||||
Context: core.RequestInfoContextRealtime,
|
Context: core.RequestInfoContextRealtime,
|
||||||
@ -515,10 +523,14 @@ func realtimeBroadcastRecord(app core.App, action string, record *core.Record, d
|
|||||||
Auth: clientAuth,
|
Auth: clientAuth,
|
||||||
}
|
}
|
||||||
|
|
||||||
if !realtimeCanAccessRecord(app, cleanRecord, requestInfo, rule) {
|
if !realtimeCanAccessRecord(accessCheckApp, record, requestInfo, rule) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create a clean record copy without expand and unknown fields because we don't know yet
|
||||||
|
// which exact fields the client subscription requested or has permissions to access
|
||||||
|
cleanRecord := record.Fresh()
|
||||||
|
|
||||||
// trigger the enrich hooks
|
// trigger the enrich hooks
|
||||||
enrichErr := triggerRecordEnrichHooks(app, requestInfo, []*core.Record{cleanRecord}, func() error {
|
enrichErr := triggerRecordEnrichHooks(app, requestInfo, []*core.Record{cleanRecord}, func() error {
|
||||||
// apply expand
|
// apply expand
|
||||||
@ -541,7 +553,7 @@ func realtimeBroadcastRecord(app core.App, action string, record *core.Record, d
|
|||||||
// for auth owner, superuser or manager
|
// for auth owner, superuser or manager
|
||||||
if collection.IsAuth() {
|
if collection.IsAuth() {
|
||||||
if isSameAuth(clientAuth, cleanRecord) ||
|
if isSameAuth(clientAuth, cleanRecord) ||
|
||||||
realtimeCanAccessRecord(app, cleanRecord, requestInfo, collection.ManageRule) {
|
realtimeCanAccessRecord(accessCheckApp, cleanRecord, requestInfo, collection.ManageRule) {
|
||||||
cleanRecord.IgnoreEmailVisibility(true)
|
cleanRecord.IgnoreEmailVisibility(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user