// Copyright 2015 The Vanadium 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 oauth implements an http.Handler that has two main purposes
// listed below:
//
// (1) Uses OAuth to authenticate and then renders a page that
//     displays all the blessings that were provided for that Google user.
//     The client calls the /listblessings route which redirects to listblessingscallback which
//     renders the list.
// (2) Performs the oauth flow for seeking a blessing using the principal tool
//     located at v.io/x/ref/cmd/principal.
//     The seek blessing flow works as follows:
//     (a) Client (principal tool) hits the /seekblessings route.
//     (b) /seekblessings performs oauth with a redirect to /seekblessingscallback.
//     (c) Client specifies desired caveats in the form that /seekblessingscallback displays.
//     (d) Submission of the form sends caveat information to /sendmacaroon.
//     (e) /sendmacaroon sends a macaroon with blessing information to client
//         (via a redirect to an HTTP server run by the tool).
//     (f) Client invokes bless rpc with macaroon.

package oauth

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"path"
	"strings"
	"time"

	"v.io/v23/security"
	"v.io/v23/vom"
	"v.io/x/lib/vlog"
	"v.io/x/ref/services/identity/internal/auditor"
	"v.io/x/ref/services/identity/internal/caveats"
	"v.io/x/ref/services/identity/internal/revocation"
	"v.io/x/ref/services/identity/internal/templates"
	"v.io/x/ref/services/identity/internal/util"
)

const (
	clientIDCookie = "VeyronHTTPIdentityClientID"

	ListBlessingsRoute         = "listblessings"
	listBlessingsCallbackRoute = "listblessingscallback"
	revokeRoute                = "revoke"
	SeekBlessingsRoute         = "seekblessings"
	addCaveatsRoute            = "addcaveats"
	sendMacaroonRoute          = "sendmacaroon"
)

type HandlerArgs struct {
	// The principal to use.
	Principal security.Principal
	// The Key that is used for creating and verifying macaroons.
	// This needs to be common between the handler and the MacaroonBlesser service.
	MacaroonKey []byte
	// URL at which the hander is installed.
	// e.g. http://host:port/google/
	Addr string
	// BlessingLogReder is needed for reading audit logs.
	BlessingLogReader auditor.BlessingLogReader
	// The RevocationManager is used to revoke blessings granted with a revocation caveat.
	// If nil, then revocation caveats cannot be added to blessings and an expiration caveat
	// will be used instead.
	RevocationManager revocation.RevocationManager
	// The object name of the discharger service.
	DischargerLocation string
	// MacaroonBlessingService is the object name to which macaroons create by this HTTP
	// handler can be exchanged for a blessing.
	MacaroonBlessingService string
	// OAuthProvider is used to authenticate and get a blessee email.
	OAuthProvider OAuthProvider
	// CaveatSelector is used to obtain caveats from the user when seeking a blessing.
	CaveatSelector caveats.CaveatSelector
	// AssetsPrefix is the host where web assets for rendering the list blessings template are stored.
	AssetsPrefix string
	// GoogleServers is the list of published Google blessings services.
	GoogleServers []string
	// DischargeServers is the list of published disharges services.
	DischargeServers []string
}

// BlessingMacaroon contains the data that is encoded into the macaroon for creating blessings.
type BlessingMacaroon struct {
	Creation  time.Time
	Caveats   []security.Caveat
	Name      string
	PublicKey []byte // Marshaled public key of the principal tool.
}

func redirectURL(baseURL, suffix string) string {
	if !strings.HasSuffix(baseURL, "/") {
		baseURL += "/"
	}
	return baseURL + suffix
}

// NewHandler returns an http.Handler that expects to be rooted at args.Addr
// and can be used to authenticate with args.OAuthProvider, mint a new
// identity and bless it with the OAuthProvider email address.
func NewHandler(args HandlerArgs) (http.Handler, error) {
	csrfCop, err := util.NewCSRFCop()
	if err != nil {
		return nil, fmt.Errorf("NewHandler failed to create csrfCop: %v", err)
	}
	return &handler{
		args:    args,
		csrfCop: csrfCop,
	}, nil
}

