// 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 handlers

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"net/http"
	"strings"
	"sync"
	"time"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/security"
	"v.io/v23/vom"
	"v.io/x/ref/lib/stats"
	"v.io/x/ref/lib/stats/counter"
	"v.io/x/ref/services/identity/internal/oauth"
	"v.io/x/ref/services/identity/internal/revocation"
	"v.io/x/ref/services/identity/internal/util"
)

const (
	publicKeyFormKey    = "public_key"
	tokenFormKey        = "token"
	caveatsFormKey      = "caveats"
	outputFormatFormKey = "output_format"

	jsonFormat      = "json"
	base64VomFormat = "base64vom"
)

// Map of client id -> blessing extension
// The blessing given for a token with ClientID 'id' is generated by extending
// the default blessing of this service's principal with the extension held
// in this map for 'id'.
// The string "{email}" in the Extension will be replaced by the email from the
// request's access token.
type RegisteredAppMap map[string]struct {
	Extension string
}

// OAuthBlesserParams represents all the parameters required for exchanging an
// OAuth token for blessings.
type OAuthBlesserParams struct {
	// The OAuth provider that must have issued the access tokens accepted by ths service.
	OAuthProvider oauth.OAuthProvider
	// The object name of the discharger service. If this is empty then revocation caveats will not be granted.
	DischargerLocation string
	// The revocation manager that generates caveats and manages revocation.
	RevocationManager revocation.RevocationManager
	// The duration for which blessings will be valid. (Used iff RevocationManager is nil).
	BlessingDuration time.Duration
}

type accessTokenBlesser struct {
	ctx    *context.T
	params OAuthBlesserParams
	apps   RegisteredAppMap

	countersMu sync.Mutex
	counters   map[string]*counter.Counter
}

// NewOAuthBlessingHandler returns an http.Handler that uses Google OAuth2 Access tokens
// to obtain the username of the requestor and reponds with blessings for that username.
//
// The blessings are namespaced under the ClientID for the access token. In particular,
// the name of the granted blessing is of the form <idp>:<appID>:<email> where <idp>
// is the name of the default blessings used by the identity provider and
// <appID> is the name of the 'app' - either the OAuth ClientID or a registered
// alias.
//
// Blessings generated by this service carry a third-party revocation caveat if a
// RevocationManager is specified by the params or they carry an ExpiryCaveat that
// expires after the duration specified by the params.
//
// The handler expects the following request parameters:
// - "public_key": Base64 DER encoded PKIX representation of the client's public key
// - "caveats": Base64 VOM encoded list of caveats [OPTIONAL]
// - "token": Google OAuth2 Access token
// - "output_format": The encoding format for the returned blessings. The following
//   formats are supported:
//     - "json": JSON-encoding of the wire format of Blessings.
//     - "base64vom": Base64URL encoding of VOM-encoded Blessings [DEFAULT]
//
// The response consists of blessings encoded in the requested output format.
//
// WARNINGS:
//   - There is no binding between the channel over which the access token
//     was obtained and the channel used to make this request.
//   - There is no "proof of possession of private key" required by the server.
// Thus, if Mallory (attacker) possesses the access token associated with Alice's
// account (victim), she may be able to obtain a blessing with Alice's name on it
// for any public key of her choice.
func NewOAuthBlessingHandler(ctx *context.T, params OAuthBlesserParams, apps RegisteredAppMap) http.Handler {
	if apps == nil {
		apps = make(RegisteredAppMap)
	}
	return &accessTokenBlesser{ctx: ctx, params: params, apps: apps}
}

func (a *accessTokenBlesser) blessingCaveats(r *http.Request, p security.Principal) ([]security.Caveat, error) {
	var caveats []security.Caveat
	if base64VomCaveats := r.FormValue(caveatsFormKey); len(base64VomCaveats) != 0 {
		vomCaveats, err := base64.URLEncoding.DecodeString(base64VomCaveats)
		if err != nil {
			return nil, fmt.Errorf("base64.URLEncoding.DecodeString failed: %v", err)
		}

		if err := vom.Decode(vomCaveats, &caveats); err != nil {
			return nil, fmt.Errorf("vom.Decode failed: %v", err)
		}
	}
	if len(caveats) == 0 {
		var (
			cav security.Caveat
			err error
		)
		if a.params.RevocationManager != nil {
			cav, err = a.params.RevocationManager.NewCaveat(p.PublicKey(), a.params.DischargerLocation)
		} else {
			cav, err = security.NewExpiryCaveat(time.Now().Add(a.params.BlessingDuration))
		}
		if err != nil {
			return nil, fmt.Errorf("failed to construct caveats: %v", err)
		}
		caveats = append(caveats, cav)
	}
	return caveats, nil

}

