// login handles logging in users.
package login

// Theory of operation.
//
// We use OAuth 2.0 handle authentication. We are essentially doing OpenID
// Connect, but vastly simplified since we are hardcoded to Google's endpoints.
//
// We do a simple OAuth 2.0 flow where the user is asked to grant permission to
// the 'email' scope. See https://developers.google.com/+/api/oauth#email for
// details on that scope. Note that you need to have the Google Plus API turned
// on in your project for this to work, but note that the 'email' scope will
// still work for people w/o Google Plus accounts.
//
// Now in theory once we are authorized and have an Access Token we could call
// https://developers.google.com/+/api/openidconnect/getOpenIdConnect and get the
// users email address. But here we can cheat, as we know it's Google and that for
// the 'email' scope an ID Token will be returned along with the Access Token.
// If we decode the ID Token we can get the email address out of that w/o the
// need for the second round trip. This is all clearly *ahem* explained here:
//
//   https://developers.google.com/accounts/docs/OAuth2Login#exchangecode
//
// Once we get the users email address we put it in a cookie for later
// retrieval. The cookie value is validated using HMAC to stop spoofing.
//
// N.B. The cookiesaltkey metadata value must be set on the GCE instance.

import (
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
	"time"

	"github.com/gorilla/securecookie"
	"go.skia.org/infra/go/allowed"
	"go.skia.org/infra/go/httputils"
	"go.skia.org/infra/go/metadata"
	"go.skia.org/infra/go/skerr"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/util"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
	oauth2_api "google.golang.org/api/oauth2/v2"
)

const (
	COOKIE_NAME         = "sktoken"
	SESSION_COOKIE_NAME = "sksession"
	DEFAULT_COOKIE_SALT = "notverysecret"

	// DEFAULT_REDIRECT_URL is the redirect URL to use if Init is called with DEFAULT_DOMAIN_WHITELIST.
	DEFAULT_REDIRECT_URL = "https://skia.org/oauth2callback/"

	// DEFAULT_OAUTH2_CALLBACK is the default relative OAuth2 redirect URL.
	DEFAULT_OAUTH2_CALLBACK = "/oauth2callback/"

	// DEFAULT_DOMAIN_WHITELIST is a white list of domains we use frequently.
	DEFAULT_DOMAIN_WHITELIST = "google.com chromium.org skia.org"

	// DEFAULT_ADMIN_WHITELIST is the white list of users we consider admins when we can't retrieve the whitelist from metadata.
	DEFAULT_ADMIN_WHITELIST = "benjaminwagner@google.com borenet@google.com jcgregorio@google.com kjlubick@google.com rmistry@google.com stephana@google.com"

	// COOKIE_DOMAIN_SKIA_ORG is the cookie domain for skia.org.
	COOKIE_DOMAIN_SKIA_ORG = "skia.org"

	// COOKIE_DOMAIN_SKIA_CORP is the cookie domain for skia*.corp.goog.
	COOKIE_DOMAIN_SKIA_CORP = "corp.goog"

	// LOGIN_CONFIG_FILE is the location of the login config when running in kubernetes.
	LOGIN_CONFIG_FILE = "/etc/skia.org/login.json"

	// DEFAULT_CLIENT_SECRET_FILE is the default path to the file used for OAuth2 login.
	DEFAULT_CLIENT_SECRET_FILE = "client_secret.json"
)