type handler struct {
	args    HandlerArgs
	csrfCop *util.CSRFCop
}

func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	switch path.Base(r.URL.Path) {
	case ListBlessingsRoute:
		h.listBlessings(w, r)
	case listBlessingsCallbackRoute:
		h.listBlessingsCallback(w, r)
	case revokeRoute:
		h.revoke(w, r)
	case SeekBlessingsRoute:
		h.seekBlessings(w, r)
	case addCaveatsRoute:
		h.addCaveats(w, r)
	case sendMacaroonRoute:
		h.sendMacaroon(w, r)
	default:
		util.HTTPBadRequest(w, r, nil)
	}
}

func (h *handler) listBlessings(w http.ResponseWriter, r *http.Request) {
	csrf, err := h.csrfCop.NewToken(w, r, clientIDCookie, nil)
	if err != nil {
		vlog.Infof("Failed to create CSRF token[%v] for request %#v", err, r)
		util.HTTPServerError(w, fmt.Errorf("failed to create new token: %v", err))
		return
	}
	http.Redirect(w, r, h.args.OAuthProvider.AuthURL(redirectURL(h.args.Addr, listBlessingsCallbackRoute), csrf, ReuseApproval), http.StatusFound)
}

func (h *handler) listBlessingsCallback(w http.ResponseWriter, r *http.Request) {
	if err := h.csrfCop.ValidateToken(r.FormValue("state"), r, clientIDCookie, nil); err != nil {
		vlog.Infof("Invalid CSRF token: %v in request: %#v", err, r)
		util.HTTPBadRequest(w, r, fmt.Errorf("Suspected request forgery: %v", err))
		return
	}
	email, err := h.args.OAuthProvider.ExchangeAuthCodeForEmail(r.FormValue("code"), redirectURL(h.args.Addr, listBlessingsCallbackRoute))
	if err != nil {
		util.HTTPBadRequest(w, r, err)
		return
	}

	type tmplentry struct {
		Timestamp      time.Time
		Caveats        []string
		RevocationTime time.Time
		Blessed        security.Blessings
		Token          string
		Error          error
	}
	tmplargs := struct {
		Log                              chan tmplentry
		Email, RevokeRoute, AssetsPrefix string
		Self                             security.Blessings
		GoogleServers, DischargeServers  []string
	}{
		Log:              make(chan tmplentry),
		Email:            email,
		RevokeRoute:      revokeRoute,
		AssetsPrefix:     h.args.AssetsPrefix,
		Self:             h.args.Principal.BlessingStore().Default(),
		GoogleServers:    h.args.GoogleServers,
		DischargeServers: h.args.DischargeServers,
	}
	entrych := h.args.BlessingLogReader.Read(email)

	w.Header().Set("Context-Type", "text/html")
	// This MaybeSetCookie call is needed to ensure that a cookie is created. Since the
	// header cannot be changed once the body is written to, this needs to be called first.
	if _, err = h.csrfCop.MaybeSetCookie(w, r, clientIDCookie); err != nil {
		vlog.Infof("Failed to set CSRF cookie[%v] for request %#v", err, r)
		util.HTTPServerError(w, err)
		return
	}
	go func(ch chan tmplentry) {
		defer close(ch)
		for entry := range entrych {
			tmplEntry := tmplentry{
				Error:     entry.DecodeError,
				Timestamp: entry.Timestamp,
				Blessed:   entry.Blessings,
			}
			if len(entry.Caveats) > 0 {
				if tmplEntry.Caveats, err = prettyPrintCaveats(entry.Caveats); err != nil {
					vlog.Errorf("Failed to pretty print caveats: %v", err)
					tmplEntry.Error = fmt.Errorf("failed to pretty print caveats: %v", err)
				}
			}
			if len(entry.RevocationCaveatID) > 0 && h.args.RevocationManager != nil {
				if revocationTime := h.args.RevocationManager.GetRevocationTime(entry.RevocationCaveatID); revocationTime != nil {
					tmplEntry.RevocationTime = *revocationTime
				} else {
					caveatID := base64.URLEncoding.EncodeToString([]byte(entry.RevocationCaveatID))
					if tmplEntry.Token, err = h.csrfCop.NewToken(w, r, clientIDCookie, caveatID); err != nil {
						vlog.Errorf("Failed to create CSRF token[%v] for request %#v", err, r)
						tmplEntry.Error = fmt.Errorf("server error: unable to create revocation token")
					}
				}
			}
			ch <- tmplEntry
		}
	}(tmplargs.Log)
	if err := templates.ListBlessings.Execute(w, tmplargs); err != nil {
		vlog.Errorf("Unable to execute audit page template: %v", err)
		util.HTTPServerError(w, err)
	}
}

