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

Side by Side Diff: milo/frontend/middleware.go

Issue 2977863002: [milo] Refactor all html knowledge out of backends. (Closed)
Patch Set: now with case insensitivity Created 3 years, 5 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
« no previous file with comments | « milo/frontend/main_test.go ('k') | milo/frontend/middleware_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The LUCI Authors. 1 // Copyright 2017 The LUCI Authors. All rights reserved.
2 // 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // that can be found in the LICENSE file.
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 4
15 package common 5 package frontend
16 6
17 import ( 7 import (
18 "bytes" 8 "bytes"
19 "fmt" 9 "fmt"
20 "html/template" 10 "html/template"
21 "net/http" 11 "net/http"
12 "strconv"
22 "strings" 13 "strings"
23 "time" 14 "time"
24 15
16 "golang.org/x/net/context"
17
18 "github.com/luci/gae/service/info"
19
20 "github.com/luci/luci-go/appengine/gaeauth/server"
21 "github.com/luci/luci-go/appengine/gaemiddleware"
22 "github.com/luci/luci-go/common/clock"
23 "github.com/luci/luci-go/server/analytics"
24 "github.com/luci/luci-go/server/auth"
25 "github.com/luci/luci-go/server/auth/identity"
26 "github.com/luci/luci-go/server/router"
27 "github.com/luci/luci-go/server/templates"
28
25 "github.com/luci/luci-go/milo/api/resp" 29 "github.com/luci/luci-go/milo/api/resp"
26 ) 30 )
27 31
28 // A collection of useful templating functions 32 // A collection of useful templating functions
29 33
30 // funcMap is what gets fed into the template bundle. 34 // funcMap is what gets fed into the template bundle.
31 var funcMap = template.FuncMap{ 35 var funcMap = template.FuncMap{
32 "humanDuration": humanDuration, 36 "humanDuration": humanDuration,
33 "parseRFC3339": parseRFC3339, 37 "parseRFC3339": parseRFC3339,
34 "linkify": linkify, 38 "linkify": linkify,
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 } 217 }
214 218
215 // shortHash abbriviates a git hash into 6 characters. 219 // shortHash abbriviates a git hash into 6 characters.
216 func shortHash(s string) string { 220 func shortHash(s string) string {
217 if len(s) > 6 { 221 if len(s) > 6 {
218 return s[0:6] 222 return s[0:6]
219 } 223 }
220 return s 224 return s
221 } 225 }
222 226
227 // GetLimit extracts the "limit", "numbuilds", or "num_builds" http param from
228 // the request, or returns "-1" implying no limit was specified.
229 func GetLimit(r *http.Request) (int, error) {
230 sLimit := r.FormValue("limit")
231 if sLimit == "" {
232 sLimit = r.FormValue("numbuilds")
233 if sLimit == "" {
234 sLimit = r.FormValue("num_builds")
235 if sLimit == "" {
236 return -1, nil
237 }
238 }
239 }
240 limit, err := strconv.Atoi(sLimit)
241 if err != nil {
242 return -1, fmt.Errorf("limit parameter value %q is not a number: %s", sLimit, err)
243 }
244 if limit < 0 {
245 return -1, fmt.Errorf("limit parameter value %q is less than 0", sLimit)
246 }
247 return limit, nil
248 }
249
223 // pagedURL returns a self URL with the given cursor and limit paging options. 250 // pagedURL returns a self URL with the given cursor and limit paging options.
224 // if limit is set to 0, then inherit whatever limit is set in request. If 251 // if limit is set to 0, then inherit whatever limit is set in request. If
225 // both are unspecified, then limit is omitted. 252 // both are unspecified, then limit is omitted.
226 func pagedURL(r *http.Request, limit int, cursor string) string { 253 func pagedURL(r *http.Request, limit int, cursor string) string {
227 if limit == 0 { 254 if limit == 0 {
228 var err error 255 var err error
229 limit, err = GetLimit(r) 256 limit, err = GetLimit(r)
230 if err != nil { 257 if err != nil {
231 // This should not happen because the handler should've already validated the 258 // This should not happen because the handler should've already validated the
232 // limit earlier in the process. 259 // limit earlier in the process.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 302
276 linkifyTemplate = template.Must( 303 linkifyTemplate = template.Must(
277 template.New("linkify"). 304 template.New("linkify").
278 Parse( 305 Parse(
279 `<a href="{{.URL}}">` + 306 `<a href="{{.URL}}">` +
280 `{{if .Img}}<img src="{{.Img}}"{{if .Alt }} alt="{{.Alt}}"{{end}}>` + 307 `{{if .Img}}<img src="{{.Img}}"{{if .Alt }} alt="{{.Alt}}"{{end}}>` +
281 `{{else if .Alias}}[{{.Label}}]` + 308 `{{else if .Alias}}[{{.Label}}]` +
282 `{{else}}{{.Label}}{{end}}` + 309 `{{else}}{{.Label}}{{end}}` +
283 `</a>`)) 310 `</a>`))
284 } 311 }
312
313 var authconfig *auth.Config
314
315 // getTemplateBundles is used to render HTML templates. It provides base args
316 // passed to all templates. It takes a path to the template folder, relative
317 // to the path of the binary during runtime.
318 func getTemplateBundle(templatePath string) *templates.Bundle {
319 return &templates.Bundle{
320 Loader: templates.FileSystemLoader(templatePath),
321 DebugMode: info.IsDevAppServer,
322 DefaultTemplate: "base",
323 DefaultArgs: func(c context.Context) (templates.Args, error) {
324 r := getRequest(c)
325 path := r.URL.Path
326 loginURL, err := auth.LoginURL(c, path)
327 if err != nil {
328 return nil, err
329 }
330 logoutURL, err := auth.LogoutURL(c, path)
331 if err != nil {
332 return nil, err
333 }
334 return templates.Args{
335 "AppVersion": strings.Split(info.VersionID(c), ".")[0],
336 "IsAnonymous": auth.CurrentIdentity(c) == identi ty.AnonymousIdentity,
337 "User": auth.CurrentUser(c),
338 "LoginURL": loginURL,
339 "LogoutURL": logoutURL,
340 "CurrentTime": clock.Now(c),
341 "Analytics": analytics.Snippet(c),
342 "RequestID": info.RequestID(c),
343 "Request": r,
344 }, nil
345 },
346 FuncMap: funcMap,
347 }
348 }
349
350 // base returns the basic LUCI appengine middlewares.
351 func base(templatePath string) router.MiddlewareChain {
352 return gaemiddleware.BaseProd().Extend(
353 auth.Authenticate(server.CookieAuth),
354 withRequestMiddleware,
355 templates.WithTemplates(getTemplateBundle(templatePath)),
356 )
357 }
358
359 // The context key, so that we can embed the http.Request object into
360 // the context.
361 var requestKey = "http.request"
362
363 // withRequest returns a context with the http.Request object
364 // in it.
365 func withRequest(c context.Context, r *http.Request) context.Context {
366 return context.WithValue(c, &requestKey, r)
367 }
368
369 // withRequestMiddleware is a middleware that installs a request into the contex t.
370 // This is used for various things in the default template.
371 func withRequestMiddleware(c *router.Context, next router.Handler) {
372 c.Context = withRequest(c.Context, c.Request)
373 next(c)
374 }
375
376 func getRequest(c context.Context) *http.Request {
377 if req, ok := c.Value(&requestKey).(*http.Request); ok {
378 return req
379 }
380 panic("No http.request found in context")
381 }
OLDNEW
« no previous file with comments | « milo/frontend/main_test.go ('k') | milo/frontend/middleware_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698