var (
	// cookieSalt is some entropy for our encoders.
	cookieSalt = ""

	secureCookie *securecookie.SecureCookie = nil

	// oauthConfig is the OAuth 2.0 client configuration.
	oauthConfig = &oauth2.Config{
		ClientID:     "not-a-valid-client-id",
		ClientSecret: "not-a-valid-client-secret",
		Scopes:       DEFAULT_SCOPE,
		Endpoint:     google.Endpoint,
		RedirectURL:  "http://localhost:8000/oauth2callback/",
	}

	// activeUserDomainWhiteList is the list of domains that are allowed to
	// log in.
	activeUserDomainWhiteList map[string]bool

	// activeUserEmailWhiteList is the list of email addresses that are
	// allowed to log in (even if the domain is not whitelisted).
	activeUserEmailWhiteList map[string]bool

	// activeAdminEmailWhiteList is the list of email addresses that are
	// allowed to perform admin tasks.
	activeAdminEmailWhiteList map[string]bool

	// DEFAULT_SCOPE is the scope we request when logging in.
	DEFAULT_SCOPE = []string{"email"}

	// Auth groups which determine whether a given user has particular types
	// of access. If nil, fall back on domain and individual email
	// whitelist.
	adminAllow allowed.Allow
	editAllow  allowed.Allow
	viewAllow  allowed.Allow
)

// Session is encrypted and serialized and stored in a user's cookie.
type Session struct {
	Email     string
	ID        string
	AuthScope string
	Token     *oauth2.Token
}

// SimpleInitMust initializes the login system for the default case, which uses
// DEFAULT_REDIRECT_URL in prod along with the DEFAULT_DOMAIN_WHITELIST and
// uses a localhost'port' redirect URL if 'local' is true.
//
// If an error occurs then the function fails fatally.
func SimpleInitMust(port string, local bool) {
	redirectURL := fmt.Sprintf("http://localhost%s/oauth2callback/", port)
	if !local {
		redirectURL = DEFAULT_REDIRECT_URL
	}
	if err := Init(redirectURL, DEFAULT_DOMAIN_WHITELIST, ""); err != nil {
		sklog.Fatalf("Failed to initialize the login system: %s", err)
	}
}

// SimpleInitWithAllow initializes the login system for the default case (see
// docs for SimpleInitMust) and sets the admin, editor, and viewer lists. These
// may be nil, in which case we fall back on the default whitelists. For editors
// we default to denying access to everyone, and for viewers we default to
// allowing access to everyone.
func SimpleInitWithAllow(port string, local bool, admin, edit, view allowed.Allow) {
	redirectURL := fmt.Sprintf("http://localhost%s/oauth2callback/", port)
	if !local {
		redirectURL = DEFAULT_REDIRECT_URL
	}
	InitWithAllow(redirectURL, admin, edit, view)
}

// InitWithAllow initializes the login system with the given redirect URL. Sets
// the admin, editor, and viewer lists as provided. These may be nil, in which
// case we fall back on the default whitelists. For editors we default to
// denying access to everyone, and for viewers we default to allowing access
// to everyone.
func InitWithAllow(redirectURL string, admin, edit, view allowed.Allow) {
	adminAllow = admin
	editAllow = edit
	viewAllow = view
	if err := Init(redirectURL, DEFAULT_DOMAIN_WHITELIST, ""); err != nil {
		sklog.Fatalf("Failed to initialize the login system: %s", err)
	}
	RestrictAdmin = RestrictWithMessage(adminAllow, "User is not an admin")
	RestrictEditor = RestrictWithMessage(editAllow, "User is not an editor")
	RestrictViewer = RestrictWithMessage(viewAllow, "User is not a viewer")
}

// Init must be called before any other login methods.
//
// The function first tries to load the cookie salt, client id, and client
// secret from GCE project level metadata. If that fails it looks for a
// "client_secret.json" file in the current directory to extract the client id
// and client secret from. If both of those fail then it returns an error.
//
// The authWhiteList is the space separated list of domains and email addresses
// that are allowed to log in.
func Init(redirectURL string, authWhiteList string, clientSecretFile string) error {
	cookieSalt, clientID, clientSecret := tryLoadingFromKnownLocations()
	if clientID == "" {
		if clientSecretFile == "" {
			clientSecretFile = DEFAULT_CLIENT_SECRET_FILE
		}

		b, err := ioutil.ReadFile(clientSecretFile)
		if err != nil {
			return skerr.Fmt("Failed to read from metadata and from %s. Got error: %s", clientSecretFile, err)
		}
		config, err := google.ConfigFromJSON(b)
		if err != nil {
			return skerr.Fmt("Failed to read from metadata and decode %s. Got error: %s", clientSecretFile, err)
		}
		sklog.Infof("Successfully read client secret from %s", clientSecretFile)
		clientID = config.ClientID
		clientSecret = config.ClientSecret
	}
	initLogin(clientID, clientSecret, redirectURL, cookieSalt, DEFAULT_SCOPE, authWhiteList)
	return nil
}