func (a *accessTokenBlesser) remotePublicKey(r *http.Request) (security.PublicKey, error) {
	publicKeyVom, err := base64.URLEncoding.DecodeString(r.FormValue(publicKeyFormKey))
	if err != nil {
		return nil, fmt.Errorf("base64.URLEncoding.DecodeString failed: %v", err)
	}
	return security.UnmarshalPublicKey(publicKeyVom)
}

func (a *accessTokenBlesser) blessingExtension(r *http.Request) (string, error) {
	email, clientID, err := a.params.OAuthProvider.GetEmailAndClientID(r.FormValue(tokenFormKey))
	if err != nil {
		return "", err
	}
	if entry, ok := a.apps[clientID]; ok {
		return strings.Replace(entry.Extension, "{email}", email, -1), nil
	}

	// We use <clientID>/<email> as the extension in order to namespace the blessing under
	// the <clientID>. This has the downside that the blessing cannot be used to act on
	// behalf of the user, i.e., services access controlled to blessings matching"<idp>/<email>"
	// would not authorize this blessing.
	//
	// The alternative is to use the extension <email>/<clientID> however this is risky as it
	// may provide too much authority to the app, especially since we don't have a set of default
	// caveats to apply to the blessing.
	//
	// TODO(ataly, ashankar): Think about changing to the extension <email>/<clientID>.
	return strings.Join([]string{clientID, email}, security.ChainSeparator), nil
}

func (a *accessTokenBlesser) encodeBlessingsJson(b security.Blessings) ([]byte, error) {
	return json.Marshal(security.MarshalBlessings(b))
}

func (a *accessTokenBlesser) encodeBlessingsVom(b security.Blessings) (string, error) {
	bVom, err := vom.Encode(b)
	if err != nil {
		return "", fmt.Errorf("vom.Encode(%v) failed: %v", b, err)
	}
	return base64.URLEncoding.EncodeToString(bVom), nil
}

func (a *accessTokenBlesser) counter(name string) *counter.Counter {
	a.countersMu.Lock()
	defer a.countersMu.Unlock()
	if a.counters == nil {
		a.counters = make(map[string]*counter.Counter)
	}
	if c := a.counters[name]; c != nil {
		return c
	}
	c := stats.NewCounter(fmt.Sprint("http/blessings/", name))
	a.counters[name] = c
	return c
}

func (a *accessTokenBlesser) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	remoteKey, err := a.remotePublicKey(r)
	if err != nil {
		a.ctx.Infof("Failed to decode public key [%v] for request %#v", err, r)
		util.HTTPServerError(w, fmt.Errorf("failed to decode public key: %v", err))
		return
	}

	p := v23.GetPrincipal(a.ctx)
	with, _ := p.BlessingStore().Default()

	caveats, err := a.blessingCaveats(r, p)
	if err != nil {
		a.ctx.Infof("Failed to constuct caveats for blessing [%v] for request %#v", err, r)
		util.HTTPServerError(w, fmt.Errorf("failed to construct caveats for blessing: %v", err))
		return
	}

	extension, err := a.blessingExtension(r)
	if err != nil {
		a.ctx.Infof("Failed to process access token [%v] for request %#v", err, r)
		util.HTTPServerError(w, fmt.Errorf("failed to process access token: %v", err))
		return
	}

	blessings, err := p.Bless(remoteKey, with, extension, caveats[0], caveats[1:]...)
	if err != nil {
		a.ctx.Infof("Failed to Bless [%v] for request %#v", err, r)
		util.HTTPServerError(w, fmt.Errorf("failed to Bless: %v", err))
		return
	}
	a.counter(with.String()).Incr(1)

	outputFormat := r.FormValue(outputFormatFormKey)
	if len(outputFormat) == 0 {
		outputFormat = base64VomFormat
	}
	switch outputFormat {
	case jsonFormat:
		encodedBlessings, err := a.encodeBlessingsJson(blessings)
		if err != nil {
			a.ctx.Infof("Failed to encode blessings [%v] for request %#v", err, r)
			util.HTTPServerError(w, fmt.Errorf("failed to encode blessings in format %v: %v", outputFormat, err))
			return
		}
		w.Header().Set("Content-Type", "application/json")
		w.Write(encodedBlessings)
	case base64VomFormat:
		encodedBlessings, err := a.encodeBlessingsVom(blessings)
		if err != nil {
			a.ctx.Infof("Failed to encode blessings [%v] for request %#v", err, r)
			util.HTTPServerError(w, fmt.Errorf("failed to encode blessings in format %v: %v", outputFormat, err))
			return
		}
		w.Header().Set("Content-Type", "application/text")
		w.Write([]byte(encodedBlessings))
	default:
		a.ctx.Infof("Unrecognized output format [%v] in request %#v", outputFormat, r)
		util.HTTPServerError(w, fmt.Errorf("unrecognized output format [%v] in request. Allowed formats are [%v, %v]", outputFormat, base64VomFormat, jsonFormat))
		return
	}
}
