fetch is a generic function that wraps a database query function (returns an object and an error) with authorization. The returned function has the same arguments as the database function. The database query function will **ALWAYS** hit the database, even if the user cannot read the resource. This
( logger slog.Logger, authorizer rbac.Authorizer, action policy.Action, f DatabaseFunc, )
| 998 | // user cannot read the resource. This is because the resource details are |
| 999 | // required to run a proper authorization check. |
| 1000 | func fetchWithAction[ |
| 1001 | ArgumentType any, |
| 1002 | ObjectType rbac.Objecter, |
| 1003 | DatabaseFunc func(ctx context.Context, arg ArgumentType) (ObjectType, error), |
| 1004 | ]( |
| 1005 | logger slog.Logger, |
| 1006 | authorizer rbac.Authorizer, |
| 1007 | action policy.Action, |
| 1008 | f DatabaseFunc, |
| 1009 | ) DatabaseFunc { |
| 1010 | return func(ctx context.Context, arg ArgumentType) (empty ObjectType, err error) { |
| 1011 | // Fetch the rbac subject |
| 1012 | act, ok := ActorFromContext(ctx) |
| 1013 | if !ok { |
| 1014 | return empty, ErrNoActor |
| 1015 | } |
| 1016 | |
| 1017 | // Fetch the database object |
| 1018 | object, err := f(ctx, arg) |
| 1019 | if err != nil { |
| 1020 | return empty, xerrors.Errorf("fetch object: %w", err) |
| 1021 | } |
| 1022 | |
| 1023 | // Authorize the action |
| 1024 | err = authorizer.Authorize(ctx, act, action, object.RBACObject()) |
| 1025 | if err != nil { |
| 1026 | return empty, logNotAuthorizedError(ctx, logger, err) |
| 1027 | } |
| 1028 | |
| 1029 | return object, nil |
| 1030 | } |
| 1031 | } |
| 1032 | |
| 1033 | func fetch[ |
| 1034 | ArgumentType any, |
no test coverage detected