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

Side by Side Diff: go/src/infra/crimson/server/frontend/handler.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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 frontend implements HTTP server that handles requests to default 5 // Package frontend implements HTTP server that handles requests to default
6 // module. 6 // module.
7 package frontend 7 package frontend
8 8
9 import ( 9 import (
10 "database/sql" 10 "database/sql"
11 "net/http" 11 "net/http"
12 "strings" 12 "strings"
13 13
14 "github.com/golang/protobuf/proto" 14 "github.com/golang/protobuf/proto"
15 15
16 "github.com/julienschmidt/httprouter"
17 "github.com/luci/gae/service/info" 16 "github.com/luci/gae/service/info"
18 "github.com/luci/luci-go/appengine/gaeauth/server" 17 "github.com/luci/luci-go/appengine/gaeauth/server"
19 "github.com/luci/luci-go/appengine/gaemiddleware" 18 "github.com/luci/luci-go/appengine/gaemiddleware"
20 "github.com/luci/luci-go/common/grpcutil" 19 "github.com/luci/luci-go/common/grpcutil"
21 "github.com/luci/luci-go/common/logging" 20 "github.com/luci/luci-go/common/logging"
22 "github.com/luci/luci-go/server/auth" 21 "github.com/luci/luci-go/server/auth"
23 "github.com/luci/luci-go/server/auth/identity" 22 "github.com/luci/luci-go/server/auth/identity"
24 "github.com/luci/luci-go/server/discovery" 23 "github.com/luci/luci-go/server/discovery"
25 "github.com/luci/luci-go/server/middleware"
26 "github.com/luci/luci-go/server/prpc" 24 "github.com/luci/luci-go/server/prpc"
25 "github.com/luci/luci-go/server/router"
27 "github.com/luci/luci-go/server/templates" 26 "github.com/luci/luci-go/server/templates"
28 "golang.org/x/net/context" 27 "golang.org/x/net/context"
29 "google.golang.org/appengine" 28 "google.golang.org/appengine"
30 "google.golang.org/grpc/codes" 29 "google.golang.org/grpc/codes"
31 30
32 "infra/crimson/proto" // 'crimson' package 31 "infra/crimson/proto" // 'crimson' package
33 "infra/crimson/server/crimsondb" 32 "infra/crimson/server/crimsondb"
34 ) 33 )
35 34
36 // templateBundle is used to render HTML templates. It provides a base args 35 // templateBundle is used to render HTML templates. It provides a base args
(...skipping 25 matching lines...) Expand all
62 "IsAdmin": isAdmin, 61 "IsAdmin": isAdmin,
63 "User": auth.CurrentUser(c), 62 "User": auth.CurrentUser(c),
64 "LoginURL": loginURL, 63 "LoginURL": loginURL,
65 "LogoutURL": logoutURL, 64 "LogoutURL": logoutURL,
66 }, nil 65 }, nil
67 }, 66 },
68 } 67 }
69 ) 68 )
70 69
71 // Auth middleware. Hard fails when user is not authorized. 70 // Auth middleware. Hard fails when user is not authorized.
72 func requireAuthWeb(h middleware.Handler) middleware.Handler { 71 func requireAuthWeb(c *router.Context, next router.Handler) {
73 » return func( 72 » if auth.CurrentIdentity(c.Context) == identity.AnonymousIdentity {
74 » » c context.Context, 73 » » loginURL, err := auth.LoginURL(c.Context, "/")
75 » » rw http.ResponseWriter, 74 » » if err != nil {
76 » » r *http.Request, 75 » » » logging.Errorf(c.Context, "Failed to get login URL")
Vadim Sh. 2016/06/22 19:50:17 (I know it was like that before, but) return HTTP
nishanths 2016/06/22 20:03:48 Done.
77 » » p httprouter.Params) { 76 » » }
77 » » logging.Infof(c.Context, "Redirecting to %s", loginURL)
78 » » http.Redirect(c.Writer, c.Request, loginURL, 302)
79 » » return
80 » }
78 81
79 » » if auth.CurrentIdentity(c) == identity.AnonymousIdentity { 82 » isGoogler, err := auth.IsMember(c.Context, rwGroup)
80 » » » loginURL, err := auth.LoginURL(c, "/") 83 » if err != nil {
81 » » » if err != nil { 84 » » c.Writer.WriteHeader(http.StatusInternalServerError)
82 » » » » logging.Errorf(c, "Failed to get login URL") 85 » » logging.Errorf(c.Context, "Failed to get group membership.")
83 » » » } 86 » » return
84 » » » logging.Infof(c, "Redirecting to %s", loginURL) 87 » }
85 » » » http.Redirect(rw, r, loginURL, 302) 88 » if isGoogler {
86 » » » return 89 » » next(c)
87 » » } 90 » » return
91 » }
88 92
89 » » isGoogler, err := auth.IsMember(c, rwGroup) 93 » templates.MustRender(c.Context, c.Writer, "pages/access_denied.html", ni l)
90 » » if err != nil {
91 » » » rw.WriteHeader(http.StatusInternalServerError)
92 » » » logging.Errorf(c, "Failed to get group membership.")
93 » » » return
94 » » }
95 » » if isGoogler {
96 » » » h(c, rw, r, p)
97 » » » return
98 » » }
99
100 » » templates.MustRender(c, rw, "pages/access_denied.html", nil)
101 » }
102 } 94 }
103 95
104 func addDbToContext(h middleware.Handler) middleware.Handler { 96 func addDbToContext(c *router.Context, next router.Handler) {
105 » return func( 97 » c.Context = context.WithValue(c.Context, "dbHandle", dbHandle)
106 » » c context.Context, 98 » next(c)
107 » » rw http.ResponseWriter,
108 » » r *http.Request,
109 » » p httprouter.Params) {
110 » » c = context.WithValue(c, "dbHandle", dbHandle)
111 » » h(c, rw, r, p)
112 » }
113 } 99 }
114 100
115 // checkAuthorizationPrpc is a prelude function in the svcdec sense. 101 // checkAuthorizationPrpc is a prelude function in the svcdec sense.
116 // It hard fails when the user is not authorized. 102 // It hard fails when the user is not authorized.
117 func checkAuthorizationPrpc( 103 func checkAuthorizationPrpc(
118 c context.Context, methodName string, req proto.Message) (context.Contex t, error) { 104 c context.Context, methodName string, req proto.Message) (context.Contex t, error) {
119 105
120 identity := auth.CurrentIdentity(c) 106 identity := auth.CurrentIdentity(c)
121 logging.Infof(c, "%s", identity) 107 logging.Infof(c, "%s", identity)
122 hasAccess, err := auth.IsMember(c, rwGroup) 108 hasAccess, err := auth.IsMember(c, rwGroup)
123 if err != nil { 109 if err != nil {
124 return nil, grpcutil.Errf(codes.Internal, "%s", err) 110 return nil, grpcutil.Errf(codes.Internal, "%s", err)
125 } 111 }
126 if hasAccess { 112 if hasAccess {
127 return c, nil 113 return c, nil
128 } 114 }
129 return nil, grpcutil.Errf(codes.PermissionDenied, 115 return nil, grpcutil.Errf(codes.PermissionDenied,
130 "%s is not allowed to call APIs", auth.CurrentIdentity(c)) 116 "%s is not allowed to call APIs", auth.CurrentIdentity(c))
131 } 117 }
132 118
133 func base(h middleware.Handler) httprouter.Handle { 119 func base() router.MiddlewareChain {
134 methods := auth.Authenticator{ 120 methods := auth.Authenticator{
135 server.CookieAuth, 121 server.CookieAuth,
136 } 122 }
137 » h = auth.Authenticate(h) 123 » return append(
138 » h = auth.Use(h, methods) 124 » » gaemiddleware.BaseProd(),
139 » h = templates.WithTemplates(h, templateBundle) 125 » » templates.WithTemplates(templateBundle),
140 » return gaemiddleware.BaseProd(h) 126 » » auth.Use(methods),
127 » » auth.Authenticate,
128 » )
141 } 129 }
142 130
143 // webBase sets up authentication/authorization for http requests. 131 // webBase sets up authentication/authorization for http requests.
144 func webBase(h middleware.Handler) httprouter.Handle { 132 func webBase() router.MiddlewareChain {
145 » return base(requireAuthWeb(h)) 133 » return append(base(), requireAuthWeb)
146 } 134 }
147 135
148 // prpcBase is the middleware for pRPC API handlers. 136 // prpcBase returns the middleware for pRPC API handlers.
149 func prpcBase(h middleware.Handler) httprouter.Handle { 137 func prpcBase() router.MiddlewareChain {
150 // OAuth 2.0 with email scope is registered as a default authenticator 138 // OAuth 2.0 with email scope is registered as a default authenticator
151 // by importing "github.com/luci/luci-go/appengine/gaeauth/server". 139 // by importing "github.com/luci/luci-go/appengine/gaeauth/server".
152 // No need to setup an authenticator here. 140 // No need to setup an authenticator here.
153 // 141 //
154 // Authorization is checked in checkAuthorizationPrpc using a 142 // Authorization is checked in checkAuthorizationPrpc using a
155 // service decorator. 143 // service decorator.
156 » return gaemiddleware.BaseProd(addDbToContext(h)) 144 » return append(gaemiddleware.BaseProd(), addDbToContext)
157 } 145 }
158 146
159 //// Routes. 147 //// Routes.
160 148
161 func init() { 149 func init() {
162 150
163 // Open DB connection. 151 // Open DB connection.
164 // Declare 'err' here otherwise the next line shadows the global 'dbHand le' 152 // Declare 'err' here otherwise the next line shadows the global 'dbHand le'
165 var err error 153 var err error
166 dbHandle, err = crimsondb.GetDBHandle() 154 dbHandle, err = crimsondb.GetDBHandle()
167 if err != nil { 155 if err != nil {
168 logging.Errorf(context.Background(), 156 logging.Errorf(context.Background(),
169 "Failed to connect to CloudSQL: %v", err) 157 "Failed to connect to CloudSQL: %v", err)
170 return 158 return
171 } 159 }
172 160
173 » router := httprouter.New() 161 » r := router.New()
174 » gaemiddleware.InstallHandlers(router, base) 162 » gaemiddleware.InstallHandlers(r, base())
175 » router.GET("/", webBase(indexPage)) 163 » r.GET("/", webBase(), indexPage)
176 164
177 var api prpc.Server 165 var api prpc.Server
178 crimson.RegisterCrimsonServer(&api, &crimson.DecoratedCrimson{ 166 crimson.RegisterCrimsonServer(&api, &crimson.DecoratedCrimson{
179 Service: &crimsonService{}, 167 Service: &crimsonService{},
180 Prelude: checkAuthorizationPrpc, 168 Prelude: checkAuthorizationPrpc,
181 }) 169 })
182 discovery.Enable(&api) 170 discovery.Enable(&api)
183 » api.InstallHandlers(router, prpcBase) 171 » api.InstallHandlers(r, prpcBase())
184 172
185 » http.DefaultServeMux.Handle("/", router) 173 » http.DefaultServeMux.Handle("/", r)
186 } 174 }
187 175
188 //// Handlers. 176 //// Handlers.
189 177
190 func indexPage( 178 func indexPage(c *router.Context) {
191 » c context.Context, 179 » templates.MustRender(c.Context, c.Writer, "pages/index.html", nil)
192 » w http.ResponseWriter,
193 » r *http.Request,
194 » p httprouter.Params) {
195
196 » templates.MustRender(c, w, "pages/index.html", nil)
197 } 180 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698