@@ -21,6 +21,7 @@ import ( |
| 21 | 21 | diffsource "github.com/tenseleyFlow/shithub/internal/repos/diff/source" |
| 22 | 22 | "github.com/tenseleyFlow/shithub/internal/repos/git" |
| 23 | 23 | "github.com/tenseleyFlow/shithub/internal/repos/identity" |
| 24 | + "github.com/tenseleyFlow/shithub/internal/repos/sigverify" |
| 24 | 25 | "github.com/tenseleyFlow/shithub/internal/web/middleware" |
| 25 | 26 | ) |
| 26 | 27 | |
@@ -113,6 +114,24 @@ func (h *Handlers) commitsList(w http.ResponseWriter, r *http.Request) { |
| 113 | 114 | rows = append(rows, newCommitRow(c, resolver.Resolve(r.Context(), c.AuthorEmail))) |
| 114 | 115 | } |
| 115 | 116 | |
| 117 | + // Batch-load signature verification cache for the page. Failure |
| 118 | + // is non-fatal — the rows default to UnsignedView and the page |
| 119 | + // renders without badges. |
| 120 | + if len(rows) > 0 { |
| 121 | + oids := make([]string, len(rows)) |
| 122 | + for i := range rows { |
| 123 | + oids[i] = rows[i].Commit.OID |
| 124 | + } |
| 125 | + verifications, vErr := sigverify.LoadViewsForOIDs(r.Context(), h.d.Pool, row.ID, oids) |
| 126 | + if vErr != nil { |
| 127 | + h.d.Logger.WarnContext(r.Context(), "commits: load verifications", "error", vErr, "repo_id", row.ID) |
| 128 | + } else { |
| 129 | + for i := range rows { |
| 130 | + rows[i].Verification = sigverify.LookupView(verifications, rows[i].Commit.OID) |
| 131 | + } |
| 132 | + } |
| 133 | + } |
| 134 | + |
| 116 | 135 | filterValues := commitFilterValues(pathFilter, authorFilter, sinceRaw, untilRaw) |
| 117 | 136 | olderHref := "" |
| 118 | 137 | if len(commits) == perPage { |
@@ -221,18 +240,30 @@ func (h *Handlers) commitView(w http.ResponseWriter, r *http.Request) { |
| 221 | 240 | } |
| 222 | 241 | } |
| 223 | 242 | |
| 243 | + // Load signature verification cache row for this commit. Failure |
| 244 | + // is non-fatal — falls back to UnsignedView so the page renders |
| 245 | + // without a badge. |
| 246 | + verification, vErr := sigverify.LoadView(r.Context(), h.d.Pool, row.ID, detail.OID) |
| 247 | + if vErr != nil { |
| 248 | + // pgx.ErrNoRows is normal (commit hasn't been verified yet); |
| 249 | + // LoadView already returns UnsignedView for that case. Other |
| 250 | + // errors get logged but the page still renders. |
| 251 | + h.d.Logger.WarnContext(r.Context(), "commit: load verification", "error", vErr, "repo_id", row.ID, "sha", detail.OID) |
| 252 | + } |
| 253 | + |
| 224 | 254 | h.d.Render.RenderPage(w, r, "repo/commit", map[string]any{ |
| 225 | | - "Title": detail.Subject + " · " + row.Name, |
| 226 | | - "CSRFToken": middleware.CSRFTokenForRequest(r), |
| 227 | | - "Owner": owner.Username, |
| 228 | | - "Repo": row, |
| 229 | | - "Detail": detail, |
| 230 | | - "Author": author, |
| 231 | | - "Committer": committer, |
| 232 | | - "BodyHTML": template.HTML(linkifyCommitBody(detail.Body)), //nolint:gosec // escaped inside |
| 233 | | - "DiffHTML": diffHTML, |
| 234 | | - "DiffMode": string(mode), |
| 235 | | - "HideWS": hideWS, |
| 255 | + "Title": detail.Subject + " · " + row.Name, |
| 256 | + "CSRFToken": middleware.CSRFTokenForRequest(r), |
| 257 | + "Owner": owner.Username, |
| 258 | + "Repo": row, |
| 259 | + "Detail": detail, |
| 260 | + "Author": author, |
| 261 | + "Committer": committer, |
| 262 | + "BodyHTML": template.HTML(linkifyCommitBody(detail.Body)), //nolint:gosec // escaped inside |
| 263 | + "DiffHTML": diffHTML, |
| 264 | + "DiffMode": string(mode), |
| 265 | + "HideWS": hideWS, |
| 266 | + "Verification": verification, |
| 236 | 267 | }) |
| 237 | 268 | } |
| 238 | 269 | |
@@ -306,18 +337,20 @@ func (h *Handlers) commitsAtom(w http.ResponseWriter, r *http.Request) { |
| 306 | 337 | // git data so templates can render avatars and profile links without |
| 307 | 338 | // re-running the resolver. |
| 308 | 339 | type commitRow struct { |
| 309 | | - Commit git.Commit |
| 310 | | - Author identity.Resolved |
| 311 | | - AuthorLabel string |
| 312 | | - AuthorHref string |
| 340 | + Commit git.Commit |
| 341 | + Author identity.Resolved |
| 342 | + AuthorLabel string |
| 343 | + AuthorHref string |
| 344 | + Verification sigverify.View |
| 313 | 345 | } |
| 314 | 346 | |
| 315 | 347 | func newCommitRow(c git.Commit, author identity.Resolved) commitRow { |
| 316 | 348 | return commitRow{ |
| 317 | | - Commit: c, |
| 318 | | - Author: author, |
| 319 | | - AuthorLabel: commitAuthorLabel(c, author), |
| 320 | | - AuthorHref: commitAuthorHref(author), |
| 349 | + Commit: c, |
| 350 | + Author: author, |
| 351 | + AuthorLabel: commitAuthorLabel(c, author), |
| 352 | + AuthorHref: commitAuthorHref(author), |
| 353 | + Verification: sigverify.UnsignedView(), |
| 321 | 354 | } |
| 322 | 355 | } |
| 323 | 356 | |