package gig

import (

"crypto/x509"

)

type (

// CertAuthConfig defines the config for CertAuth middleware.

CertAuthConfig struct {

// Skipper defines a function to skip middleware.

Skipper Skipper

// Validator is a function to validate client certificate.

// Required.

Validator CertAuthValidator

}

// CertAuthValidator defines a function to validate CertAuth credentials.

CertAuthValidator func(*x509.Certificate, Context) *GeminiError

)

var (

// DefaultCertAuthConfig is the default CertAuth middleware config.

DefaultCertAuthConfig = CertAuthConfig{

Skipper: DefaultSkipper,

Validator: ValidateHasCertificate,

}

)

// ValidateHasCertificate returns ErrClientCertificateRequired if no certificate is sent.

// It also stores subject name in context under "subject".

func ValidateHasCertificate(cert *x509.Certificate, c Context) *GeminiError {

if cert == nil {

return ErrClientCertificateRequired

}

c.Set("subject", cert.Subject.CommonName)

return nil

}

// CertAuth returns an CertAuth middleware.

//

// For valid credentials it calls the next handler.

func CertAuth(fn CertAuthValidator) MiddlewareFunc {

c := DefaultCertAuthConfig

c.Validator = fn

return CertAuthWithConfig(c)

}

// CertAuthWithConfig returns an CertAuth middleware with config.

// See `CertAuth()`.

func CertAuthWithConfig(config CertAuthConfig) MiddlewareFunc {

// Defaults

if config.Validator == nil {

config.Validator = DefaultCertAuthConfig.Validator

}

if config.Skipper == nil {

config.Skipper = DefaultCertAuthConfig.Skipper

}

return func(next HandlerFunc) HandlerFunc {

return func(c Context) error {

if config.Skipper(c) {

return next(c)

}

// Verify credentials

err := config.Validator(c.Certificate(), c)

if err != nil {

return err

}

return next(c)

}

}

}


Source