| OLD | NEW |
| 1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
| 4 | 4 |
| 5 package common | 5 package common |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "net/http" | 8 "net/http" |
| 9 "strings" | 9 "strings" |
| 10 | 10 |
| 11 "cloud.google.com/go/compute/metadata" |
| 12 "cloud.google.com/go/datastore" |
| 13 |
| 11 "golang.org/x/net/context" | 14 "golang.org/x/net/context" |
| 15 "golang.org/x/oauth2" |
| 16 "golang.org/x/oauth2/google" |
| 12 | 17 |
| 18 "github.com/luci/gae/impl/cloud" |
| 19 "github.com/luci/gae/impl/memory" |
| 13 "github.com/luci/gae/service/info" | 20 "github.com/luci/gae/service/info" |
| 14 "github.com/luci/luci-go/appengine/gaeauth/server" | 21 "github.com/luci/luci-go/appengine/gaeauth/server" |
| 22 "github.com/luci/luci-go/appengine/gaeauth/server/gaesigner" |
| 15 "github.com/luci/luci-go/appengine/gaemiddleware" | 23 "github.com/luci/luci-go/appengine/gaemiddleware" |
| 24 "github.com/luci/luci-go/appengine/gaesecrets" |
| 16 "github.com/luci/luci-go/common/clock" | 25 "github.com/luci/luci-go/common/clock" |
| 26 "github.com/luci/luci-go/common/logging/gologger" |
| 17 "github.com/luci/luci-go/server/analytics" | 27 "github.com/luci/luci-go/server/analytics" |
| 18 "github.com/luci/luci-go/server/auth" | 28 "github.com/luci/luci-go/server/auth" |
| 29 "github.com/luci/luci-go/server/auth/authdb" |
| 19 "github.com/luci/luci-go/server/auth/identity" | 30 "github.com/luci/luci-go/server/auth/identity" |
| 20 "github.com/luci/luci-go/server/router" | 31 "github.com/luci/luci-go/server/router" |
| 21 "github.com/luci/luci-go/server/templates" | 32 "github.com/luci/luci-go/server/templates" |
| 22 ) | 33 ) |
| 23 | 34 |
| 24 // GetTemplateBundles is used to render HTML templates. It provides base args | 35 // GetTemplateBundles is used to render HTML templates. It provides base args |
| 25 // passed to all templates. | 36 // passed to all templates. |
| 26 func GetTemplateBundle() *templates.Bundle { | 37 func GetTemplateBundle() *templates.Bundle { |
| 27 return &templates.Bundle{ | 38 return &templates.Bundle{ |
| 28 Loader: templates.FileSystemLoader("templates"), | 39 Loader: templates.FileSystemLoader("templates"), |
| (...skipping 18 matching lines...) Expand all Loading... |
| 47 "LogoutURL": logoutURL, | 58 "LogoutURL": logoutURL, |
| 48 "CurrentTime": clock.Now(c), | 59 "CurrentTime": clock.Now(c), |
| 49 "Analytics": analytics.Snippet(c), | 60 "Analytics": analytics.Snippet(c), |
| 50 "RequestID": info.RequestID(c), | 61 "RequestID": info.RequestID(c), |
| 51 }, nil | 62 }, nil |
| 52 }, | 63 }, |
| 53 FuncMap: funcMap, | 64 FuncMap: funcMap, |
| 54 } | 65 } |
| 55 } | 66 } |
| 56 | 67 |
| 68 // authMethods returns the set of authentication methods used for Milo. |
| 69 func authMethods() auth.Authenticator { |
| 70 return auth.Authenticator{ |
| 71 &server.OAuth2Method{Scopes: []string{server.EmailScope}}, |
| 72 server.CookieAuth, |
| 73 &server.InboundAppIDAuthMethod{}, |
| 74 } |
| 75 } |
| 76 |
| 77 // Flex returns the basic middleware for use on appengine flex. Flex does not |
| 78 // allow the use of appengine APIs. |
| 79 func FlexBase() router.MiddlewareChain { |
| 80 // Get the name of this project from the metadata server, since we're on
GCE. |
| 81 project, err := metadata.Get("project/project-id") |
| 82 if err != nil { |
| 83 panic(err) |
| 84 } |
| 85 // Use the standard Go logger. |
| 86 // TODO(hinoka): Use the cloud logger, somehow. |
| 87 logger := func(c *router.Context, next router.Handler) { |
| 88 c.Context = gologger.StdConfig.Use(c.Context) |
| 89 next(c) |
| 90 } |
| 91 // The base set of services uses memory implementations. |
| 92 memory := func(c *router.Context, next router.Handler) { |
| 93 c.Context = memory.UseWithAppID(c.Context, project) |
| 94 next(c) |
| 95 } |
| 96 // Use the cloud datastore client. |
| 97 ds := func(c *router.Context, next router.Handler) { |
| 98 client, err := datastore.NewClient(c.Context, project) |
| 99 if err != nil { |
| 100 panic(err) |
| 101 } |
| 102 c.Context = cloud.UseDatastore(c.Context, client) |
| 103 next(c) |
| 104 } |
| 105 // Secret store, used for decryping OID tokens, which is needed for cook
ieauth. |
| 106 secrets := func(c *router.Context, next router.Handler) { |
| 107 c.Context = gaesecrets.Use(c.Context, nil) |
| 108 next(c) |
| 109 } |
| 110 // Swap out the default auth configs with one that uses a in-memory cach
e, since |
| 111 // we can't use memcache. |
| 112 authConfig := func(c *router.Context, next router.Handler) { |
| 113 mustToken := func(c context.Context, scopes []string) (*oauth2.T
oken, error) { |
| 114 // Ignore context and scope since its not needed. |
| 115 return google.ComputeTokenSource("").Token() |
| 116 } |
| 117 config := auth.Config{ |
| 118 DBProvider: authdb.NewDBCache(server.GetAuthDB)
, |
| 119 Signer: gaesigner.Signer{}, |
| 120 AccessTokenProvider: mustToken, |
| 121 AnonymousTransport: func(c context.Context) http.RoundTr
ipper { |
| 122 return http.DefaultTransport |
| 123 }, |
| 124 Cache: auth.MemoryCache(10), |
| 125 IsDevMode: false, |
| 126 } |
| 127 c.Context = auth.SetConfig(c.Context, config) |
| 128 next(c) |
| 129 } |
| 130 // Now chain it all together! |
| 131 return router.NewMiddlewareChain( |
| 132 logger, memory, ds, secrets, auth.Use(authMethods()), authConfig
, auth.Authenticate) |
| 133 } |
| 134 |
| 57 // Base returns the basic LUCI appengine middlewares. | 135 // Base returns the basic LUCI appengine middlewares. |
| 58 func Base() router.MiddlewareChain { | 136 func Base() router.MiddlewareChain { |
| 59 » methods := auth.Authenticator{ | 137 » m := gaemiddleware.BaseProd().Extend(auth.Use(authMethods()), auth.Authe
nticate) |
| 60 » » &server.OAuth2Method{Scopes: []string{server.EmailScope}}, | |
| 61 » » server.CookieAuth, | |
| 62 » » &server.InboundAppIDAuthMethod{}, | |
| 63 » } | |
| 64 » m := gaemiddleware.BaseProd().Extend(auth.Use(methods), auth.Authenticat
e) | |
| 65 m = m.Extend(withRequestMiddleware) | 138 m = m.Extend(withRequestMiddleware) |
| 66 m = m.Extend(templates.WithTemplates(GetTemplateBundle())) | 139 m = m.Extend(templates.WithTemplates(GetTemplateBundle())) |
| 67 return m | 140 return m |
| 68 } | 141 } |
| 69 | 142 |
| 70 // The context key, so that we can embed the http.Request object into | 143 // The context key, so that we can embed the http.Request object into |
| 71 // the context. | 144 // the context. |
| 72 var requestKey = "http.request" | 145 var requestKey = "http.request" |
| 73 | 146 |
| 74 // WithRequest returns a context with the http.Request object | 147 // WithRequest returns a context with the http.Request object |
| 75 // in it. | 148 // in it. |
| 76 func WithRequest(c context.Context, r *http.Request) context.Context { | 149 func WithRequest(c context.Context, r *http.Request) context.Context { |
| 77 return context.WithValue(c, &requestKey, r) | 150 return context.WithValue(c, &requestKey, r) |
| 78 } | 151 } |
| 79 | 152 |
| 80 // withRequestMiddleware is a middleware that installs a request into the contex
t. | 153 // withRequestMiddleware is a middleware that installs a request into the contex
t. |
| 81 // This is used for various things in the default template. | 154 // This is used for various things in the default template. |
| 82 func withRequestMiddleware(c *router.Context, next router.Handler) { | 155 func withRequestMiddleware(c *router.Context, next router.Handler) { |
| 83 c.Context = WithRequest(c.Context, c.Request) | 156 c.Context = WithRequest(c.Context, c.Request) |
| 84 next(c) | 157 next(c) |
| 85 } | 158 } |
| 86 | 159 |
| 87 func getRequest(c context.Context) *http.Request { | 160 func getRequest(c context.Context) *http.Request { |
| 88 if req, ok := c.Value(&requestKey).(*http.Request); ok { | 161 if req, ok := c.Value(&requestKey).(*http.Request); ok { |
| 89 return req | 162 return req |
| 90 } | 163 } |
| 91 panic("No http.request found in context") | 164 panic("No http.request found in context") |
| 92 } | 165 } |
| OLD | NEW |