// prettyPrintCaveats returns a user friendly string for vanadium standard caveat.
// Unrecognized caveats will fall back to the Caveat's String() method.
func prettyPrintCaveats(cavs []security.Caveat) ([]string, error) {
	s := make([]string, len(cavs))
	for i, cav := range cavs {
		if cav.Id == security.PublicKeyThirdPartyCaveat.Id {
			c := cav.ThirdPartyDetails()
			s[i] = fmt.Sprintf("ThirdPartyCaveat: Requires discharge from %v (ID=%q)", c.Location(), c.ID())
			continue
		}

		var param interface{}
		if err := vom.Decode(cav.ParamVom, &param); err != nil {
			return nil, err
		}
		switch cav.Id {
		case security.ExpiryCaveat.Id:
			s[i] = fmt.Sprintf("Expires at %v", param)
		case security.MethodCaveat.Id:
			s[i] = fmt.Sprintf("Restricted to methods %v", param)
		case security.PeerBlessingsCaveat.Id:
			s[i] = fmt.Sprintf("Restricted to peers with blessings %v", param)
		default:
			s[i] = cav.String()
		}
	}
	return s, nil
}

func (h *handler) revoke(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	const (
		success = `{"success": "true"}`
		failure = `{"success": "false"}`
	)
	if h.args.RevocationManager == nil {
		vlog.Infof("no provided revocation manager")
		w.Write([]byte(failure))
		return
	}

	content, err := ioutil.ReadAll(r.Body)
	if err != nil {
		vlog.Infof("Failed to parse request: %s", err)
		w.Write([]byte(failure))
		return
	}
	var requestParams struct {
		Token string
	}
	if err := json.Unmarshal(content, &requestParams); err != nil {
		vlog.Infof("json.Unmarshal failed : %s", err)
		w.Write([]byte(failure))
		return
	}

	var caveatID string
	if caveatID, err = h.validateRevocationToken(requestParams.Token, r); err != nil {
		vlog.Infof("failed to validate token for caveat: %s", err)
		w.Write([]byte(failure))
		return
	}
	if err := h.args.RevocationManager.Revoke(caveatID); err != nil {
		vlog.Infof("Revocation failed: %s", err)
		w.Write([]byte(failure))
		return
	}

	w.Write([]byte(success))
	return
}

func (h *handler) validateRevocationToken(Token string, r *http.Request) (string, error) {
	var encCaveatID string
	if err := h.csrfCop.ValidateToken(Token, r, clientIDCookie, &encCaveatID); err != nil {
		return "", fmt.Errorf("invalid CSRF token: %v in request: %#v", err, r)
	}
	caveatID, err := base64.URLEncoding.DecodeString(encCaveatID)
	if err != nil {
		return "", fmt.Errorf("decode caveatID failed: %v", err)
	}
	return string(caveatID), nil
}

type seekBlessingsMacaroon struct {
	RedirectURL, State string
	PublicKey          []byte // Marshaled public key of the principal tool.
}