// initLogin sets the params.  It should only be called directly for testing purposes.
// Clients should use Init().
func initLogin(clientID, clientSecret, redirectURL, cookieSalt string, scopes []string, authWhiteList string) {
	secureCookie = securecookie.New([]byte(cookieSalt), nil)
	oauthConfig.ClientID = clientID
	oauthConfig.ClientSecret = clientSecret
	oauthConfig.RedirectURL = redirectURL
	oauthConfig.Scopes = scopes

	setActiveWhitelists(authWhiteList)
}

// LoginURL returns a URL that the user is to be directed to for login.
func LoginURL(w http.ResponseWriter, r *http.Request) string {
	// Check for a session id, if not there then assign one, and add it to the redirect URL.
	session, err := r.Cookie(SESSION_COOKIE_NAME)
	state := ""
	if err != nil || session.Value == "" {
		state, err = util.GenerateID()
		if err != nil {
			sklog.Errorf("Failed to create a session token: %s", err)
			return ""
		}
		cookie := &http.Cookie{
			Name:     SESSION_COOKIE_NAME,
			Value:    state,
			Path:     "/",
			Domain:   domainFromHost(r.Host),
			HttpOnly: true,
			Expires:  time.Now().Add(365 * 24 * time.Hour),
		}
		http.SetCookie(w, cookie)
	} else {
		state = session.Value
	}

	redirect := r.Referer()
	if redirect == "" {
		// If we don't have a referrer then we need to construct the URL to
		// bounce back to. This only works if r.Host is set correctly, which
		// it should be as long as 'proxy_set_header Host $host;' is set for
		// the nginx server config.
		redirect = "https://" + r.Host + r.RequestURI
	}
	// Append the current URL to the state, in a way that's safe from tampering,
	// so that we can use it on the rebound. So the state we pass in has the
	// form:
	//
	//   <sessionid>:<hash(salt + original url)>:<original url>
	//
	// Note that the sessionid and the hash are hex values and so won't contain
	// any colons.  To break this up when returned from the server just use
	// strings.SplitN(s, ":", 3) which will ignore any colons found in the
	// Referral URL.
	//
	// On the receiving side we need to recompute the hash and compare against
	// the hash passed in, and only if they match should the redirect URL be
	// trusted.
	state = fmt.Sprintf("%s:%x:%s", state, sha256.Sum256([]byte(cookieSalt+redirect)), redirect)

	// Only retrieve an online access token, i.e. no refresh token. And when we
	// go through the approval flow again don't stop if they've already approved
	// once, unless they have a valid token but aren't in the whitelist,
	// in which case we want to use ApprovalForce so they get the chance
	// to pick a different account to log in with.
	opts := []oauth2.AuthCodeOption{oauth2.AccessTypeOnline}
	s, err := getSession(r)
	if err == nil && !inWhitelist(s.Email) {
		opts = append(opts, oauth2.ApprovalForce)
	} else {
		opts = append(opts, oauth2.SetAuthURLParam("approval_prompt", "auto"))
	}
	return oauthConfig.AuthCodeURL(state, opts...)

}

func getSession(r *http.Request) (*Session, error) {
	cookie, err := r.Cookie(COOKIE_NAME)
	if err != nil {
		return nil, err
	}
	var s Session
	if cookie != nil && len(cookie.String()) > 20 {
		sklog.Infof("Cookie is: %s", cookie.String()[:20])
	} else {
		// This is likely nil or invalid, so no need to elide.
		sklog.Infof("Cookie is: %v", cookie)
	}

	if err := secureCookie.Decode(COOKIE_NAME, cookie.Value, &s); err != nil {
		return nil, err
	}
	if s.AuthScope != strings.Join(oauthConfig.Scopes, " ") {
		return nil, fmt.Errorf("Stored auth scope differs from expected (%v vs %s)", oauthConfig.Scopes, s.AuthScope)
	}
	return &s, nil
}

