package tlsauth

import (
	"context"
	"crypto/x509"

	sr "tildegit.org/tjp/sliderule"
)

// Identity returns the client certificate for the request or nil if there is none.
func Identity(request *sr.Request) *x509.Certificate {
	if request.TLSState == nil || len(request.TLSState.PeerCertificates) == 0 {
		return nil
	}
	return request.TLSState.PeerCertificates[0]
}

// RequiredAuth produces an auth predicate.
//
// The check requires both that there is a client certificate associated with the
// request and that it passes the provided approver.
func RequiredAuth(approve Approver) func(context.Context, *sr.Request) bool {
	return func(_ context.Context, request *sr.Request) bool {
		identity := Identity(request)
		if identity == nil {
			return false
		}

		return approve(identity)
	}
}

// OptionalAuth produces an auth predicate.
//
// The check allows through any request with no client certificate, but if
// there is one present then it requires that it pass the provided approver.
func OptionalAuth(approve Approver) func(context.Context, *sr.Request) bool {
	return func(_ context.Context, request *sr.Request) bool {
		identity := Identity(request)
		if identity == nil {
			return true
		}

		return approve(identity)
	}
}