1
0
mirror of https://github.com/pocketbase/pocketbase.git synced 2025-03-18 21:57:50 +02:00

use Dao.CanAccessRecord when checking for protected file access

This commit is contained in:
Gani Georgiev 2023-07-17 00:03:09 +03:00
parent 3eaa3ca1b5
commit f421da4b9b

View File

@ -7,14 +7,11 @@ import (
"strings"
"github.com/labstack/echo/v5"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/models"
"github.com/pocketbase/pocketbase/models/schema"
"github.com/pocketbase/pocketbase/resolvers"
"github.com/pocketbase/pocketbase/tokens"
"github.com/pocketbase/pocketbase/tools/list"
"github.com/pocketbase/pocketbase/tools/search"
"github.com/pocketbase/pocketbase/tools/security"
"github.com/spf13/cast"
)
@ -97,7 +94,17 @@ func (api *fileApi) download(c echo.Context) error {
adminOrAuthRecord, _ := api.findAdminOrAuthRecordByFileToken(token)
if !api.canAccessRecord(adminOrAuthRecord, record, record.Collection().ViewRule) {
// create a copy of the cached request data and adjust it to the current auth record
requestData := *RequestData(c)
if adminOrAuthRecord != nil {
if admin, _ := adminOrAuthRecord.(*models.Admin); admin != nil {
requestData.Admin = admin
} else if record, _ := adminOrAuthRecord.(*models.Record); record != nil {
requestData.AuthRecord = record
}
}
if ok, _ := api.app.Dao().CanAccessRecord(record, &requestData, record.Collection().ViewRule); !ok {
return NewForbiddenError("Insufficient permissions to access the file resource.", nil)
}
}
@ -201,46 +208,3 @@ func (api *fileApi) findAdminOrAuthRecordByFileToken(fileToken string) (models.M
return nil, errors.New("missing or invalid file token")
}
// @todo move to a helper and maybe combine with the realtime checks when refactoring the realtime service
func (api *fileApi) canAccessRecord(adminOrAuthRecord models.Model, record *models.Record, accessRule *string) bool {
admin, _ := adminOrAuthRecord.(*models.Admin)
if admin != nil {
// admins can access everything
return true
}
if accessRule == nil {
// only admins can access this record
return false
}
ruleFunc := func(q *dbx.SelectQuery) error {
if *accessRule == "" {
return nil // empty public rule
}
// mock request data
requestData := &models.RequestData{
Method: "GET",
}
requestData.AuthRecord, _ = adminOrAuthRecord.(*models.Record)
resolver := resolvers.NewRecordFieldResolver(api.app.Dao(), record.Collection(), requestData, true)
expr, err := search.FilterData(*accessRule).BuildExpr(resolver)
if err != nil {
return err
}
resolver.UpdateQuery(q)
q.AndWhere(expr)
return nil
}
foundRecord, err := api.app.Dao().FindRecordById(record.Collection().Id, record.Id, ruleFunc)
if err == nil && foundRecord != nil {
return true
}
return false
}