// LoggedInAs returns the user's ID, i.e. their email address, if they are
// logged in, and "" if they are not logged in.
func LoggedInAs(r *http.Request) string {
	var email string
	if s, err := getSession(r); err == nil {
		email = s.Email
	} else if e, err := ViaBearerToken(r); err == nil {
		email = e
	}
	if inWhitelist(email) {
		// TODO(stephana): Uncomment the following line when Debugf is different from Infof.
		// sklog.Debugf("User %s is on the whitelist", email)
		return email
	}

	// TODO(stephana): Uncomment the following when Debugf is different from Infof.
	// 	if email != "" {
	// 	sklog.Debugf("User %s is not on whitelist", email)
	// }

	return ""
}

// ID returns the user's ID, i.e. their opaque identifier, if they are
// logged in, and "" if they are not logged in.
func ID(r *http.Request) string {
	s, err := getSession(r)
	if err != nil {
		return ""
	}
	return s.ID
}

// UserIdentifiers returns both the email and opaque user id of the logged in
// user, and will return two empty strings if they are not logged in.
func UserIdentifiers(r *http.Request) (string, string) {
	s, err := getSession(r)
	if err != nil {
		return "", ""
	}
	return s.Email, s.ID
}

// IsGoogler determines whether the user is logged in with an @google.com account.
func IsGoogler(r *http.Request) bool {
	return strings.HasSuffix(LoggedInAs(r), "@google.com")
}

// IsAdmin determines whether the user is logged in with an account on the admin
// whitelist. If true, user is allowed to perform admin tasks.
func IsAdmin(r *http.Request) bool {
	email := LoggedInAs(r)
	if adminAllow != nil {
		return adminAllow.Member(email)
	}
	return activeAdminEmailWhiteList[email]
}

// IsEditor determines whether the user is logged in with an account on the
// editor whitelist. If true, user is allowed to perform edits. Defaults to
// false if no editor whitelist is provided.
func IsEditor(r *http.Request) bool {
	email := LoggedInAs(r)
	if editAllow != nil {
		return editAllow.Member(email)
	}
	return false
}

// IsViewer determines whether the user is allowed to view this server. Defaults
// to true if no viewer whitelist is provided.
func IsViewer(r *http.Request) bool {
	email := LoggedInAs(r)
	if viewAllow != nil {
		return viewAllow.Member(email)
	}
	return true
}

// A JSON Web Token can contain much info, such as 'iss' and 'sub'. We don't care about
// that, we only want one field which is 'email'.
//
// {
//   "iss":"accounts.google.com",
//   "sub":"110642259984599645813",
//   "email":"jcgregorio@google.com",
//   ...
// }
type decodedIDToken struct {
	Email string `json:"email"`
	ID    string `json:"sub"`
}

// domainFromHost returns the value to use in the cookie Domain field based on
// the requests Host value.
func domainFromHost(fullhost string) string {
	// Split host and port.
	parts := strings.Split(fullhost, ":")
	host := parts[0]
	if strings.HasPrefix(fullhost, "localhost") {
		return host
	} else if strings.HasSuffix(fullhost, "."+COOKIE_DOMAIN_SKIA_CORP) {
		return COOKIE_DOMAIN_SKIA_CORP
	} else if strings.HasSuffix(fullhost, "."+COOKIE_DOMAIN_SKIA_ORG) {
		return COOKIE_DOMAIN_SKIA_ORG
	} else {
		sklog.Errorf("Unknown domain for host: %s; falling back to %s", fullhost, COOKIE_DOMAIN_SKIA_ORG)
		return COOKIE_DOMAIN_SKIA_ORG
	}
}

