| 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)
|
| }
|
|
|