// Utility methods for implementing authenticated webhooks.
//
// All requests must either be over a private channel (e.g. https) or must be
// idempotent and return no data. Requests sent via an open channel (e.g. http)
// could be resent by an attacker.
package webhook

import (
	"bytes"
	"context"
	"crypto/sha512"
	"encoding/base64"
	"fmt"
	"io"
	"net/http"
	"os"

	"go.skia.org/infra/go/metadata"
	"go.skia.org/infra/go/secret"
	"go.skia.org/infra/go/sklog"
	skutil "go.skia.org/infra/go/util"
)

// Required header for requests to a webhook authenticated using AuthenticateRequest. The value must
// be set to the result of ComputeAuthHashBase64.
const REQUEST_AUTH_HASH_HEADER = "X-Webhook-Auth-Hash"

var requestSalt []byte = nil

// InitRequestSaltForTesting sets requestSalt to "notverysecret". Should be called once at startup
// when running in test mode.
//
// To test a webhook endpoint using curl, the following commands should work:
// $ DATA='my post request'
// $ AUTH="$(echo -n "${DATA}notverysecret" | sha512sum | xxd -r -p - | base64 -w 0)"
// $ curl -v -H "X-Webhook-Auth-Hash: $AUTH" -d "$DATA" http://localhost:8000/endpoint
func InitRequestSaltForTesting() {
	requestSalt = []byte("notverysecret")
}

func setRequestSaltFromBase64(saltBase64 []byte) error {
	enc := base64.StdEncoding
	decodedLen := enc.DecodedLen(len(saltBase64))
	salt := make([]byte, decodedLen)
	n, err := enc.Decode(salt, saltBase64)
	if err != nil {
		return err
	}
	requestSalt = salt[:n]
	return nil
}

// InitRequestSaltFromMetadata reads requestSalt from the specified project metadata
// and returns any error encountered. Should be called once at startup.
func InitRequestSaltFromMetadata(metadataKey string) error {
	saltBase64, err := metadata.ProjectGet(metadataKey)
	if err != nil {
		return err
	}
	if err := setRequestSaltFromBase64([]byte(saltBase64)); err != nil {
		return fmt.Errorf("Could not decode salt from %s: %s", metadataKey, err)
	}
	return nil
}

// MustInitRequestSaltFromMetadata reads requestSalt from the specified project
// metadata. Exits the program on error. Should be called once at startup.
func MustInitRequestSaltFromMetadata(metadataKey string) {
	if err := InitRequestSaltFromMetadata(metadataKey); err != nil {
		sklog.Fatal(err)
	}
}

// InitRequestSaltFromFile reads requestSalt from the given file and returns any error encountered.
// Should be called once at startup.
func InitRequestSaltFromFile(filename string) error {
	saltBase64Bytes, err := os.ReadFile(filename)
	if err != nil {
		return fmt.Errorf("Could not read the webhook request salt file: %s", err)
	}
	if err = setRequestSaltFromBase64(saltBase64Bytes); err != nil {
		return fmt.Errorf("Could not decode salt from %s: %s", filename, err)
	}
	return nil
}

// MustInitRequestSaltFromFile reads requestSalt from the given file. Exits the program on error.
// Should be called once at startup.
func MustInitRequestSaltFromFile(filename string) {
	if err := InitRequestSaltFromFile(filename); err != nil {
		sklog.Fatal(err)
	}
}

// InitRequestSaltFromSecret reads requestSalt from the specified GCP secret
// and returns any error encountered. Should be called once at startup.
func InitRequestSaltFromSecret(project, secretName string) error {
	ctx := context.Background()
	secretClient, err := secret.NewClient(ctx)
	if err != nil {
		return err
	}
	saltBase64, err := secretClient.Get(ctx, project, secretName, secret.VersionLatest)
	if err != nil {
		return err
	}
	if err := setRequestSaltFromBase64([]byte(saltBase64)); err != nil {
		return fmt.Errorf("Could not decode salt from %s: %s", secretName, err)
	}
	return nil
}

// MustInitRequestSaltFromSecret reads requestSalt from the specified GCP
// secret. Exits the program on error. Should be called once at startup.
func MustInitRequestSaltFromSecret(project, secret string) {
	if err := InitRequestSaltFromSecret(project, secret); err != nil {
		sklog.Fatal(err)
	}
}

// Computes the value for REQUEST_AUTH_HASH_HEADER from the request body. Returns error if
// requestSalt has not been initialized. The result is the base64-encoded SHA-512 hash of the
// request body with requestSalt appended.
func ComputeAuthHashBase64(data []byte) (string, error) {
	if len(requestSalt) == 0 {
		return "", fmt.Errorf("requestSalt is uninitialized.")
	}
	data = append(data, requestSalt...)
	hash := sha512.Sum512(data)
	return base64.StdEncoding.EncodeToString(hash[:]), nil
}

// NewRequest is similar to http.NewRequest, but adds the REQUEST_AUTH_HASH_HEADER for
// authentication.
func NewRequest(method, urlStr string, body []byte) (*http.Request, error) {
	req, err := http.NewRequest(method, urlStr, bytes.NewReader(body))
	if err != nil {
		return nil, err
	}
	hash, err := ComputeAuthHashBase64(body)
	if err != nil {
		return nil, err
	}
	req.Header.Set(REQUEST_AUTH_HASH_HEADER, hash)
	return req, nil
}

// Authenticates a webhook request.
//   - If an error occurs reading r.Body, returns nil and the error.
//   - If the request could not be authenticated as a webhook request, returns the contents of r.Body
//     and an error.
//   - Otherwise, returns the contents of r.Body and nil.
//
// In all cases, closes r.Body.
func AuthenticateRequest(r *http.Request) ([]byte, error) {
	defer skutil.Close(r.Body)
	data, err := io.ReadAll(r.Body)
	if err != nil {
		return nil, err
	}
	headerHashBase64 := r.Header.Get(REQUEST_AUTH_HASH_HEADER)
	if headerHashBase64 == "" {
		return data, fmt.Errorf("No authentication header %s", REQUEST_AUTH_HASH_HEADER)
	}
	dataHashBase64, err := ComputeAuthHashBase64(data)
	if err != nil {
		return data, err
	}
	if headerHashBase64 == dataHashBase64 {
		return data, nil
	}
	return data, fmt.Errorf("Authentication header %s: %s did not match.", REQUEST_AUTH_HASH_HEADER, headerHashBase64)
}
