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

Unified Diff: server/auth/context.go

Issue 2043423004: Make HTTP middleware easier to use (Closed) Base URL: https://github.com/luci/luci-go@master
Patch Set: gaemiddleware: add middleware func for WithProd 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « common/testing/prpctest/server.go ('k') | server/auth/context_test.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: server/auth/context.go
diff --git a/server/auth/context.go b/server/auth/context.go
index 035d59fb1472ae58d5c8b58da3e21409c92e40fe..0599dd98927bdfab7ea38975cac78315eee6ae69 100644
--- a/server/auth/context.go
+++ b/server/auth/context.go
@@ -1,28 +1,27 @@
// Copyright 2015 The LUCI Authors. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.
package auth
import (
"fmt"
"net/http"
- "github.com/julienschmidt/httprouter"
"golang.org/x/net/context"
"github.com/luci/luci-go/common/errors"
"github.com/luci/luci-go/common/logging"
"github.com/luci/luci-go/server/auth/identity"
- "github.com/luci/luci-go/server/middleware"
+ "github.com/luci/luci-go/server/router"
)
type authenticatorKey int
// SetAuthenticator injects copy of Authenticator (list of auth methods) into
// the context to use by default in LoginURL, LogoutURL and Authenticate.
// Usually installed into the context by some base middleware.
func SetAuthenticator(c context.Context, a Authenticator) context.Context {
return context.WithValue(c, authenticatorKey(0), append(Authenticator(nil), a...))
}
@@ -30,101 +29,100 @@ func SetAuthenticator(c context.Context, a Authenticator) context.Context {
// GetAuthenticator extracts instance of Authenticator (list of auth methods)
// from the context. Returns nil if no authenticator is set.
func GetAuthenticator(c context.Context) Authenticator {
if a, ok := c.Value(authenticatorKey(0)).(Authenticator); ok {
return a
}
return nil
}
// Use is a middleware that simply puts given Authenticator into the context.
-func Use(h middleware.Handler, a Authenticator) middleware.Handler {
- return func(c context.Context, rw http.ResponseWriter, r *http.Request, p httprouter.Params) {
- h(SetAuthenticator(c, a), rw, r, p)
+func Use(a Authenticator) router.Middleware {
+ return func(c *router.Context, next router.Handler) {
+ c.Context = SetAuthenticator(c.Context, a)
+ next(c)
}
}
// LoginURL returns a URL that, when visited, prompts the user to sign in,
// then redirects the user to the URL specified by dest. It is wrapper around
// LoginURL method of Authenticator in the context.
func LoginURL(c context.Context, dest string) (string, error) {
return GetAuthenticator(c).LoginURL(c, dest)
}
// LogoutURL returns a URL that, when visited, signs the user out,
// then redirects the user to the URL specified by dest. It is wrapper around
// LogoutURL method of Authenticator in the context.
func LogoutURL(c context.Context, dest string) (string, error) {
return GetAuthenticator(c).LogoutURL(c, dest)
}
-// Authenticate returns a wrapper around middleware.Handler that performs
-// authentication (using Authenticator in the context) and calls `h`.
-func Authenticate(h middleware.Handler) middleware.Handler {
- return func(c context.Context, rw http.ResponseWriter, r *http.Request, p httprouter.Params) {
- a := GetAuthenticator(c)
- if a == nil {
- replyError(c, rw, 500, "Authentication middleware is not configured")
- return
- }
- ctx, err := a.Authenticate(c, r)
- switch {
- case errors.IsTransient(err):
- replyError(c, rw, 500, fmt.Sprintf("Transient error during authentication - %s", err))
- case err != nil:
- replyError(c, rw, 401, fmt.Sprintf("Authentication error - %s", err))
- default:
- h(ctx, rw, r, p)
- }
+// Authenticate is a middleware that performs authentication (using Authenticator
+// in the context) and calls next handler.
+func Authenticate(c *router.Context, next router.Handler) {
+ a := GetAuthenticator(c.Context)
+ if a == nil {
+ replyError(c.Context, c.Writer, 500, "Authentication middleware is not configured")
+ return
+ }
+ ctx, err := a.Authenticate(c.Context, c.Request)
+ switch {
+ case errors.IsTransient(err):
+ replyError(c.Context, c.Writer, 500, fmt.Sprintf("Transient error during authentication - %s", err))
+ case err != nil:
+ replyError(c.Context, c.Writer, 401, fmt.Sprintf("Authentication error - %s", err))
+ default:
+ c.Context = ctx
+ next(c)
}
}
// Autologin is a middleware that redirects the user to login page if the user
// is not signed in yet or authentication methods do not recognize user
// credentials. Uses Authenticator instance in the context.
-func Autologin(h middleware.Handler) middleware.Handler {
- return func(c context.Context, rw http.ResponseWriter, r *http.Request, p httprouter.Params) {
- a := GetAuthenticator(c)
- if a == nil {
- replyError(c, rw, 500, "Authentication middleware is not configured")
- return
+func Autologin(c *router.Context, next router.Handler) {
+ a := GetAuthenticator(c.Context)
+ if a == nil {
+ replyError(c.Context, c.Writer, 500, "Authentication middleware is not configured")
+ return
+ }
+ ctx, err := a.Authenticate(c.Context, c.Request)
+
+ switch {
+ case errors.IsTransient(err):
+ replyError(c.Context, c.Writer, 500, fmt.Sprintf("Transient error during authentication - %s", err))
+
+ case err != nil:
+ replyError(c.Context, c.Writer, 401, fmt.Sprintf("Authentication error - %s", err))
+
+ case CurrentIdentity(ctx).Kind() == identity.Anonymous:
+ dest := c.Request.RequestURI
+ if dest == "" {
+ // Make r.URL relative.
+ destURL := *c.Request.URL
+ destURL.Host = ""
+ destURL.Scheme = ""
+ dest = destURL.String()
}
- ctx, err := a.Authenticate(c, r)
-
- switch {
- case errors.IsTransient(err):
- replyError(c, rw, 500, fmt.Sprintf("Transient error during authentication - %s", err))
-
- case err != nil:
- replyError(c, rw, 401, fmt.Sprintf("Authentication error - %s", err))
-
- case CurrentIdentity(ctx).Kind() == identity.Anonymous:
- dest := r.RequestURI
- if dest == "" {
- // Make r.URL relative.
- destURL := *r.URL
- destURL.Host = ""
- destURL.Scheme = ""
- dest = destURL.String()
- }
- url, err := a.LoginURL(c, dest)
- if err != nil {
- if errors.IsTransient(err) {
- replyError(c, rw, 500, fmt.Sprintf("Transient error during authentication - %s", err))
- } else {
- replyError(c, rw, 401, fmt.Sprintf("Authentication error - %s", err))
- }
- return
+ url, err := a.LoginURL(c.Context, dest)
+ if err != nil {
+ if errors.IsTransient(err) {
+ replyError(c.Context, c.Writer, 500, fmt.Sprintf("Transient error during authentication - %s", err))
+ } else {
+ replyError(c.Context, c.Writer, 401, fmt.Sprintf("Authentication error - %s", err))
}
- http.Redirect(rw, r, url, 302)
-
- default:
- h(ctx, rw, r, p)
+ return
}
+ http.Redirect(c.Writer, c.Request, url, 302)
+
+ default:
+ c.Context = ctx
+ next(c)
}
}
// replyError logs the error and writes it to ResponseWriter.
func replyError(c context.Context, rw http.ResponseWriter, code int, msg string) {
logging.Errorf(c, "HTTP %d: %s", code, msg)
http.Error(rw, msg, code)
}
« no previous file with comments | « common/testing/prpctest/server.go ('k') | server/auth/context_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698