func validLoopbackURL(u string) (*url.URL, error) {
	netURL, err := url.Parse(u)
	if err != nil {
		return nil, fmt.Errorf("invalid url: %v", err)
	}
	// Remove the port from the netURL.Host.
	host, _, err := net.SplitHostPort(netURL.Host)
	// Check if its localhost or loopback ip
	if host == "localhost" {
		return netURL, nil
	}
	urlIP := net.ParseIP(host)
	if urlIP.IsLoopback() {
		return netURL, nil
	}
	return nil, fmt.Errorf("invalid loopback url")
}

func (h *handler) seekBlessings(w http.ResponseWriter, r *http.Request) {
	redirect := r.FormValue("redirect_url")
	if _, err := validLoopbackURL(redirect); err != nil {
		vlog.Infof("seekBlessings failed: invalid redirect_url: %v", err)
		util.HTTPBadRequest(w, r, fmt.Errorf("invalid redirect_url: %v", err))
		return
	}
	pubKeyBytes, err := base64.URLEncoding.DecodeString(r.FormValue("public_key"))
	if err != nil {
		vlog.Infof("seekBlessings failed: invalid public_key: %v", err)
		util.HTTPBadRequest(w, r, fmt.Errorf("invalid public_key: %v", err))
		return
	}
	outputMacaroon, err := h.csrfCop.NewToken(w, r, clientIDCookie, seekBlessingsMacaroon{
		RedirectURL: redirect,
		State:       r.FormValue("state"),
		PublicKey:   pubKeyBytes,
	})
	if err != nil {
		vlog.Infof("Failed to create CSRF token[%v] for request %#v", err, r)
		util.HTTPServerError(w, fmt.Errorf("failed to create new token: %v", err))
		return
	}
	http.Redirect(w, r, h.args.OAuthProvider.AuthURL(redirectURL(h.args.Addr, addCaveatsRoute), outputMacaroon, ExplicitApproval), http.StatusFound)
}

type addCaveatsMacaroon struct {
	ToolRedirectURL, ToolState, Email string
	ToolPublicKey                     []byte // Marshaled public key of the principal tool.
}

func (h *handler) addCaveats(w http.ResponseWriter, r *http.Request) {
	var inputMacaroon seekBlessingsMacaroon
	if err := h.csrfCop.ValidateToken(r.FormValue("state"), r, clientIDCookie, &inputMacaroon); err != nil {
		util.HTTPBadRequest(w, r, fmt.Errorf("Suspected request forgery: %v", err))
		return
	}
	email, err := h.args.OAuthProvider.ExchangeAuthCodeForEmail(r.FormValue("code"), redirectURL(h.args.Addr, addCaveatsRoute))
	if err != nil {
		util.HTTPBadRequest(w, r, err)
		return
	}
	outputMacaroon, err := h.csrfCop.NewToken(w, r, clientIDCookie, addCaveatsMacaroon{
		ToolRedirectURL: inputMacaroon.RedirectURL,
		ToolState:       inputMacaroon.State,
		ToolPublicKey:   inputMacaroon.PublicKey,
		Email:           email,
	})
	if err != nil {
		vlog.Infof("Failed to create caveatForm token[%v] for request %#v", err, r)
		util.HTTPServerError(w, fmt.Errorf("failed to create new token: %v", err))
		return
	}
	localBlessings := security.DefaultBlessingPatterns(h.args.Principal)
	if len(localBlessings) == 0 {
		vlog.Infof("server principal has no blessings: %v", h.args.Principal)
		util.HTTPServerError(w, fmt.Errorf("failed to get server blessings"))
		return
	}
	fullBlessingName := strings.Join([]string{string(localBlessings[0]), email}, security.ChainSeparator)
	if err := h.args.CaveatSelector.Render(fullBlessingName, outputMacaroon, redirectURL(h.args.Addr, sendMacaroonRoute), w, r); err != nil {
		vlog.Errorf("Unable to invoke render caveat selector: %v", err)
		util.HTTPServerError(w, err)
	}
}

