// 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/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_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 is the domain that are cookies attached to.
	COOKIE_DOMAIN = "skia.org"

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

// InitWithAllow 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 InitWithAllow(port string, local bool, admin, edit, view allowed.Allow) {
	adminAllow = admin
	editAllow = edit
	viewAllow = view
	SimpleInitMust(port, local)
	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 sklog.FmtErrorf("Failed to read from metadata and from %s. Got error: %s", clientSecretFile, err)
		}
		config, err := google.ConfigFromJSON(b)
		if err != nil {
			return sklog.FmtErrorf("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) {
		return 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 host == "localhost" {
		return host
	}
	return COOKIE_DOMAIN
}

// 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, r, err, "Invalid Origin")
			return
		}
		if strings.HasSuffix(u.Host, ".skia.org") {
			w.Header().Add("Access-Control-Allow-Origin", "https://"+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 this is not the oauth callback then redirect.
			if !strings.HasPrefix(r.URL.Path, oauthCallbackPath) {
				redirectUrl := LoginURL(w, r)
				sklog.Infof("Redirect URL: %s", redirectUrl)
				if redirectUrl == "" {
					httputils.ReportError(w, r, fmt.Errorf("Unable to get redirect URL."), "Redirect to login failed:")
					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)
}

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
}
