Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aperture as a library - nice to have's #45

Open
ghost opened this issue Sep 19, 2020 · 0 comments
Open

Aperture as a library - nice to have's #45

ghost opened this issue Sep 19, 2020 · 0 comments

Comments

@ghost
Copy link

ghost commented Sep 19, 2020

Hey guys! Thanks again for aperture, really interested mostly in using it as a library than a proxy over existing services. Not sure if that's the direction you want to be open to or not but there was some things I had in my local project that I thought would be good to discuss & potentially contribute back as feedback.

First is mostly around exports. There's some things in aperture that I'd like to not have to copy/paste into my project, so things like newStaticServiceLimiter and LndChallenger.client would be great to have exported.

Along these lines, another improvement that would be nice to have would be to allow the invoice checker to be optional. I'm kind of curious why that was introduced actually, shouldn't preimage always be good enough to prove an invoice was paid? Unless of course someone accessed the node and viewed the preimage themselves, or created the invoice with a preimage. I think those are edge cases that may be nice to ignore without having to create the classes myself with empty methods fulfilling the InvoiceChecker interface.

I created a PR here with some of these changes - mostly as a way to visualize what I mean and discuss. Happy to clean up or go a different direction with some of the code to produce a similar result. #44

And some examples of how I use the proposed code:

func (l *lightningAuth) VerifyLightningAuth(o *AuthOptions) (bool, error) {
	// challenger
	genInvoiceReq := func(price int64) (*lnrpc.Invoice, error) {
		return &lnrpc.Invoice{
			Memo:  "LSAT",
			Value: price,
		}, nil
	}
	challenger := &aperture.LndChallenger{
		Client:                  l.lndClient,
		GenInvoiceReq:           genInvoiceReq,
		VerifyInvoiceStatusFunc: VerifyInvoiceStatusNil,
	}

	// limiter
	s := lsat.Service{
		Name:  o.ServiceName,
		Tier:  lsat.BaseTier,
		Price: o.Price,
	}
	limiter := &aperture.StaticServiceLimiter{}
	if o.Capabilities != "" {
		limiter.Capabilities = map[lsat.Service]lsat.Caveat{
			s: lsat.NewCapabilitiesCaveat(s.Name, o.Capabilities),
		}
	}

	authenticator := auth.NewLsatAuthenticator(
		mint.New(&mint.Config{
			Secrets:        l.secretStorage,
			Challenger:     challenger,
			ServiceLimiter: limiter,
		}),
		challenger,
	)

	return authenticator.Accept(o.H, o.ServiceName), nil
}

func (l *lightningAuth) NewChallengeHeader(o *AuthOptions) (http.Header, error) {
	// challenger
	genInvoiceReq := func(price int64) (*lnrpc.Invoice, error) {
		return &lnrpc.Invoice{
			Memo:  "LSAT",
			Value: price,
		}, nil
	}
	challenger := &aperture.LndChallenger{
		Client:                  l.lndClient,
		GenInvoiceReq:           genInvoiceReq,
		VerifyInvoiceStatusFunc: VerifyInvoiceStatusNil,
	}

	// limiter
	s := lsat.Service{
		Name:  o.ServiceName,
		Tier:  lsat.BaseTier,
		Price: o.Price,
	}
	limiter := &aperture.StaticServiceLimiter{}
	if o.Capabilities != "" {
		limiter.Capabilities = map[lsat.Service]lsat.Caveat{
			s: lsat.NewCapabilitiesCaveat(s.Name, o.Capabilities),
		}
	}

	authenticator := auth.NewLsatAuthenticator(
		mint.New(&mint.Config{
			Secrets:        l.secretStorage,
			Challenger:     challenger,
			ServiceLimiter: limiter,
		}),
		challenger,
	)

	return authenticator.FreshChallengeHeader(o.R, o.ServiceName, o.Price)
}

I'm making the connection to LND myself, so exporting Client would be nice so I don't have to go through creating the challenger via NewLndChallenger way. Also I'm not going to be consistently connected to the possibly many lnd clients I'd be creating invoices from, so I'm simply only caring about preimage matching macaroon (so not constantly streaming invoice statuses or caring about invoice checking).

Anyways, thoughts? I'm okay keeping a fork for what could be very edge case/specialized behavior specific to me. Just thought I seen some thing that made me want to talk about contributing back. Going a different direction to establish the same goals is okay too, just got a quick mvp of what I thought I needed myself. I have some other ideas around capabilities and constraints that may be nice to chat about in another issue in the near future too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

0 participants