// CookieFor creates an encoded Cookie for the given user id.
func CookieFor(value *Session, r *http.Request) (*http.Cookie, error) {
	encoded, err := secureCookie.Encode(COOKIE_NAME, value)
	if err != nil {
		return nil, fmt.Errorf("Failed to encode cookie")
	}
	return &http.Cookie{
		Name:     COOKIE_NAME,
		Value:    encoded,
		Path:     "/",
		Domain:   domainFromHost(r.Host),
		HttpOnly: true,
		Expires:  time.Now().Add(365 * 24 * time.Hour),
	}, nil
}

func setSkIDCookieValue(w http.ResponseWriter, r *http.Request, value *Session) {
	cookie, err := CookieFor(value, r)
	if err != nil {
		http.Error(w, fmt.Sprintf("%s", err), 500)
		return
	}
	http.SetCookie(w, cookie)
}

// LogoutHandler logs the user out by overwriting the cookie with a blank email
// address.
//
// Note that this doesn't revoke the 'email' grant, so logging in later will
// still be fast. Users can always visit
//
//   https://security.google.com/settings/security/permissions
//
// to revoke any grants they make.
func LogoutHandler(w http.ResponseWriter, r *http.Request) {
	sklog.Infof("LogoutHandler")
	setSkIDCookieValue(w, r, &Session{})
	http.Redirect(w, r, r.FormValue("redirect"), 302)
}

// OAuth2CallbackHandler must be attached at a handler that matches
// the callback URL registered in the APIs Console. In this case
// "/oauth2callback".
func OAuth2CallbackHandler(w http.ResponseWriter, r *http.Request) {
	sklog.Infof("OAuth2CallbackHandler")
	cookie, err := r.Cookie(SESSION_COOKIE_NAME)
	if err != nil || cookie.Value == "" {
		http.Error(w, "Invalid session state.", 500)
		return
	}

	state := r.FormValue("state")
	stateParts := strings.SplitN(state, ":", 3)
	redirect := "/"
	// If the state contains a redirect URL.
	if len(stateParts) == 3 {
		// state has this form:   <sessionid>:<hash(salt + original url)>:<original url>
		// See LoginURL for more details.
		state = stateParts[0]
		hash := stateParts[1]
		url := stateParts[2]
		expectedHash := fmt.Sprintf("%x", sha256.Sum256([]byte(cookieSalt+url)))
		if hash == expectedHash {
			redirect = url
		} else {
			sklog.Warningf("Got an invalid redirect: %s != %s", hash, expectedHash)
		}
	}
	if state != cookie.Value {
		http.Error(w, "Session state doesn't match callback state.", 500)
		return
	}

	code := r.FormValue("code")
	sklog.Infof("Code: %s ", code[:5])
	token, err := oauthConfig.Exchange(oauth2.NoContext, code)
	if err != nil {
		sklog.Errorf("Failed to authenticate: %s", err)
		http.Error(w, "Failed to authenticate.", 500)
		return
	}
	// idToken is a JSON Web Token. We only need to decode the token, we do not
	// need to validate the token because it came to us over HTTPS directly from
	// Google's servers.
	idToken, ok := token.Extra("id_token").(string)
	if !ok {
		http.Error(w, "No id_token returned.", 500)
		return
	}
	// The id token is actually three base64 encoded parts that are "." separated.
	segments := strings.Split(idToken, ".")
	if len(segments) != 3 {
		http.Error(w, "Invalid id_token.", 500)
		return
	}
	// Now base64 decode the middle segment, which decodes to JSON.
	padding := 4 - (len(segments[1]) % 4)
	if padding == 4 {
		padding = 0
	}
	middle := segments[1] + strings.Repeat("=", padding)
	b, err := base64.URLEncoding.DecodeString(middle)
	if err != nil {
		sklog.Errorf("Failed to base64 decode middle part of token: %s From: %#v", middle, segments)
		http.Error(w, "Failed to base64 decode id_token.", 500)
		return
	}
	// Finally decode the JSON.
	decoded := &decodedIDToken{}
	if err := json.Unmarshal(b, decoded); err != nil {
		sklog.Errorf("Failed to JSON decode token: %s", string(b))
		http.Error(w, "Failed to JSON decode id_token.", 500)
		return
	}

	email := strings.ToLower(decoded.Email)
	parts := strings.Split(email, "@")
	if len(parts) != 2 {
		http.Error(w, "Invalid email address received.", 500)
		return
	}

	if !inWhitelist(email) {
		http.Error(w, "Accounts from your domain are not allowed or your email address is not white listed.", 500)
		return
	}
	s := Session{
		Email:     email,
		ID:        decoded.ID,
		AuthScope: strings.Join(oauthConfig.Scopes, " "),
		Token:     token,
	}
	setSkIDCookieValue(w, r, &s)
	http.Redirect(w, r, redirect, 302)
}

