API: Rename CommentsByID => CommentsByIDUnsafe

Because this function makes no attempt at verifying that the user is
permitted to view this comment, and it's the caller's responsibility to
verify that.
This commit is contained in:
Drew DeVault 2021-02-16 09:12:36 -05:00
parent b82659cd0b
commit 655aafa25e
2 changed files with 19 additions and 9 deletions

View File

@ -40,12 +40,18 @@ func (r *commentResolver) Author(ctx context.Context, obj *model.Comment) (model
}
func (r *commentResolver) Text(ctx context.Context, obj *model.Comment) (string, error) {
comment, err := loaders.ForContext(ctx).CommentsByID.Load(obj.Database.ID)
// The only route to this resolver is via event details, which is already
// authenticated. Further access to other resources is limited to
// authenticated routes, such as TicketByID.
comment, err := loaders.ForContext(ctx).CommentsByIDUnsafe.Load(obj.Database.ID)
return comment.Database.Text, err
}
func (r *commentResolver) Authenticity(ctx context.Context, obj *model.Comment) (model.Authenticity, error) {
comment, err := loaders.ForContext(ctx).CommentsByID.Load(obj.Database.ID)
// The only route to this resolver is via event details, which is already
// authenticated. Further access to other resources is limited to
// authenticated routes, such as TicketByID.
comment, err := loaders.ForContext(ctx).CommentsByIDUnsafe.Load(obj.Database.ID)
return comment.Database.Authenticity, err
}
@ -53,7 +59,10 @@ func (r *commentResolver) SuperceededBy(ctx context.Context, obj *model.Comment)
if obj.Database.SuperceededByID == nil {
return nil, nil
}
return loaders.ForContext(ctx).CommentsByID.Load(*obj.Database.SuperceededByID)
// The only route to this resolver is via event details, which is already
// authenticated. Further access to other resources is limited to
// authenticated routes, such as TicketByID.
return loaders.ForContext(ctx).CommentsByIDUnsafe.Load(*obj.Database.SuperceededByID)
}
func (r *createdResolver) Ticket(ctx context.Context, obj *model.Created) (*model.Ticket, error) {

View File

@ -39,9 +39,10 @@ type Loaders struct {
TrackersByName TrackersByNameLoader
TrackersByOwnerName TrackersByOwnerNameLoader
TicketsByID TicketsByIDLoader
CommentsByID CommentsByIDLoader
ParticipantsByID ParticipantsByIDLoader
LabelsByID LabelsByIDLoader
CommentsByIDUnsafe CommentsByIDLoader
}
func fetchUsersByID(ctx context.Context) func(ids []int) ([]*model.User, []error) {
@ -263,7 +264,6 @@ func fetchTrackersByOwnerName(ctx context.Context) func(tuples [][2]string) ([]*
for i, tuple := range tuples {
ownerNames[i] = tuple[0] + "/" + tuple[1]
}
// TODO: Stash the ACL details in case they're useful later?
auser := auth.ForContext(ctx)
query := database.
Select(ctx).
@ -386,8 +386,9 @@ func fetchTicketsByID(ctx context.Context) func(ids []int) ([]*model.Ticket, []e
}
}
// NOTICE: This does not do any ACL checks.
func fetchCommentsByID(ctx context.Context) func(ids []int) ([]*model.Comment, []error) {
// This function presumes that the user is authorized to read this comment, no
// ACL tests are attempted.
func fetchCommentsByIDUnsafe(ctx context.Context) func(ids []int) ([]*model.Comment, []error) {
return func(ids []int) ([]*model.Comment, []error) {
comments := make([]*model.Comment, len(ids))
if err := database.WithTx(ctx, &sql.TxOptions{
@ -630,10 +631,10 @@ func Middleware(next http.Handler) http.Handler {
wait: 1 * time.Millisecond,
fetch: fetchTicketsByID(r.Context()),
},
CommentsByID: CommentsByIDLoader{
CommentsByIDUnsafe: CommentsByIDLoader{
maxBatch: 100,
wait: 1 * time.Millisecond,
fetch: fetchCommentsByID(r.Context()),
fetch: fetchCommentsByIDUnsafe(r.Context()),
},
ParticipantsByID: ParticipantsByIDLoader{
maxBatch: 100,