mirror of
https://github.com/lightninglabs/aperture.git
synced 2026-01-24 11:44:24 +01:00
auth: LsatAuthenticator -> L402Authenticator sed -i 's/LsatAuthenticator/L402Authenticator/g' aperture.go auth/authenticator.go auth/authenticator_test.go rename package lsat to l402 git mv lsat/ l402 sed 's@aperture/lsat@aperture/l402@g' -i `git grep -l aperture/lsat` sed -i 's@package lsat@package l402@' `git grep -l 'package lsat'` sed -i 's@lsat\.@l402.@g' -i `git grep -l 'lsat\.'` sed 's@l402.Id@lsat.Id@' -i mint/mint_test.go replace lsat with l402 in the code sed 's@lsat@l402@' -i mint/mint_test.go sed 's@Lsat@L402@' -i l402/client_interceptor.go sed 's@lsatstore@l402store@' -i l402/store_test.go replace LSAT to L402 in comments sed '/\/\//s@LSAT@L402@g' -i `git grep -l '//.*LSAT'` replace LSAT -> L402 in the code, skip when a string starts with it sed 's@\([^"/]\)LSAT@\1L402@g' -i `git grep -l LSAT`
106 lines
2.7 KiB
Go
106 lines
2.7 KiB
Go
package auth
|
|
|
|
import (
|
|
"context"
|
|
"encoding/base64"
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"github.com/lightninglabs/aperture/l402"
|
|
"github.com/lightninglabs/aperture/mint"
|
|
"github.com/lightningnetwork/lnd/lnrpc"
|
|
)
|
|
|
|
// L402Authenticator is an authenticator that uses the L402 protocol to
|
|
// authenticate requests.
|
|
type L402Authenticator struct {
|
|
minter Minter
|
|
checker InvoiceChecker
|
|
}
|
|
|
|
// A compile time flag to ensure the L402Authenticator satisfies the
|
|
// Authenticator interface.
|
|
var _ Authenticator = (*L402Authenticator)(nil)
|
|
|
|
// NewL402Authenticator creates a new authenticator that authenticates requests
|
|
// based on L402 tokens.
|
|
func NewL402Authenticator(minter Minter,
|
|
checker InvoiceChecker) *L402Authenticator {
|
|
|
|
return &L402Authenticator{
|
|
minter: minter,
|
|
checker: checker,
|
|
}
|
|
}
|
|
|
|
// Accept returns whether or not the header successfully authenticates the user
|
|
// to a given backend service.
|
|
//
|
|
// NOTE: This is part of the Authenticator interface.
|
|
func (l *L402Authenticator) Accept(header *http.Header, serviceName string) bool {
|
|
// Try reading the macaroon and preimage from the HTTP header. This can
|
|
// be in different header fields depending on the implementation and/or
|
|
// protocol.
|
|
mac, preimage, err := l402.FromHeader(header)
|
|
if err != nil {
|
|
log.Debugf("Deny: %v", err)
|
|
return false
|
|
}
|
|
|
|
verificationParams := &mint.VerificationParams{
|
|
Macaroon: mac,
|
|
Preimage: preimage,
|
|
TargetService: serviceName,
|
|
}
|
|
err = l.minter.VerifyL402(context.Background(), verificationParams)
|
|
if err != nil {
|
|
log.Debugf("Deny: L402 validation failed: %v", err)
|
|
return false
|
|
}
|
|
|
|
// Make sure the backend has the invoice recorded as settled.
|
|
err = l.checker.VerifyInvoiceStatus(
|
|
preimage.Hash(), lnrpc.Invoice_SETTLED,
|
|
DefaultInvoiceLookupTimeout,
|
|
)
|
|
if err != nil {
|
|
log.Debugf("Deny: Invoice status mismatch: %v", err)
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// FreshChallengeHeader returns a header containing a challenge for the user to
|
|
// complete.
|
|
//
|
|
// NOTE: This is part of the Authenticator interface.
|
|
func (l *L402Authenticator) FreshChallengeHeader(r *http.Request,
|
|
serviceName string, servicePrice int64) (http.Header, error) {
|
|
|
|
service := l402.Service{
|
|
Name: serviceName,
|
|
Tier: l402.BaseTier,
|
|
Price: servicePrice,
|
|
}
|
|
mac, paymentRequest, err := l.minter.MintL402(
|
|
context.Background(), service,
|
|
)
|
|
if err != nil {
|
|
log.Errorf("Error minting L402: %v", err)
|
|
return nil, err
|
|
}
|
|
macBytes, err := mac.MarshalBinary()
|
|
if err != nil {
|
|
log.Errorf("Error serializing L402: %v", err)
|
|
}
|
|
|
|
str := fmt.Sprintf("LSAT macaroon=\"%s\", invoice=\"%s\"",
|
|
base64.StdEncoding.EncodeToString(macBytes), paymentRequest)
|
|
header := r.Header
|
|
header.Set("WWW-Authenticate", str)
|
|
|
|
log.Debugf("Created new challenge header: [%s]", str)
|
|
return header, nil
|
|
}
|