func (h *handler) sendMacaroon(w http.ResponseWriter, r *http.Request) {
	var inputMacaroon addCaveatsMacaroon
	caveatInfos, macaroonString, blessingExtension, err := h.args.CaveatSelector.ParseSelections(r)
	cancelled := err == caveats.ErrSeekblessingsCancelled
	if !cancelled && err != nil {
		util.HTTPBadRequest(w, r, fmt.Errorf("failed to parse blessing information: %v", err))
		return
	}
	if err := h.csrfCop.ValidateToken(macaroonString, r, clientIDCookie, &inputMacaroon); err != nil {
		util.HTTPBadRequest(w, r, fmt.Errorf("suspected request forgery: %v", err))
		return
	}
	// Construct the url to send back to the tool.
	baseURL, err := validLoopbackURL(inputMacaroon.ToolRedirectURL)
	if err != nil {
		util.HTTPBadRequest(w, r, fmt.Errorf("invalid ToolRedirectURL: %v", err))
		return
	}
	// Now that we have a valid tool redirect url, we can send the errors to the tool.
	if cancelled {
		h.sendErrorToTool(w, r, inputMacaroon.ToolState, baseURL, caveats.ErrSeekblessingsCancelled)
	}
	caveats, err := h.caveats(caveatInfos)
	if err != nil {
		h.sendErrorToTool(w, r, inputMacaroon.ToolState, baseURL, fmt.Errorf("failed to create caveats: %v", err))
		return
	}
	parts := []string{inputMacaroon.Email}
	if len(blessingExtension) > 0 {
		parts = append(parts, blessingExtension)
	}
	if len(caveats) == 0 {
		h.sendErrorToTool(w, r, inputMacaroon.ToolState, baseURL, fmt.Errorf("server disallows attempts to bless with no caveats"))
		return
	}
	m := BlessingMacaroon{
		Creation:  time.Now(),
		Caveats:   caveats,
		Name:      strings.Join(parts, security.ChainSeparator),
		PublicKey: inputMacaroon.ToolPublicKey,
	}
	macBytes, err := vom.Encode(m)
	if err != nil {
		h.sendErrorToTool(w, r, inputMacaroon.ToolState, baseURL, fmt.Errorf("failed to encode BlessingsMacaroon: %v", err))
		return
	}
	marshalKey, err := h.args.Principal.PublicKey().MarshalBinary()
	if err != nil {
		h.sendErrorToTool(w, r, inputMacaroon.ToolState, baseURL, fmt.Errorf("failed to marshal public key: %v", err))
		return
	}
	encKey := base64.URLEncoding.EncodeToString(marshalKey)
	params := url.Values{}
	params.Add("macaroon", string(util.NewMacaroon(h.args.MacaroonKey, macBytes)))
	params.Add("state", inputMacaroon.ToolState)
	params.Add("object_name", h.args.MacaroonBlessingService)
	params.Add("root_key", encKey)
	baseURL.RawQuery = params.Encode()
	http.Redirect(w, r, baseURL.String(), http.StatusFound)
}

func (h *handler) sendErrorToTool(w http.ResponseWriter, r *http.Request, toolState string, baseURL *url.URL, err error) {
	errEnc := base64.URLEncoding.EncodeToString([]byte(err.Error()))
	params := url.Values{}
	params.Add("error", errEnc)
	params.Add("state", toolState)
	baseURL.RawQuery = params.Encode()
	http.Redirect(w, r, baseURL.String(), http.StatusFound)
}

func (h *handler) caveats(caveatInfos []caveats.CaveatInfo) (cavs []security.Caveat, err error) {
	caveatFactories := caveats.NewCaveatFactory()
	for _, caveatInfo := range caveatInfos {
		if caveatInfo.Type == "Revocation" {
			caveatInfo.Args = []interface{}{h.args.RevocationManager, h.args.Principal.PublicKey(), h.args.DischargerLocation}
		}
		cav, err := caveatFactories.New(caveatInfo)
		if err != nil {
			return nil, err
		}
		cavs = append(cavs, cav)
	}
	return
}
