internal/gaby: check if comment author is allowed to bisect Change-Id: I2880436969d46b4c23eaf06975c3caf32b495a27 Reviewed-on: https://go-review.googlesource.com/c/oscar/+/641895 Reviewed-by: Jonathan Amsterdam <jba@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/internal/gaby/github_event.go b/internal/gaby/github_event.go index c6dbb22..3d76bf1 100644 --- a/internal/gaby/github_event.go +++ b/internal/gaby/github_event.go
@@ -11,6 +11,7 @@ "net/http" "slices" + "cloud.google.com/go/firestore" "golang.org/x/oscar/internal/actions" "golang.org/x/oscar/internal/docs" "golang.org/x/oscar/internal/github" @@ -177,7 +178,6 @@ // spawnBisectionTask checks if event is encoding a bisection task and, // if so, it spawns the corresponding task. func (g *Gaby) spawnBisectionTask(ctx context.Context, event *github.WebhookIssueCommentEvent) error { - // TODO: check the author via secrets? // TODO: access comment through db instead // of directly through the event? breq, err := parseBisectTrigger(event) @@ -189,9 +189,42 @@ g.slog.Info("bisect.Request no trigger", "body", event.Comment.Body) return nil } + + // Check the user only after we established that + // the comment encodes a bisection request, to + // save time on pinging firestore. + user := event.Comment.User.Login + if ok, err := userAllowedBisection(ctx, user); err != nil { + g.slog.Error("bisect.Request permission check", "err", err) + return err + } else if !ok { + g.slog.Info("bisect.Request permission denied", "user", user) + return nil + } + if err := g.bisect.BisectAsync(ctx, breq); err != nil { return err } g.slog.Info("bisect.Request trigger success", "req", fmt.Sprintf("%+v", breq)) return nil } + +// userAllowedBisection checks if the author of the +// comment event is allowed to spawn a bisection. +func userAllowedBisection(ctx context.Context, user string) (bool, error) { + fc, err := firestore.NewClient(ctx, flags.project) + if err != nil { + return false, err + } + doc := fc.Collection("auth").Doc("bisect-github-users") + sn, err := doc.Get(ctx) + if err != nil { + return false, err + } + var users map[string]bool + if err := sn.DataTo(&users); err != nil { + return false, err + } + + return users[user], nil +}
diff --git a/internal/github/webhook.go b/internal/github/webhook.go index 795005a..557e383 100644 --- a/internal/github/webhook.go +++ b/internal/github/webhook.go
@@ -184,6 +184,7 @@ type Comment struct { URL string `json:"url"` Body string `json:"body"` + User User `json:"user"` } // toWebhookEvent converts data into a WebhookEvent with a Payload of the