// inWhitelist returns true if the given email address matches either the
// domain or the user whitelist.
func inWhitelist(email string) bool {
	parts := strings.Split(email, "@")
	if len(parts) != 2 {
		return false
	}
	if viewAllow != nil {
		return viewAllow.Member(email)
	}
	if len(activeUserDomainWhiteList) > 0 && !activeUserDomainWhiteList[parts[1]] && !activeUserEmailWhiteList[email] {
		return false
	}
	return true
}

// StatusHandler returns the login status of the user as JSON that looks like:
//
// {
//   "Email":     "fred@example.com",
//   "ID":        "12342...34324",
//   "LoginURL":  "https://..."
//   "IsAGoogler": false,
//   "IsViewer":   true,
//   "IsEditor":   true,
//   "IsAdmin:     false
// }
//
func StatusHandler(w http.ResponseWriter, r *http.Request) {
	sklog.Infof("StatusHandler")
	w.Header().Set("Content-Type", "application/json")
	enc := json.NewEncoder(w)
	email, id := UserIdentifiers(r)
	body := struct {
		Email      string
		ID         string
		LoginURL   string
		IsAGoogler bool
		IsAdmin    bool
		IsEditor   bool
		IsViewer   bool
	}{
		Email:      email,
		ID:         id,
		LoginURL:   LoginURL(w, r),
		IsAGoogler: IsGoogler(r),
		IsAdmin:    IsAdmin(r),
		IsEditor:   IsEditor(r),
		IsViewer:   IsViewer(r),
	}

	sklog.Infof("Origin: %s", r.Header.Get("Origin"))
	if origin := r.Header.Get("Origin"); origin != "" {
		u, err := url.Parse(origin)
		if err != nil {
			httputils.ReportError(w, err, "Invalid Origin", http.StatusInternalServerError)
			return
		}
		if strings.HasSuffix(u.Host, "."+COOKIE_DOMAIN_SKIA_ORG) ||
			strings.HasSuffix(u.Host, "."+COOKIE_DOMAIN_SKIA_CORP) ||
			strings.HasPrefix(u.Host, "localhost:") {
			prefix := "https://"
			if strings.HasPrefix(u.Host, "localhost:") {
				prefix = "http://"
			}
			w.Header().Add("Access-Control-Allow-Origin", prefix+u.Host)
			w.Header().Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
			w.Header().Add("Access-Control-Allow-Credentials", "true")
			w.Header().Add("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
		}
	}

	if r.Method == "OPTIONS" {
		return
	}

	if err := enc.Encode(body); err != nil {
		sklog.Errorf("Failed to encode Login status to JSON: %s", err)
	}
}

// ForceAuthMiddleware does ForceAuth by returning a func that can be used as
// middleware.
func ForceAuthMiddleware(oauthCallbackPath string) func(http.Handler) http.Handler {
	return func(h http.Handler) http.Handler {
		return ForceAuth(h, oauthCallbackPath)
	}
}

// ForceAuth is middleware that enforces authentication
// before the wrapped handler is called. oauthCallbackPath is the
// URL path that the user is redirected to at the end of the auth flow.
func ForceAuth(h http.Handler, oauthCallbackPath string) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		userId := LoggedInAs(r)
		if userId == "" {
			if strings.HasPrefix(r.URL.Path, oauthCallbackPath) {
				// If this is the oauth2 callback, run that handler.
				OAuth2CallbackHandler(w, r)
				return
			} else {
				// If this is not the oauth callback then redirect.
				redirectUrl := LoginURL(w, r)
				sklog.Infof("Redirect URL: %s", redirectUrl)
				if redirectUrl == "" {
					httputils.ReportError(w, fmt.Errorf("Unable to get redirect URL."), "Redirect to login failed:", http.StatusInternalServerError)
					return
				}
				http.Redirect(w, r, redirectUrl, http.StatusTemporaryRedirect)
				return
			}
		}
		h.ServeHTTP(w, r)
	})
}

