blob: d527c5be58c3fd4094120accc303c959dc904abf [file] [log] [blame]
// Copyright 2017 The Goma Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package httprpc
import (
"context"
"fmt"
"net/http"
"go.chromium.org/goma/server/auth/enduser"
"go.chromium.org/goma/server/log"
)
// AuthChecker represents an interface to checks HTTP access.
type AuthChecker interface {
// Check represents the function to check HTTP access.
// If the access is granted, it returns non-nil enduser.EndUser instance.
Check(context.Context, *http.Request) (*enduser.EndUser, error)
}
// AuthHandler converts given http.Handler to access controlled HTTP handler using AuthChecker.
// Alternatives: WithAuth handler option if it requires retry with Unauthenticated error.
func AuthHandler(a AuthChecker, h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
ctx := req.Context()
u, err := a.Check(ctx, req)
if err != nil {
code := http.StatusUnauthorized
http.Error(w, fmt.Sprintf("auth failed %s: %v", RemoteAddr(req), err), code)
logger := log.FromContext(ctx)
logger.Errorf("auth error %s: %d %s: %v", req.URL.Path, code, http.StatusText(code), err)
return
}
req = req.WithContext(enduser.NewContext(ctx, u))
h.ServeHTTP(w, req)
})
}