| 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 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 "net/http" | 10 "net/http" |
| 11 "strings" | 11 "strings" |
| 12 | 12 |
| 13 "github.com/golang/protobuf/proto" | 13 "github.com/golang/protobuf/proto" |
| 14 "github.com/julienschmidt/httprouter" | |
| 15 "golang.org/x/net/context" | 14 "golang.org/x/net/context" |
| 16 "google.golang.org/appengine" | 15 "google.golang.org/appengine" |
| 17 | 16 |
| 18 "github.com/luci/gae/service/info" | 17 "github.com/luci/gae/service/info" |
| 19 "github.com/luci/luci-go/appengine/cmd/helloworld/proto" | 18 "github.com/luci/luci-go/appengine/cmd/helloworld/proto" |
| 20 "github.com/luci/luci-go/appengine/gaeauth/server" | 19 "github.com/luci/luci-go/appengine/gaeauth/server" |
| 21 "github.com/luci/luci-go/appengine/gaemiddleware" | 20 "github.com/luci/luci-go/appengine/gaemiddleware" |
| 22 "github.com/luci/luci-go/server/auth" | 21 "github.com/luci/luci-go/server/auth" |
| 23 "github.com/luci/luci-go/server/discovery" | 22 "github.com/luci/luci-go/server/discovery" |
| 24 "github.com/luci/luci-go/server/middleware" | |
| 25 "github.com/luci/luci-go/server/prpc" | 23 "github.com/luci/luci-go/server/prpc" |
| 24 "github.com/luci/luci-go/server/router" |
| 26 "github.com/luci/luci-go/server/templates" | 25 "github.com/luci/luci-go/server/templates" |
| 27 ) | 26 ) |
| 28 | 27 |
| 29 // templateBundle is used to render HTML templates. It provides a base args | 28 // templateBundle is used to render HTML templates. It provides a base args |
| 30 // passed to all templates. | 29 // passed to all templates. |
| 31 var templateBundle = &templates.Bundle{ | 30 var templateBundle = &templates.Bundle{ |
| 32 Loader: templates.FileSystemLoader("templates"), | 31 Loader: templates.FileSystemLoader("templates"), |
| 33 DebugMode: appengine.IsDevAppServer(), | 32 DebugMode: appengine.IsDevAppServer(), |
| 34 DefaultArgs: func(c context.Context) (templates.Args, error) { | 33 DefaultArgs: func(c context.Context) (templates.Args, error) { |
| 35 loginURL, err := auth.LoginURL(c, "/") | 34 loginURL, err := auth.LoginURL(c, "/") |
| (...skipping 12 matching lines...) Expand all Loading... |
| 48 "AppVersion": strings.Split(info.Get(c).VersionID(), ".
")[0], | 47 "AppVersion": strings.Split(info.Get(c).VersionID(), ".
")[0], |
| 49 "IsAnonymous": auth.CurrentIdentity(c) == "anonymous:ano
nymous", | 48 "IsAnonymous": auth.CurrentIdentity(c) == "anonymous:ano
nymous", |
| 50 "IsAdmin": isAdmin, | 49 "IsAdmin": isAdmin, |
| 51 "User": auth.CurrentUser(c), | 50 "User": auth.CurrentUser(c), |
| 52 "LoginURL": loginURL, | 51 "LoginURL": loginURL, |
| 53 "LogoutURL": logoutURL, | 52 "LogoutURL": logoutURL, |
| 54 }, nil | 53 }, nil |
| 55 }, | 54 }, |
| 56 } | 55 } |
| 57 | 56 |
| 58 // pageBase is middleware for page handlers. | 57 // pageBase returns the middleware chain for page handlers. |
| 59 func pageBase(h middleware.Handler) httprouter.Handle { | 58 func pageBase() router.MiddlewareChain { |
| 60 » h = auth.Use(h, auth.Authenticator{server.CookieAuth}) | 59 » return append( |
| 61 » h = templates.WithTemplates(h, templateBundle) | 60 » » gaemiddleware.BaseProd(), |
| 62 » return gaemiddleware.BaseProd(h) | 61 » » templates.WithTemplates(templateBundle), |
| 62 » » auth.Use(auth.Authenticator{server.CookieAuth}), |
| 63 » ) |
| 63 } | 64 } |
| 64 | 65 |
| 65 // prpcBase is middleware for pRPC API handlers. | 66 // prpcBase returns the middleware chain for pRPC API handlers. |
| 66 func prpcBase(h middleware.Handler) httprouter.Handle { | 67 func prpcBase() router.MiddlewareChain { |
| 67 // OAuth 2.0 with email scope is registered as a default authenticator | 68 // OAuth 2.0 with email scope is registered as a default authenticator |
| 68 // by importing "github.com/luci/luci-go/appengine/gaeauth/server". | 69 // by importing "github.com/luci/luci-go/appengine/gaeauth/server". |
| 69 // No need to setup an authenticator here. | 70 // No need to setup an authenticator here. |
| 70 // | 71 // |
| 71 // For authorization checks, we use per-service decorators; see | 72 // For authorization checks, we use per-service decorators; see |
| 72 // service registration code. | 73 // service registration code. |
| 73 » return gaemiddleware.BaseProd(h) | 74 » return gaemiddleware.BaseProd() |
| 74 } | 75 } |
| 75 | 76 |
| 76 //// Routes. | 77 //// Routes. |
| 77 | 78 |
| 78 func checkAPIAccess(c context.Context, methodName string, req proto.Message) (co
ntext.Context, error) { | 79 func checkAPIAccess(c context.Context, methodName string, req proto.Message) (co
ntext.Context, error) { |
| 79 // Implement authorization check here, for example: | 80 // Implement authorization check here, for example: |
| 80 // | 81 // |
| 81 // import "github.com/golang/protobuf/proto" | 82 // import "github.com/golang/protobuf/proto" |
| 82 // import "google.golang.org/grpc/codes" | 83 // import "google.golang.org/grpc/codes" |
| 83 // import "github.com/luci/luci-go/common/grpcutil" | 84 // import "github.com/luci/luci-go/common/grpcutil" |
| 84 // | 85 // |
| 85 // hasAccess, err := auth.IsMember(c, "my-users") | 86 // hasAccess, err := auth.IsMember(c, "my-users") |
| 86 // if err != nil { | 87 // if err != nil { |
| 87 // return nil, grpcutil.Errf(codes.Internal, "%s", err) | 88 // return nil, grpcutil.Errf(codes.Internal, "%s", err) |
| 88 // } | 89 // } |
| 89 // if !hasAccess { | 90 // if !hasAccess { |
| 90 // return nil, grpcutil.Errf(codes.PermissionDenied, "%s is not allowe
d to call APIs", auth.CurrentIdentity(c)) | 91 // return nil, grpcutil.Errf(codes.PermissionDenied, "%s is not allowe
d to call APIs", auth.CurrentIdentity(c)) |
| 91 // } | 92 // } |
| 92 | 93 |
| 93 return c, nil | 94 return c, nil |
| 94 } | 95 } |
| 95 | 96 |
| 96 func init() { | 97 func init() { |
| 97 » router := httprouter.New() | 98 » r := router.New() |
| 98 » gaemiddleware.InstallHandlers(router, pageBase) | 99 » gaemiddleware.InstallHandlers(r, pageBase()) |
| 99 » router.GET("/", pageBase(auth.Authenticate(indexPage))) | 100 » r.GET("/", append(pageBase(), auth.Authenticate), indexPage) |
| 100 | 101 |
| 101 var api prpc.Server | 102 var api prpc.Server |
| 102 helloworld.RegisterGreeterServer(&api, &helloworld.DecoratedGreeter{ | 103 helloworld.RegisterGreeterServer(&api, &helloworld.DecoratedGreeter{ |
| 103 Service: &greeterService{}, | 104 Service: &greeterService{}, |
| 104 Prelude: checkAPIAccess, | 105 Prelude: checkAPIAccess, |
| 105 }) | 106 }) |
| 106 discovery.Enable(&api) | 107 discovery.Enable(&api) |
| 107 » api.InstallHandlers(router, prpcBase) | 108 » api.InstallHandlers(r, prpcBase()) |
| 108 | 109 |
| 109 » http.DefaultServeMux.Handle("/", router) | 110 » http.DefaultServeMux.Handle("/", r) |
| 110 } | 111 } |
| 111 | 112 |
| 112 //// Handlers. | 113 //// Handlers. |
| 113 | 114 |
| 114 func indexPage(c context.Context, w http.ResponseWriter, r *http.Request, p http
router.Params) { | 115 func indexPage(c *router.Context) { |
| 115 » templates.MustRender(c, w, "pages/index.html", nil) | 116 » templates.MustRender(c.Context, c.Writer, "pages/index.html", nil) |
| 116 } | 117 } |
| OLD | NEW |