// RestrictWithMessage returns a middleware func which enforces that the user
// is logged in with an allowed account before the wrapped handler is called. It
// uses the given message when a user is denied access.
func RestrictWithMessage(allow allowed.Allow, msg string) func(http.Handler) http.Handler {
	if allow == nil {
		return func(h http.Handler) http.Handler { return h }
	}
	return func(h http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			email := LoggedInAs(r)
			if !allow.Member(email) {
				sklog.Warningf("%s: %s", msg, email)
				http.Error(w, msg, 403)
				return
			}
			h.ServeHTTP(w, r)
		})
	}
}

// Restrict returns a middleware func which enforces that the user is logged
// in with an allowed account before the wrapped handler is called.
func Restrict(allow allowed.Allow) func(http.Handler) http.Handler {
	return RestrictWithMessage(allow, "User is not in allowed list")
}

// RestrictAdmin is middleware which enforces that the user is logged in as an
// admin before the wrapped handler is called.  Filled in during InitWithAllow.
var RestrictAdmin = func(h http.Handler) http.Handler {
	sklog.Fatal("RestrictAdmin called but not configured with InitWithAllow.")
	return h
}

// RestrictEditor is middleware which enforces that the user is logged in as an
// editor before the wrapped handler is called.  Filled in during InitWithAllow.
var RestrictEditor = func(h http.Handler) http.Handler {
	sklog.Fatal("RestrictEditor called but not configured with InitWithAllow.")
	return h
}

// RestrictViewer is middleware which enforces that the user is logged in as a
// viewer before the wrapped handler is called.  Filled in during InitWithAllow.
var RestrictViewer = func(h http.Handler) http.Handler {
	sklog.Fatal("RestrictViewer called but not configured with InitWithAllow.")
	return h
}

// RestrictFn wraps an http.HandlerFunc, restricting it to the given allowed list.
func RestrictFn(h http.HandlerFunc, allow allowed.Allow) http.HandlerFunc {
	return Restrict(allow)(h).(http.HandlerFunc)
}

// RestrictAdminFn wraps an http.HandlerFunc, restricting it to admins.
func RestrictAdminFn(h http.HandlerFunc) http.HandlerFunc {
	return RestrictAdmin(h).(http.HandlerFunc)
}

// RestrictEditorFn wraps an http.HandlerFunc, restricting it to editors.
func RestrictEditorFn(h http.HandlerFunc) http.HandlerFunc {
	return RestrictEditor(h).(http.HandlerFunc)
}

// RestrictViewerFn wraps an http.HandlerFunc, restricting it to viewers.
func RestrictViewerFn(h http.HandlerFunc) http.HandlerFunc {
	return RestrictViewer(h).(http.HandlerFunc)
}

// splitAuthWhiteList splits the given whitelist into a set of domains and a set of
// individual emails
func splitAuthWhiteList(whiteList string) (map[string]bool, map[string]bool) {
	domains := map[string]bool{}
	emails := map[string]bool{}

	for _, entry := range strings.Fields(whiteList) {
		trimmed := strings.ToLower(strings.TrimSpace(entry))
		if strings.Contains(trimmed, "@") {
			emails[trimmed] = true
		} else {
			domains[trimmed] = true
		}
	}

	return domains, emails
}

