Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(166)

Side by Side Diff: go/src/infra/appengine/sheriff-o-matic/main.go

Issue 2080243005: appengine, crimson: Use updated router API (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Update infra luci-go deps Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Package som implements HTTP server that handles requests to default module. 5 // Package som implements HTTP server that handles requests to default module.
6 package som 6 package som
7 7
8 import ( 8 import (
9 "crypto/sha1" 9 "crypto/sha1"
10 "encoding/json" 10 "encoding/json"
11 "fmt" 11 "fmt"
12 "html/template" 12 "html/template"
13 "infra/monorail" 13 "infra/monorail"
14 "io/ioutil" 14 "io/ioutil"
15 "net/http" 15 "net/http"
16 "strings" 16 "strings"
17 17
18 "github.com/julienschmidt/httprouter"
19 "golang.org/x/net/context" 18 "golang.org/x/net/context"
20 "google.golang.org/appengine" 19 "google.golang.org/appengine"
21 20
22 "github.com/luci/gae/service/datastore" 21 "github.com/luci/gae/service/datastore"
23 "github.com/luci/gae/service/urlfetch" 22 "github.com/luci/gae/service/urlfetch"
24 "github.com/luci/luci-go/appengine/gaeauth/client" 23 "github.com/luci/luci-go/appengine/gaeauth/client"
25 "github.com/luci/luci-go/appengine/gaeauth/server" 24 "github.com/luci/luci-go/appengine/gaeauth/server"
26 "github.com/luci/luci-go/appengine/gaemiddleware" 25 "github.com/luci/luci-go/appengine/gaemiddleware"
27 "github.com/luci/luci-go/common/clock" 26 "github.com/luci/luci-go/common/clock"
28 "github.com/luci/luci-go/common/logging" 27 "github.com/luci/luci-go/common/logging"
29 "github.com/luci/luci-go/server/auth" 28 "github.com/luci/luci-go/server/auth"
30 "github.com/luci/luci-go/server/auth/identity" 29 "github.com/luci/luci-go/server/auth/identity"
31 "github.com/luci/luci-go/server/middleware" 30 "github.com/luci/luci-go/server/middleware"
31 "github.com/luci/luci-go/server/router"
32 "github.com/luci/luci-go/server/settings" 32 "github.com/luci/luci-go/server/settings"
33 ) 33 )
34 34
35 const authGroup = "sheriff-o-matic-access" 35 const authGroup = "sheriff-o-matic-access"
36 36
37 var ( 37 var (
38 mainPage = template.Must(template.ParseFiles("./index.html")) 38 mainPage = template.Must(template.ParseFiles("./index.html"))
39 accessDeniedPage = template.Must(template.ParseFiles("./access-denied.ht ml")) 39 accessDeniedPage = template.Must(template.ParseFiles("./access-denied.ht ml"))
40 monorailEndpoint = "https://monorail-prod.appspot.com/_ah/api/monorail/v 1/" 40 monorailEndpoint = "https://monorail-prod.appspot.com/_ah/api/monorail/v 1/"
41 ) 41 )
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 if alertStreams, ok := values["AlertStreams"]; ok && alertStreams != "" { 169 if alertStreams, ok := values["AlertStreams"]; ok && alertStreams != "" {
170 if err := writeAlertStreams(c, alertStreams); err != nil { 170 if err := writeAlertStreams(c, alertStreams); err != nil {
171 return err 171 return err
172 } 172 }
173 } 173 }
174 174
175 return nil 175 return nil
176 } 176 }
177 177
178 //// Handlers. 178 //// Handlers.
179 func indexPage(c context.Context, w http.ResponseWriter, r *http.Request, p http router.Params) { 179 func indexPage(ctx *router.Context) {
180 » c, w, r, p := ctx.Context, ctx.Writer, ctx.Request, ctx.Params
180 if p.ByName("path") == "" { 181 if p.ByName("path") == "" {
181 http.Redirect(w, r, "/chromium", http.StatusFound) 182 http.Redirect(w, r, "/chromium", http.StatusFound)
182 return 183 return
183 } 184 }
184 185
185 user := auth.CurrentIdentity(c) 186 user := auth.CurrentIdentity(c)
186 187
187 if user.Kind() == identity.Anonymous { 188 if user.Kind() == identity.Anonymous {
188 url, err := auth.LoginURL(c, "/") 189 url, err := auth.LoginURL(c, "/")
189 if err != nil { 190 if err != nil {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 "User": user.Email(), 226 "User": user.Email(),
226 "LogoutUrl": logoutURL, 227 "LogoutUrl": logoutURL,
227 } 228 }
228 229
229 err = mainPage.Execute(w, data) 230 err = mainPage.Execute(w, data)
230 if err != nil { 231 if err != nil {
231 logging.Errorf(c, "while rendering index: %s", err) 232 logging.Errorf(c, "while rendering index: %s", err)
232 } 233 }
233 } 234 }
234 235
235 func getTreesHandler(c context.Context, w http.ResponseWriter, r *http.Request, p httprouter.Params) { 236 func getTreesHandler(ctx *router.Context) {
237 » c, w := ctx.Context, ctx.Writer
238
236 if !requireGoogler(w, c) { 239 if !requireGoogler(w, c) {
237 return 240 return
238 } 241 }
239 242
240 q := datastore.NewQuery("Tree") 243 q := datastore.NewQuery("Tree")
241 results := []*Tree{} 244 results := []*Tree{}
242 err := datastore.Get(c).GetAll(q, &results) 245 err := datastore.Get(c).GetAll(q, &results)
243 if err != nil { 246 if err != nil {
244 errStatus(w, http.StatusInternalServerError, err.Error()) 247 errStatus(w, http.StatusInternalServerError, err.Error())
245 return 248 return
246 } 249 }
247 250
248 txt, err := json.Marshal(results) 251 txt, err := json.Marshal(results)
249 if err != nil { 252 if err != nil {
250 errStatus(w, http.StatusInternalServerError, err.Error()) 253 errStatus(w, http.StatusInternalServerError, err.Error())
251 return 254 return
252 } 255 }
253 256
254 w.Header().Set("Content-Type", "application/json") 257 w.Header().Set("Content-Type", "application/json")
255 w.Write(txt) 258 w.Write(txt)
256 } 259 }
257 260
258 func getAlertsHandler(c context.Context, w http.ResponseWriter, r *http.Request, p httprouter.Params) { 261 func getAlertsHandler(ctx *router.Context) {
262 » c, w, p := ctx.Context, ctx.Writer, ctx.Params
263
259 if !requireGoogler(w, c) { 264 if !requireGoogler(w, c) {
260 return 265 return
261 } 266 }
262 267
263 ds := datastore.Get(c) 268 ds := datastore.Get(c)
264 269
265 tree := p.ByName("tree") 270 tree := p.ByName("tree")
266 q := datastore.NewQuery("AlertsJSON") 271 q := datastore.NewQuery("AlertsJSON")
267 q = q.Ancestor(ds.MakeKey("Tree", tree)) 272 q = q.Ancestor(ds.MakeKey("Tree", tree))
268 q = q.Order("-Date") 273 q = q.Order("-Date")
(...skipping 10 matching lines...) Expand all
279 logging.Warningf(c, "No alerts found for tree %s", tree) 284 logging.Warningf(c, "No alerts found for tree %s", tree)
280 errStatus(w, http.StatusNotFound, fmt.Sprintf("Tree \"%s\" not f ound", tree)) 285 errStatus(w, http.StatusNotFound, fmt.Sprintf("Tree \"%s\" not f ound", tree))
281 return 286 return
282 } 287 }
283 288
284 alertsJSON := results[0] 289 alertsJSON := results[0]
285 w.Header().Set("Content-Type", "application/json") 290 w.Header().Set("Content-Type", "application/json")
286 w.Write(alertsJSON.Contents) 291 w.Write(alertsJSON.Contents)
287 } 292 }
288 293
289 func postAlertsHandler(c context.Context, w http.ResponseWriter, r *http.Request , p httprouter.Params) { 294 func postAlertsHandler(ctx *router.Context) {
295 » c, w, r, p := ctx.Context, ctx.Writer, ctx.Request, ctx.Params
296
290 if !requireGoogler(w, c) { 297 if !requireGoogler(w, c) {
291 return 298 return
292 } 299 }
293 300
294 tree := p.ByName("tree") 301 tree := p.ByName("tree")
295 ds := datastore.Get(c) 302 ds := datastore.Get(c)
296 303
297 alerts := AlertsJSON{ 304 alerts := AlertsJSON{
298 Tree: ds.MakeKey("Tree", tree), 305 Tree: ds.MakeKey("Tree", tree),
299 Date: clock.Now(c), 306 Date: clock.Now(c),
(...skipping 26 matching lines...) Expand all
326 } 333 }
327 334
328 alerts.Contents = data 335 alerts.Contents = data
329 err = datastore.Get(c).Put(&alerts) 336 err = datastore.Get(c).Put(&alerts)
330 if err != nil { 337 if err != nil {
331 errStatus(w, http.StatusInternalServerError, err.Error()) 338 errStatus(w, http.StatusInternalServerError, err.Error())
332 return 339 return
333 } 340 }
334 } 341 }
335 342
336 func getAnnotationsHandler(c context.Context, w http.ResponseWriter, r *http.Req uest, p httprouter.Params) { 343 func getAnnotationsHandler(ctx *router.Context) {
344 » c, w := ctx.Context, ctx.Writer
345
337 if !requireGoogler(w, c) { 346 if !requireGoogler(w, c) {
338 return 347 return
339 } 348 }
340 349
341 q := datastore.NewQuery("Annotation") 350 q := datastore.NewQuery("Annotation")
342 results := []*Annotation{} 351 results := []*Annotation{}
343 datastore.Get(c).GetAll(q, &results) 352 datastore.Get(c).GetAll(q, &results)
344 353
345 data, err := json.Marshal(results) 354 data, err := json.Marshal(results)
346 if err != nil { 355 if err != nil {
347 errStatus(w, http.StatusInternalServerError, err.Error()) 356 errStatus(w, http.StatusInternalServerError, err.Error())
348 return 357 return
349 } 358 }
350 359
351 w.Header().Set("Content-Type", "application/json") 360 w.Header().Set("Content-Type", "application/json")
352 w.Write(data) 361 w.Write(data)
353 } 362 }
354 363
355 func postAnnotationsHandler(c context.Context, w http.ResponseWriter, r *http.Re quest, p httprouter.Params) { 364 func postAnnotationsHandler(ctx *router.Context) {
365 » c, w, r, p := ctx.Context, ctx.Writer, ctx.Request, ctx.Params
366
356 if !requireGoogler(w, c) { 367 if !requireGoogler(w, c) {
357 return 368 return
358 } 369 }
359 370
360 annKey := p.ByName("annKey") 371 annKey := p.ByName("annKey")
361 action := p.ByName("action") 372 action := p.ByName("action")
362 ds := datastore.Get(c) 373 ds := datastore.Get(c)
363 374
364 if !(action == "add" || action == "remove") { 375 if !(action == "add" || action == "remove") {
365 errStatus(w, http.StatusNotFound, "Invalid action") 376 errStatus(w, http.StatusNotFound, "Invalid action")
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 data, err := json.Marshal(annotation) 415 data, err := json.Marshal(annotation)
405 if err != nil { 416 if err != nil {
406 errStatus(w, http.StatusInternalServerError, err.Error()) 417 errStatus(w, http.StatusInternalServerError, err.Error())
407 return 418 return
408 } 419 }
409 420
410 w.Header().Set("Content-Type", "application/json") 421 w.Header().Set("Content-Type", "application/json")
411 w.Write(data) 422 w.Write(data)
412 } 423 }
413 424
414 func getBugQueueHandler(c context.Context, w http.ResponseWriter, r *http.Reques t, p httprouter.Params) { 425 func getBugQueueHandler(ctx *router.Context) {
426 » c, w, p := ctx.Context, ctx.Writer, ctx.Params
427
415 c = client.UseServiceAccountTransport(c, nil, nil) 428 c = client.UseServiceAccountTransport(c, nil, nil)
416 mr := monorail.NewEndpointsClient(&http.Client{Transport: urlfetch.Get(c )}, monorailEndpoint) 429 mr := monorail.NewEndpointsClient(&http.Client{Transport: urlfetch.Get(c )}, monorailEndpoint)
417 tree := p.ByName("tree") 430 tree := p.ByName("tree")
418 431
419 // TODO(martiniss): make this look up request info based on Tree datasto re 432 // TODO(martiniss): make this look up request info based on Tree datasto re
420 // object 433 // object
421 req := &monorail.IssuesListRequest{ 434 req := &monorail.IssuesListRequest{
422 ProjectId: tree, 435 ProjectId: tree,
423 Can: monorail.IssuesListRequest_OPEN, 436 Can: monorail.IssuesListRequest_OPEN,
424 Q: fmt.Sprintf("label:Sheriff-%s", tree), 437 Q: fmt.Sprintf("label:Sheriff-%s", tree),
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 471
459 m := map[string]string{} 472 m := map[string]string{}
460 err = json.Unmarshal(body, &m) 473 err = json.Unmarshal(body, &m)
461 if err != nil { 474 if err != nil {
462 return nil, err 475 return nil, err
463 } 476 }
464 477
465 return m, nil 478 return m, nil
466 } 479 }
467 480
468 func getRevRangeHandler(c context.Context, w http.ResponseWriter, r *http.Reques t, p httprouter.Params) { 481 func getRevRangeHandler(ctx *router.Context) {
482 » c, w, r, p := ctx.Context, ctx.Writer, ctx.Request, ctx.Params
483
469 start := p.ByName("start") 484 start := p.ByName("start")
470 end := p.ByName("end") 485 end := p.ByName("end")
471 if start == "" || end == "" { 486 if start == "" || end == "" {
472 errStatus(w, http.StatusBadRequest, "Start and end parameters mu st be set.") 487 errStatus(w, http.StatusBadRequest, "Start and end parameters mu st be set.")
473 return 488 return
474 } 489 }
475 490
476 startRev, err := getCrRevJSON(c, start) 491 startRev, err := getCrRevJSON(c, start)
477 if err != nil { 492 if err != nil {
478 errStatus(w, http.StatusInternalServerError, err.Error()) 493 errStatus(w, http.StatusInternalServerError, err.Error())
479 return 494 return
480 } 495 }
481 496
482 endRev, err := getCrRevJSON(c, end) 497 endRev, err := getCrRevJSON(c, end)
483 if err != nil { 498 if err != nil {
484 errStatus(w, http.StatusInternalServerError, err.Error()) 499 errStatus(w, http.StatusInternalServerError, err.Error())
485 return 500 return
486 } 501 }
487 502
488 // TODO(seanmccullough): some sanity checking of the rev json (same repo etc) 503 // TODO(seanmccullough): some sanity checking of the rev json (same repo etc)
489 504
490 gitilesURL := fmt.Sprintf("https://chromium.googlesource.com/chromium/sr c/+log/%s^..%s?format=JSON", 505 gitilesURL := fmt.Sprintf("https://chromium.googlesource.com/chromium/sr c/+log/%s^..%s?format=JSON",
491 startRev["git_sha"], endRev["git_sha"]) 506 startRev["git_sha"], endRev["git_sha"])
492 507
493 http.Redirect(w, r, gitilesURL, 301) 508 http.Redirect(w, r, gitilesURL, 301)
494 } 509 }
495 510
496 // base is the root of the middleware chain. 511 // base is the root of the middleware chain.
497 func base(h middleware.Handler) httprouter.Handle { 512 func base() router.MiddlewareChain {
498 methods := auth.Authenticator{ 513 methods := auth.Authenticator{
499 &server.OAuth2Method{Scopes: []string{server.EmailScope}}, 514 &server.OAuth2Method{Scopes: []string{server.EmailScope}},
500 server.CookieAuth, 515 server.CookieAuth,
501 &server.InboundAppIDAuthMethod{}, 516 &server.InboundAppIDAuthMethod{},
502 } 517 }
503 » h = auth.Use(h, methods) 518 » if appengine.IsDevAppServer() {
Vadim Sh. 2016/06/22 19:50:17 WithPanicCatcher is part of BaseProd now, so this
nishanths 2016/06/22 20:03:48 Done.
504 » if !appengine.IsDevAppServer() { 519 » » return append(gaemiddleware.BaseProd(), auth.Use(methods))
505 » » h = middleware.WithPanicCatcher(h)
506 } 520 }
507 » return gaemiddleware.BaseProd(h) 521 » return append(
522 » » gaemiddleware.BaseProd(),
523 » » middleware.WithPanicCatcher,
Vadim Sh. 2016/06/22 19:50:17 here too
nishanths 2016/06/22 20:03:48 Done.
524 » » auth.Use(methods),
525 » )
508 } 526 }
509 527
510 //// Routes. 528 //// Routes.
511 func init() { 529 func init() {
512 settings.RegisterUIPage(settingsKey, settingsUIPage{}) 530 settings.RegisterUIPage(settingsKey, settingsUIPage{})
513 531
514 » router := httprouter.New() 532 » r := router.New()
515 » gaemiddleware.InstallHandlers(router, base) 533 » basemw := base()
516 » router.GET("/api/v1/trees/", base(auth.Authenticate(getTreesHandler))) 534 » authmw := append(basemw, auth.Authenticate)
517 » router.GET("/api/v1/alerts/:tree", base(auth.Authenticate(getAlertsHandl er)))
518 » router.POST("/api/v1/alerts/:tree", base(auth.Authenticate(postAlertsHan dler)))
519 » router.GET("/api/v1/annotations/", base(auth.Authenticate(getAnnotations Handler)))
520 » router.POST("/api/v1/annotations/:annKey/:action", base(auth.Authenticat e(postAnnotationsHandler)))
521 » router.GET("/api/v1/bugqueue/:tree", base(auth.Authenticate(getBugQueueH andler)))
522 » router.GET("/api/v1/revrange/:start/:end", base(getRevRangeHandler))
523 535
524 » rootRouter := httprouter.New() 536 » gaemiddleware.InstallHandlers(r, basemw)
525 » rootRouter.GET("/*path", base(auth.Authenticate(indexPage))) 537 » r.GET("/api/v1/trees/", authmw, getTreesHandler)
538 » r.GET("/api/v1/alerts/:tree", authmw, getAlertsHandler)
539 » r.POST("/api/v1/alerts/:tree", authmw, postAlertsHandler)
540 » r.GET("/api/v1/annotations/", authmw, getAnnotationsHandler)
541 » r.POST("/api/v1/annotations/:annKey/:action", authmw, postAnnotationsHan dler)
542 » r.GET("/api/v1/bugqueue/:tree", authmw, getBugQueueHandler)
543 » r.GET("/api/v1/revrange/:start/:end", basemw, getRevRangeHandler)
526 544
527 » http.DefaultServeMux.Handle("/api/", router) 545 » rootRouter := router.New()
528 » http.DefaultServeMux.Handle("/admin/", router) 546 » rootRouter.GET("/*path", authmw, indexPage)
529 » http.DefaultServeMux.Handle("/auth/", router) 547
530 » http.DefaultServeMux.Handle("/_ah/", router) 548 » http.DefaultServeMux.Handle("/api/", r)
549 » http.DefaultServeMux.Handle("/admin/", r)
550 » http.DefaultServeMux.Handle("/auth/", r)
551 » http.DefaultServeMux.Handle("/_ah/", r)
531 http.DefaultServeMux.Handle("/", rootRouter) 552 http.DefaultServeMux.Handle("/", rootRouter)
532 } 553 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698