mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2026-10-01 12:31:59 +00:00
feat(security): exclude hidden/masked columns from create and update payloads
This commit is contained in:
@@ -596,6 +596,9 @@ func (h *Handler) executeUpdate(ctx context.Context, schema, entity, id string,
|
||||
Data: updates,
|
||||
Tx: h.db,
|
||||
}
|
||||
if err := h.hooks.Execute(BeforeHandle, hookCtx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var updateResult interface{}
|
||||
err = h.runInTx(ctx, hookCtx, func(tx common.Database) error {
|
||||
|
||||
@@ -36,6 +36,21 @@ func RegisterSecurityHooks(handler *Handler, securityList *security.SecurityList
|
||||
return nil
|
||||
})
|
||||
|
||||
// BeforeHandle: preload column rules for writes before the handler opens its
|
||||
// transaction; the write hooks below only read the cache.
|
||||
handler.Hooks().Register(BeforeHandle, func(hookCtx *HookContext) error {
|
||||
return security.PreloadSecurityRules(newSecurityContext(hookCtx), securityList, hookCtx.Operation)
|
||||
})
|
||||
|
||||
// BeforeCreate/BeforeUpdate: drop columns hidden or masked for the user from the
|
||||
// write payload, so they cannot be inserted or updated.
|
||||
handler.Hooks().Register(BeforeCreate, func(hookCtx *HookContext) error {
|
||||
return security.ApplyWriteColumnSecurity(newSecurityContext(hookCtx), securityList)
|
||||
})
|
||||
handler.Hooks().Register(BeforeUpdate, func(hookCtx *HookContext) error {
|
||||
return security.ApplyWriteColumnSecurity(newSecurityContext(hookCtx), securityList)
|
||||
})
|
||||
|
||||
// BeforeRead (1st): load RLS + CLS rules from the provider into SecurityList.
|
||||
handler.Hooks().Register(BeforeRead, func(hookCtx *HookContext) error {
|
||||
return security.LoadSecurityRules(newSecurityContext(hookCtx), securityList)
|
||||
@@ -123,6 +138,14 @@ func (s *securityContext) SetQuery(query interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *securityContext) GetData() interface{} {
|
||||
return s.ctx.Data
|
||||
}
|
||||
|
||||
func (s *securityContext) SetData(data interface{}) {
|
||||
s.ctx.Data = data
|
||||
}
|
||||
|
||||
func (s *securityContext) GetResult() interface{} {
|
||||
return s.ctx.Result
|
||||
}
|
||||
|
||||
@@ -293,6 +293,10 @@ func TestOnTxBeginErrorRollsBackEveryOperation(t *testing.T) {
|
||||
|
||||
type stubProvider struct{ security.SecurityProvider }
|
||||
|
||||
func (stubProvider) GetColumnSecurity(context.Context, int, string, string) ([]security.ColumnSecurity, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func TestSecurityHooksStampTxSettingsOnEveryTransaction(t *testing.T) {
|
||||
h, mock, ctx := newTxHarness(t)
|
||||
list, err := security.NewSecurityList(stubProvider{})
|
||||
@@ -304,6 +308,7 @@ func TestSecurityHooksStampTxSettingsOnEveryTransaction(t *testing.T) {
|
||||
})
|
||||
RegisterSecurityHooks(h, list)
|
||||
ctx = context.WithValue(ctx, security.UserContextKey, &security.UserContext{UserID: 7, UserName: "u"})
|
||||
ctx = context.WithValue(ctx, security.UserIDKey, 7)
|
||||
|
||||
// Update opens two transactions; each must be stamped before any other SQL.
|
||||
cols := []string{"id", "name"}
|
||||
|
||||
Reference in New Issue
Block a user