// 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/context"
	"v.io/v23/security"
	"v.io/v23/vom"
	"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 a function that returns the object names to which macaroons
	// created by this HTTP handler can be exchanged for a blessing.
	MacaroonBlessingService func() []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(ctx *context.T, args HandlerArgs) (http.Handler, error) {
	csrfCop, err := util.NewCSRFCop(ctx)
	if err != nil {
		return nil, fmt.Errorf("NewHandler failed to create csrfCop: %v", err)
	}
	return &handler{
		args:    args,
		csrfCop: csrfCop,
		ctx:     ctx,
	}, nil
}

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

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

func (h *handler) listBlessings(ctx *context.T, w http.ResponseWriter, r *http.Request) {
	csrf, err := h.csrfCop.NewToken(w, r, clientIDCookie, nil)
	if err != nil {
		ctx.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(ctx *context.T, w http.ResponseWriter, r *http.Request) {
	if err := h.csrfCop.ValidateToken(r.FormValue("state"), r, clientIDCookie, nil); err != nil {
		ctx.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(ctx, 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 {
		ctx.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 {
					ctx.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 {
						ctx.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 {
		ctx.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(ctx *context.T, 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 {
		ctx.Infof("no provided revocation manager")
		w.Write([]byte(failure))
		return
	}

	content, err := ioutil.ReadAll(r.Body)
	if err != nil {
		ctx.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 {
		ctx.Infof("json.Unmarshal failed : %s", err)
		w.Write([]byte(failure))
		return
	}

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

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

func (h *handler) validateRevocationToken(ctx *context.T, 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(ctx *context.T, w http.ResponseWriter, r *http.Request) {
	redirect := r.FormValue("redirect_url")
	if _, err := validLoopbackURL(redirect); err != nil {
		ctx.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 {
		ctx.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 {
		ctx.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(ctx *context.T, 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 {
		ctx.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 {
		ctx.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 {
		ctx.Errorf("Unable to invoke render caveat selector: %v", err)
		util.HTTPServerError(w, err)
	}
}

func (h *handler) sendMacaroon(ctx *context.T, 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(ctx, w, r, inputMacaroon.ToolState, baseURL, caveats.ErrSeekblessingsCancelled)
	}
	caveats, err := h.caveats(ctx, caveatInfos)
	if err != nil {
		h.sendErrorToTool(ctx, 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(ctx, 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(ctx, 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(ctx, w, r, inputMacaroon.ToolState, baseURL, fmt.Errorf("failed to marshal public key: %v", err))
		return
	}
	encKey := base64.URLEncoding.EncodeToString(marshalKey)
	objectNames := h.args.MacaroonBlessingService()
	if len(objectNames) == 0 {
		h.sendErrorToTool(ctx, w, r, inputMacaroon.ToolState, baseURL, fmt.Errorf("failed to get local server endpoints"))
		return
	}
	params := url.Values{}
	params.Add("macaroon", string(util.NewMacaroon(h.args.MacaroonKey, macBytes)))
	params.Add("state", inputMacaroon.ToolState)
	for _, s := range objectNames {
		params.Add("object_name", s)
	}
	params.Add("root_key", encKey)
	baseURL.RawQuery = params.Encode()
	http.Redirect(w, r, baseURL.String(), http.StatusFound)
}

func (h *handler) sendErrorToTool(ctx *context.T, 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(ctx *context.T, 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
}
