Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ba172ea

Browse files
committed
Fixup generic func comments
1 parent 13f1c9f commit ba172ea

File tree

1 file changed

+47
-39
lines changed

1 file changed

+47
-39
lines changed

coderd/authzquery/authz.go

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ func LogNotAuthorizedError(ctx context.Context, logger slog.Logger, err error) e
5454
}
5555
}
5656

57+
// insert is the same as insertWithReturn, but does not return the inserted object.
5758
func insert[ArgumentType any,
5859
Insert func(ctx context.Context, arg ArgumentType) error](
5960
// Arguments
@@ -69,6 +70,9 @@ func insert[ArgumentType any,
6970
}
7071
}
7172

73+
// insertWithReturn runs an rbac.ActionCreate on the rbac object argument before
74+
// running the insertFunc. The insertFunc is expected to return the object that
75+
// was inserted.
7276
func insertWithReturn[ObjectType any, ArgumentType any,
7377
Insert func(ctx context.Context, arg ArgumentType) (ObjectType, error)](
7478
// Arguments
@@ -130,9 +134,45 @@ func update[ObjectType rbac.Objecter,
130134
return fetchAndExec(logger, authorizer, rbac.ActionUpdate, fetchFunc, updateExec)
131135
}
132136

133-
// authorizedFetchAndExecWithConverter uses authorizedFetchAndQueryWithConverter but
134-
// only cares about the error return type. SQL execs only return an error.
135-
// See authorizedFetchAndQueryWithConverter for more details.
137+
// fetch is a generic function that wraps a database
138+
// query function (returns an object and an error) with authorization. The
139+
// returned function has the same arguments as the database function.
140+
//
141+
// The database query function will **ALWAYS** hit the database, even if the
142+
// user cannot read the resource. This is because the resource details are
143+
// required to run a proper authorization check.
144+
func fetch[ArgumentType any, ObjectType rbac.Objecter,
145+
DatabaseFunc func(ctx context.Context, arg ArgumentType) (ObjectType, error)](
146+
// Arguments
147+
logger slog.Logger,
148+
authorizer rbac.Authorizer,
149+
f DatabaseFunc) DatabaseFunc {
150+
return func(ctx context.Context, arg ArgumentType) (empty ObjectType, err error) {
151+
// Fetch the rbac subject
152+
act, ok := ActorFromContext(ctx)
153+
if !ok {
154+
return empty, NoActorError
155+
}
156+
157+
// Fetch the database object
158+
object, err := f(ctx, arg)
159+
if err != nil {
160+
return empty, xerrors.Errorf("fetch object: %w", err)
161+
}
162+
163+
// Authorize the action
164+
err = authorizer.Authorize(ctx, act, rbac.ActionRead, object.RBACObject())
165+
if err != nil {
166+
return empty, LogNotAuthorizedError(ctx, logger, err)
167+
}
168+
169+
return object, nil
170+
}
171+
}
172+
173+
// fetchAndExec uses fetchAndQuery but only returns the error. The naming comes
174+
// from SQL 'exec' functions which only return an error.
175+
// See fetchAndQuery for more information.
136176
func fetchAndExec[ObjectType rbac.Objecter,
137177
ArgumentType any,
138178
Fetch func(ctx context.Context, arg ArgumentType) (ObjectType, error),
@@ -152,6 +192,10 @@ func fetchAndExec[ObjectType rbac.Objecter,
152192
}
153193
}
154194

195+
// fetchAndQuery is a generic function that wraps a database fetch and query.
196+
// The fetch is used to know which rbac object the action should be asserted on
197+
// **before** the query runs. The returns from the fetch are only used to
198+
// assert rbac. The final return of this function comes from the Query function.
155199
func fetchAndQuery[ObjectType rbac.Objecter, ArgumentType any,
156200
Fetch func(ctx context.Context, arg ArgumentType) (ObjectType, error),
157201
Query func(ctx context.Context, arg ArgumentType) (ObjectType, error)](
@@ -184,42 +228,6 @@ func fetchAndQuery[ObjectType rbac.Objecter, ArgumentType any,
184228
}
185229
}
186230

187-
// fetch is a generic function that wraps a database
188-
// query function (returns an object and an error) with authorization. The
189-
// returned function has the same arguments as the database function.
190-
//
191-
// The database query function will **ALWAYS** hit the database, even if the
192-
// user cannot read the resource. This is because the resource details are
193-
// required to run a proper authorization check.
194-
func fetch[ArgumentType any, ObjectType rbac.Objecter,
195-
DatabaseFunc func(ctx context.Context, arg ArgumentType) (ObjectType, error)](
196-
// Arguments
197-
logger slog.Logger,
198-
authorizer rbac.Authorizer,
199-
f DatabaseFunc) DatabaseFunc {
200-
return func(ctx context.Context, arg ArgumentType) (empty ObjectType, err error) {
201-
// Fetch the rbac subject
202-
act, ok := ActorFromContext(ctx)
203-
if !ok {
204-
return empty, NoActorError
205-
}
206-
207-
// Fetch the database object
208-
object, err := f(ctx, arg)
209-
if err != nil {
210-
return empty, xerrors.Errorf("fetch object: %w", err)
211-
}
212-
213-
// Authorize the action
214-
err = authorizer.Authorize(ctx, act, rbac.ActionRead, object.RBACObject())
215-
if err != nil {
216-
return empty, LogNotAuthorizedError(ctx, logger, err)
217-
}
218-
219-
return object, nil
220-
}
221-
}
222-
223231
// fetchWithPostFilter is like fetch, but works with lists of objects.
224232
// SQL filters are much more optimal.
225233
func fetchWithPostFilter[ArgumentType any, ObjectType rbac.Objecter,

0 commit comments

Comments
 (0)