// setActiveWhitelists initializes activeDomainWhiteList and
// activeEmailWhiteList from authWhiteList.
func setActiveWhitelists(authWhiteList string) {
	if adminAllow != nil || editAllow != nil || viewAllow != nil {
		return
	}
	activeUserDomainWhiteList, activeUserEmailWhiteList = splitAuthWhiteList(authWhiteList)
	adminWhiteList := metadata.ProjectGetWithDefault(metadata.ADMIN_WHITE_LIST, DEFAULT_ADMIN_WHITELIST)
	_, activeAdminEmailWhiteList = splitAuthWhiteList(adminWhiteList)
}

// loginInfo is the JSON file format that client info is stored in as a kubernetes secret.
type loginInfo struct {
	Salt         string `json:"salt"`
	ClientID     string `json:"client_id"`
	ClientSecret string `json:"client_secret"`
}

// tryLoadingFromKnownLocations tries to load the cookie salt, client id, and
// client secret from a file in a known location, and then from GCE project
// level metadata. If it fails then it returns the salt it was passed and the
// client id and secret are the empty string.
//
// Returns salt, clientID, clientSecret.
func tryLoadingFromKnownLocations() (string, string, string) {
	cookieSalt := ""
	clientID := ""
	clientSecret := ""
	var info loginInfo
	err := util.WithReadFile(LOGIN_CONFIG_FILE, func(f io.Reader) error {
		if err := json.NewDecoder(f).Decode(&info); err != nil {
			return err
		}
		cookieSalt = info.Salt
		clientID = info.ClientID
		clientSecret = info.ClientSecret
		return nil
	})

	if err == nil {
		sklog.Infof("Successfully loaded login secrets from file %s.", LOGIN_CONFIG_FILE)
		return cookieSalt, clientID, clientSecret
	}
	sklog.Infof("Failed to load login secrets from file %s. Got error: %s", LOGIN_CONFIG_FILE, err)

	cookieSalt, err = metadata.ProjectGet(metadata.COOKIESALT)
	if err != nil {
		return DEFAULT_COOKIE_SALT, "", ""
	}
	clientID, err = metadata.ProjectGet(metadata.CLIENT_ID)
	if err != nil {
		return DEFAULT_COOKIE_SALT, "", ""
	}
	clientSecret, err = metadata.ProjectGet(metadata.CLIENT_SECRET)
	if err != nil {
		return DEFAULT_COOKIE_SALT, "", ""
	}
	return cookieSalt, clientID, clientSecret
}

// ViaBearerToken tries to load an OAuth 2.0 Bearer token from from the request
// and derives the login email address from it.
func ViaBearerToken(r *http.Request) (string, error) {
	tok := r.Header.Get("Authorization")
	if tok == "" {
		return "", errors.New("User is not authenticated.")
	}
	tok = strings.TrimPrefix(tok, "Bearer ")
	tokenInfo, err := ValidateBearerToken(tok)
	if err != nil {
		return "", err
	}
	return tokenInfo.Email, nil
}

// ValidateBearerToken takes an OAuth 2.0 Bearer token (e.g. The third part of
// Authorization: Bearer ya29.Elj...
// and polls a Google HTTP endpoint to see if is valid. This is fine in low-volumne
// situations, but another solution may be needed if this goes higher than a few QPS.
func ValidateBearerToken(token string) (*oauth2_api.Tokeninfo, error) {
	c, err := oauth2_api.New(httputils.NewTimeoutClient())
	if err != nil {
		return nil, fmt.Errorf("could not make oauth2 api client: %s", err)
	}
	ti, err := c.Tokeninfo().AccessToken(token).Do()
	if err != nil {
		return nil, err
	}
	if ti.ExpiresIn <= 0 {
		return nil, fmt.Errorf("Token is expired.")
	}
	if !ti.VerifiedEmail {
		return nil, fmt.Errorf("Email not verified.")
	}
	return ti, nil
}
